Subversion Repositories Kolibri OS

Rev

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