Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
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
 
24
$Revision: 3523 $
25
 
26
uglobal
27
        net_10ms        dd ?
28
        net_tmr_count   dw ?
29
endg
30
 
3556 hidnplayr 31
DEBUG_NETWORK_ERROR     = 1
32
DEBUG_NETWORK_VERBOSE   = 0
33
 
3600 hidnplayr 34
NET_DEVICES_MAX         = 16
3545 hidnplayr 35
ARP_BLOCK               = 1             ; true or false
36
 
3600 hidnplayr 37
EPHEMERAL_PORT_MIN      = 49152
38
EPHEMERAL_PORT_MAX      = 61000
3545 hidnplayr 39
MIN_EPHEMERAL_PORT_N    = 0x00C0        ; same in Network byte order (FIXME)
40
MAX_EPHEMERAL_PORT_N    = 0x48EE        ; same in Network byte order (FIXME)
41
 
42
; Ethernet protocol numbers
3600 hidnplayr 43
ETHER_PROTO_ARP                 = 0x0608
44
ETHER_PROTO_IPv4                = 0x0008
45
ETHER_PROTO_IPv6                = 0xDD86
46
ETHER_PROTO_PPP_DISCOVERY       = 0x6388
47
ETHER_PROTO_PPP_SESSION         = 0x6488
3545 hidnplayr 48
 
3600 hidnplayr 49
; Internet protocol numbers
50
IP_PROTO_IP             = 0
51
IP_PROTO_ICMP           = 1
52
IP_PROTO_TCP            = 6
53
IP_PROTO_UDP            = 17
54
 
3545 hidnplayr 55
; PPP protocol numbers
3600 hidnplayr 56
PPP_PROTO_IPv4          = 0x2100
57
PPP_PROTO_IPV6          = 0x5780
58
PPP_PROTO_ETHERNET      = 666           ; FIXME
3545 hidnplayr 59
 
60
;Protocol family
61
AF_UNSPEC               = 0
62
AF_LOCAL                = 1
63
AF_INET4                = 2
64
AF_INET6                = 10
3600 hidnplayr 65
AF_PPP                  = 777           ; FIXME
3545 hidnplayr 66
 
67
; Socket types
68
SOCK_STREAM             = 1
69
SOCK_DGRAM              = 2
70
SOCK_RAW                = 3
71
 
72
; Socket options
73
SO_ACCEPTCON            = 1 shl 0
74
SO_BROADCAST            = 1 shl 1
75
SO_DEBUG                = 1 shl 2
76
SO_DONTROUTE            = 1 shl 3
77
SO_KEEPALIVE            = 1 shl 4
78
SO_OOBINLINE            = 1 shl 5
79
SO_REUSEADDR            = 1 shl 6
80
SO_REUSEPORT            = 1 shl 7
81
SO_USELOOPBACK          = 1 shl 8
82
SO_BINDTODEVICE         = 1 shl 9
83
 
3600 hidnplayr 84
SO_BLOCK                = 1 shl 10      ; TO BE REMOVED
3545 hidnplayr 85
SO_NONBLOCK             = 1 shl 31
86
 
87
; Socket flags for user calls
88
MSG_PEEK                = 0x02
89
MSG_DONTWAIT            = 0x40
90
 
91
; Socket level
92
SOL_SOCKET              = 0
93
 
94
 
95
; Socket States
3600 hidnplayr 96
SS_NOFDREF              = 0x0001        ; no file table ref any more
97
SS_ISCONNECTED          = 0x0002        ; socket connected to a peer
98
SS_ISCONNECTING         = 0x0004        ; in process of connecting to peer
99
SS_ISDISCONNECTING      = 0x0008        ; in process of disconnecting
100
SS_CANTSENDMORE         = 0x0010        ; can't send more data to peer
101
SS_CANTRCVMORE          = 0x0020        ; can't receive more data from peer
102
SS_RCVATMARK            = 0x0040        ; at mark on input
103
SS_ISABORTING           = 0x0080        ; aborting fd references - close()
104
SS_RESTARTSYS           = 0x0100        ; restart blocked system calls
105
SS_ISDISCONNECTED       = 0x0800        ; socket disconnected from peer
3545 hidnplayr 106
 
