Sync
This commit is contained in:
parent
372b3c16e6
commit
4d6391b4f4
91
external/bsd/dhcpcd/dist/arp.c
vendored
91
external/bsd/dhcpcd/dist/arp.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: arp.c,v 1.11 2015/03/27 18:53:15 christos Exp $");
|
||||
__RCSID("$NetBSD: arp.c,v 1.12 2015/05/02 15:18:36 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -44,6 +44,7 @@
|
||||
#define ELOOP_QUEUE 5
|
||||
#include "config.h"
|
||||
#include "arp.h"
|
||||
#include "if.h"
|
||||
#include "ipv4.h"
|
||||
#include "common.h"
|
||||
#include "dhcp.h"
|
||||
@ -57,7 +58,7 @@
|
||||
(sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN))
|
||||
|
||||
static ssize_t
|
||||
arp_send(const struct interface *ifp, int op, in_addr_t sip, in_addr_t tip)
|
||||
arp_request(const struct interface *ifp, in_addr_t sip, in_addr_t tip)
|
||||
{
|
||||
uint8_t arp_buffer[ARP_LEN];
|
||||
struct arphdr ar;
|
||||
@ -68,7 +69,7 @@ arp_send(const struct interface *ifp, int op, in_addr_t sip, in_addr_t tip)
|
||||
ar.ar_pro = htons(ETHERTYPE_IP);
|
||||
ar.ar_hln = ifp->hwlen;
|
||||
ar.ar_pln = sizeof(sip);
|
||||
ar.ar_op = htons((uint16_t)op);
|
||||
ar.ar_op = htons(ARPOP_REQUEST);
|
||||
|
||||
p = arp_buffer;
|
||||
len = 0;
|
||||
@ -99,12 +100,20 @@ eexit:
|
||||
void
|
||||
arp_report_conflicted(const struct arp_state *astate, const struct arp_msg *amsg)
|
||||
{
|
||||
char buf[HWADDR_LEN * 3];
|
||||
|
||||
logger(astate->iface->ctx, LOG_ERR, "%s: hardware address %s claims %s",
|
||||
astate->iface->name,
|
||||
hwaddr_ntoa(amsg->sha, astate->iface->hwlen, buf, sizeof(buf)),
|
||||
inet_ntoa(astate->failed));
|
||||
if (amsg) {
|
||||
char buf[HWADDR_LEN * 3];
|
||||
|
||||
logger(astate->iface->ctx, LOG_ERR,
|
||||
"%s: hardware address %s claims %s",
|
||||
astate->iface->name,
|
||||
hwaddr_ntoa(amsg->sha, astate->iface->hwlen,
|
||||
buf, sizeof(buf)),
|
||||
inet_ntoa(astate->failed));
|
||||
} else
|
||||
logger(astate->iface->ctx, LOG_ERR,
|
||||
"%s: DAD detected %s",
|
||||
astate->iface->name, inet_ntoa(astate->failed));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -226,8 +235,7 @@ arp_announce1(void *arg)
|
||||
"%s: ARP announcing %s (%d of %d)",
|
||||
ifp->name, inet_ntoa(astate->addr),
|
||||
astate->claims, ANNOUNCE_NUM);
|
||||
if (arp_send(ifp, ARPOP_REQUEST,
|
||||
astate->addr.s_addr, astate->addr.s_addr) == -1)
|
||||
if (arp_request(ifp, astate->addr.s_addr, astate->addr.s_addr) == -1)
|
||||
logger(ifp->ctx, LOG_ERR, "send_arp: %m");
|
||||
eloop_timeout_add_sec(ifp->ctx->eloop, ANNOUNCE_WAIT,
|
||||
astate->claims < ANNOUNCE_NUM ? arp_announce1 : arp_announced,
|
||||
@ -274,7 +282,7 @@ arp_probe1(void *arg)
|
||||
ifp->name, inet_ntoa(astate->addr),
|
||||
astate->probes ? astate->probes : PROBE_NUM, PROBE_NUM,
|
||||
timespec_to_double(&tv));
|
||||
if (arp_send(ifp, ARPOP_REQUEST, 0, astate->addr.s_addr) == -1)
|
||||
if (arp_request(ifp, 0, astate->addr.s_addr) == -1)
|
||||
logger(ifp->ctx, LOG_ERR, "send_arp: %m");
|
||||
}
|
||||
|
||||
@ -289,19 +297,38 @@ arp_probe(struct arp_state *astate)
|
||||
arp_probe1(astate);
|
||||
}
|
||||
|
||||
struct arp_state *
|
||||
arp_new(struct interface *ifp) {
|
||||
static struct arp_state *
|
||||
arp_find(struct interface *ifp, const struct in_addr *addr)
|
||||
{
|
||||
struct arp_state *astate;
|
||||
struct dhcp_state *state;
|
||||
|
||||
astate = calloc(1, sizeof(*astate));
|
||||
if (astate == NULL) {
|
||||
state = D_STATE(ifp);
|
||||
TAILQ_FOREACH(astate, &state->arp_states, next) {
|
||||
if (astate->addr.s_addr == addr->s_addr && astate->iface == ifp)
|
||||
return astate;
|
||||
}
|
||||
errno = ESRCH;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct arp_state *
|
||||
arp_new(struct interface *ifp, const struct in_addr *addr)
|
||||
{
|
||||
struct arp_state *astate;
|
||||
struct dhcp_state *state;
|
||||
|
||||
if (addr && (astate = arp_find(ifp, addr)))
|
||||
return astate;
|
||||
|
||||
if ((astate = calloc(1, sizeof(*astate))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
astate->iface = ifp;
|
||||
state = D_STATE(ifp);
|
||||
astate->iface = ifp;
|
||||
if (addr)
|
||||
astate->addr = *addr;
|
||||
TAILQ_INSERT_TAIL(&state->arp_states, astate, next);
|
||||
return astate;
|
||||
}
|
||||
@ -366,3 +393,33 @@ arp_close(struct interface *ifp)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
arp_handleifa(int cmd, struct interface *ifp, const struct in_addr *addr,
|
||||
int flags)
|
||||
{
|
||||
#ifdef IN_IFF_DUPLICATED
|
||||
struct dhcp_state *state = D_STATE(ifp);
|
||||
struct arp_state *astate, *asn;
|
||||
|
||||
if (cmd != RTM_NEWADDR || (state = D_STATE(ifp)) == 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->conflicted_cb)
|
||||
astate->conflicted_cb(astate, NULL);
|
||||
} else if (!(flags & IN_IFF_NOTUSEABLE)) {
|
||||
if (astate->probed_cb)
|
||||
astate->probed_cb(astate);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
UNUSED(cmd);
|
||||
UNUSED(ifp);
|
||||
UNUSED(addr);
|
||||
UNUSED(flags);
|
||||
#endif
|
||||
}
|
||||
|
6
external/bsd/dhcpcd/dist/arp.h
vendored
6
external/bsd/dhcpcd/dist/arp.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: arp.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */
|
||||
/* $NetBSD: arp.h,v 1.9 2015/05/02 15:18:36 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -71,11 +71,13 @@ TAILQ_HEAD(arp_statehead, arp_state);
|
||||
void arp_report_conflicted(const struct arp_state *, const struct arp_msg *);
|
||||
void arp_announce(struct arp_state *);
|
||||
void arp_probe(struct arp_state *);
|
||||
struct arp_state *arp_new(struct interface *);
|
||||
struct arp_state *arp_new(struct interface *, const struct in_addr *);
|
||||
void arp_cancel(struct arp_state *);
|
||||
void arp_free(struct arp_state *);
|
||||
void arp_free_but(struct arp_state *);
|
||||
void arp_close(struct interface *);
|
||||
|
||||
void arp_handleifa(int, struct interface *, const struct in_addr *, int);
|
||||
#else
|
||||
#define arp_close(a) {}
|
||||
#endif
|
||||
|
9
external/bsd/dhcpcd/dist/common.c
vendored
9
external/bsd/dhcpcd/dist/common.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: common.c,v 1.11 2015/03/31 18:01:09 christos Exp $");
|
||||
__RCSID("$NetBSD: common.c,v 1.12 2015/05/02 15:18:36 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -28,11 +28,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Needed define to get at getline for glibc and FreeBSD */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <mach/mach_time.h>
|
||||
# include <mach/kern_return.h>
|
||||
@ -196,8 +191,8 @@ logger(struct dhcpcd_ctx *ctx, int pri, const char *fmt, ...)
|
||||
return;
|
||||
|
||||
serrno = errno;
|
||||
|
||||
va_start(va, fmt);
|
||||
|
||||
#ifndef HAVE_PRINTF_M
|
||||
/* Print strerrno(errno) in place of %m */
|
||||
if (ctx == NULL || !(ctx->options & DHCPCD_QUIET) || ctx->log_fd != -1)
|
||||
|
4
external/bsd/dhcpcd/dist/defs.h
vendored
4
external/bsd/dhcpcd/dist/defs.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: defs.h,v 1.16 2015/03/27 11:33:46 roy Exp $ */
|
||||
/* $NetBSD: defs.h,v 1.17 2015/05/02 15:18:36 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -30,7 +30,7 @@
|
||||
#define CONFIG_H
|
||||
|
||||
#define PACKAGE "dhcpcd"
|
||||
#define VERSION "6.8.1"
|
||||
#define VERSION "6.8.2"
|
||||
|
||||
#ifndef CONFIG
|
||||
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
|
||||
|
299
external/bsd/dhcpcd/dist/dhcp.c
vendored
299
external/bsd/dhcpcd/dist/dhcp.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: dhcp.c,v 1.29 2015/03/28 14:16:52 christos Exp $");
|
||||
__RCSID("$NetBSD: dhcp.c,v 1.30 2015/05/02 15:18:36 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -163,6 +163,12 @@ get_option(struct dhcpcd_ctx *ctx,
|
||||
const uint8_t *op = NULL;
|
||||
size_t bl = 0;
|
||||
|
||||
/* Check we have the magic cookie */
|
||||
if (dhcp->cookie != htonl(MAGIC_COOKIE)) {
|
||||
errno = ENOTSUP;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (p < e) {
|
||||
o = *p++;
|
||||
if (o == opt) {
|
||||
@ -621,11 +627,11 @@ get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp)
|
||||
p = get_option(ifp->ctx, dhcp, DHO_STATICROUTE, &len);
|
||||
else
|
||||
p = NULL;
|
||||
if (p) {
|
||||
/* RFC 2131 Section 5.8 states length MUST be in multiples of 8 */
|
||||
if (p && len % 8 == 0) {
|
||||
e = p + len;
|
||||
while (p < e) {
|
||||
route = calloc(1, sizeof(*route));
|
||||
if (route == NULL) {
|
||||
if ((route = calloc(1, sizeof(*route))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
ipv4_freeroutes(routes);
|
||||
return NULL;
|
||||
@ -634,6 +640,13 @@ get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp)
|
||||
p += 4;
|
||||
memcpy(&route->gate.s_addr, p, 4);
|
||||
p += 4;
|
||||
/* RFC 2131 Section 5.8 states default route is
|
||||
* illegal */
|
||||
if (route->dest.s_addr == htonl(INADDR_ANY)) {
|
||||
errno = EINVAL;
|
||||
free(route);
|
||||
continue;
|
||||
}
|
||||
route->net.s_addr = route_netmask(route->dest.s_addr);
|
||||
TAILQ_INSERT_TAIL(routes, route, next);
|
||||
}
|
||||
@ -647,8 +660,7 @@ get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp)
|
||||
if (p) {
|
||||
e = p + len;
|
||||
while (p < e) {
|
||||
route = calloc(1, sizeof(*route));
|
||||
if (route == NULL) {
|
||||
if ((route = calloc(1, sizeof(*route))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
ipv4_freeroutes(routes);
|
||||
return NULL;
|
||||
@ -701,10 +713,10 @@ make_message(struct dhcp_message **message,
|
||||
{
|
||||
struct dhcp_message *dhcp;
|
||||
uint8_t *m, *lp, *p, *auth;
|
||||
uint8_t *n_params = NULL;
|
||||
uint8_t *n_params = NULL, auth_len;
|
||||
uint32_t ul;
|
||||
uint16_t sz;
|
||||
size_t len, i, auth_len;
|
||||
size_t len, i;
|
||||
const struct dhcp_opt *opt;
|
||||
struct if_options *ifo = ifp->options;
|
||||
const struct dhcp_state *state = D_CSTATE(ifp);
|
||||
@ -757,9 +769,11 @@ make_message(struct dhcp_message **message,
|
||||
dhcp->xid = htonl(state->xid);
|
||||
dhcp->cookie = htonl(MAGIC_COOKIE);
|
||||
|
||||
*p++ = DHO_MESSAGETYPE;
|
||||
*p++ = 1;
|
||||
*p++ = type;
|
||||
if (!(ifo->options & DHCPCD_BOOTP)) {
|
||||
*p++ = DHO_MESSAGETYPE;
|
||||
*p++ = 1;
|
||||
*p++ = type;
|
||||
}
|
||||
|
||||
if (state->clientid) {
|
||||
*p++ = DHO_CLIENTID;
|
||||
@ -814,23 +828,25 @@ make_message(struct dhcp_message **message,
|
||||
type == DHCP_INFORM ||
|
||||
type == DHCP_REQUEST)
|
||||
{
|
||||
int mtu;
|
||||
if (!(ifo->options & DHCPCD_BOOTP)) {
|
||||
int mtu;
|
||||
|
||||
*p++ = DHO_MAXMESSAGESIZE;
|
||||
*p++ = 2;
|
||||
mtu = if_getmtu(ifp->name);
|
||||
if (mtu < MTU_MIN) {
|
||||
if (if_setmtu(ifp->name, MTU_MIN) == 0)
|
||||
sz = MTU_MIN;
|
||||
} else if (mtu > MTU_MAX) {
|
||||
/* Even though our MTU could be greater than
|
||||
* MTU_MAX (1500) dhcpcd does not presently
|
||||
* handle DHCP packets any bigger. */
|
||||
mtu = MTU_MAX;
|
||||
*p++ = DHO_MAXMESSAGESIZE;
|
||||
*p++ = 2;
|
||||
mtu = if_getmtu(ifp->name);
|
||||
if (mtu < MTU_MIN) {
|
||||
if (if_setmtu(ifp->name, MTU_MIN) == 0)
|
||||
sz = MTU_MIN;
|
||||
} else if (mtu > MTU_MAX) {
|
||||
/* Even though our MTU could be greater than
|
||||
* MTU_MAX (1500) dhcpcd does not presently
|
||||
* handle DHCP packets any bigger. */
|
||||
mtu = MTU_MAX;
|
||||
}
|
||||
sz = htons((uint16_t)mtu);
|
||||
memcpy(p, &sz, 2);
|
||||
p += 2;
|
||||
}
|
||||
sz = htons((uint16_t)mtu);
|
||||
memcpy(p, &sz, 2);
|
||||
p += 2;
|
||||
|
||||
if (ifo->userclass[0]) {
|
||||
*p++ = DHO_USERCLASS;
|
||||
@ -1004,19 +1020,23 @@ make_message(struct dhcp_message **message,
|
||||
auth = NULL;
|
||||
|
||||
if (ifo->auth.options & DHCPCD_AUTH_SEND) {
|
||||
auth_len = (size_t)dhcp_auth_encode(&ifo->auth,
|
||||
ssize_t alen = dhcp_auth_encode(&ifo->auth,
|
||||
state->auth.token,
|
||||
NULL, 0, 4, type, NULL, 0);
|
||||
if ((ssize_t)auth_len == -1) {
|
||||
if (alen != -1 && alen > UINT8_MAX) {
|
||||
errno = ERANGE;
|
||||
alen = -1;
|
||||
}
|
||||
if (alen == -1)
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: dhcp_auth_encode: %m", ifp->name);
|
||||
auth_len = 0;
|
||||
} else if (auth_len != 0) {
|
||||
len = (size_t)((p + auth_len) - m);
|
||||
if (auth_len > 255 || len > sizeof(*dhcp))
|
||||
else if (alen != 0) {
|
||||
auth_len = (uint8_t)alen;
|
||||
len = (size_t)((p + alen) - m);
|
||||
if (len > sizeof(*dhcp))
|
||||
goto toobig;
|
||||
*p++ = DHO_AUTHENTICATION;
|
||||
*p++ = (uint8_t)auth_len;
|
||||
*p++ = auth_len;
|
||||
auth = p;
|
||||
p += auth_len;
|
||||
}
|
||||
@ -1024,13 +1044,10 @@ make_message(struct dhcp_message **message,
|
||||
|
||||
*p++ = DHO_END;
|
||||
|
||||
#ifdef BOOTP_MESSAGE_LENTH_MIN
|
||||
/* Some crappy DHCP servers think they have to obey the BOOTP minimum
|
||||
* message length.
|
||||
* They are wrong, but we should still cater for them. */
|
||||
/* Pad out to the BOOTP minimum message length.
|
||||
* Some DHCP servers incorrectly require this. */
|
||||
while (p - m < BOOTP_MESSAGE_LENTH_MIN)
|
||||
*p++ = DHO_PAD;
|
||||
#endif
|
||||
|
||||
len = (size_t)(p - m);
|
||||
if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0)
|
||||
@ -1058,7 +1075,7 @@ write_lease(const struct interface *ifp, const struct dhcp_message *dhcp)
|
||||
const struct dhcp_state *state = D_CSTATE(ifp);
|
||||
|
||||
/* We don't write BOOTP leases */
|
||||
if (is_bootp(ifp, dhcp)) {
|
||||
if (IS_BOOTP(ifp, dhcp)) {
|
||||
unlink(state->leasefile);
|
||||
return 0;
|
||||
}
|
||||
@ -1126,6 +1143,7 @@ read_lease(struct interface *ifp)
|
||||
/* We may have found a BOOTP server */
|
||||
if (get_option_uint8(ifp->ctx, &type, dhcp, DHO_MESSAGETYPE) == -1)
|
||||
type = 0;
|
||||
|
||||
/* Authenticate the message */
|
||||
auth = get_option(ifp->ctx, dhcp, DHO_AUTHENTICATION, &auth_len);
|
||||
if (auth) {
|
||||
@ -1497,18 +1515,18 @@ checksum(const void *data, unsigned int len)
|
||||
uint32_t sum = 0;
|
||||
|
||||
while (len > 1) {
|
||||
sum += (uint32_t)addr[0] * 256 + (uint32_t)addr[1];
|
||||
sum += (uint32_t)(addr[0] * 256 + addr[1]);
|
||||
addr += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
if (len == 1)
|
||||
sum += (uint32_t)*addr * 256;
|
||||
sum += (uint32_t)(*addr * 256);
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >> 16);
|
||||
|
||||
return (uint16_t)~htons(sum);
|
||||
return (uint16_t)~htons((uint16_t)sum);
|
||||
}
|
||||
|
||||
static struct udp_dhcp_packet *
|
||||
@ -1574,10 +1592,15 @@ send_message(struct interface *ifp, uint8_t type,
|
||||
in_addr_t a = INADDR_ANY;
|
||||
struct timespec tv;
|
||||
int s;
|
||||
#ifdef IN_IFF_NOTUSEABLE
|
||||
struct ipv4_addr *ia;
|
||||
#endif
|
||||
|
||||
if (!callback)
|
||||
logger(ifp->ctx, LOG_DEBUG, "%s: sending %s with xid 0x%x",
|
||||
ifp->name, get_dhcp_op(type), state->xid);
|
||||
ifp->name,
|
||||
ifo->options & DHCPCD_BOOTP ? "BOOTP" : get_dhcp_op(type),
|
||||
state->xid);
|
||||
else {
|
||||
if (state->interval == 0)
|
||||
state->interval = 4;
|
||||
@ -1592,7 +1615,9 @@ send_message(struct interface *ifp, uint8_t type,
|
||||
timespecnorm(&tv);
|
||||
logger(ifp->ctx, LOG_DEBUG,
|
||||
"%s: sending %s (xid 0x%x), next in %0.1f seconds",
|
||||
ifp->name, get_dhcp_op(type), state->xid,
|
||||
ifp->name,
|
||||
ifo->options & DHCPCD_BOOTP ? "BOOTP" : get_dhcp_op(type),
|
||||
state->xid,
|
||||
timespec_to_double(&tv));
|
||||
}
|
||||
|
||||
@ -1602,6 +1627,10 @@ send_message(struct interface *ifp, uint8_t type,
|
||||
if (state->added && !(state->added & STATE_FAKE) &&
|
||||
state->addr.s_addr != INADDR_ANY &&
|
||||
state->new != NULL &&
|
||||
#ifdef IN_IFF_NOTUSEABLE
|
||||
((ia = ipv4_iffindaddr(ifp, &state->addr, NULL)) &&
|
||||
!(ia->addr_flags & IN_IFF_NOTUSEABLE)) &&
|
||||
#endif
|
||||
(state->new->cookie == htonl(MAGIC_COOKIE) ||
|
||||
ifp->options->options & DHCPCD_INFORM))
|
||||
{
|
||||
@ -1618,7 +1647,7 @@ send_message(struct interface *ifp, uint8_t type,
|
||||
* Also, we should not unicast from a BOOTP lease. */
|
||||
if (s == -1 ||
|
||||
(!(ifo->options & DHCPCD_INFORM) &&
|
||||
is_bootp(ifp, state->new)))
|
||||
IS_BOOTP(ifp, state->new)))
|
||||
{
|
||||
a = state->addr.s_addr;
|
||||
state->addr.s_addr = INADDR_ANY;
|
||||
@ -1751,7 +1780,8 @@ dhcp_discover(void *arg)
|
||||
ifp->name, inet_ntoa(ifo->req_addr));
|
||||
else
|
||||
logger(ifp->ctx, LOG_INFO,
|
||||
"%s: soliciting a DHCP lease", ifp->name);
|
||||
"%s: soliciting a %s lease",
|
||||
ifp->name, ifo->options & DHCPCD_BOOTP ? "BOOTP" : "DHCP");
|
||||
send_discover(ifp);
|
||||
}
|
||||
|
||||
@ -1779,7 +1809,7 @@ dhcp_expire(void *arg)
|
||||
dhcp_discover(ifp);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
dhcp_decline(struct interface *ifp)
|
||||
{
|
||||
|
||||
@ -1804,12 +1834,14 @@ dhcp_renew(void *arg)
|
||||
send_renew(ifp);
|
||||
}
|
||||
|
||||
#ifndef IN_IFF_TENTATIVE
|
||||
static void
|
||||
dhcp_arp_announced(struct arp_state *astate)
|
||||
{
|
||||
|
||||
arp_close(astate->iface);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
dhcp_rebind(void *arg)
|
||||
@ -1958,13 +1990,18 @@ dhcp_bind(struct interface *ifp, struct arp_state *astate)
|
||||
|
||||
applyaddr:
|
||||
ipv4_applyaddr(ifp);
|
||||
if (dhcpcd_daemonise(ifp->ctx))
|
||||
return;
|
||||
if (ifo->options & DHCPCD_ARP) {
|
||||
if (ifo->options & DHCPCD_ARP &&
|
||||
!(ifp->ctx->options & DHCPCD_FORKED))
|
||||
{
|
||||
#ifdef IN_IFF_TENTATIVE
|
||||
if (astate)
|
||||
arp_free_but(astate);
|
||||
else if (!ipv4ll)
|
||||
arp_close(ifp);
|
||||
#else
|
||||
if (state->added) {
|
||||
if (astate == NULL) {
|
||||
astate = arp_new(ifp);
|
||||
astate->addr = state->addr;
|
||||
astate = arp_new(ifp, &state->addr);
|
||||
astate->announced_cb =
|
||||
dhcp_arp_announced;
|
||||
}
|
||||
@ -1975,6 +2012,7 @@ applyaddr:
|
||||
}
|
||||
} else if (!ipv4ll)
|
||||
arp_close(ifp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -2328,7 +2366,12 @@ dhcp_arp_probed(struct arp_state *astate)
|
||||
}
|
||||
dhcp_close(astate->iface);
|
||||
eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate->iface);
|
||||
#ifdef IN_IFF_TENTATIVE
|
||||
ipv4_finaliseaddr(astate->iface);
|
||||
arp_close(astate->iface);
|
||||
#else
|
||||
dhcp_bind(astate->iface, astate);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2341,6 +2384,7 @@ dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
|
||||
ifo = astate->iface->options;
|
||||
if (state->arping_index &&
|
||||
state->arping_index <= ifo->arping_len &&
|
||||
amsg &&
|
||||
(amsg->sip.s_addr == ifo->arping[state->arping_index - 1] ||
|
||||
(amsg->sip.s_addr == 0 &&
|
||||
amsg->tip.s_addr == ifo->arping[state->arping_index - 1])))
|
||||
@ -2367,18 +2411,30 @@ dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
|
||||
dhcpcd_startinterface(astate->iface);
|
||||
}
|
||||
|
||||
if (state->offer == NULL)
|
||||
return;
|
||||
|
||||
/* RFC 2131 3.1.5, Client-server interaction */
|
||||
if (amsg->sip.s_addr == state->offer->yiaddr ||
|
||||
(amsg->sip.s_addr == 0 && amsg->tip.s_addr == state->offer->yiaddr))
|
||||
/* RFC 2131 3.1.5, Client-server interaction
|
||||
* NULL amsg means IN_IFF_DUPLICATED */
|
||||
if (amsg == NULL || (state->offer &&
|
||||
(amsg->sip.s_addr == state->offer->yiaddr ||
|
||||
(amsg->sip.s_addr == 0 &&
|
||||
amsg->tip.s_addr == state->offer->yiaddr))))
|
||||
{
|
||||
astate->failed.s_addr = state->offer->yiaddr;
|
||||
#ifdef IN_IFF_DUPLICATED
|
||||
struct ipv4_addr *ia;
|
||||
#endif
|
||||
|
||||
if (amsg)
|
||||
astate->failed.s_addr = state->offer->yiaddr;
|
||||
else
|
||||
astate->failed = astate->addr;
|
||||
arp_report_conflicted(astate, amsg);
|
||||
unlink(state->leasefile);
|
||||
if (!state->lease.frominfo)
|
||||
dhcp_decline(astate->iface);
|
||||
#ifdef IN_IFF_DUPLICATED
|
||||
ia = ipv4_iffindaddr(astate->iface, &astate->addr, NULL);
|
||||
if (ia)
|
||||
ipv4_deladdr(astate->iface, &ia->addr, &ia->net);
|
||||
#endif
|
||||
eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
|
||||
astate->iface);
|
||||
eloop_timeout_add_sec(astate->iface->ctx->eloop,
|
||||
@ -2386,23 +2442,6 @@ dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dhcp_probe(struct interface *ifp)
|
||||
{
|
||||
const struct dhcp_state *state;
|
||||
struct arp_state *astate;
|
||||
|
||||
astate = arp_new(ifp);
|
||||
if (astate) {
|
||||
state = D_CSTATE(ifp);
|
||||
astate->addr = state->addr;
|
||||
astate->probed_cb = dhcp_arp_probed;
|
||||
astate->conflicted_cb = dhcp_arp_conflicted;
|
||||
astate->announced_cb = dhcp_arp_announced;
|
||||
arp_probe(astate);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
|
||||
const struct in_addr *from)
|
||||
@ -2417,10 +2456,18 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
|
||||
unsigned int i;
|
||||
size_t auth_len;
|
||||
char *msg;
|
||||
struct arp_state *astate;
|
||||
struct ipv4_addr *ia;
|
||||
|
||||
/* We may have found a BOOTP server */
|
||||
if (get_option_uint8(ifp->ctx, &type, dhcp, DHO_MESSAGETYPE) == -1)
|
||||
type = 0;
|
||||
else if (ifo->options & DHCPCD_BOOTP) {
|
||||
logger(ifp->ctx, LOG_DEBUG,
|
||||
"%s: ignoring DHCP reply (excpecting BOOTP)",
|
||||
ifp->name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Authenticate the message */
|
||||
auth = get_option(ifp->ctx, dhcp, DHO_AUTHENTICATION, &auth_len);
|
||||
@ -2553,9 +2600,9 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
|
||||
if (has_option_mask(ifo->requiremask, i) &&
|
||||
get_option_uint8(ifp->ctx, &tmp, dhcp, (uint8_t)i) != 0)
|
||||
{
|
||||
/* If we are bootp, then ignore the need for serverid.
|
||||
* To ignore bootp, require dhcp_message_type.
|
||||
* However, nothing really stops bootp from providing
|
||||
/* If we are BOOTP, then ignore the need for serverid.
|
||||
* To ignore BOOTP, require dhcp_message_type.
|
||||
* However, nothing really stops BOOTP from providing
|
||||
* DHCP style options as well so the above isn't
|
||||
* always true. */
|
||||
if (type == 0 && i == DHO_SERVERID)
|
||||
@ -2621,6 +2668,21 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef IN_IFF_DUPLICATED
|
||||
ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
|
||||
if (ia && ia->addr_flags & IN_IFF_DUPLICATED) {
|
||||
log_dhcp(LOG_WARNING, "declined duplicate address",
|
||||
ifp, dhcp, from);
|
||||
if (type)
|
||||
dhcp_decline(ifp);
|
||||
ipv4_deladdr(ifp, &ia->addr, &ia->net);
|
||||
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
|
||||
eloop_timeout_add_sec(ifp->ctx->eloop,
|
||||
DHCP_RAND_MAX, dhcp_discover, ifp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((type == 0 || type == DHCP_OFFER) &&
|
||||
(state->state == DHS_DISCOVER || state->state == DHS_IPV4LL_BOUND))
|
||||
{
|
||||
@ -2695,28 +2757,35 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
|
||||
|
||||
lease->frominfo = 0;
|
||||
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
|
||||
astate = NULL;
|
||||
|
||||
if (ifo->options & DHCPCD_ARP &&
|
||||
state->addr.s_addr != state->offer->yiaddr)
|
||||
#ifndef IN_IFF_TENTATIVE
|
||||
if (ifo->options & DHCPCD_ARP
|
||||
&& state->addr.s_addr != state->offer->yiaddr)
|
||||
#endif
|
||||
{
|
||||
addr.s_addr = state->offer->yiaddr;
|
||||
#ifndef IN_IFF_TENTATIVE
|
||||
/* If the interface already has the address configured
|
||||
* then we can't ARP for duplicate detection. */
|
||||
addr.s_addr = state->offer->yiaddr;
|
||||
if (!ipv4_iffindaddr(ifp, &addr, NULL)) {
|
||||
struct arp_state *astate;
|
||||
|
||||
astate = arp_new(ifp);
|
||||
ia = ipv4_findaddr(ifp->ctx, &addr);
|
||||
if (ia) {
|
||||
#endif
|
||||
astate = arp_new(ifp, &addr);
|
||||
if (astate) {
|
||||
astate->addr = addr;
|
||||
astate->probed_cb = dhcp_arp_probed;
|
||||
astate->conflicted_cb = dhcp_arp_conflicted;
|
||||
#ifndef IN_IFF_TENTATIVE
|
||||
arp_probe(astate);
|
||||
#endif
|
||||
}
|
||||
#ifndef IN_IFF_TENTATIVE
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
dhcp_bind(ifp, NULL);
|
||||
dhcp_bind(ifp, astate);
|
||||
}
|
||||
|
||||
static size_t
|
||||
@ -2939,9 +3008,8 @@ dhcp_dump(struct interface *ifp)
|
||||
AF_INET, ifp, "");
|
||||
state->new = read_lease(ifp);
|
||||
if (state->new == NULL) {
|
||||
if (errno == ENOENT)
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: no lease to dump", ifp->name);
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %s: %m",
|
||||
*ifp->name ? ifp->name : state->leasefile, __func__);
|
||||
return -1;
|
||||
}
|
||||
state->reason = "DUMP";
|
||||
@ -3098,7 +3166,8 @@ dhcp_start1(void *arg)
|
||||
/* Don't log an error if some other process
|
||||
* is handling this. */
|
||||
if (errno != EADDRINUSE)
|
||||
logger(ifp->ctx, LOG_ERR, "dhcp_openudp: %m");
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: dhcp_openudp: %m", __func__);
|
||||
} else
|
||||
eloop_event_add(ifp->ctx->eloop,
|
||||
ifp->ctx->udp_fd, dhcp_handleudp,
|
||||
@ -3118,7 +3187,7 @@ dhcp_start1(void *arg)
|
||||
if (state->arping_index < ifo->arping_len) {
|
||||
struct arp_state *astate;
|
||||
|
||||
astate = arp_new(ifp);
|
||||
astate = arp_new(ifp, NULL);
|
||||
if (astate) {
|
||||
astate->probed_cb = dhcp_arp_probed;
|
||||
astate->conflicted_cb = dhcp_arp_conflicted;
|
||||
@ -3148,8 +3217,31 @@ dhcp_start1(void *arg)
|
||||
}
|
||||
/* We don't want to read the old lease if we NAK an old test */
|
||||
nolease = state->offer && ifp->ctx->options & DHCPCD_TEST;
|
||||
if (!nolease)
|
||||
if (!nolease) {
|
||||
state->offer = read_lease(ifp);
|
||||
/* Check the saved lease matches the type we want */
|
||||
if (state->offer) {
|
||||
#ifdef IN_IFF_DUPLICATED
|
||||
struct in_addr addr;
|
||||
struct ipv4_addr *ia;
|
||||
|
||||
addr.s_addr = state->offer->yiaddr;
|
||||
ia = ipv4_iffindaddr(ifp, &addr, NULL);
|
||||
#endif
|
||||
|
||||
if ((IS_BOOTP(ifp, state->offer) &&
|
||||
!(ifo->options & DHCPCD_BOOTP)) ||
|
||||
#ifdef IN_IFF_DUPLICATED
|
||||
(ia && ia->addr_flags & IN_IFF_DUPLICATED) ||
|
||||
#endif
|
||||
(!IS_BOOTP(ifp, state->offer) &&
|
||||
ifo->options & DHCPCD_BOOTP))
|
||||
{
|
||||
free(state->offer);
|
||||
state->offer = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state->offer) {
|
||||
get_lease(ifp->ctx, &state->lease, state->offer);
|
||||
state->lease.frominfo = 1;
|
||||
@ -3253,10 +3345,11 @@ dhcp_start(struct interface *ifp)
|
||||
}
|
||||
|
||||
void
|
||||
dhcp_handleifa(int type, struct interface *ifp,
|
||||
dhcp_handleifa(int cmd, struct interface *ifp,
|
||||
const struct in_addr *addr,
|
||||
const struct in_addr *net,
|
||||
const struct in_addr *dst)
|
||||
const struct in_addr *dst,
|
||||
__unused int flags)
|
||||
{
|
||||
struct dhcp_state *state;
|
||||
struct if_options *ifo;
|
||||
@ -3266,22 +3359,20 @@ dhcp_handleifa(int type, struct interface *ifp,
|
||||
if (state == NULL)
|
||||
return;
|
||||
|
||||
if (type == RTM_DELADDR) {
|
||||
if (state->new &&
|
||||
(state->new->yiaddr == addr->s_addr ||
|
||||
(state->new->yiaddr == INADDR_ANY &&
|
||||
state->new->ciaddr == addr->s_addr)))
|
||||
if (cmd == RTM_DELADDR) {
|
||||
if (state->addr.s_addr == addr->s_addr &&
|
||||
state->net.s_addr == net->s_addr)
|
||||
{
|
||||
logger(ifp->ctx, LOG_INFO,
|
||||
"%s: removing IP address %s/%d",
|
||||
ifp->name, inet_ntoa(state->lease.addr),
|
||||
inet_ntocidr(state->lease.net));
|
||||
ifp->name, inet_ntoa(state->addr),
|
||||
inet_ntocidr(state->net));
|
||||
dhcp_drop(ifp, "EXPIRE");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != RTM_NEWADDR)
|
||||
if (cmd != RTM_NEWADDR)
|
||||
return;
|
||||
|
||||
ifo = ifp->options;
|
||||
|
11
external/bsd/dhcpcd/dist/dhcp.h
vendored
11
external/bsd/dhcpcd/dist/dhcp.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dhcp.h,v 1.8 2015/03/26 10:26:37 roy Exp $ */
|
||||
/* $NetBSD: dhcp.h,v 1.9 2015/05/02 15:18:36 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -259,8 +259,8 @@ void dhcp_printoptions(const struct dhcpcd_ctx *,
|
||||
const struct dhcp_opt *, size_t);
|
||||
int get_option_addr(struct dhcpcd_ctx *,struct in_addr *,
|
||||
const struct dhcp_message *, uint8_t);
|
||||
#define is_bootp(i, m) ((m) && \
|
||||
!IN_LINKLOCAL(htonl((m)->yiaddr)) && \
|
||||
#define IS_BOOTP(i, m) ((m) && \
|
||||
!IN_LINKLOCAL(htonl((m)->yiaddr)) && \
|
||||
get_option_uint8((i)->ctx, NULL, (m), DHO_MESSAGETYPE) == -1)
|
||||
struct rt_head *get_option_routes(struct interface *,
|
||||
const struct dhcp_message *);
|
||||
@ -276,15 +276,14 @@ ssize_t make_message(struct dhcp_message **, const struct interface *,
|
||||
int valid_dhcp_packet(unsigned char *);
|
||||
|
||||
void dhcp_handleifa(int, struct interface *,
|
||||
const struct in_addr *, const struct in_addr *, const struct in_addr *);
|
||||
const struct in_addr *, const struct in_addr *, const struct in_addr *,
|
||||
int);
|
||||
|
||||
void dhcp_drop(struct interface *, const char *);
|
||||
void dhcp_start(struct interface *);
|
||||
void dhcp_stop(struct interface *);
|
||||
void dhcp_decline(struct interface *);
|
||||
void dhcp_discover(void *);
|
||||
void dhcp_inform(struct interface *);
|
||||
void dhcp_probe(struct interface *);
|
||||
void dhcp_bind(struct interface *, struct arp_state *);
|
||||
void dhcp_reboot_newopts(struct interface *, unsigned long long);
|
||||
void dhcp_close(struct interface *);
|
||||
|
132
external/bsd/dhcpcd/dist/dhcp6.c
vendored
132
external/bsd/dhcpcd/dist/dhcp6.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: dhcp6.c,v 1.11 2015/03/28 14:16:52 christos Exp $");
|
||||
__RCSID("$NetBSD: dhcp6.c,v 1.12 2015/05/02 15:18:36 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -219,7 +219,7 @@ dhcp6_makevendor(struct dhcp6_option *o, const struct interface *ifp)
|
||||
}
|
||||
|
||||
static const struct dhcp6_option *
|
||||
dhcp6_findoption(unsigned int code, const uint8_t *d, size_t len)
|
||||
dhcp6_findoption(uint16_t code, const uint8_t *d, size_t len)
|
||||
{
|
||||
const struct dhcp6_option *o;
|
||||
size_t ol;
|
||||
@ -283,7 +283,7 @@ dhcp6_getoption(struct dhcpcd_ctx *ctx,
|
||||
}
|
||||
|
||||
static const struct dhcp6_option *
|
||||
dhcp6_getmoption(unsigned int code, const struct dhcp6_message *m, size_t len)
|
||||
dhcp6_getmoption(uint16_t code, const struct dhcp6_message *m, size_t len)
|
||||
{
|
||||
|
||||
if (len < sizeof(*m)) {
|
||||
@ -490,6 +490,21 @@ dhcp6_delegateaddr(struct in6_addr *addr, struct interface *ifp,
|
||||
return sla->prefix_len;
|
||||
}
|
||||
|
||||
int
|
||||
dhcp6_has_public_addr(const struct interface *ifp)
|
||||
{
|
||||
const struct dhcp6_state *state = D6_CSTATE(ifp);
|
||||
const struct ipv6_addr *ia;
|
||||
|
||||
if (state == NULL)
|
||||
return 0;
|
||||
TAILQ_FOREACH(ia, &state->addrs, next) {
|
||||
if (ipv6_publicaddr(ia))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dhcp6_makemessage(struct interface *ifp)
|
||||
{
|
||||
@ -497,9 +512,9 @@ dhcp6_makemessage(struct interface *ifp)
|
||||
struct dhcp6_message *m;
|
||||
struct dhcp6_option *o, *so, *eo;
|
||||
const struct dhcp6_option *si, *unicast;
|
||||
size_t l, n, len, ml, auth_len;
|
||||
size_t l, n, len, ml;
|
||||
uint8_t u8, type;
|
||||
uint16_t u16, n_options;
|
||||
uint16_t u16, n_options, auth_len;
|
||||
struct if_options *ifo;
|
||||
const struct dhcp_opt *opt, *opt2;
|
||||
uint8_t IA, *p;
|
||||
@ -704,17 +719,22 @@ dhcp6_makemessage(struct interface *ifp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
auth_len = 0;
|
||||
if (ifo->auth.options & DHCPCD_AUTH_SEND) {
|
||||
auth_len = (size_t)dhcp_auth_encode(&ifo->auth,
|
||||
ssize_t alen = dhcp_auth_encode(&ifo->auth,
|
||||
state->auth.token, NULL, 0, 6, type, NULL, 0);
|
||||
if ((ssize_t)auth_len == -1) {
|
||||
if (alen != -1 && alen > UINT16_MAX) {
|
||||
errno = ERANGE;
|
||||
alen = -1;
|
||||
}
|
||||
if (alen == -1)
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: dhcp_auth_encode: %m", ifp->name);
|
||||
auth_len = 0;
|
||||
} else if (auth_len != 0)
|
||||
else if (alen != 0) {
|
||||
auth_len = (uint16_t)alen;
|
||||
len += sizeof(*o) + auth_len;
|
||||
} else
|
||||
auth_len = 0; /* appease GCC */
|
||||
}
|
||||
}
|
||||
|
||||
state->send = malloc(len);
|
||||
if (state->send == NULL)
|
||||
@ -816,9 +836,9 @@ dhcp6_makemessage(struct interface *ifp)
|
||||
eo->len = htons(eo->len);
|
||||
}
|
||||
|
||||
u32 = (uint32_t)(ntohs(o->len) + sizeof(*so)
|
||||
u16 = (uint16_t)(ntohs(o->len) + sizeof(*so)
|
||||
+ ntohs(so->len));
|
||||
o->len = htons((uint16_t)u32);
|
||||
o->len = htons(u16);
|
||||
} else {
|
||||
so->code = htons(D6_OPTION_IA_ADDR);
|
||||
so->len = sizeof(ap->addr) +
|
||||
@ -1134,7 +1154,7 @@ logsend:
|
||||
cm->cmsg_type = IPV6_PKTINFO;
|
||||
cm->cmsg_len = CMSG_LEN(sizeof(pi));
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
pi.ipi6_ifindex = CAST_IPI6_IFINDEX(ifp->index);
|
||||
pi.ipi6_ifindex = ifp->index;
|
||||
memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
|
||||
|
||||
if (sendmsg(ctx->dhcp_fd, &ctx->sndhdr, 0) == -1) {
|
||||
@ -1241,9 +1261,6 @@ dhcp6_dadcompleted(const struct interface *ifp)
|
||||
const struct ipv6_addr *ap;
|
||||
|
||||
state = D6_CSTATE(ifp);
|
||||
if (!TAILQ_FIRST(&state->addrs))
|
||||
return 0;
|
||||
|
||||
TAILQ_FOREACH(ap, &state->addrs, next) {
|
||||
if (ap->flags & IPV6_AF_ADDED &&
|
||||
!(ap->flags & IPV6_AF_DADCOMPLETED))
|
||||
@ -2126,7 +2143,7 @@ dhcp6_writelease(const struct interface *ifp)
|
||||
}
|
||||
|
||||
static int
|
||||
dhcp6_readlease(struct interface *ifp)
|
||||
dhcp6_readlease(struct interface *ifp, int validate)
|
||||
{
|
||||
struct dhcp6_state *state;
|
||||
struct stat st;
|
||||
@ -2135,43 +2152,37 @@ dhcp6_readlease(struct interface *ifp)
|
||||
const struct dhcp6_option *o;
|
||||
struct timespec acquired;
|
||||
time_t now;
|
||||
int retval;
|
||||
|
||||
state = D6_STATE(ifp);
|
||||
if (stat(state->leasefile, &st) == -1) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
|
||||
if (stat(state->leasefile, &st) == -1)
|
||||
return -1;
|
||||
}
|
||||
logger(ifp->ctx, LOG_DEBUG, "%s: reading lease `%s'",
|
||||
ifp->name, state->leasefile);
|
||||
if (st.st_size > UINT32_MAX) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: file too big", ifp->name);
|
||||
errno = E2BIG;
|
||||
return -1;
|
||||
}
|
||||
state->new = malloc((size_t)st.st_size);
|
||||
if (state->new == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
if ((fd = open(state->leasefile, O_RDONLY)) == -1)
|
||||
return -1;
|
||||
}
|
||||
if ((state->new = malloc((size_t)st.st_size)) == NULL)
|
||||
return -1;
|
||||
retval = -1;
|
||||
state->new_len = (size_t)st.st_size;
|
||||
fd = open(state->leasefile, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %s: %s: %m",
|
||||
ifp->name, __func__, state->leasefile);
|
||||
return -1;
|
||||
}
|
||||
bytes = read(fd, state->new, state->new_len);
|
||||
close(fd);
|
||||
if (bytes != (ssize_t)state->new_len) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: read: %m", __func__);
|
||||
if (bytes != (ssize_t)state->new_len)
|
||||
goto ex;
|
||||
|
||||
/* If not validating IA's and if they have expired,
|
||||
* skip to the auth check. */
|
||||
if (!validate) {
|
||||
fd = 0;
|
||||
goto auth;
|
||||
}
|
||||
|
||||
if ((now = time(NULL)) == -1) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: time: %m", __func__);
|
||||
if ((now = time(NULL)) == -1)
|
||||
goto ex;
|
||||
}
|
||||
|
||||
get_monotonic(&acquired);
|
||||
acquired.tv_sec -= now - st.st_mtime;
|
||||
@ -2189,10 +2200,14 @@ dhcp6_readlease(struct interface *ifp)
|
||||
logger(ifp->ctx,
|
||||
LOG_DEBUG,"%s: discarding expired lease",
|
||||
ifp->name);
|
||||
retval = 0;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
auth:
|
||||
|
||||
retval = 0;
|
||||
/* Authenticate the message */
|
||||
o = dhcp6_getmoption(D6_OPTION_AUTH, state->new, state->new_len);
|
||||
if (o) {
|
||||
@ -2228,10 +2243,9 @@ ex:
|
||||
state->new_len = 0;
|
||||
if (!(ifp->ctx->options & DHCPCD_DUMPLEASE))
|
||||
unlink(state->leasefile);
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dhcp6_startinit(struct interface *ifp)
|
||||
{
|
||||
@ -2261,11 +2275,13 @@ dhcp6_startinit(struct interface *ifp)
|
||||
!(has_ta && !has_non_ta) &&
|
||||
ifp->options->reboot != 0)
|
||||
{
|
||||
r = dhcp6_readlease(ifp);
|
||||
if (r == -1)
|
||||
logger(ifp->ctx, LOG_ERR, "%s: dhcp6_readlease: %s: %m",
|
||||
ifp->name, state->leasefile);
|
||||
else if (r != 0) {
|
||||
r = dhcp6_readlease(ifp, 1);
|
||||
if (r == -1) {
|
||||
if (errno != ENOENT)
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: dhcp6_readlease: %s: %m",
|
||||
ifp->name, state->leasefile);
|
||||
} else if (r != 0) {
|
||||
/* RFC 3633 section 12.1 */
|
||||
if (dhcp6_hasprefixdelegation(ifp))
|
||||
dhcp6_startrebind(ifp);
|
||||
@ -2355,9 +2371,6 @@ dhcp6_script_try_run(struct interface *ifp, int delegated)
|
||||
int completed;
|
||||
|
||||
state = D6_STATE(ifp);
|
||||
if (!TAILQ_FIRST(&state->addrs))
|
||||
return;
|
||||
|
||||
completed = 1;
|
||||
/* If all addresses have completed DAD run the script */
|
||||
TAILQ_FOREACH(ap, &state->addrs, next) {
|
||||
@ -2409,7 +2422,7 @@ dhcp6_delegate_prefix(struct interface *ifp)
|
||||
if (strcmp(sla->ifname, ia->sla[j].ifname) == 0)
|
||||
break;
|
||||
if (j >= i &&
|
||||
if_find(ifp->ctx, sla->ifname) == NULL)
|
||||
if_find(ifp->ctx->ifaces, sla->ifname) == NULL)
|
||||
{
|
||||
logger(ifp->ctx, LOG_INFO,
|
||||
"%s: loading for delegation", sla->ifname);
|
||||
@ -2717,7 +2730,7 @@ dhcp6_handledata(void *arg)
|
||||
i++, opt++)
|
||||
{
|
||||
if (has_option_mask(ifo->requiremask6, opt->option) &&
|
||||
dhcp6_getmoption(opt->option, r, len) == NULL)
|
||||
dhcp6_getmoption((uint16_t)opt->option, r, len) == NULL)
|
||||
{
|
||||
logger(ifp->ctx, LOG_WARNING,
|
||||
"%s: reject DHCPv6 (no option %s) from %s",
|
||||
@ -2725,7 +2738,7 @@ dhcp6_handledata(void *arg)
|
||||
return;
|
||||
}
|
||||
if (has_option_mask(ifo->rejectmask6, opt->option) &&
|
||||
dhcp6_getmoption(opt->option, r, len))
|
||||
dhcp6_getmoption((uint16_t)opt->option, r, len))
|
||||
{
|
||||
logger(ifp->ctx, LOG_WARNING,
|
||||
"%s: reject DHCPv6 (option %s) from %s",
|
||||
@ -2767,6 +2780,8 @@ dhcp6_handledata(void *arg)
|
||||
case DHCP6_REPLY:
|
||||
switch(state->state) {
|
||||
case DH6S_INFORM:
|
||||
if (dhcp6_checkstatusok(ifp, r, NULL, len) == -1)
|
||||
return;
|
||||
/* RFC4242 */
|
||||
o = dhcp6_getmoption(D6_OPTION_INFO_REFRESH_TIME,
|
||||
r, len);
|
||||
@ -3027,6 +3042,7 @@ recv:
|
||||
eloop_timeout_add_sec(ifp->ctx->eloop,
|
||||
(time_t)state->expire, dhcp6_startexpire, ifp);
|
||||
|
||||
ipv6nd_runignoredra(ifp);
|
||||
ipv6_addaddrs(&state->addrs);
|
||||
dhcp6_delegate_prefix(ifp);
|
||||
|
||||
@ -3567,7 +3583,6 @@ int
|
||||
dhcp6_dump(struct interface *ifp)
|
||||
{
|
||||
struct dhcp6_state *state;
|
||||
int r;
|
||||
|
||||
ifp->if_data[IF_DATA_DHCP6] = state = calloc(1, sizeof(*state));
|
||||
if (state == NULL) {
|
||||
@ -3578,14 +3593,9 @@ dhcp6_dump(struct interface *ifp)
|
||||
dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile),
|
||||
AF_INET6, ifp,
|
||||
ifp->options->options & DHCPCD_PFXDLGONLY ? ".pd" : "");
|
||||
r = dhcp6_readlease(ifp);
|
||||
if (r == -1) {
|
||||
if (errno == ENOENT)
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: no lease to dump", ifp->name);
|
||||
else
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: dhcp6_readlease: %m", ifp->name);
|
||||
if (dhcp6_readlease(ifp, 0) == -1) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %s: %m",
|
||||
*ifp->name ? ifp->name : state->leasefile, __func__);
|
||||
return -1;
|
||||
}
|
||||
state->reason = "DUMP6";
|
||||
|
3
external/bsd/dhcpcd/dist/dhcp6.h
vendored
3
external/bsd/dhcpcd/dist/dhcp6.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dhcp6.h,v 1.8 2015/03/26 10:26:37 roy Exp $ */
|
||||
/* $NetBSD: dhcp6.h,v 1.9 2015/05/02 15:18:36 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -237,6 +237,7 @@ void dhcp6_printoptions(const struct dhcpcd_ctx *,
|
||||
struct ipv6_addr *dhcp6_findaddr(struct dhcpcd_ctx *, const struct in6_addr *,
|
||||
short);
|
||||
size_t dhcp6_find_delegates(struct interface *);
|
||||
int dhcp6_has_public_addr(const struct interface *);
|
||||
int dhcp6_start(struct interface *, enum DH6S);
|
||||
void dhcp6_reboot(struct interface *);
|
||||
ssize_t dhcp6_env(char **, const char *, const struct interface *,
|
||||
|
91
external/bsd/dhcpcd/dist/dhcpcd.c
vendored
91
external/bsd/dhcpcd/dist/dhcpcd.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: dhcpcd.c,v 1.23 2015/03/26 10:26:37 roy Exp $");
|
||||
__RCSID("$NetBSD: dhcpcd.c,v 1.24 2015/05/02 15:18:36 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -315,6 +315,17 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
dhcpcd_drop(struct interface *ifp, int stop)
|
||||
{
|
||||
|
||||
dhcp6_drop(ifp, stop ? NULL : "EXPIRE6");
|
||||
ipv6nd_drop(ifp);
|
||||
ipv6_drop(ifp);
|
||||
dhcp_drop(ifp, stop ? "STOP" : "EXPIRE");
|
||||
arp_close(ifp);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_interface(struct interface *ifp)
|
||||
{
|
||||
@ -324,11 +335,7 @@ stop_interface(struct interface *ifp)
|
||||
logger(ctx, LOG_INFO, "%s: removing interface", ifp->name);
|
||||
ifp->options->options |= DHCPCD_STOPPING;
|
||||
|
||||
dhcp6_drop(ifp, NULL);
|
||||
ipv6nd_drop(ifp);
|
||||
ipv6_drop(ifp);
|
||||
dhcp_drop(ifp, "STOP");
|
||||
arp_close(ifp);
|
||||
dhcpcd_drop(ifp, 1);
|
||||
if (ifp->options->options & DHCPCD_DEPARTED)
|
||||
script_runreason(ifp, "DEPARTED");
|
||||
else
|
||||
@ -381,7 +388,7 @@ configure_interface1(struct interface *ifp)
|
||||
ifo->options &= ~(DHCPCD_IPV6RS | DHCPCD_DHCP6);
|
||||
|
||||
if (ifo->options & DHCPCD_SLAACPRIVATE &&
|
||||
!(ifp->ctx->options & DHCPCD_TEST))
|
||||
!(ifp->ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST)))
|
||||
ifo->options |= DHCPCD_IPV6RA_OWN;
|
||||
|
||||
/* If we're a psuedo interface, ensure we disable as much as we can */
|
||||
@ -389,7 +396,9 @@ configure_interface1(struct interface *ifp)
|
||||
ifp->options->options &= ~(DHCPCD_IPV4 | DHCPCD_IPV6RS);
|
||||
|
||||
/* We want to disable kernel interface RA as early as possible. */
|
||||
if (ifo->options & DHCPCD_IPV6RS) {
|
||||
if (ifo->options & DHCPCD_IPV6RS &&
|
||||
!(ifp->ctx->options & DHCPCD_DUMPLEASE))
|
||||
{
|
||||
/* If not doing any DHCP, disable the RDNSS requirement. */
|
||||
if (!(ifo->options & (DHCPCD_DHCP | DHCPCD_DHCP6)))
|
||||
ifo->options &= ~DHCPCD_IPV6RA_REQRDNSS;
|
||||
@ -399,7 +408,8 @@ configure_interface1(struct interface *ifp)
|
||||
ifp->options->options & DHCPCD_IPV6RA_OWN ? 1 : 0);
|
||||
if (ra_global == -1 || ra_iface == -1)
|
||||
ifo->options &= ~DHCPCD_IPV6RS;
|
||||
else if (ra_iface == 0 && !(ifp->ctx->options & DHCPCD_TEST))
|
||||
else if (ra_iface == 0 &&
|
||||
!(ifp->ctx->options & DHCPCD_TEST))
|
||||
ifo->options |= DHCPCD_IPV6RA_OWN;
|
||||
}
|
||||
|
||||
@ -541,6 +551,7 @@ dhcpcd_selectprofile(struct interface *ifp, const char *profile)
|
||||
ifp->name, profile);
|
||||
} else
|
||||
*ifp->profile = '\0';
|
||||
|
||||
free_options(ifp->options);
|
||||
ifp->options = ifo;
|
||||
if (profile)
|
||||
@ -552,11 +563,20 @@ static void
|
||||
configure_interface(struct interface *ifp, int argc, char **argv,
|
||||
unsigned long long options)
|
||||
{
|
||||
time_t old;
|
||||
|
||||
old = ifp->options ? ifp->options->mtime : 0;
|
||||
dhcpcd_selectprofile(ifp, NULL);
|
||||
add_options(ifp->ctx, ifp->name, ifp->options, argc, argv);
|
||||
ifp->options->options |= options;
|
||||
configure_interface1(ifp);
|
||||
|
||||
/* If the mtime has changed drop any old lease */
|
||||
if (ifp->options && old != 0 && ifp->options->mtime != old) {
|
||||
logger(ifp->ctx, LOG_WARNING,
|
||||
"%s: confile file changed, expiring leases", ifp->name);
|
||||
dhcpcd_drop(ifp, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -584,7 +604,7 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags,
|
||||
{
|
||||
struct interface *ifp;
|
||||
|
||||
ifp = if_find(ctx, ifname);
|
||||
ifp = if_find(ctx->ifaces, ifname);
|
||||
if (ifp == NULL || !(ifp->options->options & DHCPCD_LINK))
|
||||
return;
|
||||
|
||||
@ -617,18 +637,22 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags,
|
||||
} else if (carrier == LINK_DOWN || (ifp->flags & IFF_UP) == 0) {
|
||||
if (ifp->carrier != LINK_DOWN) {
|
||||
if (ifp->carrier == LINK_UP)
|
||||
logger(ctx, LOG_INFO, "%s: carrier lost", ifp->name);
|
||||
logger(ctx, LOG_INFO, "%s: carrier lost",
|
||||
ifp->name);
|
||||
ifp->carrier = LINK_DOWN;
|
||||
script_runreason(ifp, "NOCARRIER");
|
||||
dhcp6_drop(ifp, "EXPIRE6");
|
||||
ipv6nd_drop(ifp);
|
||||
ipv6_drop(ifp);
|
||||
dhcp_drop(ifp, "EXPIRE");
|
||||
#ifdef NOCARRIER_PRESERVE_IP
|
||||
arp_close(ifp);
|
||||
ipv4_buildroutes(ifp->ctx);
|
||||
ipv6nd_expire(ifp, 0);
|
||||
#else
|
||||
dhcpcd_drop(ifp, 0);
|
||||
#endif
|
||||
}
|
||||
} else if (carrier == LINK_UP && ifp->flags & IFF_UP) {
|
||||
if (ifp->carrier != LINK_UP) {
|
||||
logger(ctx, LOG_INFO, "%s: carrier acquired", ifp->name);
|
||||
logger(ctx, LOG_INFO, "%s: carrier acquired",
|
||||
ifp->name);
|
||||
ifp->carrier = LINK_UP;
|
||||
#if !defined(__linux__) && !defined(__NetBSD__)
|
||||
/* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the
|
||||
@ -636,10 +660,30 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags,
|
||||
* through the disovery process to work it out. */
|
||||
dhcpcd_handleinterface(ctx, 0, ifp->name);
|
||||
#endif
|
||||
if (ifp->wireless)
|
||||
if (ifp->wireless) {
|
||||
uint8_t ossid[IF_SSIDSIZE];
|
||||
#ifdef NOCARRIER_PRESERVE_IP
|
||||
size_t olen;
|
||||
|
||||
olen = ifp->ssid_len;
|
||||
#endif
|
||||
memcpy(ossid, ifp->ssid, ifp->ssid_len);
|
||||
if_getssid(ifp);
|
||||
#ifdef NOCARRIER_PRESERVE_IP
|
||||
/* If we changed SSID network, drop leases */
|
||||
if (ifp->ssid_len != olen ||
|
||||
memcmp(ifp->ssid, ossid, ifp->ssid_len))
|
||||
dhcpcd_drop(ifp, 0);
|
||||
#endif
|
||||
}
|
||||
dhcpcd_initstate(ifp, 0);
|
||||
script_runreason(ifp, "CARRIER");
|
||||
#ifdef NOCARRIER_PRESERVE_IP
|
||||
/* Set any IPv6 Routers we remembered to expire
|
||||
* faster than they would normally as we
|
||||
* maybe on a new network. */
|
||||
ipv6nd_expire(ifp, RTR_CARRIER_EXPIRE);
|
||||
#endif
|
||||
/* RFC4941 Section 3.5 */
|
||||
if (ifp->options->options & DHCPCD_IPV6RA_OWN)
|
||||
ipv6_gentempifid(ifp);
|
||||
@ -900,7 +944,7 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname)
|
||||
|
||||
ctx = arg;
|
||||
if (action == -1) {
|
||||
ifp = if_find(ctx, ifname);
|
||||
ifp = if_find(ctx->ifaces, ifname);
|
||||
if (ifp == NULL) {
|
||||
errno = ESRCH;
|
||||
return -1;
|
||||
@ -931,7 +975,7 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname)
|
||||
continue;
|
||||
i = 0;
|
||||
/* Check if we already have the interface */
|
||||
iff = if_find(ctx, ifp->name);
|
||||
iff = if_find(ctx->ifaces, ifp->name);
|
||||
if (iff) {
|
||||
logger(ctx, LOG_DEBUG, "%s: interface updated", iff->name);
|
||||
/* The flags and hwaddr could have changed */
|
||||
@ -970,7 +1014,7 @@ dhcpcd_handlehwaddr(struct dhcpcd_ctx *ctx, const char *ifname,
|
||||
struct interface *ifp;
|
||||
char buf[sizeof(ifp->hwaddr) * 3];
|
||||
|
||||
ifp = if_find(ctx, ifname);
|
||||
ifp = if_find(ctx->ifaces, ifname);
|
||||
if (ifp == NULL)
|
||||
return;
|
||||
|
||||
@ -1033,7 +1077,7 @@ reconf_reboot(struct dhcpcd_ctx *ctx, int action, int argc, char **argv, int oi)
|
||||
|
||||
while ((ifp = TAILQ_FIRST(ifs))) {
|
||||
TAILQ_REMOVE(ifs, ifp, next);
|
||||
ifn = if_find(ctx, ifp->name);
|
||||
ifn = if_find(ctx->ifaces, ifp->name);
|
||||
if (ifn) {
|
||||
if (action)
|
||||
if_reboot(ifn, argc, argv);
|
||||
@ -1286,7 +1330,7 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
|
||||
return 0;
|
||||
}
|
||||
for (oi = optind; oi < argc; oi++) {
|
||||
if ((ifp = if_find(ctx, argv[oi])) == NULL)
|
||||
if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL)
|
||||
continue;
|
||||
if (do_release) {
|
||||
ifp->options->options |= DHCPCD_RELEASE;
|
||||
@ -1687,7 +1731,6 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ctx.options & DHCPCD_MASTER) {
|
||||
if (control_start(&ctx, NULL) == -1)
|
||||
logger(&ctx, LOG_ERR, "control_start: %m");
|
||||
@ -1740,7 +1783,7 @@ main(int argc, char **argv)
|
||||
goto exit_failure;
|
||||
}
|
||||
for (i = 0; i < ctx.ifc; i++) {
|
||||
if (if_find(&ctx, ctx.ifv[i]) == NULL)
|
||||
if (if_find(ctx.ifaces, ctx.ifv[i]) == NULL)
|
||||
logger(&ctx, LOG_ERR,
|
||||
"%s: interface not found or invalid",
|
||||
ctx.ifv[i]);
|
||||
|
15
external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
vendored
15
external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
vendored
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: dhcpcd.conf.5.in,v 1.19 2015/03/26 10:26:37 roy Exp $
|
||||
.\" $NetBSD: dhcpcd.conf.5.in,v 1.20 2015/05/02 15:18:37 roy Exp $
|
||||
.\" Copyright (c) 2006-2015 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 March 17, 2015
|
||||
.Dd April 6, 2015
|
||||
.Dt DHCPCD.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -111,6 +111,11 @@ Only accept packets from
|
||||
is ignored if
|
||||
.Ic whitelist
|
||||
is set.
|
||||
.It Ic bootp
|
||||
Be a BOOTP client.
|
||||
Basically, this just doesn't send a DHCP Message Type option and will only
|
||||
interact with a BOOTP server.
|
||||
All other DHCP options still work.
|
||||
.It Ic broadcast
|
||||
Instructs the DHCP server to broadcast replies back to the client.
|
||||
Normally this is only set for non Ethernet interfaces,
|
||||
@ -369,6 +374,12 @@ Each time dhcpcd receives an IPv6 Router Adveristment, dhcpcd will manage
|
||||
the default route only.
|
||||
This allows dhcpcd to prefer an interface for outbound traffic based on metric
|
||||
and/or user selection rather than the kernel.
|
||||
.It Ic ipv6ra_accept_nopublic
|
||||
Some IPv6 routers advertise themselves as a default router without any
|
||||
public prefixes or managed addresses.
|
||||
Generally, this is incorrect behaviour and
|
||||
.Nm dhcpcd
|
||||
will ignore the advertisement unless this option is turned on.
|
||||
.It Ic ipv6rs
|
||||
Enables IPv6 Router Advertisment solicitation.
|
||||
This is on by default, but is documented here in the case where it is disabled
|
||||
|
5
external/bsd/dhcpcd/dist/eloop.c
vendored
5
external/bsd/dhcpcd/dist/eloop.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: eloop.c,v 1.9 2015/03/26 10:26:37 roy Exp $");
|
||||
__RCSID("$NetBSD: eloop.c,v 1.10 2015/05/02 15:18:37 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -28,9 +28,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Needed for ppoll(2) */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
73
external/bsd/dhcpcd/dist/if-bsd.c
vendored
73
external/bsd/dhcpcd/dist/if-bsd.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: if-bsd.c,v 1.19 2015/03/27 18:51:08 christos Exp $");
|
||||
__RCSID("$NetBSD: if-bsd.c,v 1.20 2015/05/02 15:18:37 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -284,7 +284,7 @@ if_findsdl(struct dhcpcd_ctx *ctx, struct sockaddr_dl *sdl)
|
||||
char ifname[IF_NAMESIZE];
|
||||
memcpy(ifname, sdl->sdl_data, sdl->sdl_nlen);
|
||||
ifname[sdl->sdl_nlen] = '\0';
|
||||
return if_find(ctx, ifname);
|
||||
return if_find(ctx->ifaces, ifname);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -294,7 +294,7 @@ if_findsdl(struct dhcpcd_ctx *ctx, struct sockaddr_dl *sdl)
|
||||
const char *if_pfname = "Berkley Packet Filter";
|
||||
|
||||
int
|
||||
if_openrawsocket(struct interface *ifp, int protocol)
|
||||
if_openrawsocket(struct interface *ifp, uint16_t protocol)
|
||||
{
|
||||
struct dhcp_state *state;
|
||||
int fd = -1;
|
||||
@ -378,7 +378,7 @@ eexit:
|
||||
}
|
||||
|
||||
ssize_t
|
||||
if_sendrawpacket(const struct interface *ifp, int protocol,
|
||||
if_sendrawpacket(const struct interface *ifp, uint16_t protocol,
|
||||
const void *data, size_t len)
|
||||
{
|
||||
struct iovec iov[2];
|
||||
@ -388,7 +388,7 @@ if_sendrawpacket(const struct interface *ifp, int protocol,
|
||||
|
||||
memset(&hw, 0, ETHER_HDR_LEN);
|
||||
memset(&hw.ether_dhost, 0xff, ETHER_ADDR_LEN);
|
||||
hw.ether_type = htons((uint16_t)protocol);
|
||||
hw.ether_type = htons(protocol);
|
||||
iov[0].iov_base = &hw;
|
||||
iov[0].iov_len = ETHER_HDR_LEN;
|
||||
iov[1].iov_base = UNCONST(data);
|
||||
@ -404,7 +404,7 @@ if_sendrawpacket(const struct interface *ifp, int protocol,
|
||||
/* 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, int protocol,
|
||||
if_readrawpacket(struct interface *ifp, uint16_t protocol,
|
||||
void *data, size_t len, int *flags)
|
||||
{
|
||||
int fd;
|
||||
@ -520,7 +520,7 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm)
|
||||
COPYOUT(rt->gate, rti_info[RTAX_GATEWAY]);
|
||||
|
||||
if (rtm->rtm_index)
|
||||
rt->iface = if_findindex(ctx, rtm->rtm_index);
|
||||
rt->iface = if_findindex(ctx->ifaces, rtm->rtm_index);
|
||||
else if (rtm->rtm_addrs & RTA_IFP) {
|
||||
struct sockaddr_dl *sdl;
|
||||
|
||||
@ -549,7 +549,6 @@ if_route(unsigned char cmd, const struct rt *rt)
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_dl sdl;
|
||||
struct sockaddr_storage ss;
|
||||
} su;
|
||||
struct rtm
|
||||
{
|
||||
@ -609,8 +608,8 @@ if_route(unsigned char cmd, const struct rt *rt)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (rt->dest.s_addr == rt->gate.s_addr &&
|
||||
rt->net.s_addr == INADDR_BROADCAST)
|
||||
if (rt->net.s_addr == htonl(INADDR_BROADCAST) &&
|
||||
rt->gate.s_addr == htonl(INADDR_ANY))
|
||||
{
|
||||
#ifdef RTF_CLONING
|
||||
/* We add a cloning network route for a single host.
|
||||
@ -625,7 +624,7 @@ if_route(unsigned char cmd, const struct rt *rt)
|
||||
rtm.hdr.rtm_flags |= RTF_HOST;
|
||||
#endif
|
||||
} else if (rt->gate.s_addr == htonl(INADDR_LOOPBACK) &&
|
||||
rt->net.s_addr == INADDR_BROADCAST)
|
||||
rt->net.s_addr == htonl(INADDR_BROADCAST))
|
||||
{
|
||||
rtm.hdr.rtm_flags |= RTF_HOST | RTF_GATEWAY;
|
||||
/* Going via lo0 so remove the interface flags */
|
||||
@ -717,7 +716,40 @@ if_initrt(struct interface *ifp)
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SIOCGIFAFLAG_IN
|
||||
int
|
||||
if_addrflags(const struct in_addr *addr, const struct interface *ifp)
|
||||
{
|
||||
int s, flags;
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
flags = -1;
|
||||
if (s != -1) {
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
|
||||
sin = (struct sockaddr_in *)(void *)&ifr.ifr_addr;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr = *addr;
|
||||
if (ioctl(s, SIOCGIFAFLAG_IN, &ifr) != -1)
|
||||
flags = ifr.ifr_addrflags;
|
||||
close(s);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
#else
|
||||
int
|
||||
if_addrflags(__unused const struct in_addr *addr,
|
||||
__unused const struct interface *ifp)
|
||||
{
|
||||
|
||||
errno = ENOTSUP;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* INET */
|
||||
|
||||
#ifdef INET6
|
||||
static void
|
||||
@ -877,7 +909,7 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struct rt6 *rt, struct rt_msghdr *rtm)
|
||||
COPYOUT6(rt->gate, rti_info[RTAX_GATEWAY]);
|
||||
|
||||
if (rtm->rtm_index)
|
||||
rt->iface = if_findindex(ctx, rtm->rtm_index);
|
||||
rt->iface = if_findindex(ctx->ifaces, rtm->rtm_index);
|
||||
else if (rtm->rtm_addrs & RTA_IFP) {
|
||||
struct sockaddr_dl *sdl;
|
||||
|
||||
@ -905,7 +937,6 @@ if_route6(unsigned char cmd, const struct rt6 *rt)
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in6 sin;
|
||||
struct sockaddr_dl sdl;
|
||||
struct sockaddr_storage ss;
|
||||
} su;
|
||||
struct rtm
|
||||
{
|
||||
@ -1132,6 +1163,8 @@ if_managelink(struct dhcpcd_ctx *ctx)
|
||||
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
|
||||
|
||||
@ -1161,7 +1194,8 @@ if_managelink(struct dhcpcd_ctx *ctx)
|
||||
#endif
|
||||
case RTM_IFINFO:
|
||||
ifm = (struct if_msghdr *)(void *)p;
|
||||
if ((ifp = if_findindex(ctx, ifm->ifm_index)) == NULL)
|
||||
ifp = if_findindex(ctx->ifaces, ifm->ifm_index);
|
||||
if (ifp == NULL)
|
||||
break;
|
||||
switch (ifm->ifm_data.ifi_link_state) {
|
||||
case LINK_STATE_DOWN:
|
||||
@ -1237,7 +1271,8 @@ if_managelink(struct dhcpcd_ctx *ctx)
|
||||
case RTM_DELADDR: /* FALLTHROUGH */
|
||||
case RTM_NEWADDR:
|
||||
ifam = (struct ifa_msghdr *)(void *)p;
|
||||
if ((ifp = if_findindex(ctx, ifam->ifam_index)) == NULL)
|
||||
ifp = if_findindex(ctx->ifaces, ifam->ifam_index);
|
||||
if (ifp == NULL)
|
||||
break;
|
||||
cp = (char *)(void *)(ifam + 1);
|
||||
get_addrs(ifam->ifam_addrs, cp, rti_info);
|
||||
@ -1264,9 +1299,15 @@ if_managelink(struct dhcpcd_ctx *ctx)
|
||||
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);
|
||||
&rt.dest, &rt.net, &rt.gate, ifa_flags);
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
|
16
external/bsd/dhcpcd/dist/if-options.c
vendored
16
external/bsd/dhcpcd/dist/if-options.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: if-options.c,v 1.22 2015/03/27 11:33:46 roy Exp $");
|
||||
__RCSID("$NetBSD: if-options.c,v 1.23 2015/05/02 15:18:37 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -31,6 +31,7 @@
|
||||
#define _WITH_GETLINE /* Stop FreeBSD bitching */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
@ -100,6 +101,8 @@
|
||||
#define O_IPV6RA_AUTOCONF O_BASE + 38
|
||||
#define O_IPV6RA_NOAUTOCONF O_BASE + 39
|
||||
#define O_REJECT O_BASE + 40
|
||||
#define O_IPV6RA_ACCEPT_NOPUBLIC O_BASE + 41
|
||||
#define O_BOOTP O_BASE + 42
|
||||
|
||||
const struct option cf_options[] = {
|
||||
{"background", no_argument, NULL, 'b'},
|
||||
@ -159,6 +162,7 @@ const struct option cf_options[] = {
|
||||
{"ipv6ra_fork", no_argument, NULL, O_IPV6RA_FORK},
|
||||
{"ipv6ra_own", no_argument, NULL, O_IPV6RA_OWN},
|
||||
{"ipv6ra_own_default", no_argument, NULL, O_IPV6RA_OWN_D},
|
||||
{"ipv6ra_accept_nopublic", no_argument, NULL, O_IPV6RA_ACCEPT_NOPUBLIC},
|
||||
{"ipv4only", no_argument, NULL, '4'},
|
||||
{"ipv6only", no_argument, NULL, '6'},
|
||||
{"ipv4", no_argument, NULL, O_IPV4},
|
||||
@ -191,6 +195,7 @@ const struct option cf_options[] = {
|
||||
{"gateway", no_argument, NULL, O_GATEWAY},
|
||||
{"ia_pd_mix", no_argument, NULL, O_PFXDLGMIX},
|
||||
{"reject", required_argument, NULL, O_REJECT},
|
||||
{"bootp", no_argument, NULL, O_BOOTP},
|
||||
{NULL, 0, NULL, '\0'}
|
||||
};
|
||||
|
||||
@ -1237,6 +1242,9 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
|
||||
case O_IPV6RA_OWN_D:
|
||||
ifo->options |= DHCPCD_IPV6RA_OWN_DEFAULT;
|
||||
break;
|
||||
case O_IPV6RA_ACCEPT_NOPUBLIC:
|
||||
ifo->options |= DHCPCD_IPV6RA_ACCEPT_NOPUBLIC;
|
||||
break;
|
||||
case O_IPV6RA_AUTOCONF:
|
||||
ifo->options |= DHCPCD_IPV6RA_AUTOCONF;
|
||||
break;
|
||||
@ -1955,6 +1963,9 @@ err_sla:
|
||||
case O_PFXDLGMIX:
|
||||
ifo->options |= DHCPCD_PFXDLGMIX;
|
||||
break;
|
||||
case O_BOOTP:
|
||||
ifo->options |= DHCPCD_BOOTP;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -2033,6 +2044,7 @@ read_config(struct dhcpcd_ctx *ctx,
|
||||
{
|
||||
struct if_options *ifo;
|
||||
FILE *fp;
|
||||
struct stat sb;
|
||||
char *line, *buf, *option, *p;
|
||||
size_t buflen;
|
||||
ssize_t vlen;
|
||||
@ -2189,6 +2201,8 @@ read_config(struct dhcpcd_ctx *ctx,
|
||||
free(buf);
|
||||
return ifo;
|
||||
}
|
||||
if (stat(ctx->cffile, &sb) == 0)
|
||||
ifo->mtime = sb.st_mtime;
|
||||
|
||||
ldop = edop = NULL;
|
||||
while ((line = get_line(&buf, &buflen, fp))) {
|
||||
|
9
external/bsd/dhcpcd/dist/if-options.h
vendored
9
external/bsd/dhcpcd/dist/if-options.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if-options.h,v 1.9 2015/03/26 10:26:37 roy Exp $ */
|
||||
/* $NetBSD: if-options.h,v 1.10 2015/05/02 15:18:37 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -111,6 +111,12 @@
|
||||
#define DHCPCD_PFXDLGMIX (1ULL << 53)
|
||||
#define DHCPCD_IPV6RA_AUTOCONF (1ULL << 54)
|
||||
#define DHCPCD_ROUTER_HOST_ROUTE_WARNED (1ULL << 55)
|
||||
#define DHCPCD_IPV6RA_ACCEPT_NOPUBLIC (1ULL << 56)
|
||||
#define DHCPCD_BOOTP (1ULL << 57)
|
||||
|
||||
#define DHCPCD_WARNINGS (DHCPCD_CSR_WARNED | \
|
||||
DHCPCD_ROUTER_HOST_ROUTE_WARNED)
|
||||
#define DHCPCD_CONF (DHCPCD_NOPFXDLG | DHCPCD_PFXDLGONLY)
|
||||
|
||||
extern const struct option cf_options[];
|
||||
|
||||
@ -140,6 +146,7 @@ struct vivco {
|
||||
};
|
||||
|
||||
struct if_options {
|
||||
time_t mtime;
|
||||
uint8_t iaid[4];
|
||||
int metric;
|
||||
uint8_t requestmask[256 / NBBY];
|
||||
|
154
external/bsd/dhcpcd/dist/if.c
vendored
154
external/bsd/dhcpcd/dist/if.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: if.c,v 1.12 2015/03/26 10:26:37 roy Exp $");
|
||||
__RCSID("$NetBSD: if.c,v 1.13 2015/05/02 15:18:37 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -163,6 +163,67 @@ if_hasconf(struct dhcpcd_ctx *ctx, const char *ifname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void if_learnaddrs1(struct dhcpcd_ctx *ctx, struct if_head *ifs,
|
||||
struct ifaddrs *ifaddrs)
|
||||
{
|
||||
struct ifaddrs *ifa;
|
||||
struct interface *ifp;
|
||||
#ifdef INET
|
||||
const struct sockaddr_in *addr, *net, *dst;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6, *net6;
|
||||
#endif
|
||||
int ifa_flags;
|
||||
|
||||
|
||||
for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == NULL)
|
||||
continue;
|
||||
if ((ifp = if_find(ifs, ifa->ifa_name)) == NULL)
|
||||
continue;
|
||||
switch(ifa->ifa_addr->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
addr = (const struct sockaddr_in *)
|
||||
(void *)ifa->ifa_addr;
|
||||
net = (const struct sockaddr_in *)
|
||||
(void *)ifa->ifa_netmask;
|
||||
if (ifa->ifa_flags & IFF_POINTOPOINT)
|
||||
dst = (const struct sockaddr_in *)
|
||||
(void *)ifa->ifa_dstaddr;
|
||||
else
|
||||
dst = NULL;
|
||||
ifa_flags = if_addrflags(&addr->sin_addr, ifp);
|
||||
ipv4_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name,
|
||||
&addr->sin_addr,
|
||||
&net->sin_addr,
|
||||
dst ? &dst->sin_addr : NULL, ifa_flags);
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_addr;
|
||||
net6 = (struct sockaddr_in6 *)(void *)ifa->ifa_netmask;
|
||||
#ifdef __KAME__
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
|
||||
/* Remove the scope from the address */
|
||||
sin6->sin6_addr.s6_addr[2] =
|
||||
sin6->sin6_addr.s6_addr[3] = '\0';
|
||||
#endif
|
||||
ifa_flags = if_addrflags6(&sin6->sin6_addr, ifp);
|
||||
if (ifa_flags != -1)
|
||||
ipv6_handleifa(ctx, RTM_NEWADDR, ifs,
|
||||
ifa->ifa_name,
|
||||
&sin6->sin6_addr,
|
||||
ipv6_prefixlen(&net6->sin6_addr),
|
||||
ifa_flags);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct if_head *
|
||||
if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
|
||||
{
|
||||
@ -174,15 +235,6 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
|
||||
#ifdef __linux__
|
||||
char ifn[IF_NAMESIZE];
|
||||
#endif
|
||||
#ifdef INET
|
||||
const struct sockaddr_in *addr;
|
||||
const struct sockaddr_in *net;
|
||||
const struct sockaddr_in *dst;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6, *net6;
|
||||
int ifa_flags;
|
||||
#endif
|
||||
#ifdef AF_LINK
|
||||
const struct sockaddr_dl *sdl;
|
||||
#ifdef SIOCGIFPRIORITY
|
||||
@ -478,55 +530,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
|
||||
TAILQ_INSERT_TAIL(ifs, ifp, next);
|
||||
}
|
||||
|
||||
for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == NULL)
|
||||
continue;
|
||||
switch(ifa->ifa_addr->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
addr = (const struct sockaddr_in *)
|
||||
(void *)ifa->ifa_addr;
|
||||
net = (const struct sockaddr_in *)
|
||||
(void *)ifa->ifa_netmask;
|
||||
if (ifa->ifa_flags & IFF_POINTOPOINT)
|
||||
dst = (const struct sockaddr_in *)
|
||||
(void *)ifa->ifa_dstaddr;
|
||||
else
|
||||
dst = NULL;
|
||||
ipv4_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name,
|
||||
&addr->sin_addr,
|
||||
&net->sin_addr,
|
||||
dst ? &dst->sin_addr : NULL);
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
TAILQ_FOREACH(ifp, ifs, next) {
|
||||
if (strcmp(ifp->name, ifa->ifa_name) == 0)
|
||||
break;
|
||||
}
|
||||
if (ifp == NULL)
|
||||
break; /* Should be impossible */
|
||||
sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_addr;
|
||||
net6 = (struct sockaddr_in6 *)(void *)ifa->ifa_netmask;
|
||||
#ifdef __KAME__
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
|
||||
/* Remove the scope from the address */
|
||||
sin6->sin6_addr.s6_addr[2] =
|
||||
sin6->sin6_addr.s6_addr[3] = '\0';
|
||||
#endif
|
||||
ifa_flags = if_addrflags6(&sin6->sin6_addr, ifp);
|
||||
if (ifa_flags != -1)
|
||||
ipv6_handleifa(ctx, RTM_NEWADDR, ifs,
|
||||
ifa->ifa_name,
|
||||
&sin6->sin6_addr,
|
||||
ipv6_prefixlen(&net6->sin6_addr),
|
||||
ifa_flags);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if_learnaddrs1(ctx, ifs, ifaddrs);
|
||||
freeifaddrs(ifaddrs);
|
||||
|
||||
#ifdef SIOCGIFPRIORITY
|
||||
@ -540,12 +544,13 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
|
||||
}
|
||||
|
||||
static struct interface *
|
||||
if_findindexname(struct dhcpcd_ctx *ctx, unsigned int idx, const char *name)
|
||||
if_findindexname(struct if_head *ifaces, unsigned int idx, const char *name)
|
||||
{
|
||||
struct interface *ifp;
|
||||
|
||||
if (ctx != NULL && ctx->ifaces != NULL) {
|
||||
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
|
||||
if (ifaces != NULL) {
|
||||
struct interface *ifp;
|
||||
|
||||
TAILQ_FOREACH(ifp, ifaces, next) {
|
||||
if ((ifp->options == NULL ||
|
||||
!(ifp->options->options & DHCPCD_PFXDLGONLY)) &&
|
||||
((name && strcmp(ifp->name, name) == 0) ||
|
||||
@ -556,21 +561,23 @@ if_findindexname(struct dhcpcd_ctx *ctx, unsigned int idx, const char *name)
|
||||
return ifp;
|
||||
}
|
||||
}
|
||||
|
||||
errno = ESRCH;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct interface *
|
||||
if_find(struct dhcpcd_ctx *ctx, const char *name)
|
||||
if_find(struct if_head *ifaces, const char *name)
|
||||
{
|
||||
|
||||
return if_findindexname(ctx, 0, name);
|
||||
return if_findindexname(ifaces, 0, name);
|
||||
}
|
||||
|
||||
struct interface *
|
||||
if_findindex(struct dhcpcd_ctx *ctx, unsigned int idx)
|
||||
if_findindex(struct if_head *ifaces, unsigned int idx)
|
||||
{
|
||||
|
||||
return if_findindexname(ctx, idx, NULL);
|
||||
return if_findindexname(ifaces, idx, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
@ -607,6 +614,12 @@ if_cmp(const struct interface *si, const struct interface *ti)
|
||||
!(ti->options->options & DHCPCD_PFXDLGONLY))
|
||||
return 1;
|
||||
|
||||
/* Check carrier status first */
|
||||
if (si->carrier > ti->carrier)
|
||||
return -1;
|
||||
if (si->carrier < ti->carrier)
|
||||
return 1;
|
||||
|
||||
if (D_STATE_RUNNING(si) && !D_STATE_RUNNING(ti))
|
||||
return -1;
|
||||
if (!D_STATE_RUNNING(si) && D_STATE_RUNNING(ti))
|
||||
@ -621,16 +634,11 @@ if_cmp(const struct interface *si, const struct interface *ti)
|
||||
return 1;
|
||||
|
||||
#ifdef INET
|
||||
/* Special attention needed hereto due take states and IPv4LL. */
|
||||
/* Special attention needed here due to states and IPv4LL. */
|
||||
if ((r = ipv4_ifcmp(si, ti)) != 0)
|
||||
return r;
|
||||
#endif
|
||||
|
||||
/* Then carrier status. */
|
||||
if (si->carrier > ti->carrier)
|
||||
return -1;
|
||||
if (si->carrier < ti->carrier)
|
||||
return 1;
|
||||
/* Finally, metric */
|
||||
if (si->metric < ti->metric)
|
||||
return -1;
|
||||
|
28
external/bsd/dhcpcd/dist/if.h
vendored
28
external/bsd/dhcpcd/dist/if.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if.h,v 1.9 2015/03/26 10:26:37 roy Exp $ */
|
||||
/* $NetBSD: if.h,v 1.10 2015/05/02 15:18:37 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -31,8 +31,14 @@
|
||||
#define INTERFACE_H
|
||||
|
||||
#include <net/if.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <net/if_var.h>
|
||||
#endif
|
||||
#include <net/route.h> /* for RTM_ADD et all */
|
||||
#include <netinet/in.h>
|
||||
#ifdef BSD
|
||||
#include <netinet/in_var.h> /* for IN_IFF_TENTATIVE et all */
|
||||
#endif
|
||||
|
||||
/* Some systems have route metrics.
|
||||
* OpenBSD route priority is not this. */
|
||||
@ -42,6 +48,14 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some systems have in-built IPv4 DAD.
|
||||
* However, we need them to do DAD at carrier up as well. */
|
||||
#ifdef IN_IFF_TENTATIVE
|
||||
# ifdef __NetBSD__
|
||||
# define NOCARRIER_PRESERVE_IP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "dhcpcd.h"
|
||||
#include "ipv4.h"
|
||||
@ -85,8 +99,8 @@
|
||||
int if_setflag(struct interface *ifp, short flag);
|
||||
#define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING))
|
||||
struct if_head *if_discover(struct dhcpcd_ctx *, int, char * const *);
|
||||
struct interface *if_find(struct dhcpcd_ctx *, const char *);
|
||||
struct interface *if_findindex(struct dhcpcd_ctx *, unsigned int);
|
||||
struct interface *if_find(struct if_head *, const char *);
|
||||
struct interface *if_findindex(struct if_head *, unsigned int);
|
||||
void if_sortinterfaces(struct dhcpcd_ctx *);
|
||||
void if_free(struct interface *);
|
||||
int if_domtu(const char *, short int);
|
||||
@ -114,10 +128,10 @@ int if_managelink(struct dhcpcd_ctx *);
|
||||
|
||||
#ifdef INET
|
||||
extern const char *if_pfname;
|
||||
int if_openrawsocket(struct interface *, int);
|
||||
int if_openrawsocket(struct interface *, uint16_t);
|
||||
ssize_t if_sendrawpacket(const struct interface *,
|
||||
int, const void *, size_t);
|
||||
ssize_t if_readrawpacket(struct interface *, int, void *, size_t, int *);
|
||||
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 *,
|
||||
@ -127,6 +141,8 @@ int if_address(const struct interface *,
|
||||
#define if_deladdress(ifp, addr, net) \
|
||||
if_address(ifp, addr, net, NULL, -1)
|
||||
|
||||
int if_addrflags(const struct in_addr *, const struct interface *);
|
||||
|
||||
int if_route(unsigned char, const struct rt *rt);
|
||||
int if_initrt(struct interface *);
|
||||
#endif
|
||||
|
298
external/bsd/dhcpcd/dist/ipv4.c
vendored
298
external/bsd/dhcpcd/dist/ipv4.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: ipv4.c,v 1.13 2015/03/27 11:33:46 roy Exp $");
|
||||
__RCSID("$NetBSD: ipv4.c,v 1.14 2015/05/02 15:18:37 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -255,8 +255,8 @@ find_route(struct rt_head *rts, const struct rt *r, const struct rt *srt)
|
||||
TAILQ_FOREACH(rt, rts, next) {
|
||||
if (rt->dest.s_addr == r->dest.s_addr &&
|
||||
#ifdef HAVE_ROUTE_METRIC
|
||||
(srt || (!rt->iface ||
|
||||
rt->iface->metric == r->iface->metric)) &&
|
||||
(srt || (r->iface == NULL || rt->iface == NULL ||
|
||||
rt->iface->metric == r->iface->metric)) &&
|
||||
#endif
|
||||
(!srt || srt != rt) &&
|
||||
rt->net.s_addr == r->net.s_addr)
|
||||
@ -273,18 +273,18 @@ desc_route(const char *cmd, const struct rt *rt)
|
||||
const char *ifname = rt->iface ? rt->iface->name : NULL;
|
||||
|
||||
strlcpy(addr, inet_ntoa(rt->dest), sizeof(addr));
|
||||
if (rt->gate.s_addr == INADDR_ANY)
|
||||
logger(ctx, LOG_INFO, "%s: %s route to %s/%d",
|
||||
ifname, cmd, addr, inet_ntocidr(rt->net));
|
||||
else if (rt->gate.s_addr == rt->dest.s_addr &&
|
||||
rt->net.s_addr == INADDR_BROADCAST)
|
||||
if (rt->net.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->gate.s_addr == htonl(INADDR_LOOPBACK) &&
|
||||
rt->net.s_addr == INADDR_BROADCAST)
|
||||
else if (rt->net.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 == INADDR_ANY && rt->net.s_addr == INADDR_ANY)
|
||||
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));
|
||||
else if (rt->dest.s_addr == htonl(INADDR_ANY) &&
|
||||
rt->net.s_addr == htonl(INADDR_ANY))
|
||||
logger(ctx, LOG_INFO, "%s: %s default route via %s",
|
||||
ifname, cmd, inet_ntoa(rt->gate));
|
||||
else
|
||||
@ -335,12 +335,6 @@ ipv4_handlert(struct dhcpcd_ctx *ctx, int cmd, struct rt *rt)
|
||||
if (ctx->ipv4_kroutes == NULL)
|
||||
return 0;
|
||||
|
||||
/* DHCP host routes have a gateway of the destination.
|
||||
* We need to emulate that */
|
||||
if (rt->gate.s_addr == INADDR_ANY &&
|
||||
rt->net.s_addr == INADDR_BROADCAST)
|
||||
rt->gate = rt->dest;
|
||||
|
||||
f = ipv4_findrt(ctx, rt, 1);
|
||||
switch (cmd) {
|
||||
case RTM_ADD:
|
||||
@ -443,38 +437,34 @@ d_route(struct rt *rt)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct rt *
|
||||
make_subnet_route(const struct interface *ifp)
|
||||
{
|
||||
const struct dhcp_state *s;
|
||||
struct rt *r;
|
||||
|
||||
s = D_CSTATE(ifp);
|
||||
if (s->net.s_addr == INADDR_BROADCAST ||
|
||||
s->net.s_addr == INADDR_ANY)
|
||||
return NULL;
|
||||
|
||||
r = malloc(sizeof(*r));
|
||||
if (r == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
return NULL;
|
||||
}
|
||||
r->dest.s_addr = s->addr.s_addr & s->net.s_addr;
|
||||
r->net.s_addr = s->net.s_addr;
|
||||
r->gate.s_addr = INADDR_ANY;
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct rt_head *
|
||||
add_subnet_route(struct rt_head *rt, const struct interface *ifp)
|
||||
{
|
||||
const struct dhcp_state *s;
|
||||
struct rt *r;
|
||||
|
||||
if (rt == NULL) /* earlier malloc failed */
|
||||
return NULL;
|
||||
|
||||
if ((r = make_subnet_route(ifp)) == NULL)
|
||||
s = D_CSTATE(ifp);
|
||||
/* Don't create a subnet route for these addresses */
|
||||
if (s->net.s_addr == INADDR_ANY)
|
||||
return rt;
|
||||
#ifndef BSD
|
||||
/* BSD adds a route in this instance */
|
||||
if (s->net.s_addr == INADDR_BROADCAST)
|
||||
return rt;
|
||||
#endif
|
||||
|
||||
if ((r = malloc(sizeof(*r))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
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->gate.s_addr = INADDR_ANY;
|
||||
|
||||
TAILQ_INSERT_HEAD(rt, r, next);
|
||||
return rt;
|
||||
}
|
||||
@ -535,8 +525,8 @@ get_routes(struct interface *ifp)
|
||||
}
|
||||
|
||||
/* Some DHCP servers add set host routes by setting the gateway
|
||||
* to the assinged IP address. This differs from our notion of a host route
|
||||
* where the gateway is the destination address, so we fix it. */
|
||||
* to the assigned IP address or the destination address.
|
||||
* We need to change this. */
|
||||
static struct rt_head *
|
||||
massage_host_routes(struct rt_head *rt, const struct interface *ifp)
|
||||
{
|
||||
@ -544,14 +534,18 @@ massage_host_routes(struct rt_head *rt, const struct interface *ifp)
|
||||
|
||||
if (rt) {
|
||||
TAILQ_FOREACH(r, rt, next) {
|
||||
if (r->gate.s_addr == D_CSTATE(ifp)->addr.s_addr &&
|
||||
r->net.s_addr == INADDR_BROADCAST)
|
||||
r->gate.s_addr = r->dest.s_addr;
|
||||
if (r->gate.s_addr == D_CSTATE(ifp)->addr.s_addr ||
|
||||
r->gate.s_addr == r->dest.s_addr)
|
||||
{
|
||||
r->gate.s_addr = htonl(INADDR_ANY);
|
||||
r->net.s_addr = htonl(INADDR_BROADCAST);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
static struct rt_head *
|
||||
add_destination_route(struct rt_head *rt, const struct interface *ifp)
|
||||
{
|
||||
@ -641,8 +635,8 @@ add_router_host_route(struct rt_head *rt, const struct interface *ifp)
|
||||
return NULL;
|
||||
}
|
||||
rtn->dest.s_addr = rtp->gate.s_addr;
|
||||
rtn->net.s_addr = INADDR_BROADCAST;
|
||||
rtn->gate.s_addr = rtp->gate.s_addr;
|
||||
rtn->net.s_addr = htonl(INADDR_BROADCAST);
|
||||
rtn->gate.s_addr = htonl(INADDR_ANY);
|
||||
TAILQ_INSERT_BEFORE(rtp, rtn, next);
|
||||
}
|
||||
return rt;
|
||||
@ -729,32 +723,45 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx)
|
||||
}
|
||||
|
||||
/* Remove old routes we used to manage */
|
||||
TAILQ_FOREACH(rt, ctx->ipv4_routes, next) {
|
||||
if (find_route(nrs, rt, NULL) == NULL &&
|
||||
(rt->iface->options->options &
|
||||
(DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
|
||||
(DHCPCD_EXITING | DHCPCD_PERSISTENT))
|
||||
d_route(rt);
|
||||
if (ctx->ipv4_routes) {
|
||||
TAILQ_FOREACH(rt, ctx->ipv4_routes, next) {
|
||||
if (find_route(nrs, rt, NULL) == NULL &&
|
||||
(rt->iface->options->options &
|
||||
(DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
|
||||
(DHCPCD_EXITING | DHCPCD_PERSISTENT))
|
||||
d_route(rt);
|
||||
}
|
||||
}
|
||||
ipv4_freeroutes(ctx->ipv4_routes);
|
||||
ctx->ipv4_routes = nrs;
|
||||
}
|
||||
|
||||
static int
|
||||
delete_address1(struct interface *ifp,
|
||||
int
|
||||
ipv4_deladdr(struct interface *ifp,
|
||||
const struct in_addr *addr, const struct in_addr *net)
|
||||
{
|
||||
struct dhcp_state *dstate;
|
||||
int r;
|
||||
struct ipv4_state *state;
|
||||
struct ipv4_addr *ap;
|
||||
|
||||
logger(ifp->ctx, LOG_DEBUG, "%s: deleting IP address %s/%d",
|
||||
ifp->name, inet_ntoa(*addr), inet_ntocidr(*net));
|
||||
|
||||
r = if_deladdress(ifp, addr, net);
|
||||
if (r == -1 && errno != EADDRNOTAVAIL && errno != ENXIO &&
|
||||
errno != ENODEV)
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
|
||||
|
||||
dstate = D_STATE(ifp);
|
||||
if (dstate->addr.s_addr == addr->s_addr &&
|
||||
dstate->net.s_addr == net->s_addr)
|
||||
{
|
||||
dstate->added = 0;
|
||||
dstate->addr.s_addr = 0;
|
||||
dstate->net.s_addr = 0;
|
||||
}
|
||||
|
||||
state = IPV4_STATE(ifp);
|
||||
TAILQ_FOREACH(ap, &state->addrs, next) {
|
||||
if (ap->addr.s_addr == addr->s_addr &&
|
||||
@ -780,10 +787,7 @@ delete_address(struct interface *ifp)
|
||||
if (ifo->options & DHCPCD_INFORM ||
|
||||
(ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0))
|
||||
return 0;
|
||||
r = delete_address1(ifp, &state->addr, &state->net);
|
||||
state->added = 0;
|
||||
state->addr.s_addr = 0;
|
||||
state->net.s_addr = 0;
|
||||
r = ipv4_deladdr(ifp, &state->addr, &state->net);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -809,26 +813,82 @@ ipv4_getstate(struct interface *ifp)
|
||||
static int
|
||||
ipv4_addaddr(struct interface *ifp, const struct dhcp_lease *lease)
|
||||
{
|
||||
int r;
|
||||
struct ipv4_state *state;
|
||||
struct ipv4_addr *ia;
|
||||
|
||||
if ((state = ipv4_getstate(ifp)) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: ipv4_getstate: %m", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (ifp->options->options & DHCPCD_NOALIAS) {
|
||||
struct ipv4_state *state;
|
||||
struct ipv4_addr *ap, *apn;
|
||||
struct ipv4_addr *ian;
|
||||
|
||||
state = IPV4_STATE(ifp);
|
||||
TAILQ_FOREACH_SAFE(ap, &state->addrs, next, apn) {
|
||||
if (ap->addr.s_addr != lease->addr.s_addr)
|
||||
delete_address1(ifp, &ap->addr, &ap->net);
|
||||
TAILQ_FOREACH_SAFE(ia, &state->addrs, next, ian) {
|
||||
if (ia->addr.s_addr != lease->addr.s_addr)
|
||||
ipv4_deladdr(ifp, &ia->addr, &ia->net);
|
||||
}
|
||||
}
|
||||
|
||||
if ((ia = malloc(sizeof(*ia))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
logger(ifp->ctx, LOG_DEBUG, "%s: adding IP address %s/%d",
|
||||
ifp->name, inet_ntoa(lease->addr),
|
||||
inet_ntocidr(lease->net));
|
||||
r = if_addaddress(ifp, &lease->addr, &lease->net, &lease->brd);
|
||||
if (r == -1 && errno != EEXIST)
|
||||
logger(ifp->ctx, LOG_ERR, "%s: if_addaddress: %m", __func__);
|
||||
return r;
|
||||
if (if_addaddress(ifp, &lease->addr, &lease->net, &lease->brd) == -1) {
|
||||
if (errno != EEXIST)
|
||||
logger(ifp->ctx, LOG_ERR, "%s: if_addaddress: %m",
|
||||
__func__);
|
||||
free(ia);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ia->iface = ifp;
|
||||
ia->addr = lease->addr;
|
||||
ia->net = lease->net;
|
||||
#ifdef IN_IFF_TENTATIVE
|
||||
ia->addr_flags = IN_IFF_TENTATIVE;
|
||||
#endif
|
||||
TAILQ_INSERT_TAIL(&state->addrs, ia, next);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ipv4_finalisert(struct interface *ifp)
|
||||
{
|
||||
const struct dhcp_state *state = D_CSTATE(ifp);
|
||||
|
||||
/* 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);
|
||||
ipv4_buildroutes(ifp->ctx);
|
||||
script_runreason(ifp, state->reason);
|
||||
|
||||
dhcpcd_daemonise(ifp->ctx);
|
||||
}
|
||||
|
||||
void
|
||||
ipv4_finaliseaddr(struct interface *ifp)
|
||||
{
|
||||
struct dhcp_state *state = D_STATE(ifp);
|
||||
struct dhcp_lease *lease;
|
||||
|
||||
lease = &state->lease;
|
||||
|
||||
/* Delete the old address if different */
|
||||
if (state->addr.s_addr != lease->addr.s_addr &&
|
||||
state->addr.s_addr != 0 &&
|
||||
ipv4_iffindaddr(ifp, &lease->addr, NULL))
|
||||
delete_address(ifp);
|
||||
|
||||
state->added = STATE_ADDED;
|
||||
state->defend = 0;
|
||||
state->addr.s_addr = lease->addr.s_addr;
|
||||
state->net.s_addr = lease->net.s_addr;
|
||||
ipv4_finalisert(ifp);
|
||||
}
|
||||
|
||||
void
|
||||
@ -840,7 +900,6 @@ ipv4_applyaddr(void *arg)
|
||||
struct dhcp_lease *lease;
|
||||
struct if_options *ifo = ifp->options;
|
||||
struct ipv4_addr *ap;
|
||||
struct ipv4_state *istate = NULL;
|
||||
int r;
|
||||
|
||||
if (state == NULL)
|
||||
@ -902,13 +961,13 @@ ipv4_applyaddr(void *arg)
|
||||
ifn->name);
|
||||
state->addr.s_addr = lease->addr.s_addr;
|
||||
state->net.s_addr = lease->net.s_addr;
|
||||
goto routes;
|
||||
ipv4_finalisert(ifp);
|
||||
}
|
||||
logger(ifp->ctx, LOG_INFO, "%s: preferring %s on %s",
|
||||
ifn->name,
|
||||
inet_ntoa(lease->addr),
|
||||
ifp->name);
|
||||
delete_address1(ifn, &nstate->addr, &nstate->net);
|
||||
ipv4_deladdr(ifn, &nstate->addr, &nstate->net);
|
||||
nstate->added = 0;
|
||||
break;
|
||||
}
|
||||
@ -921,14 +980,14 @@ ipv4_applyaddr(void *arg)
|
||||
continue;
|
||||
ap = ipv4_iffindaddr(ifn, &lease->addr, NULL);
|
||||
if (ap)
|
||||
delete_address1(ifn, &ap->addr, &ap->net);
|
||||
ipv4_deladdr(ifn, &ap->addr, &ap->net);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the netmask is different, delete the addresss */
|
||||
ap = ipv4_iffindaddr(ifp, &lease->addr, NULL);
|
||||
if (ap && ap->net.s_addr != lease->net.s_addr)
|
||||
delete_address1(ifp, &ap->addr, &ap->net);
|
||||
ipv4_deladdr(ifp, &ap->addr, &ap->net);
|
||||
|
||||
if (ipv4_iffindaddr(ifp, &lease->addr, &lease->net))
|
||||
logger(ifp->ctx, LOG_DEBUG,
|
||||
@ -939,40 +998,26 @@ ipv4_applyaddr(void *arg)
|
||||
r = ipv4_addaddr(ifp, lease);
|
||||
if (r == -1 && errno != EEXIST)
|
||||
return;
|
||||
istate = ipv4_getstate(ifp);
|
||||
ap = malloc(sizeof(*ap));
|
||||
ap->iface = ifp;
|
||||
ap->addr = lease->addr;
|
||||
ap->net = lease->net;
|
||||
ap->dst.s_addr = INADDR_ANY;
|
||||
TAILQ_INSERT_TAIL(&istate->addrs, ap, next);
|
||||
}
|
||||
|
||||
/* Now delete the old address if different */
|
||||
if (state->addr.s_addr != lease->addr.s_addr &&
|
||||
state->addr.s_addr != 0 &&
|
||||
ipv4_iffindaddr(ifp, &lease->addr, NULL))
|
||||
delete_address(ifp);
|
||||
#ifdef IN_IFF_NOTUSEABLE
|
||||
ap = ipv4_iffindaddr(ifp, &lease->addr, NULL);
|
||||
if (ap == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: added address vanished",
|
||||
ifp->name);
|
||||
return;
|
||||
} else if (ap->addr_flags & IN_IFF_NOTUSEABLE)
|
||||
return;
|
||||
#endif
|
||||
|
||||
state->added = STATE_ADDED;
|
||||
state->defend = 0;
|
||||
state->addr.s_addr = lease->addr.s_addr;
|
||||
state->net.s_addr = lease->net.s_addr;
|
||||
|
||||
routes:
|
||||
/* 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);
|
||||
ipv4_buildroutes(ifp->ctx);
|
||||
script_runreason(ifp, state->reason);
|
||||
ipv4_finaliseaddr(ifp);
|
||||
}
|
||||
|
||||
void
|
||||
ipv4_handleifa(struct dhcpcd_ctx *ctx,
|
||||
int type, struct if_head *ifs, const char *ifname,
|
||||
int cmd, struct if_head *ifs, const char *ifname,
|
||||
const struct in_addr *addr, const struct in_addr *net,
|
||||
const struct in_addr *dst)
|
||||
const struct in_addr *dst, int flags)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct ipv4_state *state;
|
||||
@ -988,44 +1033,39 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx,
|
||||
errno = EINVAL;
|
||||
return;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(ifp, ifs, next) {
|
||||
if (strcmp(ifp->name, ifname) == 0)
|
||||
break;
|
||||
}
|
||||
if (ifp == NULL) {
|
||||
errno = ESRCH;
|
||||
if ((ifp = if_find(ifs, ifname)) == NULL)
|
||||
return;
|
||||
}
|
||||
state = ipv4_getstate(ifp);
|
||||
if (state == NULL) {
|
||||
if ((state = ipv4_getstate(ifp)) == NULL) {
|
||||
errno = ENOENT;
|
||||
return;
|
||||
}
|
||||
|
||||
ap = ipv4_iffindaddr(ifp, addr, net);
|
||||
if (type == RTM_NEWADDR && ap == NULL) {
|
||||
ap = malloc(sizeof(*ap));
|
||||
if (cmd == RTM_NEWADDR) {
|
||||
if (ap == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
return;
|
||||
if ((ap = malloc(sizeof(*ap))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
return;
|
||||
}
|
||||
ap->iface = ifp;
|
||||
ap->addr = *addr;
|
||||
ap->net = *net;
|
||||
if (dst)
|
||||
ap->dst.s_addr = dst->s_addr;
|
||||
else
|
||||
ap->dst.s_addr = INADDR_ANY;
|
||||
TAILQ_INSERT_TAIL(&state->addrs, ap, next);
|
||||
}
|
||||
ap->addr_flags = flags;
|
||||
} else if (cmd == RTM_DELADDR) {
|
||||
if (ap) {
|
||||
TAILQ_REMOVE(&state->addrs, ap, next);
|
||||
free(ap);
|
||||
}
|
||||
ap->iface = ifp;
|
||||
ap->addr.s_addr = addr->s_addr;
|
||||
ap->net.s_addr = net->s_addr;
|
||||
if (dst)
|
||||
ap->dst.s_addr = dst->s_addr;
|
||||
else
|
||||
ap->dst.s_addr = INADDR_ANY;
|
||||
TAILQ_INSERT_TAIL(&state->addrs, ap, next);
|
||||
} else if (type == RTM_DELADDR) {
|
||||
if (ap == NULL)
|
||||
return;
|
||||
TAILQ_REMOVE(&state->addrs, ap, next);
|
||||
free(ap);
|
||||
}
|
||||
|
||||
dhcp_handleifa(type, ifp, addr, net, dst);
|
||||
dhcp_handleifa(cmd, ifp, addr, net, dst, flags);
|
||||
arp_handleifa(cmd, ifp, addr, flags);
|
||||
}
|
||||
|
||||
void
|
||||
|
16
external/bsd/dhcpcd/dist/ipv4.h
vendored
16
external/bsd/dhcpcd/dist/ipv4.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ipv4.h,v 1.9 2015/03/26 10:26:37 roy Exp $ */
|
||||
/* $NetBSD: ipv4.h,v 1.10 2015/05/02 15:18:37 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -32,6 +32,11 @@
|
||||
|
||||
#include "dhcpcd.h"
|
||||
|
||||
#ifdef IN_IFF_TENTATIVE
|
||||
#define IN_IFF_NOTUSEABLE \
|
||||
(IN_IFF_TENTATIVE | IN_IFF_DUPLICATED | IN_IFF_DETACHED)
|
||||
#endif
|
||||
|
||||
struct rt {
|
||||
TAILQ_ENTRY(rt) next;
|
||||
struct in_addr dest;
|
||||
@ -42,7 +47,7 @@ struct rt {
|
||||
unsigned int metric;
|
||||
#endif
|
||||
struct in_addr src;
|
||||
uint8_t flags;
|
||||
unsigned int flags;
|
||||
};
|
||||
TAILQ_HEAD(rt_head, rt);
|
||||
|
||||
@ -52,6 +57,7 @@ struct ipv4_addr {
|
||||
struct in_addr net;
|
||||
struct in_addr dst;
|
||||
struct interface *iface;
|
||||
int addr_flags;
|
||||
};
|
||||
TAILQ_HEAD(ipv4_addrhead, ipv4_addr);
|
||||
|
||||
@ -77,6 +83,9 @@ int ipv4_addrexists(struct dhcpcd_ctx *, const struct in_addr *);
|
||||
#define STATE_FAKE 0x02
|
||||
|
||||
void ipv4_buildroutes(struct dhcpcd_ctx *);
|
||||
void ipv4_finaliseaddr(struct interface *);
|
||||
int ipv4_deladdr(struct interface *ifp, const struct in_addr *,
|
||||
const struct in_addr *);
|
||||
void ipv4_applyaddr(void *);
|
||||
int ipv4_handlert(struct dhcpcd_ctx *, int, struct rt *);
|
||||
void ipv4_freerts(struct rt_head *);
|
||||
@ -86,7 +95,8 @@ struct ipv4_addr *ipv4_iffindaddr(struct interface *,
|
||||
struct ipv4_addr *ipv4_iffindlladdr(struct interface *);
|
||||
struct ipv4_addr *ipv4_findaddr(struct dhcpcd_ctx *, const struct in_addr *);
|
||||
void ipv4_handleifa(struct dhcpcd_ctx *, int, struct if_head *, const char *,
|
||||
const struct in_addr *, const struct in_addr *, const struct in_addr *);
|
||||
const struct in_addr *, const struct in_addr *, const struct in_addr *,
|
||||
int);
|
||||
|
||||
void ipv4_freeroutes(struct rt_head *);
|
||||
|
||||
|
29
external/bsd/dhcpcd/dist/ipv4ll.c
vendored
29
external/bsd/dhcpcd/dist/ipv4ll.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: ipv4ll.c,v 1.9 2015/03/26 10:26:37 roy Exp $");
|
||||
__RCSID("$NetBSD: ipv4ll.c,v 1.10 2015/05/02 15:18:37 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -108,11 +108,17 @@ static void
|
||||
ipv4ll_probed(struct arp_state *astate)
|
||||
{
|
||||
struct dhcp_state *state = D_STATE(astate->iface);
|
||||
struct dhcp_message *offer;
|
||||
|
||||
if (state->state == DHS_IPV4LL_BOUND) {
|
||||
ipv4_finaliseaddr(astate->iface);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->state != DHS_BOUND) {
|
||||
struct dhcp_message *offer;
|
||||
|
||||
/* A DHCP lease could have already been offered.
|
||||
* Backup and replace once the IPv4LL addres is bound */
|
||||
* Backup and replace once the IPv4LL address is bound */
|
||||
offer = state->offer;
|
||||
state->offer = ipv4ll_make_lease(astate->addr.s_addr);
|
||||
if (state->offer == NULL)
|
||||
@ -136,7 +142,11 @@ static void
|
||||
ipv4ll_probe(void *arg)
|
||||
{
|
||||
|
||||
#ifdef IN_IFF_TENTATIVE
|
||||
ipv4ll_probed(arg);
|
||||
#else
|
||||
arp_probe(arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@ -147,13 +157,14 @@ ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
|
||||
|
||||
fail = 0;
|
||||
/* RFC 3927 2.2.1, Probe Conflict Detection */
|
||||
if (amsg->sip.s_addr == astate->addr.s_addr ||
|
||||
(amsg->sip.s_addr == 0 && amsg->tip.s_addr == astate->addr.s_addr))
|
||||
if (amsg == NULL ||
|
||||
(amsg->sip.s_addr == astate->addr.s_addr ||
|
||||
(amsg->sip.s_addr == 0 && amsg->tip.s_addr == astate->addr.s_addr)))
|
||||
fail = astate->addr.s_addr;
|
||||
|
||||
/* RFC 3927 2.5, Conflict Defense */
|
||||
if (IN_LINKLOCAL(htonl(state->addr.s_addr)) &&
|
||||
amsg->sip.s_addr == state->addr.s_addr)
|
||||
amsg && amsg->sip.s_addr == state->addr.s_addr)
|
||||
fail = state->addr.s_addr;
|
||||
|
||||
if (fail == 0)
|
||||
@ -221,7 +232,7 @@ ipv4ll_start(void *arg)
|
||||
initstate(seed, state->randomstate, sizeof(state->randomstate));
|
||||
}
|
||||
|
||||
if ((astate = arp_new(ifp)) == NULL)
|
||||
if ((astate = arp_new(ifp, NULL)) == NULL)
|
||||
return;
|
||||
|
||||
state->arp_ipv4ll = astate;
|
||||
@ -257,7 +268,11 @@ ipv4ll_start(void *arg)
|
||||
}
|
||||
if (astate->addr.s_addr == INADDR_ANY)
|
||||
astate->addr.s_addr = ipv4ll_pick_addr(astate);
|
||||
#ifdef IN_IFF_TENTATIVE
|
||||
ipv4ll_probed(astate);
|
||||
#else
|
||||
arp_probe(astate);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
15
external/bsd/dhcpcd/dist/ipv6.c
vendored
15
external/bsd/dhcpcd/dist/ipv6.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: ipv6.c,v 1.10 2015/03/27 11:33:46 roy Exp $");
|
||||
__RCSID("$NetBSD: ipv6.c,v 1.11 2015/05/02 15:18:37 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -748,6 +748,14 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timespec *now)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipv6_publicaddr(const struct ipv6_addr *ia)
|
||||
{
|
||||
return (ia->prefix_pltime &&
|
||||
(ia->addr.s6_addr[0] & 0xfe) != 0xc &&
|
||||
!(ia->addr_flags & IN6_IFF_NOTUSEABLE));
|
||||
}
|
||||
|
||||
struct ipv6_addr *
|
||||
ipv6_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr, short flags)
|
||||
{
|
||||
@ -1963,7 +1971,7 @@ static void
|
||||
ipv6_build_ra_routes(struct ipv6_ctx *ctx, struct rt6_head *dnr, int expired)
|
||||
{
|
||||
struct rt6 *rt;
|
||||
const struct ra *rap;
|
||||
struct ra *rap;
|
||||
const struct ipv6_addr *addr;
|
||||
|
||||
TAILQ_FOREACH(rap, ctx->ra_routers, next) {
|
||||
@ -1977,7 +1985,8 @@ ipv6_build_ra_routes(struct ipv6_ctx *ctx, struct rt6_head *dnr, int expired)
|
||||
}
|
||||
}
|
||||
if (rap->lifetime && rap->iface->options->options &
|
||||
(DHCPCD_IPV6RA_OWN | DHCPCD_IPV6RA_OWN_DEFAULT))
|
||||
(DHCPCD_IPV6RA_OWN | DHCPCD_IPV6RA_OWN_DEFAULT) &&
|
||||
!rap->no_public_warned)
|
||||
{
|
||||
rt = make_router(rap);
|
||||
if (rt)
|
||||
|
16
external/bsd/dhcpcd/dist/ipv6.h
vendored
16
external/bsd/dhcpcd/dist/ipv6.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ipv6.h,v 1.11 2015/03/26 10:26:37 roy Exp $ */
|
||||
/* $NetBSD: ipv6.h,v 1.12 2015/05/02 15:18:37 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -31,14 +31,8 @@
|
||||
#define IPV6_H
|
||||
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#if defined(__linux__) && defined(__GLIBC__)
|
||||
# define _LINUX_IN6_H
|
||||
# include <linux/ipv6.h>
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "dhcpcd.h"
|
||||
|
||||
@ -198,13 +192,6 @@ struct ipv6_state {
|
||||
CMSG_SPACE(sizeof(int)))
|
||||
|
||||
|
||||
/* ipi6.ifiindex differes between OS's so have a cast function */
|
||||
#ifdef __linux__
|
||||
#define CAST_IPI6_IFINDEX(idx) (int)(idx)
|
||||
#else
|
||||
#define CAST_IPI6_IFINDEX(idx) (idx)
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
struct ipv6_ctx {
|
||||
struct sockaddr_in6 from;
|
||||
@ -248,6 +235,7 @@ void ipv6_handleifa(struct dhcpcd_ctx *ctx, int, struct if_head *,
|
||||
const char *, const struct in6_addr *, uint8_t, int);
|
||||
int ipv6_handleifa_addrs(int, struct ipv6_addrhead *,
|
||||
const struct in6_addr *, int);
|
||||
int ipv6_publicaddr(const struct ipv6_addr *);
|
||||
const struct ipv6_addr *ipv6_iffindaddr(const struct interface *,
|
||||
const struct in6_addr *);
|
||||
struct ipv6_addr *ipv6_findaddr(struct dhcpcd_ctx *,
|
||||
|
122
external/bsd/dhcpcd/dist/ipv6nd.c
vendored
122
external/bsd/dhcpcd/dist/ipv6nd.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: ipv6nd.c,v 1.22 2015/03/28 14:16:52 christos Exp $");
|
||||
__RCSID("$NetBSD: ipv6nd.c,v 1.23 2015/05/02 15:18:37 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -57,9 +57,6 @@
|
||||
/* Debugging Router Solicitations is a lot of spam, so disable it */
|
||||
//#define DEBUG_RS
|
||||
|
||||
#define RTR_SOLICITATION_INTERVAL 4 /* seconds */
|
||||
#define MAX_RTR_SOLICITATIONS 3 /* times */
|
||||
|
||||
#ifndef ND_OPT_RDNSS
|
||||
#define ND_OPT_RDNSS 25
|
||||
struct nd_opt_rdnss { /* RDNSS option RFC 6106 */
|
||||
@ -298,7 +295,7 @@ ipv6nd_sendrsprobe(void *arg)
|
||||
cm->cmsg_type = IPV6_PKTINFO;
|
||||
cm->cmsg_len = CMSG_LEN(sizeof(pi));
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
pi.ipi6_ifindex = CAST_IPI6_IFINDEX(ifp->index);
|
||||
pi.ipi6_ifindex = ifp->index;
|
||||
memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
|
||||
|
||||
logger(ifp->ctx, LOG_DEBUG,
|
||||
@ -314,9 +311,48 @@ ipv6nd_sendrsprobe(void *arg)
|
||||
if (state->rsprobes++ < MAX_RTR_SOLICITATIONS)
|
||||
eloop_timeout_add_sec(ifp->ctx->eloop,
|
||||
RTR_SOLICITATION_INTERVAL, ipv6nd_sendrsprobe, ifp);
|
||||
else
|
||||
else {
|
||||
logger(ifp->ctx, LOG_WARNING,
|
||||
"%s: no IPv6 Routers available", ifp->name);
|
||||
ipv6nd_drop(ifp);
|
||||
dhcp6_drop(ifp, "EXPIRE6");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ipv6nd_expire(struct interface *ifp, uint32_t seconds)
|
||||
{
|
||||
struct ra *rap;
|
||||
struct timespec now;
|
||||
|
||||
get_monotonic(&now);
|
||||
|
||||
TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
|
||||
if (rap->iface == ifp) {
|
||||
rap->received = now;
|
||||
rap->expired = seconds ? 0 : 1;
|
||||
if (seconds) {
|
||||
struct ra_opt *rao;
|
||||
struct ipv6_addr *ap;
|
||||
|
||||
rap->lifetime = seconds;
|
||||
TAILQ_FOREACH(ap, &rap->addrs, next) {
|
||||
if (ap->prefix_vltime) {
|
||||
ap->prefix_vltime = seconds;
|
||||
ap->prefix_pltime = seconds / 2;
|
||||
}
|
||||
}
|
||||
ipv6_addaddrs(&rap->addrs);
|
||||
TAILQ_FOREACH(rao, &rap->options, next) {
|
||||
timespecclear(&rao->expire);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (seconds)
|
||||
ipv6nd_expirera(ifp);
|
||||
else
|
||||
ipv6_buildroutes(ifp->ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -410,7 +446,6 @@ void ipv6nd_freedrop_ra(struct ra *rap, int drop)
|
||||
ipv6nd_free_opts(rap);
|
||||
free(rap->data);
|
||||
free(rap);
|
||||
|
||||
}
|
||||
|
||||
ssize_t
|
||||
@ -676,6 +711,19 @@ try_script:
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ipv6nd_ra_has_public_addr(const struct ra *rap)
|
||||
{
|
||||
const struct ipv6_addr *ia;
|
||||
|
||||
TAILQ_FOREACH(ia, &rap->addrs, next) {
|
||||
if (ia->flags & IPV6_AF_AUTOCONF &&
|
||||
ipv6_publicaddr(ia))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp,
|
||||
struct icmp6_hdr *icp, size_t len)
|
||||
@ -763,6 +811,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp,
|
||||
if (rap) {
|
||||
free(rap->data);
|
||||
rap->data_len = 0;
|
||||
rap->no_public_warned = 0;
|
||||
}
|
||||
new_data = 1;
|
||||
} else
|
||||
@ -836,7 +885,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp,
|
||||
}
|
||||
if (olen > len) {
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: Option length exceeds message", ifp->name);
|
||||
"%s: option length exceeds message", ifp->name);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1061,8 +1110,8 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp,
|
||||
STRING | ARRAY | DOMAIN,
|
||||
(const uint8_t *)tmp, l);
|
||||
} else
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m",
|
||||
__func__);
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: %m", __func__);
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
@ -1123,6 +1172,19 @@ extra_opt:
|
||||
|
||||
if (new_rap)
|
||||
add_router(ifp->ctx->ipv6, rap);
|
||||
if (!ipv6nd_ra_has_public_addr(rap) &&
|
||||
!(rap->iface->options->options & DHCPCD_IPV6RA_ACCEPT_NOPUBLIC) &&
|
||||
(!(rap->flags & ND_RA_FLAG_MANAGED) ||
|
||||
!dhcp6_has_public_addr(rap->iface)))
|
||||
{
|
||||
logger(rap->iface->ctx,
|
||||
rap->no_public_warned ? LOG_DEBUG : LOG_WARNING,
|
||||
"%s: ignoring RA from %s"
|
||||
" (no public prefix, no managed address)",
|
||||
rap->iface->name, rap->sfrom);
|
||||
rap->no_public_warned = 1;
|
||||
return;
|
||||
}
|
||||
if (ifp->ctx->options & DHCPCD_TEST) {
|
||||
script_runreason(ifp, "TEST");
|
||||
goto handle_flag;
|
||||
@ -1170,6 +1232,34 @@ nodhcp6:
|
||||
ipv6nd_expirera(ifp);
|
||||
}
|
||||
|
||||
/* Run RA's we ignored becuase they had no public addresses
|
||||
* This should only be called when DHCPv6 applies a public address */
|
||||
void
|
||||
ipv6nd_runignoredra(struct interface *ifp)
|
||||
{
|
||||
struct ra *rap;
|
||||
|
||||
TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
|
||||
if (rap->iface == ifp &&
|
||||
!rap->expired &&
|
||||
rap->no_public_warned)
|
||||
{
|
||||
rap->no_public_warned = 0;
|
||||
logger(rap->iface->ctx, LOG_INFO,
|
||||
"%s: applying ignored RA from %s",
|
||||
rap->iface->name, rap->sfrom);
|
||||
if (ifp->ctx->options & DHCPCD_TEST) {
|
||||
script_runreason(ifp, "TEST");
|
||||
continue;
|
||||
}
|
||||
if (ipv6nd_scriptrun(rap))
|
||||
return;
|
||||
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
|
||||
eloop_timeout_delete(ifp->ctx->eloop, NULL, rap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ipv6nd_hasra(const struct interface *ifp)
|
||||
{
|
||||
@ -1336,13 +1426,14 @@ ipv6nd_expirera(void *arg)
|
||||
struct ra *rap, *ran;
|
||||
struct ra_opt *rao, *raon;
|
||||
struct timespec now, lt, expire, next;
|
||||
int expired, valid;
|
||||
uint8_t expired, valid, validone;
|
||||
|
||||
ifp = arg;
|
||||
get_monotonic(&now);
|
||||
expired = 0;
|
||||
timespecclear(&next);
|
||||
|
||||
validone = 0;
|
||||
TAILQ_FOREACH_SAFE(rap, ifp->ctx->ipv6->ra_routers, next, ran) {
|
||||
if (rap->iface != ifp)
|
||||
continue;
|
||||
@ -1358,6 +1449,7 @@ ipv6nd_expirera(void *arg)
|
||||
"%s: %s: router expired",
|
||||
ifp->name, rap->sfrom);
|
||||
rap->expired = expired = 1;
|
||||
rap->lifetime = 0;
|
||||
}
|
||||
} else {
|
||||
valid = 1;
|
||||
@ -1410,6 +1502,8 @@ ipv6nd_expirera(void *arg)
|
||||
* as well punt it. */
|
||||
if (!valid && TAILQ_FIRST(&rap->addrs) == NULL)
|
||||
ipv6nd_free_ra(rap);
|
||||
else
|
||||
validone = 1;
|
||||
}
|
||||
|
||||
if (timespecisset(&next))
|
||||
@ -1419,13 +1513,17 @@ ipv6nd_expirera(void *arg)
|
||||
ipv6_buildroutes(ifp->ctx);
|
||||
script_runreason(ifp, "ROUTERADVERT");
|
||||
}
|
||||
|
||||
/* No valid routers? Kill any DHCPv6. */
|
||||
if (!validone)
|
||||
dhcp6_drop(ifp, "EXPIRE6");
|
||||
}
|
||||
|
||||
void
|
||||
ipv6nd_drop(struct interface *ifp)
|
||||
{
|
||||
struct ra *rap;
|
||||
int expired = 0;
|
||||
uint8_t expired = 0;
|
||||
TAILQ_HEAD(rahead, ra) rtrs;
|
||||
|
||||
if (ifp->ctx->ipv6 == NULL)
|
||||
|
15
external/bsd/dhcpcd/dist/ipv6nd.h
vendored
15
external/bsd/dhcpcd/dist/ipv6nd.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ipv6nd.h,v 1.10 2015/03/26 10:26:37 roy Exp $ */
|
||||
/* $NetBSD: ipv6nd.h,v 1.11 2015/05/02 15:18:37 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -58,7 +58,8 @@ struct ra {
|
||||
uint32_t mtu;
|
||||
struct ipv6_addrhead addrs;
|
||||
TAILQ_HEAD(, ra_opt) options;
|
||||
int expired;
|
||||
uint8_t expired;
|
||||
uint8_t no_public_warned;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(ra_head, ra);
|
||||
@ -74,6 +75,14 @@ struct rs_state {
|
||||
|
||||
#define MAX_RTR_SOLICITATION_DELAY 1 /* seconds */
|
||||
#define MAX_UNICAST_SOLICIT 3 /* 3 transmissions */
|
||||
#define RTR_SOLICITATION_INTERVAL 4 /* seconds */
|
||||
#define MAX_RTR_SOLICITATIONS 3 /* times */
|
||||
|
||||
/* On carrier up, expire known routers after RTR_CARRIER_EXPIRE seconds. */
|
||||
#define RTR_CARRIER_EXPIRE \
|
||||
(MAX_RTR_SOLICITATION_DELAY + \
|
||||
(MAX_RTR_SOLICITATIONS + 1) * \
|
||||
RTR_SOLICITATION_INTERVAL)
|
||||
|
||||
#define MAX_REACHABLE_TIME 3600000 /* milliseconds */
|
||||
#define REACHABLE_TIME 30000 /* milliseconds */
|
||||
@ -95,9 +104,11 @@ ssize_t ipv6nd_free(struct interface *);
|
||||
void ipv6nd_expirera(void *arg);
|
||||
int ipv6nd_hasra(const struct interface *);
|
||||
int ipv6nd_hasradhcp(const struct interface *);
|
||||
void ipv6nd_runignoredra(struct interface *);
|
||||
void ipv6nd_handleifa(struct dhcpcd_ctx *, int,
|
||||
const char *, const struct in6_addr *, int);
|
||||
int ipv6nd_dadcompleted(const struct interface *);
|
||||
void ipv6nd_expire(struct interface *, uint32_t);
|
||||
void ipv6nd_drop(struct interface *);
|
||||
void ipv6nd_neighbour(struct dhcpcd_ctx *, struct in6_addr *, int);
|
||||
#else
|
||||
|
12
external/bsd/dhcpcd/dist/script.c
vendored
12
external/bsd/dhcpcd/dist/script.c
vendored
@ -1,5 +1,5 @@
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: script.c,v 1.18 2015/03/26 10:26:37 roy Exp $");
|
||||
__RCSID("$NetBSD: script.c,v 1.19 2015/05/02 15:18:37 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
@ -89,14 +89,8 @@ if_printoptions(void)
|
||||
printf(" - %s\n", *p);
|
||||
}
|
||||
|
||||
#ifdef USE_SIGNALS
|
||||
#define U
|
||||
#else
|
||||
#define U __unused
|
||||
#endif
|
||||
static int
|
||||
exec_script(U const struct dhcpcd_ctx *ctx, char *const *argv, char *const *env)
|
||||
#undef U
|
||||
exec_script(const struct dhcpcd_ctx *ctx, char *const *argv, char *const *env)
|
||||
{
|
||||
pid_t pid;
|
||||
posix_spawnattr_t attr;
|
||||
@ -104,6 +98,8 @@ exec_script(U const struct dhcpcd_ctx *ctx, char *const *argv, char *const *env)
|
||||
#ifdef USE_SIGNALS
|
||||
short flags;
|
||||
sigset_t defsigs;
|
||||
#else
|
||||
UNUSED(ctx);
|
||||
#endif
|
||||
|
||||
/* posix_spawn is a safe way of executing another image
|
||||
|
Loading…
Reference in New Issue
Block a user