Subversion Repositories Kolibri OS

Rev

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