3674 hidnplayr 107
SS_ASYNC                = 0x1000        ; async i/o notify
108
SS_ISCONFIRMING         = 0x2000        ; deciding to accept connection req
109
SS_MORETOCOME           = 0x4000
3545 hidnplayr 110
 
111
SS_BLOCKED              = 0x8000
112
 
113
 
3600 hidnplayr 114
SOCKET_MAXDATA          = 4096*32       ; must be 4096*(power of 2) where 'power of 2' is at least 8
115
MAX_backlog             = 20            ; maximum backlog for stream sockets
3545 hidnplayr 116
 
117
; Error Codes
3674 hidnplayr 118
ENOBUFS                 = 1
119
EOPNOTSUPP              = 4
120
EWOULDBLOCK             = 6
121
ENOTCONN                = 9
122
EALREADY                = 10
123
EINVAL                  = 11
124
EMSGSIZE                = 12
125
ENOMEM                  = 18
126
EADDRINUSE              = 20
3545 hidnplayr 127
ECONNREFUSED            = 61
128
ECONNRESET              = 52
129
ETIMEDOUT               = 60
130
ECONNABORTED            = 53
131
 
132
; Api protocol numbers
133
API_ETH                 = 0
134
API_IPv4                = 1
135
API_ICMP                = 2
136
API_UDP                 = 3
137
API_TCP                 = 4
138
API_ARP                 = 5
139
API_PPPOE               = 6
140
API_IPv6                = 7
141
 
3600 hidnplayr 142
; Network device types
143
NET_DEVICE_LOOPBACK     = 0
144
NET_DEVICE_ETH          = 1
145
NET_DEVICE_SLIP         = 2
146
 
147
; Network link types (link protocols)
148
NET_LINK_LOOPBACK       = 0     ;;; Really a link type?
149
NET_LINK_MAC            = 1     ; Media access control (ethernet, isdn, ...)
150
NET_LINK_PPP            = 2     ; Point to Point Protocol (PPPoE, ...)
151
NET_LINK_IEEE802.11     = 3     ; IEEE 802.11 (WiFi)
152
 
153
; Hardware acceleration bits
3545 hidnplayr 154
HWACC_TCP_IPv4          = 1 shl 0
155
 
156
struct  NET_DEVICE
157
 
3600 hidnplayr 158
        device_type     dd ?    ; Type field
3545 hidnplayr 159
        mtu             dd ?    ; Maximal Transmission Unit
160
        name            dd ?    ; Ptr to 0 terminated string
161
 
162
        unload          dd ?    ; Ptrs to driver functions
163
        reset           dd ?    ;
164
        transmit        dd ?    ;
165
 
166
        bytes_tx        dq ?    ; Statistics, updated by the driver
167
        bytes_rx        dq ?    ;
168
        packets_tx      dd ?    ;
169
        packets_rx      dd ?    ;
170
 
3600 hidnplayr 171
        link_state      dd ?    ; link state (0 = no link)
3545 hidnplayr 172
        hwacc           dd ?    ; bitmask stating enabled HW accelerations (offload engines)
173
 
174
ends
175
 
176
 
177
; Exactly as it says..
178
macro pseudo_random reg {
179
        add     reg, [esp]
180
        rol     reg, 5
181
        xor     reg, [timer_ticks]
182
;        add     reg, [CPU_FREQ]
183
        imul    reg, 214013
184
        xor     reg, 0xdeadbeef
185
        rol     reg, 9
186
}
187
 
188
; Network to Hardware byte order (dword)
189
macro ntohd reg {
190
 
191
        rol     word reg, 8
192
        rol     dword reg, 16
193
        rol     word reg , 8
194
 
195
}
196
 
197
; Network to Hardware byte order (word)
198
macro ntohw reg {
199
 
200
        rol     word reg, 8
201
 
202
}
203
 
204
 
205
include "queue.inc"
206
 
207
include "loopback.inc"
208
include "ethernet.inc"
209
 
210
include "PPPoE.inc"
211
 
212
include "ARP.inc"
213
include "IPv4.inc"
214
include "IPv6.inc"
215
 
216
include "icmp.inc"
217
include "udp.inc"
218
include "tcp.inc"
219
 
220
include "socket.inc"
221
 
222
 
223
 
3698 hidnplayr 224
uglobal
3545 hidnplayr 225
align 4
226
 
227
        NET_RUNNING     dd  ?
