Subversion Repositories Kolibri OS

Rev

Rev 2994 | Blame | Last modification | View Log | Download | RSS feed

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