Subversion Repositories Kolibri OS

Rev

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