Module Name:    src
Committed By:   roy
Date:           Mon Jan  1 11:50:56 UTC 2018

Modified Files:
        src/external/bsd/dhcpcd/dist/src: bpf.c dhcp.c dhcpcd.c if-options.c

Log Message:
Sync


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/external/bsd/dhcpcd/dist/src/bpf.c \
    src/external/bsd/dhcpcd/dist/src/if-options.c
cvs rdiff -u -r1.6 -r1.7 src/external/bsd/dhcpcd/dist/src/dhcp.c \
    src/external/bsd/dhcpcd/dist/src/dhcpcd.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/src/bpf.c
diff -u src/external/bsd/dhcpcd/dist/src/bpf.c:1.5 src/external/bsd/dhcpcd/dist/src/bpf.c:1.6
--- src/external/bsd/dhcpcd/dist/src/bpf.c:1.5	Wed Dec  6 10:35:05 2017
+++ src/external/bsd/dhcpcd/dist/src/bpf.c	Mon Jan  1 11:50:56 2018
@@ -1,6 +1,6 @@
 /*
  * dhcpcd: BPF arp and bootp filtering
- * Copyright (c) 2006-2017 Roy Marples <r...@marples.name>
+ * Copyright (c) 2006-2018 Roy Marples <r...@marples.name>
  * All rights reserved
 
  * Redistribution and use in source and binary forms, with or without
Index: src/external/bsd/dhcpcd/dist/src/if-options.c
diff -u src/external/bsd/dhcpcd/dist/src/if-options.c:1.5 src/external/bsd/dhcpcd/dist/src/if-options.c:1.6
--- src/external/bsd/dhcpcd/dist/src/if-options.c:1.5	Tue Sep 19 19:19:21 2017
+++ src/external/bsd/dhcpcd/dist/src/if-options.c	Mon Jan  1 11:50:56 2018
@@ -1,6 +1,6 @@
 /*
  * dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2017 Roy Marples <r...@marples.name>
+ * Copyright (c) 2006-2018 Roy Marples <r...@marples.name>
  * All rights reserved
 
  * Redistribution and use in source and binary forms, with or without

Index: src/external/bsd/dhcpcd/dist/src/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcp.c:1.6 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.7
--- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.6	Wed Dec  6 10:35:05 2017
+++ src/external/bsd/dhcpcd/dist/src/dhcp.c	Mon Jan  1 11:50:56 2018
@@ -1,6 +1,6 @@
 /*
  * dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2017 Roy Marples <r...@marples.name>
+ * Copyright (c) 2006-2018 Roy Marples <r...@marples.name>
  * All rights reserved
 
  * Redistribution and use in source and binary forms, with or without
@@ -777,7 +777,8 @@ make_message(struct bootp **bootpm, cons
 	    (type == DHCP_INFORM || type == DHCP_RELEASE ||
 	    (type == DHCP_REQUEST &&
 	    state->addr->mask.s_addr == lease->mask.s_addr &&
-	    (state->new == NULL || IS_DHCP(state->new)))))
+	    (state->new == NULL || IS_DHCP(state->new)) &&
+	    !(state->added & STATE_FAKE))))
 		bootp->ciaddr = state->addr->addr.s_addr;
 
 	bootp->op = BOOTREQUEST;
@@ -845,6 +846,7 @@ make_message(struct bootp **bootpm, cons
 		if (type == DHCP_DECLINE ||
 		    (type == DHCP_REQUEST &&
 		    (state->addr == NULL ||
+		    state->added & STATE_FAKE ||
 		    lease->addr.s_addr != state->addr->addr.s_addr)))
 		{
 			PUT_ADDR(DHO_IPADDRESS, &lease->addr);
@@ -1587,10 +1589,6 @@ dhcp_openudp(struct interface *ifp)
 	int s;
 	struct sockaddr_in sin;
 	int n;
-	struct dhcp_state *state;
-#ifdef SO_BINDTODEVICE
-	struct ifreq ifr;
-#endif
 
 	if ((s = xsocket(PF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP)) == -1)
 		return -1;
@@ -1598,20 +1596,12 @@ dhcp_openudp(struct interface *ifp)
 	n = 1;
 	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
 		goto eexit;
-#ifdef SO_BINDTODEVICE
-	if (ifp) {
-		memset(&ifr, 0, sizeof(ifr));
-		strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
-		if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, &ifr,
-		    sizeof(ifr)) == -1)
-		        goto eexit;
-	}
-#endif
 	memset(&sin, 0, sizeof(sin));
 	sin.sin_family = AF_INET;
 	sin.sin_port = htons(BOOTPC);
 	if (ifp) {
-		state = D_STATE(ifp);
+		struct dhcp_state *state = D_STATE(ifp);
+
 		if (state->addr)
 			sin.sin_addr.s_addr = state->addr->addr.s_addr;
 	}
@@ -1694,6 +1684,63 @@ dhcp_makeudppacket(size_t *sz, const uin
 	return udpp;
 }
 
+static ssize_t
+dhcp_sendudp(struct interface *ifp, struct in_addr *to, void *data, size_t len)
+{
+	int s;
+	struct msghdr msg;
+	struct sockaddr_in sin;
+	struct iovec iov[1];
+	ssize_t r;
+#ifdef IP_PKTINFO
+	uint8_t cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))];
+	struct cmsghdr *cm;
+	struct in_pktinfo ipi;
+#endif
+
+	iov[0].iov_base = data;
+	iov[0].iov_len = len;
+
+	memset(&sin, 0, sizeof(sin));
+	sin.sin_family = AF_INET;
+	sin.sin_addr = *to;
+	sin.sin_port = htons(BOOTPS);
+#ifdef HAVE_SA_LEN
+	sin.sin_len = sizeof(sin);
+#endif
+
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_name = (void *)&sin;
+	msg.msg_namelen = sizeof(sin);
+	msg.msg_iov = iov;
+	msg.msg_iovlen = 1;
+
+#ifdef IP_PKTINFO
+	/* Set the outbound interface */
+	msg.msg_control = cmsg;
+	msg.msg_controllen = sizeof(cmsg);
+
+	memset(&ipi, 0, sizeof(ipi));
+	ipi.ipi_ifindex = ifp->index;
+	cm = CMSG_FIRSTHDR(&msg);
+	if (cm == NULL) {
+		errno = ESRCH;
+		return -1;
+	}
+	cm->cmsg_level = IPPROTO_IP;
+	cm->cmsg_type = IP_PKTINFO;
+	cm->cmsg_len = CMSG_LEN(sizeof(ipi));
+	memcpy(CMSG_DATA(cm), &ipi, sizeof(ipi));
+#endif
+
+	s = dhcp_openudp(ifp);
+	if (s == -1)
+		return -1;
+	r = sendmsg(s, &msg, 0);
+	close(s);
+	return r;
+}
+
 static void
 send_message(struct interface *ifp, uint8_t type,
     void (*callback)(void *))
