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

ip.h File Reference

#include "lwip/arch.h"
#include "lwip/def.h"
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#include "lwip/err.h"

Include dependency graph for ipv4/lwip/ip.h:

Go to the source code of this file.

Data Structures

struct  ip_hdr

Defines

#define IP_HLEN   20
#define IP_PROTO_ICMP   1
#define IP_PROTO_UDP   17
#define IP_PROTO_UDPLITE   170
#define IP_PROTO_TCP   6
#define IP_HDRINCL   NULL
#define IP_RF   0x8000
#define IP_DF   0x4000
#define IP_MF   0x2000
#define IP_OFFMASK   0x1fff
#define IPH_V(hdr)   (ntohs((hdr)->_v_hl_tos) >> 12)
#define IPH_HL(hdr)   ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)
#define IPH_TOS(hdr)   (htons((ntohs((hdr)->_v_hl_tos) & 0xff)))
#define IPH_LEN(hdr)   ((hdr)->_len)
#define IPH_ID(hdr)   ((hdr)->_id)
#define IPH_OFFSET(hdr)   ((hdr)->_offset)
#define IPH_TTL(hdr)   (ntohs((hdr)->_ttl_proto) >> 8)
#define IPH_PROTO(hdr)   (ntohs((hdr)->_ttl_proto) & 0xff)
#define IPH_CHKSUM(hdr)   ((hdr)->_chksum)
#define IPH_VHLTOS_SET(hdr, v, hl, tos)   (hdr)->_v_hl_tos = (htons(((v) << 12) | ((hl) << 8) | (tos)))
#define IPH_LEN_SET(hdr, len)   (hdr)->_len = (len)
#define IPH_ID_SET(hdr, id)   (hdr)->_id = (id)
#define IPH_OFFSET_SET(hdr, off)   (hdr)->_offset = (off)
#define IPH_TTL_SET(hdr, ttl)   (hdr)->_ttl_proto = (htons(IPH_PROTO(hdr) | ((ttl) << 8)))
#define IPH_PROTO_SET(hdr, proto)   (hdr)->_ttl_proto = (htons((proto) | (IPH_TTL(hdr) << 8)))
#define IPH_CHKSUM_SET(hdr, chksum)   (hdr)->_chksum = (chksum)

Functions

void ip_init (void)
u8_t ip_lookup (void *header, struct netif *inp)
netifip_route (struct ip_addr *dest)
err_t ip_input (struct pbuf *p, struct netif *inp)
err_t ip_output (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t ttl, u8_t proto)
err_t ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t ttl, u8_t proto, struct netif *netif)

Variables

PACK_STRUCT_BEGIN struct ip_hdr PACK_STRUCT_STRUCT


Define Documentation

#define IP_DF   0x4000
 

Definition at line 90 of file ipv4/lwip/ip.h.

Referenced by ip_output_if().

#define IP_HDRINCL   NULL
 

Definition at line 74 of file ipv4/lwip/ip.h.

Referenced by icmp_input(), and ip_output_if().

#define IP_HLEN   20
 

Definition at line 61 of file ipv4/lwip/ip.h.

Referenced by icmp_dest_unreach(), icmp_input(), icmp_time_exceeded(), ip_frag(), ip_input(), ip_output_if(), and ip_reass().

#define IP_MF   0x2000
 

Definition at line 91 of file ipv4/lwip/ip.h.

Referenced by ip_frag(), ip_input(), and ip_reass().

#define IP_OFFMASK   0x1fff
 

Definition at line 92 of file ipv4/lwip/ip.h.

Referenced by ip_frag(), ip_input(), and ip_reass().

#define IP_PROTO_ICMP   1
 

Definition at line 63 of file ipv4/lwip/ip.h.

Referenced by icmp_dest_unreach(), icmp_input(), icmp_time_exceeded(), ip_forward(), and ip_input().

#define IP_PROTO_TCP   6
 

Definition at line 66 of file ipv4/lwip/ip.h.

Referenced by ip_input().

#define IP_PROTO_UDP   17
 

Definition at line 64 of file ipv4/lwip/ip.h.

Referenced by ip_input().

#define IP_PROTO_UDPLITE   170
 

Definition at line 65 of file ipv4/lwip/ip.h.

#define IP_RF   0x8000
 

Definition at line 89 of file ipv4/lwip/ip.h.

#define IPH_CHKSUM hdr   )     ((hdr)->_chksum)
 

Definition at line 114 of file ipv4/lwip/ip.h.

#define IPH_CHKSUM_SET hdr,
chksum   )     (hdr)->_chksum = (chksum)
 

Definition at line 122 of file ipv4/lwip/ip.h.

Referenced by ip_frag(), ip_output_if(), and ip_reass().

#define IPH_HL hdr   )     ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)
 

Definition at line 107 of file ipv4/lwip/ip.h.

