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_ip6.c
00001 /** 00002 * @file 00003 * 00004 * IPv6 layer. 00005 */ 00006 00007 /* 00008 * Copyright (c) 2010 Inico Technologies Ltd. 00009 * All rights reserved. 00010 * 00011 * Redistribution and use in source and binary forms, with or without modification, 00012 * are permitted provided that the following conditions are met: 00013 * 00014 * 1. Redistributions of source code must retain the above copyright notice, 00015 * this list of conditions and the following disclaimer. 00016 * 2. Redistributions in binary form must reproduce the above copyright notice, 00017 * this list of conditions and the following disclaimer in the documentation 00018 * and/or other materials provided with the distribution. 00019 * 3. The name of the author may not be used to endorse or promote products 00020 * derived from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00023 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00024 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00025 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00026 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00027 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00028 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00029 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00030 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00031 * OF SUCH DAMAGE. 00032 * 00033 * This file is part of the lwIP TCP/IP stack. 00034 * 00035 * Author: Ivan Delamer <delamer@inicotech.com> 00036 * 00037 * 00038 * Please coordinate changes and requests with Ivan Delamer 00039 * <delamer@inicotech.com> 00040 */ 00041 00042 #include "lwip/opt.h" 00043 00044 #if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ 00045 00046 #include "lwip/def.h" 00047 #include "lwip/mem.h" 00048 #include "lwip/netif.h" 00049 #include "lwip/ip.h" 00050 #include "lwip/ip6.h" 00051 #include "lwip/ip6_addr.h" 00052 #include "lwip/ip6_frag.h" 00053 #include "lwip/icmp6.h" 00054 #include "lwip/raw.h" 00055 #include "lwip/udp.h" 00056 #include "lwip/priv/tcp_priv.h" 00057 #include "lwip/dhcp6.h" 00058 #include "lwip/nd6.h" 00059 #include "lwip/mld6.h" 00060 #include "lwip/debug.h" 00061 #include "lwip/stats.h" 00062 00063 #ifdef LWIP_HOOK_FILENAME 00064 #include LWIP_HOOK_FILENAME 00065 #endif 00066 00067 /** 00068 * Finds the appropriate network interface for a given IPv6 address. It tries to select 00069 * a netif following a sequence of heuristics: 00070 * 1) if there is only 1 netif, return it 00071 * 2) if the destination is a link-local address, try to match the src address to a netif. 00072 * this is a tricky case because with multiple netifs, link-local addresses only have 00073 * meaning within a particular subnet/link. 00074 * 3) tries to match the destination subnet to a configured address 00075 * 4) tries to find a router-announced route 00076 * 5) tries to match the source address to the netif 00077 * 6) returns the default netif, if configured 00078 * 00079 * @param src the source IPv6 address, if known 00080 * @param dest the destination IPv6 address for which to find the route 00081 * @return the netif on which to send to reach dest 00082 */ 00083 struct netif * 00084 ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest) 00085 { 00086 struct netif *netif; 00087 s8_t i; 00088 00089 /* If single netif configuration, fast return. */ 00090 if ((netif_list != NULL) && (netif_list->next == NULL)) { 00091 if (!netif_is_up(netif_list) || !netif_is_link_up(netif_list)) { 00092 return NULL; 00093 } 00094 return netif_list; 00095 } 00096 00097 /* Special processing for link-local addresses. */ 00098 if (ip6_addr_islinklocal(dest)) { 00099 if (ip6_addr_isany(src)) { 00100 /* Use default netif, if Up. */ 00101 if (netif_default == NULL || !netif_is_up(netif_default) || 00102 !netif_is_link_up(netif_default)) { 00103 return NULL; 00104 } 00105 return netif_default; 00106 } 00107 00108 /* Try to find the netif for the source address, checking that link is up. */ 00109 for (netif = netif_list; netif != NULL; netif = netif->next) { 00110 if (!netif_is_up(netif) || !netif_is_link_up(netif)) { 00111 continue; 00112 } 00113 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00114 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && 00115 ip6_addr_cmp(src, netif_ip6_addr(netif, i))) { 00116 return netif; 00117 } 00118 } 00119 } 00120 00121 /* netif not found, use default netif, if up */ 00122 if (netif_default == NULL || !netif_is_up(netif_default) || 00123 !netif_is_link_up(netif_default)) { 00124 return NULL; 00125 } 00126 return netif_default; 00127 } 00128 00129 /* we come here for non-link-local addresses */ 00130 #ifdef LWIP_HOOK_IP6_ROUTE 00131 netif = LWIP_HOOK_IP6_ROUTE(src, dest); 00132 if (netif != NULL) { 00133 return netif; 00134 } 00135 #endif 00136 00137 /* See if the destination subnet matches a configured address. In accordance 00138 * with RFC 5942, dynamically configured addresses do not have an implied 00139 * local subnet, and thus should be considered /128 assignments. However, as 00140 * such, the destination address may still match a local address, and so we 00141 * still need to check for exact matches here. By (lwIP) policy, statically 00142 * configured addresses do always have an implied local /64 subnet. */ 00143 for (netif = netif_list; netif != NULL; netif = netif->next) { 00144 if (!netif_is_up(netif) || !netif_is_link_up(netif)) { 00145 continue; 00146 } 00147 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00148 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && 00149 ip6_addr_netcmp(dest, netif_ip6_addr(netif, i)) && 00150 (netif_ip6_addr_isstatic(netif, i) || 00151 ip6_addr_nethostcmp(dest, netif_ip6_addr(netif, i)))) { 00152 return netif; 00153 } 00154 } 00155 } 00156 00157 /* Get the netif for a suitable router-announced route. */ 00158 netif = nd6_find_route(dest); 00159 if (netif != NULL) { 00160 return netif; 00161 } 00162 00163 /* try with the netif that matches the source address. */ 00164 if (!ip6_addr_isany(src)) { 00165 for (netif = netif_list; netif != NULL; netif = netif->next) { 00166 if (!netif_is_up(netif) || !netif_is_link_up(netif)) { 00167 continue; 00168 } 00169 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00170 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && 00171 ip6_addr_cmp(src, netif_ip6_addr(netif, i))) { 00172 return netif; 00173 } 00174 } 00175 } 00176 } 00177 00178 #if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF 00179 /* loopif is disabled, loopback traffic is passed through any netif */ 00180 if (ip6_addr_isloopback(dest)) { 00181 /* don't check for link on loopback traffic */ 00182 if (netif_default != NULL && netif_is_up(netif_default)) { 00183 return netif_default; 00184 } 00185 /* default netif is not up, just use any netif for loopback traffic */ 00186 for (netif = netif_list; netif != NULL; netif = netif->next) { 00187 if (netif_is_up(netif)) { 00188 return netif; 00189 } 00190 } 00191 return NULL; 00192 } 00193 #endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ 00194 00195 /* no matching netif found, use default netif, if up */ 00196 if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default)) { 00197 return NULL; 00198 } 00199 return netif_default; 00200 } 00201 00202 /** 00203 * @ingroup ip6 00204 * Select the best IPv6 source address for a given destination IPv6 address. 00205 * 00206 * This implementation follows RFC 6724 Sec. 5 to the following extent: 00207 * - Rules 1, 2, 3: fully implemented 00208 * - Rules 4, 5, 5.5: not applicable 00209 * - Rule 6: not implemented 00210 * - Rule 7: not applicable 00211 * - Rule 8: limited to "prefer /64 subnet match over non-match" 00212 * 00213 * For Rule 2, we deliberately deviate from RFC 6724 Sec. 3.1 by considering 00214 * ULAs to be of smaller scope than global addresses, to avoid that a preferred 00215 * ULA is picked over a deprecated global address when given a global address 00216 * as destination, as that would likely result in broken two-way communication. 00217 * 00218 * As long as temporary addresses are not supported (as used in Rule 7), a 00219 * proper implementation of Rule 8 would obviate the need to implement Rule 6. 00220 * 00221 * @param netif the netif on which to send a packet 00222 * @param dest the destination we are trying to reach 00223 * @return the most suitable source address to use, or NULL if no suitable 00224 * source address is found 00225 */ 00226 const ip_addr_t * 00227 ip6_select_source_address(struct netif *netif, const ip6_addr_t *dest) 00228 { 00229 const ip_addr_t *best_addr; 00230 const ip6_addr_t *cand_addr; 00231 s8_t dest_scope, cand_scope; 00232 s8_t best_scope = IP6_MULTICAST_SCOPE_RESERVED; 00233 u8_t i, cand_pref, cand_bits; 00234 u8_t best_pref = 0; 00235 u8_t best_bits = 0; 00236 00237 /* Start by determining the scope of the given destination address. These 00238 * tests are hopefully (roughly) in order of likeliness to match. */ 00239 if (ip6_addr_isglobal(dest)) { 00240 dest_scope = IP6_MULTICAST_SCOPE_GLOBAL; 00241 } else if (ip6_addr_islinklocal(dest) || ip6_addr_isloopback(dest)) { 00242 dest_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL; 00243 } else if (ip6_addr_isuniquelocal(dest)) { 00244 dest_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL; 00245 } else if (ip6_addr_ismulticast(dest)) { 00246 dest_scope = ip6_addr_multicast_scope(dest); 00247 } else if (ip6_addr_issitelocal(dest)) { 00248 dest_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL; 00249 } else { 00250 /* no match, consider scope global */ 00251 dest_scope = IP6_MULTICAST_SCOPE_GLOBAL; 00252 } 00253 00254 best_addr = NULL; 00255 00256 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00257 /* Consider only valid (= preferred and deprecated) addresses. */ 00258 if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { 00259 continue; 00260 } 00261 /* Determine the scope of this candidate address. Same ordering idea. */ 00262 cand_addr = netif_ip6_addr(netif, i); 00263 if (ip6_addr_isglobal(cand_addr)) { 00264 cand_scope = IP6_MULTICAST_SCOPE_GLOBAL; 00265 } else if (ip6_addr_islinklocal(cand_addr)) { 00266 cand_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL; 00267 } else if (ip6_addr_isuniquelocal(cand_addr)) { 00268 cand_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL; 00269 } else if (ip6_addr_issitelocal(cand_addr)) { 00270 cand_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL; 00271 } else { 00272 /* no match, treat as low-priority global scope */ 00273 cand_scope = IP6_MULTICAST_SCOPE_RESERVEDF; 00274 } 00275 cand_pref = ip6_addr_ispreferred(netif_ip6_addr_state(netif, i)); 00276 /* @todo compute the actual common bits, for longest matching prefix. */ 00277 cand_bits = ip6_addr_netcmp(cand_addr, dest); /* just 1 or 0 for now */ 00278 if (cand_bits && ip6_addr_nethostcmp(cand_addr, dest)) { 00279 return netif_ip_addr6(netif, i); /* Rule 1 */ 00280 } 00281 if ((best_addr == NULL) || /* no alternative yet */ 00282 ((cand_scope < best_scope) && (cand_scope >= dest_scope)) || 00283 ((cand_scope > best_scope) && (best_scope < dest_scope)) || /* Rule 2 */ 00284 ((cand_scope == best_scope) && ((cand_pref > best_pref) || /* Rule 3 */ 00285 ((cand_pref == best_pref) && (cand_bits > best_bits))))) { /* Rule 8 */ 00286 /* We found a new "winning" candidate. */ 00287 best_addr = netif_ip_addr6(netif, i); 00288 best_scope = cand_scope; 00289 best_pref = cand_pref; 00290 best_bits = cand_bits; 00291 } 00292 } 00293 00294 return best_addr; /* may be NULL */ 00295 } 00296 00297 #if LWIP_IPV6_FORWARD 00298 /** 00299 * Forwards an IPv6 packet. It finds an appropriate route for the 00300 * packet, decrements the HL value of the packet, and outputs 00301 * the packet on the appropriate interface. 00302 * 00303 * @param p the packet to forward (p->payload points to IP header) 00304 * @param iphdr the IPv6 header of the input packet 00305 * @param inp the netif on which this packet was received 00306 */ 00307 static void 00308 ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp) 00309 { 00310 struct netif *netif; 00311 00312 /* do not forward link-local or loopback addresses */ 00313 if (ip6_addr_islinklocal(ip6_current_dest_addr()) || 00314 ip6_addr_isloopback(ip6_current_dest_addr())) { 00315 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n")); 00316 IP6_STATS_INC(ip6.rterr); 00317 IP6_STATS_INC(ip6.drop); 00318 return; 00319 } 00320 00321 /* Find network interface where to forward this IP packet to. */ 00322 netif = ip6_route(IP6_ADDR_ANY6, ip6_current_dest_addr()); 00323 if (netif == NULL) { 00324 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", 00325 IP6_ADDR_BLOCK1(ip6_current_dest_addr()), 00326 IP6_ADDR_BLOCK2(ip6_current_dest_addr()), 00327 IP6_ADDR_BLOCK3(ip6_current_dest_addr()), 00328 IP6_ADDR_BLOCK4(ip6_current_dest_addr()), 00329 IP6_ADDR_BLOCK5(ip6_current_dest_addr()), 00330 IP6_ADDR_BLOCK6(ip6_current_dest_addr()), 00331 IP6_ADDR_BLOCK7(ip6_current_dest_addr()), 00332 IP6_ADDR_BLOCK8(ip6_current_dest_addr()))); 00333 #if LWIP_ICMP6 00334 /* Don't send ICMP messages in response to ICMP messages */ 00335 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { 00336 icmp6_dest_unreach(p, ICMP6_DUR_NO_ROUTE); 00337 } 00338 #endif /* LWIP_ICMP6 */ 00339 IP6_STATS_INC(ip6.rterr); 00340 IP6_STATS_INC(ip6.drop); 00341 return; 00342 } 00343 /* Do not forward packets onto the same network interface on which 00344 * they arrived. */ 00345 if (netif == inp) { 00346 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not bouncing packets back on incoming interface.\n")); 00347 IP6_STATS_INC(ip6.rterr); 00348 IP6_STATS_INC(ip6.drop); 00349 return; 00350 } 00351 00352 /* decrement HL */ 00353 IP6H_HOPLIM_SET(iphdr, IP6H_HOPLIM(iphdr) - 1); 00354 /* send ICMP6 if HL == 0 */ 00355 if (IP6H_HOPLIM(iphdr) == 0) { 00356 #if LWIP_ICMP6 00357 /* Don't send ICMP messages in response to ICMP messages */ 00358 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { 00359 icmp6_time_exceeded(p, ICMP6_TE_HL); 00360 } 00361 #endif /* LWIP_ICMP6 */ 00362 IP6_STATS_INC(ip6.drop); 00363 return; 00364 } 00365 00366 if (netif->mtu && (p->tot_len > netif->mtu)) { 00367 #if LWIP_ICMP6 00368 /* Don't send ICMP messages in response to ICMP messages */ 00369 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { 00370 icmp6_packet_too_big(p, netif->mtu); 00371 } 00372 #endif /* LWIP_ICMP6 */ 00373 IP6_STATS_INC(ip6.drop); 00374 return; 00375 } 00376 00377 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: forwarding packet to %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", 00378 IP6_ADDR_BLOCK1(ip6_current_dest_addr()), 00379 IP6_ADDR_BLOCK2(ip6_current_dest_addr()), 00380 IP6_ADDR_BLOCK3(ip6_current_dest_addr()), 00381 IP6_ADDR_BLOCK4(ip6_current_dest_addr()), 00382 IP6_ADDR_BLOCK5(ip6_current_dest_addr()), 00383 IP6_ADDR_BLOCK6(ip6_current_dest_addr()), 00384 IP6_ADDR_BLOCK7(ip6_current_dest_addr()), 00385 IP6_ADDR_BLOCK8(ip6_current_dest_addr()))); 00386 00387 /* transmit pbuf on chosen interface */ 00388 netif->output_ip6(netif, p, ip6_current_dest_addr()); 00389 IP6_STATS_INC(ip6.fw); 00390 IP6_STATS_INC(ip6.xmit); 00391 return; 00392 } 00393 #endif /* LWIP_IPV6_FORWARD */ 00394 00395 /** 00396 * This function is called by the network interface device driver when 00397 * an IPv6 packet is received. The function does the basic checks of the 00398 * IP header such as packet size being at least larger than the header 00399 * size etc. If the packet was not destined for us, the packet is 00400 * forwarded (using ip6_forward). 00401 * 00402 * Finally, the packet is sent to the upper layer protocol input function. 00403 * 00404 * @param p the received IPv6 packet (p->payload points to IPv6 header) 00405 * @param inp the netif on which this packet was received 00406 * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't 00407 * processed, but currently always returns ERR_OK) 00408 */ 00409 err_t 00410 ip6_input(struct pbuf *p, struct netif *inp) 00411 { 00412 struct ip6_hdr *ip6hdr; 00413 struct netif *netif; 00414 u8_t nexth; 00415 u16_t hlen; /* the current header length */ 00416 u8_t i; 00417 #if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/ 00418 @todo 00419 int check_ip_src=1; 00420 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ 00421 00422 IP6_STATS_INC(ip6.recv); 00423 00424 /* identify the IP header */ 00425 ip6hdr = (struct ip6_hdr *)p->payload; 00426 if (IP6H_V(ip6hdr) != 6) { 00427 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n", 00428 IP6H_V(ip6hdr))); 00429 pbuf_free(p); 00430 IP6_STATS_INC(ip6.err); 00431 IP6_STATS_INC(ip6.drop); 00432 return ERR_OK; 00433 } 00434 00435 #ifdef LWIP_HOOK_IP6_INPUT 00436 if (LWIP_HOOK_IP6_INPUT(p, inp)) { 00437 /* the packet has been eaten */ 00438 return ERR_OK; 00439 } 00440 #endif 00441 00442 /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ 00443 if ((IP6_HLEN > p->len) || ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len)) { 00444 if (IP6_HLEN > p->len) { 00445 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00446 ("IPv6 header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", 00447 (u16_t)IP6_HLEN, p->len)); 00448 } 00449 if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) { 00450 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00451 ("IPv6 (plen %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", 00452 (u16_t)(IP6H_PLEN(ip6hdr) + IP6_HLEN), p->tot_len)); 00453 } 00454 /* free (drop) packet pbufs */ 00455 pbuf_free(p); 00456 IP6_STATS_INC(ip6.lenerr); 00457 IP6_STATS_INC(ip6.drop); 00458 return ERR_OK; 00459 } 00460 00461 /* Trim pbuf. This should have been done at the netif layer, 00462 * but we'll do it anyway just to be sure that its done. */ 00463 pbuf_realloc(p, IP6_HLEN + IP6H_PLEN(ip6hdr)); 00464 00465 /* copy IP addresses to aligned ip6_addr_t */ 00466 ip_addr_copy_from_ip6(ip_data.current_iphdr_dest, ip6hdr->dest); 00467 ip_addr_copy_from_ip6(ip_data.current_iphdr_src, ip6hdr->src); 00468 00469 /* Don't accept virtual IPv4 mapped IPv6 addresses. 00470 * Don't accept multicast source addresses. */ 00471 if (ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_dest)) || 00472 ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_src)) || 00473 ip6_addr_ismulticast(ip_2_ip6(&ip_data.current_iphdr_src))) { 00474 IP6_STATS_INC(ip6.err); 00475 IP6_STATS_INC(ip6.drop); 00476 return ERR_OK; 00477 } 00478 00479 /* current header pointer. */ 00480 ip_data.current_ip6_header = ip6hdr; 00481 00482 /* In netif, used in case we need to send ICMPv6 packets back. */ 00483 ip_data.current_netif = inp; 00484 ip_data.current_input_netif = inp; 00485 00486 /* match packet against an interface, i.e. is this packet for us? */ 00487 if (ip6_addr_ismulticast(ip6_current_dest_addr())) { 00488 /* Always joined to multicast if-local and link-local all-nodes group. */ 00489 if (ip6_addr_isallnodes_iflocal(ip6_current_dest_addr()) || 00490 ip6_addr_isallnodes_linklocal(ip6_current_dest_addr())) { 00491 netif = inp; 00492 } 00493 #if LWIP_IPV6_MLD 00494 else if (mld6_lookfor_group(inp, ip6_current_dest_addr())) { 00495 netif = inp; 00496 } 00497 #else /* LWIP_IPV6_MLD */ 00498 else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) { 00499 /* Filter solicited node packets when MLD is not enabled 00500 * (for Neighbor discovery). */ 00501 netif = NULL; 00502 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00503 if (ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) && 00504 ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) { 00505 netif = inp; 00506 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %c%c\n", 00507 netif->name[0], netif->name[1])); 00508 break; 00509 } 00510 } 00511 } 00512 #endif /* LWIP_IPV6_MLD */ 00513 else { 00514 netif = NULL; 00515 } 00516 } else { 00517 /* start trying with inp. if that's not acceptable, start walking the 00518 list of configured netifs. 00519 'first' is used as a boolean to mark whether we started walking the list */ 00520 int first = 1; 00521 netif = inp; 00522 do { 00523 /* interface is up? */ 00524 if (netif_is_up(netif)) { 00525 /* unicast to this interface address? address configured? */ 00526 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00527 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && 00528 ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i))) { 00529 /* exit outer loop */ 00530 goto netif_found; 00531 } 00532 } 00533 } 00534 if (first) { 00535 if (ip6_addr_islinklocal(ip6_current_dest_addr()) 00536 #if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF 00537 || ip6_addr_isloopback(ip6_current_dest_addr()) 00538 #endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ 00539 ) { 00540 /* Do not match link-local addresses to other netifs. The loopback 00541 * address is to be considered link-local and packets to it should be 00542 * dropped on other interfaces, as per RFC 4291 Sec. 2.5.3. This 00543 * requirement cannot be implemented in the case that loopback 00544 * traffic is sent across a non-loopback interface, however. 00545 */ 00546 netif = NULL; 00547 break; 00548 } 00549 first = 0; 00550 netif = netif_list; 00551 } else { 00552 netif = netif->next; 00553 } 00554 if (netif == inp) { 00555 netif = netif->next; 00556 } 00557 } while (netif != NULL); 00558 netif_found: 00559 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n", 00560 netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X')); 00561 } 00562 00563 /* "::" packet source address? (used in duplicate address detection) */ 00564 if (ip6_addr_isany(ip6_current_src_addr()) && 00565 (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) { 00566 /* packet source is not valid */ 00567 /* free (drop) packet pbufs */ 00568 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n")); 00569 pbuf_free(p); 00570 IP6_STATS_INC(ip6.drop); 00571 goto ip6_input_cleanup; 00572 } 00573 00574 /* packet not for us? */ 00575 if (netif == NULL) { 00576 /* packet not for us, route or discard */ 00577 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_TRACE, ("ip6_input: packet not for us.\n")); 00578 #if LWIP_IPV6_FORWARD 00579 /* non-multicast packet? */ 00580 if (!ip6_addr_ismulticast(ip6_current_dest_addr())) { 00581 /* try to forward IP packet on (other) interfaces */ 00582 ip6_forward(p, ip6hdr, inp); 00583 } 00584 #endif /* LWIP_IPV6_FORWARD */ 00585 pbuf_free(p); 00586 goto ip6_input_cleanup; 00587 } 00588 00589 /* current netif pointer. */ 00590 ip_data.current_netif = netif; 00591 00592 /* Save next header type. */ 00593 nexth = IP6H_NEXTH(ip6hdr); 00594 00595 /* Init header length. */ 00596 hlen = ip_data.current_ip_header_tot_len = IP6_HLEN; 00597 00598 /* Move to payload. */ 00599 pbuf_header(p, -IP6_HLEN); 00600 00601 /* Process known option extension headers, if present. */ 00602 while (nexth != IP6_NEXTH_NONE) 00603 { 00604 switch (nexth) { 00605 case IP6_NEXTH_HOPBYHOP: 00606 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n")); 00607 /* Get next header type. */ 00608 nexth = *((u8_t *)p->payload); 00609 00610 /* Get the header length. */ 00611 hlen = 8 * (1 + *((u8_t *)p->payload + 1)); 00612 ip_data.current_ip_header_tot_len += hlen; 00613 00614 /* Skip over this header. */ 00615 if (hlen > p->len) { 00616 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00617 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", 00618 hlen, p->len)); 00619 /* free (drop) packet pbufs */ 00620 pbuf_free(p); 00621 IP6_STATS_INC(ip6.lenerr); 00622 IP6_STATS_INC(ip6.drop); 00623 goto ip6_input_cleanup; 00624 } 00625 00626 pbuf_header(p, -(s16_t)hlen); 00627 break; 00628 case IP6_NEXTH_DESTOPTS: 00629 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Destination options header\n")); 00630 /* Get next header type. */ 00631 nexth = *((u8_t *)p->payload); 00632 00633 /* Get the header length. */ 00634 hlen = 8 * (1 + *((u8_t *)p->payload + 1)); 00635 ip_data.current_ip_header_tot_len += hlen; 00636 00637 /* Skip over this header. */ 00638 if (hlen > p->len) { 00639 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00640 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", 00641 hlen, p->len)); 00642 /* free (drop) packet pbufs */ 00643 pbuf_free(p); 00644 IP6_STATS_INC(ip6.lenerr); 00645 IP6_STATS_INC(ip6.drop); 00646 goto ip6_input_cleanup; 00647 } 00648 00649 pbuf_header(p, -(s16_t)hlen); 00650 break; 00651 case IP6_NEXTH_ROUTING: 00652 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n")); 00653 /* Get next header type. */ 00654 nexth = *((u8_t *)p->payload); 00655 00656 /* Get the header length. */ 00657 hlen = 8 * (1 + *((u8_t *)p->payload + 1)); 00658 ip_data.current_ip_header_tot_len += hlen; 00659 00660 /* Skip over this header. */ 00661 if (hlen > p->len) { 00662 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00663 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", 00664 hlen, p->len)); 00665 /* free (drop) packet pbufs */ 00666 pbuf_free(p); 00667 IP6_STATS_INC(ip6.lenerr); 00668 IP6_STATS_INC(ip6.drop); 00669 goto ip6_input_cleanup; 00670 } 00671 00672 pbuf_header(p, -(s16_t)hlen); 00673 break; 00674 00675 case IP6_NEXTH_FRAGMENT: 00676 { 00677 struct ip6_frag_hdr *frag_hdr; 00678 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n")); 00679 00680 frag_hdr = (struct ip6_frag_hdr *)p->payload; 00681 00682 /* Get next header type. */ 00683 nexth = frag_hdr->_nexth; 00684 00685 /* Fragment Header length. */ 00686 hlen = 8; 00687 ip_data.current_ip_header_tot_len += hlen; 00688 00689 /* Make sure this header fits in current pbuf. */ 00690 if (hlen > p->len) { 00691 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00692 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", 00693 hlen, p->len)); 00694 /* free (drop) packet pbufs */ 00695 pbuf_free(p); 00696 IP6_FRAG_STATS_INC(ip6_frag.lenerr); 00697 IP6_FRAG_STATS_INC(ip6_frag.drop); 00698 goto ip6_input_cleanup; 00699 } 00700 00701 /* Offset == 0 and more_fragments == 0? */ 00702 if ((frag_hdr->_fragment_offset & 00703 PP_HTONS(IP6_FRAG_OFFSET_MASK | IP6_FRAG_MORE_FLAG)) == 0) { 00704 /* This is a 1-fragment packet, usually a packet that we have 00705 * already reassembled. Skip this header anc continue. */ 00706 pbuf_header(p, -(s16_t)hlen); 00707 } else { 00708 #if LWIP_IPV6_REASS 00709 00710 /* reassemble the packet */ 00711 p = ip6_reass(p); 00712 /* packet not fully reassembled yet? */ 00713 if (p == NULL) { 00714 goto ip6_input_cleanup; 00715 } 00716 00717 /* Returned p point to IPv6 header. 00718 * Update all our variables and pointers and continue. */ 00719 ip6hdr = (struct ip6_hdr *)p->payload; 00720 nexth = IP6H_NEXTH(ip6hdr); 00721 hlen = ip_data.current_ip_header_tot_len = IP6_HLEN; 00722 pbuf_header(p, -IP6_HLEN); 00723 00724 #else /* LWIP_IPV6_REASS */ 00725 /* free (drop) packet pbufs */ 00726 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header dropped (with LWIP_IPV6_REASS==0)\n")); 00727 pbuf_free(p); 00728 IP6_STATS_INC(ip6.opterr); 00729 IP6_STATS_INC(ip6.drop); 00730 goto ip6_input_cleanup; 00731 #endif /* LWIP_IPV6_REASS */ 00732 } 00733 break; 00734 } 00735 default: 00736 goto options_done; 00737 break; 00738 } 00739 } 00740 options_done: 00741 00742 /* p points to IPv6 header again. */ 00743 pbuf_header_force(p, (s16_t)ip_data.current_ip_header_tot_len); 00744 00745 /* send to upper layers */ 00746 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n")); 00747 ip6_debug_print(p); 00748 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); 00749 00750 #if LWIP_RAW 00751 /* raw input did not eat the packet? */ 00752 if (raw_input(p, inp) == 0) 00753 #endif /* LWIP_RAW */ 00754 { 00755 switch (nexth) { 00756 case IP6_NEXTH_NONE: 00757 pbuf_free(p); 00758 break; 00759 #if LWIP_UDP 00760 case IP6_NEXTH_UDP: 00761 #if LWIP_UDPLITE 00762 case IP6_NEXTH_UDPLITE: 00763 #endif /* LWIP_UDPLITE */ 00764 /* Point to payload. */ 00765 pbuf_header(p, -(s16_t)ip_data.current_ip_header_tot_len); 00766 udp_input(p, inp); 00767 break; 00768 #endif /* LWIP_UDP */ 00769 #if LWIP_TCP 00770 case IP6_NEXTH_TCP: 00771 /* Point to payload. */ 00772 pbuf_header(p, -(s16_t)ip_data.current_ip_header_tot_len); 00773 tcp_input(p, inp); 00774 break; 00775 #endif /* LWIP_TCP */ 00776 #if LWIP_ICMP6 00777 case IP6_NEXTH_ICMP6: 00778 /* Point to payload. */ 00779 pbuf_header(p, -(s16_t)ip_data.current_ip_header_tot_len); 00780 icmp6_input(p, inp); 00781 break; 00782 #endif /* LWIP_ICMP */ 00783 default: 00784 #if LWIP_ICMP6 00785 /* send ICMP parameter problem unless it was a multicast or ICMPv6 */ 00786 if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) && 00787 (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) { 00788 icmp6_param_problem(p, ICMP6_PP_HEADER, ip_data.current_ip_header_tot_len - hlen); 00789 } 00790 #endif /* LWIP_ICMP */ 00791 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr))); 00792 pbuf_free(p); 00793 IP6_STATS_INC(ip6.proterr); 00794 IP6_STATS_INC(ip6.drop); 00795 break; 00796 } 00797 } 00798 00799 ip6_input_cleanup: 00800 ip_data.current_netif = NULL; 00801 ip_data.current_input_netif = NULL; 00802 ip_data.current_ip6_header = NULL; 00803 ip_data.current_ip_header_tot_len = 0; 00804 ip6_addr_set_zero(ip6_current_src_addr()); 00805 ip6_addr_set_zero(ip6_current_dest_addr()); 00806 00807 return ERR_OK; 00808 } 00809 00810 00811 /** 00812 * Sends an IPv6 packet on a network interface. This function constructs 00813 * the IPv6 header. If the source IPv6 address is NULL, the IPv6 "ANY" address is 00814 * used as source (usually during network startup). If the source IPv6 address it 00815 * IP6_ADDR_ANY, the most appropriate IPv6 address of the outgoing network 00816 * interface is filled in as source address. If the destination IPv6 address is 00817 * LWIP_IP_HDRINCL, p is assumed to already include an IPv6 header and 00818 * p->payload points to it instead of the data. 00819 * 00820 * @param p the packet to send (p->payload points to the data, e.g. next 00821 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an 00822 IPv6 header and p->payload points to that IPv6 header) 00823 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an 00824 * IP address of the netif is selected and used as source address. 00825 * if src == NULL, IP6_ADDR_ANY is used as source) 00826 * @param dest the destination IPv6 address to send the packet to 00827 * @param hl the Hop Limit value to be set in the IPv6 header 00828 * @param tc the Traffic Class value to be set in the IPv6 header 00829 * @param nexth the Next Header to be set in the IPv6 header 00830 * @param netif the netif on which to send this packet 00831 * @return ERR_OK if the packet was sent OK 00832 * ERR_BUF if p doesn't have enough space for IPv6/LINK headers 00833 * returns errors returned by netif->output 00834 */ 00835 err_t 00836 ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, 00837 u8_t hl, u8_t tc, 00838 u8_t nexth, struct netif *netif) 00839 { 00840 const ip6_addr_t *src_used = src; 00841 if (dest != LWIP_IP_HDRINCL) { 00842 if (src != NULL && ip6_addr_isany(src)) { 00843 src_used = ip_2_ip6(ip6_select_source_address(netif, dest)); 00844 if ((src_used == NULL) || ip6_addr_isany(src_used)) { 00845 /* No appropriate source address was found for this packet. */ 00846 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n")); 00847 IP6_STATS_INC(ip6.rterr); 00848 return ERR_RTE; 00849 } 00850 } 00851 } 00852 return ip6_output_if_src(p, src_used, dest, hl, tc, nexth, netif); 00853 } 00854 00855 /** 00856 * Same as ip6_output_if() but 'src' address is not replaced by netif address 00857 * when it is 'any'. 00858 */ 00859 err_t 00860 ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, 00861 u8_t hl, u8_t tc, 00862 u8_t nexth, struct netif *netif) 00863 { 00864 struct ip6_hdr *ip6hdr; 00865 ip6_addr_t dest_addr; 00866 00867 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); 00868 00869 /* Should the IPv6 header be generated or is it already included in p? */ 00870 if (dest != LWIP_IP_HDRINCL) { 00871 /* generate IPv6 header */ 00872 if (pbuf_header(p, IP6_HLEN)) { 00873 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n")); 00874 IP6_STATS_INC(ip6.err); 00875 return ERR_BUF; 00876 } 00877 00878 ip6hdr = (struct ip6_hdr *)p->payload; 00879 LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr", 00880 (p->len >= sizeof(struct ip6_hdr))); 00881 00882 IP6H_HOPLIM_SET(ip6hdr, hl); 00883 IP6H_NEXTH_SET(ip6hdr, nexth); 00884 00885 /* dest cannot be NULL here */ 00886 ip6_addr_copy(ip6hdr->dest, *dest); 00887 00888 IP6H_VTCFL_SET(ip6hdr, 6, tc, 0); 00889 IP6H_PLEN_SET(ip6hdr, p->tot_len - IP6_HLEN); 00890 00891 if (src == NULL) { 00892 src = IP6_ADDR_ANY6; 00893 } 00894 /* src cannot be NULL here */ 00895 ip6_addr_copy(ip6hdr->src, *src); 00896 00897 } else { 00898 /* IP header already included in p */ 00899 ip6hdr = (struct ip6_hdr *)p->payload; 00900 ip6_addr_copy(dest_addr, ip6hdr->dest); 00901 dest = &dest_addr; 00902 } 00903 00904 IP6_STATS_INC(ip6.xmit); 00905 00906 LWIP_DEBUGF(IP6_DEBUG, ("ip6_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num)); 00907 ip6_debug_print(p); 00908 00909 #if ENABLE_LOOPBACK 00910 { 00911 int i; 00912 #if !LWIP_HAVE_LOOPIF 00913 if (ip6_addr_isloopback(dest)) { 00914 return netif_loop_output(netif, p); 00915 } 00916 #endif /* !LWIP_HAVE_LOOPIF */ 00917 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00918 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && 00919 ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) { 00920 /* Packet to self, enqueue it for loopback */ 00921 LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n")); 00922 return netif_loop_output(netif, p); 00923 } 00924 } 00925 } 00926 #endif /* ENABLE_LOOPBACK */ 00927 #if LWIP_IPV6_FRAG 00928 /* don't fragment if interface has mtu set to 0 [loopif] */ 00929 if (netif->mtu && (p->tot_len > nd6_get_destination_mtu(dest, netif))) { 00930 return ip6_frag(p, netif, dest); 00931 } 00932 #endif /* LWIP_IPV6_FRAG */ 00933 00934 LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n")); 00935 return netif->output_ip6(netif, p, dest); 00936 } 00937 00938 /** 00939 * Simple interface to ip6_output_if. It finds the outgoing network 00940 * interface and calls upon ip6_output_if to do the actual work. 00941 * 00942 * @param p the packet to send (p->payload points to the data, e.g. next 00943 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an 00944 IPv6 header and p->payload points to that IPv6 header) 00945 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an 00946 * IP address of the netif is selected and used as source address. 00947 * if src == NULL, IP6_ADDR_ANY is used as source) 00948 * @param dest the destination IPv6 address to send the packet to 00949 * @param hl the Hop Limit value to be set in the IPv6 header 00950 * @param tc the Traffic Class value to be set in the IPv6 header 00951 * @param nexth the Next Header to be set in the IPv6 header 00952 * 00953 * @return ERR_RTE if no route is found 00954 * see ip_output_if() for more return values 00955 */ 00956 err_t 00957 ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, 00958 u8_t hl, u8_t tc, u8_t nexth) 00959 { 00960 struct netif *netif; 00961 struct ip6_hdr *ip6hdr; 00962 ip6_addr_t src_addr, dest_addr; 00963 00964 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); 00965 00966 if (dest != LWIP_IP_HDRINCL) { 00967 netif = ip6_route(src, dest); 00968 } else { 00969 /* IP header included in p, read addresses. */ 00970 ip6hdr = (struct ip6_hdr *)p->payload; 00971 ip6_addr_copy(src_addr, ip6hdr->src); 00972 ip6_addr_copy(dest_addr, ip6hdr->dest); 00973 netif = ip6_route(&src_addr, &dest_addr); 00974 } 00975 00976 if (netif == NULL) { 00977 LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", 00978 IP6_ADDR_BLOCK1(dest), 00979 IP6_ADDR_BLOCK2(dest), 00980 IP6_ADDR_BLOCK3(dest), 00981 IP6_ADDR_BLOCK4(dest), 00982 IP6_ADDR_BLOCK5(dest), 00983 IP6_ADDR_BLOCK6(dest), 00984 IP6_ADDR_BLOCK7(dest), 00985 IP6_ADDR_BLOCK8(dest))); 00986 IP6_STATS_INC(ip6.rterr); 00987 return ERR_RTE; 00988 } 00989 00990 return ip6_output_if(p, src, dest, hl, tc, nexth, netif); 00991 } 00992 00993 00994 #if LWIP_NETIF_HWADDRHINT 00995 /** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint 00996 * before calling ip6_output_if. 00997 * 00998 * @param p the packet to send (p->payload points to the data, e.g. next 00999 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an 01000 IPv6 header and p->payload points to that IPv6 header) 01001 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an 01002 * IP address of the netif is selected and used as source address. 01003 * if src == NULL, IP6_ADDR_ANY is used as source) 01004 * @param dest the destination IPv6 address to send the packet to 01005 * @param hl the Hop Limit value to be set in the IPv6 header 01006 * @param tc the Traffic Class value to be set in the IPv6 header 01007 * @param nexth the Next Header to be set in the IPv6 header 01008 * @param addr_hint address hint pointer set to netif->addr_hint before 01009 * calling ip_output_if() 01010 * 01011 * @return ERR_RTE if no route is found 01012 * see ip_output_if() for more return values 01013 */ 01014 err_t 01015 ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, 01016 u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint) 01017 { 01018 struct netif *netif; 01019 struct ip6_hdr *ip6hdr; 01020 ip6_addr_t src_addr, dest_addr; 01021 err_t err; 01022 01023 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); 01024 01025 if (dest != LWIP_IP_HDRINCL) { 01026 netif = ip6_route(src, dest); 01027 } else { 01028 /* IP header included in p, read addresses. */ 01029 ip6hdr = (struct ip6_hdr *)p->payload; 01030 ip6_addr_copy(src_addr, ip6hdr->src); 01031 ip6_addr_copy(dest_addr, ip6hdr->dest); 01032 netif = ip6_route(&src_addr, &dest_addr); 01033 } 01034 01035 if (netif == NULL) { 01036 LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", 01037 IP6_ADDR_BLOCK1(dest), 01038 IP6_ADDR_BLOCK2(dest), 01039 IP6_ADDR_BLOCK3(dest), 01040 IP6_ADDR_BLOCK4(dest), 01041 IP6_ADDR_BLOCK5(dest), 01042 IP6_ADDR_BLOCK6(dest), 01043 IP6_ADDR_BLOCK7(dest), 01044 IP6_ADDR_BLOCK8(dest))); 01045 IP6_STATS_INC(ip6.rterr); 01046 return ERR_RTE; 01047 } 01048 01049 NETIF_SET_HWADDRHINT(netif, addr_hint); 01050 err = ip6_output_if(p, src, dest, hl, tc, nexth, netif); 01051 NETIF_SET_HWADDRHINT(netif, NULL); 01052 01053 return err; 01054 } 01055 #endif /* LWIP_NETIF_HWADDRHINT*/ 01056 01057 #if LWIP_IPV6_MLD 01058 /** 01059 * Add a hop-by-hop options header with a router alert option and padding. 01060 * 01061 * Used by MLD when sending a Multicast listener report/done message. 01062 * 01063 * @param p the packet to which we will prepend the options header 01064 * @param nexth the next header protocol number (e.g. IP6_NEXTH_ICMP6) 01065 * @param value the value of the router alert option data (e.g. IP6_ROUTER_ALERT_VALUE_MLD) 01066 * @return ERR_OK if hop-by-hop header was added, ERR_* otherwise 01067 */ 01068 err_t 01069 ip6_options_add_hbh_ra(struct pbuf *p, u8_t nexth, u8_t value) 01070 { 01071 struct ip6_hbh_hdr *hbh_hdr; 01072 01073 /* Move pointer to make room for hop-by-hop options header. */ 01074 if (pbuf_header(p, sizeof(struct ip6_hbh_hdr))) { 01075 LWIP_DEBUGF(IP6_DEBUG, ("ip6_options: no space for options header\n")); 01076 IP6_STATS_INC(ip6.err); 01077 return ERR_BUF; 01078 } 01079 01080 hbh_hdr = (struct ip6_hbh_hdr *)p->payload; 01081 01082 /* Set fields. */ 01083 hbh_hdr->_nexth = nexth; 01084 hbh_hdr->_hlen = 0; 01085 hbh_hdr->_ra_opt_type = IP6_ROUTER_ALERT_OPTION; 01086 hbh_hdr->_ra_opt_dlen = 2; 01087 hbh_hdr->_ra_opt_data = value; 01088 hbh_hdr->_padn_opt_type = IP6_PADN_ALERT_OPTION; 01089 hbh_hdr->_padn_opt_dlen = 0; 01090 01091 return ERR_OK; 01092 } 01093 #endif /* LWIP_IPV6_MLD */ 01094 01095 #if IP6_DEBUG 01096 /* Print an IPv6 header by using LWIP_DEBUGF 01097 * @param p an IPv6 packet, p->payload pointing to the IPv6 header 01098 */ 01099 void 01100 ip6_debug_print(struct pbuf *p) 01101 { 01102 struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload; 01103 01104 TRACE_TO_ASCII_HEX_DUMPF("IP>", IP6H_PLEN(ip6hdr) + 40, (char *) ip6hdr); 01105 01106 LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n")); 01107 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); 01108 LWIP_DEBUGF(IP6_DEBUG, ("| %2"U16_F" | %3"U16_F" | %7"U32_F" | (ver, class, flow)\n", 01109 IP6H_V(ip6hdr), 01110 IP6H_TC(ip6hdr), 01111 IP6H_FL(ip6hdr))); 01112 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); 01113 LWIP_DEBUGF(IP6_DEBUG, ("| %5"U16_F" | %3"U16_F" | %3"U16_F" | (plen, nexth, hopl)\n", 01114 IP6H_PLEN(ip6hdr), 01115 IP6H_NEXTH(ip6hdr), 01116 IP6H_HOPLIM(ip6hdr))); 01117 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); 01118 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (src)\n", 01119 IP6_ADDR_BLOCK1(&(ip6hdr->src)), 01120 IP6_ADDR_BLOCK2(&(ip6hdr->src)), 01121 IP6_ADDR_BLOCK3(&(ip6hdr->src)), 01122 IP6_ADDR_BLOCK4(&(ip6hdr->src)))); 01123 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", 01124 IP6_ADDR_BLOCK5(&(ip6hdr->src)), 01125 IP6_ADDR_BLOCK6(&(ip6hdr->src)), 01126 IP6_ADDR_BLOCK7(&(ip6hdr->src)), 01127 IP6_ADDR_BLOCK8(&(ip6hdr->src)))); 01128 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); 01129 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (dest)\n", 01130 IP6_ADDR_BLOCK1(&(ip6hdr->dest)), 01131 IP6_ADDR_BLOCK2(&(ip6hdr->dest)), 01132 IP6_ADDR_BLOCK3(&(ip6hdr->dest)), 01133 IP6_ADDR_BLOCK4(&(ip6hdr->dest)))); 01134 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", 01135 IP6_ADDR_BLOCK5(&(ip6hdr->dest)), 01136 IP6_ADDR_BLOCK6(&(ip6hdr->dest)), 01137 IP6_ADDR_BLOCK7(&(ip6hdr->dest)), 01138 IP6_ADDR_BLOCK8(&(ip6hdr->dest)))); 01139 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); 01140 } 01141 #endif /* IP6_DEBUG */ 01142 01143 #endif /* LWIP_IPV6 */
Generated on Fri Jul 22 2022 04:53:52 by
1.7.2
