#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/ip.h"
#include "lwip/ip_frag.h"
#include "lwip/inet.h"
#include "lwip/netif.h"
#include "lwip/icmp.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
Include dependency graph for ip.c:
Go to the source code of this file.
Defines | |
#define | htons HTONS |
#define | htonl HTONL |
Functions | |
void | ip_init (void) |
netif * | ip_route (struct ip_addr *dest) |
err_t | ip_input (struct pbuf *p, struct netif *inp) |
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) |
err_t | ip_output (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t ttl, u8_t proto) |
|
|
|
|
|
Definition at line 75 of file ip.c. Referenced by tcpip_thread().
00076 { 00077 } |
|
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 } |
|
Definition at line 518 of file ip.c.
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 } |
|
Definition at line 446 of file ip.c.
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 } |
|
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 } |