Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
lwip_ip4.c
Go to the documentation of this file.
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 Sun Jul 17 2022 08:25:24 by 1.7.2