[PATCH] ipconfig.c : implement DHCP Class-identifier

Previous thread: [PATCH] spi: Fix error paths on txx9spi_probe by Atsushi Nemoto on Thursday, November 8, 2007 - 7:35 am. (2 messages)

Next thread: Re: 2.6.24-rc1-gb4f5550 oops by Rafael J. Wysocki on Thursday, November 8, 2007 - 8:53 am. (7 messages)
From: Rainer Jochem
Date: Thursday, November 8, 2007 - 7:32 am

This patch implements the DHCP Class identifier (see rfc1533) which is
used by DHCP clients to optionally identify the type and configuration of 
a DHCP client which is send as a string to the server. For example, the
identifier may encode the client's hardware configuration. If the newly 
introduced kernel-parameter 'dhcpclass' is set, then the kernel sends 
the given string in its DHCP-request to the server.
If the option is omitted, the behaviour is as before without this patch.


Patch applies to:
Version:	2.6.23.1
File:		net/ipv4/ipconfig.c


Signed-off-by: Rainer Jochem <rainer.jochem@mpi-sb.mpg.de>

---

--- net/ipv4/ipconfig.c.orig	2007-11-08 14:54:11.001662860 +0100
+++ net/ipv4/ipconfig.c	2007-11-08 14:54:15.961480524 +0100
@@ -139,6 +139,8 @@ __be32 ic_servaddr = NONE;	/* Boot serve
 __be32 root_server_addr = NONE;	/* Address of NFS server */
 u8 root_server_path[256] = { 0, };	/* Path to mount as root */
 
+char vendor_class_identifier[256] = { 0, }; /* vendor class identifier */
+
 /* Persistent data: */
 
 static int ic_proto_used;			/* Protocol used, if any */
@@ -620,6 +622,17 @@ ic_dhcp_init_options(u8 *options)
 		*e++ = sizeof(ic_req_params);
 		memcpy(e, ic_req_params, sizeof(ic_req_params));
 		e += sizeof(ic_req_params);
+
+		// Send it only if the according kernel parameter was set
+		if (*vendor_class_identifier) {
+			printk(KERN_INFO "Sending class identifier \"%s\"\n",
+			       vendor_class_identifier);
+			*e++ = 60;	/* Class-identifier */
+			*e++ = strlen(vendor_class_identifier);
+			memcpy(e, vendor_class_identifier,
+			       strlen(vendor_class_identifier));
+			e += strlen(vendor_class_identifier);
+		}
 	}
 
 	*e++ = 255;	/* End of the list */
@@ -1507,5 +1520,14 @@ static int __init nfsaddrs_config_setup(
 	return ip_auto_config_setup(addrs);
 }
 
