Subversion Repositories Kolibri OS

Rev

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