summaryrefslogtreecommitdiff
path: root/usr.sbin/dhcpd
diff options
context:
space:
mode:
authorYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2014-07-11 16:48:30 +0000
committerYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2014-07-11 16:48:30 +0000
commit7f9d98eed1a665afa99ce28226c40b59031f42cb (patch)
tree93f559392f7c194c602c0c41b1aa89f62b15bcfe /usr.sbin/dhcpd
parentfc08f62e7314dbb7d02a33b2624dc42e31f39855 (diff)
Fix DHCPINFORM not to lookup the lease database, not to fill the yiaddr
field and not to include the lease time parameters. ok krw
Diffstat (limited to 'usr.sbin/dhcpd')
-rw-r--r--usr.sbin/dhcpd/dhcp.c125
-rw-r--r--usr.sbin/dhcpd/dhcpd.h3
2 files changed, 67 insertions, 61 deletions
diff --git a/usr.sbin/dhcpd/dhcp.c b/usr.sbin/dhcpd/dhcp.c
index 8370affb09b..f80f35d4787 100644
--- a/usr.sbin/dhcpd/dhcp.c
+++ b/usr.sbin/dhcpd/dhcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhcp.c,v 1.37 2014/07/11 09:42:27 yasuoka Exp $ */
+/* $OpenBSD: dhcp.c,v 1.38 2014/07/11 16:48:29 yasuoka Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998, 1999
@@ -500,7 +500,7 @@ dhcpdecline(struct packet *packet)
void
dhcpinform(struct packet *packet)
{
- struct lease *lease;
+ struct lease lease;
struct iaddr cip;
struct subnet *subnet;
@@ -509,9 +509,17 @@ dhcpinform(struct packet *packet)
* not all clients are standards compliant.
*/
cip.len = 4;
- if (packet->raw->ciaddr.s_addr)
+ if (packet->raw->ciaddr.s_addr) {
+ if (memcmp(&packet->raw->ciaddr.s_addr,
+ packet->client_addr.iabuf, 4) != 0) {
+ note("DHCPINFORM from %s but ciaddr %s is not "
+ "consitent with actual address",
+ piaddr(packet->client_addr),
+ inet_ntoa(packet->raw->ciaddr));
+ return;
+ }
memcpy(cip.iabuf, &packet->raw->ciaddr.s_addr, 4);
- else
+ } else
memcpy(cip.iabuf, &packet->client_addr.iabuf, 4);
note("DHCPINFORM from %s", piaddr(cip));
@@ -528,28 +536,21 @@ dhcpinform(struct packet *packet)
return;
}
- lease = find_lease(packet, subnet->shared_network, 0);
- if (!lease) {
- note("DHCPINFORM packet from %s but no lease present",
- print_hw_addr(packet->raw->htype, packet->raw->hlen,
- packet->raw->chaddr));
- return;
- }
+ /* Use a fake lease entry */
+ memset(&lease, 0, sizeof(lease));
+ lease.subnet = subnet;
+ lease.shared_network = subnet->shared_network;
- /* If this subnet won't boot unknown clients, ignore the
- request. */
- if (!lease->host &&
- !lease->subnet->group->boot_unknown_clients) {
- note("Ignoring unknown client %s",
- print_hw_addr(packet->raw->htype, packet->raw->hlen,
- packet->raw->chaddr));
- } else if (lease->host && !lease->host->group->allow_booting) {
- note("Declining to boot client %s",
- lease->host->name ? lease->host->name :
- print_hw_addr(packet->raw->htype, packet->raw->hlen,
- packet->raw->chaddr));
- } else
- ack_lease(packet, lease, DHCPACK, 0);
+ if (packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len)
+ lease.host = find_hosts_by_uid(
+ packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data,
+ packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len);
+
+ lease.starts = lease.timestamp = lease.ends = MIN_TIME;
+ lease.flags = INFORM_NOLEASE;
+ ack_lease(packet, &lease, DHCPACK, 0);
+ if (lease.state != NULL)
+ free_lease_state(lease.state, "ack_lease");
}
void
@@ -881,7 +882,7 @@ ack_lease(struct packet *packet, struct lease *lease, unsigned int offer,
lt.shared_network = lease->shared_network;
/* Don't call supersede_lease on a mocked-up lease. */
- if (lease->flags & STATIC_LEASE) {
+ if (lease->flags & (STATIC_LEASE | INFORM_NOLEASE)) {
/* Copy the hardware address into the static lease
structure. */
lease->hardware_addr.hlen = packet->raw->hlen;
@@ -1043,6 +1044,42 @@ ack_lease(struct packet *packet, struct lease *lease, unsigned int offer,
memcpy(state->from.iabuf, state->options[i]->value,
state->from.len);
}
+ /* If we used the vendor class the client specified, we
+ have to return it. */
+ if (vendor_class) {
+ i = DHO_DHCP_CLASS_IDENTIFIER;
+ state->options[i] =
+ new_tree_cache("class-identifier");
+ state->options[i]->flags = TC_TEMPORARY;
+ state->options[i]->value =
+ (unsigned char *)vendor_class->name;
+ state->options[i]->len =
+ strlen(vendor_class->name);
+ state->options[i]->buf_size =
+ state->options[i]->len;
+ state->options[i]->timeout = -1;
+ state->options[i]->tree = NULL;
+ }
+
+ /* If we used the user class the client specified, we
+ have to return it. */
+ if (user_class) {
+ i = DHO_DHCP_USER_CLASS_ID;
+ state->options[i] = new_tree_cache("user-class");
+ state->options[i]->flags = TC_TEMPORARY;
+ state->options[i]->value =
+ (unsigned char *)user_class->name;
+ state->options[i]->len =
+ strlen(user_class->name);
+ state->options[i]->buf_size =
+ state->options[i]->len;
+ state->options[i]->timeout = -1;
+ state->options[i]->tree = NULL;
+ }
+ }
+
+ /* for DHCPINFORM, don't include lease time parameters */
+ if (state->offer && (lease->flags & INFORM_NOLEASE) == 0) {
/* Sanity check the lease time. */
if ((state->offered_expiry - cur_time) < 15)
@@ -1093,39 +1130,6 @@ ack_lease(struct packet *packet, struct lease *lease, unsigned int offer,
state->options[i]->buf_size = sizeof state->rebind;
state->options[i]->timeout = -1;
state->options[i]->tree = NULL;
-
- /* If we used the vendor class the client specified, we
- have to return it. */
- if (vendor_class) {
- i = DHO_DHCP_CLASS_IDENTIFIER;
- state->options[i] =
- new_tree_cache("class-identifier");
- state->options[i]->flags = TC_TEMPORARY;
- state->options[i]->value =
- (unsigned char *)vendor_class->name;
- state->options[i]->len =
- strlen(vendor_class->name);
- state->options[i]->buf_size =
- state->options[i]->len;
- state->options[i]->timeout = -1;
- state->options[i]->tree = NULL;
- }
-
- /* If we used the user class the client specified, we
- have to return it. */
- if (user_class) {
- i = DHO_DHCP_USER_CLASS_ID;
- state->options[i] = new_tree_cache("user-class");
- state->options[i]->flags = TC_TEMPORARY;
- state->options[i]->value =
- (unsigned char *)user_class->name;
- state->options[i]->len =
- strlen(user_class->name);
- state->options[i]->buf_size =
- state->options[i]->len;
- state->options[i]->timeout = -1;
- state->options[i]->tree = NULL;
- }
}
/* Use the subnet mask from the subnet declaration if no other
@@ -1280,7 +1284,8 @@ dhcp_reply(struct lease *lease)
}
memcpy(&raw.ciaddr, &state->ciaddr, sizeof raw.ciaddr);
- memcpy(&raw.yiaddr, lease->ip_addr.iabuf, 4);
+ if ((lease->flags & INFORM_NOLEASE) == 0)
+ memcpy(&raw.yiaddr, lease->ip_addr.iabuf, 4);
/* Figure out the address of the next server. */
if (lease->host && lease->host->group->next_server.len)
diff --git a/usr.sbin/dhcpd/dhcpd.h b/usr.sbin/dhcpd/dhcpd.h
index e13a52be339..87323ce01cd 100644
--- a/usr.sbin/dhcpd/dhcpd.h
+++ b/usr.sbin/dhcpd/dhcpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhcpd.h,v 1.51 2014/07/11 09:42:27 yasuoka Exp $ */
+/* $OpenBSD: dhcpd.h,v 1.52 2014/07/11 16:48:29 yasuoka Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998, 1999
@@ -180,6 +180,7 @@ struct lease {
#define EPHEMERAL_FLAGS (BOOTP_LEASE)
#define MS_NULL_TERMINATION 8
#define ABANDONED_LEASE 16
+#define INFORM_NOLEASE 32
struct lease_state *state;
u_int8_t releasing;