Subversion Repositories Kolibri OS

Rev

Rev 1249 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2009. 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: 1251 $
  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. ;
  61. ; UDP_Handler:
  62. ;
  63. ;  Called by IPv4_handler,
  64. ;  this procedure will inject the udp data diagrams in the application sockets.
  65. ;
  66. ;  IN:  Pointer to buffer in [esp]
  67. ;       size of buffer in [esp+4]
  68. ;       pointer to device struct in ebx
  69. ;       UDP Packet size in ecx
  70. ;       pointer to UDP Packet data in edx
  71. ;  OUT: /
  72. ;
  73. ;-----------------------------------------------------------------
  74. align 4
  75. UDP_handler:
  76.  
  77.         DEBUGF 1,"UDP_Handler\n"
  78.         ; First validate, checksum:
  79.  
  80.         DEBUGF 1,"Real UDP checksum: %x\n", [edx + UDP_Packet.Checksum]:4
  81.         mov    [edx + UDP_Packet.Checksum], 0
  82.  
  83.         pusha
  84.  
  85.         rol     cx, 8
  86.         push    cx
  87.         rol     cx, 8
  88.         push    word IP_PROTO_UDP shl 8
  89.         push    edi
  90.         push    esi
  91.  
  92.         mov     esi, edx
  93.         xor     edx, edx
  94.         call    checksum_1
  95. ; Checksum for pseudoheader
  96.         mov     ecx, 12
  97.         mov     esi, esp
  98.         call    checksum_1
  99.         add     esp, 12
  100.         call    checksum_2
  101.  
  102.         popa
  103.  
  104.  
  105.  
  106.         ; Look for a socket where
  107.         ; IP Packet UDP Destination Port = local Port
  108.         ; IP Packet SA = Remote IP
  109.  
  110.         mov     eax, net_sockets
  111.   .try_more:
  112.         mov     bx , [edx + UDP_Packet.DestinationPort]   ; get the local port from the IP Packet's UDP header
  113.   .next_socket:
  114.         mov     eax, [eax + SOCKET_head.NextPtr]
  115.         or      eax, eax
  116.         jz      .dump
  117.         cmp     [eax + SOCKET_head.Domain], AF_INET4
  118.         jne     .next_socket
  119.         cmp     [eax + SOCKET_head.Type], IP_PROTO_UDP
  120.         jne     .next_socket
  121.         cmp     [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
  122.         jne     .next_socket
  123.  
  124.         DEBUGF 1,"found socket with matching domain, type and localport\n"
  125.  
  126.         ; For dhcp, we must allow any remote server to respond.
  127.         ; I will accept the first incoming response to be the one
  128.         ; I bind to, if the socket is opened with a destination IP address of
  129.         ; 255.255.255.255
  130.         cmp     [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff
  131.         je      .ok1
  132.  
  133.         mov     ebx, [esp]
  134.         mov     ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet   FIXME
  135.         cmp     [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
  136.         jne     .try_more                                             ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
  137.  
  138.  
  139.         DEBUGF 1,"Remote Ip matches\n"
  140.   .ok1:
  141.  
  142.         mov     bx, [edx + UDP_Packet.SourcePort]                     ; Remote port must be 0, or equal to sourceport of packet
  143.  
  144.         cmp     [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], 0
  145.         je      .ok2
  146.  
  147.         cmp     [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
  148.         jne     .dump
  149.  
  150.   .ok2:
  151.  
  152.         DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
  153.         lea     esi, [edx + UDP_Packet.Data]
  154.         movzx   ecx, [edx + UDP_Packet.Length]
  155.         rol     cx , 8
  156.         sub     cx , UDP_Packet.Data
  157.         mov     dx , bx
  158.  
  159.  
  160.         lea     ebx, [eax + SOCKET_head.lock]
  161.         call    wait_mutex
  162.         mov     [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], dx          ; update remote port number
  163.         mov     [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], edi
  164.         inc     [UDP_PACKETS_RX]
  165.  
  166.         pop     edi
  167.         add     esp, 4
  168.  
  169.         sub     esi, edi
  170.         xchg    esi, edi
  171.         jmp     socket_internal_receiver
  172.  
  173.  
  174.   .dump:
  175.         DEBUGF 1,"Dumping UDP packet\n"
  176.         call    kernel_free
  177.         add     esp, 4 ; pop (balance stack)
  178.  
  179.         ret
  180.  
  181.  
  182.  
  183.  
  184. ;-----------------------------------------------------------------
  185. ;
  186. ; UDP_socket_send
  187. ;
  188. ; IN: eax = socket pointer
  189. ;     ecx = number of bytes to send
  190. ;     esi = pointer to data
  191. ;
  192. ;-----------------------------------------------------------------
  193.  
  194. align 4
  195. UDP_socket_send:
  196.  
  197.         mov     edx, dword [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort] ; load local port and remote port at once
  198.         DEBUGF  1,"local port: %x, remote port: %x\n",\
  199.         [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort]:4,\
  200.         [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort]:4
  201.         mov     ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
  202.         mov     eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
  203.  
  204.         DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
  205.  
  206.         mov     di , IP_PROTO_UDP
  207.  
  208.         sub     esp, 8                                          ; reserve some place in stack for later
  209.  
  210. ; Create the pseudoheader in stack,
  211. ; (now that we still have all the variables that are needed.)
  212.         push    dword IP_PROTO_UDP shl 8
  213.  
  214.         add     ecx, UDP_Packet.Data
  215.  
  216. ; TODO: fill in:   dx  = fragment id
  217.  
  218.         push    edx esi
  219.         call    IPv4_create_packet                              ; TODO: figure out a way to choose between IPv4 and IPv6
  220.         cmp     edi, -1
  221.         je      .fail
  222.  
  223.         mov     [esp + 8 + 4], eax                              ; pointer to buffer start
  224.         mov     [esp + 8 + 4 + 4], edx                          ; buffer size
  225.  
  226.         rol     cx, 8
  227.         mov     [edi + UDP_Packet.Length], cx
  228.         mov     [esp + 8 + 2], 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]                   ; fill in both portnumbers
  243.         mov     [edi + UDP_Packet.Checksum], 0                  ; set it to zero, to calculate checksum
  244.  
  245. ; Checksum for UDP header + data
  246.         xor     edx, edx
  247.         mov     esi, edi
  248.         call    checksum_1
  249. ; Checksum for pseudoheader
  250.         pushd   [edi-4] ; destination address
  251.         pushd   [edi-8] ; source address
  252.         mov     ecx, 12
  253.         mov     esi, esp
  254.         call    checksum_1
  255.         add     esp, 12                                         ; remove the pseudoheader from stack
  256. ; Now create the final checksum and store it in UDP header
  257.         call    checksum_2
  258.         mov     [edi + UDP_Packet.Checksum], dx
  259.  
  260.         inc     [UDP_PACKETS_TX]
  261.  
  262.         DEBUGF 1,"Sending UDP Packet to device %x\n", ebx      ;
  263.         jmp     ETH_sender                                     ;
  264.  
  265.   .fail:
  266.         ; todo: queue the packet
  267.         add     esp, 8+12+8
  268.         ret
  269.  
  270.  
  271.  
  272.  
  273. ;---------------------------------------------------------------------------
  274. ;
  275. ; UDP_API
  276. ;
  277. ; This function is called by system function 75
  278. ;
  279. ; IN:  subfunction number in bl
  280. ;      device number in bh
  281. ;      ecx, edx, .. depends on subfunction
  282. ;
  283. ; OUT:
  284. ;
  285. ;---------------------------------------------------------------------------
  286.  
  287. align 4
  288. UDP_API:
  289.  
  290.         movzx   eax, bh
  291.         shl     eax, 2
  292.  
  293.         test    bl, bl
  294.         jz      .packets_tx     ; 0
  295.         dec     bl
  296.         jz      .packets_rx     ; 1
  297.  
  298. .error:
  299.         mov     eax, -1
  300.         ret
  301.  
  302. .packets_tx:
  303.         add     eax, UDP_PACKETS_TX
  304.         mov     eax, [eax]
  305.         ret
  306.  
  307. .packets_rx:
  308.         add     eax, UDP_PACKETS_RX
  309.         mov     eax, [eax]
  310.         ret
  311.