Subversion Repositories Kolibri OS

Rev

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