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