Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2288 | clevermous | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
2455 | mario79 | 3 | ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
2288 | clevermous | 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 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
16 | |||
17 | $Revision: 2455 $ |
||
18 | |||
19 | |||
20 | ;******************************************************************* |
||
21 | ; Interface |
||
22 | ; |
||
23 | ; udp_rx Handles received IP packets with the UDP protocol |
||
24 | ; |
||
25 | ;******************************************************************* |
||
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 | |||
56 | ;*************************************************************************** |
||
57 | ; Function |
||
58 | ; udp_rx [by Johnny_B] |
||
59 | ; |
||
60 | ; Description |
||
61 | ; UDP protocol handler |
||
62 | ; This is a kernel function, called by ip_rx |
||
63 | ; IP buffer address given in edx |
||
64 | ; IP buffer number in eax |
||
65 | ; Free up (or re-use) IP buffer when finished |
||
66 | ; |
||
67 | ;*************************************************************************** |
||
68 | |||
69 | proc udp_rx stdcall |
||
70 | push eax |
||
71 | |||
72 | ; First validate the header & checksum. Discard buffer if error |
||
73 | |||
74 | ; Look for a socket where |
||
75 | ; IP Packet UDP Destination Port = local Port |
||
76 | ; IP Packet SA = Remote IP |
||
77 | |||
78 | mov ax, [edx + 20 + UDP_PACKET.DestinationPort] ; get the local port from |
||
79 | ; the IP packet's UDP header |
||
80 | |||
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, |
||
88 | ; but the comparision is correct |
||
89 | jne .next_socket ; Return back if no match |
||
90 | |||
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 |
||
95 | cmp [ebx + SOCKET.RemoteIP], 0xffffffff |
||
96 | je @f |
||
97 | |||
98 | mov eax, [edx + IP_PACKET.SourceAddress] ; get the Source address from the IP packet |
||
99 | cmp [ebx + SOCKET.RemoteIP], eax |
||
100 | jne .exit ; Quit if the source IP is not valid |
||
101 | |||
102 | @@: ; OK - we have a valid UDP packet for this socket. |
||
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 |
||
106 | mov ax, [edx + 20 + UDP_PACKET.SourcePort] ; get the UDP source port |
||
107 | ; ( was 69, now new ) |
||
108 | mov [ebx + SOCKET.RemotePort], ax |
||
109 | |||
110 | ; Now, copy data to socket. We have socket address as [eax + sockets]. |
||
111 | ; We have IP packet in edx |
||
112 | |||
113 | ; get # of bytes in ecx |
||
114 | movzx ecx, [edx + IP_PACKET.TotalLength] ; total length of IP packet. Subtract |
||
115 | xchg cl, ch ; 20 + 8 gives data length |
||
116 | sub ecx, 28 |
||
117 | |||
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 |
||
120 | |||
121 | ; ecx has count, edx points to data |
||
122 | |||
123 | add edx, 28 ; edx now points to the data |
||
124 | lea edi, [ebx + eax + SOCKETHEADERSIZE] |
||
125 | mov esi, edx |
||
126 | |||
127 | cld |
||
128 | rep movsb ; copy the data across |
||
129 | |||
130 | ; flag an event to the application |
||
131 | mov eax, [ebx + SOCKET.PID] ; get socket owner PID |
||
132 | mov ecx, 1 |
||
133 | mov esi, TASK_DATA + TASKDATA.pid |
||
134 | |||
135 | .next_pid: |
||
136 | cmp [esi], eax |
||
137 | je .found_pid |
||
138 | inc ecx |
||
139 | add esi, 0x20 |
||
140 | cmp ecx, [TASK_COUNT] |
||
141 | jbe .next_pid |
||
142 | |||
143 | jmp .exit |
||
144 | |||
145 | .found_pid: |
||
146 | shl ecx, 8 |
||
147 | or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event |
||
148 | |||
149 | mov [check_idle_semaphore], 200 |
||
150 | |||
151 | .exit: |
||
152 | pop eax |
||
153 | call freeBuff ; Discard the packet |
||
154 | ret |
||
155 | endp |