Subversion Repositories Kolibri OS

Rev

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