File 0006-dhcp-4.3.2-dhclient-send-hostname-or-fqdn.patch of Package dhcp

From ec55fe43e597e5ea0f8dff5b8edef091c0911801 Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.de>
Date: Thu, 18 Aug 2011 10:49:07 +0200
Subject: [PATCH] dhcp-4.3.2-dhclient-send-hostname-or-fqdn

Signed-off-by: Marius Tomaschewski <mt@suse.de>

diff --git a/client/dhclient.8 b/client/dhclient.8
index 5b05698..d9a26b7 100644
--- a/client/dhclient.8
+++ b/client/dhclient.8
@@ -66,6 +66,10 @@ dhclient - Dynamic Host Configuration Protocol Client
 .I LL|LLT
 ]
 [
+.B -H
+.I hostname
+]
+[
 .B -p
 .I port-number
 ]
@@ -326,6 +330,11 @@ transmits these messages to 255.255.255.255 (the IP limited broadcast
 address).  Overriding this is mostly useful for debugging purposes.  This
 feature is not supported in DHCPv6 (\fB-6\fR) mode.
 .TP
+.BI \-H \ hostname
+This flag may be used to specify a client hostname that should be sent to
+the DHCP server as host-name (ipv4 only) or fqdn to perform dns update.
+Note, that this option is a SUSE/Novell extension.
+.TP
 .BI \-g \ relay
 .\" mockup relay
 Set the giaddr field of all packets to the \fIrelay\fR IP address
diff --git a/client/dhclient.c b/client/dhclient.c
index cf612d1..0e39161 100644
--- a/client/dhclient.c
+++ b/client/dhclient.c
@@ -124,6 +124,7 @@ main(int argc, char **argv) {
 	int no_dhclient_db = 0;
 	int no_dhclient_pid = 0;
 	int no_dhclient_script = 0;
+	char *dhclient_hostname = NULL;
 #ifdef DHCPv6
 	int local_family_set = 0;
 #endif /* DHCPv6 */
@@ -241,6 +242,24 @@ main(int argc, char **argv) {
 			if (++i == argc)
 				usage();
 			mockup_relay = argv[i];
+		} else if (!strcmp (argv[i], "-H")) {
+			size_t len;
+			if (++i == argc || !argv[i] || *(argv[i]) == '\0')
+				usage ();
+			len = strlen (argv[i]);
+			if (len > HOST_NAME_MAX) {
+				log_error("-H option hostname string \"%s\" is too long:"
+					  "maximum length is %d characters",
+					  argv[i], HOST_NAME_MAX);
+				exit(1);
+			} else if(check_domain_name(argv[i], len,
+						local_family == AF_INET6 ? 1 : 0) != 0) {
+				log_error("suspect %s in -H option: \"%s\"",
+					  local_family == AF_INET6 ? "fqdn" : "hostname",
+					  argv[i]);
+				exit(1);
+			}
+			dhclient_hostname = argv [i];
 		} else if (!strcmp(argv[i], "-nw")) {
 			nowait = 1;
 		} else if (!strcmp(argv[i], "-n")) {
@@ -510,6 +529,48 @@ main(int argc, char **argv) {
 	/* Parse the dhclient.conf file. */
 	read_client_conf();
 
+	/* If the user specified a hostname, send it here and now */
+	if ((dhclient_hostname != NULL) && (*dhclient_hostname != '\0') ) {
+		struct parse *cfile = NULL;
+		char buf[1024] = {'\0'};
+		int len;
+
+		if (strchr(dhclient_hostname, '.')) {
+			len = strlen(dhclient_hostname);
+			snprintf (buf, sizeof(buf),
+				"send fqdn.fqdn \"%s%s\";\n"
+				"send fqdn.encoded on;\n"
+				"send fqdn.server-update on;\n"
+				"also request %s;\n",
+				dhclient_hostname,
+				dhclient_hostname[len - 1] == '.' ? "" : ".",
+				local_family == AF_INET6 ? "dhcp6.fqdn" : "fqdn");
+		} else if (local_family == AF_INET) {
+			snprintf (buf, sizeof(buf),
+				"send host-name \"%s\";",
+				dhclient_hostname);
+		}
+		if ((len = strlen(buf))) {
+			status = new_parse (&cfile, -1, buf, len,
+						"hostname update options", 0);
+			if (status != ISC_R_SUCCESS)
+				log_fatal ("Cannot parse send host-name statement!");
+
+			for (;;) {
+				const char *val = NULL;
+				int token;
+
+				token = peek_token (&val, (unsigned *)0, cfile);
+				if (token == END_OF_FILE)
+					break;
+
+				parse_client_statement (cfile, NULL,
+							&top_level_config);
+			}
+			end_parse (&cfile);
+		}
+	}
+
 	/* Parse the lease database. */
 	read_client_leases();
 
@@ -756,6 +817,7 @@ static void usage()
 #else /* DHCPv6 */
 		  "[-I1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n"
 #endif /* DHCPv6 */
+		  "                [-H hostname]\n"
 		  "                [-s server-addr] [-cf config-file]\n"
 		  "                [-df duid-file] [-lf lease-file]\n"
 		  "                [-pf pid-file] [--no-pid] [-e VAR=val]\n"
-- 
2.1.4