Subversion Repositories Kolibri OS

Rev

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