]> git.sur5r.net Git - freertos/blob - Demo/Common/ethernet/lwIP/core/ipv4/ip.c
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@82 1d2547de-c912-0410-9cb9...
[freertos] / Demo / Common / ethernet / lwIP / 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  * Initializes the IP layer.\r
64  */\r
65 \r
66 void\r
67 ip_init(void)\r
68 {\r
69 #if IP_FRAG\r
70   ip_frag_init();\r
71 #endif\r
72 }\r
73 \r
74 /**\r
75  * Finds the appropriate network interface for a given IP address. It\r
76  * searches the list of network interfaces linearly. A match is found\r
77  * if the masked IP address of the network interface equals the masked\r
78  * IP address given to the function.\r
79  */\r
80 \r
81 struct netif *\r
82 ip_route(struct ip_addr *dest)\r
83 {\r
84   struct netif *netif;\r
85 \r
86   /* iterate through netifs */\r
87   for(netif = netif_list; netif != NULL; netif = netif->next) {\r
88     /* network mask matches? */\r
89     if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {\r
90       /* return netif on which to forward IP packet */\r
91       return netif;\r
92     }\r
93   }\r
94   /* no matching netif found, use default netif */\r
95   return netif_default;\r
96 }\r
97 #if IP_FORWARD\r
98 \r
99 /**\r
100  * Forwards an IP packet. It finds an appropriate route for the\r
101  * packet, decrements the TTL value of the packet, adjusts the\r
102  * checksum and outputs the packet on the appropriate interface.\r
103  */\r
104 \r
105 static struct netif *\r
106 ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)\r
107 {\r
108   struct netif *netif;\r
109 \r
110   PERF_START;\r
111   /* Find network interface where to forward this IP packet to. */\r
112   netif = ip_route((struct ip_addr *)&(iphdr->dest));\r
113   if (netif == NULL) {\r
114     LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%"X32_F" found\n",\r
115                       iphdr->dest.addr));\r
116     snmp_inc_ipoutnoroutes();\r
117     return (struct netif *)NULL;\r
118   }\r
119   /* Do not forward packets onto the same network interface on which\r
120    * they arrived. */\r
121   if (netif == inp) {\r
122     LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));\r
123     snmp_inc_ipoutnoroutes();\r
124     return (struct netif *)NULL;\r
125   }\r
126 \r
127   /* decrement TTL */\r
128   IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);\r
129   /* send ICMP if TTL == 0 */\r
130   if (IPH_TTL(iphdr) == 0) {\r
131     snmp_inc_ipinhdrerrors();\r
132     /* Don't send ICMP messages in response to ICMP messages */\r
133     if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {\r
134       icmp_time_exceeded(p, ICMP_TE_TTL);\r
135     }\r
136     return (struct netif *)NULL;\r
137   }\r
138 \r
139   /* Incrementally update the IP checksum. */\r
140   if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {\r
141     IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);\r
142   } else {\r
143     IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));\r
144   }\r
145 \r
146   LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%"X32_F"\n",\r
147                     iphdr->dest.addr));\r
148 \r
149   IP_STATS_INC(ip.fw);\r
150   IP_STATS_INC(ip.xmit);\r
151   snmp_inc_ipforwdatagrams();\r
152 \r
153   PERF_STOP("ip_forward");\r
154   /* transmit pbuf on chosen interface */\r
155   netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));\r
156   return netif;\r
157 }\r
158 #endif /* IP_FORWARD */\r
159 \r
160 /**\r
161  * This function is called by the network interface device driver when\r
162  * an IP packet is received. The function does the basic checks of the\r
163  * IP header such as packet size being at least larger than the header\r
164  * size etc. If the packet was not destined for us, the packet is\r
165  * forwarded (using ip_forward). The IP checksum is always checked.\r
166  *\r
167  * Finally, the packet is sent to the upper layer protocol input function.\r
168  * \r
169  * \r
170  * \r
171  */\r
172 \r
173 err_t\r
174 ip_input(struct pbuf *p, struct netif *inp) {\r
175   struct ip_hdr *iphdr;\r
176   struct netif *netif;\r
177   u16_t iphdrlen;\r
178 \r
179   IP_STATS_INC(ip.recv);\r
180   snmp_inc_ipinreceives();\r
181 \r
182   /* identify the IP header */\r
183   iphdr = p->payload;\r
184   if (IPH_V(iphdr) != 4) {\r
185     LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));\r
186     ip_debug_print(p);\r
187     pbuf_free(p);\r
188     IP_STATS_INC(ip.err);\r
189     IP_STATS_INC(ip.drop);\r
190     snmp_inc_ipinhdrerrors();\r
191     return ERR_OK;\r
192   }\r
193   /* obtain IP header length in number of 32-bit words */\r
194   iphdrlen = IPH_HL(iphdr);\r
195   /* calculate IP header length in bytes */\r
196   iphdrlen *= 4;\r
197 \r
198   /* header length exceeds first pbuf length? */\r
199   if (iphdrlen > p->len) {\r
200     LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet droppped.\n",\r
201       iphdrlen, p->len));\r
202     /* free (drop) packet pbufs */\r
203     pbuf_free(p);\r
204     IP_STATS_INC(ip.lenerr);\r
205     IP_STATS_INC(ip.drop);\r
206     snmp_inc_ipindiscards();\r
207     return ERR_OK;\r
208   }\r
209 \r
210   /* verify checksum */\r
211 #if CHECKSUM_CHECK_IP\r
212   if (inet_chksum(iphdr, iphdrlen) != 0) {\r
213 \r
214     LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));\r
215     ip_debug_print(p);\r
216     pbuf_free(p);\r
217     IP_STATS_INC(ip.chkerr);\r
218     IP_STATS_INC(ip.drop);\r
219     snmp_inc_ipinhdrerrors();\r
220     return ERR_OK;\r
221   }\r
222 #endif\r
223 \r
224   /* Trim pbuf. This should have been done at the netif layer,\r
225    * but we'll do it anyway just to be sure that its done. */\r
226   pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));\r
227 \r
228   /* match packet against an interface, i.e. is this packet for us? */\r
229   for (netif = netif_list; netif != NULL; netif = netif->next) {\r
230 \r
231     LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",\r
232       iphdr->dest.addr, netif->ip_addr.addr,\r
233       iphdr->dest.addr & netif->netmask.addr,\r
234       netif->ip_addr.addr & netif->netmask.addr,\r
235       iphdr->dest.addr & ~(netif->netmask.addr)));\r
236 \r
237     /* interface is up and configured? */\r
238     if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr))))\r
239     {\r
240       /* unicast to this interface address? */\r
241       if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||\r
242          /* or broadcast on this interface network address? */\r
243          ip_addr_isbroadcast(&(iphdr->dest), netif)) {\r
244         LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",\r
245           netif->name[0], netif->name[1]));\r
246         /* break out of for loop */\r
247         break;\r
248       }\r
249     }\r
250   }\r
251 #if LWIP_DHCP\r
252   /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed\r
253    * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.\r
254    * According to RFC 1542 section 3.1.1, referred by RFC 2131).\r
255    */\r
256   if (netif == NULL) {\r
257     /* remote port is DHCP server? */\r
258     if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {\r
259       LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",\r
260         ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));\r
261       if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {\r
262         LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));\r
263         netif = inp;\r
264       }\r
265     }\r
266   }\r
267 #endif /* LWIP_DHCP */\r
268   /* packet not for us? */\r
269   if (netif == NULL) {\r
270     /* packet not for us, route or discard */\r
271     LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));\r
272 #if IP_FORWARD\r
273     /* non-broadcast packet? */\r
274     if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {\r
275       /* try to forward IP packet on (other) interfaces */\r
276       ip_forward(p, iphdr, inp);\r
277     }\r
278     else\r
279 #endif /* IP_FORWARD */\r
280     {\r
281       snmp_inc_ipinaddrerrors();\r
282       snmp_inc_ipindiscards();\r
283     }\r
284     pbuf_free(p);\r
285     return ERR_OK;\r
286   }\r
287   /* packet consists of multiple fragments? */\r
288   if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {\r
289 #if IP_REASSEMBLY /* packet fragment reassembly code present? */\r
290     LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n",\r
291       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
292     /* reassemble the packet*/\r
293     p = ip_reass(p);\r
294     /* packet not fully reassembled yet? */\r
295     if (p == NULL) {\r
296       return ERR_OK;\r
297     }\r
298     iphdr = p->payload;\r
299 #else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */\r
300     pbuf_free(p);\r
301     LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",\r
302       ntohs(IPH_OFFSET(iphdr))));\r
303     IP_STATS_INC(ip.opterr);\r
304     IP_STATS_INC(ip.drop);\r
305     /* unsupported protocol feature */\r
306     snmp_inc_ipinunknownprotos();\r
307     return ERR_OK;\r
308 #endif /* IP_REASSEMBLY */\r
309   }\r
310 \r
311 #if IP_OPTIONS == 0 /* no support for IP options in the IP header? */\r
312   if (iphdrlen > IP_HLEN) {\r
313     LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));\r
314     pbuf_free(p);\r
315     IP_STATS_INC(ip.opterr);\r
316     IP_STATS_INC(ip.drop);\r
317     /* unsupported protocol feature */\r
318     snmp_inc_ipinunknownprotos();\r
319     return ERR_OK;\r
320   }\r
321 #endif /* IP_OPTIONS == 0 */\r
322 \r
323   /* send to upper layers */\r
324   LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));\r
325   ip_debug_print(p);\r
326   LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));\r
327 \r
328 #if LWIP_RAW\r
329   /* raw input did not eat the packet? */\r
330   if (raw_input(p, inp) == 0) {\r
331 #endif /* LWIP_RAW */\r
332 \r
333   switch (IPH_PROTO(iphdr)) {\r
334 #if LWIP_UDP\r
335   case IP_PROTO_UDP:\r
336   case IP_PROTO_UDPLITE:\r
337     snmp_inc_ipindelivers();\r
338     udp_input(p, inp);\r
339     break;\r
340 #endif /* LWIP_UDP */\r
341 #if LWIP_TCP\r
342   case IP_PROTO_TCP:\r
343     snmp_inc_ipindelivers();\r
344     tcp_input(p, inp);\r
345     break;\r
346 #endif /* LWIP_TCP */\r
347   case IP_PROTO_ICMP:\r
348     snmp_inc_ipindelivers();\r
349     icmp_input(p, inp);\r
350     break;\r
351   default:\r
352     /* send ICMP destination protocol unreachable unless is was a broadcast */\r
353     if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&\r
354         !ip_addr_ismulticast(&(iphdr->dest))) {\r
355       p->payload = iphdr;\r
356       icmp_dest_unreach(p, ICMP_DUR_PROTO);\r
357     }\r
358     pbuf_free(p);\r
359 \r
360     LWIP_DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));\r
361 \r
362     IP_STATS_INC(ip.proterr);\r
363     IP_STATS_INC(ip.drop);\r
364     snmp_inc_ipinunknownprotos();\r
365   }\r
366 #if LWIP_RAW\r
367   } /* LWIP_RAW */\r
368 #endif\r
369   return ERR_OK;\r
370 }\r
371 \r
372 /**\r
373  * Sends an IP packet on a network interface. This function constructs\r
374  * the IP header and calculates the IP header checksum. If the source\r
375  * IP address is NULL, the IP address of the outgoing network\r
376  * interface is filled in as source address.\r
377  *\r
378  * @note ip_id: RFC791 "some host may be able to simply use\r
379  *  unique identifiers independent of destination"\r
380  */\r
381 \r
382 err_t\r
383 ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
384              u8_t ttl, u8_t tos,\r
385              u8_t proto, struct netif *netif)\r
386 {\r
387   struct ip_hdr *iphdr;\r
388   static u16_t ip_id = 0;\r
389 \r
390   snmp_inc_ipoutrequests();\r
391 \r
392   if (dest != IP_HDRINCL) {\r
393     if (pbuf_header(p, IP_HLEN)) {\r
394       LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));\r
395 \r
396       IP_STATS_INC(ip.err);\r
397       snmp_inc_ipoutdiscards();\r
398       return ERR_BUF;\r
399     }\r
400 \r
401     iphdr = p->payload;\r
402 \r
403     IPH_TTL_SET(iphdr, ttl);\r
404     IPH_PROTO_SET(iphdr, proto);\r
405 \r
406     ip_addr_set(&(iphdr->dest), dest);\r
407 \r
408     IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, tos);\r
409     IPH_LEN_SET(iphdr, htons(p->tot_len));\r
410     IPH_OFFSET_SET(iphdr, htons(IP_DF));\r
411     IPH_ID_SET(iphdr, htons(ip_id));\r
412     ++ip_id;\r
413 \r
414     if (ip_addr_isany(src)) {\r
415       ip_addr_set(&(iphdr->src), &(netif->ip_addr));\r
416     } else {\r
417       ip_addr_set(&(iphdr->src), src);\r
418     }\r
419 \r
420     IPH_CHKSUM_SET(iphdr, 0);\r
421 #if CHECKSUM_GEN_IP\r
422     IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));\r
423 #endif\r
424   } else {\r
425     iphdr = p->payload;\r
426     dest = &(iphdr->dest);\r
427   }\r
428 \r
429 #if IP_FRAG\r
430   /* don't fragment if interface has mtu set to 0 [loopif] */\r
431   if (netif->mtu && (p->tot_len > netif->mtu))\r
432     return ip_frag(p,netif,dest);\r
433 #endif\r
434 \r
435   IP_STATS_INC(ip.xmit);\r
436 \r
437   LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));\r
438   ip_debug_print(p);\r
439 \r
440   LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));\r
441 \r
442   return netif->output(netif, p, dest);\r
443 }\r
444 \r
445 /**\r
446  * Simple interface to ip_output_if. It finds the outgoing network\r
447  * interface and calls upon ip_output_if to do the actual work.\r
448  */\r
449 \r
450 err_t\r
451 ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,\r
452           u8_t ttl, u8_t tos, u8_t proto)\r
453 {\r
454   struct netif *netif;\r
455 \r
456   if ((netif = ip_route(dest)) == NULL) {\r
457     LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));\r
458 \r
459     IP_STATS_INC(ip.rterr);\r
460     snmp_inc_ipoutnoroutes();\r
461     return ERR_RTE;\r
462   }\r
463 \r
464   return ip_output_if(p, src, dest, ttl, tos, proto, netif);\r
465 }\r
466 \r
467 #if IP_DEBUG\r
468 void\r
469 ip_debug_print(struct pbuf *p)\r
470 {\r
471   struct ip_hdr *iphdr = p->payload;\r
472   u8_t *payload;\r
473 \r
474   payload = (u8_t *)iphdr + IP_HLEN;\r
475 \r
476   LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));\r
477   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
478   LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" |  0x%02"X16_F" |     %5"U16_F"     | (v, hl, tos, len)\n",\r
479                     IPH_V(iphdr),\r
480                     IPH_HL(iphdr),\r
481                     IPH_TOS(iphdr),\r
482                     ntohs(IPH_LEN(iphdr))));\r
483   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
484   LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      |%"U16_F"%"U16_F"%"U16_F"|    %4"U16_F"   | (id, flags, offset)\n",\r
485                     ntohs(IPH_ID(iphdr)),\r
486                     ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,\r
487                     ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,\r
488                     ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,\r
489                     ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));\r
490   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
491   LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |    0x%04"X16_F"     | (ttl, proto, chksum)\n",\r
492                     IPH_TTL(iphdr),\r
493                     IPH_PROTO(iphdr),\r
494                     ntohs(IPH_CHKSUM(iphdr))));\r
495   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
496   LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (src)\n",\r
497                     ip4_addr1(&iphdr->src),\r
498                     ip4_addr2(&iphdr->src),\r
499                     ip4_addr3(&iphdr->src),\r
500                     ip4_addr4(&iphdr->src)));\r
501   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
502   LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (dest)\n",\r
503                     ip4_addr1(&iphdr->dest),\r
504                     ip4_addr2(&iphdr->dest),\r
505                     ip4_addr3(&iphdr->dest),\r
506                     ip4_addr4(&iphdr->dest)));\r
507   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));\r
508 }\r
509 #endif /* IP_DEBUG */\r
510 \r
511 \r
512 \r
513 \r
514 \r
515 \r