3600 hidnplayr 228
        NET_DRV_LIST    rd  NET_DEVICES_MAX
3545 hidnplayr 229
 
230
endg
231
 
232
 
233
;-----------------------------------------------------------------
234
;
235
; stack_init
236
;
237
;  This function calls all network init procedures
238
;
239
;  IN:  /
240
;  OUT: /
241
;
242
;-----------------------------------------------------------------
243
align 4
244
stack_init:
245
 
246
; Init the network drivers list
247
        xor     eax, eax
248
        mov     edi, NET_RUNNING
3600 hidnplayr 249
        mov     ecx, (NET_DEVICES_MAX + 2)
3545 hidnplayr 250
        rep     stosd
251
 
252
        PPPoE_init
253
 
254
        IPv4_init
255
;        IPv6_init
256
        ICMP_init
257
 
258
        ARP_init
259
        UDP_init
260
        TCP_init
261
 
262
        SOCKET_init
263
 
3601 hidnplayr 264
        LOOP_init
265
 
3545 hidnplayr 266
        mov     [net_tmr_count], 0
267
 
268
        ret
269
 
270
 
271
 
272
; Wakeup every tick.
273
proc stack_handler_has_work?
274
 
275
        mov eax, [timer_ticks]
276
        cmp eax, [net_10ms]
277
 
278
        ret
279
endp
280
 
281
 
282
;-----------------------------------------------------------------
283
;
284
; stack_handler
285
;
286
;  This function is called in kernel loop
287
;
288
;  IN:  /
289
;  OUT: /
290
;
291
;-----------------------------------------------------------------
292
align 4
293
stack_handler:
294
 
295
        ; Test for 10ms tick
296
        mov     eax, [timer_ticks]
297
        cmp     eax, [net_10ms]
298
        je      .exit
299
        mov     [net_10ms], eax
300
 
301
        cmp     [NET_RUNNING], 0
302
        je      .exit
303
 
304
        test    [net_10ms], 0x0f        ; 160ms
305
        jnz     .exit
306
 
307
        TCP_timer_160ms
308
 
309
        test    [net_10ms], 0x3f        ; 640ms
310
        jnz     .exit
311
 
312
        TCP_timer_640ms
313
        ARP_decrease_entry_ttls
314
        IPv4_decrease_fragment_ttls
315
 
316
  .exit:
317
        ret
318
 
319
 
320
 
321
align 4
322
NET_link_changed:
323
 
3601 hidnplayr 324
        DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state]
3545 hidnplayr 325
 
326
align 4
327
NET_send_event:
328
 
3556 hidnplayr 329
        DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_send_event\n"
3545 hidnplayr 330
 
331
; Send event to all applications
332
        push    edi ecx
333
        mov     edi, SLOT_BASE
334
        mov     ecx, [TASK_COUNT]
335
  .loop:
336
        add     edi, 256
337
        or      [edi + APPDATA.event_mask], EVENT_NETWORK2
338
        loop    .loop
339
        pop     ecx edi
340
 
341
        ret
342
 
343
 
344
 
345
;-----------------------------------------------------------------
346
;
347
; NET_add_device:
348
;
349
;  This function is called by the network drivers,
350
;  to register each running NIC to the kernel
351
;
352
;  IN:  Pointer to device structure in ebx
353
;  OUT: Device num in eax, -1 on error
354
;
355
;-----------------------------------------------------------------
356
align 4
357
NET_add_device:
358
 
3556 hidnplayr 359
        DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_Add_Device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
3545 hidnplayr 360
 
3600 hidnplayr 361
        cmp     [NET_RUNNING], NET_DEVICES_MAX
3545 hidnplayr 362
        jae     .error
363
 
364
;----------------------------------
365
; Check if device is already listed
366
        mov     eax, ebx
3600 hidnplayr 367
        mov     ecx, NET_DEVICES_MAX    ; We need to check whole list because a device may be removed without re-organizing list
3545 hidnplayr 368
        mov     edi, NET_DRV_LIST
369
 
370
        repne   scasd                   ; See if device is already in the list
371
        jz      .error
372
 
373
;----------------------------
374
; Find empty slot in the list
375
        xor     eax, eax
3600 hidnplayr 376
        mov     ecx, NET_DEVICES_MAX
