Module Name: src
Committed By: roy
Date: Fri Jun 17 19:42:32 UTC 2016
Modified Files:
src/external/bsd/dhcpcd/dist: arp.c arp.h bpf-filter.h defs.h
dhcp-common.c dhcp.c dhcp.h dhcp6.c dhcp6.h dhcpcd.c
dhcpcd.conf.5.in dhcpcd.h if-bsd.c if-options.c if.c if.h ipv4.c
ipv4.h ipv4ll.c ipv4ll.h ipv6.c ipv6.h ipv6nd.c script.c
src/external/bsd/dhcpcd/dist/dhcpcd-hooks: 20-resolv.conf 30-hostname
Log Message:
Sync
To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/external/bsd/dhcpcd/dist/arp.c
cvs rdiff -u -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/arp.h \
src/external/bsd/dhcpcd/dist/dhcp6.h
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/bpf-filter.h
cvs rdiff -u -r1.27 -r1.28 src/external/bsd/dhcpcd/dist/defs.h \
src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
cvs rdiff -u -r1.17 -r1.18 src/external/bsd/dhcpcd/dist/dhcp-common.c \
src/external/bsd/dhcpcd/dist/dhcpcd.h src/external/bsd/dhcpcd/dist/ipv4.h
cvs rdiff -u -r1.42 -r1.43 src/external/bsd/dhcpcd/dist/dhcp.c
cvs rdiff -u -r1.16 -r1.17 src/external/bsd/dhcpcd/dist/dhcp.h \
src/external/bsd/dhcpcd/dist/if.h src/external/bsd/dhcpcd/dist/ipv4ll.c
cvs rdiff -u -r1.21 -r1.22 src/external/bsd/dhcpcd/dist/dhcp6.c \
src/external/bsd/dhcpcd/dist/if.c
cvs rdiff -u -r1.34 -r1.35 src/external/bsd/dhcpcd/dist/dhcpcd.c
cvs rdiff -u -r1.30 -r1.31 src/external/bsd/dhcpcd/dist/if-bsd.c
cvs rdiff -u -r1.33 -r1.34 src/external/bsd/dhcpcd/dist/if-options.c
cvs rdiff -u -r1.22 -r1.23 src/external/bsd/dhcpcd/dist/ipv4.c
cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/ipv4ll.h
cvs rdiff -u -r1.18 -r1.19 src/external/bsd/dhcpcd/dist/ipv6.c \
src/external/bsd/dhcpcd/dist/ipv6.h
cvs rdiff -u -r1.29 -r1.30 src/external/bsd/dhcpcd/dist/ipv6nd.c
cvs rdiff -u -r1.26 -r1.27 src/external/bsd/dhcpcd/dist/script.c
cvs rdiff -u -r1.8 -r1.9 \
src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf
cvs rdiff -u -r1.7 -r1.8 \
src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname
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/arp.c
diff -u src/external/bsd/dhcpcd/dist/arp.c:1.19 src/external/bsd/dhcpcd/dist/arp.c:1.20
--- src/external/bsd/dhcpcd/dist/arp.c:1.19 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/arp.c Fri Jun 17 19:42:31 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: arp.c,v 1.19 2016/05/09 10:15:59 roy Exp $");
+ __RCSID("$NetBSD: arp.c,v 1.20 2016/06/17 19:42:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -65,6 +65,7 @@ arp_request(const struct interface *ifp,
struct arphdr ar;
size_t len;
uint8_t *p;
+ const struct iarp_state *state;
ar.ar_hrd = htons(ifp->family);
ar.ar_pro = htons(ETHERTYPE_IP);
@@ -91,7 +92,9 @@ arp_request(const struct interface *ifp,
APPEND(&sip, sizeof(sip));
ZERO(ifp->hwlen);
APPEND(&tip, sizeof(tip));
- return if_sendrawpacket(ifp, ETHERTYPE_ARP, arp_buffer, len);
+
+ state = ARP_CSTATE(ifp);
+ return if_sendraw(ifp, state->fd, ETHERTYPE_ARP, arp_buffer, len);
eexit:
errno = ENOBUFS;
@@ -123,7 +126,7 @@ arp_packet(void *arg)
{
struct interface *ifp = arg;
const struct interface *ifn;
- uint8_t arp_buffer[ARP_LEN];
+ uint8_t buf[ARP_LEN];
struct arphdr ar;
struct arp_msg arm;
ssize_t bytes;
@@ -134,65 +137,62 @@ arp_packet(void *arg)
state = ARP_STATE(ifp);
flags = 0;
- while (!(flags & RAW_EOF)) {
- bytes = if_readrawpacket(ifp, ETHERTYPE_ARP,
- arp_buffer, sizeof(arp_buffer), &flags);
- if (bytes == -1) {
- logger(ifp->ctx, LOG_ERR,
- "%s: arp if_readrawpacket: %m", ifp->name);
- arp_close(ifp);
- return;
- }
- /* We must have a full ARP header */
- if ((size_t)bytes < sizeof(ar))
- continue;
- memcpy(&ar, arp_buffer, sizeof(ar));
- /* Families must match */
- if (ar.ar_hrd != htons(ifp->family))
- continue;
+ bytes = if_readraw(ifp, state->fd, buf, sizeof(buf), &flags);
+ if (bytes == -1) {
+ logger(ifp->ctx, LOG_ERR,
+ "%s: arp if_readrawpacket: %m", ifp->name);
+ arp_close(ifp);
+ return;
+ }
+ /* We must have a full ARP header */
+ if ((size_t)bytes < sizeof(ar))
+ return;
+ memcpy(&ar, buf, sizeof(ar));
+ /* Families must match */
+ if (ar.ar_hrd != htons(ifp->family))
+ return;
#if 0
- /* These checks are enforced in the BPF filter. */
- /* Protocol must be IP. */
- if (ar.ar_pro != htons(ETHERTYPE_IP))
- continue;
- /* Only these types are recognised */
- if (ar.ar_op != htons(ARPOP_REPLY) &&
- ar.ar_op != htons(ARPOP_REQUEST))
- continue;
+ /* These checks are enforced in the BPF filter. */
+ /* Protocol must be IP. */
+ if (ar.ar_pro != htons(ETHERTYPE_IP))
+ continue;
+ /* Only these types are recognised */
+ if (ar.ar_op != htons(ARPOP_REPLY) &&
+ ar.ar_op != htons(ARPOP_REQUEST))
+ continue;
#endif
- if (ar.ar_pln != sizeof(arm.sip.s_addr))
- continue;
+ if (ar.ar_pln != sizeof(arm.sip.s_addr))
+ return;
- /* Get pointers to the hardware addreses */
- hw_s = arp_buffer + sizeof(ar);
- hw_t = hw_s + ar.ar_hln + ar.ar_pln;
- /* Ensure we got all the data */
- if ((hw_t + ar.ar_hln + ar.ar_pln) - arp_buffer > bytes)
- continue;
- /* Ignore messages from ourself */
- TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
- if (ar.ar_hln == ifn->hwlen &&
- memcmp(hw_s, ifn->hwaddr, ifn->hwlen) == 0)
- break;
- }
- if (ifn) {
+ /* Get pointers to the hardware addreses */
+ hw_s = buf + sizeof(ar);
+ hw_t = hw_s + ar.ar_hln + ar.ar_pln;
+ /* Ensure we got all the data */
+ if ((hw_t + ar.ar_hln + ar.ar_pln) - buf > bytes)
+ return;
+ /* Ignore messages from ourself */
+ TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
+ if (ar.ar_hln == ifn->hwlen &&
+ memcmp(hw_s, ifn->hwaddr, ifn->hwlen) == 0)
+ break;
+ }
+ if (ifn) {
#if 0
- logger(ifp->ctx, LOG_DEBUG,
- "%s: ignoring ARP from self", ifp->name);
+ logger(ifp->ctx, LOG_DEBUG,
+ "%s: ignoring ARP from self", ifp->name);
#endif
- continue;
- }
- /* Copy out the HW and IP addresses */
- memcpy(&arm.sha, hw_s, ar.ar_hln);
- memcpy(&arm.sip.s_addr, hw_s + ar.ar_hln, ar.ar_pln);
- memcpy(&arm.tha, hw_t, ar.ar_hln);
- memcpy(&arm.tip.s_addr, hw_t + ar.ar_hln, ar.ar_pln);
-
- /* Run the conflicts */
- TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, astaten) {
- if (astate->conflicted_cb)
- astate->conflicted_cb(astate, &arm);
- }
+ return;
+ }
+ /* Copy out the HW and IP addresses */
+ memcpy(&arm.sha, hw_s, ar.ar_hln);
+ memcpy(&arm.sip.s_addr, hw_s + ar.ar_hln, ar.ar_pln);
+ memcpy(&arm.tha, hw_t, ar.ar_hln);
+ memcpy(&arm.tip.s_addr, hw_t + ar.ar_hln, ar.ar_pln);
+
+ /* Run the conflicts */
+ TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, astaten) {
+ if (astate->conflicted_cb)
+ astate->conflicted_cb(astate, &arm);
}
}
@@ -203,7 +203,7 @@ arp_open(struct interface *ifp)
state = ARP_STATE(ifp);
if (state->fd == -1) {
- state->fd = if_openrawsocket(ifp, ETHERTYPE_ARP);
+ state->fd = if_openraw(ifp, ETHERTYPE_ARP);
if (state->fd == -1) {
logger(ifp->ctx, LOG_ERR, "%s: %s: %m",
__func__, ifp->name);
@@ -391,7 +391,7 @@ arp_free(struct arp_state *astate)
TAILQ_FIRST(&state->arp_states) == NULL)
{
eloop_event_delete(ifp->ctx->eloop, state->fd);
- close(state->fd);
+ if_closeraw(ifp, state->fd);
free(state);
ifp->if_data[IF_DATA_ARP] = NULL;
}
@@ -428,22 +428,21 @@ arp_close(struct interface *ifp)
}
void
-arp_handleifa(int cmd, struct interface *ifp, const struct in_addr *addr,
- int flags)
+arp_handleifa(int cmd, struct ipv4_addr *addr)
{
#ifdef IN_IFF_DUPLICATED
struct iarp_state *state;
struct arp_state *astate, *asn;
- if (cmd != RTM_NEWADDR || (state = ARP_STATE(ifp)) == NULL)
+ if (cmd != RTM_NEWADDR || (state = ARP_STATE(addr->iface)) == NULL)
return;
TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, asn) {
- if (astate->addr.s_addr == addr->s_addr) {
- if (flags & IN_IFF_DUPLICATED) {
+ if (astate->addr.s_addr == addr->addr.s_addr) {
+ if (addr->addr_flags & IN_IFF_DUPLICATED) {
if (astate->conflicted_cb)
astate->conflicted_cb(astate, NULL);
- } else if (!(flags & IN_IFF_NOTUSEABLE)) {
+ } else if (!(addr->addr_flags & IN_IFF_NOTUSEABLE)) {
if (astate->probed_cb)
astate->probed_cb(astate);
}
@@ -451,8 +450,6 @@ arp_handleifa(int cmd, struct interface
}
#else
UNUSED(cmd);
- UNUSED(ifp);
UNUSED(addr);
- UNUSED(flags);
#endif
}
Index: src/external/bsd/dhcpcd/dist/arp.h
diff -u src/external/bsd/dhcpcd/dist/arp.h:1.13 src/external/bsd/dhcpcd/dist/arp.h:1.14
--- src/external/bsd/dhcpcd/dist/arp.h:1.13 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/arp.h Fri Jun 17 19:42:31 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: arp.h,v 1.13 2016/05/09 10:15:59 roy Exp $ */
+/* $NetBSD: arp.h,v 1.14 2016/06/17 19:42:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -43,6 +43,7 @@
#define DEFEND_INTERVAL 10
#include "dhcpcd.h"
+#include "if.h"
struct arp_msg {
uint16_t op;
@@ -91,7 +92,7 @@ void arp_free_but(struct arp_state *);
struct arp_state *arp_find(struct interface *, const struct in_addr *);
void arp_close(struct interface *);
-void arp_handleifa(int, struct interface *, const struct in_addr *, int);
+void arp_handleifa(int, struct ipv4_addr *);
#else
#define arp_close(a) {}
#endif
Index: src/external/bsd/dhcpcd/dist/dhcp6.h
diff -u src/external/bsd/dhcpcd/dist/dhcp6.h:1.13 src/external/bsd/dhcpcd/dist/dhcp6.h:1.14
--- src/external/bsd/dhcpcd/dist/dhcp6.h:1.13 Sun Apr 10 21:00:53 2016
+++ src/external/bsd/dhcpcd/dist/dhcp6.h Fri Jun 17 19:42:31 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp6.h,v 1.13 2016/04/10 21:00:53 roy Exp $ */
+/* $NetBSD: dhcp6.h,v 1.14 2016/06/17 19:42:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -250,6 +250,7 @@ void dhcp6_handleifa(struct dhcpcd_ctx *
const struct in6_addr *addr, int);
int dhcp6_dadcompleted(const struct interface *);
void dhcp6_drop(struct interface *, const char *);
+void dhcp6_dropnondelegates(struct interface *ifp);
int dhcp6_dump(struct interface *);
#else
#define dhcp6_find_delegates(a) {}
Index: src/external/bsd/dhcpcd/dist/bpf-filter.h
diff -u src/external/bsd/dhcpcd/dist/bpf-filter.h:1.10 src/external/bsd/dhcpcd/dist/bpf-filter.h:1.11
--- src/external/bsd/dhcpcd/dist/bpf-filter.h:1.10 Thu Jan 7 20:09:43 2016
+++ src/external/bsd/dhcpcd/dist/bpf-filter.h Fri Jun 17 19:42:31 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: bpf-filter.h,v 1.10 2016/01/07 20:09:43 roy Exp $ */
+/* $NetBSD: bpf-filter.h,v 1.11 2016/06/17 19:42:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -51,7 +51,7 @@ static const struct bpf_insn arp_bpf_fil
/* Otherwise, drop it. */
BPF_STMT(BPF_RET + BPF_K, 0),
};
-#define arp_bpf_filter_len sizeof(arp_bpf_filter) / sizeof(arp_bpf_filter[0])
+#define arp_bpf_filter_len __arraycount(arp_bpf_filter)
/* dhcp_bpf_filter taken from bpf.c in dhcp-3.1.0
@@ -78,7 +78,7 @@ static const struct bpf_insn arp_bpf_fil
* http://www.isc.org/
*/
-static const struct bpf_insn dhcp_bpf_filter [] = {
+static const struct bpf_insn bootp_bpf_filter [] = {
#ifndef BPF_SKIPTYPE
/* Make sure this is an IP packet... */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12),
@@ -94,10 +94,10 @@ static const struct bpf_insn dhcp_bpf_fi
BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14 + BPF_ETHCOOK),
/* Make sure it's to the right port... */
BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16 + BPF_ETHCOOK),
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_CLIENT_PORT, 0, 1),
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTPC, 0, 1),
/* If we passed all the tests, ask for the whole packet. */
BPF_STMT(BPF_RET + BPF_K, BPF_WHOLEPACKET),
/* Otherwise, drop it. */
BPF_STMT(BPF_RET + BPF_K, 0),
};
-#define dhcp_bpf_filter_len sizeof(dhcp_bpf_filter) / sizeof(dhcp_bpf_filter[0])
+#define bootp_bpf_filter_len __arraycount(bootp_bpf_filter)
Index: src/external/bsd/dhcpcd/dist/defs.h
diff -u src/external/bsd/dhcpcd/dist/defs.h:1.27 src/external/bsd/dhcpcd/dist/defs.h:1.28
--- src/external/bsd/dhcpcd/dist/defs.h:1.27 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/defs.h Fri Jun 17 19:42:31 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: defs.h,v 1.27 2016/05/09 10:15:59 roy Exp $ */
+/* $NetBSD: defs.h,v 1.28 2016/06/17 19:42:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -30,7 +30,7 @@
#define CONFIG_H
#define PACKAGE "dhcpcd"
-#define VERSION "6.11.0"
+#define VERSION "6.11.1"
#ifndef CONFIG
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.27 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.28
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.27 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in Fri Jun 17 19:42:31 2016
@@ -1,4 +1,4 @@
-.\" $NetBSD: dhcpcd.conf.5.in,v 1.27 2016/05/09 10:15:59 roy Exp $
+.\" $NetBSD: dhcpcd.conf.5.in,v 1.28 2016/06/17 19:42:31 roy Exp $
.\" Copyright (c) 2006-2016 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 April 21, 2016
+.Dd June 14, 2016
.Dt DHCPCD.CONF 5
.Os
.Sh NAME
@@ -156,7 +156,7 @@ 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
+If the hostname is set, it will be will set to the FQDN if possible as per
RFC 4702 section 3.1.
If the FQDN option is missing,
.Nm dhcpcd
@@ -262,14 +262,14 @@ You can use this option to stop this fro
Fallback to using this profile if DHCP fails.
This allows you to configure a static profile instead of using ZeroConf.
.It Ic hostname Ar name
-Sends
-.Ar hostname
+Sends the hostname
+.Ar name
to the DHCP server so it can be registered in DNS.
If
-.Ar hostname
+.Ar name
is an empty string then the current system hostname is sent.
If
-.Ar hostname
+.Ar name
is a FQDN (ie, contains a .) then it will be encoded as such.
.It Ic hostname_short
Sends the short hostname to the DHCP server instead of the FQDN.
@@ -523,6 +523,12 @@ to handle ND options, but this only work
and
.Ic require
options.
+.Pp
+To see a list of options you can use, call
+.Nm dhcpcd
+with the
+.Fl V , Fl Fl variables
+argument.
.It Ic nooption Ar option
Remove the option from the message before it's processed.
.It Ic require Ar option
Index: src/external/bsd/dhcpcd/dist/dhcp-common.c
diff -u src/external/bsd/dhcpcd/dist/dhcp-common.c:1.17 src/external/bsd/dhcpcd/dist/dhcp-common.c:1.18
--- src/external/bsd/dhcpcd/dist/dhcp-common.c:1.17 Wed Jun 8 01:33:08 2016
+++ src/external/bsd/dhcpcd/dist/dhcp-common.c Fri Jun 17 19:42:31 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp-common.c,v 1.17 2016/06/08 01:33:08 christos Exp $");
+ __RCSID("$NetBSD: dhcp-common.c,v 1.18 2016/06/17 19:42:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -833,7 +833,7 @@ int
dhcp_set_leasefile(char *leasefile, size_t len, int family,
const struct interface *ifp)
{
- char ssid[1 + (IF_SSIDLEN * 4) + 1];
+ char ssid[1 + (IF_SSIDLEN * 4) + 1]; /* - prefix and NUL terminated. */
if (ifp->name[0] == '\0') {
strlcpy(leasefile, ifp->ctx->pidfile, len);
Index: src/external/bsd/dhcpcd/dist/dhcpcd.h
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.h:1.17 src/external/bsd/dhcpcd/dist/dhcpcd.h:1.18
--- src/external/bsd/dhcpcd/dist/dhcpcd.h:1.17 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/dhcpcd.h Fri Jun 17 19:42:31 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcpcd.h,v 1.17 2016/05/09 10:15:59 roy Exp $ */
+/* $NetBSD: dhcpcd.h,v 1.18 2016/06/17 19:42:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -200,7 +200,7 @@ int dhcpcd_handleargs(struct dhcpcd_ctx
void dhcpcd_handlecarrier(struct dhcpcd_ctx *, int, unsigned int, const char *);
int dhcpcd_handleinterface(void *, int, const char *);
void dhcpcd_handlehwaddr(struct dhcpcd_ctx *, const char *,
- const unsigned char *, uint8_t);
+ const void *, uint8_t);
void dhcpcd_dropinterface(struct interface *, const char *);
int dhcpcd_selectprofile(struct interface *, const char *);
Index: src/external/bsd/dhcpcd/dist/ipv4.h
diff -u src/external/bsd/dhcpcd/dist/ipv4.h:1.17 src/external/bsd/dhcpcd/dist/ipv4.h:1.18
--- src/external/bsd/dhcpcd/dist/ipv4.h:1.17 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/ipv4.h Fri Jun 17 19:42:32 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv4.h,v 1.17 2016/05/09 10:15:59 roy Exp $ */
+/* $NetBSD: ipv4.h,v 1.18 2016/06/17 19:42:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -57,7 +57,7 @@
struct rt {
TAILQ_ENTRY(rt) next;
struct in_addr dest;
- struct in_addr net;
+ struct in_addr mask;
struct in_addr gate;
const struct interface *iface;
#ifdef HAVE_ROUTE_METRIC
@@ -73,13 +73,20 @@ TAILQ_HEAD(rt_head, rt);
struct ipv4_addr {
TAILQ_ENTRY(ipv4_addr) next;
struct in_addr addr;
- struct in_addr net;
+ struct in_addr mask;
struct in_addr brd;
struct interface *iface;
int addr_flags;
+ char saddr[INET_ADDRSTRLEN + 3];
};
TAILQ_HEAD(ipv4_addrhead, ipv4_addr);
+#define IPV4_ADDR_EQ(a1, a2) ((a1) && (a1)->addr.s_addr == (a2)->addr.s_addr)
+#define IPV4_MASK1_EQ(a1, a2) ((a1) && (a1)->mask.s_addr == (a2)->mask.s_addr)
+#define IPV4_MASK_EQ(a1, a2) (IPV4_ADDR_EQ(a1, a2) && IPV4_MASK1_EQ(a1, a2))
+#define IPV4_BRD1_EQ(a1, a2) ((a1) && (a1)->brd.s_addr == (a2)->brd.s_addr)
+#define IPV4_BRD_EQ(a1, a2) (IPV4_MASK_EQ(a1, a2) && IPV4_BRD1_EQ(a1, a2))
+
struct ipv4_state {
struct ipv4_addrhead addrs;
struct rt_head routes;
@@ -87,7 +94,7 @@ struct ipv4_state {
#ifdef BSD
/* Buffer for BPF */
size_t buffer_size, buffer_len, buffer_pos;
- uint8_t *buffer;
+ char *buffer;
#endif
};
@@ -99,7 +106,6 @@ struct ipv4_state {
#ifdef INET
struct ipv4_state *ipv4_getstate(struct interface *);
int ipv4_init(struct dhcpcd_ctx *);
-int ipv4_protocol_fd(const struct interface *, uint16_t);
int ipv4_ifcmp(const struct interface *, const struct interface *);
uint8_t inet_ntocidr(struct in_addr);
int inet_cidrtoaddr(int, struct in_addr *);
@@ -110,8 +116,7 @@ int ipv4_hasaddr(const struct interface
#define STATE_FAKE 0x02
void ipv4_buildroutes(struct dhcpcd_ctx *);
-int ipv4_deladdr(struct interface *, const struct in_addr *,
- const struct in_addr *, int);
+int ipv4_deladdr(struct ipv4_addr *, int);
int ipv4_preferanother(struct interface *);
struct ipv4_addr *ipv4_addaddr(struct interface *,
const struct in_addr *, const struct in_addr *, const struct in_addr *);
Index: src/external/bsd/dhcpcd/dist/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.42 src/external/bsd/dhcpcd/dist/dhcp.c:1.43
--- src/external/bsd/dhcpcd/dist/dhcp.c:1.42 Thu May 26 09:09:47 2016
+++ src/external/bsd/dhcpcd/dist/dhcp.c Fri Jun 17 19:42:31 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp.c,v 1.42 2016/05/26 09:09:47 prlw1 Exp $");
+ __RCSID("$NetBSD: dhcp.c,v 1.43 2016/06/17 19:42:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -434,7 +434,7 @@ decode_rfc3442_rt(struct dhcpcd_ctx *ctx
if (ocets > 0) {
memcpy(&rt->dest.s_addr, p, ocets);
p += ocets;
- rt->net.s_addr = htonl(~0U << (32 - cidr));
+ rt->mask.s_addr = htonl(~0U << (32 - cidr));
}
/* Finally, snag the router */
@@ -629,9 +629,9 @@ get_option_routes(struct interface *ifp,
route->gate.s_addr == bootp->yiaddr)
{
route->gate.s_addr = htonl(INADDR_ANY);
- route->net.s_addr = htonl(INADDR_BROADCAST);
+ route->mask.s_addr = htonl(INADDR_BROADCAST);
} else
- route->net.s_addr =
+ route->mask.s_addr =
route_netmask(route->dest.s_addr);
TAILQ_INSERT_TAIL(routes, route, next);
}
@@ -671,7 +671,7 @@ dhcp_get_mtu(const struct interface *ifp
if ((state = D_CSTATE(ifp)) == NULL ||
has_option_mask(ifp->options->nomask, DHO_MTU) ||
get_option_uint16(ifp->ctx, &mtu,
- state->new, state->new_len, DHO_MTU) == -1)
+ state->new, state->new_len, DHO_MTU) == -1)
return 0;
return mtu;
}
@@ -763,18 +763,14 @@ make_message(struct bootp **bootpm, cons
return -1;
*bootpm = bootp;
- if ((type == DHCP_INFORM || type == DHCP_RELEASE ||
- (type == DHCP_REQUEST && state->net.s_addr == lease->net.s_addr &&
+ if (state->addr != NULL &&
+ (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)))))
- {
- /* In-case we haven't actually configured the address yet */
- if (type == DHCP_INFORM && state->addr.s_addr == 0)
- bootp->ciaddr = lease->addr.s_addr;
- else
- bootp->ciaddr = state->addr.s_addr;
- }
+ bootp->ciaddr = state->addr->addr.s_addr;
- bootp->op = DHCP_BOOTREQUEST;
+ bootp->op = BOOTREQUEST;
bootp->htype = (uint8_t)ifp->family;
switch (ifp->family) {
case ARPHRD_ETHER:
@@ -789,7 +785,7 @@ make_message(struct bootp **bootpm, cons
type != DHCP_DECLINE &&
type != DHCP_RELEASE)
bootp->flags = htons(BROADCAST_FLAG);
-#if 0
+
if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
struct timespec tv;
@@ -800,7 +796,7 @@ make_message(struct bootp **bootpm, cons
else
bootp->secs = htons((uint16_t)tv.tv_sec);
}
-#endif
+
bootp->xid = htonl(state->xid);
if (ifo->options & DHCPCD_BOOTP)
@@ -838,7 +834,8 @@ make_message(struct bootp **bootpm, cons
if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
if (type == DHCP_DECLINE ||
(type == DHCP_REQUEST &&
- lease->addr.s_addr != state->addr.s_addr))
+ (state->addr == NULL ||
+ lease->addr.s_addr != state->addr->addr.s_addr)))
{
PUT_ADDR(DHO_IPADDRESS, &lease->addr);
if (lease->server.s_addr)
@@ -1171,7 +1168,12 @@ read_lease(struct interface *ifp, struct
return 0;
}
- if (bytes < sizeof(**bootp)) {
+ /* Ensure the packet is at lease BOOTP sized
+ * with a vendor area of 4 octets
+ * (it should be more, and our read packet enforces this so this
+ * code should not be needed, but of course people could
+ * scribble whatever in the stored lease file. */
+ if (bytes < offsetof(struct bootp, vend) + 4) {
free(lease);
logger(ifp->ctx, LOG_ERR, "%s: truncated lease", __func__);
return 0;
@@ -1429,19 +1431,40 @@ dhcp_env(char **env, const char *prefix,
}
static void
-get_lease(struct dhcpcd_ctx *ctx,
+get_lease(struct interface *ifp,
struct dhcp_lease *lease, const struct bootp *bootp, size_t len)
{
+ struct dhcpcd_ctx *ctx;
assert(bootp != NULL);
memcpy(&lease->cookie, bootp->vend, sizeof(lease->cookie));
/* BOOTP does not set yiaddr for replies when ciaddr is set. */
lease->addr.s_addr = bootp->yiaddr ? bootp->yiaddr : bootp->ciaddr;
- if (get_option_addr(ctx, &lease->net, bootp, len, DHO_SUBNETMASK) == -1)
- lease->net.s_addr = ipv4_getnetmask(lease->addr.s_addr);
- if (get_option_addr(ctx, &lease->brd, bootp, len, DHO_BROADCAST) == -1)
- lease->brd.s_addr = lease->addr.s_addr | ~lease->net.s_addr;
+ ctx = ifp->ctx;
+ if (ifp->options->options & (DHCPCD_STATIC | DHCPCD_INFORM)) {
+ if (ifp->options->req_addr.s_addr != INADDR_ANY) {
+ lease->mask = ifp->options->req_mask;
+ lease->brd.s_addr =
+ lease->addr.s_addr | ~lease->mask.s_addr;
+ } else {
+ const struct ipv4_addr *ia;
+
+ ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
+ assert(ia != NULL);
+ lease->mask = ia->mask;
+ lease->brd = ia->brd;
+ }
+ } else {
+ if (get_option_addr(ctx, &lease->mask, bootp, len,
+ DHO_SUBNETMASK) == -1)
+ lease->mask.s_addr =
+ ipv4_getnetmask(lease->addr.s_addr);
+ if (get_option_addr(ctx, &lease->brd, bootp, len,
+ DHO_BROADCAST) == -1)
+ lease->brd.s_addr =
+ lease->addr.s_addr | ~lease->mask.s_addr;
+ }
if (get_option_uint32(ctx, &lease->leasetime,
bootp, len, DHO_LEASETIME) != 0)
lease->leasetime = ~0U; /* Default to infinite lease */
@@ -1502,7 +1525,7 @@ dhcp_close(struct interface *ifp)
if (state->raw_fd != -1) {
eloop_event_delete(ifp->ctx->eloop, state->raw_fd);
- close(state->raw_fd);
+ if_closeraw(ifp, state->raw_fd);
state->raw_fd = -1;
}
@@ -1542,12 +1565,12 @@ dhcp_openudp(struct interface *ifp)
#endif
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
- sin.sin_port = htons(DHCP_CLIENT_PORT);
+ sin.sin_port = htons(BOOTPC);
if (ifp) {
state = D_STATE(ifp);
- sin.sin_addr.s_addr = state->addr.s_addr;
- } else
- state = NULL; /* appease gcc */
+ if (state->addr)
+ sin.sin_addr.s_addr = state->addr->addr.s_addr;
+ }
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
goto eexit;
@@ -1610,8 +1633,8 @@ dhcp_makeudppacket(size_t *sz, const uin
else
ip->ip_dst.s_addr = dest.s_addr;
- udp->uh_sport = htons(DHCP_CLIENT_PORT);
- udp->uh_dport = htons(DHCP_SERVER_PORT);
+ udp->uh_sport = htons(BOOTPC);
+ udp->uh_dport = htons(BOOTPS);
udp->uh_ulen = htons((uint16_t)(sizeof(*udp) + length));
ip->ip_len = udp->uh_ulen;
udp->uh_sum = checksum(udpp, sizeof(*ip) + sizeof(*udp) + length);
@@ -1638,7 +1661,7 @@ send_message(struct interface *ifp, uint
size_t len;
ssize_t r;
struct in_addr from, to;
- in_addr_t a = INADDR_ANY;
+ struct ipv4_addr *iap;
struct timespec tv;
int s;
#ifdef IN_IFF_NOTUSEABLE
@@ -1681,11 +1704,11 @@ send_message(struct interface *ifp, uint
if (dhcp_open(ifp) == -1)
return;
+ iap = state->addr;
if (state->added && !(state->added & STATE_FAKE) &&
- state->addr.s_addr != INADDR_ANY &&
- state->new != NULL &&
+ state->addr != NULL && state->new != NULL &&
#ifdef IN_IFF_NOTUSEABLE
- ((ia = ipv4_iffindaddr(ifp, &state->addr, NULL)) &&
+ ((ia = ipv4_iffindaddr(ifp, &state->addr->addr, NULL)) &&
!(ia->addr_flags & IN_IFF_NOTUSEABLE)) &&
#endif
(state->lease.server.s_addr ||
@@ -1698,14 +1721,12 @@ send_message(struct interface *ifp, uint
logger(ifp->ctx, LOG_ERR,
"%s: dhcp_openudp: %m", ifp->name);
/* We cannot renew */
- a = state->addr.s_addr;
- state->addr.s_addr = INADDR_ANY;
+ state->addr = NULL;
}
}
r = make_message(&bootp, ifp, type);
- if (a != INADDR_ANY)
- state->addr.s_addr = a;
+ state->addr = iap;
if (r == -1)
goto fail;
len = (size_t)r;
@@ -1720,7 +1741,7 @@ send_message(struct interface *ifp, uint
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);
+ sin.sin_port = htons(BOOTPS);
r = sendto(s, (uint8_t *)bootp, len, 0,
(struct sockaddr *)&sin, sizeof(sin));
if (r == -1)
@@ -1730,12 +1751,12 @@ send_message(struct interface *ifp, uint
size_t ulen;
r = 0;
- udp = dhcp_makeudppacket(&ulen, (uint8_t *)bootp, len, from, to);
+ udp = dhcp_makeudppacket(&ulen, (uint8_t *)bootp, len, from,to);
if (udp == NULL) {
logger(ifp->ctx, LOG_ERR, "dhcp_makeudppacket: %m");
} else {
- r = if_sendrawpacket(ifp, ETHERTYPE_IP,
- (uint8_t *)udp, ulen);
+ r = if_sendraw(ifp, state->raw_fd,
+ ETHERTYPE_IP, (uint8_t *)udp, ulen);
free(udp);
}
/* If we failed to send a raw packet this normally means
@@ -1745,7 +1766,7 @@ send_message(struct interface *ifp, uint
* stopping the interface. */
if (r == -1) {
logger(ifp->ctx, LOG_ERR,
- "%s: if_sendrawpacket: %m", ifp->name);
+ "%s: if_sendraw: %m", ifp->name);
switch(errno) {
case ENETDOWN:
case ENETRESET:
@@ -1994,7 +2015,7 @@ dhcp_arp_probed(struct arp_state *astate
len = state->new_len;
state->new = state->offer;
state->new_len = state->offer_len;
- get_lease(astate->iface->ctx, &state->lease,
+ get_lease(astate->iface, &state->lease,
state->new, state->new_len);
ipv4_applyaddr(astate->iface);
state->new = bootp;
@@ -2073,9 +2094,8 @@ dhcp_arp_conflicted(struct arp_state *as
!state->lease.frominfo)
dhcp_decline(ifp);
#ifdef IN_IFF_DUPLICATED
- ia = ipv4_iffindaddr(ifp, &astate->addr, NULL);
- if (ia)
- ipv4_deladdr(ifp, &ia->addr, &ia->net, 1);
+ if ((ia = ipv4_iffindaddr(ifp, &astate->addr, NULL)) != NULL)
+ ipv4_deladdr(ia, 1);
#endif
arp_free(astate);
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
@@ -2085,11 +2105,12 @@ dhcp_arp_conflicted(struct arp_state *as
}
/* Bound address */
- if (amsg &&
- (amsg->sip.s_addr == state->addr.s_addr ||
- (amsg->sip.s_addr == 0 && amsg->tip.s_addr == state->addr.s_addr)))
+ if (amsg && state->addr &&
+ (amsg->sip.s_addr == state->addr->addr.s_addr ||
+ (amsg->sip.s_addr == 0 &&
+ amsg->tip.s_addr == state->addr->addr.s_addr)))
{
- astate->failed = state->addr;
+ astate->failed = state->addr->addr;
arp_report_conflicted(astate, amsg);
if (state->state == DHS_BOUND) {
/* For now, just report the duplicated address */
@@ -2120,11 +2141,11 @@ dhcp_bind(struct interface *ifp)
state->offer = NULL;
state->offer_len = 0;
}
- get_lease(ifp->ctx, lease, state->new, state->new_len);
+ get_lease(ifp, lease, state->new, state->new_len);
if (ifo->options & DHCPCD_STATIC) {
logger(ifp->ctx, LOG_INFO, "%s: using static address %s/%d",
ifp->name, inet_ntoa(lease->addr),
- inet_ntocidr(lease->net));
+ inet_ntocidr(lease->mask));
lease->leasetime = ~0U;
state->reason = "STATIC";
} else if (ifo->options & DHCPCD_INFORM) {
@@ -2171,7 +2192,8 @@ dhcp_bind(struct interface *ifp)
ifp->name, lease->renewaltime);
}
logger(ifp->ctx,
- lease->addr.s_addr == state->addr.s_addr &&
+ state->addr &&
+ lease->addr.s_addr == state->addr->addr.s_addr &&
!(state->added & STATE_FAKE) ?
LOG_DEBUG : LOG_INFO,
"%s: leased %s for %"PRIu32" seconds", ifp->name,
@@ -2227,6 +2249,9 @@ dhcp_lastlease(void *arg)
struct interface *ifp = arg;
struct dhcp_state *state = D_STATE(ifp);
+ logger(ifp->ctx, LOG_INFO,
+ "%s: timed out contacting a DHCP server, using last lease",
+ ifp->name);
dhcp_bind(ifp);
/* If we forked, stop here. */
if (ifp->ctx->options & DHCPCD_FORKED)
@@ -2256,10 +2281,10 @@ dhcp_message_new(struct bootp **bootp,
p = (*bootp)->vend;
cookie = htonl(MAGIC_COOKIE);
- memcpy(&cookie, p, sizeof(cookie));
+ memcpy(p, &cookie, sizeof(cookie));
p += sizeof(cookie);
- if (mask && mask->s_addr != INADDR_ANY) {
+ if (mask->s_addr != INADDR_ANY) {
*p++ = DHO_SUBNETMASK;
*p++ = sizeof(mask->s_addr);
memcpy(p, &mask->s_addr, sizeof(mask->s_addr));
@@ -2297,9 +2322,9 @@ dhcp_arp_address(struct interface *ifp)
if (ia == NULL) {
struct dhcp_lease l;
- get_lease(ifp->ctx, &l, state->offer, state->offer_len);
+ get_lease(ifp, &l, state->offer, state->offer_len);
/* Add the address now, let the kernel handle DAD. */
- ipv4_addaddr(ifp, &l.addr, &l.net, &l.brd);
+ ipv4_addaddr(ifp, &l.addr, &l.mask, &l.brd);
} else
logger(ifp->ctx, LOG_INFO, "%s: waiting for DAD on %s",
ifp->name, inet_ntoa(addr));
@@ -2309,9 +2334,9 @@ dhcp_arp_address(struct interface *ifp)
if (ifp->options->options & DHCPCD_ARP && ia == NULL) {
struct dhcp_lease l;
- get_lease(ifp->ctx, &l, state->offer, state->offer_len);
+ get_lease(ifp, &l, state->offer, state->offer_len);
logger(ifp->ctx, LOG_INFO, "%s: probing address %s/%d",
- ifp->name, inet_ntoa(l.addr), inet_ntocidr(l.net));
+ ifp->name, inet_ntoa(l.addr), inet_ntocidr(l.mask));
if ((astate = arp_new(ifp, &addr)) != NULL) {
astate->probed_cb = dhcp_arp_probed;
astate->conflicted_cb = dhcp_arp_conflicted;
@@ -2358,7 +2383,7 @@ dhcp_static(struct interface *ifp)
state->offer_len = dhcp_message_new(&state->offer,
ia ? &ia->addr : &ifo->req_addr,
- ia ? &ia->net : &ifo->req_mask);
+ ia ? &ia->mask : &ifo->req_mask);
if (state->offer_len)
dhcp_arp_bind(ifp);
}
@@ -2398,6 +2423,10 @@ dhcp_inform(struct interface *ifp)
ifp->name);
return;
}
+ ia = ipv4_iffindaddr(ifp, &ifo->req_addr, NULL);
+ if (ia != NULL)
+ /* Netmask must be different, delete it. */
+ ipv4_deladdr(ia, 1);
state->offer_len = dhcp_message_new(&state->offer,
&ifo->req_addr, &ifo->req_mask);
if (dhcp_arp_address(ifp) == 0)
@@ -2408,11 +2437,12 @@ dhcp_inform(struct interface *ifp)
}
}
- state->offer_len = dhcp_message_new(&state->offer, &ia->addr, &ia->net);
+ state->addr = ia;
+ state->offer_len = dhcp_message_new(&state->offer,
+ &ia->addr, &ia->mask);
if (state->offer_len) {
state->xid = dhcp_xid(ifp);
- get_lease(ifp->ctx, &state->lease,
- state->offer, state->offer_len);
+ get_lease(ifp, &state->lease, state->offer, state->offer_len);
send_inform(ifp);
}
}
@@ -2427,7 +2457,8 @@ dhcp_reboot_newopts(struct interface *if
return;
ifo = ifp->options;
if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) &&
- state->addr.s_addr != ifo->req_addr.s_addr) ||
+ (state->addr == NULL ||
+ state->addr->addr.s_addr != ifo->req_addr.s_addr)) ||
(oldopts & (DHCPCD_INFORM | DHCPCD_STATIC) &&
!(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))))
{
@@ -2672,6 +2703,12 @@ dhcp_handledhcp(struct interface *ifp, s
#define LOGDHCP(l, m) \
log_dhcp((l), (m), ifp, bootp, bootp_len, from, 1)
+ if (bootp->op != BOOTREPLY) {
+ logger(ifp->ctx, LOG_DEBUG, "%s: op (%d) is not BOOTREPLY",
+ ifp->name, bootp->op);
+ return;
+ }
+
/* Ensure packet is for us */
if (ifp->hwlen <= sizeof(bootp->chaddr) &&
memcmp(bootp->chaddr, ifp->hwaddr, ifp->hwlen))
@@ -2901,7 +2938,7 @@ dhcp_handledhcp(struct interface *ifp, s
LOGDHCP(LOG_WARNING, "declined duplicate address");
if (type)
dhcp_decline(ifp);
- ipv4_deladdr(ifp, &ia->addr, &ia->net, 0);
+ ipv4_deladdr(ia, 0);
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
eloop_timeout_add_sec(ifp->ctx->eloop,
DHCP_RAND_MAX, dhcp_discover, ifp);
@@ -3103,69 +3140,59 @@ dhcp_handlepacket(void *arg)
/* Need this API due to BPF */
flags = 0;
bootp = NULL;
- while (!(flags & RAW_EOF)) {
- bytes = (size_t)if_readrawpacket(ifp, ETHERTYPE_IP,
- buf, sizeof(buf), &flags);
- if ((ssize_t)bytes == -1) {
- logger(ifp->ctx, LOG_ERR,
- "%s: dhcp if_readrawpacket: %m", ifp->name);
- dhcp_close(ifp);
- arp_close(ifp);
- break;
- }
- if (valid_udp_packet(buf, bytes,
- &from, flags & RAW_PARTIALCSUM) == -1)
- {
- logger(ifp->ctx, LOG_ERR,
- "%s: invalid UDP packet from %s",
- ifp->name, inet_ntoa(from));
- continue;
- }
- i = whitelisted_ip(ifp->options, from.s_addr);
- if (i == 0) {
- logger(ifp->ctx, LOG_WARNING,
- "%s: non whitelisted DHCP packet from %s",
- ifp->name, inet_ntoa(from));
- continue;
- } else if (i != 1 &&
- blacklisted_ip(ifp->options, from.s_addr) == 1)
- {
- logger(ifp->ctx, LOG_WARNING,
- "%s: blacklisted DHCP packet from %s",
- ifp->name, inet_ntoa(from));
- continue;
- }
- if (ifp->flags & IFF_POINTOPOINT &&
- state->brd.s_addr != from.s_addr)
- {
- logger(ifp->ctx, LOG_WARNING,
- "%s: server %s is not destination",
- ifp->name, inet_ntoa(from));
- }
- /*
- * DHCP has a variable option area rather than a fixed
- * vendor area.
- * Because DHCP uses the BOOTP protocol it should
- * still send BOOTP sized packets to be RFC compliant.
- * However some servers send a truncated vendor area.
- * dhcpcd can work fine without the vendor area being sent.
- */
- bytes = get_udp_data(&bootp, buf);
- if (bytes < offsetof(struct bootp, vend)) {
- logger(ifp->ctx, LOG_ERR,
- "%s: truncated packet (%zu) from %s",
- ifp->name, bytes, inet_ntoa(from));
- continue;
- }
- /* But to make our IS_DHCP macro easy, ensure the vendor
- * area has at least 4 octets. */
- while (bytes < offsetof(struct bootp, vend) + 4)
- bootp[bytes++] = '\0';
-
- dhcp_handledhcp(ifp, (struct bootp *)bootp, bytes, &from);
- if (state->raw_fd == -1)
- break;
+ bytes = (size_t)if_readraw(ifp, state->raw_fd,buf, sizeof(buf), &flags);
+ if ((ssize_t)bytes == -1) {
+ logger(ifp->ctx, LOG_ERR,
+ "%s: dhcp if_readrawpacket: %m", ifp->name);
+ dhcp_close(ifp);
+ arp_close(ifp);
+ return;
+ }
+ if (valid_udp_packet(buf, bytes, &from, flags & RAW_PARTIALCSUM) == -1)
+ {
+ logger(ifp->ctx, LOG_ERR, "%s: invalid UDP packet from %s",
+ ifp->name, inet_ntoa(from));
+ return;
+ }
+ i = whitelisted_ip(ifp->options, from.s_addr);
+ if (i == 0) {
+ logger(ifp->ctx, LOG_WARNING,
+ "%s: non whitelisted DHCP packet from %s",
+ ifp->name, inet_ntoa(from));
+ return;
+ } else if (i != 1 && blacklisted_ip(ifp->options, from.s_addr) == 1) {
+ logger(ifp->ctx, LOG_WARNING,
+ "%s: blacklisted DHCP packet from %s",
+ ifp->name, inet_ntoa(from));
+ return;
+ }
+ if (ifp->flags & IFF_POINTOPOINT &&
+ (state->addr == NULL || state->addr->brd.s_addr != from.s_addr))
+ {
+ logger(ifp->ctx, LOG_WARNING,
+ "%s: server %s is not destination",
+ ifp->name, inet_ntoa(from));
+ }
+ /*
+ * DHCP has a variable option area rather than a fixed vendor area.
+ * Because DHCP uses the BOOTP protocol it should still send BOOTP
+ * sized packets to be RFC compliant.
+ * However some servers send a truncated vendor area.
+ * dhcpcd can work fine without the vendor area being sent.
+ */
+ bytes = get_udp_data(&bootp, buf);
+ if (bytes < offsetof(struct bootp, vend)) {
+ logger(ifp->ctx, LOG_ERR,
+ "%s: truncated packet (%zu) from %s",
+ ifp->name, bytes, inet_ntoa(from));
+ return;
}
+ /* But to make our IS_DHCP macro easy, ensure the vendor
+ * area has at least 4 octets. */
+ while (bytes < offsetof(struct bootp, vend) + 4)
+ bootp[bytes++] = '\0';
+
+ dhcp_handledhcp(ifp, (struct bootp *)bootp, bytes, &from);
}
static void
@@ -3193,7 +3220,7 @@ dhcp_open(struct interface *ifp)
state = D_STATE(ifp);
if (state->raw_fd == -1) {
- state->raw_fd = if_openrawsocket(ifp, ETHERTYPE_IP);
+ state->raw_fd = if_openraw(ifp, ETHERTYPE_IP);
if (state->raw_fd == -1) {
if (errno == ENOENT) {
logger(ifp->ctx, LOG_ERR,
@@ -3293,7 +3320,7 @@ dhcp_init(struct interface *ifp)
state->raw_fd = -1;
/* Now is a good time to find IPv4 routes */
- if_initrt(ifp);
+ if_initrt(ifp->ctx);
}
state->state = DHS_INIT;
@@ -3455,11 +3482,13 @@ dhcp_start1(void *arg)
}
}
if (state->offer) {
- get_lease(ifp->ctx, &state->lease,
- state->offer, state->offer_len);
+ struct ipv4_addr *ia;
+
+ get_lease(ifp, &state->lease, state->offer, state->offer_len);
state->lease.frominfo = 1;
if (state->new == NULL &&
- ipv4_iffindaddr(ifp, &state->lease.addr, &state->lease.net))
+ (ia = ipv4_iffindaddr(ifp,
+ &state->lease.addr, &state->lease.mask)) != NULL)
{
/* We still have the IP address from the last lease.
* Fake add the address and routes from it so the lease
@@ -3468,19 +3497,17 @@ dhcp_start1(void *arg)
if (state->new) {
memcpy(state->new,
state->offer, state->offer_len);
- state->addr = state->lease.addr;
- state->net = state->lease.net;
+ state->new_len = state->offer_len;
+ state->addr = ia;
state->added |= STATE_ADDED | STATE_FAKE;
ipv4_buildroutes(ifp->ctx);
} else
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
}
if (!IS_DHCP(state->offer)) {
- if (state->offer->yiaddr == state->addr.s_addr) {
- free(state->offer);
- state->offer = NULL;
- state->offer_len = 0;
- }
+ free(state->offer);
+ state->offer = NULL;
+ state->offer_len = 0;
} else if (!(ifo->options & DHCPCD_LASTLEASE_EXTEND) &&
state->lease.leasetime != ~0U &&
stat(state->leasefile, &st) == 0)
@@ -3543,6 +3570,13 @@ dhcp_start(struct interface *ifp)
if (!(ifp->options->options & DHCPCD_IPV4))
return;
+ /* If we haven't been given a netmask for our requested address,
+ * set it now. */
+ if (ifp->options->req_addr.s_addr != INADDR_ANY &&
+ ifp->options->req_mask.s_addr == INADDR_ANY)
+ ifp->options->req_mask.s_addr =
+ ipv4_getnetmask(ifp->options->req_addr.s_addr);
+
/* If we haven't specified a ClientID and our hardware address
* length is greater than BOOTP CHADDR then we enforce a ClientID
* of the hardware address family and the hardware address.
@@ -3594,29 +3628,22 @@ dhcp_abort(struct interface *ifp)
}
void
-dhcp_handleifa(int cmd, struct interface *ifp,
- const struct in_addr *addr,
- const struct in_addr *net,
- const struct in_addr *brd,
- int flags)
+dhcp_handleifa(int cmd, struct ipv4_addr *ia)
{
+ struct interface *ifp;
struct dhcp_state *state;
struct if_options *ifo;
uint8_t i;
+ ifp = ia->iface;
state = D_STATE(ifp);
if (state == NULL)
return;
if (cmd == RTM_DELADDR) {
- if (state->addr.s_addr == addr->s_addr &&
- state->net.s_addr == net->s_addr &&
- state->brd.s_addr == brd->s_addr)
- {
+ if (IPV4_BRD_EQ(state->addr, ia)) {
logger(ifp->ctx, LOG_INFO,
- "%s: removing IP address %s/%d",
- ifp->name, inet_ntoa(state->addr),
- inet_ntocidr(state->net));
+ "%s: removing IP address %s", ifp->name, ia->saddr);
dhcp_drop(ifp, "EXPIRE");
}
return;
@@ -3626,10 +3653,8 @@ dhcp_handleifa(int cmd, struct interface
return;
#ifdef IN_IFF_NOTUSEABLE
- if (flags & IN_IFF_NOTUSEABLE)
+ if (ia->addr_flags & IN_IFF_NOTUSEABLE)
return;
-#else
- UNUSED(flags);
#endif
ifo = ifp->options;
@@ -3646,14 +3671,13 @@ dhcp_handleifa(int cmd, struct interface
free(state->old);
state->old = state->new;
- state->new_len = dhcp_message_new(&state->new, addr, net);
+ state->new_len = dhcp_message_new(&state->new, &ia->addr, &ia->mask);
if (state->new == NULL)
return;
- state->brd = *brd;
if (ifp->flags & IFF_POINTOPOINT) {
for (i = 1; i < 255; i++)
if (i != DHO_ROUTER && has_option_mask(ifo->dstmask,i))
- dhcp_message_add_addr(state->new, i, *brd);
+ dhcp_message_add_addr(state->new, i, ia->brd);
}
state->reason = "STATIC";
ipv4_buildroutes(ifp->ctx);
@@ -3661,9 +3685,8 @@ dhcp_handleifa(int cmd, struct interface
if (ifo->options & DHCPCD_INFORM) {
state->state = DHS_INFORM;
state->xid = dhcp_xid(ifp);
- state->lease.server = *brd;
- state->addr = *addr;
- state->net = *net;
+ state->lease.server.s_addr = INADDR_ANY;
+ state->addr = ia;
dhcp_inform(ifp);
}
}
Index: src/external/bsd/dhcpcd/dist/dhcp.h
diff -u src/external/bsd/dhcpcd/dist/dhcp.h:1.16 src/external/bsd/dhcpcd/dist/dhcp.h:1.17
--- src/external/bsd/dhcpcd/dist/dhcp.h:1.16 Thu May 26 09:09:47 2016
+++ src/external/bsd/dhcpcd/dist/dhcp.h Fri Jun 17 19:42:31 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp.h,v 1.16 2016/05/26 09:09:47 prlw1 Exp $ */
+/* $NetBSD: dhcp.h,v 1.17 2016/06/17 19:42:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -40,27 +40,27 @@
#include "auth.h"
#include "dhcp-common.h"
-/* UDP port numbers for DHCP */
-#define DHCP_SERVER_PORT 67
-#define DHCP_CLIENT_PORT 68
-
-#define MAGIC_COOKIE 0x63825363
-#define BROADCAST_FLAG 0x8000
-
-/* DHCP message OP code */
-#define DHCP_BOOTREQUEST 1
-#define DHCP_BOOTREPLY 2
+/* UDP port numbers for BOOTP */
+#define BOOTPS 67
+#define BOOTPC 68
+
+#define MAGIC_COOKIE 0x63825363
+#define BROADCAST_FLAG 0x8000
+
+/* BOOTP message OP code */
+#define BOOTREQUEST 1
+#define BOOTREPLY 2
/* DHCP message type */
-#define DHCP_DISCOVER 1
-#define DHCP_OFFER 2
-#define DHCP_REQUEST 3
-#define DHCP_DECLINE 4
-#define DHCP_ACK 5
-#define DHCP_NAK 6
-#define DHCP_RELEASE 7
-#define DHCP_INFORM 8
-#define DHCP_FORCERENEW 9
+#define DHCP_DISCOVER 1
+#define DHCP_OFFER 2
+#define DHCP_REQUEST 3
+#define DHCP_DECLINE 4
+#define DHCP_ACK 5
+#define DHCP_NAK 6
+#define DHCP_RELEASE 7
+#define DHCP_INFORM 8
+#define DHCP_FORCERENEW 9
/* Constants taken from RFC 2131. */
#define T1 0.5
@@ -173,7 +173,7 @@ struct bootp {
struct dhcp_lease {
struct in_addr addr;
- struct in_addr net;
+ struct in_addr mask;
struct in_addr brd;
uint32_t leasetime;
uint32_t renewaltime;
@@ -215,9 +215,7 @@ struct dhcp_state {
int socket;
int raw_fd;
- struct in_addr addr;
- struct in_addr net;
- struct in_addr brd;
+ struct ipv4_addr *addr;
uint8_t added;
char leasefile[sizeof(LEASEFILE) + IF_NAMESIZE + (IF_SSIDLEN * 4)];
@@ -253,10 +251,7 @@ struct rt_head *dhcp_get_routes(struct i
ssize_t dhcp_env(char **, const char *, const struct bootp *, size_t,
const struct interface *);
-void dhcp_handleifa(int, struct interface *,
- const struct in_addr *, const struct in_addr *, const struct in_addr *,
- int);
-
+void dhcp_handleifa(int, struct ipv4_addr *);
void dhcp_drop(struct interface *, const char *);
void dhcp_start(struct interface *);
void dhcp_abort(struct interface *);
Index: src/external/bsd/dhcpcd/dist/if.h
diff -u src/external/bsd/dhcpcd/dist/if.h:1.16 src/external/bsd/dhcpcd/dist/if.h:1.17
--- src/external/bsd/dhcpcd/dist/if.h:1.16 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/if.h Fri Jun 17 19:42:32 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.16 2016/05/09 10:15:59 roy Exp $ */
+/* $NetBSD: if.h,v 1.17 2016/06/17 19:42:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -82,13 +82,14 @@
((addr & IN_CLASSB_NET) == 0xc0a80000))
#endif
-#define RAW_EOF 1 << 0
-#define RAW_PARTIALCSUM 2 << 0
+#define RAW_PARTIALCSUM 1 << 0
#ifdef __sun
-/* platform does not supply AF_LINK with getifaddrs. */
+/* Solaris getifaddrs is very un-suitable for dhcpcd.
+ * See if-sun.c for details why. */
struct ifaddrs;
int if_getifaddrs(struct ifaddrs **);
+#define getifaddrs if_getifaddrs
#else
#define GETIFADDRS_AFLINK
#endif
@@ -114,7 +115,7 @@ int if_opensockets(struct dhcpcd_ctx *);
int if_opensockets_os(struct dhcpcd_ctx *);
void if_closesockets(struct dhcpcd_ctx *);
void if_closesockets_os(struct dhcpcd_ctx *);
-int if_managelink(struct dhcpcd_ctx *);
+int if_handlelink(struct dhcpcd_ctx *);
/* dhcpcd uses the same routing flags as BSD.
* If the platform doesn't use these flags,
@@ -141,23 +142,17 @@ int if_managelink(struct dhcpcd_ctx *);
#ifdef INET
extern const char *if_pfname;
-int if_openrawsocket(struct interface *, uint16_t);
-ssize_t if_sendrawpacket(const struct interface *,
- uint16_t, const void *, size_t);
-ssize_t if_readrawpacket(struct interface *, uint16_t, void *, size_t, int *);
-
-int if_address(const struct interface *,
- const struct in_addr *, const struct in_addr *,
- const struct in_addr *, int);
-#define if_addaddress(ifp, addr, net, brd) \
- if_address(ifp, addr, net, brd, 1)
-#define if_deladdress(ifp, addr, net) \
- if_address(ifp, addr, net, NULL, -1)
+int if_openraw(struct interface *, uint16_t);
+ssize_t if_sendraw(const struct interface *, int, uint16_t,
+ const void *, size_t);
+ssize_t if_readraw(struct interface *, int, void *, size_t, int *);
+void if_closeraw(struct interface *, int);
+int if_address(unsigned char, const struct ipv4_addr *);
int if_addrflags(const struct in_addr *, const struct interface *);
int if_route(unsigned char, const struct rt *rt);
-int if_initrt(struct interface *);
+int if_initrt(struct dhcpcd_ctx *);
#endif
#ifdef INET6
@@ -170,15 +165,12 @@ int ip6_temp_valid_lifetime(const char *
#define ip6_use_tempaddr(a) (0)
#endif
-int if_address6(const struct ipv6_addr *, int);
-#define if_addaddress6(a) if_address6(a, 1)
-#define if_deladdress6(a) if_address6(a, -1)
-
+int if_address6(unsigned char, const struct ipv6_addr *);
int if_addrflags6(const struct in6_addr *, const struct interface *);
int if_getlifetime6(struct ipv6_addr *);
int if_route6(unsigned char, const struct rt6 *rt);
-int if_initrt6(struct interface *);
+int if_initrt6(struct dhcpcd_ctx *);
#else
#define if_checkipv6(a, b, c) (-1)
#endif
Index: src/external/bsd/dhcpcd/dist/ipv4ll.c
diff -u src/external/bsd/dhcpcd/dist/ipv4ll.c:1.16 src/external/bsd/dhcpcd/dist/ipv4ll.c:1.17
--- src/external/bsd/dhcpcd/dist/ipv4ll.c:1.16 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/ipv4ll.c Fri Jun 17 19:42:32 2016
@@ -1,9 +1,9 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4ll.c,v 1.16 2016/05/09 10:15:59 roy Exp $");
+ __RCSID("$NetBSD: ipv4ll.c,v 1.17 2016/06/17 19:42:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2015 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2016 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -48,11 +48,15 @@
#include "ipv4ll.h"
#include "script.h"
-const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) };
-const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BRDC) };
+static const struct in_addr inaddr_llmask = {
+ .s_addr = HTONL(LINKLOCAL_MASK)
+};
+static const struct in_addr inaddr_llbcast = {
+ .s_addr = HTONL(LINKLOCAL_BCAST)
+};
static in_addr_t
-ipv4ll_pick_addr(const struct arp_state *astate)
+ipv4ll_pickaddr(struct arp_state *astate)
{
struct in_addr addr;
struct ipv4ll_state *istate;
@@ -78,8 +82,7 @@ ipv4ll_pick_addr(const struct arp_state
} while (ipv4_findaddr(astate->iface->ctx, &addr) != NULL);
/* Restore the original random state */
- setstate(astate->iface->ctx->randomstate);
-
+ setstate(istate->arp->iface->ctx->randomstate);
return addr.s_addr;
}
@@ -91,7 +94,7 @@ ipv4ll_subnet_route(const struct interfa
assert(ifp != NULL);
if ((state = IPV4LL_CSTATE(ifp)) == NULL ||
- state->addr.s_addr == INADDR_ANY)
+ state->addr == NULL)
return NULL;
if ((rt = calloc(1, sizeof(*rt))) == NULL) {
@@ -99,10 +102,10 @@ ipv4ll_subnet_route(const struct interfa
return NULL;
}
rt->iface = ifp;
- rt->dest.s_addr = state->addr.s_addr & inaddr_llmask.s_addr;
- rt->net = inaddr_llmask;
+ rt->dest.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
+ rt->mask.s_addr = state->addr->mask.s_addr;
rt->gate.s_addr = INADDR_ANY;
- rt->src = state->addr;
+ rt->src = state->addr->addr;
return rt;
}
@@ -114,7 +117,7 @@ ipv4ll_default_route(const struct interf
assert(ifp != NULL);
if ((state = IPV4LL_CSTATE(ifp)) == NULL ||
- state->addr.s_addr == INADDR_ANY)
+ state->addr == NULL)
return NULL;
if ((rt = calloc(1, sizeof(*rt))) == NULL) {
@@ -123,9 +126,9 @@ ipv4ll_default_route(const struct interf
}
rt->iface = ifp;
rt->dest.s_addr = INADDR_ANY;
- rt->net.s_addr = INADDR_ANY;
+ rt->mask.s_addr = INADDR_ANY;
rt->gate.s_addr = INADDR_ANY;
- rt->src = state->addr;
+ rt->src = state->addr->addr;
return rt;
}
@@ -145,18 +148,18 @@ ipv4ll_env(char **env, const char *prefi
/* Emulate a DHCP environment */
if (asprintf(&env[0], "%s%sip_address=%s",
- prefix, pf, inet_ntoa(state->addr)) == -1)
+ prefix, pf, inet_ntoa(state->addr->addr)) == -1)
return -1;
if (asprintf(&env[1], "%s%ssubnet_mask=%s",
- prefix, pf, inet_ntoa(inaddr_llmask)) == -1)
+ prefix, pf, inet_ntoa(state->addr->mask)) == -1)
return -1;
if (asprintf(&env[2], "%s%ssubnet_cidr=%d",
- prefix, pf, inet_ntocidr(inaddr_llmask)) == -1)
+ prefix, pf, inet_ntocidr(state->addr->mask)) == -1)
return -1;
if (asprintf(&env[3], "%s%sbroadcast_address=%s",
- prefix, pf, inet_ntoa(inaddr_llbcast)) == -1)
+ prefix, pf, inet_ntoa(state->addr->brd)) == -1)
return -1;
- netnum.s_addr = state->addr.s_addr & inaddr_llmask.s_addr;
+ netnum.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
if (asprintf(&env[4], "%s%snetwork_number=%s",
prefix, pf, inet_ntoa(netnum)) == -1)
return -1;
@@ -198,14 +201,14 @@ ipv4ll_probed(struct arp_state *astate)
ifp->name, inet_ntoa(astate->addr));
#endif
test:
- state->addr = astate->addr;
+ state->addr = ia;
if (ifp->ctx->options & DHCPCD_TEST) {
script_runreason(ifp, "TEST");
eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
return;
}
timespecclear(&state->defend);
- if_initrt(ifp);
+ if_initrt(ifp->ctx);
ipv4_buildroutes(ifp->ctx);
arp_announce(astate);
script_runreason(ifp, "IPV4LL");
@@ -244,6 +247,7 @@ ipv4ll_conflicted(struct arp_state *asta
ifp = astate->iface;
state = IPV4LL_STATE(ifp);
assert(state != NULL);
+ assert(state->addr != NULL);
fail = 0;
/* RFC 3927 2.2.1, Probe Conflict Detection */
@@ -253,9 +257,9 @@ ipv4ll_conflicted(struct arp_state *asta
fail = astate->addr.s_addr;
/* RFC 3927 2.5, Conflict Defense */
- if (IN_LINKLOCAL(ntohl(state->addr.s_addr)) &&
- amsg && amsg->sip.s_addr == state->addr.s_addr)
- fail = state->addr.s_addr;
+ if (IN_LINKLOCAL(ntohl(state->addr->addr.s_addr)) &&
+ amsg && amsg->sip.s_addr == state->addr->addr.s_addr)
+ fail = state->addr->addr.s_addr;
if (fail == 0)
return;
@@ -263,7 +267,7 @@ ipv4ll_conflicted(struct arp_state *asta
astate->failed.s_addr = fail;
arp_report_conflicted(astate, amsg);
- if (astate->failed.s_addr == state->addr.s_addr) {
+ if (astate->failed.s_addr == state->addr->addr.s_addr) {
struct timespec now, defend;
/* RFC 3927 Section 2.5 says a defence should
@@ -280,24 +284,23 @@ ipv4ll_conflicted(struct arp_state *asta
if (timespeccmp(&defend, &now, >))
logger(ifp->ctx, LOG_WARNING,
"%s: IPv4LL %d second defence failed for %s",
- ifp->name, DEFEND_INTERVAL,
- inet_ntoa(state->addr));
+ ifp->name, DEFEND_INTERVAL, state->addr->saddr);
else if (arp_request(ifp,
- state->addr.s_addr, state->addr.s_addr) == -1)
+ state->addr->addr.s_addr, state->addr->addr.s_addr) == -1)
logger(ifp->ctx, LOG_ERR,
"%s: arp_request: %m", __func__);
else {
logger(ifp->ctx, LOG_DEBUG,
"%s: defended IPv4LL address %s",
- ifp->name, inet_ntoa(state->addr));
+ ifp->name, state->addr->saddr);
state->defend = now;
return;
}
- ipv4_deladdr(ifp, &state->addr, &inaddr_llmask, 1);
+ ipv4_deladdr(state->addr, 1);
state->down = 1;
+ state->addr = NULL;
script_runreason(ifp, "IPV4LL");
- state->addr.s_addr = INADDR_ANY;
}
arp_cancel(astate);
@@ -305,7 +308,7 @@ ipv4ll_conflicted(struct arp_state *asta
logger(ifp->ctx, LOG_ERR,
"%s: failed to acquire an IPv4LL address",
ifp->name);
- astate->addr.s_addr = ipv4ll_pick_addr(astate);
+ astate->addr.s_addr = ipv4ll_pickaddr(astate);
eloop_timeout_add_sec(ifp->ctx->eloop,
state->conflicts >= MAX_CONFLICTS ?
RATE_LIMIT_INTERVAL : PROBE_WAIT,
@@ -338,8 +341,6 @@ ipv4ll_start(void *arg)
syslog(LOG_ERR, "%s: calloc %m", __func__);
return;
}
-
- state->addr.s_addr = INADDR_ANY;
}
if (state->arp != NULL)
@@ -384,7 +385,7 @@ ipv4ll_start(void *arg)
ia = ipv4_iffindlladdr(ifp);
#ifdef IN_IFF_TENTATIVE
if (ia != NULL && ia->addr_flags & IN_IFF_DUPLICATED) {
- ipv4_deladdr(ifp, &ia->addr, &ia->net, 0);
+ ipv4_deladdr(ia, 0);
ia = NULL;
}
#endif
@@ -398,7 +399,7 @@ ipv4ll_start(void *arg)
return;
}
logger(ifp->ctx, LOG_INFO, "%s: using IPv4LL address %s",
- ifp->name, inet_ntoa(astate->addr));
+ ifp->name, ia->saddr);
#endif
ipv4ll_probed(astate);
return;
@@ -406,7 +407,7 @@ ipv4ll_start(void *arg)
logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address",
ifp->name);
- astate->addr.s_addr = ipv4ll_pick_addr(astate);
+ astate->addr.s_addr = ipv4ll_pickaddr(astate);
#ifdef IN_IFF_TENTATIVE
ipv4ll_probed(astate);
#else
@@ -434,9 +435,9 @@ ipv4ll_freedrop(struct interface *ifp, i
if (drop && (ifp->options->options & DHCPCD_NODROP) != DHCPCD_NODROP) {
struct ipv4_state *istate;
- if (state && state->addr.s_addr != INADDR_ANY) {
- ipv4_deladdr(ifp, &state->addr, &inaddr_llmask, 1);
- state->addr.s_addr = INADDR_ANY;
+ if (state && state->addr != NULL) {
+ ipv4_deladdr(state->addr, 1);
+ state->addr = NULL;
dropped = 1;
}
@@ -446,8 +447,7 @@ ipv4ll_freedrop(struct interface *ifp, i
TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) {
if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) {
- ipv4_deladdr(ifp, &ia->addr,
- &ia->net, 0);
+ ipv4_deladdr(ia, 0);
dropped = 1;
}
}
@@ -479,12 +479,11 @@ ipv4ll_handlert(struct dhcpcd_ctx *ctx,
/* If any interface is running IPv4LL, rebuild our routing table. */
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
- if (IPV4LL_STATE_RUNNING(ifp))
+ if (IPV4LL_STATE_RUNNING(ifp)) {
+ if_initrt(ifp->ctx);
+ ipv4_buildroutes(ifp->ctx);
break;
- }
- if (ifp != NULL) {
- if_initrt(ifp);
- ipv4_buildroutes(ctx);
+ }
}
return 0;
Index: src/external/bsd/dhcpcd/dist/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/dhcp6.c:1.21 src/external/bsd/dhcpcd/dist/dhcp6.c:1.22
--- src/external/bsd/dhcpcd/dist/dhcp6.c:1.21 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/dhcp6.c Fri Jun 17 19:42:31 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp6.c,v 1.21 2016/05/09 10:15:59 roy Exp $");
+ __RCSID("$NetBSD: dhcp6.c,v 1.22 2016/06/17 19:42:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -64,10 +64,6 @@
#include "compat/bitops.h"
#endif
-#ifndef __UNCONST
-#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
-#endif
-
/* DHCPCD Project has been assigned an IANA PEN of 40712 */
#define DHCPCD_IANA_PEN 40712
@@ -320,7 +316,7 @@ dhcp6_updateelapsed(struct interface *if
if (co == NULL)
return -1;
- o = __UNCONST(co);
+ o = UNCONST(co);
state = D6_STATE(ifp);
clock_gettime(CLOCK_MONOTONIC, &tv);
if (state->RTC == 0) {
@@ -408,14 +404,29 @@ dhcp6_delegateaddr(struct in6_addr *addr
}
if (sla == NULL || sla->sla_set == 0) {
+ /* No SLA set, so make an assumption of
+ * desired SLA and prefix length. */
asla.sla = ifp->index;
asla.prefix_len = 0;
+ asla.sla_set = 0;
+ sla = &asla;
+ } else if (sla->sla == 0 && sla->prefix_len == 0) {
+ /* An SLA of 0 was set with no prefix length specified.
+ * This means we delegate the whole prefix. */
+ asla.sla = sla->sla;
+ asla.prefix_len = prefix->prefix_len;
+ asla.sla_set = 0;
sla = &asla;
} else if (sla->prefix_len == 0) {
+ /* An SLA was given, but prefix length was not.
+ * We need to work out a suitable prefix length for
+ * potentially more than one interface. */
asla.sla = sla->sla;
asla.prefix_len = 0;
+ asla.sla_set = 0;
sla = &asla;
}
+
if (sla->prefix_len == 0) {
uint32_t sla_max;
int bits;
@@ -954,7 +965,7 @@ dhcp6_update_auth(struct interface *ifp,
if (co == NULL)
return -1;
- o = __UNCONST(co);
+ o = UNCONST(co);
state = D6_STATE(ifp);
return dhcp_auth_encode(&ifp->options->auth, state->auth.token,
@@ -2393,7 +2404,7 @@ dhcp6_ifdelegateaddr(struct interface *i
ia->flags = IPV6_AF_NEW | IPV6_AF_ONLINK;
ia->dadcallback = dhcp6_dadcallback;
memcpy(&ia->iaid, &prefix->iaid, sizeof(ia->iaid));
- ia->created = ia->acquired = prefix->acquired;
+ ia->created = prefix->acquired;
ia->addr = daddr;
TAILQ_INSERT_TAIL(&state->addrs, ia, next);
@@ -2402,6 +2413,7 @@ dhcp6_ifdelegateaddr(struct interface *i
ia->delegating_prefix = prefix;
ia->prefix = addr;
ia->prefix_len = (uint8_t)pfxlen;
+ ia->acquired = prefix->acquired;
ia->prefix_pltime = prefix->prefix_pltime;
ia->prefix_vltime = prefix->prefix_vltime;
@@ -2468,6 +2480,11 @@ dhcp6_delegate_prefix(struct interface *
ifo = ifp->options;
state = D6_STATE(ifp);
+ /* Clear the logged flag. */
+ TAILQ_FOREACH(ap, &state->addrs, next) {
+ ap->flags &= ~IPV6_AF_DELEGATEDLOG;
+ }
+
TAILQ_FOREACH(ifd, ifp->ctx->ifaces, next) {
if (!ifd->active)
continue;
@@ -2476,11 +2493,15 @@ dhcp6_delegate_prefix(struct interface *
TAILQ_FOREACH(ap, &state->addrs, next) {
if (!(ap->flags & IPV6_AF_DELEGATEDPFX))
continue;
- if (ap->flags & IPV6_AF_NEW) {
- ap->flags &= ~IPV6_AF_NEW;
- logger(ifp->ctx, LOG_DEBUG,
+ if (!(ap->flags & IPV6_AF_DELEGATEDLOG)) {
+ /* We only want to log this the once as we loop
+ * through many interfaces first. */
+ ap->flags |= IPV6_AF_DELEGATEDLOG;
+ logger(ifp->ctx,
+ ap->flags & IPV6_AF_NEW ?LOG_INFO:LOG_DEBUG,
"%s: delegated prefix %s",
ifp->name, ap->saddr);
+ ap->flags &= ~IPV6_AF_NEW;
}
for (i = 0; i < ifo->ia_len; i++) {
ia = &ifo->ia[i];
@@ -2527,7 +2548,7 @@ dhcp6_delegate_prefix(struct interface *
if (k && !carrier_warned) {
ifd_state = D6_STATE(ifd);
ipv6_addaddrs(&ifd_state->addrs);
- if_initrt6(ifd);
+ if_initrt6(ifd->ctx);
ipv6_buildroutes(ifd->ctx);
dhcp6_script_try_run(ifd, 1);
}
@@ -2594,7 +2615,7 @@ dhcp6_find_delegates(struct interface *i
state = D6_STATE(ifp);
state->state = DH6S_DELEGATED;
ipv6_addaddrs(&state->addrs);
- if_initrt6(ifp);
+ if_initrt6(ifp->ctx);
ipv6_buildroutes(ifp->ctx);
dhcp6_script_try_run(ifp, 1);
}
@@ -2955,7 +2976,12 @@ dhcp6_handledata(void *arg)
case DHCP6_ADVERTISE:
if (state->state == DH6S_REQUEST) /* rapid commit */
break;
- ap = TAILQ_FIRST(&state->addrs);
+ TAILQ_FOREACH(ap, &state->addrs, next) {
+ if (!(ap->flags & IPV6_AF_REQUEST))
+ break;
+ }
+ if (ap == NULL)
+ ap = TAILQ_FIRST(&state->addrs);
logger(ifp->ctx, LOG_INFO, "%s: ADV %s from %s",
ifp->name, ap->saddr, ctx->sfrom);
if (ifp->ctx->options & DHCPCD_TEST)
@@ -3095,7 +3121,7 @@ recv:
else if (state->expire == 0)
logger(ifp->ctx, has_new ? LOG_INFO : LOG_DEBUG,
"%s: will expire", ifp->name);
- if_initrt6(ifp);
+ if_initrt6(ifp->ctx);
ipv6_buildroutes(ifp->ctx);
dhcp6_writelease(ifp);
dhcp6_delegate_prefix(ifp);
@@ -3426,6 +3452,20 @@ dhcp6_free(struct interface *ifp)
dhcp6_freedrop(ifp, 0, NULL);
}
+void dhcp6_dropnondelegates(struct interface *ifp)
+{
+ struct dhcp6_state *state;
+ struct ipv6_addr *ia;
+
+ if ((state = D6_STATE(ifp)) == NULL)
+ return;
+ TAILQ_FOREACH(ia, &state->addrs, next) {
+ if (ia->flags & (IPV6_AF_DELEGATED | IPV6_AF_DELEGATEDPFX))
+ return;
+ }
+ dhcp6_drop(ifp, "EXPIRE6");
+}
+
void
dhcp6_handleifa(struct dhcpcd_ctx *ctx, int cmd, const char *ifname,
const struct in6_addr *addr, int flags)
Index: src/external/bsd/dhcpcd/dist/if.c
diff -u src/external/bsd/dhcpcd/dist/if.c:1.21 src/external/bsd/dhcpcd/dist/if.c:1.22
--- src/external/bsd/dhcpcd/dist/if.c:1.21 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/if.c Fri Jun 17 19:42:31 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: if.c,v 1.21 2016/05/09 10:15:59 roy Exp $");
+ __RCSID("$NetBSD: if.c,v 1.22 2016/06/17 19:42:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -214,14 +214,13 @@ static void if_learnaddrs(struct dhcpcd_
addr = (void *)ifa->ifa_addr;
net = (void *)ifa->ifa_netmask;
if (ifa->ifa_flags & IFF_POINTOPOINT)
- brd = (const struct sockaddr_in *)
- (void *)ifa->ifa_dstaddr;
+ brd = (void *)ifa->ifa_dstaddr;
else
brd = (void *)ifa->ifa_broadaddr;
ifa_flags = if_addrflags(&addr->sin_addr, ifp);
ipv4_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name,
- &addr->sin_addr, &net->sin_addr, &brd->sin_addr,
- ifa_flags);
+ &addr->sin_addr, &net->sin_addr,
+ brd ? &brd->sin_addr : NULL, ifa_flags);
break;
#endif
#ifdef INET6
@@ -274,16 +273,11 @@ if_discover(struct dhcpcd_ctx *ctx, int
const struct sockaddr_ll *sll;
#endif
-#ifdef GETIFADDRS_AFLINK
if (getifaddrs(&ifaddrs) == -1)
return NULL;
-#else
- if (if_getifaddrs(&ifaddrs) == -1)
- return NULL;
-#endif
- ifs = malloc(sizeof(*ifs));
- if (ifs == NULL)
- return NULL;
+
+ if ((ifs = malloc(sizeof(*ifs))) == NULL)
+ goto failed;
TAILQ_INIT(ifs);
for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
@@ -469,7 +463,7 @@ if_discover(struct dhcpcd_ctx *ctx, int
}
ifp->hwlen = sdl->sdl_alen;
#ifndef CLLADDR
-# define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen))
+# define CLLADDR(s) (const void *)((s)->sdl_data + (s)->sdl_nlen)
#endif
memcpy(ifp->hwaddr, CLLADDR(sdl), ifp->hwlen);
#elif AF_PACKET
@@ -557,16 +551,9 @@ if_discover(struct dhcpcd_ctx *ctx, int
TAILQ_INSERT_TAIL(ifs, ifp, next);
}
-#ifdef GETIFADDRS_AFLINK
- {
-#else
+ if_learnaddrs(ctx, ifs, ifaddrs);
+failed:
freeifaddrs(ifaddrs);
- if (getifaddrs(&ifaddrs) != -1) {
-#endif
- if_learnaddrs(ctx, ifs, ifaddrs);
- freeifaddrs(ifaddrs);
- }
-
return ifs;
}
Index: src/external/bsd/dhcpcd/dist/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.c:1.34 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.35
--- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.34 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/dhcpcd.c Fri Jun 17 19:42:31 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd.c,v 1.34 2016/05/09 10:15:59 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd.c,v 1.35 2016/06/17 19:42:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -423,14 +423,17 @@ configure_interface1(struct interface *i
if (ifo->options & DHCPCD_RELEASE)
ifo->options &= ~DHCPCD_PERSISTENT;
- if (ifp->flags & IFF_POINTOPOINT && !(ifo->options & DHCPCD_INFORM))
- ifo->options |= DHCPCD_STATIC;
+ if (ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) {
+ ifo->options &= ~DHCPCD_ARP;
+ if (!(ifp->flags & IFF_MULTICAST))
+ ifo->options &= ~DHCPCD_IPV6RS;
+ if (!(ifo->options & DHCPCD_INFORM))
+ ifo->options |= DHCPCD_STATIC;
+ }
if (ifp->flags & IFF_NOARP ||
+ !(ifo->options & DHCPCD_ARP) ||
ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))
ifo->options &= ~DHCPCD_IPV4LL;
- if (ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK) ||
- !(ifp->flags & IFF_MULTICAST))
- ifo->options &= ~DHCPCD_IPV6RS;
if (ifo->metric != -1)
ifp->metric = (unsigned int)ifo->metric;
@@ -989,13 +992,13 @@ dhcpcd_activateinterface(struct interfac
}
static void
-handle_link(void *arg)
+dhcpcd_handlelink(void *arg)
{
struct dhcpcd_ctx *ctx;
ctx = arg;
- if (if_managelink(ctx) == -1) {
- logger(ctx, LOG_ERR, "if_managelink: %m");
+ if (if_handlelink(ctx) == -1) {
+ logger(ctx, LOG_ERR, "if_handlelink: %m");
eloop_event_delete(ctx->eloop, ctx->link_fd);
close(ctx->link_fd);
ctx->link_fd = -1;
@@ -1089,7 +1092,7 @@ dhcpcd_handleinterface(void *arg, int ac
void
dhcpcd_handlehwaddr(struct dhcpcd_ctx *ctx, const char *ifname,
- const uint8_t *hwaddr, uint8_t hwlen)
+ const void *hwaddr, uint8_t hwlen)
{
struct interface *ifp;
char buf[sizeof(ifp->hwaddr) * 3];
@@ -1831,7 +1834,7 @@ printpidfile:
/* Start handling kernel messages for interfaces, addreses and
* routes. */
- eloop_event_add(ctx.eloop, ctx.link_fd, handle_link, &ctx);
+ eloop_event_add(ctx.eloop, ctx.link_fd, dhcpcd_handlelink, &ctx);
/* Start any dev listening plugin which may want to
* change the interface name provided by the kernel */
Index: src/external/bsd/dhcpcd/dist/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.30 src/external/bsd/dhcpcd/dist/if-bsd.c:1.31
--- src/external/bsd/dhcpcd/dist/if-bsd.c:1.30 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/if-bsd.c Fri Jun 17 19:42:31 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: if-bsd.c,v 1.30 2016/05/09 10:15:59 roy Exp $");
+ __RCSID("$NetBSD: if-bsd.c,v 1.31 2016/06/17 19:42:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -96,16 +96,18 @@
#define COPYOUT(sin, sa) do { \
if ((sa) && ((sa)->sa_family == AF_INET || (sa)->sa_family == 255)) \
- (sin) = ((struct sockaddr_in *)(void *)(sa))->sin_addr; \
+ (sin) = ((const struct sockaddr_in *)(const void *) \
+ (sa))->sin_addr; \
} while (0)
#define COPYOUT6(sin, sa) do { \
if ((sa) && ((sa)->sa_family == AF_INET6 || (sa)->sa_family == 255)) \
- (sin) = ((struct sockaddr_in6 *)(void *)(sa))->sin6_addr; \
+ (sin) = ((const struct sockaddr_in6 *)(const void *) \
+ (sa))->sin6_addr; \
} while (0)
#ifndef CLLADDR
-# define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen))
+# define CLLADDR(s) (const void *)((s)->sdl_data + (s)->sdl_nlen)
#endif
struct priv {
@@ -145,7 +147,7 @@ if_opensockets_os(struct dhcpcd_ctx *ctx
#endif
#define SOCK_FLAGS (SOCK_CLOEXEC | SOCK_NONBLOCK)
- ctx->link_fd = xsocket(PF_ROUTE, SOCK_RAW | SOCK_FLAGS, 0);
+ ctx->link_fd = xsocket(PF_ROUTE, SOCK_RAW | SOCK_FLAGS, AF_UNSPEC);
#undef SOCK_FLAGS
return ctx->link_fd == -1 ? -1 : 0;
}
@@ -174,7 +176,7 @@ if_linkaddr(struct sockaddr_dl *sdl, con
#endif
static int
-if_getssid1(int s, const char *ifname, uint8_t *ssid)
+if_getssid1(int s, const char *ifname, void *ssid)
{
int retval = -1;
#if defined(SIOCG80211NWID)
@@ -266,13 +268,15 @@ if_vimaster(const struct dhcpcd_ctx *ctx
}
static void
-get_addrs(int type, char *cp, struct sockaddr **sa)
+get_addrs(int type, const void *data, const struct sockaddr **sa)
{
+ const char *cp;
int i;
+ cp = data;
for (i = 0; i < RTAX_MAX; i++) {
if (type & (1 << i)) {
- sa[i] = (struct sockaddr *)cp;
+ sa[i] = (const struct sockaddr *)cp;
RT_ADVANCE(cp, sa[i]);
} else
sa[i] = NULL;
@@ -362,8 +366,15 @@ if_findsa(struct dhcpcd_ctx *ctx, const
#ifdef INET
const char *if_pfname = "Berkley Packet Filter";
+void
+if_closeraw(__unused struct interface *ifp, int fd)
+{
+
+ close(fd);
+}
+
int
-if_openrawsocket(struct interface *ifp, uint16_t protocol)
+if_openraw(struct interface *ifp, uint16_t protocol)
{
struct ipv4_state *state;
int fd = -1;
@@ -443,14 +454,14 @@ if_openrawsocket(struct interface *ifp,
goto eexit;
#endif
- /* Install the DHCP filter */
+ /* Install the filter. */
memset(&pf, 0, sizeof(pf));
if (protocol == ETHERTYPE_ARP) {
pf.bf_insns = UNCONST(arp_bpf_filter);
pf.bf_len = arp_bpf_filter_len;
} else {
- pf.bf_insns = UNCONST(dhcp_bpf_filter);
- pf.bf_len = dhcp_bpf_filter_len;
+ pf.bf_insns = UNCONST(bootp_bpf_filter);
+ pf.bf_len = bootp_bpf_filter_len;
}
if (ioctl(fd, BIOCSETF, &pf) == -1)
goto eexit;
@@ -465,12 +476,11 @@ eexit:
}
ssize_t
-if_sendrawpacket(const struct interface *ifp, uint16_t protocol,
+if_sendraw(__unused const struct interface *ifp, int fd, uint16_t protocol,
const void *data, size_t len)
{
struct iovec iov[2];
struct ether_header hw;
- int fd;
memset(&hw, 0, ETHER_HDR_LEN);
memset(&hw.ether_dhost, 0xff, ETHER_ADDR_LEN);
@@ -479,25 +489,20 @@ if_sendrawpacket(const struct interface
iov[0].iov_len = ETHER_HDR_LEN;
iov[1].iov_base = UNCONST(data);
iov[1].iov_len = len;
- fd = ipv4_protocol_fd(ifp, protocol);
return writev(fd, iov, 2);
}
/* BPF requires that we read the entire buffer.
* So we pass the buffer in the API so we can loop on >1 packet. */
ssize_t
-if_readrawpacket(struct interface *ifp, uint16_t protocol,
- void *data, size_t len, int *flags)
+if_readraw(struct interface *ifp, int fd, void *data, size_t len, int *flags)
{
- int fd;
struct bpf_hdr packet;
ssize_t bytes;
- const unsigned char *payload;
+ const char *payload;
struct ipv4_state *state;
state = IPV4_STATE(ifp);
- fd = ipv4_protocol_fd(ifp, protocol);
-
*flags = 0;
for (;;) {
if (state->buffer_len == 0) {
@@ -524,10 +529,8 @@ if_readrawpacket(struct interface *ifp,
next:
state->buffer_pos += BPF_WORDALIGN(packet.bh_hdrlen +
packet.bh_caplen);
- if (state->buffer_pos >= state->buffer_len) {
+ if (state->buffer_pos >= state->buffer_len)
state->buffer_len = state->buffer_pos = 0;
- *flags |= RAW_EOF;
- }
if (bytes != -1)
return bytes;
}
@@ -535,40 +538,36 @@ next:
int
-if_address(const struct interface *ifp, const struct in_addr *address,
- const struct in_addr *netmask, const struct in_addr *broadcast,
- int action)
+if_address(unsigned char cmd, const struct ipv4_addr *ia)
{
int r;
struct in_aliasreq ifra;
memset(&ifra, 0, sizeof(ifra));
- strlcpy(ifra.ifra_name, ifp->name, sizeof(ifra.ifra_name));
+ strlcpy(ifra.ifra_name, ia->iface->name, sizeof(ifra.ifra_name));
#define ADDADDR(var, addr) do { \
(var)->sin_family = AF_INET; \
(var)->sin_len = sizeof(*(var)); \
(var)->sin_addr = *(addr); \
} while (/*CONSTCOND*/0)
- ADDADDR(&ifra.ifra_addr, address);
- ADDADDR(&ifra.ifra_mask, netmask);
- if (action >= 0 && broadcast)
- ADDADDR(&ifra.ifra_broadaddr, broadcast);
+ ADDADDR(&ifra.ifra_addr, &ia->addr);
+ ADDADDR(&ifra.ifra_mask, &ia->mask);
+ if (cmd == RTM_NEWADDR && ia->brd.s_addr != INADDR_ANY)
+ ADDADDR(&ifra.ifra_broadaddr, &ia->brd);
#undef ADDADDR
- r = ioctl(ifp->ctx->pf_inet_fd,
- action < 0 ? SIOCDIFADDR : SIOCAIFADDR, &ifra);
+ r = ioctl(ia->iface->ctx->pf_inet_fd,
+ cmd == RTM_DELADDR ? SIOCDIFADDR : SIOCAIFADDR, &ifra);
return r;
}
static int
-if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm)
+if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm)
{
- char *cp;
- struct sockaddr *sa, *rti_info[RTAX_MAX];
+ const struct sockaddr *sa, *rti_info[RTAX_MAX];
- cp = (void *)(rtm + 1);
- sa = (void *)cp;
+ sa = (const void *)(rtm + 1);
if (sa->sa_family != AF_INET)
return -1;
if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY))
@@ -586,14 +585,14 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct
return -1;
#endif
- get_addrs(rtm->rtm_addrs, cp, rti_info);
+ get_addrs(rtm->rtm_addrs, sa, rti_info);
memset(rt, 0, sizeof(*rt));
rt->flags = (unsigned int)rtm->rtm_flags;
COPYOUT(rt->dest, rti_info[RTAX_DST]);
if (rtm->rtm_addrs & RTA_NETMASK)
- COPYOUT(rt->net, rti_info[RTAX_NETMASK]);
+ COPYOUT(rt->mask, rti_info[RTAX_NETMASK]);
else
- rt->net.s_addr = INADDR_BROADCAST;
+ rt->mask.s_addr = INADDR_BROADCAST;
COPYOUT(rt->gate, rti_info[RTAX_GATEWAY]);
COPYOUT(rt->src, rti_info[RTAX_IFA]);
rt->mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu;
@@ -692,7 +691,7 @@ if_route(unsigned char cmd, const struct
if (subnet == -1) /* unikely */
rtm.hdr.rtm_addrs &= ~RTA_IFA;
}
- if (rt->net.s_addr == htonl(INADDR_BROADCAST) &&
+ if (rt->mask.s_addr == htonl(INADDR_BROADCAST) &&
rt->gate.s_addr == htonl(INADDR_ANY))
{
#ifdef RTF_CLONING
@@ -708,7 +707,7 @@ if_route(unsigned char cmd, const struct
rtm.hdr.rtm_flags |= RTF_HOST;
#endif
} else if (rt->gate.s_addr == htonl(INADDR_LOOPBACK) &&
- rt->net.s_addr == htonl(INADDR_BROADCAST))
+ rt->mask.s_addr == htonl(INADDR_BROADCAST))
{
rtm.hdr.rtm_flags |= RTF_HOST | RTF_GATEWAY;
/* Going via lo0 so remove the interface flags */
@@ -718,7 +717,7 @@ if_route(unsigned char cmd, const struct
rtm.hdr.rtm_addrs |= RTA_NETMASK;
if (rtm.hdr.rtm_flags & RTF_STATIC)
rtm.hdr.rtm_flags |= RTF_GATEWAY;
- if (rt->net.s_addr == htonl(INADDR_BROADCAST))
+ if (rt->mask.s_addr == htonl(INADDR_BROADCAST))
rtm.hdr.rtm_flags |= RTF_HOST;
}
if ((cmd == RTM_ADD || cmd == RTM_CHANGE) &&
@@ -744,7 +743,7 @@ if_route(unsigned char cmd, const struct
}
if (rtm.hdr.rtm_addrs & RTA_NETMASK)
- ADDADDR(&rt->net);
+ ADDADDR(&rt->mask);
if ((cmd == RTM_ADD || cmd == RTM_CHANGE) &&
(rtm.hdr.rtm_addrs & (RTA_IFP | RTA_IFA)))
@@ -775,7 +774,7 @@ if_route(unsigned char cmd, const struct
}
int
-if_initrt(struct interface *ifp)
+if_initrt(struct dhcpcd_ctx *ctx)
{
struct rt_msghdr *rtm;
int mib[6];
@@ -783,7 +782,7 @@ if_initrt(struct interface *ifp)
char *buf, *p, *end;
struct rt rt;
- ipv4_freerts(ifp->ctx->ipv4_kroutes);
+ ipv4_freerts(ctx->ipv4_kroutes);
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
@@ -806,17 +805,17 @@ if_initrt(struct interface *ifp)
end = buf + needed;
for (p = buf; p < end; p += rtm->rtm_msglen) {
rtm = (void *)p;
- if (if_copyrt(ifp->ctx, &rt, rtm) == 0)
- ipv4_handlert(ifp->ctx, RTM_ADD, &rt, 1);
+ if (if_copyrt(ctx, &rt, rtm) == 0)
+ ipv4_handlert(ctx, RTM_ADD, &rt, 1);
}
free(buf);
return 0;
}
-#ifdef SIOCGIFAFLAG_IN
int
if_addrflags(const struct in_addr *addr, const struct interface *ifp)
{
+#ifdef SIOCGIFAFLAG_IN
struct ifreq ifr;
struct sockaddr_in *sin;
@@ -828,17 +827,12 @@ if_addrflags(const struct in_addr *addr,
if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1)
return -1;
return ifr.ifr_addrflags;
-}
#else
-int
-if_addrflags(__unused const struct in_addr *addr,
- __unused const struct interface *ifp)
-{
-
- errno = ENOTSUP;
+ UNUSED(addr);
+ UNUSED(ifp);
return 0;
-}
#endif
+}
#endif /* INET */
#ifdef INET6
@@ -873,7 +867,7 @@ ifa_scope(struct sockaddr_in6 *sin, unsi
#endif
int
-if_address6(const struct ipv6_addr *ia, int action)
+if_address6(unsigned char cmd, const struct ipv6_addr *ia)
{
struct in6_aliasreq ifa;
struct in6_addr mask;
@@ -914,18 +908,15 @@ if_address6(const struct ipv6_addr *ia,
priv = (struct priv *)ia->iface->ctx->priv;
return ioctl(priv->pf_inet6_fd,
- action < 0 ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa);
+ cmd == RTM_DELADDR ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa);
}
-
static int
-if_copyrt6(struct dhcpcd_ctx *ctx, struct rt6 *rt, struct rt_msghdr *rtm)
+if_copyrt6(struct dhcpcd_ctx *ctx, struct rt6 *rt, const struct rt_msghdr *rtm)
{
- char *cp;
- struct sockaddr *sa, *rti_info[RTAX_MAX];
+ const struct sockaddr *sa, *rti_info[RTAX_MAX];
- cp = (void *)(rtm + 1);
- sa = (void *)cp;
+ sa = (const void *)(rtm + 1);
if (sa->sa_family != AF_INET6)
return -1;
if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY))
@@ -942,7 +933,7 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struc
return -1;
#endif
- get_addrs(rtm->rtm_addrs, cp, rti_info);
+ get_addrs(rtm->rtm_addrs, sa, rti_info);
memset(rt, 0, sizeof(*rt));
rt->flags = (unsigned int)rtm->rtm_flags;
COPYOUT6(rt->dest, rti_info[RTAX_DST]);
@@ -955,12 +946,12 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struc
* a kernel bug or actually used for something.
* Either way it needs to be zeroed out.
*/
- struct sockaddr_in6 *sin6;
+ const struct sockaddr_in6 *sin6;
size_t e, i, final = 0, illegal = 0;
const unsigned char *p;
- sin6 = (void *)rti_info[RTAX_NETMASK];
- rt->net = sin6->sin6_addr;
+ sin6 = (const void *)rti_info[RTAX_NETMASK];
+ rt->mask = sin6->sin6_addr;
e = sin6->sin6_len - offsetof(struct sockaddr_in6, sin6_addr);
if (e > sizeof(struct in6_addr))
e = sizeof(struct in6_addr);
@@ -970,7 +961,7 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struc
{
if (final && *p) {
illegal = 1;
- rt->net.s6_addr[i++] = 0x00;
+ rt->mask.s6_addr[i++] = 0x00;
continue;
}
switch (*p & 0xff) {
@@ -991,14 +982,14 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struc
break;
}
if (!illegal)
- rt->net.s6_addr[i++] &= *p;
+ rt->mask.s6_addr[i++] &= *p;
else
- rt->net.s6_addr[i++] = 0x00;
+ rt->mask.s6_addr[i++] = 0x00;
}
- while (i < sizeof(rt->net.s6_addr))
- rt->net.s6_addr[i++] = 0x00;
+ while (i < sizeof(rt->mask.s6_addr))
+ rt->mask.s6_addr[i++] = 0x00;
} else
- ipv6_mask(&rt->net, 128);
+ ipv6_mask(&rt->mask, 128);
COPYOUT6(rt->gate, rti_info[RTAX_GATEWAY]);
DESCOPE(&rt->gate);
rt->mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu;
@@ -1107,7 +1098,7 @@ if_route6(unsigned char cmd, const struc
}
if (rtm.hdr.rtm_addrs & RTA_NETMASK)
- ADDADDR(&rt->net);
+ ADDADDR(&rt->mask);
if (rtm.hdr.rtm_addrs & (RTA_IFP | RTA_IFA)) {
rtm.hdr.rtm_index = (unsigned short)rt->iface->index;
@@ -1142,7 +1133,7 @@ if_route6(unsigned char cmd, const struc
}
int
-if_initrt6(struct interface *ifp)
+if_initrt6(struct dhcpcd_ctx *ctx)
{
struct rt_msghdr *rtm;
int mib[6];
@@ -1150,7 +1141,7 @@ if_initrt6(struct interface *ifp)
char *buf, *p, *end;
struct rt6 rt;
- ipv6_freerts(&ifp->ctx->ipv6->kroutes);
+ ipv6_freerts(&ctx->ipv6->kroutes);
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
@@ -1173,8 +1164,8 @@ if_initrt6(struct interface *ifp)
end = buf + needed;
for (p = buf; p < end; p += rtm->rtm_msglen) {
rtm = (void *)p;
- if (if_copyrt6(ifp->ctx, &rt, rtm) == 0)
- ipv6_handlert(ifp->ctx, RTM_ADD, &rt);
+ if (if_copyrt6(ctx, &rt, rtm) == 0)
+ ipv6_handlert(ctx, RTM_ADD, &rt);
}
free(buf);
return 0;
@@ -1237,215 +1228,252 @@ if_getlifetime6(struct ipv6_addr *ia)
}
#endif
-int
-if_managelink(struct dhcpcd_ctx *ctx)
+static void
+if_announce(struct dhcpcd_ctx *ctx, const struct if_announcemsghdr *ifan)
+{
+
+ switch(ifan->ifan_what) {
+ case IFAN_ARRIVAL:
+ dhcpcd_handleinterface(ctx, 1, ifan->ifan_name);
+ break;
+ case IFAN_DEPARTURE:
+ dhcpcd_handleinterface(ctx, -1, ifan->ifan_name);
+ break;
+ }
+}
+
+static void
+if_ifinfo(struct dhcpcd_ctx *ctx, const struct if_msghdr *ifm)
{
- /* route and ifwatchd like a msg buf size of 2048 */
- char msg[2048], *p, *e, *cp;
- ssize_t bytes;
- struct rt_msghdr *rtm;
- struct if_announcemsghdr *ifan;
- struct if_msghdr *ifm;
- struct ifa_msghdr *ifam;
- struct sockaddr *sa, *rti_info[RTAX_MAX];
- int len;
- struct sockaddr_dl sdl;
struct interface *ifp;
+ int state;
+
+ if ((ifp = if_findindex(ctx->ifaces, ifm->ifm_index)) == NULL)
+ return;
+ switch (ifm->ifm_data.ifi_link_state) {
+ case LINK_STATE_DOWN:
+ state = LINK_DOWN;
+ break;
+ case LINK_STATE_UP:
+ state = LINK_UP;
+ break;
+ default:
+ /* handle_carrier will re-load the interface flags and check for
+ * IFF_RUNNING as some drivers that don't handle link state also
+ * don't set IFF_RUNNING when this routing message is generated.
+ * As such, it is a race ...*/
+ state = LINK_UNKNOWN;
+ break;
+ }
+ dhcpcd_handlecarrier(ctx, state,
+ (unsigned int)ifm->ifm_flags, ifp->name);
+}
+
+static void
+if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm)
+{
+ const struct sockaddr *sa;
+
+ /* Ignore messages generated by us */
+ if (rtm->rtm_pid == getpid()) {
+ ctx->options &= ~DHCPCD_RTM_PPID;
+ return;
+ }
+
+ /* Ignore messages sent by the parent after forking */
+ if ((ctx->options &
+ (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED)) ==
+ (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED) &&
+ rtm->rtm_pid == ctx->ppid)
+ {
+ /* If this is the last successful message sent,
+ * clear the check flag as it's possible another
+ * process could re-use the same pid and also
+ * manipulate therouting table. */
+ if (rtm->rtm_seq == ctx->pseq)
+ ctx->options &= ~DHCPCD_RTM_PPID;
+ return;
+ }
+
+ sa = (const void *)(rtm + 1);
+ switch (sa->sa_family) {
#ifdef INET
- struct rt rt;
+ case AF_INET:
+ {
+ struct rt rt;
+
+ if (if_copyrt(ctx, &rt, rtm) == 0)
+ ipv4_handlert(ctx, rtm->rtm_type, &rt, 0);
+ break;
+ }
#endif
#ifdef INET6
- struct rt6 rt6;
- struct in6_addr ia6, net6;
- struct sockaddr_in6 *sin6;
-#endif
-#if (defined(INET) && defined(IN_IFF_TENTATIVE)) || defined(INET6)
- int ifa_flags;
-#endif
+ case AF_INET6:
+ {
+ struct rt6 rt6;
- if ((bytes = read(ctx->link_fd, msg, sizeof(msg))) == -1)
- return -1;
- e = msg + bytes;
- for (p = msg; p < e; p += rtm->rtm_msglen) {
- rtm = (void *)p;
- switch(rtm->rtm_type) {
-#ifdef RTM_IFANNOUNCE
- case RTM_IFANNOUNCE:
- ifan = (void *)p;
- switch(ifan->ifan_what) {
- case IFAN_ARRIVAL:
- dhcpcd_handleinterface(ctx, 1,
- ifan->ifan_name);
- break;
- case IFAN_DEPARTURE:
- dhcpcd_handleinterface(ctx, -1,
- ifan->ifan_name);
- break;
- }
+ if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY))
break;
-#endif
- case RTM_IFINFO:
- ifm = (void *)p;
- ifp = if_findindex(ctx->ifaces, ifm->ifm_index);
- if (ifp == NULL)
- break;
- switch (ifm->ifm_data.ifi_link_state) {
- case LINK_STATE_DOWN:
- len = LINK_DOWN;
- break;
- case LINK_STATE_UP:
- len = LINK_UP;
- break;
- default:
- /* handle_carrier will re-load
- * the interface flags and check for
- * IFF_RUNNING as some drivers that
- * don't handle link state also don't
- * set IFF_RUNNING when this routing
- * message is generated.
- * As such, it is a race ...*/
- len = LINK_UNKNOWN;
- break;
- }
- dhcpcd_handlecarrier(ctx, len,
- (unsigned int)ifm->ifm_flags, ifp->name);
+ /*
+ * BSD announces host routes.
+ * As such, we should be notified of reachability by its
+ * existance with a hardware address.
+ */
+ if (rtm->rtm_flags & (RTF_HOST)) {
+ const struct sockaddr *rti_info[RTAX_MAX];
+ struct in6_addr dst6;
+ struct sockaddr_dl sdl;
+
+ get_addrs(rtm->rtm_addrs, rtm + 1, rti_info);
+ COPYOUT6(dst6, rti_info[RTAX_DST]);
+ DESCOPE(&dst6);
+ if (rti_info[RTAX_GATEWAY]->sa_family == AF_LINK)
+ memcpy(&sdl, rti_info[RTAX_GATEWAY],
+ sizeof(sdl));
+ else
+ sdl.sdl_alen = 0;
+ ipv6nd_neighbour(ctx, &dst6,
+ rtm->rtm_type != RTM_DELETE && sdl.sdl_alen ?
+ IPV6ND_REACHABLE : 0);
break;
- case RTM_ADD:
- case RTM_CHANGE:
- case RTM_DELETE:
- /* Ignore messages generated by us */
- if (rtm->rtm_pid == getpid()) {
- ctx->options &= ~DHCPCD_RTM_PPID;
- continue;
- }
- /* Ignore messages sent by the parent after forking */
- if ((ctx->options &
- (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED)) ==
- (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED) &&
- rtm->rtm_pid == ctx->ppid)
- {
- /* If this is the last successful message sent,
- * clear the check flag as it's possible another
- * process could re-use the same pid and also
- * manipulate therouting table. */
- if (rtm->rtm_seq == ctx->pseq)
- ctx->options &= ~DHCPCD_RTM_PPID;
- continue;
- }
- cp = (void *)(rtm + 1);
- sa = (void *)cp;
- switch (sa->sa_family) {
-#ifdef INET
- case AF_INET:
- if (if_copyrt(ctx, &rt, rtm) == 0)
- ipv4_handlert(ctx, rtm->rtm_type,&rt,0);
- break;
-#endif
-#ifdef INET6
- case AF_INET6:
- if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY))
- break;
- /*
- * BSD caches host routes in the
- * routing table.
- * As such, we should be notified of
- * reachability by its existance
- * with a hardware address
- */
- if (rtm->rtm_flags & (RTF_HOST)) {
- get_addrs(rtm->rtm_addrs, cp, rti_info);
- COPYOUT6(ia6, rti_info[RTAX_DST]);
- DESCOPE(&ia6);
- if (rti_info[RTAX_GATEWAY]->sa_family
- == AF_LINK)
- memcpy(&sdl,
- rti_info[RTAX_GATEWAY],
- sizeof(sdl));
- else
- sdl.sdl_alen = 0;
- ipv6nd_neighbour(ctx, &ia6,
- rtm->rtm_type != RTM_DELETE &&
- sdl.sdl_alen ?
- IPV6ND_REACHABLE : 0);
- break;
- }
+ }
- if (if_copyrt6(ctx, &rt6, rtm) == 0)
- ipv6_handlert(ctx, rtm->rtm_type, &rt6);
- break;
-#endif
- }
- break;
-#ifdef RTM_CHGADDR
- case RTM_CHGADDR: /* FALLTHROUGH */
+ if (if_copyrt6(ctx, &rt6, rtm) == 0)
+ ipv6_handlert(ctx, rtm->rtm_type, &rt6);
+ break;
+ }
#endif
- case RTM_DELADDR: /* FALLTHROUGH */
- case RTM_NEWADDR:
- /* XXX We have no way of knowing who generated these
- * messages wich truely sucks because we want to
- * avoid listening to our own delete messages. */
- ifam = (void *)p;
- ifp = if_findindex(ctx->ifaces, ifam->ifam_index);
- if (ifp == NULL)
- break;
- cp = (void *)(ifam + 1);
- get_addrs(ifam->ifam_addrs, cp, rti_info);
- if (rti_info[RTAX_IFA] == NULL)
- break;
- switch (rti_info[RTAX_IFA]->sa_family) {
- case AF_LINK:
+ }
+}
+
+static void
+if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
+{
+ struct interface *ifp;
+ const struct sockaddr *rti_info[RTAX_MAX];
+
+ /* XXX We have no way of knowing who generated these
+ * messages wich truely sucks because we want to
+ * avoid listening to our own delete messages. */
+ if ((ifp = if_findindex(ctx->ifaces, ifam->ifam_index)) == NULL)
+ return;
+ get_addrs(ifam->ifam_addrs, ifam + 1, rti_info);
+ if (rti_info[RTAX_IFA] == NULL)
+ return;
+ switch (rti_info[RTAX_IFA]->sa_family) {
+ case AF_LINK:
+ {
+ struct sockaddr_dl sdl;
+
#ifdef RTM_CHGADDR
- if (rtm->rtm_type != RTM_CHGADDR)
- break;
+ if (ifam->ifam_type != RTM_CHGADDR)
+ break;
#else
- if (rtm->rtm_type != RTM_NEWADDR)
- break;
+ if (ifam->ifam_type != RTM_NEWADDR)
+ break;
#endif
- memcpy(&sdl, rti_info[RTAX_IFA],
- rti_info[RTAX_IFA]->sa_len);
- dhcpcd_handlehwaddr(ctx, ifp->name,
- (const unsigned char*)CLLADDR(&sdl),
- sdl.sdl_alen);
- break;
+ memcpy(&sdl, rti_info[RTAX_IFA], rti_info[RTAX_IFA]->sa_len);
+ dhcpcd_handlehwaddr(ctx, ifp->name, CLLADDR(&sdl),sdl.sdl_alen);
+ break;
+ }
#ifdef INET
- case AF_INET:
- case 255: /* FIXME: Why 255? */
- COPYOUT(rt.dest, rti_info[RTAX_IFA]);
- COPYOUT(rt.net, rti_info[RTAX_NETMASK]);
- COPYOUT(rt.gate, rti_info[RTAX_BRD]);
- if (rtm->rtm_type == RTM_NEWADDR) {
- ifa_flags = if_addrflags(&rt.dest, ifp);
- if (ifa_flags == -1)
- break;
- } else
- ifa_flags = 0;
- ipv4_handleifa(ctx, rtm->rtm_type,
- NULL, ifp->name,
- &rt.dest, &rt.net, &rt.gate, ifa_flags);
+ case AF_INET:
+ case 255: /* FIXME: Why 255? */
+ {
+ const struct sockaddr_in *sin;
+ struct in_addr addr, mask, bcast;
+ int flags;
+
+ sin = (const void *)rti_info[RTAX_IFA];
+ addr.s_addr = sin != NULL && sin->sin_family == AF_INET ?
+ sin->sin_addr.s_addr : INADDR_ANY;
+ sin = (const void *)rti_info[RTAX_NETMASK];
+ mask.s_addr = sin != NULL && sin->sin_family == AF_INET ?
+ sin->sin_addr.s_addr : INADDR_ANY;
+ sin = (const void *)rti_info[RTAX_BRD];
+ bcast.s_addr = sin != NULL && sin->sin_family == AF_INET ?
+ sin->sin_addr.s_addr : INADDR_ANY;
+ if (ifam->ifam_type == RTM_NEWADDR) {
+ if ((flags = if_addrflags(&addr, ifp)) == -1)
break;
+ } else
+ flags = 0;
+ ipv4_handleifa(ctx, ifam->ifam_type, NULL, ifp->name,
+ &addr, &mask, &bcast, flags);
+ break;
+ }
#endif
#ifdef INET6
- case AF_INET6:
- sin6 = (void *)rti_info[RTAX_IFA];
- ia6 = sin6->sin6_addr;
- DESCOPE(&ia6);
- sin6 = (void *)rti_info[RTAX_NETMASK];
- net6 = sin6->sin6_addr;
- DESCOPE(&net6);
- if (rtm->rtm_type == RTM_NEWADDR) {
- ifa_flags = if_addrflags6(&ia6, ifp);
- if (ifa_flags == -1)
- break;
- } else
- ifa_flags = 0;
- ipv6_handleifa(ctx, rtm->rtm_type, NULL,
- ifp->name, &ia6, ipv6_prefixlen(&net6),
- ifa_flags);
+ case AF_INET6:
+ {
+ struct in6_addr addr6, mask6;
+ const struct sockaddr_in6 *sin6;
+ int flags;
+
+ sin6 = (const void *)rti_info[RTAX_IFA];
+ addr6 = sin6->sin6_addr;
+ DESCOPE(&addr6);
+ sin6 = (const void *)rti_info[RTAX_NETMASK];
+ mask6 = sin6->sin6_addr;
+ DESCOPE(&mask6);
+ if (ifam->ifam_type == RTM_NEWADDR) {
+ if ((flags = if_addrflags6(&addr6, ifp)) == -1)
break;
+ } else
+ flags = 0;
+ ipv6_handleifa(ctx, ifam->ifam_type, NULL,
+ ifp->name, &addr6, ipv6_prefixlen(&mask6), flags);
+ break;
+ }
#endif
- }
- break;
- }
+ }
+}
+
+static void
+if_dispatch(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm)
+{
+
+ switch(rtm->rtm_type) {
+#ifdef RTM_IFANNOUNCE
+ case RTM_IFANNOUNCE:
+ if_announce(ctx, (const void *)rtm);
+ break;
+#endif
+ case RTM_IFINFO:
+ if_ifinfo(ctx, (const void *)rtm);
+ break;
+ case RTM_ADD: /* FALLTHROUGH */
+ case RTM_CHANGE: /* FALLTHROUGH */
+ case RTM_DELETE:
+ if_rtm(ctx, (const void *)rtm);
+ break;
+#ifdef RTM_CHGADDR
+ case RTM_CHGADDR: /* FALLTHROUGH */
+#endif
+ case RTM_DELADDR: /* FALLTHROUGH */
+ case RTM_NEWADDR:
+ if_ifa(ctx, (const void *)rtm);
+ break;
+ }
+}
+
+int
+if_handlelink(struct dhcpcd_ctx *ctx)
+{
+ /* route and ifwatchd like a msg buf size of 2048 */
+ char buf[2048];
+ const char *p, *e;
+ size_t msglen;
+ ssize_t bytes;
+ const struct rt_msghdr *rtm;
+
+ if ((bytes = read(ctx->link_fd, buf, sizeof(buf))) == -1)
+ return -1;
+ e = buf + bytes;
+ for (p = buf; p < e; p += msglen) {
+ rtm = (const void *)p;
+ msglen = rtm->rtm_msglen;
+ if_dispatch(ctx, rtm);
}
return 0;
}
Index: src/external/bsd/dhcpcd/dist/if-options.c
diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.33 src/external/bsd/dhcpcd/dist/if-options.c:1.34
--- src/external/bsd/dhcpcd/dist/if-options.c:1.33 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/if-options.c Fri Jun 17 19:42:31 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: if-options.c,v 1.33 2016/05/09 10:15:59 roy Exp $");
+ __RCSID("$NetBSD: if-options.c,v 1.34 2016/06/17 19:42:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -1093,7 +1093,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
*fp = ' ';
return -1;
}
- if (parse_addr(ctx, &rt->dest, &rt->net, p) == -1 ||
+ if (parse_addr(ctx, &rt->dest, &rt->mask, p) == -1 ||
parse_addr(ctx, &rt->gate, NULL, np) == -1)
{
free(rt);
@@ -1118,7 +1118,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
return -1;
}
rt->dest.s_addr = INADDR_ANY;
- rt->net.s_addr = INADDR_ANY;
+ rt->mask.s_addr = INADDR_ANY;
if (parse_addr(ctx, &rt->gate, NULL, p) == -1) {
free(rt);
return -1;
Index: src/external/bsd/dhcpcd/dist/ipv4.c
diff -u src/external/bsd/dhcpcd/dist/ipv4.c:1.22 src/external/bsd/dhcpcd/dist/ipv4.c:1.23
--- src/external/bsd/dhcpcd/dist/ipv4.c:1.22 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/ipv4.c Fri Jun 17 19:42:32 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4.c,v 1.22 2016/05/09 10:15:59 roy Exp $");
+ __RCSID("$NetBSD: ipv4.c,v 1.23 2016/06/17 19:42:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -116,7 +116,7 @@ ipv4_getnetmask(uint32_t addr)
struct ipv4_addr *
ipv4_iffindaddr(struct interface *ifp,
- const struct in_addr *addr, const struct in_addr *net)
+ const struct in_addr *addr, const struct in_addr *mask)
{
struct ipv4_state *state;
struct ipv4_addr *ap;
@@ -125,7 +125,7 @@ ipv4_iffindaddr(struct interface *ifp,
if (state) {
TAILQ_FOREACH(ap, &state->addrs, next) {
if ((addr == NULL || ap->addr.s_addr == addr->s_addr) &&
- (net == NULL || ap->net.s_addr == net->s_addr))
+ (mask == NULL || ap->mask.s_addr == mask->s_addr))
return ap;
}
}
@@ -157,8 +157,8 @@ ipv4_iffindmaskaddr(struct interface *if
state = IPV4_STATE(ifp);
if (state) {
TAILQ_FOREACH (ap, &state->addrs, next) {
- if ((ap->addr.s_addr & ap->net.s_addr) ==
- (addr->s_addr & ap->net.s_addr))
+ if ((ap->addr.s_addr & ap->mask.s_addr) ==
+ (addr->s_addr & ap->mask.s_addr))
return ap;
}
}
@@ -206,31 +206,33 @@ ipv4_srcaddr(const struct rt *rt, struct
/* Prefer DHCP source address if matching */
dstate = D_CSTATE(rt->iface);
- if (dstate &&
- rt->net.s_addr == dstate->net.s_addr &&
- rt->dest.s_addr == (dstate->addr.s_addr & dstate->net.s_addr))
+ if (dstate && dstate->addr &&
+ rt->mask.s_addr == dstate->addr->mask.s_addr &&
+ rt->dest.s_addr ==
+ (dstate->addr->addr.s_addr & dstate->addr->mask.s_addr))
{
- *addr = dstate->addr;
+ *addr = dstate->addr->addr;
return 1;
}
/* Then IPv4LL source address if matching */
istate = IPV4LL_CSTATE(rt->iface);
- if (istate &&
- rt->net.s_addr == inaddr_llmask.s_addr &&
- rt->dest.s_addr == (istate->addr.s_addr & inaddr_llmask.s_addr))
+ if (istate && istate->addr &&
+ rt->mask.s_addr == istate->addr->mask.s_addr &&
+ rt->dest.s_addr ==
+ (istate->addr->addr.s_addr & istate->addr->mask.s_addr))
{
- *addr = istate->addr;
+ *addr = istate->addr->addr;
return 1;
}
/* If neither match, return DHCP then IPv4LL */
- if (dstate) {
- *addr = dstate->addr;
+ if (dstate && dstate->addr) {
+ *addr = dstate->addr->addr;
return 0;
}
- if (istate) {
- *addr = istate->addr;
+ if (istate && istate->addr) {
+ *addr = istate->addr->addr;
return 0;
}
@@ -248,8 +250,8 @@ ipv4_hasaddr(const struct interface *ifp
istate = IPV4LL_CSTATE(ifp);
return ((dstate &&
dstate->added == STATE_ADDED &&
- dstate->addr.s_addr != INADDR_ANY) ||
- (istate && istate->addr.s_addr != INADDR_ANY));
+ dstate->addr != NULL) ||
+ (istate && istate->addr));
}
void
@@ -281,25 +283,6 @@ ipv4_init(struct dhcpcd_ctx *ctx)
return 0;
}
-int
-ipv4_protocol_fd(const struct interface *ifp, uint16_t protocol)
-{
-
- if (protocol == ETHERTYPE_ARP) {
- const struct iarp_state *istate;
-
- istate = ARP_CSTATE(ifp);
- assert(istate != NULL);
- return istate->fd;
- } else {
- const struct dhcp_state *dstate;
-
- dstate = D_CSTATE(ifp);
- assert(dstate != NULL);
- return dstate->raw_fd;
- }
-}
-
/* Interface comparer for working out ordering. */
int
ipv4_ifcmp(const struct interface *si, const struct interface *ti)
@@ -349,7 +332,7 @@ find_route(struct rt_head *rts, const st
rt->iface->metric == r->iface->metric)) &&
#endif
(!srt || srt != rt) &&
- rt->net.s_addr == r->net.s_addr)
+ rt->mask.s_addr == r->mask.s_addr)
return rt;
}
return NULL;
@@ -363,28 +346,28 @@ desc_route(const char *cmd, const struct
const char *ifname = rt->iface ? rt->iface->name : NULL;
strlcpy(addr, inet_ntoa(rt->dest), sizeof(addr));
- if (rt->net.s_addr == htonl(INADDR_BROADCAST) &&
+ if (rt->mask.s_addr == htonl(INADDR_BROADCAST) &&
rt->gate.s_addr == htonl(INADDR_ANY))
logger(ctx, LOG_INFO, "%s: %s host route to %s",
ifname, cmd, addr);
- else if (rt->net.s_addr == htonl(INADDR_BROADCAST))
+ else if (rt->mask.s_addr == htonl(INADDR_BROADCAST))
logger(ctx, LOG_INFO, "%s: %s host route to %s via %s",
ifname, cmd, addr, inet_ntoa(rt->gate));
else if (rt->dest.s_addr == htonl(INADDR_ANY) &&
- rt->net.s_addr == htonl(INADDR_ANY) &&
+ rt->mask.s_addr == htonl(INADDR_ANY) &&
rt->gate.s_addr == htonl(INADDR_ANY))
logger(ctx, LOG_INFO, "%s: %s default route",
ifname, cmd);
else if (rt->gate.s_addr == htonl(INADDR_ANY))
logger(ctx, LOG_INFO, "%s: %s route to %s/%d",
- ifname, cmd, addr, inet_ntocidr(rt->net));
+ ifname, cmd, addr, inet_ntocidr(rt->mask));
else if (rt->dest.s_addr == htonl(INADDR_ANY) &&
- rt->net.s_addr == htonl(INADDR_ANY))
+ rt->mask.s_addr == htonl(INADDR_ANY))
logger(ctx, LOG_INFO, "%s: %s default route via %s",
ifname, cmd, inet_ntoa(rt->gate));
else
logger(ctx, LOG_INFO, "%s: %s route to %s/%d via %s",
- ifname, cmd, addr, inet_ntocidr(rt->net),
+ ifname, cmd, addr, inet_ntocidr(rt->mask),
inet_ntoa(rt->gate));
}
@@ -403,7 +386,7 @@ ipv4_findrt(struct dhcpcd_ctx *ctx, cons
#else
(!flags || rt->iface == r->iface) &&
#endif
- rt->net.s_addr == r->net.s_addr)
+ rt->mask.s_addr == r->mask.s_addr)
return r;
}
return NULL;
@@ -467,7 +450,7 @@ nc_route(struct rt *ort, struct rt *nrt)
/* Don't set default routes if not asked to */
if (nrt->dest.s_addr == 0 &&
- nrt->net.s_addr == 0 &&
+ nrt->mask.s_addr == 0 &&
!(nrt->iface->options->options & DHCPCD_GATEWAY))
return -1;
@@ -494,7 +477,7 @@ nc_route(struct rt *ort, struct rt *nrt)
ort->metric == nrt->metric &&
#endif
ort->dest.s_addr == nrt->dest.s_addr &&
- ort->net.s_addr == nrt->net.s_addr &&
+ ort->mask.s_addr == nrt->mask.s_addr &&
ort->gate.s_addr == nrt->gate.s_addr)
{
if (ort->mtu == nrt->mtu)
@@ -562,19 +545,23 @@ d_route(struct rt *rt)
static struct rt_head *
add_subnet_route(struct rt_head *rt, const struct interface *ifp)
{
- const struct dhcp_state *s;
+ const struct dhcp_state *state;
struct rt *r;
if (rt == NULL) /* earlier malloc failed */
return NULL;
- s = D_CSTATE(ifp);
+ /* P2P interfaces don't have subnet routes as such. */
+ if (ifp->flags & IFF_POINTOPOINT)
+ return rt;
+
+ state = D_CSTATE(ifp);
/* Don't create a subnet route for these addresses */
- if (s->net.s_addr == INADDR_ANY)
+ if (state->addr->mask.s_addr == INADDR_ANY)
return rt;
#ifndef BSD
/* BSD adds a route in this instance */
- if (s->net.s_addr == INADDR_BROADCAST)
+ if (state->addr->mask.s_addr == INADDR_BROADCAST)
return rt;
#endif
@@ -583,11 +570,11 @@ add_subnet_route(struct rt_head *rt, con
ipv4_freeroutes(rt);
return NULL;
}
- r->dest.s_addr = s->addr.s_addr & s->net.s_addr;
- r->net.s_addr = s->net.s_addr;
+ r->dest.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
+ r->mask.s_addr = state->addr->mask.s_addr;
r->gate.s_addr = INADDR_ANY;
r->mtu = dhcp_get_mtu(ifp);
- r->src = s->addr;
+ r->src = state->addr->addr;
TAILQ_INSERT_HEAD(rt, r, next);
return rt;
@@ -598,13 +585,13 @@ static struct rt_head *
add_loopback_route(struct rt_head *rt, const struct interface *ifp)
{
struct rt *r;
- const struct dhcp_state *s;
+ const struct dhcp_state *state;
if (rt == NULL) /* earlier malloc failed */
return NULL;
- s = D_CSTATE(ifp);
- if (s->addr.s_addr == INADDR_ANY)
+ state = D_CSTATE(ifp);
+ if (state->addr == NULL)
return rt;
if ((r = calloc(1, sizeof(*r))) == NULL) {
@@ -612,11 +599,11 @@ add_loopback_route(struct rt_head *rt, c
ipv4_freeroutes(rt);
return NULL;
}
- r->dest = s->addr;
- r->net.s_addr = INADDR_BROADCAST;
+ r->dest = state->addr->addr;
+ r->mask.s_addr = INADDR_BROADCAST;
r->gate.s_addr = htonl(INADDR_LOOPBACK);
r->mtu = dhcp_get_mtu(ifp);
- r->src = s->addr;
+ r->src = state->addr->addr;
TAILQ_INSERT_HEAD(rt, r, next);
return rt;
}
@@ -651,7 +638,7 @@ get_routes(struct interface *ifp)
if (nrt) {
state = D_CSTATE(ifp);
TAILQ_FOREACH(rt, nrt, next) {
- rt->src = state->addr;
+ rt->src = state->addr->addr;
}
}
@@ -676,10 +663,10 @@ add_destination_route(struct rt_head *rt
return NULL;
}
r->dest.s_addr = INADDR_ANY;
- r->net.s_addr = INADDR_ANY;
- r->gate.s_addr = state->brd.s_addr;
+ r->mask.s_addr = INADDR_ANY;
+ r->gate = state->addr->brd;
r->mtu = dhcp_get_mtu(ifp);
- r->src = state->addr;
+ r->src = state->addr->addr;
TAILQ_INSERT_HEAD(rt, r, next);
return rt;
}
@@ -697,6 +684,10 @@ add_router_host_route(struct rt_head *rt
if (rt == NULL) /* earlier malloc failed */
return NULL;
+ /* Don't add a host route for these interfaces. */
+ if (ifp->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
+ return rt;
+
TAILQ_FOREACH(rtp, rt, next) {
if (rtp->dest.s_addr != INADDR_ANY)
continue;
@@ -710,8 +701,8 @@ add_router_host_route(struct rt_head *rt
/* match subnet */
cp = (const char *)&rtp->gate.s_addr;
cp2 = (const char *)&rtn->dest.s_addr;
- cp3 = (const char *)&rtn->net.s_addr;
- cplim = cp3 + sizeof(rtn->net.s_addr);
+ cp3 = (const char *)&rtn->mask.s_addr;
+ cplim = cp3 + sizeof(rtn->mask.s_addr);
while (cp3 < cplim) {
if ((*cp++ ^ *cp2++) & *cp3++)
break;
@@ -750,10 +741,10 @@ add_router_host_route(struct rt_head *rt
return NULL;
}
rtn->dest.s_addr = rtp->gate.s_addr;
- rtn->net.s_addr = htonl(INADDR_BROADCAST);
+ rtn->mask.s_addr = htonl(INADDR_BROADCAST);
rtn->gate.s_addr = htonl(INADDR_ANY);
rtn->mtu = dhcp_get_mtu(ifp);
- rtn->src = state->addr;
+ rtn->src = state->addr->addr;
TAILQ_INSERT_BEFORE(rtp, rtn, next);
}
return rt;
@@ -906,49 +897,42 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx)
}
int
-ipv4_deladdr(struct interface *ifp,
- const struct in_addr *addr, const struct in_addr *net, int keeparp)
+ipv4_deladdr(struct ipv4_addr *addr, int keeparp)
{
- struct dhcp_state *dstate;
int r;
struct ipv4_state *state;
struct ipv4_addr *ap;
struct arp_state *astate;
- uint32_t a, n;
- logger(ifp->ctx, LOG_DEBUG,
- "%s: deleting IP address %s/%d",
- ifp->name, inet_ntoa(*addr), inet_ntocidr(*net));
+ logger(addr->iface->ctx, LOG_DEBUG,
+ "%s: deleting IP address %s", addr->iface->name, addr->saddr);
- r = if_deladdress(ifp, addr, net);
+ r = if_address(RTM_DELADDR, addr);
if (r == -1 && errno != EADDRNOTAVAIL && errno != ENXIO &&
errno != ENODEV)
- logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
+ logger(addr->iface->ctx, LOG_ERR, "%s: %s: %m",
+ addr->iface->name, __func__);
- if (!keeparp && (astate = arp_find(ifp, addr)) != NULL)
+ if (!keeparp && (astate = arp_find(addr->iface, &addr->addr)) != NULL)
arp_free(astate);
- a = addr->s_addr;
- n = net->s_addr;
- state = IPV4_STATE(ifp);
+ state = IPV4_STATE(addr->iface);
TAILQ_FOREACH(ap, &state->addrs, next) {
- if (ap->addr.s_addr == addr->s_addr &&
- ap->net.s_addr == net->s_addr)
- {
+ if (IPV4_MASK_EQ(ap, addr)) {
+ struct dhcp_state *dstate;
+
+ dstate = D_STATE(ap->iface);
TAILQ_REMOVE(&state->addrs, ap, next);
free(ap);
+
+ if (dstate && dstate->addr == ap) {
+ dstate->added = 0;
+ dstate->addr = NULL;
+ }
break;
}
}
- /* Have to do this last incase the function arguments
- * were these very pointers. */
- dstate = D_STATE(ifp);
- if (dstate && dstate->addr.s_addr == a && dstate->net.s_addr == n) {
- dstate->added = 0;
- dstate->addr.s_addr = 0;
- dstate->net.s_addr = 0;
- }
return r;
}
@@ -964,7 +948,7 @@ delete_address(struct interface *ifp)
if (ifo->options & DHCPCD_INFORM ||
(ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0))
return 0;
- r = ipv4_deladdr(ifp, &state->addr, &state->net, 0);
+ r = ipv4_deladdr(state->addr, 0);
return r;
}
@@ -997,7 +981,6 @@ ipv4_addaddr(struct interface *ifp, cons
{
struct ipv4_state *state;
struct ipv4_addr *ia;
- char bcast_str[INET_ADDRSTRLEN];
if ((state = ipv4_getstate(ifp)) == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: ipv4_getstate: %m", __func__);
@@ -1008,7 +991,7 @@ ipv4_addaddr(struct interface *ifp, cons
TAILQ_FOREACH_SAFE(ia, &state->addrs, next, ian) {
if (ia->addr.s_addr != addr->s_addr)
- ipv4_deladdr(ifp, &ia->addr, &ia->net, 0);
+ ipv4_deladdr(ia, 0);
}
}
@@ -1017,10 +1000,18 @@ ipv4_addaddr(struct interface *ifp, cons
return NULL;
}
- strlcpy(bcast_str, inet_ntoa(*bcast), sizeof(bcast_str));
- logger(ifp->ctx, LOG_DEBUG, "%s: adding IP address %s/%d broadcast %s",
- ifp->name, inet_ntoa(*addr), inet_ntocidr(*mask), bcast_str);
- if (if_addaddress(ifp, addr, mask, bcast) == -1) {
+ ia->iface = ifp;
+ ia->addr = *addr;
+ ia->mask = *mask;
+ ia->brd = *bcast;
+#ifdef IN_IFF_TENTATIVE
+ ia->addr_flags = IN_IFF_TENTATIVE;
+#endif
+ snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
+ inet_ntoa(*addr), inet_ntocidr(*mask));
+ logger(ifp->ctx, LOG_DEBUG, "%s: adding IP address %s broadcast %s",
+ ifp->name, ia->saddr, inet_ntoa(*bcast));
+ if (if_address(RTM_NEWADDR, ia) == -1) {
if (errno != EEXIST)
logger(ifp->ctx, LOG_ERR, "%s: if_addaddress: %m",
__func__);
@@ -1028,13 +1019,6 @@ ipv4_addaddr(struct interface *ifp, cons
return NULL;
}
- ia->iface = ifp;
- ia->addr = *addr;
- ia->net = *mask;
- ia->brd = *bcast;
-#ifdef IN_IFF_TENTATIVE
- ia->addr_flags = IN_IFF_TENTATIVE;
-#endif
TAILQ_INSERT_TAIL(&state->addrs, ia, next);
return ia;
}
@@ -1043,16 +1027,15 @@ static int
ipv4_daddaddr(struct interface *ifp, const struct dhcp_lease *lease)
{
struct dhcp_state *state;
+ struct ipv4_addr *ia;
- if (ipv4_addaddr(ifp, &lease->addr, &lease->net, &lease->brd) == NULL)
+ ia = ipv4_addaddr(ifp, &lease->addr, &lease->mask, &lease->brd);
+ if (ia == NULL)
return -1;
state = D_STATE(ifp);
state->added = STATE_ADDED;
-
- state->addr.s_addr = lease->addr.s_addr;
- state->net.s_addr = lease->net.s_addr;
-
+ state->addr = ia;
return 0;
}
@@ -1075,7 +1058,8 @@ ipv4_preferanother(struct interface *ifp
break; /* We are already the most preferred */
nstate = D_STATE(ifn);
if (nstate && !nstate->added &&
- nstate->lease.addr.s_addr == state->addr.s_addr)
+ state->addr != NULL &&
+ nstate->lease.addr.s_addr == state->addr->addr.s_addr)
{
preferred = 1;
delete_address(ifp);
@@ -1101,7 +1085,7 @@ ipv4_applyaddr(void *arg)
struct dhcp_state *state = D_STATE(ifp), *nstate;
struct dhcp_lease *lease;
struct if_options *ifo = ifp->options;
- struct ipv4_addr *ap;
+ struct ipv4_addr *ia;
int r;
if (state == NULL)
@@ -1133,7 +1117,8 @@ ipv4_applyaddr(void *arg)
}
nstate = D_STATE(ifn);
if (nstate && nstate->added &&
- nstate->addr.s_addr == lease->addr.s_addr)
+ nstate->addr &&
+ nstate->addr->addr.s_addr == lease->addr.s_addr)
{
if (r == 0) {
logger(ifp->ctx, LOG_INFO,
@@ -1147,7 +1132,7 @@ ipv4_applyaddr(void *arg)
ifn->name,
inet_ntoa(lease->addr),
ifp->name);
- ipv4_deladdr(ifn, &nstate->addr, &nstate->net, 0);
+ ipv4_deladdr(nstate->addr, 0);
break;
}
}
@@ -1157,64 +1142,63 @@ ipv4_applyaddr(void *arg)
TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
if (ifn == ifp)
continue;
- ap = ipv4_iffindaddr(ifn, &lease->addr, NULL);
- if (ap)
- ipv4_deladdr(ifn, &ap->addr, &ap->net, 0);
+ ia = ipv4_iffindaddr(ifn, &lease->addr, NULL);
+ if (ia != NULL)
+ ipv4_deladdr(ia, 0);
}
}
/* If the netmask or broadcast is different, re-add the addresss */
- ap = ipv4_iffindaddr(ifp, &lease->addr, NULL);
- if (ap &&
- ap->net.s_addr == lease->net.s_addr &&
- ap->brd.s_addr == lease->brd.s_addr)
+ ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
+ if (ia &&
+ ia->mask.s_addr == lease->mask.s_addr &&
+ ia->brd.s_addr == lease->brd.s_addr)
logger(ifp->ctx, LOG_DEBUG,
- "%s: IP address %s/%d already exists",
- ifp->name, inet_ntoa(lease->addr),
- inet_ntocidr(lease->net));
+ "%s: IP address %s already exists",
+ ifp->name, ia->saddr);
else {
#if __linux__
/* Linux does not change netmask/broadcast address
* for re-added addresses, so we need to delete the old one
* first. */
- if (ap != NULL)
- ipv4_deladdr(ifp, &ap->addr, &ap->net, 0);
+ if (ia != NULL)
+ ipv4_deladdr(ia, 0);
#endif
r = ipv4_daddaddr(ifp, lease);
if (r == -1 && errno != EEXIST)
return;
}
-#ifdef IN_IFF_NOTUSEABLE
- ap = ipv4_iffindaddr(ifp, &lease->addr, NULL);
- if (ap == NULL) {
+ ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
+ if (ia == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: added address vanished",
ifp->name);
return;
- } else if (ap->addr_flags & IN_IFF_NOTUSEABLE)
+ }
+#ifdef IN_IFF_NOTUSEABLE
+ if (ia->addr_flags & IN_IFF_NOTUSEABLE)
return;
#endif
/* Delete the old address if different */
- if (state->addr.s_addr != lease->addr.s_addr &&
- state->addr.s_addr != 0 &&
+ if (state->addr &&
+ state->addr->addr.s_addr != lease->addr.s_addr &&
ipv4_iffindaddr(ifp, &lease->addr, NULL))
delete_address(ifp);
+ state->addr = ia;
state->added = STATE_ADDED;
- state->addr.s_addr = lease->addr.s_addr;
- state->net.s_addr = lease->net.s_addr;
/* Find any freshly added routes, such as the subnet route.
* We do this because we cannot rely on recieving the kernel
* notification right now via our link socket. */
- if_initrt(ifp);
+ if_initrt(ifp->ctx);
ipv4_buildroutes(ifp->ctx);
/* Announce the address */
if (ifo->options & DHCPCD_ARP) {
struct arp_state *astate;
- if ((astate = arp_new(ifp, &state->addr)) != NULL)
+ if ((astate = arp_new(ifp, &state->addr->addr)) != NULL)
arp_announce(astate);
}
if (state->state == DHS_BOUND) {
@@ -1226,12 +1210,12 @@ ipv4_applyaddr(void *arg)
void
ipv4_handleifa(struct dhcpcd_ctx *ctx,
int cmd, struct if_head *ifs, const char *ifname,
- const struct in_addr *addr, const struct in_addr *net,
+ const struct in_addr *addr, const struct in_addr *mask,
const struct in_addr *brd, int flags)
{
struct interface *ifp;
struct ipv4_state *state;
- struct ipv4_addr *ap;
+ struct ipv4_addr *ia;
if (ifs == NULL)
ifs = ctx->ifaces;
@@ -1239,10 +1223,6 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx,
errno = ESRCH;
return;
}
- if (addr->s_addr == INADDR_ANY) {
- errno = EINVAL;
- return;
- }
if ((ifp = if_find(ifs, ifname)) == NULL)
return;
if ((state = ipv4_getstate(ifp)) == NULL) {
@@ -1250,43 +1230,58 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx,
return;
}
- ap = ipv4_iffindaddr(ifp, addr, NULL);
- if (cmd == RTM_NEWADDR) {
- if (ap == NULL) {
- if ((ap = malloc(sizeof(*ap))) == NULL) {
+ ia = ipv4_iffindaddr(ifp, addr, NULL);
+ switch (cmd) {
+ case RTM_NEWADDR:
+ if (ia == NULL) {
+ if ((ia = malloc(sizeof(*ia))) == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return;
}
- ap->iface = ifp;
- ap->addr = *addr;
- TAILQ_INSERT_TAIL(&state->addrs, ap, next);
- }
- ap->net = *net;
- ap->brd = *brd;
- ap->addr_flags = flags;
- } else if (cmd == RTM_DELADDR) {
- if (ap) {
- TAILQ_REMOVE(&state->addrs, ap, next);
- free(ap);
- }
+ ia->iface = ifp;
+ ia->addr = *addr;
+ TAILQ_INSERT_TAIL(&state->addrs, ia, next);
+ }
+ /* Mask could have changed */
+ ia->mask = *mask;
+ snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
+ inet_ntoa(*addr), inet_ntocidr(*mask));
+ if (brd != NULL)
+ ia->brd = *brd;
+ else
+ ia->brd.s_addr = INADDR_ANY;
+ ia->addr_flags = flags;
+ break;
+ case RTM_DELADDR:
+ if (ia == NULL)
+ return;
+ TAILQ_REMOVE(&state->addrs, ia, next);
+ break;
+ default:
+ return;
}
- arp_handleifa(cmd, ifp, addr, flags);
- dhcp_handleifa(cmd, ifp, addr, net, brd, flags);
+ if (addr->s_addr != INADDR_ANY && addr->s_addr != INADDR_BROADCAST) {
+ arp_handleifa(cmd, ia);
+ dhcp_handleifa(cmd, ia);
+ }
+
+ if (cmd == RTM_DELADDR)
+ free(ia);
}
void
ipv4_free(struct interface *ifp)
{
struct ipv4_state *state;
- struct ipv4_addr *addr;
+ struct ipv4_addr *ia;
if (ifp) {
state = IPV4_STATE(ifp);
if (state) {
- while ((addr = TAILQ_FIRST(&state->addrs))) {
- TAILQ_REMOVE(&state->addrs, addr, next);
- free(addr);
+ while ((ia = TAILQ_FIRST(&state->addrs))) {
+ TAILQ_REMOVE(&state->addrs, ia, next);
+ free(ia);
}
ipv4_freerts(&state->routes);
#ifdef BSD
Index: src/external/bsd/dhcpcd/dist/ipv4ll.h
diff -u src/external/bsd/dhcpcd/dist/ipv4ll.h:1.11 src/external/bsd/dhcpcd/dist/ipv4ll.h:1.12
--- src/external/bsd/dhcpcd/dist/ipv4ll.h:1.11 Sun Apr 10 21:00:53 2016
+++ src/external/bsd/dhcpcd/dist/ipv4ll.h Fri Jun 17 19:42:32 2016
@@ -1,8 +1,8 @@
-/* $NetBSD: ipv4ll.h,v 1.11 2016/04/10 21:00:53 roy Exp $ */
+/* $NetBSD: ipv4ll.h,v 1.12 2016/06/17 19:42:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2015 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2016 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -33,19 +33,16 @@
#ifdef INET
#include "arp.h"
-extern const struct in_addr inaddr_llmask;
-extern const struct in_addr inaddr_llbcast;
-
#define LINKLOCAL_ADDR 0xa9fe0000
#define LINKLOCAL_MASK IN_CLASSB_NET
-#define LINKLOCAL_BRDC (LINKLOCAL_ADDR | ~LINKLOCAL_MASK)
+#define LINKLOCAL_BCAST (LINKLOCAL_ADDR | ~LINKLOCAL_MASK)
#ifndef IN_LINKLOCAL
# define IN_LINKLOCAL(addr) ((addr & IN_CLASSB_NET) == LINKLOCAL_ADDR)
#endif
struct ipv4ll_state {
- struct in_addr addr;
+ struct ipv4_addr *addr;
struct arp_state *arp;
unsigned int conflicts;
struct timespec defend;
@@ -58,8 +55,8 @@ struct ipv4ll_state {
#define IPV4LL_CSTATE(ifp) \
((const struct ipv4ll_state *)(ifp)->if_data[IF_DATA_IPV4LL])
#define IPV4LL_STATE_RUNNING(ifp) \
- (IPV4LL_CSTATE((ifp)) && !IPV4LL_CSTATE((ifp))->down && \
- IN_LINKLOCAL(ntohl(IPV4LL_CSTATE((ifp))->addr.s_addr)))
+ (IPV4LL_CSTATE((ifp)) && !IPV4LL_CSTATE((ifp))->down && \
+ (IPV4LL_CSTATE((ifp))->addr != NULL))
struct rt* ipv4ll_subnet_route(const struct interface *);
struct rt* ipv4ll_default_route(const struct interface *);
Index: src/external/bsd/dhcpcd/dist/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/ipv6.c:1.18 src/external/bsd/dhcpcd/dist/ipv6.c:1.19
--- src/external/bsd/dhcpcd/dist/ipv6.c:1.18 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/ipv6.c Fri Jun 17 19:42:32 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6.c,v 1.18 2016/05/09 10:15:59 roy Exp $");
+ __RCSID("$NetBSD: ipv6.c,v 1.19 2016/06/17 19:42:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -592,9 +592,9 @@ ipv6_deleteaddr(struct ipv6_addr *ia)
logger(ia->iface->ctx, LOG_INFO, "%s: deleting address %s",
ia->iface->name, ia->saddr);
- if (if_deladdress6(ia) == -1 &&
+ if (if_address6(RTM_DELADDR, ia) == -1 &&
errno != EADDRNOTAVAIL && errno != ENXIO && errno != ENODEV)
- logger(ia->iface->ctx, LOG_ERR, "if_deladdress6: :%m");
+ logger(ia->iface->ctx, LOG_ERR, "if_address6: :%m");
/* NOREJECT is set if we delegated exactly the prefix to another
* address.
@@ -704,7 +704,7 @@ ipv6_addaddr(struct ipv6_addr *ap, const
#endif
}
- if (if_addaddress6(ap) == -1) {
+ if (if_address6(RTM_NEWADDR, ap) == -1) {
logger(ap->iface->ctx, LOG_ERR, "if_addaddress6: %m");
/* Restore real pltime and vltime */
ap->prefix_pltime = pltime;
@@ -827,10 +827,10 @@ ipv6_addaddrs(struct ipv6_addrhead *addr
apf->iface->name,
ap->saddr,
ap->iface->name);
- if (if_deladdress6(apf) == -1 &&
+ if (if_address6(RTM_DELADDR, apf) == -1 &&
errno != EADDRNOTAVAIL && errno != ENXIO)
logger(apf->iface->ctx, LOG_ERR,
- "if_deladdress6: %m");
+ "if_address6: %m");
apf->flags &=
~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED);
} else if (apf)
@@ -1453,7 +1453,7 @@ ipv6_startstatic(struct interface *ifp)
ia->prefix_pltime = ND6_INFINITE_LIFETIME;
ia->dadcallback = ipv6_staticdadcallback;
ipv6_addaddr(ia, NULL);
- if_initrt6(ifp);
+ if_initrt6(ifp->ctx);
ipv6_buildroutes(ifp->ctx);
if (run_script)
script_runreason(ifp, "STATIC6");
@@ -1476,7 +1476,7 @@ ipv6_start(struct interface *ifp)
}
/* Load existing routes */
- if_initrt6(ifp);
+ if_initrt6(ifp->ctx);
if (!IN6_IS_ADDR_UNSPECIFIED(&ifp->options->req_addr6))
ipv6_buildroutes(ifp->ctx);
return 0;
@@ -1497,7 +1497,7 @@ ipv6_freedrop(struct interface *ifp, int
ipv6_freedrop_addrs(&state->addrs, drop ? 2 : 0, NULL);
if (drop) {
if (ifp->ctx->ipv6 != NULL) {
- if_initrt6(ifp);
+ if_initrt6(ifp->ctx);
ipv6_buildroutes(ifp->ctx);
}
} else {
@@ -1955,7 +1955,7 @@ find_route6(struct rt6_head *rts, const
(r->iface == NULL || rt->iface == NULL ||
rt->iface->metric == r->iface->metric) &&
#endif
- IN6_ARE_ADDR_EQUAL(&rt->net, &r->net))
+ IN6_ARE_ADDR_EQUAL(&rt->mask, &r->mask))
return rt;
}
return NULL;
@@ -1975,16 +1975,16 @@ desc_route(const char *cmd, const struct
gate = inet_ntop(AF_INET6, &rt->gate, gatebuf, INET6_ADDRSTRLEN);
if (IN6_ARE_ADDR_EQUAL(&rt->gate, &in6addr_any))
logger(ctx, LOG_INFO, "%s: %s route to %s/%d",
- ifname, cmd, dest, ipv6_prefixlen(&rt->net));
+ ifname, cmd, dest, ipv6_prefixlen(&rt->mask));
else if (IN6_ARE_ADDR_EQUAL(&rt->dest, &in6addr_any) &&
- IN6_ARE_ADDR_EQUAL(&rt->net, &in6addr_any))
+ IN6_ARE_ADDR_EQUAL(&rt->mask, &in6addr_any))
logger(ctx, LOG_INFO, "%s: %s default route via %s",
ifname, cmd, gate);
else
logger(ctx, LOG_INFO, "%s: %s%s route to %s/%d via %s",
ifname, cmd,
rt->flags & RTF_REJECT ? " reject" : "",
- dest, ipv6_prefixlen(&rt->net), gate);
+ dest, ipv6_prefixlen(&rt->mask), gate);
}
static struct rt6*
@@ -2002,7 +2002,7 @@ ipv6_findrt(struct dhcpcd_ctx *ctx, cons
(!flags || rt->iface == r->iface ||
(rt->flags & RTF_REJECT && r->flags & RTF_REJECT)) &&
#endif
- IN6_ARE_ADDR_EQUAL(&rt->net, &r->net))
+ IN6_ARE_ADDR_EQUAL(&rt->mask, &r->mask))
return r;
}
return NULL;
@@ -2064,7 +2064,7 @@ nc_route(struct rt6 *ort, struct rt6 *nr
/* Don't set default routes if not asked to */
if (IN6_IS_ADDR_UNSPECIFIED(&nrt->dest) &&
- IN6_IS_ADDR_UNSPECIFIED(&nrt->net) &&
+ IN6_IS_ADDR_UNSPECIFIED(&nrt->mask) &&
!(nrt->iface->options->options & DHCPCD_GATEWAY))
return -1;
@@ -2208,7 +2208,7 @@ make_prefix(const struct interface *ifp,
if (r == NULL)
return NULL;
r->dest = addr->prefix;
- ipv6_mask(&r->net, addr->prefix_len);
+ ipv6_mask(&r->mask, addr->prefix_len);
if (addr->flags & IPV6_AF_DELEGATEDPFX) {
r->flags |= RTF_REJECT;
r->gate = in6addr_loopback;
@@ -2226,14 +2226,14 @@ make_router(const struct ra *rap)
if (r == NULL)
return NULL;
r->dest = in6addr_any;
- r->net = in6addr_any;
+ r->mask = in6addr_any;
r->gate = rap->from;
return r;
}
#define RT_IS_DEFAULT(rtp) \
(IN6_ARE_ADDR_EQUAL(&((rtp)->dest), &in6addr_any) && \
- IN6_ARE_ADDR_EQUAL(&((rtp)->net), &in6addr_any))
+ IN6_ARE_ADDR_EQUAL(&((rtp)->mask), &in6addr_any))
static void
ipv6_build_static_routes(struct dhcpcd_ctx *ctx, struct rt6_head *dnr)
Index: src/external/bsd/dhcpcd/dist/ipv6.h
diff -u src/external/bsd/dhcpcd/dist/ipv6.h:1.18 src/external/bsd/dhcpcd/dist/ipv6.h:1.19
--- src/external/bsd/dhcpcd/dist/ipv6.h:1.18 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/ipv6.h Fri Jun 17 19:42:32 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6.h,v 1.18 2016/05/09 10:15:59 roy Exp $ */
+/* $NetBSD: ipv6.h,v 1.19 2016/06/17 19:42:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -183,14 +183,15 @@ struct ipv6_addr {
#define IPV6_AF_NOREJECT 0x0200
#define IPV6_AF_REQUEST 0x0400
#define IPV6_AF_STATIC 0x0800
+#define IPV6_AF_DELEGATEDLOG 0x1000
#ifdef IPV6_MANAGETEMPADDR
-#define IPV6_AF_TEMPORARY 0X1000
+#define IPV6_AF_TEMPORARY 0X2000
#endif
struct rt6 {
TAILQ_ENTRY(rt6) next;
struct in6_addr dest;
- struct in6_addr net;
+ struct in6_addr mask;
struct in6_addr gate;
const struct interface *iface;
unsigned int flags;
Index: src/external/bsd/dhcpcd/dist/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.29 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.30
--- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.29 Wed Apr 20 08:53:01 2016
+++ src/external/bsd/dhcpcd/dist/ipv6nd.c Fri Jun 17 19:42:32 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6nd.c,v 1.29 2016/04/20 08:53:01 roy Exp $");
+ __RCSID("$NetBSD: ipv6nd.c,v 1.30 2016/06/17 19:42:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -258,15 +258,6 @@ ipv6nd_makersprobe(struct interface *ifp
return 0;
}
-static void ipv6nd_dropdhcp6(struct interface *ifp)
-{
- const struct dhcp6_state *d6;
-
- /* Don't drop DHCP6 if the interface is delegated to. */
- if ((d6 = D6_CSTATE(ifp)) != NULL && d6->state != DH6S_DELEGATED)
- dhcp6_drop(ifp, "EXPIRE6");
-}
-
static void
ipv6nd_sendrsprobe(void *arg)
{
@@ -330,7 +321,7 @@ ipv6nd_sendrsprobe(void *arg)
logger(ifp->ctx, LOG_WARNING,
"%s: no IPv6 Routers available", ifp->name);
ipv6nd_drop(ifp);
- ipv6nd_dropdhcp6(ifp);
+ dhcp6_dropnondelegates(ifp);
}
}
@@ -660,9 +651,9 @@ ipv6nd_dadcallback(void *arg)
}
logger(ifp->ctx, LOG_INFO, "%s: deleting address %s",
ifp->name, ap->saddr);
- if (if_deladdress6(ap) == -1 &&
+ if (if_address6(RTM_DELADDR, ap) == -1 &&
errno != EADDRNOTAVAIL && errno != ENXIO)
- logger(ifp->ctx, LOG_ERR, "if_deladdress6: %m");
+ logger(ifp->ctx, LOG_ERR, "if_address6: %m");
dadcounter = ap->dadcounter;
if (ipv6_makestableprivate(&ap->addr,
&ap->prefix, ap->prefix_len,
@@ -1102,7 +1093,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
/* Find any freshly added routes, such as the subnet route.
* We do this because we cannot rely on recieving the kernel
* notification right now via our link socket. */
- if_initrt6(ifp);
+ if_initrt6(ifp->ctx);
ipv6_buildroutes(ifp->ctx);
if (ipv6nd_scriptrun(rap))
@@ -1395,7 +1386,7 @@ ipv6nd_expirera(void *arg)
/* No valid routers? Kill any DHCPv6. */
if (!validone)
- ipv6nd_dropdhcp6(ifp);
+ dhcp6_dropnondelegates(ifp);
}
void
Index: src/external/bsd/dhcpcd/dist/script.c
diff -u src/external/bsd/dhcpcd/dist/script.c:1.26 src/external/bsd/dhcpcd/dist/script.c:1.27
--- src/external/bsd/dhcpcd/dist/script.c:1.26 Mon May 9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/script.c Fri Jun 17 19:42:32 2016
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: script.c,v 1.26 2016/05/09 10:15:59 roy Exp $");
+ __RCSID("$NetBSD: script.c,v 1.27 2016/06/17 19:42:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -264,7 +264,7 @@ make_env(const struct interface *ifp, co
ra = 1;
#endif
#ifdef INET
- else if (istate && istate->addr.s_addr != INADDR_ANY)
+ else if (istate && istate->addr != NULL)
ipv4ll = 1;
else
dhcp = 1;
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.8 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.9
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.8 Fri Aug 21 10:39:00 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf Fri Jun 17 19:42:32 2016
@@ -1,4 +1,4 @@
-# $NetBSD: 20-resolv.conf,v 1.8 2015/08/21 10:39:00 roy Exp $
+# $NetBSD: 20-resolv.conf,v 1.9 2016/06/17 19:42:32 roy Exp $
# Generate /etc/resolv.conf
# Support resolvconf(8) if available
@@ -94,8 +94,8 @@ eval_nd_dns()
[ -z "$rdnss" -a -z "$dnssl" ] && return 1
- new_rdnss="$new_rdnss${new_rdnss:+ }$rdnss"
- new_dnssl="$new_dnssl${new_dnssl:+ }$dnssl"
+ [ -n "$rdnss" ] && new_rdnss="$new_rdnss${new_rdnss:+ }$rdnss"
+ [ -n "$dnssl" ] && new_dnssl="$new_dnssl${new_dnssl:+ }$dnssl"
j=$(($j + 1))
return 0
}
@@ -116,8 +116,10 @@ add_resolv_conf()
j=1
eval_nd_dns || break
done
- new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss"
- new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl"
+ [ -n "$new_rdnss" ] && \
+ new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss"
+ [ -n "$new_dnssl" ] && \
+ new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl"
# Derive a new domain from our various hostname options
if [ -z "$new_domain_name" ]; then
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.7 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.8
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.7 Fri Aug 21 10:39:00 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname Fri Jun 17 19:42:32 2016
@@ -1,4 +1,4 @@
-# $NetBSD: 30-hostname,v 1.7 2015/08/21 10:39:00 roy Exp $
+# $NetBSD: 30-hostname,v 1.8 2016/06/17 19:42:32 roy Exp $
# Set the hostname from DHCP data if required
@@ -68,7 +68,7 @@ need_hostname()
case "$hostname_fqdn" in
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) hfqdn=true;;
- [Ss][Ee][Rr][Vv][Ee][Rr]) ;;
+ ""|[Ss][Ee][Rr][Vv][Ee][Rr]) ;;
*) hshort=true;;
esac
@@ -117,7 +117,7 @@ set_hostname()
case "$hostname_fqdn" in
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) hfqdn=true;;
- "") ;;
+ ""|[Ss][Ee][Rr][Vv][Ee][Rr]) ;;
*) hshort=true;;
esac