Subversion Repositories Kolibri OS

Rev

Rev 8896 | Rev 9045 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
8866 rgimad 3
;; Copyright (C) KolibriOS team 2004-2021. All rights reserved.    ;;
3545 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  STACK.INC                                                      ;;
7
;;                                                                 ;;
8
;;  TCP/IP stack for KolibriOS                                     ;;
9
;;                                                                 ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
11
;;                                                                 ;;
12
;;     Some parts of code are based on the work of:                ;;
13
;;      Mike Hibbett (menuetos network stack)                      ;;
14
;;      Eugen Brasoveanu (solar os network stack and drivers)      ;;
15
;;      mike.dld (kolibrios socket code)                           ;;
16
;;                                                                 ;;
17
;;     TCP part is based on 4.4BSD                                 ;;
18
;;                                                                 ;;
19
;;          GNU GENERAL PUBLIC LICENSE                             ;;
20
;;             Version 2, June 1991                                ;;
21
;;                                                                 ;;
22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
23
 
4850 mario79 24
$Revision: 9017 $
3545 hidnplayr 25
 
26
uglobal
27
        net_10ms        dd ?
28
        net_tmr_count   dw ?
29
endg
30
 
3556 hidnplayr 31
DEBUG_NETWORK_ERROR     = 1
4388 hidnplayr 32
DEBUG_NETWORK_VERBOSE   = 0
9017 hidnplayr 33
NETWORK_SANITY_CHECKS   = 1
3556 hidnplayr 34
 
3600 hidnplayr 35
NET_DEVICES_MAX         = 16
5528 hidnplayr 36
NET_BUFFERS             = 512
37
NET_BUFFER_SIZE         = 2048
3545 hidnplayr 38
ARP_BLOCK               = 1             ; true or false
39
 
3600 hidnplayr 40
EPHEMERAL_PORT_MIN      = 49152
41
EPHEMERAL_PORT_MAX      = 61000
3545 hidnplayr 42
MIN_EPHEMERAL_PORT_N    = 0x00C0        ; same in Network byte order (FIXME)
43
MAX_EPHEMERAL_PORT_N    = 0x48EE        ; same in Network byte order (FIXME)
44
 
45
; Ethernet protocol numbers
3600 hidnplayr 46
ETHER_PROTO_ARP                 = 0x0608
47
ETHER_PROTO_IPv4                = 0x0008
48
ETHER_PROTO_IPv6                = 0xDD86
49
ETHER_PROTO_PPP_DISCOVERY       = 0x6388
50
ETHER_PROTO_PPP_SESSION         = 0x6488
3545 hidnplayr 51
 
3600 hidnplayr 52
; Internet protocol numbers
53
IP_PROTO_IP             = 0
54
IP_PROTO_ICMP           = 1
55
IP_PROTO_TCP            = 6
56
IP_PROTO_UDP            = 17
5842 hidnplayr 57
IP_PROTO_RAW            = 255
3600 hidnplayr 58
 
5842 hidnplayr 59
; IP options
60
IP_TOS                  = 1
61
IP_TTL                  = 2
62
IP_HDRINCL              = 3
63
 
3545 hidnplayr 64
; PPP protocol numbers
3600 hidnplayr 65
PPP_PROTO_IPv4          = 0x2100
66
PPP_PROTO_IPV6          = 0x5780
67
PPP_PROTO_ETHERNET      = 666           ; FIXME
3545 hidnplayr 68
 
69
;Protocol family
70
AF_UNSPEC               = 0
71
AF_LOCAL                = 1
72
AF_INET4                = 2
73
AF_INET6                = 10
3600 hidnplayr 74
AF_PPP                  = 777           ; FIXME
3545 hidnplayr 75
 
76
; Socket types
77
SOCK_STREAM             = 1
78
SOCK_DGRAM              = 2
79
SOCK_RAW                = 3
80
 
5842 hidnplayr 81
; Socket level
82
SOL_SOCKET              = 0xffff
83
 
3545 hidnplayr 84
; Socket options
85
SO_ACCEPTCON            = 1 shl 0
86
SO_BROADCAST            = 1 shl 1
87
SO_DEBUG                = 1 shl 2
88
SO_DONTROUTE            = 1 shl 3
89
SO_KEEPALIVE            = 1 shl 4
90
SO_OOBINLINE            = 1 shl 5
91
SO_REUSEADDR            = 1 shl 6
92
SO_REUSEPORT            = 1 shl 7
93
SO_USELOOPBACK          = 1 shl 8
94
SO_BINDTODEVICE         = 1 shl 9
6476 hidnplayr 95
SO_LINGER               = 1 shl 10
3545 hidnplayr 96
 
97
SO_NONBLOCK             = 1 shl 31
98
 
99
; Socket flags for user calls
100
MSG_PEEK                = 0x02
101
MSG_DONTWAIT            = 0x40
102
 
