Subversion Repositories Kolibri OS

Rev

Rev 5522 | Rev 5524 | 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: 5523 $
  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.         jmp     kernel_alloc
  348.  
  349.  
  350. align 4
  351. NET_BUFF_free:
  352.         jmp     kernel_free
  353.  
  354.  
  355. align 4
  356. NET_link_changed:
  357.  
  358.         DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state]
  359.  
  360. align 4
  361. NET_send_event:
  362.  
  363.         DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_send_event\n"
  364.  
  365. ; Send event to all applications
  366.         push    edi ecx
  367.         mov     edi, SLOT_BASE
  368.         mov     ecx, [TASK_COUNT]
  369.   .loop:
  370.         add     edi, 256
  371.         or      [edi + APPDATA.event_mask], EVENT_NETWORK2
  372.         loop    .loop
  373.         pop     ecx edi
  374.  
  375.         ret
  376.  
  377.  
  378.  
  379. ;-----------------------------------------------------------------
  380. ;
  381. ; NET_add_device:
  382. ;
  383. ;  This function is called by the network drivers,
  384. ;  to register each running NIC to the kernel
  385. ;
  386. ;  IN:  Pointer to device structure in ebx
  387. ;  OUT: Device num in eax, -1 on error
  388. ;
  389. ;-----------------------------------------------------------------
  390. align 4
  391. NET_add_device:
  392.  
  393.         DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_Add_Device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
  394.  
  395.         cmp     [NET_RUNNING], NET_DEVICES_MAX
  396.         jae     .error
  397.  
  398. ;----------------------------------
  399. ; Check if device is already listed
  400.         mov     eax, ebx
  401.         mov     ecx, NET_DEVICES_MAX    ; We need to check whole list because a device may be removed without re-organizing list
  402.         mov     edi, NET_DRV_LIST
  403.  
  404.         repne scasd                     ; See if device is already in the list
  405.         jz      .error
  406.  
  407. ;----------------------------
  408. ; Find empty slot in the list
  409.         xor     eax, eax
  410.         mov     ecx, NET_DEVICES_MAX
  411.         mov     edi, NET_DRV_LIST
  412.  
  413.         repne scasd
  414.         jnz     .error
  415.  
  416.         sub     edi, 4
  417.  
  418. ;-----------------------------
  419. ; Add device to the found slot
  420.         mov     [edi], ebx              ; add device to list
  421.  
  422.         mov     eax, edi                ; Calculate device number in eax
  423.         sub     eax, NET_DRV_LIST
  424.         shr     eax, 2
  425.  
  426.         inc     [NET_RUNNING]           ; Indicate that one more network device is up and running
  427.  
  428.         call    NET_send_event
  429.  
  430.         DEBUGF  DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax
  431.         ret
  432.  
  433.   .error:
  434.         or      eax, -1
  435.         DEBUGF  DEBUG_NETWORK_ERROR, "Adding network device failed\n"
  436.         ret
  437.  
  438.  
  439.  
  440. ;-----------------------------------------------------------------
  441. ;
  442. ; NET_Remove_Device:
  443. ;
  444. ;  This function is called by network drivers,
  445. ;  to unregister network devices from the kernel
  446. ;
  447. ;  IN:  Pointer to device structure in ebx
  448. ;  OUT: eax: -1 on error
  449. ;
  450. ;-----------------------------------------------------------------
  451. align 4
  452. NET_remove_device:
  453.  
  454.         cmp     [NET_RUNNING], 0
  455.         je      .error
  456.  
  457. ;----------------------------
  458. ; Find the driver in the list
  459.  
  460.         mov     eax, ebx
  461.         mov     ecx, NET_DEVICES_MAX
  462.         mov     edi, NET_DRV_LIST
  463.  
  464.         repne scasd
  465.         jnz     .error
  466.  
  467. ;------------------------
  468. ; Remove it from the list
  469.  
  470.         xor     eax, eax
  471.         mov     dword [edi-4], eax
  472.         dec     [NET_RUNNING]
  473.  
  474.         call    NET_send_event
  475.  
  476.         xor     eax, eax
  477.         ret
  478.  
  479.   .error:
  480.         or      eax, -1
  481.         ret
  482.  
  483.  
  484.  
  485. ;-----------------------------------------------------------------
  486. ;
  487. ; NET_ptr_to_num
  488. ;
  489. ; IN:  ebx = ptr to device struct
  490. ; OUT: edi = -1 on error, device number otherwise
  491. ;
  492. ;-----------------------------------------------------------------
  493. align 4
  494. NET_ptr_to_num:
  495.  
  496.         call    NET_ptr_to_num4
  497.         ror     edi, 2          ; If -1, stay -1
  498.                                 ; valid device numbers have last two bits 0, so do just shr
  499.  
  500.         ret
  501.  
  502. align 4
  503. NET_ptr_to_num4:                ; Todo, place number in device structure so we only need to verify?
  504.  
  505.         test    ebx, ebx
  506.         jz      .fail
  507.  
  508.         push    ecx
  509.         mov     ecx, NET_DEVICES_MAX
  510.         mov     edi, NET_DRV_LIST
  511.   .loop:
  512.         cmp     ebx, [edi]
  513.         je      .found
  514.         add     edi, 4
  515.         dec     ecx
  516.         jnz     .loop
  517.  
  518.         pop     ecx
  519.   .fail:
  520.         or      edi, -1
  521.         ret
  522.  
  523.   .found:
  524.         sub     edi, NET_DRV_LIST
  525.         pop     ecx
  526.         ret
  527.  
  528. ;-----------------------------------------------------------------
  529. ;
  530. ; checksum_1
  531. ;
  532. ;  This is the first of two functions needed to calculate a checksum.
  533. ;
  534. ;  IN:  edx = start offset for semi-checksum
  535. ;       esi = pointer to data
  536. ;       ecx = data size
  537. ;  OUT: edx = semi-checksum
  538. ;
  539. ;
  540. ; Code was optimized by diamond
  541. ;
  542. ;-----------------------------------------------------------------
  543. align 4
  544. checksum_1:
  545.  
  546.         shr     ecx, 1
  547.         pushf
  548.         jz      .no_2
  549.  
  550.         shr     ecx, 1
  551.         pushf
  552.         jz      .no_4
  553.  
  554.         shr     ecx, 1
  555.         pushf
  556.         jz      .no_8
  557.  
  558.   .loop:
  559.         add     dl, [esi+1]
  560.         adc     dh, [esi+0]
  561.  
  562.         adc     dl, [esi+3]
  563.         adc     dh, [esi+2]
  564.  
  565.         adc     dl, [esi+5]
  566.         adc     dh, [esi+4]
  567.  
  568.         adc     dl, [esi+7]
  569.         adc     dh, [esi+6]
  570.  
  571.         adc     edx, 0
  572.         add     esi, 8
  573.  
  574.         dec     ecx
  575.         jnz     .loop
  576.  
  577.         adc     edx, 0
  578.  
  579.   .no_8:
  580.         popf
  581.         jnc     .no_4
  582.  
  583.         add     dl, [esi+1]
  584.         adc     dh, [esi+0]
  585.  
  586.         adc     dl, [esi+3]
  587.         adc     dh, [esi+2]
  588.  
  589.         adc     edx, 0
  590.         add     esi, 4
  591.  
  592.   .no_4:
  593.         popf
  594.         jnc     .no_2
  595.  
  596.         add     dl, [esi+1]
  597.         adc     dh, [esi+0]
  598.  
  599.         adc     edx, 0
  600.         inc     esi
  601.         inc     esi
  602.  
  603.   .no_2:
  604.         popf
  605.         jnc     .end
  606.  
  607.         add     dh, [esi+0]
  608.         adc     edx, 0
  609.   .end:
  610.         ret
  611.  
  612. ;-----------------------------------------------------------------
  613. ;
  614. ; checksum_2
  615. ;
  616. ;  This function calculates the final ip/tcp/udp checksum for you
  617. ;
  618. ;  IN:  edx = semi-checksum
  619. ;  OUT: dx = checksum (in INET byte order)
  620. ;
  621. ;-----------------------------------------------------------------
  622. align 4
  623. checksum_2:
  624.  
  625.         mov     ecx, edx
  626.         shr     ecx, 16
  627.         and     edx, 0xffff
  628.         add     edx, ecx
  629.  
  630.         mov     ecx, edx
  631.         shr     ecx, 16
  632.         add     dx, cx
  633.         test    dx, dx          ; it seems that ZF is not set when CF is set :(
  634.         not     dx
  635.         jnz     .not_zero
  636.         dec     dx
  637.   .not_zero:
  638.         xchg    dl, dh
  639.  
  640.         DEBUGF  DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
  641.  
  642.         ret
  643.  
  644.  
  645.  
  646. ;----------------------------------------------------------------
  647. ;
  648. ;  System function to work with network devices (74)
  649. ;
  650. ;----------------------------------------------------------------
  651. align 4
  652. sys_network:
  653.  
  654.         cmp     bl, 255
  655.         jne     @f
  656.  
  657.         mov     eax, [NET_RUNNING]
  658.         mov     [esp+32], eax
  659.         ret
  660.  
  661.    @@:
  662.         cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
  663.         jae     .doesnt_exist
  664.  
  665.         mov     esi, ebx
  666.         and     esi, 0x0000ff00
  667.         shr     esi, 6
  668.  
  669.         cmp     dword [esi + NET_DRV_LIST], 0   ; check if driver is running
  670.         je      .doesnt_exist
  671.  
  672.         mov     eax, [esi + NET_DRV_LIST]
  673.  
  674.         and     ebx, 0x000000ff
  675.         cmp     ebx, .number
  676.         ja      .doesnt_exist
  677.         jmp     dword [.table + 4*ebx]
  678.  
  679.   .table:
  680.         dd      .get_type               ; 0
  681.         dd      .get_dev_name           ; 1
  682.         dd      .reset                  ; 2
  683.         dd      .stop                   ; 3
  684.         dd      .get_ptr                ; 4
  685.         dd      .get_drv_name           ; 5
  686.  
  687.         dd      .packets_tx             ; 6
  688.         dd      .packets_rx             ; 7
  689.         dd      .bytes_tx               ; 8
  690.         dd      .bytes_rx               ; 9
  691.         dd      .state                  ; 10
  692.   .number = ($ - .table) / 4 - 1
  693.  
  694.   .get_type:
  695.         mov     eax, [eax + NET_DEVICE.device_type]
  696.         mov     [esp+32], eax
  697.         ret
  698.  
  699.   .get_dev_name:
  700.         mov     esi, [eax + NET_DEVICE.name]
  701.         mov     edi, ecx
  702.  
  703.         mov     ecx, 64/4 ; max length
  704.         rep movsd
  705.  
  706.         xor     eax, eax
  707.         mov     [esp+32], eax
  708.         ret
  709.  
  710.   .reset:
  711.         call    [eax + NET_DEVICE.reset]
  712.         mov     [esp+32], eax
  713.         ret
  714.  
  715.   .stop:
  716.         call    [eax + NET_DEVICE.unload]
  717.         mov     [esp+32], eax
  718.         ret
  719.  
  720.  
  721.   .get_ptr:
  722.         mov     [esp+32], eax
  723.         ret
  724.  
  725.  
  726.   .get_drv_name:
  727.         xor     eax, eax
  728.         mov     [esp+32], eax
  729.         ret
  730.  
  731.   .packets_tx:
  732.         mov     eax, [eax + NET_DEVICE.packets_tx]
  733.         mov     [esp+32], eax
  734.         ret
  735.  
  736.   .packets_rx:
  737.         mov     eax, [eax + NET_DEVICE.packets_rx]
  738.         mov     [esp+32], eax
  739.         ret
  740.  
  741.   .bytes_tx:
  742.         mov     ebx, dword [eax + NET_DEVICE.bytes_tx + 4]
  743.         mov     [esp+20], ebx
  744.         mov     eax, dword [eax + NET_DEVICE.bytes_tx]
  745.         mov     [esp+32], eax
  746.         ret
  747.  
  748.   .bytes_rx:
  749.         mov     ebx, dword [eax + NET_DEVICE.bytes_rx + 4]
  750.         mov     [esp+20], ebx
  751.         mov     eax, dword [eax + NET_DEVICE.bytes_rx]
  752.         mov     [esp+32], eax
  753.         ret
  754.  
  755.   .state:
  756.         mov     eax, [eax + NET_DEVICE.link_state]
  757.         mov     [esp+32], eax
  758.         ret
  759.  
  760.  
  761.   .doesnt_exist:
  762.         mov     dword[esp+32], -1
  763.         ret
  764.  
  765.  
  766.  
  767. ;----------------------------------------------------------------
  768. ;
  769. ;  System function to work with protocols  (76)
  770. ;
  771. ;----------------------------------------------------------------
  772. align 4
  773. sys_protocols:
  774.         cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
  775.         jae     .doesnt_exist
  776.  
  777.         mov     esi, ebx
  778.         and     esi, 0x0000ff00
  779.         shr     esi, 6                          ; now we have the device num * 4 in esi
  780.         cmp     [esi + NET_DRV_LIST], 0         ; check if driver is running
  781.         je      .doesnt_exist
  782.  
  783.         push    .return                         ; return address (we will be using jumps instead of calls)
  784.  
  785.         mov     eax, ebx                        ; set ax to protocol number
  786.         shr     eax, 16                         ;
  787.  
  788.         cmp     ax, API_ETH
  789.         je      ETH_api
  790.  
  791.         cmp     ax, API_IPv4
  792.         je      IPv4_api
  793.  
  794.         cmp     ax, API_ICMP
  795.         je      ICMP_api
  796.  
  797.         cmp     ax, API_UDP
  798.         je      UDP_api
  799.  
  800.         cmp     ax, API_TCP
  801.         je      TCP_api
  802.  
  803.         cmp     ax, API_ARP
  804.         je      ARP_api
  805.  
  806.         cmp     ax, API_PPPOE
  807.         je      PPPoE_api
  808.  
  809.         cmp     ax, API_IPv6
  810.         je      IPv6_api
  811.  
  812.         add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
  813.  
  814.   .doesnt_exist:
  815.         mov     eax, -1
  816.  
  817.   .return:
  818.         mov     [esp+28+4], eax                 ; return eax value to the program
  819.         ret
  820.