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-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @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 2.4.0
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 
63  //Debug message
64  TRACE_INFO("Starting DHCPv6 relay agent...\r\n");
65 
66  //Ensure the parameters are valid
67  if(!context || !settings)
69  //The pointer to the network-facing interface shall be valid
70  if(!settings->serverInterface)
72  //Check the number of client-facing interfaces
73  if(!settings->clientInterfaceCount)
77 
78  //Loop through the client-facing interfaces
79  for(i = 0; i < settings->clientInterfaceCount; i++)
80  {
81  //A valid pointer is required for each interface
82  if(!settings->clientInterface[i])
84  }
85 
86  //Check the address to be used when forwarding messages to the server
88  return ERROR_INVALID_ADDRESS;
89 
90  //Clear the DHCPv6 relay agent context
91  osMemset(context, 0, sizeof(Dhcpv6RelayContext));
92 
93  //Initialize task parameters
94  context->taskParams = settings->task;
95  context->taskId = OS_INVALID_TASK_ID;
96 
97  //Save the network-facing interface
98  context->serverInterface = settings->serverInterface;
99  //Save the number of client-facing interfaces
100  context->clientInterfaceCount = settings->clientInterfaceCount;
101 
102  //Save all the client-facing interfaces
103  for(i = 0; i < context->clientInterfaceCount; i++)
104  {
105  context->clientInterface[i] = settings->clientInterface[i];
106  }
107 
108  //Save the address to be used when relaying client messages to the server
109  context->serverAddress = settings->serverAddress;
110 
111  //Join the All_DHCP_Relay_Agents_and_Servers multicast group
112  //for each client-facing interface
113  error = dhcpv6RelayJoinMulticastGroup(context);
114  //Any error to report?
115  if(error)
116  return error;
117 
118  //Start of exception handling block
119  do
120  {
121  //Open a UDP socket to handle the network-facing interface
123  //Failed to open socket?
124  if(!context->serverSocket)
125  {
126  //Report an error
127  error = ERROR_OPEN_FAILED;
128  //Stop processing
129  break;
130  }
131 
132  //Explicitly associate the socket with the relevant interface
133  error = socketBindToInterface(context->serverSocket, context->serverInterface);
134  //Unable to bind the socket to the desired interface?
135  if(error)
136  break;
137 
138  //Relay agents listen for DHCPv6 messages on UDP port 547
140  //Unable to bind the socket to the desired port?
141  if(error)
142  break;
143 
144  //Only accept datagrams with source port number 547
146  //Any error to report?
147  if(error)
148  break;
149 
150  //If the relay agent relays messages to the All_DHCP_Servers address
151  //or other multicast addresses, it sets the Hop Limit field to 32
152 
153  //Loop through the client-facing interfaces
154  for(i = 0; i < context->clientInterfaceCount; i++)
155  {
156  //Open a UDP socket to handle the current interface
158  //Failed to open socket?
159  if(!context->clientSocket[i])
160  {
161  //Report an error
162  error = ERROR_OPEN_FAILED;
163  //Stop processing
164  break;
165  }
166 
167  //Explicitly associate the socket with the relevant interface
168  error = socketBindToInterface(context->clientSocket[i], context->clientInterface[i]);
169  //Unable to bind the socket to the desired interface?
170  if(error)
171  break;
172 
173  //Relay agents listen for DHCPv6 messages on UDP port 547
174  error = socketBind(context->clientSocket[i], &IP_ADDR_ANY, DHCPV6_SERVER_PORT);
175  //Unable to bind the socket to the desired port?
176  if(error)
177  break;
178 
179  //Only accept datagrams with source port number 546
181  //Any error to report?
182  if(error)
183  break;
184  }
185 
186  //Propagate exception if necessary
187  if(error)
188  break;
189 
190  //Initialize event object
191  if(!osCreateEvent(&context->event))
192  {
193  //Failed to create event
194  error = ERROR_OUT_OF_RESOURCES;
195  //Stop processing
196  break;
197  }
198 
199  //Initialize ACK event object
200  if(!osCreateEvent(&context->ackEvent))
201  {
202  //Failed to create event
203  error = ERROR_OUT_OF_RESOURCES;
204  //Stop processing
205  break;
206  }
207 
208  //The DHCPv6 relay agent is now running
209  context->running = TRUE;
210 
211  //Create a task
212  context->taskId = osCreateTask("DHCPv6 Relay",
213  (OsTaskCode) dhcpv6RelayTask, context, &context->taskParams);
214 
215  //Failed to create task?
216  if(context->taskId == OS_INVALID_TASK_ID)
217  error = ERROR_OUT_OF_RESOURCES;
218 
219  //End of exception handling block
220  } while(0);
221 
222  //Did we encounter an error?
223  if(error)
224  {
225  //Close the socket associated with the network-facing interface
226  socketClose(context->serverSocket);
227 
228  //Close the socket associated with each client-facing interface
229  for(i = 0; i < context->clientInterfaceCount; i++)
230  {
231  socketClose(context->clientSocket[i]);
232  }
233 
234  //Leave the All_DHCP_Relay_Agents_and_Servers multicast group
235  //for each client-facing interface
237 
238  //Delete event objects
239  osDeleteEvent(&context->event);
240  osDeleteEvent(&context->ackEvent);
241  }
242 
243  //Return status code
244  return error;
245 }
246 
247 
248 /**
249  * @brief Stop DHCPv6 relay agent
250  * @param[in] context Pointer to the DHCPv6 relay agent context
251  * @return Error code
252  **/
253 
255 {
256  uint_t i;
257 
258  //Make sure the DHCPv6 relay agent context is valid
259  if(context == NULL)
261 
262  //Debug message
263  TRACE_INFO("Stopping DHCPv6 relay agent...\r\n");
264 
265  //Check DHCPv6 relay agent state
266  if(!context->running)
267  return ERROR_WRONG_STATE;
268 
269  //Reset ACK event before sending the kill signal
270  osResetEvent(&context->ackEvent);
271  //Stop the DHCPv6 relay agent task
272  context->stopRequest = TRUE;
273  //Send a signal to the task in order to abort any blocking operation
274  osSetEvent(&context->event);
275 
276  //Wait for the process to terminate...
278 
279  //Leave the All_DHCP_Relay_Agents_and_Servers multicast group
280  //for each client-facing interface
282 
283  //Close the socket that carries traffic towards the DHCPv6 server
284  socketClose(context->serverSocket);
285 
286  //Properly dispose the sockets that carry traffic towards the DHCPv6 clients
287  for(i = 0; i < context->clientInterfaceCount; i++)
288  {
289  socketClose(context->clientSocket[i]);
290  }
291 
292  //Delete event objects
293  osDeleteEvent(&context->event);
294  osDeleteEvent(&context->ackEvent);
295 
296  //Successful processing
297  return NO_ERROR;
298 }
299 
300 
301 /**
302  * @brief Join All_DHCP_Relay_Agents_and_Servers multicast group
303  * @param[in] context Pointer to the DHCPv6 relay agent context
304  **/
305 
307 {
308  uint_t i;
309  uint_t j;
310 
311  //Initialize status code
312  error_t error = NO_ERROR;
313 
314  //Loop through the client-facing interfaces
315  for(i = 0; i < context->clientInterfaceCount; i++)
316  {
317  //Join the All_DHCP_Relay_Agents_and_Servers multicast
318  //group for each interface
319  error = ipv6JoinMulticastGroup(context->clientInterface[i],
321  //Unable to join the specified multicast group?
322  if(error)
323  break;
324  }
325 
326  //Did we encounter an error?
327  if(error)
328  {
329  //Clean up side effects before returning...
330  for(j = 0; j < i; j++)
331  {
332  //Leave the multicast group for each interface
335  }
336  }
337 
338  //Return status code
339  return error;
340 }
341 
342 
343 /**
344  * @brief Leave All_DHCP_Relay_Agents_and_Servers multicast group
345  * @param[in] context Pointer to the DHCPv6 relay agent context
346  **/
347 
349 {
350  uint_t i;
351 
352  //Loop through the client-facing interfaces
353  for(i = 0; i < context->clientInterfaceCount; i++)
354  {
355  //Leave the All_DHCP_Relay_Agents_and_Servers multicast
356  //group for each interface
359  }
360 
361  //Successsful processing
362  return NO_ERROR;
363 }
364 
365 
366 /**
367  * @brief DHCPv6 relay agent task
368  * @param[in] param Pointer to the DHCPv6 relay agent context
369  **/
370 
371 void dhcpv6RelayTask(void *param)
372 {
373  error_t error;
374  uint_t i;
375  Dhcpv6RelayContext *context;
376 
377  //Task prologue
378  osEnterTask();
379 
380  //Point to the DHCPv6 relay agent context
381  context = (Dhcpv6RelayContext *) param;
382 
383  //Specify the events the application is interested in for
384  //each client-facing sockets
385  for(i = 0; i < context->clientInterfaceCount; i++)
386  {
387  context->eventDesc[i].socket = context->clientSocket[i];
389  }
390 
391  //Specify the events the application is interested in for
392  //the network-facing socket
393  context->eventDesc[i].socket = context->serverSocket;
395 
396  //Main loop
397  while(1)
398  {
399  //Wait for incoming packets on network-facing or client-facing interfaces
400  error = socketPoll(context->eventDesc, context->clientInterfaceCount + 1,
401  &context->event, INFINITE_DELAY);
402 
403  //Stop DHCPv6 relay agent?
404  if(context->stopRequest)
405  {
406  //The DHCPv6 relay agent is about to stop
407  context->stopRequest = FALSE;
408  context->running = FALSE;
409  //Acknowledge the reception of the user request
410  osSetEvent(&context->ackEvent);
411  //Task epilogue
412  osExitTask();
413  //Kill ourselves
415  }
416 
417  //Verify status code
418  if(error == NO_ERROR || error == ERROR_WAIT_CANCELED)
419  {
420  //Check the state of each client-facing socket
421  for(i = 0; i < context->clientInterfaceCount; i++)
422  {
423  //Relay client messages if applicable
424  if(context->eventDesc[i].eventFlags & SOCKET_EVENT_RX_READY)
425  dhcpv6ForwardClientMessage(context, i);
426  }
427 
428  //Check the state of the network-facing socket
429  if(context->eventDesc[i].eventFlags & SOCKET_EVENT_RX_READY)
430  {
431  //Forward Relay-Reply messages from the network
433  }
434  }
435  }
436 }
437 
438 
439 /**
440  * @brief Forward client message
441  * @param[in] context Pointer to the DHCPv6 relay agent context
442  * @param[in] index Index identifying the interface on which the message was received
443  * @return Error code
444  **/
445 
447 {
448  error_t error;
449  uint32_t interfaceId;
450  size_t inputMessageLen;
451  size_t outputMessageLen;
452  Dhcpv6RelayMessage *inputMessage;
453  Dhcpv6RelayMessage *outputMessage;
454  Dhcpv6Option *option;
455  IpAddr ipAddr;
456 
457  //Point to the buffer where to store the incoming DHCPv6 message
458  inputMessage = (Dhcpv6RelayMessage *) (context->buffer + DHCPV6_RELAY_FORW_OVERHEAD);
459  //Message that will be forwarded by the DHCPv6 relay agent
460  outputMessage = (Dhcpv6RelayMessage *) context->buffer;
461 
462  //Read incoming message
463  error = socketReceiveFrom(context->clientSocket[index], &ipAddr, NULL, inputMessage,
464  DHCPV6_MAX_MSG_SIZE - DHCPV6_RELAY_FORW_OVERHEAD, &inputMessageLen, 0);
465  //Any error to report?
466  if(error)
467  return error;
468 
469  //Debug message
470  TRACE_INFO("\r\nDHCPv6 message received on client-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
471  context->clientInterface[index]->name, inputMessageLen);
472 
473  //Dump the contents of the message for debugging purpose
474  dhcpv6DumpMessage(inputMessage, inputMessageLen);
475 
476  //The source address must be a valid IPv6 address
477  if(ipAddr.length != sizeof(Ipv6Addr))
478  return ERROR_INVALID_ADDRESS;
479  //Check the length of the DHCPv6 message
480  if(inputMessageLen < sizeof(Dhcpv6Message))
481  return ERROR_INVALID_MESSAGE;
482 
483  //When the relay agent receives a valid message to be relayed,
484  //it constructs a new Relay-Forward message
485  outputMessage->msgType = DHCPV6_MSG_TYPE_RELAY_FORW;
486 
487  //Inspect the message type
488  switch(inputMessage->msgType)
489  {
490  //Message received from a client?
499  //If the relay agent received the message to be relayed from a client
500  //the hop-count in the Relay-Forward message is set to 0
501  outputMessage->hopCount = 0;
502  //Continue processing
503  break;
504 
505  //Message received from another relay agent?
507  //If the message received by the relay agent is a Relay-Forward message
508  //and the hop-count in the message is greater than or equal to
509  //HOP_COUNT_LIMIT, the relay agent discards the received message
510  if(inputMessage->hopCount >= DHCPV6_HOP_COUNT_LIMIT)
511  return ERROR_INVALID_MESSAGE;
512  //Set the hop-count field to the value of the hop-count field in
513  //the received message incremented by 1
514  outputMessage->hopCount = inputMessage->hopCount + 1;
515  //Continue processing
516  break;
517 
518  //Message received from a server?
519  default:
520  //Discard ADVERTISE, REPLY, RECONFIGURE and RELAY-REPL messages
521  return ERROR_INVALID_MESSAGE;
522  }
523 
524  //Set the link-address field to the unspecified address
525  outputMessage->linkAddress = IPV6_UNSPECIFIED_ADDR;
526  //Copy the source address from the header of the IP datagram in
527  //which the message was received to the peer-address field
528  outputMessage->peerAddress = ipAddr.ipv6Addr;
529  //Size of the Relay-Forward message
530  outputMessageLen = sizeof(Dhcpv6RelayMessage);
531 
532  //Get the interface identifier
533  interfaceId = context->clientInterface[index]->id;
534  //Convert the 32-bit integer to network byte order
536 
537  //If the relay agent cannot use the address in the link-address field
538  //to identify the interface through which the response to the client
539  //will be relayed, the relay agent must include an Interface ID option
540  dhcpv6AddOption(outputMessage, &outputMessageLen,
542 
543  //Copy the received DHCPv6 message into a Relay Message option
544  option = dhcpv6AddOption(outputMessage, &outputMessageLen,
545  DHCPV6_OPT_RELAY_MSG, NULL, 0);
546 
547  //Set the appropriate length of the option
548  option->length = htons(inputMessageLen);
549  //Adjust the length of the Relay-Forward message
550  outputMessageLen += inputMessageLen;
551 
552  //Debug message
553  TRACE_INFO("Forwarding DHCPv6 message on network-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
554  context->serverInterface->name, outputMessageLen);
555 
556  //Dump the contents of the message for debugging purpose
557  dhcpv6DumpMessage(outputMessage, outputMessageLen);
558 
559  //Destination address to be used when relaying the client message
560  ipAddr.length = sizeof(Ipv6Addr);
561  ipAddr.ipv6Addr = context->serverAddress;
562 
563  //Relay the client message to the server
564  return socketSendTo(context->serverSocket, &ipAddr,
565  DHCPV6_SERVER_PORT, outputMessage, outputMessageLen, NULL, 0);
566 }
567 
568 
569 /**
570  * @brief Forward Relay-Reply message
571  * @param[in] context Pointer to the DHCPv6 relay agent context
572  * @return Error code
573  **/
574 
576 {
577  error_t error;
578  uint_t i;
579  uint32_t interfaceId;
580  size_t inputMessageLen;
581  size_t outputMessageLen;
582  Dhcpv6RelayMessage *inputMessage;
583  Dhcpv6Message *outputMessage;
584  Dhcpv6Option *option;
585  IpAddr ipAddr;
586  uint16_t port;
587 
588  //Point to the buffer where to store the incoming DHCPv6 message
589  inputMessage = (Dhcpv6RelayMessage *) context->buffer;
590 
591  //Read incoming message
592  error = socketReceiveFrom(context->serverSocket, &ipAddr, &port,
593  inputMessage, DHCPV6_MAX_MSG_SIZE, &inputMessageLen, 0);
594  //Any error to report?
595  if(error)
596  return error;
597 
598  //Debug message
599  TRACE_INFO("\r\nDHCPv6 message received on network-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
600  context->serverInterface->name, inputMessageLen);
601 
602  //Dump the contents of the message for debugging purpose
603  dhcpv6DumpMessage(inputMessage, inputMessageLen);
604 
605  //Check the length of the DHCPv6 message
606  if(inputMessageLen < sizeof(Dhcpv6RelayMessage))
607  return ERROR_INVALID_MESSAGE;
608 
609  //Inspect the message type and only forward Relay-Reply messages.
610  //Other DHCPv6 message types must be silently discarded
611  if(inputMessage->msgType != DHCPV6_MSG_TYPE_RELAY_REPL)
612  return ERROR_INVALID_MESSAGE;
613 
614  //Get the length of the Options field
615  inputMessageLen -= sizeof(Dhcpv6Message);
616 
617  //Check whether an Interface ID option is included in the Relay-Reply
618  option = dhcpv6GetOption(inputMessage->options, inputMessageLen, DHCPV6_OPT_INTERFACE_ID);
619  //Failed to retrieve specified option?
620  if(option == NULL || ntohs(option->length) != sizeof(interfaceId))
621  return ERROR_INVALID_MESSAGE;
622 
623  //Read the Interface ID option contents
624  osMemcpy(&interfaceId, option->value, sizeof(interfaceId));
625  //Convert the 32-bit integer from network byte order
627 
628  //The Relay-Reply message must include a Relay Message option
629  option = dhcpv6GetOption(inputMessage->options, inputMessageLen, DHCPV6_OPT_RELAY_MSG);
630  //Failed to retrieve specified option?
631  if(option == NULL || ntohs(option->length) < sizeof(Dhcpv6Message))
632  return ERROR_INVALID_MESSAGE;
633 
634  //Extract the message from the Relay Message option
635  outputMessage = (Dhcpv6Message *) option->value;
636  //Save the length of the message
637  outputMessageLen = ntohs(option->length);
638 
639  //Loop through client-facing interfaces
640  for(i = 0; i < context->clientInterfaceCount; i++)
641  {
642  //Check whether the current interface matches the Interface ID option
643  if(context->clientInterface[i]->id == interfaceId)
644  {
645  //Debug message
646  TRACE_INFO("Forwarding DHCPv6 message on client-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
647  context->clientInterface[i]->name, outputMessageLen);
648 
649  //Dump the contents of the message for debugging purpose
650  dhcpv6DumpMessage(outputMessage, outputMessageLen);
651 
652  //Copy the peer-address into the destination IP address
653  ipAddr.length = sizeof(Ipv6Addr);
654  ipAddr.ipv6Addr = inputMessage->peerAddress;
655 
656  //Select the relevant port number to use
657  if(outputMessage->msgType == DHCPV6_MSG_TYPE_RELAY_REPL)
658  {
660  }
661  else
662  {
664  }
665 
666  //Relay the DHCPv6 message to the client on the link
667  //identified by the Interface ID option
668  return socketSendTo(context->clientSocket[i], &ipAddr,
669  port, outputMessage, outputMessageLen, NULL, 0);
670  }
671  }
672 
673  //Unknown interface identifier...
674  return ERROR_INVALID_OPTION;
675 }
676 
677 #endif
unsigned int uint_t
Definition: compiler_port.h:50
#define PRIuSIZE
#define ntohl(value)
Definition: cpu_endian.h:422
#define htonl(value)
Definition: cpu_endian.h:414
#define htons(value)
Definition: cpu_endian.h:413
#define ntohs(value)
Definition: cpu_endian.h:421
Debugging facilities.
#define TRACE_INFO(...)
Definition: debug.h:95
Dhcpv6Option * dhcpv6GetOption(const uint8_t *options, size_t optionsLength, uint16_t optionCode)
Search a DHCPv6 message for a given option.
Dhcpv6Option * dhcpv6AddOption(void *message, size_t *messageLen, uint16_t optionCode, const void *optionValue, size_t optionLen)
Add an option to a DHCPv6 message.
const Ipv6Addr DHCPV6_ALL_RELAY_AGENTS_AND_SERVERS_ADDR
Definition: dhcpv6_common.c:54
Definitions common to DHCPv6 client, server and relay agent.
Dhcpv6Option
#define DHCPV6_MAX_MSG_SIZE
Definition: dhcpv6_common.h:44
#define DHCPV6_CLIENT_PORT
Definition: dhcpv6_common.h:40
Dhcpv6Message
#define DHCPV6_HOP_COUNT_LIMIT
Definition: dhcpv6_common.h:49
#define DHCPV6_SERVER_PORT
Definition: dhcpv6_common.h:41
Dhcpv6RelayMessage
@ DHCPV6_OPT_RELAY_MSG
@ DHCPV6_OPT_INTERFACE_ID
@ DHCPV6_MSG_TYPE_RELAY_REPL
@ DHCPV6_MSG_TYPE_INFO_REQUEST
@ DHCPV6_MSG_TYPE_RELAY_FORW
@ DHCPV6_MSG_TYPE_DECLINE
Definition: dhcpv6_common.h:98
@ DHCPV6_MSG_TYPE_CONFIRM
Definition: dhcpv6_common.h:93
@ DHCPV6_MSG_TYPE_REBIND
Definition: dhcpv6_common.h:95
@ DHCPV6_MSG_TYPE_REQUEST
Definition: dhcpv6_common.h:92
@ DHCPV6_MSG_TYPE_RELEASE
Definition: dhcpv6_common.h:97
@ DHCPV6_MSG_TYPE_RENEW
Definition: dhcpv6_common.h:94
@ DHCPV6_MSG_TYPE_SOLICIT
Definition: dhcpv6_common.h:90
error_t dhcpv6DumpMessage(const void *message, size_t length)
Dump DHCPv6 message for debugging purpose.
Definition: dhcpv6_debug.c:123
Data logging functions for debugging purpose (DHCPv6)
error_t dhcpv6ForwardRelayReplyMessage(Dhcpv6RelayContext *context)
Forward Relay-Reply message.
Definition: dhcpv6_relay.c:575
error_t dhcpv6RelayLeaveMulticastGroup(Dhcpv6RelayContext *context)
Leave All_DHCP_Relay_Agents_and_Servers multicast group.
Definition: dhcpv6_relay.c:348
error_t dhcpv6RelayStop(Dhcpv6RelayContext *context)
Stop DHCPv6 relay agent.
Definition: dhcpv6_relay.c:254
error_t dhcpv6RelayJoinMulticastGroup(Dhcpv6RelayContext *context)
Join All_DHCP_Relay_Agents_and_Servers multicast group.
Definition: dhcpv6_relay.c:306
error_t dhcpv6RelayStart(Dhcpv6RelayContext *context, const Dhcpv6RelaySettings *settings)
Start DHCPv6 relay agent.
Definition: dhcpv6_relay.c:58
error_t dhcpv6ForwardClientMessage(Dhcpv6RelayContext *context, uint_t index)
Forward client message.
Definition: dhcpv6_relay.c:446
void dhcpv6RelayTask(void *param)
DHCPv6 relay agent task.
Definition: dhcpv6_relay.c:371
DHCPv6 relay agent (Dynamic Host Configuration Protocol for IPv6)
#define DHCPV6_RELAY_FORW_OVERHEAD
Definition: dhcpv6_relay.h:65
#define DHCPV6_RELAY_MAX_CLIENT_IF
Definition: dhcpv6_relay.h:59
uint16_t port
Definition: dns_common.h:267
error_t
Error codes.
Definition: error.h:43
@ ERROR_WAIT_CANCELED
Definition: error.h:73
@ ERROR_INVALID_INTERFACE
Invalid interface.
Definition: error.h:53
@ ERROR_INVALID_ADDRESS
Definition: error.h:103
@ ERROR_INVALID_OPTION
Definition: error.h:98
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
@ ERROR_INVALID_MESSAGE
Definition: error.h:105
@ ERROR_OPEN_FAILED
Definition: error.h:75
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_WRONG_STATE
Definition: error.h:209
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
const IpAddr IP_ADDR_ANY
Definition: ip.c:51
Ipv4Addr ipAddr
Definition: ipcp.h:105
error_t ipv6LeaveMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Leave an IPv6 multicast group.
Definition: ipv6.c:2145
const Ipv6Addr IPV6_UNSPECIFIED_ADDR
Definition: ipv6.c:65
error_t ipv6JoinMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Join an IPv6 multicast group.
Definition: ipv6.c:2035
Ipv6Addr
Definition: ipv6.h:251
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:120
Eui64 interfaceId
Definition: ipv6cp.h:71
TCP/IP stack core.
#define socketBindToInterface
Definition: net_legacy.h:193
#define osMemset(p, value, length)
Definition: os_port.h:135
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define INFINITE_DELAY
Definition: os_port.h:75
bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
Wait until the specified event is in the signaled state.
void osDeleteEvent(OsEvent *event)
Delete an event object.
OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *arg, const OsTaskParameters *params)
Create a task.
void osResetEvent(OsEvent *event)
Set the specified event object to the nonsignaled state.
void osDeleteTask(OsTaskId taskId)
Delete a task.
bool_t osCreateEvent(OsEvent *event)
Create an event object.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
void(* OsTaskCode)(void *arg)
Task routine.
#define osEnterTask()
#define OS_SELF_TASK_ID
#define OS_INVALID_TASK_ID
#define osExitTask()
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:1174
error_t socketBind(Socket *socket, const IpAddr *localIpAddr, uint16_t localPort)
Associate a local address with a socket.
Definition: socket.c:778
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:1592
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:967
Socket * socketOpen(uint_t type, uint_t protocol)
Create a socket (UDP or TCP)
Definition: socket.c:125
void socketClose(Socket *socket)
Close an existing socket.
Definition: socket.c:1517
error_t socketConnect(Socket *socket, const IpAddr *remoteIpAddr, uint16_t remotePort)
Establish a connection to a specified socket.
Definition: socket.c:811
@ SOCKET_IP_PROTO_UDP
Definition: socket.h:101
@ SOCKET_TYPE_DGRAM
Definition: socket.h:86
@ SOCKET_EVENT_RX_READY
Definition: socket.h:169
DHCPv6 relay agent context.
Definition: dhcpv6_relay.h:92
NetInterface * clientInterface[DHCPV6_RELAY_MAX_CLIENT_IF]
Client-facing interfaces.
Definition: dhcpv6_relay.h:94
NetInterface * serverInterface
Network-facing interface.
Definition: dhcpv6_relay.h:93
SocketEventDesc eventDesc[DHCPV6_RELAY_MAX_CLIENT_IF]
The events the application is interested in.
Definition: dhcpv6_relay.h:99
Socket * serverSocket
Socket that handles the network-facing interface.
Definition: dhcpv6_relay.h:97
Ipv6Addr serverAddress
Address to be used when relaying messages to the server.
Definition: dhcpv6_relay.h:96
OsTaskId taskId
Task identifier.
Definition: dhcpv6_relay.h:105
bool_t running
DHCPv6 relay agent is currently running or not?
Definition: dhcpv6_relay.h:100
OsTaskParameters taskParams
Task parameters.
Definition: dhcpv6_relay.h:104
uint8_t buffer[DHCPV6_MAX_MSG_SIZE]
Scratch buffer to store DHCPv6 messages.
Definition: dhcpv6_relay.h:106
Socket * clientSocket[DHCPV6_RELAY_MAX_CLIENT_IF]
Sockets that handle client-facing interfaces.
Definition: dhcpv6_relay.h:98
OsEvent ackEvent
Event object use to acknowledge user requests.
Definition: dhcpv6_relay.h:102
bool_t stopRequest
Stop request.
Definition: dhcpv6_relay.h:101
OsEvent event
Event object used to poll the sockets.
Definition: dhcpv6_relay.h:103
uint_t clientInterfaceCount
Number of client-facing interfaces.
Definition: dhcpv6_relay.h:95
DHCPv6 relay agent settings.
Definition: dhcpv6_relay.h:78
OsTaskParameters task
Task parameters.
Definition: dhcpv6_relay.h:79
NetInterface * clientInterface[DHCPV6_RELAY_MAX_CLIENT_IF]
Client-facing interfaces.
Definition: dhcpv6_relay.h:81
NetInterface * serverInterface
Network-facing interface.
Definition: dhcpv6_relay.h:80
Ipv6Addr serverAddress
Address to be used when relaying messages to the server.
Definition: dhcpv6_relay.h:83
uint_t clientInterfaceCount
Number of client-facing interfaces.
Definition: dhcpv6_relay.h:82
IP network address.
Definition: ip.h:79
uint_t eventMask
Requested events.
Definition: socket.h:400
Socket * socket
Handle to a socket to monitor.
Definition: socket.h:399
uint_t eventFlags
Returned events.
Definition: socket.h:401