@@ -1738,9 +1785,6 @@ send_message(struct interface *ifp, uint
 		    timespec_to_double(&tv));
 	}
 
-	if (dhcp_openbpf(ifp) == -1)
-		return;
-
 	r = make_message(&bootp, ifp, type);
 	if (r == -1)
 		goto fail;
@@ -1750,6 +1794,18 @@ send_message(struct interface *ifp, uint
 		to.s_addr = state->lease.server.s_addr;
 	else
 		to.s_addr = INADDR_ANY;
+
+	/* If unicasting, try and void sending by BPF so we don't
+	 * use a L2 broadcast. */
+	if (to.s_addr != INADDR_ANY && to.s_addr != INADDR_BROADCAST) {
+		if (dhcp_sendudp(ifp, &to, bootp, len) != -1)
+			goto out;
+		logerr("%s: dhcp_sendudp", ifp->name);
+	}
+
+	if (dhcp_openbpf(ifp) == -1)
+		goto out;
+
 	udp = dhcp_makeudppacket(&ulen, (uint8_t *)bootp, len, from, to);
 	if (udp == NULL) {
 		logerr("%s: dhcp_makeudppacket", ifp->name);
@@ -1780,6 +1836,8 @@ send_message(struct interface *ifp, uint
 			callback = NULL;
 		}
 	}
+
+out:
 	free(bootp);
 
 fail:
@@ -1972,7 +2030,7 @@ dhcp_rebind(void *arg)
 	    ifp->name, lease->leasetime - lease->rebindtime);
 	state->state = DHS_REBIND;
 	eloop_timeout_delete(ifp->ctx->eloop, send_renew, ifp);
-	state->lease.server.s_addr = 0;
+	state->lease.server.s_addr = INADDR_ANY;
 	state->interval = 0;
 	ifp->options->options &= ~(DHCPCD_CSR_WARNED |
 	    DHCPCD_ROUTER_HOST_ROUTE_WARNED);
@@ -2327,7 +2385,6 @@ dhcp_arp_address(struct interface *ifp)
 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 
 	state = D_STATE(ifp);
-	state->state = DHS_PROBE;
 	addr.s_addr = state->offer->yiaddr == INADDR_ANY ?
 	    state->offer->ciaddr : state->offer->yiaddr;
 	/* If the interface already has the address configured
@@ -2340,6 +2397,7 @@ dhcp_arp_address(struct interface *ifp)
 
 #ifdef IN_IFF_TENTATIVE
 	if (ia == NULL || ia->addr_flags & IN_IFF_NOTUSEABLE) {
+		state->state = DHS_PROBE;
 		if (ia == NULL) {
 			struct dhcp_lease l;
 
@@ -2355,6 +2413,7 @@ dhcp_arp_address(struct interface *ifp)
 	if (ifp->options->options & DHCPCD_ARP && ia == NULL) {
 		struct dhcp_lease l;
 
+		state->state = DHS_PROBE;
 		get_lease(ifp, &l, state->offer, state->offer_len);
 		loginfox("%s: probing address %s/%d",
 		    ifp->name, inet_ntoa(l.addr), inet_ntocidr(l.mask));
@@ -2570,7 +2629,7 @@ dhcp_reboot(struct interface *ifp)
 #endif
 
 	dhcp_new_xid(ifp);
-	state->lease.server.s_addr = 0;
+	state->lease.server.s_addr = INADDR_ANY;
 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 
 #ifdef IPV4LL
Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.6 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.7
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.6	Wed Dec  6 10:35:05 2017
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c	Mon Jan  1 11:50:56 2018
@@ -1,6 +1,6 @@
 /*
  * dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2017 Roy Marples <r...@marples.name>
+ * Copyright (c) 2006-2018 Roy Marples <r...@marples.name>
  * All rights reserved
 
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  */
 