103
; Socket States
3600 hidnplayr 104
SS_NOFDREF              = 0x0001        ; no file table ref any more
105
SS_ISCONNECTED          = 0x0002        ; socket connected to a peer
106
SS_ISCONNECTING         = 0x0004        ; in process of connecting to peer
107
SS_ISDISCONNECTING      = 0x0008        ; in process of disconnecting
108
SS_CANTSENDMORE         = 0x0010        ; can't send more data to peer
109
SS_CANTRCVMORE          = 0x0020        ; can't receive more data from peer
110
SS_RCVATMARK            = 0x0040        ; at mark on input
111
SS_ISABORTING           = 0x0080        ; aborting fd references - close()
112
SS_RESTARTSYS           = 0x0100        ; restart blocked system calls
113
SS_ISDISCONNECTED       = 0x0800        ; socket disconnected from peer
3545 hidnplayr 114
 
3674 hidnplayr 115
SS_ASYNC                = 0x1000        ; async i/o notify
116
SS_ISCONFIRMING         = 0x2000        ; deciding to accept connection req
117
SS_MORETOCOME           = 0x4000
3545 hidnplayr 118
 
119
SS_BLOCKED              = 0x8000
120
 
121
 
6413 hidnplayr 122
SOCKET_BUFFER_SIZE      = 4096*8        ; must be 4096*(power of 2) where 'power of 2' is at least 8
3600 hidnplayr 123
MAX_backlog             = 20            ; maximum backlog for stream sockets
3545 hidnplayr 124
 
125
; Error Codes
3674 hidnplayr 126
ENOBUFS                 = 1
4025 hidnplayr 127
EINPROGRESS             = 2
3674 hidnplayr 128
EOPNOTSUPP              = 4
129
EWOULDBLOCK             = 6
130
ENOTCONN                = 9
131
EALREADY                = 10
132
EINVAL                  = 11
133
EMSGSIZE                = 12
134
ENOMEM                  = 18
135
EADDRINUSE              = 20
6476 hidnplayr 136
EADDRNOTAVAIL           = 21
3545 hidnplayr 137
ECONNRESET              = 52
6476 hidnplayr 138
ECONNABORTED            = 53
4025 hidnplayr 139
EISCONN                 = 56
3545 hidnplayr 140
ETIMEDOUT               = 60
6476 hidnplayr 141
ECONNREFUSED            = 61
3545 hidnplayr 142
 
143
; Api protocol numbers
144
API_ETH                 = 0
145
API_IPv4                = 1
146
API_ICMP                = 2
147
API_UDP                 = 3
148
API_TCP                 = 4
149
API_ARP                 = 5
150
API_PPPOE               = 6
151
API_IPv6                = 7
152
 
3600 hidnplayr 153
; Network device types
154
NET_DEVICE_LOOPBACK     = 0
155
NET_DEVICE_ETH          = 1
156
NET_DEVICE_SLIP         = 2
157
 
158
; Network link types (link protocols)
5528 hidnplayr 159
NET_LINK_LOOPBACK       = 0
3600 hidnplayr 160
NET_LINK_MAC            = 1     ; Media access control (ethernet, isdn, ...)
161
NET_LINK_PPP            = 2     ; Point to Point Protocol (PPPoE, ...)
162
NET_LINK_IEEE802.11     = 3     ; IEEE 802.11 (WiFi)
163
 
164
; Hardware acceleration bits
4387 hidnplayr 165
NET_HWACC_TCP_IPv4_IN   = 1 shl 0
166
NET_HWACC_TCP_IPv4_OUT  = 1 shl 1
3545 hidnplayr 167
 
5522 hidnplayr 168
; Network frame types
6011 hidnplayr 169
NET_BUFF_LOOPBACK       = 0
170
NET_BUFF_ETH            = 1
5522 hidnplayr 171
 
3545 hidnplayr 172
struct  NET_DEVICE
173
 
3600 hidnplayr 174
        device_type     dd ?    ; Type field
3545 hidnplayr 175
        mtu             dd ?    ; Maximal Transmission Unit
176
        name            dd ?    ; Ptr to 0 terminated string
177
 
178
        unload          dd ?    ; Ptrs to driver functions
179
        reset           dd ?    ;
180
        transmit        dd ?    ;
181
 
8896 hidnplayr 182
        link_state      dd ?    ; link state (0 = no link)
183
        hwacc           dd ?    ; bitmask stating enabled HW accelerations (offload engines)
184
 
3545 hidnplayr 185
        bytes_tx        dq ?    ; Statistics, updated by the driver
186
        bytes_rx        dq ?    ;
8896 hidnplayr 187
 
3545 hidnplayr 188
        packets_tx      dd ?    ;
8896 hidnplayr 189
        packets_tx_err  dd ?    ; CRC errors, too long or too short frames
190
        packets_tx_drop dd ?    ;
191
        packets_tx_ovr  dd ?    ; FIFO overrun
192
 
3545 hidnplayr 193
        packets_rx      dd ?    ;
8896 hidnplayr 194
        packets_rx_err  dd ?    ; CRC errors, too long or too short frames
