changeset 2182:8eb411a50b05 draft

If an embedded or encapsulated option variable differs from the parent variable, prefix it with the parent varaible and an underscore. Document request, norequest and array. Ignore string arrays.
author Roy Marples <roy@marples.name>
date Mon, 02 Dec 2013 14:34:04 +0000
parents 3517466bff67
children d274de400a33
files dhcp-common.c dhcpcd-embedded.conf dhcpcd.conf.5.in if-options.c
diffstat 4 files changed, 89 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/dhcp-common.c	Sun Dec 01 17:45:42 2013 +0000
+++ b/dhcp-common.c	Mon Dec 02 14:34:04 2013 +0000
@@ -539,6 +539,8 @@
 	const uint8_t *ed;
 	int el;
 	const struct dhcp_opt *eopt;
+	char *eprefix;
+	const char *p;
 
 	/* If no embedded or encapsulated options, it's easy */
 	if (opt->embopts_len == 0 && opt->encopts_len == 0) {
@@ -548,6 +550,20 @@
 		return 1;
 	}
 
+	/* Create a new prefix based on the option */
+	if (env) {
+		e = strlen(famprefix) + strlen(opt->v.var) + 2;
+		eprefix = malloc(e);
+		if (eprefix == NULL) {
+			syslog(LOG_ERR, "%s: %m", __func__);
+			return 0;
+		}
+		snprintf(eprefix, e, "%s_%s", famprefix, opt->v.var);
+	}
+	/* Silence bogus gcc warning */
+	else
+		eprefix = NULL;
+
 	/* Embedded options are always processed first as that
 	 * is a fixed layout */
 	n = 0;
@@ -557,9 +573,17 @@
 		if (e == 0)
 			/* Report error? */
 			return 0;
-		if (env)
-			dhcp_envoption1(&env[n], prefix, famprefix, ifname,
+		if (env) {
+			/* Use the option prefix if the embedded option
+			 * name is different.
+			 * This avoids new_fqdn_fqdn which would be silly. */
+			if (strcmp(opt->v.var, eopt->v.var) == 0)
+				p = famprefix;
+			else
+				p = eprefix;
+			dhcp_envoption1(&env[n], prefix, p, ifname,
 			    eopt, od, e);
+		}
 		n++;
 		od += e;
 		ol -= e;
@@ -569,13 +593,21 @@
 	for (i = 0; i < opt->encopts_len; i++) {
 		eopt = &opt->encopts[i];
 		if ((ed = dgetopt(&el, eopt->option, od, ol))) {
-			if (env)
-				dhcp_envoption1(&env[n], prefix,
-				    famprefix, ifname, eopt, ed, el);
+			if (env) {
+				if (strcmp(opt->v.var, eopt->v.var) == 0)
+					p = famprefix;
+				else
+					p = eprefix;
+				dhcp_envoption1(&env[n], prefix, p,
+				    ifname, eopt, ed, el);
+			}
 			n++;
 		}
 	}
 
+	if (env)
+		free(eprefix);
+
 	/* Return number of options found */
 	return n;
 }
--- a/dhcpcd-embedded.conf	Sun Dec 01 17:45:42 2013 +0000
+++ b/dhcpcd-embedded.conf	Mon Dec 02 14:34:04 2013 +0000
@@ -1,19 +1,19 @@
 # Embedded option definitions for dhcpcd(8)
 
-# DHCP option 81, Fully Qualified Domain Name, RFC4702
-define 81 embed
-embed byte fqdn_flags
-embed byte fqdn_rcode1
-embed byte fqdn_rcode2
-embed domain fqdn
+# DHCP Fully Qualified Domain Name, RFC4702
+define 81	embed			fqdn
+embed		byte			flags
+embed		byte			rcode1
+embed		byte			rcode2
+embed		domain			fqdn
 
-# DHCPv6 option 39, Fully Qualified Domain Name, RFC4704
-define6 39 embed
-embed byte fqdn_flags
-embed domain fqdn
+# DHCPv6 Fully Qualified Domain Name, RFC4704
+define6 39	embed			fqdn
+embed		byte			flags
+embed		domain			fqdn
 
-# DHCPv6 option 56 NTP Server, RFC5908
-define6 56 encap
-encap 1 ip6address ntp_server_addr
-encap 2 ip6address ntp_mcast_addr
-encap 3 ip6address ntp_server_fqdn
+# DHCPv6 Network Time Protocol Server, RFC5908
+define6 56	encap			ntp_server
+encap 1		ip6address		addr
+encap 2		ip6address		mcast_addr
+encap 3		ip6address		fqdn
--- a/dhcpcd.conf.5.in	Sun Dec 01 17:45:42 2013 +0000
+++ b/dhcpcd.conf.5.in	Mon Dec 02 14:34:04 2013 +0000
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd December 1, 2013
+.Dd December 2, 2013
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -509,10 +509,35 @@
 Defines an embedded variable within the defined option.
 The length is determined by the
 .Ar type .
+If the
+.Ar variable
+is not the same as defined in the parent option,
+it is prefixed with the parent
+.Ar variable
+first with an underscore.
 .It Ic encap Ar code Ar type Ar variable
 Defines an encapsulated variable within the defined option.
 The length is determined by the
 .Ar type .
+If the
+.Ar variable
+is not the same as defined in the parent option,
+it is prefixed with the parent
+.Ar variable
+first with an underscore.
+.El
+.Ss Type prefix
+These keywords come before the type itself, to describe it more fully.
+You can use more than one, but they must appear in the order listed below.
+.Bl -tag -width -indent
+.It Ic request
+Requests the option by default without having to be specified in user
+configuration
+.It Ic norequest
+This option cannot be requested, regardless of user configuration
+.It Ic array
+The option data is split into a space seperated array, each element being
+the same type.
 .El
 .Ss Types to define
 The type directly affects the length of data consumed inside the option.
@@ -549,17 +574,17 @@
 .El
 .Ss Example definition
 .D1 # DHCP option 81, Fully Qualified Domain Name, RFC4702
-.D1 define 81 embed
-.D1 embed byte fqdn_flags
-.D1 embed byte fqdn_rcode1
-.D1 embed byte fqdn_rcode2
+.D1 define 81 embed fqdn
+.D1 embed byte flags
+.D1 embed byte rcode1
+.D1 embed byte rcode2
 .D1 embed domain fqdn
 .Pp
 .D1 # DHCP option 125, Vendor Specific Information Option, RFC3925
-.D1 define 125 encap
-.D1 embed uint32 vsio_enterprise_number
+.D1 define 125 encap vsio
+.D1 embed uint32 enterprise_number
 .D1 # Options defined for the enterprise number
-.D1 encap 1 ipaddress vsio_ipaddress
+.D1 encap 1 ipaddress ipaddress
 .Sh SEE ALSO
 .Xr fnmatch 3 ,
 .Xr if_nametoindex 3 ,
--- a/if-options.c	Sun Dec 01 17:45:42 2013 +0000
+++ b/if-options.c	Mon Dec 02 14:34:04 2013 +0000
@@ -1325,6 +1325,10 @@
 			    "ignoring length for type `%s'", arg);
 			l = 0;
 		}
+		if (t & ARRAY && t & (STRING | BINHEX)) {
+			syslog(LOG_WARNING, "ignoring array for strings");
+			t &= ~ARRAY;
+		}
 		/* variable */
 		if (fp) {
 			arg = strskipwhite(fp);