2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-31 06:15:55 +00:00

merge 17500

This commit is contained in:
Francis Dupont
2008-05-23 13:56:07 +00:00
parent 3dbe22465b
commit 420d8b3f0c
10 changed files with 1368 additions and 535 deletions

View File

@@ -83,6 +83,9 @@ work on other platforms. Please report any problems and suggested fixes to
on the DHCPv6 ORO. This resolves a bug where VSIO options were placed
in IA_NA encapsulated options fields.
- Integrated client with stateless, temporary address and prefix delegation
support.
Changes since 4.0.0 (new features)
- Added DHCPv6 rapid commit support.

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
.\" $Id: dhclient.8,v 1.27 2008/01/24 02:43:04 each Exp $
.\" $Id: dhclient.8,v 1.28 2008/05/23 13:56:07 fdupont Exp $
.\"
.\" Copyright (c) 2004,2007-2008 by Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (c) 1996-2003 by Internet Software Consortium
@@ -35,6 +35,27 @@ dhclient - Dynamic Host Configuration Protocol Client
.B -6
]
[
.B -S
]
[
.B -N
[
.B -N...
]
]
[
.B -T
[
.B -T...
]
]
[
.B -P
[
.B -P...
]
]
[
.B -p
.I port
]
@@ -53,8 +74,7 @@ dhclient - Dynamic Host Configuration Protocol Client
]
[
.B -r
]
[
|
.B -x
]
[
@@ -123,7 +143,23 @@ DHCPv4 protocol to obtain an IPv4 address and configuration parameters.
.PP
If given the -6 command line argument, dhclient will use the DHCPv6
protocol to obtain whatever IPv6 addresses are available along with
configuration parameters. Information-request is not yet supported.
configuration parameters. But with
.B -S
it uses Information-request to get only (i.e., without address)
stateless configuration parameters.
.PP
The default DHCPv6 behavior is modified too with
.B -T
which asks for IPv6 temporary addresses, one set per
.B -T
flag.
.B -P
enables the IPv6 prefix delegation.
As temporary addresses or prefix delegation disables the normal
address query,
.B -N
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
version number and exit.
@@ -198,6 +234,7 @@ the server transmit these messages to some other address. This can
be specified with the
.B -s
flag, followed by the IP address or domain name of the destination.
This feature is not supported by DHCPv6.
.PP
For testing purposes, the giaddr field of all packets that the client
sends can be set using the

View File

@@ -76,11 +76,14 @@ int onetry=0;
int quiet = 1;
int nowait = 0;
int stateless = 0;
int wanted_ia_na = -1; /* the absolute value is the real one. */
int wanted_ia_ta = 0;
int wanted_ia_pd = 0;
char *mockup_relay = NULL;
void run_stateless(int exit_mode);
static void usage PROTO ((void));
static void usage(void);
static isc_result_t write_duid(struct data_string *duid);
@@ -91,7 +94,7 @@ main(int argc, char **argv) {
struct interface_info *ip;
struct client_state *client;
unsigned seed;
char *server = (char *)0;
char *server = NULL;
isc_result_t status;
int exit_mode = 0;
int release_mode = 0;
@@ -226,13 +229,46 @@ main(int argc, char **argv) {
tmp->next = client_env;
client_env = tmp;
client_env_count++;
#ifdef DHCPv6
} else if (!strcmp(argv[i], "-S")) {
if (local_family_set && (local_family == AF_INET)) {
usage();
}
local_family_set = 1;
local_family = AF_INET6;
wanted_ia_na = 0;
stateless = 1;
} else if (!strcmp(argv[i], "-N")) {
if (local_family_set && (local_family == AF_INET)) {
usage();
}
local_family_set = 1;
local_family = AF_INET6;
if (wanted_ia_na < 0) {
wanted_ia_na = 0;
}
wanted_ia_na++;
} else if (!strcmp(argv[i], "-T")) {
if (local_family_set && (local_family == AF_INET)) {
usage();
}
local_family_set = 1;
local_family = AF_INET6;
if (wanted_ia_na < 0) {
wanted_ia_na = 0;
}
wanted_ia_ta++;
} else if (!strcmp(argv[i], "-P")) {
if (local_family_set && (local_family == AF_INET)) {
usage();
}
local_family_set = 1;
local_family = AF_INET6;
if (wanted_ia_na < 0) {
wanted_ia_na = 0;
}
wanted_ia_pd++;
#endif /* DHCPv6 */
} else if (!strcmp(argv[i], "-v")) {
quiet = 0;
} else if (!strcmp(argv[i], "--version")) {
@@ -243,7 +279,8 @@ main(int argc, char **argv) {
} else if (interfaces_requested < 0) {
usage();
} else {
struct interface_info *tmp = (struct interface_info *)0;
struct interface_info *tmp = NULL;
status = interface_allocate(&tmp, MDL);
if (status != ISC_R_SUCCESS)
log_fatal("Can't record interface %s:%s",
@@ -263,6 +300,15 @@ main(int argc, char **argv) {
}
}
if (wanted_ia_na < 0) {
wanted_ia_na = 1;
}
/* Support only one (requested) interface for Prefix Delegation. */
if (wanted_ia_pd && (interfaces_requested != 1)) {
usage();
}
if (!no_dhclient_conf && (s = getenv("PATH_DHCLIENT_CONF"))) {
path_dhclient_conf = s;
}
@@ -382,7 +428,9 @@ main(int argc, char **argv) {
/* Stateless special case. */
if (stateless) {
if (release_mode || (interfaces_requested != 1)) {
if (release_mode || (wanted_ia_na > 0) ||
wanted_ia_ta || wanted_ia_pd ||
(interfaces_requested != 1)) {
usage();
}
run_stateless(exit_mode);
@@ -404,17 +452,22 @@ main(int argc, char **argv) {
/* XXX */
/* config_counter(&snd_counter, &rcv_counter); */
/* If no broadcast interfaces were discovered, call the script
and tell it so. */
/*
* If no broadcast interfaces were discovered, call the script
* and tell it so.
*/
if (!interfaces) {
/* Call dhclient-script with the NBI flag, in case somebody
cares. */
script_init ((struct client_state *)0, "NBI",
(struct string_list *)0);
script_go ((struct client_state *)0);
/*
* Call dhclient-script with the NBI flag,
* in case somebody cares.
*/
script_init(NULL, "NBI", NULL);
script_go(NULL);
/* If we haven't been asked to persist, waiting for new
interfaces, then just exit. */
/*
* If we haven't been asked to persist, waiting for new
* interfaces, then just exit.
*/
if (!persist) {
/* Nothing more to do. */
log_info("No broadcast interfaces found - exiting.");
@@ -423,8 +476,10 @@ main(int argc, char **argv) {
} else if (!release_mode && !exit_mode) {
/* Call the script with the list of interfaces. */
for (ip = interfaces; ip; ip = ip->next) {
/* If interfaces were specified, don't configure
interfaces that weren't specified! */
/*
* If interfaces were specified, don't configure
* interfaces that weren't specified!
*/
if ((interfaces_requested > 0) &&
((ip->flags & (INTERFACE_REQUESTED |
INTERFACE_AUTOMATIC)) !=
@@ -543,7 +598,7 @@ main(int argc, char **argv) {
/* Start up a listener for the object management API protocol. */
if (top_level_config.omapi_port != -1) {
listener = (omapi_object_t *)0;
listener = NULL;
result = omapi_generic_new(&listener, MDL);
if (result != ISC_R_SUCCESS)
log_fatal("Can't allocate new generic object: %s\n",
@@ -596,7 +651,7 @@ static void usage ()
log_error("Usage: dhclient %s %s",
#ifdef DHCPv6
"[-4|-6] [-S1dvrx] [-nw] [-p <port>]",
"[-4|-6] [-SNTP1dvrx] [-nw] [-p <port>]",
#else /* DHCPv6 */
"[-1dvrx] [-nw] [-p <port>]",
#endif /* DHCPv6 */
@@ -608,6 +663,7 @@ static void usage ()
void run_stateless(int exit_mode)
{
#ifdef DHCPv6
struct client_state *client;
omapi_object_t *listener;
isc_result_t result;
@@ -647,7 +703,7 @@ void run_stateless(int exit_mode)
/* Start up a listener for the object management API protocol. */
if (top_level_config.omapi_port != -1) {
listener = (omapi_object_t *)0;
listener = NULL;
result = omapi_generic_new(&listener, MDL);
if (result != ISC_R_SUCCESS)
log_fatal("Can't allocate new generic object: %s\n",
@@ -685,6 +741,7 @@ void run_stateless(int exit_mode)
dispatch();
/*NOTREACHED*/
#endif /* DHCPv6 */
return;
}
@@ -766,20 +823,24 @@ void state_reboot (cpp)
/* We are in the rebooting state. */
client -> state = S_REBOOTING;
/* make_request doesn't initialize xid because it normally comes
from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
so pick an xid now. */
/*
* make_request doesn't initialize xid because it normally comes
* from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
* so pick an xid now.
*/
client -> xid = random ();
/* Make a DHCPREQUEST packet, and set appropriate per-interface
flags. */
/*
* Make a DHCPREQUEST packet, and set
* appropriate per-interface flags.
*/
make_request (client, client -> active);
client -> destination = iaddr_broadcast;
client -> first_sending = cur_time;
client -> interval = client -> config -> initial_interval;
/* Zap the medium list... */
client -> medium = (struct string_list *)0;
client -> medium = NULL;
/* Send out the first DHCPREQUEST packet. */
send_request (client);
@@ -809,8 +870,10 @@ void state_init (cpp)
send_discover (client);
}
/* state_selecting is called when one or more DHCPOFFER packets have been
received and a configurable period of time has passed. */
/*
* state_selecting is called when one or more DHCPOFFER packets have been
* received and a configurable period of time has passed.
*/
void state_selecting (cpp)
void *cpp;
@@ -821,31 +884,39 @@ void state_selecting (cpp)
ASSERT_STATE(state, S_SELECTING);
/* Cancel state_selecting and send_discover timeouts, since either
one could have got us here. */
/*
* Cancel state_selecting and send_discover timeouts, since either
* one could have got us here.
*/
cancel_timeout (state_selecting, client);
cancel_timeout (send_discover, client);
/* We have received one or more DHCPOFFER packets. Currently,
the only criterion by which we judge leases is whether or
not we get a response when we arp for them. */
picked = (struct client_lease *)0;
/*
* We have received one or more DHCPOFFER packets. Currently,
* the only criterion by which we judge leases is whether or
* not we get a response when we arp for them.
*/
picked = NULL;
for (lp = client -> offered_leases; lp; lp = next) {
next = lp -> next;
/* Check to see if we got an ARPREPLY for the address
in this particular lease. */
/*
* Check to see if we got an ARPREPLY for the address
* in this particular lease.
*/
if (!picked) {
picked = lp;
picked -> next = (struct client_lease *)0;
picked -> next = NULL;
} else {
destroy_client_lease (lp);
}
}
client -> offered_leases = (struct client_lease *)0;
client -> offered_leases = NULL;
/* If we just tossed all the leases we were offered, go back
to square one. */
/*
* If we just tossed all the leases we were offered, go back
* to square one.
*/
if (!picked) {
client -> state = S_INIT;
state_init (client);

View File

@@ -242,6 +242,12 @@ if [ ${reason} = PREINIT6 ] ; then
exit_with_hooks 0
fi
if [ x${old_ip6_prefix} != x ] || [ x${new_ip6_prefix} != x ] ; then
echo Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix}
exit_with_hooks 0
fi
if [ ${reason} = BOUND6 ] ; then
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
exit_with_hooks 2;

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# $Id: freebsd,v 1.21 2008/01/16 23:02:10 dhankins Exp $
# $Id: freebsd,v 1.22 2008/05/23 13:56:07 fdupont Exp $
#
# $FreeBSD$
@@ -306,6 +306,12 @@ if [ ${reason} = PREINIT6 ] ; then
exit_with_hooks 0
fi
if [ x${old_ip6_prefix} != x ] || [ x${new_ip6_prefix} != x ] ; then
echo Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix}
exit_with_hooks 0
fi
if [ ${reason} = BOUND6 ] ; then
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
exit_with_hooks 2;
@@ -332,13 +338,11 @@ if [ ${reason} = RENEW6 ] || [ ${reason} = REBIND6 ] ; then
fi
if [ ${reason} = DEPREF6 ] ; then
if [ x${new_ip6_prefixlen} = x ] ; then
if [ x${new_ip6_address} = x ] ; then
exit_with_hooks 2;
fi
# XXX:
# There doesn't appear to be a way to update an addr to indicate
# preference.
ifconfig ${interface} inet6 ${new_ip6_address} deprecated
exit_with_hooks 0
fi

View File

@@ -243,6 +243,12 @@ if [ ${reason} = PREINIT6 ] ; then
exit_with_hooks 0
fi
if [ x${old_ip6_prefix} != x ] || [ x${new_ip6_prefix} != x ] ; then
echo Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix}
exit_with_hooks 0
fi
if [ ${reason} = BOUND6 ] ; then
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
exit_with_hooks 2;
@@ -274,10 +280,8 @@ if [ ${reason} = DEPREF6 ] ; then
exit_with_hooks 2;
fi
# There doesn't appear to be a way to update an addr to indicate
# preference.
# ${ip} -f inet6 addr ??? ${new_ip6_address}/${new_ip6_prefixlen} \
# dev ${interface} scope global deprecated?
${ip} -f inet6 addr change ${new_ip6_address}/${new_ip6_prefixlen} \
dev ${interface} scope global preferred_lft 0
exit_with_hooks 0
fi

View File

@@ -242,6 +242,12 @@ if [ ${reason} = PREINIT6 ] ; then
exit_with_hooks 0
fi
if [ x${old_ip6_prefix} != x ] || [ x${new_ip6_prefix} != x ] ; then
echo Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix}
exit_with_hooks 0
fi
if [ ${reason} = BOUND6 ] ; then
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
exit_with_hooks 2;

View File

@@ -242,6 +242,12 @@ if [ ${reason} = PREINIT6 ] ; then
exit_with_hooks 0
fi
if [ x${old_ip6_prefix} != x ] || [ x${new_ip6_prefix} != x ] ; then
echo Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix}
exit_with_hooks 0
fi
if [ ${reason} = BOUND6 ] ; then
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
exit_with_hooks 2;

View File

@@ -2441,6 +2441,10 @@ char *piaddrcidr(const struct iaddr *, unsigned int);
/* dhclient.c */
extern int nowait;
extern int wanted_ia_na;
extern int wanted_ia_ta;
extern int wanted_ia_pd;
extern const char *path_dhclient_conf;
extern const char *path_dhclient_db;
extern const char *path_dhclient_pid;