rpms/dhcp/FC-3 dhcp-3.0.1-bz160655_obz15293.patch, NONE, 1.1 dhcp-3.0.1-bz167028-ibm-unicast-bootp.patch, NONE, 1.1 dhcp-3.0.1-bz173324.patch, NONE, 1.1 dhcp-3.0.1-bz176270.patch, NONE, 1.1 dhcp-3.0.1-bz176615.patch, NONE, 1.1 dhcp-3.0.1-bz177845.patch, NONE, 1.1 dhcp-3.0.1-dhclient_routes.patch, NONE, 1.1 dhcp-3.0.1-dhclient-script-fixes.patch, NONE, 1.1

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Tue Feb 14 18:49:18 UTC 2006


Author: jvdias

Update of /cvs/dist/rpms/dhcp/FC-3
In directory cvs.devel.redhat.com:/tmp/cvs-serv25783

Added Files:
	dhcp-3.0.1-bz160655_obz15293.patch 
	dhcp-3.0.1-bz167028-ibm-unicast-bootp.patch 
	dhcp-3.0.1-bz173324.patch dhcp-3.0.1-bz176270.patch 
	dhcp-3.0.1-bz176615.patch dhcp-3.0.1-bz177845.patch 
	dhcp-3.0.1-dhclient_routes.patch 
	dhcp-3.0.1-dhclient-script-fixes.patch 
Log Message:
import fixes from RHEL-4

dhcp-3.0.1-bz160655_obz15293.patch:
 common/options.c |  178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 includes/dhcpd.h |    3 
 server/dhcp.c    |   19 ++---
 3 files changed, 190 insertions(+), 10 deletions(-)

--- NEW FILE dhcp-3.0.1-bz160655_obz15293.patch ---
--- dhcp-3.0.1/server/dhcp.c.bz160655_obz15293	2005-11-18 17:39:56.000000000 -0500
+++ dhcp-3.0.1/server/dhcp.c	2005-11-18 17:39:56.000000000 -0500
@@ -188,17 +188,16 @@
 	}
       nolease:
 
-	/* Classify the client. */
-	if ((oc = lookup_option (&dhcp_universe, packet -> options,
-				 DHO_HOST_NAME))) {
-		if (!oc -> expression)
-			while (oc -> data.len &&
-			       oc -> data.data [oc -> data.len - 1] == 0) {
-				ms_nulltp = 1;
-				oc -> data.len--;
-			}
-	}
+ 	/* If a client null terminates options it sends, it probably
+ 	 * expects the server to reciprocate.
+ 	 */
+  	if ((oc = lookup_option (&dhcp_universe, packet -> options,
+  				 DHO_HOST_NAME))) {
+  		if (!oc -> expression)
+ 			ms_nulltp = oc->flags & OPTION_HAD_NULLS;
+  	}
 
+	/* Classify the client. */	
 	classify_client (packet);
 
 	switch (packet -> packet_type) {
--- dhcp-3.0.1/includes/dhcpd.h.bz160655_obz15293	2005-11-18 17:39:56.000000000 -0500
+++ dhcp-3.0.1/includes/dhcpd.h	2005-11-18 17:41:49.000000000 -0500
@@ -187,6 +187,9 @@
 	struct expression *expression;
 	struct option *option;
 	struct data_string data;
+
+	#define OPTION_HAD_NULLS	0x00000001
+	u_int32_t flags;
 };
 
 struct option_state {
--- dhcp-3.0.1/common/options.c.bz160655_obz15293	2004-06-10 13:59:19.000000000 -0400
+++ dhcp-3.0.1/common/options.c	2005-11-18 17:39:56.000000000 -0500
@@ -958,6 +958,169 @@
 	return bufix;
 }
 
