diff --git a/RELNOTES b/RELNOTES index 466a5dbf..6a67baa0 100644 --- a/RELNOTES +++ b/RELNOTES @@ -49,6 +49,8 @@ work on other platforms. Please report any problems and suggested fixes to - Added client support for setting interface MTU and metric, thanks to Roy "UberLord" Marples . +- Added client -D option to specify DUID type to send. + Changes since 4.1.0 (bug fixes) - Remove infinite loop in token_print_indent_concat(). diff --git a/client/dhc6.c b/client/dhc6.c index b9f79af7..dc48c465 100644 --- a/client/dhc6.c +++ b/client/dhc6.c @@ -143,15 +143,18 @@ form_duid(struct data_string *duid, const char *file, int line) (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf))) log_fatal("Impossible hardware address length at %s:%d.", MDL); + if (duid_type == 0) + duid_type = stateless ? DUID_LL : DUID_LLT; + /* * 2 bytes for the 'duid type' field. * 2 bytes for the 'htype' field. - * (not stateless) 4 bytes for the 'current time'. + * (DUID_LLT) 4 bytes for the 'current time'. * enough bytes for the hardware address (note that hw_address has * the 'htype' on byte zero). */ len = 4 + (ip->hw_address.hlen - 1); - if (!stateless) + if (duid_type == DUID_LLT) len += 4; if (!buffer_allocate(&duid->buffer, len, MDL)) log_fatal("no memory for default DUID!"); @@ -159,7 +162,7 @@ form_duid(struct data_string *duid, const char *file, int line) duid->len = len; /* Basic Link Local Address type of DUID. */ - if (!stateless) { + if (duid_type == DUID_LLT) { putUShort(duid->buffer->data, DUID_LLT); putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]); putULong(duid->buffer->data + 4, cur_time - DUID_TIME_EPOCH); diff --git a/client/dhclient.8 b/client/dhclient.8 index 4437b9b4..cdd6c9ba 100644 --- a/client/dhclient.8 +++ b/client/dhclient.8 @@ -1,4 +1,4 @@ -.\" $Id: dhclient.8,v 1.30 2008/11/20 14:55:14 jreed Exp $ +.\" $Id: dhclient.8,v 1.31 2009/05/27 20:11:38 pselkirk Exp $ .\" .\" Copyright (c) 2004,2007-2008 by Internet Systems Consortium, Inc. ("ISC") .\" Copyright (c) 1996-2003 by Internet Software Consortium @@ -56,6 +56,10 @@ dhclient - Dynamic Host Configuration Protocol Client ] ] [ +.B -D +.I LL|LLT +] +[ .B -p .I port ] @@ -138,10 +142,14 @@ important details about the network to which it is attached, such as the location of a default router, the location of a name server, and so on. .PP -If given the -4 command line argument (default), dhclient will use the +If given the +.B -4 +command line argument (default), dhclient will use the DHCPv4 protocol to obtain an IPv4 address and configuration parameters. .PP -If given the -6 command line argument, dhclient will use the DHCPv6 +If given the +.B -6 +command line argument, dhclient will use the DHCPv6 protocol to obtain whatever IPv6 addresses are available along with configuration parameters. But with .B -S @@ -161,7 +169,17 @@ address query, restores it. Note it is not recommended to mix queries of different types together, or even to share the lease file between them. .PP -If given the --version command line argument, dhclient will print its +By default, DHCPv6 dhclient creates an identifier based on the +link-layer address (DUID-LL) if it is running in stateless mode (with +-S, not requesting an address), or it creates an identifier based on +the link-layer address plus a timestamp (DUID-LLT) if it is running in +stateful mode (without -S, requesting an address). +.B -D +overrides this default, with a value of either "LL" or "LLT". +.PP +If given the +.B --version +command line argument, dhclient will print its version number and exit. .PP On startup, dhclient reads the diff --git a/client/dhclient.c b/client/dhclient.c index dcd294a8..580c7126 100644 --- a/client/dhclient.c +++ b/client/dhclient.c @@ -57,6 +57,7 @@ struct in_addr inaddr_any; struct sockaddr_in sockaddr_broadcast; struct in_addr giaddr; struct data_string default_duid; +int duid_type = 0; /* ASSERT_STATE() does nothing now; it used to be assert (state_is == state_shouldbe). */ @@ -268,6 +269,21 @@ main(int argc, char **argv) { wanted_ia_na = 0; } wanted_ia_pd++; + } else if (!strcmp(argv[i], "-D")) { + if (local_family_set && (local_family == AF_INET)) { + usage(); + } + local_family_set = 1; + local_family = AF_INET6; + if (++i == argc) + usage(); + if (!strcasecmp(argv[i], "LL")) { + duid_type = DUID_LL; + } else if (!strcasecmp(argv[i], "LLT")) { + duid_type = DUID_LLT; + } else { + usage(); + } #endif /* DHCPv6 */ } else if (!strcmp(argv[i], "-v")) { quiet = 0; @@ -651,7 +667,7 @@ static void usage() log_error("Usage: dhclient %s %s", #ifdef DHCPv6 - "[-4|-6] [-SNTP1dvrx] [-nw] [-p ]", + "[-4|-6] [-SNTP1dvrx] [-nw] [-p ] [-D LL|LLT]", #else /* DHCPv6 */ "[-1dvrx] [-nw] [-p ]", #endif /* DHCPv6 */ diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 22db8aea..b0c4969d 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -2471,6 +2471,7 @@ extern const char *path_dhclient_pid; extern char *path_dhclient_script; extern int interfaces_requested; extern struct data_string default_duid; +extern int duid_type; extern struct client_config top_level_config;