Subversion Repositories Kolibri OS

Rev

Rev 1485 | 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. ;;  UDP.INC                                                        ;;
  7. ;;                                                                 ;;
  8. ;;  Part of the tcp/ip network stack for KolibriOS                 ;;
  9. ;;                                                                 ;;
  10. ;;    Written by hidnplayr@kolibrios.org                           ;;
  11. ;;                                                                 ;;
  12. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  13. ;;             Version 2, June 1991                                ;;
  14. ;;                                                                 ;;
  15. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  16.  
  17. $Revision: 1514 $
  18.  
  19.  
  20. struct  UDP_Packet
  21.         .SourcePort             dw  ?
  22.         .DestinationPort        dw  ?
  23.         .Length                 dw  ?  ; Length of (UDP Header + Data)
  24.         .Checksum               dw  ?
  25.         .Data:
  26.  
  27. ends
  28.  
  29.  
  30. align 4
  31. uglobal
  32.         UDP_PACKETS_TX          rd  MAX_IP
  33.         UDP_PACKETS_RX          rd  MAX_IP
  34. endg
  35.  
  36.  
  37. ;-----------------------------------------------------------------
  38. ;
  39. ; UDP_init
  40. ;
  41. ;  This function resets all UDP variables
  42. ;
  43. ;  IN:  /
  44. ;  OUT: /
  45. ;
  46. ;-----------------------------------------------------------------
  47. align 4
  48. UDP_init:
  49.  
  50.         xor     eax, eax
  51.         mov     edi, UDP_PACKETS_TX
  52.         mov     ecx, 2*MAX_IP
  53.         rep     stosd
  54.  
  55.         ret
  56.  
  57.  
  58. ;-----------------------------------------------------------------
  59. ;
  60. ; UDP_input:
  61. ;
  62. ;  Called by IPv4_input,
  63. ;  this procedure will inject the udp data diagrams in the application sockets.
  64. ;
  65. ;  IN:  Pointer to buffer in [esp]
  66. ;       size of buffer in [esp+4]
  67. ;       pointer to device struct in ebx
  68. ;       UDP Packet size in ecx
  69. ;       pointer to UDP Packet in edx
  70. ;
  71. ;       esi = ipv4 source address
  72. ;       edi = ipv4 dest   address
  73. ;
  74. ;  OUT: /
  75. ;
  76. ;-----------------------------------------------------------------
  77. align 4
  78. UDP_input:
  79.  
  80.         DEBUGF  1,"UDP_input, size:%u\n", ecx
  81.  
  82. ; First validate, checksum:
  83.         cmp     [edx + UDP_Packet.Checksum], 0
  84.         jz      .no_checksum
  85.  
  86.         xchg    edi, esi        ; save ipv4 source address to edi so we can use it later
  87.  
  88.         push    edx
  89.         push    esi edi
  90.         mov     esi, edx
  91.         call    UDP_checksum    ; this destroys edx, ecx and esi (but not edi...)
  92.         pop     edx
  93.  
  94.         cmp     [edx + UDP_Packet.Checksum], 0
  95.         jnz     .checksum_mismatch
  96.  
  97.   .no_checksum:
  98.         DEBUGF  1,"UDP Checksum is correct\n"
  99.  
  100.         ; Look for a socket where
  101.         ; IP Packet UDP Destination Port = local Port
  102.         ; IP Packet SA = Remote IP
  103.  
  104.         mov     eax, net_sockets
  105.   .try_more:
  106.         mov     si , [edx + UDP_Packet.DestinationPort]   ; get the local port from the IP Packet's UDP header
  107.         rol     si , 8
  108.   .next_socket:
  109.         mov     eax, [eax + SOCKET.NextPtr]
  110.         or      eax, eax
  111.         jz      .dump
  112.         cmp     [eax + SOCKET.Domain], AF_INET4
  113.         jne     .next_socket
  114.         cmp     [eax + SOCKET.Type], IP_PROTO_UDP
  115.         jne     .next_socket
  116.         cmp     [eax + UDP_SOCKET.LocalPort], si
  117.         jne     .next_socket
  118.  
  119.         DEBUGF  1,"using socket: %x\n", eax
  120.  
  121.         ;;; TODO: when packet is processed, check more sockets!
  122.  
  123.         cmp     [eax + IP_SOCKET.RemoteIP], 0xffffffff
  124.         je      @f
  125.         cmp     [eax + IP_SOCKET.RemoteIP], edi         ; edi is the packets source address
  126.         jne     .try_more
  127.        @@:
  128.  
  129.         cmp     [eax + UDP_SOCKET.firstpacket], 0
  130.         jz      .updateport
  131.  
  132.         mov     si, [edx + UDP_Packet.SourcePort]
  133.         rol     si, 8
  134.         cmp     [eax + UDP_SOCKET.RemotePort], si
  135.         jne     .dump
  136.  
  137.         push    ebx
  138.         lea     ebx, [eax + SOCKET.lock]
  139.         call    wait_mutex
  140.         pop     ebx
  141.  
  142.   .updatesock:
  143.         inc     [UDP_PACKETS_RX]
  144.         DEBUGF  1,"Found valid UDP packet for socket %x\n", eax
  145.         lea     esi, [edx + UDP_Packet.Data]
  146.         movzx   ecx, [edx + UDP_Packet.Length]
  147.         rol     cx , 8
  148.         sub     cx , UDP_Packet.Data
  149.  
  150.         jmp     SOCKET_input
  151.  
  152.   .updateport:
  153.         push    ebx
  154.         lea     ebx, [eax + SOCKET.lock]
  155.         call    wait_mutex
  156.         pop     ebx
  157.  
  158.         mov     si, [edx + UDP_Packet.SourcePort]
  159.         rol     si, 8
  160.         DEBUGF  1,"Changing remote port to: %u\n", si
  161.         mov     [eax + UDP_SOCKET.RemotePort], si
  162.         inc     [eax + UDP_SOCKET.firstpacket]
  163.  
  164.         jmp     .updatesock
  165.  
  166.  
  167.   .checksum_mismatch:
  168.  
  169.         DEBUGF  2,"UDP_Handler - checksum mismatch\n"
  170.  
  171. ;        mov     esi, edx
  172. ;       @@:                         ;
  173. ;        lodsb                      ;
  174. ;        DEBUGF  2,"%x ", eax:2     ;
  175. ;        loop    @r                 ;
  176.  
  177.   .dump:
  178.         call    kernel_free
  179.         add     esp, 4 ; pop (balance stack)
  180.         DEBUGF  2,"UDP_Handler - dumping\n"
  181.  
  182.         ret
  183.  
  184.  
  185.  
  186.  
  187. ;-----------------------------------------------------------------
  188. ;
  189. ; UDP_output
  190. ;
  191. ; IN: eax = socket pointer
  192. ;     ecx = number of bytes to send
  193. ;     esi = pointer to data
  194. ;
  195. ;-----------------------------------------------------------------
  196.  
  197. align 4
  198. UDP_output:
  199.  
  200.         DEBUGF  1,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi
  201.  
  202.         mov     dx, [eax + UDP_SOCKET.RemotePort]
  203.         DEBUGF  1,"remote port: %u\n", dx
  204.         rol     dx, 8
  205.         rol     edx, 16
  206.         mov     dx, [eax + UDP_SOCKET.LocalPort]
  207.         DEBUGF  1,"local port: %u\n", dx
  208.         rol     dx, 8
  209.  
  210.  
  211.         mov     ebx, [eax + IP_SOCKET.LocalIP]
  212.         mov     eax, [eax + IP_SOCKET.RemoteIP]
  213.  
  214.         mov     di , IP_PROTO_UDP
  215.         sub     esp, 8                                          ; Data ptr and data size will be placed here
  216.         add     ecx, UDP_Packet.Data
  217.  
  218. ;;; TODO: fragment id
  219.  
  220.         push    edx esi
  221.         call    IPv4_create_packet
  222.         jz      .fail
  223.  
  224.         mov     [esp + 8], eax                                  ; pointer to buffer start
  225.         mov     [esp + 8 + 4], edx                              ; buffer size
  226.  
  227.         rol     cx, 8
  228.         mov     [edi + UDP_Packet.Length], cx
  229.         ror     cx, 8
  230.  
  231.         pop     esi
  232.         push    edi ecx
  233.         sub     ecx, UDP_Packet.Data
  234.         add     edi, UDP_Packet.Data
  235.         shr     ecx, 2
  236.         rep     movsd
  237.         mov     ecx, [esp]
  238.         and     ecx, 3
  239.         rep     movsb
  240.         pop     ecx edi
  241.  
  242.         pop     dword [edi + UDP_Packet.SourcePort]
  243.         mov     [edi + UDP_Packet.Checksum], 0                  ; set it to zero, to calculate checksum
  244.  
  245. ; Checksum
  246.         mov     esi, edi
  247.         pushd   [edi-4] ; destination address                   ; TODO: fix this, IPv4 packet could have options..
  248.         pushd   [edi-8] ; source address
  249.         call    UDP_checksum
  250.  
  251.         inc     [UDP_PACKETS_TX]
  252.  
  253.         DEBUGF  1,"Sending UDP Packet to device %x\n", ebx
  254.  
  255.         jmp     NET_send
  256.  
  257.   .fail:
  258.         add     esp, 8+8
  259.         ret
  260.  
  261.  
  262.  
  263.  
  264. ;-----------------------------------------------------------------
  265. ;
  266. ; UDP_checksum
  267. ;
  268. ; This is the fast procedure to create or check a UDP header
  269. ;  - To create a new checksum, the checksum field must be set to 0 before computation
  270. ;  - To check an existing checksum, leave the checksum as is,
  271. ;     and it will be 0 after this procedure, if it was correct
  272. ;
  273. ;  IN:  push source ip
  274. ;       push dest ip
  275. ;       esi = packet ptr
  276. ;
  277. ;  OUT: checksum is filled in in packet! (but also in dx)
  278. ;
  279. ;-----------------------------------------------------------------
  280.  
  281. align 4
  282. UDP_checksum:
  283.  
  284. ; Pseudoheader
  285.         mov     edx, IP_PROTO_UDP               ; NO shl 8 here ! (it took me ages to figure this one out)
  286.  
  287.         add     dl, [esp+1+4]
  288.         adc     dh, [esp+0+4]
  289.         adc     dl, [esp+3+4]
  290.         adc     dh, [esp+2+4]
  291.  
  292.         adc     dl, [esp+1+8]
  293.         adc     dh, [esp+0+8]
  294.         adc     dl, [esp+3+8]
  295.         adc     dh, [esp+2+8]
  296.  
  297.  
  298.         adc     dl, cl ; byte[esi+UDP_Packet.Length+1]
  299.         adc     dh, ch ; byte[esi+UDP_Packet.Length+0]
  300.  
  301. ; Done with pseudoheader, now do real header
  302.         adc     dl, byte[esi+UDP_Packet.SourcePort+1]
  303.         adc     dh, byte[esi+UDP_Packet.SourcePort+0]
  304.  
  305.         adc     dl, byte[esi+UDP_Packet.DestinationPort+1]
  306.         adc     dh, byte[esi+UDP_Packet.DestinationPort+0]
  307.  
  308.         adc     dl, byte[esi+UDP_Packet.Length+1]
  309.         adc     dh, byte[esi+UDP_Packet.Length+0]
  310.  
  311.         adc     edx, 0
  312.  
  313. ; Done with header, now do data
  314.         push    esi
  315.         movzx   ecx, [esi+UDP_Packet.Length]
  316.         rol     cx , 8
  317.         sub     cx , UDP_Packet.Data
  318.         add     esi, UDP_Packet.Data
  319.  
  320.         call    checksum_1
  321.         call    checksum_2
  322.         pop     esi
  323.  
  324.         neg     [esi+UDP_Packet.Checksum]           ; zero will stay zero so we just get the checksum
  325.         add     [esi+UDP_Packet.Checksum], dx       ;  , else we will get (new checksum - old checksum) in the end, wich should be 0 :)
  326.  
  327.         ret     8
  328.  
  329.  
  330.  
  331.  
  332. ;---------------------------------------------------------------------------
  333. ;
  334. ; UDP_API
  335. ;
  336. ; This function is called by system function 75
  337. ;
  338. ; IN:  subfunction number in bl
  339. ;      device number in bh
  340. ;      ecx, edx, .. depends on subfunction
  341. ;
  342. ; OUT:
  343. ;
  344. ;---------------------------------------------------------------------------
  345.  
  346. align 4
  347. UDP_API:
  348.  
  349.         movzx   eax, bh
  350.         shl     eax, 2
  351.  
  352.         test    bl, bl
  353.         jz      .packets_tx     ; 0
  354.         dec     bl
  355.         jz      .packets_rx     ; 1
  356.  
  357. .error:
  358.         mov     eax, -1
  359.         ret
  360.  
  361. .packets_tx:
  362.         add     eax, UDP_PACKETS_TX
  363.         mov     eax, [eax]
  364.         ret
  365.  
  366. .packets_rx:
  367.         add     eax, UDP_PACKETS_RX
  368.         mov     eax, [eax]
  369.         ret
  370.