summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore24
-rw-r--r--RELNOTES6
-rw-r--r--common/options.c19
-rw-r--r--common/tree.c66
-rw-r--r--includes/dhcpd.h3
-rw-r--r--server/bootp.c49
-rw-r--r--server/dhcp.c67
7 files changed, 147 insertions, 87 deletions
diff --git a/.gitignore b/.gitignore
index a238dcd5..18d4580a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,27 @@ doc/html
.deps
Makefile
autom4te.cache
+client/dhclient
+client/tests/
+common/tests/alloc_unittest
+common/tests/dns_unittest
+common/tests/misc_unittest
+config.log
+config.report
+config.status
+dhcpctl/cltest
+dhcpctl/omshell
+doc/devel/doxyfile
+dst/libdst.a
+includes/.dhcpd.h.swp
+includes/stamp-h1
+omapip/svtest
+relay/dhcrelay
+server/dhcpd
+server/tests/dhcpd_unittests
+server/tests/hash_unittests
+server/tests/legacy_unittests
+server/tests/load_bal_unittests
+server/tests/test-suite.log
+tests/libt_api.a
+minires/libres.a
diff --git a/RELNOTES b/RELNOTES
index e74fff12..b999d111 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -103,11 +103,15 @@ by Eric Young (eay@cryptsoft.com).
[ISC-Bus #24216]
[ISC-Bus #25587]
+- Added support of the configuration parameter, use-host-decl-names, to
+ BOOTP request handling.
+ [ISC-Bugs #36233]
+
Changes since 4.1-ESV-R10rc1
- None
- Changes since 4.1-ESV-R10b1
+ Changes since 4.3.1b1
- Modify the linux and openwrt dhclient scripts to process information
from a stateless request. Thanks to Jiri Popelka at Red Hat for the
diff --git a/common/options.c b/common/options.c
index db8d8071..140a1aea 100644
--- a/common/options.c
+++ b/common/options.c
@@ -43,17 +43,11 @@ static int prepare_option_buffer(struct universe *universe, struct buffer *bp,
struct option_cache **opp);
/* Parse all available options out of the specified packet. */
-
+/* Note, the caller is responsible for allocating packet->options. */
int parse_options (packet)
struct packet *packet;
{
- struct option_cache *op = (struct option_cache *)0;
-
- /* Allocate a new option state. */
- if (!option_state_allocate (&packet -> options, MDL)) {
- packet -> options_valid = 0;
- return 0;
- }
+ struct option_cache *op = NULL;
/* If we don't see the magic cookie, there's nothing to parse. */
if (memcmp (packet -> raw -> options, DHCP_OPTIONS_COOKIE, 4)) {
@@ -3790,12 +3784,15 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
return;
}
+ /* Allocate packet->options now so it is non-null for all packets */
+ decoded_packet->options_valid = 0;
+ if (!option_state_allocate (&decoded_packet->options, MDL)) {
+ return;
+ }
+
/* If there's an option buffer, try to parse it. */
if (decoded_packet->packet_length >= DHCP_FIXED_NON_UDP + 4) {
if (!parse_options(decoded_packet)) {
- if (decoded_packet->options)
- option_state_dereference
- (&decoded_packet->options, MDL);
packet_dereference (&decoded_packet, MDL);
return;
}
diff --git a/common/tree.c b/common/tree.c
index ef3e3091..838dbcaa 100644
--- a/common/tree.c
+++ b/common/tree.c
@@ -2900,9 +2900,16 @@ int evaluate_option_cache (result, packet, lease, client_state,
oc -> expression, file, line);
}
-/* Evaluate an option cache and extract a boolean from the result,
- returning the boolean. Return false if there is no data. */
-
+/* Evaluate an option cache and extract a boolean from the result.
+ * The boolean option cache is actually a trinary value where:
+ *
+ * 0 = return 0, ignore parameter 0 (also the case for no data)
+ * 1 = return 1, ignore parameter 0
+ * 2 = return 0, ignore parameter 1
+ *
+ * This supports both classic boolean flags on/off as well as the
+ * allow/deny/ignore keywords
+*/
int evaluate_boolean_option_cache (ignorep, packet,
lease, client_state, in_options,
cfg_options, scope, oc, file, line)
@@ -2917,36 +2924,35 @@ int evaluate_boolean_option_cache (ignorep, packet,
const char *file;
int line;
{
- struct data_string ds;
- int result;
+ int result = 0;
+ if (ignorep)
+ *ignorep = 0;
- /* So that we can be called with option_lookup as an argument. */
- if (!oc || !in_options)
- return 0;
-
- memset (&ds, 0, sizeof ds);
- if (!evaluate_option_cache (&ds, packet,
- lease, client_state, in_options,
- cfg_options, scope, oc, file, line))
- return 0;
+ /* Only attempt to evaluate if option_cache is not null. This permits
+ * us to be called with option_lookup() as an argument. */
+ if (oc && in_options) {
+ struct data_string ds;
+
+ memset(&ds, 0, sizeof ds);
+ if (evaluate_option_cache(&ds, packet,
+ lease, client_state, in_options,
+ cfg_options, scope, oc, file,
+ line)) {
+ /* We have a value for the option set result and
+ * ignore parameter accordingly. */
+ if (ds.len) {
+ if (ds.data[0] == 1)
+ result = 1;
+ else if ((ds.data[0] == 2) && (ignorep != NULL))
+ *ignorep = 1;
+ }
- /* The boolean option cache is actually a trinary value. Zero is
- * off, one is on, and 2 is 'ignore'.
- */
- if (ds.len) {
- result = ds.data [0];
- if (result == 2) {
- result = 0;
- if (ignorep != NULL)
- *ignorep = 1;
- } else if (ignorep != NULL)
- *ignorep = 0;
- } else
- result = 0;
- data_string_forget (&ds, MDL);
- return result;
+ data_string_forget(&ds, MDL);
+ }
+ }
+
+ return (result);
}
-
/* Evaluate a boolean expression and return the result of the evaluation,
or FALSE if it failed. */
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index fed7b595..97b0951d 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -2010,7 +2010,8 @@ isc_result_t get_client_id(struct packet *, struct data_string *);
void dhcpv6(struct packet *);
/* bootp.c */
-void bootp (struct packet *);
+void bootp(struct packet *);
+void use_host_decl_name(struct packet *, struct lease* , struct option_state *);
/* memory.c */
extern int (*group_write_hook) (struct group_object *);
diff --git a/server/bootp.c b/server/bootp.c
index d6dd96a2..7397cec1 100644
--- a/server/bootp.c
+++ b/server/bootp.c
@@ -180,21 +180,21 @@ void bootp (packet)
/* Drop the request if it's not allowed for this client. */
if ((oc = lookup_option (&server_universe, options, SV_ALLOW_BOOTP)) &&
- !evaluate_boolean_option_cache (&ignorep, packet, lease,
- (struct client_state *)0,
- packet -> options, options,
- &lease -> scope, oc, MDL)) {
+ !evaluate_boolean_option_cache(&ignorep, packet, lease,
+ NULL,
+ packet->options, options,
+ &lease->scope, oc, MDL)) {
if (!ignorep)
log_info ("%s: bootp disallowed", msgbuf);
goto out;
}
- if ((oc = lookup_option (&server_universe,
+ if ((oc = lookup_option(&server_universe,
options, SV_ALLOW_BOOTING)) &&
- !evaluate_boolean_option_cache (&ignorep, packet, lease,
- (struct client_state *)0,
- packet -> options, options,
- &lease -> scope, oc, MDL)) {
+ !evaluate_boolean_option_cache(&ignorep, packet, lease,
+ NULL,
+ packet->options, options,
+ &lease->scope, oc, MDL)) {
if (!ignorep)
log_info ("%s: booting disallowed", msgbuf);
goto out;
@@ -207,20 +207,26 @@ void bootp (packet)
/* If we didn't get a known vendor magic number on the way in,
just copy the input options to the output. */
- if (!packet -> options_valid &&
- !(evaluate_boolean_option_cache
- (&ignorep, packet, lease, (struct client_state *)0,
- packet -> options, options, &lease -> scope,
- lookup_option (&server_universe, options,
- SV_ALWAYS_REPLY_RFC1048), MDL))) {
- memcpy (outgoing.raw -> options,
- packet -> raw -> options, DHCP_MAX_OPTION_LEN);
- outgoing.packet_length = BOOTP_MIN_LEN;
+ i = SV_ALWAYS_REPLY_RFC1048;
+ if (!packet->options_valid &&
+ !(evaluate_boolean_option_cache(&ignorep, packet, lease, NULL,
+ packet->options, options,
+ &lease->scope,
+ lookup_option (&server_universe,
+ options, i), MDL))) {
+ if (packet->packet_length > DHCP_FIXED_NON_UDP) {
+ memcpy(outgoing.raw->options, packet->raw->options,
+ packet->packet_length - DHCP_FIXED_NON_UDP);
+ }
+
+ outgoing.packet_length =
+ (packet->packet_length < BOOTP_MIN_LEN)
+ ? BOOTP_MIN_LEN
+ : packet->packet_length;
} else {
/* Use the subnet mask from the subnet declaration if no other
mask has been provided. */
-
oc = (struct option_cache *)0;
i = DHO_SUBNET_MASK;
if (!lookup_option (&dhcp_universe, options, i)) {
@@ -240,6 +246,11 @@ void bootp (packet)
}
}
+ /* If use-host-decl-names is enabled and there is a hostname
+ * defined in the host delcartion, send it back in hostname
+ * option */
+ use_host_decl_name(packet, lease, options);
+
/* Pack the options into the buffer. Unlike DHCP, we
can't pack options into the filename and server
name buffers. */
diff --git a/server/dhcp.c b/server/dhcp.c
index 08b67d74..0b0f6322 100644
--- a/server/dhcp.c
+++ b/server/dhcp.c
@@ -2732,33 +2732,10 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
}
}
- /* Use the hostname from the host declaration if there is one
+ /* Use the name of the host declaration if there is one
and no hostname has otherwise been provided, and if the
use-host-decl-name flag is set. */
- i = DHO_HOST_NAME;
- j = SV_USE_HOST_DECL_NAMES;
- if (!lookup_option (&dhcp_universe, state -> options, i) &&
- lease -> host && lease -> host -> name &&
- (evaluate_boolean_option_cache
- (&ignorep, packet, lease, (struct client_state *)0,
- packet -> options, state -> options, &lease -> scope,
- lookup_option (&server_universe, state -> options, j), MDL))) {
- oc = (struct option_cache *)0;
- if (option_cache_allocate (&oc, MDL)) {
- if (make_const_data (&oc -> expression,
- ((unsigned char *)
- lease -> host -> name),
- strlen (lease -> host -> name),
- 1, 0, MDL)) {
- option_code_hash_lookup(&oc->option,
- dhcp_universe.code_hash,
- &i, 0, MDL);
- save_option (&dhcp_universe,
- state -> options, oc);
- }
- option_cache_dereference (&oc, MDL);
- }
- }
+ use_host_decl_name(packet, lease, state->options);
/* If we don't have a hostname yet, and we've been asked to do
a reverse lookup to find the hostname, do it. */
@@ -4538,3 +4515,43 @@ lowest_site_code(const void *key, unsigned len, void *object)
return ISC_R_SUCCESS;
}
+/*!
+ * \brief Adds hostname option when use-host-decl-names is enabled.
+ *
+ * Constructs a hostname option from the name of the host declaration if
+ * there is one and no hostname has otherwise been provided and the
+ * use-host-decl-names flag is set, then adds the new option to the given
+ * option_state. This funciton is used for both bootp and dhcp.
+ *
+ * \param packet inbound packet received from the client
+ * \param lease lease associated with the client
+ * \param options option state to search and update
+ */
+void use_host_decl_name(struct packet* packet,
+ struct lease *lease,
+ struct option_state *options) {
+ unsigned int ocode = SV_USE_HOST_DECL_NAMES;
+ if ((lease->host && lease->host->name) &&
+ !lookup_option(&dhcp_universe, options, DHO_HOST_NAME) &&
+ (evaluate_boolean_option_cache(NULL, packet, lease, NULL,
+ packet->options, options,
+ &lease->scope,
+ lookup_option(&server_universe,
+ options, ocode),
+ MDL))) {
+ struct option_cache *oc = NULL;
+ if (option_cache_allocate (&oc, MDL)) {
+ if (make_const_data(&oc -> expression,
+ ((unsigned char*)lease->host->name),
+ strlen(lease->host->name),
+ 1, 0, MDL)) {
+ ocode = DHO_HOST_NAME;
+ option_code_hash_lookup(&oc->option,
+ dhcp_universe.code_hash,
+ &ocode, 0, MDL);
+ save_option(&dhcp_universe, options, oc);
+ }
+ option_cache_dereference(&oc, MDL);
+ }
+ }
+}