Module Name:    src
Committed By:   roy
Date:           Tue Sep 16 22:27:04 UTC 2014

Modified Files:
        src/external/bsd/dhcpcd/dist: dhcp.c dhcpcd-run-hooks.8.in dhcpcd.8.in
            dhcpcd.c dhcpcd.conf dhcpcd.conf.5.in if-bsd.c if-options.c
            ipv6nd.c script.c

Log Message:
Sync


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/external/bsd/dhcpcd/dist/dhcp.c
cvs rdiff -u -r1.5 -r1.6 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in
cvs rdiff -u -r1.29 -r1.30 src/external/bsd/dhcpcd/dist/dhcpcd.8.in
cvs rdiff -u -r1.7 -r1.8 src/external/bsd/dhcpcd/dist/dhcpcd.c \
    src/external/bsd/dhcpcd/dist/if-bsd.c \
    src/external/bsd/dhcpcd/dist/script.c
cvs rdiff -u -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/dhcpcd.conf
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in \
    src/external/bsd/dhcpcd/dist/ipv6nd.c
cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/if-options.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/dhcpcd/dist/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.15 src/external/bsd/dhcpcd/dist/dhcp.c:1.16
--- src/external/bsd/dhcpcd/dist/dhcp.c:1.15	Wed Jul 30 15:47:32 2014
+++ src/external/bsd/dhcpcd/dist/dhcp.c	Tue Sep 16 22:27:04 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp.c,v 1.15 2014/07/30 15:47:32 roy Exp $");
+ __RCSID("$NetBSD: dhcp.c,v 1.16 2014/09/16 22:27:04 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -126,7 +126,7 @@ struct udp_dhcp_packet
 
 static const size_t udp_dhcp_len = sizeof(struct udp_dhcp_packet);
 
-static int dhcp_open(struct interface *);
+static int dhcp_open(struct interface *ifp);
 
 void
 dhcp_printoptions(const struct dhcpcd_ctx *ctx,
@@ -302,6 +302,10 @@ decode_rfc3442(char *out, size_t len, co
 			return -1;
 		}
 		ocets = (cidr + 7) / NBBY;
+		if (p + 4 + ocets > e) {
+			errno = ERANGE;
+			return -1;
+		}
 		if (!out) {
 			p += 4 + ocets;
 			bytes += ((4 * 4) * 2) + 4;
@@ -364,6 +368,13 @@ decode_rfc3442_rt(const uint8_t *data, s
 			return NULL;
 		}
 
+		ocets = (cidr + 7) / NBBY;
+		if (p + 4 + ocets > e) {
+			ipv4_freeroutes(routes);
+			errno = ERANGE;
+			return NULL;
+		}
+
 		rt = calloc(1, sizeof(*rt));
 		if (rt == NULL) {
 			syslog(LOG_ERR, "%s: %m", __func__);
@@ -372,7 +383,6 @@ decode_rfc3442_rt(const uint8_t *data, s
 		}
 		TAILQ_INSERT_TAIL(routes, rt, next);
 
-		ocets = (cidr + 7) / NBBY;
 		/* If we have ocets then we have a destination and netmask */
 		if (ocets > 0) {
 			memcpy(&rt->dest.s_addr, p, ocets);
@@ -831,7 +841,6 @@ make_message(struct dhcp_message **messa
 			p += ifo->vendorclassid[0] + 1;
 		}
 
-
 		if (type != DHCP_INFORM) {
 			if (ifo->leasetime != 0) {
 				*p++ = DHO_LEASETIME;
@@ -993,7 +1002,11 @@ make_message(struct dhcp_message **messa
 		auth_len = (size_t)dhcp_auth_encode(&ifo->auth,
 		    state->auth.token,
 		    NULL, 0, 4, type, NULL, 0);
-		if (auth_len > 0) {
+		if ((ssize_t)auth_len == -1) {
+			syslog(LOG_ERR, "%s: dhcp_auth_encode: %m",
+			    iface->name);
+			auth_len = 0;
+		} else if (auth_len != 0) {
 			len = (size_t)((p + auth_len) - m);
 			if (auth_len > 255 || len > sizeof(*dhcp))
 				goto toobig;
@@ -1001,9 +1014,7 @@ make_message(struct dhcp_message **messa
 			*p++ = (uint8_t)auth_len;
 			auth = p;
 			p += auth_len;
-		} else if ((ssize_t)auth_len == -1)
-			syslog(LOG_ERR, "%s: dhcp_auth_encode: %m",
-			    iface->name);
+		}
 	}
 
 	*p++ = DHO_END;
@@ -1017,7 +1028,7 @@ make_message(struct dhcp_message **messa
 #endif
 
 	len = (size_t)(p - m);
-	if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len > 0)
+	if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0)
 		dhcp_auth_encode(&ifo->auth, state->auth.token,
 		    m, len, 4, type, auth, auth_len);
 
@@ -1398,26 +1409,21 @@ dhcp_close(struct interface *ifp)
 		return;
 
 	if (state->arp_fd != -1) {
-		eloop_event_delete(ifp->ctx->eloop, state->arp_fd);
+		eloop_event_delete(ifp->ctx->eloop, state->arp_fd, 0);
 		close(state->arp_fd);
 		state->arp_fd = -1;
 	}
 	if (state->raw_fd != -1) {
-		eloop_event_delete(ifp->ctx->eloop, state->raw_fd);
+		eloop_event_delete(ifp->ctx->eloop, state->raw_fd, 0);
 		close(state->raw_fd);
 		state->raw_fd = -1;
 	}
-	if (state->udp_fd != -1) {
-		eloop_event_delete(ifp->ctx->eloop, state->udp_fd);
-		close(state->udp_fd);
-		state->udp_fd = -1;
-	}
 
 	state->interval = 0;
 }
 
 static int
-dhcp_openudp(struct dhcpcd_ctx *ctx, struct interface *ifp)
+dhcp_openudp(struct interface *ifp)
 {
 	int s;
 	struct sockaddr_in sin;
@@ -1469,31 +1475,13 @@ dhcp_openudp(struct dhcpcd_ctx *ctx, str
 	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
 		goto eexit;
 
-	if (ifp)
-		state->udp_fd = s;
-	else
-		ctx->udp_fd = s;
-	return 0;
+	return s;
 
 eexit:
 	close(s);
 	return -1;
 }
 
-static ssize_t
-dhcp_sendpacket(const struct interface *iface, struct in_addr to,
-    const uint8_t *data, size_t len)
-{
-	struct sockaddr_in sin;
-
-	memset(&sin, 0, sizeof(sin));
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = to.s_addr;
-	sin.sin_port = htons(DHCP_SERVER_PORT);
-	return sendto(D_CSTATE(iface)->udp_fd, data, len, 0,
-	    (struct sockaddr *)&sin, sizeof(sin));
-}
-
 static uint16_t
 checksum(const void *data, uint16_t len)
 {
@@ -1578,8 +1566,9 @@ send_message(struct interface *iface, ui
 	size_t len;
 	ssize_t r;
 	struct in_addr from, to;
-	in_addr_t a = 0;
+	in_addr_t a = INADDR_ANY;
 	struct timeval tv;
+	int s;
 
 	if (!callback)
 		syslog(LOG_DEBUG, "%s: sending %s with xid 0x%x",
@@ -1602,23 +1591,30 @@ send_message(struct interface *iface, ui
 		    timeval_to_double(&tv));
 	}
 
-	/* Ensure sockets are open. */
-	if (dhcp_open(iface) == -1) {
-		if (!(iface->ctx->options & DHCPCD_TEST))
-			dhcp_drop(iface, "FAIL");
+	if (dhcp_open(iface) == -1)
 		return;
-	}
+
+	if (state->addr.s_addr != INADDR_ANY &&
+	    state->new != NULL &&
+	    (state->new->cookie == htonl(MAGIC_COOKIE) ||
+	    iface->options->options & DHCPCD_INFORM))
+	{
+		s = dhcp_openudp(iface);
+		if (s == -1 && errno != EADDRINUSE)
+			syslog(LOG_ERR, "%s: dhcp_openudp: %m", iface->name);
+	} else
+		s = -1;
 
 	/* If we couldn't open a UDP port for our IP address
 	 * then we cannot renew.
 	 * This could happen if our IP was pulled out from underneath us.
 	 * Also, we should not unicast from a BOOTP lease. */
-	if (state->udp_fd == -1 ||
+	if (s == -1 ||
 	    (!(ifo->options & DHCPCD_INFORM) &&
 	    is_bootp(iface, state->new)))
 	{
 		a = state->addr.s_addr;
-		state->addr.s_addr = 0;
+		state->addr.s_addr = INADDR_ANY;
 	}
 	r = make_message(&dhcp, iface, type);
 	if (r == -1)
@@ -1630,13 +1626,18 @@ send_message(struct interface *iface, ui
 	if (from.s_addr)
 		to.s_addr = state->lease.server.s_addr;
 	else
-		to.s_addr = 0;
+		to.s_addr = INADDR_ANY;
 	if (to.s_addr && to.s_addr != INADDR_BROADCAST) {
-		r = dhcp_sendpacket(iface, to, (uint8_t *)dhcp, len);
-		if (r == -1) {
+		struct sockaddr_in sin;
+
+		memset(&sin, 0, sizeof(sin));
+		sin.sin_family = AF_INET;
+		sin.sin_addr.s_addr = to.s_addr;
+		sin.sin_port = htons(DHCP_SERVER_PORT);
+		r = sendto(s, (uint8_t *)dhcp, len, 0,
+		    (struct sockaddr *)&sin, sizeof(sin));
+		if (r == -1)
 			syslog(LOG_ERR, "%s: dhcp_sendpacket: %m", iface->name);
-			dhcp_close(iface);
-		}
 	} else {
 		size_t ulen;
 
@@ -1675,6 +1676,9 @@ send_message(struct interface *iface, ui
 	free(dhcp);
 
 fail:
+	if (s != -1)
+		close(s);
+
 	/* Even if we fail to send a packet we should continue as we are
 	 * as our failure timeouts will change out codepath when needed. */
 	if (callback)
@@ -2144,7 +2148,7 @@ dhcp_drop(struct interface *ifp, const c
 	dhcp_auth_reset(&state->auth);
 	dhcp_close(ifp);
 	arp_close(ifp);
-	eloop_timeouts_delete(ifp->ctx->eloop, ifp, dhcp_expire, NULL);
+	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 	if (ifp->options->options & DHCPCD_RELEASE) {
 		unlink(state->leasefile);
 		if (ifp->carrier != LINK_DOWN &&
@@ -2697,38 +2701,21 @@ dhcp_handlepacket(void *arg)
 }
 
 static void
-dhcp_handleudp1(struct dhcpcd_ctx *ctx, int *fd, const char *ifname)
-{
-	uint8_t buffer[sizeof(struct dhcp_message)];
-
-	/* Just read what's in the UDP fd and discard it as we always read
-	 * from the raw fd */
-	if (read(*fd, buffer, sizeof(buffer)) == -1) {
-		syslog(LOG_ERR, "%s: %s: %m", ifname, __func__);
-		eloop_event_delete(ctx->eloop, *fd);
-		close(*fd);
-		*fd = -1;
-	}
-}
-
-static void
 dhcp_handleudp(void *arg)
 {
 	struct dhcpcd_ctx *ctx;
+	uint8_t buffer[sizeof(struct dhcp_message)];
 
 	ctx = arg;
-	dhcp_handleudp1(arg, &ctx->udp_fd, NULL);
-}
 
-static void
-dhcp_handleifudp(void *arg)
-{
-	const struct interface *ifp;
-	struct dhcp_state *state;
-
-	ifp = arg;
-	state = D_STATE(ifp);
-	dhcp_handleudp1(ifp->ctx, &state->udp_fd, ifp->name);
+	/* Just read what's in the UDP fd and discard it as we always read
+	 * from the raw fd */
+	if (read(ctx->udp_fd, buffer, sizeof(buffer)) == -1) {
+		syslog(LOG_ERR, "%s: %m", __func__);
+		eloop_event_delete(ctx->eloop, ctx->udp_fd, 0);
+		close(ctx->udp_fd);
+		ctx->udp_fd = -1;
+	}
 }
 
 static int
@@ -2752,21 +2739,7 @@ dhcp_open(struct interface *ifp)
 			return -1;
 		}
 		eloop_event_add(ifp->ctx->eloop,
-		    state->raw_fd, dhcp_handlepacket, ifp);
-	}
-	if (state->udp_fd == -1 &&
-	    state->addr.s_addr != 0 &&
-	    state->new != NULL &&
-	    (state->new->cookie == htonl(MAGIC_COOKIE) ||
-	    ifp->options->options & DHCPCD_INFORM))
-	{
-		if (dhcp_openudp(ifp->ctx, ifp) == -1 && errno != EADDRINUSE) {
-			syslog(LOG_ERR, "%s: dhcp_openudp: %m", ifp->name);
-			return -1;
-		}
-		if (state->udp_fd != -1)
-			eloop_event_add(ifp->ctx->eloop,
-			    state->udp_fd, dhcp_handleifudp, ifp);
+		    state->raw_fd, dhcp_handlepacket, ifp, NULL, NULL);
 	}
 	return 0;
 }
@@ -2826,7 +2799,7 @@ dhcp_free(struct interface *ifp)
 	}
 	if (ifp == NULL) {
 		if (ctx->udp_fd != -1) {
-			eloop_event_delete(ctx->eloop, ctx->udp_fd);
+			eloop_event_delete(ctx->eloop, ctx->udp_fd, 0);
 			close(ctx->udp_fd);
 			ctx->udp_fd = -1;
 		}
@@ -2853,7 +2826,7 @@ dhcp_init(struct interface *ifp)
 		if (state == NULL)
 			return -1;
 		/* 0 is a valid fd, so init to -1 */
-		state->raw_fd = state->udp_fd = state->arp_fd = -1;
+		state->raw_fd = state->arp_fd = -1;
 	}
 
 	state->state = DHS_INIT;
@@ -2934,9 +2907,15 @@ dhcp_start1(void *arg)
 
 	/* Listen on *.*.*.*:bootpc so that the kernel never sends an
 	 * ICMP port unreachable message back to the DHCP server */
-	if (ifp->ctx->udp_fd == -1 && dhcp_openudp(ifp->ctx, NULL) != -1)
+	if (ifp->ctx->udp_fd == -1) {
+		ifp->ctx->udp_fd = dhcp_openudp(NULL);
+		if (ifp->ctx->udp_fd == -1) {
+			syslog(LOG_ERR, "dhcp_openudp: %m");
+			return;
+		}
 		eloop_event_add(ifp->ctx->eloop,
-		    ifp->ctx->udp_fd, dhcp_handleudp, ifp->ctx);
+		    ifp->ctx->udp_fd, dhcp_handleudp, ifp->ctx, NULL, NULL);
+	}
 
 	if (dhcp_init(ifp) == -1) {
 		syslog(LOG_ERR, "%s: dhcp_init: %m", ifp->name);
@@ -3038,20 +3017,13 @@ dhcp_start(struct interface *ifp)
 		return;
 
 	/* No point in delaying a static configuration */
-	if (ifp->options->options & DHCPCD_STATIC &&
-	    !(ifp->options->options & DHCPCD_INFORM))
-	{
-		tv.tv_sec = 0;
-		tv.tv_usec = 0;
-	} else {
-		tv.tv_sec = DHCP_MIN_DELAY;
-		tv.tv_usec = (suseconds_t)arc4random_uniform(
-		    (DHCP_MAX_DELAY - DHCP_MIN_DELAY) * 1000000);
-		timernorm(&tv);
-		syslog(LOG_DEBUG,
-		    "%s: delaying DHCP for %0.1f seconds",
-		    ifp->name, timeval_to_double(&tv));
-	}
+	tv.tv_sec = DHCP_MIN_DELAY;
+	tv.tv_usec = (suseconds_t)arc4random_uniform(
+	    (DHCP_MAX_DELAY - DHCP_MIN_DELAY) * 1000000);
+	timernorm(&tv);
+	syslog(LOG_DEBUG,
+	    "%s: delaying IPv4 for %0.1f seconds",
+	    ifp->name, timeval_to_double(&tv));
 
 	eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcp_start1, ifp);
 }

Index: src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.5 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.6
--- src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.5	Mon Jul 29 20:39:28 2013
+++ src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in	Tue Sep 16 22:27:04 2014
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd-run-hooks.8.in,v 1.5 2013/07/29 20:39:28 roy Exp $
+.\"     $NetBSD: dhcpcd-run-hooks.8.in,v 1.6 2014/09/16 22:27:04 roy Exp $
 .\" Copyright (c) 2006-2013 Roy Marples
 .\" All rights reserved
 .\"
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd June 6, 2013
+.Dd September 12, 2014
 .Dt DHCPCD-RUN-HOOKS 8
 .Os
 .Sh NAME
@@ -70,12 +70,15 @@ argument.
 Here's a list of reasons why
 .Nm
 could be invoked:
-.Bl -tag -width ROUTERADVERT
+.Bl -tag -width EXPIREXXXEXPIRE6
 .It Dv PREINIT
 dhcpcd is starting up and any pre-initialisation should be done.
 .It Dv CARRIER
 dhcpcd has detected the carrier is up.
 This is generally just a notification and no action need be taken.
+.It Dv NOCARRIER
+dhcpcd lost the carrier.
+The cable may have been unplugged or association to the wireless point lost.
 .It Dv INFORM | Dv INFORM6
 dhcpcd informed a DHCP server about it's address and obtained other
 configuration details.
@@ -103,18 +106,19 @@ dhcpcd received a NAK from the DHCP serv
 This should be treated as EXPIRE.
 .It Dv RECONFIGURE
 dhcpcd has been instructed to reconfigure an interface.
-.It Dv NOCARRIER
-dhcpcd lost the carrier.
-The cable may have been unplugged or association to the wireless point lost.
+.It Dv ROUTERADVERT
+dhcpcd has received an IPv6 Router Advertisment, or one has expired.
+.It Dv STOP | Dv STOP6
+dhcpcd stopped running on the interface.
+.It Dv STOPPED
+dhcpcd has stopped entirely.
+.It Dv DEPARTED
+The interface has been removed.
 .It Dv FAIL
 dhcpcd failed to operate on the interface.
 This normally happens when dhcpcd does not support the raw interface, which
 means it cannot work as a DHCP or ZeroConf client.
 Static configuration and DHCP INFORM is still allowed.
-.It Dv STOP | Dv STOP6
-dhcpcd stopped running on the interface.
-.It Dv DEPARTED
-The interface has been removed.
 .It Dv DUMP
 dhcpcd has been asked to dump the last lease for the interface.
 .It Dv TEST
@@ -122,8 +126,77 @@ dhcpcd received an OFFER from a DHCP ser
 interface.
 This is primarily used to test the variables are filled correctly for the
 script to process them.
-.It Dv ROUTERADVERT
-dhcpcd has received an IPv6 Router Advertisment, or one has expired.
+.El
+.Sh ENVIRONMENT
+.Nm dhcpcd
+will clear the environment variables aside from
+.Ev $PATH
+and
+.Ev $RC_SVCNAME .
+The following variables will then be set, along with any protocol supplied
+ones.
+.Bl -tag -width Xinterface_order
+.It Ev $interface
+the name of the interface.
+.It Ev $reason
+as described above.
+.It Ev $pid
+the pid of
+.Nm dhcpcd .
+.It Ev $ifcarrier
+the link status of
+.Ev $interface :
+.Dv unknown ,
+.Dv up
+or
+.Dv down .
+.It Ev $ifmetric
+.Ev $interface
+preference, lower is better.
+.It Ev $ifwireless
+.Dv 1 if
+.Ev $interface
+is wireless, otherwise
+.Dv 0 .
+.It Ev $ifflags
+.Ev $interface
+flags.
+.It Ev $ifmtu
+.Ev $interface
+MTU.
+.It Ev $interface_order
+A list of interfaces, in order of preference.
+.It Ev $if_up
+.Dv true
+if the
+.Ev interface
+is up, otherwise
+.Dv false .
+.It Ev $if_down
+.Dv true
+if the
+.Ev interface
+is down, otherwise
+.Dv false .
+.It Ev $if_oneup
+.Dv true
+if any interface is up, otherwise false.
+.It Ev $if_ipwaited
+.Dv true
+if any interface has been assigned an IP address which matches any wait
+requirements specified in
+.Xr dhcpcd.conf 5 .
+.It Ev $profile
+the name of the profile selected from
+.Xr dhcpcd.conf 5 .
+.It Ev $new_ssid
+the name of the SSID the
+.Ev interface
+is connected to.
+.It Ev $old_ssid
+the name of the SSID the
+.Ev interface
+was connected to.
 .El
 .Sh FILES
 When

Index: src/external/bsd/dhcpcd/dist/dhcpcd.8.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.29 src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.30
--- src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.29	Mon Jul 14 11:49:48 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.8.in	Tue Sep 16 22:27:04 2014
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd.8.in,v 1.29 2014/07/14 11:49:48 roy Exp $
+.\"     $NetBSD: dhcpcd.8.in,v 1.30 2014/09/16 22:27:04 roy Exp $
 .\" Copyright (c) 2006-2014 Roy Marples
 .\" All rights reserved
 .\"
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd July 7, 2014
+.Dd September 15, 2014
 .Dt DHCPCD 8
 .Os
 .Sh NAME
@@ -144,6 +144,14 @@ If a list of interfaces are given on the
 only works with those interfaces, otherwise
 .Nm
 discovers available Ethernet interfaces.
+This is called Master mode and this behaviour can be forced with the
+.Fl M , Fl Fl master
+option so that an individual interface can start
+.Nm
+but only one instance is running.
+The
+.Nm dhcpcd-ui
+project expects dhcpcd to be running this way.
 If any interface reports a working carrier then
 .Nm
 will try and obtain a lease before forking to the background,
@@ -322,6 +330,7 @@ DHCP server.
 Start
 .Nm
 in master mode even if only one interface specified on the command line.
+See the Multiple Interfaces section above.
 .It Fl m , Fl Fl metric Ar metric
 Metrics are used to prefer an interface over another one, lowest wins.
 .Nm
@@ -481,9 +490,9 @@ configured exactly how the the DHCP serv
 Here are some options that deal with turning these bits off.
 .Bl -tag -width indent
 .It Fl 4 , Fl Fl ipv4only
-Only configure IPv4.
+Configure IPv4 only.
 .It Fl 6 , Fl Fl ipv6only
-Only confgiure IPv6.
+Configure IPv6 only.
 .It Fl A , Fl Fl noarp
 Don't request or claim the address by ARP.
 This also disables IPv4LL.
@@ -665,6 +674,9 @@ running on the
 .Ar interface .
 .It Pa @RUNDIR@/dhcpcd.sock
 Control socket to the master daemon.
+.It Pa @RUNDIR@/dhcpcd.unpriv.sock
+Unpriviledged socket to the master daemon, only allows state retrieval.
+Control socket to the master daemon.
 .It Pa @RUNDIR@/dhcpcd\- Ns Ar interface Ns .sock
 Control socket to per interface daemon.
 .El

Index: src/external/bsd/dhcpcd/dist/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.c:1.7 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.8
--- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.7	Wed Jul 30 15:47:32 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.c	Tue Sep 16 22:27:04 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd.c,v 1.7 2014/07/30 15:47:32 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd.c,v 1.8 2014/09/16 22:27:04 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -212,6 +212,40 @@ handle_exit_timeout(void *arg)
 	eloop_timeout_add_sec(ctx->eloop, timeout, handle_exit_timeout, ctx);
 }
 
+int
+dhcpcd_oneup(struct dhcpcd_ctx *ctx)
+{
+	const struct interface *ifp;
+
+	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+		if (D_STATE_RUNNING(ifp) ||
+		    RS_STATE_RUNNING(ifp) ||
+		    D6_STATE_RUNNING(ifp))
+			return 1;
+	}
+	return 0;
+}
+
+int
+dhcpcd_ipwaited(struct dhcpcd_ctx *ctx)
+{
+
+	if (ctx->options & DHCPCD_WAITIP4 &&
+	    !ipv4_addrexists(ctx, NULL))
+		return 0;
+	if (ctx->options & DHCPCD_WAITIP6 &&
+	    !ipv6nd_addrexists(ctx, NULL) &&
+	    !dhcp6_addrexists(ctx, NULL))
+		return 0;
+	if (ctx->options & DHCPCD_WAITIP &&
+	    !(ctx->options & (DHCPCD_WAITIP4 | DHCPCD_WAITIP6)) &&
+	    !ipv4_addrexists(ctx, NULL) &&
+	    !ipv6nd_addrexists(ctx, NULL) &&
+	    !dhcp6_addrexists(ctx, NULL))
+		return 0;
+	return 1;
+}
+
 /* Returns the pid of the child, otherwise 0. */
 pid_t
 dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
@@ -228,19 +262,7 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
 	if (ctx->options & DHCPCD_DAEMONISE &&
 	    !(ctx->options & DHCPCD_DAEMONISED))
 	{
-		if (ctx->options & DHCPCD_WAITIP4 &&
-		    !ipv4_addrexists(ctx, NULL))
-			return 0;
-		if (ctx->options & DHCPCD_WAITIP6 &&
-		    !ipv6nd_addrexists(ctx, NULL) &&
-		    !dhcp6_addrexists(ctx, NULL))
-			return 0;
-		if ((ctx->options &
-		    (DHCPCD_WAITIP | DHCPCD_WAITIP4 | DHCPCD_WAITIP6)) ==
-		    (DHCPCD_WAITIP | DHCPCD_WAITIP4 | DHCPCD_WAITIP6) &&
-		    !ipv4_addrexists(ctx, NULL) &&
-		    !ipv6nd_addrexists(ctx, NULL) &&
-		    !dhcp6_addrexists(ctx, NULL))
+		if (!dhcpcd_ipwaited(ctx))
 			return 0;
 	}
 
@@ -469,8 +491,18 @@ int
 dhcpcd_selectprofile(struct interface *ifp, const char *profile)
 {
 	struct if_options *ifo;
+	char pssid[PROFILE_LEN];
 
-	ifo = read_config(ifp->ctx, ifp->name, ifp->ssid, profile);
+	if (ifp->ssid_len) {
+		ssize_t r;
+		r =print_string(pssid, sizeof(pssid), ifp->ssid, ifp->ssid_len);
+		if (r == -1) {
+			syslog(LOG_ERR, "%s: %s: %m", ifp->name, __func__);
+			pssid[0] = '\0';
+		}
+	} else
+		pssid[0] = '\0';
+	ifo = read_config(ifp->ctx, ifp->name, pssid, profile);
 	if (ifo == NULL) {
 		syslog(LOG_DEBUG, "%s: no profile %s", ifp->name, profile);
 		return -1;
@@ -554,7 +586,7 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *
 			dhcpcd_handleinterface(ctx, 0, ifp->name);
 #endif
 			if (ifp->wireless)
-				if_getssid(ifp->name, ifp->ssid);
+				if_getssid(ifp);
 			configure_interface(ifp, ctx->argc, ctx->argv);
 			script_runreason(ifp, "CARRIER");
 			dhcpcd_startinterface(ifp);
@@ -723,7 +755,7 @@ handle_link(void *arg)
 	ctx = arg;
 	if (if_managelink(ctx) == -1) {
 		syslog(LOG_ERR, "if_managelink: %m");
-		eloop_event_delete(ctx->eloop, ctx->link_fd);
+		eloop_event_delete(ctx->eloop, ctx->link_fd, 0);
 		close(ctx->link_fd);
 		ctx->link_fd = -1;
 	}
@@ -1049,6 +1081,32 @@ signal_init(void (*func)(int, siginfo_t 
 }
 #endif
 
+static void
+dhcpcd_getinterfaces(void *arg)
+{
+	struct fd_list *fd = arg;
+	struct interface *ifp;
+	size_t len;
+
+	len = 0;
+	TAILQ_FOREACH(ifp, fd->ctx->ifaces, next) {
+		len++;
+		if (D_STATE_RUNNING(ifp))
+			len++;
+		if (RS_STATE_RUNNING(ifp))
+			len++;
+		if (D6_STATE_RUNNING(ifp))
+			len++;
+	}
+	if (write(fd->fd, &len, sizeof(len)) != sizeof(len))
+		return;
+	eloop_event_delete(fd->ctx->eloop, fd->fd, 1);
+	TAILQ_FOREACH(ifp, fd->ctx->ifaces, next) {
+		if (send_interface(fd, ifp) == -1)
+			syslog(LOG_ERR, "send_interface %d: %m", fd->fd);
+	}
+}
+
 int
 dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
     int argc, char **argv)
@@ -1057,87 +1115,31 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx
 	int do_exit = 0, do_release = 0, do_reboot = 0;
 	int opt, oi = 0;
 	size_t len, l;
-	struct iovec iov[2];
 	char *tmp, *p;
 
-	if (fd != NULL) {
-		/* Special commands for our control socket */
-		if (strcmp(*argv, "--version") == 0) {
-			len = strlen(VERSION) + 1;
-			iov[0].iov_base = &len;
-			iov[0].iov_len = sizeof(ssize_t);
-			iov[1].iov_base = UNCONST(VERSION);
-			iov[1].iov_len = len;
-			if (writev(fd->fd, iov, 2) == -1) {
-				syslog(LOG_ERR, "writev: %m");
-				return -1;
-			}
-			return 0;
-		} else if (strcmp(*argv, "--getconfigfile") == 0) {
-			len = strlen(ctx->cffile) + 1;
-			iov[0].iov_base = &len;
-			iov[0].iov_len = sizeof(ssize_t);
-			iov[1].iov_base = UNCONST(ctx->cffile);
-			iov[1].iov_len = len;
-			if (writev(fd->fd, iov, 2) == -1) {
-				syslog(LOG_ERR, "writev: %m");
-				return -1;
-			}
-			return 0;
-		} else if (strcmp(*argv, "--getinterfaces") == 0) {
-			len = 0;
-			if (argc == 1) {
-				TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-					len++;
-					if (D_STATE(ifp))
-						len++;
-					if (D6_STATE_RUNNING(ifp))
-						len++;
-					if (ipv6nd_hasra(ifp))
-						len++;
-				}
-				if (write(fd->fd, &len, sizeof(len)) !=
-				    sizeof(len))
-					return -1;
-				TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-					if (send_interface(fd->fd, ifp) == -1)
-						syslog(LOG_ERR,
-						    "send_interface %d: %m",
-						    fd->fd);
-				}
-				return 0;
-			}
-			opt = 0;
-			while (argv[++opt] != NULL) {
-				TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-					if (strcmp(argv[opt], ifp->name) == 0) {
-						len++;
-						if (D_STATE(ifp))
-							len++;
-						if (D6_STATE_RUNNING(ifp))
-							len++;
-						if (ipv6nd_hasra(ifp))
-							len++;
-					}
-				}
-			}
-			if (write(fd->fd, &len, sizeof(len)) != sizeof(len))
-				return -1;
-			opt = 0;
-			while (argv[++opt] != NULL) {
-				TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-					if (strcmp(argv[opt], ifp->name)== 0 &&
-					    send_interface(fd->fd, ifp) == -1)
-						syslog(LOG_ERR,
-						    "send_interface %d: %m",
-						    fd->fd);
-				}
-			}
-			return 0;
-		} else if (strcmp(*argv, "--listen") == 0) {
-			fd->listener = 1;
-			return 0;
-		}
+	/* Special commands for our control socket
+	 * as the other end should be blocking until it gets the
+	 * expected reply we should be safely able just to change the
+	 * write callback on the fd */
+	if (strcmp(*argv, "--version") == 0) {
+		return control_queue(fd, UNCONST(VERSION),
+		    strlen(VERSION) + 1, 0);
+	} else if (strcmp(*argv, "--getconfigfile") == 0) {
+		return control_queue(fd, UNCONST(fd->ctx->cffile),
+		    strlen(fd->ctx->cffile) + 1, 0);
+	} else if (strcmp(*argv, "--getinterfaces") == 0) {
+		eloop_event_add(fd->ctx->eloop, fd->fd, NULL, NULL,
+		    dhcpcd_getinterfaces, fd);
+		return 0;
+	} else if (strcmp(*argv, "--listen") == 0) {
+		fd->flags |= FD_LISTEN;
+		return 0;
+	}
+
+	/* Only priviledged users can control dhcpcd via the socket. */
+	if (fd->flags & FD_UNPRIV) {
+		errno = EPERM;
+		return -1;
 	}
 
 	/* Log the command */
@@ -1145,10 +1147,8 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx
 	for (opt = 0; opt < argc; opt++)
 		len += strlen(argv[opt]) + 1;
 	tmp = malloc(len);
-	if (tmp == NULL) {
-		syslog(LOG_ERR, "%s: %m", __func__);
+	if (tmp == NULL)
 		return -1;
-	}
 	p = tmp;
 	for (opt = 0; opt < argc; opt++) {
 		l = strlen(argv[opt]);
@@ -1254,7 +1254,8 @@ main(int argc, char **argv)
 
 	ifo = NULL;
 	ctx.cffile = CONFIG;
-	ctx.pid_fd = ctx.control_fd = ctx.link_fd = -1;
+	ctx.pid_fd = ctx.control_fd = ctx.control_unpriv_fd = ctx.link_fd = -1;
+	TAILQ_INIT(&ctx.control_fds);
 #ifdef PLUGIN_DEV
 	ctx.dev_fd = -1;
 #endif
@@ -1630,7 +1631,8 @@ main(int argc, char **argv)
 	if (ctx.link_fd == -1)
 		syslog(LOG_ERR, "open_link_socket: %m");
 	else
-		eloop_event_add(ctx.eloop, ctx.link_fd, handle_link, &ctx);
+		eloop_event_add(ctx.eloop, ctx.link_fd,
+		    handle_link, &ctx, NULL, NULL);
 
 	/* Start any dev listening plugin which may want to
 	 * change the interface name provided by the kernel */
@@ -1720,7 +1722,7 @@ exit1:
 	}
 	free(ctx.duid);
 	if (ctx.link_fd != -1) {
-		eloop_event_delete(ctx.eloop, ctx.link_fd);
+		eloop_event_delete(ctx.eloop, ctx.link_fd, 0);
 		close(ctx.link_fd);
 	}
 
Index: src/external/bsd/dhcpcd/dist/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.7 src/external/bsd/dhcpcd/dist/if-bsd.c:1.8
--- src/external/bsd/dhcpcd/dist/if-bsd.c:1.7	Mon Jul 14 11:49:48 2014
+++ src/external/bsd/dhcpcd/dist/if-bsd.c	Tue Sep 16 22:27:04 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if-bsd.c,v 1.7 2014/07/14 11:49:48 roy Exp $");
+ __RCSID("$NetBSD: if-bsd.c,v 1.8 2014/09/16 22:27:04 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -140,8 +140,8 @@ if_openlinksocket(void)
 #endif
 }
 
-int
-if_getssid(const char *ifname, char *ssid)
+static int
+if_getssid1(const char *ifname, uint8_t *ssid)
 {
 	int s, retval = -1;
 #if defined(SIOCG80211NWID)
@@ -161,8 +161,13 @@ if_getssid(const char *ifname, char *ssi
 	memset(&nwid, 0, sizeof(nwid));
 	ifr.ifr_data = (void *)&nwid;
 	if (ioctl(s, SIOCG80211NWID, &ifr) == 0) {
-		retval = nwid.i_len;
-		if (ssid) {
+		if (ssid == NULL)
+			retval = nwid.i_len;
+		else if (nwid.i_len > IF_SSIDSIZE) {
+			errno = ENOBUFS;
+			retval = -1;
+		} else {
+			retval = nwid.i_len;
 			memcpy(ssid, nwid.i_nwid, nwid.i_len);
 			ssid[nwid.i_len] = '\0';
 		}
@@ -175,8 +180,13 @@ if_getssid(const char *ifname, char *ssi
 	memset(nwid, 0, sizeof(nwid));
 	ireq.i_data = &nwid;
 	if (ioctl(s, SIOCG80211, &ireq) == 0) {
-		retval = ireq.i_len;
-		if (ssid) {
+		if (ssid == NULL)
+			retval = ireq.i_len;
+		else if (ireq.i_len > IF_SSIDSIZE) {
+			errno = ENOBUFS;
+			retval = -1;
+		} else  {
+			retval = ireq.i_len;
 			memcpy(ssid, nwid, ireq.i_len);
 			ssid[ireq.i_len] = '\0';
 		}
@@ -187,6 +197,17 @@ if_getssid(const char *ifname, char *ssi
 	return retval;
 }
 
+int
+if_getssid(struct interface *ifp)
+{
+	int r;
+
+	r = if_getssid1(ifp->name, ifp->ssid);
+	if (r != -1)
+		ifp->ssid_len = (unsigned int)r;
+	return r;
+}
+
 /*
  * FreeBSD allows for Virtual Access Points
  * We need to check if the interface is a Virtual Interface Master
@@ -211,7 +232,7 @@ if_vimaster(const char *ifname)
 	if (ifmr.ifm_status & IFM_AVALID &&
 	    IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211)
 	{
-		if (if_getssid(ifname, NULL) == -1)
+		if (if_getssid1(ifname, NULL) == -1)
 			return 1;
 	}
 	return 0;
@@ -293,13 +314,6 @@ if_openrawsocket(struct interface *ifp, 
 	if (ioctl(fd, BIOCSETF, &pf) == -1)
 		goto eexit;
 
-#ifdef __OpenBSD__
-	/* For some reason OpenBSD fails to open the fd as non blocking */
-	if ((flags = fcntl(fd, F_GETFL, 0)) == -1 ||
-	    fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
-		goto eexit;
-#endif
-
 	return fd;
 
 eexit:
@@ -351,9 +365,7 @@ if_readrawpacket(struct interface *ifp, 
 	else
 		fd = state->raw_fd;
 
-	if (flags != NULL)
-		*flags = 0; /* Not supported on BSD */
-
+	*flags = 0;
 	for (;;) {
 		if (state->buffer_len == 0) {
 			bytes = read(fd, state->buffer, state->buffer_size);
Index: src/external/bsd/dhcpcd/dist/script.c
diff -u src/external/bsd/dhcpcd/dist/script.c:1.7 src/external/bsd/dhcpcd/dist/script.c:1.8
--- src/external/bsd/dhcpcd/dist/script.c:1.7	Mon Jul 14 11:49:48 2014
+++ src/external/bsd/dhcpcd/dist/script.c	Tue Sep 16 22:27:04 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: script.c,v 1.7 2014/07/14 11:49:48 roy Exp $");
+ __RCSID("$NetBSD: script.c,v 1.8 2014/09/16 22:27:04 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -60,6 +60,11 @@
 #include "compat/posix_spawn.h"
 #endif
 
+/* Allow the OS to define another script env var name */
+#ifndef RC_SVCNAME
+#define RC_SVCNAME "RC_SVCNAME"
+#endif
+
 #define DEFAULT_PATH	"PATH=/usr/bin:/usr/sbin:/bin:/sbin"
 
 static const char * const if_params[] = {
@@ -283,7 +288,7 @@ make_env(const struct interface *ifp, co
 	if (ifp->ctx->options & DHCPCD_DUMPLEASE)
 		elen = 2;
 	else
-		elen = 11;
+		elen = 13;
 
 #define EMALLOC(i, l) if ((env[(i)] = malloc((l))) == NULL) goto eexit;
 	/* Make our env */
@@ -354,27 +359,46 @@ make_env(const struct interface *ifp, co
 	}
 	if (env[9] == NULL || env[10] == NULL)
 		goto eexit;
+	if (dhcpcd_oneup(ifp->ctx))
+		env[11] = strdup("if_oneup=true");
+	else
+		env[11] = strdup("if_oneup=false");
+	if (env[11] == NULL)
+		goto eexit;
+	if (dhcpcd_ipwaited(ifp->ctx))
+		env[12] = strdup("if_ipwaited=true");
+	else
+		env[12] = strdup("if_ipwaited=false");
+	if (env[12] == NULL)
+		goto eexit;
 	if (*ifp->profile) {
 		e = strlen("profile=") + strlen(ifp->profile) + 2;
 		EMALLOC(elen, e);
 		snprintf(env[elen++], e, "profile=%s", ifp->profile);
 	}
 	if (ifp->wireless) {
-		e = strlen("new_ssid=") + strlen(ifp->ssid) + 2;
-		if (strcmp(reason, "CARRIER") == 0) {
-			nenv = realloc(env, sizeof(char *) * (elen + 2));
-			if (nenv == NULL)
-				goto eexit;
-			env = nenv;
-			EMALLOC(elen, e);
-			snprintf(env[elen++], e, "new_ssid=%s", ifp->ssid);
-		} else if (strcmp(reason, "NOCARRIER") == 0) {
-			nenv = realloc(env, sizeof(char *) * (elen + 2));
-			if (nenv == NULL)
-				goto eexit;
-			env = nenv;
-			EMALLOC(elen, e);
-			snprintf(env[elen++], e, "old_ssid=%s", ifp->ssid);
+		const char *pfx;
+
+		if (strcmp(reason, "CARRIER") == 0)
+			pfx = "new_ssid=";
+		else if (strcmp(reason, "NOCARRIER") == 0)
+			pfx = "old_ssid=";
+		else	
+			pfx = NULL;
+		if (pfx) {
+			size_t pfx_len;
+			ssize_t psl;
+
+			pfx_len = strlen(pfx);
+			psl = print_string(NULL, 0,
+			    (const uint8_t *)ifp->ssid, ifp->ssid_len);
+			if (psl != -1) {
+				EMALLOC(elen, pfx_len + (size_t)psl + 1);
+				memcpy(env[elen], pfx, pfx_len);
+				print_string(env[elen] + pfx_len, (size_t)psl,
+				    (const uint8_t *)ifp->ssid, ifp->ssid_len);
+				elen++;
+			}
 		}
 	}
 #ifdef INET
@@ -515,42 +539,40 @@ eexit:
 	return -1;
 }
 
-static ssize_t
-send_interface1(int fd, const struct interface *iface, const char *reason)
+static int
+send_interface1(struct fd_list *fd, const struct interface *iface,
+    const char *reason)
 {
 	char **env, **ep, *s;
 	size_t elen;
-	struct iovec iov[2];
-	ssize_t retval;
+	int retval;
 
 	if (make_env(iface, reason, &env) == -1)
 		return -1;
+	s = NULL;
 	elen = (size_t)arraytostr((const char *const *)env, &s);
-	if ((ssize_t)elen == -1)
+	if ((ssize_t)elen == -1) {
+		free(s);
 		return -1;
-	iov[0].iov_base = &elen;
-	iov[0].iov_len = sizeof(elen);
-	iov[1].iov_base = s;
-	iov[1].iov_len = elen;
-	retval = writev(fd, iov, 2);
+	}
+	retval = control_queue(fd, s, elen, 1);
 	ep = env;
 	while (*ep)
 		free(*ep++);
 	free(env);
-	free(s);
 	return retval;
 }
 
 int
-send_interface(int fd, const struct interface *ifp)
+send_interface(struct fd_list *fd, const struct interface *ifp)
 {
 	const char *reason;
 	int retval = 0;
 #ifdef INET
-	const struct dhcp_state *d = D_CSTATE(ifp);
+	const struct dhcp_state *d;
 #endif
 #ifdef INET6
-	const struct dhcp6_state *d6 = D6_CSTATE(ifp);
+	const struct dhcp6_state *d6;
 #endif
 
 	switch (ifp->carrier) {
@@ -565,19 +587,22 @@ send_interface(int fd, const struct inte
 		break;
 	}
 	if (send_interface1(fd, ifp, reason) == -1)
-			retval = -1;
+		retval = -1;
 #ifdef INET
-	if (d && d->reason)
+	if (D_STATE_RUNNING(ifp)) {
+		d = D_CSTATE(ifp);
 		if (send_interface1(fd, ifp, d->reason) == -1)
 			retval = -1;
+	}
 #endif
 
 #ifdef INET6
-	if (ipv6nd_hasra(ifp)) {
+	if (RS_STATE_RUNNING(ifp)) {
 		if (send_interface1(fd, ifp, "ROUTERADVERT") == -1)
 			retval = -1;
 	}
-	if (D6_STATE_RUNNING(ifp) && d6->reason) {
+	if (D6_STATE_RUNNING(ifp)) {
+		d6 = D6_CSTATE(ifp);
 		if (send_interface1(fd, ifp, d6->reason) == -1)
 			retval = -1;
 	}
@@ -591,12 +616,11 @@ script_runreason(const struct interface 
 {
 	char *argv[2];
 	char **env = NULL, **ep;
-	char *path, *bigenv;
+	char *svcname, *path, *bigenv;
 	size_t e, elen = 0;
 	pid_t pid;
 	int status = 0;
-	const struct fd_list *fd;
-	struct iovec iov[2];
+	struct fd_list *fd;
 
 	if (ifp->options->script &&
 	    (ifp->options->script[0] == '\0' ||
@@ -614,7 +638,9 @@ script_runreason(const struct interface 
 		syslog(LOG_ERR, "%s: make_env: %m", ifp->name);
 		return -1;
 	}
-	ep = realloc(env, sizeof(char *) * (elen + 2));
+	/* Resize for PATH and RC_SVCNAME */
+	svcname = getenv(RC_SVCNAME);
+	ep = realloc(env, sizeof(char *) * (elen + 2 + (svcname ? 1 : 0)));
 	if (ep == NULL) {
 		elen = 0;
 		goto out;
@@ -637,6 +663,15 @@ script_runreason(const struct interface 
 			goto out;
 		}
 	}
+	if (svcname) {
+		e = strlen(RC_SVCNAME) + strlen(svcname) + 2;
+		env[++elen] = malloc(e);
+		if (env[elen] == NULL) {
+			elen = 0;
+			goto out;
+		}
+		snprintf(env[elen], e, "%s=%s", RC_SVCNAME, svcname);
+	}
 	env[++elen] = NULL;
 
 	pid = exec_script(ifp->ctx, argv, env);
@@ -663,26 +698,26 @@ script_runreason(const struct interface 
 
 	/* Send to our listeners */
 	bigenv = NULL;
-	for (fd = ifp->ctx->control_fds; fd != NULL; fd = fd->next) {
-		if (fd->listener) {
-			if (bigenv == NULL) {
-				elen = (size_t)arraytostr((const char *const *)env,
-				    &bigenv);
-				if ((ssize_t)elen == -1) {
-					syslog(LOG_ERR, "%s: arraytostr: %m",
-					    ifp->name);
-					continue;
-				}
-				iov[0].iov_base = &elen;
-				iov[0].iov_len = sizeof(size_t);
-				iov[1].iov_base = bigenv;
-				iov[1].iov_len = elen;
+	status = 0;
+	TAILQ_FOREACH(fd, &ifp->ctx->control_fds, next) {
+		if (!(fd->flags & FD_LISTEN))
+			continue;
+		if (bigenv == NULL) {
+			elen = (size_t)arraytostr((const char *const *)env,
+			    &bigenv);
+			if ((ssize_t)elen == -1) {
+				syslog(LOG_ERR, "%s: arraytostr: %m",
+				    ifp->name);
+				    break;
 			}
-			if (writev(fd->fd, iov, 2) == -1)
-				syslog(LOG_ERR, "%s: writev: %m", __func__);
 		}
+		if (control_queue(fd, bigenv, elen, 1) == -1)
+			syslog(LOG_ERR, "%s: control_queue: %m", __func__);
+		else
+			status = 1;
 	}
-	free(bigenv);
+	if (!status)
+		free(bigenv);
 
 out:
 	/* Cleanup */

Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.9 src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.10
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.9	Sat Jun 14 20:55:37 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf	Tue Sep 16 22:27:04 2014
@@ -1,8 +1,11 @@
-# $NetBSD: dhcpcd.conf,v 1.9 2014/06/14 20:55:37 roy Exp $
+# $NetBSD: dhcpcd.conf,v 1.10 2014/09/16 22:27:04 roy Exp $
 
 # A sample configuration for dhcpcd.
 # See dhcpcd.conf(5) for details.
 
+# Allow users of this group to interact with dhcpcd via the control socket.
+#controlgroup wheel
+
 # Inform the DHCP server of our hostname for DDNS.
 hostname
 

Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.10 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.11
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.10	Wed Jul 30 15:47:32 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in	Tue Sep 16 22:27:04 2014
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd.conf.5.in,v 1.10 2014/07/30 15:47:32 roy Exp $
+.\"     $NetBSD: dhcpcd.conf.5.in,v 1.11 2014/09/16 22:27:04 roy Exp $
 .\" Copyright (c) 2006-2014 Roy Marples
 .\" All rights reserved
 .\"
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd July 14, 2014
+.Dd September 14, 2014
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -72,7 +72,7 @@ Example:
 .D1 static ip_address=192.168.0.10/24
 .It Ic authprotocol Ar protocol Ar algorithm Ar rdm
 Authenticate DHCP messages.
-See the Supported Protocols section.
+See the Supported Authentication Protocols section.
 .It Ic authtoken Ar secretid Ar realm Ar expire Ar key
 Define a shared key for use in authentication.
 .Ar realm can be "" to for use with the
@@ -85,6 +85,18 @@ You can use the keyword
 or
 .Ar 0
 which means the token never expires.
+For the token protocol,
+.Ar secretid
+needs to be 0 and
+.Ar realm
+needs to be "".
+If
+.Nm dhcpcd
+has the error
+.D1 dhcp_auth_encode: Invalid argument
+then it means that
+.Nm dhcpcd
+could not find the correct authentication token in your configuration.
 .It Ic background
 Background immediately.
 This is useful for startup scripts which don't disable link messages for
@@ -128,6 +140,11 @@ to the environment for use in
 For example, you can force the hostname hook to always set the hostname with
 .Ic env
 .Va force_hostname=YES .
+Or set which driver
+.Xr wpa_supplicant 8
+should use with
+.Ic env
+.Va wpa_supplicant_driver=nl80211
 .Pp
 If the hostname is set, will be will set to the FQDN if possible as per
 RFC 4702 section 3.1.
@@ -704,10 +721,10 @@ References an option from the global def
 .D1 embed uint32 enterprise_number
 .D1 # Options defined for the enterprise number
 .D1 encap 1 ipaddress ipaddress
-.Ss Supported protocols
+.Ss Supported Authentication Protocols
 .Bl -tag -width -indent
 .It Ic token
-Sends and expects the token with the secretid 0 in each message.
+Sends and expects the token with the secretid 0 and realm of "" in each message.
 .It Ic delayedrealm
 Delayed Authentication.
 .Nm dhcpcd
@@ -724,7 +741,7 @@ This token is used to authenicate all ot
 .It Ic delayed
 Same as above, but without a realm.
 .El
-.Ss Supported algorithms
+.Ss Supported Authentication Algorithms
 If none specified,
 .Ic hmac-md5
 is the default.
Index: src/external/bsd/dhcpcd/dist/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.10 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.11
--- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.10	Wed Jul 30 15:47:32 2014
+++ src/external/bsd/dhcpcd/dist/ipv6nd.c	Tue Sep 16 22:27:04 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6nd.c,v 1.10 2014/07/30 15:47:32 roy Exp $");
+ __RCSID("$NetBSD: ipv6nd.c,v 1.11 2014/09/16 22:27:04 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -221,12 +221,13 @@ ipv6nd_open(struct dhcpcd_ctx *dctx)
 	    &filt, sizeof(filt)) == -1)
 		goto eexit;
 
-	eloop_event_add(dctx->eloop, ctx->nd_fd, ipv6nd_handledata, dctx);
+	eloop_event_add(dctx->eloop, ctx->nd_fd,
+	    ipv6nd_handledata, dctx, NULL, NULL);
 	return ctx->nd_fd;
 
 eexit:
 	if (ctx->nd_fd != -1) {
-		eloop_event_delete(dctx->eloop, ctx->nd_fd);
+		eloop_event_delete(dctx->eloop, ctx->nd_fd, 0);
 		close(ctx->nd_fd);
 		ctx->nd_fd = -1;
 	}
@@ -469,7 +470,7 @@ ipv6nd_free(struct interface *ifp)
 	}
 	if (ifp == NULL) {
 		if (ctx->ipv6->nd_fd != -1) {
-			eloop_event_delete(ctx->eloop, ctx->ipv6->nd_fd);
+			eloop_event_delete(ctx->eloop, ctx->ipv6->nd_fd, 0);
 			close(ctx->ipv6->nd_fd);
 			ctx->ipv6->nd_fd = -1;
 		}
@@ -582,6 +583,24 @@ ipv6nd_addaddr(void *arg)
 	ipv6_addaddr(ap);
 }
 
+int
+ipv6nd_dadcompleted(const struct interface *ifp)
+{
+	const struct ra *rap;
+	const struct ipv6_addr *ap;
+
+	TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
+		if (rap->iface != ifp)
+			continue;
+		TAILQ_FOREACH(ap, &rap->addrs, next) {
+			if (ap->flags & IPV6_AF_AUTOCONF &&
+			    !(ap->flags & IPV6_AF_DADCOMPLETED))
+			    	return 0;
+		}
+	}
+	return 1;
+}
+
 static void
 ipv6nd_dadcallback(void *arg)
 {
@@ -1457,7 +1476,7 @@ ipv6nd_handledata(void *arg)
 	len = recvmsg(ctx->nd_fd, &ctx->rcvhdr, 0);
 	if (len == -1 || len == 0) {
 		syslog(LOG_ERR, "recvmsg: %m");
-		eloop_event_delete(dhcpcd_ctx->eloop, ctx->nd_fd);
+		eloop_event_delete(dhcpcd_ctx->eloop, ctx->nd_fd, 0);
 		close(ctx->nd_fd);
 		ctx->nd_fd = -1;
 		return;

Index: src/external/bsd/dhcpcd/dist/if-options.c
diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.11 src/external/bsd/dhcpcd/dist/if-options.c:1.12
--- src/external/bsd/dhcpcd/dist/if-options.c:1.11	Wed Jul 30 15:47:32 2014
+++ src/external/bsd/dhcpcd/dist/if-options.c	Tue Sep 16 22:27:04 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if-options.c,v 1.11 2014/07/30 15:47:32 roy Exp $");
+ __RCSID("$NetBSD: if-options.c,v 1.12 2014/09/16 22:27:04 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -1984,6 +1984,7 @@ read_config(struct dhcpcd_ctx *ctx,
 	FILE *fp;
 	char *line, *buf, *option, *p;
 	size_t buflen;
+	ssize_t vlen;
 	int skip = 0, have_profile = 0;
 #ifndef EMBEDDED_CONFIG
 	const char * const *e;
@@ -2019,9 +2020,9 @@ read_config(struct dhcpcd_ctx *ctx,
 	ifo->auth.options |= DHCPCD_AUTH_REQUIRE;
 	TAILQ_INIT(&ifo->auth.tokens);
 
-	ifo->vendorclassid[0] =
-	    (uint8_t)dhcp_vendor((char *)ifo->vendorclassid + 1,
-	    sizeof(ifo->vendorclassid) - 1);
+	vlen = dhcp_vendor((char *)ifo->vendorclassid + 1,
+	            sizeof(ifo->vendorclassid) - 1);
+	ifo->vendorclassid[0] = vlen == -1 ? 0 : (uint8_t)vlen;
 
 	buf = NULL;
 	buflen = 0;

Reply via email to