Subversion Repositories Kolibri OS

Rev

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