Referenced by icmp_input(), ip_input(), and ip_reass().

#define IPH_ID hdr   )     ((hdr)->_id)
 

Definition at line 110 of file ipv4/lwip/ip.h.

Referenced by ip_input(), and ip_reass().

#define IPH_ID_SET hdr,
id   )     (hdr)->_id = (id)
 

Definition at line 118 of file ipv4/lwip/ip.h.

Referenced by ip_output_if().

#define IPH_LEN hdr   )     ((hdr)->_len)
 

Definition at line 109 of file ipv4/lwip/ip.h.

Referenced by ip_input(), and ip_reass().

#define IPH_LEN_SET hdr,
len   )     (hdr)->_len = (len)
 

Definition at line 117 of file ipv4/lwip/ip.h.

Referenced by ip_frag(), ip_output_if(), and ip_reass().

#define IPH_OFFSET hdr   )     ((hdr)->_offset)
 

Definition at line 111 of file ipv4/lwip/ip.h.

Referenced by ip_frag(), ip_input(), and ip_reass().

#define IPH_OFFSET_SET hdr,
off   )     (hdr)->_offset = (off)
 

Definition at line 119 of file ipv4/lwip/ip.h.

Referenced by ip_frag(), ip_output_if(), and ip_reass().

#define IPH_PROTO hdr   )     (ntohs((hdr)->_ttl_proto) & 0xff)
 

Definition at line 113 of file ipv4/lwip/ip.h.

Referenced by ip_input().

#define IPH_PROTO_SET hdr,
proto   )     (hdr)->_ttl_proto = (htons((proto) | (IPH_TTL(hdr) << 8)))
 

Definition at line 121 of file ipv4/lwip/ip.h.

Referenced by ip_output_if().

#define IPH_TOS hdr   )     (htons((ntohs((hdr)->_v_hl_tos) & 0xff)))
 

Definition at line 108 of file ipv4/lwip/ip.h.

#define IPH_TTL hdr   )     (ntohs((hdr)->_ttl_proto) >> 8)
 

Definition at line 112 of file ipv4/lwip/ip.h.

Referenced by icmp_input().

#define IPH_TTL_SET hdr,
ttl   )     (hdr)->_ttl_proto = (htons(IPH_PROTO(hdr) | ((ttl) << 8)))
 

Definition at line 120 of file ipv4/lwip/ip.h.

Referenced by ip_output_if().

#define IPH_V hdr   )     (ntohs((hdr)->_v_hl_tos) >> 12)
 

Definition at line 106 of file ipv4/lwip/ip.h.

Referenced by ip_input().

#define IPH_VHLTOS_SET hdr,
v,
hl,
tos   )     (hdr)->_v_hl_tos = (htons(((v) << 12) | ((hl) << 8) | (tos)))
 

Definition at line 116 of file ipv4/lwip/ip.h.

Referenced by ip_output_if().


Function Documentation

void ip_init void   ) 
 

Definition at line 75 of file ip.c.

00076 {
00077 }

err_t ip_input struct pbuf p,
struct netif inp
 

Definition at line 230 of file ip.c.

00230                                             {
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 }

u8_t ip_lookup void *  header,
struct netif inp
 

err_t ip_output struct pbuf p,
struct ip_addr src,
struct ip_addr dest,
u8_t  ttl,
u8_t  proto
 

Definition at line 518 of file ip.c.

References ip_addr::addr, DEBUGF, ERR_RTE, IP_DEBUG, ip_output_if(), ip_route(), NULL, snmp_inc_ipoutdiscards, and u8_t.

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 }

Here is the call graph for this function:

err_t ip_output_if struct pbuf p,
struct ip_addr src,
struct ip_addr dest,
u8_t  ttl,
u8_t  proto,
struct netif netif
 

Definition at line 446 of file ip.c.

References DEBUGF, ip_hdr::dest, ERR_BUF, htons, inet_chksum(), netif::ip_addr, ip_addr_isany, ip_addr_set, IP_DEBUG, IP_DF, ip_frag(), IP_HDRINCL, IP_HLEN, IPH_CHKSUM_SET, IPH_ID_SET, IPH_LEN_SET, IPH_OFFSET_SET, IPH_PROTO_SET, IPH_TTL_SET, IPH_VHLTOS_SET, netif::mtu, netif::name, netif::num, netif::output, pbuf::payload, pbuf_header(), snmp_inc_ipoutdiscards, snmp_inc_ipoutrequests, pbuf::tot_len, u16_t, and u8_t.

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 }

Here is the call graph for this function:

struct netif* ip_route struct ip_addr dest  ) 
 

Definition at line 138 of file ip.c.

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 }


Variable Documentation

PACK_STRUCT_BEGIN struct ip_hdr PACK_STRUCT_STRUCT
 


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