Subversion Repositories Kolibri OS

Rev

Rev 3601 | Rev 3674 | 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:
3643 hidnplayr 453
 
454
        call    NET_ptr_to_num4
455
        ror     edi, 2          ; If -1, stay -1
456
                                ; valid device numbers have last two bits 0, so do just shr
457
 
458
        ret
459
 
460
align 4
461
NET_ptr_to_num4:                ; Todo, place number in device structure so we only need to verify?
462
 
3545 hidnplayr 463
        push    ecx
464
 
3600 hidnplayr 465
        mov     ecx, NET_DEVICES_MAX
3545 hidnplayr 466
        mov     edi, NET_DRV_LIST
467
  .loop:
468
        cmp     ebx, [edi]
3643 hidnplayr 469
        je      .found
3545 hidnplayr 470
        add     edi, 4
471
        dec     ecx
472
        jnz     .loop
473
 
474
        or      edi, -1
475
        pop     ecx
476
        ret
477
 
478
  .found:
479
        sub     edi, NET_DRV_LIST
480
        pop     ecx
481
        ret
482
 
483
;-----------------------------------------------------------------
484
;
485
; checksum_1
486
;
487
;  This is the first of two functions needed to calculate a checksum.
488
;
489
;  IN:  edx = start offset for semi-checksum
490
;       esi = pointer to data
491
;       ecx = data size
492
;  OUT: edx = semi-checksum
493
;
494
;
495
; Code was optimized by diamond
496
;
497
;-----------------------------------------------------------------
498
align 4
499
checksum_1:
500
 
501
        shr     ecx, 1
502
        pushf
503
        jz      .no_2
504
 
505
        shr     ecx, 1
506
        pushf
507
        jz      .no_4
508
 
509
        shr     ecx, 1
510
        pushf
511
        jz      .no_8
512
 
513
  .loop:
514
        add     dl, [esi+1]
515
        adc     dh, [esi+0]
516
 
517
        adc     dl, [esi+3]
518
        adc     dh, [esi+2]
519
 
520
        adc     dl, [esi+5]
521
        adc     dh, [esi+4]
522
 
523
        adc     dl, [esi+7]
524
        adc     dh, [esi+6]
525
 
526
        adc     edx, 0
527
        add     esi, 8
528
 
529
        dec     ecx
530
        jnz     .loop
531
 
532
        adc     edx, 0
533
 
534
  .no_8:
535
        popf
536
        jnc     .no_4
537
 
538
        add     dl, [esi+1]
539
        adc     dh, [esi+0]
540
 
541
        adc     dl, [esi+3]
542
        adc     dh, [esi+2]
543
 
544
        adc     edx, 0
545
        add     esi, 4
546
 
547
  .no_4:
548
        popf
549
        jnc     .no_2
550
 
551
        add     dl, [esi+1]
552
        adc     dh, [esi+0]
553
 
554
        adc     edx, 0
555
        inc     esi
556
        inc     esi
557
 
558
  .no_2:
559
        popf
560
        jnc     .end
561
 
562
        add     dh, [esi+0]
563
        adc     edx, 0
564
  .end:
565
        ret
566
 
567
;-----------------------------------------------------------------
568
;
569
; checksum_2
570
;
571
;  This function calculates the final ip/tcp/udp checksum for you
572
;
573
;  IN:  edx = semi-checksum
574
;  OUT: dx = checksum (in INET byte order)
575
;
576
;-----------------------------------------------------------------
577
align 4
578
checksum_2:
579
 
580
        mov     ecx, edx
581
        shr     ecx, 16
582
        and     edx, 0xffff
583
        add     edx, ecx
584
 
585
        mov     ecx, edx
586
        shr     ecx, 16
587
        add     dx, cx