+/* Return true if the format string has a variable length text option
+ * ("t"), return false otherwise.
+ */
+
+int
+format_has_text(format)
+	const char *format;
+{
+	const char *p;
+/*	int retval = 0; */
+
+	p = format;
+	while (*p != '\0') {
+		switch (*p++) {
+		    case 'd':
+		    case 't':
+			return 1;
+
+			/* These symbols are arbitrary, not fixed or
+			 * determinable length...text options with them is
+			 * invalid.
+			 */
+		    case 'A':
+		    case 'a':
+		    case 'X':
+		    case 'x':
+			return 0;
+
+			/* 'E' is variable length, but not arbitrary...you
+			 * can find its length if you can find an END option.
+			 * N is one-byte in length but trails a name of a
+			 * space defining the enumeration values.  So treat
+			 * both the same - valid, fixed-length fields.
+			 */
+		    case 'E':
+		    case 'N':
+			/* Consume the space name. */
+			while ((*p != '\0') && (*p++ != '.'))
+				;
+			break;
+
+		    default:
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/* Determine the minimum length of a DHCP option prior to any variable
+ * or inconsistent length formats, according to its configured format
+ * variable (and possibly from supplied option cache contents for variable
+ * length format symbols).
+ */
+
+int
+format_min_length(format, oc)
+	const char *format;
+	struct option_cache *oc;
+{
+	const char *p;
+	int min_len = 0;
+	int last_size = 0;
+
+	p = format;
+	while (*p != '\0') {
+		switch (*p++) {
+		    case 'I': /* IPv4 Address */
+		    case 'l': /* int32_t */
+		    case 'L': /* uint32_t */
+		    case 'T': /* Lease Time, uint32_t equivalent */
+			min_len += 4;
+			last_size = 4;
+			break;
+
+		    case 's': /* int16_t */
+		    case 'S': /* uint16_t */
+			min_len += 2;
+			last_size = 2;
+			break;
+
+		    case 'N': /* Enumeration in 1-byte values. */
+			/* Consume space name. */
+			while ((*p != '\0') && (*p++ != '.'))
+				;
+
+			/* Fall Through to handle as one-byte field */
+
+		    case 'b': /* int8_t */
+		    case 'B': /* uint8_t */
+		    case 'F': /* Flag that is always true. */
+		    case 'f': /* Flag */
+			min_len++;
+			last_size = 1;
+			break;
+
+		    case 'o': /* Last argument is optional. */
+			min_len -= last_size;
+		    case 'e': /* Encapsulation hint (there is an 'E' later). */
+			last_size = 0;
+			break;
+
+		    case 'E': /* Encapsulated options. */
+			/* Consume space name. */
+			while ((*p != '\0') && (*p++ != '.'))
+				;
+
+			/* Find an end option, or find that the encaps options
+			 * go all the way to the end (or beyond) of the data
+			 * portion of the option.
+			 */
+			last_size = 0;
+			while (min_len < oc->data.len) {
+				if (oc->data.data[min_len] == DHO_END) {
+					min_len++;
+					last_size++;
+					break;
+				} else if (oc->data.data[min_len] == DHO_PAD) {
+					min_len++;
+					last_size++;
+				} else if ((min_len + 1) < oc->data.len) {
+					min_len += oc->data.data[min_len+1]+2;
+					last_size += oc->data.data[min_len+1]+2;
+				} else {
+					/* Suboption length is out of bounds,
+					 * advance beyond the code/length pair
+					 * to trigger below error conditonal.
+					 */
+					min_len += 2;
+					last_size += 2;
+					break;
+				}
+			}
+
+			if (min_len > oc->data.len) {
+				log_error("format_min_length(%s): "
+					  "Encapsulated options exceed "
+					  "supplied buffer.", format);
+				return INT_MAX;
+			}
+
+			break;
+
+		    case 'd': /* "Domain name" */
+		    case 't': /* "ASCII Text" */
+		    case 'X': /* "ASCII or Hex Conditional */
+		    case 'x': /* "Hex" */
+		    case 'A': /* Array of all that precedes. */
+		    case 'a': /* Array of preceding symbol. */
+			return min_len;
+
+		    default:
+			/* No safe value is known. */
+			log_error("format_min_length(%s): No safe value "
+				  "for unknown format symbols.", format);
+			return INT_MAX;
+		}
+	}
+
+	return min_len;
+}
+
+
 /* Format the specified option so that a human can easily read it. */
 
 const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
@@ -1412,6 +1575,21 @@
 	
 	op -> option = option;
 
+	/* If this option is ultimately a text option, null determinate to
+	 * comply with RFC2132 section 2.  Mark a flag so this can be sensed
+	 * later to echo NULLs back to clients that supplied them (they
+	 * probably expect them).
+	 */
+	if (format_has_text(option->format)) {
+		int min_len = format_min_length(option->format, op);
+
+		while ((op->data.len > min_len) &&
+		       (op->data.data[op->data.len-1] == '\0')) {
+			op->data.len--;
+			op->flags |= OPTION_HAD_NULLS;
+		}
+	}
+
 	/* Now store the option. */
 	save_option (universe, options, op);
 

dhcp-3.0.1-bz167028-ibm-unicast-bootp.patch:
 bootp.c |   13 ++++++++++++-
 dhcp.c  |   38 ++++++++++++++++++++++++++++++--------
 2 files changed, 42 insertions(+), 9 deletions(-)

--- NEW FILE dhcp-3.0.1-bz167028-ibm-unicast-bootp.patch ---
--- dhcp-3.0.3/server/bootp.c.bz167028	2005-05-18 15:54:17.000000000 -0400
+++ dhcp-3.0.3/server/bootp.c	2005-11-15 12:04:29.000000000 -0500
@@ -62,6 +62,7 @@
 	char msgbuf [1024];
 	int ignorep;
 	int peer_has_leases = 0;
+	int norelay = 0;
 
 	if (packet -> raw -> op != BOOTREQUEST)
 		return;
@@ -77,7 +78,7 @@
 		 ? inet_ntoa (packet -> raw -> giaddr)
 		 : packet -> interface -> name);
 
-	if (!locate_network (packet)) {
+	if ((norelay = locate_network (packet)) == 0) {
 		log_info ("%s: network unknown", msgbuf);
 		return;
 	}
@@ -357,6 +358,16 @@
 					      from, &to, &hto);
 			goto out;
 		}
+	} else if (norelay == 2) {
+		to.sin_addr = raw.ciaddr;
+		to.sin_port = remote_port;
+		if (fallback_interface) {
+			result = send_packet (fallback_interface,
+					      (struct packet *)0,
+					      &raw, outgoing.packet_length,
+					      from, &to, &hto);
+			goto out;                
+		}
 
 	/* If it comes from a client that already knows its address
 	   and is not requesting a broadcast response, and we can
--- dhcp-3.0.3/server/dhcp.c.bz167028	2005-11-15 12:00:35.000000000 -0500
+++ dhcp-3.0.3/server/dhcp.c	2005-11-15 12:04:29.000000000 -0500
@@ -3787,6 +3787,7 @@
 	struct data_string data;
 	struct subnet *subnet = (struct subnet *)0;
 	struct option_cache *oc;
+	int norelay = 0;
 
 	/* See if there's a subnet selection option. */
 	oc = lookup_option (&dhcp_universe, packet -> options,
@@ -3796,12 +3797,27 @@
 	   from the interface, if there is one.   If not, fail. */
 	if (!oc && !packet -> raw -> giaddr.s_addr) {
 		if (packet -> interface -> shared_network) {
-			shared_network_reference
-				(&packet -> shared_network,
-				 packet -> interface -> shared_network, MDL);
-			return 1;
-		}
-		return 0;
+			struct in_addr any_addr;
+			any_addr.s_addr = INADDR_ANY;
+			if (!packet -> packet_type &&
+			    memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) {
+				struct iaddr cip;
+				memcpy(cip.iabuf, &packet -> raw -> ciaddr, 4);
+				cip.len = 4;
+				if (!find_grouped_subnet(&subnet,
+				    packet -> interface -> shared_network, 
+				    cip, MDL)) 
+					norelay = 2;
+			}
+			if (!norelay) {
+				shared_network_reference
+					(&packet -> shared_network,
+					 packet -> interface -> shared_network,
+					 MDL);
+				return 1;
+			}
+		} else
+			return 0;
 	}
 
 	/* If there's an SSO, and it's valid, use it to figure out the
@@ -3823,7 +3839,10 @@
 		data_string_forget (&data, MDL);
 	} else {
 		ia.len = 4;
-		memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
+		if (norelay)
+			memcpy (ia.iabuf, &packet -> raw -> ciaddr, 4);
+		else
+			memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
 	}
 
 	/* If we know the subnet on which the IP address lives, use it. */
@@ -3831,7 +3850,10 @@
 		shared_network_reference (&packet -> shared_network,
 					  subnet -> shared_network, MDL);
 		subnet_dereference (&subnet, MDL);
-		return 1;
+		if (norelay)
+			return norelay;
+		else
+			return 1;
 	}
 
 	/* Otherwise, fail. */

