ipv6_misc.c
Go to the documentation of this file.
1 /**
2  * @file ipv6_misc.c
3  * @brief Helper functions for IPv6
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL IPV6_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "ipv6/ipv6.h"
37 #include "ipv6/ipv6_misc.h"
38 #include "ipv6/ndp.h"
39 #include "ipv6/ndp_cache.h"
40 #include "mdns/mdns_responder.h"
41 #include "mibs/ip_mib_module.h"
42 #include "debug.h"
43 
44 //Check TCP/IP stack configuration
45 #if (IPV6_SUPPORT == ENABLED)
46 
47 
48 /**
49  * @brief Get the state of the specified IPv6 address
50  * @param[in] interface Underlying network interface
51  * @param[in] addr IPv6 address
52  * @return Address state
53  **/
54 
56 {
57  uint_t i;
58  Ipv6AddrEntry *entry;
59 
60  //Loop through the list of IPv6 addresses assigned to the interface
61  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
62  {
63  //Point to the current entry
64  entry = &interface->ipv6Context.addrList[i];
65 
66  //Valid IPv6 address
67  if(entry->state != IPV6_ADDR_STATE_INVALID)
68  {
69  //Check whether the current entry matches the specified address
70  if(ipv6CompAddr(&entry->addr, addr))
71  {
72  //Return the state of the IPv6 address
73  return entry->state;
74  }
75  }
76  }
77 
78  //The specified IPv6 address is not valid
80 }
81 
82 
83 /**
84  * @brief Set IPv6 address and address state
85  * @param[in] interface Pointer to the desired network interface
86  * @param[in] index Zero-based index
87  * @param[in] addr IPv6 address
88  * @param[in] state State of the IPv6 address
89  * @param[in] validLifetime Valid lifetime
90  * @param[in] preferredLifetime Preferred lifetime
91  * @param[in] permanent Permanently assigned address
92  * @return Error code
93  **/
94 
98 {
99  error_t error;
100  NetInterface *physicalInterface;
101  Ipv6AddrEntry *entry;
102  Ipv6Addr solicitedNodeAddr;
103 
104  //Check parameters
105  if(interface == NULL || addr == NULL)
107 
108  //Make sure that the index is valid
109  if(index >= IPV6_ADDR_LIST_SIZE)
110  return ERROR_OUT_OF_RANGE;
111 
112  //The IPv6 address must be a valid unicast address
114  return ERROR_INVALID_ADDRESS;
115 
116  //Initialize status code
117  error = NO_ERROR;
118 
119  //Point to the physical interface
120  physicalInterface = nicGetPhysicalInterface(interface);
121 
122  //Point to the corresponding entry
123  entry = &interface->ipv6Context.addrList[index];
124 
125  //Check whether an IPv6 address is already assigned
126  if(!ipv6CompAddr(&entry->addr, &IPV6_UNSPECIFIED_ADDR))
127  {
128  //Check the state of the IPv6 address
129  if(entry->state != IPV6_ADDR_STATE_INVALID)
130  {
131  //Ethernet interface?
132  if(physicalInterface->nicDriver != NULL &&
133  physicalInterface->nicDriver->type == NIC_TYPE_ETHERNET)
134  {
135  //Form the Solicited-Node address
136  ipv6ComputeSolicitedNodeAddr(&entry->addr, &solicitedNodeAddr);
137  //Leave the Solicited-Node multicast group
138  ipv6LeaveMulticastGroup(interface, &solicitedNodeAddr);
139  }
140  }
141  }
142 
143  //The current IPv6 address is no more valid
145  entry->validLifetime = 0;
146  entry->preferredLifetime = 0;
147  entry->permanent = FALSE;
148 
149  //Assign the new IPv6 address
150  entry->addr = *addr;
151 
152  //Check whether the new IPv6 address is valid
154  {
155  //Check the state of the IPv6 address
156  if(state != IPV6_ADDR_STATE_INVALID)
157  {
158  //Ethernet interface?
159  if(physicalInterface->nicDriver != NULL &&
160  physicalInterface->nicDriver->type == NIC_TYPE_ETHERNET)
161  {
162  //Form the Solicited-Node address for the link-local address
163  ipv6ComputeSolicitedNodeAddr(addr, &solicitedNodeAddr);
164  //Join the Solicited-Node multicast group for each assigned address
165  error = ipv6JoinMulticastGroup(interface, &solicitedNodeAddr);
166  }
167  //6LoWPAN interface?
168  else if(interface->nicDriver != NULL &&
169  interface->nicDriver->type == NIC_TYPE_6LOWPAN)
170  {
171  //There is no need to join the solicited-node multicast address,
172  //since nobody multicasts Neighbor Solicitations in this type of
173  //network (refer to RFC 6775 section 5.2)
174  }
175  }
176 
177  //Check status code
178  if(!error)
179  {
180  //Set the state of the IPv6 address
181  entry->state = state;
182 
183  //Clear duplicate flag
184  entry->duplicate = FALSE;
185 
186  //Save preferred and valid lifetimes
188  entry->validLifetime = validLifetime;
189 
190  //Set time stamp
191  entry->timestamp = osGetSystemTime();
192 
193  //Initialize DAD related variables
194  entry->dadTimeout = 0;
195  entry->dadRetransmitCount = 0;
196  }
197 
198  //This flag tells whether the IPv6 address should be permanently assigned
199  entry->permanent = permanent;
200  }
201 
202 #if (MDNS_RESPONDER_SUPPORT == ENABLED)
203  //Link-local address?
204  if(index == 0)
205  {
206  //Restart mDNS probing process
207  mdnsResponderStartProbing(interface->mdnsResponderContext);
208  }
209 #endif
210 
211  //Return status code
212  return error;
213 }
214 
215 
216 /**
217  * @brief Add a new entry to the list of IPv6 addresses
218  * @param[in] interface Underlying network interface
219  * @param[in] addr IPv6 address
220  * @param[in] validLifetime Valid lifetime, in seconds
221  * @param[in] preferredLifetime Preferred lifetime, in seconds
222  **/
223 
224 void ipv6AddAddr(NetInterface *interface, const Ipv6Addr *addr,
225  uint32_t validLifetime, uint32_t preferredLifetime)
226 {
227  uint_t i;
228  Ipv6AddrEntry *entry;
229 
230  //Check the valid lifetime
232  {
233  //The length of time in seconds that the address is valid
234  if(validLifetime < (MAX_DELAY / 1000))
235  validLifetime *= 1000;
236  else
238  }
239  else
240  {
241  //A value of all one bits (0xffffffff) represents infinity
243  }
244 
245  //Check the preferred lifetime
247  {
248  //The length of time in seconds that the address remains preferred
249  if(preferredLifetime < (MAX_DELAY / 1000))
250  preferredLifetime *= 1000;
251  else
253  }
254  else
255  {
256  //A value of all one bits (0xffffffff) represents infinity
258  }
259 
260  //Loop through the list of IPv6 addresses assigned to the interface
261  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
262  {
263  //Point to the current entry
264  entry = &interface->ipv6Context.addrList[i];
265 
266  //Check the state of the IPv6 address
267  if(entry->state == IPV6_ADDR_STATE_PREFERRED ||
269  {
270  //Check whether the current entry matches the specified address
271  if(ipv6CompAddr(&entry->addr, addr))
272  {
273  //The IPv6 address should be preserved if it has been manually assigned
274  if(!entry->permanent)
275  {
276  //Update the lifetimes of the entry
277  entry->validLifetime = validLifetime;
279 
280  //Save current time
281  entry->timestamp = osGetSystemTime();
282  //Update the state of the IPv6 address
284  }
285 
286  //Exit immediately
287  return;
288  }
289  }
290  }
291 
292  //If no matching entry was found, then try to create a new entry
293  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
294  {
295  //Point to the current entry
296  entry = &interface->ipv6Context.addrList[i];
297 
298  //Check the state of the IPv6 address
299  if(entry->state == IPV6_ADDR_STATE_INVALID)
300  {
301  //The IPv6 address should be preserved if it has been manually assigned
302  if(!entry->permanent)
303  {
304 #if (NDP_SUPPORT == ENABLED)
305  //Check whether Duplicate Address Detection should be performed
306  if(interface->ndpContext.dupAddrDetectTransmits > 0)
307  {
308  //Use the IPv6 address as a tentative address
311  }
312  else
313 #endif
314  {
315  //The use of the IPv6 address is now unrestricted
318  }
319 
320  //Exit immediately
321  return;
322  }
323  }
324  }
325 }
326 
327 
328 /**
329  * @brief Remove an entry from the list of IPv6 addresses
330  * @param[in] interface Underlying network interface
331  * @param[in] addr IPv6 address
332  **/
333 
334 void ipv6RemoveAddr(NetInterface *interface, const Ipv6Addr *addr)
335 {
336  uint_t i;
337  Ipv6AddrEntry *entry;
338 
339  //Loop through the list of IPv6 addresses assigned to the interface
340  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
341  {
342  //Point to the current entry
343  entry = &interface->ipv6Context.addrList[i];
344 
345  //Valid IPv6 address?
346  if(entry->validLifetime)
347  {
348  //Check whether the current entry matches the specified address
349  if(ipv6CompAddr(&entry->addr, addr))
350  {
351  //The IPv6 address should be preserved if it has been manually assigned
352  if(!entry->permanent)
353  {
354  //Remove the IPv6 address from the list
355  ipv6SetAddr(interface, i, &IPV6_UNSPECIFIED_ADDR,
357  }
358  }
359  }
360  }
361 }
362 
363 
364 /**
365  * @brief Add a new entry to the Prefix List
366  * @param[in] interface Underlying network interface
367  * @param[in] prefix IPv6 prefix
368  * @param[in] length The number of leading bits in the prefix that are valid
369  * @param[in] onLinkFlag On-link flag
370  * @param[in] autonomousFlag Autonomous flag
371  * @param[in] validLifetime Valid lifetime, in seconds
372  * @param[in] preferredLifetime Preferred lifetime, in seconds
373  **/
374 
375 void ipv6AddPrefix(NetInterface *interface, const Ipv6Addr *prefix,
376  uint_t length, bool_t onLinkFlag, bool_t autonomousFlag,
377  uint32_t validLifetime, uint32_t preferredLifetime)
378 {
379  uint_t i;
380  Ipv6PrefixEntry *entry;
381  Ipv6PrefixEntry *firstFreeEntry;
382 
383  //Initialize variables
384  entry = NULL;
385  firstFreeEntry = NULL;
386 
387  //Loop through the Prefix List
388  for(i = 0; i < IPV6_PREFIX_LIST_SIZE; i++)
389  {
390  //Point to the current entry
391  entry = &interface->ipv6Context.prefixList[i];
392 
393  //Valid prefix?
394  if(entry->validLifetime)
395  {
396  //Compare prefix length against the specified value
397  if(entry->prefixLen == length)
398  {
399  //Check whether the current entry matches the specified prefix
400  if(ipv6CompPrefix(&entry->prefix, prefix, length))
401  break;
402  }
403  }
404  else
405  {
406  //The IPv6 prefix should be preserved if it has been manually assigned
407  if(!entry->permanent)
408  {
409  //Keep track of the first free entry
410  if(firstFreeEntry == NULL)
411  firstFreeEntry = entry;
412  }
413  }
414  }
415 
416  //No matching entry found?
417  if(i >= IPV6_PREFIX_LIST_SIZE)
418  entry = firstFreeEntry;
419 
420  //Update the entry if necessary
421  if(entry != NULL)
422  {
423  //The IPv6 prefix should be preserved if it has been manually assigned
424  if(!entry->permanent)
425  {
426  //Save the IPv6 prefix
427  entry->prefix = *prefix;
428  entry->prefixLen = length;
429 
430  //Save On-link and Autonomous flags
431  entry->onLinkFlag = onLinkFlag;
432  entry->autonomousFlag = autonomousFlag;
433 
434  //Check the valid lifetime
436  {
437  //The length of time in seconds that the prefix is valid
438  //for the purpose of on-link determination
439  if(validLifetime < (MAX_DELAY / 1000))
440  entry->validLifetime = validLifetime * 1000;
441  else
442  entry->validLifetime = MAX_DELAY;
443  }
444  else
445  {
446  //A value of all one bits (0xffffffff) represents infinity
447  entry->validLifetime = INFINITE_DELAY;
448  }
449 
450  //Check the preferred lifetime
452  {
453  //The length of time in seconds that addresses generated from the
454  //prefix via stateless address autoconfiguration remain preferred
455  if(preferredLifetime < (MAX_DELAY / 1000))
456  entry->preferredLifetime = preferredLifetime * 1000;
457  else
458  entry->preferredLifetime = MAX_DELAY;
459  }
460  else
461  {
462  //A value of all one bits (0xffffffff) represents infinity
464  }
465 
466  //Save current time
467  entry->timestamp = osGetSystemTime();
468  }
469  }
470 }
471 
472 
473 /**
474  * @brief Remove an entry from the Prefix List
475  * @param[in] interface Underlying network interface
476  * @param[in] prefix IPv6 prefix
477  * @param[in] length The number of leading bits in the prefix that are valid
478  **/
479 
481  uint_t length)
482 {
483  uint_t i;
484  Ipv6PrefixEntry *entry;
485 
486  //Loop through the Prefix List
487  for(i = 0; i < IPV6_PREFIX_LIST_SIZE; i++)
488  {
489  //Point to the current entry
490  entry = &interface->ipv6Context.prefixList[i];
491 
492  //Valid prefix?
493  if(entry->validLifetime)
494  {
495  //Compare prefix length against the specified value
496  if(entry->prefixLen == length)
497  {
498  //Check whether the current entry matches the specified prefix
499  if(ipv6CompPrefix(&entry->prefix, prefix, length))
500  {
501  //The IPv6 prefix should be preserved if it has been manually assigned
502  if(!entry->permanent)
503  {
504  //When removing an entry from the Prefix List, there is no need
505  //to purge any entries from the Destination or Neighbor Caches
506  entry->prefix = IPV6_UNSPECIFIED_ADDR;
507  entry->prefixLen = 0;
508  entry->validLifetime = 0;
509  }
510  }
511  }
512  }
513  }
514 }
515 
516 
517 /**
518  * @brief Add a new entry to the Default Router List
519  * @param[in] interface Underlying network interface
520  * @param[in] addr IPv6 address of the router
521  * @param[in] lifetime Router lifetime, in seconds
522  * @param[in] preference Preference value
523  **/
524 
526  uint16_t lifetime, uint8_t preference)
527 {
528  uint_t i;
529  Ipv6RouterEntry *entry;
530  Ipv6RouterEntry *firstFreeEntry;
531 
532  //Initialize variables
533  entry = NULL;
534  firstFreeEntry = NULL;
535 
536  //Loop through the Default Router List
537  for(i = 0; i < IPV6_ROUTER_LIST_SIZE; i++)
538  {
539  //Point to the current entry
540  entry = &interface->ipv6Context.routerList[i];
541 
542  //Check the lifetime associated with the default router
543  if(entry->lifetime)
544  {
545  //Check whether the current entry matches the specified router address
546  if(ipv6CompAddr(&entry->addr, addr))
547  break;
548  }
549  else
550  {
551  //The router address should be preserved if it has been manually assigned
552  if(!entry->permanent)
553  {
554  //Keep track of the first free entry
555  if(firstFreeEntry == NULL)
556  firstFreeEntry = entry;
557  }
558  }
559  }
560 
561  //No matching entry found?
562  if(i >= IPV6_ROUTER_LIST_SIZE)
563  entry = firstFreeEntry;
564 
565  //Update the entry if necessary
566  if(entry != NULL)
567  {
568  //The router address should be preserved if it has been manually assigned
569  if(!entry->permanent)
570  {
571  //Save the IPv6 address of the router
572  entry->addr = *addr;
573  //The lifetime associated with the default router
574  entry->lifetime = lifetime * 1000;
575  //Save preference value
576  entry->preference = preference;
577  //Save current time
578  entry->timestamp = osGetSystemTime();
579  }
580  }
581 }
582 
583 
584 /**
585  * @brief Remove an entry from the Default Router List
586  * @param[in] interface Underlying network interface
587  * @param[in] addr IPv6 address of the router to be removed from the list
588  **/
589 
591 {
592  uint_t i;
593  bool_t flag;
594  Ipv6RouterEntry *entry;
595 
596  //This flag will be set if any entry has been removed from
597  //the Default Router List
598  flag = FALSE;
599 
600  //Loop through the Default Router List
601  for(i = 0; i < IPV6_ROUTER_LIST_SIZE; i++)
602  {
603  //Point to the current entry
604  entry = &interface->ipv6Context.routerList[i];
605 
606  //Check the lifetime associated with the default router
607  if(entry->lifetime)
608  {
609  //Check whether the current entry matches the specified router address
610  if(ipv6CompAddr(&entry->addr, addr))
611  {
612  //The router address should be preserved if it has been manually assigned
613  if(!entry->permanent)
614  {
615  //Immediately time-out the entry
616  entry->addr = IPV6_UNSPECIFIED_ADDR;
617  entry->lifetime = 0;
618 
619  //Set flag
620  flag = TRUE;
621  }
622  }
623  }
624  }
625 
626  //Check whether an entry has been removed from the list
627  if(flag)
628  {
629 #if (NDP_SUPPORT == ENABLED)
630  //When removing a router from the Default Router list, the node must
631  //update the Destination Cache in such a way that all entries using
632  //the router perform next-hop determination again
633  ndpFlushDestCache(interface);
634 #endif
635  }
636 }
637 
638 
639 /**
640  * @brief Flush the list of IPv6 addresses
641  * @param[in] interface Underlying network interface
642  **/
643 
645 {
646  uint_t i;
647  Ipv6AddrEntry *entry;
648 
649  //Go through the list of IPv6 addresses
650  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
651  {
652  //Point to the current entry
653  entry = &interface->ipv6Context.addrList[i];
654 
655  //Valid IPv6 address?
656  if(entry->validLifetime > 0)
657  {
658  //The IPv6 address should be preserved if it has been manually assigned
659  if(!entry->permanent)
660  {
661  //The IPv6 address is not longer valid
662  ipv6SetAddr(interface, i, &IPV6_UNSPECIFIED_ADDR,
664  }
665  }
666  }
667 }
668 
669 
670 /**
671  * @brief Flush the Prefix List
672  * @param[in] interface Underlying network interface
673  **/
674 
676 {
677  uint_t i;
678  Ipv6PrefixEntry *entry;
679 
680  //Go through the Prefix List
681  for(i = 0; i < IPV6_PREFIX_LIST_SIZE; i++)
682  {
683  //Point to the current entry
684  entry = &interface->ipv6Context.prefixList[i];
685 
686  //Valid IPv6 prefix?
687  if(entry->validLifetime > 0)
688  {
689  //The IPv6 prefix should be preserved if it has been manually assigned
690  if(!entry->permanent)
691  {
692  //Remove the entry from the Prefix List
693  entry->prefix = IPV6_UNSPECIFIED_ADDR;
694  entry->prefixLen = 0;
695  entry->validLifetime = 0;
696  }
697  }
698  }
699 }
700 
701 
702 /**
703  * @brief Flush the Default Router List
704  * @param[in] interface Underlying network interface
705  **/
706 
708 {
709  uint_t i;
710  Ipv6RouterEntry *entry;
711 
712  //Go through the Default Router List
713  for(i = 0; i < IPV6_ROUTER_LIST_SIZE; i++)
714  {
715  //Point to the current entry
716  entry = &interface->ipv6Context.routerList[i];
717 
718  //Valid entry?
719  if(entry->lifetime > 0)
720  {
721  //The router address should be preserved if it has been manually assigned
722  if(!entry->permanent)
723  {
724  //Clear the current entry
725  entry->addr = IPV6_UNSPECIFIED_ADDR;
726  //Remove the entry from the Default Router List
727  entry->lifetime = 0;
728  }
729  }
730  }
731 }
732 
733 
734 /**
735  * @brief Flush the list of DNS servers
736  * @param[in] interface Underlying network interface
737  **/
738 
740 {
741  //Clear the list of DNS servers
742  memset(interface->ipv6Context.dnsServerList, 0,
743  sizeof(interface->ipv6Context.dnsServerList));
744 }
745 
746 
747 /**
748  * @brief Source IPv6 address filtering
749  * @param[in] interface Underlying network interface
750  * @param[in] ipAddr Source IPv6 address to be checked
751  * @return Error code
752  **/
753 
755 {
756  //Multicast addresses cannot be used as source address
758  {
759  //Debug message
760  TRACE_WARNING("Wrong source IPv6 address!\r\n");
761  //The source address not is acceptable
762  return ERROR_INVALID_ADDRESS;
763  }
764 
765  //The source address is acceptable
766  return NO_ERROR;
767 }
768 
769 
770 /**
771  * @brief Destination IPv6 address filtering
772  * @param[in] interface Underlying network interface
773  * @param[in] ipAddr Destination IPv6 address to be checked
774  * @return Error code
775  **/
776 
778 {
779  error_t error;
780  uint_t i;
781  Ipv6AddrEntry *entry;
782 
783  //Filter out any invalid addresses
784  error = ERROR_INVALID_ADDRESS;
785 
786  //Multicast address?
788  {
789  //Go through the multicast filter table
790  for(i = 0; i < IPV6_MULTICAST_FILTER_SIZE; i++)
791  {
792  Ipv6FilterEntry *entry;
793 
794  //Point to the current entry
795  entry = &interface->ipv6Context.multicastFilter[i];
796 
797  //Valid entry?
798  if(entry->refCount > 0)
799  {
800  //Check whether the destination IPv6 address matches
801  //a relevant multicast address
802  if(ipv6CompAddr(&entry->addr, ipAddr))
803  {
804  //The multicast address is acceptable
805  error = NO_ERROR;
806  //Stop immediately
807  break;
808  }
809  }
810  }
811  }
812  //Unicast address?
813  else
814  {
815  //Loop through the list of IPv6 unicast addresses
816  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
817  {
818  //Point to the current entry
819  entry = &interface->ipv6Context.addrList[i];
820 
821  //Valid entry?
822  if(entry->state != IPV6_ADDR_STATE_INVALID)
823  {
824  //Check whether the destination address matches a valid unicast
825  //address assigned to the interface
826  if(ipv6CompAddr(&entry->addr, ipAddr))
827  {
828  //The destination address is acceptable
829  error = NO_ERROR;
830  //We are done
831  break;
832  }
833  }
834  }
835 
836  //Check whether the specified is a valid unicast address
837  if(error == ERROR_INVALID_ADDRESS)
838  {
839  Ipv6Addr *anycastAddrList;
840 
841  //Point to the list of anycast addresses assigned to the interface
842  anycastAddrList = interface->ipv6Context.anycastAddrList;
843 
844  //Loop through the list of IPv6 anycast addresses
845  for(i = 0; i < IPV6_ANYCAST_ADDR_LIST_SIZE; i++)
846  {
847  //Valid entry?
848  if(!ipv6CompAddr(&anycastAddrList[i], &IPV6_UNSPECIFIED_ADDR))
849  {
850  //Check whether the destination address matches a valid anycast
851  //address assigned to the interface
852  if(ipv6CompAddr(&anycastAddrList[i], ipAddr))
853  {
854  //The destination address is acceptable
855  error = NO_ERROR;
856  //We are done
857  break;
858  }
859  }
860  }
861  }
862  }
863 
864  //Return status code
865  return error;
866 }
867 
868 
869 /**
870  * @brief IPv6 source address selection
871  *
872  * This function selects the source address and the relevant network interface
873  * to be used in order to join the specified destination address
874  *
875  * @param[in,out] interface A pointer to a valid network interface may be provided as
876  * a hint. The function returns a pointer identifying the interface to be used
877  * @param[in] destAddr Destination IPv6 address
878  * @param[out] srcAddr Local IPv6 address to be used
879  * @return Error code
880  **/
881 
884 {
885  error_t error;
886  uint_t i;
887  uint_t j;
888  NetInterface *currentInterface;
889  NetInterface *bestInterface;
890  Ipv6AddrEntry *currentAddr;
891  Ipv6AddrEntry *bestAddr;
892 
893  //Initialize variables
894  bestInterface = NULL;
895  bestAddr = NULL;
896 
897  //Loop through network interfaces
898  for(i = 0; i < NET_INTERFACE_COUNT; i++)
899  {
900  //Point to the current interface
901  currentInterface = &netInterface[i];
902 
903  //A network interface may be provided as a hint
904  if(*interface != currentInterface && *interface != NULL)
905  {
906  //Select the next interface in the list
907  continue;
908  }
909 
910  //A sort of the candidate source addresses is being performed, where a
911  //set of rules define the ordering among addresses (refer to RFC 6724)
912  for(j = 0; j < IPV6_ADDR_LIST_SIZE; j++)
913  {
914  //Point to the current entry
915  currentAddr = &currentInterface->ipv6Context.addrList[j];
916 
917  //Check the state of the address
918  if(currentAddr->state == IPV6_ADDR_STATE_PREFERRED ||
919  currentAddr->state == IPV6_ADDR_STATE_DEPRECATED)
920  {
921  //Select the first address as default
922  if(bestAddr == NULL)
923  {
924  //Give the current source address the higher precedence
925  bestInterface = currentInterface;
926  bestAddr = currentAddr;
927 
928  //Select the next address in the list
929  continue;
930  }
931 
932  //Rule 1: Prefer same address
933  if(ipv6CompAddr(&bestAddr->addr, destAddr))
934  {
935  //Select the next address in the list
936  continue;
937  }
938  else if(ipv6CompAddr(&currentAddr->addr, destAddr))
939  {
940  //Give the current source address the higher precedence
941  bestInterface = currentInterface;
942  bestAddr = currentAddr;
943 
944  //Select the next address in the list
945  continue;
946  }
947 
948  //Rule 2: Prefer appropriate scope
949  if(ipv6GetAddrScope(&currentAddr->addr) < ipv6GetAddrScope(&bestAddr->addr))
950  {
951  if(ipv6GetAddrScope(&currentAddr->addr) >= ipv6GetAddrScope(destAddr))
952  {
953  //Give the current source address the higher precedence
954  bestInterface = currentInterface;
955  bestAddr = currentAddr;
956  }
957 
958  //Select the next address in the list
959  continue;
960  }
961  else if(ipv6GetAddrScope(&bestAddr->addr) < ipv6GetAddrScope(&currentAddr->addr))
962  {
964  {
965  //Give the current source address the higher precedence
966  bestInterface = currentInterface;
967  bestAddr = currentAddr;
968  }
969 
970  //Select the next address in the list
971  continue;
972  }
973 
974  //Rule 3: Avoid deprecated addresses
975  if(bestAddr->state == IPV6_ADDR_STATE_PREFERRED &&
976  currentAddr->state == IPV6_ADDR_STATE_DEPRECATED)
977  {
978  //Select the next address in the list
979  continue;
980  }
981  else if(currentAddr->state == IPV6_ADDR_STATE_PREFERRED &&
982  bestAddr->state == IPV6_ADDR_STATE_DEPRECATED)
983  {
984  //Give the current source address the higher precedence
985  bestInterface = currentInterface;
986  bestAddr = currentAddr;
987 
988  //Select the next address in the list
989  continue;
990  }
991 
992  //Rule 8: Use longest matching prefix
993  if(ipv6GetCommonPrefixLength(&currentAddr->addr, destAddr) >
995  {
996  //Give the current source address the higher precedence
997  bestInterface = currentInterface;
998  bestAddr = currentAddr;
999  }
1000  }
1001  }
1002  }
1003 
1004  //Valid source address?
1005  if(bestAddr != NULL)
1006  {
1007  //Return the out-going interface and the source address to be used
1008  *interface = bestInterface;
1009  *srcAddr = bestAddr->addr;
1010 
1011  //Successful source address selection
1012  error = NO_ERROR;
1013  }
1014  else
1015  {
1016  //Report an error
1017  error = ERROR_NO_ADDRESS;
1018  }
1019 
1020  //Return status code
1021  return error;
1022 }
1023 
1024 
1025 /**
1026  * @brief Check whether an IPv6 address is on-link
1027  * @param[in] interface Underlying network interface
1028  * @param[in] ipAddr IPv6 address to be checked
1029  * @return TRUE if the IPv6 address is on-link, else FALSE
1030  **/
1031 
1033 {
1034  uint_t i;
1035  Ipv6PrefixEntry *entry;
1036 
1037  //Link-local prefix?
1039  {
1040  //The link-local prefix is considered to be on the prefix list with
1041  //an infinite invalidation timer regardless of whether routers are
1042  //advertising a prefix for it
1043  return TRUE;
1044  }
1045 
1046  //Loop through the Prefix List
1047  for(i = 0; i < IPV6_PREFIX_LIST_SIZE; i++)
1048  {
1049  //Point to the current entry
1050  entry = &interface->ipv6Context.prefixList[i];
1051 
1052  //Valid prefix?
1053  if(entry->validLifetime > 0)
1054  {
1055  //Check the specified address against the prefix
1056  if(ipv6CompPrefix(ipAddr, &entry->prefix, entry->prefixLen))
1057  {
1058  //The specified IPv6 address is on-link
1059  return TRUE;
1060  }
1061  }
1062  }
1063 
1064  //The specified IPv6 address is off-link
1065  return FALSE;
1066 }
1067 
1068 
1069 /**
1070  * @brief Check whether an IPv6 address is an anycast address
1071  * @param[in] interface Underlying network interface
1072  * @param[in] ipAddr IPv6 address to be checked
1073  * @return TRUE if the IPv6 address is an anycast address, else FALSE
1074  **/
1075 
1077 {
1078  uint_t i;
1079  Ipv6Addr *anycastAddrList;
1080 
1081  //Point to the list of anycast addresses assigned to the interface
1082  anycastAddrList = interface->ipv6Context.anycastAddrList;
1083 
1084  //Loop through the list of IPv6 anycast addresses
1085  for(i = 0; i < IPV6_ANYCAST_ADDR_LIST_SIZE; i++)
1086  {
1087  //Valid entry?
1088  if(!ipv6CompAddr(&anycastAddrList[i], &IPV6_UNSPECIFIED_ADDR))
1089  {
1090  //Check whether the specified address matches a valid anycast
1091  //address assigned to the interface
1092  if(ipv6CompAddr(&anycastAddrList[i], ipAddr))
1093  {
1094  //The specified IPv6 address is an anycast address
1095  return TRUE;
1096  }
1097  }
1098  }
1099 
1100  //The specified IPv6 address is not an anycast address
1101  return FALSE;
1102 }
1103 
1104 
1105 /**
1106  * @brief Check whether an IPv6 address is a tentative address
1107  * @param[in] interface Underlying network interface
1108  * @param[in] ipAddr IPv6 address to be checked
1109  * @return TRUE if the IPv6 address is a tentative address, else FALSE
1110  **/
1111 
1113 {
1114  uint_t i;
1115  Ipv6AddrEntry *entry;
1116 
1117  //Loop through the list of IPv6 unicast addresses
1118  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
1119  {
1120  //Point to the current entry
1121  entry = &interface->ipv6Context.addrList[i];
1122 
1123  //Tentative address?
1124  if(entry->state == IPV6_ADDR_STATE_TENTATIVE)
1125  {
1126  //Check whether the specified address matches a valid unicast
1127  //address assigned to the interface
1128  if(ipv6CompAddr(&entry->addr, ipAddr))
1129  {
1130  //The specified IPv6 address is a tentative address
1131  return TRUE;
1132  }
1133  }
1134  }
1135 
1136  //The specified IPv6 address is not a tentative address
1137  return FALSE;
1138 }
1139 
1140 
1141 /**
1142  * @brief Check whether the specified IPv6 is assigned to the host
1143  * @param[in] ipAddr IPv6 address to be checked
1144  * @return TRUE if the IPv6 address matches any address assigned to the host,
1145  * else FALSE
1146  **/
1147 
1149 {
1150  uint_t i;
1151  uint_t j;
1152  bool_t flag;
1153  NetInterface *interface;
1154  Ipv6AddrEntry *entry;
1155 
1156  //Initialize flag
1157  flag = FALSE;
1158 
1159  //Loopback address?
1161  {
1162  //If an application in a host sends packets to this address, the IPv6
1163  //stack will loop these packets back on the same virtual interface
1164  flag = TRUE;
1165  }
1166  else
1167  {
1168  //Loop through network interfaces
1169  for(i = 0; i < NET_INTERFACE_COUNT && !flag; i++)
1170  {
1171  //Point to the current interface
1172  interface = &netInterface[i];
1173 
1174  //Iterate through the list of addresses assigned to the interface
1175  for(j = 0; j < IPV6_ADDR_LIST_SIZE && !flag; j++)
1176  {
1177  //Point to the current entry
1178  entry = &interface->ipv6Context.addrList[j];
1179 
1180  //Valid entry?
1181  if(entry->state == IPV6_ADDR_STATE_PREFERRED ||
1183  {
1184  //Check whether the specified IPv6 address matches any address
1185  //assigned to the host
1186  if(ipv6CompAddr(&entry->addr, ipAddr))
1187  {
1188  flag = TRUE;
1189  }
1190  }
1191  }
1192  }
1193  }
1194 
1195  //Return TRUE if the specified address matches any address assigned to the host
1196  return flag;
1197 }
1198 
1199 
1200 /**
1201  * @brief Compare IPv6 address prefixes
1202  * @param[in] ipAddr1 Pointer to the first IPv6 address
1203  * @param[in] ipAddr2 Pointer to the second IPv6 address
1204  * @param[in] length Prefix length
1205  * @return TRUE if the prefixes match each other, else FALSE
1206  **/
1207 
1208 bool_t ipv6CompPrefix(const Ipv6Addr *ipAddr1, const Ipv6Addr *ipAddr2,
1209  size_t length)
1210 {
1211  size_t n;
1212  size_t m;
1213  uint8_t mask;
1214 
1215  //Ensure the prefix length is valid
1216  if(length > 128)
1217  return FALSE;
1218 
1219  //Number of complete bytes
1220  n = length / 8;
1221  //Number of bits in the last byte, if any
1222  m = length % 8;
1223 
1224  //Compare the first part
1225  if(n > 0)
1226  {
1227  if(memcmp(ipAddr1, ipAddr2, n))
1228  return FALSE;
1229  }
1230 
1231  //Compare the remaining bits, if any
1232  if(m > 0)
1233  {
1234  //Calculate the mask to be applied
1235  mask = ((1 << m) - 1) << (8 - m);
1236 
1237  //Check remaining bits
1238  if((ipAddr1->b[n] & mask) != (ipAddr2->b[n] & mask))
1239  return FALSE;
1240  }
1241 
1242  //The prefixes match each other
1243  return TRUE;
1244 }
1245 
1246 
1247 /**
1248  * @brief Retrieve the scope of an IPv6 address
1249  * @param[in] ipAddr Pointer to an IPv6 address
1250  * @return IPv6 address scope
1251  **/
1252 
1254 {
1255  uint_t scope;
1256 
1257  //Multicast address?
1259  {
1260  //Retrieve the scope of the multicast address
1262  }
1263  //Loopback address?
1265  {
1266  //The loopback address may be used by a node to send an IPv6 packet
1267  //to itself
1269  }
1270  //Link-local unicast address?
1272  {
1273  //A link-local address is for use on a single link
1275  }
1276  //Site-local unicast address?
1278  {
1279  //A site-local address is for use in a single site
1281  }
1282  //Global address?
1283  else
1284  {
1285  //Global scope
1286  scope = IPV6_ADDR_SCOPE_GLOBAL;
1287  }
1288 
1289  //Return the scope of the specified IPv6 address
1290  return scope;
1291 }
1292 
1293 
1294 /**
1295  * @brief Retrieve the scope of an IPv6 multicast address
1296  * @param[in] ipAddr Pointer to an IPv6 multicast address
1297  * @return IPv6 address scope
1298  **/
1299 
1301 {
1302  uint_t scope;
1303 
1304  //The scope field is a 4-bit value
1305  scope = ipAddr->b[1] & 0x0F;
1306 
1307  //If the scope field contains the reserved value F, an IPv6 packet
1308  //must be treated the same as packets destined to a global multicast
1309  //address (refer to RFC 3513 section 2.7)
1310  if(scope == 0x0F)
1311  {
1312  scope = IPV6_ADDR_SCOPE_GLOBAL;
1313  }
1314 
1315  //Return the scope of the specified IPv6 multicast address
1316  return scope;
1317 }
1318 
1319 
1320 /**
1321  * @brief Compute the length of the longest common prefix
1322  * @param[in] ipAddr1 Pointer to the first IPv6 address
1323  * @param[in] ipAddr2 Pointer to the second IPv6 address
1324  * @return The length of the longest common prefix, in bits
1325  **/
1326 
1328  const Ipv6Addr *ipAddr2)
1329 {
1330  uint_t i;
1331  uint_t j;
1332  uint8_t mask;
1333 
1334  //Clear bit counter
1335  j = 0;
1336 
1337  //Perform a byte-for-byte comparison
1338  for(i = 0; i < sizeof(Ipv6Addr); i++)
1339  {
1340  //Loop as long as prefixes match
1341  if(ipAddr1->b[i] != ipAddr2->b[i])
1342  {
1343  break;
1344  }
1345  }
1346 
1347  //Any mismatch?
1348  if(i < sizeof(Ipv6Addr))
1349  {
1350  //Perform a bit-for-bit comparison
1351  for(j = 0; j < 8; j++)
1352  {
1353  //Calculate the mask to be applied
1354  mask = 1 << (7 - j);
1355 
1356  //Loop as long as prefixes match
1357  if((ipAddr1->b[i] & mask) != (ipAddr2->b[i] & mask))
1358  {
1359  break;
1360  }
1361  }
1362  }
1363 
1364  //Return the length of the longest prefix that the two addresses
1365  //have in common
1366  return i * 8 + j;
1367 }
1368 
1369 
1370 /**
1371  * @brief Form a solicited-node address from an IPv6 address
1372  * @param[in] ipAddr Unicast or anycast address
1373  * @param[out] solicitedNodeAddr Corresponding solicited-node address
1374  * @return Error code
1375  **/
1376 
1378  Ipv6Addr *solicitedNodeAddr)
1379 {
1380  error_t error;
1381 
1382  //Ensure the specified address is a valid unicast or anycast address
1384  {
1385  //Copy the 104-bit prefix
1386  ipv6CopyAddr(solicitedNodeAddr, &IPV6_SOLICITED_NODE_ADDR_PREFIX);
1387 
1388  //Take the low-order 24 bits of the address (unicast or anycast) and
1389  //append those bits to the prefix
1390  solicitedNodeAddr->b[13] = ipAddr->b[13];
1391  solicitedNodeAddr->b[14] = ipAddr->b[14];
1392  solicitedNodeAddr->b[15] = ipAddr->b[15];
1393 
1394  //Sucessful processing
1395  error = NO_ERROR;
1396  }
1397  else
1398  {
1399  //Report an error
1400  error = ERROR_INVALID_ADDRESS;
1401  }
1402 
1403  //Return status code
1404  return error;
1405 }
1406 
1407 
1408 /**
1409  * @brief Map an IPv6 multicast address to a MAC-layer multicast address
1410  * @param[in] ipAddr IPv6 multicast address
1411  * @param[out] macAddr Corresponding MAC-layer multicast address
1412  * @return Error code
1413  **/
1414 
1416 {
1417  error_t error;
1418 
1419  //Ensure the specified IPv6 address is a multicast address
1421  {
1422  //To support IPv6 multicasting, MAC address range of 33-33-00-00-00-00
1423  //to 33-33-FF-FF-FF-FF is reserved (refer to RFC 2464)
1424  macAddr->b[0] = 0x33;
1425  macAddr->b[1] = 0x33;
1426 
1427  //The low-order 32 bits of the IPv6 multicast address are mapped directly
1428  //to the low-order 32 bits in the MAC-layer multicast address
1429  macAddr->b[2] = ipAddr->b[12];
1430  macAddr->b[3] = ipAddr->b[13];
1431  macAddr->b[4] = ipAddr->b[14];
1432  macAddr->b[5] = ipAddr->b[15];
1433 
1434  //The specified IPv6 multicast address was successfully mapped to a
1435  //MAC-layer address
1436  error = NO_ERROR;
1437  }
1438  else
1439  {
1440  //Report an error
1441  error = ERROR_INVALID_ADDRESS;
1442  }
1443 
1444  //Return status code
1445  return error;
1446 }
1447 
1448 
1449 /**
1450  * @brief Generate a IPv6 link-local address from an interface identifier
1451  * @param[in] interfaceId Interface identifier
1452  * @param[out] ipAddr Corresponding IPv6 link-local address
1453  **/
1454 
1456 {
1457  //A link-local address is formed by combining the well-known link-local
1458  //prefix fe80::/10 with the interface identifier
1459  ipAddr->w[0] = HTONS(0xFE80);
1460  ipAddr->w[1] = HTONS(0x0000);
1461  ipAddr->w[2] = HTONS(0x0000);
1462  ipAddr->w[3] = HTONS(0x0000);
1463  ipAddr->w[4] = interfaceId->w[0];
1464  ipAddr->w[5] = interfaceId->w[1];
1465  ipAddr->w[6] = interfaceId->w[2];
1466  ipAddr->w[7] = interfaceId->w[3];
1467 }
1468 
1469 
1470 /**
1471  * @brief Update IPv6 input statistics
1472  * @param[in] interface Underlying network interface
1473  * @param[in] destIpAddr Destination IP address
1474  * @param[in] length Length of the incoming IP packet
1475  **/
1476 
1478  size_t length)
1479 {
1480  //Check whether the destination address is a unicast or multicast address
1482  {
1483  //Number of IP multicast datagrams transmitted
1484  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsInMcastPkts, 1);
1485  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCInMcastPkts, 1);
1486  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsInMcastPkts, 1);
1487  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCInMcastPkts, 1);
1488 
1489  //Total number of octets transmitted in IP multicast datagrams
1490  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsInMcastOctets, length);
1491  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCInMcastOctets, length);
1492  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsInMcastOctets, length);
1493  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCInMcastOctets, length);
1494  }
1495 }
1496 
1497 
1498 /**
1499  * @brief Update IPv6 output statistics
1500  * @param[in] interface Underlying network interface
1501  * @param[in] destIpAddr Destination IP address
1502  * @param[in] length Length of the outgoing IP packet
1503  **/
1504 
1506  size_t length)
1507 {
1508  //Check whether the destination address is a unicast or multicast address
1510  {
1511  //Number of IP multicast datagrams transmitted
1512  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsOutMcastPkts, 1);
1513  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCOutMcastPkts, 1);
1514  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsOutMcastPkts, 1);
1515  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCOutMcastPkts, 1);
1516 
1517  //Total number of octets transmitted in IP multicast datagrams
1518  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsOutMcastOctets, length);
1519  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCOutMcastOctets, length);
1520  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsOutMcastOctets, length);
1521  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCOutMcastOctets, length);
1522  }
1523 
1524  //Total number of IP datagrams that this entity supplied to the lower
1525  //layers for transmission
1526  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsOutTransmits, 1);
1527  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCOutTransmits, 1);
1528  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsOutTransmits, 1);
1529  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCOutTransmits, 1);
1530 
1531  //Total number of octets in IP datagrams delivered to the lower layers
1532  //for transmission
1533  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsOutOctets, length);
1534  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCOutOctets, length);
1535  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsOutOctets, length);
1536  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCOutOctets, length);
1537 }
1538 
1539 #endif
An address whose uniqueness on a link is being verified.
Definition: ipv6.h:172
systime_t timestamp
Timestamp to manage entry lifetime.
Definition: ipv6.h:440
IPv6 (Internet Protocol Version 6)
void ipv6AddDefaultRouter(NetInterface *interface, const Ipv6Addr *addr, uint16_t lifetime, uint8_t preference)
Add a new entry to the Default Router List.
Definition: ipv6_misc.c:525
uint8_t length
Definition: dtls_misc.h:149
systime_t lifetime
Router lifetime.
Definition: ipv6.h:437
int bool_t
Definition: compiler_port.h:49
MacAddr srcAddr
Definition: ethernet.h:193
__start_packed struct @109 Eui64
EUI-64 identifier.
void ipv6FlushPrefixList(NetInterface *interface)
Flush the Prefix List.
Definition: ipv6_misc.c:675
void ipv6UpdateOutStats(NetInterface *interface, const Ipv6Addr *destIpAddr, size_t length)
Update IPv6 output statistics.
Definition: ipv6_misc.c:1505
void ipv6RemovePrefix(NetInterface *interface, const Ipv6Addr *prefix, uint_t length)
Remove an entry from the Prefix List.
Definition: ipv6_misc.c:480
#define IP_MIB_INC_COUNTER32(name, value)
Definition: ip_mib_module.h:46
void ipv6RemoveDefaultRouter(NetInterface *interface, const Ipv6Addr *addr)
Remove an entry from the Default Router List.
Definition: ipv6_misc.c:590
systime_t preferredLifetime
Preferred lifetime.
Definition: ipv6.h:424
uint_t dadRetransmitCount
Retransmission counter for Duplicate Address Detection.
Definition: ipv6.h:409
const Ipv6Addr IPV6_SOLICITED_NODE_ADDR_PREFIX
Definition: ipv6.c:87
#define TRUE
Definition: os_port.h:50
uint32_t preferredLifetime
Ipv6AddrState ipv6GetAddrState(NetInterface *interface, const Ipv6Addr *addr)
Get the state of the specified IPv6 address.
Definition: ipv6_misc.c:55
Ipv6Addr addr
IPv6 address.
Definition: ipv6.h:401
systime_t preferredLifetime
Preferred lifetime.
Definition: ipv6.h:405
void ipv6FlushAddrList(NetInterface *interface)
Flush the list of IPv6 addresses.
Definition: ipv6_misc.c:644
systime_t timestamp
Timestamp to manage entry lifetime.
Definition: ipv6.h:426
bool_t autonomousFlag
Autonomous flag.
Definition: ipv6.h:422
systime_t validLifetime
Valid lifetime.
Definition: ipv6.h:423
#define NET_INTERFACE_COUNT
Definition: net.h:109
bool_t ipv6IsTentativeAddr(NetInterface *interface, const Ipv6Addr *ipAddr)
Check whether an IPv6 address is a tentative address.
Definition: ipv6_misc.c:1112
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:121
Ipv6Addr prefix
IPv6 prefix information.
Definition: ipv6.h:419
Ipv6Addr addr
Router address.
Definition: ipv6.h:436
uint32_t lifetime
Definition: ndp.h:479
Ipv6Addr prefix
#define NDP_INFINITE_LIFETIME
Definition: ndp.h:202
An address that is not assigned to any interface.
Definition: ipv6.h:171
#define ipv6IsSiteLocalUnicastAddr(ipAddr)
Definition: ipv6.h:129
MacAddr destAddr
Definition: ethernet.h:192
#define ipv6IsMulticastAddr(ipAddr)
Definition: ipv6.h:133
uint_t ipv6GetCommonPrefixLength(const Ipv6Addr *ipAddr1, const Ipv6Addr *ipAddr2)
Compute the length of the longest common prefix.
Definition: ipv6_misc.c:1327
#define FALSE
Definition: os_port.h:46
NetInterface netInterface[NET_INTERFACE_COUNT]
Definition: net.c:79
Invalid parameter.
Definition: error.h:47
void ipv6FlushDnsServerList(NetInterface *interface)
Flush the list of DNS servers.
Definition: ipv6_misc.c:739
NetInterface * nicGetPhysicalInterface(NetInterface *interface)
Retrieve physical interface.
Definition: nic.c:84
Ipv6AddrState
IPv6 address state.
Definition: ipv6.h:169
bool_t ipv6IsLocalHostAddr(const Ipv6Addr *ipAddr)
Check whether the specified IPv6 is assigned to the host.
Definition: ipv6_misc.c:1148
error_t
Error codes.
Definition: error.h:42
#define IP_MIB_INC_COUNTER64(name, value)
Definition: ip_mib_module.h:47
systime_t dadTimeout
Timeout value for Duplicate Address Detection.
Definition: ipv6.h:408
error_t ipv6SelectSourceAddr(NetInterface **interface, const Ipv6Addr *destAddr, Ipv6Addr *srcAddr)
IPv6 source address selection.
Definition: ipv6_misc.c:882
Prefix list entry.
Definition: ipv6.h:417
uint8_t preference
Preference value.
Definition: ipv6.h:438
bool_t permanent
Permanently assigned address.
Definition: ipv6.h:406
#define NetInterface
Definition: net.h:36
error_t ipv6CheckDestAddr(NetInterface *interface, const Ipv6Addr *ipAddr)
Destination IPv6 address filtering.
Definition: ipv6_misc.c:777
uint_t ipv6GetAddrScope(const Ipv6Addr *ipAddr)
Retrieve the scope of an IPv6 address.
Definition: ipv6_misc.c:1253
Helper functions for IPv6.
uint8_t mask
Definition: web_socket.h:317
#define IPV6_MULTICAST_FILTER_SIZE
Definition: ipv6.h:101
const Ipv6Addr IPV6_UNSPECIFIED_ADDR
Definition: ipv6.c:67
error_t ipv6LeaveMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Leave an IPv6 multicast group.
Definition: ipv6.c:2038
__start_packed struct @179 Ipv6Addr
IPv6 network address.
error_t ipv6JoinMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Join an IPv6 multicast group.
Definition: ipv6.c:1928
const Ipv6Addr IPV6_LOOPBACK_ADDR
Definition: ipv6.c:71
uint_t refCount
Reference count for the current entry.
Definition: ipv6.h:451
bool_t duplicate
The address is a duplicate.
Definition: ipv6.h:403
Eui64 interfaceId
Definition: ipv6cp.h:69
void ipv6RemoveAddr(NetInterface *interface, const Ipv6Addr *addr)
Remove an entry from the list of IPv6 addresses.
Definition: ipv6_misc.c:334
Neighbor and destination cache management.
Ipv6Addr addr
Multicast address.
Definition: ipv6.h:450
#define ipv6IsLinkLocalUnicastAddr(ipAddr)
Definition: ipv6.h:125
NDP (Neighbor Discovery Protocol)
void ipv6FlushDefaultRouterList(NetInterface *interface)
Flush the Default Router List.
Definition: ipv6_misc.c:707
bool_t onLinkFlag
On-link flag.
Definition: ipv6.h:421
error_t ipv6SetAddr(NetInterface *interface, uint_t index, const Ipv6Addr *addr, Ipv6AddrState state, systime_t validLifetime, systime_t preferredLifetime, bool_t permanent)
Set IPv6 address and address state.
Definition: ipv6_misc.c:95
bool_t permanent
Permanently assigned prefix.
Definition: ipv6.h:425
#define TRACE_WARNING(...)
Definition: debug.h:84
uint8_t prefixLen
IPv6 prefix length.
Definition: ipv6.h:420
void ndpFlushDestCache(NetInterface *interface)
Flush Destination Cache.
Definition: ndp_cache.c:472
void ipv6AddAddr(NetInterface *interface, const Ipv6Addr *addr, uint32_t validLifetime, uint32_t preferredLifetime)
Add a new entry to the list of IPv6 addresses.
Definition: ipv6_misc.c:224
#define ipv6CopyAddr(destIpAddr, srcIpAddr)
Definition: ipv6.h:117
#define IPV6_ANYCAST_ADDR_LIST_SIZE
Definition: ipv6.h:73
Default router list entry.
Definition: ipv6.h:434
IPv6 address entry.
Definition: ipv6.h:399
uint8_t m
Definition: ndp.h:302
#define HTONS(value)
Definition: cpu_endian.h:390
uint8_t n
#define IPV6_ROUTER_LIST_SIZE
Definition: ipv6.h:87
IP MIB module.
#define IPV6_ADDR_LIST_SIZE
Definition: ipv6.h:66
void ipv6GenerateLinkLocalAddr(const Eui64 *interfaceId, Ipv6Addr *ipAddr)
Generate a IPv6 link-local address from an interface identifier.
Definition: ipv6_misc.c:1455
bool_t ipv6IsAnycastAddr(NetInterface *interface, const Ipv6Addr *ipAddr)
Check whether an IPv6 address is an anycast address.
Definition: ipv6_misc.c:1076
bool_t ipv6CompPrefix(const Ipv6Addr *ipAddr1, const Ipv6Addr *ipAddr2, size_t length)
Compare IPv6 address prefixes.
Definition: ipv6_misc.c:1208
void ipv6AddPrefix(NetInterface *interface, const Ipv6Addr *prefix, uint_t length, bool_t onLinkFlag, bool_t autonomousFlag, uint32_t validLifetime, uint32_t preferredLifetime)
Add a new entry to the Prefix List.
Definition: ipv6_misc.c:375
error_t ipv6ComputeSolicitedNodeAddr(const Ipv6Addr *ipAddr, Ipv6Addr *solicitedNodeAddr)
Form a solicited-node address from an IPv6 address.
Definition: ipv6_misc.c:1377
systime_t validLifetime
Valid lifetime.
Definition: ipv6.h:404
uint32_t validLifetime
Ipv4Addr addr
Definition: nbns_common.h:121
#define MAX_DELAY
Definition: os_port.h:76
An address assigned to an interface whose use is unrestricted.
Definition: ipv6.h:173
bool_t permanent
Permanently assigned router.
Definition: ipv6.h:439
Ipv6AddrState state
IPv6 address state.
Definition: ipv6.h:402
uint_t ipv6GetMulticastAddrScope(const Ipv6Addr *ipAddr)
Retrieve the scope of an IPv6 multicast address.
Definition: ipv6_misc.c:1300
#define IPV6_PREFIX_LIST_SIZE
Definition: ipv6.h:80
6LoWPAN interface
Definition: nic.h:81
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
An address assigned to an interface whose use is discouraged.
Definition: ipv6.h:174
error_t ipv6CheckSourceAddr(NetInterface *interface, const Ipv6Addr *ipAddr)
Source IPv6 address filtering.
Definition: ipv6_misc.c:754
bool_t ipv6IsOnLink(NetInterface *interface, const Ipv6Addr *ipAddr)
Check whether an IPv6 address is on-link.
Definition: ipv6_misc.c:1032
error_t ipv6MapMulticastAddrToMac(const Ipv6Addr *ipAddr, MacAddr *macAddr)
Map an IPv6 multicast address to a MAC-layer multicast address.
Definition: ipv6_misc.c:1415
uint32_t systime_t
Definition: compiler_port.h:46
void ipv6UpdateInStats(NetInterface *interface, const Ipv6Addr *destIpAddr, size_t length)
Update IPv6 input statistics.
Definition: ipv6_misc.c:1477
uint8_t ipAddr[4]
Definition: mib_common.h:187
error_t mdnsResponderStartProbing(MdnsResponderContext *context)
Restart probing process.
Success.
Definition: error.h:44
Debugging facilities.
#define INFINITE_DELAY
Definition: os_port.h:74
__start_packed struct @108 MacAddr
MAC address.
systime_t timestamp
Timestamp to manage entry lifetime.
Definition: ipv6.h:407
mDNS responder (Multicast DNS)
IPv6 multicast filter entry.
Definition: ipv6.h:448
Ethernet interface.
Definition: nic.h:79
systime_t osGetSystemTime(void)
Retrieve system time.
Ipv4Addr destIpAddr
Definition: ipcp.h:78