Subversion Repositories Kolibri OS

Rev

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