Subversion Repositories Kolibri OS

Rev

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

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