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