Subversion Repositories Kolibri OS

Rev

Rev 1161 | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2008. 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: 983 $
  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.  
  48. align 4
  49. UDP_init:
  50.  
  51.         xor     eax, eax
  52.         mov     edi, UDP_PACKETS_TX
  53.         mov     ecx, 2*MAX_IP
  54.         rep     stosd
  55.  
  56.         ret
  57.  
  58.  
  59.  
  60. ;-----------------------------------------------------------------
  61. ;
  62. ; UDP_Handler:
  63. ;
  64. ;  Called by IPv4_handler,
  65. ;  this procedure will inject the udp data diagrams in the application sockets.
  66. ;
  67. ;  IN:  Pointer to buffer in [esp]
  68. ;       size of buffer in [esp+4]
  69. ;       pointer to device struct in ebx
  70. ;       UDP Packet size in ecx
  71. ;       pointer to UDP Packet data in edx
  72. ;  OUT: /
  73. ;
  74. ;-----------------------------------------------------------------
  75.  
  76. UDP_Handler:
  77.  
  78.         DEBUGF 1,"UDP_Handler\n"
  79.         ; TODO: First validate the header & checksum. Discard buffer if error
  80.  
  81.         ; Look for a socket where
  82.         ; IP Packet UDP Destination Port = local Port
  83.         ; IP Packet SA = Remote IP
  84.  
  85.         mov     esi, net_sockets
  86.   .try_more:
  87.         mov     ax , [edx + UDP_Packet.DestinationPort]   ; get the local port from the IP Packet's UDP header
  88.         rol     ax , 8
  89.   .next_socket:
  90.         mov     esi, [esi + SOCKET.NextPtr]
  91.         or      esi, esi
  92.         jz      .dump
  93.         cmp     [esi + SOCKET.Type], IP_PROTO_UDP
  94.         jne     .next_socket
  95.         cmp     [esi + SOCKET.LocalPort], ax
  96.         jne     .next_socket
  97.  
  98.         ; For dhcp, we must allow any remote server to respond.
  99.         ; I will accept the first incoming response to be the one
  100.         ; I bind to, if the socket is opened with a destination IP address of
  101.         ; 255.255.255.255
  102.         cmp     [esi + SOCKET.RemoteIP], 0xffffffff
  103.         je      @f
  104.  
  105.         mov     eax, [esp]
  106.         mov     eax, [eax + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet
  107.         cmp     [esi + SOCKET.RemoteIP], eax
  108.         jne     .try_more                                             ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
  109.  
  110.     @@:
  111.         DEBUGF 1,"Found valid UDP packet for socket %x\n", esi
  112.  
  113.  
  114. ;        sub     ecx, UDP_Packet.Data                    ; get # of bytes in ecx
  115. ;        mov     eax, ecx
  116.  
  117.         movzx   ecx, [edx + UDP_Packet.Length]
  118.         xchg    cl , ch
  119.  
  120. ;        cmp     ecx, eax                                ; If UDP packet size is bigger then IP packet told us,
  121. ;        jg      .error                                  ; Something must went wrong!
  122.  
  123.         lea     ebx, [esi + SOCKET.lock]
  124.         call    wait_mutex
  125.  
  126.         ; OK - we have a valid UDP Packet for this socket.
  127.         ; First, update the sockets remote port number with the incoming msg
  128.         ; - it will have changed
  129.         ; from the original ( 69 normally ) to allow further connects
  130.         mov     ax, [edx + UDP_Packet.SourcePort]          ; get the UDP source port
  131.         xchg    al, ah
  132.         mov     [esi + SOCKET.RemotePort], ax
  133.  
  134.         ; Now, copy data to socket. We have socket address as [eax + sockets].
  135.         ; We have IP Packet in edx
  136.  
  137.         add     edx, UDP_Packet.Data
  138.         mov     eax, [esi + SOCKET.rxDataCount]         ; get # of bytes already in buffer
  139.         DEBUGF 1,"bytes in socket: %u ", eax
  140.         lea     edi, [ecx + eax]                        ; check for buffer overflow
  141.         cmp     edi, SOCKETBUFFSIZE - SOCKETHEADERSIZE  ;
  142.         jg      .dump                                   ;
  143.         add     [esi + SOCKET.rxDataCount], ecx         ; increment the count of bytes in buffer
  144.         DEBUGF 1,"adding %u bytes\n", ecx
  145.  
  146.         ; ecx has count, edx points to data
  147.  
  148.         lea     edi, [esi + eax + SOCKETHEADERSIZE]
  149.         push    esi
  150.         push    ecx
  151.         mov     esi, edx
  152.         shr     ecx, 2
  153.         rep     movsd          ; copy the data across
  154.         pop     ecx
  155.         and     ecx, 3
  156.         rep     movsb
  157.         pop     esi
  158.  
  159.         DEBUGF 1,"UDP socket updated\n"
  160.  
  161.         mov     [esi + SOCKET.lock], 0
  162.  
  163.         ; flag an event to the application
  164.         mov     eax, [esi + SOCKET.PID]                 ; get socket owner PID
  165.         mov     ecx, 1
  166.         mov     esi, TASK_DATA + TASKDATA.pid
  167.  
  168.        .next_pid:
  169.         cmp     [esi], eax
  170.         je      .found_pid
  171.         inc     ecx
  172.         add     esi, 0x20
  173.         cmp     ecx, [TASK_COUNT]
  174.         jbe     .next_pid
  175.  
  176.         jmp     .dump
  177.  
  178.        .found_pid:
  179.         shl     ecx, 8
  180.         or      [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
  181.  
  182.         mov     [check_idle_semaphore], 200
  183.  
  184.        .dump:
  185.         DEBUGF 1,"UDP_handler - dumping\n"
  186.  
  187.         call    kernel_free
  188.         add     esp, 4 ; pop (balance stack)
  189.  
  190.         ret
  191.  
  192.  
  193.  
  194.  
  195. ;-----------------------------------------------------------------
  196. ;
  197. ; Note: UDP works only on top of IP protocol :)
  198. ;
  199. ; IN: eax = dest ip
  200. ;     ebx = source ip
  201. ;     ecx = data length
  202. ;     edx = remote port shl 16 + local port
  203. ;     esi = data offset
  204. ;
  205. ;-----------------------------------------------------------------
  206.  
  207. UDP_create_Packet:
  208.  
  209.         DEBUGF 1,"Create UDP Packet\n"
  210.  
  211.         push    edx esi
  212.  
  213.         add     ecx, UDP_Packet.Data
  214.         mov     di , IP_PROTO_UDP
  215.  
  216. ;       dx  = fragment id
  217.  
  218.         call    IPv4_create_Packet                              ; TODO: figure out a way to choose between IPv4 and IPv6
  219.         cmp     edi, -1
  220.         je      .exit
  221.  
  222.         mov     byte[edi + UDP_Packet.Length], ch
  223.         mov     byte[edi + UDP_Packet.Length+1], cl
  224.         sub     ecx , UDP_Packet.Data
  225.  
  226.         pop     esi
  227.         push    edi
  228.         add     edi, UDP_Packet.Data
  229.         push    cx
  230.         shr     ecx, 2
  231.         rep     movsd
  232.         pop     cx
  233.         and     cx , 3
  234.         rep     movsb
  235.         pop     edi
  236.  
  237.         pop     ecx
  238.         bswap   ecx                                             ; convert little endian - big endian
  239.         rol     ecx, 16                                         ;
  240.         mov     dword [edi + UDP_Packet.SourcePort], ecx        ; notice: we write both port's at once
  241.  
  242.  
  243.         mov     [edi + UDP_Packet.Checksum], 0
  244.  
  245.         ; TODO: calculate checksum using Pseudo-header  (However, using a 0 as checksum shouldnt generate any errors :)
  246.  
  247.         push    ebx eax                      ; TODO: make this work on other protocols besides ethernet
  248.         mov     ebx,edx                      ;
  249.         DEBUGF 1,"Sending UDP Packet to device %x\n", ebx      ;
  250.         jmp     ETH_Sender                   ;
  251.  
  252.   .exit:
  253.         ret
  254.  
  255.  
  256.  
  257. ;---------------------------------------------------------------------------
  258. ;
  259. ; UDP_API
  260. ;
  261. ; This function is called by system function 75
  262. ;
  263. ; IN:  subfunction number in bl
  264. ;      device number in bh
  265. ;      ecx, edx, .. depends on subfunction
  266. ;
  267. ; OUT:
  268. ;
  269. ;---------------------------------------------------------------------------
  270.  
  271. align 4
  272. UDP_API:
  273.  
  274.         movzx   eax, bh
  275.         shl     eax, 2
  276.  
  277.         test    bl, bl
  278.         jz      .packets_tx     ; 0
  279.         dec     bl
  280.         jz      .packets_rx     ; 1
  281.  
  282. .error:
  283.         mov     eax, -1
  284.         ret
  285.  
  286. .packets_tx:
  287.         add     eax, UDP_PACKETS_TX
  288.         mov     eax, [eax]
  289.         ret
  290.  
  291. .packets_rx:
  292.         add     eax, UDP_PACKETS_RX
  293.         mov     eax, [eax]
  294.         ret
  295.