Subversion Repositories Kolibri OS

Rev

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