Subversion Repositories Kolibri OS

Rev

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