]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/ipv4/ip.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / lwIP_Demo_Rowley_ARM7 / lwip-1.1.0 / src / core / ipv4 / ip.c
1 /* @file\r
2  *\r
3  * This is the IP layer implementation for incoming and outgoing IP traffic.\r
4  * \r
5  * @see ip_frag.c\r
6  *\r
7  */\r
8 /*\r
9  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
10  * All rights reserved.\r
11  *\r
12  * Redistribution and use in source and binary forms, with or without modification,\r
13  * are permitted provided that the following conditions are met:\r
14  *\r
15  * 1. Redistributions of source code must retain the above copyright notice,\r
16  *    this list of conditions and the following disclaimer.\r
17  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
18  *    this list of conditions and the following disclaimer in the documentation\r
19  *    and/or other materials provided with the distribution.\r
20  * 3. The name of the author may not be used to endorse or promote products\r
21  *    derived from this software without specific prior written permission.\r
22  *\r
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
24  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
26  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
28  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
31  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
32  * OF SUCH DAMAGE.\r
33  *\r
34  * This file is part of the lwIP TCP/IP stack.\r
35  *\r
36  * Author: Adam Dunkels <adam@sics.se>\r
37  *\r
38  */\r
39 \r
40 #include "lwip/opt.h"\r
41 \r
42 #include "lwip/def.h"\r
43 #include "lwip/mem.h"\r
44 #include "lwip/ip.h"\r
45 #include "lwip/ip_frag.h"\r
46 #include "lwip/inet.h"\r
47 #include "lwip/netif.h"\r
48 #include "lwip/icmp.h"\r
49 #include "lwip/raw.h"\r
50 #include "lwip/udp.h"\r
51 #include "lwip/tcp.h"\r
52 \r
53 #include "lwip/stats.h"\r
54 \r
55 #include "arch/perf.h"\r
56 \r
57 #include "lwip/snmp.h"\r
58 #if LWIP_DHCP\r
59 #  include "lwip/dhcp.h"\r
60 #endif /* LWIP_DHCP */\r
61 \r
62 \r
63 /**\r
64  * Initializes the IP layer.\r
65  */\r
66 \r
67 void\r
68 ip_init(void)\r
69 {\r
70   /* no initializations as of yet */\r
71 }\r
72 \r
73 /**\r
74  * Finds the appropriate network interface for a given IP address. It\r
75  * searches the list of network interfaces linearly. A match is found\r
76  * if the masked IP address of the network interface equals the masked\r
77  * IP address given to the function.\r
78  */\r
79 \r
80 struct netif *\r
81 ip_route(struct ip_addr *dest)\r
82 {\r
83   struct netif *netif;\r
84 \r
85   /* iterate through netifs */\r
86   for(netif = netif_list; netif != NULL; netif = netif->next) {\r
87     /* network mask matches? */\r
88     if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {\r
89       /* return netif on which to forward IP packet */\r
90       return netif;\r
91     }\r
92   }\r
93   /* no matching netif found, use default netif */\r
94   return netif_default;\r
95 }\r
96 #if IP_FORWARD\r
97 \r
98 /**\r
99  * Forwards an IP packet. It finds an appropriate route for the\r
100  * packet, decrements the TTL value of the packet, adjusts the\r
101  * checksum and outputs the packet on the appropriate interface.\r
102  */\r
103 \r
104 static struct netif *\r
105 ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)\r
106 {\r
107   struct netif *netif;\r
108 \r
109   PERF_START;\r
110   /* Find network interface where to forward this IP packet to. */\r
111   netif = ip_route((struct ip_addr *)&(iphdr->dest));\r
112   if (netif == NULL) {\r
113     LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n",\r
114                       iphdr->dest.addr));\r
115     snmp_inc_ipnoroutes();\r
116     return (struct netif *)NULL;\r
117   }\r
118   /* Do not forward packets onto the same network interface on which\r
119    * they arrived. */\r
120   if (netif == inp) {\r
121     LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));\r
122     snmp_inc_ipnoroutes();\r
123     return (struct netif *)NULL;\r
124   }\r
125 \r
126   /* decrement TTL */\r
127   IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);\r
128   /* send ICMP if TTL == 0 */\r
129   if (IPH_TTL(iphdr) == 0) {\r
130     /* Don't send ICMP messages in response to ICMP messages */\r
131     if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {\r
132       icmp_time_exceeded(p, ICMP_TE_TTL);\r
133       snmp_inc_icmpouttimeexcds();\r
134     }\r
135     return (struct netif *)NULL;\r
136   }\r
137 \r
138   /* Incrementally update the IP checksum. */\r
139   if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {\r
140     IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);\r
141   } else {\r
142     IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));\r
143   }\r
144 \r
145   LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%lx\n",\r
146                     iphdr->dest.addr));\r
147 \r
148   IP_STATS_INC(ip.fw);\r
149   IP_STATS_INC(ip.xmit);\r
150     snmp_inc_ipforwdatagrams();\r
151 \r
152   PERF_STOP("ip_forward");\r
153   /* transmit pbuf on chosen interface */\r
154   netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));\r
155   return netif;\r
156 }\r
157 #endif /* IP_FORWARD */\r
158 \r
159 /**\r
160  * This function is called by the network interface device driver when\r
161  * an IP packet is received. The function does the basic checks of the\r
162  * IP header such as packet size being at least larger than the header\r
163  * size etc. If the packet was not destined for us, the packet is\r
164  * forwarded (using ip_forward). The IP checksum is always checked.\r
165  *\r
166  * Finally, the packet is sent to the upper layer protocol input function.\r
167  * \r
168  * \r
169  * \r
170  */\r
171 \r
172 err_t\r
173 ip_input(struct pbuf *p, struct netif *inp) {\r
174   struct ip_hdr *iphdr;\r
175   struct netif *netif;\r
176   u16_t iphdrlen;\r
177 \r
178   IP_STATS_INC(ip.recv);\r
179   snmp_inc_ipinreceives();\r
180 \r
181   /* identify the IP header */\r
182   iphdr = p->payload;\r
183   if (IPH_V(iphdr) != 4) {\r
184     LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %u\n", IPH_V(iphdr)));\r
185     ip_debug_print(p);\r
186     pbuf_free(p);\r
187     IP_STATS_INC(ip.err);\r
188     IP_STATS_INC(ip.drop);\r
189     snmp_inc_ipunknownprotos();\r
190     return ERR_OK;\r
191   }\r
192   /* obtain IP header length in number of 32-bit words */\r
193   iphdrlen = IPH_HL(iphdr);\r
194   /* calculate IP header length in bytes */\r
195   iphdrlen *= 4;\r
196 \r
197   /* header length exceeds first pbuf length? */\r
198   if (iphdrlen > p->len) {\r
199     LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",\r
200       iphdrlen, p->len));\r
201     /* free (drop) packet pbufs */\r
202     pbuf_free(p);\r
203     IP_STATS_INC(ip.lenerr);\r
204     IP_STATS_INC(ip.drop);\r
205     snmp_inc_ipindiscards();\r
206     return ERR_OK;\r
207   }\r
208 \r
209   /* verify checksum */\r
210 #if CHECKSUM_CHECK_IP\r
211   if (inet_chksum(iphdr, iphdrlen) != 0) {\r
212 \r
213     LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));\r
214     ip_debug_print(p);\r
215     pbuf_free(p);\r
216     IP_STATS_INC(ip.chkerr);\r
217     IP_STATS_INC(ip.drop);\r
218     snmp_inc_ipindiscards();\r
219     return ERR_OK;\r
220   }\r
221 #endif\r
222 \r
223   /* Trim pbuf. This should have been done at the netif layer,\r
224    * but we'll do it anyway just to be sure that its done. */\r
225   pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));\r
226 \r
227   /* match packet against an interface, i.e. is this packet for us? */\r
228   for (netif = netif_list; netif != NULL; netif = netif->next) {\r
229 \r
230     LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%lx netif->ip_addr 0x%lx (0x%lx, 0x%lx, 0x%lx)\n",\r
231       iphdr->dest.addr, netif->ip_addr.addr,\r
232       iphdr->dest.addr & netif->netmask.addr,\r
233       netif->ip_addr.addr & netif->netmask.addr,\r
234       iphdr->dest.addr & ~(netif->netmask.addr)));\r
235 \r
236     /* interface is up and configured? */\r
237     if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr))))\r
238     {\r
239       /* unicast to this interface address? */\r
240       if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||\r
241          /* or broadcast on this interface network address? */\r
242          ip_addr_isbroadcast(&(iphdr->dest), netif)) {\r
243         LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",\r
244           netif->name[0], netif->name[1]));\r
245         /* break out of for loop */\r
246         break;\r
247       }\r
248     }\r
249   }\r
250 #if LWIP_DHCP\r
251   /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed\r
252    * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.\r
253    * According to RFC 1542 section 3.1.1, referred by RFC 2131).\r
254    */\r
255   if (netif == NULL) {\r
256     /* remote port is DHCP server? */\r
257     if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {\r
258       LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %u\n",\r
259         ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));\r
260       if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {\r
261         LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));\r
262         netif = inp;\r
263       }\r
264     }\r
265   }\r
266 #endif /* LWIP_DHCP */\r
267   /* packet not for us? */\r
268   if (netif == NULL) {\r
269     /* packet not for us, route or discard */\r
270     LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));\r
271 #if IP_FORWARD\r
272     /* non-broadcast packet? */\r
273     if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {\r
274       /* try to forward IP packet on (other) interfaces */\r
275       ip_forward(p, iphdr, inp);\r
276     }\r
277     else\r
278 #endif /* IP_FORWARD */\r
279     {\r
280       snmp_inc_ipindiscards();\r
281     }\r
282     pbuf_free(p);\r
283     return ERR_OK;\r
284   }\r
285   /* packet consists of multiple fragments? */\r
286   if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {\r
287 #if IP_REASSEMBLY /* packet fragment reassembly code present? */\r
288     LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n",\r
289       ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));\r
290     /* reassemble the packet*/\r
291     p = ip_reass(p);\r
292     /* packet not fully reassembled yet? */\r
293     if (p == NULL) {\r
294       return ERR_OK;\r
295     }\r
296     iphdr = p->payload;\r
297 #else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */\r
298     pbuf_free(p);\r
299     LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",\r
300       ntohs(IPH_OFFSET(iphdr))));\r
301     IP_STATS_INC(ip.opterr);\r
302     IP_STATS_INC(ip.drop);\r
303     snmp_inc_ipunknownprotos();\r
304     return ERR_OK;\r
305 #endif /* IP_REASSEMBLY */\r
306   }\r
307 \r
308 #if IP_OPTIONS == 0 /* no support for IP options in the IP header? */\r
309   if (iphdrlen > IP_HLEN) {\r
310     LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));\r
311     pbuf_free(p);\r
312     IP_STATS_INC(ip.opterr);\r
313     IP_STATS_INC(ip.drop);\r
314     snmp_inc_ipunknownprotos();\r
315     return ERR_OK;\r
316   }\r
317 #endif /* IP_OPTIONS == 0 */\r
318 \r
319   /* send to upper layers */\r
320   LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));\r
321   ip_debug_print(p);\r
322   LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));\r
323 \r
324 #if LWIP_RAW\r
325   /* raw input did not eat the packet? */\r
326   if (raw_input(p, inp) == 0) {\r
327 #endif /* LWIP_RAW */\r
328 \r
329   switch (IPH_PROTO(iphdr)) {\r
330 #if LWIP_UDP\r
331   case IP_PROTO_UDP:\r
332   case IP_PROTO_UDPLITE:\r
333     snmp_inc_ipindelivers();\r
334     udp_input(p, inp);\r
335     break;\r
336 #endif /* LWIP_UDP */\r
337 #if LWIP_TCP\r
338   case IP_PROTO_TCP:\r
339     snmp_inc_ipindelivers();\r
340     tcp_input(p, inp);\r
341     break;\r
342 #endif /* LWIP_TCP */\r
343   case IP_PROTO_ICMP:\r
344     snmp_inc_ipindelivers();\r
345     icmp_input(p, inp);\r
346     break;\r
347   default:\r
348     /* send ICMP destination protocol unreachable unless is was a broadcast */\r
349     if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&\r
350         !ip_addr_ismulticast(&(iphdr->dest))) {\r
351       p->payload = iphdr;\r
352       icmp_dest_unreach(p, ICMP_DUR_PROTO);\r
353     }\r
354     pbuf_free(p);\r
355 \r
356     LWIP_DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %d\n", IPH_PROTO(iphdr)));\r
357 \r
358     IP_STATS_INC(ip.proterr);\r
359     IP_STATS_INC(ip.drop);\r
360     snmp_inc_ipunknownprotos();\r
361   }\r
362 #if LWIP_RAW\r
363   } /* LWIP_RAW */\r
364 #endif\r
365   return ERR_OK;\r
366 }\r
367 \r
368 /**\r
369  * Sends an IP packet on a network interface. This function constructs\r
370  * the IP header and calculates the IP header checksum. If the source\r
371  * IP address is NULL, the IP address of the outgoing network\r
372  * interface is filled in as source address.\r
373  */\r
374 \r
375 err_t\r
376 ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
377              u8_t ttl, u8_t tos,\r
378              u8_t proto, struct netif *netif)\r
379 {\r
380   struct ip_hdr *iphdr;\r
381   u16_t ip_id = 0;\r
382 \r
383   snmp_inc_ipoutrequests();\r
384 \r
385   if (dest != IP_HDRINCL) {\r
386     if (pbuf_header(p, IP_HLEN)) {\r
387       LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));\r
388 \r
389       IP_STATS_INC(ip.err);\r
390       snmp_inc_ipoutdiscards();\r
391       return ERR_BUF;\r
392     }\r
393 \r
394     iphdr = p->payload;\r
395 \r
396     IPH_TTL_SET(iphdr, ttl);\r
397     IPH_PROTO_SET(iphdr, proto);\r
398 \r
399     ip_addr_set(&(iphdr->dest), dest);\r
400 \r
401     IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, tos);\r
402     IPH_LEN_SET(iphdr, htons(p->tot_len));\r
403     IPH_OFFSET_SET(iphdr, htons(IP_DF));\r
404     IPH_ID_SET(iphdr, htons(ip_id));\r
405     ++ip_id;\r
406 \r
407     if (ip_addr_isany(src)) {\r
408       ip_addr_set(&(iphdr->src), &(netif->ip_addr));\r
409     } else {\r
410       ip_addr_set(&(iphdr->src), src);\r
411     }\r
412 \r
413     IPH_CHKSUM_SET(iphdr, 0);\r
414 #if CHECKSUM_GEN_IP\r
415     IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));\r
416 #endif\r
417   } else {\r
418     iphdr = p->payload;\r
419     dest = &(iphdr->dest);\r
420   }\r
421 \r
422 #if IP_FRAG\r
423   /* don't fragment if interface has mtu set to 0 [loopif] */\r
424   if (netif->mtu && (p->tot_len > netif->mtu))\r
425     return ip_frag(p,netif,dest);\r
426 #endif\r
427 \r
428   IP_STATS_INC(ip.xmit);\r
429 \r
430   LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%u\n", netif->name[0], netif->name[1], netif->num));\r
431   ip_debug_print(p);\r
432 \r
433   LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));\r
434 \r
435   return netif->output(netif, p, dest);\r
436 }\r
437 \r
438 /**\r
439  * Simple interface to ip_output_if. It finds the outgoing network\r
440  * interface and calls upon ip_output_if to do the actual work.\r
441  */\r
442 \r
443 err_t\r
444 ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
445           u8_t ttl, u8_t tos, u8_t proto)\r
446 {\r
447   struct netif *netif;\r
448 \r
449   if ((netif = ip_route(dest)) == NULL) {\r
450     LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));\r
451 \r
452     IP_STATS_INC(ip.rterr);\r
453     snmp_inc_ipoutdiscards();\r
454     return ERR_RTE;\r
455   }\r
456 \r
457   return ip_output_if(p, src, dest, ttl, tos, proto, netif);\r
458 }\r
459 \r
460 #if IP_DEBUG\r
461 void\r
462 ip_debug_print(struct pbuf *p)\r
463 {\r
464   struct ip_hdr *iphdr = p->payload;\r
465   u8_t *payload;\r
466 \r
467   payload = (u8_t *)iphdr + IP_HLEN;\r
468 \r
469   LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));\r
470   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
471   LWIP_DEBUGF(IP_DEBUG, ("|%2d |%2d |  0x%02x |     %5u     | (v, hl, tos, len)\n",\r
472                     IPH_V(iphdr),\r
473                     IPH_HL(iphdr),\r
474                     IPH_TOS(iphdr),\r
475                     ntohs(IPH_LEN(iphdr))));\r
476   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
477   LWIP_DEBUGF(IP_DEBUG, ("|    %5u      |%u%u%u|    %4u   | (id, flags, offset)\n",\r
478                     ntohs(IPH_ID(iphdr)),\r
479                     ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,\r
480                     ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,\r
481                     ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,\r
482                     ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));\r
483   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
484   LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |    0x%04x     | (ttl, proto, chksum)\n",\r
485                     IPH_TTL(iphdr),\r
486                     IPH_PROTO(iphdr),\r
487                     ntohs(IPH_CHKSUM(iphdr))));\r
488   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
489   LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |  %3u  |  %3u  | (src)\n",\r
490                     ip4_addr1(&iphdr->src),\r
491                     ip4_addr2(&iphdr->src),\r
492                     ip4_addr3(&iphdr->src),\r
493                     ip4_addr4(&iphdr->src)));\r
494   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
495   LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |  %3u  |  %3u  | (dest)\n",\r
496                     ip4_addr1(&iphdr->dest),\r
497                     ip4_addr2(&iphdr->dest),\r
498                     ip4_addr3(&iphdr->dest),\r
499                     ip4_addr4(&iphdr->dest)));\r
500   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
501 }\r
502 #endif /* IP_DEBUG */\r
503 \r
504 \r
505 \r
506 \r
507 \r
508 \r