-const char dhcpcd_copyright[] = "Copyright (c) 2006-2017 Roy Marples";
+const char dhcpcd_copyright[] = "Copyright (c) 2006-2018 Roy Marples";
 
 #include <sys/file.h>
 #include <sys/socket.h>
@@ -438,7 +438,7 @@ configure_interface1(struct interface *i
 		    ~(DHCPCD_IPV6RS | DHCPCD_DHCP6 | DHCPCD_WAITIP6);
 
 	/* We want to disable kernel interface RA as early as possible. */
-	if (ifo->options & DHCPCD_IPV6RS &&
+	if (ifp->active == IF_ACTIVE_USER &&
 	    !(ifp->ctx->options & DHCPCD_DUMPLEASE))
 	{
 		int ra_global, ra_iface;
@@ -975,6 +975,7 @@ int
 dhcpcd_handleinterface(void *arg, int action, const char *ifname)
 {
 	struct dhcpcd_ctx *ctx;
+	struct ifaddrs *ifaddrs;
 	struct if_head *ifs;
 	struct interface *ifp, *iff, *ifn;
 	const char * const argv[] = { ifname };
@@ -998,7 +999,7 @@ dhcpcd_handleinterface(void *arg, int ac
 	}
 
 	i = -1;
-	ifs = if_discover(ctx, -1, UNCONST(argv));
+	ifs = if_discover(ctx, &ifaddrs, -1, UNCONST(argv));
 	if (ifs == NULL) {
 		logerr(__func__);
 		return -1;
@@ -1043,6 +1044,17 @@ dhcpcd_handleinterface(void *arg, int ac
 			dhcpcd_prestartinterface(iff);
 	}
 
+	if_learnaddrs(ctx, ifs, &ifaddrs);
+
+	/* Now we have learned addresses, start the interface */
+	TAILQ_FOREACH_SAFE(ifp, ifs, next, ifn) {
+		if (strcmp(ifp->name, ifname) != 0)
+			continue;
+		iff = if_find(ctx->ifaces, ifp->name);
+		if (action > 0 && iff->active)
+			dhcpcd_prestartinterface(iff);
+	}
+
 	/* Free our discovered list */
 	while ((ifp = TAILQ_FIRST(ifs))) {
 		TAILQ_REMOVE(ifs, ifp, next);
@@ -1403,6 +1415,7 @@ int
 main(int argc, char **argv)
 {
 	struct dhcpcd_ctx ctx;
+	struct ifaddrs *ifaddrs = NULL;
 	struct if_options *ifo;
 	struct interface *ifp;
 	uint16_t family = 0;
@@ -1678,7 +1691,7 @@ printpidfile:
 		if (optind != argc) {
 			/* We need to try and find the interface so we can load
 			 * the hardware address to compare automated IAID */
-			ctx.ifaces = if_discover(&ctx,
+			ctx.ifaces = if_discover(&ctx, &ifaddrs,
 			    argc - optind, argv + optind);
 		} else {
 			if ((ctx.ifaces = malloc(sizeof(*ctx.ifaces))) != NULL)
@@ -1842,7 +1855,7 @@ printpidfile:
 	    (DHCPCD_MASTER | DHCPCD_DEV))
 		dev_start(&ctx);
 
-	ctx.ifaces = if_discover(&ctx, ctx.ifc, ctx.ifv);
+	ctx.ifaces = if_discover(&ctx, &ifaddrs, ctx.ifc, ctx.ifv);
 	if (ctx.ifaces == NULL) {
 		logerr("%s: if_discover", __func__);
 		goto exit_failure;
@@ -1878,6 +1891,7 @@ printpidfile:
 		if (ifp->active)
 			dhcpcd_initstate1(ifp, argc, argv, 0);
 	}
+	if_learnaddrs(&ctx, ctx.ifaces, &ifaddrs);
 
 	if (ctx.options & DHCPCD_BACKGROUND && dhcpcd_daemonise(&ctx))
 		goto exit_success;
@@ -1948,6 +1962,8 @@ exit_failure:
 	i = EXIT_FAILURE;
 
 exit1:
+	if (ifaddrs != NULL)
+		freeifaddrs(ifaddrs);
 	if (control_stop(&ctx) == -1)
 		logerr("%s: control_stop", __func__);
 	/* Free memory and close fd's */

Reply via email to