195
        packets_rx_drop dd ?    ;
196
        packets_rx_ovr  dd ?    ; FIFO overrun
3545 hidnplayr 197
 
198
ends
199
 
5522 hidnplayr 200
struct  NET_BUFF
3545 hidnplayr 201
 
5522 hidnplayr 202
        NextPtr         dd ?    ; pointer to next frame in list
203
        PrevPtr         dd ?    ; pointer to previous frame in list
204
        device          dd ?    ; ptr to NET_DEVICE structure
205
        type            dd ?    ; encapsulation type: e.g. Ethernet
206
        length          dd ?    ; size of encapsulated data
207
        offset          dd ?    ; offset to actual data (24 bytes for default frame)
208
        data            rb 0
209
 
210
ends
211
 
212
 
3545 hidnplayr 213
; Exactly as it says..
214
macro pseudo_random reg {
215
        add     reg, [esp]
216
        rol     reg, 5
217
        xor     reg, [timer_ticks]
218
;        add     reg, [CPU_FREQ]
219
        imul    reg, 214013
220
        xor     reg, 0xdeadbeef
221
        rol     reg, 9
222
}
223
 
224
; Network to Hardware byte order (dword)
225
macro ntohd reg {
226
 
227
        rol     word reg, 8
228
        rol     dword reg, 16
229
        rol     word reg , 8
230
 
231
}
232
 
233
; Network to Hardware byte order (word)
234
macro ntohw reg {
235
 
236
        rol     word reg, 8
237
 
238
}
239
 
240
 
241
include "queue.inc"
242
 
243
include "loopback.inc"
244
include "ethernet.inc"
245
 
246
include "PPPoE.inc"
247
 
248
include "ARP.inc"
249
include "IPv4.inc"
250
include "IPv6.inc"
251
 
252
include "icmp.inc"
253
include "udp.inc"
254
include "tcp.inc"
255
 
256
include "socket.inc"
257
 
258
 
259
 
3698 hidnplayr 260
uglobal
3545 hidnplayr 261
align 4
262
 
7679 hidnplayr 263
        net_device_count        dd ?
264
        net_device_list         rd NET_DEVICES_MAX
3545 hidnplayr 265
 
9017 hidnplayr 266
        net_buffs_free          rd NET_BUFFERS  ; list of pointers to actual net buffs
267
        .current                dd ?            ; pointer to current element in net_buffs_free list
5528 hidnplayr 268
 
9017 hidnplayr 269
if defined NETWORK_SANITY_CHECKS
270
        net_buffs_low           dd ?            ; actual net buff mem region start
271
        net_buffs_high          dd ?            ; actual net buff mem region stop
272
end if
273
 
3545 hidnplayr 274
endg
275
 
276
 
6011 hidnplayr 277
;-----------------------------------------------------------------;
278
;                                                                 ;
279
; stack_init: Initialize all network variables                    ;
280
;                                                                 ;
281
;  IN:  /                                                         ;
282
;  OUT: /                                                         ;
283
;                                                                 ;
284
;-----------------------------------------------------------------;
3545 hidnplayr 285
align 4
286
stack_init:
287
 
5528 hidnplayr 288
; allocate network buffers
289
        stdcall kernel_alloc, NET_BUFFER_SIZE*NET_BUFFERS
290
        test    eax, eax
291
        jz      .fail
292
 
9017 hidnplayr 293
if defined NETWORK_SANITY_CHECKS
294
        mov     [net_buffs_low], eax
295
end if
296
 
7678 hidnplayr 297
        mov     edi, net_buffs_free
5528 hidnplayr 298
        mov     ecx, NET_BUFFERS
299
        cld
300
  .loop:
301
        stosd
302
        add     eax, NET_BUFFER_SIZE
303
        dec     ecx
304
        jnz     .loop
305
 
9017 hidnplayr 306
if defined NETWORK_SANITY_CHECKS
307
        sub     eax, NET_BUFFER_SIZE
308
        mov     [net_buffs_high], eax
309
end if
310
 
7678 hidnplayr 311
        mov     eax, net_buffs_free
5528 hidnplayr 312
        stosd
313
 
3545 hidnplayr 314
; Init the network drivers list
315
        xor     eax, eax
7679 hidnplayr 316
        mov     edi, net_device_count
5524 hidnplayr 317
        mov     ecx, (NET_DEVICES_MAX + 1)
3711 clevermous 318
        rep stosd
3545 hidnplayr 319
 
6011 hidnplayr 320
        eth_init
3982 hidnplayr 321
 
6011 hidnplayr 322
        pppoe_init
3545 hidnplayr 323
 
6011 hidnplayr 324
        ipv4_init
325
;        ipv6_init
326
        icmp_init
3545 hidnplayr 327
 
6011 hidnplayr 328
        arp_init
329
        udp_init
330
        tcp_init
3545 hidnplayr 331
 
6011 hidnplayr 332
        socket_init
3545 hidnplayr 333
 
