Subversion Repositories Kolibri OS

Rev

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