Rev 9736 | Rev 9800 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9736 | Rev 9799 | ||
---|---|---|---|
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: 9736 $ |
19 | $Revision: 9799 $ |
20 | 20 | ||
Line 21... | Line 21... | ||
21 | IPv4_MAX_FRAGMENTS = 64 |
21 | IPv4_MAX_FRAGMENTS = 64 |
Line 391... | Line 391... | ||
391 | 391 | ||
392 | mov [esi + IPv4_FRAGMENT_slot.ttl], 15 ; Reset the ttl |
392 | mov [esi + IPv4_FRAGMENT_slot.ttl], 15 ; Reset the ttl |
393 | mov esi, [esi + IPv4_FRAGMENT_slot.ptr] |
393 | mov esi, [esi + IPv4_FRAGMENT_slot.ptr] |
394 | or edi, -1 |
394 | or edi, -1 |
395 | .find_last_entry: ; The following routine will try to find the last entry |
395 | .find_last_entry: ; The following routine will try to find the last entry |
396 | cmp edi, [esi + IPv4_FRAGMENT_entry.PrevPtr] |
396 | cmp edi, [esi + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.PrevPtr] |
397 | jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
397 | jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
398 | mov edi, esi |
398 | mov edi, esi |
399 | mov esi, [esi + IPv4_FRAGMENT_entry.NextPtr] |
399 | mov esi, [esi + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.NextPtr] |
400 | cmp esi, -1 |
400 | cmp esi, -1 |
401 | jne .find_last_entry |
401 | jne .find_last_entry |
402 | ; We found the last entry (pointer is now in edi) |
402 | ; We found the last entry (pointer is now in edi) |
Line 403... | Line 403... | ||
403 | ; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure |
403 | ; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure |
404 | 404 | ||
405 | pop eax ; pointer to packet |
405 | pop eax ; pointer to packet |
406 | mov [edi + IPv4_FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry |
406 | mov [edi + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry |
407 | mov [eax + IPv4_FRAGMENT_entry.NextPtr], -1 |
407 | mov [eax + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.NextPtr], -1 |
Line 408... | Line 408... | ||
408 | mov [eax + IPv4_FRAGMENT_entry.PrevPtr], edi |
408 | mov [eax + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.PrevPtr], edi |
Line 409... | Line 409... | ||
409 | mov [eax + IPv4_FRAGMENT_entry.Owner], ebx |
409 | mov [eax + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.Owner], ebx |
Line 435... | Line 435... | ||
435 | mov eax, [edx + IPv4_header.DestinationAddress] |
435 | mov eax, [edx + IPv4_header.DestinationAddress] |
436 | mov [esi + IPv4_FRAGMENT_slot.DstIP], eax |
436 | mov [esi + IPv4_FRAGMENT_slot.DstIP], eax |
437 | pop eax |
437 | pop eax |
438 | mov [esi + IPv4_FRAGMENT_slot.ptr], eax |
438 | mov [esi + IPv4_FRAGMENT_slot.ptr], eax |
439 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
439 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
440 | mov [eax + IPv4_FRAGMENT_entry.NextPtr], -1 |
440 | mov [eax + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.NextPtr], -1 |
441 | mov [eax + IPv4_FRAGMENT_entry.PrevPtr], -1 |
441 | mov [eax + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.PrevPtr], -1 |
442 | mov [eax + IPv4_FRAGMENT_entry.Owner], ebx |
442 | mov [eax + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.Owner], ebx |
Line 443... | Line 443... | ||
443 | 443 | ||
Line 444... | Line 444... | ||
444 | ret |
444 | ret |
Line 458... | Line 458... | ||
458 | push esi |
458 | push esi |
459 | xor eax, eax |
459 | xor eax, eax |
460 | or edi, -1 |
460 | or edi, -1 |
Line 461... | Line 461... | ||
461 | 461 | ||
462 | .count_bytes: |
462 | .count_bytes: |
463 | cmp [esi + IPv4_FRAGMENT_entry.PrevPtr], edi |
463 | cmp [esi + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.PrevPtr], edi |
464 | jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
464 | jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
465 | mov cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length |
465 | mov cx, [esi + sizeof.NET_BUFF + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length |
466 | xchg cl, ch |
466 | xchg cl, ch |
467 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx |
467 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx |
468 | add ax, cx |
468 | add ax, cx |
469 | movzx cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length |
469 | movzx cx, [esi + sizeof.NET_BUFF + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length |
470 | and cx, 0x000F |
470 | and cx, 0x000F |
471 | shl cx, 2 |
471 | shl cx, 2 |
472 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Header size=%u\n", cx |
472 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Header size=%u\n", cx |
473 | sub ax, cx |
473 | sub ax, cx |
474 | mov edi, esi |
474 | mov edi, esi |
475 | mov esi, [esi + IPv4_FRAGMENT_entry.NextPtr] |
475 | mov esi, [esi + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.NextPtr] |
476 | cmp esi, -1 |
476 | cmp esi, -1 |
Line 477... | Line 477... | ||
477 | jne .count_bytes |
477 | jne .count_bytes |
478 | 478 | ||
479 | mov esi, [esp+4] |
479 | mov esi, [esp+4] |
480 | mov [edi + IPv4_FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
480 | mov [edi + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
481 | mov [esi + IPv4_FRAGMENT_entry.NextPtr], -1 |
481 | mov [esi + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.NextPtr], -1 |
Line 482... | Line 482... | ||
482 | mov [esi + IPv4_FRAGMENT_entry.PrevPtr], edi |
482 | mov [esi + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.PrevPtr], edi |
483 | mov [esi + IPv4_FRAGMENT_entry.Owner], ebx |
483 | mov [esi + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.Owner], ebx |
484 | 484 | ||
485 | mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length |
485 | mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length |
Line 505... | Line 505... | ||
505 | test eax, eax |
505 | test eax, eax |
506 | je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot |
506 | je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot |
507 | mov edx, [esp+4] ; Get pointer to first fragment entry back in edx |
507 | mov edx, [esp+4] ; Get pointer to first fragment entry back in edx |
Line 508... | Line 508... | ||
508 | 508 | ||
509 | .rebuild_packet_loop: |
509 | .rebuild_packet_loop: |
510 | movzx ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset |
510 | movzx ecx, [edx + sizeof.NET_BUFF + sizeof.IPv4_FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset |
511 | xchg cl, ch ; intel byte order |
511 | xchg cl, ch ; intel byte order |
512 | shl cx, 3 ; multiply by 8 and clear first 3 bits |
512 | shl cx, 3 ; multiply by 8 and clear first 3 bits |
Line 513... | Line 513... | ||
513 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Fragment offset=%u\n", cx |
513 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Fragment offset=%u\n", cx |
514 | 514 | ||
515 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
515 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
516 | movzx ebx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment |
516 | movzx ebx, [edx + sizeof.NET_BUFF + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment |
Line 517... | Line 517... | ||
517 | and bx, 0x000F ; |
517 | and bx, 0x000F ; |
518 | shl bx, 2 ; |
518 | shl bx, 2 ; |
519 | 519 | ||
Line 520... | Line 520... | ||
520 | lea esi, [edx + sizeof.IPv4_FRAGMENT_entry] ; Set esi to the correct begin of fragment |
520 | lea esi, [edx + sizeof.NET_BUFF + sizeof.IPv4_FRAGMENT_entry] ; Set esi to the correct begin of fragment |
521 | movzx ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment |
521 | movzx ecx, [edx + sizeof.NET_BUFF + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment |
522 | xchg cl, ch ; intel byte order |
522 | xchg cl, ch ; intel byte order |
Line 535... | Line 535... | ||
535 | pop cx ; |
535 | pop cx ; |
536 | and cx, 3 ; |
536 | and cx, 3 ; |
537 | rep movsb ; |
537 | rep movsb ; |
Line 538... | Line 538... | ||
538 | 538 | ||
539 | push eax |
539 | push eax |
540 | push [edx + IPv4_FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet |
540 | push [edx + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet |
541 | push [edx + IPv4_FRAGMENT_entry.NextPtr] ; Set edx to the next pointer |
541 | push [edx + sizeof.NET_BUFF + IPv4_FRAGMENT_entry.NextPtr] ; Set edx to the next pointer |
542 | push edx ; Push pointer to fragment onto stack |
542 | push edx ; Push pointer to fragment onto stack |
543 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Next Fragment: 0x%x\n", edx |
543 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Next Fragment: 0x%x\n", edx |
544 | call net_buff_free ; free the previous fragment buffer (this uses the value from stack) |
544 | call net_buff_free ; free the previous fragment buffer (this uses the value from stack) |
545 | pop edx ebx eax |
545 | pop edx ebx eax |