6011 hidnplayr 334
        loop_init
3601 hidnplayr 335
 
3545 hidnplayr 336
        mov     [net_tmr_count], 0
5528 hidnplayr 337
        ret
3545 hidnplayr 338
 
5528 hidnplayr 339
  .fail:
340
        DEBUGF  DEBUG_NETWORK_ERROR, "Stack init failed!\n"
3545 hidnplayr 341
        ret
342
 
343
 
344
 
345
; Wakeup every tick.
346
proc stack_handler_has_work?
347
 
3711 clevermous 348
        mov     eax, [timer_ticks]
349
        cmp     eax, [net_10ms]
3545 hidnplayr 350
 
351
        ret
352
endp
353
 
354
 
6011 hidnplayr 355
;-----------------------------------------------------------------;
356
;                                                                 ;
357
; stack_handler: Network handlers called from os_loop.            ;
358
;                                                                 ;
359
;  IN:  /                                                         ;
360
;  OUT: /                                                         ;
361
;                                                                 ;
362
;-----------------------------------------------------------------;
3545 hidnplayr 363
align 4
364
stack_handler:
365
 
366
        ; Test for 10ms tick
367
        mov     eax, [timer_ticks]
368
        cmp     eax, [net_10ms]
369
        je      .exit
370
        mov     [net_10ms], eax
371
 
7679 hidnplayr 372
        cmp     [net_device_count], 0
3545 hidnplayr 373
        je      .exit
374
 
375
        test    [net_10ms], 0x0f        ; 160ms
376
        jnz     .exit
377
 
6011 hidnplayr 378
        tcp_timer_160ms
3545 hidnplayr 379
 
380
        test    [net_10ms], 0x3f        ; 640ms
381
        jnz     .exit
382
 
6011 hidnplayr 383
        arp_decrease_entry_ttls
384
        ipv4_decrease_fragment_ttls
3545 hidnplayr 385
 
5013 hidnplayr 386
        xor     edx, edx
387
        mov     eax, [TCP_timer1_event]
388
        mov     ebx, [eax + EVENT.id]
389
        xor     esi, esi
390
        call    raise_event
391
 
3545 hidnplayr 392
  .exit:
393
        ret
394
 
395
 
3861 hidnplayr 396
align 4
6011 hidnplayr 397
proc net_buff_alloc stdcall, buffersize
398
 
5528 hidnplayr 399
        cmp     [buffersize], NET_BUFFER_SIZE
400
        ja      .too_large
5522 hidnplayr 401
 
5528 hidnplayr 402
        spin_lock_irqsave
5522 hidnplayr 403
 
7678 hidnplayr 404
        mov     eax, [net_buffs_free.current]
405
        cmp     eax, net_buffs_free+NET_BUFFERS*4
5528 hidnplayr 406
        jae     .out_of_mem
407
        mov     eax, [eax]
7678 hidnplayr 408
        add     [net_buffs_free.current], 4
5528 hidnplayr 409
 
410
        spin_unlock_irqrestore
411
 
9017 hidnplayr 412
if defined NETWORK_SANITY_CHECKS
413
        cmp     eax, [net_buffs_low]
414
        cmp     eax, [net_buffs_low]
415
        jb      .assert_mbuff
416
        cmp     eax, [net_buffs_high]
417
        ja      .assert_mbuff
418
        test    eax, 0x7ff
419
        jnz     .assert_mbuff
420
end if
421
 
6011 hidnplayr 422
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_buff_alloc: 0x%x\n", eax
5528 hidnplayr 423
        ret
424
 
425
  .out_of_mem:
426
        spin_unlock_irqrestore
427
 
428
        xor     eax, eax
6011 hidnplayr 429
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: out of mem!\n"
5528 hidnplayr 430
        ret
431
 
432
  .too_large:
433
        xor     eax, eax
6011 hidnplayr 434
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: too large!\n"
5528 hidnplayr 435
        ret
9017 hidnplayr 436
 
437
if defined NETWORK_SANITY_CHECKS
438
  .assert_mbuff:
439
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: invalid buffer 0x%x\n", eax
440
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: caller=0x%x\n", [esp+4]
441
        xor     eax, eax
442
        ret
443
end if
444
 
5528 hidnplayr 445
endp
446
 
447
 
5522 hidnplayr 448
align 4
6011 hidnplayr 449
proc net_buff_free stdcall, buffer
3545 hidnplayr 450
 
6011 hidnplayr 451
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_buff_free: 0x%x\n", [buffer]
3861 hidnplayr 452
 
9017 hidnplayr 453
if defined NETWORK_SANITY_CHECKS
454
        mov     eax, [buffer]
455
        cmp     eax, [net_buffs_low]
456
        jb      .assert_mbuff
457
        cmp     eax, [net_buffs_high]
458
        ja      .assert_mbuff
459
        test    eax, 0x7ff
460
        jnz     .assert_mbuff
461
end if
462
 
5528 hidnplayr 463
        spin_lock_irqsave
464
 
