Subversion Repositories Kolibri OS

Rev

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