2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-30 13:57:50 +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 on the DHCPv6 ORO. This resolves a bug where VSIO options were placed
in IA_NA encapsulated options fields. in IA_NA encapsulated options fields.
- Integrated client with stateless, temporary address and prefix delegation
support.
Changes since 4.0.0 (new features) Changes since 4.0.0 (new features)
- Added DHCPv6 rapid commit support. - 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) 2004,2007-2008 by Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (c) 1996-2003 by Internet Software Consortium .\" Copyright (c) 1996-2003 by Internet Software Consortium
@@ -35,6 +35,27 @@ dhclient - Dynamic Host Configuration Protocol Client
.B -6 .B -6
] ]
[ [
.B -S
]
[
.B -N
[
.B -N...
]
]
[
.B -T
[
.B -T...
]
]
[
.B -P
[
.B -P...
]
]
[
.B -p .B -p
.I port .I port
] ]
@@ -53,8 +74,7 @@ dhclient - Dynamic Host Configuration Protocol Client
] ]
[ [
.B -r .B -r
] |
[
.B -x .B -x
] ]
[ [
@@ -123,7 +143,23 @@ DHCPv4 protocol to obtain an IPv4 address and configuration parameters.
.PP .PP
If given the -6 command line argument, dhclient will use the DHCPv6 If given the -6 command line argument, dhclient will use the DHCPv6
protocol to obtain whatever IPv6 addresses are available along with 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 .PP
If given the --version command line argument, dhclient will print its If given the --version command line argument, dhclient will print its
version number and exit. version number and exit.
@@ -198,6 +234,7 @@ the server transmit these messages to some other address. This can
be specified with the be specified with the
.B -s .B -s
flag, followed by the IP address or domain name of the destination. flag, followed by the IP address or domain name of the destination.
This feature is not supported by DHCPv6.
.PP .PP
For testing purposes, the giaddr field of all packets that the client For testing purposes, the giaddr field of all packets that the client
sends can be set using the sends can be set using the

View File

@@ -44,7 +44,7 @@ TIME max_lease_time = 86400; /* 24 hours... */
const char *path_dhclient_conf = _PATH_DHCLIENT_CONF; const char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
const char *path_dhclient_db = NULL; const char *path_dhclient_db = NULL;
const char *path_dhclient_pid = NULL; const char *path_dhclient_pid = NULL;
static char path_dhclient_script_array [] = _PATH_DHCLIENT_SCRIPT; static char path_dhclient_script_array[] = _PATH_DHCLIENT_SCRIPT;
char *path_dhclient_script = path_dhclient_script_array; char *path_dhclient_script = path_dhclient_script_array;
int dhcp_max_agent_option_packet_length = 0; int dhcp_max_agent_option_packet_length = 0;
@@ -67,20 +67,23 @@ static char arr [] = "All rights reserved.";
static char message [] = "Internet Systems Consortium DHCP Client"; static char message [] = "Internet Systems Consortium DHCP Client";
static char url [] = "For info, please visit http://www.isc.org/sw/dhcp/"; static char url [] = "For info, please visit http://www.isc.org/sw/dhcp/";
u_int16_t local_port=0; u_int16_t local_port = 0;
u_int16_t remote_port=0; u_int16_t remote_port = 0;
int no_daemon=0; int no_daemon = 0;
struct string_list *client_env=NULL; struct string_list *client_env = NULL;
int client_env_count=0; int client_env_count = 0;
int onetry=0; int onetry = 0;
int quiet=1; int quiet = 1;
int nowait=0; int nowait = 0;
int stateless=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; char *mockup_relay = NULL;
void run_stateless(int exit_mode); 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); static isc_result_t write_duid(struct data_string *duid);
@@ -91,7 +94,7 @@ main(int argc, char **argv) {
struct interface_info *ip; struct interface_info *ip;
struct client_state *client; struct client_state *client;
unsigned seed; unsigned seed;
char *server = (char *)0; char *server = NULL;
isc_result_t status; isc_result_t status;
int exit_mode = 0; int exit_mode = 0;
int release_mode = 0; int release_mode = 0;
@@ -124,21 +127,21 @@ main(int argc, char **argv) {
else if (fd != -1) else if (fd != -1)
close(fd); close(fd);
openlog ("dhclient", LOG_NDELAY, LOG_DAEMON); openlog("dhclient", LOG_NDELAY, LOG_DAEMON);
#if !(defined (DEBUG) || defined (__CYGWIN32__)) #if !(defined(DEBUG) || defined(__CYGWIN32__))
setlogmask (LOG_UPTO (LOG_INFO)); setlogmask(LOG_UPTO(LOG_INFO));
#endif #endif
/* Set up the OMAPI. */ /* Set up the OMAPI. */
status = omapi_init (); status = omapi_init();
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
log_fatal ("Can't initialize OMAPI: %s", log_fatal("Can't initialize OMAPI: %s",
isc_result_totext (status)); isc_result_totext(status));
/* Set up the OMAPI wrappers for various server database internal /* Set up the OMAPI wrappers for various server database internal
objects. */ objects. */
dhcp_common_objects_setup (); dhcp_common_objects_setup();
dhcp_interface_discovery_hook = dhclient_interface_discovery_hook; dhcp_interface_discovery_hook = dhclient_interface_discovery_hook;
dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook; dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook;
@@ -162,117 +165,160 @@ main(int argc, char **argv) {
local_family_set = 1; local_family_set = 1;
local_family = AF_INET6; local_family = AF_INET6;
#endif /* DHCPv6 */ #endif /* DHCPv6 */
} else if (!strcmp (argv [i], "-x")) { /* eXit, no release */ } else if (!strcmp(argv[i], "-x")) { /* eXit, no release */
release_mode = 0; release_mode = 0;
no_daemon = 0; no_daemon = 0;
exit_mode = 1; exit_mode = 1;
} else if (!strcmp (argv [i], "-p")) { } else if (!strcmp(argv[i], "-p")) {
if (++i == argc) if (++i == argc)
usage (); usage();
local_port = htons (atoi (argv [i])); local_port = htons(atoi(argv[i]));
log_debug ("binding to user-specified port %d", log_debug("binding to user-specified port %d",
ntohs (local_port)); ntohs(local_port));
} else if (!strcmp (argv [i], "-d")) { } else if (!strcmp(argv[i], "-d")) {
no_daemon = 1; no_daemon = 1;
quiet = 0; quiet = 0;
} else if (!strcmp (argv [i], "-pf")) { } else if (!strcmp(argv[i], "-pf")) {
if (++i == argc) if (++i == argc)
usage (); usage();
path_dhclient_pid = argv [i]; path_dhclient_pid = argv[i];
no_dhclient_pid = 1; no_dhclient_pid = 1;
} else if (!strcmp (argv [i], "-cf")) { } else if (!strcmp(argv[i], "-cf")) {
if (++i == argc) if (++i == argc)
usage (); usage();
path_dhclient_conf = argv [i]; path_dhclient_conf = argv[i];
no_dhclient_conf = 1; no_dhclient_conf = 1;
} else if (!strcmp (argv [i], "-lf")) { } else if (!strcmp(argv[i], "-lf")) {
if (++i == argc) if (++i == argc)
usage (); usage();
path_dhclient_db = argv [i]; path_dhclient_db = argv[i];
no_dhclient_db = 1; no_dhclient_db = 1;
} else if (!strcmp (argv [i], "-sf")) { } else if (!strcmp(argv[i], "-sf")) {
if (++i == argc) if (++i == argc)
usage (); usage();
path_dhclient_script = argv [i]; path_dhclient_script = argv[i];
no_dhclient_script = 1; no_dhclient_script = 1;
} else if (!strcmp (argv [i], "-1")) { } else if (!strcmp(argv[i], "-1")) {
onetry = 1; onetry = 1;
} else if (!strcmp (argv [i], "-q")) { } else if (!strcmp(argv[i], "-q")) {
quiet = 1; quiet = 1;
} else if (!strcmp (argv [i], "-s")) { } else if (!strcmp(argv[i], "-s")) {
if (++i == argc) if (++i == argc)
usage (); usage();
server = argv [i]; server = argv[i];
} else if (!strcmp (argv [i], "-g")) { } else if (!strcmp(argv[i], "-g")) {
if (++i == argc) if (++i == argc)
usage (); usage();
mockup_relay = argv [i]; mockup_relay = argv[i];
} else if (!strcmp (argv [i], "-nw")) { } else if (!strcmp(argv[i], "-nw")) {
nowait = 1; nowait = 1;
} else if (!strcmp (argv [i], "-n")) { } else if (!strcmp(argv[i], "-n")) {
/* do not start up any interfaces */ /* do not start up any interfaces */
interfaces_requested = -1; interfaces_requested = -1;
} else if (!strcmp (argv [i], "-w")) { } else if (!strcmp(argv[i], "-w")) {
/* do not exit if there are no broadcast interfaces. */ /* do not exit if there are no broadcast interfaces. */
persist = 1; persist = 1;
} else if (!strcmp (argv [i], "-e")) { } else if (!strcmp(argv[i], "-e")) {
struct string_list *tmp; struct string_list *tmp;
if (++i == argc) if (++i == argc)
usage (); usage();
tmp = dmalloc (strlen (argv [i]) + sizeof *tmp, MDL); tmp = dmalloc(strlen(argv[i]) + sizeof *tmp, MDL);
if (!tmp) if (!tmp)
log_fatal ("No memory for %s", argv [i]); log_fatal("No memory for %s", argv[i]);
strcpy (tmp -> string, argv [i]); strcpy(tmp->string, argv[i]);
tmp -> next = client_env; tmp->next = client_env;
client_env = tmp; client_env = tmp;
client_env_count++; client_env_count++;
#ifdef DHCPv6
} else if (!strcmp(argv[i], "-S")) { } else if (!strcmp(argv[i], "-S")) {
if (local_family_set && (local_family == AF_INET)) { if (local_family_set && (local_family == AF_INET)) {
usage (); usage();
} }
local_family_set = 1; local_family_set = 1;
local_family = AF_INET6; local_family = AF_INET6;
wanted_ia_na = 0;
stateless = 1; 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")) { } else if (!strcmp(argv[i], "-v")) {
quiet = 0; quiet = 0;
} else if (!strcmp (argv [i], "--version")) { } else if (!strcmp(argv[i], "--version")) {
log_info ("isc-dhclient-%s", PACKAGE_VERSION); log_info("isc-dhclient-%s", PACKAGE_VERSION);
exit (0); exit(0);
} else if (argv [i][0] == '-') { } else if (argv[i][0] == '-') {
usage (); usage();
} else if (interfaces_requested < 0) { } else if (interfaces_requested < 0) {
usage (); usage();
} else { } else {
struct interface_info *tmp = (struct interface_info *)0; struct interface_info *tmp = NULL;
status = interface_allocate (&tmp, MDL);
status = interface_allocate(&tmp, MDL);
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
log_fatal ("Can't record interface %s:%s", log_fatal("Can't record interface %s:%s",
argv [i], isc_result_totext (status)); argv[i], isc_result_totext(status));
if (strlen(argv[i]) >= sizeof(tmp->name)) if (strlen(argv[i]) >= sizeof(tmp->name))
log_fatal("%s: interface name too long (is %ld)", log_fatal("%s: interface name too long (is %ld)",
argv [i], (long)strlen(argv[i])); argv[i], (long)strlen(argv[i]));
strcpy(tmp->name, argv[i]); strcpy(tmp->name, argv[i]);
if (interfaces) { if (interfaces) {
interface_reference (&tmp -> next, interface_reference(&tmp->next,
interfaces, MDL); interfaces, MDL);
interface_dereference (&interfaces, MDL); interface_dereference(&interfaces, MDL);
} }
interface_reference (&interfaces, tmp, MDL); interface_reference(&interfaces, tmp, MDL);
tmp -> flags = INTERFACE_REQUESTED; tmp->flags = INTERFACE_REQUESTED;
interfaces_requested++; interfaces_requested++;
} }
} }
if (!no_dhclient_conf && (s = getenv ("PATH_DHCLIENT_CONF"))) { 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; path_dhclient_conf = s;
} }
if (!no_dhclient_db && (s = getenv ("PATH_DHCLIENT_DB"))) { if (!no_dhclient_db && (s = getenv("PATH_DHCLIENT_DB"))) {
path_dhclient_db = s; path_dhclient_db = s;
} }
if (!no_dhclient_pid && (s = getenv ("PATH_DHCLIENT_PID"))) { if (!no_dhclient_pid && (s = getenv("PATH_DHCLIENT_PID"))) {
path_dhclient_pid = s; path_dhclient_pid = s;
} }
if (!no_dhclient_script && (s = getenv ("PATH_DHCLIENT_SCRIPT"))) { if (!no_dhclient_script && (s = getenv("PATH_DHCLIENT_SCRIPT"))) {
path_dhclient_script = s; path_dhclient_script = s;
} }
@@ -297,7 +343,7 @@ main(int argc, char **argv) {
char *path = dmalloc(PATH_MAX, MDL); char *path = dmalloc(PATH_MAX, MDL);
if (path == NULL) if (path == NULL)
log_fatal("No memory for filename\n"); log_fatal("No memory for filename\n");
path_dhclient_db = realpath(path_dhclient_db, path); path_dhclient_db = realpath(path_dhclient_db, path);
if (path_dhclient_db == NULL) if (path_dhclient_db == NULL)
log_fatal("%s: %s", path, strerror(errno)); log_fatal("%s: %s", path, strerror(errno));
} }
@@ -306,7 +352,7 @@ main(int argc, char **argv) {
char *path = dmalloc(PATH_MAX, MDL); char *path = dmalloc(PATH_MAX, MDL);
if (path == NULL) if (path == NULL)
log_fatal("No memory for filename\n"); log_fatal("No memory for filename\n");
path_dhclient_script = realpath(path_dhclient_script, path); path_dhclient_script = realpath(path_dhclient_script, path);
if (path_dhclient_script == NULL) if (path_dhclient_script == NULL)
log_fatal("%s: %s", path, strerror(errno)); log_fatal("%s: %s", path, strerror(errno));
} }
@@ -332,11 +378,11 @@ main(int argc, char **argv) {
} }
if (!quiet) { if (!quiet) {
log_info ("%s %s", message, PACKAGE_VERSION); log_info("%s %s", message, PACKAGE_VERSION);
log_info (copyright); log_info(copyright);
log_info (arr); log_info(arr);
log_info (url); log_info(url);
log_info ("%s", ""); log_info("%s", "");
} else { } else {
log_perror = 0; log_perror = 0;
quiet_interface_discovery = 1; quiet_interface_discovery = 1;
@@ -345,14 +391,14 @@ main(int argc, char **argv) {
/* If we're given a relay agent address to insert, for testing /* If we're given a relay agent address to insert, for testing
purposes, figure out what it is. */ purposes, figure out what it is. */
if (mockup_relay) { if (mockup_relay) {
if (!inet_aton (mockup_relay, &giaddr)) { if (!inet_aton(mockup_relay, &giaddr)) {
struct hostent *he; struct hostent *he;
he = gethostbyname (mockup_relay); he = gethostbyname(mockup_relay);
if (he) { if (he) {
memcpy (&giaddr, he -> h_addr_list [0], memcpy(&giaddr, he->h_addr_list[0],
sizeof giaddr); sizeof giaddr);
} else { } else {
log_fatal ("%s: no such host", mockup_relay); log_fatal("%s: no such host", mockup_relay);
} }
} }
} }
@@ -363,13 +409,13 @@ main(int argc, char **argv) {
sockaddr_broadcast.sin_family = AF_INET; sockaddr_broadcast.sin_family = AF_INET;
sockaddr_broadcast.sin_port = remote_port; sockaddr_broadcast.sin_port = remote_port;
if (server) { if (server) {
if (!inet_aton (server, &sockaddr_broadcast.sin_addr)) { if (!inet_aton(server, &sockaddr_broadcast.sin_addr)) {
struct hostent *he; struct hostent *he;
he = gethostbyname (server); he = gethostbyname(server);
if (he) { if (he) {
memcpy (&sockaddr_broadcast.sin_addr, memcpy(&sockaddr_broadcast.sin_addr,
he -> h_addr_list [0], he->h_addr_list[0],
sizeof sockaddr_broadcast.sin_addr); sizeof sockaddr_broadcast.sin_addr);
} else } else
sockaddr_broadcast.sin_addr.s_addr = sockaddr_broadcast.sin_addr.s_addr =
INADDR_BROADCAST; INADDR_BROADCAST;
@@ -382,52 +428,61 @@ main(int argc, char **argv) {
/* Stateless special case. */ /* Stateless special case. */
if (stateless) { if (stateless) {
if (release_mode || (interfaces_requested != 1)) { if (release_mode || (wanted_ia_na > 0) ||
usage (); wanted_ia_ta || wanted_ia_pd ||
(interfaces_requested != 1)) {
usage();
} }
run_stateless (exit_mode); run_stateless(exit_mode);
return 0; return 0;
} }
/* Discover all the network interfaces. */ /* Discover all the network interfaces. */
discover_interfaces (DISCOVER_UNCONFIGURED); discover_interfaces(DISCOVER_UNCONFIGURED);
/* Parse the dhclient.conf file. */ /* Parse the dhclient.conf file. */
read_client_conf (); read_client_conf();
/* Parse the lease database. */ /* Parse the lease database. */
read_client_leases (); read_client_leases();
/* Rewrite the lease database... */ /* Rewrite the lease database... */
rewrite_client_leases (); rewrite_client_leases();
/* XXX */ /* XXX */
/* config_counter(&snd_counter, &rcv_counter); */ /* 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) { if (!interfaces) {
/* Call dhclient-script with the NBI flag, in case somebody /*
cares. */ * Call dhclient-script with the NBI flag,
script_init ((struct client_state *)0, "NBI", * in case somebody cares.
(struct string_list *)0); */
script_go ((struct client_state *)0); 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) { if (!persist) {
/* Nothing more to do. */ /* Nothing more to do. */
log_info ("No broadcast interfaces found - exiting."); log_info("No broadcast interfaces found - exiting.");
exit (0); exit(0);
} }
} else if (!release_mode && !exit_mode) { } else if (!release_mode && !exit_mode) {
/* Call the script with the list of interfaces. */ /* Call the script with the list of interfaces. */
for (ip = interfaces; ip; ip = ip -> next) { 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) && if ((interfaces_requested > 0) &&
((ip -> flags & (INTERFACE_REQUESTED | ((ip->flags & (INTERFACE_REQUESTED |
INTERFACE_AUTOMATIC)) != INTERFACE_AUTOMATIC)) !=
INTERFACE_REQUESTED)) INTERFACE_REQUESTED))
continue; continue;
@@ -440,7 +495,7 @@ main(int argc, char **argv) {
"alias_", "alias_",
ip->client->alias); ip->client->alias);
} }
script_go (ip->client); script_go(ip->client);
} }
} }
@@ -448,9 +503,9 @@ main(int argc, char **argv) {
are relevant should be running, so now we once again call are relevant should be running, so now we once again call
discover_interfaces(), and this time ask it to actually set discover_interfaces(), and this time ask it to actually set
up the interfaces. */ up the interfaces. */
discover_interfaces (interfaces_requested != 0 discover_interfaces(interfaces_requested != 0
? DISCOVER_REQUESTED ? DISCOVER_REQUESTED
: DISCOVER_RUNNING); : DISCOVER_RUNNING);
/* Make up a seed for the random number generator from current /* Make up a seed for the random number generator from current
time plus the sum of the last four bytes of each time plus the sum of the last four bytes of each
@@ -458,14 +513,14 @@ main(int argc, char **argv) {
Not much entropy, but we're booting, so we're not likely to Not much entropy, but we're booting, so we're not likely to
find anything better. */ find anything better. */
seed = 0; seed = 0;
for (ip = interfaces; ip; ip = ip -> next) { for (ip = interfaces; ip; ip = ip->next) {
int junk; int junk;
memcpy (&junk, memcpy(&junk,
&ip -> hw_address.hbuf [ip -> hw_address.hlen - &ip->hw_address.hbuf[ip->hw_address.hlen -
sizeof seed], sizeof seed); sizeof seed], sizeof seed);
seed += junk; seed += junk;
} }
srandom (seed + cur_time); srandom(seed + cur_time);
/* Start a configuration state machine for each interface. */ /* Start a configuration state machine for each interface. */
#ifdef DHCPv6 #ifdef DHCPv6
@@ -543,18 +598,18 @@ main(int argc, char **argv) {
/* Start up a listener for the object management API protocol. */ /* Start up a listener for the object management API protocol. */
if (top_level_config.omapi_port != -1) { if (top_level_config.omapi_port != -1) {
listener = (omapi_object_t *)0; listener = NULL;
result = omapi_generic_new (&listener, MDL); result = omapi_generic_new(&listener, MDL);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
log_fatal ("Can't allocate new generic object: %s\n", log_fatal("Can't allocate new generic object: %s\n",
isc_result_totext (result)); isc_result_totext(result));
result = omapi_protocol_listen (listener, result = omapi_protocol_listen(listener,
(unsigned) (unsigned)
top_level_config.omapi_port, top_level_config.omapi_port,
1); 1);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
log_fatal ("Can't start OMAPI protocol: %s", log_fatal("Can't start OMAPI protocol: %s",
isc_result_totext (result)); isc_result_totext (result));
} }
/* Set up the bootp packet handler... */ /* Set up the bootp packet handler... */
@@ -563,8 +618,8 @@ main(int argc, char **argv) {
dhcpv6_packet_handler = do_packet6; dhcpv6_packet_handler = do_packet6;
#endif /* DHCPv6 */ #endif /* DHCPv6 */
#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \ #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
dmalloc_cutoff_generation = dmalloc_generation; dmalloc_cutoff_generation = dmalloc_generation;
dmalloc_longterm = dmalloc_outstanding; dmalloc_longterm = dmalloc_outstanding;
dmalloc_outstanding = 0; dmalloc_outstanding = 0;
@@ -573,41 +628,42 @@ main(int argc, char **argv) {
/* If we're not supposed to wait before getting the address, /* If we're not supposed to wait before getting the address,
don't. */ don't. */
if (nowait) if (nowait)
go_daemon (); go_daemon();
/* If we're not going to daemonize, write the pid file /* If we're not going to daemonize, write the pid file
now. */ now. */
if (no_daemon || nowait) if (no_daemon || nowait)
write_client_pid_file (); write_client_pid_file();
/* Start dispatching packets and timeouts... */ /* Start dispatching packets and timeouts... */
dispatch (); dispatch();
/*NOTREACHED*/ /*NOTREACHED*/
return 0; return 0;
} }
static void usage () static void usage()
{ {
log_info ("%s %s", message, PACKAGE_VERSION); log_info("%s %s", message, PACKAGE_VERSION);
log_info (copyright); log_info(copyright);
log_info (arr); log_info(arr);
log_info (url); log_info(url);
log_error ("Usage: dhclient %s %s", log_error("Usage: dhclient %s %s",
#ifdef DHCPv6 #ifdef DHCPv6
"[-4|-6] [-S1dvrx] [-nw] [-p <port>]", "[-4|-6] [-SNTP1dvrx] [-nw] [-p <port>]",
#else /* DHCPv6 */ #else /* DHCPv6 */
"[-1dvrx] [-nw] [-p <port>]", "[-1dvrx] [-nw] [-p <port>]",
#endif /* DHCPv6 */ #endif /* DHCPv6 */
"[-s server]"); "[-s server]");
log_error (" [-cf config-file] [-lf lease-file]%s", log_error(" [-cf config-file] [-lf lease-file]%s",
"[-pf pid-file] [-e VAR=val]"); "[-pf pid-file] [-e VAR=val]");
log_fatal (" [-sf script-file] [interface]"); log_fatal(" [-sf script-file] [interface]");
} }
void run_stateless(int exit_mode) void run_stateless(int exit_mode)
{ {
#ifdef DHCPv6
struct client_state *client; struct client_state *client;
omapi_object_t *listener; omapi_object_t *listener;
isc_result_t result; isc_result_t result;
@@ -647,7 +703,7 @@ void run_stateless(int exit_mode)
/* Start up a listener for the object management API protocol. */ /* Start up a listener for the object management API protocol. */
if (top_level_config.omapi_port != -1) { if (top_level_config.omapi_port != -1) {
listener = (omapi_object_t *)0; listener = NULL;
result = omapi_generic_new(&listener, MDL); result = omapi_generic_new(&listener, MDL);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
log_fatal("Can't allocate new generic object: %s\n", log_fatal("Can't allocate new generic object: %s\n",
@@ -664,8 +720,8 @@ void run_stateless(int exit_mode)
/* Set up the packet handler... */ /* Set up the packet handler... */
dhcpv6_packet_handler = do_packet6; dhcpv6_packet_handler = do_packet6;
#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \ #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
dmalloc_cutoff_generation = dmalloc_generation; dmalloc_cutoff_generation = dmalloc_generation;
dmalloc_longterm = dmalloc_outstanding; dmalloc_longterm = dmalloc_outstanding;
dmalloc_outstanding = 0; dmalloc_outstanding = 0;
@@ -685,6 +741,7 @@ void run_stateless(int exit_mode)
dispatch(); dispatch();
/*NOTREACHED*/ /*NOTREACHED*/
#endif /* DHCPv6 */
return; return;
} }
@@ -766,20 +823,24 @@ void state_reboot (cpp)
/* We are in the rebooting state. */ /* We are in the rebooting state. */
client -> state = S_REBOOTING; client -> state = S_REBOOTING;
/* make_request doesn't initialize xid because it normally comes /*
from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER, * make_request doesn't initialize xid because it normally comes
so pick an xid now. */ * from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
* so pick an xid now.
*/
client -> xid = random (); 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); make_request (client, client -> active);
client -> destination = iaddr_broadcast; client -> destination = iaddr_broadcast;
client -> first_sending = cur_time; client -> first_sending = cur_time;
client -> interval = client -> config -> initial_interval; client -> interval = client -> config -> initial_interval;
/* Zap the medium list... */ /* Zap the medium list... */
client -> medium = (struct string_list *)0; client -> medium = NULL;
/* Send out the first DHCPREQUEST packet. */ /* Send out the first DHCPREQUEST packet. */
send_request (client); send_request (client);
@@ -809,8 +870,10 @@ void state_init (cpp)
send_discover (client); 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 state_selecting (cpp)
void *cpp; void *cpp;
@@ -821,31 +884,39 @@ void state_selecting (cpp)
ASSERT_STATE(state, S_SELECTING); 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 (state_selecting, client);
cancel_timeout (send_discover, 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 * We have received one or more DHCPOFFER packets. Currently,
not we get a response when we arp for them. */ * the only criterion by which we judge leases is whether or
picked = (struct client_lease *)0; * not we get a response when we arp for them.
*/
picked = NULL;
for (lp = client -> offered_leases; lp; lp = next) { for (lp = client -> offered_leases; lp; lp = next) {
next = 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) { if (!picked) {
picked = lp; picked = lp;
picked -> next = (struct client_lease *)0; picked -> next = NULL;
} else { } else {
destroy_client_lease (lp); 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) { if (!picked) {
client -> state = S_INIT; client -> state = S_INIT;
state_init (client); state_init (client);

View File

@@ -242,6 +242,12 @@ if [ ${reason} = PREINIT6 ] ; then
exit_with_hooks 0 exit_with_hooks 0
fi 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 [ ${reason} = BOUND6 ] ; then
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
exit_with_hooks 2; exit_with_hooks 2;

View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/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$ # $FreeBSD$
@@ -306,6 +306,12 @@ if [ ${reason} = PREINIT6 ] ; then
exit_with_hooks 0 exit_with_hooks 0
fi 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 [ ${reason} = BOUND6 ] ; then
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
exit_with_hooks 2; exit_with_hooks 2;
@@ -332,13 +338,11 @@ if [ ${reason} = RENEW6 ] || [ ${reason} = REBIND6 ] ; then
fi fi
if [ ${reason} = DEPREF6 ] ; then if [ ${reason} = DEPREF6 ] ; then
if [ x${new_ip6_prefixlen} = x ] ; then if [ x${new_ip6_address} = x ] ; then
exit_with_hooks 2; exit_with_hooks 2;
fi fi
# XXX: ifconfig ${interface} inet6 ${new_ip6_address} deprecated
# There doesn't appear to be a way to update an addr to indicate
# preference.
exit_with_hooks 0 exit_with_hooks 0
fi fi

View File

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

View File

@@ -242,6 +242,12 @@ if [ ${reason} = PREINIT6 ] ; then
exit_with_hooks 0 exit_with_hooks 0
fi 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 [ ${reason} = BOUND6 ] ; then
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
exit_with_hooks 2; exit_with_hooks 2;

View File

@@ -242,6 +242,12 @@ if [ ${reason} = PREINIT6 ] ; then
exit_with_hooks 0 exit_with_hooks 0
fi 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 [ ${reason} = BOUND6 ] ; then
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
exit_with_hooks 2; exit_with_hooks 2;

View File

@@ -2441,6 +2441,10 @@ char *piaddrcidr(const struct iaddr *, unsigned int);
/* dhclient.c */ /* dhclient.c */
extern int nowait; 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_conf;
extern const char *path_dhclient_db; extern const char *path_dhclient_db;
extern const char *path_dhclient_pid; extern const char *path_dhclient_pid;