3545 hidnplayr 377
        mov     edi, NET_DRV_LIST
378
 
379
        repne   scasd
380
        jnz     .error
381
 
382
        sub     edi, 4
383
 
384
;-----------------------------
385
; Add device to the found slot
386
        mov     [edi], ebx              ; add device to list
387
 
388
        mov     eax, edi                ; Calculate device number in eax
389
        sub     eax, NET_DRV_LIST
390
        shr     eax, 2
391
 
392
        inc     [NET_RUNNING]           ; Indicate that one more network device is up and running
393
 
394
        call    NET_send_event
395
 
3556 hidnplayr 396
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax
3545 hidnplayr 397
        ret
398
 
399
  .error:
400
        or      eax, -1
3556 hidnplayr 401
        DEBUGF  DEBUG_NETWORK_ERROR, "Adding network device failed\n"
3545 hidnplayr 402
        ret
403
 
404
 
405
 
406
;-----------------------------------------------------------------
407
;
408
; NET_Remove_Device:
409
;
3601 hidnplayr 410
;  This function is called by network drivers,
3545 hidnplayr 411
;  to unregister network devices from the kernel
412
;
413
;  IN:  Pointer to device structure in ebx
414
;  OUT: eax: -1 on error
415
;
416
;-----------------------------------------------------------------
417
align 4
418
NET_remove_device:
419
 
420
        cmp     [NET_RUNNING], 0
421
        je      .error
422
 
423
;----------------------------
424
; Find the driver in the list
425
 
426
        mov     eax, ebx
3600 hidnplayr 427
        mov     ecx, NET_DEVICES_MAX
3601 hidnplayr 428
        mov     edi, NET_DRV_LIST
3545 hidnplayr 429
 
430
        repne   scasd
431
        jnz     .error
432
 
433
;------------------------
434
; Remove it from the list
435
 
436
        xor     eax, eax
437
        mov     dword [edi-4], eax
3601 hidnplayr 438
        dec     [NET_RUNNING]
3545 hidnplayr 439
 
440
        call    NET_send_event
441
 
3601 hidnplayr 442
        xor     eax, eax
3545 hidnplayr 443
        ret
444
 
445
  .error:
446
        or      eax, -1
447
        ret
448
 
449
 
450
 
451
;-----------------------------------------------------------------
452
;
453
; NET_ptr_to_num
454
;
455
; IN:  ebx = ptr to device struct
456
; OUT: edi = -1 on error, device number otherwise
457
;
458
;-----------------------------------------------------------------
459
align 4
460
NET_ptr_to_num:
3643 hidnplayr 461
 
462
        call    NET_ptr_to_num4
463
        ror     edi, 2          ; If -1, stay -1
464
                                ; valid device numbers have last two bits 0, so do just shr
465
 
466
        ret
467
 
468
align 4
469
NET_ptr_to_num4:                ; Todo, place number in device structure so we only need to verify?
470
 
3545 hidnplayr 471
        push    ecx
472
 
3600 hidnplayr 473
        mov     ecx, NET_DEVICES_MAX
3545 hidnplayr 474
        mov     edi, NET_DRV_LIST
475
  .loop:
476
        cmp     ebx, [edi]
3643 hidnplayr 477
        je      .found
3545 hidnplayr 478
        add     edi, 4
479
        dec     ecx
480
        jnz     .loop
481
 
482
        or      edi, -1
483
        pop     ecx
484
        ret
485
 
486
  .found:
487
        sub     edi, NET_DRV_LIST
488
        pop     ecx
489
        ret
490
 
491
;-----------------------------------------------------------------
492
;
493
; checksum_1
494
;
495
;  This is the first of two functions needed to calculate a checksum.
496
;
497
;  IN:  edx = start offset for semi-checksum
498
;       esi = pointer to data
499
;       ecx = data size
500
;  OUT: edx = semi-checksum
501
;
502
;
503
; Code was optimized by diamond
504
;
505
;-----------------------------------------------------------------
506
align 4
507
checksum_1:
508
 
509
        shr     ecx, 1
510
        pushf
511
        jz      .no_2
512
 
513
        shr     ecx, 1
514
        pushf
515
        jz      .no_4
516
 
517
        shr     ecx, 1
518
        pushf
519
        jz      .no_8
520
 
521
  .loop:
