Rev 2302 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2302 | Rev 2305 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; IPv4.INC ;; |
6 | ;; IPv4.INC ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Part of the tcp/ip network stack for KolibriOS ;; |
8 | ;; Part of the tcp/ip network stack for KolibriOS ;; |
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: 2302 $ |
19 | $Revision: 2305 $ |
20 | 20 | ||
21 | MAX_FRAGMENTS equ 64 |
21 | MAX_FRAGMENTS equ 64 |
Line 22... | Line 22... | ||
22 | MAX_IP equ MAX_NET_DEVICES |
22 | MAX_IP equ MAX_NET_DEVICES |
- | 23 | IP_MAX_INTERFACES equ MAX_IP |
|
23 | IP_MAX_INTERFACES equ MAX_IP |
24 | |
24 | 25 | struct IPv4_header |
|
25 | struct IPv4_Packet |
26 | |
26 | .VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] |
27 | VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] |
27 | .TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0] |
28 | TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0] |
28 | .TotalLength dw ? |
29 | TotalLength dw ? |
29 | .Identification dw ? |
30 | Identification dw ? |
30 | .FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] |
31 | FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] |
31 | .TimeToLive db ? ; |
32 | TimeToLive db ? ; |
32 | .Protocol db ? |
33 | Protocol db ? |
33 | .HeaderChecksum dw ? |
- | |
- | 34 | HeaderChecksum dw ? |
|
34 | .SourceAddress dd ? |
35 | SourceAddress dd ? |
Line 35... | Line 36... | ||
35 | .DestinationAddress dd ? |
36 | DestinationAddress dd ? |
- | 37 | ||
36 | .DataOrOptional: |
38 | ends |
37 | ends |
39 | |
38 | 40 | struct FRAGMENT_slot |
|
39 | struct FRAGMENT_slot |
41 | |
40 | .ttl dw ? ; Time to live for this entry, 0 for empty slot's |
42 | ttl dw ? ; Time to live for this entry, 0 for empty slot's |
41 | .id dw ? ; Identification field from IP header |
43 | id dw ? ; Identification field from IP header |
42 | .SrcIP dd ? ; .. from IP header |
44 | SrcIP dd ? ; .. from IP header |
Line 43... | Line 45... | ||
43 | .DstIP dd ? ; .. from IP header |
45 | DstIP dd ? ; .. from IP header |
- | 46 | ptr dd ? ; Pointer to first packet |
|
44 | .ptr dd ? ; Pointer to first packet |
47 | |
45 | .size: |
48 | ends |
46 | ends |
49 | |
47 | 50 | struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets |
|
48 | struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets |
51 | |
49 | .PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet) |
52 | PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet) |
Line 50... | Line 53... | ||
50 | .NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet) |
53 | NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet) |
51 | .Owner dd ? ; Pointer to structure of driver |
54 | Owner dd ? ; Pointer to structure of driver |
Line 63... | Line 66... | ||
63 | GATEWAY_LIST rd MAX_IP |
66 | GATEWAY_LIST rd MAX_IP |
Line 64... | Line 67... | ||
64 | 67 | ||
65 | IP_PACKETS_TX rd MAX_IP |
68 | IP_PACKETS_TX rd MAX_IP |
Line 66... | Line 69... | ||
66 | IP_PACKETS_RX rd MAX_IP |
69 | IP_PACKETS_RX rd MAX_IP |
67 | 70 | ||
Line 68... | Line 71... | ||
68 | FRAGMENT_LIST rb MAX_FRAGMENTS*FRAGMENT_slot.size |
71 | FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot |
69 | endg |
72 | endg |
Line 82... | Line 85... | ||
82 | mov edi, IP_LIST |
85 | mov edi, IP_LIST |
83 | mov ecx, 4*MAX_IP |
86 | mov ecx, 4*MAX_IP |
84 | rep stosd |
87 | rep stosd |
Line 85... | Line 88... | ||
85 | 88 | ||
86 | mov edi, FRAGMENT_LIST |
89 | mov edi, FRAGMENT_LIST |
87 | mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP |
90 | mov ecx, sizeof.FRAGMENT_slot*MAX_FRAGMENTS/4 + 2*MAX_IP |
Line 88... | Line 91... | ||
88 | rep stosd |
91 | rep stosd |
Line 198... | Line 201... | ||
198 | align 4 |
201 | align 4 |
199 | IPv4_input: ; TODO: implement handler for IP options |
202 | IPv4_input: ; TODO: implement handler for IP options |
200 | ; TODO2: add code for raw sockets |
203 | ; TODO2: add code for raw sockets |
Line 201... | Line 204... | ||
201 | 204 | ||
202 | DEBUGF 1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\ |
205 | DEBUGF 1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\ |
203 | [edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1 |
206 | [edx + IPv4_header.SourceAddress]:1,[edx + IPv4_header.SourceAddress + 1]:1,[edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1 |
204 | DEBUGF 1,"to: %u.%u.%u.%u\n",\ |
207 | DEBUGF 1,"to: %u.%u.%u.%u\n",\ |
Line 205... | Line 208... | ||
205 | [edx + IPv4_Packet.DestinationAddress]:1,[edx + IPv4_Packet.DestinationAddress + 1]:1,[edx + IPv4_Packet.DestinationAddress + 2]:1,[edx + IPv4_Packet.DestinationAddress + 3]:1 |
208 | [edx + IPv4_header.DestinationAddress]:1,[edx + IPv4_header.DestinationAddress + 1]:1,[edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1 |
206 | 209 | ||
Line 207... | Line 210... | ||
207 | ;------------------------------------------- |
210 | ;------------------------------------------- |
208 | ; Check if the packet still has time to live |
211 | ; Check if the packet still has time to live |
Line 209... | Line 212... | ||
209 | 212 | ||
210 | cmp byte [edx + IPv4_Packet.TimeToLive], 0 |
213 | cmp byte [edx + IPv4_header.TimeToLive], 0 |
Line 211... | Line 214... | ||
211 | je .dump |
214 | je .dump |
212 | 215 | ||
213 | ;-------------------------------------- |
216 | ;-------------------------------------- |
214 | ; First, check if IP packet has options |
217 | ; First, check if IP packet has options |
Line 215... | Line 218... | ||
215 | 218 | ||
Line 233... | Line 236... | ||
233 | shl edi, 2 |
236 | shl edi, 2 |
Line 234... | Line 237... | ||
234 | 237 | ||
Line 235... | Line 238... | ||
235 | ; check if it matches local ip |
238 | ; check if it matches local ip |
236 | 239 | ||
237 | mov eax, [IP_LIST+edi] |
240 | mov eax, [IP_LIST+edi] |
Line 238... | Line 241... | ||
238 | cmp [edx + IPv4_Packet.DestinationAddress], eax |
241 | cmp [edx + IPv4_header.DestinationAddress], eax |
Line 239... | Line 242... | ||
239 | je .ip_ok |
242 | je .ip_ok |
240 | 243 | ||
241 | ; check for broadcast |
244 | ; check for broadcast |
242 | 245 | ||
243 | mov eax, [SUBNET_LIST+edi] |
246 | mov eax, [SUBNET_LIST+edi] |
Line 244... | Line 247... | ||
244 | not eax |
247 | not eax |
Line 245... | Line 248... | ||
245 | or eax, [IP_LIST+edi] |
248 | or eax, [IP_LIST+edi] |
246 | cmp [edx + IPv4_Packet.DestinationAddress], eax |
249 | cmp [edx + IPv4_header.DestinationAddress], eax |
Line 247... | Line 250... | ||
247 | je .ip_ok |
250 | je .ip_ok |
Line 248... | Line 251... | ||
248 | 251 | ||
249 | ; or a special broadcast |
252 | ; or a special broadcast |
250 | 253 | ||
251 | cmp [edx + IPv4_Packet.DestinationAddress], -1 |
254 | cmp [edx + IPv4_header.DestinationAddress], -1 |
Line 252... | Line 255... | ||
252 | je .ip_ok |
255 | je .ip_ok |
Line 275... | Line 278... | ||
275 | inc [IP_PACKETS_RX+edi] |
278 | inc [IP_PACKETS_RX+edi] |
Line 276... | Line 279... | ||
276 | 279 | ||
277 | ;---------------------------------- |
280 | ;---------------------------------- |
Line 278... | Line 281... | ||
278 | ; Check if the packet is fragmented |
281 | ; Check if the packet is fragmented |
279 | 282 | ||
Line 280... | Line 283... | ||
280 | test [edx + IPv4_Packet.FlagsAndFragmentOffset], 1 shl 5 ; Is 'more fragments' flag set ? |
283 | test [edx + IPv4_header.FlagsAndFragmentOffset], 1 shl 5 ; Is 'more fragments' flag set ? |
281 | jnz .has_fragments ; If so, we definately have a fragmented packet |
284 | jnz .has_fragments ; If so, we definately have a fragmented packet |
Line 282... | Line 285... | ||
282 | 285 | ||
283 | test [edx + IPv4_Packet.FlagsAndFragmentOffset], 0xff1f ; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets |
286 | test [edx + IPv4_header.FlagsAndFragmentOffset], 0xff1f ; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets |
Line 284... | Line 287... | ||
284 | jnz .is_last_fragment |
287 | jnz .is_last_fragment |
285 | 288 | ||
286 | ;------------------------------------------------------------------- |
289 | ;------------------------------------------------------------------- |
287 | ; No, it's just a regular IP packet, pass it to the higher protocols |
290 | ; No, it's just a regular IP packet, pass it to the higher protocols |
288 | 291 | ||
289 | .handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed |
292 | .handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed |
290 | movzx eax, [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
293 | movzx eax, [edx + IPv4_header.VersionAndIHL] ; Calculate Header length by using IHL field |
Line 291... | Line 294... | ||
291 | and eax, 0x0000000f ; |
294 | and eax, 0x0000000f ; |
292 | shl eax, 2 ; |
295 | shl eax, 2 ; |
Line 293... | Line 296... | ||
293 | movzx ecx, [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet |
296 | movzx ecx, [edx + IPv4_header.TotalLength] ; Calculate length of encapsulated Packet |
294 | xchg cl , ch ; |
297 | xchg cl , ch ; |
295 | sub ecx, eax ; |
298 | sub ecx, eax ; |
296 | 299 | ||
Line 297... | Line 300... | ||
297 | add eax, edx |
300 | add eax, edx |
298 | push eax |
301 | push eax |
Line 324... | Line 327... | ||
324 | ;--------------------------- |
327 | ;--------------------------- |
325 | ; Fragmented packet handler |
328 | ; Fragmented packet handler |
Line 326... | Line 329... | ||
326 | 329 | ||
327 | 330 | ||
328 | .has_fragments: |
331 | .has_fragments: |
329 | movzx eax, [edx + IPv4_Packet.FlagsAndFragmentOffset] |
332 | movzx eax, [edx + IPv4_header.FlagsAndFragmentOffset] |
Line 330... | Line 333... | ||
330 | xchg al , ah |
333 | xchg al , ah |
Line 331... | Line 334... | ||
331 | shl ax , 3 |
334 | shl ax , 3 |
332 | 335 | ||
Line 377... | Line 380... | ||
377 | mov ecx, MAX_FRAGMENTS |
380 | mov ecx, MAX_FRAGMENTS |
378 | mov esi, FRAGMENT_LIST |
381 | mov esi, FRAGMENT_LIST |
379 | .find_free_slot: |
382 | .find_free_slot: |
380 | cmp word [esi + FRAGMENT_slot.ttl], 0 |
383 | cmp word [esi + FRAGMENT_slot.ttl], 0 |
381 | je .found_free_slot |
384 | je .found_free_slot |
382 | add esi, FRAGMENT_slot.size |
385 | add esi, sizeof.FRAGMENT_slot |
383 | loop .find_free_slot |
386 | loop .find_free_slot |
384 | jmp .dump ; If no free slot was found, dump the packet |
387 | jmp .dump ; If no free slot was found, dump the packet |
Line 385... | Line 388... | ||
385 | 388 | ||
386 | .found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure |
389 | .found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure |
387 | mov [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl |
390 | mov [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl |
388 | mov ax , [edx + IPv4_Packet.Identification] |
391 | mov ax , [edx + IPv4_header.Identification] |
389 | mov [esi + FRAGMENT_slot.id], ax |
392 | mov [esi + FRAGMENT_slot.id], ax |
390 | mov eax,[edx + IPv4_Packet.SourceAddress] |
393 | mov eax,[edx + IPv4_header.SourceAddress] |
391 | mov [esi + FRAGMENT_slot.SrcIP], eax |
394 | mov [esi + FRAGMENT_slot.SrcIP], eax |
392 | mov eax, [edx + IPv4_Packet.DestinationAddress] |
395 | mov eax, [edx + IPv4_header.DestinationAddress] |
393 | mov [esi + FRAGMENT_slot.DstIP], eax |
396 | mov [esi + FRAGMENT_slot.DstIP], eax |
394 | pop eax |
397 | pop eax |
395 | mov [esi + FRAGMENT_slot.ptr], eax |
398 | mov [esi + FRAGMENT_slot.ptr], eax |
396 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
399 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
Line 418... | Line 421... | ||
418 | or edi, -1 |
421 | or edi, -1 |
Line 419... | Line 422... | ||
419 | 422 | ||
420 | .count_bytes: |
423 | .count_bytes: |
421 | cmp [esi + FRAGMENT_entry.PrevPtr], edi |
424 | cmp [esi + FRAGMENT_entry.PrevPtr], edi |
422 | jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
425 | jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
423 | mov cx, [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Add total length |
426 | mov cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length |
424 | xchg cl, ch |
427 | xchg cl, ch |
425 | DEBUGF 1,"Packet size: %u\n", cx |
428 | DEBUGF 1,"Packet size: %u\n", cx |
426 | add ax, cx |
429 | add ax, cx |
427 | movzx cx, [esi + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Sub Header length |
430 | movzx cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length |
428 | and cx, 0x000F |
431 | and cx, 0x000F |
429 | shl cx, 2 |
432 | shl cx, 2 |
430 | DEBUGF 1,"Header size: %u\n", cx |
433 | DEBUGF 1,"Header size: %u\n", cx |
431 | sub ax, cx |
434 | sub ax, cx |
Line 438... | Line 441... | ||
438 | mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
441 | mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
439 | mov [esi + FRAGMENT_entry.NextPtr], -1 |
442 | mov [esi + FRAGMENT_entry.NextPtr], -1 |
440 | mov [esi + FRAGMENT_entry.PrevPtr], edi |
443 | mov [esi + FRAGMENT_entry.PrevPtr], edi |
441 | mov [esi + FRAGMENT_entry.Owner], ebx |
444 | mov [esi + FRAGMENT_entry.Owner], ebx |
Line 442... | Line 445... | ||
442 | 445 | ||
443 | mov cx, [edx + IPv4_Packet.TotalLength] ; Note: This time we dont substract Header length |
446 | mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length |
444 | xchg cl , ch |
447 | xchg cl , ch |
445 | DEBUGF 1,"Packet size: %u\n", cx |
448 | DEBUGF 1,"Packet size: %u\n", cx |
446 | add ax , cx |
449 | add ax , cx |
Line 447... | Line 450... | ||
447 | DEBUGF 1,"Total Received data size: %u\n", eax |
450 | DEBUGF 1,"Total Received data size: %u\n", eax |
448 | 451 | ||
449 | push eax |
452 | push eax |
450 | mov ax , [edx + IPv4_Packet.FlagsAndFragmentOffset] |
453 | mov ax , [edx + IPv4_header.FlagsAndFragmentOffset] |
451 | xchg al , ah |
454 | xchg al , ah |
452 | shl ax , 3 |
455 | shl ax , 3 |
453 | add cx , ax |
456 | add cx , ax |
Line 463... | Line 466... | ||
463 | test eax, eax |
466 | test eax, eax |
464 | je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot |
467 | je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot |
465 | mov edx, [esp+4] ; Get pointer to first fragment entry back in edx |
468 | mov edx, [esp+4] ; Get pointer to first fragment entry back in edx |
Line 466... | Line 469... | ||
466 | 469 | ||
467 | .rebuild_packet_loop: |
470 | .rebuild_packet_loop: |
468 | movzx ecx, [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset] ; Calculate the fragment offset |
471 | movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset |
469 | xchg cl , ch ; intel byte order |
472 | xchg cl , ch ; intel byte order |
470 | shl cx , 3 ; multiply by 8 and clear first 3 bits |
473 | shl cx , 3 ; multiply by 8 and clear first 3 bits |
Line 471... | Line 474... | ||
471 | DEBUGF 1,"Fragment offset: %u\n", cx |
474 | DEBUGF 1,"Fragment offset: %u\n", cx |
472 | 475 | ||
473 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
476 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
474 | movzx ebx, [edx + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Find header size (in ebx) of fragment |
477 | movzx ebx, [edx + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment |
Line 475... | Line 478... | ||
475 | and bx , 0x000F ; |
478 | and bx , 0x000F ; |
476 | shl bx , 2 ; |
479 | shl bx , 2 ; |
477 | 480 | ||
Line 478... | Line 481... | ||
478 | lea esi, [edx + FRAGMENT_entry.Data] ; Set esi to the correct begin of fragment |
481 | lea esi, [edx + sizeof.FRAGMENT_entry] ; Set esi to the correct begin of fragment |
479 | movzx ecx, [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Calculate total length of fragment |
482 | movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment |
480 | xchg cl, ch ; intel byte order |
483 | xchg cl, ch ; intel byte order |
Line 502... | Line 505... | ||
502 | jne .rebuild_packet_loop |
505 | jne .rebuild_packet_loop |
Line 503... | Line 506... | ||
503 | 506 | ||
504 | pop ecx |
507 | pop ecx |
505 | xchg cl, ch |
508 | xchg cl, ch |
506 | mov edx, eax |
509 | mov edx, eax |
507 | mov [edx + IPv4_Packet.TotalLength], cx |
510 | mov [edx + IPv4_header.TotalLength], cx |
Line 508... | Line 511... | ||
508 | add esp, 8 |
511 | add esp, 8 |
Line 509... | Line 512... | ||
509 | 512 | ||
Line 548... | Line 551... | ||
548 | IPv4_find_fragment_slot: |
551 | IPv4_find_fragment_slot: |
Line 549... | Line 552... | ||
549 | 552 | ||
Line 550... | Line 553... | ||
550 | ;;; TODO: the RFC says we should check protocol number too |
553 | ;;; TODO: the RFC says we should check protocol number too |
551 | 554 | ||
552 | push eax ebx ecx edx |
555 | push eax ebx ecx edx |
553 | mov ax , [edx + IPv4_Packet.Identification] |
556 | mov ax , [edx + IPv4_header.Identification] |
554 | mov ecx, MAX_FRAGMENTS |
557 | mov ecx, MAX_FRAGMENTS |
555 | mov esi, FRAGMENT_LIST |
558 | mov esi, FRAGMENT_LIST |
556 | mov ebx, [edx + IPv4_Packet.SourceAddress] |
559 | mov ebx, [edx + IPv4_header.SourceAddress] |
557 | mov edx, [edx + IPv4_Packet.DestinationAddress] |
560 | mov edx, [edx + IPv4_header.DestinationAddress] |
558 | .find_slot: |
561 | .find_slot: |
559 | cmp [esi + FRAGMENT_slot.id], ax |
562 | cmp [esi + FRAGMENT_slot.id], ax |
560 | jne .try_next |
563 | jne .try_next |
561 | cmp [esi + FRAGMENT_slot.SrcIP], ebx |
564 | cmp [esi + FRAGMENT_slot.SrcIP], ebx |
562 | jne .try_next |
565 | jne .try_next |
563 | cmp [esi + FRAGMENT_slot.DstIP], edx |
566 | cmp [esi + FRAGMENT_slot.DstIP], edx |
564 | je .found_slot |
567 | je .found_slot |
565 | .try_next: |
568 | .try_next: |
566 | add esi, FRAGMENT_slot.size |
569 | add esi, sizeof.FRAGMENT_slot |
567 | loop .find_slot |
570 | loop .find_slot |
568 | ; pop edx ebx |
571 | ; pop edx ebx |
Line 615... | Line 618... | ||
615 | inc [IP_PACKETS_TX+edi] |
618 | inc [IP_PACKETS_TX+edi] |
616 | mov ebx, [NET_DRV_LIST+edi] |
619 | mov ebx, [NET_DRV_LIST+edi] |
617 | lea eax, [ebx + ETH_DEVICE.mac] |
620 | lea eax, [ebx + ETH_DEVICE.mac] |
618 | mov edx, esp |
621 | mov edx, esp |
619 | mov ecx, [esp + 18] |
622 | mov ecx, [esp + 18] |
620 | add ecx, IPv4_Packet.DataOrOptional |
623 | add ecx, sizeof.IPv4_header |
621 | mov di , ETHER_IPv4 |
624 | mov di , ETHER_IPv4 |
622 | call ETH_output |
625 | call ETH_output |
623 | jz .error |
626 | jz .error |
Line 624... | Line 627... | ||
624 | 627 | ||
Line 625... | Line 628... | ||
625 | add esp, 6 ; pop the mac |
628 | add esp, 6 ; pop the mac |
626 | 629 | ||
627 | mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) |
630 | mov [edi + IPv4_header.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) |
628 | mov [edi + IPv4_Packet.TypeOfService], 0 ; nothing special, just plain ip packet |
631 | mov [edi + IPv4_header.TypeOfService], 0 ; nothing special, just plain ip packet |
629 | mov [edi + IPv4_Packet.TotalLength], cx |
632 | mov [edi + IPv4_header.TotalLength], cx |
630 | rol [edi + IPv4_Packet.TotalLength], 8 ; internet byte order |
633 | rol [edi + IPv4_header.TotalLength], 8 ; internet byte order |
631 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000 |
634 | mov [edi + IPv4_header.FlagsAndFragmentOffset], 0x0000 |
632 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
635 | mov [edi + IPv4_header.HeaderChecksum], 0 |
633 | pop word [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol |
636 | pop word [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol |
634 | ; [edi + IPv4_Packet.Protocol] |
637 | ; [edi + IPv4_header.Protocol] |
635 | popw [edi + IPv4_Packet.Identification] ; fragment id |
638 | popw [edi + IPv4_header.Identification] ; fragment id |
Line 636... | Line 639... | ||
636 | popd [edi + IPv4_Packet.SourceAddress] |
639 | popd [edi + IPv4_header.SourceAddress] |
Line 637... | Line 640... | ||
637 | popd [edi + IPv4_Packet.DestinationAddress] |
640 | popd [edi + IPv4_header.DestinationAddress] |
638 | 641 | ||
639 | pop ecx |
642 | pop ecx |
640 | 643 | ||
Line 641... | Line 644... | ||
641 | IPv4_checksum edi |
644 | IPv4_checksum edi |
642 | add edi, IPv4_Packet.DataOrOptional |
645 | add edi, sizeof.IPv4_header |
Line 692... | Line 695... | ||
692 | inc [IP_PACKETS_TX+edi] |
695 | inc [IP_PACKETS_TX+edi] |
693 | mov ebx, [NET_DRV_LIST+edi] |
696 | mov ebx, [NET_DRV_LIST+edi] |
694 | lea eax, [ebx + ETH_DEVICE.mac] |
697 | lea eax, [ebx + ETH_DEVICE.mac] |
695 | mov edx, esp |
698 | mov edx, esp |
696 | mov ecx, [esp + 6+4] |
699 | mov ecx, [esp + 6+4] |
697 | add ecx, IPv4_Packet.DataOrOptional |
700 | add ecx, sizeof.IPv4_header |
698 | mov di, ETHER_IPv4 |
701 | mov di, ETHER_IPv4 |
699 | call ETH_output |
702 | call ETH_output |
700 | jz .error |
703 | jz .error |
Line 701... | Line 704... | ||
701 | 704 | ||
Line 709... | Line 712... | ||
709 | 712 | ||
710 | push edi ecx |
713 | push edi ecx |
711 | rep movsb |
714 | rep movsb |
Line 712... | Line 715... | ||
712 | pop ecx edi |
715 | pop ecx edi |
713 | 716 | ||
714 | ; [edi + IPv4_Packet.VersionAndIHL] ; IPv4, normal length (no Optional header) |
717 | ; [edi + IPv4_header.VersionAndIHL] ; IPv4, normal length (no Optional header) |
715 | ; [edi + IPv4_Packet.TypeOfService] ; nothing special, just plain ip packet |
718 | ; [edi + IPv4_header.TypeOfService] ; nothing special, just plain ip packet |
716 | ; [edi + IPv4_Packet.TotalLength] |
719 | ; [edi + IPv4_header.TotalLength] |
717 | ; [edi + IPv4_Packet.TotalLength] ; internet byte order |
720 | ; [edi + IPv4_header.TotalLength] ; internet byte order |
718 | ; [edi + IPv4_Packet.FlagsAndFragmentOffset] |
721 | ; [edi + IPv4_header.FlagsAndFragmentOffset] |
719 | 722 | ||
720 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
723 | mov [edi + IPv4_header.HeaderChecksum], 0 |
721 | 724 | ||
722 | ; [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol |
725 | ; [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol |
723 | ; [edi + IPv4_Packet.Protocol] |
726 | ; [edi + IPv4_header.Protocol] |
724 | ; [edi + IPv4_Packet.Identification] ; fragment id |
727 | ; [edi + IPv4_header.Identification] ; fragment id |
Line 725... | Line 728... | ||
725 | ; [edi + IPv4_Packet.SourceAddress] |
728 | ; [edi + IPv4_header.SourceAddress] |
726 | ; [edi + IPv4_Packet.DestinationAddress] |
729 | ; [edi + IPv4_header.DestinationAddress] |
727 | 730 | ||
728 | IPv4_checksum edi ;;;; todo: checksum for IP packet with options! |
731 | IPv4_checksum edi ;;;; todo: checksum for IP packet with options! |
729 | add edi, IPv4_Packet.DataOrOptional |
732 | add edi, sizeof.IPv4_header |
Line 730... | Line 733... | ||
730 | DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx |
733 | DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx |
Line 758... | Line 761... | ||
758 | 761 | ||
Line 759... | Line 762... | ||
759 | DEBUGF 1,"IPv4_fragment\n" |
762 | DEBUGF 1,"IPv4_fragment\n" |
Line 760... | Line 763... | ||
760 | 763 | ||
761 | and ecx, not 111b ; align 4 |
764 | and ecx, not 111b ; align 4 |
Line 762... | Line 765... | ||
762 | 765 | ||
763 | cmp ecx, IPv4_Packet.DataOrOptional + 8 ; must be able to put at least 8 bytes |
766 | cmp ecx, sizeof.IPv4_header + 8 ; must be able to put at least 8 bytes |
764 | jb .err2 |
767 | jb .err2 |
765 | 768 | ||
766 | push esi ecx |
769 | push esi ecx |
767 | mov eax, [esi + IPv4_Packet.DestinationAddress] |
770 | mov eax, [esi + IPv4_header.DestinationAddress] |
Line 777... | Line 780... | ||
777 | lea eax, [ebx + ETH_DEVICE.mac] |
780 | lea eax, [ebx + ETH_DEVICE.mac] |
778 | push eax |
781 | push eax |
Line 779... | Line 782... | ||
779 | 782 | ||
780 | 783 | ||
781 | push esi ; ptr to ip header |
784 | push esi ; ptr to ip header |
782 | sub ecx, IPv4_Packet.DataOrOptional ; substract header size |
785 | sub ecx, sizeof.IPv4_header ; substract header size |
Line 783... | Line 786... | ||
783 | push ecx ; max data size |
786 | push ecx ; max data size |
784 | push dword 0 ; offset |
787 | push dword 0 ; offset |
Line 800... | Line 803... | ||
800 | mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header! |
803 | mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header! |
801 | rep movsd |
804 | rep movsd |
Line 802... | Line 805... | ||
802 | 805 | ||
803 | ; copy data |
806 | ; copy data |
804 | mov esi, [esp + 2*4] |
807 | mov esi, [esp + 2*4] |
805 | add esi, IPv4_Packet.DataOrOptional |
808 | add esi, sizeof.IPv4_header |
Line 806... | Line 809... | ||
806 | add esi, [esp] ; offset |
809 | add esi, [esp] ; offset |
807 | 810 | ||
808 | mov ecx, [esp + 1*4] |
811 | mov ecx, [esp + 1*4] |
Line 809... | Line 812... | ||
809 | DEBUGF 1,"IPv4_fragment - copying data (%u bytes)\n", ecx |
812 | DEBUGF 1,"IPv4_fragment - copying data (%u bytes)\n", ecx |
810 | rep movsb |
813 | rep movsb |
811 | 814 | ||
812 | ; now, correct header |
815 | ; now, correct header |
813 | mov ecx, [esp + 1*4] |
816 | mov ecx, [esp + 1*4] |
Line 814... | Line 817... | ||
814 | add ecx, IPv4_Packet.DataOrOptional |
817 | add ecx, sizeof.IPv4_header |
815 | xchg cl, ch |
818 | xchg cl, ch |
Line 816... | Line 819... | ||
816 | mov [edi + IPv4_Packet.TotalLength], cx |
819 | mov [edi + IPv4_header.TotalLength], cx |
817 | 820 | ||
818 | mov ecx, [esp] ; offset |
821 | mov ecx, [esp] ; offset |
819 | xchg cl, ch |
822 | xchg cl, ch |
820 | 823 | ||
Line 821... | Line 824... | ||
821 | ; cmp dword[esp + 4*4], 0 ; last fragment?;<<<<<< |
824 | ; cmp dword[esp + 4*4], 0 ; last fragment?;<<<<<< |
Line 822... | Line 825... | ||
822 | ; je .last_fragment |
825 | ; je .last_fragment |
823 | or cx, 1 shl 2 ; more fragments |
826 | or cx, 1 shl 2 ; more fragments |
Line 824... | Line 827... | ||
824 | ; .last_fragment: |
827 | ; .last_fragment: |