8896 hidnplayr 465
        sub     [net_buffs_free.current], 4             ; move pointer backwards
466
        mov     eax, [net_buffs_free.current]           ; place free'd buffer pointer on the list
5528 hidnplayr 467
        push    [buffer]
468
        pop     dword[eax]
469
 
470
        spin_unlock_irqrestore
471
 
472
        ret
9017 hidnplayr 473
 
474
if defined NETWORK_SANITY_CHECKS
475
  .assert_mbuff:
476
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_free: invalid buffer 0x%x\n", eax
477
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_free: caller=0x%x\n", [esp+4]
478
        xor     eax, eax
479
        ret
480
end if
481
 
5528 hidnplayr 482
endp
483
 
484
 
3545 hidnplayr 485
align 4
6011 hidnplayr 486
net_link_changed:
3545 hidnplayr 487
 
6011 hidnplayr 488
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state]
3545 hidnplayr 489
 
490
align 4
6011 hidnplayr 491
net_send_event:
3545 hidnplayr 492
 
6011 hidnplayr 493
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_send_event\n"
3545 hidnplayr 494
 
495
; Send event to all applications
496
        push    edi ecx
497
        mov     edi, SLOT_BASE
8866 rgimad 498
        mov     ecx, [thread_count]
3545 hidnplayr 499
  .loop:
8867 rgimad 500
        add     edi, sizeof.APPDATA
501
        or      [edi + APPDATA.occurred_events], EVENT_NETWORK2
3545 hidnplayr 502
        loop    .loop
503
        pop     ecx edi
504
 
505
        ret
506
 
507
 
508
 
6011 hidnplayr 509
;-----------------------------------------------------------------;
510
;                                                                 ;
511
; net_add_device: Called by network driver to register interface. ;
512
;                                                                 ;
513
;  IN:  ebx = ptr to device structure                             ;
514
;                                                                 ;
515
;  OUT: eax = device num on success                               ;
516
;       eax = -1 on error                                         ;
517
;                                                                 ;
518
;-----------------------------------------------------------------;
3545 hidnplayr 519
align 4
6011 hidnplayr 520
net_add_device:
3545 hidnplayr 521
 
6011 hidnplayr 522
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_add_device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
3545 hidnplayr 523
 
7679 hidnplayr 524
        cmp     [net_device_count], NET_DEVICES_MAX
3545 hidnplayr 525
        jae     .error
526
 
527
;----------------------------------
528
; Check if device is already listed
529
        mov     eax, ebx
3600 hidnplayr 530
        mov     ecx, NET_DEVICES_MAX    ; We need to check whole list because a device may be removed without re-organizing list
7679 hidnplayr 531
        mov     edi, net_device_list
3545 hidnplayr 532
 
3711 clevermous 533
        repne scasd                     ; See if device is already in the list
3545 hidnplayr 534
        jz      .error
535
 
536
;----------------------------
537
; Find empty slot in the list
538
        xor     eax, eax
3600 hidnplayr 539
        mov     ecx, NET_DEVICES_MAX
7679 hidnplayr 540
        mov     edi, net_device_list
3545 hidnplayr 541
 
3711 clevermous 542
        repne scasd
3545 hidnplayr 543
        jnz     .error
544
 
545
        sub     edi, 4
546
 
547
;-----------------------------
548
; Add device to the found slot
549
        mov     [edi], ebx              ; add device to list
550
 
551
        mov     eax, edi                ; Calculate device number in eax
7679 hidnplayr 552
        sub     eax, net_device_list
3545 hidnplayr 553
        shr     eax, 2
554
 
7679 hidnplayr 555
        inc     [net_device_count]      ; Indicate that one more network device is up and running
3545 hidnplayr 556
 
6011 hidnplayr 557
        call    net_send_event
3545 hidnplayr 558
 
3556 hidnplayr 559
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax
3545 hidnplayr 560
        ret
561
 
562
  .error:
563
        or      eax, -1
3556 hidnplayr 564
        DEBUGF  DEBUG_NETWORK_ERROR, "Adding network device failed\n"
3545 hidnplayr 565
        ret
566
 
567
 
568
 
6011 hidnplayr 569
;-----------------------------------------------------------------;
570
;                                                                 ;
571
; net_remove_device: Called by network driver to unregister dev.  ;
572
;                                                                 ;
573
;  IN:  ebx = ptr to device                                       ;
574
;                                                                 ;
575
;  OUT: eax: -1 on error                                          ;
576
;                                                                 ;
577
;-----------------------------------------------------------------;
3545 hidnplayr 578
align 4
6011 hidnplayr 579
net_remove_device:
3545 hidnplayr 580
 
7679 hidnplayr 581
        cmp     [net_device_count], 0
3545 hidnplayr 582
        je      .error
583
 
584
;----------------------------
585
; Find the driver in the list
586
 
587
        mov     eax, ebx
3600 hidnplayr 588
        mov     ecx, NET_DEVICES_MAX
