Subversion Repositories Kolibri OS

Rev

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

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