Module Name: src
Committed By: roy
Date: Fri Apr 21 16:54:26 UTC 2023
Modified Files:
src/external/bsd/dhcpcd/dist/hooks: 20-resolv.conf 29-lookup-hostname
30-hostname 50-ntp.conf
src/external/bsd/dhcpcd/dist/src: bpf.c dhcp.c dhcp6.c dhcpcd.c
if-bsd.c if-options.c ipv6.c ipv6.h ipv6nd.c logerr.c privsep.c
script.c
Log Message:
Merge changes
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/external/bsd/dhcpcd/dist/hooks/20-resolv.conf
cvs rdiff -u -r1.2 -r1.3 \
src/external/bsd/dhcpcd/dist/hooks/29-lookup-hostname
cvs rdiff -u -r1.5 -r1.6 src/external/bsd/dhcpcd/dist/hooks/30-hostname \
src/external/bsd/dhcpcd/dist/hooks/50-ntp.conf
cvs rdiff -u -r1.18 -r1.19 src/external/bsd/dhcpcd/dist/src/bpf.c
cvs rdiff -u -r1.46 -r1.47 src/external/bsd/dhcpcd/dist/src/dhcp.c
cvs rdiff -u -r1.28 -r1.29 src/external/bsd/dhcpcd/dist/src/dhcp6.c \
src/external/bsd/dhcpcd/dist/src/ipv6nd.c
cvs rdiff -u -r1.49 -r1.50 src/external/bsd/dhcpcd/dist/src/dhcpcd.c
cvs rdiff -u -r1.27 -r1.28 src/external/bsd/dhcpcd/dist/src/if-bsd.c
cvs rdiff -u -r1.32 -r1.33 src/external/bsd/dhcpcd/dist/src/if-options.c
cvs rdiff -u -r1.17 -r1.18 src/external/bsd/dhcpcd/dist/src/ipv6.c
cvs rdiff -u -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/src/ipv6.h \
src/external/bsd/dhcpcd/dist/src/privsep.c
cvs rdiff -u -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/src/logerr.c
cvs rdiff -u -r1.14 -r1.15 src/external/bsd/dhcpcd/dist/src/script.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/external/bsd/dhcpcd/dist/hooks/20-resolv.conf
diff -u src/external/bsd/dhcpcd/dist/hooks/20-resolv.conf:1.6 src/external/bsd/dhcpcd/dist/hooks/20-resolv.conf:1.7
--- src/external/bsd/dhcpcd/dist/hooks/20-resolv.conf:1.6 Mon Dec 28 13:57:40 2020
+++ src/external/bsd/dhcpcd/dist/hooks/20-resolv.conf Fri Apr 21 16:54:26 2023
@@ -11,7 +11,7 @@ nocarrier_roaming_dir="$state_dir/roamin
NL="
"
: ${resolvconf:=resolvconf}
-if type "$resolvconf" >/dev/null 2>&1; then
+if command -v "$resolvconf" >/dev/null 2>&1; then
have_resolvconf=true
else
have_resolvconf=false
Index: src/external/bsd/dhcpcd/dist/hooks/29-lookup-hostname
diff -u src/external/bsd/dhcpcd/dist/hooks/29-lookup-hostname:1.2 src/external/bsd/dhcpcd/dist/hooks/29-lookup-hostname:1.3
--- src/external/bsd/dhcpcd/dist/hooks/29-lookup-hostname:1.2 Sat Sep 22 13:17:46 2018
+++ src/external/bsd/dhcpcd/dist/hooks/29-lookup-hostname Fri Apr 21 16:54:26 2023
@@ -4,20 +4,20 @@ lookup_hostname()
{
[ -z "$new_ip_address" ] && return 1
# Silly ISC programs love to send error text to stdout
- if type dig >/dev/null 2>&1; then
+ if command -v dig >/dev/null 2>&1; then
h=$(dig +short -x $new_ip_address)
if [ $? = 0 ]; then
echo "$h" | sed 's/\.$//'
return 0
fi
- elif type host >/dev/null 2>&1; then
+ elif command -v host >/dev/null 2>&1; then
h=$(host $new_ip_address)
if [ $? = 0 ]; then
echo "$h" \
| sed 's/.* domain name pointer \(.*\)./\1/'
return 0
fi
- elif type getent >/dev/null 2>&1; then
+ elif command -v getent >/dev/null 2>&1; then
h=$(getent hosts $new_ip_address)
if [ $? = 0 ]; then
echo "$h" | sed 's/[^ ]* *\([^ ]*\).*/\1/'
Index: src/external/bsd/dhcpcd/dist/hooks/30-hostname
diff -u src/external/bsd/dhcpcd/dist/hooks/30-hostname:1.5 src/external/bsd/dhcpcd/dist/hooks/30-hostname:1.6
--- src/external/bsd/dhcpcd/dist/hooks/30-hostname:1.5 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/hooks/30-hostname Fri Apr 21 16:54:26 2023
@@ -25,7 +25,7 @@ _hostname()
if [ -z "${1+x}" ]; then
if [ -r /proc/sys/kernel/hostname ]; then
read name </proc/sys/kernel/hostname && echo "$name"
- elif type hostname >/dev/null 2>/dev/null; then
+ elif command -v hostname >/dev/null 2>/dev/null; then
hostname
elif sysctl kern.hostname >/dev/null 2>&1; then
sysctl -n kern.hostname
@@ -39,7 +39,7 @@ _hostname()
if [ -w /proc/sys/kernel/hostname ]; then
echo "$1" >/proc/sys/kernel/hostname
- elif [ -n "$1" ] && type hostname >/dev/null 2>&1; then
+ elif [ -n "$1" ] && command -v hostname >/dev/null 2>&1; then
hostname "$1"
elif sysctl kern.hostname >/dev/null 2>&1; then
sysctl -w "kern.hostname=$1" >/dev/null
Index: src/external/bsd/dhcpcd/dist/hooks/50-ntp.conf
diff -u src/external/bsd/dhcpcd/dist/hooks/50-ntp.conf:1.5 src/external/bsd/dhcpcd/dist/hooks/50-ntp.conf:1.6
--- src/external/bsd/dhcpcd/dist/hooks/50-ntp.conf:1.5 Fri Nov 20 13:24:58 2020
+++ src/external/bsd/dhcpcd/dist/hooks/50-ntp.conf Fri Apr 21 16:54:26 2023
@@ -43,7 +43,7 @@ fi
# Debian has a separate file for DHCP config to avoid stamping on
# the master.
-if [ "$ntp_service" = ntpd ] && type invoke-rc.d >/dev/null 2>&1; then
+if [ "$ntp_service" = ntpd ] && command -v invoke-rc.d >/dev/null 2>&1; then
[ -e /var/lib/ntp ] || mkdir /var/lib/ntp
: ${ntp_service:=ntp}
: ${NTP_DHCP_CONF:=/var/lib/ntp/ntp.conf.dhcp}
@@ -113,7 +113,7 @@ add_ntp_conf()
[ -e "$cf" ] && rm "$cf"
[ -d "$ntp_conf_dir" ] || mkdir -p "$ntp_conf_dir"
if [ -n "$new_ntp_servers" ]; then
- for x in $new_ntp_servers; do
+ for x in $(uniqify $new_ntp_servers); do
echo "server $x" >> "$cf"
done
fi
@@ -131,7 +131,7 @@ remove_ntp_conf()
# For ease of use, map DHCP6 names onto our DHCP4 names
case "$reason" in
BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
- new_ntp_servers="$new_dhcp6_sntp_servers"
+ new_ntp_servers="$new_dhcp6_sntp_servers $new_dhcp6_ntp_server_addr $new_dhcp6_ntp_server_fqdn"
;;
esac
Index: src/external/bsd/dhcpcd/dist/src/bpf.c
diff -u src/external/bsd/dhcpcd/dist/src/bpf.c:1.18 src/external/bsd/dhcpcd/dist/src/bpf.c:1.19
--- src/external/bsd/dhcpcd/dist/src/bpf.c:1.18 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/bpf.c Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* dhcpcd: BPF arp and bootp filtering
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,6 @@
#include <errno.h>
#include <fcntl.h>
-#include <paths.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@@ -155,6 +154,11 @@ bpf_open(const struct interface *ifp,
struct bpf_version pv = { .bv_major = 0, .bv_minor = 0 };
struct ifreq ifr = { .ifr_flags = 0 };
int ibuf_len = 0;
+#ifdef O_CLOEXEC
+#define BPF_OPEN_FLAGS O_RDWR | O_NONBLOCK | O_CLOEXEC
+#else
+#define BPF_OPEN_FLAGS O_RDWR | O_NONBLOCK
+#endif
#ifdef BIOCIMMEDIATE
unsigned int flags;
#endif
@@ -167,25 +171,19 @@ bpf_open(const struct interface *ifp,
return NULL;
bpf->bpf_ifp = ifp;
-#ifdef _PATH_BPF
- bpf->bpf_fd = open(_PATH_BPF, O_RDWR | O_NONBLOCK
-#ifdef O_CLOEXEC
- | O_CLOEXEC
-#endif
- );
-#else
- char device[32];
- int n = 0;
+ /* /dev/bpf is a cloner on modern kernels */
+ bpf->bpf_fd = open("/dev/bpf", BPF_OPEN_FLAGS);
- do {
- snprintf(device, sizeof(device), "/dev/bpf%d", n++);
- bpf->bpf_fd = open(device, O_RDWR | O_NONBLOCK
-#ifdef O_CLOEXEC
- | O_CLOEXEC
-#endif
- );
- } while (bpf->bpf_fd == -1 && errno == EBUSY);
-#endif
+ /* Support older kernels where /dev/bpf is not a cloner */
+ if (bpf->bpf_fd == -1) {
+ char device[32];
+ int n = 0;
+
+ do {
+ snprintf(device, sizeof(device), "/dev/bpf%d", n++);
+ bpf->bpf_fd = open(device, BPF_OPEN_FLAGS);
+ } while (bpf->bpf_fd == -1 && errno == EBUSY);
+ }
if (bpf->bpf_fd == -1)
goto eexit;
Index: src/external/bsd/dhcpcd/dist/src/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcp.c:1.46 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.47
--- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.46 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/dhcp.c Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -84,11 +84,6 @@
/* We should define a maximum for the NAK exponential backoff */
#define NAKOFF_MAX 60
-/* Wait N nanoseconds between sending a RELEASE and dropping the address.
- * This gives the kernel enough time to actually send it. */
-#define RELEASE_DELAY_S 0
-#define RELEASE_DELAY_NS 10000000
-
#ifndef IPDEFTTL
#define IPDEFTTL 64 /* RFC1340 */
#endif
@@ -137,7 +132,7 @@ static void dhcp_arp_found(struct arp_st
#endif
static void dhcp_handledhcp(struct interface *, struct bootp *, size_t,
const struct in_addr *);
-static void dhcp_handleifudp(void *);
+static void dhcp_handleifudp(void *, unsigned short);
static int dhcp_initstate(struct interface *);
void
@@ -400,7 +395,7 @@ print_rfc3442(FILE *fp, const uint8_t *d
static int
decode_rfc3442_rt(rb_tree_t *routes, struct interface *ifp,
- const uint8_t *data, size_t dl, const struct bootp *bootp)
+ const uint8_t *data, size_t dl)
{
const uint8_t *p = data;
const uint8_t *e;
@@ -447,15 +442,6 @@ decode_rfc3442_rt(rb_tree_t *routes, str
memcpy(&gateway.s_addr, p, 4);
p += 4;
- /* An on-link host route is normally set by having the
- * gateway match the destination or assigned address */
- if (gateway.s_addr == dest.s_addr ||
- (gateway.s_addr == bootp->yiaddr ||
- gateway.s_addr == bootp->ciaddr))
- {
- gateway.s_addr = INADDR_ANY;
- netmask.s_addr = INADDR_BROADCAST;
- }
if (netmask.s_addr == INADDR_BROADCAST)
rt->rt_flags = RTF_HOST;
@@ -594,7 +580,7 @@ get_option_routes(rb_tree_t *routes, str
if (p)
csr = "MS ";
}
- if (p && (n = decode_rfc3442_rt(routes, ifp, p, len, bootp)) != -1) {
+ if (p && (n = decode_rfc3442_rt(routes, ifp, p, len)) != -1) {
const struct dhcp_state *state;
state = D_CSTATE(ifp);
@@ -782,7 +768,7 @@ make_message(struct bootp **bootpm, cons
bootp->op = BOOTREQUEST;
bootp->htype = (uint8_t)ifp->hwtype;
- if (ifp->hwlen != 0 && ifp->hwlen < sizeof(bootp->chaddr)) {
+ if (ifp->hwlen != 0 && ifp->hwlen <= sizeof(bootp->chaddr)) {
bootp->hlen = (uint8_t)ifp->hwlen;
memcpy(&bootp->chaddr, &ifp->hwaddr, ifp->hwlen);
}
@@ -2005,7 +1991,7 @@ dhcp_finish_dad(struct interface *ifp, s
{
struct dhcp_state *state = D_STATE(ifp);
- if (state->state != DHS_PROBE)
+ if (state->state == DHS_BOUND)
return;
if (state->offer == NULL || state->offer->yiaddr != ia->s_addr)
return;
@@ -2407,7 +2393,9 @@ openudp:
dhcp_openbpf(ifp);
return;
}
- eloop_event_add(ctx->eloop, state->udp_rfd, dhcp_handleifudp, ifp);
+ if (eloop_event_add(ctx->eloop, state->udp_rfd, ELE_READ,
+ dhcp_handleifudp, ifp) == -1)
+ logerr("%s: eloop_event_add", __func__);
}
static size_t
@@ -2753,12 +2741,8 @@ dhcp_reboot(struct interface *ifp)
void
dhcp_drop(struct interface *ifp, const char *reason)
{
- struct dhcp_state *state;
-#ifdef RELEASE_SLOW
- struct timespec ts;
-#endif
+ struct dhcp_state *state = D_STATE(ifp);
- state = D_STATE(ifp);
/* dhcp_start may just have been called and we don't yet have a state
* but we do have a timeout, so punt it. */
if (state == NULL || state->state == DHS_NONE) {
@@ -2792,12 +2776,6 @@ dhcp_drop(struct interface *ifp, const c
ifp->name, inet_ntoa(state->lease.addr));
dhcp_new_xid(ifp);
send_message(ifp, DHCP_RELEASE, NULL);
-#ifdef RELEASE_SLOW
- /* Give the packet a chance to go */
- ts.tv_sec = RELEASE_DELAY_S;
- ts.tv_nsec = RELEASE_DELAY_NS;
- nanosleep(&ts, NULL);
-#endif
}
}
#ifdef AUTH
@@ -2818,10 +2796,6 @@ dhcp_drop(struct interface *ifp, const c
dhcp_auth_reset(&state->auth);
#endif
- /* Close DHCP ports so a changed interface family is picked
- * up by a new BPF state. */
- dhcp_close(ifp);
-
state->state = DHS_NONE;
free(state->offer);
state->offer = NULL;
@@ -2845,6 +2819,10 @@ dhcp_drop(struct interface *ifp, const c
state->lease.addr.s_addr = 0;
ifp->options->options &= ~(DHCPCD_CSR_WARNED |
DHCPCD_ROUTER_HOST_ROUTE_WARNED);
+
+ /* Close DHCP ports so a changed interface family is picked
+ * up by a new BPF state. */
+ dhcp_close(ifp);
}
static int
@@ -3623,7 +3601,7 @@ dhcp_packet(struct interface *ifp, uint8
}
static void
-dhcp_readbpf(void *arg)
+dhcp_readbpf(void *arg, unsigned short events)
{
struct interface *ifp = arg;
uint8_t buf[FRAMELEN_MAX];
@@ -3631,6 +3609,9 @@ dhcp_readbpf(void *arg)
struct dhcp_state *state = D_STATE(ifp);
struct bpf *bpf = state->bpf;
+ if (events != ELE_READ)
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
bpf->bpf_flags &= ~BPF_EOF;
while (!(bpf->bpf_flags & BPF_EOF)) {
bytes = bpf_read(bpf, buf, sizeof(buf));
@@ -3694,7 +3675,8 @@ dhcp_recvmsg(struct dhcpcd_ctx *ctx, str
}
static void
-dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp)
+dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp,
+ unsigned short events)
{
const struct dhcp_state *state;
struct sockaddr_in from;
@@ -3722,6 +3704,9 @@ dhcp_readudp(struct dhcpcd_ctx *ctx, str
int s;
ssize_t bytes;
+ if (events != ELE_READ)
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
if (ifp != NULL) {
state = D_CSTATE(ifp);
s = state->udp_rfd;
@@ -3739,19 +3724,19 @@ dhcp_readudp(struct dhcpcd_ctx *ctx, str
}
static void
-dhcp_handleudp(void *arg)
+dhcp_handleudp(void *arg, unsigned short events)
{
struct dhcpcd_ctx *ctx = arg;
- dhcp_readudp(ctx, NULL);
+ dhcp_readudp(ctx, NULL, events);
}
static void
-dhcp_handleifudp(void *arg)
+dhcp_handleifudp(void *arg, unsigned short events)
{
struct interface *ifp = arg;
- dhcp_readudp(ifp->ctx, ifp);
+ dhcp_readudp(ifp->ctx, ifp, events);
}
static int
@@ -3786,8 +3771,9 @@ dhcp_openbpf(struct interface *ifp)
return -1;
}
- eloop_event_add(ifp->ctx->eloop,
- state->bpf->bpf_fd, dhcp_readbpf, ifp);
+ if (eloop_event_add(ifp->ctx->eloop, state->bpf->bpf_fd, ELE_READ,
+ dhcp_readbpf, ifp) == -1)
+ logerr("%s: eloop_event_add", __func__);
return 0;
}
@@ -3833,6 +3819,7 @@ dhcp_free(struct interface *ifp)
free(ctx->opt_buffer);
ctx->opt_buffer = NULL;
+ ctx->opt_buffer_len = 0;
}
}
@@ -3963,7 +3950,9 @@ dhcp_start1(void *arg)
logerr(__func__);
return;
}
- eloop_event_add(ctx->eloop, ctx->udp_rfd, dhcp_handleudp, ctx);
+ if (eloop_event_add(ctx->eloop, ctx->udp_rfd, ELE_READ,
+ dhcp_handleudp, ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
}
if (!IN_PRIVSEP(ctx) && ctx->udp_wfd == -1) {
ctx->udp_wfd = xsocket(PF_INET, SOCK_RAW|SOCK_CXNB,IPPROTO_UDP);
Index: src/external/bsd/dhcpcd/dist/src/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.28 src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.29
--- src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.28 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/dhcp6.c Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -147,12 +147,18 @@ struct dhcp_compat {
uint16_t dhcp6_opt;
};
+/*
+ * RFC 5908 deprecates OPTION_SNTP_SERVERS.
+ * But we can support both as the hook scripts will uniqify the
+ * results if the server returns both options.
+ */
static const struct dhcp_compat dhcp_compats[] = {
{ DHO_DNSSERVER, D6_OPTION_DNS_SERVERS },
{ DHO_HOSTNAME, D6_OPTION_FQDN },
{ DHO_DNSDOMAIN, D6_OPTION_FQDN },
{ DHO_NISSERVER, D6_OPTION_NIS_SERVERS },
{ DHO_NTPSERVER, D6_OPTION_SNTP_SERVERS },
+ { DHO_NTPSERVER, D6_OPTION_NTP_SERVER },
{ DHO_RAPIDCOMMIT, D6_OPTION_RAPID_COMMIT },
{ DHO_FQDN, D6_OPTION_FQDN },
{ DHO_VIVCO, D6_OPTION_VENDOR_CLASS },
@@ -173,7 +179,7 @@ static const char * const dhcp6_statuses
static void dhcp6_bind(struct interface *, const char *, const char *);
static void dhcp6_failinform(void *);
-static void dhcp6_recvaddr(void *);
+static void dhcp6_recvaddr(void *, unsigned short);
static void dhcp6_startdecline(struct interface *);
#ifdef SMALL
@@ -962,6 +968,8 @@ dhcp6_makemessage(struct interface *ifp)
else
ia_na_len = sizeof(ia_na);
memcpy(ia_na.iaid, ifia->iaid, sizeof(ia_na.iaid));
+ /* RFC 8415 21.4 and 21.21 state that T1 and T2 should be zero.
+ * An RFC compliant server MUST ignore them anyway. */
ia_na.t1 = 0;
ia_na.t2 = 0;
COPYIN(ifia->ia_type, &ia_na, ia_na_len);
@@ -980,11 +988,16 @@ dhcp6_makemessage(struct interface *ifp)
continue;
if (ap->ia_type == D6_OPTION_IA_PD) {
#ifndef SMALL
- struct dhcp6_pd_addr pdp;
+ struct dhcp6_pd_addr pdp = {
+ .prefix_len = ap->prefix_len,
+ /*
+ * RFC 8415 21.22 states that the
+ * valid and preferred lifetimes sent by
+ * the client SHOULD be zero and MUST
+ * be ignored by the server.
+ */
+ };
- pdp.pltime = htonl(ap->prefix_pltime);
- pdp.vltime = htonl(ap->prefix_vltime);
- pdp.prefix_len = ap->prefix_len;
/* pdp.prefix is not aligned, so copy it in. */
memcpy(&pdp.prefix, &ap->prefix, sizeof(pdp.prefix));
COPYIN(D6_OPTION_IAPREFIX, &pdp, sizeof(pdp));
@@ -1019,11 +1032,16 @@ dhcp6_makemessage(struct interface *ifp)
}
#endif
} else {
- struct dhcp6_ia_addr ia;
+ struct dhcp6_ia_addr ia = {
+ .addr = ap->addr,
+ /*
+ * RFC 8415 21.6 states that the
+ * valid and preferred lifetimes sent by
+ * the client SHOULD be zero and MUST
+ * be ignored by the server.
+ */
+ };
- ia.addr = ap->addr;
- ia.pltime = htonl(ap->prefix_pltime);
- ia.vltime = htonl(ap->prefix_vltime);
COPYIN(D6_OPTION_IA_ADDR, &ia, sizeof(ia));
ia_na_len = (uint16_t)
(ia_na_len + sizeof(o) + sizeof(ia));
@@ -1219,7 +1237,7 @@ dhcp6_sendmessage(struct interface *ifp,
struct dhcp6_state *state = D6_STATE(ifp);
struct dhcpcd_ctx *ctx = ifp->ctx;
unsigned int RT;
- bool broadcast = true;
+ bool multicast = true;
struct sockaddr_in6 dst = {
.sin6_family = AF_INET6,
/* Setting the port on Linux gives EINVAL when sending.
@@ -1259,24 +1277,24 @@ dhcp6_sendmessage(struct interface *ifp,
/* Unicasting is denied for these types. */
break;
default:
- broadcast = false;
+ multicast = false;
inet_ntop(AF_INET6, &state->unicast, uaddr,
sizeof(uaddr));
break;
}
}
- dst.sin6_addr = broadcast ? alldhcp : state->unicast;
+ dst.sin6_addr = multicast ? alldhcp : state->unicast;
if (!callback) {
logdebugx("%s: %s %s with xid 0x%02x%02x%02x%s%s",
ifp->name,
- broadcast ? "broadcasting" : "unicasting",
+ multicast ? "multicasting" : "unicasting",
dhcp6_get_op(state->send->type),
state->send->xid[0],
state->send->xid[1],
state->send->xid[2],
- !broadcast ? " " : "",
- !broadcast ? uaddr : "");
+ !multicast ? " " : "",
+ !multicast ? uaddr : "");
RT = 0;
} else {
if (state->IMD &&
@@ -1314,13 +1332,13 @@ dhcp6_sendmessage(struct interface *ifp,
" next in %0.1f seconds",
ifp->name,
state->IMD != 0 ? "delaying" :
- broadcast ? "broadcasting" : "unicasting",
+ multicast ? "multicasting" : "unicasting",
dhcp6_get_op(state->send->type),
state->send->xid[0],
state->send->xid[1],
state->send->xid[2],
- state->IMD == 0 && !broadcast ? " " : "",
- state->IMD == 0 && !broadcast ? uaddr : "",
+ state->IMD == 0 && !multicast ? " " : "",
+ state->IMD == 0 && !multicast ? uaddr : "",
(float)RT / MSEC_PER_SEC);
/* Wait the initial delay */
@@ -1347,7 +1365,7 @@ dhcp6_sendmessage(struct interface *ifp,
#endif
/* Set the outbound interface */
- if (broadcast) {
+ if (multicast) {
struct cmsghdr *cm;
struct in6_pktinfo pi = { .ipi6_ifindex = ifp->index };
@@ -2254,8 +2272,8 @@ dhcp6_findpd(struct interface *ifp, cons
if (!(a->flags & IPV6_AF_DELEGATEDPFX))
a->flags |= IPV6_AF_NEW | IPV6_AF_DELEGATEDPFX;
a->flags &= ~(IPV6_AF_STALE |
- IPV6_AF_EXTENDED |
- IPV6_AF_REQUEST);
+ IPV6_AF_EXTENDED |
+ IPV6_AF_REQUEST);
if (a->prefix_vltime != pdp.vltime)
a->flags |= IPV6_AF_NEW;
}
@@ -2407,7 +2425,7 @@ dhcp6_findia(struct interface *ifp, stru
logwarnx("%s: IAID %s T1(%d) > T2(%d) from %s",
ifp->name,
hwaddr_ntoa(iaid, sizeof(iaid), buf,
- sizeof(buf)),
+ sizeof(buf)),
ia.t1, ia.t2, sfrom);
continue;
}
@@ -2840,7 +2858,7 @@ dhcp6_script_try_run(struct interface *i
if (ap->flags & IPV6_AF_ONLINK) {
if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
ipv6_iffindaddr(ap->iface, &ap->addr,
- IN6_IFF_TENTATIVE))
+ IN6_IFF_TENTATIVE))
ap->flags |= IPV6_AF_DADCOMPLETED;
if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0
#ifndef SMALL
@@ -3091,7 +3109,7 @@ dhcp6_bind(struct interface *ifp, const
if (state->reason == NULL)
state->reason = "INFORM6";
o = dhcp6_findmoption(state->new, state->new_len,
- D6_OPTION_INFO_REFRESH_TIME, &ol);
+ D6_OPTION_INFO_REFRESH_TIME, &ol);
if (o == NULL || ol != sizeof(uint32_t))
state->renew = IRT_DEFAULT;
else {
@@ -3711,7 +3729,7 @@ recvif:
}
static void
-dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
+dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia, unsigned short events)
{
struct sockaddr_in6 from;
union {
@@ -3733,6 +3751,9 @@ dhcp6_recv(struct dhcpcd_ctx *ctx, struc
int s;
ssize_t bytes;
+ if (events != ELE_READ)
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
s = ia != NULL ? ia->dhcp6_fd : ctx->dhcp6_rfd;
bytes = recvmsg(s, &msg, 0);
if (bytes == -1) {
@@ -3745,19 +3766,20 @@ dhcp6_recv(struct dhcpcd_ctx *ctx, struc
}
static void
-dhcp6_recvaddr(void *arg)
+
+dhcp6_recvaddr(void *arg, unsigned short events)
{
struct ipv6_addr *ia = arg;
- dhcp6_recv(ia->iface->ctx, ia);
+ dhcp6_recv(ia->iface->ctx, ia, events);
}
static void
-dhcp6_recvctx(void *arg)
+dhcp6_recvctx(void *arg, unsigned short events)
{
struct dhcpcd_ctx *ctx = arg;
- dhcp6_recv(ctx, NULL);
+ dhcp6_recv(ctx, NULL, events);
}
int
@@ -3878,7 +3900,9 @@ dhcp6_start1(void *arg)
logerr(__func__);
return;
}
- eloop_event_add(ctx->eloop, ctx->dhcp6_rfd, dhcp6_recvctx, ctx);
+ if (eloop_event_add(ctx->eloop, ctx->dhcp6_rfd, ELE_READ,
+ dhcp6_recvctx, ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
}
if (!IN_PRIVSEP(ctx) && ctx->dhcp6_wfd == -1) {
@@ -4197,13 +4221,13 @@ dhcp6_handleifa(int cmd, struct ipv6_add
if (ia->dhcp6_fd == -1)
ia->dhcp6_fd = dhcp6_openudp(ia->iface->index,
&ia->addr);
- if (ia->dhcp6_fd != -1)
- eloop_event_add(ia->iface->ctx->eloop,
- ia->dhcp6_fd, dhcp6_recvaddr, ia);
+ if (ia->dhcp6_fd != -1 &&
+ eloop_event_add(ia->iface->ctx->eloop,
+ ia->dhcp6_fd, ELE_READ, dhcp6_recvaddr, ia) == -1)
+ logerr("%s: eloop_event_add", __func__);
}
}
-
if ((state = D6_STATE(ifp)) != NULL)
ipv6_handleifa_addrs(cmd, &state->addrs, ia, pid);
}
@@ -4314,7 +4338,7 @@ dhcp6_env(FILE *fp, const char *prefix,
delegated:
#ifndef SMALL
- /* Needed for Delegated Prefixes */
+ /* Needed for Delegated Prefixes */
state = D6_CSTATE(ifp);
TAILQ_FOREACH(ap, &state->addrs, next) {
if (ap->delegating_prefix)
@@ -4333,7 +4357,7 @@ delegated:
}
if (fprintf(fp, "%s", ap->saddr) == -1)
return -1;
- }
+ }
if (fputc('\0', fp) == EOF)
return -1;
#endif
Index: src/external/bsd/dhcpcd/dist/src/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.28 src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.29
--- src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.28 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/ipv6nd.c Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* dhcpcd - IPv6 ND handling
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -78,7 +78,7 @@ struct nd_opt_rdnss { /* RDNSS
uint8_t nd_opt_rdnss_len;
uint16_t nd_opt_rdnss_reserved;
uint32_t nd_opt_rdnss_lifetime;
- /* followed by list of IP prefixes */
+ /* followed by list of IP prefixes */
};
__CTASSERT(sizeof(struct nd_opt_rdnss) == 8);
#endif
@@ -92,7 +92,7 @@ struct nd_opt_dnssl { /* DNSSL option R
uint32_t nd_opt_dnssl_lifetime;
/* followed by list of DNS servers */
};
-__CTASSERT(sizeof(struct nd_opt_rdnss) == 8);
+__CTASSERT(sizeof(struct nd_opt_dnssl) == 8);
#endif
/* Impossible options, so we can easily add extras */
@@ -131,7 +131,7 @@ __CTASSERT(sizeof(struct nd_opt_rdnss) =
//#define DEBUG_NS
//
-static void ipv6nd_handledata(void *);
+static void ipv6nd_handledata(void *, unsigned short);
/*
* Android ships buggy ICMP6 filter headers.
@@ -281,8 +281,14 @@ ipv6nd_openif(struct interface *ifp)
return -1;
}
+ if (eloop_event_add(ifp->ctx->eloop, fd, ELE_READ,
+ ipv6nd_handledata, ifp) == -1)
+ {
+ close(fd);
+ return -1;
+ }
+
state->nd_fd = fd;
- eloop_event_add(ifp->ctx->eloop, fd, ipv6nd_handledata, ifp);
return fd;
}
#endif
@@ -388,7 +394,9 @@ ipv6nd_sendrsprobe(void *arg)
logerr(__func__);
return;
}
- eloop_event_add(ctx->eloop, ctx->nd_fd, ipv6nd_handledata, ctx);
+ if (eloop_event_add(ctx->eloop, ctx->nd_fd, ELE_READ,
+ ipv6nd_handledata, ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
}
s = ifp->ctx->nd_fd;
#endif
@@ -1306,6 +1314,9 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx,
switch (ndo.nd_opt_type) {
case ND_OPT_PREFIX_INFORMATION:
+ {
+ uint32_t vltime, pltime;
+
loglevel = new_data ? LOG_ERR : LOG_DEBUG;
if (ndo.nd_opt_len != 4) {
logmessage(loglevel,
@@ -1329,9 +1340,10 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx,
ifp->name);
continue;
}
- if (ntohl(pi.nd_opt_pi_preferred_time) >
- ntohl(pi.nd_opt_pi_valid_time))
- {
+
+ vltime = ntohl(pi.nd_opt_pi_valid_time);
+ pltime = ntohl(pi.nd_opt_pi_preferred_time);
+ if (pltime > vltime) {
logmessage(loglevel, "%s: pltime > vltime",
ifp->name);
continue;
@@ -1356,10 +1368,15 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx,
&pi_prefix, pi.nd_opt_pi_prefix_len, flags);
if (ia == NULL)
break;
+
ia->prefix = pi_prefix;
+ ia->created = ia->acquired = rap->acquired;
+ ia->prefix_vltime = vltime;
+ ia->prefix_pltime = pltime;
+
if (flags & IPV6_AF_AUTOCONF)
ia->dadcallback = ipv6nd_dadcallback;
- ia->created = ia->acquired = rap->acquired;
+
TAILQ_INSERT_TAIL(&rap->addrs, ia, next);
#ifdef IPV6_MANAGETEMPADDR
@@ -1376,18 +1393,58 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx,
else
new_ia = true;
#endif
+
} else {
-#ifdef IPV6_MANAGETEMPADDR
- new_ia = false;
-#endif
+ uint32_t rmtime;
+
+ /*
+ * RFC 4862 5.5.3.e
+ * Don't terminate existing connections.
+ * This means that to actually remove the
+ * existing prefix, the RA needs to stop
+ * broadcasting the prefix and just let it
+ * expire in 2 hours.
+ * It might want to broadcast it to reduce
+ * the vltime if it was greater than 2 hours
+ * to start with/
+ */
+ ia->prefix_pltime = pltime;
+ if (ia->prefix_vltime) {
+ uint32_t elapsed;
+
+ elapsed = (uint32_t)eloop_timespec_diff(
+ &rap->acquired, &ia->acquired,
+ NULL);
+ rmtime = ia->prefix_vltime - elapsed;
+ if (rmtime > ia->prefix_vltime)
+ rmtime = 0;
+ } else
+ rmtime = 0;
+ if (vltime > MIN_EXTENDED_VLTIME ||
+ vltime > rmtime)
+ ia->prefix_vltime = vltime;
+ else if (rmtime <= MIN_EXTENDED_VLTIME)
+ /* No SEND support from RFC 3971 so
+ * leave vltime alone */
+ ia->prefix_vltime = rmtime;
+ else
+ ia->prefix_vltime = MIN_EXTENDED_VLTIME;
+
+ /* Ensure pltime still fits */
+ if (pltime < ia->prefix_vltime)
+ ia->prefix_pltime = pltime;
+ else
+ ia->prefix_pltime = ia->prefix_vltime;
+
ia->flags |= flags;
ia->flags &= ~IPV6_AF_STALE;
ia->acquired = rap->acquired;
+
+#ifdef IPV6_MANAGETEMPADDR
+ new_ia = false;
+#endif
}
- ia->prefix_vltime =
- ntohl(pi.nd_opt_pi_valid_time);
- ia->prefix_pltime =
- ntohl(pi.nd_opt_pi_preferred_time);
+
if (ia->prefix_vltime != 0 &&
ia->flags & IPV6_AF_AUTOCONF)
has_address = true;
@@ -1410,6 +1467,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx,
}
#endif
break;
+ }
case ND_OPT_MTU:
if (len < sizeof(mtu)) {
@@ -1977,7 +2035,7 @@ ipv6nd_recvmsg(struct dhcpcd_ctx *ctx, s
}
static void
-ipv6nd_handledata(void *arg)
+ipv6nd_handledata(void *arg, unsigned short events)
{
struct dhcpcd_ctx *ctx;
int fd;
@@ -2013,6 +2071,10 @@ ipv6nd_handledata(void *arg)
ctx = arg;
fd = ctx->nd_fd;
#endif
+
+ if (events != ELE_READ)
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
len = recvmsg(fd, &msg, 0);
if (len == -1) {
logerr(__func__);
Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.49 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.50
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.49 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
* SUCH DAMAGE.
*/
-static const char dhcpcd_copyright[] = "Copyright (c) 2006-2021 Roy Marples";
+static const char dhcpcd_copyright[] = "Copyright (c) 2006-2023 Roy Marples";
#include <sys/file.h>
#include <sys/ioctl.h>
@@ -1105,15 +1105,19 @@ out:
if_free(ifp);
}
free(ifs);
+ if_freeifaddrs(ctx, &ifaddrs);
return e;
}
static void
-dhcpcd_handlelink(void *arg)
+dhcpcd_handlelink(void *arg, unsigned short events)
{
struct dhcpcd_ctx *ctx = arg;
+ if (events != ELE_READ)
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
if (if_handlelink(ctx) == -1) {
if (errno == ENOBUFS || errno == ENOMEM) {
dhcpcd_linkoverflow(ctx);
@@ -1241,6 +1245,7 @@ dhcpcd_linkoverflow(struct dhcpcd_ctx *c
if_markaddrsstale(ctx->ifaces);
if_learnaddrs(ctx, ctx->ifaces, &ifaddrs);
if_deletestaleaddrs(ctx->ifaces);
+ if_freeifaddrs(ctx, &ifaddrs);
}
void
@@ -1406,7 +1411,7 @@ dhcpcd_renew(struct dhcpcd_ctx *ctx)
#ifdef USE_SIGNALS
#define sigmsg "received %s, %s"
-static void
+void
dhcpcd_signal_cb(int sig, void *arg)
{
struct dhcpcd_ctx *ctx = arg;
@@ -1465,8 +1470,12 @@ dhcpcd_signal_cb(int sig, void *arg)
logerr("logopen");
return;
case SIGCHLD:
+#ifdef PRIVSEP
+ ps_root_signalcb(sig, ctx);
+#else
while (waitpid(-1, NULL, WNOHANG) > 0)
;
+#endif
return;
default:
logerrx("received signal %d but don't know what to do with it",
@@ -1648,15 +1657,18 @@ dumperr:
return 0;
}
-static void dhcpcd_readdump1(void *);
+static void dhcpcd_readdump1(void *, unsigned short);
static void
-dhcpcd_readdump2(void *arg)
+dhcpcd_readdump2(void *arg, unsigned short events)
{
struct dhcpcd_ctx *ctx = arg;
ssize_t len;
int exit_code = EXIT_FAILURE;
+ if (events != ELE_READ)
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
len = read(ctx->control_fd, ctx->ctl_buf + ctx->ctl_bufpos,
ctx->ctl_buflen - ctx->ctl_bufpos);
if (len == -1) {
@@ -1675,8 +1687,9 @@ dhcpcd_readdump2(void *arg)
fflush(stdout);
if (--ctx->ctl_extra != 0) {
putchar('\n');
- eloop_event_add(ctx->eloop, ctx->control_fd,
- dhcpcd_readdump1, ctx);
+ if (eloop_event_add(ctx->eloop, ctx->control_fd, ELE_READ,
+ dhcpcd_readdump1, ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
return;
}
exit_code = EXIT_SUCCESS;
@@ -1687,11 +1700,14 @@ finished:
}
static void
-dhcpcd_readdump1(void *arg)
+dhcpcd_readdump1(void *arg, unsigned short events)
{
struct dhcpcd_ctx *ctx = arg;
ssize_t len;
+ if (events != ELE_READ)
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
len = read(ctx->control_fd, &ctx->ctl_buflen, sizeof(ctx->ctl_buflen));
if (len != sizeof(ctx->ctl_buflen)) {
if (len != -1)
@@ -1709,8 +1725,9 @@ dhcpcd_readdump1(void *arg)
goto err;
ctx->ctl_bufpos = 0;
- eloop_event_add(ctx->eloop, ctx->control_fd,
- dhcpcd_readdump2, ctx);
+ if (eloop_event_add(ctx->eloop, ctx->control_fd, ELE_READ,
+ dhcpcd_readdump2, ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
return;
err:
@@ -1719,11 +1736,14 @@ err:
}
static void
-dhcpcd_readdump0(void *arg)
+dhcpcd_readdump0(void *arg, unsigned short events)
{
struct dhcpcd_ctx *ctx = arg;
ssize_t len;
+ if (events != ELE_READ)
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
len = read(ctx->control_fd, &ctx->ctl_extra, sizeof(ctx->ctl_extra));
if (len != sizeof(ctx->ctl_extra)) {
if (len != -1)
@@ -1738,8 +1758,9 @@ dhcpcd_readdump0(void *arg)
return;
}
- eloop_event_add(ctx->eloop, ctx->control_fd,
- dhcpcd_readdump1, ctx);
+ if (eloop_event_add(ctx->eloop, ctx->control_fd, ELE_READ,
+ dhcpcd_readdump1, ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
}
static void
@@ -1759,17 +1780,20 @@ dhcpcd_readdump(struct dhcpcd_ctx *ctx)
if (eloop_timeout_add_sec(ctx->eloop, 5,
dhcpcd_readdumptimeout, ctx) == -1)
return -1;
- return eloop_event_add(ctx->eloop, ctx->control_fd,
+ return eloop_event_add(ctx->eloop, ctx->control_fd, ELE_READ,
dhcpcd_readdump0, ctx);
}
static void
-dhcpcd_fork_cb(void *arg)
+dhcpcd_fork_cb(void *arg, unsigned short events)
{
struct dhcpcd_ctx *ctx = arg;
int exit_code;
ssize_t len;
+ if (!(events & ELE_READ))
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
len = read(ctx->fork_fd, &exit_code, sizeof(exit_code));
if (len == -1) {
logerr(__func__);
@@ -1786,12 +1810,15 @@ dhcpcd_fork_cb(void *arg)
}
static void
-dhcpcd_stderr_cb(void *arg)
+dhcpcd_stderr_cb(void *arg, unsigned short events)
{
struct dhcpcd_ctx *ctx = arg;
char log[BUFSIZ];
ssize_t len;
+ if (events != ELE_READ)
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
len = read(ctx->stderr_fd, log, sizeof(log));
if (len == -1) {
if (errno != ECONNRESET)
@@ -1803,6 +1830,24 @@ dhcpcd_stderr_cb(void *arg)
fprintf(stderr, "%s", log);
}
+static void
+dhcpcd_pidfile_timeout(void *arg)
+{
+ struct dhcpcd_ctx *ctx = arg;
+ pid_t pid;
+
+ pid = pidfile_read(ctx->pidfile);
+
+ if(pid == -1)
+ eloop_exit(ctx->eloop, EXIT_SUCCESS);
+ else if (++ctx->duid_len >= 100) { /* overload duid_len */
+ logerrx("pid %d failed to exit", pid);
+ eloop_exit(ctx->eloop, EXIT_FAILURE);
+ } else
+ eloop_timeout_add_msec(ctx->eloop, 100,
+ dhcpcd_pidfile_timeout, ctx);
+}
+
int
main(int argc, char **argv, char **envp)
{
@@ -1897,8 +1942,7 @@ main(int argc, char **argv, char **envp)
ctx.dhcp6_wfd = -1;
#endif
#ifdef PRIVSEP
- ctx.ps_root_fd = ctx.ps_log_fd = ctx.ps_data_fd = -1;
- ctx.ps_inet_fd = ctx.ps_control_fd = -1;
+ ctx.ps_log_fd = -1;
TAILQ_INIT(&ctx.ps_processes);
#endif
@@ -1940,12 +1984,6 @@ main(int argc, char **argv, char **envp)
sig = SIGHUP;
siga = "HUP";
break;
- case 'g':
- case 'p':
- /* Force going via command socket as we're
- * out of user definable signals. */
- i = 4;
- break;
case 'q':
/* -qq disables console output entirely.
* This is important for systemd because it logs
@@ -2095,6 +2133,14 @@ printpidfile:
snprintf(ctx.pidfile, sizeof(ctx.pidfile),
PIDFILE, "", "", "");
ctx.options |= DHCPCD_MANAGER;
+
+ /*
+ * If we are given any interfaces, we
+ * cannot send a signal as that would impact
+ * other interfaces.
+ */
+ if (optind != argc)
+ sig = 0;
}
if (ctx.options & DHCPCD_PRINT_PIDFILE) {
printf("%s\n", ctx.pidfile);
@@ -2130,31 +2176,20 @@ printpidfile:
if (pid != 0 && pid != -1)
loginfox("sending signal %s to pid %d", siga, pid);
if (pid == 0 || pid == -1 || kill(pid, sig) != 0) {
- if (sig != SIGHUP && sig != SIGUSR1 && errno != EPERM)
- logerrx(PACKAGE" not running");
if (pid != 0 && pid != -1 && errno != ESRCH) {
logerr("kill");
goto exit_failure;
}
unlink(ctx.pidfile);
- if (sig != SIGHUP && sig != SIGUSR1)
- goto exit_failure;
+ /* We can still continue and send the command
+ * via the control socket. */
} else {
- struct timespec ts;
-
if (sig == SIGHUP || sig == SIGUSR1)
goto exit_success;
/* Spin until it exits */
loginfox("waiting for pid %d to exit", pid);
- ts.tv_sec = 0;
- ts.tv_nsec = 100000000; /* 10th of a second */
- for(i = 0; i < 100; i++) {
- nanosleep(&ts, NULL);
- if (pidfile_read(ctx.pidfile) == -1)
- goto exit_success;
- }
- logerrx("pid %d failed to exit", pid);
- goto exit_failure;
+ dhcpcd_pidfile_timeout(&ctx);
+ goto run_loop;
}
}
#endif
@@ -2207,12 +2242,8 @@ printpidfile:
}
#endif
- /* Test against siga instead of sig to avoid gcc
- * warning about a bogus potential signed overflow.
- * The end result will be the same. */
- if ((siga == NULL || i == 4 || ctx.ifc != 0) &&
- !(ctx.options & DHCPCD_TEST))
- {
+ /* Try and contact the manager process to send the instruction. */
+ if (!(ctx.options & DHCPCD_TEST)) {
ctx.options |= DHCPCD_FORKED; /* avoid socket unlink */
if (!(ctx.options & DHCPCD_MANAGER))
ctx.control_fd = control_open(argv[optind], family,
@@ -2249,9 +2280,14 @@ printpidfile:
} else {
if (errno != ENOENT)
logerr("%s: control_open", __func__);
- if (ctx.options & DHCPCD_DUMPLEASE) {
+ /* If asking dhcpcd to exit and we failed to
+ * send a signal or a message then we
+ * don't proceed past here. */
+ if (ctx.options & DHCPCD_DUMPLEASE ||
+ sig == SIGTERM || sig == SIGALRM)
+ {
if (errno == ENOENT)
- logerrx("dhcpcd is not running");
+ logerrx(PACKAGE" is not running");
goto exit_failure;
}
if (errno == EPERM || errno == EACCES)
@@ -2286,9 +2322,9 @@ printpidfile:
if (!(ctx.options & DHCPCD_DAEMONISE))
goto start_manager;
- if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fork_fd) == -1 ||
+ if (xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, fork_fd) == -1 ||
(ctx.stderr_valid &&
- xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, stderr_fd) == -1))
+ xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, stderr_fd) == -1))
{
logerr("socketpair");
goto exit_failure;
@@ -2306,7 +2342,9 @@ printpidfile:
goto exit_failure;
}
#endif
- eloop_event_add(ctx.eloop, ctx.fork_fd, dhcpcd_fork_cb, &ctx);
+ if (eloop_event_add(ctx.eloop, ctx.fork_fd, ELE_READ,
+ dhcpcd_fork_cb, &ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
/*
* Redirect stderr to the stderr socketpair.
@@ -2335,6 +2373,7 @@ printpidfile:
logerr("fork");
goto exit_failure;
case 0:
+ eloop_forked(ctx.eloop);
break;
default:
ctx.options |= DHCPCD_FORKED; /* A lie */
@@ -2353,7 +2392,9 @@ printpidfile:
goto exit_failure;
}
#endif
- eloop_event_add(ctx.eloop, ctx.fork_fd, dhcpcd_fork_cb, &ctx);
+ if (eloop_event_add(ctx.eloop, ctx.fork_fd, ELE_READ,
+ dhcpcd_fork_cb, &ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
if (ctx.stderr_valid) {
ctx.stderr_fd = stderr_fd[0];
@@ -2364,8 +2405,9 @@ printpidfile:
goto exit_failure;
}
#endif
- eloop_event_add(ctx.eloop, ctx.stderr_fd,
- dhcpcd_stderr_cb, &ctx);
+ if (eloop_event_add(ctx.eloop, ctx.stderr_fd, ELE_READ,
+ dhcpcd_stderr_cb, &ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
}
#ifdef PRIVSEP
if (IN_PRIVSEP(&ctx) && ps_managersandbox(&ctx, NULL) == -1)
@@ -2447,7 +2489,9 @@ start_manager:
/* Start handling kernel messages for interfaces, addresses and
* routes. */
- eloop_event_add(ctx.eloop, ctx.link_fd, dhcpcd_handlelink, &ctx);
+ if (eloop_event_add(ctx.eloop, ctx.link_fd, ELE_READ,
+ dhcpcd_handlelink, &ctx) == -1)
+ logerr("%s: eloop_event_add", __func__);
#ifdef PRIVSEP
if (IN_PRIVSEP(&ctx) && ps_managersandbox(&ctx, "stdio route") == -1)
@@ -2497,6 +2541,8 @@ start_manager:
dhcpcd_initstate1(ifp, argc, argv, 0);
}
if_learnaddrs(&ctx, ctx.ifaces, &ifaddrs);
+ if_freeifaddrs(&ctx, &ifaddrs);
+ ifaddrs = NULL;
if (ctx.options & DHCPCD_BACKGROUND)
dhcpcd_daemonise(&ctx);
@@ -2567,17 +2613,7 @@ exit_failure:
exit1:
if (!(ctx.options & DHCPCD_TEST) && control_stop(&ctx) == -1)
logerr("%s: control_stop", __func__);
- if (ifaddrs != NULL) {
-#ifdef PRIVSEP_GETIFADDRS
- if (IN_PRIVSEP(&ctx))
- free(ifaddrs);
- else
-#endif
- freeifaddrs(ifaddrs);
- }
- /* ps_stop will clear DHCPCD_PRIVSEP but we need to
- * remember it to avoid attemping to remove the pidfile */
- oi = ctx.options & DHCPCD_PRIVSEP ? 1 : 0;
+ if_freeifaddrs(&ctx, &ifaddrs);
#ifdef PRIVSEP
ps_stop(&ctx);
#endif
@@ -2611,14 +2647,20 @@ exit1:
#ifdef PLUGIN_DEV
dev_stop(&ctx);
#endif
-#ifdef PRIVSEP
- eloop_free(ctx.ps_eloop);
-#endif
- eloop_free(ctx.eloop);
if (ctx.script != dhcpcd_default_script)
free(ctx.script);
+#ifdef PRIVSEP
+ if (ps_stopwait(&ctx) != EXIT_SUCCESS)
+ i = EXIT_FAILURE;
+#endif
if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED))
loginfox(PACKAGE " exited");
+#ifdef PRIVSEP
+ if (ps_root_stop(&ctx) == -1)
+ i = EXIT_FAILURE;
+ eloop_free(ctx.ps_eloop);
+#endif
+ eloop_free(ctx.eloop);
logclose();
free(ctx.logfile);
free(ctx.ctl_buf);
@@ -2632,7 +2674,7 @@ exit1:
write(ctx.fork_fd, &i, sizeof(i)) == -1)
logerr("%s: write", __func__);
}
- if (ctx.options & DHCPCD_FORKED || oi != 0)
+ if (ctx.options & (DHCPCD_FORKED | DHCPCD_PRIVSEP))
_exit(i); /* so atexit won't remove our pidfile */
#endif
return i;
Index: src/external/bsd/dhcpcd/dist/src/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.27 src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.28
--- src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.27 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/if-bsd.c Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* BSD interface driver for dhcpcd
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -104,6 +104,7 @@
* just won't work without explicit configuration. */
static const char * const ifnames_ignore[] = {
"bridge",
+ "epair", /* Virtual patch cable */
"fwe", /* Firewire */
"fwip", /* Firewire */
"tap",
@@ -112,10 +113,6 @@ static const char * const ifnames_ignore
NULL
};
-struct priv {
- int pf_inet6_fd;
-};
-
struct rtm
{
struct rt_msghdr hdr;
@@ -222,6 +219,12 @@ if_opensockets_os(struct dhcpcd_ctx *ctx
ps_rights_limit_fd_sockopt(ctx->link_fd);
#endif
+
+#if defined(SIOCALIFADDR) && defined(IFLR_ACTIVE) /*NetBSD */
+ priv->pf_link_fd = socket(PF_LINK, SOCK_DGRAM, 0);
+ if (priv->pf_link_fd == -1)
+ logerr("%s: socket(PF_LINK)", __func__);
+#endif
return 0;
}
@@ -233,6 +236,10 @@ if_closesockets_os(struct dhcpcd_ctx *ct
priv = (struct priv *)ctx->priv;
if (priv->pf_inet6_fd != -1)
close(priv->pf_inet6_fd);
+#if defined(SIOCALIFADDR) && defined(IFLR_ACTIVE) /*NetBSD */
+ if (priv->pf_link_fd != -1)
+ close(priv->pf_link_fd);
+#endif
free(priv);
ctx->priv = NULL;
free(ctx->rt_missfilter);
@@ -242,22 +249,14 @@ if_closesockets_os(struct dhcpcd_ctx *ct
static int
if_ioctllink(struct dhcpcd_ctx *ctx, unsigned long req, void *data, size_t len)
{
- int s;
- int retval;
+ struct priv *priv = (struct priv *)ctx->priv;
#ifdef PRIVSEP
if (ctx->options & DHCPCD_PRIVSEP)
return (int)ps_root_ioctllink(ctx, req, data, len);
-#else
- UNUSED(ctx);
#endif
- s = socket(PF_LINK, SOCK_DGRAM, 0);
- if (s == -1)
- return -1;
- retval = ioctl(s, req, data, len);
- close(s);
- return retval;
+ return ioctl(priv->pf_link_fd, req, data, len);
}
#endif
@@ -914,37 +913,47 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct
return 0;
}
+static int
+if_sysctl(struct dhcpcd_ctx *ctx,
+ const int *name, u_int namelen,
+ void *oldp, size_t *oldlenp, void *newp, size_t newlen)
+{
+#if defined(PRIVSEP) && defined(HAVE_CAPSICUM)
+ if (IN_PRIVSEP(ctx))
+ return (int)ps_root_sysctl(ctx, name, namelen,
+ oldp, oldlenp, newp, newlen);
+#else
+ UNUSED(ctx);
+#endif
+
+ return sysctl(name, namelen, oldp, oldlenp, newp, newlen);
+}
+
int
if_initrt(struct dhcpcd_ctx *ctx, rb_tree_t *kroutes, int af)
{
struct rt_msghdr *rtm;
- int mib[6];
- size_t needed;
+ int mib[6] = { CTL_NET, PF_ROUTE, 0, af, NET_RT_DUMP, 0 };
+ size_t bufl;
char *buf, *p, *end;
struct rt rt, *rtn;
- mib[0] = CTL_NET;
- mib[1] = PF_ROUTE;
- mib[2] = 0;
- mib[3] = af;
- mib[4] = NET_RT_DUMP;
- mib[5] = 0;
-
- if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
+ if (if_sysctl(ctx, mib, __arraycount(mib), NULL, &bufl, NULL, 0) == -1)
return -1;
- if (needed == 0)
+ if (bufl == 0)
return 0;
- if ((buf = malloc(needed)) == NULL)
+ if ((buf = malloc(bufl)) == NULL)
return -1;
- if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) {
+ if (if_sysctl(ctx, mib, __arraycount(mib), buf, &bufl, NULL, 0) == -1)
+ {
free(buf);
return -1;
}
- end = buf + needed;
+ end = buf + bufl;
for (p = buf; p < end; p += rtm->rtm_msglen) {
rtm = (void *)p;
- if (p + rtm->rtm_msglen >= end) {
+ if (p + sizeof(*rtm) > end || p + rtm->rtm_msglen > end) {
errno = EINVAL;
break;
}
@@ -1246,8 +1255,8 @@ if_rtm(struct dhcpcd_ctx *ctx, const str
/* Ignore messages from ourself. */
#ifdef PRIVSEP
- if (ctx->ps_root_pid != 0) {
- if (rtm->rtm_pid == ctx->ps_root_pid)
+ if (ctx->ps_root != NULL) {
+ if (rtm->rtm_pid == ctx->ps_root->psp_pid)
return 0;
}
#endif
@@ -1298,8 +1307,8 @@ if_ifa(struct dhcpcd_ctx *ctx, const str
* We need to process address flag changes though. */
if (ifam->ifam_type == RTM_DELADDR) {
#ifdef PRIVSEP
- if (ctx->ps_root_pid != 0) {
- if (ifam->ifam_pid == ctx->ps_root_pid)
+ if (ctx->ps_root != NULL) {
+ if (ifam->ifam_pid == ctx->ps_root->psp_pid)
return 0;
} else
#endif
@@ -1649,12 +1658,11 @@ inet6_sysctl(int code, int val, int acti
mib[3] = code;
size = sizeof(val);
if (action) {
- if (sysctl(mib, sizeof(mib)/sizeof(mib[0]),
- NULL, 0, &val, size) == -1)
+ if (sysctl(mib, __arraycount(mib), NULL, 0, &val, size) == -1)
return -1;
return 0;
}
- if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &val, &size, NULL, 0) == -1)
+ if (sysctl(mib, __arraycount(mib), &val, &size, NULL, 0) == -1)
return -1;
return val;
}
Index: src/external/bsd/dhcpcd/dist/src/if-options.c
diff -u src/external/bsd/dhcpcd/dist/src/if-options.c:1.32 src/external/bsd/dhcpcd/dist/src/if-options.c:1.33
--- src/external/bsd/dhcpcd/dist/src/if-options.c:1.32 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/if-options.c Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -193,7 +193,10 @@ add_environ(char ***array, const char *v
l = strlen(match);
while (list && list[i]) {
- if (match && strncmp(list[i], match, l) == 0) {
+ /* We know that it must contain '=' due to the above test */
+ size_t listl = (size_t)(strchr(list[i], '=') - list[i]);
+
+ if (l == listl && strncmp(list[i], match, l) == 0) {
if (uniq) {
n = strdup(value);
if (n == NULL) {
@@ -266,7 +269,13 @@ parse_str(char *sbuf, size_t slen, const
}
} else {
l = (size_t)hwaddr_aton(NULL, str);
- if ((ssize_t) l != -1 && l > 1) {
+ if (l > 0) {
+ if ((ssize_t)l == -1) {
+ errno = ENOBUFS;
+ return -1;
+ }
+ if (sbuf == NULL)
+ return (ssize_t)l;
if (l > slen) {
errno = ENOBUFS;
return -1;
@@ -1108,8 +1117,13 @@ parse_option(struct dhcpcd_ctx *ctx, con
logerrx("static assignment required");
return -1;
}
- p++;
+ p = strskipwhite(++p);
if (strncmp(arg, "ip_address=", strlen("ip_address=")) == 0) {
+ if (p == NULL) {
+ ifo->options &= ~DHCPCD_STATIC;
+ ifo->req_addr.s_addr = INADDR_ANY;
+ break;
+ }
if (parse_addr(&ifo->req_addr,
ifo->req_mask.s_addr == 0 ? &ifo->req_mask : NULL,
p) != 0)
@@ -1120,11 +1134,19 @@ parse_option(struct dhcpcd_ctx *ctx, con
} else if (strncmp(arg, "subnet_mask=",
strlen("subnet_mask=")) == 0)
{
+ if (p == NULL) {
+ ifo->req_mask.s_addr = INADDR_ANY;
+ break;
+ }
if (parse_addr(&ifo->req_mask, NULL, p) != 0)
return -1;
} else if (strncmp(arg, "broadcast_address=",
strlen("broadcast_address=")) == 0)
{
+ if (p == NULL) {
+ ifo->req_brd.s_addr = INADDR_ANY;
+ break;
+ }
if (parse_addr(&ifo->req_brd, NULL, p) != 0)
return -1;
} else if (strncmp(arg, "routes=", strlen("routes=")) == 0 ||
@@ -1137,6 +1159,12 @@ parse_option(struct dhcpcd_ctx *ctx, con
{
struct in_addr addr3;
+ if (p == NULL) {
+ rt_headclear(&ifo->routes, AF_INET);
+ add_environ(&ifo->config, arg, 1);
+ break;
+ }
+
fp = np = strwhite(p);
if (np == NULL) {
logerrx("all routes need a gateway");
@@ -1159,6 +1187,11 @@ parse_option(struct dhcpcd_ctx *ctx, con
if (rt_proto_add_ctx(&ifo->routes, rt, ctx))
add_environ(&ifo->config, arg, 0);
} else if (strncmp(arg, "routers=", strlen("routers=")) == 0) {
+ if (p == NULL) {
+ rt_headclear(&ifo->routes, AF_INET);
+ add_environ(&ifo->config, arg, 1);
+ break;
+ }
if (parse_addr(&addr, NULL, p) == -1)
return -1;
if ((rt = rt_new0(ctx)) == NULL)
@@ -1173,6 +1206,8 @@ parse_option(struct dhcpcd_ctx *ctx, con
strlen("interface_mtu=")) == 0 ||
strncmp(arg, "mtu=", strlen("mtu=")) == 0)
{
+ if (p == NULL)
+ break;
ifo->mtu = (unsigned int)strtou(p, NULL, 0,
MTU_MIN, MTU_MAX, &e);
if (e) {
@@ -1180,6 +1215,12 @@ parse_option(struct dhcpcd_ctx *ctx, con
return -1;
}
} else if (strncmp(arg, "ip6_address=", strlen("ip6_address=")) == 0) {
+ if (p == NULL) {
+ memset(&ifo->req_addr6, 0,
+ sizeof(ifo->req_addr6));
+ break;
+ }
+
np = strchr(p, '/');
if (np)
*np++ = '\0';
@@ -1205,8 +1246,9 @@ parse_option(struct dhcpcd_ctx *ctx, con
return -1;
}
} else
- add_environ(&ifo->config, arg, 1);
+ add_environ(&ifo->config, arg, p == NULL ? 1 : 0);
break;
+
case 'W':
if (parse_addr(&addr, &addr2, arg) != 0)
return -1;
@@ -2061,7 +2103,7 @@ err_sla:
arg = fp;
fp = strend(arg);
if (fp == NULL) {
- logerrx("authtoken requies an a key");
+ logerrx("authtoken requires a realm");
goto invalid_token;
}
*fp++ = '\0';
@@ -2114,7 +2156,7 @@ err_sla:
if (s == -1)
logerr("token_len");
else
- logerrx("authtoken needs a key");
+ logerrx("authtoken requires a key");
goto invalid_token;
}
token->key_len = (size_t)s;
@@ -2229,6 +2271,24 @@ invalid_token:
ifo->options |= DHCPCD_SLAACPRIVATE;
else
ifo->options &= ~DHCPCD_SLAACPRIVATE;
+#ifdef INET6
+ if (strcmp(arg, "token") == 0) {
+ if (np == NULL) {
+ logerrx("slaac token: no token specified");
+ return -1;
+ }
+ arg = np;
+ np = strwhite(np);
+ if (np != NULL) {
+ *np++ = '\0';
+ np = strskipwhite(np);
+ }
+ if (inet_pton(AF_INET6, arg, &ifo->token) != 1) {
+ logerrx("slaac token: invalid token");
+ return -1;
+ }
+ }
+#endif
if (np != NULL &&
(strcmp(np, "temp") == 0 || strcmp(np, "temporary") == 0))
ifo->options |= DHCPCD_SLAACTEMP;
Index: src/external/bsd/dhcpcd/dist/src/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/src/ipv6.c:1.17 src/external/bsd/dhcpcd/dist/src/ipv6.c:1.18
--- src/external/bsd/dhcpcd/dist/src/ipv6.c:1.17 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/ipv6.c Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -359,51 +359,6 @@ again:
}
#endif
-int
-ipv6_makeaddr(struct in6_addr *addr, struct interface *ifp,
- const struct in6_addr *prefix, int prefix_len, unsigned int flags)
-{
- const struct ipv6_addr *ap;
- int dad;
-
- if (prefix_len < 0 || prefix_len > 120) {
- errno = EINVAL;
- return -1;
- }
-
-#ifdef IPV6_AF_TEMPORARY
- if (flags & IPV6_AF_TEMPORARY)
- return ipv6_maketemporaryaddress(addr, prefix, prefix_len, ifp);
-#else
- UNUSED(flags);
-#endif
-
- if (ifp->options->options & DHCPCD_SLAACPRIVATE) {
- dad = 0;
- if (ipv6_makestableprivate(addr,
- prefix, prefix_len, ifp, &dad) == -1)
- return -1;
- return dad;
- }
-
- if (prefix_len > 64) {
- errno = EINVAL;
- return -1;
- }
- if ((ap = ipv6_linklocal(ifp)) == NULL) {
- /* We delay a few functions until we get a local-link address
- * so this should never be hit. */
- errno = ENOENT;
- return -1;
- }
-
- /* Make the address from the first local-link address */
- memcpy(addr, prefix, sizeof(*prefix));
- addr->s6_addr32[2] = ap->addr.s6_addr32[2];
- addr->s6_addr32[3] = ap->addr.s6_addr32[3];
- return 0;
-}
-
static int
ipv6_makeprefix(struct in6_addr *prefix, const struct in6_addr *addr, int len)
{
@@ -478,6 +433,68 @@ ipv6_prefixlen(const struct in6_addr *ma
return (uint8_t)(x * NBBY + y);
}
+int
+ipv6_makeaddr(struct in6_addr *addr, struct interface *ifp,
+ const struct in6_addr *prefix, int prefix_len, unsigned int flags)
+{
+ const struct ipv6_addr *ap;
+ const struct if_options *ifo = ifp->options;
+ int dad;
+
+ if (prefix_len < 0 || prefix_len > 120) {
+ errno = EINVAL;
+ return -1;
+ }
+
+#ifdef IPV6_AF_TEMPORARY
+ if (flags & IPV6_AF_TEMPORARY)
+ return ipv6_maketemporaryaddress(addr, prefix, prefix_len, ifp);
+#else
+ UNUSED(flags);
+#endif
+
+ if (ifo->options & DHCPCD_SLAACPRIVATE) {
+ dad = 0;
+ if (ipv6_makestableprivate(addr,
+ prefix, prefix_len, ifp, &dad) == -1)
+ return -1;
+ return dad;
+ } else if (!IN6_IS_ADDR_UNSPECIFIED(&ifo->token)) {
+ int bytes = prefix_len / NBBY;
+ int bits = prefix_len % NBBY;
+
+ // Copy the token into the address.
+ *addr = ifo->token;
+
+ // If we have any dangling bits, just copy that in also.
+ // XXX Can we preserve part of the token still?
+ if (bits != 0)
+ bytes++;
+
+ // Copy the prefix in.
+ if (bytes > 0)
+ memcpy(addr->s6_addr, prefix->s6_addr, (size_t)bytes);
+ return 0;
+ }
+
+ if (prefix_len > 64) {
+ errno = EINVAL;
+ return -1;
+ }
+ if ((ap = ipv6_linklocal(ifp)) == NULL) {
+ /* We delay a few functions until we get a local-link address
+ * so this should never be hit. */
+ errno = ENOENT;
+ return -1;
+ }
+
+ /* Make the address from the first local-link address */
+ memcpy(addr, prefix, sizeof(*prefix));
+ addr->s6_addr32[2] = ap->addr.s6_addr32[2];
+ addr->s6_addr32[3] = ap->addr.s6_addr32[3];
+ return 0;
+}
+
static void
in6_to_h64(uint64_t *vhigh, uint64_t *vlow, const struct in6_addr *addr)
{
Index: src/external/bsd/dhcpcd/dist/src/ipv6.h
diff -u src/external/bsd/dhcpcd/dist/src/ipv6.h:1.13 src/external/bsd/dhcpcd/dist/src/ipv6.h:1.14
--- src/external/bsd/dhcpcd/dist/src/ipv6.h:1.13 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/ipv6.h Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
Index: src/external/bsd/dhcpcd/dist/src/privsep.c
diff -u src/external/bsd/dhcpcd/dist/src/privsep.c:1.13 src/external/bsd/dhcpcd/dist/src/privsep.c:1.14
--- src/external/bsd/dhcpcd/dist/src/privsep.c:1.13 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/privsep.c Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Privilege Separation for dhcpcd
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -75,6 +75,7 @@
#ifdef HAVE_CAPSICUM
#include <sys/capsicum.h>
+#include <sys/procdesc.h>
#include <capsicum_helpers.h>
#endif
#ifdef HAVE_UTIL_H
@@ -144,33 +145,27 @@ ps_dropprivs(struct dhcpcd_ctx *ctx)
struct rlimit rzero = { .rlim_cur = 0, .rlim_max = 0 };
- if (ctx->ps_control_pid != getpid()) {
- /* Prohibit new files, sockets, etc */
-#if defined(__linux__) || defined(__sun) || defined(__OpenBSD__)
- /*
- * If poll(2) is called with nfds > RLIMIT_NOFILE
- * then it returns EINVAL.
- * This blows.
- * Do the best we can and limit to what we need.
- * An attacker could potentially close a file and
- * open a new one still, but that cannot be helped.
- */
- unsigned long maxfd;
- maxfd = (unsigned long)eloop_event_count(ctx->eloop);
- if (IN_PRIVSEP_SE(ctx))
- maxfd++; /* XXX why? */
-
- struct rlimit rmaxfd = {
- .rlim_cur = maxfd,
- .rlim_max = maxfd
- };
- if (setrlimit(RLIMIT_NOFILE, &rmaxfd) == -1)
- logerr("setrlimit RLIMIT_NOFILE");
-#else
+ /* Prohibit new files, sockets, etc */
+ /*
+ * If poll(2) is called with nfds>RLIMIT_NOFILE then it returns EINVAL.
+ * We don't know the final value of nfds at this point *easily*.
+ * Sadly, this is a POSIX limitation and most platforms adhere to it.
+ * However, some are not that strict and are whitelisted below.
+ * Also, if we're not using poll then we can be restrictive.
+ *
+ * For the non whitelisted platforms there should be a sandbox to
+ * fallback to where we don't allow new files, etc:
+ * Linux:seccomp, FreeBSD:capsicum, OpenBSD:pledge
+ * Solaris users are sadly out of luck on both counts.
+ */
+#if defined(__NetBSD__) || defined(__DragonFly__) || \
+ defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
+ /* The control proxy *does* need to create new fd's via accept(2). */
+ if (ctx->ps_ctl == NULL || ctx->ps_ctl->psp_pid != getpid()) {
if (setrlimit(RLIMIT_NOFILE, &rzero) == -1)
logerr("setrlimit RLIMIT_NOFILE");
-#endif
}
+#endif
#define DHC_NOCHKIO (DHCPCD_STARTED | DHCPCD_DAEMONISE)
/* Prohibit writing to files.
@@ -324,17 +319,41 @@ ps_rights_limit_stdio(struct dhcpcd_ctx
}
#endif
+#ifdef HAVE_CAPSICUM
+static void
+ps_processhangup(void *arg, unsigned short events)
+{
+ struct ps_process *psp = arg;
+ struct dhcpcd_ctx *ctx = psp->psp_ctx;
+
+ if (!(events & ELE_HANGUP))
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
+ logdebugx("%s%s%s exited from PID %d",
+ psp->psp_ifname, psp->psp_ifname[0] != '\0' ? ": " : "",
+ psp->psp_name, psp->psp_pid);
+
+ ps_freeprocess(psp);
+
+ if (!(ctx->options & DHCPCD_EXITING))
+ return;
+ if (!(ps_waitforprocs(ctx)))
+ eloop_exit(ctx->ps_eloop, EXIT_SUCCESS);
+}
+#endif
+
pid_t
-ps_dostart(struct dhcpcd_ctx *ctx,
- pid_t *priv_pid, int *priv_fd,
- void (*recv_msg)(void *), void (*recv_unpriv_msg),
- void *recv_ctx, int (*callback)(void *), void (*signal_cb)(int, void *),
+ps_startprocess(struct ps_process *psp,
+ void (*recv_msg)(void *, unsigned short),
+ void (*recv_unpriv_msg)(void *, unsigned short),
+ int (*callback)(struct ps_process *), void (*signal_cb)(int, void *),
unsigned int flags)
{
+ struct dhcpcd_ctx *ctx = psp->psp_ctx;
int fd[2];
pid_t pid;
- if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fd) == -1) {
+ if (xsocketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CXNB, 0, fd) == -1) {
logerr("%s: socketpair", __func__);
return -1;
}
@@ -349,37 +368,62 @@ ps_dostart(struct dhcpcd_ctx *ctx,
}
#endif
- switch (pid = fork()) {
+#ifdef HAVE_CAPSICUM
+ pid = pdfork(&psp->psp_pfd, PD_CLOEXEC);
+#else
+ pid = fork();
+#endif
+ switch (pid) {
case -1:
+#ifdef HAVE_CAPSICUM
+ logerr("pdfork");
+#else
logerr("fork");
+#endif
return -1;
case 0:
- *priv_fd = fd[1];
+ psp->psp_pid = getpid();
+ psp->psp_fd = fd[1];
close(fd[0]);
break;
default:
- *priv_pid = pid;
- *priv_fd = fd[0];
+ psp->psp_pid = pid;
+ psp->psp_fd = fd[0];
close(fd[1]);
if (recv_unpriv_msg == NULL)
;
- else if (eloop_event_add(ctx->eloop, *priv_fd,
- recv_unpriv_msg, recv_ctx) == -1)
+ else if (eloop_event_add(ctx->eloop, psp->psp_fd, ELE_READ,
+ recv_unpriv_msg, psp) == -1)
{
- logerr("%s: eloop_event_add", __func__);
+ logerr("%s: eloop_event_add fd %d",
+ __func__, psp->psp_fd);
return -1;
}
+#ifdef HAVE_CAPSICUM
+ if (eloop_event_add(ctx->eloop, psp->psp_pfd, ELE_HANGUP,
+ ps_processhangup, psp) == -1)
+ {
+ logerr("%s: eloop_event_add pfd %d",
+ __func__, psp->psp_pfd);
+ return -1;
+ }
+#endif
+ psp->psp_started = true;
return pid;
}
- ctx->options |= DHCPCD_FORKED;
- if (ctx->fork_fd != -1) {
- close(ctx->fork_fd);
- ctx->fork_fd = -1;
- }
- pidfile_clean();
- eloop_clear(ctx->eloop);
+#ifdef PLUGIN_DEV
+ /* If we are not the root process, stop listening to devices. */
+ if (ctx->ps_root != psp)
+ dev_stop(ctx);
+#endif
+
+ ctx->options |= DHCPCD_FORKED;
+ if (ctx->ps_log_fd != -1)
+ logsetfd(ctx->ps_log_fd);
+ eloop_clear(ctx->eloop, -1);
+ eloop_forked(ctx->eloop);
eloop_signal_set_cb(ctx->eloop,
dhcpcd_signals, dhcpcd_signals_len, signal_cb, ctx);
/* ctx->sigset aready has the initial sigmask set in main() */
@@ -388,16 +432,31 @@ ps_dostart(struct dhcpcd_ctx *ctx,
goto errexit;
}
- /* We are not root */
- if (priv_fd != &ctx->ps_root_fd) {
- ps_freeprocesses(ctx, recv_ctx);
- if (ctx->ps_root_fd != -1) {
- close(ctx->ps_root_fd);
- ctx->ps_root_fd = -1;
- }
+ if (ctx->fork_fd != -1) {
+ /* Already removed from eloop thanks to above clear. */
+ close(ctx->fork_fd);
+ ctx->fork_fd = -1;
+ }
+ /* This process has no need of the blocking inner eloop. */
+ if (!(flags & PSF_ELOOP)) {
+ eloop_free(ctx->ps_eloop);
+ ctx->ps_eloop = NULL;
+ } else
+ eloop_forked(ctx->ps_eloop);
+
+ pidfile_clean();
+ ps_freeprocesses(ctx, psp);
+
+ if (ctx->ps_root != psp) {
+ ctx->options &= ~DHCPCD_PRIVSEPROOT;
+ ctx->ps_root = NULL;
+ if (ctx->ps_log_root_fd != -1) {
+ /* Already removed from eloop thanks to above clear. */
+ close(ctx->ps_log_root_fd);
+ ctx->ps_log_root_fd = -1;
+ }
#ifdef PRIVSEP_RIGHTS
- /* We cannot limit the root process in any way. */
if (ps_rights_limit_stdio(ctx) == -1) {
logerr("ps_rights_limit_stdio");
goto errexit;
@@ -405,58 +464,88 @@ ps_dostart(struct dhcpcd_ctx *ctx,
#endif
}
- if (priv_fd != &ctx->ps_inet_fd && ctx->ps_inet_fd != -1) {
- close(ctx->ps_inet_fd);
- ctx->ps_inet_fd = -1;
- }
+ if (ctx->ps_inet != psp)
+ ctx->ps_inet = NULL;
+ if (ctx->ps_ctl != psp)
+ ctx->ps_ctl = NULL;
+
+#if 0
+ char buf[1024];
+ errno = 0;
+ ssize_t xx = recv(psp->psp_fd, buf, sizeof(buf), MSG_PEEK);
+ logerr("pid %d test fd %d recv peek %zd", getpid(), psp->psp_fd, xx);
+#endif
- if (eloop_event_add(ctx->eloop, *priv_fd, recv_msg, recv_ctx) == -1)
+ if (eloop_event_add(ctx->eloop, psp->psp_fd, ELE_READ,
+ recv_msg, psp) == -1)
{
- logerr("%s: eloop_event_add", __func__);
+ logerr("%d %s: eloop_event_add XX fd %d", getpid(), __func__, psp->psp_fd);
goto errexit;
}
- if (callback(recv_ctx) == -1)
+ if (callback(psp) == -1)
goto errexit;
if (flags & PSF_DROPPRIVS)
ps_dropprivs(ctx);
+ psp->psp_started = true;
return 0;
errexit:
- /* Failure to start root or inet processes is fatal. */
- if (priv_fd == &ctx->ps_root_fd || priv_fd == &ctx->ps_inet_fd)
- (void)ps_sendcmd(ctx, *priv_fd, PS_STOP, 0, NULL, 0);
- shutdown(*priv_fd, SHUT_RDWR);
- *priv_fd = -1;
+ if (psp->psp_fd != -1) {
+ close(psp->psp_fd);
+ psp->psp_fd = -1;
+ }
eloop_exit(ctx->eloop, EXIT_FAILURE);
return -1;
}
+void
+ps_process_timeout(void *arg)
+{
+ struct dhcpcd_ctx *ctx = arg;
+
+ logerrx("%s: timed out", __func__);
+ eloop_exit(ctx->eloop, EXIT_FAILURE);
+}
+
int
-ps_dostop(struct dhcpcd_ctx *ctx, pid_t *pid, int *fd)
+ps_stopprocess(struct ps_process *psp)
{
int err = 0;
+ if (psp == NULL)
+ return 0;
+
+ psp->psp_started = false;
+
#ifdef PRIVSEP_DEBUG
- logdebugx("%s: pid=%d fd=%d", __func__, *pid, *fd);
+ logdebugx("%s: me=%d pid=%d fd=%d %s", __func__,
+ getpid(), psp->psp_pid, psp->psp_fd, psp->psp_name);
#endif
- if (*fd != -1) {
- eloop_event_delete(ctx->eloop, *fd);
- if (ps_sendcmd(ctx, *fd, PS_STOP, 0, NULL, 0) == -1) {
+ if (psp->psp_fd != -1) {
+ eloop_event_delete(psp->psp_ctx->eloop, psp->psp_fd);
+#if 0
+ if (ps_sendcmd(psp->psp_ctx, psp->psp_fd, PS_STOP, 0,
+ NULL, 0) == -1)
+ {
+ logerr("%d %d %s %s", getpid(), psp->psp_pid, psp->psp_name, __func__);
+ err = -1;
+ }
+ shutdown(psp->psp_fd, SHUT_WR);
+#else
+ if (shutdown(psp->psp_fd, SHUT_WR) == -1) {
logerr(__func__);
err = -1;
}
- (void)shutdown(*fd, SHUT_RDWR);
- close(*fd);
- *fd = -1;
+#endif
+ psp->psp_fd = -1;
}
/* Don't wait for the process as it may not respond to the shutdown
* request. We'll reap the process on receipt of SIGCHLD. */
- *pid = 0;
return err;
}
@@ -467,6 +556,13 @@ ps_start(struct dhcpcd_ctx *ctx)
TAILQ_INIT(&ctx->ps_processes);
+ /* We need an inner eloop to block with. */
+ if ((ctx->ps_eloop = eloop_new()) == NULL)
+ return -1;
+ eloop_signal_set_cb(ctx->ps_eloop,
+ dhcpcd_signals, dhcpcd_signals_len,
+ dhcpcd_signal_cb, ctx);
+
switch (pid = ps_root_start(ctx)) {
case -1:
logerr("ps_root_start");
@@ -557,7 +653,7 @@ ps_managersandbox(struct dhcpcd_ctx *ctx
* If it cannot be opened before chrooting then syslog(3) will fail.
* openlog(3) does not return an error which doubly sucks.
*/
- if (ctx->ps_root_fd == -1) {
+ if (ctx->ps_root == NULL) {
unsigned int logopts = loggetopts();
logopts &= ~LOGERR_LOG;
@@ -606,39 +702,106 @@ ps_stop(struct dhcpcd_ctx *ctx)
ctx->eloop == NULL)
return 0;
- r = ps_ctl_stop(ctx);
- if (r != 0)
- ret = r;
-
- r = ps_inet_stop(ctx);
- if (r != 0)
- ret = r;
-
- /* We've been chrooted, so we need to tell the
- * privileged proxy to remove the pidfile. */
- ps_root_unlink(ctx, ctx->pidfile);
-
- r = ps_root_stop(ctx);
- if (r != 0)
- ret = r;
+ if (ctx->ps_ctl != NULL) {
+ r = ps_ctl_stop(ctx);
+ if (r != 0)
+ ret = r;
+ }
+
+ if (ctx->ps_inet != NULL) {
+ r = ps_inet_stop(ctx);
+ if (r != 0)
+ ret = r;
+ }
+
+ if (ctx->ps_root != NULL) {
+ if (ps_root_stopprocesses(ctx) == -1)
+ ret = -1;
+ }
- ctx->options &= ~DHCPCD_PRIVSEP;
return ret;
}
+bool
+ps_waitforprocs(struct dhcpcd_ctx *ctx)
+{
+ struct ps_process *psp = TAILQ_FIRST(&ctx->ps_processes);
+
+ if (psp == NULL)
+ return false;
+
+ /* Different processes */
+ if (psp != TAILQ_LAST(&ctx->ps_processes, ps_process_head))
+ return true;
+
+ return !psp->psp_started;
+}
+
+int
+ps_stopwait(struct dhcpcd_ctx *ctx)
+{
+ int error = EXIT_SUCCESS;
+
+ if (ctx->ps_eloop == NULL || !ps_waitforprocs(ctx))
+ return 0;
+
+ ctx->options |= DHCPCD_EXITING;
+ if (eloop_timeout_add_sec(ctx->ps_eloop, PS_PROCESS_TIMEOUT,
+ ps_process_timeout, ctx) == -1)
+ logerr("%s: eloop_timeout_add_sec", __func__);
+ eloop_enter(ctx->ps_eloop);
+
+#ifdef HAVE_CAPSICUM
+ struct ps_process *psp;
+
+ TAILQ_FOREACH(psp, &ctx->ps_processes, next) {
+ if (psp->psp_pfd == -1)
+ continue;
+ if (eloop_event_add(ctx->ps_eloop, psp->psp_pfd,
+ ELE_HANGUP, ps_processhangup, psp) == -1)
+ logerr("%s: eloop_event_add pfd %d",
+ __func__, psp->psp_pfd);
+ }
+#endif
+
+ error = eloop_start(ctx->ps_eloop, &ctx->sigset);
+ if (error != EXIT_SUCCESS)
+ logerr("%s: eloop_start", __func__);
+
+ eloop_timeout_delete(ctx->ps_eloop, ps_process_timeout, ctx);
+
+ return error;
+}
+
void
ps_freeprocess(struct ps_process *psp)
{
+ struct dhcpcd_ctx *ctx = psp->psp_ctx;
+
+ TAILQ_REMOVE(&ctx->ps_processes, psp, next);
- TAILQ_REMOVE(&psp->psp_ctx->ps_processes, psp, next);
if (psp->psp_fd != -1) {
- eloop_event_delete(psp->psp_ctx->eloop, psp->psp_fd);
+ eloop_event_delete(ctx->eloop, psp->psp_fd);
close(psp->psp_fd);
}
if (psp->psp_work_fd != -1) {
- eloop_event_delete(psp->psp_ctx->eloop, psp->psp_work_fd);
+ eloop_event_delete(ctx->eloop, psp->psp_work_fd);
close(psp->psp_work_fd);
}
+#ifdef HAVE_CAPSICUM
+ if (psp->psp_pfd != -1) {
+ eloop_event_delete(ctx->eloop, psp->psp_pfd);
+ if (ctx->ps_eloop != NULL)
+ eloop_event_delete(ctx->ps_eloop, psp->psp_pfd);
+ close(psp->psp_pfd);
+ }
+#endif
+ if (ctx->ps_root == psp)
+ ctx->ps_root = NULL;
+ if (ctx->ps_inet == psp)
+ ctx->ps_inet = NULL;
+ if (ctx->ps_ctl == psp)
+ ctx->ps_ctl = NULL;
#ifdef INET
if (psp->psp_bpf != NULL)
bpf_close(psp->psp_bpf);
@@ -649,12 +812,23 @@ ps_freeprocess(struct ps_process *psp)
static void
ps_free(struct dhcpcd_ctx *ctx)
{
- struct ps_process *psp;
- bool stop = ctx->ps_root_pid == getpid();
+ struct ps_process *ppsp, *psp;
+ bool stop;
+
+ if (ctx->ps_root != NULL)
+ ppsp = ctx->ps_root;
+ else if (ctx->ps_ctl != NULL)
+ ppsp = ctx->ps_ctl;
+ else
+ ppsp = NULL;
+ if (ppsp != NULL)
+ stop = ppsp->psp_pid == getpid();
+ else
+ stop = false;
while ((psp = TAILQ_FIRST(&ctx->ps_processes)) != NULL) {
- if (stop)
- ps_dostop(ctx, &psp->psp_pid, &psp->psp_fd);
+ if (stop && psp != ppsp)
+ ps_stopprocess(psp);
ps_freeprocess(psp);
}
}
@@ -760,7 +934,6 @@ ps_sendpsmmsg(struct dhcpcd_ctx *ctx, in
len = writev(fd, iov, iovlen);
if (len == -1) {
- logerr(__func__);
if (ctx->options & DHCPCD_FORKED &&
!(ctx->options & DHCPCD_PRIVSEPROOT))
eloop_exit(ctx->eloop, EXIT_FAILURE);
@@ -896,7 +1069,8 @@ nobufs:
}
ssize_t
-ps_recvmsg(struct dhcpcd_ctx *ctx, int rfd, uint16_t cmd, int wfd)
+ps_recvmsg(struct dhcpcd_ctx *ctx, int rfd, unsigned short events,
+ uint16_t cmd, int wfd)
{
struct sockaddr_storage ss = { .ss_family = AF_UNSPEC };
uint8_t controlbuf[sizeof(struct sockaddr_storage)] = { 0 };
@@ -909,32 +1083,33 @@ ps_recvmsg(struct dhcpcd_ctx *ctx, int r
.msg_control = controlbuf, .msg_controllen = sizeof(controlbuf),
.msg_iov = iov, .msg_iovlen = 1,
};
+ ssize_t len;
- ssize_t len = recvmsg(rfd, &msg, 0);
+ if (!(events & ELE_READ))
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+ len = recvmsg(rfd, &msg, 0);
if (len == -1)
logerr("%s: recvmsg", __func__);
if (len == -1 || len == 0) {
- if (ctx->options & DHCPCD_FORKED &&
- !(ctx->options & DHCPCD_PRIVSEPROOT))
+ if (ctx->options & DHCPCD_FORKED)
eloop_exit(ctx->eloop,
- len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+ len != -1 ? EXIT_SUCCESS : EXIT_FAILURE);
return len;
}
iov[0].iov_len = (size_t)len;
len = ps_sendcmdmsg(wfd, cmd, &msg);
if (len == -1) {
- logerr("ps_sendcmdmsg");
- if (ctx->options & DHCPCD_FORKED &&
- !(ctx->options & DHCPCD_PRIVSEPROOT))
+ logerr("%s: ps_sendcmdmsg", __func__);
+ if (ctx->options & DHCPCD_FORKED)
eloop_exit(ctx->eloop, EXIT_FAILURE);
}
return len;
}
ssize_t
-ps_recvpsmsg(struct dhcpcd_ctx *ctx, int fd,
+ps_recvpsmsg(struct dhcpcd_ctx *ctx, int fd, unsigned short events,
ssize_t (*callback)(void *, struct ps_msghdr *, struct msghdr *),
void *cbctx)
{
@@ -945,6 +1120,9 @@ ps_recvpsmsg(struct dhcpcd_ctx *ctx, int
struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 1 };
bool stop = false;
+ if (!(events & ELE_READ))
+ logerrx("%s: unexpected event 0x%04x", __func__, events);
+
len = read(fd, &psm, sizeof(psm));
#ifdef PRIVSEP_DEBUG
logdebugx("%s: %zd", __func__, len);
@@ -966,13 +1144,11 @@ ps_recvpsmsg(struct dhcpcd_ctx *ctx, int
}
if (stop) {
+ ctx->options |= DHCPCD_EXITING;
#ifdef PRIVSEP_DEBUG
logdebugx("process %d stopping", getpid());
#endif
ps_free(ctx);
-#ifdef PLUGIN_DEV
- dev_stop(ctx);
-#endif
eloop_exit(ctx->eloop, len != -1 ? EXIT_SUCCESS : EXIT_FAILURE);
return len;
}
@@ -994,6 +1170,8 @@ ps_findprocess(struct dhcpcd_ctx *ctx, s
struct ps_process *psp;
TAILQ_FOREACH(psp, &ctx->ps_processes, next) {
+ if (!(psp->psp_started))
+ continue;
if (memcmp(&psp->psp_id, psid, sizeof(psp->psp_id)) == 0)
return psp;
}
@@ -1002,6 +1180,19 @@ ps_findprocess(struct dhcpcd_ctx *ctx, s
}
struct ps_process *
+ps_findprocesspid(struct dhcpcd_ctx *ctx, pid_t pid)
+{
+ struct ps_process *psp;
+
+ TAILQ_FOREACH(psp, &ctx->ps_processes, next) {
+ if (psp->psp_pid == pid)
+ return psp;
+ }
+ errno = ESRCH;
+ return NULL;
+}
+
+struct ps_process *
ps_newprocess(struct dhcpcd_ctx *ctx, struct ps_id *psid)
{
struct ps_process *psp;
@@ -1012,6 +1203,12 @@ ps_newprocess(struct dhcpcd_ctx *ctx, st
psp->psp_ctx = ctx;
memcpy(&psp->psp_id, psid, sizeof(psp->psp_id));
psp->psp_work_fd = -1;
+#ifdef HAVE_CAPSICUM
+ psp->psp_pfd = -1;
+#endif
+
+ if (!(ctx->options & DHCPCD_MANAGER))
+ strlcpy(psp->psp_ifname, ctx->ifv[0], sizeof(psp->psp_name));
TAILQ_INSERT_TAIL(&ctx->ps_processes, psp, next);
return psp;
}
Index: src/external/bsd/dhcpcd/dist/src/logerr.c
diff -u src/external/bsd/dhcpcd/dist/src/logerr.c:1.12 src/external/bsd/dhcpcd/dist/src/logerr.c:1.13
--- src/external/bsd/dhcpcd/dist/src/logerr.c:1.12 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/logerr.c Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* logerr: errx with logging
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
Index: src/external/bsd/dhcpcd/dist/src/script.c
diff -u src/external/bsd/dhcpcd/dist/src/script.c:1.14 src/external/bsd/dhcpcd/dist/src/script.c:1.15
--- src/external/bsd/dhcpcd/dist/src/script.c:1.14 Fri Oct 22 13:23:20 2021
+++ src/external/bsd/dhcpcd/dist/src/script.c Fri Apr 21 16:54:26 2023
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2021 Roy Marples <[email protected]>
+ * Copyright (c) 2006-2023 Roy Marples <[email protected]>
* All rights reserved
* Redistribution and use in source and binary forms, with or without