Rev 1482 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1482 | Rev 1514 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2010. 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 | $Revision: 1482 $ |
- | |
20 | - | ||
21 | ; IP underlying protocols numbers |
- | |
22 | - | ||
23 | ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel |
19 | $Revision: 1514 $ |
24 | 20 | ||
- | 21 | MAX_FRAGMENTS equ 64 |
|
Line 25... | Line 22... | ||
25 | MAX_FRAGMENTS equ 16 |
22 | MAX_IP equ MAX_NET_DEVICES |
26 | MAX_IP equ MAX_NET_DEVICES |
23 | IP_MAX_INTERFACES equ MAX_IP |
27 | 24 | ||
28 | struct IPv4_Packet |
25 | struct IPv4_Packet |
29 | .VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] |
26 | .VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] |
30 | .TypeOfService db ? |
27 | .TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0] |
31 | .TotalLength dw ? |
28 | .TotalLength dw ? |
32 | .Identification dw ? |
29 | .Identification dw ? |
Line 56... | Line 53... | ||
56 | .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) |
57 | ends |
54 | ends |
Line 58... | Line 55... | ||
58 | 55 | ||
59 | align 4 |
56 | align 4 |
60 | uglobal |
- | |
- | 57 | uglobal |
|
61 | BROADCAST dd ? |
58 | |
62 | IP_LIST rd MAX_IP |
59 | IP_LIST rd MAX_IP |
63 | SUBNET_LIST rd MAX_IP |
60 | SUBNET_LIST rd MAX_IP |
64 | DNS_LIST rd MAX_IP |
61 | DNS_LIST rd MAX_IP |
- | 62 | GATEWAY_LIST rd MAX_IP |
|
65 | GATEWAY_LIST rd MAX_IP |
63 | |
66 | IP_PACKETS_TX rd MAX_IP |
64 | IP_PACKETS_TX rd MAX_IP |
- | 65 | IP_PACKETS_RX rd MAX_IP |
|
67 | IP_PACKETS_RX rd MAX_IP |
66 | |
68 | FRAGMENT_LIST rb MAX_FRAGMENTS*FRAGMENT_slot.size |
67 | FRAGMENT_LIST rb MAX_FRAGMENTS*FRAGMENT_slot.size |
Line 69... | Line 68... | ||
69 | endg |
68 | endg |
Line 81... | Line 80... | ||
81 | ;----------------------------------------------------------------- |
80 | ;----------------------------------------------------------------- |
82 | align 4 |
81 | align 4 |
83 | IPv4_init: |
82 | IPv4_init: |
Line 84... | Line 83... | ||
84 | 83 | ||
85 | or eax, -1 |
84 | or eax, -1 |
86 | mov edi, BROADCAST |
85 | mov edi, IP_LIST |
87 | mov ecx, 4*MAX_IP+1 |
86 | mov ecx, 4*MAX_IP |
Line 88... | Line 87... | ||
88 | rep stosd |
87 | rep stosd |
89 | 88 | ||
90 | xor eax, eax |
89 | inc eax |
91 | mov edi, FRAGMENT_LIST |
90 | mov edi, FRAGMENT_LIST |
Line 92... | Line 91... | ||
92 | mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP |
91 | mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP |
Line 112... | Line 111... | ||
112 | ; OUT: / |
111 | ; OUT: / |
113 | ; |
112 | ; |
114 | ;----------------------------------------------------------------- |
113 | ;----------------------------------------------------------------- |
115 | align 4 |
114 | align 4 |
116 | IPv4_handler: ; TODO: implement handler for IP options |
115 | IPv4_handler: ; TODO: implement handler for IP options |
117 | ; TODO2: add code for IPv4 sockets (raw sockets) |
116 | ; TODO2: add code for raw sockets |
118 | - | ||
119 | DEBUGF 1,"IP_Handler - start\n" |
- | |
Line -... | Line 117... | ||
- | 117 | ||
- | 118 | 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 |
|
- | 120 | DEBUGF 1,"to: %u.%u.%u.%u\n",\ |
|
Line 120... | Line 121... | ||
120 | 121 | [edx + IPv4_Packet.DestinationAddress]:1,[edx + IPv4_Packet.DestinationAddress + 1]:1,[edx + IPv4_Packet.DestinationAddress + 2]:1,[edx + IPv4_Packet.DestinationAddress + 3]:1 |
|
121 | 122 | ||
Line 122... | Line 123... | ||
122 | ;------------------------------------------- |
123 | ;------------------------------------------- |
Line 131... | Line 132... | ||
131 | movzx eax, [edx + IPv4_Packet.VersionAndIHL] |
132 | movzx eax, [edx + IPv4_Packet.VersionAndIHL] |
132 | and al , 0x0f ; get IHL(header length) |
133 | and al , 0x0f ; get IHL(header length) |
133 | cmp al , 0x05 ; IHL!= 5*4(20 bytes) |
134 | cmp al , 0x05 ; IHL!= 5*4(20 bytes) |
134 | jnz .has_options |
135 | jnz .has_options |
Line 135... | Line -... | ||
135 | - | ||
136 | 136 | ||
137 | ;------------------------------- |
137 | ;------------------------------- |
Line 138... | Line -... | ||
138 | ; Now, re-calcualte the checksum |
- | |
139 | 138 | ; Now, re-calculate the checksum |
|
140 | ; Re-calculate checksum |
139 | |
141 | push edx ebx |
140 | push edx ebx |
142 | mov esi, edx |
141 | mov esi, edx |
Line 143... | Line -... | ||
143 | call IPv4_checksum |
- | |
144 | pop ebx edx |
142 | call IPv4_checksum |
145 | 143 | pop ebx edx |
|
Line 146... | Line 144... | ||
146 | ; now see if it was correct |
144 | |
Line 147... | Line 145... | ||
147 | cmp [edx + IPv4_Packet.HeaderChecksum], 0 |
145 | cmp [edx + IPv4_Packet.HeaderChecksum], 0 |
148 | jne .dump ; if checksum isn't valid then dump packet |
146 | jne .dump ; if checksum isn't valid then dump packet |
Line 149... | Line 147... | ||
149 | 147 | ||
- | 148 | DEBUGF 1,"IPv4 Checksum is correct\n" |
|
Line 150... | Line -... | ||
150 | DEBUGF 1,"IPv4 Checksum is correct\n" |
- | |
151 | - | ||
152 | ;------------------------------------------------------- |
- | |
153 | ; Time to find out what interface this packet belongs to |
- | |
154 | - | ||
155 | ; Therefore we will scan the current list of IP's |
149 | |
156 | - | ||
157 | mov eax, [edx + IPv4_Packet.DestinationAddress] |
- | |
158 | mov edi, BROADCAST |
- | |
159 | mov ecx, MAX_IP+1 |
- | |
Line -... | Line 150... | ||
- | 150 | ;----------------------------------- |
|
160 | 151 | ; Check if destination IP is correct |
|
- | 152 | ||
- | 153 | call NET_ptr_to_num |
|
- | 154 | shl edi, 2 |
|
- | 155 | ||
- | 156 | ; check if it matches local ip |
|
161 | .find_ip_loop: |
157 | |
162 | cmp eax, dword [edi] |
158 | mov eax, dword[IP_LIST+edi] |
- | 159 | cmp [edx + IPv4_Packet.DestinationAddress], eax |
|
163 | jz .ip_ok |
160 | je .ip_ok |
Line 164... | Line 161... | ||
164 | add edi, 4 |
161 | |
Line 165... | Line 162... | ||
165 | dec ecx |
162 | ; check for broadcast |
- | 163 | ||
Line -... | Line 164... | ||
- | 164 | mov eax, dword[SUBNET_LIST+edi] |
|
- | 165 | not eax |
|
- | 166 | or eax, dword[IP_LIST+edi] |
|
- | 167 | cmp [edx + IPv4_Packet.DestinationAddress], eax |
|
- | 168 | je .ip_ok |
|
166 | jnz .find_ip_loop |
169 | |
Line -... | Line 170... | ||
- | 170 | ; or a special broadcast |
|
Line 167... | Line -... | ||
167 | - | ||
168 | ; it was not on the list, perhaps it's a loopback ? |
171 | |
- | 172 | cmp [edx + IPv4_Packet.DestinationAddress], -1 |
|
Line 169... | Line -... | ||
169 | not eax |
- | |
170 | test eax, 127 shl 24 ; 127.x.x.x |
- | |
171 | jz .ip_ok |
- | |
172 | 173 | je .ip_ok |
|
173 | ; TODO: we need to check for broadcasts (other then 255.255.255.255) |
- | |
Line -... | Line 174... | ||
- | 174 | ||
- | 175 | ; ; maybe it's a multicast then |
|
Line -... | Line 176... | ||
- | 176 | ; |
|
- | 177 | ; mov eax, [edx + IPv4_Packet.DestinationAddress] |
|
Line -... | Line 178... | ||
- | 178 | ; and eax, 0xff000000 |
|
- | 179 | ; cmp eax, 224 shl 24 |
|
Line 174... | Line 180... | ||
174 | 180 | ; je .ip_ok |
|
175 | DEBUGF 2,"Destination address does not match!\n" |
181 | |
Line 176... | Line 182... | ||
176 | 182 | ; or a loopback address |
|
177 | jmp .dump |
183 | |
Line 178... | Line 184... | ||
178 | 184 | cmp eax, 127 shl 24 |
|
179 | 185 | je .ip_ok |
|
Line 180... | Line -... | ||
180 | ;--------------------------------------------------- |
- | |
181 | ; Now we can update stats and find the device number |
- | |
182 | 186 | ||
183 | .ip_ok: |
187 | ; or it's not meant for us.. |
Line 184... | Line 188... | ||
184 | call ETH_struc2dev ; TODO: make this work on other protocols too! |
188 | |
185 | inc [IP_PACKETS_RX+4*edi] |
189 | DEBUGF 2,"Destination address does not match!\n" |
186 | DEBUGF 1,"Packet comes from %u.%u.%u.%u\n",\ |
190 | jmp .dump |
187 | [edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1 |
191 | |
188 | 192 | ;------------------------ |
|
189 | 193 | ; Now we can update stats |
|
190 | 194 | ||
Line 218... | Line 222... | ||
218 | mov edi, [edx + IPv4_Packet.DestinationAddress] ; |
222 | mov edi, [edx + IPv4_Packet.DestinationAddress] ; |
219 | mov al , [edx + IPv4_Packet.Protocol] |
223 | mov al , [edx + IPv4_Packet.Protocol] |
220 | pop edx ; Offset to data (tcp/udp/icmp/.. Packet) |
224 | pop edx ; Offset to data (tcp/udp/icmp/.. Packet) |
Line 221... | Line 225... | ||
221 | 225 | ||
222 | cmp al , IP_PROTO_TCP |
226 | cmp al , IP_PROTO_TCP |
Line 223... | Line 227... | ||
223 | je TCP_handler |
227 | je TCP_input |
224 | 228 | ||
Line 225... | Line 229... | ||
225 | cmp al , IP_PROTO_UDP |
229 | cmp al , IP_PROTO_UDP |
226 | je UDP_handler |
230 | je UDP_input |
Line 227... | Line 231... | ||
227 | 231 | ||
Line 228... | Line 232... | ||
228 | cmp al , IP_PROTO_ICMP |
232 | cmp al , IP_PROTO_ICMP |
229 | je ICMP_handler |
233 | je ICMP_input |
Line 349... | Line 353... | ||
349 | mov edi, esi |
353 | mov edi, esi |
350 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
354 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
351 | cmp esi, -1 |
355 | cmp esi, -1 |
352 | jne .count_bytes |
356 | jne .count_bytes |
Line 353... | Line 357... | ||
353 | 357 | ||
354 | mov esi, [esp+4] ;;; |
358 | mov esi, [esp+4] |
355 | mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
359 | mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
356 | mov [esi + FRAGMENT_entry.NextPtr], -1 |
360 | mov [esi + FRAGMENT_entry.NextPtr], -1 |
357 | mov [esi + FRAGMENT_entry.PrevPtr], edi |
361 | mov [esi + FRAGMENT_entry.PrevPtr], edi |
Line 461... | Line 465... | ||
461 | 465 | ||
462 | ;----------------------------------------------------------------- |
466 | ;----------------------------------------------------------------- |
463 | ; |
467 | ; |
464 | ; find fragment slot |
468 | ; find fragment slot |
465 | ; |
469 | ; |
466 | ; IN: pointer to fragmented packet in edx ; TODO: the RFC says we should check protocol too |
470 | ; IN: pointer to fragmented packet in edx |
467 | ; OUT: pointer to slot in edi, -1 on error |
471 | ; OUT: pointer to slot in edi, -1 on error |
468 | ; |
472 | ; |
469 | ;----------------------------------------------------------------- |
473 | ;----------------------------------------------------------------- |
470 | align 4 |
474 | align 4 |
Line -... | Line 475... | ||
- | 475 | IPv4_find_fragment_slot: |
|
- | 476 | ||
471 | IPv4_find_fragment_slot: |
477 | ;;; TODO: the RFC says we should check protocol number too |
472 | 478 | ||
473 | push eax ebx ecx edx |
479 | push eax ebx ecx edx |
474 | mov ax , word [edx + IPv4_Packet.Identification] |
480 | mov ax , word [edx + IPv4_Packet.Identification] |
475 | mov ecx, MAX_FRAGMENTS |
481 | mov ecx, MAX_FRAGMENTS |
Line 512... | Line 518... | ||
512 | cmp [esi + FRAGMENT_slot.ttl], 0 |
518 | cmp [esi + FRAGMENT_slot.ttl], 0 |
513 | je .try_next |
519 | je .try_next |
514 | dec [esi + FRAGMENT_slot.ttl] |
520 | dec [esi + FRAGMENT_slot.ttl] |
515 | jnz .try_next |
521 | jnz .try_next |
516 | DEBUGF 1,"Fragment slot timed-out!\n" |
522 | DEBUGF 1,"Fragment slot timed-out!\n" |
517 | ; TODO: clear all entry's of timed-out slot |
523 | ;;; TODO: clear all entry's of timed-out slot |
518 | .try_next: |
524 | .try_next: |
519 | add esi, 4 |
525 | add esi, 4 |
520 | loop .loop |
526 | loop .loop |
521 | ret |
527 | ret |
Line 522... | Line 528... | ||
522 | 528 | ||
- | 529 | ||
- | 530 | ||
- | 531 | ||
- | 532 | ||
- | 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 | ;------------------------------------------------------------------ |
|
- | 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 |
|
523 | 555 | ||
524 | 556 | ||
525 | 557 | ||
526 | 558 | ||
527 | ;----------------------------------------------------------------- |
559 | ;------------------------------------------------------------------ |
528 | ; |
560 | ; |
529 | ; Create_IPv4_Packet |
561 | ; Create_IPv4_Packet |
530 | ; |
562 | ; |
531 | ; IN: eax = dest ip |
563 | ; IN: eax = dest ip |
532 | ; ebx = source ip |
564 | ; ebx = source ip |
533 | ; ecx = data length |
565 | ; ecx = data length |
534 | ; dx = fragment id |
566 | ; dx = fragment id ;;;; |
535 | ; di = protocol |
567 | ; di = protocol |
536 | ; |
- | |
537 | ; OUT: eax = pointer to buffer start |
568 | ; |
538 | ; ebx = pointer to device struct (needed for sending procedure) |
569 | ; OUT: eax = pointer to buffer start |
539 | ; ecx = unchanged (packet size of embedded data) |
570 | ; ebx = pointer to device struct (needed for sending procedure) |
540 | ; edx = size of complete buffer |
571 | ; ecx = unchanged (packet size of embedded data) |
541 | ; esi = pointer to sending procedure |
572 | ; edx = size of complete buffer |
Line 542... | Line 573... | ||
542 | ; edi = pointer to start of data (-1 on error) |
573 | ; edi = pointer to start of data (0 on error) |
Line 543... | Line 574... | ||
543 | ; |
574 | ; |
544 | ;----------------------------------------------------------------- ;;; TODO: create fragmented packets |
575 | ;------------------------------------------------------------------ |
Line 545... | Line 576... | ||
545 | align 4 |
576 | align 4 |
546 | IPv4_create_packet: |
577 | IPv4_create_packet: |
547 | 578 | ||
548 | DEBUGF 1,"Create IPv4 Packet (size=%u)\n", ecx |
579 | DEBUGF 1,"Create IPv4 Packet (size=%u)\n", ecx |
549 | 580 | ||
550 | cmp ecx, 1480 |
581 | cmp ecx, 65500 ; Max IPv4 packet size |
551 | jg .exit_ |
582 | jg .exit_ |
552 | 583 | ||
553 | test ebx, ebx ; if dest ip = 0 |
584 | test ebx, ebx ; if source ip = 0 |
Line 554... | Line 585... | ||
554 | jnz .ip_ok ; and local ip is valid |
585 | jnz .ip_ok ; and local ip is valid |
Line 555... | Line 586... | ||
555 | ; use local ip instead |
586 | ; use local ip instead |
556 | cmp [IP_LIST],0xffffffff ; |
587 | cmp [IP_LIST],0xffffffff ; |
Line 557... | Line 588... | ||
557 | je .ip_ok ; TODO: find solution to send broadcast |
588 | je .ip_ok ; TODO: find solution to send broadcast |
Line 558... | Line 589... | ||
558 | ; on device other then device 0 |
589 | ; on device other then device 0 |
559 | mov ebx, [IP_LIST] ; |
590 | mov ebx, [IP_LIST] ; |
Line 580... | Line 611... | ||
580 | push dword -1 |
611 | push dword -1 |
Line 581... | Line 612... | ||
581 | 612 | ||
582 | .send: |
613 | .send: |
583 | call IPv4_dest_to_dev |
614 | call IPv4_dest_to_dev |
584 | inc [IP_PACKETS_TX+4*edi] |
615 | inc [IP_PACKETS_TX+4*edi] |
585 | mov edx, [ETH_DRV_LIST + 4*edi] |
616 | mov edx, [NET_DRV_LIST + 4*edi] |
586 | lea eax, [edx + ETH_DEVICE.mac] |
617 | lea eax, [edx + ETH_DEVICE.mac] |
587 | mov ebx, esp |
618 | mov ebx, esp |
588 | mov ecx, [esp+18] ;; 18 or 22 ?? |
619 | mov ecx, [esp+18] ;; 18 or 22 ?? |
589 | add ecx, IPv4_Packet.DataOrOptional |
620 | add ecx, IPv4_Packet.DataOrOptional |
- | 621 | mov di , ETHER_IPv4 |
|
590 | mov di , ETHER_IPv4 |
622 | ;;; TODO: detect if packet is too large for ethernet, if so, call IPv4_fragment |
591 | call ETH_create_packet ; TODO: figure out a way to make this work with other protocols too |
623 | call ETH_create_packet ;;; TODO: figure out a way to make this work with other protocols too |
592 | add esp, 6 |
624 | add esp, 6 |
593 | cmp edi, -1 |
625 | test edi, edi |
Line 594... | Line 626... | ||
594 | je .exit |
626 | jz .exit |
595 | 627 | ||
596 | mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) |
628 | mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) |
597 | mov [edi + IPv4_Packet.TypeOfService], 0 |
629 | mov [edi + IPv4_Packet.TypeOfService], 0 |
Line 613... | Line 645... | ||
613 | mov esi, edi |
645 | mov esi, edi |
614 | call IPv4_checksum |
646 | call IPv4_checksum |
615 | pop esi edx eax ecx |
647 | pop esi edx eax ecx |
616 | add edi, IPv4_Packet.DataOrOptional |
648 | add edi, IPv4_Packet.DataOrOptional |
Line 617... | Line 649... | ||
617 | 649 | ||
Line 618... | Line 650... | ||
618 | DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx |
650 | DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx |
Line 619... | Line 651... | ||
619 | 651 | ||
620 | ret |
652 | ret |
621 | 653 | ||
622 | 654 | ||
623 | .not_found: |
655 | .not_found: |
624 | DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n" |
656 | DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n" |
625 | ; TODO: QUEUE the packet to resend later! |
657 | ;;;;;; |
626 | .exit: |
658 | .exit: |
627 | add esp, 16 |
659 | add esp, 16 |
Line 628... | Line 660... | ||
628 | .exit_: |
660 | .exit_: |