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 #if LWIP_NAT64
64 #include "lwip/nat64.h"
65 #endif
66
67 #if LWIP_RIPPLE
68 #include "lwip/lwip_rpl.h"
69 #endif
70
71 #if LWIP_IP6IN4
72 #include "lwip/ip6in4.h"
73 #endif
74 #if LWIP_MPL
75 #include "mcast6.h"
76 #ifndef MCAST6_IS_FROM_CONN_PEER
77 #define MCAST6_IS_FROM_CONN_PEER mcast6_esmrf_from_conn_peer
78 #endif /* MCAST6_IS_FROM_CONN_PEER */
79
80 #ifndef MCAST6_FORWARD
81 #define MCAST6_FORWARD mcast6_esmrf_in
82 #endif /* MCAST6_FORWARD */
83 #endif /* LWIP_MPL */
84
85 #ifdef LWIP_HOOK_FILENAME
86 #include LWIP_HOOK_FILENAME
87 #endif
88
89 #if LWIP_IPV6_FILTER
90 /* This function is called when an ip packet received. The return value of this function will
91 * decide accept or drop a ip packet when LWIP_IPV6_FILTER is Enabled and ip_filter function has been set
92 */
93 static ip_filter_fn ip6_filter = NULL;
94 #endif /* LWIP_IPV6_FILTER */
95
96 #ifndef LWIP_RPI_LEN
97 #define LWIP_RPI_LEN 6
98 #endif
99
100 #if LWIP_RIPPLE
101 typedef struct {
102 u32_t route_up:1;
103 u32_t next_hop_nonmesh:1;
104 } pkt_rte_status;
105 static pkt_rte_status g_pkt_rte_stat;
106
107 int
lwip_get_pkt_route_status(void)108 lwip_get_pkt_route_status(void)
109 {
110 return (int)g_pkt_rte_stat.route_up;
111 }
112
113 void
lwip_set_pkt_route_status(int up)114 lwip_set_pkt_route_status(int up)
115 {
116 g_pkt_rte_stat.route_up = !!up;
117 }
118
119 int
lwip_get_rte_nexthop_nonmesh(void)120 lwip_get_rte_nexthop_nonmesh(void)
121 {
122 return (int)g_pkt_rte_stat.next_hop_nonmesh;
123 }
124
125 void
lwip_set_rte_nexthop_nonmesh(int stat)126 lwip_set_rte_nexthop_nonmesh(int stat)
127 {
128 g_pkt_rte_stat.next_hop_nonmesh = !!stat;
129 }
130
131 /*
132 * Hardcoded lenghth of HBH,
133 * providing function for future enhancement.
134 */
135 u16_t
lwip_hbh_len(struct pbuf * p)136 lwip_hbh_len(struct pbuf *p)
137 {
138 u16_t hbh_len = 0;
139 /* pbuf alloc will pass NULL as pbuf. */
140 if (p == NULL) {
141 /* 2: add for 8 byte Aligned */
142 hbh_len = IP6_HBH_HLEN + LWIP_RPI_LEN;
143 }
144
145 return hbh_len;
146 }
147
148 static err_t
ip6_process_hbh_exth_options(struct pbuf * p,const struct netif * iface)149 ip6_process_hbh_exth_options(struct pbuf *p, const struct netif *iface)
150 {
151 u16_t ext_len;
152 u16_t hbh_opt_offset = IP6_OPT_HLEN; /* skipping first 2 header bytes */
153 u16_t tmp_hbh_opt_offset; /* Used two iterator variables to check overflow. */
154 const struct ip6_hdr *ip6hdr = (struct ip6_hdr *)((char *)(p->payload) - IP6_HLEN); /* for accessing dest */
155
156 struct ip6_opt_hdr *opt_tlv = NULL;
157 struct ip6_hbh_hdr *ext_hdr = (struct ip6_hbh_hdr *)(p->payload);
158 (void)iface;
159
160 LWIP_DEBUGF(IP6_DEBUG, ("Next header is [%x]\n", IP6H_NEXTH(ip6hdr)));
161 if (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_HOPBYHOP) {
162 return 0;
163 }
164
165 LWIP_DEBUGF(IP6_DEBUG, ("nexth %u, hlen %u\n", ext_hdr->_nexth, ext_hdr->_hlen));
166 #if LWIP_RIPPLE
167 /* do not handle non mesh interface packet. */
168 if (lwip_rpl_is_rpl_netif(iface) == lwIP_FALSE) {
169 return ERR_OK;
170 }
171 #endif
172 if (p->len < IP6_HBH_HLEN) {
173 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
174 ("IP6_NEXTH_HOPBYHOP: pbuf (len %"U16_F") is less than 2.\n", p->len));
175 /* free (drop) packet pbufs */
176 IP6_STATS_INC(ip6.lenerr);
177 return -1;
178 }
179
180 /*
181 * max value can be stored in hbh_ext_len(8 bits) is 255
182 * so max value after multilication and addition will be
183 * ((255 * 8) + 8) : 2048 and local variable u16_t ext_len can
184 * store 65535 implies -> No Overflow.
185 */
186 /* hbh hlen is saved in units of octets excluding first octet. */
187 ext_len = (ext_hdr->_hlen << 3) + 8;
188
189 /* Validate the received IP packet length gainst the hbh total length */
190 if (ext_len > p->len) {
191 LWIP_ERROR("Received malformed packet\n", 0, return -1);
192 }
193
194 while (hbh_opt_offset < ext_len) {
195 opt_tlv = (struct ip6_opt_hdr *)((char *)(p->payload) + hbh_opt_offset);
196 switch (opt_tlv->_opt_type) {
197 case LWIP_EXT_HDR_OPT_PAD1:
198 LWIP_DEBUGF(IP6_DEBUG, ("processing PAD1 option\n"));
199 tmp_hbh_opt_offset = hbh_opt_offset + 1;
200 LWIP_ERROR("overflow occured in ext len\n", tmp_hbh_opt_offset > hbh_opt_offset, return -1);
201 hbh_opt_offset = tmp_hbh_opt_offset;
202
203 break;
204 case LWIP_EXT_HDR_OPT_PADN:
205 LWIP_DEBUGF(IP6_DEBUG, ("processing PADN option\n"));
206 tmp_hbh_opt_offset = (u16_t)(hbh_opt_offset + IP6_HBH_HLEN + opt_tlv->_opt_dlen);
207 LWIP_ERROR("overflow occured in ext len\n", tmp_hbh_opt_offset > hbh_opt_offset, return -1);
208 hbh_opt_offset = tmp_hbh_opt_offset;
209 break;
210 case LWIP_RPL_RPI_TYPE_NEW:
211 case LWIP_RPL_RPI_TYPE_OLD:
212 /*
213 * Fixes situation when a node that is not using RPL
214 * joins a network which does. The received packages will include the
215 * RPL header and processed by the "default" case of the switch
216 * (0x63 & 0xC0 = 0x40). Hence, the packet is discarded as the header
217 * is considered invalid.
218 * Using this fix, the header is ignored, and the next header (if
219 * present) is processed.
220 */
221 #if LWIP_RIPPLE
222 LWIP_DEBUGF(IP6_DEBUG, ("Processing RPL opt\n"));
223 if (lwip_verify_rplext_header((void *)p, hbh_opt_offset)) {
224 LWIP_ERROR("RPL Opt Error: Dropping Pkt\n", 0, ;);
225 return -1;
226 }
227 #endif
228 tmp_hbh_opt_offset = (u16_t)(hbh_opt_offset + IP6_HBH_HLEN + opt_tlv->_opt_dlen);
229 LWIP_ERROR("overflow occured in ext len\n", tmp_hbh_opt_offset > hbh_opt_offset, return -1);
230 hbh_opt_offset = tmp_hbh_opt_offset;
231 p->flags |= PBUF_FLAG_RPI;
232 /* Should we return or process rest of the options */
233 return 0;
234 default:
235 /*
236 * check the two highest order bits of the option
237 * - 00 skip over this option and continue processing the header.
238 * - 01 discard the packet.
239 * - 10 discard the packet and, regardless of whether or not the
240 * - packet's Destination Address was a multicast address, send an
241 * - ICMP Parameter Problem, Code 2, message to the packet's
242 * - Source Address, pointing to the unrecognized Option Type.
243 * - 11 discard the packet and, only if the packet's Destination
244 * - Address was not a multicast address, send an ICMP Parameter
245 * - Problem, Code 2, message to the packet's Source Address,
246 * - pointing to the unrecognized Option Type.
247 */
248 LWIP_DEBUGF(IP6_DEBUG, ("MSB %x\n", opt_tlv->_opt_type));
249 switch (opt_tlv->_opt_type & 0xC0) {
250 case 0:
251 break;
252 case 0x40:
253 return -1;
254 case 0xC0:
255 if (ip6_addr_ismulticast(&ip6hdr->dest)) {
256 return -1;
257 }
258 /* fall-through */
259 case 0x80:
260 icmp6_param_problem(p, ICMP6_PP_OPTION, opt_tlv);
261 return -1;
262 default:
263 break;
264 }
265
266 tmp_hbh_opt_offset = (u16_t)(hbh_opt_offset + IP6_HBH_HLEN + opt_tlv->_opt_dlen);
267 LWIP_ERROR("overflow occured in ext len\n", tmp_hbh_opt_offset > hbh_opt_offset, return -1);
268 hbh_opt_offset = tmp_hbh_opt_offset;
269 break;
270 }
271 }
272
273 return ERR_OK;
274 }
275
276 #ifdef LWIP_HOOK_IP6_ROUTE
277 static err_t
lwip_rpl_same_prefix(const ip6_addr_t * dest)278 lwip_rpl_same_prefix(const ip6_addr_t *dest)
279 {
280 ip6_addr_t prefix;
281 uint8_t len;
282 err_t ret;
283
284 ret = lwip_rpl_get_default_prefix(&prefix, &len);
285 if (ret != ERR_OK) {
286 return ERR_VAL;
287 }
288 /* now our prefix len is 64, this will be ok. */
289 if (memcmp(dest, &prefix, (len >> 3)) != 0) {
290 return ERR_VAL;
291 }
292 return ERR_OK;
293 }
294 #endif
295 #endif /* LWIP_RIPPLE */
296 /**
297 * Finds the appropriate network interface for a given IPv6 address. It tries to select
298 * a netif following a sequence of heuristics:
299 * 1) if there is only 1 netif, return it
300 * 2) if the destination is a zoned address, match its zone to a netif
301 * 3) if the either the source or destination address is a scoped address,
302 * match the source address's zone (if set) or address (if not) to a netif
303 * 4) tries to match the destination subnet to a configured address
304 * 5) tries to find a router-announced route
305 * 6) tries to match the (unscoped) source address to the netif
306 * 7) returns the default netif, if configured
307 *
308 * Note that each of the two given addresses may or may not be properly zoned.
309 *
310 * @param src the source IPv6 address, if known
311 * @param dest the destination IPv6 address for which to find the route
312 * @return the netif on which to send to reach dest
313 */
314 struct netif *
ip6_route(const ip6_addr_t * src,const ip6_addr_t * dest)315 ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
316 {
317 #if LWIP_SINGLE_NETIF
318 LWIP_UNUSED_ARG(src);
319 LWIP_UNUSED_ARG(dest);
320 #else /* LWIP_SINGLE_NETIF */
321 struct netif *netif;
322 s8_t i;
323
324 LWIP_ASSERT_CORE_LOCKED();
325
326 #if !LWIP_SO_DONTROUTE
327 /* If single netif configuration, fast return. */
328 if ((netif_list != NULL) && (netif_list->next == NULL)) {
329 if (!netif_is_up(netif_list) || !netif_is_link_up(netif_list) ||
330 (ip6_addr_has_zone(dest) && !ip6_addr_test_zone(dest, netif_list))) {
331 return NULL;
332 }
333 return netif_list;
334 }
335 #endif
336
337 #if LWIP_IPV6_SCOPES
338 /* Special processing for zoned destination addresses. This includes link-
339 * local unicast addresses and interface/link-local multicast addresses. Use
340 * the zone to find a matching netif. If the address is not zoned, then there
341 * is technically no "wrong" netif to choose, and we leave routing to other
342 * rules; in most cases this should be the scoped-source rule below. */
343 if (ip6_addr_has_zone(dest)) {
344 IP6_ADDR_ZONECHECK(dest);
345 /* Find a netif based on the zone. For custom mappings, one zone may map
346 * to multiple netifs, so find one that can actually send a packet. */
347 NETIF_FOREACH(netif) {
348 if (ip6_addr_test_zone(dest, netif) &&
349 netif_is_up(netif) && netif_is_link_up(netif)) {
350 NETIF_SET_SCOPE(netif, RT_SCOPE_LINK);
351 return netif;
352 }
353 }
354 /* No matching netif found. Do no try to route to a different netif,
355 * as that would be a zone violation, resulting in any packets sent to
356 * that netif being dropped on output. */
357 return NULL;
358 }
359 #endif /* LWIP_IPV6_SCOPES */
360
361 /* Special processing for scoped source and destination addresses. If we get
362 * here, the destination address does not have a zone, so either way we need
363 * to look at the source address, which may or may not have a zone. If it
364 * does, the zone is restrictive: there is (typically) only one matching
365 * netif for it, and we should avoid routing to any other netif as that would
366 * result in guaranteed zone violations. For scoped source addresses that do
367 * not have a zone, use (only) a netif that has that source address locally
368 * assigned. This case also applies to the loopback source address, which has
369 * an implied link-local scope. If only the destination address is scoped
370 * (but, again, not zoned), we still want to use only the source address to
371 * determine its zone because that's most likely what the user/application
372 * wants, regardless of whether the source address is scoped. Finally, some
373 * of this story also applies if scoping is disabled altogether. */
374 #if LWIP_IPV6_SCOPES
375 if (ip6_addr_has_scope(dest, IP6_UNKNOWN) ||
376 ip6_addr_has_scope(src, IP6_UNICAST) ||
377 #else /* LWIP_IPV6_SCOPES */
378 if (ip6_addr_islinklocal(dest) || ip6_addr_ismulticast_iflocal(dest) ||
379 ip6_addr_ismulticast_linklocal(dest) || ip6_addr_islinklocal(src) ||
380 #endif /* LWIP_IPV6_SCOPES */
381 ip6_addr_isloopback(src)) {
382 #if LWIP_IPV6_SCOPES
383 if (ip6_addr_has_zone(src)) {
384 /* Find a netif matching the source zone (relatively cheap). */
385 NETIF_FOREACH(netif) {
386 if (netif_is_up(netif) && netif_is_link_up(netif) &&
387 ip6_addr_test_zone(src, netif)) {
388 NETIF_SET_SCOPE(netif, RT_SCOPE_LINK);
389 return netif;
390 }
391 }
392 } else
393 #endif /* LWIP_IPV6_SCOPES */
394 {
395 if (ip6_addr_isany(src)) {
396 /* Use default netif, if Up. */
397 if (netif_default == NULL || !netif_is_up(netif_default) ||
398 !netif_is_link_up(netif_default)) {
399 return NULL;
400 }
401 return netif_default;
402 }
403 /* Find a netif matching the source address (relatively expensive). */
404 NETIF_FOREACH(netif) {
405 if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
406 continue;
407 }
408 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
409 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
410 ip6_addr_cmp_zoneless(src, netif_ip6_addr(netif, i))) {
411 NETIF_SET_SCOPE(netif, RT_SCOPE_HOST);
412 return netif;
413 }
414 }
415 }
416 }
417 /* Again, do not use any other netif in this case, as that could result in
418 * zone boundary violations. */
419 return NULL;
420 }
421
422 /* We come here only if neither source nor destination is scoped. */
423 IP6_ADDR_ZONECHECK(src);
424
425 #ifdef LWIP_HOOK_IP6_ROUTE
426 netif = LWIP_HOOK_IP6_ROUTE(src, dest);
427 if (netif != NULL) {
428 NETIF_SET_SCOPE(netif, RT_SCOPE_UNIVERSAL);
429 return netif;
430 }
431 #endif
432
433 #if LWIP_RIPPLE
434 u8_t dest_same_prefix = lwIP_FALSE;
435 if (lwip_rpl_same_prefix(dest) == ERR_OK) {
436 dest_same_prefix = lwIP_TRUE;
437 }
438
439 /* for the mbr node, first to check the default route */
440 netif = nd6_find_route(dest);
441 if ((netif != NULL) && netif_is_up(netif) && netif_is_link_up(netif) &&
442 (dest_same_prefix == lwIP_TRUE) && (lwip_rpl_is_br() == lwIP_TRUE) &&
443 (lwip_rpl_is_rpl_netif(netif) == lwIP_FALSE)) {
444 return netif;
445 }
446
447 if ((netif_default != NULL) && netif_is_up(netif_default) && netif_is_link_up(netif_default) &&
448 (dest_same_prefix == lwIP_TRUE) && (lwip_rpl_is_br() == lwIP_TRUE) &&
449 (lwip_rpl_is_rpl_netif(netif_default) == lwIP_FALSE)) {
450 return netif_default;
451 }
452 #endif /* LWIP_RIPPLE */
453
454
455 /* See if the destination subnet matches a configured address. In accordance
456 * with RFC 5942, dynamically configured addresses do not have an implied
457 * local subnet, and thus should be considered /128 assignments. However, as
458 * such, the destination address may still match a local address, and so we
459 * still need to check for exact matches here. By (lwIP) policy, statically
460 * configured addresses do always have an implied local /64 subnet. */
461 NETIF_FOREACH(netif) {
462 if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
463 continue;
464 }
465 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
466 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
467 ip6_addr_netcmp(dest, netif_ip6_addr(netif, i)) &&
468 (netif_ip6_addr_isstatic(netif, i) ||
469 ip6_addr_nethostcmp(dest, netif_ip6_addr(netif, i)))) {
470 NETIF_SET_SCOPE(netif, RT_SCOPE_UNIVERSAL);
471 return netif;
472 }
473 }
474 }
475
476 /* Get the netif for a suitable router-announced route. */
477 netif = nd6_find_route(dest);
478 if (netif != NULL) {
479 NETIF_SET_SCOPE(netif, RT_SCOPE_UNIVERSAL);
480 return netif;
481 }
482
483 /* Try with the netif that matches the source address. Given the earlier rule
484 * for scoped source addresses, this applies to unscoped addresses only. */
485 if (!ip6_addr_isany(src)) {
486 NETIF_FOREACH(netif) {
487 if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
488 continue;
489 }
490 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
491 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
492 ip6_addr_cmp(src, netif_ip6_addr(netif, i))) {
493 NETIF_SET_SCOPE(netif, RT_SCOPE_HOST);
494 return netif;
495 }
496 }
497 }
498 }
499
500 #if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
501 /* loopif is disabled, loopback traffic is passed through any netif */
502 if (ip6_addr_isloopback(dest)) {
503 /* don't check for link on loopback traffic */
504 if (netif_default != NULL && netif_is_up(netif_default)) {
505 #if LWIP_SO_DONTROUTE
506 netif_default->scope = RT_SCOPE_HOST;
507 #endif
508 return netif_default;
509 }
510 /* default netif is not up, just use any netif for loopback traffic */
511 NETIF_FOREACH(netif) {
512 if (netif_is_up(netif)) {
513 NETIF_SET_SCOPE(netif, RT_SCOPE_HOST);
514 return netif;
515 }
516 }
517 return NULL;
518 }
519 #endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
520 #endif /* !LWIP_SINGLE_NETIF */
521
522 /* no matching netif found, use default netif, if up */
523 if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default)) {
524 return NULL;
525 }
526 NETIF_SET_SCOPE(netif_default, RT_SCOPE_UNIVERSAL);
527 return netif_default;
528 }
529
530 /**
531 * @ingroup ip6
532 * Select the best IPv6 source address for a given destination
533 * IPv6 address. Loosely follows RFC 3484. "Strong host" behavior
534 * is assumed.
535 *
536 * @param addr1 IPv6 Address 1
537 * @param addr2 IPv6 Address 2
538 * @param prefix_length Length of network prefix(in bits)
539 * @return
540 * Number of common prefix bits in addr1 & addr2 : On success
541 * -1 : Invalid parameters
542 */
ip6_common_prefix_length(const ip6_addr_t * addr1,const ip6_addr_t * addr2,u8_t prefix_length)543 int ip6_common_prefix_length(const ip6_addr_t *addr1, const ip6_addr_t *addr2, u8_t prefix_length)
544 {
545 int common_prefix_length = 0;
546 int i = 0;
547 int bit_index;
548 u8_t *addr1_char = NULL;
549 u8_t *addr2_char = NULL;
550
551 LWIP_ERROR("ip6_common_prefix_length: addr1 != NULL", (addr1 != NULL), return -1);
552 LWIP_ERROR("ip6_common_prefix_length: addr2 != NULL", (addr2 != NULL), return -1);
553
554 if ((prefix_length < 1) || (prefix_length > IP6_ADDR_LEN)) {
555 LWIP_DEBUGF(IP6_DEBUG, ("ip6_common_prefix_length: Prefix length = %"X8_F": is invalid", prefix_length));
556 return -1;
557 }
558
559 // Checking Word-By-Word
560 while ((common_prefix_length < prefix_length) && (i < IP6_ADDR_U32_ARR_SIZE)) {
561 if (addr1->addr[i] == addr2->addr[i]) {
562 common_prefix_length += 32; // u32_t occupy 32 bits
563 ++i;
564 continue;
565 }
566 break;
567 }
568
569 // If Already "prefix_length" number of bits are matched, then skip remaining part of the function
570 if (common_prefix_length >= prefix_length) {
571 goto exit;
572 }
573
574 // Checking Byte-By-Byte
575 addr1_char = (u8_t *)(addr1);
576 addr2_char = (u8_t *)(addr2);
577
578 // Advancing i To Proper value so that it now indexes the next byte for comparison
579 i *= 4; // u32_t occupy 4 u8_t
580
581 while ((common_prefix_length < prefix_length)) {
582 if (addr1_char[i] == addr2_char[i]) {
583 common_prefix_length += 8; // u8_t occupy 8 bits
584 ++i;
585 continue;
586 }
587 break;
588 }
589
590 // If Already "prefix_length" number of bits are matched, then skip remaining part of the function
591 if (common_prefix_length >= prefix_length) {
592 goto exit;
593 }
594
595 // Checking Bit by Bit
596 // bit_index is set to 7 so that the entire eight bits has to be checked
597 bit_index = 7;
598
599 // Checking whether the first nibble of the byte matches
600 // This is done so as to reduce the number of bit-by-bit comparisons that may be done afterwards
601 if ((u8_t)(addr1_char[i] >> 4) == (u8_t)(addr2_char[i] >> 4)) {
602 common_prefix_length += 4;
603 // bit_index is set to 3 so that only the last 4 bits has to be checked
604 // (because the first 4 bits have already proved to be equal)
605 bit_index = 3;
606 }
607
608 // If already "prefix_length" number of bits are matched, then skip remaining part of the function
609 if (common_prefix_length >= prefix_length) {
610 goto exit;
611 }
612
613 while (bit_index >= 0) {
614 if ((u8_t)(addr1_char[i] >> (u32_t)bit_index) == (u8_t)(addr2_char[i] >> (u32_t)bit_index)) {
615 ++common_prefix_length;
616 --bit_index;
617 continue;
618 }
619 break;
620 }
621
622 exit:
623 // Placing an upper bound so that the prefix length matched does not go beyond "prefix_length"
624 common_prefix_length = LWIP_MIN(common_prefix_length, prefix_length);
625
626 return common_prefix_length;
627 }
628
629 /**
630 * @ingroup ip6
631 * Select the best IPv6 source address for a given destination IPv6 address.
632 *
633 * This implementation follows RFC 6724 Sec. 5 to the following extent:
634 * - Rules 1, 2, 3: fully implemented
635 * - Rules 4, 5, 5.5: not applicable
636 * - Rule 6: not implemented
637 * - Rule 7: not applicable
638 * - Rule 8: limited to "prefer /64 subnet match over non-match"
639 *
640 * For Rule 2, we deliberately deviate from RFC 6724 Sec. 3.1 by considering
641 * ULAs to be of smaller scope than global addresses, to avoid that a preferred
642 * ULA is picked over a deprecated global address when given a global address
643 * as destination, as that would likely result in broken two-way communication.
644 *
645 * As long as temporary addresses are not supported (as used in Rule 7), a
646 * proper implementation of Rule 8 would obviate the need to implement Rule 6.
647 *
648 * @param netif the netif on which to send a packet
649 * @param dest the destination we are trying to reach (possibly not properly
650 * zoned)
651 * @return the most suitable source address to use, or NULL if no suitable
652 * source address is found
653 */
654 const ip_addr_t *
ip6_select_source_address(struct netif * netif,const ip6_addr_t * dest)655 ip6_select_source_address(struct netif *netif, const ip6_addr_t *dest)
656 {
657 const ip_addr_t *best_addr;
658 const ip6_addr_t *cand_addr;
659 s8_t dest_scope, cand_scope;
660 s8_t best_scope = IP6_MULTICAST_SCOPE_RESERVED;
661 u8_t i, cand_pref;
662 u8_t best_pref = 0;
663 int best_bits = 0;
664 u8_t prefix_length = 64;
665 int cand_bits;
666
667 /* Start by determining the scope of the given destination address. These
668 * tests are hopefully (roughly) in order of likeliness to match. */
669 if (ip6_addr_isglobal(dest)) {
670 dest_scope = IP6_MULTICAST_SCOPE_GLOBAL;
671 } else if (ip6_addr_islinklocal(dest) || ip6_addr_isloopback(dest)) {
672 dest_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL;
673 } else if (ip6_addr_isuniquelocal(dest)) {
674 dest_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL;
675 } else if (ip6_addr_ismulticast(dest)) {
676 dest_scope = ip6_addr_multicast_scope(dest);
677 } else if (ip6_addr_issitelocal(dest)) {
678 dest_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL;
679 } else {
680 /* no match, consider scope global */
681 dest_scope = IP6_MULTICAST_SCOPE_RESERVEDF;
682 }
683
684 best_addr = NULL;
685
686 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
687 /* Consider only valid (= preferred and deprecated) addresses. */
688 if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) {
689 continue;
690 }
691 /* Determine the scope of this candidate address. Same ordering idea. */
692 cand_addr = netif_ip6_addr(netif, i);
693 if (ip6_addr_isglobal(cand_addr)) {
694 cand_scope = IP6_MULTICAST_SCOPE_GLOBAL;
695 } else if (ip6_addr_islinklocal(cand_addr)) {
696 cand_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL;
697 } else if (ip6_addr_isuniquelocal(cand_addr)) {
698 cand_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL;
699 } else if (ip6_addr_issitelocal(cand_addr)) {
700 cand_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL;
701 } else {
702 /* no match, treat as low-priority global scope */
703 cand_scope = IP6_MULTICAST_SCOPE_RESERVEDF;
704 }
705 cand_pref = ip6_addr_ispreferred(netif_ip6_addr_state(netif, i));
706 cand_bits = ip6_common_prefix_length(cand_addr, dest, prefix_length);
707 if (cand_bits == -1) {
708 cand_bits = 0;
709 }
710
711 if ((best_addr == NULL) || /* no alternative yet */
712 ((cand_scope < best_scope) && (cand_scope >= dest_scope)) ||
713 ((cand_scope > best_scope) && (best_scope < dest_scope)) || /* Rule 2 */
714 ((cand_scope == best_scope) && ((cand_pref > best_pref) || /* Rule 3 */
715 ((cand_pref == best_pref) && (cand_bits > best_bits))))) { /* Rule 8 */
716 /* We found a new "winning" candidate. */
717 best_addr = netif_ip_addr6(netif, i);
718 best_scope = cand_scope;
719 best_pref = cand_pref;
720 best_bits = cand_bits;
721 }
722 }
723
724 return best_addr; /* may be NULL */
725 }
726
727 #if LWIP_IPV6_FORWARD
728 #if LWIP_RIPPLE
729 #define IP6_FORWARD_BIG_DROP 1
730 #define IP6_FORWARD_BIG_HANDLED 2
731 #define IP6_FORWARD_BIG_ASSEMBLED 3
732 static int
ip6_forward_big_packet(struct pbuf ** q,struct ip6_hdr ** oiphdr,const struct netif * outp,u8_t * big_packet)733 ip6_forward_big_packet(struct pbuf **q, struct ip6_hdr **oiphdr, const struct netif *outp, u8_t *big_packet)
734 {
735 u16_t ip6_hdr_len;
736 u8_t nexth;
737 u8_t flags;
738 u16_t optlen;
739 struct pbuf *p = *q;
740 struct ip6_hdr *iphdr = *oiphdr;
741
742 /* send ICMP6 if HL == 0 */
743 if ((IP6H_HOPLIM(iphdr) == 0) || ((IP6H_HOPLIM(iphdr) - 1) == 0)) {
744 #if LWIP_ICMP6
745 /* Don't send ICMP messages in response to ICMP messages */
746 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
747 icmp6_time_exceeded(p, ICMP6_TE_HL);
748 }
749 #endif /* LWIP_ICMP6 */
750 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward_big_packet:hop limit drop\n"));
751 IP6_STATS_INC(ip6.drop);
752 return IP6_FORWARD_BIG_DROP;
753 }
754 LWIP_UNUSED_ARG(outp);
755 nexth = IP6H_NEXTH(iphdr);
756 ip6_hdr_len = IP6_HLEN;
757
758 /* find the data in ip6 pkt */
759 /* Move to payload. */
760 (void)pbuf_header(p, -IP6_HLEN);
761 *big_packet = 1;
762 flags = 0;
763 /* Process option extension headers, if present. */
764 while (nexth != IP6_NEXTH_NONE) {
765 if ((nexth == IP6_NEXTH_TCP) || (nexth == IP6_NEXTH_UDP) ||
766 (nexth == IP6_NEXTH_ICMP6) || (flags != 0)) {
767 break;
768 }
769
770 switch (nexth) {
771 case IP6_NEXTH_HOPBYHOP:
772 case IP6_NEXTH_ENCAPS:
773 case IP6_NEXTH_ROUTING:
774 case IP6_NEXTH_DESTOPTS:
775 /* Get next header type. */
776 nexth = *((u8_t *)p->payload);
777
778 if (p->len < IP6_HBH_HLEN) {
779 LWIP_DEBUGF(IP6_DEBUG, ("pbuf (len %"U16_F") is less than 2.\n", p->len));
780 IP_STATS_INC(ip6.drop);
781 return IP6_FORWARD_BIG_DROP;
782 }
783 /* Get the header length. */
784 /* 8: go to option length segment and multily by eight */
785 optlen = 8 * (1 + (u16_t)*((u8_t *)p->payload + 1));
786
787 /* Skip over this header. */
788 if (optlen > p->len) {
789 LWIP_DEBUGF(IP6_DEBUG,
790 ("IPv6 opt header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 pac dropped.\n",
791 optlen, p->len));
792 IP_STATS_INC(ip6.drop);
793 return IP6_FORWARD_BIG_DROP;
794 }
795
796 ip6_hdr_len += optlen;
797 (void)pbuf_header(p, (s16_t)(-(s16_t)optlen));
798 break;
799 case IP6_NEXTH_FRAGMENT: {
800 struct ip6_frag_hdr *frag_hdr = NULL;
801 LWIP_DEBUGF(IP6_DEBUG, ("nat64_ip6_input: packet with Fragment header\n"));
802
803 frag_hdr = (struct ip6_frag_hdr *)p->payload;
804
805 if (p->len < IP6_HBH_HLEN) {
806 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
807 ("IP6_NEXTH_FRAGMENT:(pbuf len %"U16_F" is less than 2), IPv6 packet dropped.\n",
808 p->len));
809 IP6_STATS_INC(ip6.drop);
810 return IP6_FORWARD_BIG_DROP;
811 }
812
813 /* Get next header type. */
814 nexth = frag_hdr->_nexth;
815
816 /* 8 : Fragment Header length. */
817 optlen = 8;
818 ip6_hdr_len += optlen;
819
820 /* Make sure this header fits in current pbuf. */
821 if (optlen > p->len) {
822 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
823 ("IPv6 opt header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 pac dropped.\n",
824 optlen, p->len));
825 IP6_STATS_INC(ip6.drop);
826 return IP6_FORWARD_BIG_DROP;
827 }
828
829 /* check payload length is multiple of 8 octets when mbit is set */
830 if (IP6_FRAG_MBIT(frag_hdr) && ((IP6H_PLEN(iphdr) & 0x7) != 0)) {
831 /* ipv6 payload length is not multiple of 8 octets */
832 icmp6_param_problem(p, ICMP6_PP_FIELD, frag_hdr);
833 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward_big_packet: packet with invalid payload length dropped\n"));
834 IP6_STATS_INC(ip6.drop);
835 return IP6_FORWARD_BIG_DROP;
836 }
837
838 /* Offset == 0 and more_fragments == 0? */
839 if ((frag_hdr->_fragment_offset &
840 PP_HTONS(IP6_FRAG_OFFSET_MASK | IP6_FRAG_MORE_FLAG)) == 0) {
841 /*
842 * This is a 1-fragment packet, usually a packet that we have
843 * already reassembled. Skip this header anc continue.
844 */
845 (void)pbuf_header(p, (s16_t)(-(s16_t)optlen));
846 } else {
847 #if LWIP_IPV6_REASS
848 /* reassemble the packet */
849 p = ip6_reass(p);
850 /* packet not fully reassembled yet? */
851 if (p == NULL) {
852 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward_big_packet:fragment is not fully reassembled yet\n"));
853 /* note: the pkt has been free in the ip6_reass */
854 return IP6_FORWARD_BIG_ASSEMBLED;
855 }
856
857 /*
858 * Returned p point to IPv6 header.
859 * Update all our variables and pointers and continue.
860 */
861 iphdr = (struct ip6_hdr *)p->payload;
862 nexth = IP6H_NEXTH(iphdr);
863 optlen = 0;
864 ip6_hdr_len = 0;
865 *q = p;
866 *oiphdr = iphdr;
867 (void)pbuf_header(p, -IP6_HLEN);
868 ip6_hdr_len = IP6_HLEN;
869
870 #else /* LWIP_IPV6_REASS */
871 /* free (drop) packet pbufs */
872 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward_big_packet: packet with Fragment header dropped.\n"));
873 IP6_STATS_INC(ip6.drop);
874 return IP6_FORWARD_BIG_DROP;
875 #endif /* LWIP_IPV6_REASS */
876 }
877 break;
878 }
879 default:
880 flags = 1;
881 break;
882 }
883 }
884
885 if ((nexth != IP6_NEXTH_TCP) && (nexth != IP6_NEXTH_UDP) &&
886 (nexth != IP6_NEXTH_ICMP6)) {
887 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward_big_packet: nexth is not correct.\n"));
888 IP6_STATS_INC(ip6.drop);
889 return IP6_FORWARD_BIG_DROP;
890 }
891
892 (void)pbuf_header(p, (s16_t)ip6_hdr_len);
893 return IP6_FORWARD_BIG_HANDLED;
894 }
895 #endif
896 /**
897 * Forwards an IPv6 packet. It finds an appropriate route for the
898 * packet, decrements the HL value of the packet, and outputs
899 * the packet on the appropriate interface.
900 *
901 * @param p the packet to forward (p->payload points to IP header)
902 * @param iphdr the IPv6 header of the input packet
903 * @param inp the netif on which this packet was received
904 */
905 static void
ip6_forward(struct pbuf * p,struct ip6_hdr * iphdr,struct netif * inp,u8_t * free_flag)906 ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp, u8_t *free_flag)
907 {
908 struct netif *netif;
909 u8_t big_packet = 0;
910
911 /* do not forward link-local or loopback addresses */
912 if (ip6_addr_islinklocal(ip6_current_dest_addr()) ||
913 ip6_addr_isloopback(ip6_current_dest_addr())) {
914 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n"));
915 IP6_STATS_INC(ip6.rterr);
916 IP6_STATS_INC(ip6.drop);
917 return;
918 }
919
920 /* Find network interface where to forward this IP packet to. */
921 netif = ip6_route(IP6_ADDR_ANY6, ip6_current_dest_addr());
922 if (netif == NULL) {
923 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",
924 IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
925 IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
926 IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
927 IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
928 IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
929 IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
930 IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
931 IP6_ADDR_BLOCK8(ip6_current_dest_addr())));
932 #if LWIP_ICMP6
933 /* Don't send ICMP messages in response to ICMP messages */
934 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
935 icmp6_dest_unreach(p, ICMP6_DUR_NO_ROUTE);
936 }
937 #endif /* LWIP_ICMP6 */
938 IP6_STATS_INC(ip6.rterr);
939 IP6_STATS_INC(ip6.drop);
940 return;
941 }
942 #if LWIP_IPV6_SCOPES
943 /* Do not forward packets with a zoned (e.g., link-local) source address
944 * outside of their zone. We determined the zone a bit earlier, so we know
945 * that the address is properly zoned here, so we can safely use has_zone.
946 * Also skip packets with a loopback source address (link-local implied). */
947 if ((ip6_addr_has_zone(ip6_current_src_addr()) &&
948 !ip6_addr_test_zone(ip6_current_src_addr(), netif)) ||
949 ip6_addr_isloopback(ip6_current_src_addr())) {
950 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding packet beyond its source address zone.\n"));
951 IP6_STATS_INC(ip6.rterr);
952 IP6_STATS_INC(ip6.drop);
953 return;
954 }
955 #endif /* LWIP_IPV6_SCOPES */
956 /* Do not forward packets onto the same network interface on which
957 * they arrived. */
958 if ((netif == inp)
959 #if LWIP_RIPPLE
960 && (lwip_rpl_is_rpl_netif(inp) == lwIP_FALSE)
961 #endif
962 ) {
963 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not bouncing packets back on incoming interface.\n"));
964 IP6_STATS_INC(ip6.rterr);
965 IP6_STATS_INC(ip6.drop);
966 return;
967 }
968
969 #if LWIP_RIPPLE
970 int ret;
971 if (lwip_rpl_is_br() && (lwip_rpl_is_rpl_netif(inp) == lwIP_FALSE) &&
972 (lwip_rpl_is_rpl_netif(netif) == lwIP_TRUE)) {
973 /* should handle the big packet. */
974 ret = ip6_forward_big_packet(&p, &iphdr, netif, &big_packet);
975 if (ret == IP6_FORWARD_BIG_DROP) {
976 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: DROP\n"));
977 IP6_STATS_INC(ip6.drop);
978 return;
979 } else if (ret == IP6_FORWARD_BIG_ASSEMBLED) {
980 *free_flag = lwIP_FALSE;
981 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: ressa\n"));
982 return;
983 }
984 }
985 #else
986 LWIP_UNUSED_ARG(big_packet);
987 LWIP_UNUSED_ARG(free_flag);
988 #endif
989 /* decrement HL */
990 if (IP6H_HOPLIM(iphdr)) {
991 IP6H_HOPLIM_SET(iphdr, IP6H_HOPLIM(iphdr) - 1);
992 }
993 /* send ICMP6 if HL == 0 */
994 if (IP6H_HOPLIM(iphdr) == 0) {
995 #if LWIP_ICMP6
996 /* Don't send ICMP messages in response to ICMP messages */
997 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
998 icmp6_time_exceeded(p, ICMP6_TE_HL);
999 }
1000 #endif /* LWIP_ICMP6 */
1001 IP6_STATS_INC(ip6.drop);
1002 return;
1003 }
1004
1005 if (netif->mtu && (p->tot_len > netif->mtu) && (big_packet == 0)) {
1006 #if LWIP_ICMP6
1007 /* Don't send ICMP messages in response to ICMP messages */
1008 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
1009 icmp6_packet_too_big(p, netif->mtu);
1010 }
1011 #endif /* LWIP_ICMP6 */
1012 IP6_STATS_INC(ip6.drop);
1013 return;
1014 }
1015
1016 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",
1017 IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
1018 IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
1019 IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
1020 IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
1021 IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
1022 IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
1023 IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
1024 IP6_ADDR_BLOCK8(ip6_current_dest_addr())));
1025
1026 #if LWIP_RIPPLE
1027 /* Update the RPI extended header before forwarding */
1028 if ((p->flags & PBUF_FLAG_HBH_SPACE) != 0) {
1029 if (lwip_get_pkt_route_status()) {
1030 p->pkt_up = lwIP_TRUE;
1031 } else {
1032 p->pkt_up = lwIP_FALSE;
1033 }
1034 if (ip6_update_rpi(p, netif) != ERR_OK) {
1035 IP6_STATS_INC(ip6.rterr);
1036 IP6_STATS_INC(ip6.drop);
1037 return;
1038 }
1039 }
1040 #endif
1041 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num));
1042 ip6_debug_print(p);
1043
1044 #if LWIP_IPV6_FRAG
1045 /* don't fragment if interface has mtu set to 0 [loopif] */
1046 if ((big_packet != 0) && netif_mtu6(netif) &&
1047 (p->tot_len > nd6_get_destination_mtu(ip6_current_dest_addr(), netif))) {
1048 (void)ip6_frag(p, netif, ip6_current_dest_addr());
1049 *free_flag = lwIP_FALSE;
1050 (void)pbuf_free(p);
1051 return;
1052 }
1053 #endif /* LWIP_IPV6_FRAG */
1054
1055 /* transmit pbuf on chosen interface */
1056 netif->output_ip6(netif, p, ip6_current_dest_addr());
1057 IP6_STATS_INC(ip6.fw);
1058 IP6_STATS_INC(ip6.xmit);
1059 return;
1060 }
1061 #endif /* LWIP_IPV6_FORWARD */
1062
1063 static u8_t
ip6_process_destination_header_extension_unknown_options(struct pbuf * p,const struct ip6_opt_hdr * opt_hdr)1064 ip6_process_destination_header_extension_unknown_options(struct pbuf *p, const struct ip6_opt_hdr *opt_hdr)
1065 {
1066 u8_t clear_resource = 0;
1067 /* Check 2 MSB of Destination header type. */
1068 switch (IP6_OPT_TYPE_ACTION(opt_hdr)) {
1069 case 1:
1070 /* Discard the packet. */
1071 LWIP_DEBUGF(IP6_DEBUG,
1072 ("ip6_input: packet with invalid destination option type dropped, \
1073 highest order 2 bits value is 1\n"));
1074 clear_resource = 1;
1075 break;
1076 case 2:
1077 /* Send ICMP Parameter Problem */
1078 LWIP_DEBUGF(IP6_DEBUG,
1079 ("ip6_input: packet with invalid destination option type dropped, \
1080 highest order 2 bits value is 2\n"));
1081 /* move payload pointer back to ip header */
1082 (void)pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (const u8_t *)ip6_current_header()));
1083 icmp6_param_problem(p, ICMP6_PP_OPTION, (const void *)opt_hdr);
1084 clear_resource = 1;
1085 break;
1086 case 3:
1087 /* Send ICMP Parameter Problem if destination address is not a multicast address */
1088 LWIP_DEBUGF(IP6_DEBUG,
1089 ("ip6_input: packet with invalid destination option type dropped, \
1090 highest order 2 bits value is 3\n"));
1091 if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
1092 /* move payload pointer back to ip header */
1093 (void)pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (const u8_t *)ip6_current_header()));
1094 icmp6_param_problem(p, ICMP6_PP_OPTION, (const void *)opt_hdr);
1095 }
1096 clear_resource = 1;
1097 break;
1098
1099 default:
1100 break;
1101 }
1102
1103 return clear_resource;
1104 }
1105 /*
1106 * This function is called when there is extension options to be processed in destination header in IPV6 packet
1107 * @param p points to the pbuf buffer
1108 * @param dest_hdr points to the destination header in the IPV6
1109 * @param hlen header lenght of the destination option
1110 * @return need_ip6_input_cleanup = 1 means discard, 0 means continue process the packet
1111 */
ip6_process_destination_header_extension_options(struct pbuf * p,struct ip6_dest_hdr * dest_hdr,u16_t hlen,u8_t * need_ip6_input_cleanup)1112 void ip6_process_destination_header_extension_options(struct pbuf *p, struct ip6_dest_hdr *dest_hdr,
1113 u16_t hlen, u8_t *need_ip6_input_cleanup)
1114 {
1115 s32_t opt_offset;
1116 struct ip6_opt_hdr *opt_hdr = NULL;
1117 if ((p == NULL) || (dest_hdr == NULL) || (need_ip6_input_cleanup == NULL)) {
1118 return;
1119 }
1120 *need_ip6_input_cleanup = 0;
1121
1122 /* The extended option header starts right after Destination header. */
1123 opt_offset = IP6_DEST_HLEN;
1124 while (opt_offset < (s32_t)hlen) {
1125 s32_t opt_dlen = 0;
1126 u8_t clear_resource = 0;
1127
1128 opt_hdr = (struct ip6_opt_hdr *)((u8_t *)dest_hdr + opt_offset);
1129
1130 /*
1131 * @page RFC-2460 RFC-2460
1132 * @par RFC-2460 Compliance Information
1133 * @par Compliant Section
1134 * IPv6 Extension Headers. Test v6LC.1.2.8: Option Processing, Destination Options Header
1135 * @par Behavior Description
1136 *
1137 * Our node conforms to RFC-2460. \n
1138 * RFC-2460 does not support below extension options and the features corresponding to it. \n
1139 * @verbatim
1140 * RFC-3775 --> IPV6 Mobility Support - IP6_HOME_ADDRESS_OPTION (Option_Type = 201)
1141 * RFC-2711 --> IPv6 Router Alert Option - IP6_ROUTER_ALERT_OPTION (Option_Type = 5)
1142 * RFC-2675 --> IPV6 Jumbo Payload Option - IP6_JUMBO_OPTION (Option_Type = 194)
1143 * @endverbatim
1144 * \n
1145 * For these options and other extension header options, our node action conforms to RFC-2460: \n
1146 * If the IPv6 node does not recognize the Option_Type, then the action it should take depends
1147 * on the highest order two bits of the Option_Type.
1148 */
1149 switch (IP6_OPT_TYPE(opt_hdr)) {
1150 case IP6_PAD1_OPTION:
1151 /* PAD1 option deosn't have length and value field */
1152 opt_dlen = -1;
1153 break;
1154
1155 case IP6_PADN_OPTION:
1156 if ((hlen - opt_offset) >= IP6_OPT_HLEN) { /* malformed packet */
1157 opt_dlen = IP6_OPT_DLEN(opt_hdr);
1158 } else {
1159 /* Discard the packet. */
1160 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1161 ("ip6_input: malformed packet detected in PADN option rocessing, discarding it \n"));
1162 clear_resource = 1;
1163 }
1164 break;
1165
1166 default:
1167 clear_resource = ip6_process_destination_header_extension_unknown_options(p, opt_hdr);
1168 if (clear_resource == 0) {
1169 /* Skip over this option. */
1170 if ((hlen - opt_offset) >= IP6_OPT_HLEN) { /* malformed packet */
1171 opt_dlen = IP6_OPT_DLEN(opt_hdr);
1172 } else {
1173 /* Discard the packet. */
1174 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1175 ("ip6_input: malformed packet detected in Unknown option processing, discarding it \n"));
1176 clear_resource = 1;
1177 }
1178 }
1179 break;
1180 }
1181
1182 if (clear_resource != 0) {
1183 (void)pbuf_free(p);
1184 IP6_STATS_INC(ip6.drop);
1185 *need_ip6_input_cleanup = 1;
1186 break;
1187 }
1188 /* Adjust the offset to move to the next extended option header */
1189 opt_offset = opt_offset + IP6_OPT_HLEN + opt_dlen;
1190 }
1191
1192 return;
1193 }
1194 #if LWIP_IPV6_MLD_QUERIER
1195 static u8_t
ip6_mld6_check(struct pbuf * p,struct ip6_hdr * ip6hdr)1196 ip6_mld6_check(struct pbuf *p, struct ip6_hdr *ip6hdr)
1197 {
1198 u16_t *opt_data;
1199 u32_t offset = 0;
1200 struct ip6_hbh_hdr *hbh_hdr = NULL;
1201 struct ip6_opt_hdr *opt_hdr = NULL;
1202
1203 if (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_HOPBYHOP) {
1204 return lwIP_FALSE;
1205 }
1206
1207 /* Move to payload. */
1208 (void)pbuf_header(p, -IP6_HLEN);
1209 if (p->len < sizeof(struct ip6_hbh_hdr)) {
1210 return lwIP_FALSE;
1211 }
1212 hbh_hdr = (struct ip6_hbh_hdr *)(p->payload);
1213 if (hbh_hdr->_nexth != IP6_NEXTH_ICMP6) {
1214 return lwIP_FALSE;
1215 }
1216 offset = IP6_HBH_HLEN;
1217
1218 opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + offset);
1219 if (IP6_OPT_TYPE(opt_hdr) != IP6_ROUTER_ALERT_OPTION) {
1220 return lwIP_FALSE;
1221 }
1222 offset += IP6_OPT_HLEN;
1223
1224 /* Set router alert option data */
1225 opt_data = (u16_t *)((u8_t *)hbh_hdr + offset);
1226 if (*opt_data != IP6_ROUTER_ALERT_VALUE_MLD) {
1227 return lwIP_FALSE;
1228 }
1229
1230 /* Move to ip6 header */
1231 (void)pbuf_header(p, IP6_HLEN);
1232 return lwIP_TRUE;
1233 }
1234 #endif /* LWIP_IPV6_MLD_QUERIER */
1235
1236 #if LWIP_IPV6_MLD && LWIP_MPL
1237 static u8_t
ip6_mld6_mpl_check(struct pbuf * p,struct netif * inp)1238 ip6_mld6_mpl_check(struct pbuf *p, struct netif *inp)
1239 {
1240 LWIP_ASSERT("invalid pointer\n", (p != NULL && inp != NULL));
1241 if ((inp->flags & NETIF_IS_RPL_UP) == NETIF_IS_RPL_UP) {
1242 if ((ip6_addr_multicast_scope(ip6_current_dest_addr()) > IP6_MULTICAST_SCOPE_LINK_LOCAL) &&
1243 (MCAST6_IS_FROM_CONN_PEER(p) == MCAST6_FALSE)) {
1244 return lwIP_FALSE;
1245 }
1246 } else {
1247 u8_t mesh_ap;
1248 if ((is_connect_to_ap(&mesh_ap) == lwIP_TRUE) && (mesh_ap == lwIP_TRUE) &&
1249 (is_connected_ap(p->mac_address, sizeof(p->mac_address)) == lwIP_FALSE)) {
1250 return lwIP_FALSE;
1251 }
1252 }
1253 return lwIP_TRUE;
1254 }
1255 #endif /* LWIP_IPV6_MLD && LWIP_MPL */
1256 #if LWIP_RIPPLE && defined(LWIP_NA_PROXY) && LWIP_NA_PROXY
1257 static err_t
ip6_na_proxy(ip6_addr_t * src,ip6_addr_t * target,struct netif * inp)1258 ip6_na_proxy(ip6_addr_t *src, ip6_addr_t *target, struct netif *inp)
1259 {
1260 if (ip6_addr_isany_val(*src)) {
1261 return ERR_ARG;
1262 }
1263
1264 if (lwip_rpl_is_rpl_netif(inp)) {
1265 /* only the non-mesh node be proxy */
1266 return lwip_rpl_nonmesh_solicited_node(src);
1267 } else if (lwip_rpl_is_br()) {
1268 /* the node behind the MBR will be proxy */
1269 return lwip_rpl_behind_mbr_solicited_node(target);
1270 }
1271
1272 return ERR_VAL;
1273 }
1274 #endif
1275
1276 /** Return true if the current input packet should be accepted on this netif */
1277 static int
ip6_input_accept(struct netif * netif)1278 ip6_input_accept(struct netif *netif)
1279 {
1280 /* interface is up? */
1281 if (netif_is_up(netif)) {
1282 u8_t i;
1283 /* unicast to this interface address? address configured? */
1284 /* If custom scopes are used, the destination zone will be tested as
1285 * part of the local-address comparison, but we need to test the source
1286 * scope as well (e.g., is this interface on the same link?). */
1287 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
1288 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
1289 ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i))
1290 #if IPV6_CUSTOM_SCOPES
1291 && (!ip6_addr_has_zone(ip6_current_src_addr()) ||
1292 ip6_addr_test_zone(ip6_current_src_addr(), netif))
1293 #endif /* IPV6_CUSTOM_SCOPES */
1294 ) {
1295 /* accept on this netif */
1296 return 1;
1297 }
1298 }
1299 }
1300 return 0;
1301 }
1302
1303 /**
1304 * This function is called by the network interface device driver when
1305 * an IPv6 packet is received. The function does the basic checks of the
1306 * IP header such as packet size being at least larger than the header
1307 * size etc. If the packet was not destined for us, the packet is
1308 * forwarded (using ip6_forward).
1309 *
1310 * Finally, the packet is sent to the upper layer protocol input function.
1311 *
1312 * @param p the received IPv6 packet (p->payload points to IPv6 header)
1313 * @param inp the netif on which this packet was received
1314 * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't
1315 * processed, but currently always returns ERR_OK)
1316 */
1317 err_t
ip6_input(struct pbuf * p,struct netif * inp)1318 ip6_input(struct pbuf *p, struct netif *inp)
1319 {
1320 struct ip6_hdr *ip6hdr;
1321 struct netif *netif;
1322 const u8_t *nexth;
1323 u16_t hlen, hlen_tot; /* the current header length */
1324 #if LWIP_RAW
1325 raw_input_state_t raw_status;
1326 #endif /* LWIP_RAW */
1327 u8_t need_ip6_input_cleanup = 0;
1328 u8_t assemble_flag;
1329
1330 LWIP_ASSERT_CORE_LOCKED();
1331
1332 IP6_STATS_INC(ip6.recv);
1333
1334 #if LWIP_IPV6_FILTER
1335 if (ip6_filter != NULL && ip6_filter(p, inp) != ERR_OK) {
1336 (void)pbuf_free(p);
1337 IP6_STATS_INC(ip6.drop);
1338 return ERR_OK;
1339 }
1340 #endif /* LWIP_IPV6_FILTER */
1341
1342 if ((IP6_HLEN > p->len)) {
1343 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1344 ("IPv6 header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
1345 (u16_t)IP6_HLEN, p->len));
1346
1347 /* free (drop) packet pbufs */
1348 (void)pbuf_free(p);
1349 IP6_STATS_INC(ip6.lenerr);
1350 IP6_STATS_INC(ip6.drop);
1351 return ERR_OK;
1352 }
1353
1354 /* identify the IP header */
1355 ip6hdr = (struct ip6_hdr *)p->payload;
1356 if (IP6H_V(ip6hdr) != 6) {
1357 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n",
1358 IP6H_V(ip6hdr)));
1359 pbuf_free(p);
1360 IP6_STATS_INC(ip6.err);
1361 IP6_STATS_INC(ip6.drop);
1362 return ERR_OK;
1363 }
1364
1365 #ifdef LWIP_HOOK_IP6_INPUT
1366 if (LWIP_HOOK_IP6_INPUT(p, inp)) {
1367 /* the packet has been eaten */
1368 return ERR_OK;
1369 }
1370 #endif
1371
1372 /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
1373
1374 if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) {
1375 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1376 ("IPv6 (plen %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
1377 (u16_t)(IP6H_PLEN(ip6hdr) + IP6_HLEN), p->tot_len));
1378
1379 /* free (drop) packet pbufs */
1380 pbuf_free(p);
1381 IP6_STATS_INC(ip6.lenerr);
1382 IP6_STATS_INC(ip6.drop);
1383 return ERR_OK;
1384 }
1385
1386 /* Trim pbuf. This should have been done at the netif layer,
1387 * but we'll do it anyway just to be sure that its done. */
1388 pbuf_realloc(p, (u16_t)(IP6_HLEN + IP6H_PLEN(ip6hdr)));
1389
1390 /* copy IP addresses to aligned ip6_addr_t */
1391 ip_addr_copy_from_ip6_packed(ip_data.current_iphdr_dest, ip6hdr->dest);
1392 ip_addr_copy_from_ip6_packed(ip_data.current_iphdr_src, ip6hdr->src);
1393
1394 /* Don't accept virtual IPv4 mapped IPv6 addresses.
1395 * Don't accept multicast source addresses. */
1396 if (ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_dest)) ||
1397 ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_src)) ||
1398 ip6_addr_ismulticast(ip_2_ip6(&ip_data.current_iphdr_src))) {
1399 /* free (drop) packet pbufs */
1400 pbuf_free(p);
1401 IP6_STATS_INC(ip6.err);
1402 IP6_STATS_INC(ip6.drop);
1403 return ERR_OK;
1404 }
1405
1406 /* Set the appropriate zone identifier on the addresses. */
1407 ip6_addr_assign_zone(ip_2_ip6(&ip_data.current_iphdr_dest), IP6_UNKNOWN, inp);
1408 ip6_addr_assign_zone(ip_2_ip6(&ip_data.current_iphdr_src), IP6_UNICAST, inp);
1409
1410 #if LWIP_MPL
1411 /*
1412 * Don't accept the packet which was sent by us.
1413 */
1414 for (netif = netif_list; netif != NULL; netif = netif->next) {
1415 u8_t i;
1416 if (netif->flags & NETIF_FLAG_LOOPBACK) {
1417 continue;
1418 }
1419 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
1420 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
1421 ip6_addr_cmp(ip6_current_src_addr(), netif_ip6_addr(netif, i))) {
1422 /* free (drop) packet pbufs */
1423 (void)pbuf_free(p);
1424 IP6_STATS_INC(ip6.err);
1425 IP6_STATS_INC(ip6.drop);
1426 return ERR_OK;
1427 }
1428 }
1429 }
1430 #endif
1431
1432 #if LWIP_RIPPLE && defined(LWIP_NA_PROXY) && LWIP_NA_PROXY
1433 p->na_proxy = lwIP_FALSE;
1434 #endif
1435 /* current header pointer. */
1436 ip_data.current_ip6_header = ip6hdr;
1437
1438 /* In netif, used in case we need to send ICMPv6 packets back. */
1439 ip_data.current_netif = inp;
1440 ip_data.current_input_netif = inp;
1441
1442 /* match packet against an interface, i.e. is this packet for us? */
1443 if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
1444 /* Always joined to multicast if-local and link-local all-nodes group. */
1445 if (ip6_addr_isallnodes_iflocal(ip6_current_dest_addr()) ||
1446 ip6_addr_isallnodes_linklocal(ip6_current_dest_addr())
1447 #if LWIP_RIPPLE
1448 || ip6_addr_isallrpl_nodes_linklocal(ip6_current_dest_addr())
1449 || ip6_addr_isallrouters_linklocal(ip6_current_dest_addr())
1450 #endif
1451 ) {
1452 netif = inp;
1453 }
1454 #if LWIP_IPV6_MLD
1455 else if (mld6_lookfor_group(inp, ip6_current_dest_addr())
1456 #if LWIP_MPL_IPV4_BCAST
1457 || ip6_addr_is_mpl_ip4_bcast(ip6_current_dest_addr())
1458 #endif
1459 ) {
1460 netif = inp;
1461 #if LWIP_MPL
1462 if (ip6_mld6_mpl_check(p, inp) == lwIP_FALSE) {
1463 /* free (drop) packet pbufs */
1464 (void)pbuf_free(p);
1465 IP6_STATS_INC(ip6.err);
1466 IP6_STATS_INC(ip6.drop);
1467 return ERR_OK;
1468 }
1469 #endif
1470 }
1471 #else /* LWIP_IPV6_MLD */
1472 else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) {
1473 u8_t i;
1474 /* Filter solicited node packets when MLD is not enabled
1475 * (for Neighbor discovery). */
1476 netif = NULL;
1477 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
1478 if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) &&
1479 ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) {
1480 netif = inp;
1481 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %s\n",
1482 netif->name));
1483 break;
1484 }
1485 }
1486 #if LWIP_RIPPLE && defined(LWIP_NA_PROXY) && LWIP_NA_PROXY
1487 if ((netif == NULL) &&
1488 (ip6_na_proxy(ip6_current_src_addr(), ip6_current_dest_addr(), inp) == ERR_OK)) {
1489 netif = inp;
1490 p->na_proxy = lwIP_TRUE;
1491 }
1492 #endif
1493 }
1494 #endif /* LWIP_IPV6_MLD */
1495 #if LWIP_IPV6_MLD_QUERIER
1496 else if (
1497 #if LWIP_MPL
1498 (ip6_addr_multicast_scope(ip6_current_dest_addr()) > IP6_MULTICAST_SCOPE_LINK_LOCAL) &&
1499 (MCAST6_IS_FROM_CONN_PEER(p) == MCAST6_TRUE) &&
1500 #endif /* LWIP_MPL */
1501 (ip6_addr_isallrouters_linklocal(ip6_current_dest_addr()) ||
1502 (ip6_mld6_check(p, ip6hdr) == lwIP_TRUE))) {
1503 netif = inp;
1504 }
1505 #endif
1506 #if LWIP_RIPPLE && defined(LWIP_NA_PROXY) && LWIP_NA_PROXY
1507 else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) {
1508 u8_t i = 0;
1509 /*
1510 * Filter solicited node packets when MLD is not enabled
1511 * (for Neighbor discovery).
1512 */
1513 netif = NULL;
1514 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
1515 if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) &&
1516 ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) {
1517 netif = inp;
1518 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %c%c\n",
1519 netif->name[0], netif->name[1]));
1520 break;
1521 }
1522 }
1523
1524 if ((netif == NULL) &&
1525 (ip6_na_proxy(ip6_current_src_addr(), ip6_current_dest_addr(), inp) == ERR_OK)) {
1526 netif = inp;
1527 p->na_proxy = lwIP_TRUE;
1528 }
1529 }
1530 #endif
1531 else {
1532 netif = NULL;
1533 }
1534 #if LWIP_MPL
1535 if (ip6_addr_multicast_scope(ip6_current_dest_addr()) > IP6_MULTICAST_SCOPE_LINK_LOCAL) {
1536 MCAST6_FORWARD(p, ip6hdr);
1537 }
1538 #endif /* LWIP_MPL */
1539 } else {
1540 /* start trying with inp. if that's not acceptable, start walking the
1541 list of configured netifs. */
1542 if (ip6_input_accept(inp)) {
1543 netif = inp;
1544 } else {
1545 netif = NULL;
1546 #if !IPV6_CUSTOM_SCOPES
1547 /* Shortcut: stop looking for other interfaces if either the source or
1548 * the destination has a scope constrained to this interface. Custom
1549 * scopes may break the 1:1 link/interface mapping, however. */
1550 if (ip6_addr_islinklocal(ip6_current_dest_addr()) ||
1551 ip6_addr_islinklocal(ip6_current_src_addr())) {
1552 goto netif_found;
1553 }
1554 #endif /* !IPV6_CUSTOM_SCOPES */
1555 #if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
1556 /* The loopback address is to be considered link-local. Packets to it
1557 * should be dropped on other interfaces, as per RFC 4291 Sec. 2.5.3.
1558 * Its implied scope means packets *from* the loopback address should
1559 * not be accepted on other interfaces, either. These requirements
1560 * cannot be implemented in the case that loopback traffic is sent
1561 * across a non-loopback interface, however. */
1562 if (ip6_addr_isloopback(ip6_current_dest_addr()) ||
1563 ip6_addr_isloopback(ip6_current_src_addr())) {
1564 goto netif_found;
1565 }
1566 #endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
1567 #if !LWIP_SINGLE_NETIF
1568 NETIF_FOREACH(netif) {
1569 if (netif == inp) {
1570 /* we checked that before already */
1571 continue;
1572 }
1573 if (ip6_input_accept(netif)) {
1574 break;
1575 }
1576 }
1577 #endif /* !LWIP_SINGLE_NETIF */
1578 }
1579 netif_found:
1580 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %s\n",
1581 netif ? netif->name : "XX"));
1582 }
1583
1584 /* "::" packet source address? (used in duplicate address detection) */
1585 if (ip6_addr_isany_val(*ip6_current_src_addr()) &&
1586 (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) {
1587 /* packet source is not valid */
1588 /* free (drop) packet pbufs */
1589 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n"));
1590 pbuf_free(p);
1591 IP6_STATS_INC(ip6.drop);
1592 goto ip6_input_cleanup;
1593 }
1594
1595 /* packet not for us? */
1596 if (netif == NULL) {
1597 u8_t free_flag = lwIP_TRUE;
1598 /* packet not for us, route or discard */
1599 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_TRACE, ("ip6_input: packet not for us.\n"));
1600 #if LWIP_IP6IN4 && LWIP_IP6IN4_PRIOR_NAT64
1601 if (ip6in4_ip6_input(p, ip6hdr, inp, NULL)) {
1602 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip6in4_ip6_input: packet handle.\n"));
1603 goto ip6_input_cleanup;
1604 }
1605 #endif
1606 #if LWIP_NAT64
1607 if (nat64_ip6_input(p, ip6hdr, inp)) {
1608 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("nat64_ip6_input: packet handle.\n"));
1609 goto ip6_input_cleanup;
1610 }
1611 #endif /* LWIP_NAT64 */
1612 #if LWIP_IP6IN4 && !LWIP_IP6IN4_PRIOR_NAT64 && !LWIP_NAT64_IP6IN4
1613 if (ip6in4_ip6_input(p, ip6hdr, inp, NULL)) {
1614 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip6in4_ip6_input: packet handle.\n"));
1615 goto ip6_input_cleanup;
1616 }
1617 #endif
1618 #if LWIP_IPV6_FORWARD
1619 /* non-multicast packet? */
1620 if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
1621 /* try to forward IP packet on (other) interfaces */
1622 #if LWIP_RIPPLE
1623 (void)pbuf_header(p, -IP6_HLEN);
1624 if (ip6_process_hbh_exth_options(p, inp) == ERR_OK) {
1625 (void)pbuf_header(p, IP6_HLEN);
1626 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: RPI validation Success\n"));
1627 ip6_forward(p, ip6hdr, inp, &free_flag);
1628 }
1629 #else
1630 ip6_forward(p, ip6hdr, inp, &free_flag);
1631 #endif
1632 }
1633 #endif /* LWIP_IPV6_FORWARD */
1634 if (free_flag == lwIP_TRUE) {
1635 (void)pbuf_free(p);
1636 }
1637 IP6_STATS_INC(ip6.drop);
1638 goto ip6_input_cleanup;
1639 }
1640
1641 /* current netif pointer. */
1642 ip_data.current_netif = netif;
1643
1644 /* Save next header type. */
1645 nexth = &IP6H_NEXTH(ip6hdr);
1646
1647 /* Init header length. */
1648 hlen = hlen_tot = IP6_HLEN;
1649
1650 /* Move to payload. */
1651 pbuf_remove_header(p, IP6_HLEN);
1652
1653 /* Process known option extension headers, if present. */
1654 while (*nexth != IP6_NEXTH_NONE)
1655 {
1656 assemble_flag = 0;
1657 switch (*nexth) {
1658 case IP6_NEXTH_HOPBYHOP:
1659 {
1660 s32_t opt_offset;
1661 struct ip6_hbh_hdr *hbh_hdr;
1662 struct ip6_opt_hdr *opt_hdr;
1663 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n"));
1664
1665 /* Get and check the header length, while staying in packet bounds. */
1666 hbh_hdr = (struct ip6_hbh_hdr *)p->payload;
1667
1668 /* Get next header type. */
1669 #if LWIP_RIPPLE
1670 if (ip6_process_hbh_exth_options(p, netif) != ERR_OK) {
1671 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: RPI validation failed\n"));
1672 (void)pbuf_free(p);
1673 IP6_STATS_INC(ip6.drop);
1674 goto ip6_input_cleanup;
1675 }
1676 #endif
1677 nexth = &IP6_HBH_NEXTH(hbh_hdr);
1678 /*
1679 *@page RFC-2460 RFC-2460
1680 *@par Compliant Section
1681 *Section 4. IPv6 Extension Headers. Test v6LC.1.2.1: Next Header Zero
1682 *@par Behavior Description
1683 *The lwIP stack will not send back the ICMP Parameter Problem message and discard
1684 *the packet when a packet has Next Header field of zero in a header other than an IPv6 header.
1685 *Also the processing of Hop-by-Hop Options is not performed.
1686 *The exception referred to in the preceding paragraph is the Hop-by-
1687 *Hop Options header, which carries information that must be examined
1688 *and processed by every node along a packet's delivery path, including
1689 *the source and destination nodes. The Hop-by-Hop Options header,
1690 *when present, must immediately follow the IPv6 header. Its presence
1691 *is indicated by the value zero in the Next Header field of the IPv6
1692 *header. \n
1693 *If, as a result of processing a header, a node is required to proceed
1694 *to the next header but the Next Header value in the current header is
1695 *unrecognized by the node, it should discard the packet and send an
1696 *ICMP Parameter Problem message to the source of the packet, with an
1697 *ICMP Code value of 1 ("unrecognized Next Header type encountered")
1698 *and the ICMP Pointer field containing the offset of the unrecognized
1699 *value within the original packet. The same action should be taken if
1700 *a node encounters a Next Header value of zero in any header other \,
1701 *than an IPv6 header. \n
1702 *[RFC 8200 4. IPv6 Extension Headers] Modified the above behavior. By default no need to send
1703 *back the ICMP Parameter Problem message and discard the packet when a packet has Next
1704 *Header field of zero in a header other than an IPv6 header. Also the processing of Hop-by-Hop
1705 *Options header is changed from 'must' to 'may' by every node in the path \n
1706 * \n
1707 *NOTE: While RFC-2460 required that all nodes must examine and
1708 *process the Hop-by-Hop Options header, it is now expected that nodes
1709 *along a packet's delivery path only examine and process the
1710 *Hop-by-Hop Options header if explicitly configured to do so.
1711 */
1712 if (p->len < IP6_OPT_HLEN) {
1713 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1714 ("IP6_NEXTH_HOPBYHOP: pbuf (len %"U16_F") is less than 2.\n", p->len));
1715 /* free (drop) packet pbufs */
1716 (void)pbuf_free(p);
1717 IP6_STATS_INC(ip6.lenerr);
1718 IP6_STATS_INC(ip6.drop);
1719 goto ip6_input_cleanup;
1720 }
1721
1722 /* Get the header length. */
1723 hlen = (u16_t)(8 * (1 + hbh_hdr->_hlen));
1724
1725 if ((p->len < 8) || (hlen > p->len)) {
1726 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1727 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
1728 hlen, p->len));
1729 /* free (drop) packet pbufs */
1730 pbuf_free(p);
1731 IP6_STATS_INC(ip6.lenerr);
1732 IP6_STATS_INC(ip6.drop);
1733 goto ip6_input_cleanup;
1734 }
1735
1736 hlen_tot = (u16_t)(hlen_tot + hlen);
1737
1738 /* The extended option header starts right after Hop-by-Hop header. */
1739 opt_offset = IP6_HBH_HLEN;
1740 while (opt_offset < hlen)
1741 {
1742 s32_t opt_dlen = 0;
1743
1744 opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + opt_offset);
1745
1746 switch (IP6_OPT_TYPE(opt_hdr)) {
1747 /* @todo: process IPV6 Hop-by-Hop option data */
1748 case IP6_PAD1_OPTION:
1749 /* PAD1 option doesn't have length and value field */
1750 opt_dlen = -1;
1751 break;
1752 case IP6_PADN_OPTION:
1753 opt_dlen = IP6_OPT_DLEN(opt_hdr);
1754 break;
1755 case IP6_ROUTER_ALERT_OPTION:
1756 opt_dlen = IP6_OPT_DLEN(opt_hdr);
1757 break;
1758 case IP6_JUMBO_OPTION:
1759 opt_dlen = IP6_OPT_DLEN(opt_hdr);
1760 break;
1761 default:
1762 /* Check 2 MSB of Hop-by-Hop header type. */
1763 switch (IP6_OPT_TYPE_ACTION(opt_hdr)) {
1764 case 1:
1765 /* Discard the packet. */
1766 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n"));
1767 pbuf_free(p);
1768 IP6_STATS_INC(ip6.drop);
1769 goto ip6_input_cleanup;
1770 case 2:
1771 /* Send ICMP Parameter Problem */
1772 /* move payload pointer back to ip header */
1773 (void)pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (const u8_t *)ip6_current_header()));
1774 icmp6_param_problem(p, ICMP6_PP_OPTION, (const void *)opt_hdr);
1775 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n"));
1776 pbuf_free(p);
1777 IP6_STATS_INC(ip6.drop);
1778 goto ip6_input_cleanup;
1779 case 3:
1780 /* Send ICMP Parameter Problem if destination address is not a multicast address */
1781 if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
1782 /* move payload pointer back to ip header */
1783 (void)pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (const u8_t *)ip6_current_header()));
1784 icmp6_param_problem(p, ICMP6_PP_OPTION, (const void *)opt_hdr);
1785 }
1786 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n"));
1787 pbuf_free(p);
1788 IP6_STATS_INC(ip6.drop);
1789 goto ip6_input_cleanup;
1790 default:
1791 /* Skip over this option. */
1792 opt_dlen = IP6_OPT_DLEN(opt_hdr);
1793 break;
1794 }
1795 break;
1796 }
1797
1798 /* Adjust the offset to move to the next extended option header */
1799 opt_offset = opt_offset + IP6_OPT_HLEN + opt_dlen;
1800 }
1801 pbuf_remove_header(p, hlen);
1802 break;
1803 }
1804 case IP6_NEXTH_DESTOPTS:
1805 {
1806 struct ip6_dest_hdr *dest_hdr;
1807 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Destination options header\n"));
1808
1809 dest_hdr = (struct ip6_dest_hdr *)p->payload;
1810
1811 /* Get next header type. */
1812 nexth = &IP6_DEST_NEXTH(dest_hdr);
1813 if (p->len < IP6_DEST_HLEN) {
1814 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1815 ("IP6_NEXTH_DESTOPTS: pbuf (len %"U16_F") is less than 2.\n", p->len));
1816 /* free (drop) packet pbufs */
1817 (void)pbuf_free(p);
1818 IP6_STATS_INC(ip6.lenerr);
1819 IP6_STATS_INC(ip6.drop);
1820 goto ip6_input_cleanup;
1821 }
1822
1823 /* Get the header length. */
1824 hlen = 8 * (1 + dest_hdr->_hlen);
1825 if ((p->len < 8) || (hlen > p->len)) {
1826 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1827 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
1828 hlen, p->len));
1829 /* free (drop) packet pbufs */
1830 pbuf_free(p);
1831 IP6_STATS_INC(ip6.lenerr);
1832 IP6_STATS_INC(ip6.drop);
1833 goto ip6_input_cleanup;
1834 }
1835
1836 hlen_tot = (u16_t)(hlen_tot + hlen);
1837 /*
1838 *@page RFC-2460 RFC-2460
1839 *@par Compliant Section
1840 *Section 4. IPv6 Extension Headers. Test v6LC.1.2.8: Option Processing, Destination Options Header
1841 *@par Behavior Description
1842 *Our code conforms to RFC-2460. \n
1843 * RFC-2460 does not support the following extension options and the features corresponding to it. \n
1844 *@verbatim
1845 * RFC-3775 --> IPV6 Mobility Support - IP6_HOME_ADDRESS_OPTION (Option_Type = 201)
1846 * RFC-2711 --> IPv6 Router Alert Option - IP6_ROUTER_ALERT_OPTION (Option_Type = 5)
1847 * RFC-2675 --> IPV6 Jumbo Payload Option - IP6_JUMBO_OPTION (Option Type = 194)
1848 * @endverbatim
1849 * For these options and other extension header options, our node action will conform to RFC-2460: \n
1850 * If the IPv6 node does not recognize the Option_Type, then the action it should take depends
1851 * on the highest order two bits of the Option_Type.
1852 */
1853 /* The extended option header starts right after Destination header. */
1854 ip6_process_destination_header_extension_options(p, dest_hdr, hlen, &need_ip6_input_cleanup);
1855 if (need_ip6_input_cleanup) {
1856 goto ip6_input_cleanup;
1857 }
1858
1859 pbuf_remove_header(p, hlen);
1860 break;
1861 }
1862 case IP6_NEXTH_ROUTING:
1863 {
1864 struct ip6_rout_hdr *rout_hdr;
1865 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n"));
1866
1867 rout_hdr = (struct ip6_rout_hdr *)p->payload;
1868
1869 /* Get next header type. */
1870 nexth = &IP6_ROUT_NEXTH(rout_hdr);
1871 if (p->len < IP6_OPT_HLEN) {
1872 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1873 ("IP6_NEXTH_ROUTING: pbuf (len %"U16_F") is less than 2.\n", p->len));
1874 /* free (drop) packet pbufs */
1875 (void)pbuf_free(p);
1876 IP6_STATS_INC(ip6.lenerr);
1877 IP6_STATS_INC(ip6.drop);
1878 goto ip6_input_cleanup;
1879 }
1880
1881 /* Get the header length. */
1882 hlen = 8 * (1 + rout_hdr->_hlen);
1883
1884 if ((p->len < 8) || (hlen > p->len)) {
1885 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1886 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
1887 hlen, p->len));
1888 /* free (drop) packet pbufs */
1889 pbuf_free(p);
1890 IP6_STATS_INC(ip6.lenerr);
1891 IP6_STATS_INC(ip6.drop);
1892 goto ip6_input_cleanup;
1893 }
1894
1895 /* Skip over this header. */
1896 hlen_tot = (u16_t)(hlen_tot + hlen);
1897
1898 /* if segment left value is 0 in routing header, ignore the option */
1899 if (IP6_ROUT_SEG_LEFT(rout_hdr)) {
1900 /* The length field of routing option header must be even */
1901 if (rout_hdr->_hlen & 0x1) {
1902 /* Discard and send parameter field error */
1903 icmp6_param_problem(p, ICMP6_PP_FIELD, &rout_hdr->_hlen);
1904 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid routing type dropped\n"));
1905 pbuf_free(p);
1906 IP6_STATS_INC(ip6.drop);
1907 goto ip6_input_cleanup;
1908 }
1909
1910 switch (IP6_ROUT_TYPE(rout_hdr))
1911 {
1912 /* TODO: process routing by the type */
1913 case IP6_ROUT_TYPE2:
1914 break;
1915 case IP6_ROUT_RPL:
1916 break;
1917 default:
1918 /* Discard unrecognized routing type and send parameter field error */
1919 icmp6_param_problem(p, ICMP6_PP_FIELD, &IP6_ROUT_TYPE(rout_hdr));
1920 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid routing type dropped\n"));
1921 pbuf_free(p);
1922 IP6_STATS_INC(ip6.drop);
1923 goto ip6_input_cleanup;
1924 }
1925 }
1926
1927 pbuf_remove_header(p, hlen);
1928 break;
1929 }
1930 case IP6_NEXTH_FRAGMENT:
1931 {
1932 struct ip6_frag_hdr *frag_hdr;
1933 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n"));
1934
1935 frag_hdr = (struct ip6_frag_hdr *)p->payload;
1936
1937 if (p->len < IP6_OPT_HLEN) {
1938 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1939 ("IP6_NEXTH_FRAGMENT:(pbuf len %"U16_F" is less than 2), IPv6 packet dropped.\n",
1940 p->len));
1941 /* free (drop) packet pbufs */
1942 (void)pbuf_free(p);
1943 IP6_STATS_INC(ip6.lenerr);
1944 IP6_STATS_INC(ip6.drop);
1945 goto ip6_input_cleanup;
1946 }
1947 /* Get next header type. */
1948 nexth = &IP6_FRAG_NEXTH(frag_hdr);
1949
1950 /* Fragment Header length. */
1951 hlen = 8;
1952
1953 /* Make sure this header fits in current pbuf. */
1954 if (hlen > p->len) {
1955 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
1956 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
1957 hlen, p->len));
1958 /* free (drop) packet pbufs */
1959 pbuf_free(p);
1960 IP6_FRAG_STATS_INC(ip6_frag.lenerr);
1961 IP6_FRAG_STATS_INC(ip6_frag.drop);
1962 goto ip6_input_cleanup;
1963 }
1964
1965 hlen_tot = (u16_t)(hlen_tot + hlen);
1966
1967 /* check payload length is multiple of 8 octets when mbit is set */
1968 if (IP6_FRAG_MBIT(frag_hdr) && (IP6H_PLEN(ip6hdr) & 0x7)) {
1969 /* move payload pointer back to ip header */
1970 (void)pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (const u8_t *)ip6_current_header()));
1971 /* ipv6 payload length is not multiple of 8 octets */
1972 icmp6_param_problem(p, ICMP6_PP_FIELD, LWIP_PACKED_CAST(const void *, &ip6hdr->_plen));
1973 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid payload length dropped\n"));
1974 pbuf_free(p);
1975 IP6_FRAG_STATS_INC(ip6_frag.lenerr);
1976 IP6_FRAG_STATS_INC(ip6_frag.drop);
1977 goto ip6_input_cleanup;
1978 }
1979
1980 /* Offset == 0 and more_fragments == 0? */
1981 if ((frag_hdr->_fragment_offset &
1982 PP_HTONS(IP6_FRAG_OFFSET_MASK | IP6_FRAG_MORE_FLAG)) == 0) {
1983 /* This is a 1-fragment packet. Skip this header and continue. */
1984 pbuf_remove_header(p, hlen);
1985 } else {
1986 #if LWIP_IPV6_REASS
1987 /* reassemble the packet */
1988 ip_data.current_ip_header_tot_len = hlen_tot;
1989 p = ip6_reass(p);
1990 /* packet not fully reassembled yet? */
1991 if (p == NULL) {
1992 goto ip6_input_cleanup;
1993 }
1994
1995 /* Returned p point to IPv6 header.
1996 * Update all our variables and pointers and continue. */
1997 ip6hdr = (struct ip6_hdr *)p->payload;
1998 nexth = &IP6H_NEXTH(ip6hdr);
1999 hlen = hlen_tot = IP6_HLEN;
2000 assemble_flag = 1;
2001 pbuf_remove_header(p, IP6_HLEN);
2002
2003 #else /* LWIP_IPV6_REASS */
2004 /* free (drop) packet pbufs */
2005 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header dropped (with LWIP_IPV6_REASS==0)\n"));
2006 pbuf_free(p);
2007 IP6_STATS_INC(ip6.opterr);
2008 IP6_STATS_INC(ip6.drop);
2009 goto ip6_input_cleanup;
2010 #endif /* LWIP_IPV6_REASS */
2011 }
2012 break;
2013 }
2014 default:
2015 goto options_done;
2016 }
2017
2018 if ((assemble_flag == 0) && (*nexth == IP6_NEXTH_HOPBYHOP)) {
2019 /* move payload pointer back to ip header */
2020 (void)pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (const u8_t *)ip6_current_header()));
2021 /* Hop-by-Hop header comes only as a first option */
2022 icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
2023 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header dropped (only valid as a first option)\n"));
2024 pbuf_free(p);
2025 IP6_STATS_INC(ip6.opterr);
2026 IP6_STATS_INC(ip6.drop);
2027 goto ip6_input_cleanup;
2028 }
2029 }
2030
2031 options_done:
2032
2033 /* p points to IPv6 header again for raw_input. */
2034 pbuf_add_header_force(p, hlen_tot);
2035 /* send to upper layers */
2036 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n"));
2037 ip6_debug_print(p);
2038 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
2039
2040 ip_data.current_ip_header_tot_len = hlen_tot;
2041 #if IP_STATS
2042 /* Successfully received bytes */
2043 STATS_INC_NUM(ip6.ip_rx_bytes, p->tot_len);
2044 #endif
2045
2046 struct ip6_hdr *ip6hdrtmp = (struct ip6_hdr *)p->payload;
2047 u8_t proto = IP6H_NEXTH(ip6hdrtmp);
2048 s8_t is_chksum_invalid = 0;
2049 /* fragmentation data all merged will be given app */
2050 if ((proto == IP6_NEXTH_FRAGMENT) || (proto == IP6_NEXTH_HOPBYHOP)) {
2051 proto = *nexth;
2052 }
2053 #if LWIP_RIPPLE && defined(LWIP_NA_PROXY) && LWIP_NA_PROXY
2054 if ((p->na_proxy == lwIP_TRUE) && (*nexth != IP6_NEXTH_ICMP6)) {
2055 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input:not icmp6, na_proxy return..\n"));
2056 (void)pbuf_free(p);
2057 goto ip6_input_cleanup;
2058 }
2059 #endif
2060 /* Point to payload. */
2061 pbuf_remove_header(p, hlen_tot);
2062 #if LWIP_RAW
2063 /*
2064 * @page RFC-2292 RFC-2292
2065 * @par Compliant Sections
2066 * Section 3. IPv6 Raw Sockets
2067 * Section 3.1. Checksums
2068 * Section 3.2. ICMPv6 Type Filtering
2069 * @par Behavior Description
2070 * Support IPv6 raw sockets.
2071 * Support IPv6 raw checksums.
2072 * Support ICMPv6 Type Filtering.
2073 * @par Non-Compliant Section
2074 * Section 4. Ancillary Data
2075 * @par Behavior Description
2076 * Ancillary data is not supported.
2077 */
2078 /* raw input did not eat the packet? */
2079 raw_status = raw_input6(p, proto, &is_chksum_invalid);
2080 if (is_chksum_invalid) {
2081 /* checksum validation is failed */
2082 /* It means packet is not given to application either due to checksum failure or some
2083 * or some other recv failure at the application side.
2084 */
2085 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input:Failed in checksum validation proto = %"U16_F" \n", proto));
2086 (void)pbuf_free(p);
2087 IP6_STATS_INC(ip6.chkerr);
2088 IP6_STATS_INC(ip6.drop);
2089 goto ip6_input_cleanup;
2090 }
2091
2092 #endif /* LWIP_RAW */
2093 switch (*nexth) {
2094 case IP6_NEXTH_NONE:
2095 pbuf_free(p);
2096 break;
2097 #if LWIP_UDP
2098 case IP6_NEXTH_UDP:
2099 #if LWIP_UDPLITE
2100 case IP6_NEXTH_UDPLITE:
2101 #endif /* LWIP_UDPLITE */
2102 udp_input(p, inp);
2103 break;
2104 #endif /* LWIP_UDP */
2105 #if LWIP_TCP
2106 case IP6_NEXTH_TCP:
2107 tcp_input(p, inp);
2108 break;
2109 #endif /* LWIP_TCP */
2110 #if LWIP_ICMP6
2111 case IP6_NEXTH_ICMP6:
2112 icmp6_input(p, inp);
2113 break;
2114 #endif /* LWIP_ICMP */
2115 default:
2116 #if LWIP_RAW
2117 if (raw_status != RAW_INPUT_NONE) {
2118 /* @todo: ipv6 mib in-delivers? */
2119 } else
2120 #endif /* LWIP_RAW */
2121 {
2122 #if LWIP_ICMP6
2123 /* p points to IPv6 header again for raw_input. */
2124 pbuf_add_header_force(p, hlen_tot);
2125 /* send ICMP parameter problem unless it was a multicast or ICMPv6 */
2126 if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) &&
2127 (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
2128 icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
2129 }
2130 #endif /* LWIP_ICMP */
2131 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr)));
2132 IP6_STATS_INC(ip6.proterr);
2133 IP6_STATS_INC(ip6.drop);
2134 }
2135 pbuf_free(p);
2136 break;
2137 }
2138
2139 ip6_input_cleanup:
2140 ip_data.current_netif = NULL;
2141 ip_data.current_input_netif = NULL;
2142 ip_data.current_ip6_header = NULL;
2143 ip_data.current_ip_header_tot_len = 0;
2144 ip6_addr_set_zero(ip6_current_src_addr());
2145 ip6_addr_set_zero(ip6_current_dest_addr());
2146
2147 return ERR_OK;
2148 }
2149
2150
2151 /**
2152 * Sends an IPv6 packet on a network interface. This function constructs
2153 * the IPv6 header. If the source IPv6 address is NULL, the IPv6 "ANY" address is
2154 * used as source (usually during network startup). If the source IPv6 address it
2155 * IP6_ADDR_ANY, the most appropriate IPv6 address of the outgoing network
2156 * interface is filled in as source address. If the destination IPv6 address is
2157 * LWIP_IP_HDRINCL, p is assumed to already include an IPv6 header and
2158 * p->payload points to it instead of the data.
2159 *
2160 * @param p the packet to send (p->payload points to the data, e.g. next
2161 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
2162 IPv6 header and p->payload points to that IPv6 header)
2163 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
2164 * IP address of the netif is selected and used as source address.
2165 * if src == NULL, IP6_ADDR_ANY is used as source) (src is possibly not
2166 * properly zoned)
2167 * @param dest the destination IPv6 address to send the packet to (possibly not
2168 * properly zoned)
2169 * @param hl the Hop Limit value to be set in the IPv6 header
2170 * @param tc the Traffic Class value to be set in the IPv6 header
2171 * @param nexth the Next Header to be set in the IPv6 header
2172 * @param netif the netif on which to send this packet
2173 * @return ERR_OK if the packet was sent OK
2174 * ERR_BUF if p doesn't have enough space for IPv6/LINK headers
2175 * returns errors returned by netif->output_ip6
2176 */
2177 err_t
ip6_output_if(struct pbuf * p,const ip6_addr_t * src,const ip6_addr_t * dest,u8_t hl,u8_t tc,u8_t nexth,struct netif * netif)2178 ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
2179 u8_t hl, u8_t tc,
2180 u8_t nexth, struct netif *netif)
2181 {
2182 const ip6_addr_t *src_used = src;
2183 if (dest != LWIP_IP_HDRINCL) {
2184 if (src != NULL && ip6_addr_isany(src)) {
2185 src_used = ip_2_ip6(ip6_select_source_address(netif, dest));
2186 if ((src_used == NULL) || ip6_addr_isany(src_used)) {
2187 /* No appropriate source address was found for this packet. */
2188 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n"));
2189 IP6_STATS_INC(ip6.rterr);
2190 return ERR_RTE;
2191 }
2192 }
2193 }
2194 return ip6_output_if_src(p, src_used, dest, hl, tc, nexth, netif);
2195 }
2196
2197 /**
2198 * Same as ip6_output_if() but 'src' address is not replaced by netif address
2199 * when it is 'any'.
2200 */
2201 err_t
ip6_output_if_src(struct pbuf * p,const ip6_addr_t * src,const ip6_addr_t * dest,u8_t hl,u8_t tc,u8_t nexth,struct netif * netif)2202 ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
2203 u8_t hl, u8_t tc,
2204 u8_t nexth, struct netif *netif)
2205 {
2206 struct ip6_hdr *ip6hdr;
2207 ip6_addr_t dest_addr;
2208
2209 LWIP_ASSERT_CORE_LOCKED();
2210 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
2211
2212 /* Should the IPv6 header be generated or is it already included in p? */
2213 if (dest != LWIP_IP_HDRINCL) {
2214 #if LWIP_IPV6_SCOPES
2215 /* If the destination address is scoped but lacks a zone, add a zone now,
2216 * based on the outgoing interface. The lower layers (e.g., nd6) absolutely
2217 * require addresses to be properly zoned for correctness. In some cases,
2218 * earlier attempts will have been made to add a zone to the destination,
2219 * but this function is the only one that is called in all (other) cases,
2220 * so we must do this here. */
2221 if (ip6_addr_lacks_zone(dest, IP6_UNKNOWN)) {
2222 ip6_addr_copy(dest_addr, *dest);
2223 ip6_addr_assign_zone(&dest_addr, IP6_UNKNOWN, netif);
2224 dest = &dest_addr;
2225 }
2226 #endif /* LWIP_IPV6_SCOPES */
2227
2228 #if LWIP_RIPPLE
2229 if (nexth == IP6_NEXTH_ICMP6) {
2230 /* check ICMP type is neither Echo request nor Echo reply */
2231 if ((*((u8_t *)p->payload) != ICMP6_TYPE_EREQ) && (*((u8_t *)p->payload) != ICMP6_TYPE_EREP)) {
2232 p->flags |= PBUF_FLAG_CTRL_PKT;
2233 #if LWIP_SO_PRIORITY
2234 p->priority = LWIP_PKT_PRIORITY_CTRL;
2235 #endif /* LWIP_SO_PRIORITY */
2236 }
2237 }
2238 #endif /* LWIP_RIPPLE */
2239 /* generate IPv6 header */
2240 if (pbuf_add_header(p, IP6_HLEN)) {
2241 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n"));
2242 IP6_STATS_INC(ip6.err);
2243 return ERR_BUF;
2244 }
2245
2246 ip6hdr = (struct ip6_hdr *)p->payload;
2247 LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr",
2248 (p->len >= sizeof(struct ip6_hdr)));
2249
2250 IP6H_HOPLIM_SET(ip6hdr, hl);
2251 IP6H_NEXTH_SET(ip6hdr, nexth);
2252
2253 /* dest cannot be NULL here */
2254 ip6_addr_copy_to_packed(ip6hdr->dest, *dest);
2255
2256 IP6H_VTCFL_SET(ip6hdr, 6, tc, 0);
2257 IP6H_PLEN_SET(ip6hdr, (u16_t)(p->tot_len - IP6_HLEN));
2258
2259 if (src == NULL) {
2260 src = IP6_ADDR_ANY6;
2261 }
2262 /* src cannot be NULL here */
2263 ip6_addr_copy_to_packed(ip6hdr->src, *src);
2264
2265 } else {
2266 /* IP header already included in p */
2267 ip6hdr = (struct ip6_hdr *)p->payload;
2268 ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
2269 ip6_addr_assign_zone(&dest_addr, IP6_UNKNOWN, netif);
2270 dest = &dest_addr;
2271 }
2272
2273 IP6_STATS_INC(ip6.xmit);
2274 #if IP_STATS
2275 STATS_INC_NUM(ip6.ip_tx_bytes, p->tot_len);
2276 #endif
2277
2278 LWIP_DEBUGF(IP6_DEBUG, ("ip6_output_if: %s%"U16_F"\n", netif->name, (u16_t)netif->num));
2279 ip6_debug_print(p);
2280
2281 #if ENABLE_LOOPBACK
2282 {
2283 int i;
2284 #if !LWIP_HAVE_LOOPIF
2285 if (ip6_addr_isloopback(dest)) {
2286 return netif_loop_output(netif, p);
2287 }
2288 #endif /* !LWIP_HAVE_LOOPIF */
2289 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
2290 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
2291 ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) {
2292 /* Packet to self, enqueue it for loopback */
2293 LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n"));
2294 return netif_loop_output(netif, p);
2295 }
2296 }
2297 }
2298 #if LWIP_MULTICAST_TX_OPTIONS
2299 if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
2300 netif_loop_output(netif, p);
2301 }
2302 #endif /* LWIP_MULTICAST_TX_OPTIONS */
2303 #endif /* ENABLE_LOOPBACK */
2304 #if LWIP_RIPPLE
2305 if ((!ip6_addr_islinklocal(dest)) &&
2306 (!ip6_addr_ismulticast(dest)) &&
2307 (p->flags & PBUF_FLAG_HBH_SPACE) &&
2308 lwip_rpl_is_rpl_netif(netif)) {
2309 struct pbuf *new_p = NULL;
2310 /* add Hop by Hop header for rpl. If space for HBH is not allocated then pbuf will be expanded. */
2311 (void)ip6_route(src, dest);
2312
2313 if (lwip_get_pkt_route_status()) {
2314 p->pkt_up = lwIP_TRUE;
2315 } else {
2316 p->pkt_up = lwIP_FALSE;
2317 }
2318 new_p = lwip_add_rpi_hdr(p, nexth, lwip_hbh_len(p), 1);
2319 if (new_p == NULL) {
2320 LWIP_ERROR("Could not add HBH header.\n", 0, ;);
2321 IP6_STATS_INC(ip6.err);
2322 return ERR_BUF;
2323 } else {
2324 p = new_p;
2325 }
2326 }
2327 #endif /* LWIP_RIPPLE */
2328 #if LWIP_IPV6_FRAG
2329 /* don't fragment if interface has mtu set to 0 [loopif] */
2330 if (netif_mtu6(netif) && (p->tot_len > nd6_get_destination_mtu(dest, netif))) {
2331 return ip6_frag(p, netif, dest);
2332 }
2333 #endif /* LWIP_IPV6_FRAG */
2334
2335 LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n"));
2336 return netif->output_ip6(netif, p, dest);
2337 }
2338
2339 /**
2340 * Simple interface to ip6_output_if. It finds the outgoing network
2341 * interface and calls upon ip6_output_if to do the actual work.
2342 *
2343 * @param p the packet to send (p->payload points to the data, e.g. next
2344 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
2345 IPv6 header and p->payload points to that IPv6 header)
2346 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
2347 * IP address of the netif is selected and used as source address.
2348 * if src == NULL, IP6_ADDR_ANY is used as source)
2349 * @param dest the destination IPv6 address to send the packet to
2350 * @param hl the Hop Limit value to be set in the IPv6 header
2351 * @param tc the Traffic Class value to be set in the IPv6 header
2352 * @param nexth the Next Header to be set in the IPv6 header
2353 *
2354 * @return ERR_RTE if no route is found
2355 * see ip_output_if() for more return values
2356 */
2357 err_t
ip6_output(struct pbuf * p,const ip6_addr_t * src,const ip6_addr_t * dest,u8_t hl,u8_t tc,u8_t nexth)2358 ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
2359 u8_t hl, u8_t tc, u8_t nexth)
2360 {
2361 struct netif *netif;
2362 struct ip6_hdr *ip6hdr;
2363 ip6_addr_t src_addr, dest_addr;
2364
2365 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
2366
2367 IP6_ADDR(&dest_addr, 0, 0, 0, 0);
2368
2369 if (dest != LWIP_IP_HDRINCL) {
2370 netif = ip6_route(src, dest);
2371 } else {
2372 /* IP header included in p, read addresses. */
2373 ip6hdr = (struct ip6_hdr *)p->payload;
2374 ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
2375 ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
2376 netif = ip6_route(&src_addr, &dest_addr);
2377 dest = &dest_addr;
2378 }
2379
2380 if (netif == NULL) {
2381 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",
2382 IP6_ADDR_BLOCK1(dest),
2383 IP6_ADDR_BLOCK2(dest),
2384 IP6_ADDR_BLOCK3(dest),
2385 IP6_ADDR_BLOCK4(dest),
2386 IP6_ADDR_BLOCK5(dest),
2387 IP6_ADDR_BLOCK6(dest),
2388 IP6_ADDR_BLOCK7(dest),
2389 IP6_ADDR_BLOCK8(dest)));
2390 IP6_STATS_INC(ip6.rterr);
2391 return ERR_RTE;
2392 }
2393
2394 return ip6_output_if(p, src, dest, hl, tc, nexth, netif);
2395 }
2396
2397
2398 #if LWIP_NETIF_USE_HINTS
2399 /** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint
2400 * before calling ip6_output_if.
2401 *
2402 * @param p the packet to send (p->payload points to the data, e.g. next
2403 protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
2404 IPv6 header and p->payload points to that IPv6 header)
2405 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
2406 * IP address of the netif is selected and used as source address.
2407 * if src == NULL, IP6_ADDR_ANY is used as source)
2408 * @param dest the destination IPv6 address to send the packet to
2409 * @param hl the Hop Limit value to be set in the IPv6 header
2410 * @param tc the Traffic Class value to be set in the IPv6 header
2411 * @param nexth the Next Header to be set in the IPv6 header
2412 * @param netif_hint netif output hint pointer set to netif->hint before
2413 * calling ip_output_if()
2414 *
2415 * @return ERR_RTE if no route is found
2416 * see ip_output_if() for more return values
2417 */
2418 err_t
ip6_output_hinted(struct pbuf * p,const ip6_addr_t * src,const ip6_addr_t * dest,u8_t hl,u8_t tc,u8_t nexth,struct netif_hint * netif_hint)2419 ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
2420 u8_t hl, u8_t tc, u8_t nexth, struct netif_hint *netif_hint)
2421 {
2422 struct netif *netif;
2423 struct ip6_hdr *ip6hdr;
2424 ip6_addr_t src_addr, dest_addr;
2425 err_t err;
2426
2427 LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
2428
2429 if (dest != LWIP_IP_HDRINCL) {
2430 netif = ip6_route(src, dest);
2431 } else {
2432 /* IP header included in p, read addresses. */
2433 ip6hdr = (struct ip6_hdr *)p->payload;
2434 ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
2435 ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
2436 netif = ip6_route(&src_addr, &dest_addr);
2437 dest = &dest_addr;
2438 }
2439
2440 if (netif == NULL) {
2441 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",
2442 IP6_ADDR_BLOCK1(dest),
2443 IP6_ADDR_BLOCK2(dest),
2444 IP6_ADDR_BLOCK3(dest),
2445 IP6_ADDR_BLOCK4(dest),
2446 IP6_ADDR_BLOCK5(dest),
2447 IP6_ADDR_BLOCK6(dest),
2448 IP6_ADDR_BLOCK7(dest),
2449 IP6_ADDR_BLOCK8(dest)));
2450 IP6_STATS_INC(ip6.rterr);
2451 return ERR_RTE;
2452 }
2453
2454 NETIF_SET_HINTS(netif, netif_hint);
2455 err = ip6_output_if(p, src, dest, hl, tc, nexth, netif);
2456 NETIF_RESET_HINTS(netif);
2457
2458 return err;
2459 }
2460 #endif /* LWIP_NETIF_USE_HINTS*/
2461
2462 #if LWIP_IPV6_MLD
2463 /**
2464 * Add a hop-by-hop options header with a router alert option and padding.
2465 *
2466 * Used by MLD when sending a Multicast listener report/done message.
2467 *
2468 * @param p the packet to which we will prepend the options header
2469 * @param nexth the next header protocol number (e.g. IP6_NEXTH_ICMP6)
2470 * @param value the value of the router alert option data (e.g. IP6_ROUTER_ALERT_VALUE_MLD)
2471 * @return ERR_OK if hop-by-hop header was added, ERR_* otherwise
2472 */
2473 err_t
ip6_options_add_hbh_ra(struct pbuf * p,u8_t nexth,u8_t value)2474 ip6_options_add_hbh_ra(struct pbuf *p, u8_t nexth, u8_t value)
2475 {
2476 u8_t *opt_data;
2477 u32_t offset = 0;
2478 struct ip6_hbh_hdr *hbh_hdr;
2479 struct ip6_opt_hdr *opt_hdr;
2480
2481 /* fixed 4 bytes for router alert option and 2 bytes padding */
2482 const u8_t hlen = sizeof(struct ip6_hbh_hdr) + sizeof(struct ip6_opt_hdr) + IP6_ROUTER_ALERT_DLEN;
2483 /* Move pointer to make room for hop-by-hop options header. */
2484 if (pbuf_add_header(p, sizeof(struct ip6_hbh_hdr) + hlen)) {
2485 LWIP_DEBUGF(IP6_DEBUG, ("ip6_options: no space for options header\n"));
2486 IP6_STATS_INC(ip6.err);
2487 return ERR_BUF;
2488 }
2489
2490 /* Set fields of Hop-by-Hop header */
2491 hbh_hdr = (struct ip6_hbh_hdr *)p->payload;
2492 IP6_HBH_NEXTH(hbh_hdr) = nexth;
2493 hbh_hdr->_hlen = 0;
2494 offset = IP6_HBH_HLEN;
2495
2496 /* Set router alert options to Hop-by-Hop extended option header */
2497 opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + offset);
2498 IP6_OPT_TYPE(opt_hdr) = IP6_ROUTER_ALERT_OPTION;
2499 IP6_OPT_DLEN(opt_hdr) = IP6_ROUTER_ALERT_DLEN;
2500 offset += IP6_OPT_HLEN;
2501
2502 /* Set router alert option data */
2503 opt_data = (u8_t *)hbh_hdr + offset;
2504 opt_data[0] = value;
2505 opt_data[1] = 0;
2506 offset += IP6_OPT_DLEN(opt_hdr);
2507
2508 /* add 2 bytes padding to make 8 bytes Hop-by-Hop header length */
2509 opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + offset);
2510 IP6_OPT_TYPE(opt_hdr) = IP6_PADN_OPTION;
2511 IP6_OPT_DLEN(opt_hdr) = 0;
2512
2513 return ERR_OK;
2514 }
2515 #endif /* LWIP_IPV6_MLD */
2516
2517 #if LWIP_IPV6_FILTER
2518 /*
2519 * Set ip filter for input packet.
2520 */
set_ip6_filter(ip_filter_fn filter_fn)2521 err_t set_ip6_filter(ip_filter_fn filter_fn)
2522 {
2523 ip6_filter = filter_fn;
2524 return ERR_OK;
2525 }
2526 #endif /* LWIP_IPV6_FILTER */
2527
2528 #if IP6_DEBUG
2529 /* Print an IPv6 header by using LWIP_DEBUGF
2530 * @param p an IPv6 packet, p->payload pointing to the IPv6 header
2531 */
2532 void
ip6_debug_print(struct pbuf * p)2533 ip6_debug_print(struct pbuf *p)
2534 {
2535 struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload;
2536
2537 LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n"));
2538 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
2539 LWIP_DEBUGF(IP6_DEBUG, ("| %2"U16_F" | %3"U16_F" | %7"U32_F" | (ver, class, flow)\n",
2540 IP6H_V(ip6hdr),
2541 IP6H_TC(ip6hdr),
2542 IP6H_FL(ip6hdr)));
2543 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
2544 LWIP_DEBUGF(IP6_DEBUG, ("| %5"U16_F" | %3"U16_F" | %3"U16_F" | (plen, nexth, hopl)\n",
2545 IP6H_PLEN(ip6hdr),
2546 IP6H_NEXTH(ip6hdr),
2547 IP6H_HOPLIM(ip6hdr)));
2548 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
2549 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (src)\n",
2550 IP6_ADDR_BLOCK1(&(ip6hdr->src)),
2551 IP6_ADDR_BLOCK2(&(ip6hdr->src)),
2552 IP6_ADDR_BLOCK3(&(ip6hdr->src)),
2553 IP6_ADDR_BLOCK4(&(ip6hdr->src))));
2554 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n",
2555 IP6_ADDR_BLOCK5(&(ip6hdr->src)),
2556 IP6_ADDR_BLOCK6(&(ip6hdr->src)),
2557 IP6_ADDR_BLOCK7(&(ip6hdr->src)),
2558 IP6_ADDR_BLOCK8(&(ip6hdr->src))));
2559 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
2560 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (dest)\n",
2561 IP6_ADDR_BLOCK1(&(ip6hdr->dest)),
2562 IP6_ADDR_BLOCK2(&(ip6hdr->dest)),
2563 IP6_ADDR_BLOCK3(&(ip6hdr->dest)),
2564 IP6_ADDR_BLOCK4(&(ip6hdr->dest))));
2565 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n",
2566 IP6_ADDR_BLOCK5(&(ip6hdr->dest)),
2567 IP6_ADDR_BLOCK6(&(ip6hdr->dest)),
2568 IP6_ADDR_BLOCK7(&(ip6hdr->dest)),
2569 IP6_ADDR_BLOCK8(&(ip6hdr->dest))));
2570 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
2571
2572 if (IP6H_NEXTH(ip6hdr) == IP6_NEXTH_ICMP6)
2573 {
2574 struct icmpv6_hdr *icmp6hdr;
2575 pbuf_header(p, (s16_t)(-(s16_t)IP6_HLEN));
2576 icmp6hdr = (struct icmpv6_hdr *)p->payload;
2577 LWIP_DEBUGF(IP6_DEBUG, ("| %8"U16_F" | %8"U16_F" | (ICMPv6-Type, ICMPv6-Code)\n",
2578 icmp6hdr->type,
2579 icmp6hdr->code));
2580 pbuf_header(p, (s16_t)((s16_t)IP6_HLEN));
2581 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
2582
2583 }
2584 }
2585 #endif /* IP6_DEBUG */
2586
2587 #endif /* LWIP_IPV6 */
2588