[dhcp] RFC 3442 - Classless Static Route Option for DHCPv4 (#516325)
Jiří Popelka
jpopelka at fedoraproject.org
Tue Aug 31 11:26:02 UTC 2010
commit a21bc05f7d31dc7ddc84e4d1cd810daf6bdf279d
Author: Jiri Popelka <jpopelka at redhat.com>
Date: Tue Aug 31 13:01:51 2010 +0200
RFC 3442 - Classless Static Route Option for DHCPv4 (#516325)
.gitignore | 2 -
dhclient-script | 142 +++++---
dhcp-4.2.0-rfc3442-classless-static-routes.patch | 405 ++++++++++++++++++++++
dhcp.spec | 10 +-
sources | 2 -
5 files changed, 501 insertions(+), 60 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 5e21cc6..d904b0b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1 @@
-ldap-for-dhcp-4.1.1-2.tar.gz
-dhcp-4.1.1-P1.tar.gz
dhcp-4.2.0.tar.gz
diff --git a/dhclient-script b/dhclient-script
index eb0e840..9290d91 100755
--- a/dhclient-script
+++ b/dhclient-script
@@ -171,13 +171,28 @@ num2ip() {
echo "${o1}.${o2}.${o3}.${o4}"
}
-mask() {
+get_network_address() {
+# get network address for the given IP address and (netmask or prefix)
ip="${1}"
- m="${2}"
- let ip="$(IFS="." ip2num ${ip})"
- let m="$(IFS="." ip2num ${m})"
- let n="ip & m"
- num2ip ${n}
+ nm="${2}"
+
+ if [ -n "${ip}" -a -n "${nm}" ]; then
+ if [[ "${nm}" = *.* ]]; then
+ ipcalc -s -n ${ip} ${nm} | cut -d '=' -f 2
+ else
+ ipcalc -s -n ${ip}/${nm} | cut -d '=' -f 2
+ fi
+ fi
+}
+
+get_prefix() {
+# get prefix for the given IP address and mask
+ ip="${1}"
+ nm="${2}"
+
+ if [ -n "${ip}" -a -n "${nm}" ]; then
+ ipcalc -s -p ${ip} ${nm} | cut -d '=' -f 2
+ fi
}
class_bits() {
@@ -198,8 +213,8 @@ class_bits() {
is_router_reachable() {
# handle DHCP servers that give us a router not on our subnet
router="${1}"
- routersubnet="$(mask ${router} ${new_subnet_mask})"
- mysubnet="$(mask ${new_ip_address} ${new_subnet_mask})"
+ routersubnet="$(get_network_address ${router} ${new_subnet_mask})"
+ mysubnet="$(get_network_address ${new_ip_address} ${new_subnet_mask})"
unreachable=0
if [ ! "${routersubnet}" = "${mysubnet}" ]; then
@@ -280,6 +295,69 @@ dhconfig() {
. ${ETCDIR}/dhclient-up-hooks
fi
+ # static routes
+ if [ -n "${new_classless_static_routes}" ] ||
+ [ -n "${new_static_routes}" ]; then
+ if [ -n "${new_classless_static_routes}" ]; then
+ IFS=', |' static_routes=(${new_classless_static_routes})
+
+ # If the DHCP server returns both a Classless Static Routes option and
+ # a Router option, the DHCP client MUST ignore the Router option. (RFC3442)
+ new_routers=""
+ else
+ IFS=', |' static_routes=(${new_static_routes})
+ fi
+ route_targets=()
+
+ for((i=0; i<${#static_routes[@]}; i+=2)); do
+ target=${static_routes[$i]}
+ if [ -n "${new_classless_static_routes}" ]; then
+ prefix=$(echo ${target} | cut -d "." -f 1)
+ target=$(echo ${target} | cut -d "." -f 2-)
+ IFS="." target_arr=(${target})
+ unset IFS
+ ((pads=4-${#target_arr[@]}))
+ for j in $(seq $pads); do
+ target=${target}".0"
+ done
+
+ # Client MUST zero any bits in the subnet number where the corresponding bit in the mask is zero.
+ # In other words, the subnet number installed in the routing table is the logical AND of
+ # the subnet number and subnet mask given in the Classless Static Routes option. (RFC3442)
+ target="$(get_network_address ${target} ${prefix})"
+ else
+ prefix=$(class_bits ${target})
+ fi
+ gateway=${static_routes[$i+1]}
+
+ metric=''
+ for t in ${route_targets[@]}; do
+ if [ ${t} = ${target} ]; then
+ if [ -z "${metric}" ]; then
+ metric=1
+ else
+ ((metric=metric+1))
+ fi
+ fi
+ done
+
+ if [ -n "${metric}" ]; then
+ metric="metric ${metric}"
+ fi
+
+ if is_router_reachable ${gateway}; then
+ ip -4 route replace ${target}/${prefix} via ${gateway} dev ${interface} ${metric}
+
+ if [ $? -ne 0 ]; then
+ logmessage "failed to create static route: ${target}/${prefix} via ${gateway} dev ${interface} ${metric}"
+ else
+ route_targets=(${route_targets[@]} ${target})
+ fi
+ fi
+ done
+ fi
+
+ # gateways
if [[ ( "${DEFROUTE}" != "no") &&
(( -z "${GATEWAYDEV}" ) ||
( "${GATEWAYDEV}" = "${interface}" )) ]]; then
@@ -313,8 +391,8 @@ dhconfig() {
metric=${i}
done
elif [ -n "${GATEWAY}" ]; then
- routersubnet=$(mask ${GATEWAY} ${new_subnet_mask})
- mysubnet=$(mask ${new_ip_address} ${new_subnet_mask})
+ routersubnet=$(get_network_address ${GATEWAY} ${new_subnet_mask})
+ mysubnet=$(get_network_address ${new_ip_address} ${new_subnet_mask})
if [ "${routersubnet}" = "${mysubnet}" ]; then
ip -4 route replace default via ${GATEWAY} dev ${interface}
@@ -322,41 +400,6 @@ dhconfig() {
fi
fi
- # static routes
- if [ -n "${new_static_routes}" ]; then
- IFS=', |' static_routes=(${new_static_routes})
- route_targets=()
-
- for((i=0; i<${#static_routes[@]}; i+=2)); do
- target=${static_routes[$i]}
- gateway=${static_routes[$i+1]}
- metric=''
-
- for t in ${route_targets[@]}; do
- if [ ${t} = ${target} ]; then
- if [ -z "${metric}" ]; then
- metric=1
- else
- ((metric=metric+1))
- fi
- fi
- done
-
- if [ -n "${metric}" ]; then
- metric="metric ${metric}"
- fi
-
- if is_router_reachable ${gateway}; then
- ip -4 route replace ${target}/$(class_bits ${target}) via ${gateway} dev ${interface} ${metric}
-
- if [ $? -ne 0 ]; then
- logmessage "failed to create static route: ${target}/$(class_bits ${target}) via ${gateway} dev ${interface} ${metric}"
- else
- route_targets=(${route_targets[@]} ${target})
- fi
- fi
- done
- fi
fi
if [ ! "${new_ip_address}" = "${alias_ip_address}" ] &&
@@ -490,15 +533,6 @@ dh6config() {
fi
}
-get_prefix() {
- ip="${1}"
- nm="${2}"
-
- if [ -n "${ip}" -a -n "${nm}" ]; then
- ipcalc -s -p ${ip} ${nm} | cut -d '=' -f 2
- fi
-}
-
#
# ### MAIN
diff --git a/dhcp-4.2.0-rfc3442-classless-static-routes.patch b/dhcp-4.2.0-rfc3442-classless-static-routes.patch
new file mode 100644
index 0000000..c98ddc2
--- /dev/null
+++ b/dhcp-4.2.0-rfc3442-classless-static-routes.patch
@@ -0,0 +1,405 @@
+diff -up dhcp-4.2.0/client/clparse.c.rfc3442 dhcp-4.2.0/client/clparse.c
+--- dhcp-4.2.0/client/clparse.c.rfc3442 2010-08-31 10:12:51.000000000 +0200
++++ dhcp-4.2.0/client/clparse.c 2010-08-31 10:13:49.000000000 +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.0/common/dhcp-options.5.rfc3442 dhcp-4.2.0/common/dhcp-options.5
+--- dhcp-4.2.0/common/dhcp-options.5.rfc3442 2010-08-31 10:12:51.000000000 +0200
++++ dhcp-4.2.0/common/dhcp-options.5 2010-08-31 10:13:49.000000000 +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.0/common/inet.c.rfc3442 dhcp-4.2.0/common/inet.c
+--- dhcp-4.2.0/common/inet.c.rfc3442 2009-11-20 02:49:00.000000000 +0100
++++ dhcp-4.2.0/common/inet.c 2010-08-31 10:13:49.000000000 +0200
+@@ -526,6 +526,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 "<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 -up dhcp-4.2.0/common/options.c.rfc3442 dhcp-4.2.0/common/options.c
+--- dhcp-4.2.0/common/options.c.rfc3442 2010-06-01 19:29:59.000000000 +0200
++++ dhcp-4.2.0/common/options.c 2010-08-31 10:13:49.000000000 +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 (op = 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 "<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 -up dhcp-4.2.0/common/parse.c.rfc3442 dhcp-4.2.0/common/parse.c
+--- dhcp-4.2.0/common/parse.c.rfc3442 2010-08-31 10:12:51.000000000 +0200
++++ dhcp-4.2.0/common/parse.c 2010-08-31 10:13:49.000000000 +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
+@@ -707,8 +740,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,
+@@ -1619,6 +1654,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;
+@@ -5232,6 +5270,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;
+@@ -5492,6 +5539,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.0/common/tables.c.rfc3442 dhcp-4.2.0/common/tables.c
+--- dhcp-4.2.0/common/tables.c.rfc3442 2010-08-31 10:12:51.000000000 +0200
++++ dhcp-4.2.0/common/tables.c 2010-08-31 10:13:49.000000000 +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.0/includes/dhcpd.h.rfc3442 dhcp-4.2.0/includes/dhcpd.h
+--- dhcp-4.2.0/includes/dhcpd.h.rfc3442 2010-08-31 10:12:51.000000000 +0200
++++ dhcp-4.2.0/includes/dhcpd.h 2010-08-31 10:13:49.000000000 +0200
+@@ -2638,6 +2638,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 PROTO ((struct iaddr));
++const char *pdestdesc PROTO ((struct iaddr));
+ char *piaddrmask(struct iaddr *, struct iaddr *);
+ char *piaddrcidr(const struct iaddr *, unsigned int);
+ u_int16_t validate_port(char *);
+@@ -2849,6 +2850,7 @@ void parse_client_lease_declaration PROT
+ int parse_option_decl PROTO ((struct option_cache **, struct parse *));
+ void parse_string_list PROTO ((struct parse *, struct string_list **, int));
+ int parse_ip_addr PROTO ((struct parse *, struct iaddr *));
++int parse_destination_descriptor PROTO ((struct parse *, struct iaddr *));
+ int parse_ip_addr_with_subnet(struct parse *, struct iaddrmatch *);
+ void parse_reject_statement PROTO ((struct parse *, struct client_config *));
+
+diff -up dhcp-4.2.0/includes/dhcp.h.rfc3442 dhcp-4.2.0/includes/dhcp.h
+--- dhcp-4.2.0/includes/dhcp.h.rfc3442 2009-11-20 02:49:01.000000000 +0100
++++ dhcp-4.2.0/includes/dhcp.h 2010-08-31 10:13:49.000000000 +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.0/includes/dhctoken.h.rfc3442 dhcp-4.2.0/includes/dhctoken.h
+--- dhcp-4.2.0/includes/dhctoken.h.rfc3442 2010-08-31 10:12:51.000000000 +0200
++++ dhcp-4.2.0/includes/dhctoken.h 2010-08-31 10:15:39.000000000 +0200
+@@ -358,7 +358,8 @@ enum dhcp_token {
+ AUTO_PARTNER_DOWN = 661,
+ GETHOSTNAME = 662,
+ REWIND = 663,
+- BOOTP_BROADCAST_ALWAYS = 664
++ BOOTP_BROADCAST_ALWAYS = 664,
++ DESTINATION_DESCRIPTOR = 666
+ };
+
+ #define is_identifier(x) ((x) >= FIRST_TOKEN && \
diff --git a/dhcp.spec b/dhcp.spec
index ed222ec..44f5331 100644
--- a/dhcp.spec
+++ b/dhcp.spec
@@ -7,7 +7,7 @@
Summary: Dynamic host configuration protocol software
Name: dhcp
Version: 4.2.0
-Release: 3%{?dist}
+Release: 4%{?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.
@@ -26,7 +26,6 @@ Source6: 11-dhclient
Source7: 12-dhcpd
Source8: 56dhclient
-
Patch0: dhcp-4.2.0-errwarn-message.patch
Patch1: dhcp-4.2.0-options.patch
Patch2: dhcp-4.2.0-release-by-ifup.patch
@@ -54,6 +53,7 @@ Patch24: dhcp-4.2.0-retransmission.patch
Patch25: dhcp-4.2.0-release6-elapsed.patch
Patch26: dhcp-4.2.0-initialization-delay.patch
Patch27: dhcp-4.2.0-parse_date.patch
+Patch28: dhcp-4.2.0-rfc3442-classless-static-routes.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: autoconf
@@ -226,6 +226,9 @@ libdhcpctl and libomapi static libraries are also included in this package.
# (Submitted to dhcp-bugs at isc.org - [ISC-Bugs #21501])
%patch27 -p1 -b .parse_date
+# RFC 3442 - Classless Static Route Option for DHCPv4 (#516325)
+%patch28 -p1 -b .rfc3442
+
# Copy in the Fedora/RHEL dhclient script
%{__install} -p -m 0755 %{SOURCE4} client/scripts/linux
%{__install} -p -m 0644 %{SOURCE5} .
@@ -507,6 +510,9 @@ fi
%attr(0644,root,root) %{_mandir}/man3/omapi.3.gz
%changelog
+* Tue Aug 31 2010 Jiri Popelka <jpopelka at redhat.com> - 12:4.2.0-4
+- RFC 3442 - Classless Static Route Option for DHCPv4 (#516325)
+
* Fri Aug 20 2010 Jiri Popelka <jpopelka at redhat.com> - 12:4.2.0-3
- Add DHCRELAYARGS variable to /etc/sysconfig/dhcrelay
diff --git a/sources b/sources
index 90101ef..98008bc 100644
--- a/sources
+++ b/sources
@@ -1,3 +1 @@
-9fa2f64826c969a55fd28263e4b6cad6 ldap-for-dhcp-4.1.1-2.tar.gz
-ee390a35687dd75dbfc32c856c0938d1 dhcp-4.1.1-P1.tar.gz
83abd7c4f9c24d8dd024ca5a71380c0a dhcp-4.2.0.tar.gz
More information about the scm-commits
mailing list