+static int __init vendor_class_identifier_setup(char *addrs)
+{
+	if (strlcpy(vendor_class_identifier, addrs, 250) > 250)
+		printk(KERN_WARNING "vendorclass too long, ...
From: Patrick McHardy
Date: Thursday, November 8, 2007 - 8:45 am

You could avoid these three strlen calls by using a temporary

sizeof(vendor_class_identifier). Why are you using 250 but the


-

From: Rainer Jochem
Date: Wednesday, November 14, 2007 - 1:44 am

This information is only sent in the case that the option is actually used.
And in this case it might be useful for the user to see to which string the 
option was set.


--- net/ipv4/ipconfig.c.orig	2007-11-14 09:16:15.800566536 +0100
+++ net/ipv4/ipconfig.c	2007-11-14 09:16:20.200403710 +0100
@@ -139,6 +139,8 @@ __be32 ic_servaddr = NONE;	/* Boot serve
 __be32 root_server_addr = NONE;	/* Address of NFS server */
 u8 root_server_path[256] = { 0, };	/* Path to mount as root */
 
+static char vendor_class_identifier[253]; /* vendor class identifier */
+
 /* Persistent data: */
 
 static int ic_proto_used;			/* Protocol used, if any */
@@ -580,6 +582,7 @@ ic_dhcp_init_options(u8 *options)
 	u8 mt = ((ic_servaddr == NONE)
 		 ? DHCPDISCOVER : DHCPREQUEST);
 	u8 *e = options;
+	int len = 0;
 
 #ifdef IPCONFIG_DEBUG
 	printk("DHCP: Sending message type %d\n", mt);
@@ -620,6 +623,16 @@ ic_dhcp_init_options(u8 *options)
 		*e++ = sizeof(ic_req_params);
 		memcpy(e, ic_req_params, sizeof(ic_req_params));
 		e += sizeof(ic_req_params);
+
+		if (*vendor_class_identifier) {
+			printk(KERN_INFO "Sending class identifier \"%s\"\n",
+			       vendor_class_identifier);
+			*e++ = 60;	/* Class-identifier */
+			len = strlen(vendor_class_identifier);
+			*e++ = len;
+			memcpy(e, vendor_class_identifier, len);
+			e += len;
+		}
 	}
 
 	*e++ = 255;	/* End of the list */
@@ -1507,5 +1520,16 @@ static int __init nfsaddrs_config_setup(
 	return ip_auto_config_setup(addrs);
 }
 
+static int __init vendor_class_identifier_setup(char *addrs)
+{
+	if (strlcpy(vendor_class_identifier, addrs,
+		    sizeof(vendor_class_identifier))
+	    > sizeof(vendor_class_identifier))
+		printk(KERN_WARNING "vendorclass too long, truncated to \"%s\"",
+		       vendor_class_identifier);
+	return 1;
+}
+
 __setup("ip=", ip_auto_config_setup);
 __setup("nfsaddrs=", nfsaddrs_config_setup);
+__setup("dhcpclass=", vendor_class_identifier_setup);




----



--- ...
From: Patrick McHardy
Date: Wednesday, November 14, 2007 - 1:56 am

I don't think its very useful since you can simply get this information
from /proc/cmdline in case something goes wrong, but if you insist at


Should be >= I think.
-

From: Rainer Jochem
Date: Wednesday, November 14, 2007 - 2:45 am

Fixed.


Regards,
 Rainer

----

--- net/ipv4/ipconfig.c.orig	2007-11-14 09:16:15.800566536 +0100
+++ net/ipv4/ipconfig.c	2007-11-14 10:34:22.471219274 +0100
@@ -139,6 +139,8 @@ __be32 ic_servaddr = NONE;	/* Boot serve
 __be32 root_server_addr = NONE;	/* Address of NFS server */
 u8 root_server_path[256] = { 0, };	/* Path to mount as root */
 
+static char vendor_class_identifier[253]; /* vendor class identifier */
+
 /* Persistent data: */
 
 static int ic_proto_used;			/* Protocol used, if any */
@@ -580,6 +582,7 @@ ic_dhcp_init_options(u8 *options)
 	u8 mt = ((ic_servaddr == NONE)
 		 ? DHCPDISCOVER : DHCPREQUEST);
 	u8 *e = options;
+	int len;
 
 #ifdef IPCONFIG_DEBUG
 	printk("DHCP: Sending message type %d\n", mt);
@@ -620,6 +623,16 @@ ic_dhcp_init_options(u8 *options)
 		*e++ = sizeof(ic_req_params);
 		memcpy(e, ic_req_params, sizeof(ic_req_params));
 		e += sizeof(ic_req_params);
+
+		if (*vendor_class_identifier) {
+			printk(KERN_INFO "DHCP: sending class identifier \"%s\"\n",
+			       vendor_class_identifier);
+			*e++ = 60;	/* Class-identifier */
+			len = strlen(vendor_class_identifier);
+			*e++ = len;
+			memcpy(e, vendor_class_identifier, len);
+			e += len;
+		}
 	}
 
 	*e++ = 255;	/* End of the list */
@@ -1507,5 +1520,16 @@ static int __init nfsaddrs_config_setup(
 	return ip_auto_config_setup(addrs);
 }
 
+static int __init vendor_class_identifier_setup(char *addrs)
+{
+	if (strlcpy(vendor_class_identifier, addrs,
+		    sizeof(vendor_class_identifier))
+	    >= sizeof(vendor_class_identifier))
+		printk(KERN_WARNING "DHCP: vendorclass too long, truncated to \"%s\"",
+		       vendor_class_identifier);
+	return 1;
+}
+
 __setup("ip=", ip_auto_config_setup);
 __setup("nfsaddrs=", nfsaddrs_config_setup);
+__setup("dhcpclass=", vendor_class_identifier_setup);
-

From: Patrick McHardy
Date: Wednesday, November 14, 2007 - 2:48 am

Looks fine, thanks.


-

From: David Miller
Date: Wednesday, November 14, 2007 - 3:18 am

From: Patrick McHardy <kaber@trash.net>

Applied to net-2.6.25, thanks everyone.
-

From: Francois Romieu
Date: Wednesday, November 14, 2007 - 3:11 pm

Rainer Jochem <rainer.jochem@mpi-sb.mpg.de> :

ic_dhcp_init_options is __init. Should it not be __initdata ?

-- 
Ueimor
-

From: David Miller
Date: Monday, November 19, 2007 - 10:56 pm

From: Francois Romieu <romieu@fr.zoreil.com>

I think so and I've made that change in net-2.6.25, thanks.
-

From: Ilpo Järvinen
Date: Thursday, November 8, 2007 - 1:27 pm

No C99 comments please. Though I'm not sure if this comment is that 

-- 
 i.
-

Previous thread: [PATCH] spi: Fix error paths on txx9spi_probe by Atsushi Nemoto on Thursday, November 8, 2007 - 7:35 am. (2 messages)

Next thread: Re: 2.6.24-rc1-gb4f5550 oops by Rafael J. Wysocki on Thursday, November 8, 2007 - 8:53 am. (7 messages)