From 06c72f2ea4c2a182f6a82dc79903f39b9be15f01 Mon Sep 17 00:00:00 2001 From: Jiri Popelka Date: Oct 18 2011 17:13:08 +0000 Subject: 4.2.3rc1 --- diff --git a/.gitignore b/.gitignore index a8c2e3f..b92c17d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /dhcp-4.2.2b1.tar.gz /dhcp-4.2.2rc1.tar.gz /dhcp-4.2.2.tar.gz +/dhcp-4.2.3rc1.tar.gz diff --git a/dhcp-4.2.2-options.patch b/dhcp-4.2.2-options.patch deleted file mode 100644 index 32e2add..0000000 --- a/dhcp-4.2.2-options.patch +++ /dev/null @@ -1,401 +0,0 @@ -diff -up dhcp-4.2.2b1/client/clparse.c.options dhcp-4.2.2b1/client/clparse.c ---- dhcp-4.2.2b1/client/clparse.c.options 2011-04-21 16:08:14.000000000 +0200 -+++ dhcp-4.2.2b1/client/clparse.c 2011-07-01 13:51:52.935755570 +0200 -@@ -146,6 +146,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) -@@ -313,7 +314,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; -@@ -732,6 +734,12 @@ void parse_client_statement (cfile, ip, - parse_reject_statement (cfile, config); - return; - -+ case BOOTP_BROADCAST_ALWAYS: -+ token = next_token(&val, (unsigned*)0, cfile); -+ config -> bootp_broadcast_always = 1; -+ parse_semi (cfile); -+ return; -+ - default: - lose = 0; - stmt = (struct executable_statement *)0; -diff -up dhcp-4.2.2b1/client/dhclient.c.options dhcp-4.2.2b1/client/dhclient.c ---- dhcp-4.2.2b1/client/dhclient.c.options 2011-05-11 16:20:59.000000000 +0200 -+++ dhcp-4.2.2b1/client/dhclient.c 2011-07-01 13:51:52.936755545 +0200 -@@ -39,6 +39,12 @@ - #include - #include - -+/* -+ * 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... */ - -@@ -87,6 +93,9 @@ int wanted_ia_na = -1; /* the absolute - int wanted_ia_ta = 0; - int wanted_ia_pd = 0; - char *mockup_relay = NULL; -+int bootp_broadcast_always = 0; -+ -+extern u_int32_t default_requested_options[]; - - void run_stateless(int exit_mode); - -@@ -123,6 +132,15 @@ main(int argc, char **argv) { - int local_family_set = 0; - #endif /* DHCPv6 */ - char *s; -+ 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)); -@@ -310,6 +328,88 @@ main(int argc, char **argv) { - } else if (!strcmp(argv[i], "--version")) { - log_info("isc-dhclient-%s", PACKAGE_VERSION); - exit(0); -+ } else if (!strcmp(argv[i], "-I")) { -+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) { -+ usage(); -+ exit(1); -+ } -+ -+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) { -+ log_error("-I 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(); -+ 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 and -F 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(); -+ 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 argument can be specified"); -+ exit(1); -+ } -+ -+ if (dhcp_host_name_arg != NULL) { -+ log_error("The -F and -H 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(); -+ exit(1); -+ } -+ -+ if ((timeout_arg = atoi(argv[i])) <= 0) { -+ log_error("-T 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(); -+ 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], "-R")) { -+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) { -+ usage(); -+ exit(1); -+ } -+ -+ dhclient_request_options = argv[i]; - } else if (argv[i][0] == '-') { - usage(); - } else if (interfaces_requested < 0) { -@@ -484,6 +584,166 @@ 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 -I 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 -R 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 -R 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 -I/-H/-F/-timeout/-V/-R 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 -I/-H/-F/-timeout/-V/-R configuration arguments", 0); -+ -+ if ((status != ISC_R_SUCCESS) || (cfile -> warnings_occurred)) -+ log_fatal("Cannot parse -I/-H/-F/-timeout/-V/-R 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 -I/-H/-F/-timeout/-V/-R configuration arguments !"); -+ end_parse(&cfile); -+ -+ if (timeout_arg) { -+ /* we just set the toplevel timeout, but per-client -+ * timeouts may still be at defaults. Also, it makes no -+ * sense having the reboot_timeout or backoff_cutoff -+ * greater than the timeout: -+ */ -+ if ((top_level_config.backoff_cutoff == 15) && (top_level_config.backoff_cutoff > (timeout_arg / 2))) -+ top_level_config.backoff_cutoff = (((unsigned long)(timeout_arg / 2)) == 0) ? timeout_arg : (unsigned long)(timeout_arg / 2); -+ -+ for (ip=interfaces; ip; ip = ip->next) { -+ if (ip->client->config->timeout == 60) -+ ip->client->config->timeout = timeout_arg; -+ -+ if ((ip->client->config->reboot_timeout == 10) && (ip->client->config->reboot_timeout > ip->client->config->timeout)) -+ ip->client->config->reboot_timeout = ip->client->config->timeout; -+ if ((ip->client->config->backoff_cutoff == 15) && (ip->client->config->backoff_cutoff > top_level_config.backoff_cutoff)) -+ ip->client->config->backoff_cutoff = top_level_config.backoff_cutoff; -+ } -+ } -+ -+ 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(); - -@@ -2397,7 +2657,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); -@@ -2481,7 +2742,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); -@@ -2543,7 +2806,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 -up dhcp-4.2.2b1/common/conflex.c.options dhcp-4.2.2b1/common/conflex.c ---- dhcp-4.2.2b1/common/conflex.c.options 2011-05-11 16:20:59.000000000 +0200 -+++ dhcp-4.2.2b1/common/conflex.c 2011-07-01 13:51:52.938755494 +0200 -@@ -808,6 +808,8 @@ intern(char *atom, enum dhcp_token dfv) - return BALANCE; - if (!strcasecmp (atom + 1, "ound")) - return BOUND; -+ if (!strcasecmp (atom + 1, "ootp-broadcast-always")) -+ return BOOTP_BROADCAST_ALWAYS; - break; - case 'c': - if (!strcasecmp(atom + 1, "ase")) -diff -up dhcp-4.2.2b1/includes/dhcpd.h.options dhcp-4.2.2b1/includes/dhcpd.h ---- dhcp-4.2.2b1/includes/dhcpd.h.options 2011-05-20 16:21:11.000000000 +0200 -+++ dhcp-4.2.2b1/includes/dhcpd.h 2011-07-01 13:51:52.940755442 +0200 -@@ -1147,6 +1147,9 @@ struct client_config { - int do_forward_update; /* If nonzero, and if we have the - information we need, update the - A record for the address we get. */ -+ -+ int bootp_broadcast_always; /* If nonzero, always set the BOOTP_BROADCAST -+ flag in requests */ - }; - - /* Per-interface state used in the dhcp client... */ -diff -up dhcp-4.2.2b1/includes/dhctoken.h.options dhcp-4.2.2b1/includes/dhctoken.h ---- dhcp-4.2.2b1/includes/dhctoken.h.options 2011-05-12 14:02:47.000000000 +0200 -+++ dhcp-4.2.2b1/includes/dhctoken.h 2011-07-01 13:53:43.316861637 +0200 -@@ -361,7 +361,8 @@ enum dhcp_token { - GETHOSTNAME = 662, - REWIND = 663, - INITIAL_DELAY = 664, -- GETHOSTBYNAME = 665 -+ GETHOSTBYNAME = 665, -+ BOOTP_BROADCAST_ALWAYS = 666 - }; - - #define is_identifier(x) ((x) >= FIRST_TOKEN && \ diff --git a/dhcp-4.2.2-rfc3442-classless-static-routes.patch b/dhcp-4.2.2-rfc3442-classless-static-routes.patch deleted file mode 100644 index 0a0bfcb..0000000 --- a/dhcp-4.2.2-rfc3442-classless-static-routes.patch +++ /dev/null @@ -1,405 +0,0 @@ -diff -up dhcp-4.2.2b1/client/clparse.c.rfc3442 dhcp-4.2.2b1/client/clparse.c ---- dhcp-4.2.2b1/client/clparse.c.rfc3442 2011-07-01 14:22:38.031534508 +0200 -+++ dhcp-4.2.2b1/client/clparse.c 2011-07-01 14:22:38.128532940 +0200 -@@ -37,7 +37,7 @@ - - struct client_config top_level_config; - --#define NUM_DEFAULT_REQUESTED_OPTS 14 -+#define NUM_DEFAULT_REQUESTED_OPTS 15 - struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 1]; - - static void parse_client_default_duid(struct parse *cfile); -@@ -82,7 +82,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); - -@@ -136,6 +140,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 -up dhcp-4.2.2b1/common/dhcp-options.5.rfc3442 dhcp-4.2.2b1/common/dhcp-options.5 ---- dhcp-4.2.2b1/common/dhcp-options.5.rfc3442 2011-07-01 14:22:38.020534686 +0200 -+++ dhcp-4.2.2b1/common/dhcp-options.5 2011-07-01 14:22:38.129532924 +0200 -@@ -115,6 +115,26 @@ hexadecimal, separated by colons. For - 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 -@@ -931,6 +951,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 -up dhcp-4.2.2b1/common/inet.c.rfc3442 dhcp-4.2.2b1/common/inet.c ---- dhcp-4.2.2b1/common/inet.c.rfc3442 2011-05-11 02:47:22.000000000 +0200 -+++ dhcp-4.2.2b1/common/inet.c 2011-07-01 14:22:38.130532908 +0200 -@@ -528,6 +528,60 @@ free_iaddrcidrnetlist(struct iaddrcidrne - 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 ""; -+ } -+ 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 -up dhcp-4.2.2b1/common/options.c.rfc3442 dhcp-4.2.2b1/common/options.c ---- dhcp-4.2.2b1/common/options.c.rfc3442 2011-03-24 22:57:13.000000000 +0100 -+++ dhcp-4.2.2b1/common/options.c 2011-07-01 14:22:38.132532876 +0200 -@@ -706,7 +706,11 @@ cons_options(struct packet *inpacket, st - * 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; -@@ -1683,6 +1687,7 @@ const char *pretty_print_option (option, - const unsigned char *dp = data; - char comma; - unsigned long tval; -+ unsigned int octets = 0; - - if (emit_commas) - comma = ','; -@@ -1691,6 +1696,7 @@ const char *pretty_print_option (option, - - 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) -@@ -1840,6 +1846,33 @@ const char *pretty_print_option (option, - 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++) { - for (j = 0; j < numelem; j++) { -@@ -1978,6 +2011,20 @@ const char *pretty_print_option (option, - 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 ""; -+ } -+ -+ 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 -up dhcp-4.2.2b1/common/parse.c.rfc3442 dhcp-4.2.2b1/common/parse.c ---- dhcp-4.2.2b1/common/parse.c.rfc3442 2011-07-01 14:22:38.097533441 +0200 -+++ dhcp-4.2.2b1/common/parse.c 2011-07-01 14:22:38.135532828 +0200 -@@ -341,6 +341,39 @@ int parse_ip_addr (cfile, addr) - } - - /* -+ * 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. - */ - static int -@@ -700,8 +733,10 @@ unsigned char *parse_numeric_aggregate ( - 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, -@@ -1624,6 +1659,9 @@ int parse_option_code_definition (cfile, - case IP_ADDRESS: - type = 'I'; - break; -+ case DESTINATION_DESCRIPTOR: -+ type = 'R'; -+ break; - case IP6_ADDRESS: - type = '6'; - break; -@@ -5288,6 +5326,15 @@ int parse_option_token (rv, cfile, fmt, - } - 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; -@@ -5548,6 +5595,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 -up dhcp-4.2.2b1/common/tables.c.rfc3442 dhcp-4.2.2b1/common/tables.c ---- dhcp-4.2.2b1/common/tables.c.rfc3442 2011-07-01 14:22:38.087533601 +0200 -+++ dhcp-4.2.2b1/common/tables.c 2011-07-01 14:22:38.137532796 +0200 -@@ -51,6 +51,7 @@ HASH_FUNCTIONS (option_code, const unsig - Format codes: - - I - IPv4 address -+ R - destination descriptor (RFC3442) - 6 - IPv6 address - l - 32-bit signed integer - L - 32-bit unsigned integer -@@ -208,6 +209,7 @@ static struct option dhcp_options[] = { - { "default-url", "t", &dhcp_universe, 114, 1 }, - { "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 -up dhcp-4.2.2b1/includes/dhcpd.h.rfc3442 dhcp-4.2.2b1/includes/dhcpd.h ---- dhcp-4.2.2b1/includes/dhcpd.h.rfc3442 2011-07-01 14:22:38.000000000 +0200 -+++ dhcp-4.2.2b1/includes/dhcpd.h 2011-07-01 14:24:19.999810333 +0200 -@@ -2662,6 +2662,7 @@ isc_result_t range2cidr(struct iaddrcidr - 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 *); -@@ -2869,6 +2870,7 @@ void parse_client_lease_declaration (str - 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 -up dhcp-4.2.2b1/includes/dhcp.h.rfc3442 dhcp-4.2.2b1/includes/dhcp.h ---- dhcp-4.2.2b1/includes/dhcp.h.rfc3442 2009-11-20 02:49:01.000000000 +0100 -+++ dhcp-4.2.2b1/includes/dhcp.h 2011-07-01 14:22:38.145532665 +0200 -@@ -158,6 +158,7 @@ struct dhcp_packet { - #define DHO_ASSOCIATED_IP 92 - #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 -up dhcp-4.2.2b1/includes/dhctoken.h.rfc3442 dhcp-4.2.2b1/includes/dhctoken.h ---- dhcp-4.2.2b1/includes/dhctoken.h.rfc3442 2011-07-01 14:22:37.000000000 +0200 -+++ dhcp-4.2.2b1/includes/dhctoken.h 2011-07-01 14:25:12.541867623 +0200 -@@ -362,7 +362,8 @@ enum dhcp_token { - REWIND = 663, - INITIAL_DELAY = 664, - GETHOSTBYNAME = 665, -- BOOTP_BROADCAST_ALWAYS = 666 -+ BOOTP_BROADCAST_ALWAYS = 666, -+ DESTINATION_DESCRIPTOR = 667 - }; - - #define is_identifier(x) ((x) >= FIRST_TOKEN && \ diff --git a/dhcp-4.2.3-options.patch b/dhcp-4.2.3-options.patch new file mode 100644 index 0000000..09726ce --- /dev/null +++ b/dhcp-4.2.3-options.patch @@ -0,0 +1,401 @@ +diff -up dhcp-4.2.3rc1/client/clparse.c.options dhcp-4.2.3rc1/client/clparse.c +--- dhcp-4.2.3rc1/client/clparse.c.options 2011-04-21 16:08:14.000000000 +0200 ++++ dhcp-4.2.3rc1/client/clparse.c 2011-10-18 18:43:04.341962957 +0200 +@@ -146,6 +146,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) +@@ -313,7 +314,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; +@@ -732,6 +734,12 @@ void parse_client_statement (cfile, ip, + parse_reject_statement (cfile, config); + return; + ++ case BOOTP_BROADCAST_ALWAYS: ++ token = next_token(&val, (unsigned*)0, cfile); ++ config -> bootp_broadcast_always = 1; ++ parse_semi (cfile); ++ return; ++ + default: + lose = 0; + stmt = (struct executable_statement *)0; +diff -up dhcp-4.2.3rc1/client/dhclient.c.options dhcp-4.2.3rc1/client/dhclient.c +--- dhcp-4.2.3rc1/client/dhclient.c.options 2011-07-01 13:58:53.000000000 +0200 ++++ dhcp-4.2.3rc1/client/dhclient.c 2011-10-18 18:43:04.342962944 +0200 +@@ -39,6 +39,12 @@ + #include + #include + ++/* ++ * 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... */ + +@@ -87,6 +93,9 @@ int wanted_ia_na = -1; /* the absolute + int wanted_ia_ta = 0; + int wanted_ia_pd = 0; + char *mockup_relay = NULL; ++int bootp_broadcast_always = 0; ++ ++extern u_int32_t default_requested_options[]; + + void run_stateless(int exit_mode); + +@@ -123,6 +132,15 @@ main(int argc, char **argv) { + int local_family_set = 0; + #endif /* DHCPv6 */ + char *s; ++ 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)); +@@ -310,6 +328,88 @@ main(int argc, char **argv) { + } else if (!strcmp(argv[i], "--version")) { + log_info("isc-dhclient-%s", PACKAGE_VERSION); + exit(0); ++ } else if (!strcmp(argv[i], "-I")) { ++ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) { ++ usage(); ++ exit(1); ++ } ++ ++ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) { ++ log_error("-I 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(); ++ 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 and -F 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(); ++ 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 argument can be specified"); ++ exit(1); ++ } ++ ++ if (dhcp_host_name_arg != NULL) { ++ log_error("The -F and -H 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(); ++ exit(1); ++ } ++ ++ if ((timeout_arg = atoi(argv[i])) <= 0) { ++ log_error("-T 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(); ++ 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], "-R")) { ++ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) { ++ usage(); ++ exit(1); ++ } ++ ++ dhclient_request_options = argv[i]; + } else if (argv[i][0] == '-') { + usage(); + } else if (interfaces_requested < 0) { +@@ -484,6 +584,166 @@ 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 -I 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 -R 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 -R 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 -I/-H/-F/-timeout/-V/-R 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 -I/-H/-F/-timeout/-V/-R configuration arguments", 0); ++ ++ if ((status != ISC_R_SUCCESS) || (cfile -> warnings_occurred)) ++ log_fatal("Cannot parse -I/-H/-F/-timeout/-V/-R 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 -I/-H/-F/-timeout/-V/-R configuration arguments !"); ++ end_parse(&cfile); ++ ++ if (timeout_arg) { ++ /* we just set the toplevel timeout, but per-client ++ * timeouts may still be at defaults. Also, it makes no ++ * sense having the reboot_timeout or backoff_cutoff ++ * greater than the timeout: ++ */ ++ if ((top_level_config.backoff_cutoff == 15) && (top_level_config.backoff_cutoff > (timeout_arg / 2))) ++ top_level_config.backoff_cutoff = (((unsigned long)(timeout_arg / 2)) == 0) ? timeout_arg : (unsigned long)(timeout_arg / 2); ++ ++ for (ip=interfaces; ip; ip = ip->next) { ++ if (ip->client->config->timeout == 60) ++ ip->client->config->timeout = timeout_arg; ++ ++ if ((ip->client->config->reboot_timeout == 10) && (ip->client->config->reboot_timeout > ip->client->config->timeout)) ++ ip->client->config->reboot_timeout = ip->client->config->timeout; ++ if ((ip->client->config->backoff_cutoff == 15) && (ip->client->config->backoff_cutoff > top_level_config.backoff_cutoff)) ++ ip->client->config->backoff_cutoff = top_level_config.backoff_cutoff; ++ } ++ } ++ ++ 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(); + +@@ -2397,7 +2657,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); +@@ -2481,7 +2742,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); +@@ -2543,7 +2806,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 -up dhcp-4.2.3rc1/common/conflex.c.options dhcp-4.2.3rc1/common/conflex.c +--- dhcp-4.2.3rc1/common/conflex.c.options 2011-09-21 22:43:10.000000000 +0200 ++++ dhcp-4.2.3rc1/common/conflex.c 2011-10-18 18:43:04.347962883 +0200 +@@ -808,6 +808,8 @@ intern(char *atom, enum dhcp_token dfv) + return BALANCE; + if (!strcasecmp (atom + 1, "ound")) + return BOUND; ++ if (!strcasecmp (atom + 1, "ootp-broadcast-always")) ++ return BOOTP_BROADCAST_ALWAYS; + break; + case 'c': + if (!strcasecmp(atom + 1, "ase")) +diff -up dhcp-4.2.3rc1/includes/dhcpd.h.options dhcp-4.2.3rc1/includes/dhcpd.h +--- dhcp-4.2.3rc1/includes/dhcpd.h.options 2011-10-04 21:43:12.000000000 +0200 ++++ dhcp-4.2.3rc1/includes/dhcpd.h 2011-10-18 18:43:04.388962369 +0200 +@@ -1147,6 +1147,9 @@ struct client_config { + int do_forward_update; /* If nonzero, and if we have the + information we need, update the + A record for the address we get. */ ++ ++ int bootp_broadcast_always; /* If nonzero, always set the BOOTP_BROADCAST ++ flag in requests */ + }; + + /* Per-interface state used in the dhcp client... */ +diff -up dhcp-4.2.3rc1/includes/dhctoken.h.options dhcp-4.2.3rc1/includes/dhctoken.h +--- dhcp-4.2.3rc1/includes/dhctoken.h.options 2011-09-21 22:43:10.000000000 +0200 ++++ dhcp-4.2.3rc1/includes/dhctoken.h 2011-10-18 18:47:08.039916315 +0200 +@@ -363,7 +363,8 @@ enum dhcp_token { + INITIAL_DELAY = 664, + GETHOSTBYNAME = 665, + PRIMARY6 = 666, +- SECONDARY6 = 667 ++ SECONDARY6 = 667, ++ BOOTP_BROADCAST_ALWAYS = 668 + }; + + #define is_identifier(x) ((x) >= FIRST_TOKEN && \ diff --git a/dhcp-4.2.3-rfc3442-classless-static-routes.patch b/dhcp-4.2.3-rfc3442-classless-static-routes.patch new file mode 100644 index 0000000..5897c21 --- /dev/null +++ b/dhcp-4.2.3-rfc3442-classless-static-routes.patch @@ -0,0 +1,405 @@ +diff -up dhcp-4.2.3rc1/client/clparse.c.rfc3442 dhcp-4.2.3rc1/client/clparse.c +--- dhcp-4.2.3rc1/client/clparse.c.rfc3442 2011-10-18 18:50:11.564621939 +0200 ++++ dhcp-4.2.3rc1/client/clparse.c 2011-10-18 18:50:11.661620727 +0200 +@@ -37,7 +37,7 @@ + + struct client_config top_level_config; + +-#define NUM_DEFAULT_REQUESTED_OPTS 14 ++#define NUM_DEFAULT_REQUESTED_OPTS 15 + struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 1]; + + static void parse_client_default_duid(struct parse *cfile); +@@ -82,7 +82,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); + +@@ -136,6 +140,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 -up dhcp-4.2.3rc1/common/dhcp-options.5.rfc3442 dhcp-4.2.3rc1/common/dhcp-options.5 +--- dhcp-4.2.3rc1/common/dhcp-options.5.rfc3442 2011-10-18 18:50:11.550622114 +0200 ++++ dhcp-4.2.3rc1/common/dhcp-options.5 2011-10-18 18:50:11.662620715 +0200 +@@ -115,6 +115,26 @@ hexadecimal, separated by colons. For + 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 +@@ -931,6 +951,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 -up dhcp-4.2.3rc1/common/inet.c.rfc3442 dhcp-4.2.3rc1/common/inet.c +--- dhcp-4.2.3rc1/common/inet.c.rfc3442 2011-05-11 02:47:22.000000000 +0200 ++++ dhcp-4.2.3rc1/common/inet.c 2011-10-18 18:50:11.665620676 +0200 +@@ -528,6 +528,60 @@ free_iaddrcidrnetlist(struct iaddrcidrne + 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 ""; ++ } ++ 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 -up dhcp-4.2.3rc1/common/options.c.rfc3442 dhcp-4.2.3rc1/common/options.c +--- dhcp-4.2.3rc1/common/options.c.rfc3442 2011-07-20 00:22:48.000000000 +0200 ++++ dhcp-4.2.3rc1/common/options.c 2011-10-18 18:50:11.725619925 +0200 +@@ -706,7 +706,11 @@ cons_options(struct packet *inpacket, st + * 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; +@@ -1683,6 +1687,7 @@ const char *pretty_print_option (option, + const unsigned char *dp = data; + char comma; + unsigned long tval; ++ unsigned int octets = 0; + + if (emit_commas) + comma = ','; +@@ -1691,6 +1696,7 @@ const char *pretty_print_option (option, + + 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) +@@ -1840,6 +1846,33 @@ const char *pretty_print_option (option, + 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++) { + for (j = 0; j < numelem; j++) { +@@ -1978,6 +2011,20 @@ const char *pretty_print_option (option, + 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 ""; ++ } ++ ++ 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 -up dhcp-4.2.3rc1/common/parse.c.rfc3442 dhcp-4.2.3rc1/common/parse.c +--- dhcp-4.2.3rc1/common/parse.c.rfc3442 2011-10-18 18:50:11.609621377 +0200 ++++ dhcp-4.2.3rc1/common/parse.c 2011-10-18 18:50:11.731619852 +0200 +@@ -341,6 +341,39 @@ int parse_ip_addr (cfile, addr) + } + + /* ++ * 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. + */ + static int +@@ -700,8 +733,10 @@ unsigned char *parse_numeric_aggregate ( + 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, +@@ -1624,6 +1659,9 @@ int parse_option_code_definition (cfile, + case IP_ADDRESS: + type = 'I'; + break; ++ case DESTINATION_DESCRIPTOR: ++ type = 'R'; ++ break; + case IP6_ADDRESS: + type = '6'; + break; +@@ -5372,6 +5410,15 @@ int parse_option_token (rv, cfile, fmt, + } + 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; +@@ -5632,6 +5679,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 -up dhcp-4.2.3rc1/common/tables.c.rfc3442 dhcp-4.2.3rc1/common/tables.c +--- dhcp-4.2.3rc1/common/tables.c.rfc3442 2011-10-18 18:50:11.600621489 +0200 ++++ dhcp-4.2.3rc1/common/tables.c 2011-10-18 18:50:11.736619789 +0200 +@@ -51,6 +51,7 @@ HASH_FUNCTIONS (option_code, const unsig + Format codes: + + I - IPv4 address ++ R - destination descriptor (RFC3442) + 6 - IPv6 address + l - 32-bit signed integer + L - 32-bit unsigned integer +@@ -208,6 +209,7 @@ static struct option dhcp_options[] = { + { "default-url", "t", &dhcp_universe, 114, 1 }, + { "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 -up dhcp-4.2.3rc1/includes/dhcpd.h.rfc3442 dhcp-4.2.3rc1/includes/dhcpd.h +--- dhcp-4.2.3rc1/includes/dhcpd.h.rfc3442 2011-10-18 18:50:11.561621977 +0200 ++++ dhcp-4.2.3rc1/includes/dhcpd.h 2011-10-18 18:50:11.767619401 +0200 +@@ -2665,6 +2665,7 @@ isc_result_t range2cidr(struct iaddrcidr + 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 *); +@@ -2872,6 +2873,7 @@ void parse_client_lease_declaration (str + 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 -up dhcp-4.2.3rc1/includes/dhcp.h.rfc3442 dhcp-4.2.3rc1/includes/dhcp.h +--- dhcp-4.2.3rc1/includes/dhcp.h.rfc3442 2009-11-20 02:49:01.000000000 +0100 ++++ dhcp-4.2.3rc1/includes/dhcp.h 2011-10-18 18:50:11.772619339 +0200 +@@ -158,6 +158,7 @@ struct dhcp_packet { + #define DHO_ASSOCIATED_IP 92 + #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 -up dhcp-4.2.3rc1/includes/dhctoken.h.rfc3442 dhcp-4.2.3rc1/includes/dhctoken.h +--- dhcp-4.2.3rc1/includes/dhctoken.h.rfc3442 2011-10-18 18:50:11.000000000 +0200 ++++ dhcp-4.2.3rc1/includes/dhctoken.h 2011-10-18 18:50:55.753069508 +0200 +@@ -364,7 +364,8 @@ enum dhcp_token { + GETHOSTBYNAME = 665, + PRIMARY6 = 666, + SECONDARY6 = 667, +- BOOTP_BROADCAST_ALWAYS = 668 ++ BOOTP_BROADCAST_ALWAYS = 668, ++ DESTINATION_DESCRIPTOR = 669 + }; + + #define is_identifier(x) ((x) >= FIRST_TOKEN && \ diff --git a/dhcp.spec b/dhcp.spec index 5776a19..3a13838 100644 --- a/dhcp.spec +++ b/dhcp.spec @@ -10,16 +10,16 @@ # Patch version #%global patchver P1 # Pre-Release version -#%global prever rc1 +%global prever rc1 #%global VERSION %{version}-%{patchver} -#%global VERSION %{version}%{prever} -%global VERSION %{version} +#%global VERSION %{version} +%global VERSION %{version}%{prever} Summary: Dynamic host configuration protocol software Name: dhcp -Version: 4.2.2 -Release: 12%{?dist} +Version: 4.2.3 +Release: 0.1.%{prever}%{?dist} # NEVER CHANGE THE EPOCH on this package. The previous maintainer (prior to # dcantrell maintaining the package) made incorrect use of the epoch and # that's why it is at 12 now. It should have never been used, but it was. @@ -42,7 +42,7 @@ Source10: dhcpd6.service Source11: dhcrelay.service Patch0: dhcp-4.2.0-errwarn-message.patch -Patch1: dhcp-4.2.2-options.patch +Patch1: dhcp-4.2.3-options.patch Patch2: dhcp-4.2.0-release-by-ifup.patch Patch3: dhcp-4.2.0-dhclient-decline-backoff.patch Patch4: dhcp-4.2.0-unicast-bootp.patch @@ -62,7 +62,7 @@ Patch20: dhcp-4.2.0-logpid.patch Patch21: dhcp-4.2.0-UseMulticast.patch Patch22: dhcp-4.2.1-sendDecline.patch Patch23: dhcp-4.2.1-retransmission.patch -Patch25: dhcp-4.2.2-rfc3442-classless-static-routes.patch +Patch25: dhcp-4.2.3-rfc3442-classless-static-routes.patch Patch27: dhcp-4.2.0-honor-expired.patch Patch28: dhcp-4.2.0-noprefixavail.patch Patch29: dhcp-4.2.2-remove-bind.patch @@ -662,6 +662,9 @@ fi %{_initddir}/dhcrelay %changelog +* Tue Oct 18 2011 Jiri Popelka - 12:4.2.3-0.1.rc1 +- 4.2.3rc1 + * Sun Oct 09 2011 Jiri Popelka - 12:4.2.2-12 - change ownership of /var/lib/dhcpd/ to dhcpd:dhcpd (#744292) - no need to drop capabilies in dhcpd since it's been running as regular user diff --git a/sources b/sources index 503d838..ded7651 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -bb0f0434cd796f76aa7cead391d71f31 dhcp-4.2.2.tar.gz +2471fd1657ef8da3dfa053a5b54a8324 dhcp-4.2.3rc1.tar.gz