Subversion Repositories Kolibri OS

Rev

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