Subversion Repositories Kolibri OS

Rev

Rev 2366 | 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: 2382 $
  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. 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. wait_mutex:                     ; stub
  155.         inc     dword [ebx]
  156.  
  157.         ret
  158.  
  159.  
  160. include "queue.inc"
  161.  
  162. include "ethernet.inc"
  163.  
  164. ;include "slip.inc"
  165. ;include "pppoe.inc"
  166.  
  167. include "ARP.inc"
  168. include "IPv4.inc"
  169.  
  170. include "icmp.inc"
  171. include "udp.inc"
  172. include "tcp.inc"
  173.  
  174. include "socket.inc"
  175.  
  176.  
  177.  
  178. align 4
  179. uglobal
  180.  
  181.         NET_RUNNING     dd  ?
  182.         NET_DEFAULT     dd  ?
  183.         NET_DRV_LIST    rd  MAX_NET_DEVICES
  184.  
  185. endg
  186.  
  187.  
  188. ;-----------------------------------------------------------------
  189. ;
  190. ; stack_init
  191. ;
  192. ;  This function calls all network init procedures
  193. ;
  194. ;  IN:  /
  195. ;  OUT: /
  196. ;
  197. ;-----------------------------------------------------------------
  198. align 4
  199. stack_init:
  200.  
  201. ; Init the network drivers list
  202.         xor     eax, eax
  203.         mov     edi, NET_RUNNING
  204.         mov     ecx, (MAX_NET_DEVICES + 2)
  205.         rep     stosd
  206.  
  207. ;        SLIP_init
  208. ;        PPPOE_init
  209.  
  210.         IPv4_init
  211.         ICMP_init
  212.  
  213.         ARP_init
  214.         UDP_init
  215.         TCP_init
  216.  
  217.         SOCKET_init
  218.  
  219.         mov     [net_tmr_count], 0
  220.  
  221.         ret
  222.  
  223.  
  224. ;-----------------------------------------------------------------
  225. ;
  226. ; stack_handler
  227. ;
  228. ;  This function is called in kernel loop
  229. ;
  230. ;  IN:  /
  231. ;  OUT: /
  232. ;
  233. ;-----------------------------------------------------------------
  234. align 4
  235. stack_handler:
  236.  
  237.         cmp     [NET_RUNNING], 0
  238.         je      .exit
  239.  
  240.         ; Test for 10ms tick
  241.         mov     eax, [timer_ticks]
  242.         cmp     eax, [net_10ms]
  243.         je      .exit
  244.         mov     [net_10ms], eax
  245.  
  246.         test    [net_10ms], 0x0f        ; 160ms
  247.         jnz     .exit
  248.  
  249.         TCP_timer_160ms
  250.  
  251.         test    [net_10ms], 0x3f        ; 640ms
  252.         jnz     .exit
  253.  
  254.         TCP_timer_640ms
  255.         ARP_decrease_entry_ttls
  256.         IPv4_decrease_fragment_ttls
  257.  
  258.   .exit:
  259.         ret
  260.  
  261.  
  262.  
  263. ;-----------------------------------------------------------------
  264. ;
  265. ; NET_add_device:
  266. ;
  267. ;  This function is called by the network drivers,
  268. ;  to register each running NIC to the kernel
  269. ;
  270. ;  IN:  Pointer to device structure in ebx
  271. ;  OUT: Device num in eax, -1 on error
  272. ;
  273. ;-----------------------------------------------------------------
  274. align 4
  275. NET_add_device:
  276.  
  277.         DEBUGF  1,"NET_Add_Device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
  278.  
  279.         mov     eax, [NET_RUNNING]
  280.         cmp     eax, MAX_NET_DEVICES
  281.         jae     .error
  282.  
  283. ;----------------------------------
  284. ; Check if device is already listed
  285.         mov     eax, ebx
  286.         mov     ecx, MAX_NET_DEVICES    ; We need to check whole list because a device may be removed without re-organizing list
  287.         mov     edi, NET_DRV_LIST
  288.  
  289.         repne   scasd                   ; See if device is already in the list
  290.         jz      .error
  291.  
  292. ;----------------------------
  293. ; Find empty slot in the list
  294.         xor     eax, eax
  295.         mov     ecx, MAX_NET_DEVICES
  296.         mov     edi, NET_DRV_LIST
  297.  
  298.         repne   scasd
  299.         jnz     .error
  300.  
  301.         sub     edi, 4
  302.  
  303. ;-----------------------------
  304. ; Add device to the found slot
  305.         mov     [edi], ebx              ; add device to list
  306.  
  307.         mov     eax, edi                ; Calculate device number in eax
  308.         sub     eax, NET_DRV_LIST
  309.         shr     eax, 2
  310.  
  311.         inc     [NET_RUNNING]           ; Indicate that one more network device is up and running
  312.  
  313.         cmp     eax, 1                  ; If it's the first network device, try to set it as default
  314.         jne     @f
  315.         push    eax
  316.         call    NET_set_default
  317.         pop     eax
  318.        @@:
  319.  
  320.         DEBUGF  1,"Device number: %u\n", eax
  321.         ret
  322.  
  323.   .error:
  324.         or      eax, -1
  325.         DEBUGF  2,"Adding network device failed\n"
  326.         ret
  327.  
  328.  
  329.  
  330. ;-----------------------------------------------------------------
  331. ;
  332. ; NET_set_default
  333. ;
  334. ;  API to set the default interface
  335. ;
  336. ;  IN:  Device num in eax
  337. ;  OUT: Device num in eax, -1 on error
  338. ;
  339. ;-----------------------------------------------------------------
  340. align 4
  341. NET_set_default:
  342.  
  343.         DEBUGF  1,"NET_set_default %x\n", eax
  344.  
  345.         cmp     eax, MAX_NET_DEVICES
  346.         jae     .error
  347.  
  348.         cmp     [NET_DRV_LIST+eax*4], 0
  349.         je      .error
  350.  
  351.         mov     [NET_DEFAULT], eax
  352.  
  353.         DEBUGF  1,"Device number %u is now default!\n", eax
  354.         ret
  355.  
  356.   .error:
  357.         or      eax, -1
  358.         DEBUGF  2,"Setting default network device failed\n"
  359.         ret
  360.  
  361.  
  362. ;-----------------------------------------------------------------
  363. ;
  364. ; NET_Remove_Device:
  365. ;
  366. ;  This function is called by etwork drivers,
  367. ;  to unregister network devices from the kernel
  368. ;                                                                                                                                d
  369. ;  IN:  Pointer to device structure in ebx
  370. ;  OUT: eax: -1 on error
  371. ;
  372. ;-----------------------------------------------------------------
  373. align 4
  374. NET_remove_device:
  375.  
  376.         cmp     [NET_RUNNING], 0
  377.         je      .error
  378.  
  379.         cmp     [NET_DRV_LIST], ebx
  380.         jne     @f
  381.         mov     [NET_DRV_LIST], 0
  382.         cmp     [NET_RUNNING], 1
  383.         je      @f
  384.         ; there are still active devices, find one and make it default
  385.         xor     eax, eax
  386.         mov     ecx, MAX_NET_DEVICES
  387.         mov     edi, NET_DRV_LIST
  388.         repe    scasd
  389.         je      @f
  390.         shr     edi, 2
  391.         dec     edi
  392.         mov     [NET_DEFAULT], edi
  393.        @@:
  394.  
  395. ;----------------------------
  396. ; Find the driver in the list
  397.  
  398.         mov     eax, ebx
  399.         mov     ecx, MAX_NET_DEVICES
  400.         mov     edi, NET_DRV_LIST+4
  401.  
  402.         repne   scasd
  403.         jnz     .error
  404.  
  405. ;------------------------
  406. ; Remove it from the list
  407.  
  408.         xor     eax, eax
  409.         mov     dword [edi-4], eax
  410.  
  411.         dec     [NET_RUNNING]
  412.         ret
  413.  
  414.   .error:
  415.         or      eax, -1
  416.         ret
  417.  
  418.  
  419.  
  420. ;-----------------------------------------------------------------
  421. ;
  422. ; NET_ptr_to_num
  423. ;
  424. ; IN:  ebx = ptr to device struct
  425. ; OUT: edi = -1 on error, device number otherwise
  426. ;
  427. ;-----------------------------------------------------------------
  428. align 4
  429. NET_ptr_to_num:
  430.         push    ecx
  431.  
  432.         mov     ecx, MAX_NET_DEVICES
  433.         mov     edi, NET_DRV_LIST
  434.  
  435.   .loop:
  436.         cmp     ebx, [edi]
  437.         jz      .found
  438.         add     edi, 4
  439.         dec     ecx
  440.         jnz     .loop
  441.  
  442.         ; repnz  scasd could work too if eax is used instead of ebx!
  443.  
  444.         or      edi, -1
  445.  
  446.         pop     ecx
  447.         ret
  448.  
  449.   .found:
  450.         sub     edi, NET_DRV_LIST
  451.         shr     edi, 2
  452.  
  453.         pop     ecx
  454.         ret
  455.  
  456. ;-----------------------------------------------------------------
  457. ;
  458. ; checksum_1
  459. ;
  460. ;  This is the first of two functions needed to calculate a checksum.
  461. ;
  462. ;  IN:  edx = start offset for semi-checksum
  463. ;       esi = pointer to data
  464. ;       ecx = data size
  465. ;  OUT: edx = semi-checksum
  466. ;
  467. ;
  468. ; Code was optimized by diamond
  469. ;
  470. ;-----------------------------------------------------------------
  471. align 4
  472. checksum_1:
  473.  
  474.         shr     ecx, 1
  475.         pushf
  476.         jz      .no_2
  477.  
  478.         shr     ecx, 1
  479.         pushf
  480.         jz      .no_4
  481.  
  482.         shr     ecx, 1
  483.         pushf
  484.         jz      .no_8
  485.  
  486.   .loop:
  487.         add     dl, [esi+1]
  488.         adc     dh, [esi+0]
  489.  
  490.         adc     dl, [esi+3]
  491.         adc     dh, [esi+2]
  492.  
  493.         adc     dl, [esi+5]
  494.         adc     dh, [esi+4]
  495.  
  496.         adc     dl, [esi+7]
  497.         adc     dh, [esi+6]
  498.  
  499.         adc     edx, 0
  500.         add     esi, 8
  501.  
  502.         dec     ecx
  503.         jnz     .loop
  504.  
  505.         adc     edx, 0
  506.  
  507.   .no_8:
  508.         popf
  509.         jnc     .no_4
  510.  
  511.         add     dl, [esi+1]
  512.         adc     dh, [esi+0]
  513.  
  514.         adc     dl, [esi+3]
  515.         adc     dh, [esi+2]
  516.  
  517.         adc     edx, 0
  518.         add     esi, 4
  519.  
  520.   .no_4:
  521.         popf
  522.         jnc     .no_2
  523.  
  524.         add     dl, [esi+1]
  525.         adc     dh, [esi+0]
  526.  
  527.         adc     edx, 0
  528.         inc     esi
  529.         inc     esi
  530.  
  531.   .no_2:
  532.         popf
  533.         jnc     .end
  534.  
  535.         add     dh, [esi+0]
  536.         adc     edx, 0
  537.   .end:
  538.         ret
  539.  
  540. ;-----------------------------------------------------------------
  541. ;
  542. ; checksum_2
  543. ;
  544. ;  This function calculates the final ip/tcp/udp checksum for you
  545. ;
  546. ;  IN:  edx = semi-checksum
  547. ;  OUT: dx = checksum (in INET byte order)
  548. ;
  549. ;-----------------------------------------------------------------
  550. align 4
  551. checksum_2:
  552.  
  553.         mov     ecx, edx
  554.         shr     ecx, 16
  555.         and     edx, 0xffff
  556.         add     edx, ecx
  557.  
  558.         mov     ecx, edx
  559.         shr     ecx, 16
  560.         add     dx, cx
  561.         test    dx, dx          ; it seems that ZF is not set when CF is set :(
  562.         not     dx
  563.         jnz     .not_zero
  564.         dec     dx
  565.   .not_zero:
  566.         xchg    dl, dh
  567.  
  568.         DEBUGF 1,"Checksum: %x\n", dx
  569.  
  570.         ret
  571.  
  572.  
  573.  
  574. ;----------------------------------------------------------------
  575. ;
  576. ;  System function to work with network devices (73)
  577. ;
  578. ;----------------------------------------------------------------
  579. align 4
  580. sys_network:                    ; FIXME: make default device easily accessible
  581.  
  582.         cmp     ebx, -1
  583.         jne     @f
  584.  
  585.         mov     eax, [NET_RUNNING]
  586.         jmp     .return
  587.  
  588.    @@:
  589.         cmp     bh, MAX_NET_DEVICES             ; Check if device number exists
  590.         jae     .doesnt_exist
  591.  
  592.         mov     esi, ebx
  593.         and     esi, 0x0000ff00
  594.         shr     esi, 6
  595.  
  596.         cmp     dword [esi + NET_DRV_LIST], 0   ; check if driver is running
  597.         je      .doesnt_exist
  598.  
  599.  
  600.  
  601.         test    bl, bl                  ; 0 = Get device type (ethernet/token ring/...)
  602.         jnz     @f
  603.  
  604.         xor     eax, eax
  605.         jmp     .return
  606.  
  607.  
  608.   @@:
  609.         dec     bl                      ; 1 = Get device name
  610.         jnz     @f
  611.  
  612.         mov     esi, [esi + NET_DRV_LIST]
  613.         mov     esi, [esi + NET_DEVICE.name]
  614.         mov     edi, ecx
  615.  
  616.         mov     ecx, 64 ; max length
  617.         repnz   movsb
  618.  
  619.         xor     eax, eax
  620.         jmp     .return
  621.  
  622.   @@:
  623.  
  624.         dec     bl                      ; 2 = Reset the device
  625.         jnz     @f
  626.  
  627.         mov     esi, [esi + NET_DRV_LIST]
  628.         call    [esi + NET_DEVICE.reset]
  629.         jmp     .return
  630.  
  631.   @@:
  632.  
  633.         dec     bl                      ; 3 = Stop driver for this device
  634.         jnz     @f
  635.  
  636.         mov     esi, [esi + NET_DRV_LIST]
  637.         call    [esi + NET_DEVICE.unload]
  638.         jmp     .return
  639.  
  640.   @@:
  641.         dec     bl                      ; 4 = Get driver pointer
  642.         jnz     @f
  643.  
  644.         ; ..;
  645.         xor     eax, eax
  646.         jmp     .return
  647.  
  648.  
  649.   @@:
  650.         dec     bl                      ; 5 = Get driver name
  651.         jnz     @f
  652.  
  653.         ; ..;
  654.         xor     eax, eax
  655.         jmp     .return
  656.  
  657.  
  658.   @@:
  659.         dec     bl                      ; 6 = Set default device
  660.         jnz     @f
  661.  
  662.         mov     eax, esi
  663.         call    NET_set_default
  664.         jmp     .return
  665.  
  666.  
  667.   @@:
  668.  
  669.   .doesnt_exist:
  670.         DEBUGF  1,"sys_network: invalid device/function specified!\n"
  671.         mov     eax, -1
  672.  
  673.   .return:
  674.         mov     [esp+28+4], eax
  675.         ret
  676.  
  677.  
  678. ;----------------------------------------------------------------
  679. ;
  680. ;  System function to work with protocols  (75)
  681. ;
  682. ;----------------------------------------------------------------
  683. align 4
  684. sys_protocols:
  685.         cmp     bh, MAX_NET_DEVICES             ; Check if device number exists
  686.         jae     .doesnt_exist
  687.  
  688.         mov     esi, ebx
  689.         and     esi, 0x0000ff00
  690.         shr     esi, 6                          ; now we have the device num * 4 in esi
  691.         cmp     [esi + NET_DRV_LIST], 0         ; check if driver is running
  692.         je      .doesnt_exist
  693.  
  694.         push    .return                         ; return address (we will be using jumps instead of calls)
  695.  
  696.         mov     eax, ebx                        ; set ax to protocol number
  697.         shr     eax, 16                         ;
  698.  
  699.         cmp     ax , IP_PROTO_IP
  700.         je      IPv4_API
  701.  
  702.         cmp     ax , IP_PROTO_ICMP
  703.         je      ICMP_API
  704.  
  705.         cmp     ax , IP_PROTO_UDP
  706.         je      UDP_API
  707.  
  708.         cmp     ax , IP_PROTO_TCP
  709.         je      TCP_API
  710.  
  711.         cmp     ax , ETHER_ARP
  712.         je      ARP_API
  713.  
  714.         cmp     ax , 1337  ;;;;;
  715.         je      ETH_API
  716.  
  717.         add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
  718.  
  719.   .doesnt_exist:
  720.         DEBUGF  1,"sys_protocols: protocol %u doesnt exist on device %u!\n", ax, bh
  721.         mov     eax, -1
  722.  
  723.   .return:
  724.         mov     [esp+28+4], eax
  725.         ret
  726.  
  727.  
  728. __DEBUG_LEVEL__ equ __DEBUG_LEVEL_OLD__