Rev 2301 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2301 | Rev 2302 | ||
---|---|---|---|
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: 2301 $ |
19 | $Revision: 2302 $ |
20 | 20 | ||
21 | MAX_FRAGMENTS equ 64 |
21 | MAX_FRAGMENTS equ 64 |
Line 232... | Line 232... | ||
232 | call NET_ptr_to_num |
232 | call NET_ptr_to_num |
233 | shl edi, 2 |
233 | shl edi, 2 |
Line 234... | Line 234... | ||
234 | 234 | ||
Line 235... | Line 235... | ||
235 | ; check if it matches local ip |
235 | ; check if it matches local ip |
236 | 236 | ||
237 | mov eax, dword[IP_LIST+edi] |
237 | mov eax, [IP_LIST+edi] |
Line 238... | Line 238... | ||
238 | cmp [edx + IPv4_Packet.DestinationAddress], eax |
238 | cmp [edx + IPv4_Packet.DestinationAddress], eax |
Line 285... | Line 285... | ||
285 | 285 | ||
286 | ;------------------------------------------------------------------- |
286 | ;------------------------------------------------------------------- |
Line 287... | Line 287... | ||
287 | ; No, it's just a regular IP packet, pass it to the higher protocols |
287 | ; No, it's just a regular IP packet, pass it to the higher protocols |
288 | 288 | ||
289 | .handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed |
289 | .handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed |
290 | movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
290 | movzx eax, [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
291 | and eax, 0x0000000f ; |
291 | and eax, 0x0000000f ; |
292 | shl eax, 2 ; |
292 | shl eax, 2 ; |
293 | movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet |
293 | movzx ecx, [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet |
Line 294... | Line 294... | ||
294 | xchg cl , ch ; |
294 | xchg cl , ch ; |
295 | sub ecx, eax ; |
295 | sub ecx, eax ; |
Line 343... | Line 343... | ||
343 | 343 | ||
344 | call IPv4_find_fragment_slot |
344 | call IPv4_find_fragment_slot |
345 | cmp esi, -1 |
345 | cmp esi, -1 |
Line 346... | Line 346... | ||
346 | je .dump |
346 | je .dump |
347 | 347 | ||
348 | mov word [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl |
348 | mov [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl |
349 | mov esi, [esi + FRAGMENT_slot.ptr] |
349 | mov esi, [esi + FRAGMENT_slot.ptr] |
350 | or edi, -1 |
350 | or edi, -1 |
351 | .find_last_entry: ; The following routine will try to find the last entry |
351 | .find_last_entry: ; The following routine will try to find the last entry |
Line 382... | Line 382... | ||
382 | add esi, FRAGMENT_slot.size |
382 | add esi, FRAGMENT_slot.size |
383 | loop .find_free_slot |
383 | loop .find_free_slot |
384 | jmp .dump ; If no free slot was found, dump the packet |
384 | jmp .dump ; If no free slot was found, dump the packet |
Line 385... | Line 385... | ||
385 | 385 | ||
386 | .found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure |
386 | .found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure |
387 | mov word [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl |
387 | mov [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl |
388 | mov ax , word [edx + IPv4_Packet.Identification] |
388 | mov ax , [edx + IPv4_Packet.Identification] |
389 | mov word [esi + FRAGMENT_slot.id], ax |
389 | mov [esi + FRAGMENT_slot.id], ax |
390 | mov eax, dword [edx + IPv4_Packet.SourceAddress] |
390 | mov eax,[edx + IPv4_Packet.SourceAddress] |
391 | mov dword [esi + FRAGMENT_slot.SrcIP], eax |
391 | mov [esi + FRAGMENT_slot.SrcIP], eax |
392 | mov eax, dword [edx + IPv4_Packet.DestinationAddress] |
392 | mov eax, [edx + IPv4_Packet.DestinationAddress] |
393 | mov dword [esi + FRAGMENT_slot.DstIP], eax |
393 | mov [esi + FRAGMENT_slot.DstIP], eax |
394 | pop eax |
394 | pop eax |
395 | mov dword [esi + FRAGMENT_slot.ptr], eax |
395 | mov [esi + FRAGMENT_slot.ptr], eax |
396 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
396 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
397 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
397 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
398 | mov [eax + FRAGMENT_entry.PrevPtr], -1 |
398 | mov [eax + FRAGMENT_entry.PrevPtr], -1 |
Line 418... | Line 418... | ||
418 | or edi, -1 |
418 | or edi, -1 |
Line 419... | Line 419... | ||
419 | 419 | ||
420 | .count_bytes: |
420 | .count_bytes: |
421 | cmp [esi + FRAGMENT_entry.PrevPtr], edi |
421 | 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!) |
422 | jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
423 | mov cx, word [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Add total length |
423 | mov cx, [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Add total length |
424 | xchg cl, ch |
424 | xchg cl, ch |
425 | DEBUGF 1,"Packet size: %u\n", cx |
425 | DEBUGF 1,"Packet size: %u\n", cx |
426 | add ax, cx |
426 | add ax, cx |
427 | movzx cx, byte [esi + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Sub Header length |
427 | movzx cx, [esi + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Sub Header length |
428 | and cx, 0x000F |
428 | and cx, 0x000F |
429 | shl cx, 2 |
429 | shl cx, 2 |
430 | DEBUGF 1,"Header size: %u\n", cx |
430 | DEBUGF 1,"Header size: %u\n", cx |
431 | sub ax, cx |
431 | sub ax, cx |
Line 463... | Line 463... | ||
463 | test eax, eax |
463 | test eax, eax |
464 | je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot |
464 | 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 |
465 | mov edx, [esp+4] ; Get pointer to first fragment entry back in edx |
Line 466... | Line 466... | ||
466 | 466 | ||
467 | .rebuild_packet_loop: |
467 | .rebuild_packet_loop: |
468 | movzx ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset] ; Calculate the fragment offset |
468 | movzx ecx, [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset] ; Calculate the fragment offset |
469 | xchg cl , ch ; intel byte order |
469 | xchg cl , ch ; intel byte order |
470 | shl cx , 3 ; multiply by 8 and clear first 3 bits |
470 | shl cx , 3 ; multiply by 8 and clear first 3 bits |
Line 471... | Line 471... | ||
471 | DEBUGF 1,"Fragment offset: %u\n", cx |
471 | DEBUGF 1,"Fragment offset: %u\n", cx |
472 | 472 | ||
473 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
473 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
474 | movzx ebx, byte [edx + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Find header size (in ebx) of fragment |
474 | movzx ebx, [edx + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Find header size (in ebx) of fragment |
Line 475... | Line 475... | ||
475 | and bx , 0x000F ; |
475 | and bx , 0x000F ; |
476 | shl bx , 2 ; |
476 | shl bx , 2 ; |
477 | 477 | ||
Line 478... | Line 478... | ||
478 | lea esi, [edx + FRAGMENT_entry.Data] ; Set esi to the correct begin of fragment |
478 | lea esi, [edx + FRAGMENT_entry.Data] ; Set esi to the correct begin of fragment |
479 | movzx ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Calculate total length of fragment |
479 | movzx ecx, [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Calculate total length of fragment |
480 | xchg cl, ch ; intel byte order |
480 | xchg cl, ch ; intel byte order |
Line 499... | Line 499... | ||
499 | call kernel_free ; free the previous fragment buffer (this uses the value from stack) |
499 | call kernel_free ; free the previous fragment buffer (this uses the value from stack) |
500 | pop eax |
500 | pop eax |
501 | cmp edx, -1 ; Check if it is last fragment in chain |
501 | cmp edx, -1 ; Check if it is last fragment in chain |
502 | jne .rebuild_packet_loop |
502 | jne .rebuild_packet_loop |
Line 503... | Line 503... | ||
503 | 503 | ||
504 | pop ecx ; |
504 | pop ecx |
505 | xchg cl, ch |
505 | xchg cl, ch |
506 | mov edx, eax |
506 | mov edx, eax |
507 | mov word [edx + IPv4_Packet.TotalLength], cx |
507 | mov [edx + IPv4_Packet.TotalLength], cx |
Line 508... | Line 508... | ||
508 | add esp, 8 |
508 | add esp, 8 |
Line 509... | Line 509... | ||
509 | 509 | ||
Line 548... | Line 548... | ||
548 | IPv4_find_fragment_slot: |
548 | IPv4_find_fragment_slot: |
Line 549... | Line 549... | ||
549 | 549 | ||
Line 550... | Line 550... | ||
550 | ;;; TODO: the RFC says we should check protocol number too |
550 | ;;; TODO: the RFC says we should check protocol number too |
551 | 551 | ||
552 | push eax ebx ecx edx |
552 | push eax ebx ecx edx |
553 | mov ax , word [edx + IPv4_Packet.Identification] |
553 | mov ax , [edx + IPv4_Packet.Identification] |
554 | mov ecx, MAX_FRAGMENTS |
554 | mov ecx, MAX_FRAGMENTS |
555 | mov esi, FRAGMENT_LIST |
555 | mov esi, FRAGMENT_LIST |
556 | mov ebx, dword [edx + IPv4_Packet.SourceAddress] |
556 | mov ebx, [edx + IPv4_Packet.SourceAddress] |
557 | mov edx, dword [edx + IPv4_Packet.DestinationAddress] |
557 | mov edx, [edx + IPv4_Packet.DestinationAddress] |
558 | .find_slot: |
558 | .find_slot: |
559 | cmp word [esi + FRAGMENT_slot.id], ax |
559 | cmp [esi + FRAGMENT_slot.id], ax |
560 | jne .try_next |
560 | jne .try_next |
561 | cmp dword [esi + FRAGMENT_slot.SrcIP], ebx |
561 | cmp [esi + FRAGMENT_slot.SrcIP], ebx |
562 | jne .try_next |
562 | jne .try_next |
563 | cmp dword [esi + FRAGMENT_slot.DstIP], edx |
563 | cmp [esi + FRAGMENT_slot.DstIP], edx |
564 | je .found_slot |
564 | je .found_slot |
565 | .try_next: |
565 | .try_next: |
566 | add esi, FRAGMENT_slot.size |
566 | add esi, FRAGMENT_slot.size |
Line 628... | Line 628... | ||
628 | mov [edi + IPv4_Packet.TypeOfService], 0 ; nothing special, just plain ip packet |
628 | mov [edi + IPv4_Packet.TypeOfService], 0 ; nothing special, just plain ip packet |
629 | mov [edi + IPv4_Packet.TotalLength], cx |
629 | mov [edi + IPv4_Packet.TotalLength], cx |
630 | rol [edi + IPv4_Packet.TotalLength], 8 ; internet byte order |
630 | rol [edi + IPv4_Packet.TotalLength], 8 ; internet byte order |
631 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000 |
631 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000 |
632 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
632 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
633 | popw word [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol |
633 | pop word [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol |
634 | ; [edi + IPv4_Packet.Protocol] |
634 | ; [edi + IPv4_Packet.Protocol] |
635 | popw [edi + IPv4_Packet.Identification] ; fragment id |
635 | popw [edi + IPv4_Packet.Identification] ; fragment id |
636 | popd [edi + IPv4_Packet.SourceAddress] |
636 | popd [edi + IPv4_Packet.SourceAddress] |
637 | popd [edi + IPv4_Packet.DestinationAddress] |
637 | popd [edi + IPv4_Packet.DestinationAddress] |