Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of lwip by
ip.c
00001 /** 00002 * @file 00003 * This is the IPv4 layer implementation for incoming and outgoing IP traffic. 00004 * 00005 * @see ip_frag.c 00006 * 00007 */ 00008 00009 /* 00010 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00011 * All rights reserved. 00012 * 00013 * Redistribution and use in source and binary forms, with or without modification, 00014 * are permitted provided that the following conditions are met: 00015 * 00016 * 1. Redistributions of source code must retain the above copyright notice, 00017 * this list of conditions and the following disclaimer. 00018 * 2. Redistributions in binary form must reproduce the above copyright notice, 00019 * this list of conditions and the following disclaimer in the documentation 00020 * and/or other materials provided with the distribution. 00021 * 3. The name of the author may not be used to endorse or promote products 00022 * derived from this software without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00025 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00026 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00027 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00028 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00029 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00030 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00031 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00032 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00033 * OF SUCH DAMAGE. 00034 * 00035 * This file is part of the lwIP TCP/IP stack. 00036 * 00037 * Author: Adam Dunkels <adam@sics.se> 00038 * 00039 */ 00040 00041 #include "lwip/opt.h" 00042 #include "lwip/ip.h" 00043 #include "lwip/def.h" 00044 #include "lwip/mem.h" 00045 #include "lwip/ip_frag.h" 00046 #include "lwip/inet_chksum.h" 00047 #include "lwip/netif.h" 00048 #include "lwip/icmp.h" 00049 #include "lwip/igmp.h" 00050 #include "lwip/raw.h" 00051 #include "lwip/udp.h" 00052 #include "lwip/tcp_impl.h" 00053 #include "lwip/snmp.h" 00054 #include "lwip/dhcp.h " 00055 #include "lwip/autoip.h" 00056 #include "lwip/stats.h" 00057 #include "arch/perf.h" 00058 00059 #include <string.h> 00060 00061 /** Set this to 0 in the rare case of wanting to call an extra function to 00062 * generate the IP checksum (in contrast to calculating it on-the-fly). */ 00063 #ifndef LWIP_INLINE_IP_CHKSUM 00064 #define LWIP_INLINE_IP_CHKSUM 1 00065 #endif 00066 #if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP 00067 #define CHECKSUM_GEN_IP_INLINE 1 00068 #else 00069 #define CHECKSUM_GEN_IP_INLINE 0 00070 #endif 00071 00072 #if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT) 00073 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 1 00074 00075 /** Some defines for DHCP to let link-layer-addressed packets through while the 00076 * netif is down. 00077 * To use this in your own application/protocol, define LWIP_IP_ACCEPT_UDP_PORT 00078 * to return 1 if the port is accepted and 0 if the port is not accepted. 00079 */ 00080 #if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) 00081 /* accept DHCP client port and custom port */ 00082 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \ 00083 || (LWIP_IP_ACCEPT_UDP_PORT(port))) 00084 #elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ 00085 /* accept custom port only */ 00086 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(dst_port)) 00087 #else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ 00088 /* accept DHCP client port only */ 00089 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT)) 00090 #endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ 00091 00092 #else /* LWIP_DHCP */ 00093 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 0 00094 #endif /* LWIP_DHCP */ 00095 00096 /** 00097 * The interface that provided the packet for the current callback 00098 * invocation. 00099 */ 00100 struct netif *current_netif; 00101 00102 /** 00103 * Header of the input packet currently being processed. 00104 */ 00105 const struct ip_hdr *current_header; 00106 /** Source IP address of current_header */ 00107 ip_addr_t current_iphdr_src; 00108 /** Destination IP address of current_header */ 00109 ip_addr_t current_iphdr_dest; 00110 00111 /** The IP header ID of the next outgoing IP packet */ 00112 static u16_t ip_id; 00113 00114 /** 00115 * Finds the appropriate network interface for a given IP address. It 00116 * searches the list of network interfaces linearly. A match is found 00117 * if the masked IP address of the network interface equals the masked 00118 * IP address given to the function. 00119 * 00120 * @param dest the destination IP address for which to find the route 00121 * @return the netif on which to send to reach dest 00122 */ 00123 struct netif * 00124 ip_route(ip_addr_t *dest) 00125 { 00126 struct netif *netif; 00127 00128 /* iterate through netifs */ 00129 for(netif = netif_list; netif != NULL; netif = netif->next) { 00130 /* network mask matches? */ 00131 if (netif_is_up(netif)) { 00132 if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { 00133 /* return netif on which to forward IP packet */ 00134 return netif; 00135 } 00136 } 00137 } 00138 if ((netif_default == NULL) || (!netif_is_up(netif_default))) { 00139 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00140 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); 00141 IP_STATS_INC(ip.rterr); 00142 snmp_inc_ipoutnoroutes(); 00143 return NULL; 00144 } 00145 /* no matching netif found, use default netif */ 00146 return netif_default; 00147 } 00148 00149 #if IP_FORWARD 00150 /** 00151 * Forwards an IP packet. It finds an appropriate route for the 00152 * packet, decrements the TTL value of the packet, adjusts the 00153 * checksum and outputs the packet on the appropriate interface. 00154 * 00155 * @param p the packet to forward (p->payload points to IP header) 00156 * @param iphdr the IP header of the input packet 00157 * @param inp the netif on which this packet was received 00158 */ 00159 static void 00160 ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) 00161 { 00162 struct netif *netif; 00163 00164 PERF_START; 00165 00166 /* RFC3927 2.7: do not forward link-local addresses */ 00167 if (ip_addr_islinklocal(¤t_iphdr_dest)) { 00168 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00169 ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), 00170 ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); 00171 goto return_noroute; 00172 } 00173 00174 /* Find network interface where to forward this IP packet to. */ 00175 netif = ip_route(¤t_iphdr_dest); 00176 if (netif == NULL) { 00177 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", 00178 ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), 00179 ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); 00180 goto return_noroute; 00181 } 00182 /* Do not forward packets onto the same network interface on which 00183 * they arrived. */ 00184 if (netif == inp) { 00185 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n")); 00186 goto return_noroute; 00187 } 00188 00189 /* decrement TTL */ 00190 IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); 00191 /* send ICMP if TTL == 0 */ 00192 if (IPH_TTL(iphdr) == 0) { 00193 snmp_inc_ipinhdrerrors(); 00194 #if LWIP_ICMP 00195 /* Don't send ICMP messages in response to ICMP messages */ 00196 if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { 00197 icmp_time_exceeded(p, ICMP_TE_TTL); 00198 } 00199 #endif /* LWIP_ICMP */ 00200 return; 00201 } 00202 00203 /* Incrementally update the IP checksum. */ 00204 if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) { 00205 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1); 00206 } else { 00207 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100)); 00208 } 00209 00210 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00211 ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), 00212 ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); 00213 00214 IP_STATS_INC(ip.fw); 00215 IP_STATS_INC(ip.xmit); 00216 snmp_inc_ipforwdatagrams(); 00217 00218 PERF_STOP("ip_forward"); 00219 /* transmit pbuf on chosen interface */ 00220 netif->output(netif, p, ¤t_iphdr_dest); 00221 return; 00222 return_noroute: 00223 snmp_inc_ipoutnoroutes(); 00224 } 00225 #endif /* IP_FORWARD */ 00226 00227 /** 00228 * This function is called by the network interface device driver when 00229 * an IP packet is received. The function does the basic checks of the 00230 * IP header such as packet size being at least larger than the header 00231 * size etc. If the packet was not destined for us, the packet is 00232 * forwarded (using ip_forward). The IP checksum is always checked. 00233 * 00234 * Finally, the packet is sent to the upper layer protocol input function. 00235 * 00236 * @param p the received IP packet (p->payload points to IP header) 00237 * @param inp the netif on which this packet was received 00238 * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't 00239 * processed, but currently always returns ERR_OK) 00240 */ 00241 err_t 00242 ip_input(struct pbuf *p, struct netif *inp) 00243 { 00244 struct ip_hdr *iphdr; 00245 struct netif *netif; 00246 u16_t iphdr_hlen; 00247 u16_t iphdr_len; 00248 #if IP_ACCEPT_LINK_LAYER_ADDRESSING 00249 int check_ip_src=1; 00250 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ 00251 00252 IP_STATS_INC(ip.recv); 00253 snmp_inc_ipinreceives(); 00254 00255 /* identify the IP header */ 00256 iphdr = (struct ip_hdr *)p->payload; 00257 if (IPH_V(iphdr) != 4) { 00258 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr))); 00259 ip_debug_print(p); 00260 pbuf_free(p); 00261 IP_STATS_INC(ip.err); 00262 IP_STATS_INC(ip.drop); 00263 snmp_inc_ipinhdrerrors(); 00264 return ERR_OK; 00265 } 00266 00267 /* obtain IP header length in number of 32-bit words */ 00268 iphdr_hlen = IPH_HL(iphdr); 00269 /* calculate IP header length in bytes */ 00270 iphdr_hlen *= 4; 00271 /* obtain ip length in bytes */ 00272 iphdr_len = ntohs(IPH_LEN(iphdr)); 00273 00274 /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ 00275 if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) { 00276 if (iphdr_hlen > p->len) { 00277 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00278 ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", 00279 iphdr_hlen, p->len)); 00280 } 00281 if (iphdr_len > p->tot_len) { 00282 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00283 ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", 00284 iphdr_len, p->tot_len)); 00285 } 00286 /* free (drop) packet pbufs */ 00287 pbuf_free(p); 00288 IP_STATS_INC(ip.lenerr); 00289 IP_STATS_INC(ip.drop); 00290 snmp_inc_ipindiscards(); 00291 return ERR_OK; 00292 } 00293 00294 /* verify checksum */ 00295 #if CHECKSUM_CHECK_IP 00296 if (inet_chksum(iphdr, iphdr_hlen) != 0) { 00297 00298 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00299 ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); 00300 ip_debug_print(p); 00301 pbuf_free(p); 00302 IP_STATS_INC(ip.chkerr); 00303 IP_STATS_INC(ip.drop); 00304 snmp_inc_ipinhdrerrors(); 00305 return ERR_OK; 00306 } 00307 #endif 00308 00309 /* Trim pbuf. This should have been done at the netif layer, 00310 * but we'll do it anyway just to be sure that its done. */ 00311 pbuf_realloc(p, iphdr_len); 00312 00313 /* copy IP addresses to aligned ip_addr_t */ 00314 ip_addr_copy(current_iphdr_dest, iphdr->dest); 00315 ip_addr_copy(current_iphdr_src, iphdr->src); 00316 00317 /* match packet against an interface, i.e. is this packet for us? */ 00318 #if LWIP_IGMP 00319 if (ip_addr_ismulticast(¤t_iphdr_dest)) { 00320 if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ¤t_iphdr_dest))) { 00321 netif = inp; 00322 } else { 00323 netif = NULL; 00324 } 00325 } else 00326 #endif /* LWIP_IGMP */ 00327 { 00328 /* start trying with inp. if that's not acceptable, start walking the 00329 list of configured netifs. 00330 'first' is used as a boolean to mark whether we started walking the list */ 00331 int first = 1; 00332 netif = inp; 00333 do { 00334 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", 00335 ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(&netif->ip_addr), 00336 ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(&netif->netmask), 00337 ip4_addr_get_u32(&netif->ip_addr) & ip4_addr_get_u32(&netif->netmask), 00338 ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(&netif->netmask))); 00339 00340 /* interface is up and configured? */ 00341 if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) { 00342 /* unicast to this interface address? */ 00343 if (ip_addr_cmp(¤t_iphdr_dest, &(netif->ip_addr)) || 00344 /* or broadcast on this interface network address? */ 00345 ip_addr_isbroadcast(¤t_iphdr_dest, netif)) { 00346 LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n", 00347 netif->name[0], netif->name[1])); 00348 /* break out of for loop */ 00349 break; 00350 } 00351 #if LWIP_AUTOIP 00352 /* connections to link-local addresses must persist after changing 00353 the netif's address (RFC3927 ch. 1.9) */ 00354 if ((netif->autoip != NULL) && 00355 ip_addr_cmp(¤t_iphdr_dest, &(netif->autoip->llipaddr))) { 00356 LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n", 00357 netif->name[0], netif->name[1])); 00358 /* break out of for loop */ 00359 break; 00360 } 00361 #endif /* LWIP_AUTOIP */ 00362 } 00363 if (first) { 00364 first = 0; 00365 netif = netif_list; 00366 } else { 00367 netif = netif->next; 00368 } 00369 if (netif == inp) { 00370 netif = netif->next; 00371 } 00372 } while(netif != NULL); 00373 } 00374 00375 #if IP_ACCEPT_LINK_LAYER_ADDRESSING 00376 /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed 00377 * using link layer addressing (such as Ethernet MAC) so we must not filter on IP. 00378 * According to RFC 1542 section 3.1.1, referred by RFC 2131). 00379 * 00380 * If you want to accept private broadcast communication while a netif is down, 00381 * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.: 00382 * 00383 * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345)) 00384 */ 00385 if (netif == NULL) { 00386 /* remote port is DHCP server? */ 00387 if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { 00388 struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen); 00389 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n", 00390 ntohs(udphdr->dest))); 00391 if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) { 00392 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n")); 00393 netif = inp; 00394 check_ip_src = 0; 00395 } 00396 } 00397 } 00398 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ 00399 00400 /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ 00401 #if IP_ACCEPT_LINK_LAYER_ADDRESSING 00402 /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ 00403 if (check_ip_src && current_iphdr_src.addr != IPADDR_ANY) 00404 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ 00405 { if ((ip_addr_isbroadcast(¤t_iphdr_src, inp)) || 00406 (ip_addr_ismulticast(¤t_iphdr_src))) { 00407 /* packet source is not valid */ 00408 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n")); 00409 /* free (drop) packet pbufs */ 00410 pbuf_free(p); 00411 IP_STATS_INC(ip.drop); 00412 snmp_inc_ipinaddrerrors(); 00413 snmp_inc_ipindiscards(); 00414 return ERR_OK; 00415 } 00416 } 00417 00418 /* packet not for us? */ 00419 if (netif == NULL) { 00420 /* packet not for us, route or discard */ 00421 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n")); 00422 #if IP_FORWARD 00423 /* non-broadcast packet? */ 00424 if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp)) { 00425 /* try to forward IP packet on (other) interfaces */ 00426 ip_forward(p, iphdr, inp); 00427 } else 00428 #endif /* IP_FORWARD */ 00429 { 00430 snmp_inc_ipinaddrerrors(); 00431 snmp_inc_ipindiscards(); 00432 } 00433 pbuf_free(p); 00434 return ERR_OK; 00435 } 00436 /* packet consists of multiple fragments? */ 00437 if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { 00438 #if IP_REASSEMBLY /* packet fragment reassembly code present? */ 00439 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", 00440 ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)); 00441 /* reassemble the packet*/ 00442 p = ip_reass(p); 00443 /* packet not fully reassembled yet? */ 00444 if (p == NULL) { 00445 return ERR_OK; 00446 } 00447 iphdr = (struct ip_hdr *)p->payload; 00448 #else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */ 00449 pbuf_free(p); 00450 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n", 00451 ntohs(IPH_OFFSET(iphdr)))); 00452 IP_STATS_INC(ip.opterr); 00453 IP_STATS_INC(ip.drop); 00454 /* unsupported protocol feature */ 00455 snmp_inc_ipinunknownprotos(); 00456 return ERR_OK; 00457 #endif /* IP_REASSEMBLY */ 00458 } 00459 00460 #if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */ 00461 00462 #if LWIP_IGMP 00463 /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */ 00464 if((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) { 00465 #else 00466 if (iphdr_hlen > IP_HLEN) { 00467 #endif /* LWIP_IGMP */ 00468 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n")); 00469 pbuf_free(p); 00470 IP_STATS_INC(ip.opterr); 00471 IP_STATS_INC(ip.drop); 00472 /* unsupported protocol feature */ 00473 snmp_inc_ipinunknownprotos(); 00474 return ERR_OK; 00475 } 00476 #endif /* IP_OPTIONS_ALLOWED == 0 */ 00477 00478 /* send to upper layers */ 00479 LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n")); 00480 ip_debug_print(p); 00481 LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); 00482 00483 current_netif = inp; 00484 current_header = iphdr; 00485 00486 #if LWIP_RAW 00487 /* raw input did not eat the packet? */ 00488 if (raw_input(p, inp) == 0) 00489 #endif /* LWIP_RAW */ 00490 { 00491 00492 switch (IPH_PROTO(iphdr)) { 00493 #if LWIP_UDP 00494 case IP_PROTO_UDP: 00495 #if LWIP_UDPLITE 00496 case IP_PROTO_UDPLITE: 00497 #endif /* LWIP_UDPLITE */ 00498 snmp_inc_ipindelivers(); 00499 udp_input(p, inp); 00500 break; 00501 #endif /* LWIP_UDP */ 00502 #if LWIP_TCP 00503 case IP_PROTO_TCP: 00504 snmp_inc_ipindelivers(); 00505 tcp_input(p, inp); 00506 break; 00507 #endif /* LWIP_TCP */ 00508 #if LWIP_ICMP 00509 case IP_PROTO_ICMP: 00510 snmp_inc_ipindelivers(); 00511 icmp_input(p, inp); 00512 break; 00513 #endif /* LWIP_ICMP */ 00514 #if LWIP_IGMP 00515 case IP_PROTO_IGMP: 00516 igmp_input(p, inp, ¤t_iphdr_dest); 00517 break; 00518 #endif /* LWIP_IGMP */ 00519 default: 00520 #if LWIP_ICMP 00521 /* send ICMP destination protocol unreachable unless is was a broadcast */ 00522 if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp) && 00523 !ip_addr_ismulticast(¤t_iphdr_dest)) { 00524 p->payload = iphdr; 00525 icmp_dest_unreach(p, ICMP_DUR_PROTO); 00526 } 00527 #endif /* LWIP_ICMP */ 00528 pbuf_free(p); 00529 00530 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr))); 00531 00532 IP_STATS_INC(ip.proterr); 00533 IP_STATS_INC(ip.drop); 00534 snmp_inc_ipinunknownprotos(); 00535 } 00536 } 00537 00538 current_netif = NULL; 00539 current_header = NULL; 00540 ip_addr_set_any(¤t_iphdr_src); 00541 ip_addr_set_any(¤t_iphdr_dest); 00542 00543 return ERR_OK; 00544 } 00545 00546 /** 00547 * Sends an IP packet on a network interface. This function constructs 00548 * the IP header and calculates the IP header checksum. If the source 00549 * IP address is NULL, the IP address of the outgoing network 00550 * interface is filled in as source address. 00551 * If the destination IP address is IP_HDRINCL, p is assumed to already 00552 * include an IP header and p->payload points to it instead of the data. 00553 * 00554 * @param p the packet to send (p->payload points to the data, e.g. next 00555 protocol header; if dest == IP_HDRINCL, p already includes an IP 00556 header and p->payload points to that IP header) 00557 * @param src the source IP address to send from (if src == IP_ADDR_ANY, the 00558 * IP address of the netif used to send is used as source address) 00559 * @param dest the destination IP address to send the packet to 00560 * @param ttl the TTL value to be set in the IP header 00561 * @param tos the TOS value to be set in the IP header 00562 * @param proto the PROTOCOL to be set in the IP header 00563 * @param netif the netif on which to send this packet 00564 * @return ERR_OK if the packet was sent OK 00565 * ERR_BUF if p doesn't have enough space for IP/LINK headers 00566 * returns errors returned by netif->output 00567 * 00568 * @note ip_id: RFC791 "some host may be able to simply use 00569 * unique identifiers independent of destination" 00570 */ 00571 err_t 00572 ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, 00573 u8_t ttl, u8_t tos, 00574 u8_t proto, struct netif *netif) 00575 { 00576 #if IP_OPTIONS_SEND 00577 return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0); 00578 } 00579 00580 /** 00581 * Same as ip_output_if() but with the possibility to include IP options: 00582 * 00583 * @ param ip_options pointer to the IP options, copied into the IP header 00584 * @ param optlen length of ip_options 00585 */ 00586 err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, 00587 u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, 00588 u16_t optlen) 00589 { 00590 #endif /* IP_OPTIONS_SEND */ 00591 struct ip_hdr *iphdr; 00592 ip_addr_t dest_addr; 00593 #if CHECKSUM_GEN_IP_INLINE 00594 u32_t chk_sum = 0; 00595 #endif /* CHECKSUM_GEN_IP_INLINE */ 00596 00597 /* pbufs passed to IP must have a ref-count of 1 as their payload pointer 00598 gets altered as the packet is passed down the stack */ 00599 LWIP_ASSERT("p->ref == 1", p->ref == 1); 00600 00601 snmp_inc_ipoutrequests(); 00602 00603 /* Should the IP header be generated or is it already included in p? */ 00604 if (dest != IP_HDRINCL) { 00605 u16_t ip_hlen = IP_HLEN; 00606 #if IP_OPTIONS_SEND 00607 u16_t optlen_aligned = 0; 00608 if (optlen != 0) { 00609 #if CHECKSUM_GEN_IP_INLINE 00610 int i; 00611 #endif /* CHECKSUM_GEN_IP_INLINE */ 00612 /* round up to a multiple of 4 */ 00613 optlen_aligned = ((optlen + 3) & ~3); 00614 ip_hlen += optlen_aligned; 00615 /* First write in the IP options */ 00616 if (pbuf_header(p, optlen_aligned)) { 00617 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n")); 00618 IP_STATS_INC(ip.err); 00619 snmp_inc_ipoutdiscards(); 00620 return ERR_BUF; 00621 } 00622 MEMCPY(p->payload, ip_options, optlen); 00623 if (optlen < optlen_aligned) { 00624 /* zero the remaining bytes */ 00625 memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen); 00626 } 00627 #if CHECKSUM_GEN_IP_INLINE 00628 for (i = 0; i < optlen_aligned/2; i++) { 00629 chk_sum += ((u16_t*)p->payload)[i]; 00630 } 00631 #endif /* CHECKSUM_GEN_IP_INLINE */ 00632 } 00633 #endif /* IP_OPTIONS_SEND */ 00634 /* generate IP header */ 00635 if (pbuf_header(p, IP_HLEN)) { 00636 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n")); 00637 00638 IP_STATS_INC(ip.err); 00639 snmp_inc_ipoutdiscards(); 00640 return ERR_BUF; 00641 } 00642 00643 iphdr = (struct ip_hdr *)p->payload; 00644 LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", 00645 (p->len >= sizeof(struct ip_hdr))); 00646 00647 IPH_TTL_SET(iphdr, ttl); 00648 IPH_PROTO_SET(iphdr, proto); 00649 #if CHECKSUM_GEN_IP_INLINE 00650 chk_sum += LWIP_MAKE_U16(proto, ttl); 00651 #endif /* CHECKSUM_GEN_IP_INLINE */ 00652 00653 /* dest cannot be NULL here */ 00654 ip_addr_copy(iphdr->dest, *dest); 00655 #if CHECKSUM_GEN_IP_INLINE 00656 chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; 00657 chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; 00658 #endif /* CHECKSUM_GEN_IP_INLINE */ 00659 00660 IPH_VHLTOS_SET(iphdr, 4, ip_hlen / 4, tos); 00661 #if CHECKSUM_GEN_IP_INLINE 00662 chk_sum += iphdr->_v_hl_tos; 00663 #endif /* CHECKSUM_GEN_IP_INLINE */ 00664 IPH_LEN_SET(iphdr, htons(p->tot_len)); 00665 #if CHECKSUM_GEN_IP_INLINE 00666 chk_sum += iphdr->_len; 00667 #endif /* CHECKSUM_GEN_IP_INLINE */ 00668 IPH_OFFSET_SET(iphdr, 0); 00669 IPH_ID_SET(iphdr, htons(ip_id)); 00670 #if CHECKSUM_GEN_IP_INLINE 00671 chk_sum += iphdr->_id; 00672 #endif /* CHECKSUM_GEN_IP_INLINE */ 00673 ++ip_id; 00674 00675 if (ip_addr_isany(src)) { 00676 ip_addr_copy(iphdr->src, netif->ip_addr); 00677 } else { 00678 /* src cannot be NULL here */ 00679 ip_addr_copy(iphdr->src, *src); 00680 } 00681 00682 #if CHECKSUM_GEN_IP_INLINE 00683 chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; 00684 chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; 00685 chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); 00686 chk_sum = (chk_sum >> 16) + chk_sum; 00687 chk_sum = ~chk_sum; 00688 iphdr->_chksum = chk_sum; /* network order */ 00689 #else /* CHECKSUM_GEN_IP_INLINE */ 00690 IPH_CHKSUM_SET(iphdr, 0); 00691 #if CHECKSUM_GEN_IP 00692 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); 00693 #endif 00694 #endif /* CHECKSUM_GEN_IP_INLINE */ 00695 } else { 00696 /* IP header already included in p */ 00697 iphdr = (struct ip_hdr *)p->payload; 00698 ip_addr_copy(dest_addr, iphdr->dest); 00699 dest = &dest_addr; 00700 } 00701 00702 IP_STATS_INC(ip.xmit); 00703 00704 LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num)); 00705 ip_debug_print(p); 00706 00707 #if ENABLE_LOOPBACK 00708 if (ip_addr_cmp(dest, &netif->ip_addr)) { 00709 /* Packet to self, enqueue it for loopback */ 00710 LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); 00711 return netif_loop_output(netif, p, dest); 00712 } 00713 #if LWIP_IGMP 00714 if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) { 00715 netif_loop_output(netif, p, dest); 00716 } 00717 #endif /* LWIP_IGMP */ 00718 #endif /* ENABLE_LOOPBACK */ 00719 #if IP_FRAG 00720 /* don't fragment if interface has mtu set to 0 [loopif] */ 00721 if (netif->mtu && (p->tot_len > netif->mtu)) { 00722 return ip_frag(p, netif, dest); 00723 } 00724 #endif /* IP_FRAG */ 00725 00726 LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); 00727 return netif->output(netif, p, dest); 00728 } 00729 00730 /** 00731 * Simple interface to ip_output_if. It finds the outgoing network 00732 * interface and calls upon ip_output_if to do the actual work. 00733 * 00734 * @param p the packet to send (p->payload points to the data, e.g. next 00735 protocol header; if dest == IP_HDRINCL, p already includes an IP 00736 header and p->payload points to that IP header) 00737 * @param src the source IP address to send from (if src == IP_ADDR_ANY, the 00738 * IP address of the netif used to send is used as source address) 00739 * @param dest the destination IP address to send the packet to 00740 * @param ttl the TTL value to be set in the IP header 00741 * @param tos the TOS value to be set in the IP header 00742 * @param proto the PROTOCOL to be set in the IP header 00743 * 00744 * @return ERR_RTE if no route is found 00745 * see ip_output_if() for more return values 00746 */ 00747 err_t 00748 ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, 00749 u8_t ttl, u8_t tos, u8_t proto) 00750 { 00751 struct netif *netif; 00752 00753 /* pbufs passed to IP must have a ref-count of 1 as their payload pointer 00754 gets altered as the packet is passed down the stack */ 00755 LWIP_ASSERT("p->ref == 1", p->ref == 1); 00756 00757 if ((netif = ip_route(dest)) == NULL) { 00758 LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00759 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); 00760 IP_STATS_INC(ip.rterr); 00761 return ERR_RTE; 00762 } 00763 00764 return ip_output_if(p, src, dest, ttl, tos, proto, netif); 00765 } 00766 00767 #if LWIP_NETIF_HWADDRHINT 00768 /** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint 00769 * before calling ip_output_if. 00770 * 00771 * @param p the packet to send (p->payload points to the data, e.g. next 00772 protocol header; if dest == IP_HDRINCL, p already includes an IP 00773 header and p->payload points to that IP header) 00774 * @param src the source IP address to send from (if src == IP_ADDR_ANY, the 00775 * IP address of the netif used to send is used as source address) 00776 * @param dest the destination IP address to send the packet to 00777 * @param ttl the TTL value to be set in the IP header 00778 * @param tos the TOS value to be set in the IP header 00779 * @param proto the PROTOCOL to be set in the IP header 00780 * @param addr_hint address hint pointer set to netif->addr_hint before 00781 * calling ip_output_if() 00782 * 00783 * @return ERR_RTE if no route is found 00784 * see ip_output_if() for more return values 00785 */ 00786 err_t 00787 ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, 00788 u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) 00789 { 00790 struct netif *netif; 00791 err_t err; 00792 00793 /* pbufs passed to IP must have a ref-count of 1 as their payload pointer 00794 gets altered as the packet is passed down the stack */ 00795 LWIP_ASSERT("p->ref == 1", p->ref == 1); 00796 00797 if ((netif = ip_route(dest)) == NULL) { 00798 LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00799 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); 00800 IP_STATS_INC(ip.rterr); 00801 return ERR_RTE; 00802 } 00803 00804 netif->addr_hint = addr_hint; 00805 err = ip_output_if(p, src, dest, ttl, tos, proto, netif); 00806 netif->addr_hint = NULL; 00807 00808 return err; 00809 } 00810 #endif /* LWIP_NETIF_HWADDRHINT*/ 00811 00812 #if IP_DEBUG 00813 /* Print an IP header by using LWIP_DEBUGF 00814 * @param p an IP packet, p->payload pointing to the IP header 00815 */ 00816 void 00817 ip_debug_print(struct pbuf *p) 00818 { 00819 struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; 00820 u8_t *payload; 00821 00822 payload = (u8_t *)iphdr + IP_HLEN; 00823 00824 LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); 00825 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 00826 LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", 00827 IPH_V(iphdr), 00828 IPH_HL(iphdr), 00829 IPH_TOS(iphdr), 00830 ntohs(IPH_LEN(iphdr)))); 00831 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 00832 LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", 00833 ntohs(IPH_ID(iphdr)), 00834 ntohs(IPH_OFFSET(iphdr)) >> 15 & 1, 00835 ntohs(IPH_OFFSET(iphdr)) >> 14 & 1, 00836 ntohs(IPH_OFFSET(iphdr)) >> 13 & 1, 00837 ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)); 00838 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 00839 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", 00840 IPH_TTL(iphdr), 00841 IPH_PROTO(iphdr), 00842 ntohs(IPH_CHKSUM(iphdr)))); 00843 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 00844 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", 00845 ip4_addr1_16(&iphdr->src), 00846 ip4_addr2_16(&iphdr->src), 00847 ip4_addr3_16(&iphdr->src), 00848 ip4_addr4_16(&iphdr->src))); 00849 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 00850 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", 00851 ip4_addr1_16(&iphdr->dest), 00852 ip4_addr2_16(&iphdr->dest), 00853 ip4_addr3_16(&iphdr->dest), 00854 ip4_addr4_16(&iphdr->dest))); 00855 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 00856 } 00857 #endif /* IP_DEBUG */
Generated on Tue Jul 12 2022 13:44:40 by
