changeset 2226:d890d1db44ae draft

IAID must be used within an interface block. IA_PD must be used within an interface block. You cannot assign a delegated prefix to the requesting interface.
author Roy Marples <roy@marples.name>
date Sat, 18 Jan 2014 14:49:29 +0000
parents 5e0603406161
children 2ceab9da867e
files dhcpcd.c dhcpcd.conf.5.in if-options.c if-options.h
diffstat 4 files changed, 46 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/dhcpcd.c	Thu Jan 16 09:29:42 2014 +0000
+++ b/dhcpcd.c	Sat Jan 18 14:49:29 2014 +0000
@@ -495,7 +495,7 @@
 {
 
 	select_profile(ifp, NULL);
-	add_options(ifp->options, argc, argv);
+	add_options(ifp->name, ifp->options, argc, argv);
 	configure_interface1(ifp);
 }
 
@@ -839,7 +839,7 @@
 	ifdv = NULL;
 
 	ifo = read_config(cffile, NULL, NULL, NULL);
-	add_options(ifo, margc, margv);
+	add_options(NULL, ifo, margc, margv);
 	/* We need to preserve these two options. */
 	if (options & DHCPCD_MASTER)
 		ifo->options |= DHCPCD_MASTER;
@@ -1167,7 +1167,7 @@
 	margv = argv;
 	margc = argc;
 	if_options = read_config(cffile, NULL, NULL, NULL);
-	opt = add_options(if_options, argc, argv);
+	opt = add_options(NULL, if_options, argc, argv);
 	if (opt != 1) {
 		if (opt == 0)
 			usage();
--- a/dhcpcd.conf.5.in	Thu Jan 16 09:29:42 2014 +0000
+++ b/dhcpcd.conf.5.in	Sat Jan 18 14:49:29 2014 +0000
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2006-2013 Roy Marples
+.\" Copyright (c) 2006-2014 Roy Marples
 .\" All rights reserved
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd December 6, 2013
+.Dd January 18, 2014
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -146,6 +146,9 @@
 .It Ic iaid Ar iaid
 Set the Interface Association Identifier to
 .Ar iaid .
+This option must be used in an
+.Ic interface
+block.
 This defaults to the last 4 bytes of the hardware address assigned to the
 interface.
 Each instance of this should be unique within the scope of the client and
@@ -200,6 +203,9 @@
 .It Ic ia_pd Op Ar iaid Op Ar interface Op / Ar sla_id Op / Ar prefix_len
 Request a DHCPv6 Delegated Prefix for
 .Ar iaid .
+This option must be used in an
+.Ic interface
+block.
 If no
 .Ar interface
 is given then we will assign a prefix to every other interface with a unique
@@ -208,7 +214,8 @@
 Otherwise addresses are only assigned for each
 .Ar interface
 and
-.Ar sla_id
+.Ar sla_id .
+You cannot assign a prefix to the requesting interface.
 A default
 .Ar prefix_len
 of 64 is assumed.
--- a/if-options.c	Thu Jan 16 09:29:42 2014 +0000
+++ b/if-options.c	Sat Jan 18 14:49:29 2014 +0000
@@ -550,7 +550,8 @@
 }
 
 static int
-parse_option(struct if_options *ifo, int opt, const char *arg)
+parse_option(const char *ifname, struct if_options *ifo,
+    int opt, const char *arg)
 {
 	int i, l, t;
 	unsigned int u;
@@ -1081,6 +1082,11 @@
 		break;
 #endif
 	case O_IAID:
+		if (ifname == NULL) {
+			syslog(LOG_ERR,
+			    "IAID must belong in an interface block");
+			return -1;
+		}
 		if (parse_iaid(ifo->iaid, arg, sizeof(ifo->iaid)) == -1)
 			return -1;
 		ifo->options |= DHCPCD_IAID;
@@ -1112,8 +1118,19 @@
 			i = D6_OPTION_IA_TA;
 		/* FALLTHROUGH */
 	case O_IA_PD:
-		if (i == 0)
+		if (i == 0) {
+			if (ifname == NULL) {
+				syslog(LOG_ERR,
+				    "IA PD must belong in an interface block");
+				return -1;
+			}
 			i = D6_OPTION_IA_PD;
+		}
+		if (arg != NULL && ifname == NULL) {
+			syslog(LOG_ERR,
+			    "IA with IAID must belong in an interface block");
+			return -1;
+		}
 		ifo->options |= DHCPCD_IA_FORCED;
 		if (ifo->ia_type != 0 && ifo->ia_type != i) {
 			syslog(LOG_ERR, "cannot specify a different IA type");
@@ -1173,6 +1190,12 @@
 			np = strchr(p, '/');
 			if (np)
 				*np++ = '\0';
+			if (strcmp(ifname, p) == 0) {
+				syslog(LOG_ERR,
+				    "%s: cannot assign IA_PD to itself",
+				    ifname);
+				return -1;
+			}
 			if (strlcpy(sla->ifname, p,
 			    sizeof(sla->ifname)) >= sizeof(sla->ifname))
 			{
@@ -1506,7 +1529,8 @@
 }
 
 static int
-parse_config_line(struct if_options *ifo, const char *opt, char *line)
+parse_config_line(const char *ifname, struct if_options *ifo,
+    const char *opt, char *line)
 {
 	unsigned int i;
 
@@ -1522,7 +1546,7 @@
 			return -1;
 		}
 
-		return parse_option(ifo, cf_options[i].val, line);
+		return parse_option(ifname, ifo, cf_options[i].val, line);
 	}
 
 	fprintf(stderr, PACKAGE ": unknown option -- %s\n", opt);
@@ -1648,7 +1672,7 @@
 				    *(p - 1) != '\\')
 					*p-- = '\0';
 			}
-			parse_config_line(ifo, option, line);
+			parse_config_line(NULL, ifo, option, line);
 
 		}
 
@@ -1737,7 +1761,7 @@
 		}
 		if (skip)
 			continue;
-		parse_config_line(ifo, option, line);
+		parse_config_line(ifname, ifo, option, line);
 	}
 	fclose(f);
 
@@ -1752,7 +1776,7 @@
 }
 
 int
-add_options(struct if_options *ifo, int argc, char **argv)
+add_options(const char *ifname, struct if_options *ifo, int argc, char **argv)
 {
 	int oi, opt, r;
 
@@ -1763,7 +1787,7 @@
 	r = 1;
 	while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1)
 	{
-		r = parse_option(ifo, opt, optarg);
+		r = parse_option(ifname, ifo, opt, optarg);
 		if (r != 1)
 			break;
 	}
--- a/if-options.h	Thu Jan 16 09:29:42 2014 +0000
+++ b/if-options.h	Sat Jan 18 14:49:29 2014 +0000
@@ -182,7 +182,7 @@
 
 struct if_options *read_config(const char *,
     const char *, const char *, const char *);
-int add_options(struct if_options *, int, char **);
+int add_options(const char *, struct if_options *, int, char **);
 void free_dhcp_opt_embenc(struct dhcp_opt *);
 void free_options(struct if_options *);