Subversion Repositories Kolibri OS

Rev

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