Subversion Repositories Kolibri OS

Rev

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