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-2022 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 2.2.0
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  //Restart mDNS probing process
204  mdnsResponderStartProbing(interface->mdnsResponderContext);
205 #endif
206 
207  //Return status code
208  return error;
209 }
210 
211 
212 /**
213  * @brief Add a new entry to the list of IPv6 addresses
214  * @param[in] interface Underlying network interface
215  * @param[in] addr IPv6 address
216  * @param[in] validLifetime Valid lifetime, in seconds
217  * @param[in] preferredLifetime Preferred lifetime, in seconds
218  **/
219 
220 void ipv6AddAddr(NetInterface *interface, const Ipv6Addr *addr,
221  uint32_t validLifetime, uint32_t preferredLifetime)
222 {
223  uint_t i;
224  Ipv6AddrEntry *entry;
225 
226  //Check the valid lifetime
228  {
229  //The length of time in seconds that the address is valid
230  if(validLifetime < (MAX_DELAY / 1000))
231  validLifetime *= 1000;
232  else
234  }
235  else
236  {
237  //A value of all one bits (0xffffffff) represents infinity
239  }
240 
241  //Check the preferred lifetime
243  {
244  //The length of time in seconds that the address remains preferred
245  if(preferredLifetime < (MAX_DELAY / 1000))
246  preferredLifetime *= 1000;
247  else
249  }
250  else
251  {
252  //A value of all one bits (0xffffffff) represents infinity
254  }
255 
256  //Loop through the list of IPv6 addresses assigned to the interface
257  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
258  {
259  //Point to the current entry
260  entry = &interface->ipv6Context.addrList[i];
261 
262  //Check the state of the IPv6 address
263  if(entry->state == IPV6_ADDR_STATE_PREFERRED ||
265  {
266  //Check whether the current entry matches the specified address
267  if(ipv6CompAddr(&entry->addr, addr))
268  {
269  //The IPv6 address should be preserved if it has been manually assigned
270  if(!entry->permanent)
271  {
272  //Update the lifetimes of the entry
273  entry->validLifetime = validLifetime;
275 
276  //Save current time
277  entry->timestamp = osGetSystemTime();
278  //Update the state of the IPv6 address
280  }
281 
282  //Exit immediately
283  return;
284  }
285  }
286  }
287 
288  //If no matching entry was found, then try to create a new entry
289  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
290  {
291  //Point to the current entry
292  entry = &interface->ipv6Context.addrList[i];
293 
294  //Check the state of the IPv6 address
295  if(entry->state == IPV6_ADDR_STATE_INVALID)
296  {
297  //The IPv6 address should be preserved if it has been manually assigned
298  if(!entry->permanent)
299  {
300 #if (NDP_SUPPORT == ENABLED)
301  //Check whether Duplicate Address Detection should be performed
302  if(interface->ndpContext.dupAddrDetectTransmits > 0)
303  {
304  //Use the IPv6 address as a tentative address
307  }
308  else
309 #endif
310  {
311  //The use of the IPv6 address is now unrestricted
314  }
315 
316  //Exit immediately
317  return;
318  }
319  }
320  }
321 }
322 
323 
324 /**
325  * @brief Remove an entry from the list of IPv6 addresses
326  * @param[in] interface Underlying network interface
327  * @param[in] addr IPv6 address
328  **/
329 
330 void ipv6RemoveAddr(NetInterface *interface, const Ipv6Addr *addr)
331 {
332  uint_t i;
333  Ipv6AddrEntry *entry;
334 
335  //Loop through the list of IPv6 addresses assigned to the interface
336  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
337  {
338  //Point to the current entry
339  entry = &interface->ipv6Context.addrList[i];
340 
341  //Valid IPv6 address?
342  if(entry->validLifetime)
343  {
344  //Check whether the current entry matches the specified address
345  if(ipv6CompAddr(&entry->addr, addr))
346  {
347  //The IPv6 address should be preserved if it has been manually assigned
348  if(!entry->permanent)
349  {
350  //Remove the IPv6 address from the list
351  ipv6SetAddr(interface, i, &IPV6_UNSPECIFIED_ADDR,
353  }
354  }
355  }
356  }
357 }
358 
359 
360 /**
361  * @brief Add a new entry to the Prefix List
362  * @param[in] interface Underlying network interface
363  * @param[in] prefix IPv6 prefix
364  * @param[in] length The number of leading bits in the prefix that are valid
365  * @param[in] onLinkFlag On-link flag
366  * @param[in] autonomousFlag Autonomous flag
367  * @param[in] validLifetime Valid lifetime, in seconds
368  * @param[in] preferredLifetime Preferred lifetime, in seconds
369  **/
370 
371 void ipv6AddPrefix(NetInterface *interface, const Ipv6Addr *prefix,
372  uint_t length, bool_t onLinkFlag, bool_t autonomousFlag,
373  uint32_t validLifetime, uint32_t preferredLifetime)
374 {
375  uint_t i;
376  Ipv6PrefixEntry *entry;
377  Ipv6PrefixEntry *firstFreeEntry;
378 
379  //Initialize variables
380  entry = NULL;
381  firstFreeEntry = NULL;
382 
383  //Loop through the Prefix List
384  for(i = 0; i < IPV6_PREFIX_LIST_SIZE; i++)
385  {
386  //Point to the current entry
387  entry = &interface->ipv6Context.prefixList[i];
388 
389  //Valid prefix?
390  if(entry->validLifetime)
391  {
392  //Compare prefix length against the specified value
393  if(entry->prefixLen == length)
394  {
395  //Check whether the current entry matches the specified prefix
396  if(ipv6CompPrefix(&entry->prefix, prefix, length))
397  break;
398  }
399  }
400  else
401  {
402  //The IPv6 prefix should be preserved if it has been manually assigned
403  if(!entry->permanent)
404  {
405  //Keep track of the first free entry
406  if(firstFreeEntry == NULL)
407  firstFreeEntry = entry;
408  }
409  }
410  }
411 
412  //No matching entry found?
413  if(i >= IPV6_PREFIX_LIST_SIZE)
414  entry = firstFreeEntry;
415 
416  //Update the entry if necessary
417  if(entry != NULL)
418  {
419  //The IPv6 prefix should be preserved if it has been manually assigned
420  if(!entry->permanent)
421  {
422  //Save the IPv6 prefix
423  entry->prefix = *prefix;
424  entry->prefixLen = length;
425 
426  //Save On-link and Autonomous flags
427  entry->onLinkFlag = onLinkFlag;
428  entry->autonomousFlag = autonomousFlag;
429 
430  //Check the valid lifetime
432  {
433  //The length of time in seconds that the prefix is valid
434  //for the purpose of on-link determination
435  if(validLifetime < (MAX_DELAY / 1000))
436  entry->validLifetime = validLifetime * 1000;
437  else
438  entry->validLifetime = MAX_DELAY;
439  }
440  else
441  {
442  //A value of all one bits (0xffffffff) represents infinity
443  entry->validLifetime = INFINITE_DELAY;
444  }
445 
446  //Check the preferred lifetime
448  {
449  //The length of time in seconds that addresses generated from the
450  //prefix via stateless address autoconfiguration remain preferred
451  if(preferredLifetime < (MAX_DELAY / 1000))
452  entry->preferredLifetime = preferredLifetime * 1000;
453  else
454  entry->preferredLifetime = MAX_DELAY;
455  }
456  else
457  {
458  //A value of all one bits (0xffffffff) represents infinity
460  }
461 
462  //Save current time
463  entry->timestamp = osGetSystemTime();
464  }
465  }
466 }
467 
468 
469 /**
470  * @brief Remove an entry from the Prefix List
471  * @param[in] interface Underlying network interface
472  * @param[in] prefix IPv6 prefix
473  * @param[in] length The number of leading bits in the prefix that are valid
474  **/
475 
477  uint_t length)
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  osMemset(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  error_t error;
883  uint_t i;
884  uint_t j;
885  NetInterface *currentInterface;
886  NetInterface *bestInterface;
887  Ipv6AddrEntry *currentAddr;
888  Ipv6AddrEntry *bestAddr;
889 
890  //Initialize variables
891  bestInterface = NULL;
892  bestAddr = NULL;
893 
894  //Loop through network interfaces
895  for(i = 0; i < NET_INTERFACE_COUNT; i++)
896  {
897  //Point to the current interface
898  currentInterface = &netInterface[i];
899 
900  //A network interface may be provided as a hint
901  if(*interface != currentInterface && *interface != NULL)
902  {
903  //Select the next interface in the list
904  continue;
905  }
906 
907  //A sort of the candidate source addresses is being performed, where a
908  //set of rules define the ordering among addresses (refer to RFC 6724)
909  for(j = 0; j < IPV6_ADDR_LIST_SIZE; j++)
910  {
911  //Point to the current entry
912  currentAddr = &currentInterface->ipv6Context.addrList[j];
913 
914  //Check the state of the address
915  if(currentAddr->state == IPV6_ADDR_STATE_PREFERRED ||
916  currentAddr->state == IPV6_ADDR_STATE_DEPRECATED)
917  {
918  //Select the first address as default
919  if(bestAddr == NULL)
920  {
921  //Give the current source address the higher precedence
922  bestInterface = currentInterface;
923  bestAddr = currentAddr;
924 
925  //Select the next address in the list
926  continue;
927  }
928 
929  //Rule 1: Prefer same address
930  if(ipv6CompAddr(&bestAddr->addr, destAddr))
931  {
932  //Select the next address in the list
933  continue;
934  }
935  else if(ipv6CompAddr(&currentAddr->addr, destAddr))
936  {
937  //Give the current source address the higher precedence
938  bestInterface = currentInterface;
939  bestAddr = currentAddr;
940 
941  //Select the next address in the list
942  continue;
943  }
944 
945  //Rule 2: Prefer appropriate scope
946  if(ipv6GetAddrScope(&currentAddr->addr) < ipv6GetAddrScope(&bestAddr->addr))
947  {
948  if(ipv6GetAddrScope(&currentAddr->addr) >= ipv6GetAddrScope(destAddr))
949  {
950  //Give the current source address the higher precedence
951  bestInterface = currentInterface;
952  bestAddr = currentAddr;
953  }
954 
955  //Select the next address in the list
956  continue;
957  }
958  else if(ipv6GetAddrScope(&bestAddr->addr) < ipv6GetAddrScope(&currentAddr->addr))
959  {
961  {
962  //Give the current source address the higher precedence
963  bestInterface = currentInterface;
964  bestAddr = currentAddr;
965  }
966 
967  //Select the next address in the list
968  continue;
969  }
970 
971  //Rule 3: Avoid deprecated addresses
972  if(bestAddr->state == IPV6_ADDR_STATE_PREFERRED &&
973  currentAddr->state == IPV6_ADDR_STATE_DEPRECATED)
974  {
975  //Select the next address in the list
976  continue;
977  }
978  else if(currentAddr->state == IPV6_ADDR_STATE_PREFERRED &&
979  bestAddr->state == IPV6_ADDR_STATE_DEPRECATED)
980  {
981  //Give the current source address the higher precedence
982  bestInterface = currentInterface;
983  bestAddr = currentAddr;
984 
985  //Select the next address in the list
986  continue;
987  }
988 
989  //Rule 8: Use longest matching prefix
990  if(ipv6GetCommonPrefixLength(&currentAddr->addr, destAddr) >
992  {
993  //Give the current source address the higher precedence
994  bestInterface = currentInterface;
995  bestAddr = currentAddr;
996  }
997  }
998  }
999  }
1000 
1001  //Valid source address?
1002  if(bestAddr != NULL)
1003  {
1004  //Return the out-going interface and the source address to be used
1005  *interface = bestInterface;
1006  *srcAddr = bestAddr->addr;
1007 
1008  //Successful source address selection
1009  error = NO_ERROR;
1010  }
1011  else
1012  {
1013  //Report an error
1014  error = ERROR_NO_ADDRESS;
1015  }
1016 
1017  //Return status code
1018  return error;
1019 }
1020 
1021 
1022 /**
1023  * @brief Check whether an IPv6 address is on-link
1024  * @param[in] interface Underlying network interface
1025  * @param[in] ipAddr IPv6 address to be checked
1026  * @return TRUE if the IPv6 address is on-link, else FALSE
1027  **/
1028 
1030 {
1031  uint_t i;
1032  Ipv6PrefixEntry *entry;
1033 
1034  //Link-local prefix?
1036  {
1037  //The link-local prefix is considered to be on the prefix list with
1038  //an infinite invalidation timer regardless of whether routers are
1039  //advertising a prefix for it
1040  return TRUE;
1041  }
1042 
1043  //Loop through the Prefix List
1044  for(i = 0; i < IPV6_PREFIX_LIST_SIZE; i++)
1045  {
1046  //Point to the current entry
1047  entry = &interface->ipv6Context.prefixList[i];
1048 
1049  //Valid prefix?
1050  if(entry->validLifetime > 0)
1051  {
1052  //Check the specified address against the prefix
1053  if(ipv6CompPrefix(ipAddr, &entry->prefix, entry->prefixLen))
1054  {
1055  //The specified IPv6 address is on-link
1056  return TRUE;
1057  }
1058  }
1059  }
1060 
1061  //The specified IPv6 address is off-link
1062  return FALSE;
1063 }
1064 
1065 
1066 /**
1067  * @brief Check whether an IPv6 address is an anycast address
1068  * @param[in] interface Underlying network interface
1069  * @param[in] ipAddr IPv6 address to be checked
1070  * @return TRUE if the IPv6 address is an anycast address, else FALSE
1071  **/
1072 
1074 {
1075  uint_t i;
1076  Ipv6Addr *anycastAddrList;
1077 
1078  //Point to the list of anycast addresses assigned to the interface
1079  anycastAddrList = interface->ipv6Context.anycastAddrList;
1080 
1081  //Loop through the list of IPv6 anycast addresses
1082  for(i = 0; i < IPV6_ANYCAST_ADDR_LIST_SIZE; i++)
1083  {
1084  //Valid entry?
1085  if(!ipv6CompAddr(&anycastAddrList[i], &IPV6_UNSPECIFIED_ADDR))
1086  {
1087  //Check whether the specified address matches a valid anycast
1088  //address assigned to the interface
1089  if(ipv6CompAddr(&anycastAddrList[i], ipAddr))
1090  {
1091  //The specified IPv6 address is an anycast address
1092  return TRUE;
1093  }
1094  }
1095  }
1096 
1097  //The specified IPv6 address is not an anycast address
1098  return FALSE;
1099 }
1100 
1101 
1102 /**
1103  * @brief Check whether an IPv6 address is a tentative address
1104  * @param[in] interface Underlying network interface
1105  * @param[in] ipAddr IPv6 address to be checked
1106  * @return TRUE if the IPv6 address is a tentative address, else FALSE
1107  **/
1108 
1110 {
1111  uint_t i;
1112  Ipv6AddrEntry *entry;
1113 
1114  //Loop through the list of IPv6 unicast addresses
1115  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
1116  {
1117  //Point to the current entry
1118  entry = &interface->ipv6Context.addrList[i];
1119 
1120  //Tentative address?
1121  if(entry->state == IPV6_ADDR_STATE_TENTATIVE)
1122  {
1123  //Check whether the specified address matches a valid unicast
1124  //address assigned to the interface
1125  if(ipv6CompAddr(&entry->addr, ipAddr))
1126  {
1127  //The specified IPv6 address is a tentative address
1128  return TRUE;
1129  }
1130  }
1131  }
1132 
1133  //The specified IPv6 address is not a tentative address
1134  return FALSE;
1135 }
1136 
1137 
1138 /**
1139  * @brief Check whether the specified IPv6 is assigned to the host
1140  * @param[in] ipAddr IPv6 address to be checked
1141  * @return TRUE if the IPv6 address matches any address assigned to the host,
1142  * else FALSE
1143  **/
1144 
1146 {
1147  uint_t i;
1148  uint_t j;
1149  bool_t flag;
1150  NetInterface *interface;
1151  Ipv6AddrEntry *entry;
1152 
1153  //Initialize flag
1154  flag = FALSE;
1155 
1156  //Loopback address?
1158  {
1159  //If an application in a host sends packets to this address, the IPv6
1160  //stack will loop these packets back on the same virtual interface
1161  flag = TRUE;
1162  }
1163  else
1164  {
1165  //Loop through network interfaces
1166  for(i = 0; i < NET_INTERFACE_COUNT && !flag; i++)
1167  {
1168  //Point to the current interface
1169  interface = &netInterface[i];
1170 
1171  //Iterate through the list of addresses assigned to the interface
1172  for(j = 0; j < IPV6_ADDR_LIST_SIZE && !flag; j++)
1173  {
1174  //Point to the current entry
1175  entry = &interface->ipv6Context.addrList[j];
1176 
1177  //Valid entry?
1178  if(entry->state == IPV6_ADDR_STATE_PREFERRED ||
1180  {
1181  //Check whether the specified IPv6 address matches any address
1182  //assigned to the host
1183  if(ipv6CompAddr(&entry->addr, ipAddr))
1184  {
1185  flag = TRUE;
1186  }
1187  }
1188  }
1189  }
1190  }
1191 
1192  //Return TRUE if the specified address matches any address assigned to the host
1193  return flag;
1194 }
1195 
1196 
1197 /**
1198  * @brief Compare IPv6 address prefixes
1199  * @param[in] ipAddr1 Pointer to the first IPv6 address
1200  * @param[in] ipAddr2 Pointer to the second IPv6 address
1201  * @param[in] length Prefix length
1202  * @return TRUE if the prefixes match each other, else FALSE
1203  **/
1204 
1205 bool_t ipv6CompPrefix(const Ipv6Addr *ipAddr1, const Ipv6Addr *ipAddr2,
1206  size_t length)
1207 {
1208  size_t n;
1209  size_t m;
1210  uint8_t mask;
1211 
1212  //Ensure the prefix length is valid
1213  if(length > 128)
1214  return FALSE;
1215 
1216  //Number of complete bytes
1217  n = length / 8;
1218  //Number of bits in the last byte, if any
1219  m = length % 8;
1220 
1221  //Compare the first part
1222  if(n > 0)
1223  {
1224  if(osMemcmp(ipAddr1, ipAddr2, n))
1225  return FALSE;
1226  }
1227 
1228  //Compare the remaining bits, if any
1229  if(m > 0)
1230  {
1231  //Calculate the mask to be applied
1232  mask = ((1 << m) - 1) << (8 - m);
1233 
1234  //Check remaining bits
1235  if((ipAddr1->b[n] & mask) != (ipAddr2->b[n] & mask))
1236  return FALSE;
1237  }
1238 
1239  //The prefixes match each other
1240  return TRUE;
1241 }
1242 
1243 
1244 /**
1245  * @brief Retrieve the scope of an IPv6 address
1246  * @param[in] ipAddr Pointer to an IPv6 address
1247  * @return IPv6 address scope
1248  **/
1249 
1251 {
1252  uint_t scope;
1253 
1254  //Multicast address?
1256  {
1257  //Retrieve the scope of the multicast address
1259  }
1260  //Loopback address?
1262  {
1263  //The loopback address may be used by a node to send an IPv6 packet
1264  //to itself
1266  }
1267  //Link-local unicast address?
1269  {
1270  //A link-local address is for use on a single link
1272  }
1273  //Site-local unicast address?
1275  {
1276  //A site-local address is for use in a single site
1278  }
1279  //Global address?
1280  else
1281  {
1282  //Global scope
1283  scope = IPV6_ADDR_SCOPE_GLOBAL;
1284  }
1285 
1286  //Return the scope of the specified IPv6 address
1287  return scope;
1288 }
1289 
1290 
1291 /**
1292  * @brief Retrieve the scope of an IPv6 multicast address
1293  * @param[in] ipAddr Pointer to an IPv6 multicast address
1294  * @return IPv6 address scope
1295  **/
1296 
1298 {
1299  uint_t scope;
1300 
1301  //The scope field is a 4-bit value
1302  scope = ipAddr->b[1] & 0x0F;
1303 
1304  //If the scope field contains the reserved value F, an IPv6 packet
1305  //must be treated the same as packets destined to a global multicast
1306  //address (refer to RFC 3513 section 2.7)
1307  if(scope == 0x0F)
1308  {
1309  scope = IPV6_ADDR_SCOPE_GLOBAL;
1310  }
1311 
1312  //Return the scope of the specified IPv6 multicast address
1313  return scope;
1314 }
1315 
1316 
1317 /**
1318  * @brief Compute the length of the longest common prefix
1319  * @param[in] ipAddr1 Pointer to the first IPv6 address
1320  * @param[in] ipAddr2 Pointer to the second IPv6 address
1321  * @return The length of the longest common prefix, in bits
1322  **/
1323 
1325  const Ipv6Addr *ipAddr2)
1326 {
1327  uint_t i;
1328  uint_t j;
1329  uint8_t mask;
1330 
1331  //Clear bit counter
1332  j = 0;
1333 
1334  //Perform a byte-for-byte comparison
1335  for(i = 0; i < sizeof(Ipv6Addr); i++)
1336  {
1337  //Loop as long as prefixes match
1338  if(ipAddr1->b[i] != ipAddr2->b[i])
1339  {
1340  break;
1341  }
1342  }
1343 
1344  //Any mismatch?
1345  if(i < sizeof(Ipv6Addr))
1346  {
1347  //Perform a bit-for-bit comparison
1348  for(j = 0; j < 8; j++)
1349  {
1350  //Calculate the mask to be applied
1351  mask = 1 << (7 - j);
1352 
1353  //Loop as long as prefixes match
1354  if((ipAddr1->b[i] & mask) != (ipAddr2->b[i] & mask))
1355  {
1356  break;
1357  }
1358  }
1359  }
1360 
1361  //Return the length of the longest prefix that the two addresses
1362  //have in common
1363  return i * 8 + j;
1364 }
1365 
1366 
1367 /**
1368  * @brief Form a solicited-node address from an IPv6 address
1369  * @param[in] ipAddr Unicast or anycast address
1370  * @param[out] solicitedNodeAddr Corresponding solicited-node address
1371  * @return Error code
1372  **/
1373 
1375  Ipv6Addr *solicitedNodeAddr)
1376 {
1377  error_t error;
1378 
1379  //Ensure the specified address is a valid unicast or anycast address
1381  {
1382  //Copy the 104-bit prefix
1383  ipv6CopyAddr(solicitedNodeAddr, &IPV6_SOLICITED_NODE_ADDR_PREFIX);
1384 
1385  //Take the low-order 24 bits of the address (unicast or anycast) and
1386  //append those bits to the prefix
1387  solicitedNodeAddr->b[13] = ipAddr->b[13];
1388  solicitedNodeAddr->b[14] = ipAddr->b[14];
1389  solicitedNodeAddr->b[15] = ipAddr->b[15];
1390 
1391  //Successful processing
1392  error = NO_ERROR;
1393  }
1394  else
1395  {
1396  //Report an error
1397  error = ERROR_INVALID_ADDRESS;
1398  }
1399 
1400  //Return status code
1401  return error;
1402 }
1403 
1404 
1405 /**
1406  * @brief Map an IPv6 multicast address to a MAC-layer multicast address
1407  * @param[in] ipAddr IPv6 multicast address
1408  * @param[out] macAddr Corresponding MAC-layer multicast address
1409  * @return Error code
1410  **/
1411 
1413 {
1414  error_t error;
1415 
1416  //Ensure the specified IPv6 address is a multicast address
1418  {
1419  //To support IPv6 multicasting, MAC address range of 33-33-00-00-00-00
1420  //to 33-33-FF-FF-FF-FF is reserved (refer to RFC 2464)
1421  macAddr->b[0] = 0x33;
1422  macAddr->b[1] = 0x33;
1423 
1424  //The low-order 32 bits of the IPv6 multicast address are mapped directly
1425  //to the low-order 32 bits in the MAC-layer multicast address
1426  macAddr->b[2] = ipAddr->b[12];
1427  macAddr->b[3] = ipAddr->b[13];
1428  macAddr->b[4] = ipAddr->b[14];
1429  macAddr->b[5] = ipAddr->b[15];
1430 
1431  //The specified IPv6 multicast address was successfully mapped to a
1432  //MAC-layer address
1433  error = NO_ERROR;
1434  }
1435  else
1436  {
1437  //Report an error
1438  error = ERROR_INVALID_ADDRESS;
1439  }
1440 
1441  //Return status code
1442  return error;
1443 }
1444 
1445 
1446 /**
1447  * @brief Generate a IPv6 link-local address from an interface identifier
1448  * @param[in] interfaceId Interface identifier
1449  * @param[out] ipAddr Corresponding IPv6 link-local address
1450  **/
1451 
1453 {
1454  //A link-local address is formed by combining the well-known link-local
1455  //prefix fe80::/10 with the interface identifier
1456  ipAddr->w[0] = HTONS(0xFE80);
1457  ipAddr->w[1] = HTONS(0x0000);
1458  ipAddr->w[2] = HTONS(0x0000);
1459  ipAddr->w[3] = HTONS(0x0000);
1460  ipAddr->w[4] = interfaceId->w[0];
1461  ipAddr->w[5] = interfaceId->w[1];
1462  ipAddr->w[6] = interfaceId->w[2];
1463  ipAddr->w[7] = interfaceId->w[3];
1464 }
1465 
1466 
1467 /**
1468  * @brief Update IPv6 input statistics
1469  * @param[in] interface Underlying network interface
1470  * @param[in] destIpAddr Destination IP address
1471  * @param[in] length Length of the incoming IP packet
1472  **/
1473 
1475  size_t length)
1476 {
1477  //Check whether the destination address is a unicast or multicast address
1479  {
1480  //Number of IP multicast datagrams transmitted
1481  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsInMcastPkts, 1);
1482  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCInMcastPkts, 1);
1483  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsInMcastPkts, 1);
1484  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCInMcastPkts, 1);
1485 
1486  //Total number of octets transmitted in IP multicast datagrams
1487  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsInMcastOctets, length);
1488  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCInMcastOctets, length);
1489  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsInMcastOctets, length);
1490  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCInMcastOctets, length);
1491  }
1492 }
1493 
1494 
1495 /**
1496  * @brief Update IPv6 output statistics
1497  * @param[in] interface Underlying network interface
1498  * @param[in] destIpAddr Destination IP address
1499  * @param[in] length Length of the outgoing IP packet
1500  **/
1501 
1503  size_t length)
1504 {
1505  //Check whether the destination address is a unicast or multicast address
1507  {
1508  //Number of IP multicast datagrams transmitted
1509  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsOutMcastPkts, 1);
1510  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCOutMcastPkts, 1);
1511  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsOutMcastPkts, 1);
1512  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCOutMcastPkts, 1);
1513 
1514  //Total number of octets transmitted in IP multicast datagrams
1515  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsOutMcastOctets, length);
1516  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCOutMcastOctets, length);
1517  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsOutMcastOctets, length);
1518  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCOutMcastOctets, length);
1519  }
1520 
1521  //Total number of IP datagrams that this entity supplied to the lower
1522  //layers for transmission
1523  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsOutTransmits, 1);
1524  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCOutTransmits, 1);
1525  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsOutTransmits, 1);
1526  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCOutTransmits, 1);
1527 
1528  //Total number of octets in IP datagrams delivered to the lower layers
1529  //for transmission
1530  IP_MIB_INC_COUNTER32(ipv6SystemStats.ipSystemStatsOutOctets, length);
1531  IP_MIB_INC_COUNTER64(ipv6SystemStats.ipSystemStatsHCOutOctets, length);
1532  IP_MIB_INC_COUNTER32(ipv6IfStatsTable[interface->index].ipIfStatsOutOctets, length);
1533  IP_MIB_INC_COUNTER64(ipv6IfStatsTable[interface->index].ipIfStatsHCOutOctets, length);
1534 }
1535 
1536 #endif
@ IPV6_ADDR_STATE_TENTATIVE
An address whose uniqueness on a link is being verified.
Definition: ipv6.h:168
__start_packed struct @1 Eui64
EUI-64 identifier.
systime_t timestamp
Timestamp to manage entry lifetime.
Definition: ipv6.h:436
uint8_t length
Definition: coap_common.h:193
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:521
systime_t lifetime
Router lifetime.
Definition: ipv6.h:433
@ ERROR_NO_ADDRESS
Definition: error.h:198
int bool_t
Definition: compiler_port.h:48
@ ERROR_OUT_OF_RANGE
Definition: error.h:136
MacAddr srcAddr
Definition: ethernet.h:218
void ipv6FlushPrefixList(NetInterface *interface)
Flush the Prefix List.
Definition: ipv6_misc.c:671
void ipv6UpdateOutStats(NetInterface *interface, const Ipv6Addr *destIpAddr, size_t length)
Update IPv6 output statistics.
Definition: ipv6_misc.c:1502
@ IPV6_ADDR_SCOPE_INTERFACE_LOCAL
Definition: ipv6.h:152
void ipv6RemovePrefix(NetInterface *interface, const Ipv6Addr *prefix, uint_t length)
Remove an entry from the Prefix List.
Definition: ipv6_misc.c:476
#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:586
systime_t preferredLifetime
Preferred lifetime.
Definition: ipv6.h:420
uint_t dadRetransmitCount
Retransmission counter for Duplicate Address Detection.
Definition: ipv6.h:405
const Ipv6Addr IPV6_SOLICITED_NODE_ADDR_PREFIX
Definition: ipv6.c:86
#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:397
systime_t preferredLifetime
Preferred lifetime.
Definition: ipv6.h:401
void ipv6FlushAddrList(NetInterface *interface)
Flush the list of IPv6 addresses.
Definition: ipv6_misc.c:640
systime_t timestamp
Timestamp to manage entry lifetime.
Definition: ipv6.h:422
bool_t autonomousFlag
Autonomous flag.
Definition: ipv6.h:418
systime_t validLifetime
Valid lifetime.
Definition: ipv6.h:419
#define osMemcmp(p1, p2, length)
Definition: os_port.h:149
#define NET_INTERFACE_COUNT
Definition: net.h:113
bool_t ipv6IsTentativeAddr(NetInterface *interface, const Ipv6Addr *ipAddr)
Check whether an IPv6 address is a tentative address.
Definition: ipv6_misc.c:1109
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:121
Ipv6Addr prefix
IPv6 prefix information.
Definition: ipv6.h:415
Ipv6Addr addr
Router address.
Definition: ipv6.h:432
uint32_t lifetime
Definition: ndp.h:478
Ipv6Addr prefix
#define NDP_INFINITE_LIFETIME
Definition: ndp.h:202
@ IPV6_ADDR_STATE_INVALID
An address that is not assigned to any interface.
Definition: ipv6.h:167
#define ipv6IsSiteLocalUnicastAddr(ipAddr)
Definition: ipv6.h:129
MacAddr destAddr
Definition: ethernet.h:217
#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:1324
#define FALSE
Definition: os_port.h:46
__start_packed struct @0 MacAddr
MAC address.
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
void ipv6FlushDnsServerList(NetInterface *interface)
Flush the list of DNS servers.
Definition: ipv6_misc.c:735
NetInterface * nicGetPhysicalInterface(NetInterface *interface)
Retrieve physical interface.
Definition: nic.c:84
Ipv6AddrState
IPv6 address state.
Definition: ipv6.h:166
bool_t ipv6IsLocalHostAddr(const Ipv6Addr *ipAddr)
Check whether the specified IPv6 is assigned to the host.
Definition: ipv6_misc.c:1145
error_t
Error codes.
Definition: error.h:43
#define netInterface
Definition: net_legacy.h:270
#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:404
error_t ipv6SelectSourceAddr(NetInterface **interface, const Ipv6Addr *destAddr, Ipv6Addr *srcAddr)
IPv6 source address selection.
Definition: ipv6_misc.c:879
Prefix list entry.
Definition: ipv6.h:414
@ ERROR_INVALID_ADDRESS
Definition: error.h:102
uint8_t preference
Preference value.
Definition: ipv6.h:434
bool_t permanent
Permanently assigned address.
Definition: ipv6.h:402
#define NetInterface
Definition: net.h:36
error_t ipv6CheckDestAddr(NetInterface *interface, const Ipv6Addr *ipAddr)
Destination IPv6 address filtering.
Definition: ipv6_misc.c:773
uint_t ipv6GetAddrScope(const Ipv6Addr *ipAddr)
Retrieve the scope of an IPv6 address.
Definition: ipv6_misc.c:1250
Helper functions for IPv6.
@ IPV6_ADDR_SCOPE_GLOBAL
Definition: ipv6.h:157
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:66
error_t ipv6LeaveMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Leave an IPv6 multicast group.
Definition: ipv6.c:2111
error_t ipv6JoinMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Join an IPv6 multicast group.
Definition: ipv6.c:2001
const Ipv6Addr IPV6_LOOPBACK_ADDR
Definition: ipv6.c:70
uint_t refCount
Reference count for the current entry.
Definition: ipv6.h:447
bool_t duplicate
The address is a duplicate.
Definition: ipv6.h:399
Eui64 interfaceId
Definition: ipv6cp.h:69
@ IPV6_ADDR_SCOPE_LINK_LOCAL
Definition: ipv6.h:153
void ipv6RemoveAddr(NetInterface *interface, const Ipv6Addr *addr)
Remove an entry from the list of IPv6 addresses.
Definition: ipv6_misc.c:330
Neighbor and destination cache management.
Ipv6Addr addr
Multicast address.
Definition: ipv6.h:446
#define ipv6IsLinkLocalUnicastAddr(ipAddr)
Definition: ipv6.h:125
NDP (Neighbor Discovery Protocol)
void ipv6FlushDefaultRouterList(NetInterface *interface)
Flush the Default Router List.
Definition: ipv6_misc.c:703
bool_t onLinkFlag
On-link flag.
Definition: ipv6.h:417
uint32_t systime_t
System time.
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:421
#define TRACE_WARNING(...)
Definition: debug.h:85
uint8_t prefixLen
IPv6 prefix length.
Definition: ipv6.h:416
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:220
#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:431
IPv6 address entry.
Definition: ipv6.h:396
uint8_t m
Definition: ndp.h:302
#define HTONS(value)
Definition: cpu_endian.h:410
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:1452
bool_t ipv6IsAnycastAddr(NetInterface *interface, const Ipv6Addr *ipAddr)
Check whether an IPv6 address is an anycast address.
Definition: ipv6_misc.c:1073
bool_t ipv6CompPrefix(const Ipv6Addr *ipAddr1, const Ipv6Addr *ipAddr2, size_t length)
Compare IPv6 address prefixes.
Definition: ipv6_misc.c:1205
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:371
error_t ipv6ComputeSolicitedNodeAddr(const Ipv6Addr *ipAddr, Ipv6Addr *solicitedNodeAddr)
Form a solicited-node address from an IPv6 address.
Definition: ipv6_misc.c:1374
systime_t validLifetime
Valid lifetime.
Definition: ipv6.h:400
@ IPV6_ADDR_SCOPE_SITE_LOCAL
Definition: ipv6.h:155
uint32_t validLifetime
Ipv4Addr addr
Definition: nbns_common.h:121
#define MAX_DELAY
Definition: os_port.h:76
@ IPV6_ADDR_STATE_PREFERRED
An address assigned to an interface whose use is unrestricted.
Definition: ipv6.h:169
bool_t permanent
Permanently assigned router.
Definition: ipv6.h:435
Ipv6AddrState state
IPv6 address state.
Definition: ipv6.h:398
uint_t ipv6GetMulticastAddrScope(const Ipv6Addr *ipAddr)
Retrieve the scope of an IPv6 multicast address.
Definition: ipv6_misc.c:1297
#define IPV6_PREFIX_LIST_SIZE
Definition: ipv6.h:80
@ NIC_TYPE_6LOWPAN
6LoWPAN interface
Definition: nic.h:85
unsigned int uint_t
Definition: compiler_port.h:45
#define osMemset(p, value, length)
Definition: os_port.h:131
TCP/IP stack core.
@ IPV6_ADDR_STATE_DEPRECATED
An address assigned to an interface whose use is discouraged.
Definition: ipv6.h:170
error_t ipv6CheckSourceAddr(NetInterface *interface, const Ipv6Addr *ipAddr)
Source IPv6 address filtering.
Definition: ipv6_misc.c:750
bool_t ipv6IsOnLink(NetInterface *interface, const Ipv6Addr *ipAddr)
Check whether an IPv6 address is on-link.
Definition: ipv6_misc.c:1029
error_t ipv6MapMulticastAddrToMac(const Ipv6Addr *ipAddr, MacAddr *macAddr)
Map an IPv6 multicast address to a MAC-layer multicast address.
Definition: ipv6_misc.c:1412
__start_packed struct @0 Ipv6Addr
IPv6 network address.
void ipv6UpdateInStats(NetInterface *interface, const Ipv6Addr *destIpAddr, size_t length)
Update IPv6 input statistics.
Definition: ipv6_misc.c:1474
uint8_t ipAddr[4]
Definition: mib_common.h:187
error_t mdnsResponderStartProbing(MdnsResponderContext *context)
Restart probing process.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
#define INFINITE_DELAY
Definition: os_port.h:74
systime_t timestamp
Timestamp to manage entry lifetime.
Definition: ipv6.h:403
mDNS responder (Multicast DNS)
IPv6 multicast filter entry.
Definition: ipv6.h:445
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
systime_t osGetSystemTime(void)
Retrieve system time.
Ipv4Addr destIpAddr
Definition: ipcp.h:78