Subversion Repositories Kolibri OS

Rev

Rev 3674 | Rev 3704 | 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: 3523 $
  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_BLOCK                = 1 shl 10      ; TO BE REMOVED
  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
  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
  106.  
  107. SS_ASYNC                = 0x1000        ; async i/o notify
  108. SS_ISCONFIRMING         = 0x2000        ; deciding to accept connection req
  109. SS_MORETOCOME           = 0x4000
  110.  
  111. SS_BLOCKED              = 0x8000
  112.  
  113.  
  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
  116.  
  117. ; Error Codes
  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
  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.  
  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
  154. HWACC_TCP_IPv4          = 1 shl 0
  155.  
  156. struct  NET_DEVICE
  157.  
  158.         device_type     dd ?    ; Type field
  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.  
  171.         link_state      dd ?    ; link state (0 = no link)
  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.  
  224. uglobal
  225. align 4
  226.  
  227.         NET_RUNNING     dd  ?
  228.         NET_DRV_LIST    rd  NET_DEVICES_MAX
  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
  249.         mov     ecx, (NET_DEVICES_MAX + 2)
  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.  
  264.         LOOP_init
  265.  
  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.  
  324.         DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state]
  325.  
  326. align 4
  327. NET_send_event:
  328.  
  329.         DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_send_event\n"
  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.  
  359.         DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_Add_Device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
  360.  
  361.         cmp     [NET_RUNNING], NET_DEVICES_MAX
  362.         jae     .error
  363.  
  364. ;----------------------------------
  365. ; Check if device is already listed
  366.         mov     eax, ebx
  367.         mov     ecx, NET_DEVICES_MAX    ; We need to check whole list because a device may be removed without re-organizing list
  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
  376.         mov     ecx, NET_DEVICES_MAX
  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.  
  396.         DEBUGF  DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax
  397.         ret
  398.  
  399.   .error:
  400.         or      eax, -1
  401.         DEBUGF  DEBUG_NETWORK_ERROR, "Adding network device failed\n"
  402.         ret
  403.  
  404.  
  405.  
  406. ;-----------------------------------------------------------------
  407. ;
  408. ; NET_Remove_Device:
  409. ;
  410. ;  This function is called by network drivers,
  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
  427.         mov     ecx, NET_DEVICES_MAX
  428.         mov     edi, NET_DRV_LIST
  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
  438.         dec     [NET_RUNNING]
  439.  
  440.         call    NET_send_event
  441.  
  442.         xor     eax, eax
  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:
  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.  
  471.         push    ecx
  472.  
  473.         mov     ecx, NET_DEVICES_MAX
  474.         mov     edi, NET_DRV_LIST
  475.   .loop:
  476.         cmp     ebx, [edi]
  477.         je      .found
  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.  
  603.         DEBUGF  DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
  604.  
  605.         ret
  606.  
  607.  
  608.  
  609. ;----------------------------------------------------------------
  610. ;
  611. ;  System function to work with network devices (74)
  612. ;
  613. ;----------------------------------------------------------------
  614. align 4
  615. sys_network:
  616.  
  617.         cmp     ebx, -1
  618.         jne     @f
  619.  
  620.         mov     eax, [NET_RUNNING]
  621.         mov     [esp+32], eax
  622.         ret
  623.  
  624.    @@:
  625.         cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
  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
  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
  655.   .number = ($ - .table) / 4 - 1
  656.  
  657.   .get_type:
  658.         mov     eax, [eax + NET_DEVICE.device_type]
  659.         mov     [esp+32], eax
  660.         ret
  661.  
  662.   .get_dev_name:
  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
  670.         mov     [esp+32], eax
  671.         ret
  672.  
  673.   .reset:
  674.         call    [eax + NET_DEVICE.reset]
  675.         mov     [esp+32], eax
  676.         ret
  677.  
  678.   .stop:
  679.         call    [eax + NET_DEVICE.unload]
  680.         mov     [esp+32], eax
  681.         ret
  682.  
  683.  
  684.   .get_ptr:
  685.         mov     [esp+32], eax
  686.         ret
  687.  
  688.  
  689.   .get_drv_name:
  690.         xor     eax, eax
  691.         mov     [esp+32], eax
  692.         ret
  693.  
  694.   .packets_tx:
  695.         mov     eax, [eax + NET_DEVICE.packets_tx]
  696.         mov     [esp+32], eax
  697.         ret
  698.  
  699.   .packets_rx:
  700.         mov     eax, [eax + NET_DEVICE.packets_rx]
  701.         mov     [esp+32], eax
  702.         ret
  703.  
  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
  710.  
  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
  717.  
  718.   .state:
  719.         mov     eax, [eax + NET_DEVICE.link_state]
  720.         mov     [esp+32], eax
  721.         ret
  722.  
  723.  
  724.   .doesnt_exist:
  725.         mov     dword[esp+32], -1
  726.         ret
  727.  
  728.  
  729.  
  730. ;----------------------------------------------------------------
  731. ;
  732. ;  System function to work with protocols  (76)
  733. ;
  734. ;----------------------------------------------------------------
  735. align 4
  736. sys_protocols:
  737.         cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
  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
  783.