Sync
This commit is contained in:
parent
13da755153
commit
d5314d23aa
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: control.c,v 1.9 2015/05/16 23:31:32 roy Exp $");
|
||||
__RCSID("$NetBSD: control.c,v 1.10 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -46,6 +46,7 @@
|
|||
#include "dhcpcd.h"
|
||||
#include "control.h"
|
||||
#include "eloop.h"
|
||||
#include "if.h"
|
||||
|
||||
#ifndef SUN_LEN
|
||||
#define SUN_LEN(su) \
|
||||
|
@ -210,28 +211,8 @@ make_sock(struct sockaddr_un *sa, const char *ifname, int unpriv)
|
|||
{
|
||||
int fd;
|
||||
|
||||
#ifdef SOCK_CLOEXEC
|
||||
if ((fd = socket(AF_UNIX,
|
||||
SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) == -1)
|
||||
if ((fd = xsocket(AF_UNIX, SOCK_STREAM, 0, O_NONBLOCK|O_CLOEXEC)) == -1)
|
||||
return -1;
|
||||
#else
|
||||
int flags;
|
||||
|
||||
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||
return -1;
|
||||
if ((flags = fcntl(fd, F_GETFD, 0)) == -1 ||
|
||||
fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
if ((flags = fcntl(fd, F_GETFL, 0)) == -1 ||
|
||||
fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
memset(sa, 0, sizeof(*sa));
|
||||
sa->sun_family = AF_UNIX;
|
||||
if (unpriv)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: defs.h,v 1.19 2015/07/09 10:15:34 roy Exp $ */
|
||||
/* $NetBSD: defs.h,v 1.20 2015/08/21 10:39:00 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -30,7 +30,7 @@
|
|||
#define CONFIG_H
|
||||
|
||||
#define PACKAGE "dhcpcd"
|
||||
#define VERSION "6.9.1"
|
||||
#define VERSION "6.9.2"
|
||||
|
||||
#ifndef CONFIG
|
||||
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: dhcp.c,v 1.32 2015/07/09 10:15:34 roy Exp $");
|
||||
__RCSID("$NetBSD: dhcp.c,v 1.33 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -278,6 +278,23 @@ get_option_uint32(struct dhcpcd_ctx *ctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_option_uint16(struct dhcpcd_ctx *ctx,
|
||||
uint16_t *i, const struct dhcp_message *dhcp, uint8_t option)
|
||||
{
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
uint16_t d;
|
||||
|
||||
p = get_option(ctx, dhcp, option, &len);
|
||||
if (!p || len < (ssize_t)sizeof(d))
|
||||
return -1;
|
||||
memcpy(&d, p, sizeof(d));
|
||||
if (i)
|
||||
*i = ntohs(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_option_uint8(struct dhcpcd_ctx *ctx,
|
||||
uint8_t *i, const struct dhcp_message *dhcp, uint8_t option)
|
||||
|
@ -586,7 +603,7 @@ route_netmask(uint32_t ip_in)
|
|||
/* We need to obey routing options.
|
||||
* If we have a CSR then we only use that.
|
||||
* Otherwise we add static routes and then routers. */
|
||||
struct rt_head *
|
||||
static struct rt_head *
|
||||
get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp)
|
||||
{
|
||||
struct if_options *ifo = ifp->options;
|
||||
|
@ -692,6 +709,40 @@ get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp)
|
|||
return routes;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
dhcp_get_mtu(const struct interface *ifp)
|
||||
{
|
||||
const struct dhcp_message *dhcp;
|
||||
uint16_t mtu;
|
||||
|
||||
if ((dhcp = D_CSTATE(ifp)->new) == NULL ||
|
||||
has_option_mask(ifp->options->nomask, DHO_MTU) ||
|
||||
get_option_uint16(ifp->ctx, &mtu, dhcp, DHO_MTU) == -1)
|
||||
return 0;
|
||||
return mtu;
|
||||
}
|
||||
|
||||
/* Grab our routers from the DHCP message and apply any MTU value
|
||||
* the message contains */
|
||||
struct rt_head *
|
||||
dhcp_get_routes(struct interface *ifp)
|
||||
{
|
||||
struct rt_head *routes;
|
||||
uint16_t mtu;
|
||||
const struct dhcp_message *dhcp;
|
||||
|
||||
dhcp = D_CSTATE(ifp)->new;
|
||||
routes = get_option_routes(ifp, dhcp);
|
||||
if ((mtu = dhcp_get_mtu(ifp)) != 0) {
|
||||
struct rt *rt;
|
||||
|
||||
TAILQ_FOREACH(rt, routes, next) {
|
||||
rt->mtu = mtu;
|
||||
}
|
||||
}
|
||||
return routes;
|
||||
}
|
||||
|
||||
#define PUTADDR(_type, _val) \
|
||||
{ \
|
||||
*p++ = _type; \
|
||||
|
@ -852,21 +903,27 @@ make_message(struct dhcp_message **message,
|
|||
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;
|
||||
if ((mtu = if_getmtu(ifp)) == -1)
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: if_getmtu: %m", ifp->name);
|
||||
else if (mtu < MTU_MIN) {
|
||||
if (if_setmtu(ifp, MTU_MIN) == -1)
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: if_setmtu: %m", ifp->name);
|
||||
mtu = 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;
|
||||
if (mtu != -1) {
|
||||
*p++ = DHO_MAXMESSAGESIZE;
|
||||
*p++ = 2;
|
||||
sz = htons((uint16_t)mtu);
|
||||
memcpy(p, &sz, 2);
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (ifo->userclass[0]) {
|
||||
|
@ -1184,6 +1241,13 @@ read_lease(struct interface *ifp)
|
|||
else
|
||||
logger(ifp->ctx, LOG_DEBUG,
|
||||
"%s: accepted reconfigure key", ifp->name);
|
||||
} else if ((ifp->options->auth.options & DHCPCD_AUTH_SENDREQUIRE) ==
|
||||
DHCPCD_AUTH_SENDREQUIRE)
|
||||
{
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: authentication now required", ifp->name);
|
||||
free(dhcp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dhcp;
|
||||
|
@ -1483,19 +1547,8 @@ dhcp_openudp(struct interface *ifp)
|
|||
char *p;
|
||||
#endif
|
||||
|
||||
#ifdef SOCK_CLOEXEC
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP)) == -1)
|
||||
if ((s = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP, O_CLOEXEC)) == -1)
|
||||
return -1;
|
||||
#else
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
|
||||
return -1;
|
||||
if ((n = fcntl(s, F_GETFD, 0)) == -1 ||
|
||||
fcntl(s, F_SETFD, n | FD_CLOEXEC) == -1)
|
||||
{
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
n = 1;
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
|
||||
|
@ -2325,6 +2378,8 @@ dhcp_drop(struct interface *ifp, const char *reason)
|
|||
dhcp_auth_reset(&state->auth);
|
||||
dhcp_close(ifp);
|
||||
|
||||
free(state->offer);
|
||||
state->offer = NULL;
|
||||
free(state->old);
|
||||
state->old = state->new;
|
||||
state->new = NULL;
|
||||
|
@ -2481,12 +2536,15 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
|
|||
else
|
||||
logger(ifp->ctx, LOG_DEBUG,
|
||||
"%s: accepted reconfigure key", ifp->name);
|
||||
} else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
|
||||
log_dhcp1(LOG_ERR, "no authentication", ifp, dhcp, from, 0);
|
||||
return;
|
||||
} else if (ifo->auth.options & DHCPCD_AUTH_SEND)
|
||||
} else if (ifo->auth.options & DHCPCD_AUTH_SEND) {
|
||||
if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
|
||||
log_dhcp1(LOG_ERR, "no authentication",
|
||||
ifp, dhcp, from, 0);
|
||||
return;
|
||||
}
|
||||
log_dhcp1(LOG_WARNING, "no authentication",
|
||||
ifp, dhcp, from, 0);
|
||||
}
|
||||
|
||||
/* RFC 3203 */
|
||||
if (type == DHCP_FORCERENEW) {
|
||||
|
@ -2500,7 +2558,8 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
|
|||
if (auth == NULL) {
|
||||
log_dhcp(LOG_ERR, "unauthenticated Force Renew",
|
||||
ifp, dhcp, from);
|
||||
return;
|
||||
if (ifo->auth.options & DHCPCD_AUTH_REQUIRE)
|
||||
return;
|
||||
}
|
||||
if (state->state != DHS_BOUND && state->state != DHS_INFORM) {
|
||||
log_dhcp(LOG_DEBUG, "not bound, ignoring Force Renew",
|
||||
|
@ -3203,7 +3262,7 @@ 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 && ifo->options & DHCPCD_DHCP) {
|
||||
state->offer = read_lease(ifp);
|
||||
/* Check the saved lease matches the type we want */
|
||||
if (state->offer) {
|
||||
|
@ -3294,13 +3353,8 @@ dhcp_start1(void *arg)
|
|||
}
|
||||
|
||||
if (!(ifo->options & DHCPCD_DHCP)) {
|
||||
if (ifo->options & DHCPCD_IPV4LL) {
|
||||
if (state->offer && state->offer->cookie != 0) {
|
||||
free(state->offer);
|
||||
state->offer = NULL;
|
||||
}
|
||||
if (ifo->options & DHCPCD_IPV4LL)
|
||||
ipv4ll_start(ifp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3337,6 +3391,13 @@ dhcp_start(struct interface *ifp)
|
|||
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcp_start1, ifp);
|
||||
}
|
||||
|
||||
void
|
||||
dhcp_abort(struct interface *ifp)
|
||||
{
|
||||
|
||||
eloop_timeout_delete(ifp->ctx->eloop, dhcp_start1, ifp);
|
||||
}
|
||||
|
||||
void
|
||||
dhcp_handleifa(int cmd, struct interface *ifp,
|
||||
const struct in_addr *addr,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dhcp.h,v 1.10 2015/07/09 10:15:34 roy Exp $ */
|
||||
/* $NetBSD: dhcp.h,v 1.11 2015/08/21 10:39:00 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -247,8 +247,8 @@ int get_option_addr(struct dhcpcd_ctx *,struct in_addr *,
|
|||
const struct dhcp_message *, uint8_t);
|
||||
#define IS_BOOTP(i, m) ((m) != NULL && \
|
||||
get_option_uint8((i)->ctx, NULL, (m), DHO_MESSAGETYPE) == -1)
|
||||
struct rt_head *get_option_routes(struct interface *,
|
||||
const struct dhcp_message *);
|
||||
uint16_t dhcp_get_mtu(const struct interface *);
|
||||
struct rt_head *dhcp_get_routes(struct interface *);
|
||||
ssize_t dhcp_env(char **, const char *, const struct dhcp_message *,
|
||||
const struct interface *);
|
||||
|
||||
|
@ -266,7 +266,7 @@ void dhcp_handleifa(int, struct interface *,
|
|||
|
||||
void dhcp_drop(struct interface *, const char *);
|
||||
void dhcp_start(struct interface *);
|
||||
void dhcp_stop(struct interface *);
|
||||
void dhcp_abort(struct interface *);
|
||||
void dhcp_discover(void *);
|
||||
void dhcp_inform(struct interface *);
|
||||
void dhcp_bind(struct interface *);
|
||||
|
@ -277,6 +277,7 @@ int dhcp_dump(struct interface *);
|
|||
#else
|
||||
#define dhcp_drop(a, b) {}
|
||||
#define dhcp_start(a) {}
|
||||
#define dhcp_abort(a) {}
|
||||
#define dhcp_reboot(a, b) (b = b)
|
||||
#define dhcp_reboot_newopts(a, b) (b = b)
|
||||
#define dhcp_close(a) {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: dhcp6.c,v 1.14 2015/07/09 10:15:34 roy Exp $");
|
||||
__RCSID("$NetBSD: dhcp6.c,v 1.15 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -43,6 +43,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define ELOOP_QUEUE 4
|
||||
#include "config.h"
|
||||
|
@ -2247,7 +2248,9 @@ auth:
|
|||
else
|
||||
logger(ifp->ctx, LOG_DEBUG,
|
||||
"%s: accepted reconfigure key", ifp->name);
|
||||
} else if (ifp->options->auth.options & DHCPCD_AUTH_REQUIRE) {
|
||||
} else if ((ifp->options->auth.options & DHCPCD_AUTH_SENDREQUIRE) ==
|
||||
DHCPCD_AUTH_SENDREQUIRE)
|
||||
{
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: authentication now required", ifp->name);
|
||||
goto ex;
|
||||
|
@ -2753,13 +2756,16 @@ dhcp6_handledata(void *arg)
|
|||
else
|
||||
logger(ifp->ctx, LOG_DEBUG,
|
||||
"%s: accepted reconfigure key", ifp->name);
|
||||
} else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: no authentication from %s", ifp->name, ctx->sfrom);
|
||||
return;
|
||||
} else if (ifo->auth.options & DHCPCD_AUTH_SEND)
|
||||
} else if (ifo->auth.options & DHCPCD_AUTH_SEND) {
|
||||
if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: no authentication from %s",
|
||||
ifp->name, ctx->sfrom);
|
||||
return;
|
||||
}
|
||||
logger(ifp->ctx, LOG_WARNING,
|
||||
"%s: no authentication from %s", ifp->name, ctx->sfrom);
|
||||
}
|
||||
|
||||
op = dhcp6_get_op(r->type);
|
||||
switch(r->type) {
|
||||
|
@ -2863,7 +2869,8 @@ dhcp6_handledata(void *arg)
|
|||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: unauthenticated %s from %s",
|
||||
ifp->name, op, ctx->sfrom);
|
||||
return;
|
||||
if (ifo->auth.options & DHCPCD_AUTH_REQUIRE)
|
||||
return;
|
||||
}
|
||||
logger(ifp->ctx, LOG_INFO, "%s: %s from %s",
|
||||
ifp->name, op, ctx->sfrom);
|
||||
|
@ -3073,30 +3080,10 @@ dhcp6_open(struct dhcpcd_ctx *dctx)
|
|||
#endif
|
||||
|
||||
ctx = dctx->ipv6;
|
||||
#ifdef SOCK_CLOEXEC
|
||||
ctx->dhcp_fd = socket(PF_INET6,
|
||||
SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
|
||||
IPPROTO_UDP);
|
||||
ctx->dhcp_fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP,
|
||||
O_NONBLOCK|O_CLOEXEC);
|
||||
if (ctx->dhcp_fd == -1)
|
||||
return -1;
|
||||
#else
|
||||
if ((ctx->dhcp_fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1)
|
||||
return -1;
|
||||
if ((n = fcntl(ctx->dhcp_fd, F_GETFD, 0)) == -1 ||
|
||||
fcntl(ctx->dhcp_fd, F_SETFD, n | FD_CLOEXEC) == -1)
|
||||
{
|
||||
close(ctx->dhcp_fd);
|
||||
ctx->dhcp_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
if ((n = fcntl(ctx->dhcp_fd, F_GETFL, 0)) == -1 ||
|
||||
fcntl(ctx->dhcp_fd, F_SETFL, n | O_NONBLOCK) == -1)
|
||||
{
|
||||
close(ctx->dhcp_fd);
|
||||
ctx->dhcp_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
n = 1;
|
||||
if (setsockopt(ctx->dhcp_fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
|
@ -3143,8 +3130,8 @@ dhcp6_start1(void *arg)
|
|||
const struct dhcp_compat *dhc;
|
||||
|
||||
state = D6_STATE(ifp);
|
||||
/* Match any DHCPv4 opton to DHCPv6 options if given for easy
|
||||
* configuration */
|
||||
/* If no DHCPv6 options are configured,
|
||||
match configured DHCPv4 options to DHCPv6 equivalents. */
|
||||
for (i = 0; i < sizeof(ifo->requestmask6); i++) {
|
||||
if (ifo->requestmask6[i] != '\0')
|
||||
break;
|
||||
|
@ -3160,7 +3147,7 @@ dhcp6_start1(void *arg)
|
|||
add_option_mask(ifo->requestmask6, D6_OPTION_FQDN);
|
||||
}
|
||||
|
||||
/* Rapid commit won't wor with Prefix Delegation Exclusion */
|
||||
/* Rapid commit won't work with Prefix Delegation Exclusion */
|
||||
if (dhcp6_findselfsla(ifp, NULL))
|
||||
del_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT);
|
||||
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
# $NetBSD: 10-mtu,v 1.6 2014/11/07 20:51:03 roy Exp $
|
||||
|
||||
# Configure the MTU for the interface
|
||||
|
||||
mtu_dir="$state_dir/mtu"
|
||||
|
||||
set_mtu()
|
||||
{
|
||||
local mtu=$1
|
||||
|
||||
if [ -w /sys/class/net/$interface/mtu ]; then
|
||||
echo "$mtu" >/sys/class/net/$interface/mtu
|
||||
else
|
||||
ifconfig "$interface" mtu "$mtu"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$reason" = PREINIT -a -e "$mtu_dir/$interface" ]; then
|
||||
rm "$mtu_dir/$interface"
|
||||
elif [ -n "$new_interface_mtu" ] && $if_up; then
|
||||
# The smalled MTU dhcpcd can work with is 576
|
||||
if [ "$new_interface_mtu" -ge 576 ]; then
|
||||
if set_mtu "$new_interface_mtu"; then
|
||||
syslog info "MTU set to $new_interface_mtu"
|
||||
# Save the MTU so we can restore it later
|
||||
if [ ! -e "$mtu_dir/$interface" ]; then
|
||||
mkdir -p "$mtu_dir"
|
||||
echo "$ifmtu" > "$mtu_dir/$interface"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
elif [ -e "$mtu_dir/$interface" ]; then
|
||||
if $if_up || $if_down; then
|
||||
# No MTU in this state, so restore the prior MTU
|
||||
mtu=$(cat "$mtu_dir/$interface")
|
||||
syslog info "MTU restored to $mtu"
|
||||
set_mtu "$mtu"
|
||||
rm "$mtu_dir/$interface"
|
||||
fi
|
||||
fi
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: 20-resolv.conf,v 1.7 2015/05/16 23:31:32 roy Exp $
|
||||
# $NetBSD: 20-resolv.conf,v 1.8 2015/08/21 10:39:00 roy Exp $
|
||||
|
||||
# Generate /etc/resolv.conf
|
||||
# Support resolvconf(8) if available
|
||||
|
@ -119,14 +119,6 @@ add_resolv_conf()
|
|||
new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss"
|
||||
new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl"
|
||||
|
||||
# If we don't have any configuration, remove it
|
||||
if [ -z "$new_domain_name_servers" -a \
|
||||
-z "$new_domain_name" -a \
|
||||
-z "$new_domain_search" ]; then
|
||||
remove_resolv_conf
|
||||
return $?
|
||||
fi
|
||||
|
||||
# Derive a new domain from our various hostname options
|
||||
if [ -z "$new_domain_name" ]; then
|
||||
if [ "$new_dhcp6_fqdn" != "${new_dhcp6_fqdn#*.}" ]; then
|
||||
|
@ -138,6 +130,14 @@ add_resolv_conf()
|
|||
fi
|
||||
fi
|
||||
|
||||
# If we don't have any configuration, remove it
|
||||
if [ -z "$new_domain_name_servers" -a \
|
||||
-z "$new_domain_name" -a \
|
||||
-z "$new_domain_search" ]; then
|
||||
remove_resolv_conf
|
||||
return $?
|
||||
fi
|
||||
|
||||
if [ -n "$new_domain_name" ]; then
|
||||
set -- $new_domain_name
|
||||
if valid_domainname "$1"; then
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: 30-hostname,v 1.6 2014/11/07 20:51:03 roy Exp $
|
||||
# $NetBSD: 30-hostname,v 1.7 2015/08/21 10:39:00 roy Exp $
|
||||
|
||||
# Set the hostname from DHCP data if required
|
||||
|
||||
|
@ -148,6 +148,7 @@ set_hostname()
|
|||
case "$reason" in
|
||||
BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
|
||||
new_fqdn="$new_dhcp6_fqdn"
|
||||
old_fqdn="$old_dhcp6_fqdn"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh
|
||||
# $NetBSD: dhcpcd-run-hooks.in,v 1.10 2015/07/09 10:15:34 roy Exp $
|
||||
# $NetBSD: dhcpcd-run-hooks.in,v 1.11 2015/08/21 10:39:00 roy Exp $
|
||||
|
||||
# dhcpcd client configuration script
|
||||
|
||||
|
@ -120,8 +120,7 @@ remove_markers()
|
|||
comp_file()
|
||||
{
|
||||
|
||||
[ -e "$1" ] || return 1
|
||||
[ -e "$2" ] || return 1
|
||||
[ -e "$1" -a -e "$2" ] || return 1
|
||||
|
||||
if type cmp >/dev/null 2>&1; then
|
||||
cmp -s "$1" "$2"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: dhcpcd.8.in,v 1.43 2015/07/09 10:15:34 roy Exp $
|
||||
.\" $NetBSD: dhcpcd.8.in,v 1.44 2015/08/21 10:39:00 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 July 3, 2015
|
||||
.Dd August 21, 2015
|
||||
.Dt DHCPCD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -204,7 +204,7 @@ This script runs each script found in
|
|||
in a lexical order.
|
||||
The default installation supplies the scripts
|
||||
.Pa 01-test ,
|
||||
.Pa 10-mtu ,
|
||||
.Pa 02-dump ,
|
||||
.Pa 10-wpa_supplicant ,
|
||||
.Pa 15-timezone ,
|
||||
.Pa 20-resolv.conf
|
||||
|
@ -552,8 +552,8 @@ Matches full name, or prefixed with 2 numbers optionally ending with
|
|||
.Pp
|
||||
So to stop
|
||||
.Nm
|
||||
from touching your DNS or MTU settings you would do:-
|
||||
.D1 dhcpcd -C resolv.conf -C mtu eth0
|
||||
from touching your DNS settings you would do:-
|
||||
.D1 dhcpcd -C resolv.conf eth0
|
||||
.It Fl G , Fl Fl nogateway
|
||||
Don't set any default routes.
|
||||
.It Fl H , Fl Fl xidhwaddr
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: dhcpcd.c,v 1.26 2015/07/09 10:15:34 roy Exp $");
|
||||
__RCSID("$NetBSD: dhcpcd.c,v 1.27 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -575,10 +575,6 @@ configure_interface1(struct interface *ifp)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If we are not sending an authentication option, don't require it */
|
||||
if (!(ifo->auth.options & DHCPCD_AUTH_SEND))
|
||||
ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -703,6 +699,7 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags,
|
|||
script_runreason(ifp, "NOCARRIER");
|
||||
#ifdef NOCARRIER_PRESERVE_IP
|
||||
arp_close(ifp);
|
||||
dhcp_abort(ifp);
|
||||
if_sortinterfaces(ctx);
|
||||
ipv4_preferanother(ifp);
|
||||
ipv6nd_expire(ifp, 0);
|
||||
|
@ -907,7 +904,9 @@ dhcpcd_prestartinterface(void *arg)
|
|||
struct interface *ifp = arg;
|
||||
|
||||
pre_start(ifp);
|
||||
if (if_up(ifp) == -1)
|
||||
if ((!(ifp->ctx->options & DHCPCD_MASTER) ||
|
||||
ifp->options->options & DHCPCD_IF_UP) &&
|
||||
if_up(ifp) == -1)
|
||||
logger(ifp->ctx, LOG_ERR, "%s: if_up: %m", ifp->name);
|
||||
|
||||
if (ifp->options->options & DHCPCD_LINK &&
|
||||
|
@ -1395,6 +1394,14 @@ main(int argc, char **argv)
|
|||
ifo = NULL;
|
||||
ctx.cffile = CONFIG;
|
||||
ctx.pid_fd = ctx.control_fd = ctx.control_unpriv_fd = ctx.link_fd = -1;
|
||||
ctx.pf_inet_fd = -1;
|
||||
#if defined(INET6) && defined(BSD)
|
||||
ctx.pf_inet6_fd = -1;
|
||||
#endif
|
||||
#ifdef IFLR_ACTIVE
|
||||
ctx.pf_link_fd = -1;
|
||||
#endif
|
||||
|
||||
TAILQ_INIT(&ctx.control_fds);
|
||||
#ifdef PLUGIN_DEV
|
||||
ctx.dev_fd = -1;
|
||||
|
@ -1760,17 +1767,12 @@ main(int argc, char **argv)
|
|||
if (ctx.ifc == 1 && !(ctx.options & DHCPCD_BACKGROUND))
|
||||
ctx.options |= DHCPCD_WAITIP;
|
||||
|
||||
/* RTM_NEWADDR goes through the link socket as well which we
|
||||
* need for IPv6 DAD, so we check for DHCPCD_LINK in
|
||||
* dhcpcd_handlecarrier instead.
|
||||
* We also need to open this before checking for interfaces below
|
||||
* so that we pickup any new addresses during the discover phase. */
|
||||
ctx.link_fd = if_openlinksocket();
|
||||
if (ctx.link_fd == -1)
|
||||
logger(&ctx, LOG_ERR, "open_link_socket: %m");
|
||||
else
|
||||
eloop_event_add(ctx.eloop, ctx.link_fd,
|
||||
handle_link, &ctx, NULL, NULL);
|
||||
/* Open our persistent sockets. */
|
||||
if (if_opensockets(&ctx) == -1) {
|
||||
logger(&ctx, LOG_ERR, "if_opensockets: %m");
|
||||
goto exit_failure;
|
||||
}
|
||||
eloop_event_add(ctx.eloop, ctx.link_fd, handle_link, &ctx, NULL, NULL);
|
||||
|
||||
/* Start any dev listening plugin which may want to
|
||||
* change the interface name provided by the kernel */
|
||||
|
@ -1875,6 +1877,17 @@ exit1:
|
|||
eloop_event_delete(ctx.eloop, ctx.link_fd);
|
||||
close(ctx.link_fd);
|
||||
}
|
||||
if (ctx.pf_inet_fd != -1)
|
||||
close(ctx.pf_inet_fd);
|
||||
#if defined(INET6) && defined(BSD)
|
||||
if (ctx.pf_inet6_fd != -1)
|
||||
close(ctx.pf_inet6_fd);
|
||||
#endif
|
||||
#ifdef IFLR_ACTIVE
|
||||
if (ctx.pf_link_fd != -1)
|
||||
close(ctx.pf_link_fd);
|
||||
#endif
|
||||
|
||||
|
||||
free_options(ifo);
|
||||
free_globals(&ctx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: dhcpcd.conf,v 1.16 2015/03/26 10:26:37 roy Exp $
|
||||
# $NetBSD: dhcpcd.conf,v 1.17 2015/08/21 10:39:00 roy Exp $
|
||||
|
||||
# A sample configuration for dhcpcd.
|
||||
# See dhcpcd.conf(5) for details.
|
||||
|
@ -30,9 +30,8 @@ option domain_name_servers, domain_name, domain_search, host_name
|
|||
option classless_static_routes
|
||||
# Most distributions have NTP support.
|
||||
option ntp_servers
|
||||
# Respect the network MTU.
|
||||
# Some interface drivers reset when changing the MTU so disabled by default.
|
||||
#option interface_mtu
|
||||
# Respect the network MTU. This is applied to DHCP routes.
|
||||
option interface_mtu
|
||||
|
||||
# A ServerID is required by RFC2131.
|
||||
require dhcp_server_identifier
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: dhcpcd.conf.5.in,v 1.22 2015/07/09 10:15:34 roy Exp $
|
||||
.\" $NetBSD: dhcpcd.conf.5.in,v 1.23 2015/08/21 10:39:00 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 July 9, 2015
|
||||
.Dd August 1, 2015
|
||||
.Dt DHCPCD.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -408,6 +408,7 @@ Don't send any ARP requests.
|
|||
This also disables IPv4LL.
|
||||
.It Ic noauthrequired
|
||||
Don't require authentication even though we requested it.
|
||||
Also allows FORCERENEW and RECONFIGURE messages without authentication.
|
||||
.It Ic nodelay
|
||||
Don't delay for an initial randomised time when starting protocols.
|
||||
.It Ic nodev
|
||||
|
@ -431,8 +432,8 @@ Matches full name, or prefixed with 2 numbers optionally ending with
|
|||
.Pp
|
||||
So to stop
|
||||
.Nm dhcpcd
|
||||
from touching your DNS or MTU settings you would do:-
|
||||
.D1 nohook resolv.conf, mtu
|
||||
from touching your DNS settings or starting wpa_supplicant you would do:-
|
||||
.D1 nohook resolv.conf, wpa_supplicant
|
||||
.It Ic noipv4
|
||||
Don't attempt to configure an IPv4 address.
|
||||
.It Ic noipv4ll
|
||||
|
@ -448,6 +449,14 @@ Disable solicitation and receipt of IPv6 Router Advertisements.
|
|||
.It Ic nolink
|
||||
Don't receive link messages about carrier status.
|
||||
You should only set this for buggy interface drivers.
|
||||
.It Ic noup
|
||||
Don't bring the interface up when in master mode.
|
||||
If
|
||||
.Nm
|
||||
cannot determine the carrier state,
|
||||
.Nm
|
||||
will enter a tight polling loop until the interface is marked up and running
|
||||
or a valid carrier state is reported.
|
||||
.It Ic option Ar option
|
||||
Requests the
|
||||
.Ar option
|
||||
|
@ -464,7 +473,8 @@ lines.
|
|||
Prepend dhcp6_ to
|
||||
.Ar option
|
||||
to request a DHCPv6 option.
|
||||
DHCPv4 options are mapped to DHCPv6 where applicable.
|
||||
If no DHCPv6 options are configured,
|
||||
then DHCPv4 options are mapped to equivalent DHCPv6 options.
|
||||
.Pp
|
||||
Prepend nd_ to
|
||||
.Ar option
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dhcpcd.h,v 1.12 2015/07/09 10:15:34 roy Exp $ */
|
||||
/* $NetBSD: dhcpcd.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -64,6 +64,11 @@
|
|||
* dhcpcd can poll it for the relevant flags periodically */
|
||||
#define IF_POLL_UP 100 /* milliseconds */
|
||||
|
||||
#ifdef __QNX__
|
||||
/* QNX carries defines for, but does not actually support PF_LINK */
|
||||
#undef IFLR_ACTIVE
|
||||
#endif
|
||||
|
||||
struct interface {
|
||||
struct dhcpcd_ctx *ctx;
|
||||
TAILQ_ENTRY(interface) next;
|
||||
|
@ -107,9 +112,17 @@ struct dhcpcd_ctx {
|
|||
char **ifcv; /* configured interfaces */
|
||||
unsigned char *duid;
|
||||
size_t duid_len;
|
||||
int link_fd;
|
||||
struct if_head *ifaces;
|
||||
|
||||
int pf_inet_fd;
|
||||
#if defined(INET6) && defined(BSD)
|
||||
int pf_inet6_fd;
|
||||
#endif
|
||||
#ifdef IFLR_ACTIVE
|
||||
int pf_link_fd;
|
||||
#endif
|
||||
int link_fd;
|
||||
|
||||
#ifdef USE_SIGNALS
|
||||
sigset_t sigset;
|
||||
#endif
|
||||
|
@ -125,6 +138,8 @@ struct dhcpcd_ctx {
|
|||
struct dhcp_opt *vivso;
|
||||
size_t vivso_len;
|
||||
|
||||
char *randomstate; /* original state */
|
||||
|
||||
#ifdef INET
|
||||
struct dhcp_opt *dhcp_opts;
|
||||
size_t dhcp_opts_len;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: if-bsd.c,v 1.22 2015/07/09 10:15:34 roy Exp $");
|
||||
__RCSID("$NetBSD: if-bsd.c,v 1.23 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -84,6 +84,7 @@
|
|||
#include "if.h"
|
||||
#include "if-options.h"
|
||||
#include "ipv4.h"
|
||||
#include "ipv4ll.h"
|
||||
#include "ipv6.h"
|
||||
#include "ipv6nd.h"
|
||||
|
||||
|
@ -127,27 +128,7 @@ int
|
|||
if_openlinksocket(void)
|
||||
{
|
||||
|
||||
#ifdef SOCK_CLOEXEC
|
||||
return socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
|
||||
#else
|
||||
int s, flags;
|
||||
|
||||
if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
|
||||
return -1;
|
||||
if ((flags = fcntl(s, F_GETFD, 0)) == -1 ||
|
||||
fcntl(s, F_SETFD, flags | FD_CLOEXEC) == -1)
|
||||
{
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
if ((flags = fcntl(s, F_GETFL, 0)) == -1 ||
|
||||
fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1)
|
||||
{
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
return s;
|
||||
#endif
|
||||
return xsocket(PF_ROUTE, SOCK_RAW, 0, O_NONBLOCK|O_CLOEXEC);
|
||||
}
|
||||
|
||||
#if defined(INET) || defined(INET6)
|
||||
|
@ -164,9 +145,9 @@ if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp)
|
|||
#endif
|
||||
|
||||
static int
|
||||
if_getssid1(const char *ifname, uint8_t *ssid)
|
||||
if_getssid1(int s, const char *ifname, uint8_t *ssid)
|
||||
{
|
||||
int s, retval = -1;
|
||||
int retval = -1;
|
||||
#if defined(SIOCG80211NWID)
|
||||
struct ifreq ifr;
|
||||
struct ieee80211_nwid nwid;
|
||||
|
@ -175,9 +156,6 @@ if_getssid1(const char *ifname, uint8_t *ssid)
|
|||
char nwid[IEEE80211_NWID_LEN + 1];
|
||||
#endif
|
||||
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
|
||||
#if defined(SIOCG80211NWID) /* NetBSD */
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
|
@ -216,7 +194,6 @@ if_getssid1(const char *ifname, uint8_t *ssid)
|
|||
}
|
||||
#endif
|
||||
|
||||
close(s);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -225,7 +202,7 @@ if_getssid(struct interface *ifp)
|
|||
{
|
||||
int r;
|
||||
|
||||
r = if_getssid1(ifp->name, ifp->ssid);
|
||||
r = if_getssid1(ifp->ctx->pf_inet_fd, ifp->name, ifp->ssid);
|
||||
if (r != -1)
|
||||
ifp->ssid_len = (unsigned int)r;
|
||||
return r;
|
||||
|
@ -239,23 +216,20 @@ if_getssid(struct interface *ifp)
|
|||
* returning the SSID gives an error.
|
||||
*/
|
||||
int
|
||||
if_vimaster(const char *ifname)
|
||||
if_vimaster(const struct dhcpcd_ctx *ctx, const char *ifname)
|
||||
{
|
||||
int s, r;
|
||||
int r;
|
||||
struct ifmediareq ifmr;
|
||||
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
memset(&ifmr, 0, sizeof(ifmr));
|
||||
strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
|
||||
r = ioctl(s, SIOCGIFMEDIA, &ifmr);
|
||||
close(s);
|
||||
r = ioctl(ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr);
|
||||
if (r == -1)
|
||||
return -1;
|
||||
if (ifmr.ifm_status & IFM_AVALID &&
|
||||
IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211)
|
||||
{
|
||||
if (if_getssid1(ifname, NULL) == -1)
|
||||
if (if_getssid1(ctx->pf_inet_fd, ifname, NULL) == -1)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -450,12 +424,9 @@ if_address(const struct interface *ifp, const struct in_addr *address,
|
|||
const struct in_addr *netmask, const struct in_addr *broadcast,
|
||||
int action)
|
||||
{
|
||||
int s, r;
|
||||
int r;
|
||||
struct in_aliasreq ifra;
|
||||
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
|
||||
memset(&ifra, 0, sizeof(ifra));
|
||||
strlcpy(ifra.ifra_name, ifp->name, sizeof(ifra.ifra_name));
|
||||
|
||||
|
@ -470,9 +441,8 @@ if_address(const struct interface *ifp, const struct in_addr *address,
|
|||
ADDADDR(&ifra.ifra_broadaddr, broadcast);
|
||||
#undef ADDADDR
|
||||
|
||||
r = ioctl(s,
|
||||
r = ioctl(ifp->ctx->pf_inet_fd,
|
||||
action < 0 ? SIOCDIFADDR : SIOCAIFADDR, &ifra);
|
||||
close(s);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -503,6 +473,7 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm)
|
|||
|
||||
get_addrs(rtm->rtm_addrs, cp, rti_info);
|
||||
memset(rt, 0, sizeof(*rt));
|
||||
rt->flags = (unsigned int)rtm->rtm_flags;
|
||||
COPYOUT(rt->dest, rti_info[RTAX_DST]);
|
||||
if (rtm->rtm_addrs & RTA_NETMASK)
|
||||
COPYOUT(rt->net, rti_info[RTAX_NETMASK]);
|
||||
|
@ -511,6 +482,9 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm)
|
|||
COPYOUT(rt->gate, rti_info[RTAX_GATEWAY]);
|
||||
COPYOUT(rt->src, rti_info[RTAX_IFA]);
|
||||
|
||||
if (rtm->rtm_inits & RTV_MTU)
|
||||
rt->mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu;
|
||||
|
||||
if (rtm->rtm_index)
|
||||
rt->iface = if_findindex(ctx->ifaces, rtm->rtm_index);
|
||||
else if (rtm->rtm_addrs & RTA_IFP) {
|
||||
|
@ -519,6 +493,7 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm)
|
|||
sdl = (struct sockaddr_dl *)(void *)rti_info[RTAX_IFP];
|
||||
rt->iface = if_findsdl(ctx, sdl);
|
||||
}
|
||||
|
||||
/* If we don't have an interface and it's a host route, it maybe
|
||||
* to a local ip via the loopback interface. */
|
||||
if (rt->iface == NULL &&
|
||||
|
@ -537,6 +512,7 @@ int
|
|||
if_route(unsigned char cmd, const struct rt *rt)
|
||||
{
|
||||
const struct dhcp_state *state;
|
||||
const struct ipv4ll_state *istate;
|
||||
union sockunion {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sin;
|
||||
|
@ -549,10 +525,6 @@ if_route(unsigned char cmd, const struct rt *rt)
|
|||
} rtm;
|
||||
char *bp = rtm.buffer;
|
||||
size_t l;
|
||||
int s, retval;
|
||||
|
||||
if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
|
||||
return -1;
|
||||
|
||||
#define ADDSU { \
|
||||
l = RT_ROUNDUP(su.sa.sa_len); \
|
||||
|
@ -563,14 +535,18 @@ if_route(unsigned char cmd, const struct rt *rt)
|
|||
memset(&su, 0, sizeof(su)); \
|
||||
su.sin.sin_family = AF_INET; \
|
||||
su.sin.sin_len = sizeof(su.sin); \
|
||||
(&su.sin)->sin_addr = *addr; \
|
||||
(&su.sin)->sin_addr = *(addr); \
|
||||
ADDSU; \
|
||||
}
|
||||
|
||||
if (cmd != RTM_DELETE)
|
||||
if (cmd != RTM_DELETE) {
|
||||
state = D_CSTATE(rt->iface);
|
||||
else /* appease GCC */
|
||||
istate = IPV4LL_CSTATE(rt->iface);
|
||||
} else {
|
||||
/* appease GCC */
|
||||
state = NULL;
|
||||
istate = NULL;
|
||||
}
|
||||
memset(&rtm, 0, sizeof(rtm));
|
||||
rtm.hdr.rtm_version = RTM_VERSION;
|
||||
rtm.hdr.rtm_seq = 1;
|
||||
|
@ -587,9 +563,14 @@ if_route(unsigned char cmd, const struct rt *rt)
|
|||
if (cmd != RTM_DELETE) {
|
||||
rtm.hdr.rtm_addrs |= RTA_IFA | RTA_IFP;
|
||||
/* None interface subnet routes are static. */
|
||||
if (rt->gate.s_addr != INADDR_ANY ||
|
||||
if ((rt->gate.s_addr != INADDR_ANY ||
|
||||
rt->net.s_addr != state->net.s_addr ||
|
||||
rt->dest.s_addr != (state->addr.s_addr & state->net.s_addr))
|
||||
rt->dest.s_addr !=
|
||||
(state->addr.s_addr & state->net.s_addr)) &&
|
||||
(istate == NULL ||
|
||||
rt->dest.s_addr !=
|
||||
(istate->addr.s_addr & inaddr_llmask.s_addr) ||
|
||||
rt->net.s_addr != inaddr_llmask.s_addr))
|
||||
rtm.hdr.rtm_flags |= RTF_STATIC;
|
||||
else {
|
||||
#ifdef RTF_CLONING
|
||||
|
@ -660,16 +641,20 @@ if_route(unsigned char cmd, const struct rt *rt)
|
|||
}
|
||||
|
||||
if (rtm.hdr.rtm_addrs & RTA_IFA)
|
||||
ADDADDR(&state->addr);
|
||||
ADDADDR(istate == NULL ? &state->addr : &istate->addr);
|
||||
|
||||
if (rt->mtu) {
|
||||
rtm.hdr.rtm_inits |= RTV_MTU;
|
||||
rtm.hdr.rtm_rmx.rmx_mtu = rt->mtu;
|
||||
}
|
||||
}
|
||||
|
||||
#undef ADDADDR
|
||||
#undef ADDSU
|
||||
|
||||
rtm.hdr.rtm_msglen = (unsigned short)(bp - (char *)&rtm);
|
||||
retval = write(s, &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0;
|
||||
close(s);
|
||||
return retval;
|
||||
return write(rt->iface->ctx->link_fd,
|
||||
&rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -713,23 +698,17 @@ if_initrt(struct interface *ifp)
|
|||
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;
|
||||
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(ifp->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1)
|
||||
return -1;
|
||||
return ifr.ifr_addrflags;
|
||||
}
|
||||
#else
|
||||
int
|
||||
|
@ -775,17 +754,13 @@ ifa_scope(struct sockaddr_in6 *sin, unsigned int ifindex)
|
|||
#endif
|
||||
|
||||
int
|
||||
if_address6(const struct ipv6_addr *a, int action)
|
||||
if_address6(const struct ipv6_addr *ia, int action)
|
||||
{
|
||||
int s, r;
|
||||
struct in6_aliasreq ifa;
|
||||
struct in6_addr mask;
|
||||
|
||||
if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
|
||||
memset(&ifa, 0, sizeof(ifa));
|
||||
strlcpy(ifa.ifra_name, a->iface->name, sizeof(ifa.ifra_name));
|
||||
strlcpy(ifa.ifra_name, ia->iface->name, sizeof(ifa.ifra_name));
|
||||
/*
|
||||
* We should not set IN6_IFF_TENTATIVE as the kernel should be
|
||||
* able to work out if it's a new address or not.
|
||||
|
@ -795,31 +770,30 @@ if_address6(const struct ipv6_addr *a, int action)
|
|||
* either.
|
||||
*/
|
||||
#if 0
|
||||
if (a->autoconf)
|
||||
if (ia->autoconf)
|
||||
ifa.ifra_flags |= IN6_IFF_AUTOCONF;
|
||||
#endif
|
||||
#ifdef IPV6_MANGETEMPADDR
|
||||
if (a->flags & IPV6_AF_TEMPORARY)
|
||||
if (ia->flags & IPV6_AF_TEMPORARY)
|
||||
ifa.ifra_flags |= IN6_IFF_TEMPORARY;
|
||||
#endif
|
||||
|
||||
#define ADDADDR(v, addr) { \
|
||||
(v)->sin6_family = AF_INET6; \
|
||||
(v)->sin6_len = sizeof(*v); \
|
||||
(v)->sin6_addr = *addr; \
|
||||
(v)->sin6_addr = *(addr); \
|
||||
}
|
||||
|
||||
ADDADDR(&ifa.ifra_addr, &a->addr);
|
||||
ifa_scope(&ifa.ifra_addr, a->iface->index);
|
||||
ipv6_mask(&mask, a->prefix_len);
|
||||
ADDADDR(&ifa.ifra_addr, &ia->addr);
|
||||
ifa_scope(&ifa.ifra_addr, ia->iface->index);
|
||||
ipv6_mask(&mask, ia->prefix_len);
|
||||
ADDADDR(&ifa.ifra_prefixmask, &mask);
|
||||
ifa.ifra_lifetime.ia6t_vltime = a->prefix_vltime;
|
||||
ifa.ifra_lifetime.ia6t_pltime = a->prefix_pltime;
|
||||
ifa.ifra_lifetime.ia6t_vltime = ia->prefix_vltime;
|
||||
ifa.ifra_lifetime.ia6t_pltime = ia->prefix_pltime;
|
||||
#undef ADDADDR
|
||||
|
||||
r = ioctl(s, action < 0 ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa);
|
||||
close(s);
|
||||
return r;
|
||||
return ioctl(ia->iface->ctx->pf_inet6_fd,
|
||||
action < 0 ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa);
|
||||
}
|
||||
|
||||
|
||||
|
@ -900,6 +874,9 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struct rt6 *rt, struct rt_msghdr *rtm)
|
|||
ipv6_mask(&rt->net, 128);
|
||||
COPYOUT6(rt->gate, rti_info[RTAX_GATEWAY]);
|
||||
|
||||
if (rtm->rtm_inits & RTV_MTU)
|
||||
rt->mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu;
|
||||
|
||||
if (rtm->rtm_index)
|
||||
rt->iface = if_findindex(ctx->ifaces, rtm->rtm_index);
|
||||
else if (rtm->rtm_addrs & RTA_IFP) {
|
||||
|
@ -937,10 +914,6 @@ if_route6(unsigned char cmd, const struct rt6 *rt)
|
|||
} rtm;
|
||||
char *bp = rtm.buffer;
|
||||
size_t l;
|
||||
int s, retval;
|
||||
|
||||
if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
|
||||
return -1;
|
||||
|
||||
#define ADDSU { \
|
||||
l = RT_ROUNDUP(su.sa.sa_len); \
|
||||
|
@ -1025,9 +998,8 @@ if_route6(unsigned char cmd, const struct rt6 *rt)
|
|||
#undef ADDSU
|
||||
|
||||
rtm.hdr.rtm_msglen = (unsigned short)(bp - (char *)&rtm);
|
||||
retval = write(s, &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0;
|
||||
close(s);
|
||||
return retval;
|
||||
return write(rt->iface->ctx->link_fd,
|
||||
&rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1070,67 +1042,56 @@ if_initrt6(struct interface *ifp)
|
|||
int
|
||||
if_addrflags6(const struct in6_addr *addr, const struct interface *ifp)
|
||||
{
|
||||
int s, flags;
|
||||
int flags;
|
||||
struct in6_ifreq ifr6;
|
||||
|
||||
s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
flags = -1;
|
||||
if (s != -1) {
|
||||
memset(&ifr6, 0, sizeof(ifr6));
|
||||
strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name));
|
||||
ifr6.ifr_addr.sin6_family = AF_INET6;
|
||||
ifr6.ifr_addr.sin6_addr = *addr;
|
||||
ifa_scope(&ifr6.ifr_addr, ifp->index);
|
||||
if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) != -1)
|
||||
flags = ifr6.ifr_ifru.ifru_flags6;
|
||||
close(s);
|
||||
}
|
||||
memset(&ifr6, 0, sizeof(ifr6));
|
||||
strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name));
|
||||
ifr6.ifr_addr.sin6_family = AF_INET6;
|
||||
ifr6.ifr_addr.sin6_addr = *addr;
|
||||
ifa_scope(&ifr6.ifr_addr, ifp->index);
|
||||
if (ioctl(ifp->ctx->pf_inet6_fd, SIOCGIFAFLAG_IN6, &ifr6) != -1)
|
||||
flags = ifr6.ifr_ifru.ifru_flags6;
|
||||
else
|
||||
flags = -1;
|
||||
return flags;
|
||||
}
|
||||
|
||||
int
|
||||
if_getlifetime6(struct ipv6_addr *ia)
|
||||
{
|
||||
int s, r;
|
||||
int r;
|
||||
struct in6_ifreq ifr6;
|
||||
time_t t;
|
||||
struct in6_addrlifetime *lifetime;
|
||||
|
||||
s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
r = -1;
|
||||
if (s != -1) {
|
||||
memset(&ifr6, 0, sizeof(ifr6));
|
||||
strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name));
|
||||
ifr6.ifr_addr.sin6_family = AF_INET6;
|
||||
ifr6.ifr_addr.sin6_addr = ia->addr;
|
||||
ifa_scope(&ifr6.ifr_addr, ia->iface->index);
|
||||
if (ioctl(s, SIOCGIFALIFETIME_IN6, &ifr6) != -1) {
|
||||
time_t t;
|
||||
struct in6_addrlifetime *lifetime;
|
||||
memset(&ifr6, 0, sizeof(ifr6));
|
||||
strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name));
|
||||
ifr6.ifr_addr.sin6_family = AF_INET6;
|
||||
ifr6.ifr_addr.sin6_addr = ia->addr;
|
||||
ifa_scope(&ifr6.ifr_addr, ia->iface->index);
|
||||
if (ioctl(ia->iface->ctx->pf_inet6_fd,
|
||||
SIOCGIFALIFETIME_IN6, &ifr6) == -1)
|
||||
return -1;
|
||||
|
||||
t = time(NULL);
|
||||
lifetime = &ifr6.ifr_ifru.ifru_lifetime;
|
||||
t = time(NULL);
|
||||
lifetime = &ifr6.ifr_ifru.ifru_lifetime;
|
||||
|
||||
if (lifetime->ia6t_preferred)
|
||||
ia->prefix_pltime =
|
||||
(uint32_t)(lifetime->ia6t_preferred -
|
||||
MIN(t, lifetime->ia6t_preferred));
|
||||
else
|
||||
ia->prefix_pltime = ND6_INFINITE_LIFETIME;
|
||||
if (lifetime->ia6t_expire) {
|
||||
ia->prefix_vltime =
|
||||
(uint32_t)(lifetime->ia6t_expire -
|
||||
MIN(t, lifetime->ia6t_expire));
|
||||
/* Calculate the created time */
|
||||
clock_gettime(CLOCK_MONOTONIC, &ia->created);
|
||||
ia->created.tv_sec -=
|
||||
lifetime->ia6t_vltime - ia->prefix_vltime;
|
||||
} else
|
||||
ia->prefix_vltime = ND6_INFINITE_LIFETIME;
|
||||
|
||||
r = 0;
|
||||
}
|
||||
close(s);
|
||||
}
|
||||
return r;
|
||||
if (lifetime->ia6t_preferred)
|
||||
ia->prefix_pltime = (uint32_t)(lifetime->ia6t_preferred -
|
||||
MIN(t, lifetime->ia6t_preferred));
|
||||
else
|
||||
ia->prefix_pltime = ND6_INFINITE_LIFETIME;
|
||||
if (lifetime->ia6t_expire) {
|
||||
ia->prefix_vltime = (uint32_t)(lifetime->ia6t_expire -
|
||||
MIN(t, lifetime->ia6t_expire));
|
||||
/* Calculate the created time */
|
||||
clock_gettime(CLOCK_MONOTONIC, &ia->created);
|
||||
ia->created.tv_sec -= lifetime->ia6t_vltime - ia->prefix_vltime;
|
||||
} else
|
||||
ia->prefix_vltime = ND6_INFINITE_LIFETIME;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1670,12 +1631,7 @@ _if_checkipv6(int s, struct dhcpcd_ctx *ctx,
|
|||
int
|
||||
if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
|
||||
{
|
||||
int s, r;
|
||||
|
||||
if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
r = _if_checkipv6(s, ctx, ifp, own);
|
||||
close(s);
|
||||
return r;
|
||||
return _if_checkipv6(ctx->pf_inet6_fd, ctx, ifp, own);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: if-options.c,v 1.25 2015/07/09 10:15:34 roy Exp $");
|
||||
__RCSID("$NetBSD: if-options.c,v 1.26 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -97,7 +97,7 @@
|
|||
#define O_CONTROLGRP O_BASE + 34
|
||||
#define O_SLAAC O_BASE + 35
|
||||
#define O_GATEWAY O_BASE + 36
|
||||
// unassigned O_BASE + 37
|
||||
#define O_NOUP O_BASE + 37
|
||||
#define O_IPV6RA_AUTOCONF O_BASE + 38
|
||||
#define O_IPV6RA_NOAUTOCONF O_BASE + 39
|
||||
#define O_REJECT O_BASE + 40
|
||||
|
@ -199,6 +199,7 @@ const struct option cf_options[] = {
|
|||
{"reject", required_argument, NULL, O_REJECT},
|
||||
{"bootp", no_argument, NULL, O_BOOTP},
|
||||
{"nodelay", no_argument, NULL, O_NODELAY},
|
||||
{"noup", no_argument, NULL, O_NOUP},
|
||||
{NULL, 0, NULL, '\0'}
|
||||
};
|
||||
|
||||
|
@ -2006,6 +2007,9 @@ err_sla:
|
|||
case O_GATEWAY:
|
||||
ifo->options |= DHCPCD_GATEWAY;
|
||||
break;
|
||||
case O_NOUP:
|
||||
ifo->options &= ~DHCPCD_IF_UP;
|
||||
break;
|
||||
case O_SLAAC:
|
||||
if (strcmp(arg, "private") == 0 ||
|
||||
strcmp(arg, "stableprivate") == 0 ||
|
||||
|
@ -2120,6 +2124,7 @@ read_config(struct dhcpcd_ctx *ctx,
|
|||
return NULL;
|
||||
}
|
||||
ifo->options |= DHCPCD_DAEMONISE | DHCPCD_LINK | DHCPCD_INITIAL_DELAY;
|
||||
ifo->options |= DHCPCD_IF_UP;
|
||||
#ifdef PLUGIN_DEV
|
||||
ifo->options |= DHCPCD_DEV;
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if-options.h,v 1.12 2015/07/09 10:15:34 roy Exp $ */
|
||||
/* $NetBSD: if-options.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -106,7 +106,7 @@
|
|||
#define DHCPCD_IAID (1ULL << 48)
|
||||
#define DHCPCD_DHCP (1ULL << 49)
|
||||
#define DHCPCD_DHCP6 (1ULL << 50)
|
||||
// unassigned (1ULL << 51)
|
||||
#define DHCPCD_IF_UP (1ULL << 51)
|
||||
// unassigned (1ULL << 52)
|
||||
// unassinged (1ULL << 53)
|
||||
#define DHCPCD_IPV6RA_AUTOCONF (1ULL << 54)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: if.c,v 1.14 2015/07/09 10:15:34 roy Exp $");
|
||||
__RCSID("$NetBSD: if.c,v 1.15 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -61,6 +61,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
|
@ -73,11 +74,6 @@
|
|||
#include "ipv4ll.h"
|
||||
#include "ipv6nd.h"
|
||||
|
||||
#ifdef __QNX__
|
||||
/* QNX carries defines for, but does not actually support PF_LINK */
|
||||
#undef IFLR_ACTIVE
|
||||
#endif
|
||||
|
||||
void
|
||||
if_free(struct interface *ifp)
|
||||
{
|
||||
|
@ -95,28 +91,50 @@ if_free(struct interface *ifp)
|
|||
}
|
||||
|
||||
int
|
||||
if_carrier(struct interface *iface)
|
||||
if_opensockets(struct dhcpcd_ctx *ctx)
|
||||
{
|
||||
int s, r;
|
||||
|
||||
if ((ctx->link_fd = if_openlinksocket()) == -1)
|
||||
return -1;
|
||||
|
||||
ctx->pf_inet_fd = xsocket(PF_INET, SOCK_DGRAM, 0, O_CLOEXEC);
|
||||
if (ctx->pf_inet_fd == -1)
|
||||
return -1;
|
||||
|
||||
#if defined(INET6) && defined(BSD)
|
||||
ctx->pf_inet6_fd = xsocket(PF_INET6, SOCK_DGRAM, 0, O_CLOEXEC);
|
||||
if (ctx->pf_inet6_fd == -1)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
#ifdef IFLR_ACTIVE
|
||||
ctx->pf_link_fd = xsocket(PF_LINK, SOCK_DGRAM, 0, O_CLOEXEC);
|
||||
if (ctx->pf_link_fd == -1)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
if_carrier(struct interface *ifp)
|
||||
{
|
||||
int r;
|
||||
struct ifreq ifr;
|
||||
#ifdef SIOCGIFMEDIA
|
||||
struct ifmediareq ifmr;
|
||||
#endif
|
||||
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return LINK_UNKNOWN;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
|
||||
if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
|
||||
close(s);
|
||||
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
|
||||
if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == -1)
|
||||
return LINK_UNKNOWN;
|
||||
}
|
||||
iface->flags = (unsigned int)ifr.ifr_flags;
|
||||
ifp->flags = (unsigned int)ifr.ifr_flags;
|
||||
|
||||
#ifdef SIOCGIFMEDIA
|
||||
memset(&ifmr, 0, sizeof(ifmr));
|
||||
strlcpy(ifmr.ifm_name, iface->name, sizeof(ifmr.ifm_name));
|
||||
if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1 &&
|
||||
strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));
|
||||
if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) != -1 &&
|
||||
ifmr.ifm_status & IFM_AVALID)
|
||||
r = (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN;
|
||||
else
|
||||
|
@ -124,7 +142,6 @@ if_carrier(struct interface *iface)
|
|||
#else
|
||||
r = ifr.ifr_flags & IFF_RUNNING ? LINK_UP : LINK_DOWN;
|
||||
#endif
|
||||
close(s);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -132,24 +149,21 @@ int
|
|||
if_setflag(struct interface *ifp, short flag)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int s, r;
|
||||
int r;
|
||||
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
|
||||
r = -1;
|
||||
if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) {
|
||||
if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == 0) {
|
||||
if (flag == 0 || (ifr.ifr_flags & flag) == flag)
|
||||
r = 0;
|
||||
else {
|
||||
ifr.ifr_flags |= flag;
|
||||
if (ioctl(s, SIOCSIFFLAGS, &ifr) == 0)
|
||||
if (ioctl(ifp->ctx->pf_inet_fd, SIOCSIFFLAGS, &ifr) ==0)
|
||||
r = 0;
|
||||
}
|
||||
ifp->flags = (unsigned int)ifr.ifr_flags;
|
||||
}
|
||||
close(s);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -241,24 +255,12 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
|
|||
const struct sockaddr_dl *sdl;
|
||||
#ifdef SIOCGIFPRIORITY
|
||||
struct ifreq ifr;
|
||||
int s_inet;
|
||||
#endif
|
||||
#ifdef IFLR_ACTIVE
|
||||
struct if_laddrreq iflr;
|
||||
int s_link;
|
||||
#endif
|
||||
|
||||
#ifdef SIOCGIFPRIORITY
|
||||
if ((s_inet = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return NULL;
|
||||
#endif
|
||||
#ifdef IFLR_ACTIVE
|
||||
if ((s_link = socket(PF_LINK, SOCK_DGRAM, 0)) == -1) {
|
||||
#ifdef SIOCGIFPRIORITY
|
||||
close(s_inet);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
memset(&iflr, 0, sizeof(iflr));
|
||||
#endif
|
||||
#elif AF_PACKET
|
||||
|
@ -343,7 +345,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (if_vimaster(p) == 1) {
|
||||
if (if_vimaster(ctx, p) == 1) {
|
||||
logger(ctx, argc ? LOG_ERR : LOG_DEBUG,
|
||||
"%s: is a Virtual Interface Master, skipping", p);
|
||||
continue;
|
||||
|
@ -376,7 +378,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
|
|||
MIN(ifa->ifa_addr->sa_len, sizeof(iflr.addr)));
|
||||
iflr.flags = IFLR_PREFIX;
|
||||
iflr.prefixlen = (unsigned int)sdl->sdl_alen * NBBY;
|
||||
if (ioctl(s_link, SIOCGLIFADDR, &iflr) == -1 ||
|
||||
if (ioctl(ctx->pf_link_fd, SIOCGLIFADDR, &iflr) == -1 ||
|
||||
!(iflr.flags & IFLR_ACTIVE))
|
||||
{
|
||||
if_free(ifp);
|
||||
|
@ -497,27 +499,30 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
|
|||
}
|
||||
}
|
||||
|
||||
/* Handle any platform init for the interface */
|
||||
if (if_init(ifp) == -1) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: if_init: %m", p);
|
||||
if_free(ifp);
|
||||
continue;
|
||||
}
|
||||
if (!(ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))) {
|
||||
/* Handle any platform init for the interface */
|
||||
if (if_init(ifp) == -1) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: if_init: %m", p);
|
||||
if_free(ifp);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ensure that the MTU is big enough for DHCP */
|
||||
if (if_getmtu(ifp->name) < MTU_MIN &&
|
||||
if_setmtu(ifp->name, MTU_MIN) == -1)
|
||||
{
|
||||
logger(ifp->ctx, LOG_ERR, "%s: set_mtu: %m", p);
|
||||
if_free(ifp);
|
||||
continue;
|
||||
/* Ensure that the MTU is big enough for DHCP */
|
||||
if (if_getmtu(ifp) < MTU_MIN &&
|
||||
if_setmtu(ifp, MTU_MIN) == -1)
|
||||
{
|
||||
logger(ifp->ctx, LOG_ERR,
|
||||
"%s: if_setmtu: %m", p);
|
||||
if_free(ifp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SIOCGIFPRIORITY
|
||||
/* Respect the interface priority */
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
|
||||
if (ioctl(s_inet, SIOCGIFPRIORITY, &ifr) == 0)
|
||||
if (ioctl(ctx->pf_inet_fd, SIOCGIFPRIORITY, &ifr) == 0)
|
||||
ifp->metric = ifr.ifr_metric;
|
||||
#else
|
||||
/* We reserve the 100 range for virtual interfaces, if and when
|
||||
|
@ -535,13 +540,6 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
|
|||
if_learnaddrs1(ctx, ifs, ifaddrs);
|
||||
freeifaddrs(ifaddrs);
|
||||
|
||||
#ifdef SIOCGIFPRIORITY
|
||||
close(s_inet);
|
||||
#endif
|
||||
#ifdef IFLR_ACTIVE
|
||||
close(s_link);
|
||||
#endif
|
||||
|
||||
return ifs;
|
||||
}
|
||||
|
||||
|
@ -581,18 +579,15 @@ if_findindex(struct if_head *ifaces, unsigned int idx)
|
|||
}
|
||||
|
||||
int
|
||||
if_domtu(const char *ifname, short int mtu)
|
||||
if_domtu(const struct interface *ifp, short int mtu)
|
||||
{
|
||||
int s, r;
|
||||
int r;
|
||||
struct ifreq ifr;
|
||||
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
|
||||
ifr.ifr_mtu = mtu;
|
||||
r = ioctl(s, mtu ? SIOCSIFMTU : SIOCGIFMTU, &ifr);
|
||||
close(s);
|
||||
r = ioctl(ifp->ctx->pf_inet_fd, mtu ? SIOCSIFMTU : SIOCGIFMTU, &ifr);
|
||||
if (r == -1)
|
||||
return -1;
|
||||
return ifr.ifr_mtu;
|
||||
|
@ -667,3 +662,31 @@ if_sortinterfaces(struct dhcpcd_ctx *ctx)
|
|||
}
|
||||
TAILQ_CONCAT(ctx->ifaces, &sorted, next);
|
||||
}
|
||||
|
||||
int
|
||||
xsocket(int domain, int type, int protocol, int flags)
|
||||
{
|
||||
#ifdef SOCK_CLOEXEC
|
||||
if (flags & O_CLOEXEC)
|
||||
type |= SOCK_CLOEXEC;
|
||||
if (flags & O_NONBLOCK)
|
||||
type |= SOCK_NONBLOCK;
|
||||
|
||||
return socket(domain, type, protocol);
|
||||
#else
|
||||
int s, xflags;
|
||||
|
||||
if ((s = socket(domain, type, protocol)) == -1)
|
||||
return -1;
|
||||
if ((flags & O_CLOEXEC) && (xflags = fcntl(s, F_GETFD, 0)) == -1 ||
|
||||
fcntl(s, F_SETFD, xlags | FD_CLOEXEC) == -1)
|
||||
goto out;
|
||||
if ((flags & O_NONBLOCK) && (xflags = fcntl(s, F_GETFL, 0)) == -1 ||
|
||||
fcntl(s, F_SETFL, xflags | O_NONBLOCK) == -1)
|
||||
goto out;
|
||||
return s;
|
||||
out:
|
||||
close(s);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if.h,v 1.11 2015/07/09 10:15:34 roy Exp $ */
|
||||
/* $NetBSD: if.h,v 1.12 2015/08/21 10:39:00 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -95,16 +95,17 @@ 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);
|
||||
#define if_getmtu(iface) if_domtu(iface, 0)
|
||||
#define if_setmtu(iface, mtu) if_domtu(iface, mtu)
|
||||
int if_domtu(const struct interface *, short int);
|
||||
#define if_getmtu(ifp) if_domtu((ifp), 0)
|
||||
#define if_setmtu(ifp, mtu) if_domtu((ifp), (mtu))
|
||||
int if_carrier(struct interface *);
|
||||
|
||||
/* The below functions are provided by if-KERNEL.c */
|
||||
int if_conf(struct interface *);
|
||||
int if_init(struct interface *);
|
||||
int if_getssid(struct interface *);
|
||||
int if_vimaster(const char *);
|
||||
int if_vimaster(const struct dhcpcd_ctx *ctx, const char *);
|
||||
int if_opensockets(struct dhcpcd_ctx *);
|
||||
int if_openlinksocket(void);
|
||||
int if_managelink(struct dhcpcd_ctx *);
|
||||
|
||||
|
@ -163,4 +164,5 @@ int if_initrt6(struct interface *);
|
|||
#endif
|
||||
|
||||
int if_machinearch(char *, size_t);
|
||||
int xsocket(int, int, int, int);
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: ipv4.c,v 1.16 2015/07/09 10:15:34 roy Exp $");
|
||||
__RCSID("$NetBSD: ipv4.c,v 1.17 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -296,6 +296,11 @@ desc_route(const char *cmd, const struct rt *rt)
|
|||
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 == htonl(INADDR_ANY) &&
|
||||
rt->net.s_addr == htonl(INADDR_ANY) &&
|
||||
rt->gate.s_addr == htonl(INADDR_ANY))
|
||||
logger(ctx, LOG_INFO, "%s: %s default route",
|
||||
ifname, cmd);
|
||||
else if (rt->gate.s_addr == htonl(INADDR_ANY))
|
||||
logger(ctx, LOG_INFO, "%s: %s route to %s/%d",
|
||||
ifname, cmd, addr, inet_ntocidr(rt->net));
|
||||
|
@ -383,6 +388,7 @@ ipv4_handlert(struct dhcpcd_ctx *ctx, int cmd, struct rt *rt)
|
|||
static int
|
||||
nc_route(struct rt *ort, struct rt *nrt)
|
||||
{
|
||||
int change;
|
||||
|
||||
/* Don't set default routes if not asked to */
|
||||
if (nrt->dest.s_addr == 0 &&
|
||||
|
@ -392,6 +398,7 @@ nc_route(struct rt *ort, struct rt *nrt)
|
|||
|
||||
desc_route(ort == NULL ? "adding" : "changing", nrt);
|
||||
|
||||
change = 0;
|
||||
if (ort == NULL) {
|
||||
ort = ipv4_findrt(nrt->iface->ctx, nrt, 0);
|
||||
if (ort &&
|
||||
|
@ -401,8 +408,12 @@ nc_route(struct rt *ort, struct rt *nrt)
|
|||
ort->metric == nrt->metric &&
|
||||
#endif
|
||||
ort->gate.s_addr == nrt->gate.s_addr)))
|
||||
return 0;
|
||||
} else if (ort->flags & STATE_FAKE && !(nrt->flags & STATE_FAKE) &&
|
||||
{
|
||||
if (ort->mtu == nrt->mtu)
|
||||
return 0;
|
||||
change = 1;
|
||||
}
|
||||
} else if (ort->state & STATE_FAKE && !(nrt->state & STATE_FAKE) &&
|
||||
ort->iface == nrt->iface &&
|
||||
#ifdef HAVE_ROUTE_METRIC
|
||||
ort->metric == nrt->metric &&
|
||||
|
@ -410,12 +421,32 @@ nc_route(struct rt *ort, struct rt *nrt)
|
|||
ort->dest.s_addr == nrt->dest.s_addr &&
|
||||
ort->net.s_addr == nrt->net.s_addr &&
|
||||
ort->gate.s_addr == nrt->gate.s_addr)
|
||||
return 0;
|
||||
{
|
||||
if (ort->mtu == nrt->mtu)
|
||||
return 0;
|
||||
change = 1;
|
||||
}
|
||||
|
||||
#ifdef RTF_CLONING
|
||||
/* BSD can set routes to be cloning routes.
|
||||
* Cloned routes inherit the parent flags.
|
||||
* As such, we need to delete and re-add the route to flush children
|
||||
* to correct the flags. */
|
||||
if (change && ort != NULL && ort->flags & RTF_CLONING)
|
||||
change = 0;
|
||||
#endif
|
||||
|
||||
if (change) {
|
||||
if (if_route(RTM_CHANGE, nrt) == 0)
|
||||
return 0;
|
||||
if (errno != ESRCH)
|
||||
logger(nrt->iface->ctx, LOG_ERR, "if_route (CHG): %m");
|
||||
}
|
||||
|
||||
#ifdef HAVE_ROUTE_METRIC
|
||||
/* With route metrics, we can safely add the new route before
|
||||
* deleting the old route. */
|
||||
if (if_route(RTM_ADD, nrt) == 0) {
|
||||
if (if_route(RTM_ADD, nrt) == 0) {
|
||||
if (ort && if_route(RTM_DELETE, ort) == -1 && errno != ESRCH)
|
||||
logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m");
|
||||
return 0;
|
||||
|
@ -472,7 +503,7 @@ add_subnet_route(struct rt_head *rt, const struct interface *ifp)
|
|||
return rt;
|
||||
#endif
|
||||
|
||||
if ((r = malloc(sizeof(*r))) == NULL) {
|
||||
if ((r = calloc(1, sizeof(*r))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
ipv4_freeroutes(rt);
|
||||
return NULL;
|
||||
|
@ -480,6 +511,7 @@ add_subnet_route(struct rt_head *rt, const struct interface *ifp)
|
|||
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;
|
||||
r->mtu = dhcp_get_mtu(ifp);
|
||||
r->src = s->addr;
|
||||
|
||||
TAILQ_INSERT_HEAD(rt, r, next);
|
||||
|
@ -500,8 +532,7 @@ add_loopback_route(struct rt_head *rt, const struct interface *ifp)
|
|||
if (s->addr.s_addr == INADDR_ANY)
|
||||
return rt;
|
||||
|
||||
r = malloc(sizeof(*r));
|
||||
if (r == NULL) {
|
||||
if ((r = calloc(1, sizeof(*r))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
ipv4_freeroutes(rt);
|
||||
return NULL;
|
||||
|
@ -509,6 +540,7 @@ add_loopback_route(struct rt_head *rt, const struct interface *ifp)
|
|||
r->dest = s->addr;
|
||||
r->net.s_addr = INADDR_BROADCAST;
|
||||
r->gate.s_addr = htonl(INADDR_LOOPBACK);
|
||||
r->mtu = dhcp_get_mtu(ifp);
|
||||
r->src = s->addr;
|
||||
TAILQ_INSERT_HEAD(rt, r, next);
|
||||
return rt;
|
||||
|
@ -529,8 +561,7 @@ get_routes(struct interface *ifp)
|
|||
TAILQ_FOREACH(rt, ifp->options->routes, next) {
|
||||
if (rt->gate.s_addr == 0)
|
||||
break;
|
||||
r = malloc(sizeof(*r));
|
||||
if (r == NULL) {
|
||||
if ((r = calloc(1, sizeof(*r))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
ipv4_freeroutes(nrt);
|
||||
return NULL;
|
||||
|
@ -539,7 +570,7 @@ get_routes(struct interface *ifp)
|
|||
TAILQ_INSERT_TAIL(nrt, r, next);
|
||||
}
|
||||
} else
|
||||
nrt = get_option_routes(ifp, D_STATE(ifp)->new);
|
||||
nrt = dhcp_get_routes(ifp);
|
||||
|
||||
/* Copy our address as the source address */
|
||||
if (nrt) {
|
||||
|
@ -564,8 +595,7 @@ add_destination_route(struct rt_head *rt, const struct interface *ifp)
|
|||
(state = D_CSTATE(ifp)) == NULL)
|
||||
return rt;
|
||||
|
||||
r = malloc(sizeof(*r));
|
||||
if (r == NULL) {
|
||||
if ((r = calloc(1, sizeof(*r))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
ipv4_freeroutes(rt);
|
||||
return NULL;
|
||||
|
@ -573,6 +603,8 @@ add_destination_route(struct rt_head *rt, const struct interface *ifp)
|
|||
r->dest.s_addr = INADDR_ANY;
|
||||
r->net.s_addr = INADDR_ANY;
|
||||
r->gate.s_addr = state->dst.s_addr;
|
||||
r->mtu = dhcp_get_mtu(ifp);
|
||||
r->src = state->addr;
|
||||
TAILQ_INSERT_HEAD(rt, r, next);
|
||||
return rt;
|
||||
}
|
||||
|
@ -637,8 +669,7 @@ add_router_host_route(struct rt_head *rt, const struct interface *ifp)
|
|||
"%s: router %s requires a host route",
|
||||
ifp->name, inet_ntoa(rtp->gate));
|
||||
}
|
||||
rtn = malloc(sizeof(*rtn));
|
||||
if (rtn == NULL) {
|
||||
if ((rtn = calloc(1, sizeof(*rtn))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
|
||||
ipv4_freeroutes(rt);
|
||||
return NULL;
|
||||
|
@ -646,18 +677,72 @@ add_router_host_route(struct rt_head *rt, const struct interface *ifp)
|
|||
rtn->dest.s_addr = rtp->gate.s_addr;
|
||||
rtn->net.s_addr = htonl(INADDR_BROADCAST);
|
||||
rtn->gate.s_addr = htonl(INADDR_ANY);
|
||||
rtn->mtu = dhcp_get_mtu(ifp);
|
||||
rtn->src = state->addr;
|
||||
TAILQ_INSERT_BEFORE(rtp, rtn, next);
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
static int
|
||||
ipv4_doroute(struct rt *rt, struct rt_head *nrs)
|
||||
{
|
||||
const struct dhcp_state *state;
|
||||
struct rt *or;
|
||||
|
||||
state = D_CSTATE(rt->iface);
|
||||
rt->state = state->added & STATE_FAKE;
|
||||
#ifdef HAVE_ROUTE_METRIC
|
||||
rt->metric = rt->iface->metric;
|
||||
#endif
|
||||
/* Is this route already in our table? */
|
||||
if ((find_route(nrs, rt, NULL)) != NULL)
|
||||
return 0;
|
||||
/* Do we already manage it? */
|
||||
if ((or = find_route(rt->iface->ctx->ipv4_routes, rt, NULL))) {
|
||||
if (state->added & STATE_FAKE)
|
||||
return 0;
|
||||
if (or->state & STATE_FAKE ||
|
||||
or->iface != rt->iface ||
|
||||
#ifdef HAVE_ROUTE_METRIC
|
||||
rt->metric != or->metric ||
|
||||
#endif
|
||||
rt->src.s_addr != or->src.s_addr ||
|
||||
rt->gate.s_addr != or->gate.s_addr ||
|
||||
rt->mtu != or->mtu)
|
||||
{
|
||||
if (c_route(or, rt) != 0)
|
||||
return 0;
|
||||
}
|
||||
TAILQ_REMOVE(rt->iface->ctx->ipv4_routes, or, next);
|
||||
free(or);
|
||||
} else {
|
||||
if (state->added & STATE_FAKE) {
|
||||
if ((or = ipv4_findrt(rt->iface->ctx, rt, 1)) == NULL)
|
||||
return 0;
|
||||
rt->iface = or->iface;
|
||||
rt->gate.s_addr = or->gate.s_addr;
|
||||
#ifdef HAVE_ROUTE_METRIC
|
||||
rt->metric = or->metric;
|
||||
#endif
|
||||
rt->mtu = or->mtu;
|
||||
rt->flags = or->flags;
|
||||
} else {
|
||||
if (n_route(rt) != 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
ipv4_buildroutes(struct dhcpcd_ctx *ctx)
|
||||
{
|
||||
struct rt_head *nrs, *dnr;
|
||||
struct rt *or, *rt, *rtn;
|
||||
struct rt *rt, *rtn;
|
||||
struct interface *ifp;
|
||||
const struct dhcp_state *state;
|
||||
int has_default;
|
||||
|
||||
/* We need to have the interfaces in the correct order to ensure
|
||||
* our routes are managed correctly. */
|
||||
|
@ -669,6 +754,7 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx)
|
|||
}
|
||||
TAILQ_INIT(nrs);
|
||||
|
||||
has_default = 0;
|
||||
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
|
||||
state = D_CSTATE(ifp);
|
||||
if (state != NULL && state->new != NULL && state->added) {
|
||||
|
@ -700,48 +786,29 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx)
|
|||
continue;
|
||||
TAILQ_FOREACH_SAFE(rt, dnr, next, rtn) {
|
||||
rt->iface = ifp;
|
||||
#ifdef HAVE_ROUTE_METRIC
|
||||
rt->metric = ifp->metric;
|
||||
#endif
|
||||
rt->flags = state->added & STATE_FAKE;
|
||||
/* Is this route already in our table? */
|
||||
if ((find_route(nrs, rt, NULL)) != NULL)
|
||||
continue;
|
||||
/* Do we already manage it? */
|
||||
if ((or = find_route(ctx->ipv4_routes, rt, NULL))) {
|
||||
if (state->added & STATE_FAKE)
|
||||
continue;
|
||||
if (or->flags & STATE_FAKE ||
|
||||
or->iface != ifp ||
|
||||
#ifdef HAVE_ROUTE_METRIC
|
||||
rt->metric != or->metric ||
|
||||
#endif
|
||||
rt->src.s_addr != or->src.s_addr ||
|
||||
rt->gate.s_addr != or->gate.s_addr)
|
||||
{
|
||||
if (c_route(or, rt) != 0)
|
||||
continue;
|
||||
}
|
||||
TAILQ_REMOVE(ctx->ipv4_routes, or, next);
|
||||
free(or);
|
||||
} else {
|
||||
if (state->added & STATE_FAKE) {
|
||||
or = ipv4_findrt(ctx, rt, 1);
|
||||
if (or == NULL ||
|
||||
or->gate.s_addr != rt->gate.s_addr)
|
||||
continue;
|
||||
} else {
|
||||
if (n_route(rt) != 0)
|
||||
continue;
|
||||
}
|
||||
if (ipv4_doroute(rt, nrs) == 1) {
|
||||
TAILQ_REMOVE(dnr, rt, next);
|
||||
TAILQ_INSERT_TAIL(nrs, rt, next);
|
||||
if (rt->dest.s_addr == INADDR_ANY)
|
||||
has_default = 1;
|
||||
}
|
||||
rt->flags |= STATE_ADDED;
|
||||
TAILQ_REMOVE(dnr, rt, next);
|
||||
TAILQ_INSERT_TAIL(nrs, rt, next);
|
||||
}
|
||||
ipv4_freeroutes(dnr);
|
||||
}
|
||||
|
||||
/* If we don't manage a default route, grab one without a
|
||||
* gateway for any IPv4LL enabled interfaces. */
|
||||
if (!has_default) {
|
||||
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
|
||||
if ((rt = ipv4ll_default_route(ifp)) != NULL) {
|
||||
if (ipv4_doroute(rt, nrs) == 1)
|
||||
TAILQ_INSERT_TAIL(nrs, rt, next);
|
||||
else
|
||||
free(rt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove old routes we used to manage */
|
||||
if (ctx->ipv4_routes) {
|
||||
TAILQ_FOREACH(rt, ctx->ipv4_routes, next) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ipv4.h,v 1.12 2015/07/09 10:15:34 roy Exp $ */
|
||||
/* $NetBSD: ipv4.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -63,8 +63,10 @@ struct rt {
|
|||
#ifdef HAVE_ROUTE_METRIC
|
||||
unsigned int metric;
|
||||
#endif
|
||||
unsigned int mtu;
|
||||
struct in_addr src;
|
||||
unsigned int flags;
|
||||
unsigned int state;
|
||||
};
|
||||
TAILQ_HEAD(rt_head, rt);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: ipv4ll.c,v 1.11 2015/07/09 10:15:34 roy Exp $");
|
||||
__RCSID("$NetBSD: ipv4ll.c,v 1.12 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -48,13 +48,17 @@
|
|||
#include "ipv4ll.h"
|
||||
#include "script.h"
|
||||
|
||||
static const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) };
|
||||
static const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BRDC) };
|
||||
const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) };
|
||||
const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BRDC) };
|
||||
|
||||
static in_addr_t
|
||||
ipv4ll_pick_addr(const struct arp_state *astate)
|
||||
{
|
||||
struct in_addr addr;
|
||||
struct ipv4ll_state *istate;
|
||||
|
||||
istate = IPV4LL_STATE(astate->iface);
|
||||
setstate(istate->randomstate);
|
||||
|
||||
do {
|
||||
/* RFC 3927 Section 2.1 states that the first 256 and
|
||||
|
@ -69,6 +73,9 @@ ipv4ll_pick_addr(const struct arp_state *astate)
|
|||
/* Ensure we don't have the address on another interface */
|
||||
} while (ipv4_findaddr(astate->iface->ctx, &addr) != NULL);
|
||||
|
||||
/* Restore the original random state */
|
||||
setstate(astate->iface->ctx->randomstate);
|
||||
|
||||
return addr.s_addr;
|
||||
}
|
||||
|
||||
|
@ -83,7 +90,7 @@ ipv4ll_subnet_route(const struct interface *ifp)
|
|||
state->addr.s_addr == INADDR_ANY)
|
||||
return NULL;
|
||||
|
||||
if ((rt = malloc(sizeof(*rt))) == NULL) {
|
||||
if ((rt = calloc(1, sizeof(*rt))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: malloc: %m", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -95,6 +102,29 @@ ipv4ll_subnet_route(const struct interface *ifp)
|
|||
return rt;
|
||||
}
|
||||
|
||||
struct rt *
|
||||
ipv4ll_default_route(const struct interface *ifp)
|
||||
{
|
||||
const struct ipv4ll_state *state;
|
||||
struct rt *rt;
|
||||
|
||||
assert(ifp != NULL);
|
||||
if ((state = IPV4LL_CSTATE(ifp)) == NULL ||
|
||||
state->addr.s_addr == INADDR_ANY)
|
||||
return NULL;
|
||||
|
||||
if ((rt = calloc(1, sizeof(*rt))) == NULL) {
|
||||
logger(ifp->ctx, LOG_ERR, "%s: malloc: %m", __func__);
|
||||
return NULL;
|
||||
}
|
||||
rt->iface = ifp;
|
||||
rt->dest.s_addr = INADDR_ANY;
|
||||
rt->net.s_addr = INADDR_ANY;
|
||||
rt->gate.s_addr = INADDR_ANY;
|
||||
rt->src = state->addr;
|
||||
return rt;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ipv4ll_env(char **env, const char *prefix, const struct interface *ifp)
|
||||
{
|
||||
|
@ -162,6 +192,7 @@ ipv4ll_probed(struct arp_state *astate)
|
|||
#endif
|
||||
state->addr = astate->addr;
|
||||
timespecclear(&state->defend);
|
||||
if_initrt(ifp);
|
||||
ipv4_buildroutes(ifp->ctx);
|
||||
arp_announce(astate);
|
||||
script_runreason(ifp, "IPV4LL");
|
||||
|
@ -295,6 +326,7 @@ ipv4ll_start(void *arg)
|
|||
* the same address without persistent storage. */
|
||||
if (state->conflicts == 0) {
|
||||
unsigned int seed;
|
||||
char *orig;
|
||||
|
||||
if (sizeof(seed) > ifp->hwlen) {
|
||||
seed = 0;
|
||||
|
@ -302,7 +334,15 @@ ipv4ll_start(void *arg)
|
|||
} else
|
||||
memcpy(&seed, ifp->hwaddr + ifp->hwlen - sizeof(seed),
|
||||
sizeof(seed));
|
||||
initstate(seed, state->randomstate, sizeof(state->randomstate));
|
||||
orig = initstate(seed,
|
||||
state->randomstate, sizeof(state->randomstate));
|
||||
|
||||
/* Save the original state. */
|
||||
if (ifp->ctx->randomstate == NULL)
|
||||
ifp->ctx->randomstate = orig;
|
||||
|
||||
/* Set back the original state until we need the seeded one. */
|
||||
setstate(ifp->ctx->randomstate);
|
||||
}
|
||||
|
||||
if ((astate = arp_new(ifp, NULL)) == NULL)
|
||||
|
@ -338,7 +378,6 @@ ipv4ll_start(void *arg)
|
|||
return;
|
||||
}
|
||||
|
||||
setstate(state->randomstate);
|
||||
logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address",
|
||||
ifp->name);
|
||||
astate->addr.s_addr = ipv4ll_pick_addr(astate);
|
||||
|
@ -353,9 +392,11 @@ void
|
|||
ipv4ll_freedrop(struct interface *ifp, int drop)
|
||||
{
|
||||
struct ipv4ll_state *state;
|
||||
int dropped;
|
||||
|
||||
assert(ifp != NULL);
|
||||
state = IPV4LL_STATE(ifp);
|
||||
dropped = 0;
|
||||
|
||||
/* Free ARP state first because ipv4_deladdr might also ... */
|
||||
if (state && state->arp) {
|
||||
|
@ -370,6 +411,7 @@ ipv4ll_freedrop(struct interface *ifp, int drop)
|
|||
if (state && state->addr.s_addr != INADDR_ANY) {
|
||||
ipv4_deladdr(ifp, &state->addr, &inaddr_llmask, 1);
|
||||
state->addr.s_addr = INADDR_ANY;
|
||||
dropped = 1;
|
||||
}
|
||||
|
||||
/* Free any other link local addresses that might exist. */
|
||||
|
@ -377,18 +419,22 @@ ipv4ll_freedrop(struct interface *ifp, int drop)
|
|||
struct ipv4_addr *ia, *ian;
|
||||
|
||||
TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) {
|
||||
if (IN_LINKLOCAL(ntohl(ia->addr.s_addr)))
|
||||
if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) {
|
||||
ipv4_deladdr(ifp, &ia->addr,
|
||||
&ia->net, 0);
|
||||
dropped = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
script_runreason(ifp, "IPV4LL");
|
||||
}
|
||||
|
||||
if (state) {
|
||||
free(state);
|
||||
ifp->if_data[IF_DATA_IPV4LL] = NULL;
|
||||
|
||||
ipv4_buildroutes(ifp->ctx);
|
||||
if (dropped) {
|
||||
ipv4_buildroutes(ifp->ctx);
|
||||
script_runreason(ifp, "IPV4LL");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ipv4ll.h,v 1.9 2015/07/09 10:15:34 roy Exp $ */
|
||||
/* $NetBSD: ipv4ll.h,v 1.10 2015/08/21 10:39:00 roy Exp $ */
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -32,6 +32,9 @@
|
|||
|
||||
#include "arp.h"
|
||||
|
||||
extern const struct in_addr inaddr_llmask;
|
||||
extern const struct in_addr inaddr_llbcast;
|
||||
|
||||
#define LINKLOCAL_ADDR 0xa9fe0000
|
||||
#define LINKLOCAL_MASK IN_CLASSB_NET
|
||||
#define LINKLOCAL_BRDC (LINKLOCAL_ADDR | ~LINKLOCAL_MASK)
|
||||
|
@ -58,6 +61,7 @@ struct ipv4ll_state {
|
|||
IN_LINKLOCAL(ntohl(IPV4LL_CSTATE((ifp))->addr.s_addr)))
|
||||
|
||||
struct rt* ipv4ll_subnet_route(const struct interface *);
|
||||
struct rt* ipv4ll_default_route(const struct interface *);
|
||||
ssize_t ipv4ll_env(char **, const char *, const struct interface *);
|
||||
void ipv4ll_start(void *);
|
||||
void ipv4ll_claimed(void *);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: ipv6.c,v 1.13 2015/07/09 10:15:34 roy Exp $");
|
||||
__RCSID("$NetBSD: ipv6.c,v 1.14 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -647,7 +647,13 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timespec *now)
|
|||
ap->flags |= IPV6_AF_DADCOMPLETED;
|
||||
|
||||
logger(ap->iface->ctx, ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG,
|
||||
"%s: adding address %s", ap->iface->name, ap->saddr);
|
||||
"%s: adding %saddress %s", ap->iface->name,
|
||||
#ifdef IPV6_AF_TEMPORARY
|
||||
ap->flags & IPV6_AF_TEMPORARY ? "temporary " : "",
|
||||
#else
|
||||
"",
|
||||
#endif
|
||||
ap->saddr);
|
||||
if (ap->prefix_pltime == ND6_INFINITE_LIFETIME &&
|
||||
ap->prefix_vltime == ND6_INFINITE_LIFETIME)
|
||||
logger(ap->iface->ctx, LOG_DEBUG,
|
||||
|
@ -881,17 +887,22 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
|
|||
{
|
||||
if (drop == 2)
|
||||
TAILQ_REMOVE(addrs, ap, next);
|
||||
/* Find the same address somewhere else */
|
||||
apf = ipv6_findaddr(ap->iface->ctx, &ap->addr, 0);
|
||||
if (apf == NULL ||
|
||||
(apf->iface != ap->iface))
|
||||
ipv6_deleteaddr(ap);
|
||||
if (!(ap->iface->options->options &
|
||||
DHCPCD_EXITING) && apf)
|
||||
{
|
||||
if (!timespecisset(&now))
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
ipv6_addaddr(apf, &now);
|
||||
/* Don't drop link-local addresses. */
|
||||
if (!IN6_IS_ADDR_LINKLOCAL(&ap->addr)) {
|
||||
/* Find the same address somewhere else */
|
||||
apf = ipv6_findaddr(ap->iface->ctx, &ap->addr,
|
||||
0);
|
||||
if ((apf == NULL ||
|
||||
(apf->iface != ap->iface)))
|
||||
ipv6_deleteaddr(ap);
|
||||
if (!(ap->iface->options->options &
|
||||
DHCPCD_EXITING) && apf)
|
||||
{
|
||||
if (!timespecisset(&now))
|
||||
clock_gettime(CLOCK_MONOTONIC,
|
||||
&now);
|
||||
ipv6_addaddr(apf, &now);
|
||||
}
|
||||
}
|
||||
if (drop == 2)
|
||||
ipv6_freeaddr(ap);
|
||||
|
@ -1850,6 +1861,7 @@ ipv6_handlert(struct dhcpcd_ctx *ctx, int cmd, struct rt6 *rt)
|
|||
static int
|
||||
nc_route(struct rt6 *ort, struct rt6 *nrt)
|
||||
{
|
||||
int change;
|
||||
|
||||
/* Don't set default routes if not asked to */
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&nrt->dest) &&
|
||||
|
@ -1859,6 +1871,7 @@ nc_route(struct rt6 *ort, struct rt6 *nrt)
|
|||
|
||||
desc_route(ort == NULL ? "adding" : "changing", nrt);
|
||||
|
||||
change = 0;
|
||||
if (ort == NULL) {
|
||||
ort = ipv6_findrt(nrt->iface->ctx, nrt, 0);
|
||||
if (ort &&
|
||||
|
@ -1868,7 +1881,27 @@ nc_route(struct rt6 *ort, struct rt6 *nrt)
|
|||
ort->metric == nrt->metric &&
|
||||
#endif
|
||||
IN6_ARE_ADDR_EQUAL(&ort->gate, &nrt->gate))))
|
||||
{
|
||||
if (ort->mtu == nrt->mtu)
|
||||
return 0;
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RTF_CLONING
|
||||
/* BSD can set routes to be cloning routes.
|
||||
* Cloned routes inherit the parent flags.
|
||||
* As such, we need to delete and re-add the route to flush children
|
||||
* to correct the flags. */
|
||||
if (change && ort != NULL && ort->flags & RTF_CLONING)
|
||||
change = 0;
|
||||
#endif
|
||||
|
||||
if (change) {
|
||||
if (if_route6(RTM_CHANGE, nrt) == 0)
|
||||
return 0;
|
||||
if (errno != ESRCH)
|
||||
logger(nrt->iface->ctx, LOG_ERR, "if_route6 (CHG): %m");
|
||||
}
|
||||
|
||||
#ifdef HAVE_ROUTE_METRIC
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: ipv6nd.c,v 1.25 2015/07/09 10:15:34 roy Exp $");
|
||||
__RCSID("$NetBSD: ipv6nd.c,v 1.26 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -192,29 +192,10 @@ ipv6nd_open(struct dhcpcd_ctx *dctx)
|
|||
ctx = dctx->ipv6;
|
||||
if (ctx->nd_fd != -1)
|
||||
return ctx->nd_fd;
|
||||
#ifdef SOCK_CLOEXEC
|
||||
ctx->nd_fd = socket(PF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
|
||||
IPPROTO_ICMPV6);
|
||||
ctx->nd_fd = xsocket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
|
||||
O_NONBLOCK|O_CLOEXEC);
|
||||
if (ctx->nd_fd == -1)
|
||||
return -1;
|
||||
#else
|
||||
if ((ctx->nd_fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1)
|
||||
return -1;
|
||||
if ((on = fcntl(ctx->nd_fd, F_GETFD, 0)) == -1 ||
|
||||
fcntl(ctx->nd_fd, F_SETFD, on | FD_CLOEXEC) == -1)
|
||||
{
|
||||
close(ctx->nd_fd);
|
||||
ctx->nd_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
if ((on = fcntl(ctx->nd_fd, F_GETFL, 0)) == -1 ||
|
||||
fcntl(ctx->nd_fd, F_SETFL, on | O_NONBLOCK) == -1)
|
||||
{
|
||||
close(ctx->nd_fd);
|
||||
ctx->nd_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* RFC4861 4.1 */
|
||||
on = 255;
|
||||
|
@ -735,14 +716,19 @@ try_script:
|
|||
}
|
||||
|
||||
static int
|
||||
ipv6nd_ra_has_public_addr(const struct ra *rap)
|
||||
ipv6nd_has_public_addr(const struct interface *ifp)
|
||||
{
|
||||
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;
|
||||
TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
|
||||
if (rap->iface == ifp) {
|
||||
TAILQ_FOREACH(ia, &rap->addrs, next) {
|
||||
if (ia->flags & IPV6_AF_AUTOCONF &&
|
||||
ipv6_publicaddr(ia))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1109,7 +1095,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp,
|
|||
if (new_rap)
|
||||
add_router(ifp->ctx->ipv6, rap);
|
||||
|
||||
if (!ipv6nd_ra_has_public_addr(rap) &&
|
||||
if (!ipv6nd_has_public_addr(rap->iface) &&
|
||||
!(rap->iface->options->options & DHCPCD_IPV6RA_ACCEPT_NOPUBLIC) &&
|
||||
(!(rap->flags & ND_RA_FLAG_MANAGED) ||
|
||||
!dhcp6_has_public_addr(rap->iface)))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: script.c,v 1.21 2015/07/09 10:15:34 roy Exp $");
|
||||
__RCSID("$NetBSD: script.c,v 1.22 2015/08/21 10:39:00 roy Exp $");
|
||||
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
|
@ -325,7 +325,7 @@ make_env(const struct interface *ifp, const char *reason, char ***argv)
|
|||
EMALLOC(6, e);
|
||||
snprintf(env[6], e, "ifflags=%u", ifp->flags);
|
||||
EMALLOC(7, e);
|
||||
snprintf(env[7], e, "ifmtu=%d", if_getmtu(ifp->name));
|
||||
snprintf(env[7], e, "ifmtu=%d", if_getmtu(ifp));
|
||||
l = e = strlen("interface_order=");
|
||||
TAILQ_FOREACH(ifp2, ifp->ctx->ifaces, next) {
|
||||
e += strlen(ifp2->name) + 1;
|
||||
|
|
Loading…
Reference in New Issue