522
        add     dl, [esi+1]
523
        adc     dh, [esi+0]
524
 
525
        adc     dl, [esi+3]
526
        adc     dh, [esi+2]
527
 
528
        adc     dl, [esi+5]
529
        adc     dh, [esi+4]
530
 
531
        adc     dl, [esi+7]
532
        adc     dh, [esi+6]
533
 
534
        adc     edx, 0
535
        add     esi, 8
536
 
537
        dec     ecx
538
        jnz     .loop
539
 
540
        adc     edx, 0
541
 
542
  .no_8:
543
        popf
544
        jnc     .no_4
545
 
546
        add     dl, [esi+1]
547
        adc     dh, [esi+0]
548
 
549
        adc     dl, [esi+3]
550
        adc     dh, [esi+2]
551
 
552
        adc     edx, 0
553
        add     esi, 4
554
 
555
  .no_4:
556
        popf
557
        jnc     .no_2
558
 
559
        add     dl, [esi+1]
560
        adc     dh, [esi+0]
561
 
562
        adc     edx, 0
563
        inc     esi
564
        inc     esi
565
 
566
  .no_2:
567
        popf
568
        jnc     .end
569
 
570
        add     dh, [esi+0]
571
        adc     edx, 0
572
  .end:
573
        ret
574
 
575
;-----------------------------------------------------------------
576
;
577
; checksum_2
578
;
579
;  This function calculates the final ip/tcp/udp checksum for you
580
;
581
;  IN:  edx = semi-checksum
582
;  OUT: dx = checksum (in INET byte order)
583
;
584
;-----------------------------------------------------------------
585
align 4
586
checksum_2:
587
 
588
        mov     ecx, edx
589
        shr     ecx, 16
590
        and     edx, 0xffff
591
        add     edx, ecx
592
 
593
        mov     ecx, edx
594
        shr     ecx, 16
595
        add     dx, cx
