summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/ipxe/dhcpv6.h33
-rw-r--r--src/net/udp/dhcpv6.c36
2 files changed, 52 insertions, 17 deletions
diff --git a/src/include/ipxe/dhcpv6.h b/src/include/ipxe/dhcpv6.h
index 9307b6cae..48cb76337 100644
--- a/src/include/ipxe/dhcpv6.h
+++ b/src/include/ipxe/dhcpv6.h
@@ -157,6 +157,12 @@ struct dhcpv6_user_class_option {
/** DHCPv6 bootfile parameters option */
#define DHCPV6_BOOTFILE_PARAM 60
+/** DHCPv6 client system architecture option */
+#define DHCPV6_CLIENT_ARCHITECTURE 61
+
+/** DHCPv6 client network interface identifier option */
+#define DHCPV6_CLIENT_NDI 62
+
/** DHCPv6 syslog server option
*
* This option code has not yet been assigned by IANA. Please update
@@ -164,6 +170,33 @@ struct dhcpv6_user_class_option {
*/
#define DHCPV6_LOG_SERVERS 0xffffffffUL
+/** Construct a DHCPv6 option code */
+#define DHCPV6_CODE( code ) \
+ ( ( (code) >> 8 ) & 0xff ), ( ( (code) >> 0 ) & 0xff )
+
+/** Construct a DHCPv6 option length */
+#define DHCPV6_LEN( len ) \
+ ( ( (len) >> 8 ) & 0xff ), ( ( (len) >> 0 ) & 0xff )
+
+/** Construct a DHCPv6 option from a list of bytes */
+#define DHCPV6_OPTION( ... ) \
+ DHCPV6_LEN ( VA_ARG_COUNT ( __VA_ARGS__ ) ), __VA_ARGS__
+
+/** Construct a DHCPv6 option from a list of characters */
+#define DHCPV6_STRING( ... ) DHCPV6_OPTION ( __VA_ARGS__ )
+
+/** Construct a byte-valued DHCPv6 option */
+#define DHCPV6_BYTE( value ) DHCPV6_OPTION ( value )
+
+/** Construct a word-valued DHCPv6 option */
+#define DHCPV6_WORD( value ) DHCPV6_OPTION ( ( ( (value) >> 8 ) & 0xff ), \
+ ( ( (value) >> 0 ) & 0xff ) )
+/** Construct a dword-valued DHCPv6 option */
+#define DHCPV6_DWORD( value ) DHCPV6_OPTION ( ( ( (value) >> 24 ) & 0xff ), \
+ ( ( (value) >> 16 ) & 0xff ), \
+ ( ( (value) >> 8 ) & 0xff ), \
+ ( ( (value) >> 0 ) & 0xff ) )
+
/**
* Any DHCPv6 option
*
diff --git a/src/net/udp/dhcpv6.c b/src/net/udp/dhcpv6.c
index a63543775..8b216e9a2 100644
--- a/src/net/udp/dhcpv6.c
+++ b/src/net/udp/dhcpv6.c
@@ -40,6 +40,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/crc32.h>
#include <ipxe/errortab.h>
#include <ipxe/ipv6.h>
+#include <ipxe/dhcp_arch.h>
#include <ipxe/dhcpv6.h>
/** @file
@@ -364,10 +365,17 @@ static int dhcpv6_register ( struct dhcpv6_option_list *options,
*
*/
-/** Options to be requested */
-static uint16_t dhcpv6_requested_options[] = {
- htons ( DHCPV6_DNS_SERVERS ), htons ( DHCPV6_DOMAIN_LIST ),
- htons ( DHCPV6_BOOTFILE_URL ), htons ( DHCPV6_BOOTFILE_PARAM ),
+/** Raw option data for options common to all DHCPv6 requests */
+static uint8_t dhcpv6_request_options_data[] = {
+ DHCPV6_CODE ( DHCPV6_OPTION_REQUEST ),
+ DHCPV6_OPTION ( DHCPV6_CODE ( DHCPV6_DNS_SERVERS ),
+ DHCPV6_CODE ( DHCPV6_DOMAIN_LIST ),
+ DHCPV6_CODE ( DHCPV6_BOOTFILE_URL ),
+ DHCPV6_CODE ( DHCPV6_BOOTFILE_PARAM ) ),
+ DHCPV6_CODE ( DHCPV6_CLIENT_ARCHITECTURE ),
+ DHCPV6_WORD ( DHCP_ARCH_CLIENT_ARCHITECTURE ),
+ DHCPV6_CODE ( DHCPV6_CLIENT_NDI ),
+ DHCPV6_OPTION ( DHCP_ARCH_CLIENT_NDI )
};
/**
@@ -565,15 +573,14 @@ static int dhcpv6_tx ( struct dhcpv6_session *dhcpv6 ) {
struct dhcpv6_duid_option *server_id;
struct dhcpv6_ia_na_option *ia_na;
struct dhcpv6_iaaddr_option *iaaddr;
- struct dhcpv6_option_request_option *option_request;
struct dhcpv6_user_class_option *user_class;
struct dhcpv6_elapsed_time_option *elapsed;
struct dhcpv6_header *dhcphdr;
struct io_buffer *iobuf;
+ void *options;
size_t client_id_len;
size_t server_id_len;
size_t ia_na_len;
- size_t option_request_len;
size_t user_class_string_len;
size_t user_class_len;
size_t elapsed_len;
@@ -592,16 +599,14 @@ static int dhcpv6_tx ( struct dhcpv6_session *dhcpv6 ) {
} else {
ia_na_len = 0;
}
- option_request_len = ( sizeof ( *option_request ) +
- sizeof ( dhcpv6_requested_options ) );
user_class_string_len = dhcpv6_user_class ( NULL, 0 );
user_class_len = ( sizeof ( *user_class ) +
sizeof ( user_class->user_class[0] ) +
user_class_string_len );
elapsed_len = sizeof ( *elapsed );
total_len = ( sizeof ( *dhcphdr ) + client_id_len + server_id_len +
- ia_na_len + option_request_len + user_class_len +
- elapsed_len );
+ ia_na_len + sizeof ( dhcpv6_request_options_data ) +
+ user_class_len + elapsed_len );
/* Allocate packet */
iobuf = xfer_alloc_iob ( &dhcpv6->xfer, total_len );
@@ -652,13 +657,10 @@ static int dhcpv6_tx ( struct dhcpv6_session *dhcpv6 ) {
}
}
- /* Construct option request */
- option_request = iob_put ( iobuf, option_request_len );
- option_request->header.code = htons ( DHCPV6_OPTION_REQUEST );
- option_request->header.len = htons ( option_request_len -
- sizeof ( option_request->header ));
- memcpy ( option_request->requested, dhcpv6_requested_options,
- sizeof ( dhcpv6_requested_options ) );
+ /* Construct fixed request options */
+ options = iob_put ( iobuf, sizeof ( dhcpv6_request_options_data ) );
+ memcpy ( options, dhcpv6_request_options_data,
+ sizeof ( dhcpv6_request_options_data ) );
/* Construct user class */
user_class = iob_put ( iobuf, user_class_len );