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