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