dhcp package is retired on branch c10s for CS-2097
This commit is contained in:
parent
baddcc1dad
commit
a0843d3fce
@ -1 +0,0 @@
|
||||
1
|
12
.gitignore
vendored
12
.gitignore
vendored
@ -1,12 +0,0 @@
|
||||
/dhcp-4.3.5b1.tar.gz
|
||||
/dhcp-4.3.5.tar.gz
|
||||
/dhcp-4.3.6b1.tar.gz
|
||||
/dhcp-4.3.6.tar.gz
|
||||
/dhcp-4.4.1.tar.gz
|
||||
/dhcp-4.4.2b1.tar.gz
|
||||
/dhcp-4.4.2-P1.tar.gz
|
||||
/dhcp-4.4.2-P1.tar.gz.asc
|
||||
/dhcp-4.4.3.tar.gz
|
||||
/dhcp-4.4.3.tar.gz.asc
|
||||
/dhcp-4.4.3-P1.tar.gz
|
||||
/dhcp-4.4.3-P1.tar.gz.asc
|
@ -1,77 +0,0 @@
|
||||
From 5e9162c5ad7aa98f7f673ac7a7f46905ba2deea4 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:09:57 +0100
|
||||
Subject: [PATCH 01/28] change bug url
|
||||
|
||||
---
|
||||
omapip/errwarn.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 42 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/omapip/errwarn.c b/omapip/errwarn.c
|
||||
index 38dd9c5..d88e392 100644
|
||||
--- a/omapip/errwarn.c
|
||||
+++ b/omapip/errwarn.c
|
||||
@@ -48,6 +48,41 @@ void (*log_cleanup) (void);
|
||||
static char mbuf [CVT_BUF_MAX + 1];
|
||||
static char fbuf [CVT_BUF_MAX + 1];
|
||||
|
||||
+// get BUG_REPORT_URL from /etc/os-release
|
||||
+char * bug_report_url(void) {
|
||||
+ FILE * file = fopen("/etc/os-release", "r");
|
||||
+ size_t len;
|
||||
+ char * line = NULL;
|
||||
+ char * url = NULL;
|
||||
+ size_t url_len = 256;
|
||||
+
|
||||
+ url = (char *) malloc(url_len * sizeof(char));
|
||||
+ strcpy(url, "https://bugzilla.redhat.com/");
|
||||
+
|
||||
+ if (!file)
|
||||
+ return url;
|
||||
+
|
||||
+ while ((getline(&line, &len, file)) != -1) {
|
||||
+ if (strstr(line, "BUG_REPORT_URL") != NULL) {
|
||||
+ char * start = strchr(line, '=');
|
||||
+ char * rquotes = strrchr(line, '"');
|
||||
+
|
||||
+ if (rquotes != NULL) {
|
||||
+ *rquotes = '\0';
|
||||
+ strncpy(url, start+2, url_len);
|
||||
+ } else {
|
||||
+ strncpy(url, start+1, url_len);
|
||||
+ }
|
||||
+ url[url_len-1] = '\0';
|
||||
+ fclose(file);
|
||||
+ return url;
|
||||
+ }
|
||||
+ }
|
||||
+ fclose(file);
|
||||
+ return url;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Log an error message, then exit... */
|
||||
|
||||
void log_fatal (const char * fmt, ... )
|
||||
@@ -74,11 +109,13 @@ void log_fatal (const char * fmt, ... )
|
||||
}
|
||||
|
||||
log_error ("%s", "");
|
||||
- log_error ("If you think you have received this message due to a bug rather");
|
||||
- log_error ("than a configuration issue please read the section on submitting");
|
||||
- log_error ("bugs on either our web page at www.isc.org or in the README file");
|
||||
- log_error ("before submitting a bug. These pages explain the proper");
|
||||
- log_error ("process and the information we find helpful for debugging.");
|
||||
+ log_error ("This version of ISC DHCP is based on the release available");
|
||||
+ log_error ("on ftp.isc.org. Features have been added and other changes");
|
||||
+ log_error ("have been made to the base software release in order to make");
|
||||
+ log_error ("it work better with this distribution.");
|
||||
+ log_error ("%s", "");
|
||||
+ log_error ("Please report issues with this software via: ");
|
||||
+ log_error ("%s", bug_report_url());
|
||||
log_error ("%s", "");
|
||||
log_error ("exiting.");
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,469 +0,0 @@
|
||||
From af18c830fe55f6be0b89997a36b611d981e3c25d Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:19:47 +0100
|
||||
Subject: [PATCH 02/28] additional dhclient options
|
||||
|
||||
---
|
||||
client/clparse.c | 10 +-
|
||||
client/dhclient.8 | 27 +++++
|
||||
client/dhclient.c | 271 +++++++++++++++++++++++++++++++++++++++++++-
|
||||
common/conflex.c | 2 +
|
||||
includes/dhcpd.h | 3 +
|
||||
includes/dhctoken.h | 3 +-
|
||||
6 files changed, 309 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/client/clparse.c b/client/clparse.c
|
||||
index 74ca499..bb63825 100644
|
||||
--- a/client/clparse.c
|
||||
+++ b/client/clparse.c
|
||||
@@ -192,6 +192,7 @@ isc_result_t read_client_conf ()
|
||||
/* Requested lease time, used by DHCPv6 (DHCPv4 uses the option cache)
|
||||
*/
|
||||
top_level_config.requested_lease = 7200;
|
||||
+ top_level_config.bootp_broadcast_always = 0;
|
||||
|
||||
group_allocate (&top_level_config.on_receipt, MDL);
|
||||
if (!top_level_config.on_receipt)
|
||||
@@ -397,7 +398,8 @@ void read_client_leases ()
|
||||
interface-declaration |
|
||||
LEASE client-lease-statement |
|
||||
ALIAS client-lease-statement |
|
||||
- KEY key-definition */
|
||||
+ KEY key-definition |
|
||||
+ BOOTP_BROADCAST_ALWAYS */
|
||||
|
||||
void parse_client_statement (cfile, ip, config)
|
||||
struct parse *cfile;
|
||||
@@ -820,6 +822,12 @@ void parse_client_statement (cfile, ip, config)
|
||||
parse_lease_id_format(cfile);
|
||||
break;
|
||||
|
||||
+ case BOOTP_BROADCAST_ALWAYS:
|
||||
+ token = next_token(&val, (unsigned*)0, cfile);
|
||||
+ config -> bootp_broadcast_always = 1;
|
||||
+ parse_semi (cfile);
|
||||
+ return;
|
||||
+
|
||||
|
||||
default:
|
||||
lose = 0;
|
||||
diff --git a/client/dhclient.8 b/client/dhclient.8
|
||||
index 861ff56..5029dac 100644
|
||||
--- a/client/dhclient.8
|
||||
+++ b/client/dhclient.8
|
||||
@@ -135,6 +135,33 @@ dhclient - Dynamic Host Configuration Protocol Client
|
||||
.B -w
|
||||
]
|
||||
[
|
||||
+.B -B
|
||||
+]
|
||||
+[
|
||||
+.B -C
|
||||
+.I dhcp-client-identifier
|
||||
+]
|
||||
+[
|
||||
+.B -H
|
||||
+.I host-name
|
||||
+]
|
||||
+[
|
||||
+.B -F
|
||||
+.I fqdn.fqdn
|
||||
+]
|
||||
+[
|
||||
+.B -V
|
||||
+.I vendor-class-identifier
|
||||
+]
|
||||
+[
|
||||
+.B --request-options
|
||||
+.I request-option-list
|
||||
+]
|
||||
+[
|
||||
+.B --timeout
|
||||
+.I timeout
|
||||
+]
|
||||
+[
|
||||
.B --dad-wait-time
|
||||
.I seconds
|
||||
]
|
||||
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||
index 46dc3a7..6c1c09a 100644
|
||||
--- a/client/dhclient.c
|
||||
+++ b/client/dhclient.c
|
||||
@@ -41,6 +41,12 @@
|
||||
#include <sys/wait.h>
|
||||
#include <limits.h>
|
||||
|
||||
+/*
|
||||
+ * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
|
||||
+ * that when building ISC code.
|
||||
+ */
|
||||
+extern int asprintf(char **strp, const char *fmt, ...);
|
||||
+
|
||||
TIME default_lease_time = 43200; /* 12 hours... */
|
||||
TIME max_lease_time = 86400; /* 24 hours... */
|
||||
|
||||
@@ -113,6 +119,10 @@ char *mockup_relay = NULL;
|
||||
|
||||
char *progname = NULL;
|
||||
|
||||
+int bootp_broadcast_always = 0;
|
||||
+
|
||||
+extern struct option *default_requested_options[];
|
||||
+
|
||||
void run_stateless(int exit_mode, u_int16_t port);
|
||||
|
||||
static isc_result_t write_duid(struct data_string *duid);
|
||||
@@ -189,8 +199,12 @@ static const char use_v6command[] = "Command not used for DHCPv4: %s";
|
||||
" [-s server-addr] [-cf config-file]\n" \
|
||||
" [-df duid-file] [-lf lease-file]\n" \
|
||||
" [-pf pid-file] [--no-pid] [-e VAR=val]\n" \
|
||||
-" [-sf script-file] [interface]*"
|
||||
-
|
||||
+" [-sf script-file] [interface]*\n" \
|
||||
+" [-C <dhcp-client-identifier>] [-B]\n" \
|
||||
+" [-H <host-name> | -F <fqdn.fqdn>] [--timeout <timeout>]\n" \
|
||||
+" [-V <vendor-class-identifier>]\n" \
|
||||
+" [--request-options <request option list>]"
|
||||
+
|
||||
#define DHCLIENT_USAGEH "{--version|--help|-h}"
|
||||
|
||||
static void
|
||||
@@ -249,6 +263,16 @@ main(int argc, char **argv) {
|
||||
#else
|
||||
progname = argv[0];
|
||||
#endif
|
||||
+ char *dhcp_client_identifier_arg = NULL;
|
||||
+ char *dhcp_host_name_arg = NULL;
|
||||
+ char *dhcp_fqdn_arg = NULL;
|
||||
+ char *dhcp_vendor_class_identifier_arg = NULL;
|
||||
+ char *dhclient_request_options = NULL;
|
||||
+
|
||||
+ int timeout_arg = 0;
|
||||
+ char *arg_conf = NULL;
|
||||
+ int arg_conf_len = 0;
|
||||
+
|
||||
/* Initialize client globals. */
|
||||
memset(&default_duid, 0, sizeof(default_duid));
|
||||
|
||||
@@ -564,6 +588,89 @@ main(int argc, char **argv) {
|
||||
std_dhcid = 1;
|
||||
} else if (!strcmp(argv[i], "-v")) {
|
||||
quiet = 0;
|
||||
+ } else if (!strcmp(argv[i], "-C")) {
|
||||
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||
+ usage(use_noarg, argv[i-1]);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
|
||||
+ log_error("-C option dhcp-client-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ dhcp_client_identifier_arg = argv[i];
|
||||
+ } else if (!strcmp(argv[i], "-B")) {
|
||||
+ bootp_broadcast_always = 1;
|
||||
+ } else if (!strcmp(argv[i], "-H")) {
|
||||
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||
+ usage(use_noarg, argv[i-1]);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
|
||||
+ log_error("-H option host-name string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (dhcp_host_name_arg != NULL) {
|
||||
+ log_error("The -H <host-name> and -F <fqdn> arguments are mutually exclusive");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ dhcp_host_name_arg = argv[i];
|
||||
+ } else if (!strcmp(argv[i], "-F")) {
|
||||
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||
+ usage(use_noarg, argv[i-1]);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
|
||||
+ log_error("-F option fqdn.fqdn string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (dhcp_fqdn_arg != NULL) {
|
||||
+ log_error("Only one -F <fqdn> argument can be specified");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (dhcp_host_name_arg != NULL) {
|
||||
+ log_error("The -F <fqdn> and -H <host-name> arguments are mutually exclusive");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ dhcp_fqdn_arg = argv[i];
|
||||
+ } else if (!strcmp(argv[i], "--timeout")) {
|
||||
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||
+ usage(use_noarg, argv[i-1]);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if ((timeout_arg = atoi(argv[i])) <= 0) {
|
||||
+ log_error("timeout option must be > 0 - bad value: %s",argv[i]);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ } else if (!strcmp(argv[i], "-V")) {
|
||||
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||
+ usage(use_noarg, argv[i-1]);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
|
||||
+ log_error("-V option vendor-class-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ dhcp_vendor_class_identifier_arg = argv[i];
|
||||
+ } else if (!strcmp(argv[i], "--request-options")) {
|
||||
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||
+ usage(use_noarg, argv[i-1]);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ dhclient_request_options = argv[i];
|
||||
+
|
||||
} else if (argv[i][0] == '-') {
|
||||
usage("Unknown command: %s", argv[i]);
|
||||
} else if (interfaces_requested < 0) {
|
||||
@@ -760,6 +867,156 @@ main(int argc, char **argv) {
|
||||
/* Parse the dhclient.conf file. */
|
||||
read_client_conf();
|
||||
|
||||
+ /* Parse any extra command line configuration arguments: */
|
||||
+ if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg != '\0')) {
|
||||
+ arg_conf_len = asprintf(&arg_conf, "send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
|
||||
+
|
||||
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||
+ log_fatal("Unable to send -C option dhcp-client-identifier");
|
||||
+ }
|
||||
+
|
||||
+ if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg != '\0')) {
|
||||
+ if (arg_conf == 0) {
|
||||
+ arg_conf_len = asprintf(&arg_conf, "send host-name \"%s\";", dhcp_host_name_arg);
|
||||
+
|
||||
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||
+ log_fatal("Unable to send -H option host-name");
|
||||
+ } else {
|
||||
+ char *last_arg_conf = arg_conf;
|
||||
+ arg_conf = NULL;
|
||||
+ arg_conf_len = asprintf(&arg_conf, "%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);
|
||||
+
|
||||
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||
+ log_fatal("Unable to send -H option host-name");
|
||||
+
|
||||
+ free(last_arg_conf);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg != '\0')) {
|
||||
+ if (arg_conf == 0) {
|
||||
+ arg_conf_len = asprintf(&arg_conf, "send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);
|
||||
+
|
||||
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||
+ log_fatal("Unable to send -F option fqdn.fqdn");
|
||||
+ } else {
|
||||
+ char *last_arg_conf = arg_conf;
|
||||
+ arg_conf = NULL;
|
||||
+ arg_conf_len = asprintf(&arg_conf, "%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);
|
||||
+
|
||||
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||
+ log_fatal("Unable to send -F option fqdn.fqdn");
|
||||
+
|
||||
+ free(last_arg_conf);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (timeout_arg) {
|
||||
+ if (arg_conf == 0) {
|
||||
+ arg_conf_len = asprintf(&arg_conf, "timeout %d;", timeout_arg);
|
||||
+
|
||||
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||
+ log_fatal("Unable to process --timeout timeout argument");
|
||||
+ } else {
|
||||
+ char *last_arg_conf = arg_conf;
|
||||
+ arg_conf = NULL;
|
||||
+ arg_conf_len = asprintf(&arg_conf, "%s\ntimeout %d;", last_arg_conf, timeout_arg);
|
||||
+
|
||||
+ if ((arg_conf == 0) || (arg_conf_len == 0))
|
||||
+ log_fatal("Unable to process --timeout timeout argument");
|
||||
+
|
||||
+ free(last_arg_conf);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg != '\0')) {
|
||||
+ if (arg_conf == 0) {
|
||||
+ arg_conf_len = asprintf(&arg_conf, "send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);
|
||||
+
|
||||
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||
+ log_fatal("Unable to send -V option vendor-class-identifier");
|
||||
+ } else {
|
||||
+ char *last_arg_conf = arg_conf;
|
||||
+ arg_conf = NULL;
|
||||
+ arg_conf_len = asprintf(&arg_conf, "%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);
|
||||
+
|
||||
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||
+ log_fatal("Unable to send -V option vendor-class-identifier");
|
||||
+
|
||||
+ free(last_arg_conf);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (dhclient_request_options != NULL) {
|
||||
+ if (arg_conf == 0) {
|
||||
+ arg_conf_len = asprintf(&arg_conf, "request %s;", dhclient_request_options);
|
||||
+
|
||||
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||
+ log_fatal("Unable to parse --request-options <request options list> argument");
|
||||
+ } else {
|
||||
+ char *last_arg_conf = arg_conf;
|
||||
+ arg_conf = NULL;
|
||||
+ arg_conf_len = asprintf(&arg_conf, "%s\nrequest %s;", last_arg_conf, dhclient_request_options);
|
||||
+
|
||||
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||
+ log_fatal("Unable to parse --request-options <request options list> argument");
|
||||
+
|
||||
+ free(last_arg_conf);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (arg_conf) {
|
||||
+ if (arg_conf_len == 0)
|
||||
+ if ((arg_conf_len = strlen(arg_conf)) == 0)
|
||||
+ /* huh ? cannot happen ! */
|
||||
+ log_fatal("Unable to process -C/-H/-F/--timeout/-V/--request-options configuration arguments");
|
||||
+
|
||||
+ /* parse the extra dhclient.conf configuration arguments
|
||||
+ * into top level config: */
|
||||
+ struct parse *cfile = (struct parse *)0;
|
||||
+ const char *val = NULL;
|
||||
+ int token;
|
||||
+
|
||||
+ status = new_parse(&cfile, -1, arg_conf, arg_conf_len, "extra dhclient -C/-H/-F/--timeout/-V/--request-options configuration arguments", 0);
|
||||
+
|
||||
+ if ((status != ISC_R_SUCCESS) || (cfile -> warnings_occurred))
|
||||
+ log_fatal("Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
|
||||
+ /* more detailed parse failures will be logged */
|
||||
+
|
||||
+ do {
|
||||
+ token = peek_token(&val, (unsigned *)0, cfile);
|
||||
+ if (token == END_OF_FILE)
|
||||
+ break;
|
||||
+
|
||||
+ parse_client_statement(cfile, (struct interface_info *)0, &top_level_config);
|
||||
+ } while (1);
|
||||
+
|
||||
+ if (cfile -> warnings_occurred)
|
||||
+ log_fatal("Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
|
||||
+ end_parse(&cfile);
|
||||
+
|
||||
+ if (timeout_arg) {
|
||||
+ /* we just set the toplevel timeout, but per-client
|
||||
+ * timeouts may still be at defaults.
|
||||
+ */
|
||||
+ for (ip=interfaces; ip; ip = ip->next) {
|
||||
+ if (ip->client->config->timeout == 60)
|
||||
+ ip->client->config->timeout = timeout_arg;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((dhclient_request_options != 0) && (top_level_config.requested_options != default_requested_options)) {
|
||||
+ for (ip=interfaces; ip; ip = ip->next) {
|
||||
+ if (ip->client->config->requested_options == default_requested_options)
|
||||
+ ip->client->config->requested_options = top_level_config.requested_options;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ free(arg_conf);
|
||||
+ arg_conf = NULL;
|
||||
+ arg_conf_len = 0;
|
||||
+ }
|
||||
+
|
||||
/* Parse the lease database. */
|
||||
read_client_leases();
|
||||
|
||||
@@ -3472,7 +3729,8 @@ void make_discover (client, lease)
|
||||
client -> packet.xid = random ();
|
||||
client -> packet.secs = 0; /* filled in by send_discover. */
|
||||
|
||||
- if (can_receive_unicast_unconfigured (client -> interface))
|
||||
+ if ((!(bootp_broadcast_always || client->config->bootp_broadcast_always))
|
||||
+ && can_receive_unicast_unconfigured(client->interface))
|
||||
client -> packet.flags = 0;
|
||||
else
|
||||
client -> packet.flags = htons (BOOTP_BROADCAST);
|
||||
@@ -3557,7 +3815,9 @@ void make_request (client, lease)
|
||||
} else {
|
||||
memset (&client -> packet.ciaddr, 0,
|
||||
sizeof client -> packet.ciaddr);
|
||||
- if (can_receive_unicast_unconfigured (client -> interface))
|
||||
+ if ((!(bootp_broadcast_always ||
|
||||
+ client ->config->bootp_broadcast_always)) &&
|
||||
+ can_receive_unicast_unconfigured (client -> interface))
|
||||
client -> packet.flags = 0;
|
||||
else
|
||||
client -> packet.flags = htons (BOOTP_BROADCAST);
|
||||
@@ -3620,7 +3880,8 @@ void make_decline (client, lease)
|
||||
client -> packet.hops = 0;
|
||||
client -> packet.xid = client -> xid;
|
||||
client -> packet.secs = 0; /* Filled in by send_request. */
|
||||
- if (can_receive_unicast_unconfigured (client -> interface))
|
||||
+ if ((!(bootp_broadcast_always || client->config-> bootp_broadcast_always))
|
||||
+ && can_receive_unicast_unconfigured (client->interface))
|
||||
client -> packet.flags = 0;
|
||||
else
|
||||
client -> packet.flags = htons (BOOTP_BROADCAST);
|
||||
diff --git a/common/conflex.c b/common/conflex.c
|
||||
index 8b01dfb..1fa2be3 100644
|
||||
--- a/common/conflex.c
|
||||
+++ b/common/conflex.c
|
||||
@@ -832,6 +832,8 @@ intern(char *atom, enum dhcp_token dfv) {
|
||||
if (!strcasecmp(atom+1, "ig-endian")) {
|
||||
return TOKEN_BIG_ENDIAN;
|
||||
}
|
||||
+ if (!strcasecmp (atom + 1, "ootp-broadcast-always"))
|
||||
+ return BOOTP_BROADCAST_ALWAYS;
|
||||
break;
|
||||
case 'c':
|
||||
if (!strcasecmp(atom + 1, "ase"))
|
||||
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
||||
index f68b228..3b2e2ca 100644
|
||||
--- a/includes/dhcpd.h
|
||||
+++ b/includes/dhcpd.h
|
||||
@@ -1284,6 +1284,9 @@ struct client_config {
|
||||
|
||||
int lease_id_format; /* format for IDs in lease file,
|
||||
TOKEN_OCTAL or TOKEN_HEX */
|
||||
+
|
||||
+ int bootp_broadcast_always; /* If nonzero, always set the BOOTP_BROADCAST
|
||||
+ flag in requests */
|
||||
};
|
||||
|
||||
/* Per-interface state used in the dhcp client... */
|
||||
diff --git a/includes/dhctoken.h b/includes/dhctoken.h
|
||||
index e6d125f..6daa422 100644
|
||||
--- a/includes/dhctoken.h
|
||||
+++ b/includes/dhctoken.h
|
||||
@@ -377,7 +377,8 @@ enum dhcp_token {
|
||||
TOKEN_HEX = 677,
|
||||
TOKEN_OCTAL = 678,
|
||||
KEY_ALGORITHM = 679,
|
||||
- DISCONNECT = 680
|
||||
+ BOOTP_BROADCAST_ALWAYS = 680,
|
||||
+ DISCONNECT = 681
|
||||
};
|
||||
|
||||
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,98 +0,0 @@
|
||||
From be8f73c399c0f89192e57453db153aaa48fcbb2e Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:21:14 +0100
|
||||
Subject: [PATCH 03/28] Handle releasing interfaces requested by /sbin/ifup
|
||||
|
||||
---
|
||||
client/dhclient.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 72 insertions(+)
|
||||
|
||||
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||
index 6c1c09a..07679a7 100644
|
||||
--- a/client/dhclient.c
|
||||
+++ b/client/dhclient.c
|
||||
@@ -793,9 +793,81 @@ main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
fclose(pidfd);
|
||||
+ } else {
|
||||
+ /* handle release for interfaces requested with Red Hat
|
||||
+ * /sbin/ifup - pidfile will be /var/run/dhclient-$interface.pid
|
||||
+ */
|
||||
+
|
||||
+ if ((path_dhclient_pid == NULL) || (*path_dhclient_pid == '\0'))
|
||||
+ path_dhclient_pid = "/var/run/dhclient.pid";
|
||||
+
|
||||
+ char *new_path_dhclient_pid;
|
||||
+ struct interface_info *ip;
|
||||
+ int pdp_len = strlen(path_dhclient_pid), pfx, dpfx;
|
||||
+
|
||||
+ /* find append point: beginning of any trailing '.pid'
|
||||
+ * or '-$IF.pid' */
|
||||
+ for (pfx=pdp_len; (pfx >= 0) && (path_dhclient_pid[pfx] != '.') && (path_dhclient_pid[pfx] != '/'); pfx--);
|
||||
+ if (pfx == -1)
|
||||
+ pfx = pdp_len;
|
||||
+
|
||||
+ if (path_dhclient_pid[pfx] == '/')
|
||||
+ pfx += 1;
|
||||
+
|
||||
+ for (dpfx=pfx; (dpfx >= 0) && (path_dhclient_pid[dpfx] != '-') && (path_dhclient_pid[dpfx] != '/'); dpfx--);
|
||||
+ if ((dpfx > -1) && (path_dhclient_pid[dpfx] != '/'))
|
||||
+ pfx = dpfx;
|
||||
+
|
||||
+ for (ip = interfaces; ip; ip = ip->next) {
|
||||
+ if (interfaces_requested && (ip->flags & (INTERFACE_REQUESTED))) {
|
||||
+ int n_len = strlen(ip->name);
|
||||
+
|
||||
+ new_path_dhclient_pid = (char*) malloc(pfx + n_len + 6);
|
||||
+ strncpy(new_path_dhclient_pid, path_dhclient_pid, pfx);
|
||||
+ sprintf(new_path_dhclient_pid + pfx, "-%s.pid", ip->name);
|
||||
+
|
||||
+ if ((pidfd = fopen(new_path_dhclient_pid, "r")) != NULL) {
|
||||
+ e = fscanf(pidfd, "%ld\n", &temp);
|
||||
+ oldpid = (pid_t)temp;
|
||||
+
|
||||
+ if (e != 0 && e != EOF) {
|
||||
+ if (oldpid) {
|
||||
+ if (kill(oldpid, SIGTERM) == 0)
|
||||
+ unlink(path_dhclient_pid);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ fclose(pidfd);
|
||||
+ }
|
||||
+
|
||||
+ free(new_path_dhclient_pid);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ FILE *pidfp = NULL;
|
||||
+ long temp = 0;
|
||||
+ pid_t dhcpid = 0;
|
||||
+ int dhc_running = 0;
|
||||
+ char procfn[256] = "";
|
||||
+
|
||||
+ if ((pidfp = fopen(path_dhclient_pid, "r")) != NULL) {
|
||||
+ if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
|
||||
+ snprintf(procfn,256,"/proc/%u",dhcpid);
|
||||
+ dhc_running = (access(procfn, F_OK) == 0);
|
||||
+ }
|
||||
+
|
||||
+ fclose(pidfp);
|
||||
+ }
|
||||
+
|
||||
+ if (dhc_running) {
|
||||
+ log_fatal("dhclient(%u) is already running - exiting. ", dhcpid);
|
||||
+ return(1);
|
||||
}
|
||||
}
|
||||
|
||||
+ write_client_pid_file();
|
||||
+
|
||||
if (!quiet) {
|
||||
log_info("%s %s", message, PACKAGE_VERSION);
|
||||
log_info(copyright);
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,117 +0,0 @@
|
||||
From 0a640394cb6f4a97fb87e53f049fba23523035c8 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:22:41 +0100
|
||||
Subject: [PATCH 04/28] Support unicast BOOTP for IBM pSeries systems (and
|
||||
maybe others)
|
||||
|
||||
---
|
||||
server/bootp.c | 12 +++++++++++-
|
||||
server/dhcp.c | 33 ++++++++++++++++++++++++++-------
|
||||
2 files changed, 37 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/server/bootp.c b/server/bootp.c
|
||||
index 919d483..338aac0 100644
|
||||
--- a/server/bootp.c
|
||||
+++ b/server/bootp.c
|
||||
@@ -52,6 +52,7 @@ void bootp (packet)
|
||||
char msgbuf [1024];
|
||||
int ignorep;
|
||||
int peer_has_leases = 0;
|
||||
+ int norelay = 0;
|
||||
|
||||
if (packet -> raw -> op != BOOTREQUEST)
|
||||
return;
|
||||
@@ -67,7 +68,7 @@ void bootp (packet)
|
||||
? inet_ntoa (packet -> raw -> giaddr)
|
||||
: packet -> interface -> name);
|
||||
|
||||
- if (!locate_network (packet)) {
|
||||
+ if ((norelay = locate_network (packet)) == 0) {
|
||||
log_info ("%s: network unknown", msgbuf);
|
||||
return;
|
||||
}
|
||||
@@ -428,6 +429,15 @@ void bootp (packet)
|
||||
|
||||
goto out;
|
||||
}
|
||||
+ } else if (norelay == 2) {
|
||||
+ to.sin_addr = raw.ciaddr;
|
||||
+ to.sin_port = remote_port;
|
||||
+ if (fallback_interface) {
|
||||
+ result = send_packet (fallback_interface, NULL, &raw,
|
||||
+ outgoing.packet_length, from,
|
||||
+ &to, &hto);
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
/* If it comes from a client that already knows its address
|
||||
and is not requesting a broadcast response, and we can
|
||||
diff --git a/server/dhcp.c b/server/dhcp.c
|
||||
index 0b261c2..ae805a6 100644
|
||||
--- a/server/dhcp.c
|
||||
+++ b/server/dhcp.c
|
||||
@@ -5332,6 +5332,7 @@ int locate_network (packet)
|
||||
struct data_string data;
|
||||
struct subnet *subnet = (struct subnet *)0;
|
||||
struct option_cache *oc;
|
||||
+ int norelay = 0;
|
||||
|
||||
#if defined(DHCPv6) && defined(DHCP4o6)
|
||||
if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
|
||||
@@ -5353,12 +5354,24 @@ int locate_network (packet)
|
||||
from the interface, if there is one. If not, fail. */
|
||||
if (!oc && !packet -> raw -> giaddr.s_addr) {
|
||||
if (packet -> interface -> shared_network) {
|
||||
- shared_network_reference
|
||||
- (&packet -> shared_network,
|
||||
- packet -> interface -> shared_network, MDL);
|
||||
- return 1;
|
||||
+ struct in_addr any_addr;
|
||||
+ any_addr.s_addr = INADDR_ANY;
|
||||
+
|
||||
+ if (!packet -> packet_type && memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) {
|
||||
+ struct iaddr cip;
|
||||
+ memcpy(cip.iabuf, &packet -> raw -> ciaddr, 4);
|
||||
+ cip.len = 4;
|
||||
+ if (!find_grouped_subnet(&subnet, packet->interface->shared_network, cip, MDL))
|
||||
+ norelay = 2;
|
||||
+ }
|
||||
+
|
||||
+ if (!norelay) {
|
||||
+ shared_network_reference(&packet -> shared_network, packet -> interface -> shared_network, MDL);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ return 0;
|
||||
}
|
||||
- return 0;
|
||||
}
|
||||
|
||||
/* If there's an option indicating link connection, and it's valid,
|
||||
@@ -5384,7 +5397,10 @@ int locate_network (packet)
|
||||
data_string_forget (&data, MDL);
|
||||
} else {
|
||||
ia.len = 4;
|
||||
- memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
|
||||
+ if (norelay)
|
||||
+ memcpy (ia.iabuf, &packet->raw->ciaddr, 4);
|
||||
+ else
|
||||
+ memcpy (ia.iabuf, &packet->raw->giaddr, 4);
|
||||
}
|
||||
|
||||
/* If we know the subnet on which the IP address lives, use it. */
|
||||
@@ -5392,7 +5408,10 @@ int locate_network (packet)
|
||||
shared_network_reference (&packet -> shared_network,
|
||||
subnet -> shared_network, MDL);
|
||||
subnet_dereference (&subnet, MDL);
|
||||
- return 1;
|
||||
+ if (norelay)
|
||||
+ return norelay;
|
||||
+ else
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
/* Otherwise, fail. */
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,59 +0,0 @@
|
||||
From f994c4d208a8fe88cbf78d4374c8d44793f0598e Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:24:24 +0100
|
||||
Subject: [PATCH 05/28] Change default requested options
|
||||
|
||||
Add NIS domain, NIS servers, NTP servers, interface-mtu and domain-search
|
||||
to the list of default requested DHCP options
|
||||
---
|
||||
client/clparse.c | 27 ++++++++++++++++++++++++++-
|
||||
1 file changed, 26 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/client/clparse.c b/client/clparse.c
|
||||
index bb63825..e63ea08 100644
|
||||
--- a/client/clparse.c
|
||||
+++ b/client/clparse.c
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
struct client_config top_level_config;
|
||||
|
||||
-#define NUM_DEFAULT_REQUESTED_OPTS 9
|
||||
+#define NUM_DEFAULT_REQUESTED_OPTS 14
|
||||
/* There can be 2 extra requested options for DHCPv4-over-DHCPv6. */
|
||||
struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 2 + 1];
|
||||
|
||||
@@ -119,6 +119,31 @@ isc_result_t read_client_conf ()
|
||||
option_code_hash_lookup(&default_requested_options[8],
|
||||
dhcpv6_universe.code_hash, &code, 0, MDL);
|
||||
|
||||
+ /* 10 */
|
||||
+ code = DHO_NIS_DOMAIN;
|
||||
+ option_code_hash_lookup(&default_requested_options[9],
|
||||
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||
+
|
||||
+ /* 11 */
|
||||
+ code = DHO_NIS_SERVERS;
|
||||
+ option_code_hash_lookup(&default_requested_options[10],
|
||||
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||
+
|
||||
+ /* 12 */
|
||||
+ code = DHO_NTP_SERVERS;
|
||||
+ option_code_hash_lookup(&default_requested_options[11],
|
||||
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||
+
|
||||
+ /* 13 */
|
||||
+ code = DHO_INTERFACE_MTU;
|
||||
+ option_code_hash_lookup(&default_requested_options[12],
|
||||
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||
+
|
||||
+ /* 14 */
|
||||
+ code = DHO_DOMAIN_SEARCH;
|
||||
+ option_code_hash_lookup(&default_requested_options[13],
|
||||
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||
+
|
||||
for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) {
|
||||
if (default_requested_options[code] == NULL)
|
||||
log_fatal("Unable to find option definition for "
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,167 +0,0 @@
|
||||
From d359a7dc30e0423f9b90129291538cad1ee6a6d9 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:25:53 +0100
|
||||
Subject: [PATCH 06/28] Various man-page-only fixes
|
||||
|
||||
---
|
||||
client/dhclient-script.8 | 22 +++++++++++++++++++++-
|
||||
client/dhclient.conf.5 | 14 +++++++++++++-
|
||||
common/dhcp-options.5 | 15 +++++++++++++++
|
||||
server/dhcpd.conf.5 | 14 +++++++++-----
|
||||
4 files changed, 58 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/client/dhclient-script.8 b/client/dhclient-script.8
|
||||
index 5e5bd3d..37ecdc5 100644
|
||||
--- a/client/dhclient-script.8
|
||||
+++ b/client/dhclient-script.8
|
||||
@@ -43,7 +43,7 @@ customizations are needed, they should be possible using the enter and
|
||||
exit hooks provided (see HOOKS for details). These hooks will allow the
|
||||
user to override the default behaviour of the client in creating a
|
||||
.B /etc/resolv.conf
|
||||
-file.
|
||||
+file, and to handle DHCP options not handled by default.
|
||||
.PP
|
||||
No standard client script exists for some operating systems, even though
|
||||
the actual client may work, so a pioneering user may well need to create
|
||||
@@ -87,6 +87,26 @@ present. The
|
||||
.B ETCDIR/dhclient-exit-hooks
|
||||
script can modify the valid of exit_status to change the exit status
|
||||
of dhclient-script.
|
||||
+.PP
|
||||
+Immediately after dhclient brings an interface UP with a new IP address,
|
||||
+subnet mask, and routes, in the REBOOT/BOUND states, it will check for the
|
||||
+existence of an executable
|
||||
+.B ETCDIR/dhclient-up-hooks
|
||||
+script, and source it if found. This script can handle DHCP options in
|
||||
+the environment that are not handled by default. A per-interface.
|
||||
+.B ETCDIR/dhclient-${IF}-up-hooks
|
||||
+script will override the generic script and be sourced when interface
|
||||
+$IF has been brought up.
|
||||
+.PP
|
||||
+Immediately before dhclient brings an interface DOWN, removing its IP
|
||||
+address, subnet mask, and routes, in the STOP/RELEASE states, it will
|
||||
+check for the existence of an executable
|
||||
+.B ETCDIR/dhclient-down-hooks
|
||||
+script, and source it if found. This script can handle DHCP options in
|
||||
+the environment that are not handled by default. A per-interface
|
||||
+.B ETCDIR/dhclient-${IF}-down-hooks
|
||||
+script will override the generic script and be sourced when interface
|
||||
+$IF is about to be brought down.
|
||||
.SH OPERATION
|
||||
When dhclient needs to invoke the client configuration script, it
|
||||
defines a set of variables in the environment, and then invokes
|
||||
diff --git a/client/dhclient.conf.5 b/client/dhclient.conf.5
|
||||
index dbe6f7e..8bac980 100644
|
||||
--- a/client/dhclient.conf.5
|
||||
+++ b/client/dhclient.conf.5
|
||||
@@ -228,7 +228,8 @@ responding to the client send the client its values for the specified
|
||||
options. Only the option names should be specified in the request
|
||||
statement - not option parameters. By default, the DHCPv4 client
|
||||
requests the subnet-mask, broadcast-address, time-offset, routers,
|
||||
-domain-name, domain-name-servers and host-name options while the DHCPv6
|
||||
+domain-search, domain-name, domain-name-servers, host-name, nis-domain,
|
||||
+nis-servers, ntp-servers and interface-mtu options while the DHCPv6
|
||||
client requests the dhcp6 name-servers and domain-search options. Note
|
||||
that if you enter a \'request\' statement, you over-ride these defaults
|
||||
and these options will not be requested.
|
||||
@@ -735,6 +736,17 @@ broadcast packets transmitted by DHCP clients, but is only useful if you
|
||||
know the DHCP service(s) anycast MAC address prior to configuring your
|
||||
client. The \fIlink-type\fR and \fImac-address\fR parameters are configured
|
||||
in a similar manner to the \fBhardware\fR statement.
|
||||
+.PP
|
||||
+ \fBbootp-broadcast-always;\fR
|
||||
+.PP
|
||||
+The
|
||||
+.B bootp-broadcast-always
|
||||
+statement instructs dhclient to always set the bootp broadcast flag in
|
||||
+request packets, so that servers will always broadcast replies.
|
||||
+This is equivalent to supplying the dhclient -B argument, and has
|
||||
+the same effect as specifying 'always-broadcast' in the server's dhcpd.conf.
|
||||
+This option is provided as an extension to enable dhclient to work
|
||||
+on IBM s390 Linux guests.
|
||||
.PP
|
||||
.SH SAMPLE
|
||||
The following configuration file was used on a laptop running NetBSD
|
||||
diff --git a/common/dhcp-options.5 b/common/dhcp-options.5
|
||||
index 51f80f7..a784b32 100644
|
||||
--- a/common/dhcp-options.5
|
||||
+++ b/common/dhcp-options.5
|
||||
@@ -1075,6 +1075,21 @@ classless IP routing - it does not include a subnet mask. Since
|
||||
classless IP routing is now the most widely deployed routing standard,
|
||||
this option is virtually useless, and is not implemented by any of the
|
||||
popular DHCP clients, for example the Microsoft DHCP client.
|
||||
+.PP
|
||||
+NOTE to Fedora dhclient users:
|
||||
+.br
|
||||
+dhclient-script interprets trailing 0 octets of the target as indicating
|
||||
+the subnet class of the route, so for the following static-routes value:
|
||||
+.br
|
||||
+ option static-routes 172.0.0.0 172.16.2.254,
|
||||
+.br
|
||||
+ 192.168.0.0 192.168.2.254;
|
||||
+.br
|
||||
+dhclient-script will create routes:
|
||||
+.br
|
||||
+ 172/8 via 172.16.2.254 dev $interface
|
||||
+.br
|
||||
+ 192.168/16 via 192.168.2.254 dev $interface
|
||||
.RE
|
||||
.PP
|
||||
.nf
|
||||
diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5
|
||||
index 691e5dd..b7e79ea 100644
|
||||
--- a/server/dhcpd.conf.5
|
||||
+++ b/server/dhcpd.conf.5
|
||||
@@ -527,6 +527,9 @@ pool {
|
||||
};
|
||||
.fi
|
||||
.PP
|
||||
+Dynamic BOOTP leases are not compatible with failover, and, as such,
|
||||
+you need to disallow BOOTP in pools that you are using failover for.
|
||||
+.PP
|
||||
The server currently does very little sanity checking, so if you
|
||||
configure it wrong, it will just fail in odd ways. I would recommend
|
||||
therefore that you either do failover or don't do failover, but don't
|
||||
@@ -541,9 +544,9 @@ primary server might look like this:
|
||||
failover peer "foo" {
|
||||
primary;
|
||||
address anthrax.rc.example.com;
|
||||
- port 519;
|
||||
+ port 647;
|
||||
peer address trantor.rc.example.com;
|
||||
- peer port 520;
|
||||
+ peer port 847;
|
||||
max-response-delay 60;
|
||||
max-unacked-updates 10;
|
||||
mclt 3600;
|
||||
@@ -1323,7 +1326,7 @@ the zone containing PTR records - for ISC BIND, something like this:
|
||||
.PP
|
||||
.nf
|
||||
key DHCP_UPDATER {
|
||||
- algorithm HMAC-MD5.SIG-ALG.REG.INT;
|
||||
+ algorithm hmac-md5;
|
||||
secret pRP5FapFoJ95JEL06sv4PQ==;
|
||||
};
|
||||
|
||||
@@ -1346,7 +1349,7 @@ dhcpd.conf file:
|
||||
.PP
|
||||
.nf
|
||||
key DHCP_UPDATER {
|
||||
- algorithm HMAC-MD5.SIG-ALG.REG.INT;
|
||||
+ algorithm hmac-md5;
|
||||
secret pRP5FapFoJ95JEL06sv4PQ==;
|
||||
};
|
||||
|
||||
@@ -2918,7 +2921,8 @@ statement
|
||||
The \fInext-server\fR statement is used to specify the host address of
|
||||
the server from which the initial boot file (specified in the
|
||||
\fIfilename\fR statement) is to be loaded. \fIServer-name\fR should
|
||||
-be a numeric IP address or a domain name.
|
||||
+be a numeric IP address or a domain name. If no \fInext-server\fR statement
|
||||
+applies to a given client, the address 0.0.0.0 is used.
|
||||
.RE
|
||||
.PP
|
||||
The
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,53 +0,0 @@
|
||||
From d8da92991d93a3d1c9fc474696aee25b99623c42 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:26:34 +0100
|
||||
Subject: [PATCH 07/28] Change paths to conform to our standards
|
||||
|
||||
---
|
||||
doc/examples/dhcpd-dhcpv6.conf | 2 +-
|
||||
includes/dhcpd.h | 6 +++---
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/doc/examples/dhcpd-dhcpv6.conf b/doc/examples/dhcpd-dhcpv6.conf
|
||||
index 448a6a6..2357824 100644
|
||||
--- a/doc/examples/dhcpd-dhcpv6.conf
|
||||
+++ b/doc/examples/dhcpd-dhcpv6.conf
|
||||
@@ -43,7 +43,7 @@ option dhcp6.domain-search "test.example.com","example.com";
|
||||
option dhcp6.info-refresh-time 21600;
|
||||
|
||||
# The path of the lease file
|
||||
-dhcpv6-lease-file-name "/usr/local/var/db/dhcpd6.leases";
|
||||
+dhcpv6-lease-file-name "/var/lib/dhcpd/dhcpd6.leases";
|
||||
|
||||
# Static definition (must be global)
|
||||
host myclient {
|
||||
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
||||
index 3b2e2ca..4a57002 100644
|
||||
--- a/includes/dhcpd.h
|
||||
+++ b/includes/dhcpd.h
|
||||
@@ -1561,7 +1561,7 @@ typedef unsigned char option_mask [16];
|
||||
#else /* !DEBUG */
|
||||
|
||||
#ifndef _PATH_DHCPD_CONF
|
||||
-#define _PATH_DHCPD_CONF "/etc/dhcpd.conf"
|
||||
+#define _PATH_DHCPD_CONF "/etc/dhcp/dhcpd.conf"
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef _PATH_DHCPD_DB
|
||||
@@ -1583,11 +1583,11 @@ typedef unsigned char option_mask [16];
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef _PATH_DHCLIENT_CONF
|
||||
-#define _PATH_DHCLIENT_CONF "/etc/dhclient.conf"
|
||||
+#define _PATH_DHCLIENT_CONF "/etc/dhcp/dhclient.conf"
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_DHCLIENT_SCRIPT
|
||||
-#define _PATH_DHCLIENT_SCRIPT "/sbin/dhclient-script"
|
||||
+#define _PATH_DHCLIENT_SCRIPT "/usr/sbin/dhclient-script"
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_DHCLIENT_PID
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,366 +0,0 @@
|
||||
From 39ce1ca26128f4a5d018a567157320ba1f68f4ea Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:27:18 +0100
|
||||
Subject: [PATCH 08/28] Make sure all open file descriptors are closed-on-exec
|
||||
for SELinux
|
||||
|
||||
ISC-bug: #19148
|
||||
---
|
||||
client/clparse.c | 4 ++--
|
||||
client/dhclient.c | 28 ++++++++++++++--------------
|
||||
common/bpf.c | 2 +-
|
||||
common/dlpi.c | 2 +-
|
||||
common/nit.c | 2 +-
|
||||
common/resolv.c | 2 +-
|
||||
common/upf.c | 2 +-
|
||||
omapip/trace.c | 6 +++---
|
||||
relay/dhcrelay.c | 10 +++++-----
|
||||
server/confpars.c | 2 +-
|
||||
server/db.c | 4 ++--
|
||||
server/dhcpd.c | 14 +++++++-------
|
||||
server/ldap.c | 2 +-
|
||||
13 files changed, 40 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/client/clparse.c b/client/clparse.c
|
||||
index e63ea08..902b523 100644
|
||||
--- a/client/clparse.c
|
||||
+++ b/client/clparse.c
|
||||
@@ -291,7 +291,7 @@ int read_client_conf_file (const char *name, struct interface_info *ip,
|
||||
int token;
|
||||
isc_result_t status;
|
||||
|
||||
- if ((file = open (name, O_RDONLY)) < 0)
|
||||
+ if ((file = open (name, O_RDONLY | O_CLOEXEC)) < 0)
|
||||
return uerr2isc (errno);
|
||||
|
||||
cfile = NULL;
|
||||
@@ -367,7 +367,7 @@ void read_client_leases ()
|
||||
|
||||
/* Open the lease file. If we can't open it, just return -
|
||||
we can safely trust the server to remember our state. */
|
||||
- if ((file = open (path_dhclient_db, O_RDONLY)) < 0)
|
||||
+ if ((file = open (path_dhclient_db, O_RDONLY | O_CLOEXEC)) < 0)
|
||||
return;
|
||||
|
||||
cfile = NULL;
|
||||
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||
index 07679a7..aefc119 100644
|
||||
--- a/client/dhclient.c
|
||||
+++ b/client/dhclient.c
|
||||
@@ -279,11 +279,11 @@ main(int argc, char **argv) {
|
||||
/* Make sure that file descriptors 0 (stdin), 1, (stdout), and
|
||||
2 (stderr) are open. To do this, we assume that when we
|
||||
open a file the lowest available file descriptor is used. */
|
||||
- fd = open("/dev/null", O_RDWR);
|
||||
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
if (fd == 0)
|
||||
- fd = open("/dev/null", O_RDWR);
|
||||
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
if (fd == 1)
|
||||
- fd = open("/dev/null", O_RDWR);
|
||||
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
if (fd == 2)
|
||||
log_perror = 0; /* No sense logging to /dev/null. */
|
||||
else if (fd != -1)
|
||||
@@ -771,7 +771,7 @@ main(int argc, char **argv) {
|
||||
long temp;
|
||||
int e;
|
||||
|
||||
- if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) {
|
||||
+ if ((pidfd = fopen(path_dhclient_pid, "re")) != NULL) {
|
||||
e = fscanf(pidfd, "%ld\n", &temp);
|
||||
oldpid = (pid_t)temp;
|
||||
|
||||
@@ -826,7 +826,7 @@ main(int argc, char **argv) {
|
||||
strncpy(new_path_dhclient_pid, path_dhclient_pid, pfx);
|
||||
sprintf(new_path_dhclient_pid + pfx, "-%s.pid", ip->name);
|
||||
|
||||
- if ((pidfd = fopen(new_path_dhclient_pid, "r")) != NULL) {
|
||||
+ if ((pidfd = fopen(new_path_dhclient_pid, "re")) != NULL) {
|
||||
e = fscanf(pidfd, "%ld\n", &temp);
|
||||
oldpid = (pid_t)temp;
|
||||
|
||||
@@ -851,7 +851,7 @@ main(int argc, char **argv) {
|
||||
int dhc_running = 0;
|
||||
char procfn[256] = "";
|
||||
|
||||
- if ((pidfp = fopen(path_dhclient_pid, "r")) != NULL) {
|
||||
+ if ((pidfp = fopen(path_dhclient_pid, "re")) != NULL) {
|
||||
if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
|
||||
snprintf(procfn,256,"/proc/%u",dhcpid);
|
||||
dhc_running = (access(procfn, F_OK) == 0);
|
||||
@@ -4054,7 +4054,7 @@ void rewrite_client_leases ()
|
||||
|
||||
if (leaseFile != NULL)
|
||||
fclose (leaseFile);
|
||||
- leaseFile = fopen (path_dhclient_db, "w");
|
||||
+ leaseFile = fopen (path_dhclient_db, "we");
|
||||
if (leaseFile == NULL) {
|
||||
log_error ("can't create %s: %m", path_dhclient_db);
|
||||
return;
|
||||
@@ -4249,7 +4249,7 @@ write_duid(struct data_string *duid)
|
||||
return DHCP_R_INVALIDARG;
|
||||
|
||||
if (leaseFile == NULL) { /* XXX? */
|
||||
- leaseFile = fopen(path_dhclient_db, "w");
|
||||
+ leaseFile = fopen(path_dhclient_db, "we");
|
||||
if (leaseFile == NULL) {
|
||||
log_error("can't create %s: %m", path_dhclient_db);
|
||||
return ISC_R_IOERROR;
|
||||
@@ -4453,7 +4453,7 @@ int write_client_lease (client, lease, rewrite, makesure)
|
||||
return 1;
|
||||
|
||||
if (leaseFile == NULL) { /* XXX */
|
||||
- leaseFile = fopen (path_dhclient_db, "w");
|
||||
+ leaseFile = fopen (path_dhclient_db, "we");
|
||||
if (leaseFile == NULL) {
|
||||
log_error ("can't create %s: %m", path_dhclient_db);
|
||||
return 0;
|
||||
@@ -5039,9 +5039,9 @@ void detach ()
|
||||
(void) close(2);
|
||||
|
||||
/* Reopen them on /dev/null. */
|
||||
- (void) open("/dev/null", O_RDWR);
|
||||
- (void) open("/dev/null", O_RDWR);
|
||||
- (void) open("/dev/null", O_RDWR);
|
||||
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
|
||||
write_client_pid_file ();
|
||||
|
||||
@@ -5059,14 +5059,14 @@ void write_client_pid_file ()
|
||||
return;
|
||||
}
|
||||
|
||||
- pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
|
||||
+ pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
|
||||
|
||||
if (pfdesc < 0) {
|
||||
log_error ("Can't create %s: %m", path_dhclient_pid);
|
||||
return;
|
||||
}
|
||||
|
||||
- pf = fdopen (pfdesc, "w");
|
||||
+ pf = fdopen (pfdesc, "we");
|
||||
if (!pf) {
|
||||
close(pfdesc);
|
||||
log_error ("Can't fdopen %s: %m", path_dhclient_pid);
|
||||
diff --git a/common/bpf.c b/common/bpf.c
|
||||
index 0bffcbf..d2a0549 100644
|
||||
--- a/common/bpf.c
|
||||
+++ b/common/bpf.c
|
||||
@@ -94,7 +94,7 @@ int if_register_bpf (info)
|
||||
for (b = 0; 1; b++) {
|
||||
/* %Audit% 31 bytes max. %2004.06.17,Safe% */
|
||||
sprintf(filename, BPF_FORMAT, b);
|
||||
- sock = open (filename, O_RDWR, 0);
|
||||
+ sock = open (filename, O_RDWR | O_CLOEXEC, 0);
|
||||
if (sock < 0) {
|
||||
if (errno == EBUSY) {
|
||||
continue;
|
||||
diff --git a/common/dlpi.c b/common/dlpi.c
|
||||
index f2332c0..bf6e21f 100644
|
||||
--- a/common/dlpi.c
|
||||
+++ b/common/dlpi.c
|
||||
@@ -817,7 +817,7 @@ dlpiopen(const char *ifname) {
|
||||
}
|
||||
*dp = '\0';
|
||||
|
||||
- return open (devname, O_RDWR, 0);
|
||||
+ return open (devname, O_RDWR | O_CLOEXEC, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/common/nit.c b/common/nit.c
|
||||
index ba62488..4ebfa4a 100644
|
||||
--- a/common/nit.c
|
||||
+++ b/common/nit.c
|
||||
@@ -75,7 +75,7 @@ int if_register_nit (info)
|
||||
struct strioctl sio;
|
||||
|
||||
/* Open a NIT device */
|
||||
- sock = open ("/dev/nit", O_RDWR);
|
||||
+ sock = open ("/dev/nit", O_RDWR | O_CLOEXEC);
|
||||
if (sock < 0)
|
||||
log_fatal ("Can't open NIT device for %s: %m", info -> name);
|
||||
|
||||
diff --git a/common/resolv.c b/common/resolv.c
|
||||
index 5fd683f..3535f3e 100644
|
||||
--- a/common/resolv.c
|
||||
+++ b/common/resolv.c
|
||||
@@ -43,7 +43,7 @@ void read_resolv_conf (parse_time)
|
||||
struct domain_search_list *dp, *dl, *nd;
|
||||
isc_result_t status;
|
||||
|
||||
- if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
|
||||
+ if ((file = open (path_resolv_conf, O_RDONLY | O_CLOEXEC)) < 0) {
|
||||
log_error ("Can't open %s: %m", path_resolv_conf);
|
||||
return;
|
||||
}
|
||||
diff --git a/common/upf.c b/common/upf.c
|
||||
index 37e5cb2..b7c0649 100644
|
||||
--- a/common/upf.c
|
||||
+++ b/common/upf.c
|
||||
@@ -71,7 +71,7 @@ int if_register_upf (info)
|
||||
/* %Audit% Cannot exceed 36 bytes. %2004.06.17,Safe% */
|
||||
sprintf(filename, "/dev/pf/pfilt%d", b);
|
||||
|
||||
- sock = open (filename, O_RDWR, 0);
|
||||
+ sock = open (filename, O_RDWR | O_CLOEXEC, 0);
|
||||
if (sock < 0) {
|
||||
if (errno == EBUSY) {
|
||||
continue;
|
||||
diff --git a/omapip/trace.c b/omapip/trace.c
|
||||
index dc9185f..a605d18 100644
|
||||
--- a/omapip/trace.c
|
||||
+++ b/omapip/trace.c
|
||||
@@ -136,10 +136,10 @@ isc_result_t trace_begin (const char *filename,
|
||||
return DHCP_R_INVALIDARG;
|
||||
}
|
||||
|
||||
- traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL, 0600);
|
||||
+ traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL | O_CLOEXEC, 0600);
|
||||
if (traceoutfile < 0 && errno == EEXIST) {
|
||||
log_error ("WARNING: Overwriting trace file \"%s\"", filename);
|
||||
- traceoutfile = open (filename, O_WRONLY | O_EXCL | O_TRUNC,
|
||||
+ traceoutfile = open (filename, O_WRONLY | O_EXCL | O_TRUNC | O_CLOEXEC,
|
||||
0600);
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ void trace_file_replay (const char *filename)
|
||||
isc_result_t result;
|
||||
int len;
|
||||
|
||||
- traceinfile = fopen (filename, "r");
|
||||
+ traceinfile = fopen (filename, "re");
|
||||
if (!traceinfile) {
|
||||
log_error("Can't open tracefile %s: %m", filename);
|
||||
return;
|
||||
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||
index 946ef1b..a7b1286 100644
|
||||
--- a/relay/dhcrelay.c
|
||||
+++ b/relay/dhcrelay.c
|
||||
@@ -305,11 +305,11 @@ main(int argc, char **argv) {
|
||||
/* Make sure that file descriptors 0(stdin), 1,(stdout), and
|
||||
2(stderr) are open. To do this, we assume that when we
|
||||
open a file the lowest available file descriptor is used. */
|
||||
- fd = open("/dev/null", O_RDWR);
|
||||
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
if (fd == 0)
|
||||
- fd = open("/dev/null", O_RDWR);
|
||||
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
if (fd == 1)
|
||||
- fd = open("/dev/null", O_RDWR);
|
||||
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
if (fd == 2)
|
||||
log_perror = 0; /* No sense logging to /dev/null. */
|
||||
else if (fd != -1)
|
||||
@@ -800,13 +800,13 @@ main(int argc, char **argv) {
|
||||
/* Create the pid file. */
|
||||
if (no_pid_file == ISC_FALSE) {
|
||||
pfdesc = open(path_dhcrelay_pid,
|
||||
- O_CREAT | O_TRUNC | O_WRONLY, 0644);
|
||||
+ O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
|
||||
|
||||
if (pfdesc < 0) {
|
||||
log_error("Can't create %s: %m",
|
||||
path_dhcrelay_pid);
|
||||
} else {
|
||||
- pf = fdopen(pfdesc, "w");
|
||||
+ pf = fdopen(pfdesc, "we");
|
||||
if (!pf)
|
||||
log_error("Can't fdopen %s: %m",
|
||||
path_dhcrelay_pid);
|
||||
diff --git a/server/confpars.c b/server/confpars.c
|
||||
index 103af1e..5a6396b 100644
|
||||
--- a/server/confpars.c
|
||||
+++ b/server/confpars.c
|
||||
@@ -118,7 +118,7 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
|
||||
}
|
||||
#endif
|
||||
|
||||
- if ((file = open (filename, O_RDONLY)) < 0) {
|
||||
+ if ((file = open (filename, O_RDONLY | O_CLOEXEC)) < 0) {
|
||||
if (leasep) {
|
||||
log_error ("Can't open lease database %s: %m --",
|
||||
path_dhcpd_db);
|
||||
diff --git a/server/db.c b/server/db.c
|
||||
index cecbf6b..4243a92 100644
|
||||
--- a/server/db.c
|
||||
+++ b/server/db.c
|
||||
@@ -1154,7 +1154,7 @@ int new_lease_file (int test_mode)
|
||||
path_dhcpd_db, (int)t) >= sizeof newfname)
|
||||
log_fatal("new_lease_file: lease file path too long");
|
||||
|
||||
- db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT, 0664);
|
||||
+ db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0664);
|
||||
if (db_fd < 0) {
|
||||
log_error ("Can't create new lease file: %m");
|
||||
return 0;
|
||||
@@ -1175,7 +1175,7 @@ int new_lease_file (int test_mode)
|
||||
}
|
||||
#endif /* PARANOIA */
|
||||
|
||||
- if ((new_db_file = fdopen(db_fd, "w")) == NULL) {
|
||||
+ if ((new_db_file = fdopen(db_fd, "we")) == NULL) {
|
||||
log_error("Can't fdopen new lease file: %m");
|
||||
close(db_fd);
|
||||
goto fdfail;
|
||||
diff --git a/server/dhcpd.c b/server/dhcpd.c
|
||||
index 3522889..845d0cc 100644
|
||||
--- a/server/dhcpd.c
|
||||
+++ b/server/dhcpd.c
|
||||
@@ -300,11 +300,11 @@ main(int argc, char **argv) {
|
||||
/* Make sure that file descriptors 0 (stdin), 1, (stdout), and
|
||||
2 (stderr) are open. To do this, we assume that when we
|
||||
open a file the lowest available file descriptor is used. */
|
||||
- fd = open("/dev/null", O_RDWR);
|
||||
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
if (fd == 0)
|
||||
- fd = open("/dev/null", O_RDWR);
|
||||
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
if (fd == 1)
|
||||
- fd = open("/dev/null", O_RDWR);
|
||||
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
if (fd == 2)
|
||||
log_perror = 0; /* No sense logging to /dev/null. */
|
||||
else if (fd != -1)
|
||||
@@ -975,7 +975,7 @@ main(int argc, char **argv) {
|
||||
* appropriate.
|
||||
*/
|
||||
if (no_pid_file == ISC_FALSE) {
|
||||
- i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
||||
+ i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
|
||||
if (i >= 0) {
|
||||
sprintf(pbuf, "%d\n", (int) getpid());
|
||||
IGNORE_RET(write(i, pbuf, strlen(pbuf)));
|
||||
@@ -1028,9 +1028,9 @@ main(int argc, char **argv) {
|
||||
(void) close(2);
|
||||
|
||||
/* Reopen them on /dev/null. */
|
||||
- (void) open("/dev/null", O_RDWR);
|
||||
- (void) open("/dev/null", O_RDWR);
|
||||
- (void) open("/dev/null", O_RDWR);
|
||||
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
log_perror = 0; /* No sense logging to /dev/null. */
|
||||
|
||||
IGNORE_RET (chdir("/"));
|
||||
diff --git a/server/ldap.c b/server/ldap.c
|
||||
index e3e48f4..1a68936 100644
|
||||
--- a/server/ldap.c
|
||||
+++ b/server/ldap.c
|
||||
@@ -1447,7 +1447,7 @@ ldap_start (void)
|
||||
|
||||
if (ldap_debug_file != NULL && ldap_debug_fd == -1)
|
||||
{
|
||||
- if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY,
|
||||
+ if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC,
|
||||
S_IRUSR | S_IWUSR)) < 0)
|
||||
log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file,
|
||||
strerror (errno));
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,26 +0,0 @@
|
||||
From cfe6414644b68d5b6b5ba150bf57cff0a709a59e Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:28:13 +0100
|
||||
Subject: [PATCH 09/28] Fix 'garbage in format string' error
|
||||
|
||||
RHBZ: 450042
|
||||
---
|
||||
common/tables.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/common/tables.c b/common/tables.c
|
||||
index be37737..ce12fcd 100644
|
||||
--- a/common/tables.c
|
||||
+++ b/common/tables.c
|
||||
@@ -222,7 +222,7 @@ static struct option dhcp_options[] = {
|
||||
{ "name-service-search", "Sa", &dhcp_universe, 117, 1 },
|
||||
#endif
|
||||
{ "subnet-selection", "I", &dhcp_universe, 118, 1 },
|
||||
- { "domain-search", "Dc", &dhcp_universe, 119, 1 },
|
||||
+ { "domain-search", "D", &dhcp_universe, 119, 1 },
|
||||
{ "vivco", "Evendor-class.", &dhcp_universe, 124, 1 },
|
||||
{ "vivso", "Evendor.", &dhcp_universe, 125, 1 },
|
||||
#if 0
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 7653f3ea80230d4b38bff1c65164aa18c6e51519 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:29:08 +0100
|
||||
Subject: [PATCH 10/28] Handle null timeout
|
||||
|
||||
Handle cases in add_timeout() where the function is called with a NULL
|
||||
value for the 'when' parameter
|
||||
|
||||
ISC-Bugs: #19867 (rejected)
|
||||
---
|
||||
common/dispatch.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/common/dispatch.c b/common/dispatch.c
|
||||
index 7def34c..9741ff5 100644
|
||||
--- a/common/dispatch.c
|
||||
+++ b/common/dispatch.c
|
||||
@@ -209,6 +209,10 @@ void add_timeout (when, where, what, ref, unref)
|
||||
isc_interval_t interval;
|
||||
isc_time_t expires;
|
||||
|
||||
+ if (when == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* See if this timeout supersedes an existing timeout. */
|
||||
t = (struct timeout *)0;
|
||||
for (q = timeouts; q; q = q->next) {
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,276 +0,0 @@
|
||||
From 7ea2433d716172f160c9380ed0bb852fafe845a2 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:30:28 +0100
|
||||
Subject: [PATCH 11/28] Drop unnecessary capabilities
|
||||
|
||||
dhclient (#517649, #546765), dhcpd/dhcrelay (#699713)
|
||||
---
|
||||
client/Makefile.am | 3 ++-
|
||||
client/dhclient-script.8 | 10 ++++++++++
|
||||
client/dhclient.8 | 29 +++++++++++++++++++++++++++++
|
||||
client/dhclient.c | 24 ++++++++++++++++++++++++
|
||||
configure.ac | 35 +++++++++++++++++++++++++++++++++++
|
||||
relay/Makefile.am | 3 ++-
|
||||
relay/dhcrelay.c | 29 +++++++++++++++++++++++++++++
|
||||
7 files changed, 131 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/client/Makefile.am b/client/Makefile.am
|
||||
index d177159..0689185 100644
|
||||
--- a/client/Makefile.am
|
||||
+++ b/client/Makefile.am
|
||||
@@ -17,6 +17,7 @@ dhclient_LDADD = ../common/libdhcp.@A@ ../omapip/libomapi.@A@ \
|
||||
@BINDLIBIRSDIR@/libirs.@A@ \
|
||||
@BINDLIBDNSDIR@/libdns.@A@ \
|
||||
@BINDLIBISCCFGDIR@/libisccfg.@A@ \
|
||||
- @BINDLIBISCDIR@/libisc.@A@
|
||||
+ @BINDLIBISCDIR@/libisc.@A@ \
|
||||
+ $(CAPNG_LDADD)
|
||||
man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
diff --git a/client/dhclient-script.8 b/client/dhclient-script.8
|
||||
index 37ecdc5..1a88e0e 100644
|
||||
--- a/client/dhclient-script.8
|
||||
+++ b/client/dhclient-script.8
|
||||
@@ -249,6 +249,16 @@ repeatedly initialized to the values provided by one server, and then
|
||||
the other. Assuming the information provided by both servers is
|
||||
valid, this shouldn't cause any real problems, but it could be
|
||||
confusing.
|
||||
+.PP
|
||||
+Normally, if dhclient was compiled with libcap-ng support,
|
||||
+dhclient drops most capabilities immediately upon startup.
|
||||
+While more secure, this greatly restricts the additional actions that
|
||||
+hooks in dhclient-script can take. For example, any daemons that
|
||||
+dhclient-script starts or restarts will inherit the restricted
|
||||
+capabilities as well, which may interfere with their correct operation.
|
||||
+Thus, the
|
||||
+.BI \-nc
|
||||
+option can be used to prevent dhclient from dropping capabilities.
|
||||
.SH SEE ALSO
|
||||
dhclient(8), dhcpd(8), dhcrelay(8), dhclient.conf(5) and
|
||||
dhclient.leases(5).
|
||||
diff --git a/client/dhclient.8 b/client/dhclient.8
|
||||
index 5029dac..bacf3bc 100644
|
||||
--- a/client/dhclient.8
|
||||
+++ b/client/dhclient.8
|
||||
@@ -135,6 +135,9 @@ dhclient - Dynamic Host Configuration Protocol Client
|
||||
.B -w
|
||||
]
|
||||
[
|
||||
+.B -nc
|
||||
+]
|
||||
+[
|
||||
.B -B
|
||||
]
|
||||
[
|
||||
@@ -329,6 +332,32 @@ not to exit when it doesn't find any such interfaces. The
|
||||
program can then be used to notify the client when a network interface
|
||||
has been added or removed, so that the client can attempt to configure an IP
|
||||
address on that interface.
|
||||
+.TP
|
||||
+.BI \-nc
|
||||
+Do not drop capabilities.
|
||||
+
|
||||
+Normally, if
|
||||
+.B dhclient
|
||||
+was compiled with libcap-ng support,
|
||||
+.B dhclient
|
||||
+drops most capabilities immediately upon startup. While more secure,
|
||||
+this greatly restricts the additional actions that hooks in
|
||||
+.B dhclient-script (8)
|
||||
+can take. (For example, any daemons that
|
||||
+.B dhclient-script (8)
|
||||
+starts or restarts will inherit the restricted capabilities as well,
|
||||
+which may interfere with their correct operation.) Thus, the
|
||||
+.BI \-nc
|
||||
+option can be used to prevent
|
||||
+.B dhclient
|
||||
+from dropping capabilities.
|
||||
+
|
||||
+The
|
||||
+.BI \-nc
|
||||
+option is ignored if
|
||||
+.B dhclient
|
||||
+was not compiled with libcap-ng support.
|
||||
+
|
||||
.TP
|
||||
.BI \-n
|
||||
Do not configure any interfaces. This is most likely to be useful in
|
||||
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||
index aefc119..b49fcb3 100644
|
||||
--- a/client/dhclient.c
|
||||
+++ b/client/dhclient.c
|
||||
@@ -41,6 +41,10 @@
|
||||
#include <sys/wait.h>
|
||||
#include <limits.h>
|
||||
|
||||
+#ifdef HAVE_LIBCAP_NG
|
||||
+#include <cap-ng.h>
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
|
||||
* that when building ISC code.
|
||||
@@ -272,6 +276,9 @@ main(int argc, char **argv) {
|
||||
int timeout_arg = 0;
|
||||
char *arg_conf = NULL;
|
||||
int arg_conf_len = 0;
|
||||
+#ifdef HAVE_LIBCAP_NG
|
||||
+ int keep_capabilities = 0;
|
||||
+#endif
|
||||
|
||||
/* Initialize client globals. */
|
||||
memset(&default_duid, 0, sizeof(default_duid));
|
||||
@@ -671,6 +678,10 @@ main(int argc, char **argv) {
|
||||
|
||||
dhclient_request_options = argv[i];
|
||||
|
||||
+ } else if (!strcmp(argv[i], "-nc")) {
|
||||
+#ifdef HAVE_LIBCAP_NG
|
||||
+ keep_capabilities = 1;
|
||||
+#endif
|
||||
} else if (argv[i][0] == '-') {
|
||||
usage("Unknown command: %s", argv[i]);
|
||||
} else if (interfaces_requested < 0) {
|
||||
@@ -731,6 +742,19 @@ main(int argc, char **argv) {
|
||||
path_dhclient_script = s;
|
||||
}
|
||||
|
||||
+#ifdef HAVE_LIBCAP_NG
|
||||
+ /* Drop capabilities */
|
||||
+ if (!keep_capabilities) {
|
||||
+ capng_clear(CAPNG_SELECT_CAPS);
|
||||
+ capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
|
||||
+ CAP_DAC_OVERRIDE); // Drop this someday
|
||||
+ capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
|
||||
+ CAP_NET_ADMIN, CAP_NET_RAW,
|
||||
+ CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
|
||||
+ capng_apply(CAPNG_SELECT_CAPS);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/* Set up the initial dhcp option universe. */
|
||||
initialize_common_option_spaces();
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index b2c306b..300117f 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -603,6 +603,41 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[void foo() __attribute__((noreturn));
|
||||
# Look for optional headers.
|
||||
AC_CHECK_HEADERS(sys/socket.h net/if_dl.h net/if6.h regex.h)
|
||||
|
||||
+# look for capabilities library
|
||||
+AC_ARG_WITH(libcap-ng,
|
||||
+ [ --with-libcap-ng=[auto/yes/no] Add Libcap-ng support [default=auto]],,
|
||||
+ with_libcap_ng=auto)
|
||||
+
|
||||
+# Check for Libcap-ng API
|
||||
+#
|
||||
+# libcap-ng detection
|
||||
+if test x$with_libcap_ng = xno ; then
|
||||
+ have_libcap_ng=no;
|
||||
+else
|
||||
+ # Start by checking for header file
|
||||
+ AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no)
|
||||
+
|
||||
+ # See if we have libcap-ng library
|
||||
+ AC_CHECK_LIB(cap-ng, capng_clear,
|
||||
+ CAPNG_LDADD=-lcap-ng,)
|
||||
+
|
||||
+ # Check results are usable
|
||||
+ if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then
|
||||
+ AC_MSG_ERROR(libcap-ng support was requested and the library was not found)
|
||||
+ fi
|
||||
+ if test x$CAPNG_LDADD != x -a $capng_headers = no ; then
|
||||
+ AC_MSG_ERROR(libcap-ng libraries found but headers are missing)
|
||||
+ fi
|
||||
+fi
|
||||
+AC_SUBST(CAPNG_LDADD)
|
||||
+AC_MSG_CHECKING(whether to use libcap-ng)
|
||||
+if test x$CAPNG_LDADD != x ; then
|
||||
+ AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support])
|
||||
+ AC_MSG_RESULT(yes)
|
||||
+else
|
||||
+ AC_MSG_RESULT(no)
|
||||
+fi
|
||||
+
|
||||
# Solaris needs some libraries for functions
|
||||
AC_SEARCH_LIBS(socket, [socket])
|
||||
AC_SEARCH_LIBS(inet_ntoa, [nsl])
|
||||
diff --git a/relay/Makefile.am b/relay/Makefile.am
|
||||
index 5562b69..4c5cfa6 100644
|
||||
--- a/relay/Makefile.am
|
||||
+++ b/relay/Makefile.am
|
||||
@@ -8,6 +8,7 @@ dhcrelay_LDADD = ../common/libdhcp.@A@ ../omapip/libomapi.@A@ \
|
||||
@BINDLIBIRSDIR@/libirs.@A@ \
|
||||
@BINDLIBDNSDIR@/libdns.@A@ \
|
||||
@BINDLIBISCCFGDIR@/libisccfg.@A@ \
|
||||
- @BINDLIBISCDIR@/libisc.@A@
|
||||
+ @BINDLIBISCDIR@/libisc.@A@ \
|
||||
+ $(CAPNG_LDADD)
|
||||
man_MANS = dhcrelay.8
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||
index a7b1286..0dc17d6 100644
|
||||
--- a/relay/dhcrelay.c
|
||||
+++ b/relay/dhcrelay.c
|
||||
@@ -32,6 +32,11 @@
|
||||
#include <sys/time.h>
|
||||
#include <isc/file.h>
|
||||
|
||||
+#ifdef HAVE_LIBCAP_NG
|
||||
+# include <cap-ng.h>
|
||||
+ int keep_capabilities = 0;
|
||||
+#endif
|
||||
+
|
||||
TIME default_lease_time = 43200; /* 12 hours... */
|
||||
TIME max_lease_time = 86400; /* 24 hours... */
|
||||
struct tree_cache *global_options[256];
|
||||
@@ -614,6 +619,10 @@ main(int argc, char **argv) {
|
||||
if (++i == argc)
|
||||
usage(use_noarg, argv[i-1]);
|
||||
dhcrelay_sub_id = argv[i];
|
||||
+#endif
|
||||
+ } else if (!strcmp(argv[i], "-nc")) {
|
||||
+#ifdef HAVE_LIBCAP_NG
|
||||
+ keep_capabilities = 1;
|
||||
#endif
|
||||
} else if (!strcmp(argv[i], "-pf")) {
|
||||
if (++i == argc)
|
||||
@@ -684,6 +693,17 @@ main(int argc, char **argv) {
|
||||
#endif
|
||||
}
|
||||
|
||||
+#ifdef HAVE_LIBCAP_NG
|
||||
+ /* Drop capabilities */
|
||||
+ if (!keep_capabilities) {
|
||||
+ capng_clear(CAPNG_SELECT_BOTH);
|
||||
+ capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
|
||||
+ CAP_NET_RAW, CAP_NET_BIND_SERVICE, -1);
|
||||
+ capng_apply(CAPNG_SELECT_BOTH);
|
||||
+ log_info ("Dropped all unnecessary capabilities.");
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (!quiet) {
|
||||
log_info("%s %s", message, PACKAGE_VERSION);
|
||||
log_info(copyright);
|
||||
@@ -840,6 +860,15 @@ main(int argc, char **argv) {
|
||||
signal(SIGTERM, dhcp_signal_handler); /* kill */
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_LIBCAP_NG
|
||||
+ /* Drop all capabilities */
|
||||
+ if (!keep_capabilities) {
|
||||
+ capng_clear(CAPNG_SELECT_BOTH);
|
||||
+ capng_apply(CAPNG_SELECT_BOTH);
|
||||
+ log_info ("Dropped all capabilities.");
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/* Start dispatching packets and timeouts... */
|
||||
dispatch();
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,436 +0,0 @@
|
||||
From 7e6299e72feaaf7e8bd499614999ba8a07dd1a8a Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:32:35 +0100
|
||||
Subject: [PATCH 12/28] RFC 3442 - Classless Static Route Option for DHCPv4
|
||||
(#516325)
|
||||
|
||||
(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #24572])
|
||||
---
|
||||
client/clparse.c | 13 ++++++++--
|
||||
common/dhcp-options.5 | 43 +++++++++++++++++++++++++++++++++
|
||||
common/inet.c | 54 +++++++++++++++++++++++++++++++++++++++++
|
||||
common/options.c | 49 ++++++++++++++++++++++++++++++++++++-
|
||||
common/parse.c | 56 ++++++++++++++++++++++++++++++++++++++++++-
|
||||
common/tables.c | 2 ++
|
||||
includes/dhcp.h | 1 +
|
||||
includes/dhcpd.h | 2 ++
|
||||
includes/dhctoken.h | 3 ++-
|
||||
9 files changed, 218 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/client/clparse.c b/client/clparse.c
|
||||
index 902b523..57f6456 100644
|
||||
--- a/client/clparse.c
|
||||
+++ b/client/clparse.c
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
struct client_config top_level_config;
|
||||
|
||||
-#define NUM_DEFAULT_REQUESTED_OPTS 14
|
||||
+#define NUM_DEFAULT_REQUESTED_OPTS 15
|
||||
/* There can be 2 extra requested options for DHCPv4-over-DHCPv6. */
|
||||
struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 2 + 1];
|
||||
|
||||
@@ -90,7 +90,11 @@ isc_result_t read_client_conf ()
|
||||
dhcp_universe.code_hash, &code, 0, MDL);
|
||||
|
||||
/* 4 */
|
||||
- code = DHO_ROUTERS;
|
||||
+ /* The Classless Static Routes option code MUST appear in the parameter
|
||||
+ * request list prior to both the Router option code and the Static
|
||||
+ * Routes option code, if present. (RFC3442)
|
||||
+ */
|
||||
+ code = DHO_CLASSLESS_STATIC_ROUTES;
|
||||
option_code_hash_lookup(&default_requested_options[3],
|
||||
dhcp_universe.code_hash, &code, 0, MDL);
|
||||
|
||||
@@ -144,6 +148,11 @@ isc_result_t read_client_conf ()
|
||||
option_code_hash_lookup(&default_requested_options[13],
|
||||
dhcp_universe.code_hash, &code, 0, MDL);
|
||||
|
||||
+ /* 15 */
|
||||
+ code = DHO_ROUTERS;
|
||||
+ option_code_hash_lookup(&default_requested_options[14],
|
||||
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||
+
|
||||
for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) {
|
||||
if (default_requested_options[code] == NULL)
|
||||
log_fatal("Unable to find option definition for "
|
||||
diff --git a/common/dhcp-options.5 b/common/dhcp-options.5
|
||||
index a784b32..86f04ed 100644
|
||||
--- a/common/dhcp-options.5
|
||||
+++ b/common/dhcp-options.5
|
||||
@@ -117,6 +117,26 @@ hexadecimal, separated by colons. For example:
|
||||
or
|
||||
option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f;
|
||||
.fi
|
||||
+.PP
|
||||
+The
|
||||
+.B destination-descriptor
|
||||
+describe the IP subnet number and subnet mask
|
||||
+of a particular destination using a compact encoding. This encoding
|
||||
+consists of one octet describing the width of the subnet mask,
|
||||
+followed by all the significant octets of the subnet number.
|
||||
+The following table contains some examples of how various subnet
|
||||
+number/mask combinations can be encoded:
|
||||
+.nf
|
||||
+.sp 1
|
||||
+Subnet number Subnet mask Destination descriptor
|
||||
+0 0 0
|
||||
+10.0.0.0 255.0.0.0 8.10
|
||||
+10.0.0.0 255.255.255.0 24.10.0.0
|
||||
+10.17.0.0 255.255.0.0 16.10.17
|
||||
+10.27.129.0 255.255.255.0 24.10.27.129
|
||||
+10.229.0.128 255.255.255.128 25.10.229.0.128
|
||||
+10.198.122.47 255.255.255.255 32.10.198.122.47
|
||||
+.fi
|
||||
.SH SETTING OPTION VALUES USING EXPRESSIONS
|
||||
Sometimes it's helpful to be able to set the value of a DHCP option
|
||||
based on some value that the client has sent. To do this, you can
|
||||
@@ -1093,6 +1113,29 @@ dhclient-script will create routes:
|
||||
.RE
|
||||
.PP
|
||||
.nf
|
||||
+.B option \fBclassless-static-routes\fR \fIdestination-descriptor ip-address\fR
|
||||
+ [\fB,\fR \fIdestination-descriptor ip-address\fR...]\fB;\fR
|
||||
+.fi
|
||||
+.RS 0.25i
|
||||
+.PP
|
||||
+This option (see RFC3442) specifies a list of classless static routes
|
||||
+that the client should install in its routing cache.
|
||||
+.PP
|
||||
+This option can contain one or more static routes, each of which
|
||||
+consists of a destination descriptor and the IP address of the router
|
||||
+that should be used to reach that destination.
|
||||
+.PP
|
||||
+Many clients may not implement the Classless Static Routes option.
|
||||
+DHCP server administrators should therefore configure their DHCP
|
||||
+servers to send both a Router option and a Classless Static Routes
|
||||
+option, and should specify the default router(s) both in the Router
|
||||
+option and in the Classless Static Routes option.
|
||||
+.PP
|
||||
+If the DHCP server returns both a Classless Static Routes option and
|
||||
+a Router option, the DHCP client ignores the Router option.
|
||||
+.RE
|
||||
+.PP
|
||||
+.nf
|
||||
.B option \fBstreettalk-directory-assistance-server\fR \fIip-address\fR
|
||||
[\fB,\fR \fIip-address\fR...]\fB;\fR
|
||||
.fi
|
||||
diff --git a/common/inet.c b/common/inet.c
|
||||
index 0f7f168..7c446d4 100644
|
||||
--- a/common/inet.c
|
||||
+++ b/common/inet.c
|
||||
@@ -519,6 +519,60 @@ free_iaddrcidrnetlist(struct iaddrcidrnetlist **result) {
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
+static const char *
|
||||
+inet_ntopdd(const unsigned char *src, unsigned srclen, char *dst, size_t size)
|
||||
+{
|
||||
+ char tmp[sizeof("32.255.255.255.255")];
|
||||
+ int len;
|
||||
+
|
||||
+ switch (srclen) {
|
||||
+ case 2:
|
||||
+ len = sprintf (tmp, "%u.%u", src[0], src[1]);
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ len = sprintf (tmp, "%u.%u.%u", src[0], src[1], src[2]);
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ len = sprintf (tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]);
|
||||
+ break;
|
||||
+ case 5:
|
||||
+ len = sprintf (tmp, "%u.%u.%u.%u.%u", src[0], src[1], src[2], src[3], src[4]);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if (len < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (len > size) {
|
||||
+ errno = ENOSPC;
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return strcpy (dst, tmp);
|
||||
+}
|
||||
+
|
||||
+/* pdestdesc() turns an iaddr structure into a printable dest. descriptor */
|
||||
+const char *
|
||||
+pdestdesc(const struct iaddr addr) {
|
||||
+ static char pbuf[sizeof("255.255.255.255.255")];
|
||||
+
|
||||
+ if (addr.len == 0) {
|
||||
+ return "<null destination descriptor>";
|
||||
+ }
|
||||
+ if (addr.len == 1) {
|
||||
+ return "0";
|
||||
+ }
|
||||
+ if ((addr.len >= 2) && (addr.len <= 5)) {
|
||||
+ return inet_ntopdd(addr.iabuf, addr.len, pbuf, sizeof(pbuf));
|
||||
+ }
|
||||
+
|
||||
+ log_fatal("pdestdesc():%s:%d: Invalid destination descriptor length %d.",
|
||||
+ MDL, addr.len);
|
||||
+ /* quell compiler warnings */
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
/* piaddr() turns an iaddr structure into a printable address. */
|
||||
/* XXX: should use a const pointer rather than passing the structure */
|
||||
const char *
|
||||
diff --git a/common/options.c b/common/options.c
|
||||
index 92c8fee..66433c4 100644
|
||||
--- a/common/options.c
|
||||
+++ b/common/options.c
|
||||
@@ -734,7 +734,11 @@ cons_options(struct packet *inpacket, struct dhcp_packet *outpacket,
|
||||
* packet.
|
||||
*/
|
||||
priority_list[priority_len++] = DHO_SUBNET_MASK;
|
||||
- priority_list[priority_len++] = DHO_ROUTERS;
|
||||
+ if (lookup_option(&dhcp_universe, cfg_options,
|
||||
+ DHO_CLASSLESS_STATIC_ROUTES))
|
||||
+ priority_list[priority_len++] = DHO_CLASSLESS_STATIC_ROUTES;
|
||||
+ else
|
||||
+ priority_list[priority_len++] = DHO_ROUTERS;
|
||||
priority_list[priority_len++] = DHO_DOMAIN_NAME_SERVERS;
|
||||
priority_list[priority_len++] = DHO_HOST_NAME;
|
||||
priority_list[priority_len++] = DHO_FQDN;
|
||||
@@ -1812,6 +1816,7 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
||||
unsigned long tval;
|
||||
isc_boolean_t a_array = ISC_FALSE;
|
||||
int len_used;
|
||||
+ unsigned int octets = 0;
|
||||
|
||||
if (emit_commas)
|
||||
comma = ',';
|
||||
@@ -1820,6 +1825,7 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
||||
|
||||
memset (enumbuf, 0, sizeof enumbuf);
|
||||
|
||||
+ if (option->format[0] != 'R') { /* see explanation lower */
|
||||
/* Figure out the size of the data. */
|
||||
for (l = i = 0; option -> format [i]; i++, l++) {
|
||||
if (l >= sizeof(fmtbuf) - 1)
|
||||
@@ -2029,6 +2035,33 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
||||
if (numhunk < 0)
|
||||
numhunk = 1;
|
||||
|
||||
+ } else { /* option->format[i] == 'R') */
|
||||
+ /* R (destination descriptor) has variable length.
|
||||
+ * We can find it only in classless static route option,
|
||||
+ * so we are for sure parsing classless static route option now.
|
||||
+ * We go through whole the option to check whether there are no
|
||||
+ * missing/extra bytes.
|
||||
+ * I didn't find out how to improve the existing code and that's the
|
||||
+ * reason for this separate 'else' where I do my own checkings.
|
||||
+ * I know it's little bit unsystematic, but it works.
|
||||
+ */
|
||||
+ numhunk = 0;
|
||||
+ numelem = 2; /* RI */
|
||||
+ fmtbuf[0]='R'; fmtbuf[1]='I'; fmtbuf[2]=0;
|
||||
+ for (i =0; i < len; i = i + octets + 5) {
|
||||
+ if (data[i] > 32) { /* subnet mask width */
|
||||
+ log_error ("wrong subnet mask width in destination descriptor");
|
||||
+ break;
|
||||
+ }
|
||||
+ numhunk++;
|
||||
+ octets = ((data[i]+7) / 8);
|
||||
+ }
|
||||
+ if (i != len) {
|
||||
+ log_error ("classless static routes option has wrong size or "
|
||||
+ "there's some garbage in format");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Cycle through the array (or hunk) printing the data. */
|
||||
for (i = 0; i < numhunk; i++) {
|
||||
if ((a_array == ISC_TRUE) && (i != 0) && (numelem > 0)) {
|
||||
@@ -2197,6 +2230,20 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
||||
strcpy(op, piaddr(iaddr));
|
||||
dp += 4;
|
||||
break;
|
||||
+
|
||||
+ case 'R':
|
||||
+ if (dp[0] <= 32)
|
||||
+ iaddr.len = (((dp[0]+7)/8)+1);
|
||||
+ else {
|
||||
+ log_error ("wrong subnet mask width in destination descriptor");
|
||||
+ return "<error>";
|
||||
+ }
|
||||
+
|
||||
+ memcpy(iaddr.iabuf, dp, iaddr.len);
|
||||
+ strcpy(op, pdestdesc(iaddr));
|
||||
+ dp += iaddr.len;
|
||||
+ break;
|
||||
+
|
||||
case '6':
|
||||
iaddr.len = 16;
|
||||
memcpy(iaddr.iabuf, dp, 16);
|
||||
diff --git a/common/parse.c b/common/parse.c
|
||||
index b123a6c..7cf4f2a 100644
|
||||
--- a/common/parse.c
|
||||
+++ b/common/parse.c
|
||||
@@ -344,6 +344,39 @@ int parse_ip_addr (cfile, addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * destination-descriptor :== NUMBER DOT NUMBER |
|
||||
+ * NUMBER DOT NUMBER DOT NUMBER |
|
||||
+ * NUMBER DOT NUMBER DOT NUMBER DOT NUMBER |
|
||||
+ * NUMBER DOT NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
|
||||
+ */
|
||||
+
|
||||
+int parse_destination_descriptor (cfile, addr)
|
||||
+ struct parse *cfile;
|
||||
+ struct iaddr *addr;
|
||||
+{
|
||||
+ unsigned int mask_width, dest_dest_len;
|
||||
+ addr -> len = 0;
|
||||
+ if (parse_numeric_aggregate (cfile, addr -> iabuf,
|
||||
+ &addr -> len, DOT, 10, 8)) {
|
||||
+ mask_width = (unsigned int)addr->iabuf[0];
|
||||
+ dest_dest_len = (((mask_width+7)/8)+1);
|
||||
+ if (mask_width > 32) {
|
||||
+ parse_warn (cfile,
|
||||
+ "subnet mask width (%u) greater than 32.", mask_width);
|
||||
+ }
|
||||
+ else if (dest_dest_len != addr->len) {
|
||||
+ parse_warn (cfile,
|
||||
+ "destination descriptor with subnet mask width %u "
|
||||
+ "should have %u octets, but has %u octets.",
|
||||
+ mask_width, dest_dest_len, addr->len);
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Return true if every character in the string is hexadecimal.
|
||||
*/
|
||||
@@ -724,8 +757,10 @@ unsigned char *parse_numeric_aggregate (cfile, buf,
|
||||
if (count) {
|
||||
token = peek_token (&val, (unsigned *)0, cfile);
|
||||
if (token != separator) {
|
||||
- if (!*max)
|
||||
+ if (!*max) {
|
||||
+ *max = count;
|
||||
break;
|
||||
+ }
|
||||
if (token != RBRACE && token != LBRACE)
|
||||
token = next_token (&val,
|
||||
(unsigned *)0,
|
||||
@@ -1672,6 +1707,9 @@ int parse_option_code_definition (cfile, option)
|
||||
case IP_ADDRESS:
|
||||
type = 'I';
|
||||
break;
|
||||
+ case DESTINATION_DESCRIPTOR:
|
||||
+ type = 'R';
|
||||
+ break;
|
||||
case IP6_ADDRESS:
|
||||
type = '6';
|
||||
break;
|
||||
@@ -5124,6 +5162,15 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
|
||||
}
|
||||
break;
|
||||
|
||||
+ case 'R': /* destination descriptor */
|
||||
+ if (!parse_destination_descriptor (cfile, &addr)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (!make_const_data (&t, addr.iabuf, addr.len, 0, 1, MDL)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
case '6': /* IPv6 address. */
|
||||
if (!parse_ip6_addr(cfile, &addr)) {
|
||||
return 0;
|
||||
@@ -5401,6 +5448,13 @@ int parse_option_decl (oc, cfile)
|
||||
goto exit;
|
||||
len = ip_addr.len;
|
||||
dp = ip_addr.iabuf;
|
||||
+ goto alloc;
|
||||
+
|
||||
+ case 'R': /* destination descriptor */
|
||||
+ if (!parse_destination_descriptor (cfile, &ip_addr))
|
||||
+ goto exit;
|
||||
+ len = ip_addr.len;
|
||||
+ dp = ip_addr.iabuf;
|
||||
|
||||
alloc:
|
||||
if (hunkix + len > sizeof hunkbuf) {
|
||||
diff --git a/common/tables.c b/common/tables.c
|
||||
index ce12fcd..96521a6 100644
|
||||
--- a/common/tables.c
|
||||
+++ b/common/tables.c
|
||||
@@ -45,6 +45,7 @@ HASH_FUNCTIONS (option_code, const unsigned *, struct option,
|
||||
Format codes:
|
||||
|
||||
I - IPv4 address
|
||||
+ R - destination descriptor (RFC3442)
|
||||
6 - IPv6 address
|
||||
l - 32-bit signed integer
|
||||
L - 32-bit unsigned integer
|
||||
@@ -223,6 +224,7 @@ static struct option dhcp_options[] = {
|
||||
#endif
|
||||
{ "subnet-selection", "I", &dhcp_universe, 118, 1 },
|
||||
{ "domain-search", "D", &dhcp_universe, 119, 1 },
|
||||
+ { "classless-static-routes", "RIA", &dhcp_universe, 121, 1 },
|
||||
{ "vivco", "Evendor-class.", &dhcp_universe, 124, 1 },
|
||||
{ "vivso", "Evendor.", &dhcp_universe, 125, 1 },
|
||||
#if 0
|
||||
diff --git a/includes/dhcp.h b/includes/dhcp.h
|
||||
index cafe172..5a73129 100644
|
||||
--- a/includes/dhcp.h
|
||||
+++ b/includes/dhcp.h
|
||||
@@ -159,6 +159,7 @@ struct dhcp_packet {
|
||||
#define DHO_V6_ONLY_PREFERRED 108 /* RFC8925 */
|
||||
#define DHO_SUBNET_SELECTION 118 /* RFC3011! */
|
||||
#define DHO_DOMAIN_SEARCH 119 /* RFC3397 */
|
||||
+#define DHO_CLASSLESS_STATIC_ROUTES 121 /* RFC3442 */
|
||||
#define DHO_VIVCO_SUBOPTIONS 124
|
||||
#define DHO_VIVSO_SUBOPTIONS 125
|
||||
|
||||
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
||||
index 4a57002..25e1c72 100644
|
||||
--- a/includes/dhcpd.h
|
||||
+++ b/includes/dhcpd.h
|
||||
@@ -2967,6 +2967,7 @@ isc_result_t range2cidr(struct iaddrcidrnetlist **result,
|
||||
const struct iaddr *lo, const struct iaddr *hi);
|
||||
isc_result_t free_iaddrcidrnetlist(struct iaddrcidrnetlist **result);
|
||||
const char *piaddr (struct iaddr);
|
||||
+const char *pdestdesc (struct iaddr);
|
||||
char *piaddrmask(struct iaddr *, struct iaddr *);
|
||||
char *piaddrcidr(const struct iaddr *, unsigned int);
|
||||
u_int16_t validate_port(char *);
|
||||
@@ -3189,6 +3190,7 @@ void parse_client_lease_declaration (struct parse *,
|
||||
int parse_option_decl (struct option_cache **, struct parse *);
|
||||
void parse_string_list (struct parse *, struct string_list **, int);
|
||||
int parse_ip_addr (struct parse *, struct iaddr *);
|
||||
+int parse_destination_descriptor (struct parse *, struct iaddr *);
|
||||
int parse_ip_addr_with_subnet(struct parse *, struct iaddrmatch *);
|
||||
void parse_reject_statement (struct parse *, struct client_config *);
|
||||
|
||||
diff --git a/includes/dhctoken.h b/includes/dhctoken.h
|
||||
index 6daa422..3f5334e 100644
|
||||
--- a/includes/dhctoken.h
|
||||
+++ b/includes/dhctoken.h
|
||||
@@ -378,7 +378,8 @@ enum dhcp_token {
|
||||
TOKEN_OCTAL = 678,
|
||||
KEY_ALGORITHM = 679,
|
||||
BOOTP_BROADCAST_ALWAYS = 680,
|
||||
- DISCONNECT = 681
|
||||
+ DESTINATION_DESCRIPTOR = 681,
|
||||
+ DISCONNECT = 682
|
||||
};
|
||||
|
||||
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,175 +0,0 @@
|
||||
From fe89d58ea8627c66feffa81997daa024834eeb15 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:33:06 +0100
|
||||
Subject: [PATCH 13/28] DHCPv6 over PPP support (#626514)
|
||||
|
||||
---
|
||||
client/dhc6.c | 3 ++-
|
||||
client/dhclient.c | 17 ++++++++++++++---
|
||||
common/bpf.c | 16 ++++++++++++++++
|
||||
common/lpf.c | 16 ++++++++++++++++
|
||||
includes/dhcp.h | 2 ++
|
||||
includes/dhcpd.h | 2 +-
|
||||
server/dhcpv6.c | 3 +++
|
||||
7 files changed, 54 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/client/dhc6.c b/client/dhc6.c
|
||||
index 35cf3d0..88fd07d 100644
|
||||
--- a/client/dhc6.c
|
||||
+++ b/client/dhc6.c
|
||||
@@ -5737,7 +5737,8 @@ make_client6_options(struct client_state *client, struct option_state **op,
|
||||
*/
|
||||
if ((oc = lookup_option(&dhcpv6_universe, *op,
|
||||
D6O_CLIENTID)) == NULL) {
|
||||
- if (!option_cache(&oc, &default_duid, NULL, clientid_option,
|
||||
+ if (default_duid.len == 0 ||
|
||||
+ !option_cache(&oc, &default_duid, NULL, clientid_option,
|
||||
MDL))
|
||||
log_fatal("Failure assembling a DUID.");
|
||||
|
||||
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||
index b49fcb3..a99e21f 100644
|
||||
--- a/client/dhclient.c
|
||||
+++ b/client/dhclient.c
|
||||
@@ -1223,8 +1223,8 @@ main(int argc, char **argv) {
|
||||
if (default_duid.buffer != NULL)
|
||||
data_string_forget(&default_duid, MDL);
|
||||
|
||||
- form_duid(&default_duid, MDL);
|
||||
- write_duid(&default_duid);
|
||||
+ if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS)
|
||||
+ write_duid(&default_duid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4202,7 +4202,7 @@ write_options(struct client_state *client, struct option_state *options,
|
||||
* is not how it is intended. Upcoming rearchitecting the client should
|
||||
* address this "one daemon model."
|
||||
*/
|
||||
-void
|
||||
+isc_result_t
|
||||
form_duid(struct data_string *duid, const char *file, int line)
|
||||
{
|
||||
struct interface_info *ip;
|
||||
@@ -4215,6 +4215,15 @@ form_duid(struct data_string *duid, const char *file, int line)
|
||||
if (ip == NULL)
|
||||
log_fatal("Impossible condition at %s:%d.", MDL);
|
||||
|
||||
+ while (ip && ip->hw_address.hbuf[0] == HTYPE_RESERVED) {
|
||||
+ /* Try the other interfaces */
|
||||
+ log_debug("Cannot form default DUID from interface %s.", ip->name);
|
||||
+ ip = ip->next;
|
||||
+ }
|
||||
+ if (ip == NULL) {
|
||||
+ return ISC_R_UNEXPECTED;
|
||||
+ }
|
||||
+
|
||||
if ((ip->hw_address.hlen == 0) ||
|
||||
(ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
|
||||
log_fatal("Impossible hardware address length at %s:%d.", MDL);
|
||||
@@ -4260,6 +4269,8 @@ form_duid(struct data_string *duid, const char *file, int line)
|
||||
log_info("Created duid %s.", str);
|
||||
dfree(str, MDL);
|
||||
}
|
||||
+
|
||||
+ return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
/* Write the default DUID to the lease store. */
|
||||
diff --git a/common/bpf.c b/common/bpf.c
|
||||
index d2a0549..aede242 100644
|
||||
--- a/common/bpf.c
|
||||
+++ b/common/bpf.c
|
||||
@@ -650,6 +650,22 @@ get_hw_addr(const char *name, struct hardware *hw) {
|
||||
memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
|
||||
break;
|
||||
#endif /* IFT_FDDI */
|
||||
+#if defined(IFT_PPP)
|
||||
+ case IFT_PPP:
|
||||
+ if (local_family != AF_INET6)
|
||||
+ log_fatal("Unsupported device type %d for \"%s\"",
|
||||
+ sa->sdl_type, name);
|
||||
+ hw->hlen = 0;
|
||||
+ hw->hbuf[0] = HTYPE_RESERVED;
|
||||
+ /* 0xdeadbeef should never occur on the wire,
|
||||
+ * and is a signature that something went wrong.
|
||||
+ */
|
||||
+ hw->hbuf[1] = 0xde;
|
||||
+ hw->hbuf[2] = 0xad;
|
||||
+ hw->hbuf[3] = 0xbe;
|
||||
+ hw->hbuf[4] = 0xef;
|
||||
+ break;
|
||||
+#endif
|
||||
default:
|
||||
log_fatal("Unsupported device type %d for \"%s\"",
|
||||
sa->sdl_type, name);
|
||||
diff --git a/common/lpf.c b/common/lpf.c
|
||||
index bd20b3f..bb8822a 100644
|
||||
--- a/common/lpf.c
|
||||
+++ b/common/lpf.c
|
||||
@@ -563,6 +563,22 @@ get_hw_addr(const char *name, struct hardware *hw) {
|
||||
hw->hbuf[0] = HTYPE_FDDI;
|
||||
memcpy(&hw->hbuf[1], sa->sa_data, 6);
|
||||
break;
|
||||
+#if defined(ARPHRD_PPP)
|
||||
+ case ARPHRD_PPP:
|
||||
+ if (local_family != AF_INET6)
|
||||
+ log_fatal("Unsupported device type %d for \"%s\"",
|
||||
+ sa->sa_family, name);
|
||||
+ hw->hlen = 0;
|
||||
+ hw->hbuf[0] = HTYPE_RESERVED;
|
||||
+ /* 0xdeadbeef should never occur on the wire,
|
||||
+ * and is a signature that something went wrong.
|
||||
+ */
|
||||
+ hw->hbuf[1] = 0xde;
|
||||
+ hw->hbuf[2] = 0xad;
|
||||
+ hw->hbuf[3] = 0xbe;
|
||||
+ hw->hbuf[4] = 0xef;
|
||||
+ break;
|
||||
+#endif
|
||||
default:
|
||||
log_fatal("Unsupported device type %ld for \"%s\"",
|
||||
(long int)sa->sa_family, name);
|
||||
diff --git a/includes/dhcp.h b/includes/dhcp.h
|
||||
index 5a73129..7202f1d 100644
|
||||
--- a/includes/dhcp.h
|
||||
+++ b/includes/dhcp.h
|
||||
@@ -80,6 +80,8 @@ struct dhcp_packet {
|
||||
* is no standard for this so we
|
||||
* just steal a type */
|
||||
|
||||
+#define HTYPE_RESERVED 0 /* RFC 5494 */
|
||||
+
|
||||
/* Magic cookie validating dhcp options field (and bootp vendor
|
||||
extensions field). */
|
||||
#define DHCP_OPTIONS_COOKIE "\143\202\123\143"
|
||||
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
||||
index 25e1c72..4c5e877 100644
|
||||
--- a/includes/dhcpd.h
|
||||
+++ b/includes/dhcpd.h
|
||||
@@ -3071,7 +3071,7 @@ void client_dns_remove(struct client_state *client, struct iaddr *addr);
|
||||
|
||||
void dhcpv4_client_assignments(void);
|
||||
void dhcpv6_client_assignments(void);
|
||||
-void form_duid(struct data_string *duid, const char *file, int line);
|
||||
+isc_result_t form_duid(struct data_string *duid, const char *file, int line);
|
||||
|
||||
void dhcp4o6_start(void);
|
||||
|
||||
diff --git a/server/dhcpv6.c b/server/dhcpv6.c
|
||||
index 0ea0532..7d61dc5 100644
|
||||
--- a/server/dhcpv6.c
|
||||
+++ b/server/dhcpv6.c
|
||||
@@ -482,6 +482,9 @@ generate_new_server_duid(void) {
|
||||
if (p->hw_address.hlen > 0) {
|
||||
break;
|
||||
}
|
||||
+ if (p->next == NULL && p->hw_address.hbuf[0] == HTYPE_RESERVED) {
|
||||
+ log_error("Can not generate DUID from interfaces which do not have hardware addresses, please configure server-duid!");
|
||||
+ }
|
||||
}
|
||||
if (p == NULL) {
|
||||
return ISC_R_UNEXPECTED;
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,625 +0,0 @@
|
||||
From 90d64318e17df066c27b8e99ba6ab7f51154917b Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:34:21 +0100
|
||||
Subject: [PATCH 14/28] IPoIB support (#660681)
|
||||
|
||||
(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #24249])
|
||||
---
|
||||
client/dhclient.c | 33 ++++++
|
||||
common/bpf.c | 32 ++++++
|
||||
common/discover.c | 4 +-
|
||||
common/lpf.c | 274 ++++++++++++++++++++++++++++++++++++++++++----
|
||||
common/socket.c | 8 +-
|
||||
includes/dhcpd.h | 6 +-
|
||||
6 files changed, 329 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||
index a99e21f..48edddf 100644
|
||||
--- a/client/dhclient.c
|
||||
+++ b/client/dhclient.c
|
||||
@@ -211,6 +211,8 @@ static const char use_v6command[] = "Command not used for DHCPv4: %s";
|
||||
|
||||
#define DHCLIENT_USAGEH "{--version|--help|-h}"
|
||||
|
||||
+static void setup_ib_interface(struct interface_info *ip);
|
||||
+
|
||||
static void
|
||||
usage(const char *sfmt, const char *sarg)
|
||||
{
|
||||
@@ -1213,6 +1215,14 @@ main(int argc, char **argv) {
|
||||
}
|
||||
srandom(seed);
|
||||
|
||||
+ /* Setup specific Infiniband options */
|
||||
+ for (ip = interfaces; ip; ip = ip->next) {
|
||||
+ if (ip->client &&
|
||||
+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {
|
||||
+ setup_ib_interface(ip);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Establish a default DUID. We always do so for v6 and
|
||||
* do so if desired for v4 via the -D or -i options
|
||||
@@ -1507,6 +1517,29 @@ int find_subnet (struct subnet **sp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void setup_ib_interface(struct interface_info *ip)
|
||||
+{
|
||||
+ struct group *g;
|
||||
+
|
||||
+ /* Set the broadcast flag */
|
||||
+ ip->client->config->bootp_broadcast_always = 1;
|
||||
+
|
||||
+ /*
|
||||
+ * Find out if a dhcp-client-identifier option was specified either
|
||||
+ * in the config file or on the command line
|
||||
+ */
|
||||
+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {
|
||||
+ if ((g->statements != NULL) &&
|
||||
+ (strcmp(g->statements->data.option->option->name,
|
||||
+ "dhcp-client-identifier") == 0)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* No client ID specified */
|
||||
+ log_fatal("dhcp-client-identifier must be specified for InfiniBand");
|
||||
+}
|
||||
+
|
||||
/* Individual States:
|
||||
*
|
||||
* Each routine is called from the dhclient_state_machine() in one of
|
||||
diff --git a/common/bpf.c b/common/bpf.c
|
||||
index aede242..812cac3 100644
|
||||
--- a/common/bpf.c
|
||||
+++ b/common/bpf.c
|
||||
@@ -237,11 +237,43 @@ int dhcp_bpf_relay_filter_len =
|
||||
sizeof dhcp_bpf_relay_filter / sizeof (struct bpf_insn);
|
||||
#endif
|
||||
|
||||
+/* Packet filter program for DHCP over Infiniband.
|
||||
+ *
|
||||
+ * XXX
|
||||
+ * Changes to the filter program may require changes to the constant offsets
|
||||
+ * used in lpf_gen_filter_setup to patch the port in the BPF program!
|
||||
+ * XXX
|
||||
+ */
|
||||
+struct bpf_insn dhcp_ib_bpf_filter [] = {
|
||||
+ /* Packet filter for Infiniband */
|
||||
+ /* Make sure it's a UDP packet... */
|
||||
+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),
|
||||
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
|
||||
+
|
||||
+ /* Make sure this isn't a fragment... */
|
||||
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6),
|
||||
+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
|
||||
+
|
||||
+ /* Get the IP header length... */
|
||||
+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),
|
||||
+
|
||||
+ /* Make sure it's to the right port... */
|
||||
+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),
|
||||
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
|
||||
+
|
||||
+ /* If we passed all the tests, ask for the whole packet. */
|
||||
+ BPF_STMT(BPF_RET + BPF_K, (u_int)-1),
|
||||
+
|
||||
+ /* Otherwise, drop it. */
|
||||
+ BPF_STMT(BPF_RET + BPF_K, 0),
|
||||
+};
|
||||
+
|
||||
#if defined (DEC_FDDI)
|
||||
struct bpf_insn *bpf_fddi_filter = NULL;
|
||||
#endif
|
||||
|
||||
int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
|
||||
+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);
|
||||
#if defined (HAVE_TR_SUPPORT)
|
||||
struct bpf_insn dhcp_bpf_tr_filter [] = {
|
||||
/* accept all token ring packets due to variable length header */
|
||||
diff --git a/common/discover.c b/common/discover.c
|
||||
index ed338b4..e562225 100644
|
||||
--- a/common/discover.c
|
||||
+++ b/common/discover.c
|
||||
@@ -899,7 +899,7 @@ discover_interfaces(int state) {
|
||||
if_register_send(tmp);
|
||||
} else {
|
||||
/* get_hw_addr() was called by register. */
|
||||
- get_hw_addr(tmp->name, &tmp->hw_address);
|
||||
+ get_hw_addr(tmp);
|
||||
}
|
||||
break;
|
||||
#ifdef DHCPv6
|
||||
@@ -912,7 +912,7 @@ discover_interfaces(int state) {
|
||||
so now we have to call it explicitly
|
||||
to not leave the hardware address unknown
|
||||
(some code expects it cannot be. */
|
||||
- get_hw_addr(tmp->name, &tmp->hw_address);
|
||||
+ get_hw_addr(tmp);
|
||||
} else {
|
||||
if_register_linklocal6(tmp);
|
||||
}
|
||||
diff --git a/common/lpf.c b/common/lpf.c
|
||||
index bb8822a..fcaa13d 100644
|
||||
--- a/common/lpf.c
|
||||
+++ b/common/lpf.c
|
||||
@@ -45,6 +45,17 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
+#include <ifaddrs.h>
|
||||
+
|
||||
+/* Default broadcast address for IPoIB */
|
||||
+static unsigned char default_ib_bcast_addr[20] = {
|
||||
+ 0x00, 0xff, 0xff, 0xff,
|
||||
+ 0xff, 0x12, 0x40, 0x1b,
|
||||
+ 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0xff, 0xff, 0xff, 0xff
|
||||
+};
|
||||
+
|
||||
#endif
|
||||
|
||||
#if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
|
||||
@@ -78,10 +89,20 @@ int if_register_lpf (info)
|
||||
struct sockaddr common;
|
||||
} sa;
|
||||
struct ifreq ifr;
|
||||
+ int type;
|
||||
+ int protocol;
|
||||
+
|
||||
+ get_hw_addr(info);
|
||||
+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
|
||||
+ type = SOCK_DGRAM;
|
||||
+ protocol = ETHERTYPE_IP;
|
||||
+ } else {
|
||||
+ type = SOCK_RAW;
|
||||
+ protocol = ETH_P_ALL;
|
||||
+ }
|
||||
|
||||
/* Make an LPF socket. */
|
||||
- if ((sock = socket(PF_PACKET, SOCK_RAW,
|
||||
- htons((short)ETH_P_ALL))) < 0) {
|
||||
+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {
|
||||
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
|
||||
errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
|
||||
errno == EAFNOSUPPORT || errno == EINVAL) {
|
||||
@@ -104,6 +125,7 @@ int if_register_lpf (info)
|
||||
/* Bind to the interface name */
|
||||
memset (&sa, 0, sizeof sa);
|
||||
sa.ll.sll_family = AF_PACKET;
|
||||
+ sa.ll.sll_protocol = htons(protocol);
|
||||
sa.ll.sll_ifindex = ifr.ifr_ifindex;
|
||||
if (bind (sock, &sa.common, sizeof sa)) {
|
||||
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
|
||||
@@ -120,8 +142,6 @@ int if_register_lpf (info)
|
||||
|
||||
}
|
||||
|
||||
- get_hw_addr(info->name, &info->hw_address);
|
||||
-
|
||||
return sock;
|
||||
}
|
||||
#endif /* USE_LPF_SEND || USE_LPF_RECEIVE */
|
||||
@@ -176,6 +196,8 @@ void if_deregister_send (info)
|
||||
in bpf includes... */
|
||||
extern struct sock_filter dhcp_bpf_filter [];
|
||||
extern int dhcp_bpf_filter_len;
|
||||
+extern struct sock_filter dhcp_ib_bpf_filter [];
|
||||
+extern int dhcp_ib_bpf_filter_len;
|
||||
|
||||
#if defined(RELAY_PORT)
|
||||
extern struct sock_filter dhcp_bpf_relay_filter [];
|
||||
@@ -199,11 +221,12 @@ void if_register_receive (info)
|
||||
#ifdef PACKET_AUXDATA
|
||||
{
|
||||
int val = 1;
|
||||
-
|
||||
- if (setsockopt(info->rfdesc, SOL_PACKET, PACKET_AUXDATA,
|
||||
- &val, sizeof(val)) < 0) {
|
||||
- if (errno != ENOPROTOOPT) {
|
||||
- log_fatal ("Failed to set auxiliary packet data: %m");
|
||||
+ if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) {
|
||||
+ if (setsockopt(info->rfdesc, SOL_PACKET, PACKET_AUXDATA,
|
||||
+ &val, sizeof(val)) < 0) {
|
||||
+ if (errno != ENOPROTOOPT) {
|
||||
+ log_fatal ("Failed to set auxiliary packet data: %m");
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,6 +276,18 @@ static void lpf_gen_filter_setup (info)
|
||||
|
||||
memset(&p, 0, sizeof(p));
|
||||
|
||||
+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
|
||||
+ p.len = dhcp_ib_bpf_filter_len;
|
||||
+ p.filter = dhcp_ib_bpf_filter;
|
||||
+
|
||||
+ /* Patch the server port into the LPF program...
|
||||
+ XXX
|
||||
+ changes to filter program may require changes
|
||||
+ to the insn number(s) used below!
|
||||
+ XXX */
|
||||
+ dhcp_ib_bpf_filter[6].k = ntohs (local_port);
|
||||
+ } else {
|
||||
+
|
||||
/* Set up the bpf filter program structure. This is defined in
|
||||
bpf.c */
|
||||
p.len = dhcp_bpf_filter_len;
|
||||
@@ -275,6 +310,8 @@ static void lpf_gen_filter_setup (info)
|
||||
#endif
|
||||
dhcp_bpf_filter [8].k = ntohs (local_port);
|
||||
|
||||
+ }
|
||||
+
|
||||
if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
|
||||
sizeof p) < 0) {
|
||||
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
|
||||
@@ -330,6 +367,54 @@ static void lpf_tr_filter_setup (info)
|
||||
#endif /* USE_LPF_RECEIVE */
|
||||
|
||||
#ifdef USE_LPF_SEND
|
||||
+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)
|
||||
+ struct interface_info *interface;
|
||||
+ struct packet *packet;
|
||||
+ struct dhcp_packet *raw;
|
||||
+ size_t len;
|
||||
+ struct in_addr from;
|
||||
+ struct sockaddr_in *to;
|
||||
+ struct hardware *hto;
|
||||
+{
|
||||
+ unsigned ibufp = 0;
|
||||
+ double ih [1536 / sizeof (double)];
|
||||
+ unsigned char *buf = (unsigned char *)ih;
|
||||
+ ssize_t result;
|
||||
+
|
||||
+ union sockunion {
|
||||
+ struct sockaddr sa;
|
||||
+ struct sockaddr_ll sll;
|
||||
+ struct sockaddr_storage ss;
|
||||
+ } su;
|
||||
+
|
||||
+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
|
||||
+ to->sin_addr.s_addr, to->sin_port,
|
||||
+ (unsigned char *)raw, len);
|
||||
+ memcpy (buf + ibufp, raw, len);
|
||||
+
|
||||
+ memset(&su, 0, sizeof(su));
|
||||
+ su.sll.sll_family = AF_PACKET;
|
||||
+ su.sll.sll_protocol = htons(ETHERTYPE_IP);
|
||||
+
|
||||
+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
|
||||
+ errno = ENOENT;
|
||||
+ log_error ("send_packet_ib: %m - failed to get if index");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND);
|
||||
+ su.sll.sll_halen = sizeof(interface->bcast_addr);
|
||||
+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
|
||||
+
|
||||
+ result = sendto(interface->wfdesc, buf, ibufp + len, 0,
|
||||
+ &su.sa, sizeof(su));
|
||||
+
|
||||
+ if (result < 0)
|
||||
+ log_error ("send_packet_ib: %m");
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
ssize_t send_packet (interface, packet, raw, len, from, to, hto)
|
||||
struct interface_info *interface;
|
||||
struct packet *packet;
|
||||
@@ -350,6 +435,11 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
|
||||
return send_fallback (interface, packet, raw,
|
||||
len, from, to, hto);
|
||||
|
||||
+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
|
||||
+ return send_packet_ib(interface, packet, raw, len, from,
|
||||
+ to, hto);
|
||||
+ }
|
||||
+
|
||||
if (hto == NULL && interface->anycast_mac_addr.hlen)
|
||||
hto = &interface->anycast_mac_addr;
|
||||
|
||||
@@ -370,6 +460,42 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
|
||||
#endif /* USE_LPF_SEND */
|
||||
|
||||
#ifdef USE_LPF_RECEIVE
|
||||
+ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
|
||||
+ struct interface_info *interface;
|
||||
+ unsigned char *buf;
|
||||
+ size_t len;
|
||||
+ struct sockaddr_in *from;
|
||||
+ struct hardware *hfrom;
|
||||
+{
|
||||
+ int length = 0;
|
||||
+ int offset = 0;
|
||||
+ unsigned char ibuf [1536];
|
||||
+ unsigned bufix = 0;
|
||||
+ unsigned paylen;
|
||||
+
|
||||
+ length = read(interface->rfdesc, ibuf, sizeof(ibuf));
|
||||
+
|
||||
+ if (length <= 0)
|
||||
+ return length;
|
||||
+
|
||||
+ offset = decode_udp_ip_header(interface, ibuf, bufix, from,
|
||||
+ (unsigned)length, &paylen, 0);
|
||||
+
|
||||
+ if (offset < 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ bufix += offset;
|
||||
+ length -= offset;
|
||||
+
|
||||
+ if (length < paylen)
|
||||
+ log_fatal("Internal inconsistency at %s:%d.", MDL);
|
||||
+
|
||||
+ /* Copy out the data in the packet... */
|
||||
+ memcpy(buf, &ibuf[bufix], paylen);
|
||||
+
|
||||
+ return (ssize_t)paylen;
|
||||
+}
|
||||
+
|
||||
ssize_t receive_packet (interface, buf, len, from, hfrom)
|
||||
struct interface_info *interface;
|
||||
unsigned char *buf;
|
||||
@@ -408,6 +534,10 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
|
||||
};
|
||||
#endif /* PACKET_AUXDATA */
|
||||
|
||||
+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
|
||||
+ return receive_packet_ib(interface, buf, len, from, hfrom);
|
||||
+ }
|
||||
+
|
||||
length = recvmsg (interface->rfdesc, &msg, 0);
|
||||
if (length <= 0)
|
||||
return length;
|
||||
@@ -521,11 +651,33 @@ void maybe_setup_fallback ()
|
||||
#endif
|
||||
|
||||
#if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR)
|
||||
-void
|
||||
-get_hw_addr(const char *name, struct hardware *hw) {
|
||||
+struct sockaddr_ll *
|
||||
+get_ll (struct ifaddrs *ifaddrs, struct ifaddrs **ifa, char *name)
|
||||
+{
|
||||
+ for (*ifa = ifaddrs; *ifa != NULL; *ifa = (*ifa)->ifa_next) {
|
||||
+ if ((*ifa)->ifa_addr == NULL)
|
||||
+ continue;
|
||||
+
|
||||
+ if ((*ifa)->ifa_addr->sa_family != AF_PACKET)
|
||||
+ continue;
|
||||
+
|
||||
+ if ((*ifa)->ifa_flags & IFF_LOOPBACK)
|
||||
+ continue;
|
||||
+
|
||||
+ if (strcmp((*ifa)->ifa_name, name) == 0)
|
||||
+ return (struct sockaddr_ll *)(void *)(*ifa)->ifa_addr;
|
||||
+ }
|
||||
+ *ifa = NULL;
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+struct sockaddr_ll *
|
||||
+ioctl_get_ll(char *name)
|
||||
+{
|
||||
int sock;
|
||||
struct ifreq tmp;
|
||||
- struct sockaddr *sa;
|
||||
+ struct sockaddr *sa = NULL;
|
||||
+ struct sockaddr_ll *sll = NULL;
|
||||
|
||||
if (strlen(name) >= sizeof(tmp.ifr_name)) {
|
||||
log_fatal("Device name too long: \"%s\"", name);
|
||||
@@ -542,13 +694,58 @@ get_hw_addr(const char *name, struct hardware *hw) {
|
||||
log_fatal("Error getting hardware address for \"%s\": %m",
|
||||
name);
|
||||
}
|
||||
+ close(sock);
|
||||
|
||||
sa = &tmp.ifr_hwaddr;
|
||||
- switch (sa->sa_family) {
|
||||
+ // needs to be freed outside this function
|
||||
+ sll = dmalloc (sizeof (struct sockaddr_ll), MDL);
|
||||
+ if (!sll)
|
||||
+ log_fatal("Unable to allocate memory for link layer address");
|
||||
+ memcpy(&sll->sll_hatype, &sa->sa_family, sizeof (sll->sll_hatype));
|
||||
+ memcpy(sll->sll_addr, sa->sa_data, sizeof (sll->sll_addr));
|
||||
+ switch (sll->sll_hatype) {
|
||||
+ case ARPHRD_INFINIBAND:
|
||||
+ sll->sll_halen = HARDWARE_ADDR_LEN_IOCTL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return sll;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+get_hw_addr(struct interface_info *info)
|
||||
+{
|
||||
+ struct hardware *hw = &info->hw_address;
|
||||
+ char *name = info->name;
|
||||
+ struct ifaddrs *ifaddrs = NULL;
|
||||
+ struct ifaddrs *ifa = NULL;
|
||||
+ struct sockaddr_ll *sll = NULL;
|
||||
+ int sll_allocated = 0;
|
||||
+ char *dup = NULL;
|
||||
+ char *colon = NULL;
|
||||
+
|
||||
+ if (getifaddrs(&ifaddrs) == -1)
|
||||
+ log_fatal("Failed to get interfaces");
|
||||
+
|
||||
+ if ((sll = get_ll(ifaddrs, &ifa, name)) == NULL) {
|
||||
+ /*
|
||||
+ * We were unable to get link-layer address for name.
|
||||
+ * Fall back to ioctl(SIOCGIFHWADDR).
|
||||
+ */
|
||||
+ sll = ioctl_get_ll(name);
|
||||
+ if (sll != NULL)
|
||||
+ sll_allocated = 1;
|
||||
+ else
|
||||
+ // shouldn't happen
|
||||
+ log_fatal("Unexpected internal error");
|
||||
+ }
|
||||
+
|
||||
+ switch (sll->sll_hatype) {
|
||||
case ARPHRD_ETHER:
|
||||
hw->hlen = 7;
|
||||
hw->hbuf[0] = HTYPE_ETHER;
|
||||
- memcpy(&hw->hbuf[1], sa->sa_data, 6);
|
||||
+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);
|
||||
break;
|
||||
case ARPHRD_IEEE802:
|
||||
#ifdef ARPHRD_IEEE802_TR
|
||||
@@ -556,18 +753,50 @@ get_hw_addr(const char *name, struct hardware *hw) {
|
||||
#endif /* ARPHRD_IEEE802_TR */
|
||||
hw->hlen = 7;
|
||||
hw->hbuf[0] = HTYPE_IEEE802;
|
||||
- memcpy(&hw->hbuf[1], sa->sa_data, 6);
|
||||
+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);
|
||||
break;
|
||||
case ARPHRD_FDDI:
|
||||
hw->hlen = 7;
|
||||
hw->hbuf[0] = HTYPE_FDDI;
|
||||
- memcpy(&hw->hbuf[1], sa->sa_data, 6);
|
||||
+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);
|
||||
+ break;
|
||||
+ case ARPHRD_INFINIBAND:
|
||||
+ dup = strdup(name);
|
||||
+ /* Aliased infiniband interface is special case where
|
||||
+ * neither get_ll() nor ioctl_get_ll() get's correct hw
|
||||
+ * address, so we have to truncate the :0 and run
|
||||
+ * get_ll() again for the rest.
|
||||
+ */
|
||||
+ if ((colon = strchr(dup, ':')) != NULL) {
|
||||
+ *colon = '\0';
|
||||
+ if ((sll = get_ll(ifaddrs, &ifa, dup)) == NULL)
|
||||
+ log_fatal("Error getting hardware address for \"%s\": %m", name);
|
||||
+ }
|
||||
+ free (dup);
|
||||
+ /* For Infiniband, save the broadcast address and store
|
||||
+ * the port GUID into the hardware address.
|
||||
+ */
|
||||
+ if (ifa && (ifa->ifa_flags & IFF_BROADCAST)) {
|
||||
+ struct sockaddr_ll *bll;
|
||||
+
|
||||
+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;
|
||||
+ memcpy(&info->bcast_addr, bll->sll_addr, 20);
|
||||
+ } else {
|
||||
+ memcpy(&info->bcast_addr, default_ib_bcast_addr,
|
||||
+ 20);
|
||||
+ }
|
||||
+
|
||||
+ hw->hlen = HARDWARE_ADDR_LEN_IOCTL + 1;
|
||||
+ hw->hbuf[0] = HTYPE_INFINIBAND;
|
||||
+ memcpy(&hw->hbuf[1],
|
||||
+ &sll->sll_addr[sll->sll_halen - HARDWARE_ADDR_LEN_IOCTL],
|
||||
+ HARDWARE_ADDR_LEN_IOCTL);
|
||||
break;
|
||||
#if defined(ARPHRD_PPP)
|
||||
case ARPHRD_PPP:
|
||||
if (local_family != AF_INET6)
|
||||
- log_fatal("Unsupported device type %d for \"%s\"",
|
||||
- sa->sa_family, name);
|
||||
+ log_fatal("local_family != AF_INET6 for \"%s\"",
|
||||
+ name);
|
||||
hw->hlen = 0;
|
||||
hw->hbuf[0] = HTYPE_RESERVED;
|
||||
/* 0xdeadbeef should never occur on the wire,
|
||||
@@ -580,10 +809,13 @@ get_hw_addr(const char *name, struct hardware *hw) {
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
- log_fatal("Unsupported device type %ld for \"%s\"",
|
||||
- (long int)sa->sa_family, name);
|
||||
+ freeifaddrs(ifaddrs);
|
||||
+ log_fatal("Unsupported device type %hu for \"%s\"",
|
||||
+ sll->sll_hatype, name);
|
||||
}
|
||||
|
||||
- close(sock);
|
||||
+ if (sll_allocated)
|
||||
+ dfree(sll, MDL);
|
||||
+ freeifaddrs(ifaddrs);
|
||||
}
|
||||
#endif
|
||||
diff --git a/common/socket.c b/common/socket.c
|
||||
index 3953eac..903d034 100644
|
||||
--- a/common/socket.c
|
||||
+++ b/common/socket.c
|
||||
@@ -358,7 +358,7 @@ void if_register_send (info)
|
||||
info->wfdesc = if_register_socket(info, AF_INET, 0, NULL);
|
||||
/* If this is a normal IPv4 address, get the hardware address. */
|
||||
if (strcmp(info->name, "fallback") != 0)
|
||||
- get_hw_addr(info->name, &info->hw_address);
|
||||
+ get_hw_addr(info);
|
||||
#if defined (USE_SOCKET_FALLBACK)
|
||||
/* Fallback only registers for send, but may need to receive as
|
||||
well. */
|
||||
@@ -421,7 +421,7 @@ void if_register_receive (info)
|
||||
#endif /* IP_PKTINFO... */
|
||||
/* If this is a normal IPv4 address, get the hardware address. */
|
||||
if (strcmp(info->name, "fallback") != 0)
|
||||
- get_hw_addr(info->name, &info->hw_address);
|
||||
+ get_hw_addr(info);
|
||||
|
||||
if (!quiet_interface_discovery)
|
||||
log_info ("Listening on Socket/%s%s%s",
|
||||
@@ -577,7 +577,7 @@ if_register6(struct interface_info *info, int do_multicast) {
|
||||
if (req_multi)
|
||||
if_register_multicast(info);
|
||||
|
||||
- get_hw_addr(info->name, &info->hw_address);
|
||||
+ get_hw_addr(info);
|
||||
|
||||
if (!quiet_interface_discovery) {
|
||||
if (info->shared_network != NULL) {
|
||||
@@ -633,7 +633,7 @@ if_register_linklocal6(struct interface_info *info) {
|
||||
info->rfdesc = sock;
|
||||
info->wfdesc = sock;
|
||||
|
||||
- get_hw_addr(info->name, &info->hw_address);
|
||||
+ get_hw_addr(info);
|
||||
|
||||
if (!quiet_interface_discovery) {
|
||||
if (info->shared_network != NULL) {
|
||||
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
||||
index 4c5e877..e9e52e7 100644
|
||||
--- a/includes/dhcpd.h
|
||||
+++ b/includes/dhcpd.h
|
||||
@@ -485,6 +485,9 @@ struct packet {
|
||||
|
||||
#define HARDWARE_ADDR_LEN 20
|
||||
|
||||
+/* ioctl limits hardware addresses to 8 bytes */
|
||||
+#define HARDWARE_ADDR_LEN_IOCTL 8
|
||||
+
|
||||
struct hardware {
|
||||
u_int8_t hlen;
|
||||
u_int8_t hbuf[HARDWARE_ADDR_LEN + 1];
|
||||
@@ -1380,6 +1383,7 @@ struct interface_info {
|
||||
struct shared_network *shared_network;
|
||||
/* Networks connected to this interface. */
|
||||
struct hardware hw_address; /* Its physical address. */
|
||||
+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */
|
||||
struct in_addr *addresses; /* Addresses associated with this
|
||||
* interface.
|
||||
*/
|
||||
@@ -2649,7 +2653,7 @@ void print_dns_status (int, struct dhcp_ddns_cb *, isc_result_t);
|
||||
#endif
|
||||
const char *print_time(TIME);
|
||||
|
||||
-void get_hw_addr(const char *name, struct hardware *hw);
|
||||
+void get_hw_addr(struct interface_info *info);
|
||||
char *buf_to_hex (const unsigned char *s, unsigned len,
|
||||
const char *file, int line);
|
||||
char *format_lease_id(const unsigned char *s, unsigned len, int format,
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,327 +0,0 @@
|
||||
From 3baf35269555e2223dbd1733cb1c475cb7f2ed7a Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:35:47 +0100
|
||||
Subject: [PATCH 15/28] Add GUID/DUID to dhcpd logs (#1064416)
|
||||
|
||||
---
|
||||
client/dhclient.c | 70 ++++++++++++++++++++++++++++++++++--------
|
||||
server/dhcp.c | 78 ++++++++++++++++++++++++++++-------------------
|
||||
2 files changed, 105 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||
index 48edddf..181f6e1 100644
|
||||
--- a/client/dhclient.c
|
||||
+++ b/client/dhclient.c
|
||||
@@ -1176,6 +1176,26 @@ main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
+ /* We create a backup seed before rediscovering interfaces in order to
|
||||
+ have a seed built using all of the available interfaces
|
||||
+ It's interesting if required interfaces doesn't let us defined
|
||||
+ a really unique seed due to a lack of valid HW addr later
|
||||
+ (this is the case with DHCP over IB)
|
||||
+ We only use the last device as using a sum could broke the
|
||||
+ uniqueness of the seed among multiple nodes
|
||||
+ */
|
||||
+ unsigned backup_seed = 0;
|
||||
+ for (ip = interfaces; ip; ip = ip -> next) {
|
||||
+ int junk;
|
||||
+ if ( ip -> hw_address.hlen <= sizeof seed )
|
||||
+ continue;
|
||||
+ memcpy (&junk,
|
||||
+ &ip -> hw_address.hbuf [ip -> hw_address.hlen -
|
||||
+ sizeof seed], sizeof seed);
|
||||
+ backup_seed = junk;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
/* At this point, all the interfaces that the script thinks
|
||||
are relevant should be running, so now we once again call
|
||||
discover_interfaces(), and this time ask it to actually set
|
||||
@@ -1204,14 +1224,34 @@ main(int argc, char **argv) {
|
||||
Not much entropy, but we're booting, so we're not likely to
|
||||
find anything better. */
|
||||
|
||||
+ int seed_flag = 0;
|
||||
for (ip = interfaces; ip; ip = ip->next) {
|
||||
int junk;
|
||||
+ if ( ip -> hw_address.hlen <= sizeof seed )
|
||||
+ continue;
|
||||
memcpy(&junk,
|
||||
&ip->hw_address.hbuf[ip->hw_address.hlen -
|
||||
sizeof seed], sizeof seed);
|
||||
seed += junk;
|
||||
+ seed_flag = 1;
|
||||
}
|
||||
- seed += cur_time + (unsigned)getpid();
|
||||
+ if ( seed_flag == 0 ) {
|
||||
+ if ( backup_seed != 0 ) {
|
||||
+ seed = backup_seed;
|
||||
+ log_info ("xid: rand init seed (0x%x) built using all"
|
||||
+ " available interfaces",seed);
|
||||
+ }
|
||||
+ else {
|
||||
+ seed = cur_time^((unsigned) gethostid()) ;
|
||||
+ log_info ("xid: warning: no netdev with useable HWADDR found"
|
||||
+ " for seed's uniqueness enforcement");
|
||||
+ log_info ("xid: rand init seed (0x%x) built using gethostid",
|
||||
+ seed);
|
||||
+ }
|
||||
+ /* we only use seed and no current time as a broadcast reply */
|
||||
+ /* will certainly be used by the hwaddrless interface */
|
||||
+ }
|
||||
+ seed += ((unsigned)(cur_tv.tv_usec * 1000000)) + (unsigned)getpid();
|
||||
}
|
||||
srandom(seed);
|
||||
|
||||
@@ -1869,9 +1909,10 @@ void dhcpack (packet)
|
||||
return;
|
||||
}
|
||||
|
||||
- log_info ("DHCPACK of %s from %s",
|
||||
+ log_info ("DHCPACK of %s from %s (xid=0x%x)",
|
||||
inet_ntoa(packet->raw->yiaddr),
|
||||
- piaddr (packet->client_addr));
|
||||
+ piaddr (packet -> client_addr),
|
||||
+ ntohl(client -> xid));
|
||||
|
||||
/* Check v6only first. */
|
||||
v6only_wait = check_v6only(packet, client);
|
||||
@@ -2825,7 +2866,7 @@ void dhcpnak (packet)
|
||||
return;
|
||||
}
|
||||
|
||||
- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
|
||||
+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), ntohl(client -> xid));
|
||||
|
||||
if (!client -> active) {
|
||||
#if defined (DEBUG)
|
||||
@@ -2958,10 +2999,10 @@ void send_discover (cpp)
|
||||
(long)(client -> interval));
|
||||
} else
|
||||
#endif
|
||||
- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
|
||||
+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
|
||||
client -> name ? client -> name : client -> interface -> name,
|
||||
inet_ntoa (sockaddr_broadcast.sin_addr),
|
||||
- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
|
||||
+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), ntohl(client -> xid));
|
||||
|
||||
/* Send out a packet. */
|
||||
#if defined(DHCPv6) && defined(DHCP4o6)
|
||||
@@ -3355,10 +3396,12 @@ void send_request (cpp)
|
||||
}
|
||||
|
||||
strncpy(rip_buf, rip_str, sizeof(rip_buf)-1);
|
||||
- log_info ("DHCPREQUEST for %s on %s to %s port %d", rip_buf,
|
||||
+ log_info ("DHCPREQUEST for %s on %s to %s port %d (xid=0x%x)",
|
||||
+ rip_buf,
|
||||
client->name ? client->name : client->interface->name,
|
||||
inet_ntoa(destination.sin_addr),
|
||||
- ntohs (destination.sin_port));
|
||||
+ ntohs (destination.sin_port),
|
||||
+ ntohl(client -> xid));
|
||||
|
||||
#if defined(DHCPv6) && defined(DHCP4o6)
|
||||
if (dhcpv4_over_dhcpv6) {
|
||||
@@ -3415,11 +3458,13 @@ void send_decline (cpp)
|
||||
log_info ("DHCPDECLINE");
|
||||
} else
|
||||
#endif
|
||||
- log_info ("DHCPDECLINE of %s on %s to %s port %d",
|
||||
+ log_info ("DHCPDECLINE of %s on %s to %s port %d (xid=0x%x)",
|
||||
piaddr(client->requested_address),
|
||||
(client->name ? client->name : client->interface->name),
|
||||
inet_ntoa(sockaddr_broadcast.sin_addr),
|
||||
- ntohs(sockaddr_broadcast.sin_port));
|
||||
+ ntohs(sockaddr_broadcast.sin_port),
|
||||
+ ntohl(client -> xid));
|
||||
+
|
||||
|
||||
/* Send out a packet. */
|
||||
#if defined(DHCPv6) && defined(DHCP4o6)
|
||||
@@ -3478,11 +3523,12 @@ void send_release (cpp)
|
||||
log_info ("DHCPRELEASE");
|
||||
} else
|
||||
#endif
|
||||
- log_info ("DHCPRELEASE of %s on %s to %s port %d",
|
||||
+ log_info ("DHCPRELEASE of %s on %s to %s port %d (xid=0x%x)",
|
||||
piaddr(client->active->address),
|
||||
client->name ? client->name : client->interface->name,
|
||||
inet_ntoa (destination.sin_addr),
|
||||
- ntohs (destination.sin_port));
|
||||
+ ntohs (destination.sin_port),
|
||||
+ ntohl(client -> xid));
|
||||
|
||||
#if defined(DHCPv6) && defined(DHCP4o6)
|
||||
if (dhcpv4_over_dhcpv6) {
|
||||
diff --git a/server/dhcp.c b/server/dhcp.c
|
||||
index ae805a6..8363840 100644
|
||||
--- a/server/dhcp.c
|
||||
+++ b/server/dhcp.c
|
||||
@@ -93,6 +93,42 @@ const int dhcp_type_name_max = ((sizeof dhcp_type_names) / sizeof (char *));
|
||||
|
||||
static TIME leaseTimeCheck(TIME calculated, TIME alternate);
|
||||
|
||||
+char *print_client_identifier_from_packet (packet)
|
||||
+ struct packet *packet;
|
||||
+{
|
||||
+ struct option_cache *oc;
|
||||
+ struct data_string client_identifier;
|
||||
+ char *ci;
|
||||
+
|
||||
+ memset (&client_identifier, 0, sizeof client_identifier);
|
||||
+
|
||||
+ oc = lookup_option (&dhcp_universe, packet -> options,
|
||||
+ DHO_DHCP_CLIENT_IDENTIFIER);
|
||||
+ if (oc &&
|
||||
+ evaluate_option_cache (&client_identifier,
|
||||
+ packet, (struct lease *)0,
|
||||
+ (struct client_state *)0,
|
||||
+ packet -> options,
|
||||
+ (struct option_state *)0,
|
||||
+ &global_scope, oc, MDL)) {
|
||||
+ ci = print_hw_addr (HTYPE_INFINIBAND, client_identifier.len, client_identifier.data);
|
||||
+ data_string_forget (&client_identifier, MDL);
|
||||
+ return ci;
|
||||
+ } else
|
||||
+ return "\"no client id\"";
|
||||
+}
|
||||
+
|
||||
+char *print_hw_addr_or_client_id (packet)
|
||||
+ struct packet *packet;
|
||||
+{
|
||||
+ if (packet -> raw -> htype == HTYPE_INFINIBAND)
|
||||
+ return print_client_identifier_from_packet (packet);
|
||||
+ else
|
||||
+ return print_hw_addr (packet -> raw -> htype,
|
||||
+ packet -> raw -> hlen,
|
||||
+ packet -> raw -> chaddr);
|
||||
+}
|
||||
+
|
||||
void
|
||||
dhcp (struct packet *packet) {
|
||||
int ms_nulltp = 0;
|
||||
@@ -135,9 +171,7 @@ dhcp (struct packet *packet) {
|
||||
|
||||
log_info("%s from %s via %s: %s", s,
|
||||
(packet->raw->htype
|
||||
- ? print_hw_addr(packet->raw->htype,
|
||||
- packet->raw->hlen,
|
||||
- packet->raw->chaddr)
|
||||
+ ? print_hw_addr_or_client_id(packet)
|
||||
: "<no identifier>"),
|
||||
packet->raw->giaddr.s_addr
|
||||
? inet_ntoa(packet->raw->giaddr)
|
||||
@@ -334,9 +368,7 @@ void dhcpdiscover (packet, ms_nulltp)
|
||||
#endif
|
||||
snprintf (msgbuf, sizeof msgbuf, "DHCPDISCOVER from %s %s%s%svia %s",
|
||||
(packet -> raw -> htype
|
||||
- ? print_hw_addr (packet -> raw -> htype,
|
||||
- packet -> raw -> hlen,
|
||||
- packet -> raw -> chaddr)
|
||||
+ ? print_hw_addr_or_client_id (packet)
|
||||
: (lease
|
||||
? print_hex_1(lease->uid_len, lease->uid, 60)
|
||||
: "<no identifier>")),
|
||||
@@ -548,9 +580,7 @@ void dhcprequest (packet, ms_nulltp, ip_lease)
|
||||
"DHCPREQUEST for %s%s from %s %s%s%svia %s",
|
||||
piaddr (cip), smbuf,
|
||||
(packet -> raw -> htype
|
||||
- ? print_hw_addr (packet -> raw -> htype,
|
||||
- packet -> raw -> hlen,
|
||||
- packet -> raw -> chaddr)
|
||||
+ ? print_hw_addr_or_client_id(packet)
|
||||
: (lease
|
||||
? print_hex_1(lease->uid_len, lease->uid, 60)
|
||||
: "<no identifier>")),
|
||||
@@ -791,9 +821,7 @@ void dhcprelease (packet, ms_nulltp)
|
||||
if ((oc = lookup_option (&dhcp_universe, packet -> options,
|
||||
DHO_DHCP_REQUESTED_ADDRESS))) {
|
||||
log_info ("DHCPRELEASE from %s specified requested-address.",
|
||||
- print_hw_addr (packet -> raw -> htype,
|
||||
- packet -> raw -> hlen,
|
||||
- packet -> raw -> chaddr));
|
||||
+ print_hw_addr_or_client_id(packet));
|
||||
}
|
||||
|
||||
oc = lookup_option (&dhcp_universe, packet -> options,
|
||||
@@ -885,9 +913,7 @@ void dhcprelease (packet, ms_nulltp)
|
||||
"DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
|
||||
cstr,
|
||||
(packet -> raw -> htype
|
||||
- ? print_hw_addr (packet -> raw -> htype,
|
||||
- packet -> raw -> hlen,
|
||||
- packet -> raw -> chaddr)
|
||||
+ ? print_hw_addr_or_client_id(packet)
|
||||
: (lease
|
||||
? print_hex_1(lease->uid_len, lease->uid, 60)
|
||||
: "<no identifier>")),
|
||||
@@ -992,9 +1018,7 @@ void dhcpdecline (packet, ms_nulltp)
|
||||
"DHCPDECLINE of %s from %s %s%s%svia %s",
|
||||
piaddr (cip),
|
||||
(packet -> raw -> htype
|
||||
- ? print_hw_addr (packet -> raw -> htype,
|
||||
- packet -> raw -> hlen,
|
||||
- packet -> raw -> chaddr)
|
||||
+ ? print_hw_addr_or_client_id(packet)
|
||||
: (lease
|
||||
? print_hex_1(lease->uid_len, lease->uid, 60)
|
||||
: "<no identifier>")),
|
||||
@@ -1740,8 +1764,7 @@ void dhcpinform (packet, ms_nulltp)
|
||||
/* Report what we're sending. */
|
||||
snprintf(msgbuf, sizeof msgbuf, "DHCPACK to %s (%s) via", piaddr(cip),
|
||||
(packet->raw->htype && packet->raw->hlen) ?
|
||||
- print_hw_addr(packet->raw->htype, packet->raw->hlen,
|
||||
- packet->raw->chaddr) :
|
||||
+ print_hw_addr_or_client_id(packet) :
|
||||
"<no client hardware address>");
|
||||
log_info("%s %s", msgbuf, gip.len ? piaddr(gip) :
|
||||
packet->interface->name);
|
||||
@@ -1926,9 +1949,7 @@ void nak_lease (packet, cip, network_group)
|
||||
#endif
|
||||
log_info ("DHCPNAK on %s to %s via %s",
|
||||
piaddr (*cip),
|
||||
- print_hw_addr (packet -> raw -> htype,
|
||||
- packet -> raw -> hlen,
|
||||
- packet -> raw -> chaddr),
|
||||
+ print_hw_addr_or_client_id(packet),
|
||||
packet -> raw -> giaddr.s_addr
|
||||
? inet_ntoa (packet -> raw -> giaddr)
|
||||
: packet -> interface -> name);
|
||||
@@ -4044,7 +4065,7 @@ void dhcp_reply (lease)
|
||||
? (state -> offer == DHCPACK ? "DHCPACK" : "DHCPOFFER")
|
||||
: "BOOTREPLY"),
|
||||
piaddr (lease -> ip_addr),
|
||||
- (lease -> hardware_addr.hlen
|
||||
+ (lease -> hardware_addr.hlen > 1
|
||||
? print_hw_addr (lease -> hardware_addr.hbuf [0],
|
||||
lease -> hardware_addr.hlen - 1,
|
||||
&lease -> hardware_addr.hbuf [1])
|
||||
@@ -4605,10 +4626,7 @@ int find_lease (struct lease **lp,
|
||||
if (uid_lease) {
|
||||
if (uid_lease->binding_state == FTS_ACTIVE) {
|
||||
log_error ("client %s has duplicate%s on %s",
|
||||
- (print_hw_addr
|
||||
- (packet -> raw -> htype,
|
||||
- packet -> raw -> hlen,
|
||||
- packet -> raw -> chaddr)),
|
||||
+ (print_hw_addr_or_client_id(packet)),
|
||||
" leases",
|
||||
(ip_lease -> subnet ->
|
||||
shared_network -> name));
|
||||
@@ -4775,9 +4793,7 @@ int find_lease (struct lease **lp,
|
||||
log_error("uid lease %s for client %s is duplicate "
|
||||
"on %s",
|
||||
piaddr(uid_lease->ip_addr),
|
||||
- print_hw_addr(packet->raw->htype,
|
||||
- packet->raw->hlen,
|
||||
- packet->raw->chaddr),
|
||||
+ print_hw_addr_or_client_id(packet),
|
||||
uid_lease->subnet->shared_network->name);
|
||||
|
||||
if (!packet -> raw -> ciaddr.s_addr &&
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,125 +0,0 @@
|
||||
From 0a0a7e1afa171289b9e9d855c519101bbd71b5fe Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 10:36:30 +0100
|
||||
Subject: [PATCH 16/28] Turn on creating/sending of DUID
|
||||
|
||||
as client identifier with DHCPv4 clients (#560361c#40, rfc4361)
|
||||
---
|
||||
client/dhclient.c | 74 ++++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 70 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||
index 181f6e1..444d251 100644
|
||||
--- a/client/dhclient.c
|
||||
+++ b/client/dhclient.c
|
||||
@@ -4267,6 +4267,59 @@ write_options(struct client_state *client, struct option_state *options,
|
||||
}
|
||||
}
|
||||
|
||||
+int unhexchar(char c) {
|
||||
+
|
||||
+ if (c >= '0' && c <= '9')
|
||||
+ return c - '0';
|
||||
+
|
||||
+ if (c >= 'a' && c <= 'f')
|
||||
+ return c - 'a' + 10;
|
||||
+
|
||||
+ if (c >= 'A' && c <= 'F')
|
||||
+ return c - 'A' + 10;
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+isc_result_t
|
||||
+read_uuid(u_int8_t* uuid) {
|
||||
+ const char *id_fname = "/etc/machine-id";
|
||||
+ char id[32];
|
||||
+ size_t nread;
|
||||
+ FILE * file = fopen( id_fname , "r");
|
||||
+ if (!file) {
|
||||
+ log_debug("Cannot open %s", id_fname);
|
||||
+ return ISC_R_IOERROR;
|
||||
+ }
|
||||
+ nread = fread(id, 1, sizeof id, file);
|
||||
+ fclose(file);
|
||||
+
|
||||
+ if (nread < 32) {
|
||||
+ log_debug("Not enough data in %s", id_fname);
|
||||
+ return ISC_R_IOERROR;
|
||||
+ }
|
||||
+ int j;
|
||||
+ for (j = 0; j < 16; j++) {
|
||||
+ int a, b;
|
||||
+
|
||||
+ a = unhexchar(id[j*2]);
|
||||
+ b = unhexchar(id[j*2+1]);
|
||||
+
|
||||
+ if (a < 0 || b < 0) {
|
||||
+ log_debug("Wrong data in %s", id_fname);
|
||||
+ return ISC_R_IOERROR;
|
||||
+ }
|
||||
+ uuid[j] = a << 4 | b;
|
||||
+ }
|
||||
+
|
||||
+ /* Set UUID version to 4 --- truly random generation */
|
||||
+ uuid[6] = (uuid[6] & 0x0F) | 0x40;
|
||||
+ /* Set the UUID variant to DCE */
|
||||
+ uuid[8] = (uuid[8] & 0x3F) | 0x80;
|
||||
+
|
||||
+ return ISC_R_SUCCESS;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* The "best" default DUID, since we cannot predict any information
|
||||
* about the system (such as whether or not the hardware addresses are
|
||||
@@ -4287,6 +4340,7 @@ form_duid(struct data_string *duid, const char *file, int line)
|
||||
struct interface_info *ip;
|
||||
int len;
|
||||
char *str;
|
||||
+ u_int8_t uuid[16];
|
||||
|
||||
/* For now, just use the first interface on the list. */
|
||||
ip = interfaces;
|
||||
@@ -4307,9 +4361,16 @@ form_duid(struct data_string *duid, const char *file, int line)
|
||||
(ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
|
||||
log_fatal("Impossible hardware address length at %s:%d.", MDL);
|
||||
|
||||
- if (duid_type == 0)
|
||||
- duid_type = stateless ? DUID_LL : DUID_LLT;
|
||||
-
|
||||
+ if (duid_type == 0) {
|
||||
+ if (read_uuid(uuid) == ISC_R_SUCCESS)
|
||||
+ duid_type = DUID_UUID;
|
||||
+ else
|
||||
+ duid_type = stateless ? DUID_LL : DUID_LLT;
|
||||
+ }
|
||||
+
|
||||
+ if (duid_type == DUID_UUID)
|
||||
+ len = 2 + sizeof (uuid);
|
||||
+ else {
|
||||
/*
|
||||
* 2 bytes for the 'duid type' field.
|
||||
* 2 bytes for the 'htype' field.
|
||||
@@ -4320,13 +4381,18 @@ form_duid(struct data_string *duid, const char *file, int line)
|
||||
len = 4 + (ip->hw_address.hlen - 1);
|
||||
if (duid_type == DUID_LLT)
|
||||
len += 4;
|
||||
+ }
|
||||
if (!buffer_allocate(&duid->buffer, len, MDL))
|
||||
log_fatal("no memory for default DUID!");
|
||||
duid->data = duid->buffer->data;
|
||||
duid->len = len;
|
||||
|
||||
+ if (duid_type == DUID_UUID) {
|
||||
+ putUShort(duid->buffer->data, DUID_UUID);
|
||||
+ memcpy(duid->buffer->data + 2, uuid, sizeof(uuid));
|
||||
+ }
|
||||
/* Basic Link Local Address type of DUID. */
|
||||
- if (duid_type == DUID_LLT) {
|
||||
+ else if (duid_type == DUID_LLT) {
|
||||
putUShort(duid->buffer->data, DUID_LLT);
|
||||
putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]);
|
||||
putULong(duid->buffer->data + 4, cur_time - DUID_TIME_EPOCH);
|
||||
--
|
||||
2.35.1
|
||||
|
1
dead.package
Normal file
1
dead.package
Normal file
@ -0,0 +1 @@
|
||||
dhcp package is retired on branch c10s for CS-2097
|
Loading…
Reference in New Issue
Block a user