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-2023 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.3.2
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  //Save the network-facing interface
94  context->serverInterface = settings->serverInterface;
95  //Save the number of client-facing interfaces
96  context->clientInterfaceCount = settings->clientInterfaceCount;
97 
98  //Save all the client-facing interfaces
99  for(i = 0; i < context->clientInterfaceCount; i++)
100  {
101  context->clientInterface[i] = settings->clientInterface[i];
102  }
103 
104  //Save the address to be used when relaying client messages to the server
105  context->serverAddress = settings->serverAddress;
106 
107  //Join the All_DHCP_Relay_Agents_and_Servers multicast group
108  //for each client-facing interface
109  error = dhcpv6RelayJoinMulticastGroup(context);
110  //Any error to report?
111  if(error)
112  return error;
113 
114  //Start of exception handling block
115  do
116  {
117  //Open a UDP socket to handle the network-facing interface
119  //Failed to open socket?
120  if(!context->serverSocket)
121  {
122  //Report an error
123  error = ERROR_OPEN_FAILED;
124  //Stop processing
125  break;
126  }
127 
128  //Explicitly associate the socket with the relevant interface
129  error = socketBindToInterface(context->serverSocket, context->serverInterface);
130  //Unable to bind the socket to the desired interface?
131  if(error)
132  break;
133 
134  //Relay agents listen for DHCPv6 messages on UDP port 547
136  //Unable to bind the socket to the desired port?
137  if(error)
138  break;
139 
140  //Only accept datagrams with source port number 547
142  //Any error to report?
143  if(error)
144  break;
145 
146  //If the relay agent relays messages to the All_DHCP_Servers address
147  //or other multicast addresses, it sets the Hop Limit field to 32
148 
149  //Loop through the client-facing interfaces
150  for(i = 0; i < context->clientInterfaceCount; i++)
151  {
152  //Open a UDP socket to handle the current interface
154  //Failed to open socket?
155  if(!context->clientSocket[i])
156  {
157  //Report an error
158  error = ERROR_OPEN_FAILED;
159  //Stop processing
160  break;
161  }
162 
163  //Explicitly associate the socket with the relevant interface
164  error = socketBindToInterface(context->clientSocket[i], context->clientInterface[i]);
165  //Unable to bind the socket to the desired interface?
166  if(error)
167  break;
168 
169  //Relay agents listen for DHCPv6 messages on UDP port 547
170  error = socketBind(context->clientSocket[i], &IP_ADDR_ANY, DHCPV6_SERVER_PORT);
171  //Unable to bind the socket to the desired port?
172  if(error)
173  break;
174 
175  //Only accept datagrams with source port number 546
177  //Any error to report?
178  if(error)
179  break;
180  }
181 
182  //Propagate exception if necessary
183  if(error)
184  break;
185 
186  //Initialize event object
187  if(!osCreateEvent(&context->event))
188  {
189  //Failed to create event
190  error = ERROR_OUT_OF_RESOURCES;
191  //Stop processing
192  break;
193  }
194 
195  //Initialize ACK event object
196  if(!osCreateEvent(&context->ackEvent))
197  {
198  //Failed to create event
199  error = ERROR_OUT_OF_RESOURCES;
200  //Stop processing
201  break;
202  }
203 
204  //The DHCPv6 relay agent is now running
205  context->running = TRUE;
206 
207 #if (OS_STATIC_TASK_SUPPORT == ENABLED)
208  //Create a task using statically allocated memory
209  context->taskId = osCreateStaticTask("DHCPv6 Relay",
210  (OsTaskCode) dhcpv6RelayTask, context, &context->taskTcb,
212 #else
213  //Create a task
214  context->taskId = osCreateTask("DHCPv6 Relay",
217 #endif
218 
219  //Failed to create task?
220  if(context->taskId == OS_INVALID_TASK_ID)
221  error = ERROR_OUT_OF_RESOURCES;
222 
223  //End of exception handling block
224  } while(0);
225 
226  //Did we encounter an error?
227  if(error)
228  {
229  //Close the socket associated with the network-facing interface
230  socketClose(context->serverSocket);
231 
232  //Close the socket associated with each client-facing interface
233  for(i = 0; i < context->clientInterfaceCount; i++)
234  {
235  socketClose(context->clientSocket[i]);
236  }
237 
238  //Leave the All_DHCP_Relay_Agents_and_Servers multicast group
239  //for each client-facing interface
241 
242  //Delete event objects
243  osDeleteEvent(&context->event);
244  osDeleteEvent(&context->ackEvent);
245  }
246 
247  //Return status code
248  return error;
249 }
250 
251 
252 /**
253  * @brief Stop DHCPv6 relay agent
254  * @param[in] context Pointer to the DHCPv6 relay agent context
255  * @return Error code
256  **/
257 
259 {
260  uint_t i;
261 
262  //Make sure the DHCPv6 relay agent context is valid
263  if(context == NULL)
265 
266  //Debug message
267  TRACE_INFO("Stopping DHCPv6 relay agent...\r\n");
268 
269  //Check DHCPv6 relay agent state
270  if(!context->running)
271  return ERROR_WRONG_STATE;
272 
273  //Reset ACK event before sending the kill signal
274  osResetEvent(&context->ackEvent);
275  //Stop the DHCPv6 relay agent task
276  context->stopRequest = TRUE;
277  //Send a signal to the task in order to abort any blocking operation
278  osSetEvent(&context->event);
279 
280  //Wait for the process to terminate...
282 
283  //Leave the All_DHCP_Relay_Agents_and_Servers multicast group
284  //for each client-facing interface
286 
287  //Close the socket that carries traffic towards the DHCPv6 server
288  socketClose(context->serverSocket);
289 
290  //Properly dispose the sockets that carry traffic towards the DHCPv6 clients
291  for(i = 0; i < context->clientInterfaceCount; i++)
292  {
293  socketClose(context->clientSocket[i]);
294  }
295 
296  //Delete event objects
297  osDeleteEvent(&context->event);
298  osDeleteEvent(&context->ackEvent);
299 
300  //Successful processing
301  return NO_ERROR;
302 }
303 
304 
305 /**
306  * @brief Join All_DHCP_Relay_Agents_and_Servers multicast group
307  * @param[in] context Pointer to the DHCPv6 relay agent context
308  **/
309 
311 {
312  uint_t i;
313  uint_t j;
314 
315  //Initialize status code
316  error_t error = NO_ERROR;
317 
318  //Loop through the client-facing interfaces
319  for(i = 0; i < context->clientInterfaceCount; i++)
320  {
321  //Join the All_DHCP_Relay_Agents_and_Servers multicast
322  //group for each interface
323  error = ipv6JoinMulticastGroup(context->clientInterface[i],
325  //Unable to join the specified multicast group?
326  if(error)
327  break;
328  }
329 
330  //Did we encounter an error?
331  if(error)
332  {
333  //Clean up side effects before returning...
334  for(j = 0; j < i; j++)
335  {
336  //Leave the multicast group for each interface
339  }
340  }
341 
342  //Return status code
343  return error;
344 }
345 
346 
347 /**
348  * @brief Leave All_DHCP_Relay_Agents_and_Servers multicast group
349  * @param[in] context Pointer to the DHCPv6 relay agent context
350  **/
351 
353 {
354  uint_t i;
355 
356  //Loop through the client-facing interfaces
357  for(i = 0; i < context->clientInterfaceCount; i++)
358  {
359  //Leave the All_DHCP_Relay_Agents_and_Servers multicast
360  //group for each interface
363  }
364 
365  //Successsful processing
366  return NO_ERROR;
367 }
368 
369 
370 /**
371  * @brief DHCPv6 relay agent task
372  * @param[in] param Pointer to the DHCPv6 relay agent context
373  **/
374 
375 void dhcpv6RelayTask(void *param)
376 {
377  error_t error;
378  uint_t i;
379  Dhcpv6RelayContext *context;
380 
381  //Task prologue
382  osEnterTask();
383 
384  //Point to the DHCPv6 relay agent context
385  context = (Dhcpv6RelayContext *) param;
386 
387  //Specify the events the application is interested in for
388  //each client-facing sockets
389  for(i = 0; i < context->clientInterfaceCount; i++)
390  {
391  context->eventDesc[i].socket = context->clientSocket[i];
393  }
394 
395  //Specify the events the application is interested in for
396  //the network-facing socket
397  context->eventDesc[i].socket = context->serverSocket;
399 
400  //Main loop
401  while(1)
402  {
403  //Wait for incoming packets on network-facing or client-facing interfaces
404  error = socketPoll(context->eventDesc, context->clientInterfaceCount + 1,
405  &context->event, INFINITE_DELAY);
406 
407  //Stop DHCPv6 relay agent?
408  if(context->stopRequest)
409  {
410  //The DHCPv6 relay agent is about to stop
411  context->stopRequest = FALSE;
412  context->running = FALSE;
413  //Acknowledge the reception of the user request
414  osSetEvent(&context->ackEvent);
415  //Task epilogue
416  osExitTask();
417  //Kill ourselves
419  }
420 
421  //Verify status code
422  if(error == NO_ERROR || error == ERROR_WAIT_CANCELED)
423  {
424  //Check the state of each client-facing socket
425  for(i = 0; i < context->clientInterfaceCount; i++)
426  {
427  //Relay client messages if applicable
428  if(context->eventDesc[i].eventFlags & SOCKET_EVENT_RX_READY)
429  dhcpv6ForwardClientMessage(context, i);
430  }
431 
432  //Check the state of the network-facing socket
433  if(context->eventDesc[i].eventFlags & SOCKET_EVENT_RX_READY)
434  {
435  //Forward Relay-Reply messages from the network
437  }
438  }
439  }
440 }
441 
442 
443 /**
444  * @brief Forward client message
445  * @param[in] context Pointer to the DHCPv6 relay agent context
446  * @param[in] index Index identifying the interface on which the message was received
447  * @return Error code
448  **/
449 
451 {
452  error_t error;
453  uint32_t interfaceId;
454  size_t inputMessageLen;
455  size_t outputMessageLen;
456  Dhcpv6RelayMessage *inputMessage;
457  Dhcpv6RelayMessage *outputMessage;
458  Dhcpv6Option *option;
459  IpAddr ipAddr;
460 
461  //Point to the buffer where to store the incoming DHCPv6 message
462  inputMessage = (Dhcpv6RelayMessage *) (context->buffer + DHCPV6_RELAY_FORW_OVERHEAD);
463  //Message that will be forwarded by the DHCPv6 relay agent
464  outputMessage = (Dhcpv6RelayMessage *) context->buffer;
465 
466  //Read incoming message
467  error = socketReceiveFrom(context->clientSocket[index], &ipAddr, NULL, inputMessage,
468  DHCPV6_MAX_MSG_SIZE - DHCPV6_RELAY_FORW_OVERHEAD, &inputMessageLen, 0);
469  //Any error to report?
470  if(error)
471  return error;
472 
473  //Debug message
474  TRACE_INFO("\r\nDHCPv6 message received on client-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
475  context->clientInterface[index]->name, inputMessageLen);
476 
477  //Dump the contents of the message for debugging purpose
478  dhcpv6DumpMessage(inputMessage, inputMessageLen);
479 
480  //The source address must be a valid IPv6 address
481  if(ipAddr.length != sizeof(Ipv6Addr))
482  return ERROR_INVALID_ADDRESS;
483  //Check the length of the DHCPv6 message
484  if(inputMessageLen < sizeof(Dhcpv6Message))
485  return ERROR_INVALID_MESSAGE;
486 
487  //When the relay agent receives a valid message to be relayed,
488  //it constructs a new Relay-Forward message
489  outputMessage->msgType = DHCPV6_MSG_TYPE_RELAY_FORW;
490 
491  //Inspect the message type
492  switch(inputMessage->msgType)
493  {
494  //Message received from a client?
503  //If the relay agent received the message to be relayed from a client
504  //the hop-count in the Relay-Forward message is set to 0
505  outputMessage->hopCount = 0;
506  //Continue processing
507  break;
508 
509  //Message received from another relay agent?
511  //If the message received by the relay agent is a Relay-Forward message
512  //and the hop-count in the message is greater than or equal to
513  //HOP_COUNT_LIMIT, the relay agent discards the received message
514  if(inputMessage->hopCount >= DHCPV6_HOP_COUNT_LIMIT)
515  return ERROR_INVALID_MESSAGE;
516  //Set the hop-count field to the value of the hop-count field in
517  //the received message incremented by 1
518  outputMessage->hopCount = inputMessage->hopCount + 1;
519  //Continue processing
520  break;
521 
522  //Message received from a server?
523  default:
524  //Discard ADVERTISE, REPLY, RECONFIGURE and RELAY-REPL messages
525  return ERROR_INVALID_MESSAGE;
526  }
527 
528  //Set the link-address field to the unspecified address
529  outputMessage->linkAddress = IPV6_UNSPECIFIED_ADDR;
530  //Copy the source address from the header of the IP datagram in
531  //which the message was received to the peer-address field
532  outputMessage->peerAddress = ipAddr.ipv6Addr;
533  //Size of the Relay-Forward message
534  outputMessageLen = sizeof(Dhcpv6RelayMessage);
535 
536  //Get the interface identifier
537  interfaceId = context->clientInterface[index]->id;
538  //Convert the 32-bit integer to network byte order
540 
541  //If the relay agent cannot use the address in the link-address field
542  //to identify the interface through which the response to the client
543  //will be relayed, the relay agent must include an Interface ID option
544  dhcpv6AddOption(outputMessage, &outputMessageLen,
546 
547  //Copy the received DHCPv6 message into a Relay Message option
548  option = dhcpv6AddOption(outputMessage, &outputMessageLen,
549  DHCPV6_OPT_RELAY_MSG, NULL, 0);
550 
551  //Set the appropriate length of the option
552  option->length = htons(inputMessageLen);
553  //Adjust the length of the Relay-Forward message
554  outputMessageLen += inputMessageLen;
555 
556  //Debug message
557  TRACE_INFO("Forwarding DHCPv6 message on network-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
558  context->serverInterface->name, outputMessageLen);
559 
560  //Dump the contents of the message for debugging purpose
561  dhcpv6DumpMessage(outputMessage, outputMessageLen);
562 
563  //Destination address to be used when relaying the client message
564  ipAddr.length = sizeof(Ipv6Addr);
565  ipAddr.ipv6Addr = context->serverAddress;
566 
567  //Relay the client message to the server
568  return socketSendTo(context->serverSocket, &ipAddr,
569  DHCPV6_SERVER_PORT, outputMessage, outputMessageLen, NULL, 0);
570 }
571 
572 
573 /**
574  * @brief Forward Relay-Reply message
575  * @param[in] context Pointer to the DHCPv6 relay agent context
576  * @return Error code
577  **/
578 
580 {
581  error_t error;
582  uint_t i;
583  uint32_t interfaceId;
584  size_t inputMessageLen;
585  size_t outputMessageLen;
586  Dhcpv6RelayMessage *inputMessage;
587  Dhcpv6Message *outputMessage;
588  Dhcpv6Option *option;
589  IpAddr ipAddr;
590  uint16_t port;
591 
592  //Point to the buffer where to store the incoming DHCPv6 message
593  inputMessage = (Dhcpv6RelayMessage *) context->buffer;
594 
595  //Read incoming message
596  error = socketReceiveFrom(context->serverSocket, &ipAddr, &port,
597  inputMessage, DHCPV6_MAX_MSG_SIZE, &inputMessageLen, 0);
598  //Any error to report?
599  if(error)
600  return error;
601 
602  //Debug message
603  TRACE_INFO("\r\nDHCPv6 message received on network-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
604  context->serverInterface->name, inputMessageLen);
605 
606  //Dump the contents of the message for debugging purpose
607  dhcpv6DumpMessage(inputMessage, inputMessageLen);
608 
609  //Check the length of the DHCPv6 message
610  if(inputMessageLen < sizeof(Dhcpv6RelayMessage))
611  return ERROR_INVALID_MESSAGE;
612 
613  //Inspect the message type and only forward Relay-Reply messages.
614  //Other DHCPv6 message types must be silently discarded
615  if(inputMessage->msgType != DHCPV6_MSG_TYPE_RELAY_REPL)
616  return ERROR_INVALID_MESSAGE;
617 
618  //Get the length of the Options field
619  inputMessageLen -= sizeof(Dhcpv6Message);
620 
621  //Check whether an Interface ID option is included in the Relay-Reply
622  option = dhcpv6GetOption(inputMessage->options, inputMessageLen, DHCPV6_OPT_INTERFACE_ID);
623  //Failed to retrieve specified option?
624  if(option == NULL || ntohs(option->length) != sizeof(interfaceId))
625  return ERROR_INVALID_MESSAGE;
626 
627  //Read the Interface ID option contents
628  osMemcpy(&interfaceId, option->value, sizeof(interfaceId));
629  //Convert the 32-bit integer from network byte order
631 
632  //The Relay-Reply message must include a Relay Message option
633  option = dhcpv6GetOption(inputMessage->options, inputMessageLen, DHCPV6_OPT_RELAY_MSG);
634  //Failed to retrieve specified option?
635  if(option == NULL || ntohs(option->length) < sizeof(Dhcpv6Message))
636  return ERROR_INVALID_MESSAGE;
637 
638  //Extract the message from the Relay Message option
639  outputMessage = (Dhcpv6Message *) option->value;
640  //Save the length of the message
641  outputMessageLen = ntohs(option->length);
642 
643  //Loop through client-facing interfaces
644  for(i = 0; i < context->clientInterfaceCount; i++)
645  {
646  //Check whether the current interface matches the Interface ID option
647  if(context->clientInterface[i]->id == interfaceId)
648  {
649  //Debug message
650  TRACE_INFO("Forwarding DHCPv6 message on client-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
651  context->clientInterface[i]->name, outputMessageLen);
652 
653  //Dump the contents of the message for debugging purpose
654  dhcpv6DumpMessage(outputMessage, outputMessageLen);
655 
656  //Copy the peer-address into the destination IP address
657  ipAddr.length = sizeof(Ipv6Addr);
658  ipAddr.ipv6Addr = inputMessage->peerAddress;
659 
660  //Select the relevant port number to use
661  if(outputMessage->msgType == DHCPV6_MSG_TYPE_RELAY_REPL)
662  {
664  }
665  else
666  {
668  }
669 
670  //Relay the DHCPv6 message to the client on the link
671  //identified by the Interface ID option
672  return socketSendTo(context->clientSocket[i], &ipAddr,
673  port, outputMessage, outputMessageLen, NULL, 0);
674  }
675  }
676 
677  //Unknown interface identifier...
678  return ERROR_INVALID_OPTION;
679 }
680 
681 #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:579
error_t dhcpv6RelayLeaveMulticastGroup(Dhcpv6RelayContext *context)
Leave All_DHCP_Relay_Agents_and_Servers multicast group.
Definition: dhcpv6_relay.c:352
error_t dhcpv6RelayStop(Dhcpv6RelayContext *context)
Stop DHCPv6 relay agent.
Definition: dhcpv6_relay.c:258
error_t dhcpv6RelayJoinMulticastGroup(Dhcpv6RelayContext *context)
Join All_DHCP_Relay_Agents_and_Servers multicast group.
Definition: dhcpv6_relay.c:310
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:450
void dhcpv6RelayTask(void *param)
DHCPv6 relay agent task.
Definition: dhcpv6_relay.c:375
DHCPv6 relay agent (Dynamic Host Configuration Protocol for IPv6)
#define DHCPV6_RELAY_FORW_OVERHEAD
Definition: dhcpv6_relay.h:65
#define DHCPV6_RELAY_STACK_SIZE
Definition: dhcpv6_relay.h:47
#define DHCPV6_RELAY_MAX_CLIENT_IF
Definition: dhcpv6_relay.h:59
#define DHCPV6_RELAY_PRIORITY
Definition: dhcpv6_relay.h:54
uint16_t port
Definition: dns_common.h:265
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:103
error_t ipv6LeaveMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Leave an IPv6 multicast group.
Definition: ipv6.c:2137
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:2027
Ipv6Addr
Definition: ipv6.h:249
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:120
Eui64 interfaceId
Definition: ipv6cp.h:69
TCP/IP stack core.
#define socketBindToInterface
Definition: net_legacy.h:193
#define osMemset(p, value, length)
Definition: os_port.h:137
#define osMemcpy(dest, src, length)
Definition: os_port.h:143
#define TRUE
Definition: os_port.h:52
#define FALSE
Definition: os_port.h:48
#define INFINITE_DELAY
Definition: os_port.h:77
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.
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.
OsTaskId osCreateStaticTask(const char_t *name, OsTaskCode taskCode, void *param, OsTaskTcb *tcb, OsStackType *stack, size_t stackSize, int_t priority)
Create a task with statically allocated memory.
OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *param, size_t stackSize, int_t priority)
Create a task.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
void(* OsTaskCode)(void *param)
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:1173
error_t socketBind(Socket *socket, const IpAddr *localIpAddr, uint16_t localPort)
Associate a local address with a socket.
Definition: socket.c:777
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:1591
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:966
Socket * socketOpen(uint_t type, uint_t protocol)
Create a socket (UDP or TCP)
Definition: socket.c:124
void socketClose(Socket *socket)
Close an existing socket.
Definition: socket.c:1516
error_t socketConnect(Socket *socket, const IpAddr *remoteIpAddr, uint16_t remotePort)
Establish a connection to a specified socket.
Definition: socket.c:810
@ 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:91
NetInterface * clientInterface[DHCPV6_RELAY_MAX_CLIENT_IF]
Client-facing interfaces.
Definition: dhcpv6_relay.h:93
NetInterface * serverInterface
Network-facing interface.
Definition: dhcpv6_relay.h:92
SocketEventDesc eventDesc[DHCPV6_RELAY_MAX_CLIENT_IF]
The events the application is interested in.
Definition: dhcpv6_relay.h:98
Socket * serverSocket
Socket that handles the network-facing interface.
Definition: dhcpv6_relay.h:96
Ipv6Addr serverAddress
Address to be used when relaying messages to the server.
Definition: dhcpv6_relay.h:95
OsTaskId taskId
Task identifier.
Definition: dhcpv6_relay.h:103
bool_t running
DHCPv6 relay agent is currently running or not?
Definition: dhcpv6_relay.h:99
uint8_t buffer[DHCPV6_MAX_MSG_SIZE]
Scratch buffer to store DHCPv6 messages.
Definition: dhcpv6_relay.h:108
Socket * clientSocket[DHCPV6_RELAY_MAX_CLIENT_IF]
Sockets that handle client-facing interfaces.
Definition: dhcpv6_relay.h:97
OsTaskTcb taskTcb
Task control block.
Definition: dhcpv6_relay.h:105
OsEvent ackEvent
Event object use to acknowledge user requests.
Definition: dhcpv6_relay.h:101
bool_t stopRequest
Stop request.
Definition: dhcpv6_relay.h:100
OsEvent event
Event object used to poll the sockets.
Definition: dhcpv6_relay.h:102
OsStackType taskStack[DHCPV6_RELAY_STACK_SIZE]
Task stack.
Definition: dhcpv6_relay.h:106
uint_t clientInterfaceCount
Number of client-facing interfaces.
Definition: dhcpv6_relay.h:94
DHCPv6 relay agent settings.
Definition: dhcpv6_relay.h:78
NetInterface * clientInterface[DHCPV6_RELAY_MAX_CLIENT_IF]
Client-facing interfaces.
Definition: dhcpv6_relay.h:80
NetInterface * serverInterface
Network-facing interface.
Definition: dhcpv6_relay.h:79
Ipv6Addr serverAddress
Address to be used when relaying messages to the server.
Definition: dhcpv6_relay.h:82
uint_t clientInterfaceCount
Number of client-facing interfaces.
Definition: dhcpv6_relay.h:81
IP network address.
Definition: ip.h:72
uint_t eventMask
Requested events.
Definition: socket.h:397
Socket * socket
Handle to a socket to monitor.
Definition: socket.h:396
uint_t eventFlags
Returned events.
Definition: socket.h:398