source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/ipv6/ip6.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 53.2 KB
Line 
1/**
2 * @file
3 *
4 * IPv6 layer.
5 */
6
7/*
8 * Copyright (c) 2010 Inico Technologies Ltd.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without modification,
12 * are permitted provided that the following conditions are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31 * OF SUCH DAMAGE.
32 *
33 * This file is part of the lwIP TCP/IP stack.
34 *
35 * Author: Ivan Delamer <delamer@inicotech.com>
36 *
37 *
38 * Please coordinate changes and requests with Ivan Delamer
39 * <delamer@inicotech.com>
40 */
41
42#include "lwip/opt.h"
43
44#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
45
46#include "lwip/def.h"
47#include "lwip/mem.h"
48#include "lwip/netif.h"
49#include "lwip/ip.h"
50#include "lwip/ip6.h"
51#include "lwip/ip6_addr.h"
52#include "lwip/ip6_frag.h"
53#include "lwip/icmp6.h"
54#include "lwip/priv/raw_priv.h"
55#include "lwip/udp.h"
56#include "lwip/priv/tcp_priv.h"
57#include "lwip/dhcp6.h"
58#include "lwip/nd6.h"
59#include "lwip/mld6.h"
60#include "lwip/debug.h"
61#include "lwip/stats.h"
62
63#ifdef LWIP_HOOK_FILENAME
64#include LWIP_HOOK_FILENAME
65#endif
66
67/**
68 * Finds the appropriate network interface for a given IPv6 address. It tries to select
69 * a netif following a sequence of heuristics:
70 * 1) if there is only 1 netif, return it
71 * 2) if the destination is a zoned address, match its zone to a netif
72 * 3) if the either the source or destination address is a scoped address,
73 * match the source address's zone (if set) or address (if not) to a netif
74 * 4) tries to match the destination subnet to a configured address
75 * 5) tries to find a router-announced route
76 * 6) tries to match the (unscoped) source address to the netif
77 * 7) returns the default netif, if configured
78 *
79 * Note that each of the two given addresses may or may not be properly zoned.
80 *
81 * @param src the source IPv6 address, if known
82 * @param dest the destination IPv6 address for which to find the route
83 * @return the netif on which to send to reach dest
84 */
85struct netif *
86ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
87{
88#if LWIP_SINGLE_NETIF
89 LWIP_UNUSED_ARG(src);
90 LWIP_UNUSED_ARG(dest);
91#else /* LWIP_SINGLE_NETIF */
92 struct netif *netif;
93 s8_t i;
94
95 LWIP_ASSERT_CORE_LOCKED();
96
97 /* If single netif configuration, fast return. */
98 if ((netif_list != NULL) && (netif_list->next == NULL)) {
99 if (!netif_is_up(netif_list) || !netif_is_link_up(netif_list) ||
100 (ip6_addr_has_zone(dest) && !ip6_addr_test_zone(dest, netif_list))) {
101 return NULL;
102 }
103 return netif_list;
104 }
105
106#if LWIP_IPV6_SCOPES
107 /* Special processing for zoned destination addresses. This includes link-
108 * local unicast addresses and interface/link-local multicast addresses. Use
109 * the zone to find a matching netif. If the address is not zoned, then there
110 * is technically no "wrong" netif to choose, and we leave routing to other
111 * rules; in most cases this should be the scoped-source rule below. */
112 if (ip6_addr_has_zone(dest)) {
113 IP6_ADDR_ZONECHECK(dest);
114 /* Find a netif based on the zone. For custom mappings, one zone may map
115 * to multiple netifs, so find one that can actually send a packet. */
116 NETIF_FOREACH(netif) {
117 if (ip6_addr_test_zone(dest, netif) &&
118 netif_is_up(netif) && netif_is_link_up(netif)) {
119 return netif;
120 }
121 }
122 /* No matching netif found. Do no try to route to a different netif,
123 * as that would be a zone violation, resulting in any packets sent to
124 * that netif being dropped on output. */
125 return NULL;
126 }
127#endif /* LWIP_IPV6_SCOPES */
128
129 /* Special processing for scoped source and destination addresses. If we get
130 * here, the destination address does not have a zone, so either way we need
131 * to look at the source address, which may or may not have a zone. If it
132 * does, the zone is restrictive: there is (typically) only one matching
133 * netif for it, and we should avoid routing to any other netif as that would
134 * result in guaranteed zone violations. For scoped source addresses that do
135 * not have a zone, use (only) a netif that has that source address locally
136 * assigned. This case also applies to the loopback source address, which has
137 * an implied link-local scope. If only the destination address is scoped
138 * (but, again, not zoned), we still want to use only the source address to
139 * determine its zone because that's most likely what the user/application
140 * wants, regardless of whether the source address is scoped. Finally, some
141 * of this story also applies if scoping is disabled altogether. */
142#if LWIP_IPV6_SCOPES
143 if (ip6_addr_has_scope(dest, IP6_UNKNOWN) ||
144 ip6_addr_has_scope(src, IP6_UNICAST) ||
145#else /* LWIP_IPV6_SCOPES */
146 if (ip6_addr_islinklocal(dest) || ip6_addr_ismulticast_iflocal(dest) ||
147 ip6_addr_ismulticast_linklocal(dest) || ip6_addr_islinklocal(src) ||
148#endif /* LWIP_IPV6_SCOPES */
149 ip6_addr_isloopback(src)) {
150#if LWIP_IPV6_SCOPES
151 if (ip6_addr_has_zone(src)) {
152 /* Find a netif matching the source zone (relatively cheap). */
153 NETIF_FOREACH(netif) {
154 if (netif_is_up(netif) && netif_is_link_up(netif) &&
155 ip6_addr_test_zone(src, netif)) {
156 return netif;
157 }
158 }
159 } else
160#endif /* LWIP_IPV6_SCOPES */
161 {
162 /* Find a netif matching the source address (relatively expensive). */
163 NETIF_FOREACH(netif) {
164 if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
165 continue;
166 }
167 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
168 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
169 ip6_addr_cmp_zoneless(src, netif_ip6_addr(netif, i))) {
170 return netif;
171 }
172 }
173 }
174 }
175 /* Again, do not use any other netif in this case, as that could result in
176 * zone boundary violations. */
177 return NULL;
178 }
179
180 /* We come here only if neither source nor destination is scoped. */
181 IP6_ADDR_ZONECHECK(src);
182
183#ifdef LWIP_HOOK_IP6_ROUTE
184 netif = LWIP_HOOK_IP6_ROUTE(src, dest);
185 if (netif != NULL) {
186 return netif;
187 }
188#endif
189
190 /* See if the destination subnet matches a configured address. In accordance
191 * with RFC 5942, dynamically configured addresses do not have an implied
192 * local subnet, and thus should be considered /128 assignments. However, as
193 * such, the destination address may still match a local address, and so we
194 * still need to check for exact matches here. By (lwIP) policy, statically
195 * configured addresses do always have an implied local /64 subnet. */
196 NETIF_FOREACH(netif) {
197 if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
198 continue;
199 }
200 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
201 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
202 ip6_addr_netcmp(dest, netif_ip6_addr(netif, i)) &&
203 (netif_ip6_addr_isstatic(netif, i) ||
204 ip6_addr_nethostcmp(dest, netif_ip6_addr(netif, i)))) {
205 return netif;
206 }
207 }
208 }
209
210 /* Get the netif for a suitable router-announced route. */
211 netif = nd6_find_route(dest);
212 if (netif != NULL) {
213 return netif;
214 }
215
216 /* Try with the netif that matches the source address. Given the earlier rule
217 * for scoped source addresses, this applies to unscoped addresses only. */
218 if (!ip6_addr_isany(src)) {
219 NETIF_FOREACH(netif) {
220 if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
221 continue;
222 }
223 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
224 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
225 ip6_addr_cmp(src, netif_ip6_addr(netif, i))) {
226 return netif;
227 }
228 }
229 }
230 }
231
232#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
233 /* loopif is disabled, loopback traffic is passed through any netif */
234 if (ip6_addr_isloopback(dest)) {
235 /* don't check for link on loopback traffic */
236 if (netif_default != NULL && netif_is_up(netif_default)) {
237 return netif_default;
238 }
239 /* default netif is not up, just use any netif for loopback traffic */
240 NETIF_FOREACH(netif) {
241 if (netif_is_up(netif)) {
242 return netif;
243 }
244 }
245 return NULL;
246 }
247#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
248#endif /* !LWIP_SINGLE_NETIF */
249
250 /* no matching netif found, use default netif, if up */
251 if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default)) {
252 return NULL;
253 }
254 return netif_default;
255}
256
257/**
258 * @ingroup ip6
259 * Select the best IPv6 source address for a given destination IPv6 address.
260 *
261 * This implementation follows RFC 6724 Sec. 5 to the following extent:
262 * - Rules 1, 2, 3: fully implemented
263 * - Rules 4, 5, 5.5: not applicable
264 * - Rule 6: not implemented
265 * - Rule 7: not applicable
266 * - Rule 8: limited to "prefer /64 subnet match over non-match"
267 *
268 * For Rule 2, we deliberately deviate from RFC 6724 Sec. 3.1 by considering
269 * ULAs to be of smaller scope than global addresses, to avoid that a preferred
270 * ULA is picked over a deprecated global address when given a global address
271 * as destination, as that would likely result in broken two-way communication.
272 *
273 * As long as temporary addresses are not supported (as used in Rule 7), a
274 * proper implementation of Rule 8 would obviate the need to implement Rule 6.
275 *
276 * @param netif the netif on which to send a packet
277 * @param dest the destination we are trying to reach (possibly not properly
278 * zoned)
279 * @return the most suitable source address to use, or NULL if no suitable
280 * source address is found
281 */
282const ip_addr_t *
283ip6_select_source_address(struct netif *netif, const ip6_addr_t *dest)
284{
285 const ip_addr_t *best_addr;
286 const ip6_addr_t *cand_addr;
287 s8_t dest_scope, cand_scope;
288 s8_t best_scope = IP6_MULTICAST_SCOPE_RESERVED;
289 u8_t i, cand_pref, cand_bits;
290 u8_t best_pref = 0;
291 u8_t best_bits = 0;
292
293 /* Start by determining the scope of the given destination address. These
294 * tests are hopefully (roughly) in order of likeliness to match. */
295 if (ip6_addr_isglobal(dest)) {
296 dest_scope = IP6_MULTICAST_SCOPE_GLOBAL;
297 } else if (ip6_addr_islinklocal(dest) || ip6_addr_isloopback(dest)) {
298 dest_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL;
299 } else if (ip6_addr_isuniquelocal(dest)) {
300 dest_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL;
301 } else if (ip6_addr_ismulticast(dest)) {
302 dest_scope = ip6_addr_multicast_scope(dest);
303 } else if (ip6_addr_issitelocal(dest)) {
304 dest_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL;
305 } else {
306 /* no match, consider scope global */
307 dest_scope = IP6_MULTICAST_SCOPE_GLOBAL;
308 }
309
310 best_addr = NULL;
311
312 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
313 /* Consider only valid (= preferred and deprecated) addresses. */
314 if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) {
315 continue;
316 }
317 /* Determine the scope of this candidate address. Same ordering idea. */
318 cand_addr = netif_ip6_addr(netif, i);
319 if (ip6_addr_isglobal(cand_addr)) {
320 cand_scope = IP6_MULTICAST_SCOPE_GLOBAL;
321 } else if (ip6_addr_islinklocal(cand_addr)) {
322 cand_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL;
323 } else if (ip6_addr_isuniquelocal(cand_addr)) {
324 cand_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL;
325 } else if (ip6_addr_issitelocal(cand_addr)) {
326 cand_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL;
327 } else {
328 /* no match, treat as low-priority global scope */
329 cand_scope = IP6_MULTICAST_SCOPE_RESERVEDF;
330 }
331 cand_pref = ip6_addr_ispreferred(netif_ip6_addr_state(netif, i));
332 /* @todo compute the actual common bits, for longest matching prefix. */
333 /* We cannot count on the destination address having a proper zone
334 * assignment, so do not compare zones in this case. */
335 cand_bits = ip6_addr_netcmp_zoneless(cand_addr, dest); /* just 1 or 0 for now */
336 if (cand_bits && ip6_addr_nethostcmp(cand_addr, dest)) {
337 return netif_ip_addr6(netif, i); /* Rule 1 */
338 }
339 if ((best_addr == NULL) || /* no alternative yet */
340 ((cand_scope < best_scope) && (cand_scope >= dest_scope)) ||
341 ((cand_scope > best_scope) && (best_scope < dest_scope)) || /* Rule 2 */
342 ((cand_scope == best_scope) && ((cand_pref > best_pref) || /* Rule 3 */
343 ((cand_pref == best_pref) && (cand_bits > best_bits))))) { /* Rule 8 */
344 /* We found a new "winning" candidate. */
345 best_addr = netif_ip_addr6(netif, i);
346 best_scope = cand_scope;
347 best_pref = cand_pref;
348 best_bits = cand_bits;
349 }
350 }
351
352 return best_addr; /* may be NULL */
353}
354
355#if LWIP_IPV6_FORWARD
356/**
357 * Forwards an IPv6 packet. It finds an appropriate route for the
358 * packet, decrements the HL value of the packet, and outputs
359 * the packet on the appropriate interface.
360 *
361 * @param p the packet to forward (p->payload points to IP header)
362 * @param iphdr the IPv6 header of the input packet
363 * @param inp the netif on which this packet was received
364 */
365static void
366ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
367{
368 struct netif *netif;
369
370 /* do not forward link-local or loopback addresses */
371 if (ip6_addr_islinklocal(ip6_current_dest_addr()) ||
372 ip6_addr_isloopback(ip6_current_dest_addr())) {
373 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n"));
374 IP6_STATS_INC(ip6.rterr);
375 IP6_STATS_INC(ip6.drop);
376 return;
377 }
378
379 /* Find network interface where to forward this IP packet to. */
380 netif = ip6_route(IP6_ADDR_ANY6, ip6_current_dest_addr());
381 if (netif == NULL) {
382 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",
383 IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
384 IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
385 IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
386 IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
387 IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
388 IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
389 IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
390 IP6_ADDR_BLOCK8(ip6_current_dest_addr())));
391#if LWIP_ICMP6
392 /* Don't send ICMP messages in response to ICMP messages */
393 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
394 icmp6_dest_unreach(p, ICMP6_DUR_NO_ROUTE);
395 }
396#endif /* LWIP_ICMP6 */
397 IP6_STATS_INC(ip6.rterr);
398 IP6_STATS_INC(ip6.drop);
399 return;
400 }
401#if LWIP_IPV6_SCOPES
402 /* Do not forward packets with a zoned (e.g., link-local) source address
403 * outside of their zone. We determined the zone a bit earlier, so we know
404 * that the address is properly zoned here, so we can safely use has_zone.
405 * Also skip packets with a loopback source address (link-local implied). */
406 if ((ip6_addr_has_zone(ip6_current_src_addr()) &&
407 !ip6_addr_test_zone(ip6_current_src_addr(), netif)) ||
408 ip6_addr_isloopback(ip6_current_src_addr())) {
409 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding packet beyond its source address zone.\n"));
410 IP6_STATS_INC(ip6.rterr);
411 IP6_STATS_INC(ip6.drop);
412 return;
413 }
414#endif /* LWIP_IPV6_SCOPES */
415 /* Do not forward packets onto the same network interface on which
416 * they arrived. */
417 if (netif == inp) {
418 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not bouncing packets back on incoming interface.\n"));
419 IP6_STATS_INC(ip6.rterr);
420 IP6_STATS_INC(ip6.drop);
421 return;
422 }
423
424 /* decrement HL */
425 IP6H_HOPLIM_SET(iphdr, IP6H_HOPLIM(iphdr) - 1);
426 /* send ICMP6 if HL == 0 */
427 if (IP6H_HOPLIM(iphdr) == 0) {
428#if LWIP_ICMP6
429 /* Don't send ICMP messages in response to ICMP messages */
430 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
431 icmp6_time_exceeded(p, ICMP6_TE_HL);
432 }
433#endif /* LWIP_ICMP6 */
434 IP6_STATS_INC(ip6.drop);
435 return;
436 }
437
438 if (netif->mtu && (p->tot_len > netif->mtu)) {
439#if LWIP_ICMP6
440 /* Don't send ICMP messages in response to ICMP messages */
441 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
442 icmp6_packet_too_big(p, netif->mtu);
443 }
444#endif /* LWIP_ICMP6 */
445 IP6_STATS_INC(ip6.drop);
446 return;
447 }
448
449 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",
450 IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
451 IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
452 IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
453 IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
454 IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
455 IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
456 IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
457 IP6_ADDR_BLOCK8(ip6_current_dest_addr())));
458
459 /* transmit pbuf on chosen interface */
460 netif->output_ip6(netif, p, ip6_current_dest_addr());
461 IP6_STATS_INC(ip6.fw);
462 IP6_STATS_INC(ip6.xmit);
463 return;
464}
465#endif /* LWIP_IPV6_FORWARD */
466
467/** Return true if the current input packet should be accepted on this netif */
468static int
469ip6_input_accept(struct netif *netif)
470{
471 /* interface is up? */
472 if (netif_is_up(netif)) {
473 u8_t i;
474 /* unicast to this interface address? address configured? */
475 /* If custom scopes are used, the destination zone will be tested as
476 * part of the local-address comparison, but we need to test the source
477 * scope as well (e.g., is this interface on the same link?). */
478 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
479 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
480 ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i))
481#if IPV6_CUSTOM_SCOPES
482 && (!ip6_addr_has_zone(ip6_current_src_addr()) ||
483 ip6_addr_test_zone(ip6_current_src_addr(), netif))
484#endif /* IPV6_CUSTOM_SCOPES */
485 ) {
486 /* accept on this netif */
487 return 1;
488 }
489 }
490 }
491 return 0;
492}
493
494/**
495 * This function is called by the network interface device driver when
496 * an IPv6 packet is received. The function does the basic checks of the
497 * IP header such as packet size being at least larger than the header
498 * size etc. If the packet was not destined for us, the packet is
499 * forwarded (using ip6_forward).
500 *
501 * Finally, the packet is sent to the upper layer protocol input function.
502 *
503 * @param p the received IPv6 packet (p->payload points to IPv6 header)
504 * @param inp the netif on which this packet was received
505 * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't
506 * processed, but currently always returns ERR_OK)
507 */
508err_t
509ip6_input(struct pbuf *p, struct netif *inp)
510{
511 struct ip6_hdr *ip6hdr;
512 struct netif *netif;
513 const u8_t *nexth;
514 u16_t hlen, hlen_tot; /* the current header length */
515#if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/
516 @todo
517 int check_ip_src=1;
518#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
519#if LWIP_RAW
520 raw_input_state_t raw_status;
521#endif /* LWIP_RAW */
522
523 LWIP_ASSERT_CORE_LOCKED();
524
525 IP6_STATS_INC(ip6.recv);
526
527 /* identify the IP header */
528 ip6hdr = (struct ip6_hdr *)p->payload;
529 if (IP6H_V(ip6hdr) != 6) {
530 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n",
531 IP6H_V(ip6hdr)));
532 pbuf_free(p);
533 IP6_STATS_INC(ip6.err);
534 IP6_STATS_INC(ip6.drop);
535 return ERR_OK;
536 }
537
538#ifdef LWIP_HOOK_IP6_INPUT
539 if (LWIP_HOOK_IP6_INPUT(p, inp)) {
540 /* the packet has been eaten */
541 return ERR_OK;
542 }
543#endif
544
545 /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
546 if ((IP6_HLEN > p->len) || (IP6H_PLEN(ip6hdr) > (p->tot_len - IP6_HLEN))) {
547 if (IP6_HLEN > p->len) {
548 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
549 ("IPv6 header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
550 (u16_t)IP6_HLEN, p->len));
551 }
552 if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) {
553 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
554 ("IPv6 (plen %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
555 (u16_t)(IP6H_PLEN(ip6hdr) + IP6_HLEN), p->tot_len));
556 }
557 /* free (drop) packet pbufs */
558 pbuf_free(p);
559 IP6_STATS_INC(ip6.lenerr);
560 IP6_STATS_INC(ip6.drop);
561 return ERR_OK;
562 }
563
564 /* Trim pbuf. This should have been done at the netif layer,
565 * but we'll do it anyway just to be sure that its done. */
566 pbuf_realloc(p, (u16_t)(IP6_HLEN + IP6H_PLEN(ip6hdr)));
567
568 /* copy IP addresses to aligned ip6_addr_t */
569 ip_addr_copy_from_ip6_packed(ip_data.current_iphdr_dest, ip6hdr->dest);
570 ip_addr_copy_from_ip6_packed(ip_data.current_iphdr_src, ip6hdr->src);
571
572 /* Don't accept virtual IPv4 mapped IPv6 addresses.
573 * Don't accept multicast source addresses. */
574 if (ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_dest)) ||
575 ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_src)) ||
576 ip6_addr_ismulticast(ip_2_ip6(&ip_data.current_iphdr_src))) {
577 /* free (drop) packet pbufs */
578 pbuf_free(p);
579 IP6_STATS_INC(ip6.err);
580 IP6_STATS_INC(ip6.drop);
581 return ERR_OK;
582 }
583
584 /* Set the appropriate zone identifier on the addresses. */
585 ip6_addr_assign_zone(ip_2_ip6(&ip_data.current_iphdr_dest), IP6_UNKNOWN, inp);
586 ip6_addr_assign_zone(ip_2_ip6(&ip_data.current_iphdr_src), IP6_UNICAST, inp);
587
588 /* current header pointer. */
589 ip_data.current_ip6_header = ip6hdr;
590
591 /* In netif, used in case we need to send ICMPv6 packets back. */
592 ip_data.current_netif = inp;
593 ip_data.current_input_netif = inp;
594
595 /* match packet against an interface, i.e. is this packet for us? */
596 if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
597 /* Always joined to multicast if-local and link-local all-nodes group. */
598 if (ip6_addr_isallnodes_iflocal(ip6_current_dest_addr()) ||
599 ip6_addr_isallnodes_linklocal(ip6_current_dest_addr())) {
600 netif = inp;
601 }
602#if LWIP_IPV6_MLD
603 else if (mld6_lookfor_group(inp, ip6_current_dest_addr())) {
604 netif = inp;
605 }
606#else /* LWIP_IPV6_MLD */
607 else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) {
608 u8_t i;
609 /* Filter solicited node packets when MLD is not enabled
610 * (for Neighbor discovery). */
611 netif = NULL;
612 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
613 if (ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) &&
614 ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) {
615 netif = inp;
616 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %c%c\n",
617 netif->name[0], netif->name[1]));
618 break;
619 }
620 }
621 }
622#endif /* LWIP_IPV6_MLD */
623 else {
624 netif = NULL;
625 }
626 } else {
627 /* start trying with inp. if that's not acceptable, start walking the
628 list of configured netifs. */
629 if (ip6_input_accept(inp)) {
630 netif = inp;
631 } else {
632 netif = NULL;
633#if !IPV6_CUSTOM_SCOPES
634 /* Shortcut: stop looking for other interfaces if either the source or
635 * the destination has a scope constrained to this interface. Custom
636 * scopes may break the 1:1 link/interface mapping, however. */
637 if (ip6_addr_islinklocal(ip6_current_dest_addr()) ||
638 ip6_addr_islinklocal(ip6_current_src_addr())) {
639 goto netif_found;
640 }
641#endif /* !IPV6_CUSTOM_SCOPES */
642#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
643 /* The loopback address is to be considered link-local. Packets to it
644 * should be dropped on other interfaces, as per RFC 4291 Sec. 2.5.3.
645 * Its implied scope means packets *from* the loopback address should
646 * not be accepted on other interfaces, either. These requirements
647 * cannot be implemented in the case that loopback traffic is sent
648 * across a non-loopback interface, however. */
649 if (ip6_addr_isloopback(ip6_current_dest_addr()) ||
650 ip6_addr_isloopback(ip6_current_src_addr())) {
651 goto netif_found;
652 }
653#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
654#if !LWIP_SINGLE_NETIF
655 NETIF_FOREACH(netif) {
656 if (netif == inp) {
657 /* we checked that before already */
658 continue;
659 }
660 if (ip6_input_accept(netif)) {
661 break;
662 }
663 }
664#endif /* !LWIP_SINGLE_NETIF */
665 }
666netif_found:
667 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n",
668 netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X'));
669 }
670
671 /* "::" packet source address? (used in duplicate address detection) */
672 if (ip6_addr_isany(ip6_current_src_addr()) &&
673 (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) {
674 /* packet source is not valid */
675 /* free (drop) packet pbufs */
676 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n"));
677 pbuf_free(p);
678 IP6_STATS_INC(ip6.drop);
679 goto ip6_input_cleanup;
680 }
681
682 /* packet not for us? */
683 if (netif == NULL) {
684 /* packet not for us, route or discard */
685 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_TRACE, ("ip6_input: packet not for us.\n"));
686#if LWIP_IPV6_FORWARD
687 /* non-multicast packet? */
688 if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
689 /* try to forward IP packet on (other) interfaces */
690 ip6_forward(p, ip6hdr, inp);
691 }
692#endif /* LWIP_IPV6_FORWARD */
693 pbuf_free(p);
694 goto ip6_input_cleanup;
695 }
696
697 /* current netif pointer. */
698 ip_data.current_netif = netif;
699
700 /* Save next header type. */
701 nexth = &IP6H_NEXTH(ip6hdr);
702
703 /* Init header length. */
704 hlen = hlen_tot = IP6_HLEN;
705
706 /* Move to payload. */
707 pbuf_remove_header(p, IP6_HLEN);
708
709 /* Process known option extension headers, if present. */
710 while (*nexth != IP6_NEXTH_NONE)
711 {
712 switch (*nexth) {
713 case IP6_NEXTH_HOPBYHOP:
714 {
715 s32_t opt_offset;
716 struct ip6_hbh_hdr *hbh_hdr;
717 struct ip6_opt_hdr *opt_hdr;
718 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n"));
719
720 /* Get and check the header length, while staying in packet bounds. */
721 hbh_hdr = (struct ip6_hbh_hdr *)p->payload;
722
723 /* Get next header type. */
724 nexth = &IP6_HBH_NEXTH(hbh_hdr);
725
726 /* Get the header length. */
727 hlen = (u16_t)(8 * (1 + hbh_hdr->_hlen));
728
729 if ((p->len < 8) || (hlen > p->len)) {
730 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
731 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
732 hlen, p->len));
733 /* free (drop) packet pbufs */
734 pbuf_free(p);
735 IP6_STATS_INC(ip6.lenerr);
736 IP6_STATS_INC(ip6.drop);
737 goto ip6_input_cleanup;
738 }
739
740 hlen_tot = (u16_t)(hlen_tot + hlen);
741
742 /* The extended option header starts right after Hop-by-Hop header. */
743 opt_offset = IP6_HBH_HLEN;
744 while (opt_offset < hlen)
745 {
746 s32_t opt_dlen = 0;
747
748 opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + opt_offset);
749
750 switch (IP6_OPT_TYPE(opt_hdr)) {
751 /* @todo: process IPV6 Hop-by-Hop option data */
752 case IP6_PAD1_OPTION:
753 /* PAD1 option doesn't have length and value field */
754 opt_dlen = -1;
755 break;
756 case IP6_PADN_OPTION:
757 opt_dlen = IP6_OPT_DLEN(opt_hdr);
758 break;
759 case IP6_ROUTER_ALERT_OPTION:
760 opt_dlen = IP6_OPT_DLEN(opt_hdr);
761 break;
762 case IP6_JUMBO_OPTION:
763 opt_dlen = IP6_OPT_DLEN(opt_hdr);
764 break;
765 default:
766 /* Check 2 MSB of Hop-by-Hop header type. */
767 switch (IP6_OPT_TYPE_ACTION(opt_hdr)) {
768 case 1:
769 /* Discard the packet. */
770 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n"));
771 pbuf_free(p);
772 IP6_STATS_INC(ip6.drop);
773 goto ip6_input_cleanup;
774 case 2:
775 /* Send ICMP Parameter Problem */
776 icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr);
777 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n"));
778 pbuf_free(p);
779 IP6_STATS_INC(ip6.drop);
780 goto ip6_input_cleanup;
781 case 3:
782 /* Send ICMP Parameter Problem if destination address is not a multicast address */
783 if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
784 icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr);
785 }
786 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n"));
787 pbuf_free(p);
788 IP6_STATS_INC(ip6.drop);
789 goto ip6_input_cleanup;
790 default:
791 /* Skip over this option. */
792 opt_dlen = IP6_OPT_DLEN(opt_hdr);
793 break;
794 }
795 break;
796 }
797
798 /* Adjust the offset to move to the next extended option header */
799 opt_offset = opt_offset + IP6_OPT_HLEN + opt_dlen;
800 }
801 pbuf_remove_header(p, hlen);
802 break;
803 }
804 case IP6_NEXTH_DESTOPTS:
805 {
806 s32_t opt_offset;
807 struct ip6_dest_hdr *dest_hdr;
808 struct ip6_opt_hdr *opt_hdr;
809 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Destination options header\n"));
810
811 dest_hdr = (struct ip6_dest_hdr *)p->payload;
812
813 /* Get next header type. */
814 nexth = &IP6_DEST_NEXTH(dest_hdr);
815
816 /* Get the header length. */
817 hlen = 8 * (1 + dest_hdr->_hlen);
818 if ((p->len < 8) || (hlen > p->len)) {
819 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
820 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
821 hlen, p->len));
822 /* free (drop) packet pbufs */
823 pbuf_free(p);
824 IP6_STATS_INC(ip6.lenerr);
825 IP6_STATS_INC(ip6.drop);
826 goto ip6_input_cleanup;
827 }
828
829 hlen_tot = (u16_t)(hlen_tot + hlen);
830
831 /* The extended option header starts right after Destination header. */
832 opt_offset = IP6_DEST_HLEN;
833 while (opt_offset < hlen)
834 {
835 s32_t opt_dlen = 0;
836
837 opt_hdr = (struct ip6_opt_hdr *)((u8_t *)dest_hdr + opt_offset);
838
839 switch (IP6_OPT_TYPE(opt_hdr))
840 {
841 /* @todo: process IPV6 Destination option data */
842 case IP6_PAD1_OPTION:
843 /* PAD1 option deosn't have length and value field */
844 opt_dlen = -1;
845 break;
846 case IP6_PADN_OPTION:
847 opt_dlen = IP6_OPT_DLEN(opt_hdr);
848 break;
849 case IP6_ROUTER_ALERT_OPTION:
850 opt_dlen = IP6_OPT_DLEN(opt_hdr);
851 break;
852 case IP6_JUMBO_OPTION:
853 opt_dlen = IP6_OPT_DLEN(opt_hdr);
854 break;
855 case IP6_HOME_ADDRESS_OPTION:
856 opt_dlen = IP6_OPT_DLEN(opt_hdr);
857 break;
858 default:
859 /* Check 2 MSB of Destination header type. */
860 switch (IP6_OPT_TYPE_ACTION(opt_hdr))
861 {
862 case 1:
863 /* Discard the packet. */
864 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid destination option type dropped.\n"));
865 pbuf_free(p);
866 IP6_STATS_INC(ip6.drop);
867 goto ip6_input_cleanup;
868 case 2:
869 /* Send ICMP Parameter Problem */
870 icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr);
871 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid destination option type dropped.\n"));
872 pbuf_free(p);
873 IP6_STATS_INC(ip6.drop);
874 goto ip6_input_cleanup;
875 case 3:
876 /* Send ICMP Parameter Problem if destination address is not a multicast address */
877 if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
878 icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr);
879 }
880 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid destination option type dropped.\n"));
881 pbuf_free(p);
882 IP6_STATS_INC(ip6.drop);
883 goto ip6_input_cleanup;
884 default:
885 /* Skip over this option. */
886 opt_dlen = IP6_OPT_DLEN(opt_hdr);
887 break;
888 }
889 break;
890 }
891
892 /* Adjust the offset to move to the next extended option header */
893 opt_offset = opt_offset + IP6_OPT_HLEN + opt_dlen;
894 }
895
896 pbuf_remove_header(p, hlen);
897 break;
898 }
899 case IP6_NEXTH_ROUTING:
900 {
901 struct ip6_rout_hdr *rout_hdr;
902 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n"));
903
904 rout_hdr = (struct ip6_rout_hdr *)p->payload;
905
906 /* Get next header type. */
907 nexth = &IP6_ROUT_NEXTH(rout_hdr);
908
909 /* Get the header length. */
910 hlen = 8 * (1 + rout_hdr->_hlen);
911
912 if ((p->len < 8) || (hlen > p->len)) {
913 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
914 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
915 hlen, p->len));
916 /* free (drop) packet pbufs */
917 pbuf_free(p);
918 IP6_STATS_INC(ip6.lenerr);
919 IP6_STATS_INC(ip6.drop);
920 goto ip6_input_cleanup;
921 }
922
923 /* Skip over this header. */
924 hlen_tot = (u16_t)(hlen_tot + hlen);
925
926 /* if segment left value is 0 in routing header, ignore the option */
927 if (IP6_ROUT_SEG_LEFT(rout_hdr)) {
928 /* The length field of routing option header must be even */
929 if (rout_hdr->_hlen & 0x1) {
930 /* Discard and send parameter field error */
931 icmp6_param_problem(p, ICMP6_PP_FIELD, &rout_hdr->_hlen);
932 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid routing type dropped\n"));
933 pbuf_free(p);
934 IP6_STATS_INC(ip6.drop);
935 goto ip6_input_cleanup;
936 }
937
938 switch (IP6_ROUT_TYPE(rout_hdr))
939 {
940 /* TODO: process routing by the type */
941 case IP6_ROUT_TYPE2:
942 break;
943 case IP6_ROUT_RPL:
944 break;
945 default:
946 /* Discard unrecognized routing type and send parameter field error */
947 icmp6_param_problem(p, ICMP6_PP_FIELD, &IP6_ROUT_TYPE(rout_hdr));
948 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid routing type dropped\n"));
949 pbuf_free(p);
950 IP6_STATS_INC(ip6.drop);
951 goto ip6_input_cleanup;
952 }
953 }
954
955 pbuf_remove_header(p, hlen);
956 break;
957 }
958 case IP6_NEXTH_FRAGMENT:
959 {
960 struct ip6_frag_hdr *frag_hdr;
961 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n"));
962
963 frag_hdr = (struct ip6_frag_hdr *)p->payload;
964
965 /* Get next header type. */
966 nexth = &IP6_FRAG_NEXTH(frag_hdr);
967
968 /* Fragment Header length. */
969 hlen = 8;
970
971 /* Make sure this header fits in current pbuf. */
972 if (hlen > p->len) {
973 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
974 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
975 hlen, p->len));
976 /* free (drop) packet pbufs */
977 pbuf_free(p);
978 IP6_FRAG_STATS_INC(ip6_frag.lenerr);
979 IP6_FRAG_STATS_INC(ip6_frag.drop);
980 goto ip6_input_cleanup;
981 }
982
983 hlen_tot = (u16_t)(hlen_tot + hlen);
984
985 /* check payload length is multiple of 8 octets when mbit is set */
986 if (IP6_FRAG_MBIT(frag_hdr) && (IP6H_PLEN(ip6hdr) & 0x7)) {
987 /* ipv6 payload length is not multiple of 8 octets */
988 icmp6_param_problem(p, ICMP6_PP_FIELD, LWIP_PACKED_CAST(const void *, &ip6hdr->_plen));
989 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid payload length dropped\n"));
990 pbuf_free(p);
991 IP6_STATS_INC(ip6.drop);
992 goto ip6_input_cleanup;
993 }
994
995 /* Offset == 0 and more_fragments == 0? */
996 if ((frag_hdr->_fragment_offset &
997 PP_HTONS(IP6_FRAG_OFFSET_MASK | IP6_FRAG_MORE_FLAG)) == 0) {
998 /* This is a 1-fragment packet. Skip this header and continue. */
999 pbuf_remove_header(p, hlen);
1000 } else {
1001#if LWIP_IPV6_REASS
1002 /* reassemble the packet */
1003 ip_data.current_ip_header_tot_len = hlen_tot;
1004 p = ip6_reass(p);
1005 /* packet not fully reassembled yet? */
1006 if (p == NULL) {
1007 goto ip6_input_cleanup;
1008 }
1009
1010 /* Returned p point to IPv6 header.
1011 * Update all our variables and pointers and continue. */
1012 ip6hdr = (struct ip6_hdr *)p->payload;
1013 nexth = &IP6H_NEXTH(ip6hdr);
1014 hlen = hlen_tot = IP6_HLEN;
1015 pbuf_remove_header(p, IP6_HLEN);
1016
1017#else /* LWIP_IPV6_REASS */
1018 /* free (drop) packet pbufs */
1019 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header dropped (with LWIP_IPV6_REASS==0)\n"));
1020 pbuf_free(p);
1021 IP6_STATS_INC(ip6.opterr);
1022 IP6_STATS_INC(ip6.drop);
1023 goto ip6_input_cleanup;
1024#endif /* LWIP_IPV6_REASS */
1025 }
1026 break;
1027 }
1028 default:
1029 goto options_done;
1030 }
1031
1032 if (*nexth == IP6_NEXTH_HOPBYHOP) {
1033 /* Hop-by-Hop header comes only as a first option */
1034 icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
1035 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header dropped (only valid as a first option)\n"));
1036 pbuf_free(p);
1037 IP6_STATS_INC(ip6.drop);
1038 goto ip6_input_cleanup;
1039 }
1040 }
1041
1042options_done:
1043
1044 /* send to upper layers */
1045 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n"));
1046 ip6_debug_print(p);
1047 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
1048
1049 ip_data.current_ip_header_tot_len = hlen_tot;
1050
1051#if LWIP_RAW
1052 /* p points to IPv6 header again for raw_input. */
1053 pbuf_add_header_force(p, hlen_tot);
1054 /* raw input did not eat the packet? */
1055 raw_status = raw_input(p, inp);
1056 if (raw_status != RAW_INPUT_EATEN)
1057 {
1058 /* Point to payload. */
1059 pbuf_remove_header(p, hlen_tot);
1060#else /* LWIP_RAW */
1061 {
1062#endif /* LWIP_RAW */
1063 switch (*nexth) {
1064 case IP6_NEXTH_NONE:
1065 pbuf_free(p);
1066 break;
1067#if LWIP_UDP
1068 case IP6_NEXTH_UDP:
1069#if LWIP_UDPLITE
1070 case IP6_NEXTH_UDPLITE:
1071#endif /* LWIP_UDPLITE */
1072 udp_input(p, inp);
1073 break;
1074#endif /* LWIP_UDP */
1075#if LWIP_TCP
1076 case IP6_NEXTH_TCP:
1077 tcp_input(p, inp);
1078 break;
1079#endif /* LWIP_TCP */
1080#if LWIP_ICMP6
1081 case IP6_NEXTH_ICMP6:
1082 icmp6_input(p, inp);
1083 break;
1084#endif /* LWIP_ICMP */
1085 default:
1086#if LWIP_RAW
1087 if (raw_status == RAW_INPUT_DELIVERED) {
1088 /* @todo: ipv6 mib in-delivers? */
1089 } else
1090#endif /* LWIP_RAW */
1091 {
1092#if LWIP_ICMP6
1093 /* p points to IPv6 header again for raw_input. */
1094 pbuf_add_header_force(p, hlen_tot);
1095 /* send ICMP parameter problem unless it was a multicast or ICMPv6 */
1096 if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) &&
1097 (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
1098 icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
1099 }
1100#endif /* LWIP_ICMP */
1101 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr)));
1102 IP6_STATS_INC(ip6.proterr);
1103 IP6_STATS_INC(ip6.drop);
1104 }
1105 pbuf_free(p);
1106 break;
1107 }
1108 }
1109
1110ip6_input_cleanup:
1111 ip_data.current_netif = NULL;
1112 ip_data.current_input_netif = NULL;
1113 ip_data.current_ip6_header = NULL;
1114 ip_data.current_ip_header_tot_len = 0;
1115 ip6_addr_set_zero(ip6_current_src_addr());
1116 ip6_addr_set_zero(ip6_current_dest_addr());
1117
1118 return ERR_OK;
1119}
1120
1121
1122/**
1123 * Sends an IPv6 packet on a network interface. This function constructs
1124 * the IPv6 header. If the source IPv6 address is NULL, the IPv6 "ANY" address is
1125 * used as source (usually during network startup). If the source IPv6 address it
1126 * IP6_ADDR_ANY, the most appropriate IPv6 address of the outgoing network
1127 * interface is filled in as source address. If the destination IPv6 address is
1128 * LWIP_IP_HDRINCL, p is assumed to already include an IPv6 header and
1129 * p->payload points to it instead of the data.
1130 *
1131 * @param p the packet to send (p->payload points to the data, e.g. next
1132 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
1133 IPv6 header and p->payload points to that IPv6 header)
1134 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
1135 * IP address of the netif is selected and used as source address.
1136 * if src == NULL, IP6_ADDR_ANY is used as source) (src is possibly not
1137 * properly zoned)
1138 * @param dest the destination IPv6 address to send the packet to (possibly not
1139 * properly zoned)
1140 * @param hl the Hop Limit value to be set in the IPv6 header
1141 * @param tc the Traffic Class value to be set in the IPv6 header
1142 * @param nexth the Next Header to be set in the IPv6 header
1143 * @param netif the netif on which to send this packet
1144 * @return ERR_OK if the packet was sent OK
1145 * ERR_BUF if p doesn't have enough space for IPv6/LINK headers
1146 * returns errors returned by netif->output_ip6
1147 */
1148err_t
1149ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
1150 u8_t hl, u8_t tc,
1151 u8_t nexth, struct netif *netif)
1152{
1153 const ip6_addr_t *src_used = src;
1154 if (dest != LWIP_IP_HDRINCL) {
1155 if (src != NULL && ip6_addr_isany(src)) {
1156 src_used = ip_2_ip6(ip6_select_source_address(netif, dest));
1157 if ((src_used == NULL) || ip6_addr_isany(src_used)) {
1158 /* No appropriate source address was found for this packet. */
1159 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n"));
1160 IP6_STATS_INC(ip6.rterr);
1161 return ERR_RTE;
1162 }
1163 }
1164 }
1165 return ip6_output_if_src(p, src_used, dest, hl, tc, nexth, netif);
1166}
1167
1168/**
1169 * Same as ip6_output_if() but 'src' address is not replaced by netif address
1170 * when it is 'any'.
1171 */
1172err_t
1173ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
1174 u8_t hl, u8_t tc,
1175 u8_t nexth, struct netif *netif)
1176{
1177 struct ip6_hdr *ip6hdr;
1178 ip6_addr_t dest_addr;
1179
1180 LWIP_ASSERT_CORE_LOCKED();
1181 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
1182
1183 /* Should the IPv6 header be generated or is it already included in p? */
1184 if (dest != LWIP_IP_HDRINCL) {
1185#if LWIP_IPV6_SCOPES
1186 /* If the destination address is scoped but lacks a zone, add a zone now,
1187 * based on the outgoing interface. The lower layers (e.g., nd6) absolutely
1188 * require addresses to be properly zoned for correctness. In some cases,
1189 * earlier attempts will have been made to add a zone to the destination,
1190 * but this function is the only one that is called in all (other) cases,
1191 * so we must do this here. */
1192 if (ip6_addr_lacks_zone(dest, IP6_UNKNOWN)) {
1193 ip6_addr_copy(dest_addr, *dest);
1194 ip6_addr_assign_zone(&dest_addr, IP6_UNKNOWN, netif);
1195 dest = &dest_addr;
1196 }
1197#endif /* LWIP_IPV6_SCOPES */
1198
1199 /* generate IPv6 header */
1200 if (pbuf_add_header(p, IP6_HLEN)) {
1201 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n"));
1202 IP6_STATS_INC(ip6.err);
1203 return ERR_BUF;
1204 }
1205
1206 ip6hdr = (struct ip6_hdr *)p->payload;
1207 LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr",
1208 (p->len >= sizeof(struct ip6_hdr)));
1209
1210 IP6H_HOPLIM_SET(ip6hdr, hl);
1211 IP6H_NEXTH_SET(ip6hdr, nexth);
1212
1213 /* dest cannot be NULL here */
1214 ip6_addr_copy_to_packed(ip6hdr->dest, *dest);
1215
1216 IP6H_VTCFL_SET(ip6hdr, 6, tc, 0);
1217 IP6H_PLEN_SET(ip6hdr, (u16_t)(p->tot_len - IP6_HLEN));
1218
1219 if (src == NULL) {
1220 src = IP6_ADDR_ANY6;
1221 }
1222 /* src cannot be NULL here */
1223 ip6_addr_copy_to_packed(ip6hdr->src, *src);
1224
1225 } else {
1226 /* IP header already included in p */
1227 ip6hdr = (struct ip6_hdr *)p->payload;
1228 ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
1229 ip6_addr_assign_zone(&dest_addr, IP6_UNKNOWN, netif);
1230 dest = &dest_addr;
1231 }
1232
1233 IP6_STATS_INC(ip6.xmit);
1234
1235 LWIP_DEBUGF(IP6_DEBUG, ("ip6_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num));
1236 ip6_debug_print(p);
1237
1238#if ENABLE_LOOPBACK
1239 {
1240 int i;
1241#if !LWIP_HAVE_LOOPIF
1242 if (ip6_addr_isloopback(dest)) {
1243 return netif_loop_output(netif, p);
1244 }
1245#endif /* !LWIP_HAVE_LOOPIF */
1246 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
1247 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
1248 ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) {
1249 /* Packet to self, enqueue it for loopback */
1250 LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n"));
1251 return netif_loop_output(netif, p);
1252 }
1253 }
1254 }
1255#if LWIP_MULTICAST_TX_OPTIONS
1256 if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
1257 netif_loop_output(netif, p);
1258 }
1259#endif /* LWIP_MULTICAST_TX_OPTIONS */
1260#endif /* ENABLE_LOOPBACK */
1261#if LWIP_IPV6_FRAG
1262 /* don't fragment if interface has mtu set to 0 [loopif] */
1263 if (netif_mtu6(netif) && (p->tot_len > nd6_get_destination_mtu(dest, netif))) {
1264 return ip6_frag(p, netif, dest);
1265 }
1266#endif /* LWIP_IPV6_FRAG */
1267
1268 LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n"));
1269 return netif->output_ip6(netif, p, dest);
1270}
1271
1272/**
1273 * Simple interface to ip6_output_if. It finds the outgoing network
1274 * interface and calls upon ip6_output_if to do the actual work.
1275 *
1276 * @param p the packet to send (p->payload points to the data, e.g. next
1277 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
1278 IPv6 header and p->payload points to that IPv6 header)
1279 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
1280 * IP address of the netif is selected and used as source address.
1281 * if src == NULL, IP6_ADDR_ANY is used as source)
1282 * @param dest the destination IPv6 address to send the packet to
1283 * @param hl the Hop Limit value to be set in the IPv6 header
1284 * @param tc the Traffic Class value to be set in the IPv6 header
1285 * @param nexth the Next Header to be set in the IPv6 header
1286 *
1287 * @return ERR_RTE if no route is found
1288 * see ip_output_if() for more return values
1289 */
1290err_t
1291ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
1292 u8_t hl, u8_t tc, u8_t nexth)
1293{
1294 struct netif *netif;
1295 struct ip6_hdr *ip6hdr;
1296 ip6_addr_t src_addr, dest_addr;
1297
1298 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
1299
1300 if (dest != LWIP_IP_HDRINCL) {
1301 netif = ip6_route(src, dest);
1302 } else {
1303 /* IP header included in p, read addresses. */
1304 ip6hdr = (struct ip6_hdr *)p->payload;
1305 ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
1306 ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
1307 netif = ip6_route(&src_addr, &dest_addr);
1308 }
1309
1310 if (netif == NULL) {
1311 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",
1312 IP6_ADDR_BLOCK1(dest),
1313 IP6_ADDR_BLOCK2(dest),
1314 IP6_ADDR_BLOCK3(dest),
1315 IP6_ADDR_BLOCK4(dest),
1316 IP6_ADDR_BLOCK5(dest),
1317 IP6_ADDR_BLOCK6(dest),
1318 IP6_ADDR_BLOCK7(dest),
1319 IP6_ADDR_BLOCK8(dest)));
1320 IP6_STATS_INC(ip6.rterr);
1321 return ERR_RTE;
1322 }
1323
1324 return ip6_output_if(p, src, dest, hl, tc, nexth, netif);
1325}
1326
1327
1328#if LWIP_NETIF_USE_HINTS
1329/** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint
1330 * before calling ip6_output_if.
1331 *
1332 * @param p the packet to send (p->payload points to the data, e.g. next
1333 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
1334 IPv6 header and p->payload points to that IPv6 header)
1335 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
1336 * IP address of the netif is selected and used as source address.
1337 * if src == NULL, IP6_ADDR_ANY is used as source)
1338 * @param dest the destination IPv6 address to send the packet to
1339 * @param hl the Hop Limit value to be set in the IPv6 header
1340 * @param tc the Traffic Class value to be set in the IPv6 header
1341 * @param nexth the Next Header to be set in the IPv6 header
1342 * @param netif_hint netif output hint pointer set to netif->hint before
1343 * calling ip_output_if()
1344 *
1345 * @return ERR_RTE if no route is found
1346 * see ip_output_if() for more return values
1347 */
1348err_t
1349ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
1350 u8_t hl, u8_t tc, u8_t nexth, struct netif_hint *netif_hint)
1351{
1352 struct netif *netif;
1353 struct ip6_hdr *ip6hdr;
1354 ip6_addr_t src_addr, dest_addr;
1355 err_t err;
1356
1357 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
1358
1359 if (dest != LWIP_IP_HDRINCL) {
1360 netif = ip6_route(src, dest);
1361 } else {
1362 /* IP header included in p, read addresses. */
1363 ip6hdr = (struct ip6_hdr *)p->payload;
1364 ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
1365 ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
1366 netif = ip6_route(&src_addr, &dest_addr);
1367 }
1368
1369 if (netif == NULL) {
1370 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",
1371 IP6_ADDR_BLOCK1(dest),
1372 IP6_ADDR_BLOCK2(dest),
1373 IP6_ADDR_BLOCK3(dest),
1374 IP6_ADDR_BLOCK4(dest),
1375 IP6_ADDR_BLOCK5(dest),
1376 IP6_ADDR_BLOCK6(dest),
1377 IP6_ADDR_BLOCK7(dest),
1378 IP6_ADDR_BLOCK8(dest)));
1379 IP6_STATS_INC(ip6.rterr);
1380 return ERR_RTE;
1381 }
1382
1383 NETIF_SET_HINTS(netif, netif_hint);
1384 err = ip6_output_if(p, src, dest, hl, tc, nexth, netif);
1385 NETIF_RESET_HINTS(netif);
1386
1387 return err;
1388}
1389#endif /* LWIP_NETIF_USE_HINTS*/
1390
1391#if LWIP_IPV6_MLD
1392/**
1393 * Add a hop-by-hop options header with a router alert option and padding.
1394 *
1395 * Used by MLD when sending a Multicast listener report/done message.
1396 *
1397 * @param p the packet to which we will prepend the options header
1398 * @param nexth the next header protocol number (e.g. IP6_NEXTH_ICMP6)
1399 * @param value the value of the router alert option data (e.g. IP6_ROUTER_ALERT_VALUE_MLD)
1400 * @return ERR_OK if hop-by-hop header was added, ERR_* otherwise
1401 */
1402err_t
1403ip6_options_add_hbh_ra(struct pbuf *p, u8_t nexth, u8_t value)
1404{
1405 u8_t *opt_data;
1406 u32_t offset = 0;
1407 struct ip6_hbh_hdr *hbh_hdr;
1408 struct ip6_opt_hdr *opt_hdr;
1409
1410 /* fixed 4 bytes for router alert option and 2 bytes padding */
1411 const u8_t hlen = (sizeof(struct ip6_opt_hdr) * 2) + IP6_ROUTER_ALERT_DLEN;
1412 /* Move pointer to make room for hop-by-hop options header. */
1413 if (pbuf_add_header(p, sizeof(struct ip6_hbh_hdr) + hlen)) {
1414 LWIP_DEBUGF(IP6_DEBUG, ("ip6_options: no space for options header\n"));
1415 IP6_STATS_INC(ip6.err);
1416 return ERR_BUF;
1417 }
1418
1419 /* Set fields of Hop-by-Hop header */
1420 hbh_hdr = (struct ip6_hbh_hdr *)p->payload;
1421 IP6_HBH_NEXTH(hbh_hdr) = nexth;
1422 hbh_hdr->_hlen = 0;
1423 offset = IP6_HBH_HLEN;
1424
1425 /* Set router alert options to Hop-by-Hop extended option header */
1426 opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + offset);
1427 IP6_OPT_TYPE(opt_hdr) = IP6_ROUTER_ALERT_OPTION;
1428 IP6_OPT_DLEN(opt_hdr) = IP6_ROUTER_ALERT_DLEN;
1429 offset += IP6_OPT_HLEN;
1430
1431 /* Set router alert option data */
1432 opt_data = (u8_t *)hbh_hdr + offset;
1433 opt_data[0] = value;
1434 opt_data[1] = 0;
1435 offset += IP6_OPT_DLEN(opt_hdr);
1436
1437 /* add 2 bytes padding to make 8 bytes Hop-by-Hop header length */
1438 opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + offset);
1439 IP6_OPT_TYPE(opt_hdr) = IP6_PADN_OPTION;
1440 IP6_OPT_DLEN(opt_hdr) = 0;
1441
1442 return ERR_OK;
1443}
1444#endif /* LWIP_IPV6_MLD */
1445
1446#if IP6_DEBUG
1447/* Print an IPv6 header by using LWIP_DEBUGF
1448 * @param p an IPv6 packet, p->payload pointing to the IPv6 header
1449 */
1450void
1451ip6_debug_print(struct pbuf *p)
1452{
1453 struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload;
1454
1455 LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n"));
1456 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1457 LWIP_DEBUGF(IP6_DEBUG, ("| %2"U16_F" | %3"U16_F" | %7"U32_F" | (ver, class, flow)\n",
1458 IP6H_V(ip6hdr),
1459 IP6H_TC(ip6hdr),
1460 IP6H_FL(ip6hdr)));
1461 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1462 LWIP_DEBUGF(IP6_DEBUG, ("| %5"U16_F" | %3"U16_F" | %3"U16_F" | (plen, nexth, hopl)\n",
1463 IP6H_PLEN(ip6hdr),
1464 IP6H_NEXTH(ip6hdr),
1465 IP6H_HOPLIM(ip6hdr)));
1466 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1467 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (src)\n",
1468 IP6_ADDR_BLOCK1(&(ip6hdr->src)),
1469 IP6_ADDR_BLOCK2(&(ip6hdr->src)),
1470 IP6_ADDR_BLOCK3(&(ip6hdr->src)),
1471 IP6_ADDR_BLOCK4(&(ip6hdr->src))));
1472 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n",
1473 IP6_ADDR_BLOCK5(&(ip6hdr->src)),
1474 IP6_ADDR_BLOCK6(&(ip6hdr->src)),
1475 IP6_ADDR_BLOCK7(&(ip6hdr->src)),
1476 IP6_ADDR_BLOCK8(&(ip6hdr->src))));
1477 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1478 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (dest)\n",
1479 IP6_ADDR_BLOCK1(&(ip6hdr->dest)),
1480 IP6_ADDR_BLOCK2(&(ip6hdr->dest)),
1481 IP6_ADDR_BLOCK3(&(ip6hdr->dest)),
1482 IP6_ADDR_BLOCK4(&(ip6hdr->dest))));
1483 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n",
1484 IP6_ADDR_BLOCK5(&(ip6hdr->dest)),
1485 IP6_ADDR_BLOCK6(&(ip6hdr->dest)),
1486 IP6_ADDR_BLOCK7(&(ip6hdr->dest)),
1487 IP6_ADDR_BLOCK8(&(ip6hdr->dest))));
1488 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1489}
1490#endif /* IP6_DEBUG */
1491
1492#endif /* LWIP_IPV6 */
Note: See TracBrowser for help on using the repository browser.