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-2020 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.8
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  osMemset(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  //Make sure the DHCPv6 relay agent context is valid
252  if(context == NULL)
254 
255  //Debug message
256  TRACE_INFO("Stopping DHCPv6 relay agent...\r\n");
257 
258  //Check DHCPv6 relay agent state
259  if(!context->running)
260  return ERROR_WRONG_STATE;
261 
262  //Reset ACK event before sending the kill signal
263  osResetEvent(&context->ackEvent);
264  //Stop the DHCPv6 relay agent task
265  context->stopRequest = TRUE;
266  //Send a signal to the task in order to abort any blocking operation
267  osSetEvent(&context->event);
268 
269  //Wait for the process to terminate...
271 
272  //Leave the All_DHCP_Relay_Agents_and_Servers multicast group
273  //for each client-facing interface
275 
276  //Close the socket that carries traffic towards the DHCPv6 server
277  socketClose(context->serverSocket);
278 
279  //Properly dispose the sockets that carry traffic towards the DHCPv6 clients
280  for(i = 0; i < context->clientInterfaceCount; i++)
281  socketClose(context->clientSocket[i]);
282 
283  //Delete event objects
284  osDeleteEvent(&context->event);
285  osDeleteEvent(&context->ackEvent);
286 
287  //Successful processing
288  return NO_ERROR;
289 }
290 
291 
292 /**
293  * @brief Join All_DHCP_Relay_Agents_and_Servers multicast group
294  * @param[in] context Pointer to the DHCPv6 relay agent context
295  **/
296 
298 {
299  uint_t i;
300  uint_t j;
301 
302  //Initialize status code
303  error_t error = NO_ERROR;
304 
305  //Loop through the client-facing interfaces
306  for(i = 0; i < context->clientInterfaceCount; i++)
307  {
308  //Join the All_DHCP_Relay_Agents_and_Servers multicast
309  //group for each interface
310  error = ipv6JoinMulticastGroup(context->clientInterface[i],
312  //Unable to join the specified multicast group?
313  if(error)
314  break;
315  }
316 
317  //Did we encounter an error?
318  if(error)
319  {
320  //Clean up side effects before returning...
321  for(j = 0; j < i; j++)
322  {
323  //Leave the multicast group for each interface
326  }
327  }
328 
329  //Return status code
330  return error;
331 }
332 
333 
334 /**
335  * @brief Leave All_DHCP_Relay_Agents_and_Servers multicast group
336  * @param[in] context Pointer to the DHCPv6 relay agent context
337  **/
338 
340 {
341  uint_t i;
342 
343  //Loop through the client-facing interfaces
344  for(i = 0; i < context->clientInterfaceCount; i++)
345  {
346  //Leave the All_DHCP_Relay_Agents_and_Servers multicast
347  //group for each interface
350  }
351 
352  //Successsful processing
353  return NO_ERROR;
354 }
355 
356 
357 /**
358  * @brief DHCPv6 relay agent task
359  * @param[in] param Pointer to the DHCPv6 relay agent context
360  **/
361 
362 void dhcpv6RelayTask(void *param)
363 {
364  error_t error;
365  uint_t i;
366  Dhcpv6RelayContext *context;
367 
368  //Task prologue
369  osEnterTask();
370 
371  //Point to the DHCPv6 relay agent context
372  context = (Dhcpv6RelayContext *) param;
373 
374  //Specify the events the application is interested in for
375  //each client-facing sockets
376  for(i = 0; i < context->clientInterfaceCount; i++)
377  {
378  context->eventDesc[i].socket = context->clientSocket[i];
380  }
381 
382  //Specify the events the application is interested in for
383  //the network-facing socket
384  context->eventDesc[i].socket = context->serverSocket;
386 
387  //Main loop
388  while(1)
389  {
390  //Wait for incoming packets on network-facing or client-facing interfaces
391  error = socketPoll(context->eventDesc, context->clientInterfaceCount + 1,
392  &context->event, INFINITE_DELAY);
393 
394  //Stop DHCPv6 relay agent?
395  if(context->stopRequest)
396  {
397  //The DHCPv6 relay agent is about to stop
398  context->stopRequest = FALSE;
399  context->running = FALSE;
400  //Acknowledge the reception of the user request
401  osSetEvent(&context->ackEvent);
402  //Kill ourselves
403  osDeleteTask(NULL);
404  }
405 
406  //Verify status code
407  if(!error)
408  {
409  //Check the state of each client-facing socket
410  for(i = 0; i < context->clientInterfaceCount; i++)
411  {
412  //Relay client messages if applicable
413  if(context->eventDesc[i].eventFlags & SOCKET_EVENT_RX_READY)
414  dhcpv6ForwardClientMessage(context, i);
415  }
416 
417  //Check the state of the network-facing socket
418  if(context->eventDesc[i].eventFlags & SOCKET_EVENT_RX_READY)
419  {
420  //Forward Relay-Reply messages from the network
422  }
423  }
424  }
425 }
426 
427 
428 /**
429  * @brief Forward client message
430  * @param[in] context Pointer to the DHCPv6 relay agent context
431  * @param[in] index Index identifying the interface on which the message was received
432  * @return Error code
433  **/
434 
436 {
437  error_t error;
438  uint32_t interfaceId;
439  size_t inputMessageLen;
440  size_t outputMessageLen;
441  Dhcpv6RelayMessage *inputMessage;
442  Dhcpv6RelayMessage *outputMessage;
443  Dhcpv6Option *option;
444  IpAddr ipAddr;
445 
446  //Point to the buffer where to store the incoming DHCPv6 message
447  inputMessage = (Dhcpv6RelayMessage *) (context->buffer + DHCPV6_RELAY_FORW_OVERHEAD);
448  //Message that will be forwarded by the DHCPv6 relay agent
449  outputMessage = (Dhcpv6RelayMessage *) context->buffer;
450 
451  //Read incoming message
452  error = socketReceiveFrom(context->clientSocket[index], &ipAddr, NULL, inputMessage,
453  DHCPV6_MAX_MSG_SIZE - DHCPV6_RELAY_FORW_OVERHEAD, &inputMessageLen, 0);
454  //Any error to report?
455  if(error)
456  return error;
457 
458  //Debug message
459  TRACE_INFO("\r\nDHCPv6 message received on client-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
460  context->clientInterface[index]->name, inputMessageLen);
461 
462  //Dump the contents of the message for debugging purpose
463  dhcpv6DumpMessage(inputMessage, inputMessageLen);
464 
465  //The source address must be a valid IPv6 address
466  if(ipAddr.length != sizeof(Ipv6Addr))
467  return ERROR_INVALID_ADDRESS;
468  //Check the length of the DHCPv6 message
469  if(inputMessageLen < sizeof(Dhcpv6Message))
470  return ERROR_INVALID_MESSAGE;
471 
472  //When the relay agent receives a valid message to be relayed,
473  //it constructs a new Relay-Forward message
474  outputMessage->msgType = DHCPV6_MSG_TYPE_RELAY_FORW;
475 
476  //Inspect the message type
477  switch(inputMessage->msgType)
478  {
479  //Message received from a client?
488  //If the relay agent received the message to be relayed from a client
489  //the hop-count in the Relay-Forward message is set to 0
490  outputMessage->hopCount = 0;
491  //Continue processing
492  break;
493 
494  //Message received from another relay agent?
496  //If the message received by the relay agent is a Relay-Forward message
497  //and the hop-count in the message is greater than or equal to 32, the
498  //relay agent discards the received message
499  if(inputMessage->hopCount >= DHCPV6_HOP_COUNT_LIMIT)
500  return ERROR_INVALID_MESSAGE;
501  //Set the hop-count field to the value of the hop-count field in
502  //the received message incremented by 1
503  outputMessage->hopCount = inputMessage->hopCount + 1;
504  //Continue processing
505  break;
506 
507  //Message received from a server?
508  default:
509  //Discard ADVERTISE, REPLY, RECONFIGURE and RELAY-REPL messages
510  return ERROR_INVALID_MESSAGE;
511  }
512 
513  //Set the link-address field to the unspecified address
514  outputMessage->linkAddress = IPV6_UNSPECIFIED_ADDR;
515  //Copy the source address from the header of the IP datagram in
516  //which the message was received to the peer-address field
517  outputMessage->peerAddress = ipAddr.ipv6Addr;
518  //Size of the Relay-Forward message
519  outputMessageLen = sizeof(Dhcpv6RelayMessage);
520 
521  //Get the interface identifier
522  interfaceId = context->clientInterface[index]->id;
523  //Convert the 32-bit integer to network byte order
525 
526  //If the relay agent cannot use the address in the link-address field
527  //to identify the interface through which the response to the client
528  //will be relayed, the relay agent must include an Interface ID option
529  dhcpv6AddOption(outputMessage, &outputMessageLen,
531 
532  //Copy the received DHCPv6 message into a Relay Message option
533  option = dhcpv6AddOption(outputMessage, &outputMessageLen,
534  DHCPV6_OPTION_RELAY_MSG, NULL, 0);
535 
536  //Set the appropriate length of the option
537  option->length = htons(inputMessageLen);
538  //Adjust the length of the Relay-Forward message
539  outputMessageLen += inputMessageLen;
540 
541  //Debug message
542  TRACE_INFO("Forwarding DHCPv6 message on network-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
543  context->serverInterface->name, outputMessageLen);
544 
545  //Dump the contents of the message for debugging purpose
546  dhcpv6DumpMessage(outputMessage, outputMessageLen);
547 
548  //Destination address to be used when relaying the client message
549  ipAddr.length = sizeof(Ipv6Addr);
550  ipAddr.ipv6Addr = context->serverAddress;
551 
552  //Relay the client message to the server
553  return socketSendTo(context->serverSocket, &ipAddr,
554  DHCPV6_SERVER_PORT, outputMessage, outputMessageLen, NULL, 0);
555 }
556 
557 
558 /**
559  * @brief Forward Relay-Reply message
560  * @param[in] context Pointer to the DHCPv6 relay agent context
561  * @return Error code
562  **/
563 
565 {
566  error_t error;
567  uint_t i;
568  uint32_t interfaceId;
569  size_t inputMessageLen;
570  size_t outputMessageLen;
571  Dhcpv6RelayMessage *inputMessage;
572  Dhcpv6Message *outputMessage;
573  Dhcpv6Option *option;
574  IpAddr ipAddr;
575  uint16_t port;
576 
577  //Point to the buffer where to store the incoming DHCPv6 message
578  inputMessage = (Dhcpv6RelayMessage *) context->buffer;
579 
580  //Read incoming message
581  error = socketReceiveFrom(context->serverSocket, &ipAddr, &port,
582  inputMessage, DHCPV6_MAX_MSG_SIZE, &inputMessageLen, 0);
583  //Any error to report?
584  if(error)
585  return error;
586 
587  //Debug message
588  TRACE_INFO("\r\nDHCPv6 message received on network-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
589  context->serverInterface->name, inputMessageLen);
590 
591  //Dump the contents of the message for debugging purpose
592  dhcpv6DumpMessage(inputMessage, inputMessageLen);
593 
594  //Check the length of the DHCPv6 message
595  if(inputMessageLen < sizeof(Dhcpv6RelayMessage))
596  return ERROR_INVALID_MESSAGE;
597 
598  //Inspect the message type and only forward Relay-Reply messages.
599  //Other DHCPv6 message types must be silently discarded
600  if(inputMessage->msgType != DHCPV6_MSG_TYPE_RELAY_REPL)
601  return ERROR_INVALID_MESSAGE;
602 
603  //Get the length of the Options field
604  inputMessageLen -= sizeof(Dhcpv6Message);
605 
606  //Check whether an Interface ID option is included in the Relay-Reply
607  option = dhcpv6GetOption(inputMessage->options, inputMessageLen, DHCPV6_OPTION_INTERFACE_ID);
608  //Failed to retrieve specified option?
609  if(option == NULL || ntohs(option->length) != sizeof(interfaceId))
610  return ERROR_INVALID_MESSAGE;
611 
612  //Read the Interface ID option contents
613  osMemcpy(&interfaceId, option->value, sizeof(interfaceId));
614  //Convert the 32-bit integer from network byte order
616 
617  //The Relay-Reply message must include a Relay Message option
618  option = dhcpv6GetOption(inputMessage->options, inputMessageLen, DHCPV6_OPTION_RELAY_MSG);
619  //Failed to retrieve specified option?
620  if(option == NULL || ntohs(option->length) < sizeof(Dhcpv6Message))
621  return ERROR_INVALID_MESSAGE;
622 
623  //Extract the message from the Relay Message option
624  outputMessage = (Dhcpv6Message *) option->value;
625  //Save the length of the message
626  outputMessageLen = ntohs(option->length);
627 
628  //Loop through client-facing interfaces
629  for(i = 0; i < context->clientInterfaceCount; i++)
630  {
631  //Check whether the current interface matches the Interface ID option
632  if(context->clientInterface[i]->id == interfaceId)
633  {
634  //Debug message
635  TRACE_INFO("Forwarding DHCPv6 message on client-facing interface %s (%" PRIuSIZE " bytes)...\r\n",
636  context->clientInterface[i]->name, outputMessageLen);
637 
638  //Dump the contents of the message for debugging purpose
639  dhcpv6DumpMessage(outputMessage, outputMessageLen);
640 
641  //Copy the peer-address into the destination IP address
642  ipAddr.length = sizeof(Ipv6Addr);
643  ipAddr.ipv6Addr = inputMessage->peerAddress;
644 
645  //Select the relevant port number to use
646  if(outputMessage->msgType == DHCPV6_MSG_TYPE_RELAY_REPL)
648  else
650 
651  //Relay the DHCPv6 message to the client on the link
652  //identified by the Interface ID option
653  return socketSendTo(context->clientSocket[i], &ipAddr,
654  port, outputMessage, outputMessageLen, NULL, 0);
655  }
656  }
657 
658  //Unknown interface identifier...
659  return ERROR_INVALID_OPTION;
660 }
661 
662 #endif
bool_t running
DHCPv6 relay agent is currently running or not?
Definition: dhcpv6_relay.h:99
#define htons(value)
Definition: cpu_endian.h:413
error_t socketBind(Socket *socket, const IpAddr *localIpAddr, uint16_t localPort)
Associate a local address with a socket.
Definition: socket.c:616
DHCPv6 relay agent (Dynamic Host Configuration Protocol for IPv6)
IP network address.
Definition: ip.h:78
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:564
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:1259
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:362
error_t dhcpv6RelayStop(Dhcpv6RelayContext *context)
Stop DHCPv6 relay agent.
Definition: dhcpv6_relay.c:247
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:121
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
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:339
#define DHCPV6_RELAY_PRIORITY
Definition: dhcpv6_relay.h:54
__start_packed struct @27 Dhcpv6RelayMessage
DHCPv6 relay agent message.
error_t dhcpv6RelayStart(Dhcpv6RelayContext *context, const Dhcpv6RelaySettings *settings)
Start DHCPv6 relay agent.
Definition: dhcpv6_relay.c:58
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
Invalid parameter.
Definition: error.h:47
#define htonl(value)
Definition: cpu_endian.h:414
#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.
#define osMemcpy(dest, src, length)
Definition: os_port.h:134
OsEvent event
Event object used to poll the sockets.
Definition: dhcpv6_relay.h:102
error_t
Error codes.
Definition: error.h:42
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:297
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:972
Ipv6Addr serverAddress
Address to be used when relaying messages to the server.
Definition: dhcpv6_relay.h:82
error_t socketConnect(Socket *socket, const IpAddr *remoteIpAddr, uint16_t remotePort)
Establish a connection to a specified socket.
Definition: socket.c:642
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:2059
error_t ipv6JoinMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Join an IPv6 multicast group.
Definition: ipv6.c:1949
Eui64 interfaceId
Definition: ipv6cp.h:69
#define TRACE_INFO(...)
Definition: debug.h:95
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:119
#define osEnterTask()
uint_t eventFlags
Returned events.
Definition: socket.h:352
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:1319
#define DHCPV6_RELAY_MAX_CLIENT_IF
Definition: dhcpv6_relay.h:59
#define socketBindToInterface
Definition: net_legacy.h:264
DHCPv6 relay agent settings.
Definition: dhcpv6_relay.h:77
uint16_t port
Definition: dns_common.h:223
#define ntohs(value)
Definition: cpu_endian.h:421
__start_packed struct @26 Dhcpv6Message
DHCPv6 message.
#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
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:435
Dhcpv6Option * dhcpv6AddOption(void *message, size_t *messageLen, uint16_t optionCode, const void *optionValue, size_t optionLen)
Add an option to a DHCPv6 message.
bool_t osCreateEvent(OsEvent *event)
Create an event object.
__start_packed struct @77 Ipv6Addr
IPv6 network address.
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:796
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
__start_packed struct @28 Dhcpv6Option
DHCPv6 option.
#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:350
#define PRIuSIZE
Definition: compiler_port.h:78
unsigned int uint_t
Definition: compiler_port.h:45
#define osMemset(p, value, length)
Definition: os_port.h:128
TCP/IP stack core.
bool_t stopRequest
Stop request.
Definition: dhcpv6_relay.h:100
#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:422
uint_t eventMask
Requested events.
Definition: socket.h:351
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