Subversion Repositories Kolibri OS

Rev

Rev 1173 | 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: 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. ;        sub     ecx, UDP_Packet.Data                    ; get # of bytes in ecx
  114. ;        mov     eax, ecx
  115.  
  116.         movzx   ecx, [edx + UDP_Packet.Length]
  117.         xchg    cl , ch
  118.  
  119. ;        cmp     ecx, eax                                ; If UDP packet size is bigger then IP packet told us,
  120. ;        jg      .error                                  ; Something must went wrong!
  121.  
  122.         lea     ebx, [esi + SOCKET.lock]
  123.         call    wait_mutex
  124.  
  125.         ; OK - we have a valid UDP Packet for this socket.
  126.         ; First, update the sockets remote port number with the incoming msg
  127.         ; - it will have changed
  128.         ; from the original ( 69 normally ) to allow further connects
  129.         mov     ax, [edx + UDP_Packet.SourcePort]          ; get the UDP source port
  130.         xchg    al, ah
  131.         mov     [esi + SOCKET.RemotePort], ax
  132.  
  133.         ; Now, copy data to socket. We have socket address as [eax + sockets].
  134.         ; We have IP Packet in edx
  135.  
  136.         add     edx, UDP_Packet.Data
  137.         mov     eax, [esi + SOCKET.rxDataCount]         ; get # of bytes already in buffer
  138.         DEBUGF 1,"bytes in socket: %u ", eax
  139.         lea     edi, [ecx + eax]                        ; check for buffer overflow
  140.         cmp     edi, SOCKETBUFFSIZE - SOCKETHEADERSIZE  ;
  141.         jg      .dump                                   ;
  142.         add     [esi + SOCKET.rxDataCount], ecx         ; increment the count of bytes in buffer
  143.         DEBUGF 1,"adding %u bytes\n", ecx
  144.  
  145.         ; ecx has count, edx points to data
  146.  
  147.         lea     edi, [esi + eax + SOCKETHEADERSIZE]
  148.         push    esi
  149.         push    ecx
  150.         mov     esi, edx
  151.         shr     ecx, 2
  152.         rep     movsd          ; copy the data across
  153.         pop     ecx
  154.         and     ecx, 3
  155.         rep     movsb
  156.         pop     esi
  157.  
  158.         DEBUGF 1,"UDP socket updated\n"
  159.  
  160.         mov     [esi + SOCKET.lock], 0
  161.  
  162.         ; flag an event to the application
  163.         mov     eax, [esi + SOCKET.PID]                 ; get socket owner PID
  164.         mov     ecx, 1
  165.         mov     esi, TASK_DATA + TASKDATA.pid
  166.  
  167.        .next_pid:
  168.         cmp     [esi], eax
  169.         je      .found_pid
  170.         inc     ecx
  171.         add     esi, 0x20
  172.         cmp     ecx, [TASK_COUNT]
  173.         jbe     .next_pid
  174.  
  175.         jmp     .dump
  176.  
  177.        .found_pid:
  178.         shl     ecx, 8
  179.         or      [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
  180.  
  181.         mov     [check_idle_semaphore], 200
  182.  
  183.        .dump:
  184.         DEBUGF 1,"UDP_handler - dumping\n"
  185.  
  186.         call    kernel_free
  187.         add     esp, 4 ; pop (balance stack)
  188.  
  189.         ret
  190.  
  191.  
  192.  
  193.  
  194. ;-----------------------------------------------------------------
  195. ;
  196. ; Note: UDP works only on top of IP protocol :)
  197. ;
  198. ; IN: eax = dest ip
  199. ;     ebx = source ip
  200. ;     ecx = data length
  201. ;     edx = remote port shl 16 + local port (both in INET order)
  202. ;     esi = data offset
  203. ;
  204. ;-----------------------------------------------------------------
  205.  
  206. UDP_create_packet:
  207.  
  208.         DEBUGF 1,"Create UDP Packet\n"
  209.  
  210.         push    edx esi
  211.  
  212.         add     ecx, UDP_Packet.Data
  213.         mov     di , IP_PROTO_UDP
  214.  
  215. ;       dx  = fragment id
  216.  
  217.         call    IPv4_create_packet                              ; TODO: figure out a way to choose between IPv4 and IPv6
  218.         cmp     edi, -1
  219.         je      .exit
  220.  
  221.         sub     ecx , UDP_Packet.Data
  222.         mov     byte[edi + UDP_Packet.Length], ch
  223.         mov     byte[edi + UDP_Packet.Length+1], cl
  224.  
  225.         pop     esi
  226.         push    edi
  227.         add     edi, UDP_Packet.Data
  228.         push    cx
  229.         shr     ecx, 2
  230.         rep     movsd
  231.         pop     cx
  232.         and     cx , 3
  233.         rep     movsb
  234.         pop     edi
  235.  
  236.         pop     ecx
  237. ;        bswap   ecx                                             ; convert little endian - big endian
  238. ;        rol     ecx, 16                                         ;
  239.         mov     dword [edi + UDP_Packet.SourcePort], ecx        ; notice: we write both port's at once
  240.  
  241.  
  242.         mov     [edi + UDP_Packet.Checksum], 0
  243.  
  244.         ; TODO: calculate checksum using Pseudo-header  (However, using a 0 as checksum shouldnt generate any errors :)
  245.  
  246.         push    ebx eax                      ; TODO: make this work on other protocols besides ethernet
  247.         mov     ebx,edx                      ;
  248.         DEBUGF 1,"Sending UDP Packet to device %x\n", ebx      ;
  249.         jmp     ETH_Sender                   ;
  250.  
  251.   .exit:
  252.         ret
  253.  
  254.  
  255.  
  256. ;---------------------------------------------------------------------------
  257. ;
  258. ; UDP_API
  259. ;
  260. ; This function is called by system function 75
  261. ;
  262. ; IN:  subfunction number in bl
  263. ;      device number in bh
  264. ;      ecx, edx, .. depends on subfunction
  265. ;
  266. ; OUT:
  267. ;
  268. ;---------------------------------------------------------------------------
  269.  
  270. align 4
  271. UDP_API:
  272.  
  273.         movzx   eax, bh
  274.         shl     eax, 2
  275.  
  276.         test    bl, bl
  277.         jz      .packets_tx     ; 0
  278.         dec     bl
  279.         jz      .packets_rx     ; 1
  280.  
  281. .error:
  282.         mov     eax, -1
  283.         ret
  284.  
  285. .packets_tx:
  286.         add     eax, UDP_PACKETS_TX
  287.         mov     eax, [eax]
  288.         ret
  289.  
  290. .packets_rx:
  291.         add     eax, UDP_PACKETS_RX
  292.         mov     eax, [eax]
  293.         ret
  294.