ipv6_routing.c
Go to the documentation of this file.
1 /**
2  * @file ipv6_routing.c
3  * @brief IPv6 routing
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL IPV6_TRACE_LEVEL
31 
32 //Dependencies
33 #include <limits.h>
34 #include "core/net.h"
35 #include "core/ip.h"
36 #include "ipv6/ipv6.h"
37 #include "ipv6/ipv6_misc.h"
38 #include "ipv6/ipv6_routing.h"
39 #include "ipv6/icmpv6.h"
40 #include "ipv6/ndp.h"
41 #include "debug.h"
42 
43 //Check TCP/IP stack configuration
44 #if (IPV6_SUPPORT == ENABLED && IPV6_ROUTING_SUPPORT == ENABLED)
45 
46 //IPv6 routing table
47 static Ipv6RoutingTableEntry ipv6RoutingTable[IPV6_ROUTING_TABLE_SIZE];
48 
49 
50 /**
51  * @brief Initialize IPv6 routing table
52  * @return Error code
53  **/
54 
56 {
57  //Clear the routing table
58  memset(ipv6RoutingTable, 0, sizeof(ipv6RoutingTable));
59 
60  //Successful initialization
61  return NO_ERROR;
62 }
63 
64 
65 /**
66  * @brief Enable routing for the specified interface
67  * @param[in] interface Underlying network interface
68  * @param[in] enable When the flag is set to TRUE, routing is enabled on the
69  * interface and the router can forward packets to or from the interface
70  * @return Error code
71  **/
72 
74 {
75  //Check parameters
76  if(interface == NULL)
78 
79  //Get exclusive access
81  //Enable or disable routing
82  interface->ipv6Context.isRouter = enable;
83  //Release exclusive access
85 
86  //Successful processing
87  return NO_ERROR;
88 }
89 
90 
91 /**
92  * @brief Add a new entry in the IPv6 routing table
93  * @param[in] prefix Network destination
94  * @param[in] prefixLen Length of the prefix, in bits
95  * @param[in] interface Network interface where to forward the packet
96  * @param[in] nextHop IPv6 address of the next hop
97  * @param[in] metric Metric value
98  * @return Error code
99  **/
100 
102  NetInterface *interface, const Ipv6Addr *nextHop, uint_t metric)
103 {
104  error_t error;
105  uint_t i;
106  Ipv6RoutingTableEntry *entry;
107  Ipv6RoutingTableEntry *firstFreeEntry;
108 
109  //Check parameters
110  if(prefix == NULL || interface == NULL)
112 
113  //Keep track of the first free entry
114  firstFreeEntry = NULL;
115 
116  //Get exclusive access
118 
119  //Loop through routing table entries
120  for(i = 0; i < IPV6_ROUTING_TABLE_SIZE; i++)
121  {
122  //Point to the current entry
123  entry = &ipv6RoutingTable[i];
124 
125  //Valid entry?
126  if(entry->valid)
127  {
128  //Check prefix length
129  if(entry->prefixLen == prefixLen)
130  {
131  //Check whether the current entry matches the specified destination
132  if(ipv6CompPrefix(&entry->prefix, prefix, prefixLen))
133  break;
134  }
135  }
136  else
137  {
138  //Keep track of the first free entry
139  if(firstFreeEntry == NULL)
140  firstFreeEntry = entry;
141  }
142  }
143 
144  //If the routing table does not contain the specified destination,
145  //then a new entry should be created
146  if(i >= IPV6_ROUTING_TABLE_SIZE)
147  entry = firstFreeEntry;
148 
149  //Check whether the routing table runs out of space
150  if(entry != NULL)
151  {
152  //Network destination
153  entry->prefix = *prefix;
154  entry->prefixLen = prefixLen;
155 
156  //Interface where to forward the packet
157  entry->interface = interface;
158 
159  //Address of the next hop
160  if(nextHop != NULL)
161  entry->nextHop = *nextHop;
162  else
164 
165  //Metric value
166  entry->metric = metric;
167  //The entry is now valid
168  entry->valid = TRUE;
169 
170  //Sucessful processing
171  error = NO_ERROR;
172  }
173  else
174  {
175  //The routing table is full
176  error = ERROR_FAILURE;
177  }
178 
179  //Release exclusive access
181 
182  //Return status code
183  return error;
184 }
185 
186 
187 /**
188  * @brief Remove an entry from the IPv6 routing table
189  * @param[in] prefix Network destination
190  * @param[in] prefixLen Length of the prefix, in bits
191  * @return Error code
192  **/
193 
195 {
196  error_t error;
197  uint_t i;
198  Ipv6RoutingTableEntry *entry;
199 
200  //Initialize status code
201  error = ERROR_NOT_FOUND;
202 
203  //Get exclusive access
205 
206  //Loop through routing table entries
207  for(i = 0; i < IPV6_ROUTING_TABLE_SIZE; i++)
208  {
209  //Point to the current entry
210  entry = &ipv6RoutingTable[i];
211 
212  //Valid entry?
213  if(entry->valid)
214  {
215  //Check prefix length
216  if(entry->prefixLen == prefixLen)
217  {
218  //Check whether the current entry matches the specified destination
219  if(ipv6CompPrefix(&entry->prefix, prefix, prefixLen))
220  {
221  //Delete current entry
222  entry->valid = FALSE;
223  //The route was successfully deleted from the routing table
224  error = NO_ERROR;
225  }
226  }
227  }
228  }
229 
230  //Release exclusive access
232 
233  //Return status code
234  return error;
235 }
236 
237 
238 /**
239  * @brief Delete all routes from the IPv6 routing table
240  * @return Error code
241  **/
242 
244 {
245  //Get exclusive access
247  //Clear the routing table
248  memset(ipv6RoutingTable, 0, sizeof(ipv6RoutingTable));
249  //Release exclusive access
251 
252  //Successful processing
253  return NO_ERROR;
254 }
255 
256 
257 /**
258  * @brief Forward an IPv6 packet
259  * @param[in] srcInterface Network interface on which the packet was received
260  * @param[in] ipPacket Multi-part buffer that holds the IPv6 packet to forward
261  * @param[in] ipPacketOffset Offset to the first byte of the IPv6 packet
262  * @return Error code
263  **/
264 
266  NetBuffer *ipPacket, size_t ipPacketOffset)
267 {
268  error_t error;
269  uint_t i;
270  uint_t metric;
272  bool_t match;
273  size_t length;
274  size_t destOffset;
275  NetInterface *destInterface;
276  NetBuffer *destBuffer;
277  Ipv6Header *ipHeader;
278  Ipv6RoutingTableEntry *entry;
280 #if (ETH_SUPPORT == ENABLED)
281  NetInterface *physicalInterface;
282 #endif
283 
284  //Silently drop any IP packets received on an interface that has
285  //not been assigned a valid link-local address
287  return ERROR_NOT_CONFIGURED;
288 
289  //If routing is not enabled on the interface, then the router cannot
290  //forward packets from the interface
291  if(!srcInterface->ipv6Context.isRouter)
292  return ERROR_FAILURE;
293 
294  //Calculate the length of the IPv6 packet
295  length = netBufferGetLength(ipPacket) - ipPacketOffset;
296 
297  //Ensure the packet length is greater than 40 bytes
298  if(length < sizeof(Ipv6Header))
299  return ERROR_INVALID_LENGTH;
300 
301  //Point to the IPv6 header
302  ipHeader = netBufferAt(ipPacket, ipPacketOffset);
303 
304  //Sanity check
305  if(ipHeader == NULL)
306  return ERROR_FAILURE;
307 
308  //An IPv6 packet with a source address of unspecified must never be
309  //forwarded by an IPv6 router (refer to RFC section 3513 2.5.2)
310  if(ipv6CompAddr(&ipHeader->srcAddr, &IPV6_UNSPECIFIED_ADDR))
311  return ERROR_INVALID_ADDRESS;
312 
313  //The unspecified address must not be used as the destination address
314  //of IPv6 packets (refer to RFC section 3513 2.5.2)
315  if(ipv6CompAddr(&ipHeader->destAddr, &IPV6_UNSPECIFIED_ADDR))
316  return ERROR_INVALID_ADDRESS;
317 
318  //An IPv6 packet with a destination address of loopback must never be
319  //forwarded by an IPv6 router (refer to RFC 3513 section 2.5.3)
320  if(ipv6CompAddr(&ipHeader->destAddr, &IPV6_LOOPBACK_ADDR))
321  return ERROR_INVALID_ADDRESS;
322 
323  //Check whether the destination address is a link-local address
324  if(ipv6IsLinkLocalUnicastAddr(&ipHeader->destAddr))
325  {
326  //Forward the packet on the same network interface
327  destInterface = srcInterface;
328  //Next hop
329  destIpAddr = ipHeader->destAddr;
330  }
331  else
332  {
333  //Lowest metric value
334  metric = UINT_MAX;
335  //Longest prefix length
336  prefixLen = 0;
337  //Outgoing network interface
338  destInterface = NULL;
339 
340  //Route determination process
341  for(i = 0; i < IPV6_ROUTING_TABLE_SIZE; i++)
342  {
343  //Point to the current entry
344  entry = &ipv6RoutingTable[i];
345 
346  //Valid entry?
347  if(entry->valid && entry->interface != NULL)
348  {
349  //Clear flag
350  match = FALSE;
351 
352  //Do not forward any IP packets to an interface that has not
353  //been assigned a valid link-local address...
355  {
356  //If routing is enabled on the interface, then the router
357  //can forward packets to the interface
358  if(entry->interface->ipv6Context.isRouter)
359  {
360  //Compare the destination address with the current entry for a match
361  if(ipv6CompPrefix(&ipHeader->destAddr, &entry->prefix, entry->prefixLen))
362  {
363  //The longest matching route is the most specific route to the
364  //destination IPv6 address...
365  if(entry->prefixLen > prefixLen)
366  {
367  //Give the current route the higher precedence
368  match = TRUE;
369  }
370  else if(entry->prefixLen == prefixLen)
371  {
372  //If multiple entries with the longest match are found, the
373  //router uses the lowest metric to select the best route
374  if(entry->metric < metric)
375  {
376  //Give the current route the higher precedence
377  match = TRUE;
378  }
379  }
380  }
381  }
382  }
383 
384  //Matching entry?
385  if(match)
386  {
387  //Select the current route
388  metric = entry->metric;
389  prefixLen = entry->prefixLen;
390 
391  //Outgoing interface on which to forward the packet
392  destInterface = entry->interface;
393 
394  //Next hop
396  destIpAddr = entry->nextHop;
397  else
398  destIpAddr = ipHeader->destAddr;
399  }
400  }
401  }
402  }
403 
404  //No route to the destination?
405  if(destInterface == NULL)
406  {
407  //A Destination Unreachable message should be generated by a router
408  //in response to a packet that cannot be delivered
410  ICMPV6_CODE_NO_ROUTE_TO_DEST, 0, ipPacket, ipPacketOffset);
411 
412  //Exit immediately
413  return ERROR_NO_ROUTE;
414  }
415 
416  //Check whether the length of the IPv6 packet is larger than the link MTU
417  if(length > destInterface->ipv6Context.linkMtu)
418  {
419  //A Packet Too Big must be sent by a router in response to a packet
420  //that it cannot forward because the packet is larger than the MTU
421  //of the outgoing link
423  0, destInterface->ipv6Context.linkMtu, ipPacket, ipPacketOffset);
424 
425  //Exit immediately
426  return ERROR_INVALID_LENGTH;
427  }
428 
429  //Check whether the packet is explicitly addressed to the router itself
430  if(!ipv6CheckDestAddr(destInterface, &ipHeader->destAddr))
431  {
432  //Valid unicast address?
433  if(!ipv6IsMulticastAddr(&ipHeader->destAddr))
434  {
435  //Process IPv6 packet
436  //ipv6ProcessPacket(destInterface, ipPacket, ipPacketOffset);
437  //Exit immediately
438  return NO_ERROR;
439  }
440  }
441 
442  //Check whether the IPv6 packet is about to be sent out the interface
443  //on which it was received
444  if(destInterface == srcInterface)
445  {
446 #if (NDP_SUPPORT == ENABLED)
447  //A router should send a Redirect message whenever it forwards a packet
448  //that is not explicitly addressed to itself in which the source address
449  //identifies a neighbor, and
450  if(ipv6IsOnLink(srcInterface, &ipHeader->srcAddr))
451  {
452  //The router determines that a better first-hop node resides on the
453  //same link as the sending node for the destination address of the
454  //packet being forwarded, and
455  if(ipv6IsOnLink(destInterface, &destIpAddr))
456  {
457  //The destination address of the packet is not a multicast address
458  if(!ipv6IsMulticastAddr(&ipHeader->destAddr))
459  {
460  //Transmit a Redirect message
461  ndpSendRedirect(srcInterface, &destIpAddr, ipPacket, ipPacketOffset);
462  }
463  }
464  }
465 #endif
466  }
467  else
468  {
469  //Check whether the scope of the source address is smaller than the
470  //scope of the destination address
471  if(ipv6GetAddrScope(&ipHeader->srcAddr) < ipv6GetAddrScope(&ipHeader->destAddr))
472  {
473  //A Destination Unreachable message should be generated by a router
474  //in response to a packet that cannot be delivered without leaving
475  //the scope of the source address
477  ICMPV6_CODE_BEYOND_SCOPE_OF_SRC_ADDR, 0, ipPacket, ipPacketOffset);
478 
479  //Exit immediately
480  return ERROR_INVALID_ADDRESS;
481  }
482  }
483 
484  //Hop Limit exceeded in transit?
485  if(ipHeader->hopLimit <= 1)
486  {
487  //If a router receives a packet with a Hop Limit of zero, or if a router
488  //decrements a packet's Hop Limit to zero, it must discard the packet
489  //and originate an ICMPv6 Time Exceeded message
491  ICMPV6_CODE_HOP_LIMIT_EXCEEDED, 0, ipPacket, ipPacketOffset);
492 
493  //Exit immediately
494  return ERROR_FAILURE;
495  }
496 
497  //The Hop-by-Hop Options header, when present, must immediately follow
498  //the IPv6 header. Its presence is indicated by the value zero in the
499  //Next Header field of the IPv6 header
500  if(ipHeader->nextHeader == IPV6_HOP_BY_HOP_OPT_HEADER)
501  {
502  //Point to the extension header
503  size_t headerOffset = ipPacketOffset + sizeof(Ipv6Header);
504 
505  //Calculate the offset of the Next Header field
506  size_t nextHeaderOffset = ipPacketOffset +
507  &ipHeader->nextHeader - (uint8_t *) ipHeader;
508 
509  //The Hop-by-Hop Options header is used to carry optional information
510  //that must be examined by every node along a packet's delivery path
511  error = ipv6ParseHopByHopOptHeader(srcInterface,
512  ipPacket, ipPacketOffset, &headerOffset, &nextHeaderOffset);
513 
514  //Any error while processing the extension header?
515  if(error)
516  return error;
517  }
518 
519  //Allocate a buffer to hold the IPv6 packet
520  destBuffer = ethAllocBuffer(length, &destOffset);
521 
522  //Successful memory allocation?
523  if(destBuffer != NULL)
524  {
525  //Copy IPv6 header
526  error = netBufferCopy(destBuffer, destOffset,
527  ipPacket, ipPacketOffset, length);
528 
529  //Check status code
530  if(!error)
531  {
532  //Point to the IPv6 header
533  ipHeader = netBufferAt(destBuffer, destOffset);
534  //Every time a router forwards a packet, it decrements the Hop Limit field
535  ipHeader->hopLimit--;
536 
537 #if (ETH_SUPPORT == ENABLED)
538  //Point to the physical interface
539  physicalInterface = nicGetPhysicalInterface(destInterface);
540 
541  //Ethernet interface?
542  if(physicalInterface->nicDriver != NULL &&
543  physicalInterface->nicDriver->type == NIC_TYPE_ETHERNET)
544  {
545  MacAddr destMacAddr;
546 
547  //Destination IPv6 address
549  destIpAddr = ipHeader->destAddr;
550 
551  //Check whether the destination IPv6 address is a multicast address?
553  {
554  //Map IPv6 multicast address to MAC-layer multicast address
555  error = ipv6MapMulticastAddrToMac(&destIpAddr, &destMacAddr);
556  }
557  else
558  {
559  //Resolve host address using Neighbor Discovery protocol
560  error = ndpResolve(destInterface, &destIpAddr, &destMacAddr);
561  }
562 
563  //Successful address resolution?
564  if(!error)
565  {
566  //Debug message
567  TRACE_INFO("Forwarding IPv6 packet to %s (%" PRIuSIZE " bytes)...\r\n",
568  destInterface->name, length);
569  //Dump IP header contents for debugging purpose
570  ipv6DumpHeader(ipHeader);
571 
572  //Send Ethernet frame
573  error = ethSendFrame(destInterface, &destMacAddr,
574  destBuffer, destOffset, ETH_TYPE_IPV6);
575  }
576  //Address resolution is in progress?
577  else if(error == ERROR_IN_PROGRESS)
578  {
579  //Debug message
580  TRACE_INFO("Enqueuing IPv6 packet (%" PRIuSIZE " bytes)...\r\n", length);
581  //Dump IP header contents for debugging purpose
582  ipv6DumpHeader(ipHeader);
583 
584  //Enqueue packets waiting for address resolution
585  error = ndpEnqueuePacket(srcInterface, destInterface,
586  &destIpAddr, destBuffer, destOffset);
587  }
588  //Address resolution failed?
589  else
590  {
591  //Debug message
592  TRACE_WARNING("Cannot map IPv6 address to Ethernet address!\r\n");
593  }
594  }
595  else
596 #endif
597 #if (PPP_SUPPORT == ENABLED)
598  //PPP interface?
599  if(destInterface->nicDriver != NULL &&
600  destInterface->nicDriver->type == NIC_TYPE_PPP)
601  {
602  //Debug message
603  TRACE_INFO("Forwarding IPv6 packet to %s (%" PRIuSIZE " bytes)...\r\n",
604  destInterface->name, length);
605  //Dump IP header contents for debugging purpose
606  ipv6DumpHeader(ipHeader);
607 
608  //Send PPP frame
609  error = pppSendFrame(destInterface, destBuffer, destOffset, PPP_PROTOCOL_IPV6);
610  }
611  else
612 #endif
613  //6LoWPAN interface?
614  if(destInterface->nicDriver != NULL &&
615  destInterface->nicDriver->type == NIC_TYPE_6LOWPAN)
616  {
617  //Debug message
618  TRACE_INFO("Forwarding IPv6 packet to %s (%" PRIuSIZE " bytes)...\r\n",
619  destInterface->name, length);
620  //Dump IP header contents for debugging purpose
621  ipv6DumpHeader(ipHeader);
622 
623  //Send the packet over the specified link
624  error = nicSendPacket(destInterface, destBuffer, destOffset);
625  }
626  else
627  //Unknown interface type?
628  {
629  //Report an error
630  error = ERROR_INVALID_INTERFACE;
631  }
632  }
633 
634  //Free previously allocated memory
635  netBufferFree(destBuffer);
636  }
637  else
638  {
639  //Failed to allocate memory
640  error = ERROR_OUT_OF_MEMORY;
641  }
642 
643  //Return status code
644  return error;
645 }
646 
647 #endif
bool_t ipv6IsOnLink(NetInterface *interface, const Ipv6Addr *ipAddr)
Check whether an IPv6 address is on-link.
Definition: ipv6_misc.c:1023
#define ipv6IsMulticastAddr(ipAddr)
Definition: ipv6.h:131
#define ipv6GetLinkLocalAddrState(interface)
Definition: ipv6.h:139
error_t ipv6DeleteAllRoutes(void)
Delete all routes from the IPv6 routing table.
Definition: ipv6_routing.c:243
TCP/IP stack core.
void netBufferFree(NetBuffer *buffer)
Dispose a multi-part buffer.
Definition: net_mem.c:280
Debugging facilities.
error_t netBufferCopy(NetBuffer *dest, size_t destOffset, const NetBuffer *src, size_t srcOffset, size_t length)
Copy data between multi-part buffers.
Definition: net_mem.c:502
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:295
uint_t ipv6GetAddrScope(const Ipv6Addr *ipAddr)
Retrieve the scope of an IPv6 address.
Definition: ipv6_misc.c:1184
Generic error code.
Definition: error.h:43
Invalid parameter.
Definition: error.h:45
error_t ipv6DeleteRoute(const Ipv6Addr *prefix, uint_t prefixLen)
Remove an entry from the IPv6 routing table.
Definition: ipv6_routing.c:194
IPv4 and IPv6 common routines.
__start_packed struct @183 Ipv6Addr
IPv6 network address.
PPP interface.
Definition: nic.h:70
#define IPV6_ROUTING_TABLE_SIZE
Definition: ipv6_routing.h:45
error_t nicSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet to the network controller.
Definition: nic.c:148
error_t ndpSendRedirect(NetInterface *interface, const Ipv6Addr *targetAddr, const NetBuffer *ipPacket, size_t ipPacketOffset)
Send a Redirect message.
Definition: ndp.c:1733
#define TRUE
Definition: os_port.h:48
#define ipv6IsLinkLocalUnicastAddr(ipAddr)
Definition: ipv6.h:123
const Ipv6Addr IPV6_LOOPBACK_ADDR
Definition: ipv6.c:69
NetInterface * interface
Outgoing network interface.
Definition: ipv6_routing.h:65
void * netBufferAt(const NetBuffer *buffer, size_t offset)
Returns a pointer to the data at the specified position.
Definition: net_mem.c:411
Invalid interface.
Definition: error.h:51
uint8_t ipPacket[]
Definition: ndp.h:427
error_t ipv6ParseHopByHopOptHeader(NetInterface *interface, const NetBuffer *ipPacket, size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset)
Parse Hop-by-Hop Options header.
Definition: ipv6.c:1197
uint_t prefixLen
IPv6 prefix length.
Definition: ipv6_routing.h:64
bool_t ipv6CompPrefix(const Ipv6Addr *ipAddr1, const Ipv6Addr *ipAddr2, size_t length)
Compare IPv6 address prefixes.
Definition: ipv6_misc.c:1140
IPv6 routing.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
error_t ipv6ForwardPacket(NetInterface *srcInterface, NetBuffer *ipPacket, size_t ipPacketOffset)
Forward an IPv6 packet.
Definition: ipv6_routing.c:265
error_t ipv6AddRoute(const Ipv6Addr *prefix, uint_t prefixLen, NetInterface *interface, const Ipv6Addr *nextHop, uint_t metric)
Add a new entry in the IPv6 routing table.
Definition: ipv6_routing.c:101
error_t icmpv6SendErrorMessage(NetInterface *interface, uint8_t type, uint8_t code, uint32_t parameter, const NetBuffer *ipPacket, size_t ipPacketOffset)
Send an ICMPv6 Error message.
Definition: icmpv6.c:462
error_t ipv6MapMulticastAddrToMac(const Ipv6Addr *ipAddr, MacAddr *macAddr)
Map an IPv6 multicast address to a MAC-layer multicast address.
Definition: ipv6_misc.c:1326
error_t ipv6CheckDestAddr(NetInterface *interface, const Ipv6Addr *ipAddr)
Destination IPv6 address filtering.
Definition: ipv6_misc.c:773
An address assigned to an interface whose use is unrestricted.
Definition: ipv6.h:171
error_t ethSendFrame(NetInterface *interface, const MacAddr *destAddr, NetBuffer *buffer, size_t offset, uint16_t type)
Send an Ethernet frame.
Definition: ethernet.c:476
Helper functions for IPv6.
#define TRACE_INFO(...)
Definition: debug.h:86
error_t ipv6InitRouting(void)
Initialize IPv6 routing table.
Definition: ipv6_routing.c:55
error_t ndpEnqueuePacket(NetInterface *srcInterface, NetInterface *destInterface, const Ipv6Addr *ipAddr, NetBuffer *buffer, size_t offset)
Enqueue an IPv6 packet waiting for address resolution.
Definition: ndp.c:190
Routing table entry.
Definition: ipv6_routing.h:60
Ethernet interface.
Definition: nic.h:69
IPv6 (Internet Protocol Version 6)
Success.
Definition: error.h:42
void ipv6DumpHeader(const Ipv6Header *ipHeader)
Dump IPv6 header for debugging purpose.
Definition: ipv6.c:2367
Ipv6Addr prefix
error_t
Error codes.
Definition: error.h:40
#define TRACE_WARNING(...)
Definition: debug.h:78
NetInterface * nicGetPhysicalInterface(NetInterface *interface)
Retrieve physical interface.
Definition: nic.c:85
Ipv4Addr destIpAddr
Definition: ipcp.h:76
unsigned int uint_t
Definition: compiler_port.h:43
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
__start_packed struct @112 MacAddr
MAC address.
ICMPv6 (Internet Control Message Protocol Version 6)
#define PRIuSIZE
Definition: compiler_port.h:72
#define NetInterface
Definition: net.h:34
Ipv6Addr nextHop
Next hop.
Definition: ipv6_routing.h:66
NetBuffer * ethAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold an Ethernet frame.
Definition: ethernet.c:1107
bool_t valid
Valid entry.
Definition: ipv6_routing.h:62
uint8_t prefixLen
error_t ipv6EnableRouting(NetInterface *interface, bool_t enable)
Enable routing for the specified interface.
Definition: ipv6_routing.c:73
const Ipv6Addr IPV6_UNSPECIFIED_ADDR
Definition: ipv6.c:65
NDP (Neighbor Discovery Protocol)
6LoWPAN interface
Definition: nic.h:71
error_t pppSendFrame(NetInterface *interface, NetBuffer *buffer, size_t offset, uint16_t protocol)
Send a PPP frame.
Definition: ppp.c:1004
OsMutex netMutex
Definition: net.c:70
Internet Protocol version 6.
Definition: ppp.h:198
Ipv6Addr prefix
Destination.
Definition: ipv6_routing.h:63
uint8_t length
Definition: dtls_misc.h:140
#define Ipv6Header
Definition: ipv6.h:34
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:119
uint_t metric
Metric value.
Definition: ipv6_routing.h:67
error_t ndpResolve(NetInterface *interface, const Ipv6Addr *ipAddr, MacAddr *macAddr)
Address resolution using Neighbor Discovery protocol.
Definition: ndp.c:98