Subversion Repositories Kolibri OS

Rev

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