diff --git a/external/bsd/dhcpcd/dist/src/bpf.c b/external/bsd/dhcpcd/dist/src/bpf.c index b75bfb04ca3f..caf9fda6c328 100644 --- a/external/bsd/dhcpcd/dist/src/bpf.c +++ b/external/bsd/dhcpcd/dist/src/bpf.c @@ -610,16 +610,19 @@ static const struct bpf_insn bpf_bootp_base[] = { #define BPF_BOOTP_BASE_LEN __arraycount(bpf_bootp_base) static const struct bpf_insn bpf_bootp_read[] = { - /* Make sure it's from and to the right port. */ - BPF_STMT(BPF_LD + BPF_W + BPF_IND, 0), - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (BOOTPS << 16) + BOOTPC, 1, 0), + /* Make sure it's to the right port. + * RFC2131 makes no mention of enforcing a source port. */ + BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct udphdr, uh_dport)), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTPC, 1, 0), BPF_STMT(BPF_RET + BPF_K, 0), }; #define BPF_BOOTP_READ_LEN __arraycount(bpf_bootp_read) #ifdef BIOCSETWF static const struct bpf_insn bpf_bootp_write[] = { - /* Make sure it's from and to the right port. */ + /* Make sure it's from and to the right port. + * RFC2131 makes no mention of encforcing a source port, + * but dhcpcd does enforce it for sending. */ BPF_STMT(BPF_LD + BPF_W + BPF_IND, 0), BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (BOOTPC << 16) + BOOTPS, 1, 0), BPF_STMT(BPF_RET + BPF_K, 0), diff --git a/external/bsd/dhcpcd/dist/src/dhcp.c b/external/bsd/dhcpcd/dist/src/dhcp.c index 233bd10736d4..edd1c011bb08 100644 --- a/external/bsd/dhcpcd/dist/src/dhcp.c +++ b/external/bsd/dhcpcd/dist/src/dhcp.c @@ -3436,8 +3436,8 @@ is_packet_udp_bootp(void *packet, size_t plen) if (ip_hlen + ntohs(udp.uh_ulen) > plen) return false; - /* Check it's to and from the right ports. */ - if (udp.uh_dport != htons(BOOTPC) || udp.uh_sport != htons(BOOTPS)) + /* Check it's to the right port. */ + if (udp.uh_dport != htons(BOOTPC)) return false; return true; diff --git a/external/bsd/dhcpcd/dist/src/dhcp6.c b/external/bsd/dhcpcd/dist/src/dhcp6.c index 1131f70f1c68..e7767ca744c9 100644 --- a/external/bsd/dhcpcd/dist/src/dhcp6.c +++ b/external/bsd/dhcpcd/dist/src/dhcp6.c @@ -1667,10 +1667,7 @@ dhcp6_startinform(void *arg) ifp = arg; state = D6_STATE(ifp); - if (state->new_start || (state->new == NULL && !state->failed)) - llevel = LOG_INFO; - else - llevel = LOG_DEBUG; + llevel = state->failed ? LOG_DEBUG : LOG_INFO; logmessage(llevel, "%s: requesting DHCPv6 information", ifp->name); state->state = DH6S_INFORM; state->RTC = 0; @@ -3069,7 +3066,7 @@ dhcp6_bind(struct interface *ifp, const char *op, const char *sfrom) int loglevel; struct timespec now; - if (state->state == DH6S_RENEW && !state->new_start) { + if (state->state == DH6S_RENEW) { loglevel = LOG_DEBUG; TAILQ_FOREACH(ia, &state->addrs, next) { if (ia->flags & IPV6_AF_NEW) { @@ -3968,8 +3965,10 @@ dhcp6_start(struct interface *ifp, enum DH6S init_state) { /* We don't want log spam when the RA * has just adjusted it's prefix times. */ - if (state->state != DH6S_INFORMED) + if (state->state != DH6S_INFORMED) { state->new_start = true; + state->failed = false; + } dhcp6_startinform(ifp); } break; diff --git a/external/bsd/dhcpcd/dist/src/dhcpcd.c b/external/bsd/dhcpcd/dist/src/dhcpcd.c index d663c383e8bd..e06733d318bc 100644 --- a/external/bsd/dhcpcd/dist/src/dhcpcd.c +++ b/external/bsd/dhcpcd/dist/src/dhcpcd.c @@ -256,7 +256,7 @@ dhcpcd_ifafwaiting(const struct interface *ifp) bool foundaddr = ipv6_hasaddr(ifp); if (opts & DHCPCD_WAITIP6 && !foundaddr) - return AF_INET; + return AF_INET6; if (foundaddr) foundany = true; } @@ -1816,8 +1816,11 @@ dhcpcd_stderr_cb(void *arg, unsigned short events) char log[BUFSIZ]; ssize_t len; - if (events != ELE_READ) - logerrx("%s: unexpected event 0x%04x", __func__, events); + if (events & ELE_HANGUP) + eloop_exit(ctx->eloop, EXIT_SUCCESS); + + if (!(events & ELE_READ)) + return; len = read(ctx->stderr_fd, log, sizeof(log)); if (len == -1) { diff --git a/external/bsd/dhcpcd/dist/src/if-bsd.c b/external/bsd/dhcpcd/dist/src/if-bsd.c index 6ebba38d6cea..bab33c2ca6a9 100644 --- a/external/bsd/dhcpcd/dist/src/if-bsd.c +++ b/external/bsd/dhcpcd/dist/src/if-bsd.c @@ -153,6 +153,9 @@ if_opensockets_os(struct dhcpcd_ctx *ctx) RTM_ADD, RTM_CHANGE, RTM_DELETE, RTM_MISS, #ifdef RTM_CHGADDR RTM_CHGADDR, +#endif +#ifdef RTM_DESYNC + RTM_DESYNC, #endif RTM_NEWADDR, RTM_DELADDR }; @@ -1332,6 +1335,11 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam) ifam->ifam_msglen - sizeof(*ifam), rti_info) == -1) return -1; + /* All BSD's set IFF_UP on the interface when adding an address. + * But not all BSD's emit this via RTM_IFINFO when they do this ... */ + if (ifam->ifam_type == RTM_NEWADDR && !(ifp->flags & IFF_UP)) + dhcpcd_handlecarrier(ifp, ifp->carrier, ifp->flags | IFF_UP); + switch (rti_info[RTAX_IFA]->sa_family) { case AF_LINK: { @@ -1755,10 +1763,9 @@ ip6_forwarding(__unused const char *ifname) static int if_af_attach(const struct interface *ifp, int af) { - struct if_afreq ifar; + struct if_afreq ifar = { .ifar_af = af }; strlcpy(ifar.ifar_name, ifp->name, sizeof(ifar.ifar_name)); - ifar.ifar_af = af; return if_ioctl6(ifp->ctx, SIOCIFAFATTACH, &ifar, sizeof(ifar)); } #endif @@ -1832,23 +1839,20 @@ if_disable_rtadv(void) void if_setup_inet6(const struct interface *ifp) { +#ifdef ND6_NDI_FLAGS struct priv *priv; int s; -#ifdef ND6_NDI_FLAGS struct in6_ndireq nd; int flags; -#endif priv = (struct priv *)ifp->ctx->priv; s = priv->pf_inet6_fd; -#ifdef ND6_NDI_FLAGS memset(&nd, 0, sizeof(nd)); strlcpy(nd.ifname, ifp->name, sizeof(nd.ifname)); if (ioctl(s, SIOCGIFINFO_IN6, &nd) == -1) logerr("%s: SIOCGIFINFO_FLAGS", ifp->name); flags = (int)nd.ndi.flags; -#endif #ifdef ND6_IFF_AUTO_LINKLOCAL /* Unlike the kernel, dhcpcd make make a stable private address. */ @@ -1878,14 +1882,13 @@ if_setup_inet6(const struct interface *ifp) #endif #endif -#ifdef ND6_NDI_FLAGS if (nd.ndi.flags != (uint32_t)flags) { nd.ndi.flags = (uint32_t)flags; if (if_ioctl6(ifp->ctx, SIOCSIFINFO_FLAGS, &nd, sizeof(nd)) == -1) logerr("%s: SIOCSIFINFO_FLAGS", ifp->name); } -#endif +#endif /* ND6_NDI_FLAGS */ /* Enabling IPv6 by whatever means must be the * last action undertaken to ensure kernel RS and diff --git a/external/bsd/dhcpcd/dist/src/if-options.c b/external/bsd/dhcpcd/dist/src/if-options.c index 1ef9cc992777..bb1c1fca5793 100644 --- a/external/bsd/dhcpcd/dist/src/if-options.c +++ b/external/bsd/dhcpcd/dist/src/if-options.c @@ -958,11 +958,16 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, break; case 'w': ifo->options |= DHCPCD_WAITIP; - if (arg != NULL && arg[0] != '\0') { - if (arg[0] == '4' || arg[1] == '4') + p = UNCONST(arg); + // Generally it's --waitip=46, but some expect + // --waitip="4 6" to work as well. + // It's easier to allow it rather than have confusing docs. + while (p != NULL && p[0] != '\0') { + if (p[0] == '4' || p[1] == '4') ifo->options |= DHCPCD_WAITIP4; - if (arg[0] == '6' || arg[1] == '6') + if (p[0] == '6' || p[1] == '6') ifo->options |= DHCPCD_WAITIP6; + p = strskipwhite(++p); } break; case 'y': diff --git a/external/bsd/dhcpcd/dist/src/privsep.c b/external/bsd/dhcpcd/dist/src/privsep.c index 765756d76688..b11c0351c25e 100644 --- a/external/bsd/dhcpcd/dist/src/privsep.c +++ b/external/bsd/dhcpcd/dist/src/privsep.c @@ -1069,8 +1069,7 @@ nobufs: } ssize_t -ps_recvmsg(struct dhcpcd_ctx *ctx, int rfd, unsigned short events, - uint16_t cmd, int wfd) +ps_recvmsg(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 }; @@ -1089,22 +1088,15 @@ ps_recvmsg(struct dhcpcd_ctx *ctx, int rfd, unsigned short events, logerrx("%s: unexpected event 0x%04x", __func__, events); len = recvmsg(rfd, &msg, 0); - if (len == -1) + if (len == -1) { logerr("%s: recvmsg", __func__); - if (len == -1 || len == 0) { - if (ctx->options & DHCPCD_FORKED) - eloop_exit(ctx->eloop, - len != -1 ? EXIT_SUCCESS : EXIT_FAILURE); return len; } iov[0].iov_len = (size_t)len; len = ps_sendcmdmsg(wfd, cmd, &msg); - if (len == -1) { + if (len == -1) logerr("%s: ps_sendcmdmsg", __func__); - if (ctx->options & DHCPCD_FORKED) - eloop_exit(ctx->eloop, EXIT_FAILURE); - } return len; } diff --git a/external/bsd/dhcpcd/dist/src/script.c b/external/bsd/dhcpcd/dist/src/script.c index 94101d4d628c..2ef99e38f7ce 100644 --- a/external/bsd/dhcpcd/dist/src/script.c +++ b/external/bsd/dhcpcd/dist/src/script.c @@ -764,7 +764,7 @@ script_runreason(const struct interface *ifp, const char *reason) #ifdef PRIVSEP if (ctx->options & DHCPCD_PRIVSEP) { if (ps_root_script(ctx, - ctx->script_buf, ctx->script_buflen) == -1) + ctx->script_buf, (size_t)buflen) == -1) logerr(__func__); goto send_listeners; }