Subversion Repositories Kolibri OS

Rev

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