7679 hidnplayr 589
        mov     edi, net_device_list
3545 hidnplayr 590
 
3711 clevermous 591
        repne scasd
3545 hidnplayr 592
        jnz     .error
593
 
594
;------------------------
595
; Remove it from the list
596
 
597
        xor     eax, eax
598
        mov     dword [edi-4], eax
7679 hidnplayr 599
        dec     [net_device_count]
3545 hidnplayr 600
 
6011 hidnplayr 601
        call    net_send_event
3545 hidnplayr 602
 
3601 hidnplayr 603
        xor     eax, eax
3545 hidnplayr 604
        ret
605
 
606
  .error:
607
        or      eax, -1
608
        ret
609
 
610
 
611
 
6011 hidnplayr 612
;-----------------------------------------------------------------;
613
;                                                                 ;
614
; net_ptr_to_num                                                  ;
615
;                                                                 ;
616
;  IN:  ebx = ptr to device struct                                ;
617
;                                                                 ;
618
;  OUT: edi = device number                                       ;
619
;       edi = -1 on error                                         ;
620
;                                                                 ;
621
;-----------------------------------------------------------------;
3545 hidnplayr 622
align 4
6011 hidnplayr 623
net_ptr_to_num:
3643 hidnplayr 624
 
6011 hidnplayr 625
        call    net_ptr_to_num4
3643 hidnplayr 626
        ror     edi, 2          ; If -1, stay -1
627
                                ; valid device numbers have last two bits 0, so do just shr
628
 
629
        ret
630
 
631
align 4
6011 hidnplayr 632
net_ptr_to_num4:                ; Todo, place number in device structure so we only need to verify?
3643 hidnplayr 633
 
5522 hidnplayr 634
        test    ebx, ebx
635
        jz      .fail
636
 
3545 hidnplayr 637
        push    ecx
3600 hidnplayr 638
        mov     ecx, NET_DEVICES_MAX
7679 hidnplayr 639
        mov     edi, net_device_list
3545 hidnplayr 640
  .loop:
641
        cmp     ebx, [edi]
3643 hidnplayr 642
        je      .found
3545 hidnplayr 643
        add     edi, 4
644
        dec     ecx
645
        jnz     .loop
646
 
5522 hidnplayr 647
        pop     ecx
648
  .fail:
3545 hidnplayr 649
        or      edi, -1
650
        ret
651
 
652
  .found:
7679 hidnplayr 653
        sub     edi, net_device_list
3545 hidnplayr 654
        pop     ecx
655
        ret
656
 
6011 hidnplayr 657
;-----------------------------------------------------------------;
658
;                                                                 ;
659
; checksum_1: Calculate semi-checksum for network packets.        ;
660
;                                                                 ;
661
;  IN:  edx = start offset for semi-checksum                      ;
662
;       esi = pointer to data                                     ;
663
;       ecx = data size                                           ;
664
;                                                                 ;
665
;  OUT: edx = semi-checksum                                       ;
666
;                                                                 ;
667
;-----------------------------------------------------------------;
3545 hidnplayr 668
align 4
669
checksum_1:
670
 
671
        shr     ecx, 1
672
        pushf
673
        jz      .no_2
674
 
675
        shr     ecx, 1
676
        pushf
677
        jz      .no_4
678
 
679
        shr     ecx, 1
680
        pushf
681
        jz      .no_8
682
 
683
  .loop:
684
        add     dl, [esi+1]
685
        adc     dh, [esi+0]
686
 
687
        adc     dl, [esi+3]
688
        adc     dh, [esi+2]
689
 
690
        adc     dl, [esi+5]
691
        adc     dh, [esi+4]
692
 
693
        adc     dl, [esi+7]
694
        adc     dh, [esi+6]
695
 
696
        adc     edx, 0
697
        add     esi, 8
698
 
699
        dec     ecx
700
        jnz     .loop
701
 
702
        adc     edx, 0
703
 
704
  .no_8:
705
        popf
706
        jnc     .no_4
707
 
708
        add     dl, [esi+1]
709
        adc     dh, [esi+0]
710
 
711
        adc     dl, [esi+3]
712
        adc     dh, [esi+2]
713
 
714
        adc     edx, 0
715
        add     esi, 4
716
 
717
  .no_4:
718
        popf
719
        jnc     .no_2
720
 
721
        add     dl, [esi+1]
722
        adc     dh, [esi+0]
723
 
724
        adc     edx, 0
725
        inc     esi
726
        inc     esi
727
 
728
  .no_2:
729
        popf
730
        jnc     .end
731
 
732
        add     dh, [esi+0]
733
        adc     edx, 0
734
  .end:
735
        ret
736
 
6011 hidnplayr 737
;-----------------------------------------------------------------;
738
;                                                                 ;
739
; checksum_2: Calculate the final ip/tcp/udp checksum.            ;
740
;                                                                 ;
741
;   IN: edx = semi-checksum                                       ;
742
;                                                                 ;
743
;  OUT: dx = checksum (in INET byte order)                        ;
744
;                                                                 ;
745
;-----------------------------------------------------------------;
3545 hidnplayr 746
align 4
747
checksum_2:
748
 
