The Pedigree Project 0.1
ip6.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
26/*
27 * Copyright (c) 2010 Inico Technologies Ltd.
28 * All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without modification,
31 * are permitted provided that the following conditions are met:
32 *
33 * 1. Redistributions of source code must retain the above copyright notice,
34 * this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright notice,
36 * this list of conditions and the following disclaimer in the documentation
37 * and/or other materials provided with the distribution.
38 * 3. The name of the author may not be used to endorse or promote products
39 * derived from this software without specific prior written permission.
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
43 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
44 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
46 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
47 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
48 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
49 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
50 * OF SUCH DAMAGE.
51 *
52 * This file is part of the lwIP TCP/IP stack.
53 *
54 * Author: Ivan Delamer <delamer@inicotech.com>
55 *
56 *
57 * Please coordinate changes and requests with Ivan Delamer
58 * <delamer@inicotech.com>
59 */
60
61#include "lwip/opt.h"
62
63#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
64
65#include "lwip/def.h"
66#include "lwip/mem.h"
67#include "lwip/netif.h"
68#include "lwip/ip.h"
69#include "lwip/ip6.h"
70#include "lwip/ip6_addr.h"
71#include "lwip/ip6_frag.h"
72#include "lwip/icmp6.h"
73#include "lwip/raw.h"
74#include "lwip/udp.h"
75#include "lwip/priv/tcp_priv.h"
76#include "lwip/dhcp6.h"
77#include "lwip/nd6.h"
78#include "lwip/mld6.h"
79#include "lwip/debug.h"
80#include "lwip/stats.h"
81
82#ifdef LWIP_HOOK_FILENAME
83#include LWIP_HOOK_FILENAME
84#endif
85
102struct netif *
103ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
104{
105 struct netif *netif;
106 s8_t i;
107
108 /* If single netif configuration, fast return. */
109 if ((netif_list != NULL) && (netif_list->next == NULL)) {
111 return NULL;
112 }
113 return netif_list;
114 }
115
116 /* Special processing for link-local addresses. */
117 if (ip6_addr_islinklocal(dest)) {
118 if (ip6_addr_isany(src)) {
119 /* Use default netif, if Up. */
120 if (netif_default == NULL || !netif_is_up(netif_default) ||
122 return NULL;
123 }
124 return netif_default;
125 }
126
127 /* Try to find the netif for the source address, checking that link is up. */
128 for (netif = netif_list; netif != NULL; netif = netif->next) {
130 continue;
131 }
132 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
133 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
134 ip6_addr_cmp(src, netif_ip6_addr(netif, i))) {
135 return netif;
136 }
137 }
138 }
139
140 /* netif not found, use default netif, if up */
141 if (netif_default == NULL || !netif_is_up(netif_default) ||
143 return NULL;
144 }
145 return netif_default;
146 }
147
148 /* we come here for non-link-local addresses */
149#ifdef LWIP_HOOK_IP6_ROUTE
150 netif = LWIP_HOOK_IP6_ROUTE(src, dest);
151 if (netif != NULL) {
152 return netif;
153 }
154#endif
155
156 /* See if the destination subnet matches a configured address. */
157 for (netif = netif_list; netif != NULL; netif = netif->next) {
159 continue;
160 }
161 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
162 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
163 ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) {
164 return netif;
165 }
166 }
167 }
168
169 /* Get the netif for a suitable router. */
170 netif = nd6_find_route(dest);
171 if ((netif != NULL) && netif_is_up(netif) && netif_is_link_up(netif)) {
172 return netif;
173 }
174
175 /* try with the netif that matches the source address. */
176 if (!ip6_addr_isany(src)) {
177 for (netif = netif_list; netif != NULL; netif = netif->next) {
179 continue;
180 }
181 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
182 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
183 ip6_addr_cmp(src, netif_ip6_addr(netif, i))) {
184 return netif;
185 }
186 }
187 }
188 }
189
190#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
191 /* loopif is disabled, loopback traffic is passed through any netif */
192 if (ip6_addr_isloopback(dest)) {
193 /* don't check for link on loopback traffic */
194 if (netif_default != NULL && netif_is_up(netif_default)) {
195 return netif_default;
196 }
197 /* default netif is not up, just use any netif for loopback traffic */
198 for (netif = netif_list; netif != NULL; netif = netif->next) {
199 if (netif_is_up(netif)) {
200 return netif;
201 }
202 }
203 return NULL;
204 }
205#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
206
207 /* no matching netif found, use default netif, if up */
209 return NULL;
210 }
211 return netif_default;
212}
213
225const ip_addr_t *
226ip6_select_source_address(struct netif *netif, const ip6_addr_t *dest)
227{
228 const ip_addr_t *src = NULL;
229 u8_t i;
230
231 /* If dest is link-local, choose a link-local source. */
232 if (ip6_addr_islinklocal(dest) || ip6_addr_ismulticast_linklocal(dest) || ip6_addr_ismulticast_iflocal(dest)) {
233 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
234 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
235 ip6_addr_islinklocal(netif_ip6_addr(netif, i))) {
236 return netif_ip_addr6(netif, i);
237 }
238 }
239 }
240
241 /* Choose a site-local with matching prefix. */
242 if (ip6_addr_issitelocal(dest) || ip6_addr_ismulticast_sitelocal(dest)) {
243 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
244 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
245 ip6_addr_issitelocal(netif_ip6_addr(netif, i)) &&
246 ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) {
247 return netif_ip_addr6(netif, i);
248 }
249 }
250 }
251
252 /* Choose a unique-local with matching prefix. */
253 if (ip6_addr_isuniquelocal(dest) || ip6_addr_ismulticast_orglocal(dest)) {
254 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
255 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
256 ip6_addr_isuniquelocal(netif_ip6_addr(netif, i)) &&
257 ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) {
258 return netif_ip_addr6(netif, i);
259 }
260 }
261 }
262
263 /* Choose a global with best matching prefix. */
264 if (ip6_addr_isglobal(dest) || ip6_addr_ismulticast_global(dest)) {
265 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
266 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
267 ip6_addr_isglobal(netif_ip6_addr(netif, i))) {
268 if (src == NULL) {
269 src = netif_ip_addr6(netif, i);
270 }
271 else {
272 /* Replace src only if we find a prefix match. */
273 /* @todo find longest matching prefix. */
274 if ((!(ip6_addr_netcmp(ip_2_ip6(src), dest))) &&
275 ip6_addr_netcmp(netif_ip6_addr(netif, i), dest)) {
276 src = netif_ip_addr6(netif, i);
277 }
278 }
279 }
280 }
281 if (src != NULL) {
282 return src;
283 }
284 }
285
286 /* Last resort: see if arbitrary prefix matches. */
287 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
288 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
289 ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) {
290 return netif_ip_addr6(netif, i);
291 }
292 }
293
294 return NULL;
295}
296
297#if LWIP_IPV6_FORWARD
307static void
308ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
309{
310 struct netif *netif;
311
312 /* do not forward link-local or loopback addresses */
313 if (ip6_addr_islinklocal(ip6_current_dest_addr()) ||
314 ip6_addr_isloopback(ip6_current_dest_addr())) {
315 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n"));
316 IP6_STATS_INC(ip6.rterr);
317 IP6_STATS_INC(ip6.drop);
318 return;
319 }
320
321 /* Find network interface where to forward this IP packet to. */
322 netif = ip6_route(IP6_ADDR_ANY6, ip6_current_dest_addr());
323 if (netif == NULL) {
324 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",
325 IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
326 IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
327 IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
328 IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
329 IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
330 IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
331 IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
332 IP6_ADDR_BLOCK8(ip6_current_dest_addr())));
333#if LWIP_ICMP6
334 /* Don't send ICMP messages in response to ICMP messages */
335 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
336 icmp6_dest_unreach(p, ICMP6_DUR_NO_ROUTE);
337 }
338#endif /* LWIP_ICMP6 */
339 IP6_STATS_INC(ip6.rterr);
340 IP6_STATS_INC(ip6.drop);
341 return;
342 }
343 /* Do not forward packets onto the same network interface on which
344 * they arrived. */
345 if (netif == inp) {
346 LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not bouncing packets back on incoming interface.\n"));
347 IP6_STATS_INC(ip6.rterr);
348 IP6_STATS_INC(ip6.drop);
349 return;
350 }
351
352 /* decrement HL */
353 IP6H_HOPLIM_SET(iphdr, IP6H_HOPLIM(iphdr) - 1);
354 /* send ICMP6 if HL == 0 */
355 if (IP6H_HOPLIM(iphdr) == 0) {
356#if LWIP_ICMP6
357 /* Don't send ICMP messages in response to ICMP messages */
358 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
359 icmp6_time_exceeded(p, ICMP6_TE_HL);
360 }
361#endif /* LWIP_ICMP6 */
362 IP6_STATS_INC(ip6.drop);
363 return;
364 }
365
366 if (netif->mtu && (p->tot_len > netif->mtu)) {
367#if LWIP_ICMP6
368 /* Don't send ICMP messages in response to ICMP messages */
369 if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
370 icmp6_packet_too_big(p, netif->mtu);
371 }
372#endif /* LWIP_ICMP6 */
373 IP6_STATS_INC(ip6.drop);
374 return;
375 }
376
377 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",
378 IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
379 IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
380 IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
381 IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
382 IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
383 IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
384 IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
385 IP6_ADDR_BLOCK8(ip6_current_dest_addr())));
386
387 /* transmit pbuf on chosen interface */
388 netif->output_ip6(netif, p, ip6_current_dest_addr());
389 IP6_STATS_INC(ip6.fw);
390 IP6_STATS_INC(ip6.xmit);
391 return;
392}
393#endif /* LWIP_IPV6_FORWARD */
394
409err_t
410ip6_input(struct pbuf *p, struct netif *inp)
411{
412 struct ip6_hdr *ip6hdr;
413 struct netif *netif;
414 u8_t nexth;
415 u16_t hlen; /* the current header length */
416 u8_t i;
417#if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/
418 @todo
419 int check_ip_src=1;
420#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
421
422 IP6_STATS_INC(ip6.recv);
423
424 /* identify the IP header */
425 ip6hdr = (struct ip6_hdr *)p->payload;
426 if (IP6H_V(ip6hdr) != 6) {
427 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n",
428 IP6H_V(ip6hdr)));
429 pbuf_free(p);
430 IP6_STATS_INC(ip6.err);
431 IP6_STATS_INC(ip6.drop);
432 return ERR_OK;
433 }
434
435#ifdef LWIP_HOOK_IP6_INPUT
436 if (LWIP_HOOK_IP6_INPUT(p, inp)) {
437 /* the packet has been eaten */
438 return ERR_OK;
439 }
440#endif
441
442 /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
443 if ((IP6_HLEN > p->len) || ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len)) {
444 if (IP6_HLEN > p->len) {
446 ("IPv6 header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
447 (u16_t)IP6_HLEN, p->len));
448 }
449 if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) {
451 ("IPv6 (plen %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
452 (u16_t)(IP6H_PLEN(ip6hdr) + IP6_HLEN), p->tot_len));
453 }
454 /* free (drop) packet pbufs */
455 pbuf_free(p);
456 IP6_STATS_INC(ip6.lenerr);
457 IP6_STATS_INC(ip6.drop);
458 return ERR_OK;
459 }
460
461 /* Trim pbuf. This should have been done at the netif layer,
462 * but we'll do it anyway just to be sure that its done. */
463 pbuf_realloc(p, IP6_HLEN + IP6H_PLEN(ip6hdr));
464
465 /* copy IP addresses to aligned ip6_addr_t */
466 ip_addr_copy_from_ip6(ip_data.current_iphdr_dest, ip6hdr->dest);
467 ip_addr_copy_from_ip6(ip_data.current_iphdr_src, ip6hdr->src);
468
469 /* Don't accept virtual IPv4 mapped IPv6 addresses.
470 * Don't accept multicast source addresses. */
471 if (ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_dest)) ||
472 ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_src)) ||
473 ip6_addr_ismulticast(ip_2_ip6(&ip_data.current_iphdr_src))) {
474 IP6_STATS_INC(ip6.err);
475 IP6_STATS_INC(ip6.drop);
476 return ERR_OK;
477 }
478
479 /* current header pointer. */
480 ip_data.current_ip6_header = ip6hdr;
481
482 /* In netif, used in case we need to send ICMPv6 packets back. */
483 ip_data.current_netif = inp;
484 ip_data.current_input_netif = inp;
485
486 /* match packet against an interface, i.e. is this packet for us? */
487 if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
488 /* Always joined to multicast if-local and link-local all-nodes group. */
489 if (ip6_addr_isallnodes_iflocal(ip6_current_dest_addr()) ||
490 ip6_addr_isallnodes_linklocal(ip6_current_dest_addr())) {
491 netif = inp;
492 }
493#if LWIP_IPV6_MLD
494 else if (mld6_lookfor_group(inp, ip6_current_dest_addr())) {
495 netif = inp;
496 }
497#else /* LWIP_IPV6_MLD */
498 else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) {
499 /* Filter solicited node packets when MLD is not enabled
500 * (for Neighbor discovery). */
501 netif = NULL;
502 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
503 if (ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) &&
504 ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) {
505 netif = inp;
506 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %c%c\n",
507 netif->name[0], netif->name[1]));
508 break;
509 }
510 }
511 }
512#endif /* LWIP_IPV6_MLD */
513 else {
514 netif = NULL;
515 }
516 } else {
517 /* start trying with inp. if that's not acceptable, start walking the
518 list of configured netifs.
519 'first' is used as a boolean to mark whether we started walking the list */
520 int first = 1;
521 netif = inp;
522 do {
523 /* interface is up? */
524 if (netif_is_up(netif)) {
525 /* unicast to this interface address? address configured? */
526 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
527 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
528 ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i))) {
529 /* exit outer loop */
530 goto netif_found;
531 }
532 }
533 }
534 if (first) {
535 if (ip6_addr_islinklocal(ip6_current_dest_addr())
536#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
537 || ip6_addr_isloopback(ip6_current_dest_addr())
538#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
539 ) {
540 /* Do not match link-local addresses to other netifs. The loopback
541 * address is to be considered link-local and packets to it should be
542 * dropped on other interfaces, as per RFC 4291 Sec. 2.5.3. This
543 * requirement cannot be implemented in the case that loopback
544 * traffic is sent across a non-loopback interface, however.
545 */
546 netif = NULL;
547 break;
548 }
549 first = 0;
551 } else {
552 netif = netif->next;
553 }
554 if (netif == inp) {
555 netif = netif->next;
556 }
557 } while (netif != NULL);
558netif_found:
559 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n",
560 netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X'));
561 }
562
563 /* "::" packet source address? (used in duplicate address detection) */
564 if (ip6_addr_isany(ip6_current_src_addr()) &&
565 (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) {
566 /* packet source is not valid */
567 /* free (drop) packet pbufs */
568 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n"));
569 pbuf_free(p);
570 IP6_STATS_INC(ip6.drop);
571 goto ip6_input_cleanup;
572 }
573
574 /* packet not for us? */
575 if (netif == NULL) {
576 /* packet not for us, route or discard */
577 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_TRACE, ("ip6_input: packet not for us.\n"));
578#if LWIP_IPV6_FORWARD
579 /* non-multicast packet? */
580 if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
581 /* try to forward IP packet on (other) interfaces */
582 ip6_forward(p, ip6hdr, inp);
583 }
584#endif /* LWIP_IPV6_FORWARD */
585 pbuf_free(p);
586 goto ip6_input_cleanup;
587 }
588
589 /* current netif pointer. */
590 ip_data.current_netif = netif;
591
592 /* Save next header type. */
593 nexth = IP6H_NEXTH(ip6hdr);
594
595 /* Init header length. */
596 hlen = ip_data.current_ip_header_tot_len = IP6_HLEN;
597
598 /* Move to payload. */
599 pbuf_header(p, -IP6_HLEN);
600
601 /* Process known option extension headers, if present. */
602 while (nexth != IP6_NEXTH_NONE)
603 {
604 switch (nexth) {
605 case IP6_NEXTH_HOPBYHOP:
606 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n"));
607 /* Get next header type. */
608 nexth = *((u8_t *)p->payload);
609
610 /* Get the header length. */
611 hlen = 8 * (1 + *((u8_t *)p->payload + 1));
612 ip_data.current_ip_header_tot_len += hlen;
613
614 /* Skip over this header. */
615 if (hlen > p->len) {
617 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
618 hlen, p->len));
619 /* free (drop) packet pbufs */
620 pbuf_free(p);
621 IP6_STATS_INC(ip6.lenerr);
622 IP6_STATS_INC(ip6.drop);
623 goto ip6_input_cleanup;
624 }
625
626 pbuf_header(p, -(s16_t)hlen);
627 break;
628 case IP6_NEXTH_DESTOPTS:
629 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Destination options header\n"));
630 /* Get next header type. */
631 nexth = *((u8_t *)p->payload);
632
633 /* Get the header length. */
634 hlen = 8 * (1 + *((u8_t *)p->payload + 1));
635 ip_data.current_ip_header_tot_len += hlen;
636
637 /* Skip over this header. */
638 if (hlen > p->len) {
640 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
641 hlen, p->len));
642 /* free (drop) packet pbufs */
643 pbuf_free(p);
644 IP6_STATS_INC(ip6.lenerr);
645 IP6_STATS_INC(ip6.drop);
646 goto ip6_input_cleanup;
647 }
648
649 pbuf_header(p, -(s16_t)hlen);
650 break;
651 case IP6_NEXTH_ROUTING:
652 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n"));
653 /* Get next header type. */
654 nexth = *((u8_t *)p->payload);
655
656 /* Get the header length. */
657 hlen = 8 * (1 + *((u8_t *)p->payload + 1));
658 ip_data.current_ip_header_tot_len += hlen;
659
660 /* Skip over this header. */
661 if (hlen > p->len) {
663 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
664 hlen, p->len));
665 /* free (drop) packet pbufs */
666 pbuf_free(p);
667 IP6_STATS_INC(ip6.lenerr);
668 IP6_STATS_INC(ip6.drop);
669 goto ip6_input_cleanup;
670 }
671
672 pbuf_header(p, -(s16_t)hlen);
673 break;
674
675 case IP6_NEXTH_FRAGMENT:
676 {
677 struct ip6_frag_hdr *frag_hdr;
678 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n"));
679
680 frag_hdr = (struct ip6_frag_hdr *)p->payload;
681
682 /* Get next header type. */
683 nexth = frag_hdr->_nexth;
684
685 /* Fragment Header length. */
686 hlen = 8;
687 ip_data.current_ip_header_tot_len += hlen;
688
689 /* Make sure this header fits in current pbuf. */
690 if (hlen > p->len) {
692 ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
693 hlen, p->len));
694 /* free (drop) packet pbufs */
695 pbuf_free(p);
696 IP6_FRAG_STATS_INC(ip6_frag.lenerr);
697 IP6_FRAG_STATS_INC(ip6_frag.drop);
698 goto ip6_input_cleanup;
699 }
700
701 /* Offset == 0 and more_fragments == 0? */
702 if ((frag_hdr->_fragment_offset &
703 PP_HTONS(IP6_FRAG_OFFSET_MASK | IP6_FRAG_MORE_FLAG)) == 0) {
704 /* This is a 1-fragment packet, usually a packet that we have
705 * already reassembled. Skip this header anc continue. */
706 pbuf_header(p, -(s16_t)hlen);
707 } else {
708#if LWIP_IPV6_REASS
709
710 /* reassemble the packet */
711 p = ip6_reass(p);
712 /* packet not fully reassembled yet? */
713 if (p == NULL) {
714 goto ip6_input_cleanup;
715 }
716
717 /* Returned p point to IPv6 header.
718 * Update all our variables and pointers and continue. */
719 ip6hdr = (struct ip6_hdr *)p->payload;
720 nexth = IP6H_NEXTH(ip6hdr);
721 hlen = ip_data.current_ip_header_tot_len = IP6_HLEN;
722 pbuf_header(p, -IP6_HLEN);
723
724#else /* LWIP_IPV6_REASS */
725 /* free (drop) packet pbufs */
726 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header dropped (with LWIP_IPV6_REASS==0)\n"));
727 pbuf_free(p);
728 IP6_STATS_INC(ip6.opterr);
729 IP6_STATS_INC(ip6.drop);
730 goto ip6_input_cleanup;
731#endif /* LWIP_IPV6_REASS */
732 }
733 break;
734 }
735 default:
736 goto options_done;
737 break;
738 }
739 }
740options_done:
741
742 /* p points to IPv6 header again. */
744
745 /* send to upper layers */
746 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n"));
747 ip6_debug_print(p);
748 LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
749
750#if LWIP_RAW
751 /* raw input did not eat the packet? */
752 if (raw_input(p, inp) == 0)
753#endif /* LWIP_RAW */
754 {
755 switch (nexth) {
756 case IP6_NEXTH_NONE:
757 pbuf_free(p);
758 break;
759#if LWIP_UDP
760 case IP6_NEXTH_UDP:
761#if LWIP_UDPLITE
762 case IP6_NEXTH_UDPLITE:
763#endif /* LWIP_UDPLITE */
764 /* Point to payload. */
765 pbuf_header(p, -(s16_t)ip_data.current_ip_header_tot_len);
766 udp_input(p, inp);
767 break;
768#endif /* LWIP_UDP */
769#if LWIP_TCP
770 case IP6_NEXTH_TCP:
771 /* Point to payload. */
772 pbuf_header(p, -(s16_t)ip_data.current_ip_header_tot_len);
773 tcp_input(p, inp);
774 break;
775#endif /* LWIP_TCP */
776#if LWIP_ICMP6
777 case IP6_NEXTH_ICMP6:
778 /* Point to payload. */
779 pbuf_header(p, -(s16_t)ip_data.current_ip_header_tot_len);
780 icmp6_input(p, inp);
781 break;
782#endif /* LWIP_ICMP */
783 default:
784#if LWIP_ICMP6
785 /* send ICMP parameter problem unless it was a multicast or ICMPv6 */
786 if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) &&
787 (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
788 icmp6_param_problem(p, ICMP6_PP_HEADER, ip_data.current_ip_header_tot_len - hlen);
789 }
790#endif /* LWIP_ICMP */
791 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr)));
792 pbuf_free(p);
793 IP6_STATS_INC(ip6.proterr);
794 IP6_STATS_INC(ip6.drop);
795 break;
796 }
797 }
798
799ip6_input_cleanup:
800 ip_data.current_netif = NULL;
801 ip_data.current_input_netif = NULL;
802 ip_data.current_ip6_header = NULL;
803 ip_data.current_ip_header_tot_len = 0;
804 ip6_addr_set_zero(ip6_current_src_addr());
805 ip6_addr_set_zero(ip6_current_dest_addr());
806
807 return ERR_OK;
808}
809
810
835err_t
836ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
837 u8_t hl, u8_t tc,
838 u8_t nexth, struct netif *netif)
839{
840 const ip6_addr_t *src_used = src;
841 if (dest != LWIP_IP_HDRINCL) {
842 if (src != NULL && ip6_addr_isany(src)) {
843 src_used = ip_2_ip6(ip6_select_source_address(netif, dest));
844 if ((src_used == NULL) || ip6_addr_isany(src_used)) {
845 /* No appropriate source address was found for this packet. */
846 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n"));
847 IP6_STATS_INC(ip6.rterr);
848 return ERR_RTE;
849 }
850 }
851 }
852 return ip6_output_if_src(p, src_used, dest, hl, tc, nexth, netif);
853}
854
859err_t
860ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
861 u8_t hl, u8_t tc,
862 u8_t nexth, struct netif *netif)
863{
864 struct ip6_hdr *ip6hdr;
865 ip6_addr_t dest_addr;
866
868
869 /* Should the IPv6 header be generated or is it already included in p? */
870 if (dest != LWIP_IP_HDRINCL) {
871 /* generate IPv6 header */
872 if (pbuf_header(p, IP6_HLEN)) {
873 LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n"));
874 IP6_STATS_INC(ip6.err);
875 return ERR_BUF;
876 }
877
878 ip6hdr = (struct ip6_hdr *)p->payload;
879 LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr",
880 (p->len >= sizeof(struct ip6_hdr)));
881
882 IP6H_HOPLIM_SET(ip6hdr, hl);
883 IP6H_NEXTH_SET(ip6hdr, nexth);
884
885 /* dest cannot be NULL here */
886 ip6_addr_copy(ip6hdr->dest, *dest);
887
888 IP6H_VTCFL_SET(ip6hdr, 6, tc, 0);
889 IP6H_PLEN_SET(ip6hdr, p->tot_len - IP6_HLEN);
890
891 if (src == NULL) {
892 src = IP6_ADDR_ANY6;
893 }
894 /* src cannot be NULL here */
895 ip6_addr_copy(ip6hdr->src, *src);
896
897 } else {
898 /* IP header already included in p */
899 ip6hdr = (struct ip6_hdr *)p->payload;
900 ip6_addr_copy(dest_addr, ip6hdr->dest);
901 dest = &dest_addr;
902 }
903
904 IP6_STATS_INC(ip6.xmit);
905
906 LWIP_DEBUGF(IP6_DEBUG, ("ip6_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num));
907 ip6_debug_print(p);
908
909#if ENABLE_LOOPBACK
910 {
911 int i;
912#if !LWIP_HAVE_LOOPIF
913 if (ip6_addr_isloopback(dest)) {
914 return netif_loop_output(netif, p);
915 }
916#endif /* !LWIP_HAVE_LOOPIF */
917 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
918 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
919 ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) {
920 /* Packet to self, enqueue it for loopback */
921 LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n"));
922 return netif_loop_output(netif, p);
923 }
924 }
925 }
926#endif /* ENABLE_LOOPBACK */
927#if LWIP_IPV6_FRAG
928 /* don't fragment if interface has mtu set to 0 [loopif] */
929 if (netif->mtu && (p->tot_len > nd6_get_destination_mtu(dest, netif))) {
930 return ip6_frag(p, netif, dest);
931 }
932#endif /* LWIP_IPV6_FRAG */
933
934 LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n"));
935 return netif->output_ip6(netif, p, dest);
936}
937
956err_t
957ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
958 u8_t hl, u8_t tc, u8_t nexth)
959{
960 struct netif *netif;
961 struct ip6_hdr *ip6hdr;
962 ip6_addr_t src_addr, dest_addr;
963
965
966 if (dest != LWIP_IP_HDRINCL) {
967 netif = ip6_route(src, dest);
968 } else {
969 /* IP header included in p, read addresses. */
970 ip6hdr = (struct ip6_hdr *)p->payload;
971 ip6_addr_copy(src_addr, ip6hdr->src);
972 ip6_addr_copy(dest_addr, ip6hdr->dest);
973 netif = ip6_route(&src_addr, &dest_addr);
974 }
975
976 if (netif == NULL) {
977 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",
978 IP6_ADDR_BLOCK1(dest),
979 IP6_ADDR_BLOCK2(dest),
980 IP6_ADDR_BLOCK3(dest),
981 IP6_ADDR_BLOCK4(dest),
982 IP6_ADDR_BLOCK5(dest),
983 IP6_ADDR_BLOCK6(dest),
984 IP6_ADDR_BLOCK7(dest),
985 IP6_ADDR_BLOCK8(dest)));
986 IP6_STATS_INC(ip6.rterr);
987 return ERR_RTE;
988 }
989
990 return ip6_output_if(p, src, dest, hl, tc, nexth, netif);
991}
992
993
994#if LWIP_NETIF_HWADDRHINT
1014err_t
1015ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
1016 u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint)
1017{
1018 struct netif *netif;
1019 struct ip6_hdr *ip6hdr;
1020 ip6_addr_t src_addr, dest_addr;
1021 err_t err;
1022
1024
1025 if (dest != LWIP_IP_HDRINCL) {
1026 netif = ip6_route(src, dest);
1027 } else {
1028 /* IP header included in p, read addresses. */
1029 ip6hdr = (struct ip6_hdr *)p->payload;
1030 ip6_addr_copy(src_addr, ip6hdr->src);
1031 ip6_addr_copy(dest_addr, ip6hdr->dest);
1032 netif = ip6_route(&src_addr, &dest_addr);
1033 }
1034
1035 if (netif == NULL) {
1036 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",
1037 IP6_ADDR_BLOCK1(dest),
1038 IP6_ADDR_BLOCK2(dest),
1039 IP6_ADDR_BLOCK3(dest),
1040 IP6_ADDR_BLOCK4(dest),
1041 IP6_ADDR_BLOCK5(dest),
1042 IP6_ADDR_BLOCK6(dest),
1043 IP6_ADDR_BLOCK7(dest),
1044 IP6_ADDR_BLOCK8(dest)));
1045 IP6_STATS_INC(ip6.rterr);
1046 return ERR_RTE;
1047 }
1048
1049 NETIF_SET_HWADDRHINT(netif, addr_hint);
1050 err = ip6_output_if(p, src, dest, hl, tc, nexth, netif);
1051 NETIF_SET_HWADDRHINT(netif, NULL);
1052
1053 return err;
1054}
1055#endif /* LWIP_NETIF_HWADDRHINT*/
1056
1057#if LWIP_IPV6_MLD
1068err_t
1069ip6_options_add_hbh_ra(struct pbuf *p, u8_t nexth, u8_t value)
1070{
1071 struct ip6_hbh_hdr *hbh_hdr;
1072
1073 /* Move pointer to make room for hop-by-hop options header. */
1074 if (pbuf_header(p, sizeof(struct ip6_hbh_hdr))) {
1075 LWIP_DEBUGF(IP6_DEBUG, ("ip6_options: no space for options header\n"));
1076 IP6_STATS_INC(ip6.err);
1077 return ERR_BUF;
1078 }
1079
1080 hbh_hdr = (struct ip6_hbh_hdr *)p->payload;
1081
1082 /* Set fields. */
1083 hbh_hdr->_nexth = nexth;
1084 hbh_hdr->_hlen = 0;
1085 hbh_hdr->_ra_opt_type = IP6_ROUTER_ALERT_OPTION;
1086 hbh_hdr->_ra_opt_dlen = 2;
1087 hbh_hdr->_ra_opt_data = value;
1088 hbh_hdr->_padn_opt_type = IP6_PADN_ALERT_OPTION;
1089 hbh_hdr->_padn_opt_dlen = 0;
1090
1091 return ERR_OK;
1092}
1093#endif /* LWIP_IPV6_MLD */
1094
1095#if IP6_DEBUG
1096/* Print an IPv6 header by using LWIP_DEBUGF
1097 * @param p an IPv6 packet, p->payload pointing to the IPv6 header
1098 */
1099void
1100ip6_debug_print(struct pbuf *p)
1101{
1102 struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload;
1103
1104 LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n"));
1105 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1106 LWIP_DEBUGF(IP6_DEBUG, ("| %2"U16_F" | %3"U16_F" | %7"U32_F" | (ver, class, flow)\n",
1107 IP6H_V(ip6hdr),
1108 IP6H_TC(ip6hdr),
1109 IP6H_FL(ip6hdr)));
1110 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1111 LWIP_DEBUGF(IP6_DEBUG, ("| %5"U16_F" | %3"U16_F" | %3"U16_F" | (plen, nexth, hopl)\n",
1112 IP6H_PLEN(ip6hdr),
1113 IP6H_NEXTH(ip6hdr),
1114 IP6H_HOPLIM(ip6hdr)));
1115 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1116 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (src)\n",
1117 IP6_ADDR_BLOCK1(&(ip6hdr->src)),
1118 IP6_ADDR_BLOCK2(&(ip6hdr->src)),
1119 IP6_ADDR_BLOCK3(&(ip6hdr->src)),
1120 IP6_ADDR_BLOCK4(&(ip6hdr->src))));
1121 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n",
1122 IP6_ADDR_BLOCK5(&(ip6hdr->src)),
1123 IP6_ADDR_BLOCK6(&(ip6hdr->src)),
1124 IP6_ADDR_BLOCK7(&(ip6hdr->src)),
1125 IP6_ADDR_BLOCK8(&(ip6hdr->src))));
1126 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1127 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (dest)\n",
1128 IP6_ADDR_BLOCK1(&(ip6hdr->dest)),
1129 IP6_ADDR_BLOCK2(&(ip6hdr->dest)),
1130 IP6_ADDR_BLOCK3(&(ip6hdr->dest)),
1131 IP6_ADDR_BLOCK4(&(ip6hdr->dest))));
1132 LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n",
1133 IP6_ADDR_BLOCK5(&(ip6hdr->dest)),
1134 IP6_ADDR_BLOCK6(&(ip6hdr->dest)),
1135 IP6_ADDR_BLOCK7(&(ip6hdr->dest)),
1136 IP6_ADDR_BLOCK8(&(ip6hdr->dest))));
1137 LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1138}
1139#endif /* IP6_DEBUG */
1140
1141#endif /* LWIP_IPV6 */
s8_t err_t
Definition err.h:76
@ ERR_BUF
Definition err.h:86
@ ERR_RTE
Definition err.h:90
@ ERR_OK
Definition err.h:82
#define IP6_DEBUG
Definition opt.h:2868
#define LWIP_IPV6_NUM_ADDRESSES
Definition opt.h:2179
#define LWIP_HAVE_LOOPIF
Definition opt.h:1498
#define netif_is_up(netif)
Definition netif.h:420
void pbuf_realloc(struct pbuf *p, u16_t new_len)
Definition pbuf.c:512
u8_t pbuf_free(struct pbuf *p)
Definition pbuf.c:734
#define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p)
Definition ip.h:82
#define LWIP_DEBUGF(debug, message)
struct netif * netif_list
Definition netif.c:123
struct netif * netif_default
Definition netif.c:124
#define netif_is_link_up(netif)
Definition netif.h:432
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition pbuf.c:684
u8_t pbuf_header_force(struct pbuf *p, s16_t header_size_increment)
Definition pbuf.c:694
@ ICMP6_DUR_NO_ROUTE
Definition prot/icmp6.h:119
@ ICMP6_PP_HEADER
Definition prot/icmp6.h:147
@ ICMP6_TE_HL
Definition prot/icmp6.h:137
ip_addr_t current_iphdr_src
Definition ip.h:141
ip_addr_t current_iphdr_dest
Definition ip.h:143
u16_t current_ip_header_tot_len
Definition ip.h:139
struct netif * current_netif
Definition ip.h:127
struct netif * current_input_netif
Definition ip.h:129
Definition netif.h:244
char name[2]
Definition netif.h:326
u8_t num
Definition netif.h:328
u16_t mtu
Definition netif.h:318
struct netif * next
Definition netif.h:246
Definition pbuf.h:161
u16_t tot_len
Definition pbuf.h:175
u16_t len
Definition pbuf.h:178
void * payload
Definition pbuf.h:166