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