Subversion Repositories Kolibri OS

Rev

Rev 2614 | 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: 2621 $
  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.         mov     eax, [esi + NET_DRV_LIST]
  593.  
  594.         and     ebx, 0x000000ff
  595.         cmp     ebx, .number
  596.         ja      .doesnt_exist
  597.         jmp     dword [.table + 4*ebx]
  598.  
  599.   .table:
  600.         dd      .get_type               ; 0
  601.         dd      .get_dev_name           ; 1
  602.         dd      .reset                  ; 2
  603.         dd      .stop                   ; 3
  604.         dd      .get_ptr                ; 4
  605.         dd      .get_drv_name           ; 5
  606.         dd      .set_default            ; 6
  607.   .number = ($ - .table) / 4 - 1
  608.  
  609.   .get_type:                            ; 0 = Get device type (ethernet/token ring/...)
  610.  
  611.         mov     eax, [eax + NET_DEVICE.type]
  612.         jmp     .return
  613.  
  614.  
  615.   .get_dev_name:                        ; 1 = Get device name
  616.  
  617.         mov     esi, [eax + NET_DEVICE.name]
  618.         mov     edi, ecx
  619.  
  620.         mov     ecx, 64/4 ; max length
  621.         rep     movsd
  622.  
  623.         xor     eax, eax
  624.         jmp     .return
  625.  
  626.   .reset:                               ; 2 = Reset the device
  627.  
  628.         call    [eax + NET_DEVICE.reset]
  629.         jmp     .return
  630.  
  631.   .stop:                                ; 3 = Stop driver for this device
  632.  
  633.         call    [eax + NET_DEVICE.unload]
  634.         jmp     .return
  635.  
  636.  
  637.   .get_ptr:                             ; 4 = Get driver pointer
  638.  
  639.         jmp     .return
  640.  
  641.  
  642.   .get_drv_name:                        ; 5 = Get driver name
  643.  
  644.         xor     eax, eax
  645.         jmp     .return
  646.  
  647.  
  648.   .set_default:                         ; 6 = Set default device
  649.  
  650.         call    NET_set_default
  651.         jmp     .return
  652.  
  653.   .doesnt_exist:
  654.         DEBUGF  1,"sys_network: invalid device/function specified!\n"
  655.         mov     eax, -1
  656.  
  657.   .return:
  658.         mov     [esp+32], eax
  659.         ret
  660.  
  661.  
  662. ;----------------------------------------------------------------
  663. ;
  664. ;  System function to work with protocols  (75)
  665. ;
  666. ;----------------------------------------------------------------
  667. align 4
  668. sys_protocols:
  669.         cmp     bh, MAX_NET_DEVICES             ; Check if device number exists
  670.         jae     .doesnt_exist
  671.  
  672.         mov     esi, ebx
  673.         and     esi, 0x0000ff00
  674.         shr     esi, 6                          ; now we have the device num * 4 in esi
  675.         cmp     [esi + NET_DRV_LIST], 0         ; check if driver is running
  676.         je      .doesnt_exist
  677.  
  678.         push    .return                         ; return address (we will be using jumps instead of calls)
  679.  
  680.         mov     eax, ebx                        ; set ax to protocol number
  681.         shr     eax, 16                         ;
  682.  
  683.         cmp     ax, IP_PROTO_IP
  684.         je      IPv4_api
  685.  
  686.         cmp     ax, IP_PROTO_ICMP
  687.         je      ICMP_api
  688.  
  689.         cmp     ax, IP_PROTO_UDP
  690.         je      UDP_api
  691.  
  692.         cmp     ax, IP_PROTO_TCP
  693.         je      TCP_api
  694.  
  695.         cmp     ax, ETHER_ARP
  696.         je      ARP_api
  697.  
  698.         cmp     ax, 1337  ;;;;;
  699.         je      ETH_api
  700.  
  701. ;        cmp     ax, API_PPPoE
  702. ;        je      PPPoE_api
  703.  
  704.         add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
  705.  
  706.   .doesnt_exist:
  707.         DEBUGF  1,"sys_protocols: protocol %u doesnt exist on device %u!\n", ax, bh
  708.         mov     eax, -1
  709.  
  710.   .return:
  711.         mov     [esp+28+4], eax                 ; return eax value to the program
  712.         ret
  713.  
  714.  
  715. __DEBUG_LEVEL__ equ __DEBUG_LEVEL_OLD__