Subversion Repositories Kolibri OS

Rev

Rev 1716 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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