dhcpv6_relay.c
Go to the documentation of this file.
1 /**
2  * @file dhcpv6_relay.c
3  * @brief DHCPv6 relay agent (Dynamic Host Configuration Protocol for IPv6)
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  * @section Description
28  *
29  * DHCPv6 Relay-Agents are deployed to forward DHCPv6 messages between clients
30  * and servers when they are not on the same IPv6 link and are often implemented
31  * alongside a routing function in a common node. Refer to RFC 3315
32  *
33  * @author Oryx Embedded SARL (www.oryx-embedded.com)
34  * @version 1.9.6
35  **/
36 
37 //Switch to the appropriate trace level
38 #define TRACE_LEVEL DHCPV6_TRACE_LEVEL
39 
40 //Dependencies
41 #include "core/net.h"
42 #include "dhcpv6_relay.h"
43 #include "dhcpv6/dhcpv6_common.h"
44 #include "dhcpv6/dhcpv6_debug.h"
45 #include "debug.h"
46 
47 //Check TCP/IP stack configuration
48 #if (IPV6_SUPPORT == ENABLED && DHCPV6_RELAY_SUPPORT == ENABLED)
49 
50 
51 /**
52  * @brief Start DHCPv6 relay agent
53  * @param[in] context Pointer to the DHCPv6 relay agent context
54  * @param[in] settings DHCPv6 relay agent specific settings
55  * @return Error code
56  **/
57 
59 {
60  error_t error;
61  uint_t i;
62  OsTask *task;
63 
64  //Debug message
65  TRACE_INFO("Starting DHCPv6 relay agent...\r\n");
66 
67  //Ensure the parameters are valid
68  if(!context || !settings)
70  //The pointer to the network-facing interface shall be valid
71  if(!settings->serverInterface)
73  //Check the number of client-facing interfaces
74  if(!settings->clientInterfaceCount)
78 
79  //Loop through the client-facing interfaces
80  for(i = 0; i < settings->clientInterfaceCount; i++)
81  {
82  //A valid pointer is required for each interface
83  if(!settings->clientInterface[i])
85  }
86 
87  //Check the address to be used when forwarding messages to the server
89  return ERROR_INVALID_ADDRESS;
90 
91  //Clear the DHCPv6 relay agent context
92  memset(context, 0, sizeof(Dhcpv6RelayContext));
93 
94  //Save the network-facing interface
95  context->serverInterface = settings->serverInterface;
96  //Save the number of client-facing interfaces
97  context->clientInterfaceCount = settings->clientInterfaceCount;
98 
99  //Save all the client-facing interfaces
100  for(i = 0; i < context->clientInterfaceCount; i++)
101  context->clientInterface[i] = settings->clientInterface[i];
102 
103  //Save the address to be used when relaying client messages to the server
104  context->serverAddress = settings->serverAddress;
105 
106  //Join the All_DHCP_Relay_Agents_and_Servers multicast group
107  //for each client-facing interface
108  error = dhcpv6RelayJoinMulticastGroup(context);
109  //Any error to report?
110  if(error)
111  return error;
112 
113  //Start of exception handling block
114  do
115  {
116  //Open a UDP socket to handle the network-facing interface
118  //Failed to open socket?
119  if(!context->serverSocket)
120  {
121  //Report an error
122  error = ERROR_OPEN_FAILED;
123  //Stop processing
124  break;
125  }
126 
127  //Explicitly associate the socket with the relevant interface
128  error = socketBindToInterface(context->serverSocket, context->serverInterface);
129  //Unable to bind the socket to the desired interface?
130  if(error)
131  break;
132 
133  //Relay agents listen for DHCPv6 messages on UDP port 547
135  //Unable to bind the socket to the desired port?
136  if(error)
137  break;
138 
139  //Only accept datagrams with source port number 547
141  //Any error to report?
142  if(error)
143  break;
144 
145  //If the relay agent relays messages to the All_DHCP_Servers address
146  //or other multicast addresses, it sets the Hop Limit field to 32
147 
148  //Loop through the client-facing interfaces
149  for(i = 0; i < context->clientInterfaceCount; i++)
150  {
151  //Open a UDP socket to handle the current interface
153  //Failed to open socket?
154  if(!context->clientSocket[i])
155  {
156  //Report an error
157  error = ERROR_OPEN_FAILED;
158  //Stop processing
159  break;
160  }
161 
162  //Explicitly associate the socket with the relevant interface
163  error = socketBindToInterface(context->clientSocket[i], context->clientInterface[i]);
164  //Unable to bind the socket to the desired interface?
165  if(error)
166  break;
167 
168  //Relay agents listen for DHCPv6 messages on UDP port 547
169  error = socketBind(context->clientSocket[i], &IP_ADDR_ANY, DHCPV6_SERVER_PORT);
170  //Unable to bind the socket to the desired port?
171  if(error)
172  break;
173 
174  //Only accept datagrams with source port number 546
176  //Any error to report?
177  if(error)
178  break;
179  }
180 
181  //Propagate exception if necessary
182  if(error)
183  break;
184 
185  //Initialize event object
186  if(!osCreateEvent(&context->event))
187  {
188  //Failed to create event
189  error = ERROR_OUT_OF_RESOURCES;
190  //Stop processing
191  break;
192  }
193 
194  //Initialize ACK event object
195  if(!osCreateEvent(&context->ackEvent))
196  {
197  //Failed to create event
198  error = ERROR_OUT_OF_RESOURCES;
199  //Stop processing
200  break;
201  }
202 
203  //The DHCPv6 relay agent is now running
204  context->running = TRUE;
205 
206  //Start the DHCPv6 relay agent service
207  task = osCreateTask("DHCPv6 Relay", dhcpv6RelayTask,
209 
210  //Unable to create the task?
211  if(task == OS_INVALID_HANDLE)
212  error = ERROR_OUT_OF_RESOURCES;
213 
214  //End of exception handling block
215  } while(0);
216 
217  //Did we encounter an error?
218  if(error)
219  {
220  //Close the socket associated with the network-facing interface
221  socketClose(context->serverSocket);
222 
223  //Close the socket associated with each client-facing interface
224  for(i = 0; i < context->clientInterfaceCount; i++)
225  socketClose(context->clientSocket[i]);
226 
227  //Leave the All_DHCP_Relay_Agents_and_Servers multicast group
228  //for each client-facing interface
230 
231  //Delete event objects
232  osDeleteEvent(&context->event);
233  osDeleteEvent(&context->ackEvent);
234  }
235 
236  //Return status code
237  return error;
238 }
239 
240 
241 /**
242  * @brief Stop DHCPv6 relay agent
243  * @param[in] context Pointer to the DHCPv6 relay agent context
244  * @return Error code
245  **/
246 
248 {
249  uint_t i;
250 
251  //Debug message
252  TRACE_INFO("Stopping DHCPv6 relay agent...\r\n");
253 
254  //Ensure the specified pointer is valid
255  if(context == NULL)
257  //Check DHCPv6 relay agent state
258  if(!context->running)
259  return ERROR_WRONG_STATE;
260 
261  //Reset ACK event before sending the kill signal
262  osResetEvent(&context->ackEvent);
263  //Stop the DHCPv6 relay agent task
264  context->stopRequest = TRUE;
265  //Send a signal to the task in order to abort any blocking operation
266  osSetEvent(&context->event);
267 
268  //Wait for the process to terminate...
270 
271  //Leave the All_DHCP_Relay_Agents_and_Servers multicast group
272  //for each client-facing interface
274 
275  //Close the socket that carries traffic towards the DHCPv6 server
276  socketClose(context->serverSocket);
277 
278  //Properly dispose the sockets that carry traffic towards the DHCPv6 clients
279  for(i = 0; i < context->clientInterfaceCount; i++)
280  socketClose(context->clientSocket[i]);
281 
282  //Delete event objects
283  osDeleteEvent(&context->event);
284  osDeleteEvent(&context->ackEvent);
285 
286  //Successful processing
287  return NO_ERROR;
288 }
289 
290 
291 /**
292  * @brief Join All_DHCP_Relay_Agents_and_Servers multicast group
293  * @param[in] context Pointer to the DHCPv6 relay agent context
294  **/
295 
297 {
298  uint_t i;
299  uint_t j;
300 
301  //Initialize status code
302  error_t error = NO_ERROR;
303 
304  //Loop through the client-facing interfaces
305  for(i = 0; i < context->clientInterfaceCount; i++)
306  {
307  //Join the All_DHCP_Relay_Agents_and_Servers multicast
308  //group for each interface
309  error = ipv6JoinMulticastGroup(context->clientInterface[i],
311  //Unable to join the specified multicast group?
312  if(error)
313  break;
314  }
315 
316  //Did we encounter an error?
317  if(error)
318  {
319  //Clean up side effects before returning...
320  for(j = 0; j < i; j++)
321  {
322  //Leave the multicast group for each interface
325  }
326  }
327 
328  //Return status code
329  return error;
330 }
331 
332 
333 /**
334  * @brief Leave All_DHCP_Relay_Agents_and_Servers multicast group
335  * @param[in] context Pointer to the DHCPv6 relay agent context
336  **/
337 
339 {
340  uint_t i;
341 
342  //Loop through the client-facing interfaces
343  for(i = 0; i < context->clientInterfaceCount; i++)
344  {
345  //Leave the All_DHCP_Relay_Agents_and_Servers multicast
346  //group for each interface
349  }
350 
351  //Successsful processing
352  return NO_ERROR;
353 }
354 
355 
356 /**
357  * @brief DHCPv6 relay agent task
358  * @param[in] param Pointer to the DHCPv6 relay agent context
359  **/
360 
361 void dhcpv6RelayTask(void *param)
362 {
363  error_t error;
364  uint_t i;
365  Dhcpv6RelayContext *context;
366 
367  //Task prologue
368  osEnterTask();
369 
370  //Point to the DHCPv6 relay agent context
371  context = (Dhcpv6RelayContext *) param;
372 
373  //Specify the events the application is interested in for
374  //each client-facing sockets
375  for(i = 0; i < context->clientInterfaceCount; i++)
376  {
377  context->eventDesc[i].socket = context->clientSocket[i];
379  }
380 
381  //Specify the events the application is interested in for
382  //the network-facing socket
383  context->eventDesc[i].socket = context->serverSocket;
385 
386  //Main loop
387  while(1)
388  {
389  //Wait for incoming packets on network-facing or client-facing interfaces
390  error = socketPoll(context->eventDesc, context->clientInterfaceCount + 1,
391  &context->event, INFINITE_DELAY);
392 
393  //Stop DHCPv6 relay agent?
394  if(context->stopRequest)
395  {
396  //The DHCPv6 relay agent is about to stop
397  context->stopRequest = FALSE;
398  context->running = FALSE;
399  //Acknowledge the reception of the user request
400  osSetEvent(&context->ackEvent);
401  //Kill ourselves
402  osDeleteTask(NULL);
403  }
404 
405  //Verify status code
406  if(!error)
407  {
408  //Check the state of each client-facing socket
409  for(i = 0; i < context->clientInterfaceCount; i++)
410  {
411  //Relay client messages if applicable
412  if(context->eventDesc[i].eventFlags & SOCKET_EVENT_RX_READY)
413  dhcpv6ForwardClientMessage(context, i);
414  }
415 
416  //Check the state of the network-facing socket
417  if(context->eventDesc[i].eventFlags & SOCKET_EVENT_RX_READY)
418  {
419  //Forward Relay-Reply messages from the network
421  }
422  }
423  }
424 }
425 
426 
427 /**
428  * @brief Forward client message
429  * @param[in] context Pointer to the DHCPv6 relay agent context
430  * @param[in] index Index identifying the interface on which the message was received
431  * @return Error code
432  **/
433 
435 {
436  error_t error;
437  uint32_t interfaceId;
438  size_t inputMessageLen;
439  size_t outputMessageLen;
440  Dhcpv6RelayMessage *inputMessage;
441  Dhcpv6RelayMessage *outputMessage;
442  Dhcpv6Option *option;
443  IpAddr ipAddr;
444 
445  //Point to the buffer where to store the incoming DHCPv6 message
446  inputMessage = (Dhcpv6RelayMessage *) (context->buffer + DHCPV6_RELAY_FORW_OVERHEAD);
447  //Message that will be forwarded by the DHCPv6 relay agent
448  outputMessage = (Dhcpv6RelayMessage *) context->buffer;
449 
450  //Read incoming message
451  error = socketReceiveFrom(context->clientSocket[index], &ipAddr, NULL, inputMessage,
452  DHCPV6_MAX_MSG_SIZE - DHCPV6_RELAY_FORW_OVERHEAD, &inputMessageLen, 0);
453  //Any error to report?
454  if(error)
455  return error;
456 
457  //Debug message
458  TRACE_INFO("\r\nDHCPv6 message received on client-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
459  context->clientInterface[index]->name, inputMessageLen);
460 
461  //Dump the contents of the message for debugging purpose
462  dhcpv6DumpMessage(inputMessage, inputMessageLen);
463 
464  //The source address must be a valid IPv6 address
465  if(ipAddr.length != sizeof(Ipv6Addr))
466  return ERROR_INVALID_ADDRESS;
467  //Check the length of the DHCPv6 message
468  if(inputMessageLen < sizeof(Dhcpv6Message))
469  return ERROR_INVALID_MESSAGE;
470 
471  //When the relay agent receives a valid message to be relayed,
472  //it constructs a new Relay-Forward message
473  outputMessage->msgType = DHCPV6_MSG_TYPE_RELAY_FORW;
474 
475  //Inspect the message type
476  switch(inputMessage->msgType)
477  {
478  //Message received from a client?
487  //If the relay agent received the message to be relayed from a client
488  //the hop-count in the Relay-Forward message is set to 0
489  outputMessage->hopCount = 0;
490  //Continue processing
491  break;
492 
493  //Message received from another relay agent?
495  //If the message received by the relay agent is a Relay-Forward message
496  //and the hop-count in the message is greater than or equal to 32, the
497  //relay agent discards the received message
498  if(inputMessage->hopCount >= DHCPV6_HOP_COUNT_LIMIT)
499  return ERROR_INVALID_MESSAGE;
500  //Set the hop-count field to the value of the hop-count field in
501  //the received message incremented by 1
502  outputMessage->hopCount = inputMessage->hopCount + 1;
503  //Continue processing
504  break;
505 
506  //Message received from a server?
507  default:
508  //Discard ADVERTISE, REPLY, RECONFIGURE and RELAY-REPL messages
509  return ERROR_INVALID_MESSAGE;
510  }
511 
512  //Set the link-address field to the unspecified address
513  outputMessage->linkAddress = IPV6_UNSPECIFIED_ADDR;
514  //Copy the source address from the header of the IP datagram in
515  //which the message was received to the peer-address field
516  outputMessage->peerAddress = ipAddr.ipv6Addr;
517  //Size of the Relay-Forward message
518  outputMessageLen = sizeof(Dhcpv6RelayMessage);
519 
520  //Get the interface identifier
521  interfaceId = context->clientInterface[index]->id;
522  //Convert the 32-bit integer to network byte order
524 
525  //If the relay agent cannot use the address in the link-address field
526  //to identify the interface through which the response to the client
527  //will be relayed, the relay agent must include an Interface ID option
528  dhcpv6AddOption(outputMessage, &outputMessageLen,
530 
531  //Copy the received DHCPv6 message into a Relay Message option
532  option = dhcpv6AddOption(outputMessage, &outputMessageLen,
533  DHCPV6_OPTION_RELAY_MSG, NULL, 0);
534 
535  //Set the appropriate length of the option
536  option->length = htons(inputMessageLen);
537  //Adjust the length of the Relay-Forward message
538  outputMessageLen += inputMessageLen;
539 
540  //Debug message
541  TRACE_INFO("Forwarding DHCPv6 message on network-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
542  context->serverInterface->name, outputMessageLen);
543 
544  //Dump the contents of the message for debugging purpose
545  dhcpv6DumpMessage(outputMessage, outputMessageLen);
546 
547  //Destination address to be used when relaying the client message
548  ipAddr.length = sizeof(Ipv6Addr);
549  ipAddr.ipv6Addr = context->serverAddress;
550 
551  //Relay the client message to the server
552  return socketSendTo(context->serverSocket, &ipAddr,
553  DHCPV6_SERVER_PORT, outputMessage, outputMessageLen, NULL, 0);
554 }
555 
556 
557 /**
558  * @brief Forward Relay-Reply message
559  * @param[in] context Pointer to the DHCPv6 relay agent context
560  * @return Error code
561  **/
562 
564 {
565  error_t error;
566  uint_t i;
567  uint32_t interfaceId;
568  size_t inputMessageLen;
569  size_t outputMessageLen;
570  Dhcpv6RelayMessage *inputMessage;
571  Dhcpv6Message *outputMessage;
572  Dhcpv6Option *option;
573  IpAddr ipAddr;
574  uint16_t port;
575 
576  //Point to the buffer where to store the incoming DHCPv6 message
577  inputMessage = (Dhcpv6RelayMessage *) context->buffer;
578 
579  //Read incoming message
580  error = socketReceiveFrom(context->serverSocket, &ipAddr, &port,
581  inputMessage, DHCPV6_MAX_MSG_SIZE, &inputMessageLen, 0);
582  //Any error to report?
583  if(error)
584  return error;
585 
586  //Debug message
587  TRACE_INFO("\r\nDHCPv6 message received on network-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
588  context->serverInterface->name, inputMessageLen);
589 
590  //Dump the contents of the message for debugging purpose
591  dhcpv6DumpMessage(inputMessage, inputMessageLen);
592 
593  //Check the length of the DHCPv6 message
594  if(inputMessageLen < sizeof(Dhcpv6RelayMessage))
595  return ERROR_INVALID_MESSAGE;
596 
597  //Inspect the message type and only forward Relay-Reply messages.
598  //Other DHCPv6 message types must be silently discarded
599  if(inputMessage->msgType != DHCPV6_MSG_TYPE_RELAY_REPL)
600  return ERROR_INVALID_MESSAGE;
601 
602  //Get the length of the Options field
603  inputMessageLen -= sizeof(Dhcpv6Message);
604 
605  //Check whether an Interface ID option is included in the Relay-Reply
606  option = dhcpv6GetOption(inputMessage->options, inputMessageLen, DHCPV6_OPTION_INTERFACE_ID);
607  //Failed to retrieve specified option?
608  if(option == NULL || ntohs(option->length) != sizeof(interfaceId))
609  return ERROR_INVALID_MESSAGE;
610 
611  //Read the Interface ID option contents
612  memcpy(&interfaceId, option->value, sizeof(interfaceId));
613  //Convert the 32-bit integer from network byte order
615 
616  //The Relay-Reply message must include a Relay Message option
617  option = dhcpv6GetOption(inputMessage->options, inputMessageLen, DHCPV6_OPTION_RELAY_MSG);
618  //Failed to retrieve specified option?
619  if(option == NULL || ntohs(option->length) < sizeof(Dhcpv6Message))
620  return ERROR_INVALID_MESSAGE;
621 
622  //Extract the message from the Relay Message option
623  outputMessage = (Dhcpv6Message *) option->value;
624  //Save the length of the message
625  outputMessageLen = ntohs(option->length);
626 
627  //Loop through client-facing interfaces
628  for(i = 0; i < context->clientInterfaceCount; i++)
629  {
630  //Check whether the current interface matches the Interface ID option
631  if(context->clientInterface[i]->id == interfaceId)
632  {
633  //Debug message
634  TRACE_INFO("Forwarding DHCPv6 message on client-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
635  context->clientInterface[i]->name, outputMessageLen);
636 
637  //Dump the contents of the message for debugging purpose
638  dhcpv6DumpMessage(outputMessage, outputMessageLen);
639 
640  //Copy the peer-address into the destination IP address
641  ipAddr.length = sizeof(Ipv6Addr);
642  ipAddr.ipv6Addr = inputMessage->peerAddress;
643 
644  //Select the relevant port number to use
645  if(outputMessage->msgType == DHCPV6_MSG_TYPE_RELAY_REPL)
647  else
649 
650  //Relay the DHCPv6 message to the client on the link
651  //identified by the Interface ID option
652  return socketSendTo(context->clientSocket[i], &ipAddr,
653  port, outputMessage, outputMessageLen, NULL, 0);
654  }
655  }
656 
657  //Unknown interface identifier...
658  return ERROR_INVALID_OPTION;
659 }
660 
661 #endif
bool_t running
DHCPv6 relay agent is currently running or not?
Definition: dhcpv6_relay.h:99
#define htons(value)
Definition: cpu_endian.h:392
@ SOCKET_IP_PROTO_UDP
Definition: socket.h:93
error_t socketBind(Socket *socket, const IpAddr *localIpAddr, uint16_t localPort)
Associate a local address with a socket.
Definition: socket.c:355
__start_packed struct @130 Dhcpv6Option
DHCPv6 option.
@ DHCPV6_MSG_TYPE_DECLINE
Definition: dhcpv6_common.h:98
DHCPv6 relay agent (Dynamic Host Configuration Protocol for IPv6)
@ DHCPV6_MSG_TYPE_SOLICIT
Definition: dhcpv6_common.h:90
IP network address.
Definition: ip.h:71
@ ERROR_INVALID_INTERFACE
Invalid interface.
Definition: error.h:53
#define DHCPV6_CLIENT_PORT
Definition: dhcpv6_common.h:40
error_t dhcpv6ForwardRelayReplyMessage(Dhcpv6RelayContext *context)
Forward Relay-Reply message.
Definition: dhcpv6_relay.c:563
uint_t clientInterfaceCount
Number of client-facing interfaces.
Definition: dhcpv6_relay.h:81
#define TRUE
Definition: os_port.h:50
Definitions common to DHCPv6 client, server and relay agent.
void socketClose(Socket *socket)
Close an existing socket.
Definition: socket.c:822
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
@ DHCPV6_MSG_TYPE_REBIND
Definition: dhcpv6_common.h:95
@ DHCPV6_MSG_TYPE_RELAY_FORW
@ SOCKET_TYPE_DGRAM
Definition: socket.h:78
const Ipv6Addr DHCPV6_ALL_RELAY_AGENTS_AND_SERVERS_ADDR
Definition: dhcpv6_common.c:51
void dhcpv6RelayTask(void *param)
DHCPv6 relay agent task.
Definition: dhcpv6_relay.c:361
error_t dhcpv6RelayStop(Dhcpv6RelayContext *context)
Stop DHCPv6 relay agent.
Definition: dhcpv6_relay.c:247
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:121
@ ERROR_INVALID_MESSAGE
Definition: error.h:103
Ipv6Addr serverAddress
Address to be used when relaying messages to the server.
Definition: dhcpv6_relay.h:95
Dhcpv6Option * dhcpv6GetOption(const uint8_t *options, size_t optionsLength, uint16_t optionCode)
Find the specified option in a DHCPv6 message.
SocketEventDesc eventDesc[DHCPV6_RELAY_MAX_CLIENT_IF]
The events the application is interested in.
Definition: dhcpv6_relay.h:98
__start_packed struct @129 Dhcpv6RelayMessage
DHCPv6 relay agent message.
Socket * clientSocket[DHCPV6_RELAY_MAX_CLIENT_IF]
Sockets that handle client-facing interfaces.
Definition: dhcpv6_relay.h:97
error_t dhcpv6RelayLeaveMulticastGroup(Dhcpv6RelayContext *context)
Leave All_DHCP_Relay_Agents_and_Servers multicast group.
Definition: dhcpv6_relay.c:338
#define DHCPV6_RELAY_PRIORITY
Definition: dhcpv6_relay.h:54
error_t dhcpv6RelayStart(Dhcpv6RelayContext *context, const Dhcpv6RelaySettings *settings)
Start DHCPv6 relay agent.
Definition: dhcpv6_relay.c:58
@ ERROR_WRONG_STATE
Definition: error.h:207
@ ERROR_OPEN_FAILED
Definition: error.h:74
NetInterface * serverInterface
Network-facing interface.
Definition: dhcpv6_relay.h:79
const IpAddr IP_ADDR_ANY
Definition: ip.c:45
#define FALSE
Definition: os_port.h:46
NetInterface * serverInterface
Network-facing interface.
Definition: dhcpv6_relay.h:92
OsEvent ackEvent
Event object use to acknowledge user requests.
Definition: dhcpv6_relay.h:101
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define htonl(value)
Definition: cpu_endian.h:393
#define DHCPV6_MAX_MSG_SIZE
Definition: dhcpv6_common.h:44
OsTask * osCreateTask(const char_t *name, OsTaskCode taskCode, void *param, size_t stackSize, int_t priority)
Create a new task.
void osResetEvent(OsEvent *event)
Set the specified event object to the nonsignaled state.
OsEvent event
Event object used to poll the sockets.
Definition: dhcpv6_relay.h:102
error_t
Error codes.
Definition: error.h:42
@ ERROR_INVALID_ADDRESS
Definition: error.h:102
@ DHCPV6_MSG_TYPE_RELEASE
Definition: dhcpv6_common.h:97
void osDeleteEvent(OsEvent *event)
Delete an event object.
Task object.
error_t dhcpv6RelayJoinMulticastGroup(Dhcpv6RelayContext *context)
Join All_DHCP_Relay_Agents_and_Servers multicast group.
Definition: dhcpv6_relay.c:296
error_t socketReceiveFrom(Socket *socket, IpAddr *srcIpAddr, uint16_t *srcPort, void *data, size_t size, size_t *received, uint_t flags)
Receive a datagram from a connectionless socket.
Definition: socket.c:629
Ipv6Addr serverAddress
Address to be used when relaying messages to the server.
Definition: dhcpv6_relay.h:82
__start_packed struct @128 Dhcpv6Message
DHCPv6 message.
error_t socketConnect(Socket *socket, const IpAddr *remoteIpAddr, uint16_t remotePort)
Establish a connection to a specified socket.
Definition: socket.c:381
const Ipv6Addr IPV6_UNSPECIFIED_ADDR
Definition: ipv6.c:67
error_t ipv6LeaveMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Leave an IPv6 multicast group.
Definition: ipv6.c:2038
__start_packed struct @179 Ipv6Addr
IPv6 network address.
@ DHCPV6_MSG_TYPE_RENEW
Definition: dhcpv6_common.h:94
error_t ipv6JoinMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Join an IPv6 multicast group.
Definition: ipv6.c:1928
Eui64 interfaceId
Definition: ipv6cp.h:69
#define TRACE_INFO(...)
Definition: debug.h:94
uint8_t buffer[DHCPV6_MAX_MSG_SIZE]
Scratch buffer to store DHCPv6 messages.
Definition: dhcpv6_relay.h:103
Socket * socketOpen(uint_t type, uint_t protocol)
Create a socket (UDP or TCP)
Definition: socket.c:95
#define osEnterTask()
uint_t eventFlags
Returned events.
Definition: socket.h:311
error_t socketPoll(SocketEventDesc *eventDesc, uint_t size, OsEvent *extEvent, systime_t timeout)
Wait for one of a set of sockets to become ready to perform I/O.
Definition: socket.c:882
#define DHCPV6_RELAY_MAX_CLIENT_IF
Definition: dhcpv6_relay.h:59
#define socketBindToInterface
Definition: net_legacy.h:270
@ DHCPV6_MSG_TYPE_INFO_REQUEST
DHCPv6 relay agent settings.
Definition: dhcpv6_relay.h:77
@ DHCPV6_MSG_TYPE_RELAY_REPL
uint16_t port
Definition: dns_common.h:223
#define ntohs(value)
Definition: cpu_endian.h:398
#define DHCPV6_SERVER_PORT
Definition: dhcpv6_common.h:41
NetInterface * clientInterface[DHCPV6_RELAY_MAX_CLIENT_IF]
Client-facing interfaces.
Definition: dhcpv6_relay.h:93
#define OS_INVALID_HANDLE
Definition: os_port.h:79
#define DHCPV6_RELAY_FORW_OVERHEAD
Definition: dhcpv6_relay.h:65
@ SOCKET_EVENT_RX_READY
Definition: socket.h:160
bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
Wait until the specified event is in the signaled state.
DHCPv6 relay agent context.
Definition: dhcpv6_relay.h:90
error_t dhcpv6DumpMessage(const void *message, size_t length)
Dump DHCPv6 message for debugging purpose.
Definition: dhcpv6_debug.c:123
NetInterface * clientInterface[DHCPV6_RELAY_MAX_CLIENT_IF]
Client-facing interfaces.
Definition: dhcpv6_relay.h:80
error_t dhcpv6ForwardClientMessage(Dhcpv6RelayContext *context, uint_t index)
Forward client message.
Definition: dhcpv6_relay.c:434
Dhcpv6Option * dhcpv6AddOption(void *message, size_t *messageLen, uint16_t optionCode, const void *optionValue, size_t optionLen)
Add an option to a DHCPv6 message.
@ DHCPV6_OPTION_RELAY_MSG
bool_t osCreateEvent(OsEvent *event)
Create an event object.
void osDeleteTask(OsTask *task)
Delete a task.
error_t socketSendTo(Socket *socket, const IpAddr *destIpAddr, uint16_t destPort, const void *data, size_t length, size_t *written, uint_t flags)
Send a datagram to a specific destination.
Definition: socket.c:535
@ DHCPV6_MSG_TYPE_CONFIRM
Definition: dhcpv6_common.h:93
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
@ ERROR_INVALID_OPTION
Definition: error.h:97
#define DHCPV6_HOP_COUNT_LIMIT
Definition: dhcpv6_common.h:49
uint_t clientInterfaceCount
Number of client-facing interfaces.
Definition: dhcpv6_relay.h:94
Socket * socket
Handle to a socket to monitor.
Definition: socket.h:309
#define PRIuSIZE
Definition: compiler_port.h:78
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
bool_t stopRequest
Stop request.
Definition: dhcpv6_relay.h:100
@ DHCPV6_OPTION_INTERFACE_ID
#define DHCPV6_RELAY_STACK_SIZE
Definition: dhcpv6_relay.h:47
uint8_t ipAddr[4]
Definition: mib_common.h:187
#define ntohl(value)
Definition: cpu_endian.h:399
uint_t eventMask
Requested events.
Definition: socket.h:310
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
Socket * serverSocket
Socket that handles the network-facing interface.
Definition: dhcpv6_relay.h:96
Data logging functions for debugging purpose (DHCPv6)
#define INFINITE_DELAY
Definition: os_port.h:74
@ DHCPV6_MSG_TYPE_REQUEST
Definition: dhcpv6_common.h:92