749
        mov     ecx, edx
750
        shr     ecx, 16
751
        and     edx, 0xffff
752
        add     edx, ecx
753
 
754
        mov     ecx, edx
755
        shr     ecx, 16
756
        add     dx, cx
757
        test    dx, dx          ; it seems that ZF is not set when CF is set :(
758
        not     dx
759
        jnz     .not_zero
760
        dec     dx
761
  .not_zero:
762
        xchg    dl, dh
763
 
3556 hidnplayr 764
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
3545 hidnplayr 765
 
766
        ret
767
 
768
 
769
 
6011 hidnplayr 770
;-----------------------------------------------------------------;
771
;                                                                 ;
772
;  System function 74: Low level access to network devices.       ;
773
;                                                                 ;
774
;-----------------------------------------------------------------;
3545 hidnplayr 775
align 4
3601 hidnplayr 776
sys_network:
3545 hidnplayr 777
 
3879 hidnplayr 778
        cmp     bl, 255
3545 hidnplayr 779
        jne     @f
780
 
7679 hidnplayr 781
        mov     eax, [net_device_count]
3601 hidnplayr 782
        mov     [esp+32], eax
783
        ret
3545 hidnplayr 784
 
785
   @@:
7679 hidnplayr 786
        cmp     bh, NET_DEVICES_MAX                     ; Check if device number exists
3545 hidnplayr 787
        jae     .doesnt_exist
788
 
789
        mov     esi, ebx
790
        and     esi, 0x0000ff00
791
        shr     esi, 6
792
 
7679 hidnplayr 793
        cmp     dword[esi + net_device_list], 0         ; check if device is running
3545 hidnplayr 794
        je      .doesnt_exist
795
 
7679 hidnplayr 796
        mov     eax, [esi + net_device_list]
3545 hidnplayr 797
 
798
        and     ebx, 0x000000ff
799
        cmp     ebx, .number
800
        ja      .doesnt_exist
801
        jmp     dword [.table + 4*ebx]
802
 
803
  .table:
9017 hidnplayr 804
        dd      .get_type               ;  0
805
        dd      .get_dev_name           ;  1
806
        dd      .reset                  ;  2
807
        dd      .stop                   ;  3
808
        dd      .get_ptr                ;  4
809
        dd      .get_drv_name           ;  5
3601 hidnplayr 810
 
9017 hidnplayr 811
        dd      .packets_tx             ;  6
812
        dd      .packets_rx             ;  7
813
        dd      .bytes_tx               ;  8
814
        dd      .bytes_rx               ;  9
3601 hidnplayr 815
        dd      .state                  ; 10
9017 hidnplayr 816
        dd      .packets_tx_err         ; 11
817
        dd      .packets_tx_drop        ; 12
818
        dd      .packets_tx_ovr         ; 13
819
        dd      .packets_rx_err         ; 14
820
        dd      .packets_rx_drop        ; 15
821
        dd      .packets_rx_ovr         ; 16
822
 
3545 hidnplayr 823
  .number = ($ - .table) / 4 - 1
824
 
3601 hidnplayr 825
  .get_type:
3600 hidnplayr 826
        mov     eax, [eax + NET_DEVICE.device_type]
3601 hidnplayr 827
        mov     [esp+32], eax
828
        ret
3545 hidnplayr 829
 
3601 hidnplayr 830
  .get_dev_name:
9017 hidnplayr 831
        mov     ebx, eax
8700 Coldy 832
        stdcall is_region_userspace, ecx, 64
833
        jz      .bad_buffer
9017 hidnplayr 834
        mov     esi, [ebx + NET_DEVICE.name]
3545 hidnplayr 835
        mov     edi, ecx
836
 
837
        mov     ecx, 64/4 ; max length
3711 clevermous 838
        rep movsd
3545 hidnplayr 839
 
840
        xor     eax, eax
3601 hidnplayr 841
        mov     [esp+32], eax
842
        ret
3545 hidnplayr 843
 
3601 hidnplayr 844
  .reset:
3545 hidnplayr 845
        call    [eax + NET_DEVICE.reset]
3601 hidnplayr 846
        mov     [esp+32], eax
847
        ret
3545 hidnplayr 848
 
3601 hidnplayr 849
  .stop:
3545 hidnplayr 850
        call    [eax + NET_DEVICE.unload]
3601 hidnplayr 851
        mov     [esp+32], eax
852
        ret
3545 hidnplayr 853
 
854
 
3601 hidnplayr 855
  .get_ptr:
856
        mov     [esp+32], eax
857
        ret
3545 hidnplayr 858
 
859
 
3601 hidnplayr 860
  .get_drv_name:
861
        xor     eax, eax
862
        mov     [esp+32], eax
863
        ret
3545 hidnplayr 864
 
3601 hidnplayr 865
  .packets_tx:
866
        mov     eax, [eax + NET_DEVICE.packets_tx]
867
        mov     [esp+32], eax
868
        ret
3545 hidnplayr 869
 
3601 hidnplayr 870
  .packets_rx:
871
        mov     eax, [eax + NET_DEVICE.packets_rx]
872
        mov     [esp+32], eax
873
        ret
3545 hidnplayr 874
 
3601 hidnplayr 875
  .bytes_tx:
6011 hidnplayr 876
        mov     ebx, dword[eax + NET_DEVICE.bytes_tx + 4]
3601 hidnplayr 877
        mov     [esp+20], ebx
6011 hidnplayr 878
        mov     eax, dword[eax + NET_DEVICE.bytes_tx]
3601 hidnplayr 879
        mov     [esp+32], eax
880
        ret
3545 hidnplayr 881
 
3601 hidnplayr 882
  .bytes_rx:
6011 hidnplayr 883
        mov     ebx, dword[eax + NET_DEVICE.bytes_rx + 4]
3601 hidnplayr 884
        mov     [esp+20], ebx
6011 hidnplayr 885
        mov     eax, dword[eax + NET_DEVICE.bytes_rx]
3601 hidnplayr 886
        mov     [esp+32], eax
887
        ret
3545 hidnplayr 888
 
9017 hidnplayr 889
  .packets_tx_err:
890
        mov     eax, [eax + NET_DEVICE.packets_tx_err]
891
        mov     [esp+32], eax
892
        ret
893
 
894
  .packets_tx_drop:
895
        mov     eax, [eax + NET_DEVICE.packets_tx_drop]
896
        mov     [esp+32], eax
897
        ret
898
 
899
  .packets_tx_ovr:
900
        mov     eax, [eax + NET_DEVICE.packets_tx_ovr]
901
        mov     [esp+32], eax
902
        ret
903
 
904
  .packets_rx_err:
905
        mov     eax, [eax + NET_DEVICE.packets_rx_err]
906
        mov     [esp+32], eax
907
        ret
908
 
909
  .packets_rx_drop:
910
        mov     eax, [eax + NET_DEVICE.packets_rx_drop]
911
        mov     [esp+32], eax
912
        ret
913
 
914
  .packets_rx_ovr:
915
        mov     eax, [eax + NET_DEVICE.packets_rx_ovr]
916
        mov     [esp+32], eax
917
        ret
918
 
3601 hidnplayr 919
  .state:
920
        mov     eax, [eax + NET_DEVICE.link_state]
3545 hidnplayr 921
        mov     [esp+32], eax
922
        ret
923
 
924
 
3601 hidnplayr 925
  .doesnt_exist:
8700 Coldy 926
  .bad_buffer: ; Sanity check failed, exit
3601 hidnplayr 927
        mov     dword[esp+32], -1
928
        ret
929
 
930
 
931
 
6011 hidnplayr 932
;-----------------------------------------------------------------;
933
;                                                                 ;
934
;  System function 76: Low level access to protocol handlers.     ;
935
;                                                                 ;
936
;-----------------------------------------------------------------;
3545 hidnplayr 937
align 4
938
sys_protocols:
3600 hidnplayr 939
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3545 hidnplayr 940
        jae     .doesnt_exist
941
 
7963 hidnplayr 942
        mov     eax, ebx
943
        and     eax, 0x0000ff00
944
        shr     eax, 6                          ; now we have the device num * 4 in eax
945
        cmp     [eax + net_device_list], 0      ; check if device is running
3545 hidnplayr 946
        je      .doesnt_exist
947
 
948
        push    .return                         ; return address (we will be using jumps instead of calls)
949
 
950
        mov     eax, ebx                        ; set ax to protocol number
951
        shr     eax, 16                         ;
952
 
953
        cmp     ax, API_ETH
6011 hidnplayr 954
        je      eth_api
3545 hidnplayr 955
 
956
        cmp     ax, API_IPv4
6011 hidnplayr 957
        je      ipv4_api
3545 hidnplayr 958
 
959
        cmp     ax, API_ICMP
6011 hidnplayr 960
        je      icmp_api
3545 hidnplayr 961
 
962
        cmp     ax, API_UDP
6011 hidnplayr 963
        je      udp_api
3545 hidnplayr 964
 
965
        cmp     ax, API_TCP
6011 hidnplayr 966
        je      tcp_api
3545 hidnplayr 967
 
968
        cmp     ax, API_ARP
6011 hidnplayr 969
        je      arp_api
3545 hidnplayr 970
 
971
        cmp     ax, API_PPPOE
6011 hidnplayr 972
        je      pppoe_api
3545 hidnplayr 973
 
974
        cmp     ax, API_IPv6
6011 hidnplayr 975
        je      ipv6_api
3545 hidnplayr 976
 
977
        add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
978
 
979
  .doesnt_exist:
980
        mov     eax, -1
981
 
982
  .return:
983
        mov     [esp+28+4], eax                 ; return eax value to the program
984
        ret