Blob Blame History Raw
--- dhcp-3.0.5/client/dhclient.c.enoi	2007-03-30 16:27:32.000000000 -0400
+++ dhcp-3.0.5/client/dhclient.c	2007-03-30 16:27:51.000000000 -0400
@@ -74,6 +74,9 @@
 int onetry=0;
 int quiet=0;
 int nowait=0;
+#ifdef EXTENDED_NEW_OPTION_INFO
+int extended_option_environment = 0;
+#endif
 
 static void usage PROTO ((void));
 
@@ -203,6 +206,11 @@
 		} else if (!strcmp (argv [i], "--version")) {
 			log_info ("isc-dhclient-%s", DHCP_VERSION);
 			exit (0);
+#ifdef EXTENDED_NEW_OPTION_INFO
+		} else if (!strcmp (argv [i], "-x")) {
+			extended_option_environment = 1;
+			new_option_info_tree = GENERATE_NEW_OPTION_INFO;
+#endif
  		} else if (argv [i][0] == '-') {
  		    usage ();
 		} else {
@@ -475,7 +483,11 @@
 	log_info (arr);
 	log_info (url);
 
+#ifdef EXTENDED_NEW_OPTION_INFO
+	log_error ("Usage: dhclient [-1dqr] [-nwx] [-p <port>] %s",
+#else
 	log_error ("Usage: dhclient [-1dqr] [-nw] [-p <port>] %s",
+#endif
 		   "[-s server]");
 	log_error ("                [-cf config-file] [-lf lease-file]%s",
 		   "[-pf pid-file] [-e VAR=val]");
@@ -2426,8 +2438,30 @@
 struct envadd_state {
 	struct client_state *client;
 	const char *prefix;
+#ifdef EXTENDED_NEW_OPTION_INFO
+	struct universe *universe;
+#endif
 };
 
+#ifdef EXTENDED_NEW_OPTION_INFO
+static
+void build_universe_info_envvar
+(	struct option_cache *oc,
+	struct packet *p, struct lease *l,
+	struct client_state *client,
+	struct option_state *in_o,
+	struct option_state *cf_o,
+	struct binding_scope **scope,
+	struct universe *u, void *es
+)
+{
+	char info_name[512], info_data[512];
+	snprintf(info_name, 512, "%s._universe_.", oc->option->universe->name);
+	snprintf(info_data, 512, "%u:%s", oc->option->code,oc->option->format);
+	client_envadd( client, info_name, oc->option->name, info_data );
+}
+#endif
+
 void client_option_envadd (struct option_cache *oc,
 			   struct packet *packet, struct lease *lease,
 			   struct client_state *client_state,
@@ -2444,6 +2478,28 @@
 				   in_options, cfg_options, scope, oc, MDL)) {
 		if (data.len) {
 			char name [256];
+#ifdef EXTENDED_NEW_OPTION_INFO
+			if (extended_option_environment) {
+				if ((oc->option->universe != &dhcp_universe)
+					&& (oc->option->universe->index > fqdn_universe.index)
+					&& (es->universe !=  oc->option->universe)) {
+					es->universe = oc->option->universe;
+					(*(es->universe->foreach)) ((struct packet *)0,
+											    (struct lease *)0, 
+					                            client_state, 
+					                            in_options, cfg_options,
+					                            scope, es->universe, es,  
+					                            build_universe_info_envvar);
+				} else {
+					if (lookup_new_option_info(oc->option) != NULL) {
+						build_universe_info_envvar(oc, packet, lease,
+						                           client_state, in_options,
+						                           cfg_options, scope,
+						                           oc->option->universe, es);
+					}
+				}
+			}
+#endif
 			if (dhcp_option_ev_name (name, sizeof name,
 						 oc -> option)) {
 				client_envadd (es -> client, es -> prefix,
@@ -2470,6 +2526,7 @@
 
 	es.client = client;
 	es.prefix = prefix;
+	es.universe = NULL;
 
 	client_envadd (client,
 		       prefix, "ip_address", "%s", piaddr (lease -> address));
@@ -2679,7 +2736,14 @@
 			s = option -> name;
 			if (j + 1 == buflen)
 				return 0;
+#ifdef EXTENDED_NEW_OPTION_INFO
+			if (!extended_option_environment)
+				buf[j++] = '_';
+			else
+				buf[j++] = '.';
+#else
 			buf [j++] = '_';
+#endif
 		}
 		++i;
 	} while (i != 2);
--- dhcp-3.0.5/client/dhclient.8.enoi	2005-09-14 12:03:33.000000000 -0400
+++ dhcp-3.0.5/client/dhclient.8	2007-03-30 16:27:32.000000000 -0400
@@ -82,6 +82,9 @@
 .B -w
 ]
 [
+.B -x
+]
+[
 .I if0
 [
 .I ...ifN
@@ -265,6 +268,11 @@
 supplying the
 .B -nw
 flag.
+.PP
+The -x argument enables extended option information to be created in the
+-s dhclient-script environment, which would allow applications running
+in that environment to handle options they do not know about in advance -
+this is a Red Hat extension to support dhcdbd and NetworkManager.
 .SH CONFIGURATION
 The syntax of the dhclient.conf(5) file is discussed separately.
 .SH OMAPI
--- dhcp-3.0.5/common/parse.c.enoi	2007-03-30 16:27:32.000000000 -0400
+++ dhcp-3.0.5/common/parse.c	2007-03-30 16:27:32.000000000 -0400
@@ -1266,6 +1266,10 @@
 	option_hash_add (option -> universe -> hash,
 			 (const char *)option -> name,
 			 0, option, MDL);
+#ifdef EXTENDED_NEW_OPTION_INFO
+	if (new_option_info_tree != NULL)
+		add_new_option_info(option);
+#endif
 	return 1;
 }
 
--- dhcp-3.0.5/common/tables.c.enoi	2006-02-22 17:43:27.000000000 -0500
+++ dhcp-3.0.5/common/tables.c	2007-03-30 16:27:32.000000000 -0400
@@ -1250,3 +1250,35 @@
 			   fqdn_universe.name, 0,
 			   &fqdn_universe, MDL);
 }
+
+#ifdef EXTENDED_NEW_OPTION_INFO
+#include <search.h>
+
+void *new_option_info_tree = NULL;
+
+static int new_option_info_comparator(const void * p1, const void * p2) {
+	uint32_t ocode1 = (((const struct option*)p1)->universe->index << 8)
+	                   | (((const struct option*)p1)->code),
+	         ocode2 = (((const struct option*)p2)->universe->index << 8)
+	                   | (((const struct option*)p2)->code);
+
+	return((ocode1 == ocode2) ? 0 : ((ocode1 > ocode2) ? 1 : -1));
+}
+
+void *add_new_option_info(struct option * option) {
+	if (option->universe->index >= fqdn_universe.index)
+		return NULL;
+
+	if (new_option_info_tree == GENERATE_NEW_OPTION_INFO)
+		new_option_info_tree = NULL;
+
+    return tsearch(option, &(new_option_info_tree), new_option_info_comparator);
+}
+
+void *lookup_new_option_info(struct option * option) {
+	if (new_option_info_tree == GENERATE_NEW_OPTION_INFO)
+		return NULL;
+
+	return tfind(option, &(new_option_info_tree), new_option_info_comparator);
+}
+#endif
--- dhcp-3.0.5/includes/dhcpd.h.enoi	2006-05-17 16:16:59.000000000 -0400
+++ dhcp-3.0.5/includes/dhcpd.h	2007-03-30 16:27:32.000000000 -0400
@@ -1811,6 +1811,13 @@
 void initialize_common_option_spaces PROTO ((void));
 struct universe *config_universe;
 
+#ifdef EXTENDED_NEW_OPTION_INFO
+#define GENERATE_NEW_OPTION_INFO ((void*)1)
+extern void *new_option_info_tree;
+extern void *add_new_option_info(struct option *);
+extern void *lookup_new_option_info(struct option *);
+#endif
+
 /* stables.c */
 #if defined (FAILOVER_PROTOCOL)
 extern failover_option_t null_failover_option;