STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
ip6.c
Go to the documentation of this file.
1 
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/ip6.h"
50 #include "lwip/ip6_addr.h"
51 #include "lwip/ip6_frag.h"
52 #include "lwip/icmp6.h"
53 #include "lwip/raw.h"
54 #include "lwip/udp.h"
55 #include "lwip/priv/tcp_priv.h"
56 #include "lwip/dhcp6.h"
57 #include "lwip/nd6.h"
58 #include "lwip/mld6.h"
59 #include "lwip/debug.h"
60 #include "lwip/stats.h"
61 
62 #if !LWIP_IPV4
63 
64 struct ip_globals ip_data;
65 #endif /* !LWIP_IPV4 */
66 
83 struct netif *
84 ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
85 {
86  struct netif *netif;
87  s8_t i;
88 
89 #ifdef LWIP_HOOK_IP6_ROUTE
90  netif = LWIP_HOOK_IP6_ROUTE(src, dest);
91  if (netif != NULL) {
92  return netif;
93  }
94 #endif
95 
96  /* If single netif configuration, fast return. */
97  if ((netif_list != NULL) && (netif_list->next == NULL)) {
99  return NULL;
100  }
101  return netif_list;
102  }
103 
104  /* Special processing for link-local addresses. */
105  if (ip6_addr_islinklocal(dest)) {
106  if (ip6_addr_isany(src)) {
107  /* Use default netif, if Up. */
109  return NULL;
110  }
111  return netif_default;
112  }
113 
114  /* Try to find the netif for the source address, checking that link is up. */
115  for (netif = netif_list; netif != NULL; netif = netif->next) {
116  if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
117  continue;
118  }
119  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
120  if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
121  ip6_addr_cmp(src, netif_ip6_addr(netif, i))) {
122  return netif;
123  }
124  }
125  }
126 
127  /* netif not found, use default netif, if up */
129  return NULL;
130  }
131  return netif_default;
132  }
133 
134  /* See if the destination subnet matches a configured address. */
135  for (netif = netif_list; netif != NULL; netif = netif->next) {
136  if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
137  continue;
138  }
139  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
140  if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
141  ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) {
142  return netif;
143  }
144  }
145  }
146 
147  /* Get the netif for a suitable router. */
148  i = nd6_select_router(dest, NULL);
149  if (i >= 0) {
150  if (default_router_list[i].neighbor_entry != NULL) {
151  if (default_router_list[i].neighbor_entry->netif != NULL) {
152  if (netif_is_up(default_router_list[i].neighbor_entry->netif) && netif_is_link_up(default_router_list[i].neighbor_entry->netif)) {
153  return default_router_list[i].neighbor_entry->netif;
154  }
155  }
156  }
157  }
158 
159  /* try with the netif that matches the source address. */
160  if (!ip6_addr_isany(src)) {
161  for (netif = netif_list; netif != NULL; netif = netif->next) {
162  if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
163  continue;
164  }
165  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
166  if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
167  ip6_addr_cmp(src, netif_ip6_addr(netif, i))) {
168  return netif;
169  }
170  }
171  }
172  }
173 
174 #if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
175  /* loopif is disabled, loopback traffic is passed through any netif */
176  if (ip6_addr_isloopback(dest)) {
177  /* don't check for link on loopback traffic */
178  if (netif_is_up(netif_default)) {
179  return netif_default;
180  }
181  /* default netif is not up, just use any netif for loopback traffic */
182  for (netif = netif_list; netif != NULL; netif = netif->next) {
183  if (netif_is_up(netif)) {
184  return netif;
185  }
186  }
187  return NULL;
188  }
189 #endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
190 
191  /* no matching netif found, use default netif, if up */
193  return NULL;
194  }
195  return netif_default;
196 }
197 
208 const ip_addr_t *
209 ip6_select_source_address(struct netif *netif, const ip6_addr_t * dest)
210 {
211  const ip_addr_t *src = NULL;
212  u8_t i;
213 
214  /* If dest is link-local, choose a link-local source. */
215  if (ip6_addr_islinklocal(dest) || ip6_addr_ismulticast_linklocal(dest) || ip6_addr_ismulticast_iflocal(dest)) {
216  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
217  if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
218  ip6_addr_islinklocal(netif_ip6_addr(netif, i))) {
219  return netif_ip_addr6(netif, i);
220  }
221  }
222  }
223 
224  /* Choose a site-local with matching prefix. */
225  if (ip6_addr_issitelocal(dest) || ip6_addr_ismulticast_sitelocal(dest)) {
226  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
227  if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
228  ip6_addr_issitelocal(netif_ip6_addr(netif, i)) &&
229  ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) {
230  return netif_ip_addr6(netif, i);
231  }
232  }
233  }
234 
235  /* Choose a unique-local with matching prefix. */
236  if (ip6_addr_isuniquelocal(dest) || ip6_addr_ismulticast_orglocal(dest)) {
237  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
238  if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
239  ip6_addr_isuniquelocal(netif_ip6_addr(netif, i)) &&
240  ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) {
241  return netif_ip_addr6(netif, i);
242  }
243  }
244  }
245 
246  /* Choose a global with best matching prefix. */
247  if (ip6_addr_isglobal(dest) || ip6_addr_ismulticast_global(dest)) {
248  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
249  if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
250  ip6_addr_isglobal(netif_ip6_addr(netif, i))) {
251  if (src == NULL) {
252  src = netif_ip_addr6(netif, i);
253  }
254  else {
255  /* Replace src only if we find a prefix match. */
256  /* TODO find longest matching prefix. */
257  if ((!(ip6_addr_netcmp(ip_2_ip6(src), dest))) &&
258  ip6_addr_netcmp(netif_ip6_addr(netif, i), dest)) {
259  src = netif_ip_addr6(netif, i);
260  }
261  }
262  }
263  }
264  if (src != NULL) {
265  return src;
266  }
267  }
268 
269  /* Last resort: see if arbitrary prefix matches. */
270  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
271  if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
272  ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) {
273  return netif_ip_addr6(netif, i);
274  }
275  }
276 
277  return NULL;
278 }
279 
280 #if LWIP_IPV6_FORWARD
281 
290 static void
291 ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
292 {
293  struct netif *netif;
294 
295  /* do not forward link-local addresses */
296  if (ip6_addr_islinklocal(ip6_current_dest_addr())) {
297  LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n"));
298  IP6_STATS_INC(ip6.rterr);
299  IP6_STATS_INC(ip6.drop);
300  return;
301  }
302 
303  /* Find network interface where to forward this IP packet to. */
304  netif = ip6_route(IP6_ADDR_ANY6, ip6_current_dest_addr());
305  if (netif == NULL) {
306  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",
307  IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
308  IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
309  IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
310  IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
311  IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
312  IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
313  IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
314  IP6_ADDR_BLOCK8(ip6_current_dest_addr())));
315 #if LWIP_ICMP6
316  /* Don't send ICMP messages in response to ICMP messages */
317  if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
318  icmp6_dest_unreach(p, ICMP6_DUR_NO_ROUTE);
319  }
320 #endif /* LWIP_ICMP6 */
321  IP6_STATS_INC(ip6.rterr);
322  IP6_STATS_INC(ip6.drop);
323  return;
324  }
325  /* Do not forward packets onto the same network interface on which
326  * they arrived. */
327  if (netif == inp) {
328  LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not bouncing packets back on incoming interface.\n"));
329  IP6_STATS_INC(ip6.rterr);
330  IP6_STATS_INC(ip6.drop);
331  return;
332  }
333 
334  /* decrement HL */
335  IP6H_HOPLIM_SET(iphdr, IP6H_HOPLIM(iphdr) - 1);
336  /* send ICMP6 if HL == 0 */
337  if (IP6H_HOPLIM(iphdr) == 0) {
338 #if LWIP_ICMP6
339  /* Don't send ICMP messages in response to ICMP messages */
340  if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
341  icmp6_time_exceeded(p, ICMP6_TE_HL);
342  }
343 #endif /* LWIP_ICMP6 */
344  IP6_STATS_INC(ip6.drop);
345  return;
346  }
347 
348  if (netif->mtu && (p->tot_len > netif->mtu)) {
349 #if LWIP_ICMP6
350  /* Don't send ICMP messages in response to ICMP messages */
351  if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
352  icmp6_packet_too_big(p, netif->mtu);
353  }
354 #endif /* LWIP_ICMP6 */
355  IP6_STATS_INC(ip6.drop);
356  return;
357  }
358 
359  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",
360  IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
361  IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
362  IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
363  IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
364  IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
365  IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
366  IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
367  IP6_ADDR_BLOCK8(ip6_current_dest_addr())));
368 
369  /* transmit pbuf on chosen interface */
370  netif->output_ip6(netif, p, ip6_current_dest_addr());
371  IP6_STATS_INC(ip6.fw);
372  IP6_STATS_INC(ip6.xmit);
373  return;
374 }
375 #endif /* LWIP_IPV6_FORWARD */
376 
377 #if !LWIP_IPV4
378 /* If both IP versions are enabled, this function can dispatch packets to the correct one.
379  * If only IPv6 is enabled, this directly maps at ip6_input.
380  * May be used as netif input function.
381  */
382 err_t
383 ip_input(struct pbuf *p, struct netif *inp)
384 {
385  return ip6_input(p, inp);
386 }
387 #endif /* !LWIP_IPV4 */
388 
403 err_t
404 ip6_input(struct pbuf *p, struct netif *inp)
405 {
406  struct ip6_hdr *ip6hdr;
407  struct netif *netif;
408  u8_t nexth;
409  u16_t hlen; /* the current header length */
410  u8_t i;
411 #if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/
412  @todo
413  int check_ip_src=1;
414 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
415 
416  IP6_STATS_INC(ip6.recv);
417 
418  /* identify the IP header */
419  ip6hdr = (struct ip6_hdr *)p->payload;
420  if (IP6H_V(ip6hdr) != 6) {
421  LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n",
422  IP6H_V(ip6hdr)));
423  pbuf_free(p);
424  IP6_STATS_INC(ip6.err);
425  IP6_STATS_INC(ip6.drop);
426  return ERR_OK;
427  }
428 
429 #ifdef LWIP_HOOK_IP6_INPUT
430  if (LWIP_HOOK_IP6_INPUT(p, inp)) {
431  /* the packet has been eaten */
432  return ERR_OK;
433  }
434 #endif
435 
436  /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
437  if ((IP6_HLEN > p->len) || ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len)) {
438  if (IP6_HLEN > p->len) {
440  ("IPv6 header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
441  IP6_HLEN, p->len));
442  }
443  if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) {
445  ("IPv6 (plen %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
446  IP6H_PLEN(ip6hdr) + IP6_HLEN, p->tot_len));
447  }
448  /* free (drop) packet pbufs */
449  pbuf_free(p);
450  IP6_STATS_INC(ip6.lenerr);
451  IP6_STATS_INC(ip6.drop);
452  return ERR_OK;
453  }
454 
455  /* Trim pbuf. This should have been done at the netif layer,
456  * but we'll do it anyway just to be sure that its done. */
457  pbuf_realloc(p, IP6_HLEN + IP6H_PLEN(ip6hdr));
458 
459  /* copy IP addresses to aligned ip6_addr_t */
462 
463  /* current header pointer. */
464  ip_data.current_ip6_header = ip6hdr;
465 
466  /* In netif, used in case we need to send ICMPv6 packets back. */
467  ip_data.current_netif = inp;
469 
470  /* match packet against an interface, i.e. is this packet for us? */
471  if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
472  /* Always joined to multicast if-local and link-local all-nodes group. */
473  if (ip6_addr_isallnodes_iflocal(ip6_current_dest_addr()) ||
474  ip6_addr_isallnodes_linklocal(ip6_current_dest_addr())) {
475  netif = inp;
476  }
477 #if LWIP_IPV6_MLD
478  else if (mld6_lookfor_group(inp, ip6_current_dest_addr())) {
479  netif = inp;
480  }
481 #else /* LWIP_IPV6_MLD */
482  else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) {
483  /* Filter solicited node packets when MLD is not enabled
484  * (for Neighbor discovery). */
485  netif = NULL;
486  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
487  if (ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) &&
488  ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) {
489  netif = inp;
490  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %c%c\n",
491  netif->name[0], netif->name[1]));
492  break;
493  }
494  }
495  }
496 #endif /* LWIP_IPV6_MLD */
497  else {
498  netif = NULL;
499  }
500  } else {
501  /* start trying with inp. if that's not acceptable, start walking the
502  list of configured netifs.
503  'first' is used as a boolean to mark whether we started walking the list */
504  int first = 1;
505  netif = inp;
506  do {
507  /* interface is up? */
508  if (netif_is_up(netif)) {
509  /* unicast to this interface address? address configured? */
510  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
511  if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
512  ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i))) {
513  /* exit outer loop */
514  goto netif_found;
515  }
516  }
517  }
518  if (ip6_addr_islinklocal(ip6_current_dest_addr())) {
519  /* Do not match link-local addresses to other netifs. */
520  netif = NULL;
521  break;
522  }
523  if (first) {
524  first = 0;
525  netif = netif_list;
526  } else {
527  netif = netif->next;
528  }
529  if (netif == inp) {
530  netif = netif->next;
531  }
532  } while (netif != NULL);
533 netif_found:
534  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n",
535  netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X'));
536  }
537 
538  /* "::" packet source address? (used in duplicate address detection) */
539  if (ip6_addr_isany(ip6_current_src_addr()) &&
540  (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) {
541  /* packet source is not valid */
542  /* free (drop) packet pbufs */
543  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n"));
544  pbuf_free(p);
545  IP6_STATS_INC(ip6.drop);
546  goto ip6_input_cleanup;
547  }
548 
549  /* packet not for us? */
550  if (netif == NULL) {
551  /* packet not for us, route or discard */
552  LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_TRACE, ("ip6_input: packet not for us.\n"));
553 #if LWIP_IPV6_FORWARD
554  /* non-multicast packet? */
555  if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
556  /* try to forward IP packet on (other) interfaces */
557  ip6_forward(p, ip6hdr, inp);
558  }
559 #endif /* LWIP_IPV6_FORWARD */
560  pbuf_free(p);
561  goto ip6_input_cleanup;
562  }
563 
564  /* current netif pointer. */
565  ip_data.current_netif = netif;
566 
567  /* Save next header type. */
568  nexth = IP6H_NEXTH(ip6hdr);
569 
570  /* Init header length. */
571  hlen = ip_data.current_ip_header_tot_len = IP6_HLEN;
572 
573  /* Move to payload. */
574  pbuf_header(p, -IP6_HLEN);
575 
576  /* Process known option extension headers, if present. */
577  while (nexth != IP6_NEXTH_NONE)
578  {
579  switch (nexth) {
580  case IP6_NEXTH_HOPBYHOP:
581  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n"));
582  /* Get next header type. */
583  nexth = *((u8_t *)p->payload);
584 
585  /* Get the header length. */
586  hlen = 8 * (1 + *((u8_t *)p->payload + 1));
588 
589  /* Skip over this header. */
590  if (hlen > p->len) {
592  ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
593  hlen, p->len));
594  /* free (drop) packet pbufs */
595  pbuf_free(p);
596  IP6_STATS_INC(ip6.lenerr);
597  IP6_STATS_INC(ip6.drop);
598  goto ip6_input_cleanup;
599  }
600 
601  pbuf_header(p, -(s16_t)hlen);
602  break;
603  case IP6_NEXTH_DESTOPTS:
604  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Destination options header\n"));
605  /* Get next header type. */
606  nexth = *((u8_t *)p->payload);
607 
608  /* Get the header length. */
609  hlen = 8 * (1 + *((u8_t *)p->payload + 1));
611 
612  /* Skip over this header. */
613  if (hlen > p->len) {
615  ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
616  hlen, p->len));
617  /* free (drop) packet pbufs */
618  pbuf_free(p);
619  IP6_STATS_INC(ip6.lenerr);
620  IP6_STATS_INC(ip6.drop);
621  goto ip6_input_cleanup;
622  }
623 
624  pbuf_header(p, -(s16_t)hlen);
625  break;
626  case IP6_NEXTH_ROUTING:
627  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n"));
628  /* Get next header type. */
629  nexth = *((u8_t *)p->payload);
630 
631  /* Get the header length. */
632  hlen = 8 * (1 + *((u8_t *)p->payload + 1));
634 
635  /* Skip over this header. */
636  if (hlen > p->len) {
638  ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
639  hlen, p->len));
640  /* free (drop) packet pbufs */
641  pbuf_free(p);
642  IP6_STATS_INC(ip6.lenerr);
643  IP6_STATS_INC(ip6.drop);
644  goto ip6_input_cleanup;
645  }
646 
647  pbuf_header(p, -(s16_t)hlen);
648  break;
649 
650  case IP6_NEXTH_FRAGMENT:
651  {
652  struct ip6_frag_hdr * frag_hdr;
653  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n"));
654 
655  frag_hdr = (struct ip6_frag_hdr *)p->payload;
656 
657  /* Get next header type. */
658  nexth = frag_hdr->_nexth;
659 
660  /* Fragment Header length. */
661  hlen = 8;
663 
664  /* Make sure this header fits in current pbuf. */
665  if (hlen > p->len) {
667  ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
668  hlen, p->len));
669  /* free (drop) packet pbufs */
670  pbuf_free(p);
671  IP6_FRAG_STATS_INC(ip6_frag.lenerr);
672  IP6_FRAG_STATS_INC(ip6_frag.drop);
673  goto ip6_input_cleanup;
674  }
675 
676  /* Offset == 0 and more_fragments == 0? */
677  if ((frag_hdr->_fragment_offset &
678  PP_HTONS(IP6_FRAG_OFFSET_MASK | IP6_FRAG_MORE_FLAG)) == 0) {
679  /* This is a 1-fragment packet, usually a packet that we have
680  * already reassembled. Skip this header anc continue. */
681  pbuf_header(p, -(s16_t)hlen);
682  } else {
683 #if LWIP_IPV6_REASS
684 
685  /* reassemble the packet */
686  p = ip6_reass(p);
687  /* packet not fully reassembled yet? */
688  if (p == NULL) {
689  goto ip6_input_cleanup;
690  }
691 
692  /* Returned p point to IPv6 header.
693  * Update all our variables and pointers and continue. */
694  ip6hdr = (struct ip6_hdr *)p->payload;
695  nexth = IP6H_NEXTH(ip6hdr);
696  hlen = ip_data.current_ip_header_tot_len = IP6_HLEN;
697  pbuf_header(p, -IP6_HLEN);
698 
699 #else /* LWIP_IPV6_REASS */
700  /* free (drop) packet pbufs */
701  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header dropped (with LWIP_IPV6_REASS==0)\n"));
702  pbuf_free(p);
703  IP6_STATS_INC(ip6.opterr);
704  IP6_STATS_INC(ip6.drop);
705  goto ip6_input_cleanup;
706 #endif /* LWIP_IPV6_REASS */
707  }
708  break;
709  }
710  default:
711  goto options_done;
712  break;
713  }
714  }
715 options_done:
716 
717  /* p points to IPv6 header again. */
719 
720  /* send to upper layers */
721  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n"));
722  ip6_debug_print(p);
723  LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
724 
725 #if LWIP_RAW
726  /* raw input did not eat the packet? */
727  if (raw_input(p, inp) == 0)
728 #endif /* LWIP_RAW */
729  {
730  switch (nexth) {
731  case IP6_NEXTH_NONE:
732  pbuf_free(p);
733  break;
734 #if LWIP_UDP
735  case IP6_NEXTH_UDP:
736 #if LWIP_UDPLITE
737  case IP6_NEXTH_UDPLITE:
738 #endif /* LWIP_UDPLITE */
739  /* Point to payload. */
741  udp_input(p, inp);
742  break;
743 #endif /* LWIP_UDP */
744 #if LWIP_TCP
745  case IP6_NEXTH_TCP:
746  /* Point to payload. */
748  tcp_input(p, inp);
749  break;
750 #endif /* LWIP_TCP */
751 #if LWIP_ICMP6
752  case IP6_NEXTH_ICMP6:
753  /* Point to payload. */
755  icmp6_input(p, inp);
756  break;
757 #endif /* LWIP_ICMP */
758  default:
759 #if LWIP_ICMP6
760  /* send ICMP parameter problem unless it was a multicast or ICMPv6 */
761  if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) &&
762  (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
763  icmp6_param_problem(p, ICMP6_PP_HEADER, ip_data.current_ip_header_tot_len - hlen);
764  }
765 #endif /* LWIP_ICMP */
766  LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", IP6H_NEXTH(ip6hdr)));
767  pbuf_free(p);
768  IP6_STATS_INC(ip6.proterr);
769  IP6_STATS_INC(ip6.drop);
770  break;
771  }
772  }
773 
774 ip6_input_cleanup:
777  ip_data.current_ip6_header = NULL;
779  ip6_addr_set_zero(ip6_current_src_addr());
780  ip6_addr_set_zero(ip6_current_dest_addr());
781 
782  return ERR_OK;
783 }
784 
785 
810 err_t
811 ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
812  u8_t hl, u8_t tc,
813  u8_t nexth, struct netif *netif)
814 {
815  const ip6_addr_t *src_used = src;
816  if (dest != IP_HDRINCL) {
817  if (src != NULL && ip6_addr_isany(src)) {
818  src = ip_2_ip6(ip6_select_source_address(netif, dest));
819  if ((src == NULL) || ip6_addr_isany(src)) {
820  /* No appropriate source address was found for this packet. */
821  LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n"));
822  IP6_STATS_INC(ip6.rterr);
823  return ERR_RTE;
824  }
825  }
826  }
827  return ip6_output_if_src(p, src_used, dest, hl, tc, nexth, netif);
828 }
829 
834 err_t
835 ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
836  u8_t hl, u8_t tc,
837  u8_t nexth, struct netif *netif)
838 {
839  struct ip6_hdr *ip6hdr;
840  ip6_addr_t dest_addr;
841 
843 
844  /* Should the IPv6 header be generated or is it already included in p? */
845  if (dest != IP_HDRINCL) {
846  /* generate IPv6 header */
847  if (pbuf_header(p, IP6_HLEN)) {
848  LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n"));
849  IP6_STATS_INC(ip6.err);
850  return ERR_BUF;
851  }
852 
853  ip6hdr = (struct ip6_hdr *)p->payload;
854  LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr",
855  (p->len >= sizeof(struct ip6_hdr)));
856 
857  IP6H_HOPLIM_SET(ip6hdr, hl);
858  IP6H_NEXTH_SET(ip6hdr, nexth);
859 
860  /* dest cannot be NULL here */
861  ip6_addr_copy(ip6hdr->dest, *dest);
862 
863  IP6H_VTCFL_SET(ip6hdr, 6, tc, 0);
864  IP6H_PLEN_SET(ip6hdr, p->tot_len - IP6_HLEN);
865 
866  if (src == NULL) {
867  src = IP6_ADDR_ANY6;
868  }
869  /* src cannot be NULL here */
870  ip6_addr_copy(ip6hdr->src, *src);
871 
872  } else {
873  /* IP header already included in p */
874  ip6hdr = (struct ip6_hdr *)p->payload;
875  ip6_addr_copy(dest_addr, ip6hdr->dest);
876  dest = &dest_addr;
877  }
878 
879  IP6_STATS_INC(ip6.xmit);
880 
881  LWIP_DEBUGF(IP6_DEBUG, ("ip6_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
882  ip6_debug_print(p);
883 
884 #if ENABLE_LOOPBACK
885  {
886  int i;
887 #if !LWIP_HAVE_LOOPIF
888  if (ip6_addr_isloopback(dest)) {
889  return netif_loop_output(netif, p);
890  }
891 #endif /* !LWIP_HAVE_LOOPIF */
892  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
893  if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
894  ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) {
895  /* Packet to self, enqueue it for loopback */
896  LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n"));
897  return netif_loop_output(netif, p);
898  }
899  }
900  }
901 #endif /* ENABLE_LOOPBACK */
902 #if LWIP_IPV6_FRAG
903  /* don't fragment if interface has mtu set to 0 [loopif] */
904  if (netif->mtu && (p->tot_len > nd6_get_destination_mtu(dest, netif))) {
905  return ip6_frag(p, netif, dest);
906  }
907 #endif /* LWIP_IPV6_FRAG */
908 
909  LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n"));
910  return netif->output_ip6(netif, p, dest);
911 }
912 
931 err_t
932 ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
933  u8_t hl, u8_t tc, u8_t nexth)
934 {
935  struct netif *netif;
936  struct ip6_hdr *ip6hdr;
937  ip6_addr_t src_addr, dest_addr;
938 
940 
941  if (dest != IP_HDRINCL) {
942  netif = ip6_route(src, dest);
943  } else {
944  /* IP header included in p, read addresses. */
945  ip6hdr = (struct ip6_hdr *)p->payload;
946  ip6_addr_copy(src_addr, ip6hdr->src);
947  ip6_addr_copy(dest_addr, ip6hdr->dest);
948  netif = ip6_route(&src_addr, &dest_addr);
949  }
950 
951  if (netif == NULL) {
952  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",
953  IP6_ADDR_BLOCK1(dest),
954  IP6_ADDR_BLOCK2(dest),
955  IP6_ADDR_BLOCK3(dest),
956  IP6_ADDR_BLOCK4(dest),
957  IP6_ADDR_BLOCK5(dest),
958  IP6_ADDR_BLOCK6(dest),
959  IP6_ADDR_BLOCK7(dest),
960  IP6_ADDR_BLOCK8(dest)));
961  IP6_STATS_INC(ip6.rterr);
962  return ERR_RTE;
963  }
964 
965  return ip6_output_if(p, src, dest, hl, tc, nexth, netif);
966 }
967 
968 
969 #if LWIP_NETIF_HWADDRHINT
970 
989 err_t
990 ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
991  u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint)
992 {
993  struct netif *netif;
994  struct ip6_hdr *ip6hdr;
995  ip6_addr_t src_addr, dest_addr;
996  err_t err;
997 
999 
1000  if (dest != IP_HDRINCL) {
1001  netif = ip6_route(src, dest);
1002  } else {
1003  /* IP header included in p, read addresses. */
1004  ip6hdr = (struct ip6_hdr *)p->payload;
1005  ip6_addr_copy(src_addr, ip6hdr->src);
1006  ip6_addr_copy(dest_addr, ip6hdr->dest);
1007  netif = ip6_route(&src_addr, &dest_addr);
1008  }
1009 
1010  if (netif == NULL) {
1011  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",
1012  IP6_ADDR_BLOCK1(dest),
1013  IP6_ADDR_BLOCK2(dest),
1014  IP6_ADDR_BLOCK3(dest),
1015  IP6_ADDR_BLOCK4(dest),
1016  IP6_ADDR_BLOCK5(dest),
1017  IP6_ADDR_BLOCK6(dest),
1018  IP6_ADDR_BLOCK7(dest),
1019  IP6_ADDR_BLOCK8(dest)));
1020  IP6_STATS_INC(ip6.rterr);
1021  return ERR_RTE;
1022  }
1023 
1024  NETIF_SET_HWADDRHINT(netif, addr_hint);
1025  err = ip6_output_if(p, src, dest, hl, tc, nexth, netif);
1026  NETIF_SET_HWADDRHINT(netif, NULL);
1027 
1028  return err;
1029 }
1030 #endif /* LWIP_NETIF_HWADDRHINT*/
1031 
1032 #if LWIP_IPV6_MLD
1033 
1043 err_t
1044 ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value)
1045 {
1046  struct ip6_hbh_hdr * hbh_hdr;
1047 
1048  /* Move pointer to make room for hop-by-hop options header. */
1049  if (pbuf_header(p, sizeof(struct ip6_hbh_hdr))) {
1050  LWIP_DEBUGF(IP6_DEBUG, ("ip6_options: no space for options header\n"));
1051  IP6_STATS_INC(ip6.err);
1052  return ERR_BUF;
1053  }
1054 
1055  hbh_hdr = (struct ip6_hbh_hdr *)p->payload;
1056 
1057  /* Set fields. */
1058  hbh_hdr->_nexth = nexth;
1059  hbh_hdr->_hlen = 0;
1060  hbh_hdr->_ra_opt_type = IP6_ROUTER_ALERT_OPTION;
1061  hbh_hdr->_ra_opt_dlen = 2;
1062  hbh_hdr->_ra_opt_data = value;
1063  hbh_hdr->_padn_opt_type = IP6_PADN_ALERT_OPTION;
1064  hbh_hdr->_padn_opt_dlen = 0;
1065 
1066  return ERR_OK;
1067 }
1068 #endif /* LWIP_IPV6_MLD */
1069 
1070 #if IP6_DEBUG
1071 /* Print an IPv6 header by using LWIP_DEBUGF
1072  * @param p an IPv6 packet, p->payload pointing to the IPv6 header
1073  */
1074 void
1075 ip6_debug_print(struct pbuf *p)
1076 {
1077  struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload;
1078 
1079  LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n"));
1080  LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1081  LWIP_DEBUGF(IP6_DEBUG, ("| %2"U16_F" | %3"U16_F" | %7"U32_F" | (ver, class, flow)\n",
1082  IP6H_V(ip6hdr),
1083  IP6H_TC(ip6hdr),
1084  IP6H_FL(ip6hdr)));
1085  LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1086  LWIP_DEBUGF(IP6_DEBUG, ("| %5"U16_F" | %3"U16_F" | %3"U16_F" | (plen, nexth, hopl)\n",
1087  IP6H_PLEN(ip6hdr),
1088  IP6H_NEXTH(ip6hdr),
1089  IP6H_HOPLIM(ip6hdr)));
1090  LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1091  LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (src)\n",
1092  IP6_ADDR_BLOCK1(&(ip6hdr->src)),
1093  IP6_ADDR_BLOCK2(&(ip6hdr->src)),
1094  IP6_ADDR_BLOCK3(&(ip6hdr->src)),
1095  IP6_ADDR_BLOCK4(&(ip6hdr->src))));
1096  LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n",
1097  IP6_ADDR_BLOCK5(&(ip6hdr->src)),
1098  IP6_ADDR_BLOCK6(&(ip6hdr->src)),
1099  IP6_ADDR_BLOCK7(&(ip6hdr->src)),
1100  IP6_ADDR_BLOCK8(&(ip6hdr->src))));
1101  LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1102  LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (dest)\n",
1103  IP6_ADDR_BLOCK1(&(ip6hdr->dest)),
1104  IP6_ADDR_BLOCK2(&(ip6hdr->dest)),
1105  IP6_ADDR_BLOCK3(&(ip6hdr->dest)),
1106  IP6_ADDR_BLOCK4(&(ip6hdr->dest))));
1107  LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n",
1108  IP6_ADDR_BLOCK5(&(ip6hdr->dest)),
1109  IP6_ADDR_BLOCK6(&(ip6hdr->dest)),
1110  IP6_ADDR_BLOCK7(&(ip6hdr->dest)),
1111  IP6_ADDR_BLOCK8(&(ip6hdr->dest))));
1112  LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
1113 }
1114 #endif /* IP6_DEBUG */
1115 
1116 #endif /* LWIP_IPV6 */
1117 
#define IP6_DEBUG
Definition: opt.h:2999
struct netif * netif_list
Definition: netif.c:84
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:47
struct netif * netif_default
Definition: netif.c:85
#define ip_2_ip6(ipaddr)
Definition: ip_addr.h:200
#define LWIP_DBG_LEVEL_WARNING
Definition: debug.h:46
#define U16_F
Definition: cc.h:48
signed char s8_t
Definition: cc.h:39
signed short s16_t
Definition: cc.h:41
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:603
void pbuf_realloc(struct pbuf *p, u16_t new_len)
Definition: pbuf.c:431
#define netif_is_link_up(netif)
Definition: netif.h:368
ip_addr_t current_iphdr_dest
Definition: ip.h:145
struct netif * next
Definition: netif.h:184
u16_t mtu
Definition: netif.h:263
err_t ip_input(struct pbuf *p, struct netif *inp)
if(LCD_Lock==DISABLE)
Definition: lcd_log.c:249
u16_t len
Definition: pbuf.h:125
u16_t current_ip_header_tot_len
Definition: ip.h:141
#define IP_HDRINCL
Definition: ip.h:64
ip_addr_t current_iphdr_src
Definition: ip.h:143
char name[2]
Definition: netif.h:271
struct netif * current_netif
Definition: ip.h:129
#define NULL
Definition: usbd_def.h:53
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:652
#define U32_F
Definition: cc.h:51
#define PP_HTONS(x)
Definition: def.h:97
#define ERR_RTE
Definition: err.h:56
#define IP6_FRAG_STATS_INC(x)
Definition: stats.h:384
u8_t num
Definition: netif.h:273
#define ERR_OK
Definition: err.h:52
u16_t tot_len
Definition: pbuf.h:122
#define NETIF_SET_HWADDRHINT(netif, hint)
Definition: netif.h:411
#define LWIP_DBG_TRACE
Definition: debug.h:57
Definition: pbuf.h:108
s8_t err_t
Definition: err.h:47
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:70
Definition: netif.h:182
struct ip_globals ip_data
Definition: ip.h:126
#define ip_addr_copy_from_ip6(dest, src)
Definition: ip_addr.h:204
#define LWIP_IPV6_NUM_ADDRESSES
Definition: opt.h:2451
#define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p)
Definition: ip.h:69
u8_t pbuf_header_force(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:613
unsigned char u8_t
Definition: cc.h:38
#define IP6_STATS_INC(x)
Definition: stats.h:368
ip6_addr_t ip_addr_t
Definition: ip_addr.h:194
#define netif_is_up(netif)
Definition: netif.h:356
#define X32_F
Definition: cc.h:53
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:113
struct netif * current_input_netif
Definition: ip.h:131
unsigned short u16_t
Definition: cc.h:40
void * payload
Definition: pbuf.h:113
#define X16_F
Definition: cc.h:50
#define ERR_BUF
Definition: err.h:54