Subversion Repositories Kolibri OS

Rev

Rev 3388 | 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: 3389 $
  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.         ; Test for 10ms tick
  268.         mov     eax, [timer_ticks]
  269.         cmp     eax, [net_10ms]
  270.         je      .exit
  271.         mov     [net_10ms], eax
  272.  
  273.         test    [net_10ms], 0x0f        ; 160ms
  274.         jnz     .exit
  275.  
  276.         TCP_timer_160ms
  277.  
  278.         test    [net_10ms], 0x3f        ; 640ms
  279.         jnz     .exit
  280.  
  281.         TCP_timer_640ms
  282.         ARP_decrease_entry_ttls
  283.         IPv4_decrease_fragment_ttls
  284.  
  285.   .exit:
  286.         ret
  287.  
  288.  
  289.  
  290. align 4
  291. NET_link_changed:
  292.  
  293.         DEBUGF  1,"NET_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.state]
  294.  
  295. align 4
  296. NET_send_event:
  297.  
  298.         DEBUGF  1,"NET_send_event\n"
  299.  
  300. ; Send event to all applications
  301.         push    edi ecx
  302.         mov     edi, SLOT_BASE
  303.         mov     ecx, [TASK_COUNT]
  304.   .loop:
  305.         add     edi, 256
  306.         or      [edi + APPDATA.event_mask], EVENT_NETWORK2
  307.         loop    .loop
  308.         pop     ecx edi
  309.  
  310. ;        call    change_task
  311.  
  312.         ret
  313.  
  314.  
  315.  
  316. ;-----------------------------------------------------------------
  317. ;
  318. ; NET_add_device:
  319. ;
  320. ;  This function is called by the network drivers,
  321. ;  to register each running NIC to the kernel
  322. ;
  323. ;  IN:  Pointer to device structure in ebx
  324. ;  OUT: Device num in eax, -1 on error
  325. ;
  326. ;-----------------------------------------------------------------
  327. align 4
  328. NET_add_device:
  329.  
  330.         DEBUGF  1,"NET_Add_Device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
  331.  
  332.         cmp     [NET_RUNNING], MAX_NET_DEVICES
  333.         jae     .error
  334.  
  335. ;----------------------------------
  336. ; Check if device is already listed
  337.         mov     eax, ebx
  338.         mov     ecx, MAX_NET_DEVICES    ; We need to check whole list because a device may be removed without re-organizing list
  339.         mov     edi, NET_DRV_LIST
  340.  
  341.         repne   scasd                   ; See if device is already in the list
  342.         jz      .error
  343.  
  344. ;----------------------------
  345. ; Find empty slot in the list
  346.         xor     eax, eax
  347.         mov     ecx, MAX_NET_DEVICES
  348.         mov     edi, NET_DRV_LIST
  349.  
  350.         repne   scasd
  351.         jnz     .error
  352.  
  353.         sub     edi, 4
  354.  
  355. ;-----------------------------
  356. ; Add device to the found slot
  357.         mov     [edi], ebx              ; add device to list
  358.  
  359.         mov     eax, edi                ; Calculate device number in eax
  360.         sub     eax, NET_DRV_LIST
  361.         shr     eax, 2
  362.  
  363.         inc     [NET_RUNNING]           ; Indicate that one more network device is up and running
  364.  
  365.         cmp     eax, 1                  ; If it's the first network device, try to set it as default
  366.         jne     @f
  367.         push    eax
  368.         call    NET_set_default
  369.         pop     eax
  370.        @@:
  371.  
  372.         call    NET_send_event
  373.  
  374.         DEBUGF  1,"Device number: %u\n", eax
  375.         ret
  376.  
  377.   .error:
  378.         or      eax, -1
  379.         DEBUGF  2,"Adding network device failed\n"
  380.         ret
  381.  
  382.  
  383.  
  384. ;-----------------------------------------------------------------
  385. ;
  386. ; NET_set_default
  387. ;
  388. ;  API to set the default interface
  389. ;
  390. ;  IN:  Device num in eax
  391. ;  OUT: Device num in eax, -1 on error
  392. ;
  393. ;-----------------------------------------------------------------
  394. align 4
  395. NET_set_default:
  396.  
  397.         DEBUGF  1,"NET_set_default: device=%x\n", eax
  398.  
  399.         cmp     eax, MAX_NET_DEVICES
  400.         jae     .error
  401.  
  402.         cmp     [NET_DRV_LIST+eax*4], 0
  403.         je      .error
  404.  
  405.         mov     [NET_DEFAULT], eax
  406.  
  407.         DEBUGF  1,"NET_set_default: succes\n"
  408.         ret
  409.  
  410.   .error:
  411.         or      eax, -1
  412.         DEBUGF  1,"NET_set_default: failed\n"
  413.         ret
  414.  
  415.  
  416. ;-----------------------------------------------------------------
  417. ;
  418. ; NET_Remove_Device:
  419. ;
  420. ;  This function is called by etwork drivers,
  421. ;  to unregister network devices from the kernel
  422. ;
  423. ;  IN:  Pointer to device structure in ebx
  424. ;  OUT: eax: -1 on error
  425. ;
  426. ;-----------------------------------------------------------------
  427. align 4
  428. NET_remove_device:
  429.  
  430.         cmp     [NET_RUNNING], 0
  431.         je      .error
  432.  
  433.         cmp     [NET_DRV_LIST], ebx
  434.         jne     @f
  435.         mov     [NET_DRV_LIST], 0
  436.         cmp     [NET_RUNNING], 1
  437.         je      @f
  438.         ; there are still active devices, find one and make it default
  439.         xor     eax, eax
  440.         mov     ecx, MAX_NET_DEVICES
  441.         mov     edi, NET_DRV_LIST
  442.         repe    scasd
  443.         je      @f
  444.         shr     edi, 2
  445.         dec     edi
  446.         mov     [NET_DEFAULT], edi
  447.        @@:
  448.  
  449. ;----------------------------
  450. ; Find the driver in the list
  451.  
  452.         mov     eax, ebx
  453.         mov     ecx, MAX_NET_DEVICES
  454.         mov     edi, NET_DRV_LIST+4
  455.  
  456.         repne   scasd
  457.         jnz     .error
  458.  
  459. ;------------------------
  460. ; Remove it from the list
  461.  
  462.         xor     eax, eax
  463.         mov     dword [edi-4], eax
  464.  
  465.         call    NET_send_event
  466.  
  467.         dec     [NET_RUNNING]
  468.         ret
  469.  
  470.   .error:
  471.         or      eax, -1
  472.         ret
  473.  
  474.  
  475.  
  476. ;-----------------------------------------------------------------
  477. ;
  478. ; NET_ptr_to_num
  479. ;
  480. ; IN:  ebx = ptr to device struct
  481. ; OUT: edi = -1 on error, device number otherwise
  482. ;
  483. ;-----------------------------------------------------------------
  484. align 4
  485. NET_ptr_to_num:
  486.         push    ecx
  487.  
  488.         mov     ecx, MAX_NET_DEVICES
  489.         mov     edi, NET_DRV_LIST
  490.  
  491.   .loop:
  492.         cmp     ebx, [edi]
  493.         jz      .found
  494.         add     edi, 4
  495.         dec     ecx
  496.         jnz     .loop
  497.  
  498.         ; repnz  scasd could work too if eax is used instead of ebx!
  499.  
  500.         or      edi, -1
  501.  
  502.         pop     ecx
  503.         ret
  504.  
  505.   .found:
  506.         sub     edi, NET_DRV_LIST
  507.         shr     edi, 2
  508.  
  509.         pop     ecx
  510.         ret
  511.  
  512. ;-----------------------------------------------------------------
  513. ;
  514. ; checksum_1
  515. ;
  516. ;  This is the first of two functions needed to calculate a checksum.
  517. ;
  518. ;  IN:  edx = start offset for semi-checksum
  519. ;       esi = pointer to data
  520. ;       ecx = data size
  521. ;  OUT: edx = semi-checksum
  522. ;
  523. ;
  524. ; Code was optimized by diamond
  525. ;
  526. ;-----------------------------------------------------------------
  527. align 4
  528. checksum_1:
  529.  
  530.         shr     ecx, 1
  531.         pushf
  532.         jz      .no_2
  533.  
  534.         shr     ecx, 1
  535.         pushf
  536.         jz      .no_4
  537.  
  538.         shr     ecx, 1
  539.         pushf
  540.         jz      .no_8
  541.  
  542.   .loop:
  543.         add     dl, [esi+1]
  544.         adc     dh, [esi+0]
  545.  
  546.         adc     dl, [esi+3]
  547.         adc     dh, [esi+2]
  548.  
  549.         adc     dl, [esi+5]
  550.         adc     dh, [esi+4]
  551.  
  552.         adc     dl, [esi+7]
  553.         adc     dh, [esi+6]
  554.  
  555.         adc     edx, 0
  556.         add     esi, 8
  557.  
  558.         dec     ecx
  559.         jnz     .loop
  560.  
  561.         adc     edx, 0
  562.  
  563.   .no_8:
  564.         popf
  565.         jnc     .no_4
  566.  
  567.         add     dl, [esi+1]
  568.         adc     dh, [esi+0]
  569.  
  570.         adc     dl, [esi+3]
  571.         adc     dh, [esi+2]
  572.  
  573.         adc     edx, 0
  574.         add     esi, 4
  575.  
  576.   .no_4:
  577.         popf
  578.         jnc     .no_2
  579.  
  580.         add     dl, [esi+1]
  581.         adc     dh, [esi+0]
  582.  
  583.         adc     edx, 0
  584.         inc     esi
  585.         inc     esi
  586.  
  587.   .no_2:
  588.         popf
  589.         jnc     .end
  590.  
  591.         add     dh, [esi+0]
  592.         adc     edx, 0
  593.   .end:
  594.         ret
  595.  
  596. ;-----------------------------------------------------------------
  597. ;
  598. ; checksum_2
  599. ;
  600. ;  This function calculates the final ip/tcp/udp checksum for you
  601. ;
  602. ;  IN:  edx = semi-checksum
  603. ;  OUT: dx = checksum (in INET byte order)
  604. ;
  605. ;-----------------------------------------------------------------
  606. align 4
  607. checksum_2:
  608.  
  609.         mov     ecx, edx
  610.         shr     ecx, 16
  611.         and     edx, 0xffff
  612.         add     edx, ecx
  613.  
  614.         mov     ecx, edx
  615.         shr     ecx, 16
  616.         add     dx, cx
  617.         test    dx, dx          ; it seems that ZF is not set when CF is set :(
  618.         not     dx
  619.         jnz     .not_zero
  620.         dec     dx
  621.   .not_zero:
  622.         xchg    dl, dh
  623.  
  624.         DEBUGF  1,"Checksum: %x\n", dx
  625.  
  626.         ret
  627.  
  628.  
  629.  
  630. ;----------------------------------------------------------------
  631. ;
  632. ;  System function to work with network devices (75)
  633. ;
  634. ;----------------------------------------------------------------
  635. align 4
  636. sys_network:                    ; FIXME: make default device easily accessible
  637.  
  638.         cmp     ebx, -1
  639.         jne     @f
  640.  
  641.         mov     eax, [NET_RUNNING]
  642.         jmp     .return
  643.  
  644.    @@:
  645.         cmp     bh, MAX_NET_DEVICES             ; Check if device number exists
  646.         jae     .doesnt_exist
  647.  
  648.         mov     esi, ebx
  649.         and     esi, 0x0000ff00
  650.         shr     esi, 6
  651.  
  652.         cmp     dword [esi + NET_DRV_LIST], 0   ; check if driver is running
  653.         je      .doesnt_exist
  654.  
  655.         mov     eax, [esi + NET_DRV_LIST]
  656.  
  657.         and     ebx, 0x000000ff
  658.         cmp     ebx, .number
  659.         ja      .doesnt_exist
  660.         jmp     dword [.table + 4*ebx]
  661.  
  662.   .table:
  663.         dd      .get_type               ; 0
  664.         dd      .get_dev_name           ; 1
  665.         dd      .reset                  ; 2
  666.         dd      .stop                   ; 3
  667.         dd      .get_ptr                ; 4
  668.         dd      .get_drv_name           ; 5
  669.         dd      .set_default            ; 6
  670.   .number = ($ - .table) / 4 - 1
  671.  
  672.   .get_type:                            ; 0 = Get device type (ethernet/token ring/...)
  673.  
  674.         mov     eax, [eax + NET_DEVICE.type]
  675.         jmp     .return
  676.  
  677.  
  678.   .get_dev_name:                        ; 1 = Get device name
  679.  
  680.         mov     esi, [eax + NET_DEVICE.name]
  681.         mov     edi, ecx
  682.  
  683.         mov     ecx, 64/4 ; max length
  684.         rep     movsd
  685.  
  686.         xor     eax, eax
  687.         jmp     .return
  688.  
  689.   .reset:                               ; 2 = Reset the device
  690.  
  691.         call    [eax + NET_DEVICE.reset]
  692.         jmp     .return
  693.  
  694.   .stop:                                ; 3 = Stop driver for this device
  695.  
  696.         call    [eax + NET_DEVICE.unload]
  697.         jmp     .return
  698.  
  699.  
  700.   .get_ptr:                             ; 4 = Get driver pointer
  701.  
  702.         jmp     .return
  703.  
  704.  
  705.   .get_drv_name:                        ; 5 = Get driver name
  706.  
  707.         xor     eax, eax
  708.         jmp     .return
  709.  
  710.  
  711.   .set_default:                         ; 6 = Set default device
  712.  
  713.         call    NET_set_default
  714.         jmp     .return
  715.  
  716.   .doesnt_exist:
  717.         mov     eax, -1
  718.  
  719.   .return:
  720.         mov     [esp+32], eax
  721.         ret
  722.  
  723.  
  724. ;----------------------------------------------------------------
  725. ;
  726. ;  System function to work with protocols  (76)
  727. ;
  728. ;----------------------------------------------------------------
  729. align 4
  730. sys_protocols:
  731.         cmp     bh, MAX_NET_DEVICES             ; Check if device number exists
  732.         jae     .doesnt_exist
  733.  
  734.         mov     esi, ebx
  735.         and     esi, 0x0000ff00
  736.         shr     esi, 6                          ; now we have the device num * 4 in esi
  737.         cmp     [esi + NET_DRV_LIST], 0         ; check if driver is running
  738.         je      .doesnt_exist
  739.  
  740.         push    .return                         ; return address (we will be using jumps instead of calls)
  741.  
  742.         mov     eax, ebx                        ; set ax to protocol number
  743.         shr     eax, 16                         ;
  744.  
  745.         cmp     ax, API_ETH
  746.         je      ETH_api
  747.  
  748.         cmp     ax, API_IPv4
  749.         je      IPv4_api
  750.  
  751.         cmp     ax, API_ICMP
  752.         je      ICMP_api
  753.  
  754.         cmp     ax, API_UDP
  755.         je      UDP_api
  756.  
  757.         cmp     ax, API_TCP
  758.         je      TCP_api
  759.  
  760.         cmp     ax, API_ARP
  761.         je      ARP_api
  762.  
  763.         cmp     ax, API_PPPOE
  764.         je      PPPoE_api
  765.  
  766.         cmp     ax, API_IPv6
  767.         je      IPv6_api
  768.  
  769.         add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
  770.  
  771.   .doesnt_exist:
  772.         mov     eax, -1
  773.  
  774.   .return:
  775.         mov     [esp+28+4], eax                 ; return eax value to the program
  776.         ret
  777.