Rev 1519 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1519 | Rev 1529 | ||
---|---|---|---|
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: 1519 $ |
19 | $Revision: 1529 $ |
20 | 20 | ||
21 | MAX_FRAGMENTS equ 64 |
21 | MAX_FRAGMENTS equ 64 |
Line 51... | Line 51... | ||
51 | .Owner dd ? ; Pointer to structure of driver |
51 | .Owner dd ? ; Pointer to structure of driver |
52 | rb 2 ; to match ethernet header size ; TODO: fix this hack |
52 | rb 2 ; to match ethernet header size ; TODO: fix this hack |
53 | .Data: ; Ip header begins here (we will need the IP header to re-construct the complete packet) |
53 | .Data: ; Ip header begins here (we will need the IP header to re-construct the complete packet) |
54 | ends |
54 | ends |
Line -... | Line 55... | ||
- | 55 | ||
- | 56 | ||
- | 57 | ||
- | 58 | ||
- | 59 | macro IPv4_checksum ptr { |
|
- | 60 | ||
- | 61 | ; This is the fast procedure to create or check a IP header without options |
|
- | 62 | ; To create a new checksum, the checksum field must be set to 0 before computation |
|
- | 63 | ; To check an existing checksum, leave the checksum as is, and it will be 0 after this procedure, if it was correct |
|
- | 64 | ||
- | 65 | push ebx |
|
- | 66 | xor ebx, ebx |
|
- | 67 | add bl, [ptr+1] |
|
- | 68 | adc bh, [ptr+0] |
|
- | 69 | ||
- | 70 | adc bl, [ptr+3] |
|
- | 71 | adc bh, [ptr+2] |
|
- | 72 | ||
- | 73 | adc bl, [ptr+5] |
|
- | 74 | adc bh, [ptr+4] |
|
- | 75 | ||
- | 76 | adc bl, [ptr+7] |
|
- | 77 | adc bh, [ptr+6] |
|
- | 78 | ||
- | 79 | adc bl, [ptr+9] |
|
- | 80 | adc bh, [ptr+8] |
|
- | 81 | ||
- | 82 | ; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation |
|
- | 83 | ||
- | 84 | adc bl, [ptr+13] |
|
- | 85 | adc bh, [ptr+12] |
|
- | 86 | ||
- | 87 | adc bl, [ptr+15] |
|
- | 88 | adc bh, [ptr+14] |
|
- | 89 | ||
- | 90 | adc bl, [ptr+17] |
|
- | 91 | adc bh, [ptr+16] |
|
- | 92 | ||
- | 93 | adc bl, [ptr+19] |
|
- | 94 | adc bh, [ptr+18] |
|
- | 95 | ||
- | 96 | adc ebx, 0 |
|
- | 97 | ||
- | 98 | push ecx |
|
- | 99 | mov ecx, ebx |
|
- | 100 | shr ecx, 16 |
|
- | 101 | and ebx, 0xffff |
|
- | 102 | add ebx, ecx |
|
- | 103 | ||
- | 104 | mov ecx, ebx |
|
- | 105 | shr ecx, 16 |
|
- | 106 | add ebx, ecx |
|
- | 107 | ||
- | 108 | not bx |
|
- | 109 | jnz .not_zero |
|
- | 110 | dec bx |
|
- | 111 | .not_zero: |
|
- | 112 | xchg bl, bh |
|
- | 113 | pop ecx |
|
- | 114 | ||
- | 115 | neg word [ptr+10] ; zero will stay zero so we just get the checksum |
|
- | 116 | add word [ptr+10], bx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :) |
|
- | 117 | pop ebx |
|
- | 118 | ||
- | 119 | } |
|
- | 120 | ||
- | 121 | ||
55 | 122 | ||
56 | align 4 |
123 | align 4 |
Line 57... | Line 124... | ||
57 | uglobal |
124 | uglobal |
58 | 125 | ||
Line 72... | Line 139... | ||
72 | ; |
139 | ; |
73 | ; IPv4_init |
140 | ; IPv4_init |
74 | ; |
141 | ; |
75 | ; This function resets all IP variables |
142 | ; This function resets all IP variables |
76 | ; |
143 | ; |
77 | ; IN: / |
- | |
78 | ; OUT: / |
- | |
79 | ; |
- | |
80 | ;----------------------------------------------------------------- |
144 | ;----------------------------------------------------------------- |
81 | align 4 |
- | |
82 | IPv4_init: |
145 | macro IPv4_init { |
Line 83... | Line 146... | ||
83 | 146 | ||
84 | or eax, -1 |
147 | xor eax, eax |
85 | mov edi, IP_LIST |
148 | mov edi, IP_LIST |
86 | mov ecx, 4*MAX_IP |
149 | mov ecx, 4*MAX_IP |
Line 87... | Line -... | ||
87 | rep stosd |
- | |
88 | 150 | rep stosd |
|
89 | inc eax |
151 | |
90 | mov edi, FRAGMENT_LIST |
152 | mov edi, FRAGMENT_LIST |
Line -... | Line 153... | ||
- | 153 | mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP |
|
- | 154 | rep stosd |
|
- | 155 | ||
- | 156 | } |
|
- | 157 | ||
- | 158 | ||
- | 159 | ;----------------------------------------------------------------- |
|
- | 160 | ; |
|
- | 161 | ; Decrease TimeToLive of all fragment slots |
|
- | 162 | ; |
|
- | 163 | ;----------------------------------------------------------------- |
|
- | 164 | macro IPv4_decrease_fragment_ttls { |
|
- | 165 | ||
- | 166 | local .loop |
|
- | 167 | ||
- | 168 | mov esi, FRAGMENT_LIST |
|
91 | mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP |
169 | mov ecx, MAX_FRAGMENTS |
- | 170 | .loop: |
|
- | 171 | cmp [esi + FRAGMENT_slot.ttl], 0 |
|
- | 172 | je .try_next |
|
- | 173 | dec [esi + FRAGMENT_slot.ttl] |
|
- | 174 | jnz .try_next |
|
- | 175 | DEBUGF 1,"Fragment slot timed-out!\n" |
|
- | 176 | ;;; TODO: clear all entry's of timed-out slot |
|
- | 177 | .try_next: |
|
Line 92... | Line 178... | ||
92 | rep stosd |
178 | add esi, 4 |
93 | 179 | loop .loop |
|
94 | ret |
180 | } |
95 | 181 | ||
96 | 182 | ||
97 | 183 | ||
98 | ;----------------------------------------------------------------- |
184 | ;----------------------------------------------------------------- |
99 | ; |
185 | ; |
Line 110... | Line 196... | ||
110 | ; pointer to IP Packet data in edx |
196 | ; pointer to IP Packet data in edx |
111 | ; OUT: / |
197 | ; OUT: / |
112 | ; |
198 | ; |
113 | ;----------------------------------------------------------------- |
199 | ;----------------------------------------------------------------- |
114 | align 4 |
200 | align 4 |
115 | IPv4_handler: ; TODO: implement handler for IP options |
201 | IPv4_input: ; TODO: implement handler for IP options |
116 | ; TODO2: add code for raw sockets |
202 | ; TODO2: add code for raw sockets |
Line 117... | Line 203... | ||
117 | 203 | ||
118 | DEBUGF 1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\ |
204 | DEBUGF 1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\ |
119 | [edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1 |
205 | [edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1 |
Line 135... | Line 221... | ||
135 | jnz .has_options |
221 | jnz .has_options |
Line 136... | Line 222... | ||
136 | 222 | ||
137 | ;------------------------------- |
223 | ;------------------------------- |
Line 138... | Line -... | ||
138 | ; Now, re-calculate the checksum |
- | |
139 | - | ||
140 | push edx ebx |
224 | ; Now, re-calculate the checksum |
141 | mov esi, edx |
- | |
142 | call IPv4_checksum |
- | |
143 | pop ebx edx |
- | |
144 | 225 | ||
Line 145... | Line 226... | ||
145 | cmp [edx + IPv4_Packet.HeaderChecksum], 0 |
226 | IPv4_checksum edx |
Line 146... | Line 227... | ||
146 | jne .dump ; if checksum isn't valid then dump packet |
227 | jnz .dump ; if checksum isn't valid then dump packet |
147 | 228 | ||
Line 433... | Line 514... | ||
433 | push ecx ;;;; |
514 | push ecx ;;;; |
434 | push eax ;;;; |
515 | push eax ;;;; |
Line 435... | Line 516... | ||
435 | 516 | ||
436 | ; mov esi, edx ; This prints the IP packet to the debug board (usefull when using serial output debug..) |
517 | ; mov esi, edx ; This prints the IP packet to the debug board (usefull when using serial output debug..) |
437 | ; ; |
- | |
438 | ; @@: ; |
- | |
439 | ; lodsb ; |
- | |
440 | ; DEBUGF 1,"%x ", eax:2 ; |
518 | ; ; |
Line 441... | Line 519... | ||
441 | ; loop @r ; |
519 | ; packet_to_debug |
Line 442... | Line 520... | ||
442 | 520 | ||
443 | jmp .handle_it ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr |
521 | jmp .handle_it ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr |
Line 458... | Line 536... | ||
458 | .has_options: |
536 | .has_options: |
459 | jmp .dump |
537 | jmp .dump |
Line 460... | Line -... | ||
460 | - | ||
461 | - | ||
462 | - | ||
463 | 538 | ||
464 | 539 | ||
465 | 540 | ||
466 | ;----------------------------------------------------------------- |
541 | ;----------------------------------------------------------------- |
467 | ; |
542 | ; |
Line 499... | Line 574... | ||
499 | .found_slot: |
574 | .found_slot: |
500 | pop edx ecx ebx eax |
575 | pop edx ecx ebx eax |
501 | ret |
576 | ret |
Line 502... | Line -... | ||
502 | - | ||
503 | - | ||
504 | ;----------------------------------------------------------------- |
- | |
505 | ; |
- | |
506 | ; Decrease TimeToLive of all fragment slots |
- | |
507 | ; |
- | |
508 | ; IN: / |
- | |
509 | ; OUT: / |
- | |
510 | ; |
- | |
511 | ;----------------------------------------------------------------- |
- | |
512 | align 4 |
- | |
513 | IPv4_decrease_fragment_ttls: |
- | |
514 | - | ||
515 | mov esi, FRAGMENT_LIST |
- | |
516 | mov ecx, MAX_FRAGMENTS |
- | |
517 | .loop: |
- | |
518 | cmp [esi + FRAGMENT_slot.ttl], 0 |
- | |
519 | je .try_next |
- | |
520 | dec [esi + FRAGMENT_slot.ttl] |
- | |
521 | jnz .try_next |
- | |
522 | DEBUGF 1,"Fragment slot timed-out!\n" |
- | |
523 | ;;; TODO: clear all entry's of timed-out slot |
- | |
524 | .try_next: |
- | |
525 | add esi, 4 |
- | |
526 | loop .loop |
- | |
527 | ret |
- | |
528 | - | ||
529 | - | ||
530 | - | ||
531 | 577 | ||
532 | 578 | ||
533 | ;------------------------------------------------------------------ |
- | |
534 | ; |
- | |
535 | ; |
- | |
536 | ; IN: dword [esp] = pointer to packet to be fragmented |
- | |
537 | ; dword [esp+4] = buffer size |
- | |
538 | ; edx = pointer to IPv4 header in that packet |
- | |
539 | ; ecx = data length |
- | |
540 | ; ebx = device structure |
- | |
541 | ; |
- | |
542 | ; OUT: / |
- | |
543 | ; |
- | |
544 | ;------------------------------------------------------------------ |
579 | ;------------------------------------------------------------------ |
545 | align 4 |
- | |
546 | IPv4_fragment: |
- | |
547 | - | ||
548 | ;;; TODO: write code here |
- | |
549 | - | ||
550 | - | ||
551 | call kernel_free |
- | |
552 | add esp, 4 |
- | |
553 | - | ||
554 | ret |
- | |
555 | - | ||
556 | - | ||
557 | - | ||
558 | - | ||
559 | ;------------------------------------------------------------------ |
- | |
560 | ; |
580 | ; |
561 | ; Create_IPv4_Packet |
581 | ; IPv4_output |
562 | ; |
582 | ; |
563 | ; IN: eax = dest ip |
583 | ; IN: eax = dest ip |
564 | ; ebx = source ip |
584 | ; ebx = source ip |
565 | ; ecx = data length |
585 | ; ecx = data length |
566 | ; dx = fragment id ;;;; |
586 | ; dx = fragment id |
567 | ; di = protocol |
587 | ; di = TTL shl 8 + protocol |
568 | ; |
588 | ; |
569 | ; OUT: eax = pointer to buffer start |
589 | ; OUT: eax = pointer to buffer start |
570 | ; ebx = pointer to device struct (needed for sending procedure) |
590 | ; ebx = pointer to device struct (needed for sending procedure) |
571 | ; ecx = unchanged (packet size of embedded data) |
591 | ; ecx = unchanged (packet size of embedded data) |
572 | ; edx = size of complete buffer |
592 | ; edx = size of complete buffer |
573 | ; edi = pointer to start of data (0 on error) |
593 | ; edi = pointer to start of data (0 on error) |
574 | ; |
594 | ; |
575 | ;------------------------------------------------------------------ |
595 | ;------------------------------------------------------------------ |
Line 576... | Line 596... | ||
576 | align 4 |
596 | align 4 |
Line 577... | Line 597... | ||
577 | IPv4_create_packet: |
597 | IPv4_output: |
578 | 598 | ||
579 | DEBUGF 1,"Create IPv4 Packet (size=%u)\n", ecx |
- | |
580 | - | ||
581 | cmp ecx, 65500 ; Max IPv4 packet size |
- | |
582 | jg .exit_ |
- | |
583 | - | ||
584 | test ebx, ebx ; if source ip = 0 |
- | |
585 | jnz .ip_ok ; and local ip is valid |
- | |
586 | ; use local ip instead |
- | |
587 | cmp [IP_LIST],0xffffffff ; |
- | |
588 | je .ip_ok ; TODO: find solution to send broadcast |
- | |
Line 589... | Line 599... | ||
589 | ; on device other then device 0 |
599 | DEBUGF 1,"IPv4_create_packet: size=%u\n", ecx |
Line 590... | Line -... | ||
590 | mov ebx, [IP_LIST] ; |
- | |
591 | ; |
- | |
592 | .ip_ok: ; |
- | |
593 | 600 | ||
Line 594... | Line 601... | ||
594 | push ecx eax ebx dx di |
601 | cmp ecx, 65500 ; Max IPv4 packet size |
595 | 602 | jg .too_large |
|
Line 596... | Line 603... | ||
596 | cmp eax, -1 |
603 | |
597 | je .broadcast ; If it is broadcast, just send |
604 | push ecx eax ebx dx di |
Line 598... | Line -... | ||
598 | - | ||
599 | call ARP_IP_to_MAC |
- | |
600 | - | ||
601 | cmp eax, -1 |
- | |
602 | je .not_found |
- | |
603 | - | ||
604 | push ebx |
- | |
605 | push ax |
605 | |
606 | 606 | call ARP_IP_to_MAC |
|
607 | jmp .send |
607 | |
608 | 608 | test eax, 0xffff0000 ; error bits |
|
609 | .broadcast: |
609 | jnz .arp_error |
610 | push word -1 |
610 | |
611 | push dword -1 |
611 | push ebx ; push the mac |
612 | 612 | push ax |
|
613 | .send: |
- | |
614 | call IPv4_dest_to_dev |
- | |
615 | inc [IP_PACKETS_TX+4*edi] |
- | |
616 | mov edx, [NET_DRV_LIST + 4*edi] |
613 | |
617 | lea eax, [edx + ETH_DEVICE.mac] |
614 | call IPv4_dest_to_dev |
- | 615 | inc [IP_PACKETS_TX+edi] |
|
- | 616 | mov ebx, [NET_DRV_LIST+edi] |
|
Line 618... | Line 617... | ||
618 | mov ebx, esp |
617 | lea eax, [ebx + ETH_DEVICE.mac] |
619 | mov ecx, [esp+18] ;; 18 or 22 ?? |
618 | mov edx, esp |
620 | add ecx, IPv4_Packet.DataOrOptional |
- | |
621 | mov di , ETHER_IPv4 |
619 | mov ecx, [esp + 18] |
- | 620 | add ecx, IPv4_Packet.DataOrOptional |
|
622 | ;;; TODO: detect if packet is too large for ethernet, if so, call IPv4_fragment |
621 | mov di , ETHER_IPv4 |
623 | call ETH_create_packet ;;; TODO: figure out a way to make this work with other protocols too |
- | |
624 | add esp, 6 |
622 | call ETH_output |
625 | test edi, edi |
623 | jz .error |
626 | jz .exit |
624 | |
627 | - | ||
628 | mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) |
625 | add esp, 6 ; pop the mac |
629 | mov [edi + IPv4_Packet.TypeOfService], 0 |
626 | |
630 | xchg ch, cl |
627 | mov [edi + IPv4_Packet.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_Packet.TotalLength], cx |
629 | mov [edi + IPv4_Packet.TotalLength], cx |
632 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000 |
- | |
Line 633... | Line -... | ||
633 | mov [edi + IPv4_Packet.TimeToLive], 128 |
- | |
634 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
- | |
635 | pop cx |
630 | rol [edi + IPv4_Packet.TotalLength], 8 ; internet byte order |
636 | mov [edi + IPv4_Packet.Protocol], cl |
- | |
637 | pop cx |
631 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000 |
638 | mov [edi + IPv4_Packet.Identification], cx |
- | |
639 | pop ecx |
632 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
640 | mov [edi + IPv4_Packet.SourceAddress], ecx |
- | |
641 | pop ecx |
633 | popw word [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol |
Line 642... | Line -... | ||
642 | mov [edi + IPv4_Packet.DestinationAddress], ecx |
- | |
643 | 634 | ; [edi + IPv4_Packet.Protocol] |
|
644 | push eax edx esi |
- | |
645 | mov esi, edi |
635 | popw [edi + IPv4_Packet.Identification] ; fragment id |
646 | call IPv4_checksum |
636 | popd [edi + IPv4_Packet.SourceAddress] |
647 | pop esi edx eax ecx |
637 | popd [edi + IPv4_Packet.DestinationAddress] |
648 | add edi, IPv4_Packet.DataOrOptional |
638 | |
649 | 639 | pop ecx |
|
650 | DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx |
640 | |
651 | 641 | IPv4_checksum edi |
|
Line -... | Line 642... | ||
- | 642 | add edi, IPv4_Packet.DataOrOptional |
|
- | 643 | DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx |
|
- | 644 | ret |
|
- | 645 | ||
- | 646 | .error: |
|
- | 647 | add esp, 6 |
|
- | 648 | .arp_error: |
|
- | 649 | add esp, 4+4+4+2+2 |
|
- | 650 | .too_large: |
|
- | 651 | DEBUGF 1,"IPv4_create_packet: Failed\n" |
|
- | 652 | sub edi, edi |
|
Line 652... | Line 653... | ||
652 | ret |
653 | ret |
653 | 654 | ||
Line 654... | Line 655... | ||
654 | 655 | ||
655 | .not_found: |
- | |
656 | DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n" |
- | |
657 | ;;;;;; |
- | |
658 | .exit: |
- | |
Line 659... | Line 656... | ||
659 | add esp, 16 |
656 | ;-------------------------------------------------------- |
Line 660... | Line 657... | ||
660 | .exit_: |
657 | ; |
661 | DEBUGF 1,"Create IPv4 Packet - failed\n" |
658 | ; |
Line 662... | Line 659... | ||
662 | and edi, 0 |
659 | ; IN: dword [esp] = pointer to buffer containing ipv4 packet to be fragmented |
- | 660 | ; dword [esp+4] = buffer size |
|
- | 661 | ; esi = pointer to ip header in that buffer |
|
663 | ret |
662 | ; ecx = max size of fragments |
- | 663 | ; |
|
- | 664 | ; OUT: / |
|
Line 664... | Line 665... | ||
664 | 665 | ; |
|
665 | 666 | ;-------------------------------------------------------- |
|
Line 666... | Line 667... | ||
666 | 667 | ||
- | 668 | align 4 |
|
667 | align 4 |
669 | IPv4_fragment: |
Line 668... | Line -... | ||
668 | IPv4_checksum: |
- | |
669 | - | ||
Line -... | Line 670... | ||
- | 670 | ||
670 | ; This is the fast procedure to create or check a IP header without options |
671 | DEBUGF 1,"IPv4_fragment\n" |
- | 672 | ||
- | 673 | and ecx, not 111b ; align 4 |
|
Line 671... | Line 674... | ||
671 | ; |
674 | |
672 | ; To create a new checksum, the checksum field must be set to 0 before computation |
675 | cmp ecx, IPv4_Packet.DataOrOptional + 8 ; must be able to put at least 8 bytes |
Line 673... | Line -... | ||
673 | ; |
- | |
674 | ; To check an existing checksum, leave the checksum as is, and it will be 0 after this procedure, if it was correct |
- | |
Line 675... | Line 676... | ||
675 | 676 | jl .err2 |
|
676 | xor edx, edx |
677 | |
- | 678 | push esi ecx |
|
- | 679 | mov eax, [esi + IPv4_Packet.DestinationAddress] |
|
Line 677... | Line 680... | ||
677 | 680 | call ARP_IP_to_MAC |
|
678 | add dl, [esi+1] |
681 | pop ecx esi |
Line -... | Line 682... | ||
- | 682 | cmp eax, -1 |
|
- | 683 | jz .err2 |
|
- | 684 | ||
- | 685 | push ebx |
|
- | 686 | push ax |
|
- | 687 | ||
- | 688 | mov ebx, [NET_DRV_LIST] |
|
- | 689 | lea eax, [ebx + ETH_DEVICE.mac] |
|
- | 690 | push eax |
|
- | 691 | ||
- | 692 | ||
- | 693 | push esi ; ptr to ip header |
|
- | 694 | sub ecx, 20 ; substract header size |
|
- | 695 | push ecx ; max data size |
|
- | 696 | push dword 0 ; offset |
|
- | 697 | ||
679 | adc dh, [esi+0] |
698 | .new_fragment: |
- | 699 | DEBUGF 1,"Ipv4_fragment - new_fragmentn" |
|
- | 700 | ||
Line -... | Line 701... | ||
- | 701 | ||
680 | 702 | mov eax, [esp + 3*4] |
|
Line 681... | Line 703... | ||
681 | adc dl, [esi+3] |
703 | lea ebx, [esp + 4*4] |
- | 704 | mov di , ETHER_IPv4 |
|
- | 705 | call ETH_output |
|
- | 706 | ||
682 | adc dh, [esi+2] |
707 | cmp edi, -1 |
Line -... | Line 708... | ||
- | 708 | jz .err |
|
- | 709 | ||
- | 710 | ; copy header |
|
- | 711 | mov esi, [esp + 2*4] |
|
- | 712 | mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header! |
|
- | 713 | rep movsd |
|
- | 714 | ||
683 | 715 | ; copy data |
|
- | 716 | mov esi, [esp + 2*4] |
|
- | 717 | add esi, 20 |
|
- | 718 | add esi, [esp] ; offset |
|
- | 719 | ||
- | 720 | mov ecx, [esp + 1*4] |
|
- | 721 | DEBUGF 1,"IPv4_fragment - copying data (%u bytes)\n", ecx |
|
- | 722 | rep movsb |
|
- | 723 | ||
- | 724 | ; now, correct header |
|
- | 725 | mov ecx, [esp + 1*4] |
|
- | 726 | add ecx, 20 |
|
- | 727 | xchg cl, ch |
|
- | 728 | mov [edi + IPv4_Packet.TotalLength], cx |
|
- | 729 | ||
- | 730 | mov ecx, [esp] ; offset |
|
- | 731 | xchg cl, ch |
|
- | 732 | ||
- | 733 | ; cmp dword[esp + 4*4], 0 ; last fragment?;<<<<<< |
|
Line -... | Line 734... | ||
- | 734 | ; je .last_fragment |
|
- | 735 | or cx, 1 shl 2 ; more fragments |
|
- | 736 | ; .last_fragment: |
|
- | 737 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], cx |
|
- | 738 | ||
- | 739 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
|
- | 740 | ||
- | 741 | ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet |
|
Line -... | Line 742... | ||
- | 742 | mov ecx, [esp + 1*4] |
|
Line 684... | Line 743... | ||
684 | adc dl, [esi+5] |
743 | |
685 | adc dh, [esi+4] |
744 | push edx eax |
686 | 745 | IPv4_checksum edi |
|
687 | adc dl, [esi+7] |
746 | |
688 | adc dh, [esi+6] |
747 | call [ebx + NET_DEVICE.transmit] |
689 | 748 | ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< |
|
690 | adc dl, [esi+9] |
749 | |
691 | adc dh, [esi+8] |
750 | mov ecx, [esp+4] |
692 | 751 | add [esp], ecx |
|
693 | ; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation |
752 | |
Line 694... | Line 753... | ||
694 | 753 | mov ecx, [esp+3*4+6+4] ; ptr to begin of buff |
|
- | 754 | add ecx, [esp+3*4+6+4+4] ; buff size |
|
Line 695... | Line 755... | ||
695 | adc dl, [esi+13] |
755 | sub ecx, [esp+2*4] ; ptr to ip header |
696 | adc dh, [esi+12] |
756 | add ecx, [esp] ; offset |
Line 697... | Line 757... | ||
697 | 757 | ||
698 | adc dl, [esi+15] |
758 | DEBUGF 1,"Ipv4_fragment - bytes remaining: %u\n", ecx |
699 | adc dh, [esi+14] |
759 | |
700 | 760 | cmp ecx, [esp+1*4] |
|
- | 761 | jge .new_fragment |
|
701 | adc dl, [esi+17] |
762 | |
702 | adc dh, [esi+16] |
763 | mov [esp+4], ecx ; set fragment size to remaining packet size |
Line 703... | Line 764... | ||
703 | 764 | jmp .new_fragment |
|
704 | adc dl, [esi+19] |
765 | |
705 | adc dh, [esi+18] |
766 | .err: |
706 | 767 | DEBUGF 1,"Ipv4_fragment - failed\n" |
|
707 | adc edx, 0 |
768 | .done: |
Line -... | Line 769... | ||
- | 769 | add esp, 12 + 4 + 6 |
|
708 | 770 | .err2: |
|
Line 709... | Line 771... | ||
709 | call checksum_2 |
771 | DEBUGF 1,"Ipv4_fragment - dumping\n" |
710 | - | ||
711 | neg word [esi+10] ; zero will stay zero so we just get the checksum |
- | |
712 | add word [esi+10], dx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :) |
772 | call kernel_free |
Line 713... | Line 773... | ||
713 | 773 | add esp, 4 |
|
Line 867... | Line 927... | ||
867 | .write_gateway: |
927 | .write_gateway: |
868 | add eax, GATEWAY_LIST |
928 | add eax, GATEWAY_LIST |
869 | mov [eax], ecx |
929 | mov [eax], ecx |
870 | xor eax, eax |
930 | xor eax, eax |
871 | ret |
931 | ret |
872 | - | ||
873 | - | ||
874 | - | ||
875 | - |