Rev 914 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
431 | serge | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
2971 | Serge | 3 | ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
431 | serge | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;; ;; |
||
7 | ;; UDP.INC ;; |
||
8 | ;; ;; |
||
9 | ;; UDP Processes for Menuet OS TCP/IP stack ;; |
||
10 | ;; ;; |
||
11 | ;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
||
12 | ;; ;; |
||
13 | ;; See file COPYING for details ;; |
||
14 | ;; ;; |
||
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
379 | serge | 16 | |
593 | mikedld | 17 | $Revision: 2971 $ |
379 | serge | 18 | |
593 | mikedld | 19 | |
1 | ha | 20 | ;******************************************************************* |
21 | ; Interface |
||
22 | ; |
||
23 | ; udp_rx Handles received IP packets with the UDP protocol |
||
379 | serge | 24 | ; |
1 | ha | 25 | ;******************************************************************* |
261 | hidnplayr | 26 | |
27 | |||
28 | ; |
||
29 | ; UDP Payload ( Data field in IP datagram ) |
||
30 | ; |
||
31 | ; 0 1 2 3 |
||
32 | ; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
||
33 | ; |
||
34 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
35 | ; | Source Port | Destination Port | |
||
36 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
37 | ; | Length ( UDP Header + Data ) | Checksum | |
||
38 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
39 | ; | UDP Data | |
||
40 | ; +-+-+-.......... -+ |
||
41 | ; |
||
42 | |||
43 | struc UDP_PACKET |
||
44 | { .SourcePort dw ? ;+00 |
||
45 | .DestinationPort dw ? ;+02 |
||
46 | .Length dw ? ;+04 - Length of (UDP Header + Data) |
||
47 | .Checksum dw ? ;+06 |
||
48 | .Data db ? ;+08 |
||
49 | } |
||
50 | |||
51 | virtual at 0 |
||
52 | UDP_PACKET UDP_PACKET |
||
53 | end virtual |
||
54 | |||
55 | |||
1 | ha | 56 | ;*************************************************************************** |
57 | ; Function |
||
261 | hidnplayr | 58 | ; udp_rx [by Johnny_B] |
1 | ha | 59 | ; |
60 | ; Description |
||
61 | ; UDP protocol handler |
||
62 | ; This is a kernel function, called by ip_rx |
||
63 | ; IP buffer address given in edx |
||
261 | hidnplayr | 64 | ; IP buffer number in eax |
1 | ha | 65 | ; Free up (or re-use) IP buffer when finished |
66 | ; |
||
67 | ;*************************************************************************** |
||
914 | serge | 68 | |
69 | proc udp_rx stdcall |
||
1 | ha | 70 | push eax |
379 | serge | 71 | |
1 | ha | 72 | ; First validate the header & checksum. Discard buffer if error |
379 | serge | 73 | |
1 | ha | 74 | ; Look for a socket where |
75 | ; IP Packet UDP Destination Port = local Port |
||
76 | ; IP Packet SA = Remote IP |
||
379 | serge | 77 | |
914 | serge | 78 | mov ax, [edx + 20 + UDP_PACKET.DestinationPort] ; get the local port from |
1 | ha | 79 | ; the IP packet's UDP header |
379 | serge | 80 | |
914 | serge | 81 | mov ebx, net_sockets |
82 | |||
83 | .next_socket: |
||
84 | mov ebx, [ebx + SOCKET.NextPtr] |
||
85 | or ebx, ebx |
||
86 | jz .exit ; No match, so exit |
||
87 | cmp [ebx + SOCKET.LocalPort], ax ; ax will hold the 'wrong' value, |
||
1 | ha | 88 | ; but the comparision is correct |
914 | serge | 89 | jne .next_socket ; Return back if no match |
379 | serge | 90 | |
1 | ha | 91 | ; For dhcp, we must allow any remote server to respond. |
92 | ; I will accept the first incoming response to be the one |
||
93 | ; I bind to, if the socket is opened with a destination IP address of |
||
94 | ; 255.255.255.255 |
||
914 | serge | 95 | cmp [ebx + SOCKET.RemoteIP], 0xffffffff |
96 | je @f |
||
379 | serge | 97 | |
914 | serge | 98 | mov eax, [edx + IP_PACKET.SourceAddress] ; get the Source address from the IP packet |
2971 | Serge | 99 | cmp [ebx + SOCKET.RemoteIP], eax |
914 | serge | 100 | jne .exit ; Quit if the source IP is not valid |
1 | ha | 101 | |
914 | serge | 102 | @@: ; OK - we have a valid UDP packet for this socket. |
1 | ha | 103 | ; First, update the sockets remote port number with the incoming msg |
104 | ; - it will have changed |
||
105 | ; from the original ( 69 normally ) to allow further connects |
||
914 | serge | 106 | mov ax, [edx + 20 + UDP_PACKET.SourcePort] ; get the UDP source port |
1 | ha | 107 | ; ( was 69, now new ) |
914 | serge | 108 | mov [ebx + SOCKET.RemotePort], ax |
379 | serge | 109 | |
1 | ha | 110 | ; Now, copy data to socket. We have socket address as [eax + sockets]. |
111 | ; We have IP packet in edx |
||
379 | serge | 112 | |
1 | ha | 113 | ; get # of bytes in ecx |
914 | serge | 114 | movzx ecx, [edx + IP_PACKET.TotalLength] ; total length of IP packet. Subtract |
115 | xchg cl, ch ; 20 + 8 gives data length |
||
1 | ha | 116 | sub ecx, 28 |
379 | serge | 117 | |
914 | serge | 118 | mov eax, [ebx + SOCKET.rxDataCount] ; get # of bytes already in buffer |
119 | add [ebx + SOCKET.rxDataCount], ecx ; increment the count of bytes in buffer |
||
379 | serge | 120 | |
914 | serge | 121 | ; ecx has count, edx points to data |
379 | serge | 122 | |
1 | ha | 123 | add edx, 28 ; edx now points to the data |
914 | serge | 124 | lea edi, [ebx + eax + SOCKETHEADERSIZE] |
1 | ha | 125 | mov esi, edx |
379 | serge | 126 | |
1 | ha | 127 | cld |
128 | rep movsb ; copy the data across |
||
379 | serge | 129 | |
1 | ha | 130 | ; flag an event to the application |
914 | serge | 131 | mov eax, [ebx + SOCKET.PID] ; get socket owner PID |
132 | mov ecx, 1 |
||
133 | mov esi, TASK_DATA + TASKDATA.pid |
||
379 | serge | 134 | |
914 | serge | 135 | .next_pid: |
136 | cmp [esi], eax |
||
137 | je .found_pid |
||
1 | ha | 138 | inc ecx |
914 | serge | 139 | add esi, 0x20 |
140 | cmp ecx, [TASK_COUNT] |
||
141 | jbe .next_pid |
||
379 | serge | 142 | |
914 | serge | 143 | jmp .exit |
1 | ha | 144 | |
914 | serge | 145 | .found_pid: |
146 | shl ecx, 8 |
||
147 | or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event |
||
1 | ha | 148 | |
914 | serge | 149 | mov [check_idle_semaphore], 200 |
150 | |||
151 | .exit: |
||
1 | ha | 152 | pop eax |
153 | call freeBuff ; Discard the packet |
||
379 | serge | 154 | ret |
914 | serge | 155 | endp |