Subversion Repositories Kolibri OS

Rev

Rev 3626 | Rev 3908 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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