588
        test    dx, dx          ; it seems that ZF is not set when CF is set :(
589
        not     dx
590
        jnz     .not_zero
591
        dec     dx
592
  .not_zero:
593
        xchg    dl, dh
594
 
3556 hidnplayr 595
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
3545 hidnplayr 596
 
597
        ret
598
 
599
 
600
 
601
;----------------------------------------------------------------
602
;
3601 hidnplayr 603
;  System function to work with network devices (74)
3545 hidnplayr 604
;
605
;----------------------------------------------------------------
606
align 4
3601 hidnplayr 607
sys_network:
3545 hidnplayr 608
 
609
        cmp     ebx, -1
610
        jne     @f
611
 
612
        mov     eax, [NET_RUNNING]
3601 hidnplayr 613
        mov     [esp+32], eax
614
        ret
3545 hidnplayr 615
 
616
   @@:
3600 hidnplayr 617
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3545 hidnplayr 618
        jae     .doesnt_exist
619
 
620
        mov     esi, ebx
621
        and     esi, 0x0000ff00
622
        shr     esi, 6
623
 
624
        cmp     dword [esi + NET_DRV_LIST], 0   ; check if driver is running
625
        je      .doesnt_exist
626
 
627
        mov     eax, [esi + NET_DRV_LIST]
628
 
629
        and     ebx, 0x000000ff
630
        cmp     ebx, .number
631
        ja      .doesnt_exist
632
        jmp     dword [.table + 4*ebx]
633
 
634
  .table:
635
        dd      .get_type               ; 0
636
        dd      .get_dev_name           ; 1
637
        dd      .reset                  ; 2
638
        dd      .stop                   ; 3
639
        dd      .get_ptr                ; 4
640
        dd      .get_drv_name           ; 5
3601 hidnplayr 641
 
642
        dd      .packets_tx             ; 6
643
        dd      .packets_rx             ; 7
644
        dd      .bytes_tx               ; 8
645
        dd      .bytes_rx               ; 9
646
        dd      .state                  ; 10
3545 hidnplayr 647
  .number = ($ - .table) / 4 - 1
648
 
3601 hidnplayr 649
  .get_type:
3600 hidnplayr 650
        mov     eax, [eax + NET_DEVICE.device_type]
3601 hidnplayr 651
        mov     [esp+32], eax
652
        ret
3545 hidnplayr 653
 
3601 hidnplayr 654
  .get_dev_name:
3545 hidnplayr 655
        mov     esi, [eax + NET_DEVICE.name]
656
        mov     edi, ecx
657
 
658
        mov     ecx, 64/4 ; max length
659
        rep     movsd
660
 
661
        xor     eax, eax
3601 hidnplayr 662
        mov     [esp+32], eax
663
        ret
3545 hidnplayr 664
 
3601 hidnplayr 665
  .reset:
3545 hidnplayr 666
        call    [eax + NET_DEVICE.reset]
3601 hidnplayr 667
        mov     [esp+32], eax
668
        ret
3545 hidnplayr 669
 
3601 hidnplayr 670
  .stop:
3545 hidnplayr 671
        call    [eax + NET_DEVICE.unload]
3601 hidnplayr 672
        mov     [esp+32], eax
673
        ret
3545 hidnplayr 674
 
675
 
3601 hidnplayr 676
  .get_ptr:
677
        mov     [esp+32], eax
678
        ret
3545 hidnplayr 679
 
680
 
3601 hidnplayr 681
  .get_drv_name:
682
        xor     eax, eax
683
        mov     [esp+32], eax
684
        ret
3545 hidnplayr 685
 
3601 hidnplayr 686
  .packets_tx:
687
        mov     eax, [eax + NET_DEVICE.packets_tx]
688
        mov     [esp+32], eax
689
        ret
3545 hidnplayr 690
 
3601 hidnplayr 691
  .packets_rx:
692
        mov     eax, [eax + NET_DEVICE.packets_rx]
693
        mov     [esp+32], eax
694
        ret
3545 hidnplayr 695
 
3601 hidnplayr 696
  .bytes_tx:
697
        mov     ebx, dword [eax + NET_DEVICE.bytes_tx + 4]
698
        mov     [esp+20], ebx
699
        mov     eax, dword [eax + NET_DEVICE.bytes_tx]
700
        mov     [esp+32], eax
701
        ret
3545 hidnplayr 702
 
3601 hidnplayr 703
  .bytes_rx:
704
        mov     ebx, dword [eax + NET_DEVICE.bytes_rx + 4]
705
        mov     [esp+20], ebx
706
        mov     eax, dword [eax + NET_DEVICE.bytes_rx]
707
        mov     [esp+32], eax
708
        ret
3545 hidnplayr 709
 
3601 hidnplayr 710
  .state:
711
        mov     eax, [eax + NET_DEVICE.link_state]
3545 hidnplayr 712
        mov     [esp+32], eax
713
        ret
714
 
715
 
3601 hidnplayr 716
  .doesnt_exist:
717
        mov     dword[esp+32], -1
718
        ret
719
 
720
 
721
 
3545 hidnplayr 722
;----------------------------------------------------------------
723
;
724
;  System function to work with protocols  (76)
725
;
726
;----------------------------------------------------------------
727
align 4
728
sys_protocols:
3600 hidnplayr 729
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3545 hidnplayr 730
        jae     .doesnt_exist
731
 
732
        mov     esi, ebx
733
        and     esi, 0x0000ff00
734
        shr     esi, 6                          ; now we have the device num * 4 in esi
735
        cmp     [esi + NET_DRV_LIST], 0         ; check if driver is running
736
        je      .doesnt_exist
737
 
738
        push    .return                         ; return address (we will be using jumps instead of calls)
739
 
740
        mov     eax, ebx                        ; set ax to protocol number
741
        shr     eax, 16                         ;
742
 
743
        cmp     ax, API_ETH
744
        je      ETH_api
745
 
746
        cmp     ax, API_IPv4
747
        je      IPv4_api
748
 
749
        cmp     ax, API_ICMP
750
        je      ICMP_api
751
 
752
        cmp     ax, API_UDP
753
        je      UDP_api
754
 
755
        cmp     ax, API_TCP
756
        je      TCP_api
757
 
758
        cmp     ax, API_ARP
759
        je      ARP_api
760
 
761
        cmp     ax, API_PPPOE
762
        je      PPPoE_api
763
 
764
        cmp     ax, API_IPv6
765
        je      IPv6_api
766
 
767
        add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
768
 
769
  .doesnt_exist:
770
        mov     eax, -1
771
 
772
  .return:
773
        mov     [esp+28+4], eax                 ; return eax value to the program
774
        ret