ndp_misc.c
Go to the documentation of this file.
1 /**
2  * @file ndp_misc.c
3  * @brief Helper functions for NDP (Neighbor Discovery Protocol)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 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.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NDP_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 "ipv6/ndp_misc.h"
41 #include "mld/mld_node_misc.h"
42 #include "mdns/mdns_responder.h"
43 #include "debug.h"
44 
45 //Check TCP/IP stack configuration
46 #if (IPV6_SUPPORT == ENABLED && NDP_SUPPORT == ENABLED)
47 
48 
49 /**
50  * @brief Parse Prefix Information Option
51  * @param[in] interface Underlying network interface
52  * @param[in] option Pointer to the Prefix Information option
53  **/
54 
56 {
57  //Make sure the Prefix Information option is valid
58  if(option == NULL || option->length != 4)
59  return;
60 
61  //A prefix Information option that have the on-link flag set indicates a
62  //prefix identifying a range of addresses that should be considered on-link
63  if(!option->l)
64  return;
65 
66  //If the prefix is the link-local prefix, silently ignore the
67  //Prefix Information option
68  if(ipv6CompPrefix(&option->prefix, &IPV6_LINK_LOCAL_ADDR_PREFIX, 10))
69  return;
70 
71  //If the preferred lifetime is greater than the valid lifetime,
72  //silently ignore the Prefix Information option
73  if(ntohl(option->preferredLifetime) > ntohl(option->validLifetime))
74  return;
75 
76  //Check whether the Valid Lifetime field is non-zero
77  if(ntohl(option->validLifetime) != 0)
78  {
79  //If the prefix is not already present in the Prefix List, create a new
80  //entry for the prefix. If the prefix is already present in the list,
81  //reset its invalidation timer
82  ipv6AddPrefix(interface, &option->prefix, option->prefixLength, option->l,
83  option->a, ntohl(option->validLifetime), ntohl(option->preferredLifetime));
84  }
85  else
86  {
87  //If the new Lifetime value is zero, time-out the prefix immediately
88  ipv6RemovePrefix(interface, &option->prefix, option->prefixLength);
89  }
90 }
91 
92 
93 /**
94  * @brief Manage the lifetime of IPv6 addresses
95  * @param[in] interface Underlying network interface
96  **/
97 
99 {
100  uint_t i;
101  systime_t time;
102  Ipv6AddrEntry *entry;
103  NdpContext *context;
104 
105  //Point to the NDP context
106  context = &interface->ndpContext;
107 
108  //Get current time
109  time = osGetSystemTime();
110 
111  //Go through the list of IPv6 addresses
112  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
113  {
114  //Point to the current entry
115  entry = &interface->ipv6Context.addrList[i];
116 
117  //Tentative address?
118  if(entry->state == IPV6_ADDR_STATE_TENTATIVE)
119  {
120  //Check whether the link is up
121  if(interface->linkState)
122  {
123  //To check an address, a node should send Neighbor Solicitation messages
124  if(entry->dadRetransmitCount == 0)
125  {
126  //Set time stamp
127  entry->timestamp = time;
128 
129  //Check whether Duplicate Address Detection should be performed
130  if(context->dupAddrDetectTransmits > 0)
131  {
132  //Link-local address?
133  if(i == 0)
134  {
135  //Delay before transmitting the first solicitation
136  entry->dadTimeout = netGenerateRandRange(0,
138 
139  //Prepare to send the first Neighbor Solicitation message
140  entry->dadRetransmitCount = 1;
141  }
142  else
143  {
144  //Valid link-local address?
146  {
147  //Prepare to send the first Neighbor Solicitation message
148  entry->dadTimeout = 0;
149  entry->dadRetransmitCount = 1;
150  }
151  }
152  }
153  else
154  {
155  //Do not perform Duplicate Address Detection
157  }
158  }
159  else
160  {
161  //Check current time
162  if(timeCompare(time, entry->timestamp + entry->dadTimeout) >= 0)
163  {
164  //Duplicate Address Detection failed?
165  if(entry->duplicate)
166  {
167  //A tentative address that is determined to be a duplicate
168  //must not be assigned to an interface
169  if(entry->permanent)
170  {
171  //The IPv6 address should be preserved if it has been
172  //manually assigned
173  ipv6SetAddr(interface, i, &entry->addr,
175  }
176  else
177  {
178  //The IPv6 address is no more valid and should be
179  //removed from the list
180  ipv6SetAddr(interface, i, &IPV6_UNSPECIFIED_ADDR,
182  }
183  }
184  //Duplicate Address Detection is on-going?
185  else if(entry->dadRetransmitCount <= context->dupAddrDetectTransmits)
186  {
187 #if (MLD_NODE_SUPPORT == ENABLED)
188  Ipv6Addr solicitedNodeAddr;
189 
190  //Form the Solicited-Node address
192  &solicitedNodeAddr);
193 
194  //Send a MLD report message for the multicast address
195  mldNodeSendUnsolicitedReport(&interface->mldNodeContext,
196  &solicitedNodeAddr);
197 #endif
198  //Send a multicast Neighbor Solicitation message
199  ndpSendNeighborSol(interface, &entry->addr, TRUE);
200 
201  //Set timeout value
202  entry->dadTimeout += context->retransTimer;
203  //Increment retransmission counter
204  entry->dadRetransmitCount++;
205  }
206  //Duplicate Address Detection is complete?
207  else
208  {
209  //The use of the IPv6 address is now unrestricted
211 
212 #if (MDNS_RESPONDER_SUPPORT == ENABLED)
213  //Restart mDNS probing process
214  mdnsResponderStartProbing(interface->mdnsResponderContext);
215 #endif
216  }
217  }
218  }
219  }
220  }
221  //Preferred address?
222  else if(entry->state == IPV6_ADDR_STATE_PREFERRED)
223  {
224  //An IPv6 address with an infinite preferred lifetime is never timed out
226  {
227  //When the preferred lifetime expires, the address becomes deprecated
228  if(timeCompare(time, entry->timestamp + entry->preferredLifetime) >= 0)
229  {
230  //A deprecated address should continue to be used as a source
231  //address in existing communications, but should not be used
232  //to initiate new communications
234  }
235  }
236  }
237  //Deprecated address?
238  else if(entry->state == IPV6_ADDR_STATE_DEPRECATED)
239  {
240  //An IPv6 address with an infinite valid lifetime is never timed out
242  {
243  //When the valid lifetime expires, the address becomes invalid
244  if(timeCompare(time, entry->timestamp + entry->validLifetime) >= 0)
245  {
246  //The IPv6 address is no more valid and should be removed from the list
247  ipv6SetAddr(interface, i, &IPV6_UNSPECIFIED_ADDR,
249  }
250  }
251  }
252  }
253 }
254 
255 
256 /**
257  * @brief Periodically update Prefix List
258  * @param[in] interface Underlying network interface
259  **/
260 
262 {
263  uint_t i;
264  systime_t time;
265  Ipv6PrefixEntry *entry;
266 
267  //Get current time
268  time = osGetSystemTime();
269 
270  //Go through the Prefix List
271  for(i = 0; i < IPV6_PREFIX_LIST_SIZE; i++)
272  {
273  //Point to the current entry
274  entry = &interface->ipv6Context.prefixList[i];
275 
276  //Check the lifetime value
277  if(entry->validLifetime > 0 && entry->validLifetime < INFINITE_DELAY)
278  {
279  //A node should retain entries in the Prefix List until their
280  //lifetimes expire
281  if(timeCompare(time, entry->timestamp + entry->validLifetime) >= 0)
282  {
283  //When removing an entry from the Prefix List, there is no need
284  //to purge any entries from the Destination or Neighbor Caches
285  ipv6RemovePrefix(interface, &entry->prefix, entry->prefixLen);
286  }
287  }
288  }
289 }
290 
291 
292 /**
293  * @brief Periodically update Default Router List
294  * @param[in] interface Underlying network interface
295  **/
296 
298 {
299  uint_t i;
300  bool_t flag;
301  systime_t time;
302  Ipv6RouterEntry *entry;
303 
304  //This flag will be set if any entry has been removed from
305  //the Default Router List
306  flag = FALSE;
307 
308  //Get current time
309  time = osGetSystemTime();
310 
311  //Go through the Default Router List
312  for(i = 0; i < IPV6_ROUTER_LIST_SIZE; i++)
313  {
314  //Point to the current entry
315  entry = &interface->ipv6Context.routerList[i];
316 
317  //Check the lifetime value
318  if(entry->lifetime > 0 && entry->lifetime < INFINITE_DELAY)
319  {
320  //A node should retain entries in the Default Router List until
321  //their lifetimes expire
322  if(timeCompare(time, entry->timestamp + entry->lifetime) >= 0)
323  {
324  //Immediately time-out the entry
325  entry->addr = IPV6_UNSPECIFIED_ADDR;
326  entry->lifetime = 0;
327 
328  //Set flag
329  flag = TRUE;
330  }
331  }
332  }
333 
334  //Check whether an entry has been removed from the list
335  if(flag)
336  {
337  //When removing an entry from the Default Router List, any entries
338  //in the Destination Cache that go through that router must perform
339  //next-hop determination again to select a new default router
340  ndpFlushDestCache(interface);
341  }
342 }
343 
344 
345 /**
346  * @brief Default Router Selection
347  * @param[in] interface Underlying network interface
348  * @param[in] unreachableAddr IPv6 address of the unreachable router (optional parameter)
349  * @param[out] addr IPv6 address of the default router to be used
350  * @return Error code
351  **/
352 
354  const Ipv6Addr *unreachableAddr, Ipv6Addr *addr)
355 {
356  uint_t i;
357  uint_t j;
358  uint_t k;
359  Ipv6RouterEntry *routerEntry;
360  NdpNeighborCacheEntry *neighborCacheEntry;
361 
362  //Initialize index
363  i = 0;
364 
365  //This parameter is optional...
366  if(unreachableAddr != NULL)
367  {
368  //Search the Default Router List for the router whose reachability is suspect
369  for(j = 0; j < IPV6_ROUTER_LIST_SIZE; j++)
370  {
371  //Point to the current entry
372  routerEntry = &interface->ipv6Context.routerList[j];
373 
374  //Check the lifetime associated with the default router
375  if(routerEntry->lifetime)
376  {
377  //Check the router address against the address whose reachability is suspect
378  if(ipv6CompAddr(&routerEntry->addr, unreachableAddr))
379  {
380  //Routers should be selected in a round-robin fashion
381  i = j + 1;
382  //We are done
383  break;
384  }
385  }
386  }
387  }
388 
389  //Routers that are reachable or probably reachable should be preferred
390  //over routers whose reachability is unknown or suspect
391  for(j = 0; j < IPV6_ROUTER_LIST_SIZE; j++)
392  {
393  //Get current index
394  k = (i + j) % IPV6_ROUTER_LIST_SIZE;
395 
396  //Point to the corresponding entry
397  routerEntry = &interface->ipv6Context.routerList[k];
398 
399  //Check the lifetime associated with the default router
400  if(routerEntry->lifetime)
401  {
402  //Search the Neighbor Cache for the router address
403  neighborCacheEntry = ndpFindNeighborCacheEntry(interface, &routerEntry->addr);
404 
405  //Check whether the router is reachable or probably reachable
406  if(neighborCacheEntry != NULL)
407  {
408  //Any state other than INCOMPLETE?
409  if(neighborCacheEntry->state != NDP_STATE_INCOMPLETE)
410  {
411  //Return the IPv6 address of the default router
412  *addr = routerEntry->addr;
413  //Successful default router selection
414  return NO_ERROR;
415  }
416  }
417  }
418  }
419 
420  //When no routers on the list are known to be reachable or probably
421  //reachable, routers should be selected in a round-robin fashion, so
422  //that subsequent requests for a default router do not return the
423  //same router until all other routers have been selected
424  for(j = 0; j < IPV6_ROUTER_LIST_SIZE; j++)
425  {
426  //Get current index
427  k = (i + j) % IPV6_ROUTER_LIST_SIZE;
428 
429  //Point to the corresponding entry
430  routerEntry = &interface->ipv6Context.routerList[k];
431 
432  //Check the lifetime associated with the default router
433  if(routerEntry->lifetime)
434  {
435  //Return the IPv6 address of the default router
436  *addr = routerEntry->addr;
437  //Successful default router selection
438  return NO_ERROR;
439  }
440  }
441 
442  //No default router found
443  return ERROR_NO_ROUTE;
444 }
445 
446 
447 /**
448  * @brief Check whether an address is the first-hop router for the specified destination
449  * @param[in] interface Underlying network interface
450  * @param[in] destAddr Destination address
451  * @param[in] nextHop First-hop address to be checked
452  * @return TRUE if the address is the first-hop router, else FALSE
453  **/
454 
456  const Ipv6Addr *destAddr, const Ipv6Addr *nextHop)
457 {
458  uint_t i;
459  bool_t isFirstHopRouter;
460  Ipv6RouterEntry *routerEntry;
461  NdpDestCacheEntry *destCacheEntry;
462 
463  //Clear flag
464  isFirstHopRouter = FALSE;
465 
466  //Search the cache for the specified destination address
467  destCacheEntry = ndpFindDestCacheEntry(interface, destAddr);
468 
469  //Any matching entry?
470  if(destCacheEntry != NULL)
471  {
472  //Check if the address is the same as the current first-hop
473  //router for the specified destination
474  if(ipv6CompAddr(&destCacheEntry->nextHop, nextHop))
475  isFirstHopRouter = TRUE;
476  }
477  else
478  {
479  //Loop through the Default Router List
480  for(i = 0; i < IPV6_ROUTER_LIST_SIZE; i++)
481  {
482  //Point to the current entry
483  routerEntry = &interface->ipv6Context.routerList[i];
484 
485  //Check the lifetime associated with the default router
486  if(routerEntry->lifetime)
487  {
488  //Check whether the current entry matches the specified address
489  if(ipv6CompAddr(&routerEntry->addr, nextHop))
490  {
491  //The specified address is a valid first-hop router
492  isFirstHopRouter = TRUE;
493  //We are done
494  break;
495  }
496  }
497  }
498  }
499 
500  //Return TRUE if the address is the same as the current first-hop
501  //router for the specified destination
502  return isFirstHopRouter;
503 }
504 
505 
506 /**
507  * @brief Next-hop determination
508  * @param[in] interface Underlying network interface
509  * @param[in] destAddr Destination address
510  * @param[in] unreachableNextHop Address of the unreachable next-hop (optional
511  * parameter)
512  * @param[out] nextHop Next-hop address to be used
513  * @param[in] dontRoute Do not send the packet via a router
514  * @return Error code
515  **/
516 
518  const Ipv6Addr *unreachableNextHop, Ipv6Addr *nextHop, bool_t dontRoute)
519 {
520  error_t error;
521 
522  //Initialize status code
523  error = NO_ERROR;
524 
525  //Destination IPv6 address is a multicast address?
527  {
528  //For multicast packets, the next-hop is always the multicast destination
529  //address and is considered to be on-link
530  *nextHop = *destAddr;
531  }
532  else
533  {
534  //The sender performs a longest prefix match against the Prefix List to
535  //determine whether the packet's destination is on-link or off-link
536  if(ipv6IsOnLink(interface, destAddr))
537  {
538  //If the destination is on-link, the next-hop address is the same as
539  //the packet's destination address
540  *nextHop = *destAddr;
541  }
542  else if(dontRoute)
543  {
544  //Do not send the packet via a router
545  *nextHop = *destAddr;
546  }
547  else
548  {
549  //If the destination is off-link, the sender selects a router from
550  //the Default Router List
551  error = ndpSelectDefaultRouter(interface, unreachableNextHop, nextHop);
552  }
553  }
554 
555  //Return status code
556  return error;
557 }
558 
559 
560 /**
561  * @brief Update next-hop field of Destination Cache entries
562  * @param[in] interface Underlying network interface
563  * @param[in] unreachableNextHop Address of the unreachable next-hop
564  **/
565 
566 void ndpUpdateNextHop(NetInterface *interface, const Ipv6Addr *unreachableNextHop)
567 {
568  error_t error;
569  uint_t i;
570  NdpDestCacheEntry *entry;
571 
572  //Go through Destination Cache
573  for(i = 0; i < NDP_DEST_CACHE_SIZE; i++)
574  {
575  //Point to the current entry
576  entry = &interface->ndpContext.destCache[i];
577 
578  //Check whether the unreachable IPv6 address is used a first-hop router
579  if(ipv6CompAddr(&entry->nextHop, unreachableNextHop))
580  {
581  //Perform next-hop determination
582  error = ndpSelectNextHop(interface, &entry->destAddr, &entry->nextHop,
583  &entry->nextHop, FALSE);
584 
585  //Next-hop determination failed?
586  if(error)
587  {
588  //Remove the current entry from the Destination Cache
590  }
591  }
592  }
593 }
594 
595 
596 /**
597  * @brief Append an option to a NDP message
598  * @param[in] message Pointer to the NDP message
599  * @param[in,out] messageLen Length of the entire message
600  * @param[in] type Option type
601  * @param[in] value Option value
602  * @param[in] length Length of the option value
603  **/
604 
605 void ndpAddOption(void *message, size_t *messageLen, uint8_t type,
606  const void *value, size_t length)
607 {
608  size_t optionLen;
609  size_t paddingLen;
610  NdpOption *option;
611 
612  //Length of the option in units of 8 bytes including the type and length fields
613  optionLen = (length + sizeof(NdpOption) + 7) / 8;
614 
615  //Sanity check
616  if(optionLen <= UINT8_MAX)
617  {
618  //Point to the buffer where the option is to be written
619  option = (NdpOption *) ((uint8_t *) message + *messageLen);
620 
621  //Option type
622  option->type = type;
623  //Option length
624  option->length = (uint8_t) optionLen;
625  //Option value
626  osMemcpy(option->value, value, length);
627 
628  //Options should be padded when necessary to ensure that they end on
629  //their natural 64-bit boundaries
630  if((length + sizeof(NdpOption)) < (optionLen * 8))
631  {
632  //Determine the amount of padding data to append
633  paddingLen = (optionLen * 8) - length - sizeof(NdpOption);
634  //Write padding data
635  osMemset(option->value + length, 0, paddingLen);
636  }
637 
638  //Adjust the length of the NDP message
639  *messageLen += optionLen * 8;
640  }
641 }
642 
643 
644 /**
645  * @brief Search a NDP message for a given option
646  * @param[in] options Pointer to the Options field
647  * @param[in] length Length of the Options field
648  * @param[in] type Type of the option to find
649  * @return If the specified option is found, a pointer to the corresponding
650  * option is returned. Otherwise NULL pointer is returned
651  **/
652 
653 void *ndpGetOption(uint8_t *options, size_t length, uint8_t type)
654 {
655  size_t i;
656  NdpOption *option;
657 
658  //Point to the very first option of the NDP message
659  i = 0;
660 
661  //Parse options
662  while((i + sizeof(NdpOption)) <= length)
663  {
664  //Point to the current option
665  option = (NdpOption *) (options + i);
666 
667  //Nodes must silently discard an NDP message that contains an option
668  //with length zero
669  if(option->length == 0)
670  break;
671 
672  //Check option length
673  if((i + option->length * 8) > length)
674  break;
675 
676  //Check whether the option type matches the specified value
677  if(option->type == type || type == NDP_OPT_ANY)
678  return option;
679 
680  //Jump to the next option
681  i += option->length * 8;
682  }
683 
684  //The specified option type was not found
685  return NULL;
686 }
687 
688 
689 /**
690  * @brief Check NDP message options
691  * @param[in] options Pointer to the Options field
692  * @param[in] length Length of the Options field
693  * @return Error code
694  **/
695 
696 error_t ndpCheckOptions(const uint8_t *options, size_t length)
697 {
698  size_t i;
699  NdpOption *option;
700 
701  //Point to the very first option of the NDP message
702  i = 0;
703 
704  //Parse options
705  while((i + sizeof(NdpOption)) <= length)
706  {
707  //Point to the current option
708  option = (NdpOption *) (options + i);
709 
710  //Nodes must silently discard an NDP message that contains
711  //an option with length zero
712  if(option->length == 0)
713  return ERROR_INVALID_OPTION;
714 
715  //Jump to the next option
716  i += option->length * 8;
717  }
718 
719  //The Options field is valid
720  return NO_ERROR;
721 }
722 
723 #endif
@ IPV6_ADDR_STATE_TENTATIVE
An address whose uniqueness on a link is being verified.
Definition: ipv6.h:174
systime_t timestamp
Timestamp to manage entry lifetime.
Definition: ipv6.h:460
NdpNeighborCacheEntry * ndpFindNeighborCacheEntry(NetInterface *interface, const Ipv6Addr *ipAddr)
Search the Neighbor cache for a given IPv6 address.
Definition: ndp_cache.c:154
IPv6 (Internet Protocol Version 6)
systime_t lifetime
Router lifetime.
Definition: ipv6.h:457
int bool_t
Definition: compiler_port.h:53
Ipv4Addr destAddr
Definition: ipv4.h:329
Helper functions for NDP (Neighbor Discovery Protocol)
@ NDP_OPT_ANY
Definition: ndp.h:226
void ipv6RemovePrefix(NetInterface *interface, const Ipv6Addr *prefix, uint_t length)
Remove an entry from the Prefix List.
Definition: ipv6_misc.c:495
void ndpUpdateAddrList(NetInterface *interface)
Manage the lifetime of IPv6 addresses.
Definition: ndp_misc.c:98
uint_t dadRetransmitCount
Retransmission counter for Duplicate Address Detection.
Definition: ipv6.h:429
uint8_t message[]
Definition: chap.h:154
#define TRUE
Definition: os_port.h:50
void ndpAddOption(void *message, size_t *messageLen, uint8_t type, const void *value, size_t length)
Append an option to a NDP message.
Definition: ndp_misc.c:605
NdpDestCacheEntry * ndpFindDestCacheEntry(NetInterface *interface, const Ipv6Addr *destAddr)
Search the Destination Cache for a given destination address.
Definition: ndp_cache.c:503
Ipv6Addr addr
IPv6 address.
Definition: ipv6.h:421
systime_t preferredLifetime
Preferred lifetime.
Definition: ipv6.h:425
systime_t timestamp
Timestamp to manage entry lifetime.
Definition: ipv6.h:446
Ipv6Addr
Definition: ipv6.h:260
Neighbor cache entry.
Definition: ndp.h:549
uint8_t type
Definition: coap_common.h:176
systime_t validLifetime
Valid lifetime.
Definition: ipv6.h:443
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:127
error_t ndpSendNeighborSol(NetInterface *interface, const Ipv6Addr *targetIpAddr, bool_t multicast)
Send a Neighbor Solicitation message.
Definition: ndp.c:1693
Ipv6Addr prefix
IPv6 prefix information.
Definition: ipv6.h:439
Ipv6Addr destAddr
Destination IPv6 address.
Definition: ndp.h:568
Ipv6Addr addr
Router address.
Definition: ipv6.h:456
#define NDP_INFINITE_LIFETIME
Definition: ndp.h:202
#define timeCompare(t1, t2)
Definition: os_port.h:40
@ IPV6_ADDR_STATE_INVALID
An address that is not assigned to any interface.
Definition: ipv6.h:173
#define ipv6IsMulticastAddr(ipAddr)
Definition: ipv6.h:139
#define FALSE
Definition: os_port.h:46
uint_t dupAddrDetectTransmits
Maximum number of NS messages sent while performing DAD.
Definition: ndp.h:583
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
uint32_t netGenerateRandRange(uint32_t min, uint32_t max)
Generate a random value in the specified range.
Definition: net_misc.c:948
error_t
Error codes.
Definition: error.h:43
systime_t dadTimeout
Timeout value for Duplicate Address Detection.
Definition: ipv6.h:428
NDP context.
Definition: ndp.h:580
Prefix list entry.
Definition: ipv6.h:438
NdpOption
Definition: ndp.h:379
bool_t permanent
Permanently assigned address.
Definition: ipv6.h:426
#define NetInterface
Definition: net.h:36
Helper functions for IPv6.
void ndpUpdateNextHop(NetInterface *interface, const Ipv6Addr *unreachableNextHop)
Update next-hop field of Destination Cache entries.
Definition: ndp_misc.c:566
const Ipv6Addr IPV6_UNSPECIFIED_ADDR
Definition: ipv6.c:66
bool_t duplicate
The address is a duplicate.
Definition: ipv6.h:423
uint8_t length
Definition: tcp.h:368
error_t ndpSelectDefaultRouter(NetInterface *interface, const Ipv6Addr *unreachableAddr, Ipv6Addr *addr)
Default Router Selection.
Definition: ndp_misc.c:353
void ndpUpdateDefaultRouterList(NetInterface *interface)
Periodically update Default Router List.
Definition: ndp_misc.c:297
@ NDP_STATE_INCOMPLETE
Definition: ndp.h:250
Neighbor and destination cache management.
#define NDP_DEST_CACHE_SIZE
Definition: ndp.h:60
error_t ndpSelectNextHop(NetInterface *interface, const Ipv6Addr *destAddr, const Ipv6Addr *unreachableNextHop, Ipv6Addr *nextHop, bool_t dontRoute)
Next-hop determination.
Definition: ndp_misc.c:517
#define NDP_MAX_RTR_SOLICITATION_DELAY
Definition: ndp.h:123
bool_t ndpIsFirstHopRouter(NetInterface *interface, const Ipv6Addr *destAddr, const Ipv6Addr *nextHop)
Check whether an address is the first-hop router for the specified destination.
Definition: ndp_misc.c:455
@ ERROR_NO_ROUTE
Definition: error.h:220
NDP (Neighbor Discovery Protocol)
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:96
uint32_t retransTimer
The time between retransmissions of NS messages.
Definition: ndp.h:582
uint8_t prefixLen
IPv6 prefix length.
Definition: ipv6.h:440
void ndpFlushDestCache(NetInterface *interface)
Flush Destination Cache.
Definition: ndp_cache.c:532
uint32_t time
Default router list entry.
Definition: ipv6.h:455
IPv6 address entry.
Definition: ipv6.h:420
#define IPV6_ROUTER_LIST_SIZE
Definition: ipv6.h:86
#define IPV6_ADDR_LIST_SIZE
Definition: ipv6.h:65
NdpState state
Reachability state.
Definition: ndp.h:550
Destination cache entry.
Definition: ndp.h:567
Ipv6AddrState ipv6GetLinkLocalAddrState(NetInterface *interface)
Get the state of the link-local address.
Definition: ipv6.c:327
void mldNodeSendUnsolicitedReport(MldNodeContext *context, const Ipv6Addr *groupAddr)
Send an unsolicited Report message.
void * ndpGetOption(uint8_t *options, size_t length, uint8_t type)
Search a NDP message for a given option.
Definition: ndp_misc.c:653
uint8_t value[]
Definition: tcp.h:369
bool_t ipv6CompPrefix(const Ipv6Addr *ipAddr1, const Ipv6Addr *ipAddr2, size_t length)
Compare IPv6 address prefixes.
Definition: ipv6_misc.c:1196
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:380
error_t ipv6ComputeSolicitedNodeAddr(const Ipv6Addr *ipAddr, Ipv6Addr *solicitedNodeAddr)
Form a solicited-node address from an IPv6 address.
Definition: ipv6_misc.c:1365
error_t ndpCheckOptions(const uint8_t *options, size_t length)
Check NDP message options.
Definition: ndp_misc.c:696
uint8_t options[]
Definition: tcp.h:357
systime_t validLifetime
Valid lifetime.
Definition: ipv6.h:424
@ ERROR_INVALID_OPTION
Definition: error.h:98
void ndpUpdatePrefixList(NetInterface *interface)
Periodically update Prefix List.
Definition: ndp_misc.c:261
Ipv4Addr addr
Definition: nbns_common.h:123
void ndpParsePrefixInfoOption(NetInterface *interface, NdpPrefixInfoOption *option)
Parse Prefix Information Option.
Definition: ndp_misc.c:55
@ IPV6_ADDR_STATE_PREFERRED
An address assigned to an interface whose use is unrestricted.
Definition: ipv6.h:175
Ipv6AddrState state
IPv6 address state.
Definition: ipv6.h:422
#define IPV6_PREFIX_LIST_SIZE
Definition: ipv6.h:79
Helper functions for MLD node.
unsigned int uint_t
Definition: compiler_port.h:50
NdpPrefixInfoOption
Definition: ndp.h:418
#define osMemset(p, value, length)
Definition: os_port.h:135
TCP/IP stack core.
@ IPV6_ADDR_STATE_DEPRECATED
An address assigned to an interface whose use is discouraged.
Definition: ipv6.h:176
bool_t ipv6IsOnLink(NetInterface *interface, const Ipv6Addr *ipAddr)
Check whether an IPv6 address is on-link.
Definition: ipv6_misc.c:1020
const Ipv6Addr IPV6_LINK_LOCAL_ADDR_PREFIX
Definition: ipv6.c:82
#define ntohl(value)
Definition: cpu_endian.h:422
error_t mdnsResponderStartProbing(MdnsResponderContext *context)
Restart probing process.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
Ipv6Addr nextHop
IPv6 address of the next-hop neighbor.
Definition: ndp.h:569
#define INFINITE_DELAY
Definition: os_port.h:75
systime_t timestamp
Timestamp to manage entry lifetime.
Definition: ipv6.h:427
mDNS responder (Multicast DNS)
systime_t osGetSystemTime(void)
Retrieve system time.