596
        test    dx, dx          ; it seems that ZF is not set when CF is set :(
597
        not     dx
598
        jnz     .not_zero
599
        dec     dx
600
  .not_zero:
601
        xchg    dl, dh
602
 
3556 hidnplayr 603
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
3545 hidnplayr 604
 
605
        ret
606
 
607
 
608
 
609
;----------------------------------------------------------------
610
;
3601 hidnplayr 611
;  System function to work with network devices (74)
3545 hidnplayr 612
;
613
;----------------------------------------------------------------
614
align 4
3601 hidnplayr 615
sys_network:
3545 hidnplayr 616
 
617
        cmp     ebx, -1
618
        jne     @f
619
 
620
        mov     eax, [NET_RUNNING]
3601 hidnplayr 621
        mov     [esp+32], eax
622
        ret
3545 hidnplayr 623
 
624
   @@:
3600 hidnplayr 625
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3545 hidnplayr 626
        jae     .doesnt_exist
627
 
628
        mov     esi, ebx
629
        and     esi, 0x0000ff00
630
        shr     esi, 6
631
 
632
        cmp     dword [esi + NET_DRV_LIST], 0   ; check if driver is running
633
        je      .doesnt_exist
634
 
635
        mov     eax, [esi + NET_DRV_LIST]
636
 
637
        and     ebx, 0x000000ff
638
        cmp     ebx, .number
639
        ja      .doesnt_exist
640
        jmp     dword [.table + 4*ebx]
641
 
642
  .table:
643
        dd      .get_type               ; 0
644
        dd      .get_dev_name           ; 1
645
        dd      .reset                  ; 2
646
        dd      .stop                   ; 3
647
        dd      .get_ptr                ; 4
648
        dd      .get_drv_name           ; 5
3601 hidnplayr 649
 
650
        dd      .packets_tx             ; 6
651
        dd      .packets_rx             ; 7
652
        dd      .bytes_tx               ; 8
653
        dd      .bytes_rx               ; 9
654
        dd      .state                  ; 10
3545 hidnplayr 655
  .number = ($ - .table) / 4 - 1
656
 
3601 hidnplayr 657
  .get_type:
3600 hidnplayr 658
        mov     eax, [eax + NET_DEVICE.device_type]
3601 hidnplayr 659
        mov     [esp+32], eax
660
        ret
3545 hidnplayr 661
 
3601 hidnplayr 662
  .get_dev_name:
3545 hidnplayr 663
        mov     esi, [eax + NET_DEVICE.name]
664
        mov     edi, ecx
665
 
666
        mov     ecx, 64/4 ; max length
667
        rep     movsd
668
 
669
        xor     eax, eax
3601 hidnplayr 670
        mov     [esp+32], eax
671
        ret
3545 hidnplayr 672
 
3601 hidnplayr 673
  .reset:
3545 hidnplayr 674
        call    [eax + NET_DEVICE.reset]
3601 hidnplayr 675
        mov     [esp+32], eax
676
        ret
3545 hidnplayr 677
 
3601 hidnplayr 678
  .stop:
3545 hidnplayr 679
        call    [eax + NET_DEVICE.unload]
3601 hidnplayr 680
        mov     [esp+32], eax
681
        ret
3545 hidnplayr 682
 
683
 
3601 hidnplayr 684
  .get_ptr:
685
        mov     [esp+32], eax
686
        ret
3545 hidnplayr 687
 
688
 
3601 hidnplayr 689
  .get_drv_name:
690
        xor     eax, eax
691
        mov     [esp+32], eax
692
        ret
3545 hidnplayr 693
 
3601 hidnplayr 694
  .packets_tx:
695
        mov     eax, [eax + NET_DEVICE.packets_tx]
696
        mov     [esp+32], eax
697
        ret
3545 hidnplayr 698
 
3601 hidnplayr 699
  .packets_rx:
700
        mov     eax, [eax + NET_DEVICE.packets_rx]
701
        mov     [esp+32], eax
702
        ret
3545 hidnplayr 703
 
3601 hidnplayr 704
  .bytes_tx:
705
        mov     ebx, dword [eax + NET_DEVICE.bytes_tx + 4]
706
        mov     [esp+20], ebx
707
        mov     eax, dword [eax + NET_DEVICE.bytes_tx]
708
        mov     [esp+32], eax
709
        ret
3545 hidnplayr 710
 
3601 hidnplayr 711
  .bytes_rx:
712
        mov     ebx, dword [eax + NET_DEVICE.bytes_rx + 4]
713
        mov     [esp+20], ebx
714
        mov     eax, dword [eax + NET_DEVICE.bytes_rx]
715
        mov     [esp+32], eax
716
        ret
3545 hidnplayr 717
 
3601 hidnplayr 718
  .state:
719
        mov     eax, [eax + NET_DEVICE.link_state]
3545 hidnplayr 720
        mov     [esp+32], eax
721
        ret
722
 
723
 
3601 hidnplayr 724
  .doesnt_exist:
725
        mov     dword[esp+32], -1
726
        ret
727
 
728
 
729
 
3545 hidnplayr 730
;----------------------------------------------------------------
731
;
732
;  System function to work with protocols  (76)
733
;
734
;----------------------------------------------------------------
735
align 4
736
sys_protocols:
3600 hidnplayr 737
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3545 hidnplayr 738
        jae     .doesnt_exist
739
 
740
        mov     esi, ebx
741
        and     esi, 0x0000ff00
742
        shr     esi, 6                          ; now we have the device num * 4 in esi
743
        cmp     [esi + NET_DRV_LIST], 0         ; check if driver is running
744
        je      .doesnt_exist
745
 
746
        push    .return                         ; return address (we will be using jumps instead of calls)
747
 
748
        mov     eax, ebx                        ; set ax to protocol number
749
        shr     eax, 16                         ;
750
 
751
        cmp     ax, API_ETH
752
        je      ETH_api
753
 
754
        cmp     ax, API_IPv4
755
        je      IPv4_api
756
 
757
        cmp     ax, API_ICMP
758
        je      ICMP_api
759
 
760
        cmp     ax, API_UDP
761
        je      UDP_api
762
 
763
        cmp     ax, API_TCP
764
        je      TCP_api
765
 
766
        cmp     ax, API_ARP
767
        je      ARP_api
768
 
769
        cmp     ax, API_PPPOE
770
        je      PPPoE_api
771
 
772
        cmp     ax, API_IPv6
773
        je      IPv6_api
774
 
775
        add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
776
 
777
  .doesnt_exist:
778
        mov     eax, -1
779
 
780
  .return:
781
        mov     [esp+28+4], eax                 ; return eax value to the program
782
        ret