From a21bc05f7d31dc7ddc84e4d1cd810daf6bdf279d Mon Sep 17 00:00:00 2001 From: Jiri Popelka Date: Aug 31 2010 11:10:13 +0000 Subject: RFC 3442 - Classless Static Route Option for DHCPv4 (#516325) --- 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 ""; ++ } ++ 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 ""; ++ } ++ ++ 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@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 - 12:4.2.0-4 +- RFC 3442 - Classless Static Route Option for DHCPv4 (#516325) + * Fri Aug 20 2010 Jiri Popelka - 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