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