Rev 1208 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1208 | Rev 1249 | ||
---|---|---|---|
Line 12... | Line 12... | ||
12 | ;; GNU GENERAL PUBLIC LICENSE ;; |
12 | ;; GNU GENERAL PUBLIC LICENSE ;; |
13 | ;; Version 2, June 1991 ;; |
13 | ;; Version 2, June 1991 ;; |
14 | ;; ;; |
14 | ;; ;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 16... | Line 16... | ||
16 | 16 | ||
Line 17... | Line 17... | ||
17 | $Revision: 1208 $ |
17 | $Revision: 1249 $ |
18 | 18 | ||
19 | 19 | ||
Line 73... | Line 73... | ||
73 | ;----------------------------------------------------------------- |
73 | ;----------------------------------------------------------------- |
74 | align 4 |
74 | align 4 |
75 | UDP_handler: |
75 | UDP_handler: |
Line 76... | Line 76... | ||
76 | 76 | ||
77 | DEBUGF 1,"UDP_Handler\n" |
77 | DEBUGF 1,"UDP_Handler\n" |
- | 78 | ; First validate, checksum: |
|
- | 79 | ||
- | 80 | DEBUGF 1,"Real UDP checksum: %x\n", [edx + UDP_Packet.Checksum]:4 |
|
- | 81 | mov [edx + UDP_Packet.Checksum], 0 |
|
- | 82 | ||
- | 83 | pusha |
|
- | 84 | ||
- | 85 | rol cx, 8 |
|
- | 86 | push cx |
|
- | 87 | rol cx, 8 |
|
- | 88 | push word IP_PROTO_UDP shl 8 |
|
- | 89 | push edi |
|
- | 90 | push esi |
|
- | 91 | ||
- | 92 | mov esi, edx |
|
- | 93 | xor edx, edx |
|
- | 94 | call checksum_1 |
|
- | 95 | ; Checksum for pseudoheader |
|
- | 96 | mov ecx, 12 |
|
- | 97 | mov esi, esp |
|
- | 98 | call checksum_1 |
|
- | 99 | add esp, 12 |
|
- | 100 | call checksum_2 |
|
- | 101 | ||
- | 102 | popa |
|
- | 103 | ||
Line 78... | Line 104... | ||
78 | ; TODO: First validate the header & checksum! |
104 | |
79 | 105 | ||
80 | ; Look for a socket where |
106 | ; Look for a socket where |
Line 81... | Line 107... | ||
81 | ; IP Packet UDP Destination Port = local Port |
107 | ; IP Packet UDP Destination Port = local Port |
82 | ; IP Packet SA = Remote IP |
108 | ; IP Packet SA = Remote IP |
83 | 109 | ||
84 | mov eax, net_sockets |
110 | mov eax, net_sockets |
85 | .try_more: |
111 | .try_more: |
86 | mov bx , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header |
112 | mov bx , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header |
87 | .next_socket: |
113 | .next_socket: |
88 | mov eax, [eax + SOCKET.NextPtr] |
114 | mov eax, [eax + SOCKET_head.NextPtr] |
89 | or eax, eax |
115 | or eax, eax |
90 | jz .dump |
116 | jz .dump |
91 | cmp [eax + SOCKET.Domain], AF_INET4 |
117 | cmp [eax + SOCKET_head.Domain], AF_INET4 |
92 | jne .next_socket |
118 | jne .next_socket |
93 | cmp [eax + SOCKET.Type], IP_PROTO_UDP |
119 | cmp [eax + SOCKET_head.Type], IP_PROTO_UDP |
Line 94... | Line 120... | ||
94 | jne .next_socket |
120 | jne .next_socket |
Line 95... | Line 121... | ||
95 | cmp [eax + SOCKET.LocalPort], bx |
121 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx |
96 | jne .next_socket |
122 | jne .next_socket |
97 | 123 | ||
98 | DEBUGF 1,"found socket with matching domain, type and localport\n" |
124 | DEBUGF 1,"found socket with matching domain, type and localport\n" |
99 | 125 | ||
100 | ; For dhcp, we must allow any remote server to respond. |
126 | ; For dhcp, we must allow any remote server to respond. |
Line 101... | Line 127... | ||
101 | ; I will accept the first incoming response to be the one |
127 | ; I will accept the first incoming response to be the one |
102 | ; I bind to, if the socket is opened with a destination IP address of |
128 | ; I bind to, if the socket is opened with a destination IP address of |
103 | ; 255.255.255.255 |
129 | ; 255.255.255.255 |
104 | cmp [eax + SOCKET.RemoteIP], 0xffffffff |
130 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff |
Line 105... | Line 131... | ||
105 | je .ok1 |
131 | je .ok1 |
106 | 132 | ||
Line 107... | Line 133... | ||
107 | mov ebx, [esp] |
133 | mov ebx, [esp] |
Line 108... | Line 134... | ||
108 | mov ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet FIXME |
134 | mov ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet FIXME |
109 | cmp [eax + SOCKET.RemoteIP], ebx |
135 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx |
Line 110... | Line 136... | ||
110 | jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination |
136 | jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination |
111 | 137 | ||
Line 112... | Line 138... | ||
112 | 138 | ||
Line 113... | Line 139... | ||
113 | DEBUGF 1,"Remote Ip matches\n" |
139 | DEBUGF 1,"Remote Ip matches\n" |
Line 128... | Line 154... | ||
128 | movzx ecx, [edx + UDP_Packet.Length] |
154 | movzx ecx, [edx + UDP_Packet.Length] |
129 | rol cx , 8 |
155 | rol cx , 8 |
130 | sub cx , UDP_Packet.Data |
156 | sub cx , UDP_Packet.Data |
131 | mov dx , bx |
157 | mov dx , bx |
Line 132... | Line -... | ||
132 | - | ||
Line -... | Line 158... | ||
- | 158 | ||
- | 159 | ||
- | 160 | lea ebx, [eax + SOCKET_head.lock] |
|
- | 161 | call wait_mutex |
|
133 | call socket_internal_receiver |
162 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], dx ; update remote port number |
Line -... | Line 163... | ||
- | 163 | mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], edi |
|
- | 164 | inc [UDP_PACKETS_RX] |
|
- | 165 | ||
- | 166 | pop edi |
|
- | 167 | add esp, 4 |
|
- | 168 | ||
- | 169 | sub esi, edi |
|
- | 170 | xchg esi, edi |
|
134 | 171 | jmp socket_internal_receiver |
|
135 | inc [UDP_PACKETS_RX] |
172 | |
136 | 173 | ||
137 | .dump: |
174 | .dump: |
Line 144... | Line 181... | ||
144 | 181 | ||
145 | 182 | ||
146 | 183 | ||
147 | ;----------------------------------------------------------------- |
184 | ;----------------------------------------------------------------- |
148 | ; |
185 | ; |
149 | ; Note: UDP works only on top of IP protocol :) |
- | |
150 | ; |
186 | ; UDP_socket_send |
151 | ; IN: eax = dest ip |
- | |
152 | ; ebx = source ip |
187 | ; |
153 | ; ecx = data length |
188 | ; IN: eax = socket pointer |
154 | ; edx = remote port shl 16 + local port (both in INET order) |
189 | ; ecx = number of bytes to send |
Line -... | Line 190... | ||
- | 190 | ; esi = pointer to data |
|
155 | ; esi = data offset |
191 | ; |
- | 192 | ;----------------------------------------------------------------- |
|
- | 193 | ||
- | 194 | align 4 |
|
- | 195 | UDP_socket_send: |
|
- | 196 | ||
- | 197 | mov edx, dword [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort] ; load local port and remote port at once |
|
- | 198 | DEBUGF 1,"local port: %x, remote port: %x\n",\ |
|
Line 156... | Line 199... | ||
156 | ; |
199 | [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort]:4,\ |
Line -... | Line 200... | ||
- | 200 | [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort]:4 |
|
- | 201 | mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
|
- | 202 | mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
|
- | 203 | ||
- | 204 | DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx |
|
- | 205 | ||
- | 206 | mov di , IP_PROTO_UDP |
|
- | 207 | ||
157 | ;----------------------------------------------------------------- |
208 | sub esp, 8 ; reserve some place in stack for later |
Line 158... | Line 209... | ||
158 | 209 | ||
159 | UDP_create_packet: |
- | |
Line 160... | Line 210... | ||
160 | 210 | ; Create the pseudoheader in stack, |
|
Line -... | Line 211... | ||
- | 211 | ; (now that we still have all the variables that are needed.) |
|
161 | DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx |
212 | push dword IP_PROTO_UDP shl 8 |
162 | 213 | push eax |
|
163 | push edx esi |
214 | push ebx |
Line -... | Line 215... | ||
- | 215 | ||
164 | 216 | add ecx, UDP_Packet.Data |
|
- | 217 | ||
- | 218 | ; TODO: fill in: dx = fragment id |
|
165 | add ecx, UDP_Packet.Data |
219 | |
166 | mov di , IP_PROTO_UDP |
220 | push edx esi |
- | 221 | call IPv4_create_packet ; TODO: figure out a way to choose between IPv4 and IPv6 |
|
Line 167... | Line 222... | ||
167 | 222 | cmp edi, -1 |
|
168 | ; dx = fragment id |
223 | je .fail |
- | 224 | ||
169 | 225 | mov [esp + 8 + 12], eax ; pointer to buffer start |
|
170 | call IPv4_create_packet ; TODO: figure out a way to choose between IPv4 and IPv6 |
- | |
171 | cmp edi, -1 |
226 | mov [esp + 8 + 12 + 4], edx ; buffer size |
172 | je .fail |
227 | |
173 | 228 | rol cx, 8 |
|
174 | mov byte[edi + UDP_Packet.Length], ch |
229 | mov [edi + UDP_Packet.Length], cx |
175 | mov byte[edi + UDP_Packet.Length+1], cl |
230 | mov [esp + 8 + 10], cx |
176 | sub ecx , UDP_Packet.Data |
231 | ror cx, 8 |
Line 177... | Line -... | ||
177 | - | ||
178 | pop esi |
232 | |
- | 233 | pop esi |
|
Line -... | Line 234... | ||
- | 234 | push edi ecx |
|
- | 235 | sub ecx, UDP_Packet.Data |
|
- | 236 | add edi, UDP_Packet.Data |
|
- | 237 | shr ecx, 2 |
|
- | 238 | rep movsd |
|
- | 239 | mov ecx, [esp] |
|
- | 240 | and cx , 3 |
|
- | 241 | rep movsb |
|
- | 242 | pop ecx edi |
|
- | 243 | ||
- | 244 | pop dword [edi + UDP_Packet.SourcePort] ; fill in both portnumbers |
|
179 | push edi |
245 | mov [edi + UDP_Packet.Checksum], 0 ; set it to zero, to calculate checksum |
180 | add edi, UDP_Packet.Data |
- | |
181 | push cx |
- | |
Line 182... | Line 246... | ||
182 | shr ecx, 2 |
246 | |
Line 183... | Line -... | ||
183 | rep movsd |
- | |
184 | pop cx |
247 | ; Checksum for UDP header + data |
185 | and cx , 3 |
248 | xor edx, edx |
186 | rep movsb |
- | |
187 | pop edi |
- | |
188 | - | ||
Line 189... | Line 249... | ||
189 | pop ecx |
249 | mov esi, edi |
190 | mov dword [edi + UDP_Packet.SourcePort], ecx ; notice: we write both port's at once |
250 | call checksum_1 |
191 | 251 | ; Checksum for pseudoheader |
|
192 | mov [edi + UDP_Packet.Checksum], 0 |
252 | mov ecx, 12 |
Line -... | Line 253... | ||
- | 253 | mov esi, esp |
|
193 | 254 | call checksum_1 |
|
194 | ; TODO: calculate checksum using Pseudo-header (However, using a 0 as checksum shouldnt generate any errors :) |
255 | add esp, 12 ; remove the pseudoheader from stack |
195 | 256 | ; Now create the final checksum and store it in UDP header |
|
196 | inc [UDP_PACKETS_TX] |
257 | call checksum_2 |
197 | 258 | mov [edi + UDP_Packet.Checksum], dx |