david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[dhcpv6] Include RFC5970 client architecture options in DHCPv6 requests

RFC5970 defines DHCPv6 options 61 (client system architecture type)
and 62 (client network interface identifier), with contents equivalent
to DHCPv4 options 93 and 94 respectively.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2016-07-04 13:18:49 +01:00
parent 3d9f094022
commit fda8916c83
2 changed files with 52 additions and 17 deletions

View File

@ -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
*

View File

@ -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 );