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.
Dependents: mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more
lwip_ip4.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 00043 #if LWIP_IPV4 00044 00045 #include "lwip/ip.h" 00046 #include "lwip/def.h" 00047 #include "lwip/mem.h" 00048 #include "lwip/ip4_frag.h" 00049 #include "lwip/inet_chksum.h" 00050 #include "lwip/netif.h" 00051 #include "lwip/icmp.h" 00052 #include "lwip/igmp.h" 00053 #include "lwip/raw.h" 00054 #include "lwip/udp.h" 00055 #include "lwip/priv/tcp_priv.h" 00056 #include "lwip/autoip.h" 00057 #include "lwip/stats.h" 00058 #include "lwip/prot/dhcp.h" 00059 00060 #include <string.h> 00061 00062 /** Set this to 0 in the rare case of wanting to call an extra function to 00063 * generate the IP checksum (in contrast to calculating it on-the-fly). */ 00064 #ifndef LWIP_INLINE_IP_CHKSUM 00065 #if LWIP_CHECKSUM_CTRL_PER_NETIF 00066 #define LWIP_INLINE_IP_CHKSUM 0 00067 #else /* LWIP_CHECKSUM_CTRL_PER_NETIF */ 00068 #define LWIP_INLINE_IP_CHKSUM 1 00069 #endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ 00070 #endif 00071 00072 #if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP 00073 #define CHECKSUM_GEN_IP_INLINE 1 00074 #else 00075 #define CHECKSUM_GEN_IP_INLINE 0 00076 #endif 00077 00078 #if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT) 00079 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 1 00080 00081 /** Some defines for DHCP to let link-layer-addressed packets through while the 00082 * netif is down. 00083 * To use this in your own application/protocol, define LWIP_IP_ACCEPT_UDP_PORT(port) 00084 * to return 1 if the port is accepted and 0 if the port is not accepted. 00085 */ 00086 #if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) 00087 /* accept DHCP client port and custom port */ 00088 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \ 00089 || (LWIP_IP_ACCEPT_UDP_PORT(port))) 00090 #elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ 00091 /* accept custom port only */ 00092 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port)) 00093 #else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ 00094 /* accept DHCP client port only */ 00095 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT)) 00096 #endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ 00097 00098 #else /* LWIP_DHCP */ 00099 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 0 00100 #endif /* LWIP_DHCP */ 00101 00102 /** The IP header ID of the next outgoing IP packet */ 00103 static u16_t ip_id; 00104 00105 #if LWIP_MULTICAST_TX_OPTIONS 00106 /** The default netif used for multicast */ 00107 static struct netif* ip4_default_multicast_netif; 00108 00109 /** 00110 * @ingroup ip4 00111 * Set a default netif for IPv4 multicast. */ 00112 void 00113 ip4_set_default_multicast_netif(struct netif* default_multicast_netif) 00114 { 00115 ip4_default_multicast_netif = default_multicast_netif; 00116 } 00117 #endif /* LWIP_MULTICAST_TX_OPTIONS */ 00118 00119 #ifdef LWIP_HOOK_IP4_ROUTE_SRC 00120 /** 00121 * Source based IPv4 routing must be fully implemented in 00122 * LWIP_HOOK_IP4_ROUTE_SRC(). This function only provides he parameters. 00123 */ 00124 struct netif * 00125 ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src) 00126 { 00127 if (src != NULL) { 00128 /* when src==NULL, the hook is called from ip4_route(dest) */ 00129 struct netif *netif = LWIP_HOOK_IP4_ROUTE_SRC(dest, src); 00130 if (netif != NULL) { 00131 return netif; 00132 } 00133 } 00134 return ip4_route(dest); 00135 } 00136 #endif /* LWIP_HOOK_IP4_ROUTE_SRC */ 00137 00138 /** 00139 * Finds the appropriate network interface for a given IP address. It 00140 * searches the list of network interfaces linearly. A match is found 00141 * if the masked IP address of the network interface equals the masked 00142 * IP address given to the function. 00143 * 00144 * @param dest the destination IP address for which to find the route 00145 * @return the netif on which to send to reach dest 00146 */ 00147 struct netif * 00148 ip4_route(const ip4_addr_t *dest) 00149 { 00150 struct netif *netif; 00151 00152 #if LWIP_MULTICAST_TX_OPTIONS 00153 /* Use administratively selected interface for multicast by default */ 00154 if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) { 00155 return ip4_default_multicast_netif; 00156 } 00157 #endif /* LWIP_MULTICAST_TX_OPTIONS */ 00158 00159 /* iterate through netifs */ 00160 for (netif = netif_list; netif != NULL; netif = netif->next) { 00161 /* is the netif up, does it have a link and a valid address? */ 00162 if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { 00163 /* network mask matches? */ 00164 if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) { 00165 /* return netif on which to forward IP packet */ 00166 return netif; 00167 } 00168 /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */ 00169 if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) { 00170 /* return netif on which to forward IP packet */ 00171 return netif; 00172 } 00173 } 00174 } 00175 00176 #if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF 00177 /* loopif is disabled, looopback traffic is passed through any netif */ 00178 if (ip4_addr_isloopback(dest)) { 00179 /* don't check for link on loopback traffic */ 00180 if (netif_default != NULL && netif_is_up(netif_default)) { 00181 return netif_default; 00182 } 00183 /* default netif is not up, just use any netif for loopback traffic */ 00184 for (netif = netif_list; netif != NULL; netif = netif->next) { 00185 if (netif_is_up(netif)) { 00186 return netif; 00187 } 00188 } 00189 return NULL; 00190 } 00191 #endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ 00192 00193 #ifdef LWIP_HOOK_IP4_ROUTE_SRC 00194 netif = LWIP_HOOK_IP4_ROUTE_SRC(dest, NULL); 00195 if (netif != NULL) { 00196 return netif; 00197 } 00198 #elif defined(LWIP_HOOK_IP4_ROUTE) 00199 netif = LWIP_HOOK_IP4_ROUTE(dest); 00200 if (netif != NULL) { 00201 return netif; 00202 } 00203 #endif 00204 00205 if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) || 00206 ip4_addr_isany_val(*netif_ip4_addr(netif_default))) { 00207 /* No matching netif found and default netif is not usable. 00208 If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */ 00209 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00210 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); 00211 IP_STATS_INC(ip.rterr); 00212 MIB2_STATS_INC(mib2.ipoutnoroutes); 00213 return NULL; 00214 } 00215 00216 return netif_default; 00217 } 00218 00219 #if IP_FORWARD 00220 /** 00221 * Determine whether an IP address is in a reserved set of addresses 00222 * that may not be forwarded, or whether datagrams to that destination 00223 * may be forwarded. 00224 * @param p the packet to forward 00225 * @return 1: can forward 0: discard 00226 */ 00227 static int 00228 ip4_canforward(struct pbuf *p) 00229 { 00230 u32_t addr = lwip_htonl(ip4_addr_get_u32(ip4_current_dest_addr())); 00231 00232 if (p->flags & PBUF_FLAG_LLBCAST) { 00233 /* don't route link-layer broadcasts */ 00234 return 0; 00235 } 00236 if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) { 00237 /* don't route link-layer multicasts unless the destination address is an IP 00238 multicast address */ 00239 return 0; 00240 } 00241 if (IP_EXPERIMENTAL(addr)) { 00242 return 0; 00243 } 00244 if (IP_CLASSA(addr)) { 00245 u32_t net = addr & IP_CLASSA_NET; 00246 if ((net == 0) || (net == ((u32_t)IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) { 00247 /* don't route loopback packets */ 00248 return 0; 00249 } 00250 } 00251 return 1; 00252 } 00253 00254 /** 00255 * Forwards an IP packet. It finds an appropriate route for the 00256 * packet, decrements the TTL value of the packet, adjusts the 00257 * checksum and outputs the packet on the appropriate interface. 00258 * 00259 * @param p the packet to forward (p->payload points to IP header) 00260 * @param iphdr the IP header of the input packet 00261 * @param inp the netif on which this packet was received 00262 */ 00263 static void 00264 ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) 00265 { 00266 struct netif *netif; 00267 00268 PERF_START; 00269 LWIP_UNUSED_ARG(inp); 00270 00271 if (!ip4_canforward(p)) { 00272 goto return_noroute; 00273 } 00274 00275 /* RFC3927 2.7: do not forward link-local addresses */ 00276 if (ip4_addr_islinklocal(ip4_current_dest_addr())) { 00277 LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00278 ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), 00279 ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); 00280 goto return_noroute; 00281 } 00282 00283 /* Find network interface where to forward this IP packet to. */ 00284 netif = ip4_route_src(ip4_current_dest_addr(), ip4_current_src_addr()); 00285 if (netif == NULL) { 00286 LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", 00287 ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), 00288 ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); 00289 /* @todo: send ICMP_DUR_NET? */ 00290 goto return_noroute; 00291 } 00292 #if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF 00293 /* Do not forward packets onto the same network interface on which 00294 * they arrived. */ 00295 if (netif == inp) { 00296 LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not bouncing packets back on incoming interface.\n")); 00297 goto return_noroute; 00298 } 00299 #endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */ 00300 00301 /* decrement TTL */ 00302 IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); 00303 /* send ICMP if TTL == 0 */ 00304 if (IPH_TTL(iphdr) == 0) { 00305 MIB2_STATS_INC(mib2.ipinhdrerrors); 00306 #if LWIP_ICMP 00307 /* Don't send ICMP messages in response to ICMP messages */ 00308 if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { 00309 icmp_time_exceeded(p, ICMP_TE_TTL); 00310 } 00311 #endif /* LWIP_ICMP */ 00312 return; 00313 } 00314 00315 /* Incrementally update the IP checksum. */ 00316 if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) { 00317 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1); 00318 } else { 00319 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100)); 00320 } 00321 00322 LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00323 ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), 00324 ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); 00325 00326 IP_STATS_INC(ip.fw); 00327 MIB2_STATS_INC(mib2.ipforwdatagrams); 00328 IP_STATS_INC(ip.xmit); 00329 00330 PERF_STOP("ip4_forward"); 00331 /* don't fragment if interface has mtu set to 0 [loopif] */ 00332 if (netif->mtu && (p->tot_len > netif->mtu)) { 00333 if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { 00334 #if IP_FRAG 00335 ip4_frag(p, netif, ip4_current_dest_addr()); 00336 #else /* IP_FRAG */ 00337 /* @todo: send ICMP Destination Unreachable code 13 "Communication administratively prohibited"? */ 00338 #endif /* IP_FRAG */ 00339 } else { 00340 #if LWIP_ICMP 00341 /* send ICMP Destination Unreachable code 4: "Fragmentation Needed and DF Set" */ 00342 icmp_dest_unreach(p, ICMP_DUR_FRAG); 00343 #endif /* LWIP_ICMP */ 00344 } 00345 return; 00346 } 00347 /* transmit pbuf on chosen interface */ 00348 netif->output(netif, p, ip4_current_dest_addr()); 00349 return; 00350 return_noroute: 00351 MIB2_STATS_INC(mib2.ipoutnoroutes); 00352 } 00353 #endif /* IP_FORWARD */ 00354 00355 /** 00356 * This function is called by the network interface device driver when 00357 * an IP packet is received. The function does the basic checks of the 00358 * IP header such as packet size being at least larger than the header 00359 * size etc. If the packet was not destined for us, the packet is 00360 * forwarded (using ip_forward). The IP checksum is always checked. 00361 * 00362 * Finally, the packet is sent to the upper layer protocol input function. 00363 * 00364 * @param p the received IP packet (p->payload points to IP header) 00365 * @param inp the netif on which this packet was received 00366 * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't 00367 * processed, but currently always returns ERR_OK) 00368 */ 00369 err_t 00370 ip4_input(struct pbuf *p, struct netif *inp) 00371 { 00372 struct ip_hdr *iphdr; 00373 struct netif *netif; 00374 u16_t iphdr_hlen; 00375 u16_t iphdr_len; 00376 #if IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP 00377 int check_ip_src = 1; 00378 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP */ 00379 00380 IP_STATS_INC(ip.recv); 00381 MIB2_STATS_INC(mib2.ipinreceives); 00382 00383 /* identify the IP header */ 00384 iphdr = (struct ip_hdr *)p->payload; 00385 if (IPH_V(iphdr) != 4) { 00386 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", (u16_t)IPH_V(iphdr))); 00387 ip4_debug_print(p); 00388 pbuf_free(p); 00389 IP_STATS_INC(ip.err); 00390 IP_STATS_INC(ip.drop); 00391 MIB2_STATS_INC(mib2.ipinhdrerrors); 00392 return ERR_OK; 00393 } 00394 00395 #ifdef LWIP_HOOK_IP4_INPUT 00396 if (LWIP_HOOK_IP4_INPUT(p, inp)) { 00397 /* the packet has been eaten */ 00398 return ERR_OK; 00399 } 00400 #endif 00401 00402 /* obtain IP header length in number of 32-bit words */ 00403 iphdr_hlen = IPH_HL(iphdr); 00404 /* calculate IP header length in bytes */ 00405 iphdr_hlen *= 4; 00406 /* obtain ip length in bytes */ 00407 iphdr_len = lwip_ntohs(IPH_LEN(iphdr)); 00408 00409 /* Trim pbuf. This is especially required for packets < 60 bytes. */ 00410 if (iphdr_len < p->tot_len) { 00411 pbuf_realloc(p, iphdr_len); 00412 } 00413 00414 /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ 00415 if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len) || (iphdr_hlen < IP_HLEN)) { 00416 if (iphdr_hlen < IP_HLEN) { 00417 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00418 ("ip4_input: short IP header (%"U16_F" bytes) received, IP packet dropped\n", iphdr_hlen)); 00419 } 00420 if (iphdr_hlen > p->len) { 00421 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00422 ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", 00423 iphdr_hlen, p->len)); 00424 } 00425 if (iphdr_len > p->tot_len) { 00426 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00427 ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", 00428 iphdr_len, p->tot_len)); 00429 } 00430 /* free (drop) packet pbufs */ 00431 pbuf_free(p); 00432 IP_STATS_INC(ip.lenerr); 00433 IP_STATS_INC(ip.drop); 00434 MIB2_STATS_INC(mib2.ipindiscards); 00435 return ERR_OK; 00436 } 00437 00438 /* verify checksum */ 00439 #if CHECKSUM_CHECK_IP 00440 IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) { 00441 if (inet_chksum(iphdr, iphdr_hlen) != 0) { 00442 00443 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00444 ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); 00445 ip4_debug_print(p); 00446 pbuf_free(p); 00447 IP_STATS_INC(ip.chkerr); 00448 IP_STATS_INC(ip.drop); 00449 MIB2_STATS_INC(mib2.ipinhdrerrors); 00450 return ERR_OK; 00451 } 00452 } 00453 #endif 00454 00455 /* copy IP addresses to aligned ip_addr_t */ 00456 ip_addr_copy_from_ip4(ip_data.current_iphdr_dest, iphdr->dest); 00457 ip_addr_copy_from_ip4(ip_data.current_iphdr_src, iphdr->src); 00458 00459 /* match packet against an interface, i.e. is this packet for us? */ 00460 if (ip4_addr_ismulticast(ip4_current_dest_addr())) { 00461 #if LWIP_IGMP 00462 if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ip4_current_dest_addr()))) { 00463 /* IGMP snooping switches need 0.0.0.0 to be allowed as source address (RFC 4541) */ 00464 ip4_addr_t allsystems; 00465 IP4_ADDR(&allsystems, 224, 0, 0, 1); 00466 if (ip4_addr_cmp(ip4_current_dest_addr(), &allsystems) && 00467 ip4_addr_isany(ip4_current_src_addr())) { 00468 check_ip_src = 0; 00469 } 00470 netif = inp; 00471 } else { 00472 netif = NULL; 00473 } 00474 #else /* LWIP_IGMP */ 00475 if ((netif_is_up(inp)) && (!ip4_addr_isany_val(*netif_ip4_addr(inp)))) { 00476 netif = inp; 00477 } else { 00478 netif = NULL; 00479 } 00480 #endif /* LWIP_IGMP */ 00481 } else { 00482 /* start trying with inp. if that's not acceptable, start walking the 00483 list of configured netifs. 00484 'first' is used as a boolean to mark whether we started walking the list */ 00485 int first = 1; 00486 netif = inp; 00487 do { 00488 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", 00489 ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(netif_ip4_addr(netif)), 00490 ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(netif_ip4_netmask(netif)), 00491 ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)), 00492 ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(netif_ip4_netmask(netif)))); 00493 00494 /* interface is up and configured? */ 00495 if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) { 00496 /* unicast to this interface address? */ 00497 if (ip4_addr_cmp(ip4_current_dest_addr(), netif_ip4_addr(netif)) || 00498 /* or broadcast on this interface network address? */ 00499 ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) 00500 #if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF 00501 || (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK)) 00502 #endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ 00503 ) { 00504 LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n", 00505 netif->name[0], netif->name[1])); 00506 /* break out of for loop */ 00507 break; 00508 } 00509 #if LWIP_AUTOIP 00510 /* connections to link-local addresses must persist after changing 00511 the netif's address (RFC3927 ch. 1.9) */ 00512 if (autoip_accept_packet(netif, ip4_current_dest_addr())) { 00513 LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n", 00514 netif->name[0], netif->name[1])); 00515 /* break out of for loop */ 00516 break; 00517 } 00518 #endif /* LWIP_AUTOIP */ 00519 } 00520 if (first) { 00521 #if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF 00522 /* Packets sent to the loopback address must not be accepted on an 00523 * interface that does not have the loopback address assigned to it, 00524 * unless a non-loopback interface is used for loopback traffic. */ 00525 if (ip4_addr_isloopback(ip4_current_dest_addr())) { 00526 netif = NULL; 00527 break; 00528 } 00529 #endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ 00530 first = 0; 00531 netif = netif_list; 00532 } else { 00533 netif = netif->next; 00534 } 00535 if (netif == inp) { 00536 netif = netif->next; 00537 } 00538 } while (netif != NULL); 00539 } 00540 00541 #if IP_ACCEPT_LINK_LAYER_ADDRESSING 00542 /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed 00543 * using link layer addressing (such as Ethernet MAC) so we must not filter on IP. 00544 * According to RFC 1542 section 3.1.1, referred by RFC 2131). 00545 * 00546 * If you want to accept private broadcast communication while a netif is down, 00547 * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.: 00548 * 00549 * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345)) 00550 */ 00551 if (netif == NULL) { 00552 /* remote port is DHCP server? */ 00553 if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { 00554 struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen); 00555 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: UDP packet to DHCP client port %"U16_F"\n", 00556 lwip_ntohs(udphdr->dest))); 00557 if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) { 00558 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: DHCP packet accepted.\n")); 00559 netif = inp; 00560 check_ip_src = 0; 00561 } 00562 } 00563 } 00564 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ 00565 00566 /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ 00567 #if LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING 00568 if (check_ip_src 00569 #if IP_ACCEPT_LINK_LAYER_ADDRESSING 00570 /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ 00571 && !ip4_addr_isany_val(*ip4_current_src_addr()) 00572 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ 00573 ) 00574 #endif /* LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING */ 00575 { 00576 if ((ip4_addr_isbroadcast(ip4_current_src_addr(), inp)) || 00577 (ip4_addr_ismulticast(ip4_current_src_addr()))) { 00578 /* packet source is not valid */ 00579 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip4_input: packet source is not valid.\n")); 00580 /* free (drop) packet pbufs */ 00581 pbuf_free(p); 00582 IP_STATS_INC(ip.drop); 00583 MIB2_STATS_INC(mib2.ipinaddrerrors); 00584 MIB2_STATS_INC(mib2.ipindiscards); 00585 return ERR_OK; 00586 } 00587 } 00588 00589 /* packet not for us? */ 00590 if (netif == NULL) { 00591 /* packet not for us, route or discard */ 00592 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: packet not for us.\n")); 00593 #if IP_FORWARD 00594 /* non-broadcast packet? */ 00595 if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), inp)) { 00596 /* try to forward IP packet on (other) interfaces */ 00597 ip4_forward(p, iphdr, inp); 00598 } else 00599 #endif /* IP_FORWARD */ 00600 { 00601 IP_STATS_INC(ip.drop); 00602 MIB2_STATS_INC(mib2.ipinaddrerrors); 00603 MIB2_STATS_INC(mib2.ipindiscards); 00604 } 00605 pbuf_free(p); 00606 return ERR_OK; 00607 } 00608 /* packet consists of multiple fragments? */ 00609 if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { 00610 #if IP_REASSEMBLY /* packet fragment reassembly code present? */ 00611 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 ip4_reass()\n", 00612 lwip_ntohs(IPH_ID(iphdr)), p->tot_len, lwip_ntohs(IPH_LEN(iphdr)), (u16_t)!!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (u16_t)((lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8))); 00613 /* reassemble the packet*/ 00614 p = ip4_reass(p); 00615 /* packet not fully reassembled yet? */ 00616 if (p == NULL) { 00617 return ERR_OK; 00618 } 00619 iphdr = (struct ip_hdr *)p->payload; 00620 #else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */ 00621 pbuf_free(p); 00622 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n", 00623 lwip_ntohs(IPH_OFFSET(iphdr)))); 00624 IP_STATS_INC(ip.opterr); 00625 IP_STATS_INC(ip.drop); 00626 /* unsupported protocol feature */ 00627 MIB2_STATS_INC(mib2.ipinunknownprotos); 00628 return ERR_OK; 00629 #endif /* IP_REASSEMBLY */ 00630 } 00631 00632 #if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */ 00633 00634 #if LWIP_IGMP 00635 /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */ 00636 if ((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) { 00637 #else 00638 if (iphdr_hlen > IP_HLEN) { 00639 #endif /* LWIP_IGMP */ 00640 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n")); 00641 pbuf_free(p); 00642 IP_STATS_INC(ip.opterr); 00643 IP_STATS_INC(ip.drop); 00644 /* unsupported protocol feature */ 00645 MIB2_STATS_INC(mib2.ipinunknownprotos); 00646 return ERR_OK; 00647 } 00648 #endif /* IP_OPTIONS_ALLOWED == 0 */ 00649 00650 /* send to upper layers */ 00651 LWIP_DEBUGF(IP_DEBUG, ("ip4_input: \n")); 00652 ip4_debug_print(p); 00653 LWIP_DEBUGF(IP_DEBUG, ("ip4_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); 00654 00655 ip_data.current_netif = netif; 00656 ip_data.current_input_netif = inp; 00657 ip_data.current_ip4_header = iphdr; 00658 ip_data.current_ip_header_tot_len = IPH_HL(iphdr) * 4; 00659 00660 #if LWIP_RAW 00661 /* raw input did not eat the packet? */ 00662 if (raw_input(p, inp) == 0) 00663 #endif /* LWIP_RAW */ 00664 { 00665 pbuf_header(p, -(s16_t)iphdr_hlen); /* Move to payload, no check necessary. */ 00666 00667 switch (IPH_PROTO(iphdr)) { 00668 #if LWIP_UDP 00669 case IP_PROTO_UDP: 00670 #if LWIP_UDPLITE 00671 case IP_PROTO_UDPLITE: 00672 #endif /* LWIP_UDPLITE */ 00673 MIB2_STATS_INC(mib2.ipindelivers); 00674 udp_input(p, inp); 00675 break; 00676 #endif /* LWIP_UDP */ 00677 #if LWIP_TCP 00678 case IP_PROTO_TCP: 00679 MIB2_STATS_INC(mib2.ipindelivers); 00680 tcp_input(p, inp); 00681 break; 00682 #endif /* LWIP_TCP */ 00683 #if LWIP_ICMP 00684 case IP_PROTO_ICMP: 00685 MIB2_STATS_INC(mib2.ipindelivers); 00686 icmp_input(p, inp); 00687 break; 00688 #endif /* LWIP_ICMP */ 00689 #if LWIP_IGMP 00690 case IP_PROTO_IGMP: 00691 igmp_input(p, inp, ip4_current_dest_addr()); 00692 break; 00693 #endif /* LWIP_IGMP */ 00694 default: 00695 #if LWIP_ICMP 00696 /* send ICMP destination protocol unreachable unless is was a broadcast */ 00697 if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) && 00698 !ip4_addr_ismulticast(ip4_current_dest_addr())) { 00699 pbuf_header_force(p, iphdr_hlen); /* Move to ip header, no check necessary. */ 00700 p->payload = iphdr; 00701 icmp_dest_unreach(p, ICMP_DUR_PROTO); 00702 } 00703 #endif /* LWIP_ICMP */ 00704 pbuf_free(p); 00705 00706 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", (u16_t)IPH_PROTO(iphdr))); 00707 00708 IP_STATS_INC(ip.proterr); 00709 IP_STATS_INC(ip.drop); 00710 MIB2_STATS_INC(mib2.ipinunknownprotos); 00711 } 00712 } 00713 00714 /* @todo: this is not really necessary... */ 00715 ip_data.current_netif = NULL; 00716 ip_data.current_input_netif = NULL; 00717 ip_data.current_ip4_header = NULL; 00718 ip_data.current_ip_header_tot_len = 0; 00719 ip4_addr_set_any(ip4_current_src_addr()); 00720 ip4_addr_set_any(ip4_current_dest_addr()); 00721 00722 return ERR_OK; 00723 } 00724 00725 /** 00726 * Sends an IP packet on a network interface. This function constructs 00727 * the IP header and calculates the IP header checksum. If the source 00728 * IP address is NULL, the IP address of the outgoing network 00729 * interface is filled in as source address. 00730 * If the destination IP address is LWIP_IP_HDRINCL, p is assumed to already 00731 * include an IP header and p->payload points to it instead of the data. 00732 * 00733 * @param p the packet to send (p->payload points to the data, e.g. next 00734 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an 00735 IP header and p->payload points to that IP header) 00736 * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the 00737 * IP address of the netif used to send is used as source address) 00738 * @param dest the destination IP address to send the packet to 00739 * @param ttl the TTL value to be set in the IP header 00740 * @param tos the TOS value to be set in the IP header 00741 * @param proto the PROTOCOL to be set in the IP header 00742 * @param netif the netif on which to send this packet 00743 * @return ERR_OK if the packet was sent OK 00744 * ERR_BUF if p doesn't have enough space for IP/LINK headers 00745 * returns errors returned by netif->output 00746 * 00747 * @note ip_id: RFC791 "some host may be able to simply use 00748 * unique identifiers independent of destination" 00749 */ 00750 err_t 00751 ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, 00752 u8_t ttl, u8_t tos, 00753 u8_t proto, struct netif *netif) 00754 { 00755 #if IP_OPTIONS_SEND 00756 return ip4_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0); 00757 } 00758 00759 /** 00760 * Same as ip_output_if() but with the possibility to include IP options: 00761 * 00762 * @ param ip_options pointer to the IP options, copied into the IP header 00763 * @ param optlen length of ip_options 00764 */ 00765 err_t 00766 ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, 00767 u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, 00768 u16_t optlen) 00769 { 00770 #endif /* IP_OPTIONS_SEND */ 00771 const ip4_addr_t *src_used = src; 00772 if (dest != LWIP_IP_HDRINCL) { 00773 if (ip4_addr_isany(src)) { 00774 src_used = netif_ip4_addr(netif); 00775 } 00776 } 00777 00778 #if IP_OPTIONS_SEND 00779 return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif, 00780 ip_options, optlen); 00781 #else /* IP_OPTIONS_SEND */ 00782 return ip4_output_if_src(p, src_used, dest, ttl, tos, proto, netif); 00783 #endif /* IP_OPTIONS_SEND */ 00784 } 00785 00786 /** 00787 * Same as ip_output_if() but 'src' address is not replaced by netif address 00788 * when it is 'any'. 00789 */ 00790 err_t 00791 ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, 00792 u8_t ttl, u8_t tos, 00793 u8_t proto, struct netif *netif) 00794 { 00795 #if IP_OPTIONS_SEND 00796 return ip4_output_if_opt_src(p, src, dest, ttl, tos, proto, netif, NULL, 0); 00797 } 00798 00799 /** 00800 * Same as ip_output_if_opt() but 'src' address is not replaced by netif address 00801 * when it is 'any'. 00802 */ 00803 err_t 00804 ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, 00805 u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, 00806 u16_t optlen) 00807 { 00808 #endif /* IP_OPTIONS_SEND */ 00809 struct ip_hdr *iphdr; 00810 ip4_addr_t dest_addr; 00811 #if CHECKSUM_GEN_IP_INLINE 00812 u32_t chk_sum = 0; 00813 #endif /* CHECKSUM_GEN_IP_INLINE */ 00814 00815 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); 00816 00817 MIB2_STATS_INC(mib2.ipoutrequests); 00818 00819 /* Should the IP header be generated or is it already included in p? */ 00820 if (dest != LWIP_IP_HDRINCL) { 00821 u16_t ip_hlen = IP_HLEN; 00822 #if IP_OPTIONS_SEND 00823 u16_t optlen_aligned = 0; 00824 if (optlen != 0) { 00825 #if CHECKSUM_GEN_IP_INLINE 00826 int i; 00827 #endif /* CHECKSUM_GEN_IP_INLINE */ 00828 /* round up to a multiple of 4 */ 00829 optlen_aligned = ((optlen + 3) & ~3); 00830 ip_hlen += optlen_aligned; 00831 /* First write in the IP options */ 00832 if (pbuf_header(p, optlen_aligned)) { 00833 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output_if_opt: not enough room for IP options in pbuf\n")); 00834 IP_STATS_INC(ip.err); 00835 MIB2_STATS_INC(mib2.ipoutdiscards); 00836 return ERR_BUF; 00837 } 00838 MEMCPY(p->payload, ip_options, optlen); 00839 if (optlen < optlen_aligned) { 00840 /* zero the remaining bytes */ 00841 memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen); 00842 } 00843 #if CHECKSUM_GEN_IP_INLINE 00844 for (i = 0; i < optlen_aligned/2; i++) { 00845 chk_sum += ((u16_t*)p->payload)[i]; 00846 } 00847 #endif /* CHECKSUM_GEN_IP_INLINE */ 00848 } 00849 #endif /* IP_OPTIONS_SEND */ 00850 /* generate IP header */ 00851 if (pbuf_header(p, IP_HLEN)) { 00852 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output: not enough room for IP header in pbuf\n")); 00853 00854 IP_STATS_INC(ip.err); 00855 MIB2_STATS_INC(mib2.ipoutdiscards); 00856 return ERR_BUF; 00857 } 00858 00859 iphdr = (struct ip_hdr *)p->payload; 00860 LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", 00861 (p->len >= sizeof(struct ip_hdr))); 00862 00863 IPH_TTL_SET(iphdr, ttl); 00864 IPH_PROTO_SET(iphdr, proto); 00865 #if CHECKSUM_GEN_IP_INLINE 00866 chk_sum += PP_NTOHS(proto | (ttl << 8)); 00867 #endif /* CHECKSUM_GEN_IP_INLINE */ 00868 00869 /* dest cannot be NULL here */ 00870 ip4_addr_copy(iphdr->dest, *dest); 00871 #if CHECKSUM_GEN_IP_INLINE 00872 chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; 00873 chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; 00874 #endif /* CHECKSUM_GEN_IP_INLINE */ 00875 00876 IPH_VHL_SET(iphdr, 4, ip_hlen / 4); 00877 IPH_TOS_SET(iphdr, tos); 00878 #if CHECKSUM_GEN_IP_INLINE 00879 chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8)); 00880 #endif /* CHECKSUM_GEN_IP_INLINE */ 00881 IPH_LEN_SET(iphdr, lwip_htons(p->tot_len)); 00882 #if CHECKSUM_GEN_IP_INLINE 00883 chk_sum += iphdr->_len; 00884 #endif /* CHECKSUM_GEN_IP_INLINE */ 00885 IPH_OFFSET_SET(iphdr, 0); 00886 IPH_ID_SET(iphdr, lwip_htons(ip_id)); 00887 #if CHECKSUM_GEN_IP_INLINE 00888 chk_sum += iphdr->_id; 00889 #endif /* CHECKSUM_GEN_IP_INLINE */ 00890 ++ip_id; 00891 00892 if (src == NULL) { 00893 ip4_addr_copy(iphdr->src, *IP4_ADDR_ANY4); 00894 } else { 00895 /* src cannot be NULL here */ 00896 ip4_addr_copy(iphdr->src, *src); 00897 } 00898 00899 #if CHECKSUM_GEN_IP_INLINE 00900 chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; 00901 chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; 00902 chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); 00903 chk_sum = (chk_sum >> 16) + chk_sum; 00904 chk_sum = ~chk_sum; 00905 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { 00906 iphdr->_chksum = (u16_t)chk_sum; /* network order */ 00907 } 00908 #if LWIP_CHECKSUM_CTRL_PER_NETIF 00909 else { 00910 IPH_CHKSUM_SET(iphdr, 0); 00911 } 00912 #endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/ 00913 #else /* CHECKSUM_GEN_IP_INLINE */ 00914 IPH_CHKSUM_SET(iphdr, 0); 00915 #if CHECKSUM_GEN_IP 00916 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { 00917 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); 00918 } 00919 #endif /* CHECKSUM_GEN_IP */ 00920 #endif /* CHECKSUM_GEN_IP_INLINE */ 00921 } else { 00922 /* IP header already included in p */ 00923 iphdr = (struct ip_hdr *)p->payload; 00924 ip4_addr_copy(dest_addr, iphdr->dest); 00925 dest = &dest_addr; 00926 } 00927 00928 IP_STATS_INC(ip.xmit); 00929 00930 LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num)); 00931 ip4_debug_print(p); 00932 00933 #if ENABLE_LOOPBACK 00934 if (ip4_addr_cmp(dest, netif_ip4_addr(netif)) 00935 #if !LWIP_HAVE_LOOPIF 00936 || ip4_addr_isloopback(dest) 00937 #endif /* !LWIP_HAVE_LOOPIF */ 00938 ) { 00939 /* Packet to self, enqueue it for loopback */ 00940 LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); 00941 return netif_loop_output(netif, p); 00942 } 00943 #if LWIP_MULTICAST_TX_OPTIONS 00944 if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) { 00945 netif_loop_output(netif, p); 00946 } 00947 #endif /* LWIP_MULTICAST_TX_OPTIONS */ 00948 #endif /* ENABLE_LOOPBACK */ 00949 #if IP_FRAG 00950 /* don't fragment if interface has mtu set to 0 [loopif] */ 00951 if (netif->mtu && (p->tot_len > netif->mtu)) { 00952 return ip4_frag(p, netif, dest); 00953 } 00954 #endif /* IP_FRAG */ 00955 00956 LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: call netif->output()\n")); 00957 return netif->output(netif, p, dest); 00958 } 00959 00960 /** 00961 * Simple interface to ip_output_if. It finds the outgoing network 00962 * interface and calls upon ip_output_if to do the actual work. 00963 * 00964 * @param p the packet to send (p->payload points to the data, e.g. next 00965 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an 00966 IP header and p->payload points to that IP header) 00967 * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the 00968 * IP address of the netif used to send is used as source address) 00969 * @param dest the destination IP address to send the packet to 00970 * @param ttl the TTL value to be set in the IP header 00971 * @param tos the TOS value to be set in the IP header 00972 * @param proto the PROTOCOL to be set in the IP header 00973 * 00974 * @return ERR_RTE if no route is found 00975 * see ip_output_if() for more return values 00976 */ 00977 err_t 00978 ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, 00979 u8_t ttl, u8_t tos, u8_t proto) 00980 { 00981 struct netif *netif; 00982 00983 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); 00984 00985 if ((netif = ip4_route_src(dest, src)) == NULL) { 00986 LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00987 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); 00988 IP_STATS_INC(ip.rterr); 00989 return ERR_RTE; 00990 } 00991 00992 return ip4_output_if(p, src, dest, ttl, tos, proto, netif); 00993 } 00994 00995 #if LWIP_NETIF_HWADDRHINT 00996 /** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint 00997 * before calling ip_output_if. 00998 * 00999 * @param p the packet to send (p->payload points to the data, e.g. next 01000 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an 01001 IP header and p->payload points to that IP header) 01002 * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the 01003 * IP address of the netif used to send is used as source address) 01004 * @param dest the destination IP address to send the packet to 01005 * @param ttl the TTL value to be set in the IP header 01006 * @param tos the TOS value to be set in the IP header 01007 * @param proto the PROTOCOL to be set in the IP header 01008 * @param addr_hint address hint pointer set to netif->addr_hint before 01009 * calling ip_output_if() 01010 * 01011 * @return ERR_RTE if no route is found 01012 * see ip_output_if() for more return values 01013 */ 01014 err_t 01015 ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, 01016 u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) 01017 { 01018 struct netif *netif; 01019 err_t err; 01020 01021 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); 01022 01023 if ((netif = ip4_route_src(dest, src)) == NULL) { 01024 LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 01025 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); 01026 IP_STATS_INC(ip.rterr); 01027 return ERR_RTE; 01028 } 01029 01030 NETIF_SET_HWADDRHINT(netif, addr_hint); 01031 err = ip4_output_if(p, src, dest, ttl, tos, proto, netif); 01032 NETIF_SET_HWADDRHINT(netif, NULL); 01033 01034 return err; 01035 } 01036 #endif /* LWIP_NETIF_HWADDRHINT*/ 01037 01038 #if IP_DEBUG 01039 /* Print an IP header by using LWIP_DEBUGF 01040 * @param p an IP packet, p->payload pointing to the IP header 01041 */ 01042 void 01043 ip4_debug_print(struct pbuf *p) 01044 { 01045 struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; 01046 01047 LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); 01048 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 01049 LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", 01050 (u16_t)IPH_V(iphdr), 01051 (u16_t)IPH_HL(iphdr), 01052 (u16_t)IPH_TOS(iphdr), 01053 lwip_ntohs(IPH_LEN(iphdr)))); 01054 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 01055 LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", 01056 lwip_ntohs(IPH_ID(iphdr)), 01057 (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 15 & 1), 01058 (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 14 & 1), 01059 (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 13 & 1), 01060 (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK))); 01061 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 01062 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", 01063 (u16_t)IPH_TTL(iphdr), 01064 (u16_t)IPH_PROTO(iphdr), 01065 lwip_ntohs(IPH_CHKSUM(iphdr)))); 01066 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 01067 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", 01068 ip4_addr1_16(&iphdr->src), 01069 ip4_addr2_16(&iphdr->src), 01070 ip4_addr3_16(&iphdr->src), 01071 ip4_addr4_16(&iphdr->src))); 01072 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 01073 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", 01074 ip4_addr1_16(&iphdr->dest), 01075 ip4_addr2_16(&iphdr->dest), 01076 ip4_addr3_16(&iphdr->dest), 01077 ip4_addr4_16(&iphdr->dest))); 01078 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 01079 } 01080 #endif /* IP_DEBUG */ 01081 01082 #endif /* LWIP_IPV4 */
Generated on Tue Jul 12 2022 11:02:26 by
1.7.2