summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2013-03-22 23:58:52 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2013-03-22 23:58:52 +0000
commit69f28996217b3d38429590a7202bd7e55b7f6e97 (patch)
tree27faec8ad309a9a152cca896d913972351a592e7
parent699d62499842d9055e3dba86bdfb10b9c92b611c (diff)
Ignore client-identifier option in leases from a server. They're not supposed
to be there! Instead, always record the client-identifier used to obtain the lease. Ignore recorded leases that have a different client-identifier than the one currently in force. If a client-identifier is not specified in the dhclient.conf file, construct one from the network type and MAC, like most other clients out there do these days. Thus, if one plugs in a different USB network adapter, renewing the previous lease (which upsets servers due to the MAC being different) is skipped and DISCOVER is attempted at once. Issue noted and fix tested by tedu@.
-rw-r--r--sbin/dhclient/clparse.c16
-rw-r--r--sbin/dhclient/dhclient.c14
-rw-r--r--sbin/dhclient/dispatch.c24
3 files changed, 45 insertions, 9 deletions
diff --git a/sbin/dhclient/clparse.c b/sbin/dhclient/clparse.c
index afd1e65f209..d84dae96370 100644
--- a/sbin/dhclient/clparse.c
+++ b/sbin/dhclient/clparse.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clparse.c,v 1.54 2013/03/21 12:41:12 krw Exp $ */
+/* $OpenBSD: clparse.c,v 1.55 2013/03/22 23:58:51 krw Exp $ */
/* Parser for dhclient config and lease files... */
@@ -413,6 +413,7 @@ void
parse_client_lease_statement(FILE *cfile, int is_static)
{
struct client_lease *lease, *lp, *pl;
+ struct option_data *opt1, *opt2;
int token;
token = next_token(NULL, cfile);
@@ -442,6 +443,19 @@ parse_client_lease_statement(FILE *cfile, int is_static)
token = next_token(NULL, cfile);
/*
+ * If the new lease is for an obsolete client-identifier, toss it.
+ */
+ opt1 = &lease->options[DHO_DHCP_CLIENT_IDENTIFIER];
+ opt2 = &config->send_options[DHO_DHCP_CLIENT_IDENTIFIER];
+ if (opt1->len && opt2->len && (opt1->len != opt2->len ||
+ memcmp(opt1->data, opt2->data, opt1->len))) {
+ note("Obsolete client identifier (%s) in recorded lease",
+ pretty_print_option( DHO_DHCP_CLIENT_IDENTIFIER, opt1, 0));
+ free_client_lease(lease);
+ return;
+ }
+
+ /*
* The new lease may supersede a lease that's not the active
* lease but is still on the lease list, so scan the lease list
* looking for a lease with the same address, and if we find it,
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index dfe115a9454..9aab9204880 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhclient.c,v 1.240 2013/02/27 17:25:59 krw Exp $ */
+/* $OpenBSD: dhclient.c,v 1.241 2013/03/22 23:58:51 krw Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -1622,6 +1622,7 @@ char *
lease_as_string(char *type, struct client_lease *lease)
{
static char leasestr[8192];
+ struct option_data *opt;
char *p;
size_t sz, rsltsz;
int i, rslt;
@@ -1656,11 +1657,16 @@ lease_as_string(char *type, struct client_lease *lease)
}
for (i = 0; i < 256; i++) {
- if (lease->options[i].len == 0)
+ if (i == DHO_DHCP_CLIENT_IDENTIFIER) {
+ /* Ignore any CLIENT_IDENTIFIER from server. */
+ opt = &config->send_options[i];
+ } else if (lease->options[i].len)
+ opt = &lease->options[i];
+ else
continue;
+
rslt = snprintf(p, sz, " option %s %s;\n",
- dhcp_options[i].name,
- pretty_print_option(i, &lease->options[i], 1));
+ dhcp_options[i].name, pretty_print_option(i, opt, 1));
if (rslt == -1 || rslt >= sz)
return (NULL);
p += rslt;
diff --git a/sbin/dhclient/dispatch.c b/sbin/dhclient/dispatch.c
index ce4a7c9d91f..ed1b4bb66d5 100644
--- a/sbin/dhclient/dispatch.c
+++ b/sbin/dhclient/dispatch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dispatch.c,v 1.75 2013/02/18 15:57:08 krw Exp $ */
+/* $OpenBSD: dispatch.c,v 1.76 2013/03/22 23:58:51 krw Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -59,7 +59,9 @@ discover_interface(void)
{
struct ifaddrs *ifap, *ifa;
struct ifreq *tif;
- int len = IFNAMSIZ + sizeof(struct sockaddr_storage);
+ struct option_data *opt;
+ char *data;
+ int len;
if (getifaddrs(&ifap) != 0)
error("getifaddrs failed");
@@ -83,10 +85,24 @@ discover_interface(void)
ifi->index = foo->sdl_index;
ifi->hw_address.hlen = foo->sdl_alen;
ifi->hw_address.htype = HTYPE_ETHER; /* XXX */
- memcpy(ifi->hw_address.haddr,
- LLADDR(foo), foo->sdl_alen);
+ memcpy(ifi->hw_address.haddr, LLADDR(foo),
+ foo->sdl_alen);
+ opt = &config->send_options[DHO_DHCP_CLIENT_IDENTIFIER];
+ if (opt->len == 0) {
+ /* Build default client identifier. */
+ data = calloc(1, foo->sdl_alen + 1);
+ if (data != NULL) {
+ data[0] = ifi->hw_address.htype;
+ memcpy(&data[1], LLADDR(foo),
+ foo->sdl_alen);
+ opt->data = data;
+ opt->len = foo->sdl_alen + 1;
+ }
+ }
}
+
if (!ifi->ifp) {
+ len = IFNAMSIZ + sizeof(struct sockaddr_storage);
if ((tif = malloc(len)) == NULL)
error("no space to remember ifp");
strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ);