Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

ip.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
00003  * All rights reserved. 
00004  * 
00005  * Redistribution and use in source and binary forms, with or without modification, 
00006  * are permitted provided that the following conditions are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright notice,
00009  *    this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright notice,
00011  *    this list of conditions and the following disclaimer in the documentation
00012  *    and/or other materials provided with the distribution.
00013  * 3. The name of the author may not be used to endorse or promote products
00014  *    derived from this software without specific prior written permission. 
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
00017  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00018  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
00019  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00020  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
00021  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
00024  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
00025  * OF SUCH DAMAGE.
00026  *
00027  * This file is part of the lwIP TCP/IP stack.
00028  * 
00029  * Author: Adam Dunkels <adam@sics.se>
00030  *
00031  */
00032 
00033 
00034 /*-----------------------------------------------------------------------------------*/
00035 /* ip.c
00036  *
00037  * This is the code for the IP layer.
00038  *
00039  */   
00040 /*-----------------------------------------------------------------------------------*/
00041 
00042 #include "lwip/opt.h"
00043 
00044 
00045 #include "lwip/def.h"
00046 #include "lwip/mem.h"
00047 #include "lwip/ip.h"
00048 #include "lwip/ip_frag.h"
00049 #include "lwip/inet.h"
00050 #include "lwip/netif.h"
00051 #include "lwip/icmp.h"
00052 #include "lwip/udp.h"
00053 #include "lwip/tcp.h"
00054 
00055 #include "lwip/stats.h"
00056 
00057 
00058 #define htons HTONS
00059 #define htonl HTONL
00060 
00061 //#include "arch/perf.h"
00062 
00063 #include "lwip/snmp.h"
00064 #if LWIP_DHCP
00065 #  include "lwip/dhcp.h"
00066 #endif /* LWIP_DHCP */
00067 
00068 /*-----------------------------------------------------------------------------------*/
00069 /* ip_init:
00070  *
00071  * Initializes the IP layer.
00072  */
00073 /*-----------------------------------------------------------------------------------*/
00074 void
00075 ip_init(void)
00076 {
00077 }
00078 /*-----------------------------------------------------------------------------------*/
00079 /* ip_lookup:
00080  *
00081  * An experimental feature that will be changed in future versions. Do
00082  * not depend on it yet...
00083  */
00084 /*-----------------------------------------------------------------------------------*/
00085 #ifdef LWIP_DEBUG
00086 u8_t
00087 ip_lookup(void *header, struct netif *inp)
00088 {
00089   struct ip_hdr *iphdr;
00090 
00091   iphdr = header;
00092 
00093   /* not IP v4? */
00094   if(IPH_V(iphdr) != 4) {
00095     return 0;
00096   }
00097 
00098   /* Immediately accept/decline packets that are fragments or has
00099      options. */
00100 #if IP_REASSEMBLY == 0
00101   /*  if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
00102     return 0;
00103     }*/
00104 #endif /* IP_REASSEMBLY == 0 */
00105 
00106 #if IP_OPTIONS == 0
00107   if(IPH_HL(iphdr) != 5) {
00108     return 0;
00109   }
00110 #endif /* IP_OPTIONS == 0 */
00111   
00112   switch(IPH_PROTO(iphdr)) {
00113 #if LWIP_UDP > 0
00114   case IP_PROTO_UDP:
00115     return udp_lookup(iphdr, inp);
00116 #endif /* LWIP_UDP */
00117 #if LWIP_TCP > 0    
00118   case IP_PROTO_TCP:
00119     return 1;
00120 #endif /* LWIP_TCP */
00121   case IP_PROTO_ICMP:
00122     return 1;
00123   default:
00124     return 0;
00125   }
00126 }
00127 #endif /* LWIP_DEBUG */
00128 /*-----------------------------------------------------------------------------------*/
00129 /* ip_route:
00130  *
00131  * Finds the appropriate network interface for a given IP address. It
00132  * searches the list of network interfaces linearly. A match is found
00133  * if the masked IP address of the network interface equals the masked
00134  * IP address given to the function.
00135  */
00136 /*-----------------------------------------------------------------------------------*/
00137 struct netif *
00138 ip_route(struct ip_addr *dest)
00139 {
00140   struct netif *netif;
00141 
00142   /* iterate through netifs */  
00143   for(netif = netif_list; netif != NULL; netif = netif->next) {
00144     /* network mask matches? */
00145     if(ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
00146       /* return netif on which to forward IP packet */
00147       return netif;
00148     }
00149   }
00150   /* no matching netif found, use default netif */
00151   return netif_default;
00152 }
00153 #if IP_FORWARD
00154 /*-----------------------------------------------------------------------------------*/
00155 /* ip_forward:
00156  *
00157  * Forwards an IP packet. It finds an appropriate route for the
00158  * packet, decrements the TTL value of the packet, adjusts the
00159  * checksum and outputs the packet on the appropriate interface.
00160  */
00161 /*-----------------------------------------------------------------------------------*/
00162 static void
00163 ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
00164 {
00165   struct netif *netif;
00166   
00167 //  PERF_START;
00168   /* Find network interface where to forward this IP packet to. */
00169   netif = ip_route((struct ip_addr *)&(iphdr->dest));
00170   if(netif == NULL) {
00171     DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n",
00172                       iphdr->dest.addr));
00173     snmp_inc_ipnoroutes();
00174     return;
00175   }
00176   /* Do not forward packets onto the same network interface on which
00177      they arrived. */
00178   if(netif == inp) {
00179     DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
00180     snmp_inc_ipnoroutes();
00181     return;
00182   }
00183   
00184   /* decrement TTL */
00185   IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
00186   /* send ICMP if TTL == 0 */
00187   if(IPH_TTL(iphdr) == 0) {
00188     /* Don't send ICMP messages in response to ICMP messages */
00189     if(IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
00190       icmp_time_exceeded(p, ICMP_TE_TTL);
00191       snmp_inc_icmpouttimeexcds();
00192     }
00193     return;       
00194   }
00195   
00196   /* Incrementally update the IP checksum. */
00197   if(IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
00198     IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
00199   } else {
00200     IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));
00201   }
00202 
00203   DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%lx\n",
00204                     iphdr->dest.addr));
00205 
00206 #ifdef IP_STATS
00207   ++lwip_stats.ip.fw;
00208   ++lwip_stats.ip.xmit;
00209 #endif /* IP_STATS */
00210     snmp_inc_ipforwdatagrams();
00211 
00212 //  PERF_STOP("ip_forward");
00213   /* transmit pbuf on chosen interface */
00214   netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
00215 }
00216 #endif /* IP_FORWARD */
00217 /*-----------------------------------------------------------------------------------*/
00218 /* ip_input:
00219  *
00220  * This function is called by the network interface device driver when
00221  * an IP packet is received. The function does the basic checks of the
00222  * IP header such as packet size being at least larger than the header
00223  * size etc. If the packet was not destined for us, the packet is
00224  * forwarded (using ip_forward). The IP checksum is always checked.
00225  *
00226  * Finally, the packet is sent to the upper layer protocol input function.
00227  */
00228 /*-----------------------------------------------------------------------------------*/
00229 err_t
00230 ip_input(struct pbuf *p, struct netif *inp) {
00231   static struct ip_hdr *iphdr;
00232   static struct netif *netif;
00233   static u16_t iphdrlen;
00234   
00235 #ifdef IP_STATS
00236   ++lwip_stats.ip.recv;
00237 #endif /* IP_STATS */
00238   snmp_inc_ipinreceives();
00239 
00240   /* identify the IP header */
00241   iphdr = p->payload;
00242   if(IPH_V(iphdr) != 4) {
00243     DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %d\n", IPH_V(iphdr)));
00244 #if IP_DEBUG
00245     ip_debug_print(p);
00246 #endif /* IP_DEBUG */
00247     pbuf_free(p);
00248 #ifdef IP_STATS
00249     ++lwip_stats.ip.err;
00250     ++lwip_stats.ip.drop;
00251 #endif /* IP_STATS */
00252     snmp_inc_ipunknownprotos();
00253     return ERR_OK;
00254   }
00255   /* obtain IP header length in number of 32-bit words */
00256   iphdrlen = IPH_HL(iphdr);
00257   /* calculate IP header length in bytes */
00258   iphdrlen *= 4;
00259 
00260   /* header length exceeds first pbuf length? */  
00261   if(iphdrlen > p->len) {
00262     DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",
00263       iphdrlen, p->len));
00264     /* free (drop) packet pbufs */
00265     pbuf_free(p);
00266 #ifdef IP_STATS
00267     ++lwip_stats.ip.lenerr;
00268     ++lwip_stats.ip.drop;
00269 #endif /* IP_STATS */
00270     snmp_inc_ipindiscards();
00271     return ERR_OK;
00272   }
00273 
00274   /* verify checksum */
00275   if(inet_chksum(iphdr, iphdrlen) != 0) {
00276 
00277     DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));
00278 #if IP_DEBUG
00279     ip_debug_print(p);
00280 #endif /* IP_DEBUG */
00281     pbuf_free(p);
00282 #ifdef IP_STATS
00283     ++lwip_stats.ip.chkerr;
00284     ++lwip_stats.ip.drop;
00285 #endif /* IP_STATS */
00286     snmp_inc_ipindiscards();
00287     return ERR_OK;
00288   }
00289   
00290   /* Trim pbuf. This should have been done at the netif layer,
00291      but we'll do it anyway just to be sure that its done. */
00292   pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
00293 
00294   /* is this packet for us? */
00295   for(netif = netif_list; netif != NULL; netif = netif->next) {
00296 
00297     DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%lx netif->ip_addr 0x%lx (0x%lx, 0x%lx, 0x%lx)\n",
00298                       iphdr->dest.addr, netif->ip_addr.addr,
00299                       iphdr->dest.addr & netif->netmask.addr,
00300                       netif->ip_addr.addr & netif->netmask.addr,
00301                       iphdr->dest.addr & ~(netif->netmask.addr)));
00302 
00303     /* interface configured? */
00304     if(!ip_addr_isany(&(netif->ip_addr)))
00305     {
00306       /* unicast to this interface address? */
00307       if(ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
00308         /* or broadcast matching this interface network address? */
00309         (ip_addr_isbroadcast(&(iphdr->dest), &(netif->netmask)) &&
00310          ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) ||
00311          /* or restricted broadcast? */
00312          ip_addr_cmp(&(iphdr->dest), IP_ADDR_BROADCAST)) {
00313          DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
00314                        netif->name[0], netif->name[1]));
00315          /* break out of for loop */
00316          break;
00317       }
00318     }
00319   }
00320 #if LWIP_DHCP
00321   /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
00322      using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
00323      According to RFC 1542 section 3.1.1, referred by RFC 2131). */
00324   if(netif == NULL) {
00325     /* remote port is DHCP server? */
00326     if(IPH_PROTO(iphdr) == IP_PROTO_UDP) {
00327       DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %u\n",
00328         ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));
00329       if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {
00330         DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));
00331         netif = inp;
00332       }
00333     }
00334   }
00335 #endif /* LWIP_DHCP */
00336         /* packet not for us? */  
00337   if(netif == NULL) {
00338     /* packet not for us, route or discard */
00339     DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
00340 #if IP_FORWARD
00341     /* non-broadcast packet? */
00342     if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask))) {
00343       /* try to forward IP packet on (other) interfaces */
00344       ip_forward(p, iphdr, inp);
00345     }
00346     else
00347 #endif /* IP_FORWARD */
00348     {
00349       snmp_inc_ipindiscards();
00350     }
00351     pbuf_free(p);
00352     return ERR_OK;
00353   }
00354 
00355 #if IP_REASSEMBLY
00356   if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
00357     DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n", ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
00358     p = ip_reass(p);
00359     if(p == NULL) {
00360       return ERR_OK;
00361     }
00362     iphdr = p->payload;
00363   }
00364 #else /* IP_REASSEMBLY */
00365   if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
00366     pbuf_free(p);
00367     DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",
00368                   ntohs(IPH_OFFSET(iphdr))));
00369 #ifdef IP_STATS
00370     ++lwip_stats.ip.opterr;
00371     ++lwip_stats.ip.drop;
00372 #endif /* IP_STATS */
00373     snmp_inc_ipunknownprotos();
00374     return ERR_OK;
00375   }
00376 #endif /* IP_REASSEMBLY */
00377   
00378 #if IP_OPTIONS == 0
00379   if (iphdrlen > IP_HLEN) {
00380     DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
00381     pbuf_free(p);    
00382 #ifdef IP_STATS
00383     ++lwip_stats.ip.opterr;
00384     ++lwip_stats.ip.drop;
00385 #endif /* IP_STATS */
00386     snmp_inc_ipunknownprotos();
00387     return ERR_OK;
00388   }  
00389 #endif /* IP_OPTIONS == 0 */
00390 
00391   /* send to upper layers */
00392 #if IP_DEBUG
00393   DEBUGF(IP_DEBUG, ("ip_input: \n"));
00394   ip_debug_print(p);
00395   DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
00396 #endif /* IP_DEBUG */   
00397 
00398   switch(IPH_PROTO(iphdr)) {
00399 #if LWIP_UDP > 0    
00400   case IP_PROTO_UDP:
00401     snmp_inc_ipindelivers();
00402     udp_input(p, inp);
00403     break;
00404 #endif /* LWIP_UDP */
00405 #if LWIP_TCP > 0    
00406   case IP_PROTO_TCP:
00407     snmp_inc_ipindelivers();
00408     tcp_input(p, inp);
00409     break;
00410 #endif /* LWIP_TCP */
00411   case IP_PROTO_ICMP:
00412     snmp_inc_ipindelivers();
00413     icmp_input(p, inp);
00414     break;
00415   default:
00416     /* send ICMP destination protocol unreachable unless is was a broadcast */
00417     if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) &&
00418        !ip_addr_ismulticast(&(iphdr->dest))) {
00419       p->payload = iphdr;
00420       icmp_dest_unreach(p, ICMP_DUR_PROTO);
00421     }
00422     pbuf_free(p);
00423 
00424     DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %d\n", IPH_PROTO(iphdr)));
00425 
00426 #ifdef IP_STATS
00427     ++lwip_stats.ip.proterr;
00428     ++lwip_stats.ip.drop;
00429 #endif /* IP_STATS */
00430     snmp_inc_ipunknownprotos();
00431 
00432   }
00433   return ERR_OK;
00434 }
00435 
00436 /*-----------------------------------------------------------------------------------*/
00437 /* ip_output_if:
00438  *
00439  * Sends an IP packet on a network interface. This function constructs
00440  * the IP header and calculates the IP header checksum. If the source
00441  * IP address is NULL, the IP address of the outgoing network
00442  * interface is filled in as source address.
00443  */
00444 /*-----------------------------------------------------------------------------------*/
00445 err_t
00446 ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
00447              u8_t ttl,
00448              u8_t proto, struct netif *netif)
00449 {
00450   static struct ip_hdr *iphdr;
00451   static u16_t ip_id = 0;
00452 
00453   snmp_inc_ipoutrequests();
00454   
00455   if(dest != IP_HDRINCL) {
00456     if(pbuf_header(p, IP_HLEN)) {
00457       DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));
00458       
00459 #ifdef IP_STATS
00460       ++lwip_stats.ip.err;
00461 #endif /* IP_STATS */
00462       snmp_inc_ipoutdiscards();
00463       return ERR_BUF;
00464     }
00465     
00466     iphdr = p->payload;
00467     
00468     IPH_TTL_SET(iphdr, ttl);
00469     IPH_PROTO_SET(iphdr, proto);
00470     
00471     ip_addr_set(&(iphdr->dest), dest);
00472 
00473     IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0);
00474     IPH_LEN_SET(iphdr, htons(p->tot_len));
00475     IPH_OFFSET_SET(iphdr, htons(IP_DF));
00476     IPH_ID_SET(iphdr, htons(ip_id));
00477     ++ip_id;
00478 
00479     if(ip_addr_isany(src)) {
00480       ip_addr_set(&(iphdr->src), &(netif->ip_addr));
00481     } else {
00482       ip_addr_set(&(iphdr->src), src);
00483     }
00484 
00485     IPH_CHKSUM_SET(iphdr, 0);
00486     IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
00487   } else {
00488     iphdr = p->payload;
00489     dest = &(iphdr->dest);
00490   }
00491 
00492 #if IP_FRAG     
00493   /* don't fragment if interface has mtu set to 0 [loopif] */
00494   if (netif->mtu && (p->tot_len > netif->mtu))
00495     return ip_frag(p,netif,dest);
00496 #endif
00497   
00498 #ifdef IP_STATS
00499   lwip_stats.ip.xmit++;
00500 #endif /* IP_STATS */
00501   DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%u\n", netif->name[0], netif->name[1], netif->num));
00502 #if IP_DEBUG
00503   ip_debug_print(p);
00504 #endif /* IP_DEBUG */
00505 
00506   DEBUGF(IP_DEBUG, ("netif->output()"));
00507 
00508   return netif->output(netif, p, dest);  
00509 }
00510 /*-----------------------------------------------------------------------------------*/
00511 /* ip_output:
00512  *
00513  * Simple interface to ip_output_if. It finds the outgoing network
00514  * interface and calls upon ip_output_if to do the actual work.
00515  */
00516 /*-----------------------------------------------------------------------------------*/
00517 err_t
00518 ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
00519           u8_t ttl, u8_t proto)
00520 {
00521   struct netif *netif;
00522   
00523   if((netif = ip_route(dest)) == NULL) {
00524     DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));
00525 
00526 #ifdef IP_STATS
00527     ++lwip_stats.ip.rterr;
00528 #endif /* IP_STATS */
00529     snmp_inc_ipoutdiscards();
00530     return ERR_RTE;
00531   }
00532 
00533   return ip_output_if(p, src, dest, ttl, proto, netif);
00534 }
00535 /*-----------------------------------------------------------------------------------*/
00536 #if IP_DEBUG
00537 void
00538 ip_debug_print(struct pbuf *p)
00539 {
00540   struct ip_hdr *iphdr = p->payload;
00541   u8_t *payload;
00542 
00543   payload = (u8_t *)iphdr + IP_HLEN;
00544   
00545   DEBUGF(IP_DEBUG, ("IP header:\n"));
00546   DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00547   DEBUGF(IP_DEBUG, ("|%2d |%2d |   %2u  |      %4u     | (v, hl, tos, len)\n",
00548                     IPH_V(iphdr),
00549                     IPH_HL(iphdr),
00550                     IPH_TOS(iphdr),
00551                     ntohs(IPH_LEN(iphdr))));
00552   DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00553   DEBUGF(IP_DEBUG, ("|    %5u      |%u%u%u|    %4u   | (id, flags, offset)\n",
00554                     ntohs(IPH_ID(iphdr)),
00555                     ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
00556                     ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
00557                     ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
00558                     ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
00559   DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00560   DEBUGF(IP_DEBUG, ("|   %2u  |   %2u  |    0x%04x     | (ttl, proto, chksum)\n",
00561                     IPH_TTL(iphdr),
00562                     IPH_PROTO(iphdr),
00563                     ntohs(IPH_CHKSUM(iphdr))));
00564   DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00565   DEBUGF(IP_DEBUG, ("|  %3ld  |  %3ld  |  %3ld  |  %3ld  | (src)\n",
00566                     ntohl(iphdr->src.addr) >> 24 & 0xff,
00567                     ntohl(iphdr->src.addr) >> 16 & 0xff,
00568                     ntohl(iphdr->src.addr) >> 8 & 0xff,
00569                     ntohl(iphdr->src.addr) & 0xff));
00570   DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00571   DEBUGF(IP_DEBUG, ("|  %3ld  |  %3ld  |  %3ld  |  %3ld  | (dest)\n",
00572                     ntohl(iphdr->dest.addr) >> 24 & 0xff,
00573                     ntohl(iphdr->dest.addr) >> 16 & 0xff,
00574                     ntohl(iphdr->dest.addr) >> 8 & 0xff,
00575                     ntohl(iphdr->dest.addr) & 0xff));
00576   DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00577 }
00578 #endif /* IP_DEBUG */
00579 /*-----------------------------------------------------------------------------------*/
00580 
00581 
00582 
00583 
00584 

Generated on Wed Jan 14 12:58:56 2004 for RTL-lwIP-0.4 by doxygen 1.3.4