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