Subversion Repositories Kolibri OS

Rev

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