dhcp-3.0.1-bz173324.patch:
 dispatch.c |   37 +++++++++++++++++++++++++++----------
 1 files changed, 27 insertions(+), 10 deletions(-)

--- NEW FILE dhcp-3.0.1-bz173324.patch ---
--- dhcp-3.0.1/omapip/dispatch.c.bz173324	2004-07-09 20:11:17.000000000 -0400
+++ dhcp-3.0.1/omapip/dispatch.c	2005-11-18 17:17:25.000000000 -0500
@@ -494,27 +494,44 @@
 	return ISC_R_NOTFOUND;
 }
 
+/* omapi_io_destroy (object, MDL);
+ *
+ *	Find the requsted IO [object] and remove it from the list of io
+ * states, causing the cleanup functions to destroy it.  Note that we must
+ * hold a reference on the object while moving its ->next reference and
+ * removing the reference in the chain to the target object...otherwise it
+ * may be cleaned up from under us.
+ */
 isc_result_t omapi_io_destroy (omapi_object_t *h, const char *file, int line)
 {
-	omapi_io_object_t *obj, *p, *last;
+	omapi_io_object_t *obj = NULL, *p, *last = NULL, **holder;
 
 	if (h -> type != omapi_type_io_object)
 		return ISC_R_INVALIDARG;
 	
-	obj = (omapi_io_object_t *)h;
-
 	/* remove from the list of I/O states */
 	for (p = omapi_io_states.next; p; p = p -> next) {
-		if (p == obj) {
-			omapi_io_dereference (&last -> next, MDL);
-			omapi_io_reference (&last -> next, p -> next, MDL);
-			omapi_io_dereference (&p, MDL);
-			break;
+		if (p == (omapi_io_object_t *)h) {
+			omapi_io_reference (&obj, p, MDL);
+
+			if (last)
+				holder = &last -> next;
+			else
+				holder = &omapi_io_states.next;
+
+			omapi_io_dereference (holder, MDL);
+
+			if (obj -> next) {
+				omapi_io_reference (holder, obj -> next, MDL);
+				omapi_io_dereference (&obj -> next, MDL);
+			}
+
+			return omapi_io_dereference (&obj, MDL);
 		}
 		last = p;
 	}
-		
-	return ISC_R_SUCCESS;
+
+	return ISC_R_NOTFOUND;
 }
 
 isc_result_t omapi_io_signal_handler (omapi_object_t *h,

dhcp-3.0.1-bz176270.patch:
 linux |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

--- NEW FILE dhcp-3.0.1-bz176270.patch ---
--- dhcp-3.0.1/client/scripts/linux.bz176270	2005-12-20 14:51:40.000000000 -0500
+++ dhcp-3.0.1/client/scripts/linux	2005-12-20 15:04:57.000000000 -0500
@@ -261,9 +261,13 @@
 	let i=0;
 	default_routers=()
 	for router in $new_routers; do
-	    if [ -z "$router" ] || [ `IFS=. ip2num $router` -le 0 ] || \
-	       [[ $router = *255* ]] || [[ "${default_routers[@]}" == *"$router"* ]]; 
-	    then
+	    added_router=0
+	    for r in ${default_routers[@]}; do
+		if [ "$r" == "$router" ]; then
+		    added_router=1;
+		fi;
+	    done
+	    if [ -z "$router" ] || [ "$added_router" -eq 1 ] || [ `IFS=. ip2num $router` -le 0 ] || [[ "$router" = "$new_broadcast_address" ]]; then
 		continue;
 	    fi;
 	    default_routers=(${default_routers[@]} $router)

dhcp-3.0.1-bz176615.patch:
 dhcp.c |   11 +++++++++++
 1 files changed, 11 insertions(+)

--- NEW FILE dhcp-3.0.1-bz176615.patch ---
--- dhcp-3.0.1/server/dhcp.c.bz176615	2006-01-16 15:24:06.000000000 -0500
+++ dhcp-3.0.1/server/dhcp.c	2006-01-16 15:25:52.000000000 -0500
@@ -194,7 +194,18 @@
   	if ((oc = lookup_option (&dhcp_universe, packet -> options,
   				 DHO_HOST_NAME))) {
   		if (!oc -> expression)
+		{
  			ms_nulltp = oc->flags & OPTION_HAD_NULLS;
+			if( (!ms_nulltp) && (oc->data.data[oc->data.len-1] == '\0') )
+			{
+				while (oc -> data.len &&
+				       oc -> data.data [oc -> data.len - 1] == 0) {
+					ms_nulltp = 1;
+					oc -> data.len--;
+					oc->flags |= OPTION_HAD_NULLS;
+				}
+			}
+		}
   	}
 
 	/* Classify the client. */	

dhcp-3.0.1-bz177845.patch:
 linux |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

--- NEW FILE dhcp-3.0.1-bz177845.patch ---
--- dhcp-3.0.1/client/scripts/linux.bz177845	2006-01-16 15:24:06.000000000 -0500
+++ dhcp-3.0.1/client/scripts/linux	2006-01-16 15:32:58.000000000 -0500
@@ -267,7 +267,7 @@
 		    added_router=1;
 		fi;
 	    done
-	    if [ -z "$router" ] || [ "$added_router" -eq 1 ] || [ `IFS=. ip2num $router` -le 0 ] || [[ "$router" = "$new_broadcast_address" ]]; then
+	    if [ -z "$router" ] || [ "$added_router" -eq 1 ] || [ `IFS=. ip2num $router` -le 0 ] || [[ ( "$router" = "$new_broadcast_address" ) && ("$new_subnet_mask" != "255.255.255.255") ]]; then
 		continue;
 	    fi;
 	    default_routers=(${default_routers[@]} $router)
@@ -421,7 +421,7 @@
   fi
 }
 
-if [ x$new_broadcast_address != x ]; then
+if [ x$new_broadcast_address != x ] && [ x$new_subnet_mask != x ] && [ "$new_subnet_mask" != '255.255.255.255' ] ; then
   new_broadcast_arg="broadcast $new_broadcast_address"
 fi
 if [ x$old_broadcast_address != x ]; then

dhcp-3.0.1-dhclient_routes.patch:
 linux |   94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 86 insertions(+), 8 deletions(-)

--- NEW FILE dhcp-3.0.1-dhclient_routes.patch ---
--- dhcp-3.0.2rc3/client/scripts/linux.dhclient_routes	2005-02-10 14:20:33.000000000 -0500
+++ dhcp-3.0.2rc3/client/scripts/linux	2005-02-10 18:45:41.000000000 -0500
@@ -99,6 +99,68 @@
 relmajor=`echo $release |/bin/cut -f1 -d'.'`
 relminor=`echo $release |/bin/cut -f2 -d'.'`
 
+# simple IP arithmetic functions:
+
+function quad2num()
+{
+    if [ $# -eq 4 ]; then
+       let n="$1<<24|$2<<16|$3<<8|$4"
+       echo $n;
+       return 0;
+    fi
+    echo '0';
+    return 1;
+}
+
+function ip2num()
+{
+    IFS='.' quad2num $1;
+}
+
+function num2ip()
+{
+    let n="$1";
+    let o1='(n>>24)&0xff';
+    let o2='(n>>16)&0xff';
+    let o3='(n>>8)&0xff';
+    let o4='n & 0xff';
+    echo $o1.$o2.$o3.$o4;
+}
+
+function mask()
+{   
+    ip=$1
+    m=$2
+    let ip=`IFS='.' ip2num $ip`;
+    let m=`IFS='.' ip2num $m`;
+    let n='ip&m';
+    num2ip $n;
+}
+
+function add_default_gateway()
+{
+        router=$1
+	# Handle silly DHCP servers that give us a router not on our subnet:
+	routerSubnet=`mask $router $new_subnet_mask`
+	mySubnet=`mask $new_ip_address $new_subnet_mask`
+	routerUnreachable=0
+	if [ "$routerSubnet" != "$mySubnet" ]; then
+           if /sbin/arping -q -I $interface -w2 $router; then
+	       route add -host $router dev $interface;
+           else
+	       routerUnreachable=1;
+	       echo "dhclient: DHCP router $router is unreachable on DHCP subnet $mySubnet"
+	       if [ -x /usr/bin/logger ]; then
+		   /usr/bin/logger -p local7.notice -t "NET"  "dhclient: DHCP router $router is unreachable on DHCP subnet $mySubnet";
+	       fi;
+	   fi;
+        fi;
+	if [ "$routerUnreachable" -eq 0 ]; then
+	    /sbin/ip route replace default via $router dev $interface && return 0;
+	fi;
+	return 1;
+}
+
 if [ x$new_broadcast_address != x ]; then
   new_broadcast_arg="broadcast $new_broadcast_address"
 fi
@@ -174,10 +236,18 @@
       if [ $added_old_broadcast_route -eq 1 ]; then
 	  route del default;
       fi;
-    fi
-    for router in $new_routers; do
-      route add default gw $router && break; # there can be only one !
-    done
+    fi;
+    if [[ ( -z "$GATEWAYDEV" && -z "$GATEWAY" ) || ( -z "$GATEWAY" && ( "$GATEWAYDEV" = "$interface") )  ]]; then
+	for router in $new_routers; do
+	    add_default_gateway $router && break;
+	done
+    elif [[ ( -z "$GATEWAYDEV" || ( "$GATEWAYDEV" = "$interface" ) ) && ( -n "$GATEWAY" ) ]]; then
+	routerSubnet=`mask $GATEWAY $new_subnet_mask`
+	mySubnet=`mask $new_ip_address $new_subnet_mask`
+	if [ "$routerSubnet" = "$mySubnet" ]; then
+	   ip route replace default via $GATEWAY dev $interface 
+	fi;
+    fi;
     # static routes
     if [ "x$new_static_routes" != x ]; then
       len=`echo $new_static_routes | awk '{print NF}'`
@@ -309,7 +379,7 @@
   ifconfig $interface inet $new_ip_address $new_subnet_arg \
 					$new_broadcast_arg
   set $new_routers
-  if ping -q -c 1 -w 10 $1; then
+  if ping -q -c 1 -w 10 -I $interface $1; then
     if [ x$new_ip_address != x$alias_ip_address ] && \
 			[ x$alias_ip_address != x ]; then
       ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg
@@ -319,9 +389,17 @@
 		( [ $relmajor -eq 2 ] && [ $relminor -eq 0 ] ); then
       route add -net $new_network_number
     fi
-    for router in $new_routers; do
-      route add default gw $router
-    done
+    if [[ ( -z "$GATEWAYDEV" && -z "$GATEWAY" ) || ( -z "$GATEWAY" && ( "$GATEWAYDEV" = "$interface") )  ]]; then
+	for router in $new_routers; do
+	    add_default_gateway $router && break;
+	done
+    elif [[ ( -z "$GATEWAYDEV" || ( "$GATEWAYDEV" = "$interface" ) ) && ( -n "$GATEWAY" ) ]]; then
+	routerSubnet=`mask $GATEWAY $new_subnet_mask`
+	mySubnet=`mask $new_ip_address $new_subnet_mask`
+	if [ "$routerSubnet" = "$mySubnet" ]; then
+	   ip route replace default via $GATEWAY dev $interface 
+	fi;
+    fi;
     if [ "${PEERDNS}" != "no" ]; then 
       make_resolv_conf
     fi

dhcp-3.0.1-dhclient-script-fixes.patch:
 linux |  218 +++++++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 165 insertions(+), 53 deletions(-)

--- NEW FILE dhcp-3.0.1-dhclient-script-fixes.patch ---
--- dhcp-3.0.1/client/scripts/linux.dhclient-script-fixes	2005-11-18 18:53:53.000000000 -0500
+++ dhcp-3.0.1/client/scripts/linux	2005-11-21 12:53:33.000000000 -0500
@@ -155,38 +155,62 @@
 
 function class_bits()
 {
-    let bits=0
-    IFS='.' os="$1"
-    for b in $os; do
-       if [ $b -ne 0 ]; then
-	   let bits=bits+8;
-       fi;
-    done
-    echo $bits
+    let ip=`IFS='.' ip2num $1`;
+    let bits=32
+    let mask='255';
+    for ((i=0; i <= 3; i++, 'mask<<=8')); do
+	let v='ip&mask';
+	if [ "$v" -eq 0 ] ; then
+	    let bits-=8;
+        else
+            break;
+	fi;
+    done;
+    echo $bits;
+}
+
+function routerReachable()
+{ # Handle silly 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`
+    unreachable=0
+    if [ "$routerSubnet" != "$mySubnet" ]; then
+	unreachable=1
+	if /sbin/arping -f -q -I $interface -w2 $router; then
+	    /sbin/ip route add ${router}/32 dev $interface
+	    if [ $? -eq 0 ]; then
+		unreachable=0
+	    else
+		/usr/bin/logger -p local7.notice -t "NET"  "dhclient: failed to create host route for unreachable router $router not on subnet $mySubnet";
+	    fi
+	else
+	    unreachable=1
+	    if [ -x /usr/bin/logger ]; then
+		/usr/bin/logger -p local7.notice -t "NET"  "dhclient: DHCP router $router is unreachable on DHCP subnet $mySubnet router subnet $routerSubnet";
+	    fi;
+	fi;
+    fi;
+    return $unreachable;
 }
 
 function add_default_gateway()
 {
-        router=$1
-	# Handle silly DHCP servers that give us a router not on our subnet:
-	routerSubnet=`mask $router $new_subnet_mask`
-	mySubnet=`mask $new_ip_address $new_subnet_mask`
-	routerUnreachable=0
-	if [ "$routerSubnet" != "$mySubnet" ]; then
-           if /sbin/arping -q -I $interface -w2 $router; then
-	       /sbin/ip route replace ${router}/32 dev $interface;
-           else
-	       routerUnreachable=1;
-	       echo "dhclient: DHCP router $router is unreachable on DHCP subnet $mySubnet"
-	       if [ -x /usr/bin/logger ]; then
-		   /usr/bin/logger -p local7.notice -t "NET"  "dhclient: DHCP router $router is unreachable on DHCP subnet $mySubnet";
-	       fi;
-	   fi;
-        fi;
-	if [ "$routerUnreachable" -eq 0 ]; then
-	    /sbin/ip route replace default via $router dev $interface && return 0;
+    router=$1
+    metric=''
+    if [ $# -gt 1 ] && [ "$2" -gt 0 ]; then 
+	metric="metric $2";
+    fi;    
+    if routerReachable $router ; then
+	/sbin/ip route replace default via $router dev $interface $metric;
+	if [ $? -ne 0 ]; then 
+	    /usr/bin/logger -p local7.notice -t "NET"  'dhclient: failed to create default route: '$router dev $interface $metric;
+	    return 1;
+	else
+	    return 0;
 	fi;
-	return 1;
+    fi;
+    return 1;
 }
 
 function dhconfig()
@@ -203,11 +227,24 @@
     ifconfig $interface inet 0 down
   fi
 
-  if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \
-     [ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
+  if [ x$reason = xBOUND ] || [ x$reason = xREBOOT ] ||
+     [ x$old_ip_address  != x$new_ip_address ] ||
+     [ x$old_subnet_mask != x$new_subnet_mask ] ||
+     [ x$new_network_number != x$new_network_number ] ||
+     [ x$old_broadcast_address != x$new_broadcast_address ] ||
+     [ "x$old_routers" != "x$new_routers" ] ||
+     [ x$old_interface_mtu != x$new_interface_mtu ] ; then
 
     ifconfig $interface inet $new_ip_address $new_subnet_arg \
-							$new_broadcast_arg
+	$new_broadcast_arg
+    if [ -n "$new_interface_mtu" ]; then
+	/sbin/ip link set $interface mtu $new_interface_mtu;
+    fi;
+    if [ -x /etc/dhclient-${interface}-up-hooks ]; then
+	. /etc/dhclient-${interface}-up-hooks;
+    elif [ -x /etc/dhclient-up-hooks ]; then
+	. /etc/dhclient-up-hooks;
+    fi;
     # Add a network route to the computed network address.
     if [ $relmajor -lt 2 ] || \
 		( [ $relmajor -eq 2 ] && [ $relminor -eq 0 ] ); then
@@ -217,11 +254,26 @@
 	    /sbin/ip route del default;
 	fi;
     fi;
-    if [[ ( -z "$GATEWAYDEV" &&  (-z "$GATEWAY" || -z "$DHCLIENT_USE_GATEWAY") ) || ( (-z "$GATEWAY" || -z "$DHCLIENT_USE_GATEWAY") &&  ( "$GATEWAYDEV" = "$interface") )  ]]; then
+    if [[ ( -z "$GATEWAYDEV" &&  (-z "$GATEWAY" || -z "$DHCLIENT_USE_GATEWAY") ) || \
+	( ( -z "$GATEWAY" || -z "$DHCLIENT_USE_GATEWAY") &&  ( "$GATEWAYDEV" = "$interface") )  ]]; 
+    then
+	metric='';
+	let i=0;
+	default_routers=()
 	for router in $new_routers; do
-	    add_default_gateway $router && break;
+	    if [ -z "$router" ] || [ `IFS=. ip2num $router` -le 0 ] || \
+	       [[ $router = *255* ]] || [[ "${default_routers[@]}" == *"$router"* ]]; 
+	    then
+		continue;
+	    fi;
+	    default_routers=(${default_routers[@]} $router)
+	    add_default_gateway $router $metric;		    
+	    let i=i+1;
+	    metric=$i; 
 	done
-    elif [[ ( -z "$GATEWAYDEV" || ( "$GATEWAYDEV" = "$interface" ) ) && ( -n "$GATEWAY" && -n "$DHCLIENT_USE_GATEWAY" ) ]]; then
+    elif [[ ( -z "$GATEWAYDEV" || ( "$GATEWAYDEV" = "$interface" ) ) && \
+	    ( -n "$GATEWAY" && -n "$DHCLIENT_USE_GATEWAY" ) ]]; 
+    then
 	routerSubnet=`mask $GATEWAY $new_subnet_mask`
 	mySubnet=`mask $new_ip_address $new_subnet_mask`
 	if [ "$routerSubnet" = "$mySubnet" ]; then
@@ -231,15 +283,34 @@
     # static routes
     if [ "x$new_static_routes" != x ]; then
 	IFS=', 	' static_routes=($new_static_routes)
-	let i=0
-	while [ $i -lt ${#static_routes[@]} ]; do
+	route_targets=()
+	for((i=0; i<${#static_routes[@]}; i+=2)); do
 	    target=${static_routes[$i]}
 	    gateway=${static_routes[$i+1]}
-	    let i=i+2
-	    /sbin/ip route replace ${target}/`class_bits $target` via ${gateway} dev $interface
-	done
-    fi
-  fi
+	    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 routerReachable $gateway; then
+		/sbin/ip route replace ${target}/`class_bits $target` via ${gateway} dev $interface ${metric}
+		if [ $? -ne 0 ]; then
+		    /usr/bin/logger -p local7.notice -t 'NET' 'dhclient: 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 [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
    then
@@ -249,6 +320,9 @@
   fi
 
   make_resolv_conf
+  if [ -n "$new_host_name" ] && need_hostname; then
+      hostname $new_host_name
+  fi
 
   if [ "${PEERNIS}" = no ]; then
     :
@@ -272,8 +346,8 @@
 	if [ "$level" = "unknown" ]; then
 	    level=1;
 	fi
-	if ! pkill -HUP ypbind && [ $contents -gt 0 ] && chkconfig --level=$level ypbind; then
-	   service ypbind start >/dev/null 2>&1;
+	if [ $contents -gt 0 ] && [[ "$level" = [0-6] ]] && /sbin/chkconfig --level=$level ypbind >/dev/null 2>&1 && [ -r /var/run/ypbind.pid ] && yppid=`cat /var/run/ypbind.pid` && [ -d /proc/${yppid} ] && [ "`if [ -x /sbin/busybox ]; then /sbin/busybox readlink /proc/${yppid}/exe; else echo /sbin/ypbind; fi`" = "/sbin/ypbind" ]; then
+	    kill -HUP $yppid;	    
         fi
   elif [ -n "$new_nis_servers" ]; then
         save_previous /etc/yp.conf
@@ -289,14 +363,35 @@
 	if [ "$level" = "unknown" ]; then
 	    level=1;
 	fi
-        if ! pkill -HUP ypbind && [ $contents -gt 0 ] && chkconfig --level=$level ypbind; then
-	    service ypbind start >/dev/null 2>&1;
+	if [ $contents -gt 0 ] && [[ "$level" = [0-6] ]] && /sbin/chkconfig --level=$level ypbind >/dev/null 2>&1 && [ -r /var/run/ypbind.pid ] && yppid=`cat /var/run/ypbind.pid` && [ -d /proc/${yppid} ] && [ "`if [ -x /sbin/busybox ]; then /sbin/busybox readlink /proc/${yppid}/exe; else echo /sbin/ypbind; fi`" = "/sbin/ypbind" ]; then
+	    kill -HUP $yppid;
         fi
   fi
 
   if [ "${PEERNTP}" = no ]; then
     :
   elif [ -n "$new_ntp_servers" ] && [ -e /etc/ntp.conf ]; then
+      if [ -n "$DHCP_TIME_OFFSET_SETS_TIMEZONE" ] && [[ "$DHCP_TIME_OFFSET_SETS_TIMEZONE" = [yY1]* ]]; then
+	  if [ -n "$new_time_offset" ]; then
+	  #  DHCP option "time-offset" is requested by default and should be handled
+          #  (otherwise it is very difficult to sync a network of machines to the same wallclock time with NTP).
+	  #  The geographical zone abbreviation cannot be determined from the GMT offset,
+	  #  but the $ZONEINFO/Etc/GMT$offset file can be used - note: server must take account of DST.
+	      ((z=new_time_offset/3600));
+	      ((hoursWest=`printf '%+d' $z`))
+	      if (( $hoursWest < 0 )); then
+		   # tzdata treats negative 'hours west' as positive 'gmtoff' !
+		  ((hoursWest*=-1));
+	      fi
+	      tzfile=/usr/share/zoneinfo/Etc/GMT`printf '%+d' $hoursWest`;
+	      if [ -e $tzfile ]; then
+		  /bin/mv -f /etc/localtime /etc/localtime.predhclient;
+		  /bin/cp -fp $tzfile /etc/localtime;
+		  /bin/touch /etc/localtime;
+	      fi;
+	  fi;
+      fi;
+
       save_previous /etc/ntp.conf
       /bin/egrep -v '(^[\ \	]*server)|(generated by /sbin/dhclient-script)'< /etc/ntp.conf.predhclient > /etc/ntp.conf
       echo '# servers generated by /sbin/dhclient-script' >> /etc/ntp.conf
@@ -320,10 +415,6 @@
 	 /sbin/service ntpd condrestart >/dev/null 2>&1
       fi;
   fi
-
-  if [ -n "$new_host_name" ] && need_hostname; then
-      hostname $new_host_name
-  fi
 }
 
 if [ x$new_broadcast_address != x ]; then
@@ -367,12 +458,15 @@
   # We need to give the kernel some time to get the interface up.
   # sleep 1
   # I don't think we need to do this with modern kernels - JVD .
-
+  # but just in case:
+  if [ -n "$DHCLIENT_DELAY" ] && [ "$DHCLIENT_DELAY" -gt 0 ] ; then
+      sleep $DHCLIENT_DELAY;
+  fi;
   exit_with_hooks 0
 fi
 
 if [ x$reason = xARPCHECK ] || [ x$reason = xARPSEND ]; then
-    if [ -z "$new_ip_address" ] || [ -z "$interface" ] ||  /sbin/arping -q -c 2 -w 3 -D -I ${interface} ${new_ip_address}; then
+    if [ -z "$new_ip_address" ] || [ -z "$interface" ] ||  /sbin/arping -q -f -c 2 -w 3 -D -I ${interface} ${new_ip_address}; then
 	exit_with_hooks 0
     else
 	exit_with_hooks 1
@@ -392,6 +486,13 @@
      rm -f /etc/resolv.conf.predhclient
      [ -x /sbin/restorecon ] && /sbin/restorecon /etc/resolv.conf >/dev/null 2>&1
   fi
+  if [ -n "$DHCP_TIME_OFFSET_SETS_TIMEZONE" ] && [[ "$DHCP_TIME_OFFSET_SETS_TIMEZONE" = [yY1]* ]]; then
+      if [ -e /etc/localtime.predhclient ]; then
+	  /bin/rm -f /etc/localtime
+	  /bin/mv -f /etc/localtime.predhclient /etc/localtime;
+	  /bin/touch /etc/localtime;
+      fi;
+  fi;
   if [ -f /etc/ntp.conf.predhclient ]; then
      /bin/mv -f /etc/ntp.conf.predhclient /etc/ntp.conf
      if [ -f /etc/ntp/step-tickers.predhclient ]; then
@@ -401,10 +502,22 @@
      service ntpd condrestart >/dev/null 2>&1 
   fi
   if [ -f /etc/yp.conf.predhclient ]; then
+     /bin/rm -f /etc/yp.conf
      /bin/mv -f /etc/yp.conf.predhclient /etc/yp.conf
-     [ -x /sbin/restorecon ] && /sbin/restorecon /etc/yp.conf >/dev/null 2>&1
-     pkill -HUP ypbind
+     level=`/sbin/runlevel`
+     level=${level##*\ }
+     if [ "$level" = "unknown" ]; then
+	 level=1;
+     fi
+     if [[ "$level" = [0-6] ]] && /sbin/chkconfig --level=$level ypbind >/dev/null 2>&1 && [ -r /var/run/ypbind.pid ] && yppid=`cat /var/run/ypbind.pid` && [ -d /proc/${yppid} ] && [ "`if [ -x /sbin/busybox ]; then /sbin/busybox readlink /proc/${yppid}/exe; else echo /sbin/ypbind; fi`" = "/sbin/ypbind" ] ; then
+	 kill -HUP $yppid;
+     fi
   fi 
+  if [ -x /etc/dhclient-${interface}-down-hooks ]; then
+      . /etc/dhclient-${interface}-down-hooks;
+  elif [ -x /etc/dhclient-down-hooks ]; then
+      . /etc/dhclient-down-hooks;
+  fi;
   if [ x$alias_ip_address != x ]; then
     # Turn off alias interface.
     ifconfig $interface:0- inet 0
@@ -436,5 +549,4 @@
 elif [ x$reason = xTIMEOUT ]; then
   exit_with_hooks 1
 fi
-
 exit_with_hooks 0




More information about the fedora-cvs-commits mailing list