Subversion Repositories Kolibri OS

Rev

Rev 1885 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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