Rev 5363 | Rev 5584 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5363 | Rev 5522 | ||
---|---|---|---|
Line 14... | Line 14... | ||
14 | ;; GNU GENERAL PUBLIC LICENSE ;; |
14 | ;; GNU GENERAL PUBLIC LICENSE ;; |
15 | ;; Version 2, June 1991 ;; |
15 | ;; Version 2, June 1991 ;; |
16 | ;; ;; |
16 | ;; ;; |
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 18... | Line 18... | ||
18 | 18 | ||
Line 19... | Line 19... | ||
19 | $Revision: 5363 $ |
19 | $Revision: 5522 $ |
Line 20... | Line 20... | ||
20 | 20 | ||
Line 129... | Line 129... | ||
129 | ; |
129 | ; |
130 | ; This procedure will send reply's to ICMP echo's |
130 | ; This procedure will send reply's to ICMP echo's |
131 | ; and insert packets into sockets when needed |
131 | ; and insert packets into sockets when needed |
132 | ; |
132 | ; |
133 | ; IN: Pointer to buffer in [esp] |
133 | ; IN: Pointer to buffer in [esp] |
134 | ; size of buffer in [esp+4] |
- | |
135 | ; ebx = pointer to device struct |
134 | ; ebx = pointer to device struct |
136 | ; ecx = ICMP Packet size |
135 | ; ecx = ICMP Packet size |
137 | ; esi = ptr to ICMP Packet data |
136 | ; esi = ptr to ICMP Packet data |
138 | ; edi = ptr to ipv4 source and dest address |
137 | ; edi = ptr to ipv4 source and dest address |
139 | ; |
138 | ; |
Line 141... | Line 140... | ||
141 | ; |
140 | ; |
142 | ;----------------------------------------------------------------- |
141 | ;----------------------------------------------------------------- |
143 | align 4 |
142 | align 4 |
144 | ICMP_input: |
143 | ICMP_input: |
Line 145... | Line 144... | ||
145 | 144 | ||
146 | DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input:\n" |
- | |
147 | - | ||
Line -... | Line 145... | ||
- | 145 | DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input\n" |
|
148 | ; First, check the checksum (altough some implementations ignore it) |
146 | |
149 | 147 | ; Check the checksum |
|
150 | push esi ecx |
148 | push esi ecx |
151 | push [esi + ICMP_header.Checksum] |
149 | push [esi + ICMP_header.Checksum] |
152 | mov [esi + ICMP_header.Checksum], 0 |
150 | mov [esi + ICMP_header.Checksum], 0 |
153 | xor edx, edx |
151 | xor edx, edx |
154 | call checksum_1 |
152 | call checksum_1 |
155 | call checksum_2 |
153 | call checksum_2 |
156 | pop si |
154 | pop si |
157 | cmp dx, si |
155 | cmp dx, si |
Line 158... | Line -... | ||
158 | pop ecx edx |
- | |
159 | jne .checksum_mismatch |
- | |
160 | 156 | pop ecx esi |
|
161 | ; Check packet type |
- | |
Line 162... | Line 157... | ||
162 | 157 | jne .checksum_mismatch |
|
- | 158 | ||
163 | cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request? |
159 | DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: Checksum OK\n" |
164 | jne .check_sockets |
160 | |
165 | 161 | ; Ualidate device ptr |
|
166 | ; Update stats (and validate device ptr) |
- | |
167 | call NET_ptr_to_num4 |
- | |
168 | cmp edi, -1 |
- | |
169 | je .dump |
- | |
170 | inc [ICMP_PACKETS_RX + edi] |
- | |
171 | - | ||
172 | ; We well re-use the packet so we can create the response as fast as possible |
- | |
173 | ; Notice: this only works on pure ethernet |
- | |
174 | - | ||
175 | DEBUGF DEBUG_NETWORK_VERBOSE, "got echo request\n" |
- | |
176 | mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply |
- | |
177 | - | ||
178 | mov esi, [esp] ; Start of buffer |
- | |
179 | cmp ebx, LOOPBACK_DEVICE |
- | |
180 | je .loopback |
- | |
181 | - | ||
182 | ; FIXME: dont assume device is an ethernet device! |
- | |
183 | - | ||
184 | ; exchange dest and source address in IP header |
- | |
185 | ; exchange dest and source MAC in ETH header |
- | |
186 | push dword [esi + ETH_header.DstMAC] |
- | |
187 | push dword [esi + ETH_header.SrcMAC] |
- | |
188 | pop dword [esi + ETH_header.DstMAC] |
- | |
189 | pop dword [esi + ETH_header.SrcMAC] |
- | |
190 | push word [esi + ETH_header.DstMAC + 4] |
- | |
191 | push word [esi + ETH_header.SrcMAC + 4] |
- | |
192 | pop word [esi + ETH_header.DstMAC + 4] |
- | |
193 | pop word [esi + ETH_header.SrcMAC + 4] |
- | |
194 | add esi, sizeof.ETH_header-4 |
- | |
195 | - | ||
196 | .loopback: |
- | |
197 | add esi, 4 |
- | |
198 | push [esi + IPv4_header.SourceAddress] |
- | |
199 | push [esi + IPv4_header.DestinationAddress] |
- | |
200 | pop [esi + IPv4_header.SourceAddress] |
- | |
201 | pop [esi + IPv4_header.DestinationAddress] |
- | |
202 | - | ||
203 | ; Recalculate ip header checksum |
- | |
204 | movzx ecx, [esi + IPv4_header.VersionAndIHL] ; Calculate IP Header length by using IHL field |
- | |
205 | and ecx, 0x0f |
- | |
206 | shl cx, 2 |
- | |
207 | mov edi, ecx ; IP header length |
- | |
208 | mov eax, edx ; ICMP packet start addr |
- | |
209 | - | ||
210 | push esi ; Calculate the IP checksum |
- | |
211 | xor edx, edx ; |
- | |
212 | call checksum_1 ; |
- | |
213 | call checksum_2 ; |
- | |
214 | pop esi ; |
- | |
215 | mov [esi + IPv4_header.HeaderChecksum], dx ; |
- | |
216 | - | ||
217 | ; Recalculate ICMP CheckSum |
- | |
218 | movzx ecx, [esi + IPv4_header.TotalLength] ; Find length of IP Packet |
- | |
219 | xchg ch, cl ; |
- | |
220 | sub ecx, edi ; IP packet length - IP header length = ICMP packet length |
- | |
221 | - | ||
222 | mov esi, eax ; Calculate ICMP checksum |
- | |
223 | xor edx, edx ; |
- | |
224 | call checksum_1 ; |
- | |
225 | call checksum_2 ; |
- | |
226 | mov [eax + ICMP_header.Checksum], dx ; |
- | |
227 | - | ||
228 | ; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!) |
- | |
229 | call [ebx + NET_DEVICE.transmit] |
- | |
230 | test eax, eax |
- | |
231 | jnz @f |
- | |
232 | call NET_ptr_to_num4 |
- | |
Line -... | Line 162... | ||
- | 162 | mov eax, edi |
|
- | 163 | call NET_ptr_to_num4 |
|
Line -... | Line 164... | ||
- | 164 | cmp edi, -1 |
|
- | 165 | je .dump |
|
- | 166 | ||
Line 233... | Line -... | ||
233 | inc [ICMP_PACKETS_TX + edi] |
- | |
234 | @@: |
167 | ; Update stats |
235 | ret |
- | |
236 | 168 | inc [ICMP_PACKETS_RX + edi] |
|
237 | 169 | ||
238 | 170 | ; Is this an echo request? |
|
239 | 171 | cmp [esi + ICMP_header.Type], ICMP_ECHO |
|
Line 240... | Line 172... | ||
240 | .check_sockets: |
172 | je .echo_request |
241 | ; Look for an open ICMP socket |
173 | |
242 | 174 | ; Look for an open ICMP socket |
|
243 | pusha |
175 | pusha |
244 | mov ecx, socket_mutex |
176 | mov ecx, socket_mutex |
245 | call mutex_lock |
177 | call mutex_lock |
246 | popa |
178 | popa |
247 | 179 | ||
Line 258... | Line 190... | ||
258 | jne .next_socket |
190 | jne .next_socket |
Line 259... | Line 191... | ||
259 | 191 | ||
260 | cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP |
192 | cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP |
Line 261... | Line 193... | ||
261 | jne .next_socket |
193 | jne .next_socket |
262 | 194 | ||
Line 263... | Line 195... | ||
263 | cmp [eax + IP_SOCKET.RemoteIP], esi |
195 | cmp [eax + IP_SOCKET.RemoteIP], edx |
264 | jne .next_socket |
196 | jne .next_socket |
Line 265... | Line -... | ||
265 | - | ||
266 | ; cmp [eax + ICMP_SOCKET.Identifier], |
- | |
267 | ; jne .next_socket |
- | |
268 | - | ||
269 | ; Update stats (and validate device ptr) |
- | |
270 | call NET_ptr_to_num4 |
- | |
271 | cmp edi, -1 |
197 | |
272 | je .dump_ |
198 | ; cmp [eax + ICMP_SOCKET.Identifier], |
273 | inc [ICMP_PACKETS_RX + edi] |
199 | ; jne .next_socket |
274 | 200 | ||
Line 282... | Line 208... | ||
282 | pusha |
208 | pusha |
283 | lea ecx, [eax + SOCKET.mutex] |
209 | lea ecx, [eax + SOCKET.mutex] |
284 | call mutex_lock |
210 | call mutex_lock |
285 | popa |
211 | popa |
Line 286... | Line -... | ||
286 | - | ||
287 | mov esi, edx |
212 | |
Line 288... | Line -... | ||
288 | jmp SOCKET_input |
- | |
Line -... | Line 213... | ||
- | 213 | jmp SOCKET_input |
|
- | 214 | ||
- | 215 | ||
- | 216 | ||
- | 217 | .echo_request: |
|
- | 218 | ||
- | 219 | ; We'll reuse the packet so we can create the response as fast as possible |
|
- | 220 | DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP echo request\n" |
|
- | 221 | ||
- | 222 | ; Change Packet type to reply |
|
- | 223 | mov [esi + ICMP_header.Type], ICMP_ECHOREPLY |
|
- | 224 | ||
- | 225 | mov eax, [esp] |
|
- | 226 | lea esi, [eax + NET_BUFF.data] |
|
- | 227 | ||
- | 228 | ; Check frame type |
|
- | 229 | cmp [eax + NET_BUFF.type], NET_BUFF_ETH |
|
- | 230 | jne .not_ethernet |
|
- | 231 | ||
- | 232 | ; exchange dest and source MAC in ETH header |
|
- | 233 | push dword [esi + ETH_header.DstMAC] |
|
- | 234 | push dword [esi + ETH_header.SrcMAC] |
|
- | 235 | pop dword [esi + ETH_header.DstMAC] |
|
- | 236 | pop dword [esi + ETH_header.SrcMAC] |
|
- | 237 | push word [esi + ETH_header.DstMAC + 4] |
|
- | 238 | push word [esi + ETH_header.SrcMAC + 4] |
|
- | 239 | pop word [esi + ETH_header.DstMAC + 4] |
|
- | 240 | pop word [esi + ETH_header.SrcMAC + 4] |
|
- | 241 | add esi, sizeof.ETH_header |
|
- | 242 | ||
- | 243 | .not_ethernet: |
|
- | 244 | ; Exchange dest and source address in IP header |
|
- | 245 | push [esi + IPv4_header.SourceAddress] |
|
- | 246 | push [esi + IPv4_header.DestinationAddress] |
|
- | 247 | pop [esi + IPv4_header.SourceAddress] |
|
- | 248 | pop [esi + IPv4_header.DestinationAddress] |
|
- | 249 | ||
- | 250 | ; Calculate IP header length |
|
- | 251 | movzx ecx, [esi + IPv4_header.VersionAndIHL] |
|
- | 252 | and ecx, 0x0f |
|
- | 253 | shl cx, 2 |
|
- | 254 | mov edi, ecx ; put it in edi for later |
|
- | 255 | ||
- | 256 | ; Calculate IP checksum |
|
- | 257 | mov eax, esi |
|
- | 258 | mov [eax + IPv4_header.HeaderChecksum], 0 |
|
- | 259 | xor edx, edx |
|
- | 260 | call checksum_1 |
|
- | 261 | call checksum_2 |
|
- | 262 | mov [eax + IPv4_header.HeaderChecksum], dx |
|
- | 263 | ||
- | 264 | ; Calculate ICMP packet length |
|
- | 265 | movzx ecx, [eax + IPv4_header.TotalLength] |
|
- | 266 | xchg ch, cl |
|
- | 267 | sub ecx, edi ; IP packet length - IP header length = ICMP packet length |
|
- | 268 | ||
- | 269 | ; Calculate ICMP checkSum |
|
- | 270 | mov eax, esi |
|
- | 271 | mov [esi + ICMP_header.Checksum], 0 |
|
- | 272 | xor edx, edx |
|
- | 273 | call checksum_1 |
|
- | 274 | call checksum_2 |
|
- | 275 | mov [eax + ICMP_header.Checksum], dx |
|
- | 276 | ||
- | 277 | ; Transmit the frame |
|
- | 278 | DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP transmitting reply\n" |
|
- | 279 | call [ebx + NET_DEVICE.transmit] |
|
- | 280 | test eax, eax |
|
- | 281 | jnz @f |
|
- | 282 | DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP transmit failed\n" |
|
- | 283 | call NET_ptr_to_num4 |
|
- | 284 | inc [ICMP_PACKETS_TX + edi] |
|
- | 285 | @@: |
|
289 | 286 | ret |
|
290 | .dump_: |
287 | |
291 | 288 | .dump_: |
|
292 | pusha |
289 | pusha |
Line 293... | Line 290... | ||
293 | mov ecx, socket_mutex |
290 | mov ecx, socket_mutex |
294 | call mutex_unlock |
291 | call mutex_unlock |
Line 295... | Line -... | ||
295 | popa |
- | |
296 | 292 | popa |
|
297 | DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n" |
293 | |
Line 298... | Line 294... | ||
298 | jmp .dump |
294 | DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n" |
299 | 295 | jmp .dump |
|
300 | - | ||
301 | .checksum_mismatch: |
296 | |
302 | DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n" |
- | |
303 | - | ||
304 | .dump: |
297 | .checksum_mismatch: |
Line 305... | Line 298... | ||
305 | DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n" |
298 | DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n" |
306 | 299 | ||
Line 398... | Line 391... | ||
398 | mov eax, [eax + IP_SOCKET.RemoteIP] |
391 | mov eax, [eax + IP_SOCKET.RemoteIP] |
399 | call IPv4_output |
392 | call IPv4_output |
400 | jz .exit |
393 | jz .exit |
Line 401... | Line 394... | ||
401 | 394 | ||
402 | pop esi |
- | |
403 | push edx |
395 | pop esi |
Line 404... | Line 396... | ||
404 | push eax |
396 | push eax |
405 | 397 | ||
406 | push edi ecx |
398 | push edi ecx |
Line 424... | Line 416... | ||
424 | inc [ICMP_PACKETS_TX + edi] |
416 | inc [ICMP_PACKETS_TX + edi] |
425 | @@: |
417 | @@: |
426 | ret |
418 | ret |
427 | .exit: |
419 | .exit: |
428 | DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n" |
420 | DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n" |
429 | add esp, 4 |
- | |
430 | ret |
421 | ret |