Subversion Repositories Kolibri OS

Rev

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