This commit is contained in:
roy 2015-01-30 09:47:05 +00:00
parent b7934c7750
commit c40a479dcf
43 changed files with 1077 additions and 276 deletions

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: arp.c,v 1.8 2014/11/26 13:43:06 roy Exp $");
__RCSID("$NetBSD: arp.c,v 1.9 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,8 +1,8 @@
/* $NetBSD: arp.h,v 1.7 2014/12/19 10:54:08 roy Exp $ */
/* $NetBSD: arp.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -77,6 +77,6 @@ void arp_free(struct arp_state *);
void arp_free_but(struct arp_state *);
void arp_close(struct interface *);
#else
#define arp_close(a)
#define arp_close(a) {}
#endif
#endif

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: auth.c,v 1.7 2014/11/14 12:00:54 roy Exp $");
__RCSID("$NetBSD: auth.c,v 1.8 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,8 +1,8 @@
/* $NetBSD: auth.h,v 1.7 2014/11/14 12:00:54 roy Exp $ */
/* $NetBSD: auth.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: common.c,v 1.7 2014/11/14 12:00:54 roy Exp $");
__RCSID("$NetBSD: common.c,v 1.8 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,8 +1,8 @@
/* $NetBSD: common.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */
/* $NetBSD: common.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: control.c,v 1.6 2014/11/07 20:51:02 roy Exp $");
__RCSID("$NetBSD: control.c,v 1.7 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,8 +1,8 @@
/* $NetBSD: control.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */
/* $NetBSD: control.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,8 +1,8 @@
/* $NetBSD: crypt.h,v 1.5 2014/11/07 20:51:03 roy Exp $ */
/* $NetBSD: crypt.h,v 1.6 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: hmac_md5.c,v 1.5 2014/11/07 20:51:03 roy Exp $");
__RCSID("$NetBSD: hmac_md5.c,v 1.6 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,8 +1,8 @@
/* $NetBSD: defs.h,v 1.12 2014/12/19 10:54:08 roy Exp $ */
/* $NetBSD: defs.h,v 1.13 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
#define CONFIG_H
#define PACKAGE "dhcpcd"
#define VERSION "6.6.7"
#define VERSION "6.7.0"
#ifndef CONFIG
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"

View File

@ -1,8 +1,8 @@
/* $NetBSD: dev.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */
/* $NetBSD: dev.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: dhcp-common.c,v 1.6 2014/11/07 20:51:02 roy Exp $");
__RCSID("$NetBSD: dhcp-common.c,v 1.7 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,8 +1,8 @@
/* $NetBSD: dhcp-common.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */
/* $NetBSD: dhcp-common.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: dhcp.c,v 1.26 2014/12/17 20:50:08 roy Exp $");
__RCSID("$NetBSD: dhcp.c,v 1.27 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -2489,6 +2489,16 @@ dhcp_handledhcp(struct interface *iface, struct dhcp_message **dhcpp,
/* reset the message counter */
state->interval = 0;
/* Ensure that no reject options are present */
for (i = 1; i < 255; i++) {
if (has_option_mask(ifo->rejectmask, i) &&
get_option_uint8(iface->ctx, &tmp, dhcp, (uint8_t)i) == 0)
{
log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp, from);
return;
}
}
if (type == DHCP_NAK) {
/* For NAK, only check if we require the ServerID */
if (has_option_mask(ifo->requiremask, DHO_SERVERID) &&
@ -2525,6 +2535,23 @@ dhcp_handledhcp(struct interface *iface, struct dhcp_message **dhcpp,
return;
}
/* Ensure that all required options are present */
for (i = 1; i < 255; i++) {
if (has_option_mask(ifo->requiremask, i) &&
get_option_uint8(iface->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
* DHCP style options as well so the above isn't
* always true. */
if (type == 0 && i == DHO_SERVERID)
continue;
log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp, from);
return;
}
}
/* DHCP Auto-Configure, RFC 2563 */
if (type == DHCP_OFFER && dhcp->yiaddr == 0) {
log_dhcp(LOG_WARNING, "no address given", iface, dhcp, from);
@ -2571,20 +2598,6 @@ dhcp_handledhcp(struct interface *iface, struct dhcp_message **dhcpp,
return;
}
/* Ensure that all required options are present */
for (i = 1; i < 255; i++) {
if (has_option_mask(ifo->requiremask, i) &&
get_option_uint8(iface->ctx, &tmp, dhcp, (uint8_t)i) != 0)
{
/* If we are bootp, then ignore the need for serverid.
* To ignore bootp, require dhcp_message_type. */
if (type == 0 && i == DHO_SERVERID)
continue;
log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp, from);
return;
}
}
/* Ensure that the address offered is valid */
if ((type == 0 || type == DHCP_OFFER || type == DHCP_ACK) &&
(dhcp->ciaddr == INADDR_ANY || dhcp->ciaddr == INADDR_BROADCAST) &&
@ -2879,7 +2892,14 @@ dhcp_open(struct interface *ifp)
if (state->raw_fd == -1) {
state->raw_fd = if_openrawsocket(ifp, ETHERTYPE_IP);
if (state->raw_fd == -1) {
syslog(LOG_ERR, "%s: %s: %m", __func__, ifp->name);
if (errno == ENOENT) {
syslog(LOG_ERR, "%s not found", if_pfname);
/* May as well disable IPv4 entirely at
* this point as we really need it. */
ifp->options->options &= ~DHCPCD_IPV4;
} else
syslog(LOG_ERR, "%s: %s: %m",
__func__, ifp->name);
return -1;
}
eloop_event_add(ifp->ctx->eloop,

View File

@ -1,8 +1,8 @@
/* $NetBSD: dhcp.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */
/* $NetBSD: dhcp.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -292,13 +292,13 @@ void dhcp_close(struct interface *);
void dhcp_free(struct interface *);
int dhcp_dump(struct interface *);
#else
#define dhcp_drop(a, b)
#define dhcp_drop(a, b) {}
#define dhcp_start(a) {}
#define dhcp_reboot(a, b) b = b
#define dhcp_reboot_newopts(a, b)
#define dhcp_close(a)
#define dhcp_free(a)
#define dhcp_dump(a) -1
#define dhcp_reboot(a, b) (b = b)
#define dhcp_reboot_newopts(a, b) (b = b)
#define dhcp_close(a) {}
#define dhcp_free(a) {}
#define dhcp_dump(a) (-1)
#endif
#endif

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: dhcp6.c,v 1.8 2014/12/17 20:50:08 roy Exp $");
__RCSID("$NetBSD: dhcp6.c,v 1.9 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -1739,6 +1739,7 @@ dhcp6_findna(struct interface *ifp, uint16_t ot, const uint8_t *iaid,
a->ia_type = ot;
memcpy(a->iaid, iaid, sizeof(a->iaid));
a->addr = iap->addr;
a->created = *acquired;
/*
* RFC 5942 Section 5
@ -1821,6 +1822,7 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
}
a->iface = ifp;
a->flags = IPV6_AF_NEW | IPV6_AF_DELEGATEDPFX;
a->created = *acquired;
a->dadcallback = dhcp6_dadcallback;
a->ia_type = D6_OPTION_IA_PD;
memcpy(a->iaid, iaid, sizeof(a->iaid));
@ -2287,7 +2289,7 @@ dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix,
a->dadcallback = dhcp6_dadcallback;
a->delegating_iface = ifs;
memcpy(&a->iaid, &prefix->iaid, sizeof(a->iaid));
a->acquired = prefix->acquired;
a->created = a->acquired = prefix->acquired;
a->prefix_pltime = prefix->prefix_pltime;
a->prefix_vltime = prefix->prefix_vltime;
a->prefix = addr;
@ -2306,6 +2308,7 @@ dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix,
/* Keep our flags */
a->flags |= ap->flags;
a->flags &= ~IPV6_AF_NEW;
a->created = ap->created;
free(ap);
}
}
@ -2686,6 +2689,14 @@ dhcp6_handledata(void *arg)
ifp->name, opt->var, ctx->sfrom);
return;
}
if (has_option_mask(ifo->rejectmask6, opt->option) &&
dhcp6_getmoption(opt->option, r, len))
{
syslog(LOG_WARNING,
"%s: reject DHCPv6 (option %s) from %s",
ifp->name, opt->var, ctx->sfrom);
return;
}
}
/* Authenticate the message */
@ -3292,7 +3303,7 @@ dhcp6_freedrop(struct interface *ifp, int drop, const char *reason)
state = D6_STATE(ifp);
if (state) {
dhcp_auth_reset(&state->auth);
if (options & DHCPCD_RELEASE) {
if (drop && options & DHCPCD_RELEASE) {
if (ifp->carrier == LINK_UP)
dhcp6_startrelease(ifp);
unlink(state->leasefile);

View File

@ -1,8 +1,8 @@
/* $NetBSD: dhcp6.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */
/* $NetBSD: dhcp6.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -248,13 +248,13 @@ void dhcp6_drop(struct interface *, const char *);
int dhcp6_dump(struct interface *);
#else
#define dhcp6_findaddr(a, b, c) (0)
#define dhcp6_find_delegates(a)
#define dhcp6_find_delegates(a) {}
#define dhcp6_start(a, b) (0)
#define dhcp6_reboot(a)
#define dhcp6_env(a, b, c, d, e)
#define dhcp6_free(a)
#define dhcp6_reboot(a) {}
#define dhcp6_env(a, b, c, d, e) {}
#define dhcp6_free(a) {}
#define dhcp6_dadcompleted(a) (0)
#define dhcp6_drop(a, b)
#define dhcp6_drop(a, b) {}
#define dhcp6_dump(a) (-1)
#endif

View File

@ -1,6 +1,6 @@
# $NetBSD: dhcpcd-definitions.conf,v 1.6 2014/11/07 20:51:02 roy Exp $
# $NetBSD: dhcpcd-definitions.conf,v 1.7 2015/01/30 09:47:05 roy Exp $
# Copyright (c) 2006-2014 Roy Marples
# Copyright (c) 2006-2015 Roy Marples
# All rights reserved
# DHCP option definitions for dhcpcd(8)

View File

@ -1,5 +1,5 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: dhcpcd-embedded.c,v 1.6 2014/11/07 20:51:02 roy Exp $");
__RCSID("$NetBSD: dhcpcd-embedded.c,v 1.7 2015/01/30 09:47:05 roy Exp $");
/*
* DO NOT EDIT
@ -9,7 +9,7 @@
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2013 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,8 +1,8 @@
/* $NetBSD: dhcpcd-embedded.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */
/* $NetBSD: dhcpcd-embedded.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
.\" $NetBSD: dhcpcd-run-hooks.8.in,v 1.12 2014/11/07 20:51:02 roy Exp $
.\" Copyright (c) 2006-2014 Roy Marples
.\" $NetBSD: dhcpcd-run-hooks.8.in,v 1.13 2015/01/30 09:47:05 roy Exp $
.\" Copyright (c) 2006-2015 Roy Marples
.\" All rights reserved
.\"
.\" Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
.\" $NetBSD: dhcpcd.8.in,v 1.39 2014/12/17 20:50:08 roy Exp $
.\" Copyright (c) 2006-2014 Roy Marples
.\" $NetBSD: dhcpcd.8.in,v 1.40 2015/01/30 09:47:05 roy Exp $
.\" Copyright (c) 2006-2015 Roy Marples
.\" All rights reserved
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd November 26, 2014
.Dd January 15, 2015
.Dt DHCPCD 8
.Os
.Sh NAME
@ -123,6 +123,14 @@ and
.Li RFC 6106 .
.Pp
.Nm
is also an implementation of the IPv6 Privacy Extensions to AutoConf as
specified in
.Li RFC 4941 .
This feature needs to be enabled in the kernel and
.Nm
will start using it.
.Pp
.Nm
is also an implemenation of the DHCPv6 client as specified in
.Li RFC 3315 .
By default,
@ -702,8 +710,8 @@ RFC\ 951, RFC\ 1534, RFC\ 2104, RFC\ 2131, RFC\ 2132, RFC\ 2563, RFC\ 2855,
RFC\ 3004, RFC\ 3118, RFC\ 3203, RFC\ 3315, RFC\ 3361, RFC\ 3633, RFC\ 3396,
RFC\ 3397, RFC\ 3442, RFC\ 3495, RFC\ 3925, RFC\ 3927, RFC\ 4039, RFC\ 4075,
RFC\ 4242, RFC\ 4361, RFC\ 4390, RFC\ 4702, RFC\ 4074, RFC\ 4861, RFC\ 4833,
RFC\ 5227, RFC\ 5942, RFC\ 5969, RFC\ 6106, RFC\ 6334, RFC\ 6603, RFC\ 6704,
RFC\ 7217.
RFC\ 4941, RFC\ 5227, RFC\ 5942, RFC\ 5969, RFC\ 6106, RFC\ 6334, RFC\ 6603,
RFC\ 6704, RFC\ 7217.
.Sh AUTHORS
.An Roy Marples Aq Mt roy@marples.name
.Sh BUGS

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: dhcpcd.c,v 1.21 2014/12/20 13:15:48 prlw1 Exp $");
__RCSID("$NetBSD: dhcpcd.c,v 1.22 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -28,7 +28,7 @@
* SUCH DAMAGE.
*/
const char dhcpcd_copyright[] = "Copyright (c) 2006-2014 Roy Marples";
const char dhcpcd_copyright[] = "Copyright (c) 2006-2015 Roy Marples";
#define _WITH_DPRINTF /* Stop FreeBSD bitching */
@ -320,6 +320,7 @@ stop_interface(struct interface *ifp)
dhcp6_drop(ifp, NULL);
ipv6nd_drop(ifp);
ipv6_drop(ifp);
dhcp_drop(ifp, "STOP");
arp_close(ifp);
if (ifp->options->options & DHCPCD_DEPARTED)
@ -388,7 +389,7 @@ 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)
else if (ra_iface == 0 && !(ifp->ctx->options & DHCPCD_TEST))
ifo->options |= DHCPCD_IPV6RA_OWN;
}
@ -605,11 +606,7 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags,
script_runreason(ifp, "NOCARRIER");
dhcp6_drop(ifp, "EXPIRE6");
ipv6nd_drop(ifp);
/* Don't blindly delete our knowledge of LL addresses.
* We need to listen to what the kernel does with
* them as some OS's will remove, mark tentative or
* do nothing. */
ipv6_free_ll_callbacks(ifp);
ipv6_drop(ifp);
dhcp_drop(ifp, "EXPIRE");
arp_close(ifp);
}
@ -625,8 +622,11 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags,
#endif
if (ifp->wireless)
if_getssid(ifp);
configure_interface(ifp, ctx->argc, ctx->argv);
dhcpcd_initstate(ifp);
script_runreason(ifp, "CARRIER");
/* RFC4941 Section 3.5 */
if (ifp->options->options & DHCPCD_IPV6RA_OWN)
ipv6_gentempifid(ifp);
dhcpcd_startinterface(ifp);
}
}
@ -907,6 +907,10 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname)
i = -1;
ifs = if_discover(ctx, -1, UNCONST(argv));
if (ifs == NULL) {
syslog(LOG_ERR, "%s: if_discover: %m", __func__);
return -1;
}
TAILQ_FOREACH_SAFE(ifp, ifs, next, ifn) {
if (strcmp(ifp->name, ifname) != 0)
continue;
@ -1007,8 +1011,10 @@ reconf_reboot(struct dhcpcd_ctx *ctx, int action, int argc, char **argv, int oi)
struct interface *ifn, *ifp;
ifs = if_discover(ctx, argc - oi, argv + oi);
if (ifs == NULL)
if (ifs == NULL) {
syslog(LOG_ERR, "%s: if_discover: %m", __func__);
return;
}
while ((ifp = TAILQ_FIRST(ifs))) {
TAILQ_REMOVE(ifs, ifp, next);
@ -1514,8 +1520,10 @@ main(int argc, char **argv)
/* We need to try and find the interface so we can
* load the hardware address to compare automated IAID */
ctx.ifaces = if_discover(&ctx, 1, argv + optind);
if (ctx.ifaces == NULL)
if (ctx.ifaces == NULL) {
syslog(LOG_ERR, "if_discover: %m");
goto exit_failure;
}
ifp = TAILQ_FIRST(ctx.ifaces);
if (ifp == NULL) {
ifp = calloc(1, sizeof(*ifp));
@ -1707,12 +1715,16 @@ main(int argc, char **argv)
dev_start(&ctx);
ctx.ifaces = if_discover(&ctx, ctx.ifc, ctx.ifv);
if (ctx.ifaces == NULL) {
syslog(LOG_ERR, "if_discover: %m");
goto exit_failure;
}
for (i = 0; i < ctx.ifc; i++) {
if (if_find(&ctx, ctx.ifv[i]) == NULL)
syslog(LOG_ERR, "%s: interface not found or invalid",
ctx.ifv[i]);
}
if (ctx.ifaces == NULL || TAILQ_FIRST(ctx.ifaces) == NULL) {
if (TAILQ_FIRST(ctx.ifaces) == NULL) {
if (ctx.ifc == 0)
syslog(LOG_ERR, "no valid interfaces found");
else

View File

@ -1,5 +1,5 @@
.\" $NetBSD: dhcpcd.conf.5.in,v 1.17 2014/12/17 20:50:08 roy Exp $
.\" Copyright (c) 2006-2014 Roy Marples
.\" $NetBSD: dhcpcd.conf.5.in,v 1.18 2015/01/30 09:47:05 roy Exp $
.\" Copyright (c) 2006-2015 Roy Marples
.\" All rights reserved
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd December 13, 2014
.Dd January 20, 2015
.Dt DHCPCD.CONF 5
.Os
.Sh NAME
@ -345,6 +345,12 @@ encodes the FQDN hostname as specified in
.It Ic interface Ar interface
Subsequent options are only parsed for this
.Ar interface .
.It Ic ipv6ra_autoconf
Generate SLAAC addresses for each Prefix advertised by a
Router Advertisement message with the Auto flag set.
On by default.
.It Ic ipv6ra_noautoconf
Disables the above option.
.It Ic ipv6ra_fork
By default, when
.Nm dhcpcd
@ -484,6 +490,14 @@ To enforce that
only responds to DHCP servers and not BOOTP servers, you can
.Ic require
.Ar dhcp_message_type .
This isn't an exact science though because a BOOTP server can send DHCP like
options.
.It Ic reject Ar option
Reject a DHCP message that contains the
.Ar option .
This is useful when you cannot use
.Ic require
to select / de-select BOOTP messages.
.It Ic script Ar script
Use
.Ar script

View File

@ -1,8 +1,8 @@
/* $NetBSD: dhcpcd.h,v 1.8 2014/11/26 13:43:06 roy Exp $ */
/* $NetBSD: dhcpcd.h,v 1.9 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -62,6 +62,9 @@ struct interface {
struct dhcpcd_ctx *ctx;
TAILQ_ENTRY(interface) next;
char name[IF_NAMESIZE];
#ifdef __linux
char alias[IF_NAMESIZE];
#endif
unsigned int index;
unsigned int flags;
sa_family_t family;

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: duid.c,v 1.6 2014/11/07 20:51:02 roy Exp $");
__RCSID("$NetBSD: duid.c,v 1.7 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,8 +1,8 @@
/* $NetBSD: duid.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */
/* $NetBSD: duid.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: eloop.c,v 1.7 2014/11/14 12:00:54 roy Exp $");
__RCSID("$NetBSD: eloop.c,v 1.8 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,8 +1,8 @@
/* $NetBSD: eloop.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */
/* $NetBSD: eloop.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: if-bsd.c,v 1.16 2014/12/17 20:50:08 roy Exp $");
__RCSID("$NetBSD: if-bsd.c,v 1.17 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -64,6 +64,7 @@
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <paths.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@ -148,6 +149,7 @@ if_openlinksocket(void)
#endif
}
#if defined(INET) || defined(INET6)
static void
if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp)
{
@ -160,6 +162,7 @@ if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp)
link_addr(ifp->name, sdl);
#endif
}
#endif
static int
if_getssid1(const char *ifname, uint8_t *ssid)
@ -260,6 +263,8 @@ if_vimaster(const char *ifname)
}
#ifdef INET
const char *if_pfname = "Berkley Packet Filter";
int
if_openrawsocket(struct interface *ifp, int protocol)
{
@ -616,6 +621,8 @@ if_address6(const struct ipv6_addr *a, int action)
if (a->autoconf)
ifa.ifra_flags |= IN6_IFF_AUTOCONF;
#endif
if (a->flags & IPV6_AF_TEMPORARY)
ifa.ifra_flags |= IN6_IFF_TEMPORARY;
#define ADDADDR(v, addr) { \
(v)->sin6_family = AF_INET6; \
@ -785,6 +792,51 @@ if_addrflags6(const struct in6_addr *addr, const struct interface *ifp)
}
return flags;
}
int
if_getlifetime6(struct ipv6_addr *ia)
{
int s, r;
struct in6_ifreq ifr6;
s = socket(PF_INET6, SOCK_DGRAM, 0);
r = -1;
if (s != -1) {
memset(&ifr6, 0, sizeof(ifr6));
strncpy(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;
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 */
get_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;
}
#endif
int
@ -806,7 +858,7 @@ if_managelink(struct dhcpcd_ctx *ctx)
#endif
#ifdef INET6
struct rt6 rt6;
struct in6_addr ia6;
struct in6_addr ia6, net6;
struct sockaddr_in6 *sin6;
int ifa_flags;
#endif
@ -972,6 +1024,10 @@ if_managelink(struct dhcpcd_ctx *ctx)
rti_info[RTAX_IFA];
ia6 = sin6->sin6_addr;
DESCOPE(&ia6);
sin6 = (struct sockaddr_in6*)(void *)
rti_info[RTAX_NETMASK];
net6 = sin6->sin6_addr;
DESCOPE(&net6);
if (rtm->rtm_type == RTM_NEWADDR) {
ifa_flags = if_addrflags6(&ia6, ifp);
if (ifa_flags == -1)
@ -979,7 +1035,8 @@ if_managelink(struct dhcpcd_ctx *ctx)
} else
ifa_flags = 0;
ipv6_handleifa(ctx, rtm->rtm_type, NULL,
ifp->name, &ia6, ifa_flags);
ifp->name, &ia6, ipv6_prefixlen(&net6),
ifa_flags);
break;
#endif
}
@ -1035,6 +1092,65 @@ inet6_sysctl(int code, int val, int action)
}
#endif
#ifndef IPV6CTL_TEMPVLTIME
#define get_inet6_sysctlbyname(code) inet6_sysctlbyname(code, 0, 0)
#define set_inet6_sysctlbyname(code, val) inet6_sysctlbyname(code, val, 1)
static int
inet6_sysctlbyname(const char *name, int val, int action)
{
size_t size;
size = sizeof(val);
if (action) {
if (sysctlbyname(name, NULL, 0, &val, size) == -1)
return -1;
return 0;
}
if (sysctlbyname(name, &val, &size, NULL, 0) == -1)
return -1;
return val;
}
#endif
int
ip6_use_tempaddr(__unused const char *ifname)
{
int val;
#ifdef IPV6CTL_USETEMPADDR
val = get_inet6_sysctl(IPV6CTL_USETEMPADDR);
#else
val = get_inet6_sysctlbyname("net.inet6.ip6.use_tempaddr");
#endif
return val == -1 ? TEMP_PREFERRED_LIFETIME : val;
}
int
ip6_temp_preferred_lifetime(__unused const char *ifname)
{
int val;
#ifdef IPV6CTL_TEMPPLTIME
val = get_inet6_sysctl(IPV6CTL_TEMPPLTIME);
#else
val = get_inet6_sysctlbyname("net.inet6.ip6.temppltime");
#endif
return val < 0 ? TEMP_PREFERRED_LIFETIME : val;
}
int
ip6_temp_valid_lifetime(__unused const char *ifname)
{
int val;
#ifdef IPV6CTL_TEMPVLTIME
val = get_inet6_sysctl(IPV6CTL_TEMPVLTIME);
#else
val = get_inet6_sysctlbyname("net.inet6.ip6.tempvltime");
#endif
return val < 0 ? TEMP_VALID_LIFETIME : val;
}
#define del_if_nd6_flag(ifname, flag) if_nd6_flag(ifname, flag, -1)
#define get_if_nd6_flag(ifname, flag) if_nd6_flag(ifname, flag, 0)
#define set_if_nd6_flag(ifname, flag) if_nd6_flag(ifname, flag, 1)
@ -1186,8 +1302,16 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
syslog(LOG_ERR,
"%s: get_if_nd6_flag: ND6_IFF_OVERRIDE_RTADV: %m",
ifp->name);
else if (override == 0 && !own)
return 0;
else if (override == 0 && own) {
if (set_if_nd6_flag(ifp->name, ND6_IFF_OVERRIDE_RTADV)
== -1)
syslog(LOG_ERR,
"%s: set_if_nd6_flag: "
"ND6_IFF_OVERRIDE_RTADV: %m",
ifp->name);
else
override = 1;
}
#endif
#ifdef ND6_IFF_ACCEPT_RTADV
@ -1202,27 +1326,19 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
ifp->name);
if (del_if_nd6_flag(ifp->name, ND6_IFF_ACCEPT_RTADV)
== -1)
{
syslog(LOG_ERR,
"%s: del_if_nd6_flag: "
"ND6_IFF_ACCEPT_RTADV: %m",
ifp->name);
return ra;
}
else
ra = 0;
} else if (ra == 0 && !own)
syslog(LOG_WARNING,
"%s: IPv6 kernel autoconf disabled", ifp->name);
#ifdef ND6_IFF_OVERRIDE_RTADV
if (override == 0 &&
set_if_nd6_flag(ifp->name, ND6_IFF_OVERRIDE_RTADV)
== -1)
{
syslog(LOG_ERR,
"%s: set_if_nd6_flag: "
"ND6_IFF_OVERRIDE_RTADV: %m",
ifp->name);
return ra;
}
if (override == 0 && ra)
return ctx->ra_global;
#endif
return 0;
}
return ra;
#else
return ctx->ra_global;

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: if-options.c,v 1.19 2014/11/26 13:43:06 roy Exp $");
__RCSID("$NetBSD: if-options.c,v 1.20 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -96,6 +96,9 @@
#define O_SLAAC O_BASE + 35
#define O_GATEWAY O_BASE + 36
#define O_PFXDLGMIX O_BASE + 37
#define O_IPV6RA_AUTOCONF O_BASE + 38
#define O_IPV6RA_NOAUTOCONF O_BASE + 39
#define O_REJECT O_BASE + 40
const struct option cf_options[] = {
{"background", no_argument, NULL, 'b'},
@ -149,6 +152,8 @@ const struct option cf_options[] = {
{"fallback", required_argument, NULL, O_FALLBACK},
{"ipv6rs", no_argument, NULL, O_IPV6RS},
{"noipv6rs", no_argument, NULL, O_NOIPV6RS},
{"ipv6ra_autoconf", no_argument, NULL, O_IPV6RA_AUTOCONF},
{"ipv6ra_noautoconf", no_argument, NULL, O_IPV6RA_NOAUTOCONF},
{"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},
@ -183,6 +188,7 @@ const struct option cf_options[] = {
{"slaac", required_argument, NULL, O_SLAAC},
{"gateway", no_argument, NULL, O_GATEWAY},
{"ia_pd_mix", no_argument, NULL, O_PFXDLGMIX},
{"reject", required_argument, NULL, O_REJECT},
{NULL, 0, NULL, '\0'}
};
@ -526,9 +532,14 @@ set_option_space(struct dhcpcd_ctx *ctx,
const struct dhcp_opt **d, size_t *dl,
const struct dhcp_opt **od, size_t *odl,
struct if_options *ifo,
uint8_t *request[], uint8_t *require[], uint8_t *no[])
uint8_t *request[], uint8_t *require[], uint8_t *no[], uint8_t *reject[])
{
#if !defined(INET) && !defined(INET6)
/* Satisfy use */
ctx = ctx;
#endif
#ifdef INET6
if (strncmp(arg, "dhcp6_", strlen("dhcp6_")) == 0) {
*d = ctx->dhcp6_opts;
@ -538,6 +549,7 @@ set_option_space(struct dhcpcd_ctx *ctx,
*request = ifo->requestmask6;
*require = ifo->requiremask6;
*no = ifo->nomask6;
*reject = ifo->rejectmask6;
return arg + strlen("dhcp6_");
}
#endif
@ -556,6 +568,7 @@ set_option_space(struct dhcpcd_ctx *ctx,
*request = ifo->requestmask;
*require = ifo->requiremask;
*no = ifo->nomask;
*reject = ifo->rejectmask;
return arg;
}
@ -643,7 +656,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
in_addr_t *naddr;
struct rt *rt;
const struct dhcp_opt *d, *od;
uint8_t *request, *require, *no;
uint8_t *request, *require, *no, *reject;
struct dhcp_opt **dop, *ndop;
size_t *dop_len, dl, odl;
struct vivco *vivco;
@ -745,9 +758,21 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
break;
case 'o':
arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
&request, &require, &no);
&request, &require, &no, &reject);
if (make_option_mask(d, dl, od, odl, request, arg, 1) != 0 ||
make_option_mask(d, dl, od, odl, no, arg, -1) != 0)
make_option_mask(d, dl, od, odl, no, arg, -1) != 0 ||
make_option_mask(d, dl, od, odl, reject, arg, -1) != 0)
{
syslog(LOG_ERR, "unknown option `%s'", arg);
return -1;
}
break;
case O_REJECT:
arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
&request, &require, &no, &reject);
if (make_option_mask(d, dl, od, odl, reject, arg, 1) != 0 ||
make_option_mask(d, dl, od, odl, request, arg, -1) != 0 ||
make_option_mask(d, dl, od, odl, require, arg, -1) != 0)
{
syslog(LOG_ERR, "unknown option `%s'", arg);
return -1;
@ -964,7 +989,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
break;
case 'O':
arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
&request, &require, &no);
&request, &require, &no, &reject);
if (make_option_mask(d, dl, od, odl, request, arg, -1) != 0 ||
make_option_mask(d, dl, od, odl, require, arg, -1) != 0 ||
make_option_mask(d, dl, od, odl, no, arg, 1) != 0)
@ -975,10 +1000,11 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
break;
case 'Q':
arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
&request, &require, &no);
&request, &require, &no, &reject);
if (make_option_mask(d, dl, od, odl, require, arg, 1) != 0 ||
make_option_mask(d, dl, od, odl, request, arg, 1) != 0 ||
make_option_mask(d, dl, od, odl, no, arg, -1) != 0)
make_option_mask(d, dl, od, odl, no, arg, -1) != 0 ||
make_option_mask(d, dl, od, odl, reject, arg, -1) != 0)
{
syslog(LOG_ERR, "unknown option `%s'", arg);
return -1;
@ -1168,7 +1194,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
break;
case O_DESTINATION:
arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
&request, &require, &no);
&request, &require, &no, &reject);
if (make_option_mask(d, dl, od, odl,
ifo->dstmask, arg, 2) != 0)
{
@ -1214,6 +1240,12 @@ 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_AUTOCONF:
ifo->options |= DHCPCD_IPV6RA_AUTOCONF;
break;
case O_IPV6RA_NOAUTOCONF:
ifo->options &= ~DHCPCD_IPV6RA_AUTOCONF;
break;
case O_NOALIAS:
ifo->options |= DHCPCD_NOALIAS;
break;
@ -2026,7 +2058,8 @@ read_config(struct dhcpcd_ctx *ctx,
ifo->options |= DHCPCD_GATEWAY | DHCPCD_ARP;
#endif
#ifdef INET6
ifo->options |= DHCPCD_IPV6 | DHCPCD_IPV6RS | DHCPCD_IPV6RA_REQRDNSS;
ifo->options |= DHCPCD_IPV6 | DHCPCD_IPV6RS;
ifo->options |= DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS;
ifo->options |= DHCPCD_DHCP6;
#endif
ifo->timeout = DEFAULT_TIMEOUT;

View File

@ -1,8 +1,8 @@
/* $NetBSD: if-options.h,v 1.7 2014/11/26 13:43:06 roy Exp $ */
/* $NetBSD: if-options.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -108,6 +108,7 @@
#define DHCPCD_NOPFXDLG (1ULL << 51)
#define DHCPCD_PFXDLGONLY (1ULL << 52)
#define DHCPCD_PFXDLGMIX (1ULL << 53)
#define DHCPCD_IPV6RA_AUTOCONF (1ULL << 54)
extern const struct option cf_options[];
@ -142,9 +143,11 @@ struct if_options {
uint8_t requestmask[256 / NBBY];
uint8_t requiremask[256 / NBBY];
uint8_t nomask[256 / NBBY];
uint8_t rejectmask[256 / NBBY];
uint8_t requestmask6[(UINT16_MAX + 1) / NBBY];
uint8_t requiremask6[(UINT16_MAX + 1) / NBBY];
uint8_t nomask6[(UINT16_MAX + 1) / NBBY];
uint8_t rejectmask6[(UINT16_MAX + 1) / NBBY];
uint8_t dstmask[256 / NBBY];
uint32_t leasetime;
time_t timeout;

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: if.c,v 1.10 2014/12/17 20:50:08 roy Exp $");
__RCSID("$NetBSD: if.c,v 1.11 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -73,6 +73,11 @@
#include "ipv4.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)
{
@ -81,9 +86,9 @@ if_free(struct interface *ifp)
return;
ipv4_free(ifp);
dhcp_free(ifp);
ipv6_free(ifp);
dhcp6_free(ifp);
ipv6nd_free(ifp);
ipv6_free(ifp);
free_options(ifp->options);
free(ifp);
}
@ -96,20 +101,11 @@ if_carrier(struct interface *iface)
#ifdef SIOCGIFMEDIA
struct ifmediareq ifmr;
#endif
#ifdef __linux__
char *p;
#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));
#ifdef __linux__
/* We can only test the real interface up */
if ((p = strchr(ifr.ifr_name, ':')))
*p = '\0';
#endif
if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
close(s);
return LINK_UNKNOWN;
@ -136,19 +132,11 @@ if_setflag(struct interface *ifp, short flag)
{
struct ifreq ifr;
int s, r;
#ifdef __linux__
char *p;
#endif
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));
#ifdef __linux__
/* We can only bring the real interface up */
if ((p = strchr(ifr.ifr_name, ':')))
*p = '\0';
#endif
r = -1;
if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) {
if (flag == 0 || (ifr.ifr_flags & flag) == flag)
@ -193,7 +181,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
const struct sockaddr_in *dst;
#endif
#ifdef INET6
struct sockaddr_in6 *sin6;
struct sockaddr_in6 *sin6, *net6;
int ifa_flags;
#endif
#ifdef AF_LINK
@ -271,6 +259,9 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
p = argv[i];
} else {
p = ifa->ifa_name;
#ifdef __linux__
strlcpy(ifn, ifa->ifa_name, sizeof(ifn));
#endif
/* -1 means we're discovering against a specific
* interface, but we still need the below rules
* to apply. */
@ -311,7 +302,12 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
break;
}
ifp->ctx = ctx;
#ifdef __linux__
strlcpy(ifp->name, ifn, sizeof(ifp->name));
strlcpy(ifp->alias, p, sizeof(ifp->alias));
#else
strlcpy(ifp->name, p, sizeof(ifp->name));
#endif
ifp->flags = ifa->ifa_flags;
ifp->carrier = if_carrier(ifp);
@ -503,6 +499,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
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 */
@ -513,7 +510,9 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
if (ifa_flags != -1)
ipv6_handleifa(ctx, RTM_NEWADDR, ifs,
ifa->ifa_name,
&sin6->sin6_addr, ifa_flags);
&sin6->sin6_addr,
ipv6_prefixlen(&net6->sin6_addr),
ifa_flags);
break;
#endif
}
@ -541,6 +540,9 @@ if_findindexname(struct dhcpcd_ctx *ctx, unsigned int idx, const char *name)
if ((ifp->options == NULL ||
!(ifp->options->options & DHCPCD_PFXDLGONLY)) &&
((name && strcmp(ifp->name, name) == 0) ||
#ifdef __linux__
(name && strcmp(ifp->alias, name) == 0) ||
#endif
(!name && ifp->index == idx)))
return ifp;
}

View File

@ -1,8 +1,8 @@
/* $NetBSD: if.h,v 1.7 2014/12/17 20:50:08 roy Exp $ */
/* $NetBSD: if.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -105,6 +105,7 @@ int if_openlinksocket(void);
int if_managelink(struct dhcpcd_ctx *);
#ifdef INET
extern const char *if_pfname;
int if_openrawsocket(struct interface *, int);
ssize_t if_sendrawpacket(const struct interface *,
int, const void *, size_t);
@ -126,12 +127,16 @@ int if_route(const struct rt *rt, int);
#ifdef INET6
int if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *, int);
int ip6_use_tempaddr(const char *ifname);
int ip6_temp_preferred_lifetime(const char *ifname);
int ip6_temp_valid_lifetime(const char *ifname);
int if_address6(const struct ipv6_addr *, int);
#define if_addaddress6(a) if_address6(a, 1)
#define if_deladdress6(a) if_address6(a, -1)
int if_addrflags6(const struct in6_addr *, const struct interface *);
int if_getlifetime6(struct ipv6_addr *);
int if_route6(const struct rt6 *rt, int);
#define if_addroute6(rt) if_route6(rt, 1)

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: ipv4.c,v 1.10 2014/12/17 20:50:08 roy Exp $");
__RCSID("$NetBSD: ipv4.c,v 1.11 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,8 +1,8 @@
/* $NetBSD: ipv4.h,v 1.7 2014/11/26 13:43:06 roy Exp $ */
/* $NetBSD: ipv4.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: ipv4ll.c,v 1.7 2014/11/14 12:00:54 roy Exp $");
__RCSID("$NetBSD: ipv4ll.c,v 1.8 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: ipv6.c,v 1.7 2014/12/17 20:50:08 roy Exp $");
__RCSID("$NetBSD: ipv6.c,v 1.8 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -38,28 +38,17 @@
#include <netinet/in.h>
#include <netinet/if_ether.h>
#ifdef __linux__
/* Match Linux defines to BSD */
# ifdef IFA_F_OPTIMISTIC
# define IN6_IFF_TENTATIVE (IFA_F_TENTATIVE | IFA_F_OPTIMISTIC)
# else
# define IN6_IFF_TENTATIVE (IFA_F_TENTATIVE | 0x04)
#ifndef __linux__
# ifndef __QNX__
# include <sys/endian.h>
# endif
# ifdef IF_F_DADFAILED
# define IN6_IFF_DUPLICATED IFA_F_DADFAILED
# else
# define IN6_IFF_DUPLICATED 0x08
# endif
# define IN6_IFF_DETACHED 0
#else
# include <sys/endian.h>
# include <net/if.h>
#ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */
# include <net/if_var.h>
#endif
#ifndef __sun
# include <netinet6/in6_var.h>
#endif
# ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */
# include <net/if_var.h>
# endif
# ifndef __sun
# include <netinet6/in6_var.h>
# endif
#endif
#include <errno.h>
@ -70,6 +59,7 @@
#include <syslog.h>
#include <unistd.h>
#define ELOOP_QUEUE 7
#include "common.h"
#include "dhcpcd.h"
#include "dhcp6.h"
@ -78,6 +68,14 @@
#include "ipv6.h"
#include "ipv6nd.h"
#ifdef HAVE_MD5_H
# ifndef DEPGEN
# include <md5.h>
# endif
#else
# include "md5.h"
#endif
#ifdef SHA2_H
# include SHA2_H
#else
@ -93,6 +91,22 @@
# warning polling tentative address flags periodically instead
#endif
#ifdef __linux__
/* Match Linux defines to BSD */
# define IN6_IFF_TEMPORARY IFA_F_TEMPORARY
# ifdef IFA_F_OPTIMISTIC
# define IN6_IFF_TENTATIVE (IFA_F_TENTATIVE | IFA_F_OPTIMISTIC)
# else
# define IN6_IFF_TENTATIVE (IFA_F_TENTATIVE | 0x04)
# endif
# ifdef IF_F_DADFAILED
# define IN6_IFF_DUPLICATED IFA_F_DADFAILED
# else
# define IN6_IFF_DUPLICATED 0x08
# endif
# define IN6_IFF_DETACHED 0
#endif
#define IN6_IFF_NOTUSEABLE \
(IN6_IFF_TENTATIVE | IN6_IFF_DUPLICATED | IN6_IFF_DETACHED)
@ -105,6 +119,14 @@
# endif
#endif
#ifdef IPV6_MANAGETEMPADDR
static void ipv6_regentempifid(void *);
static void ipv6_regentempaddr(void *);
#else
#define ipv6_regentempifid(a) {}
#endif
struct ipv6_ctx *
ipv6_init(struct dhcpcd_ctx *dhcpcd_ctx)
{
@ -151,6 +173,7 @@ ipv6_init(struct dhcpcd_ctx *dhcpcd_ctx)
ctx->dhcp_fd = -1;
dhcpcd_ctx->ipv6 = ctx;
return ctx;
}
@ -570,7 +593,7 @@ ipv6_checkaddrflags(void *arg)
else if (!(ifa_flags & IN6_IFF_TENTATIVE)) {
ipv6_handleifa(ap->iface->ctx, RTM_NEWADDR,
ap->iface->ctx->ifaces, ap->iface->name,
&ap->addr, ifa_flags);
&ap->addr, ap->prefix_len, ifa_flags);
} else {
struct timeval tv;
@ -610,7 +633,6 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now)
struct interface *ifp;
struct ipv6_state *state;
struct ipv6_addr *nap;
struct timeval n;
uint32_t pltime, vltime;
/* Ensure no other interface has this address */
@ -628,6 +650,30 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now)
}
}
if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
ipv6_iffindaddr(ap->iface, &ap->addr))
ap->flags |= IPV6_AF_DADCOMPLETED;
syslog(ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG,
"%s: adding address %s", ap->iface->name, ap->saddr);
if (ap->prefix_pltime == ND6_INFINITE_LIFETIME &&
ap->prefix_vltime == ND6_INFINITE_LIFETIME)
syslog(LOG_DEBUG,
"%s: pltime infinity, vltime infinity",
ap->iface->name);
else if (ap->prefix_pltime == ND6_INFINITE_LIFETIME)
syslog(LOG_DEBUG,
"%s: pltime infinity, vltime %"PRIu32" seconds",
ap->iface->name, ap->prefix_vltime);
else if (ap->prefix_vltime == ND6_INFINITE_LIFETIME)
syslog(LOG_DEBUG,
"%s: pltime %"PRIu32"seconds, vltime infinity",
ap->iface->name, ap->prefix_pltime);
else
syslog(LOG_DEBUG,
"%s: pltime %"PRIu32" seconds, vltime %"PRIu32" seconds",
ap->iface->name, ap->prefix_pltime, ap->prefix_vltime);
/* Adjust plftime and vltime based on acquired time */
pltime = ap->prefix_pltime;
vltime = ap->prefix_vltime;
@ -635,33 +681,49 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now)
(ap->prefix_pltime != ND6_INFINITE_LIFETIME ||
ap->prefix_vltime != ND6_INFINITE_LIFETIME))
{
struct timeval n;
if (now == NULL) {
get_monotonic(&n);
now = &n;
}
timersub(now, &ap->acquired, &n);
if (ap->prefix_pltime != ND6_INFINITE_LIFETIME)
ap->prefix_pltime -= n.tv_sec;
ap->prefix_pltime -= (uint32_t)n.tv_sec;
if (ap->prefix_vltime != ND6_INFINITE_LIFETIME)
ap->prefix_vltime -= n.tv_sec;
ap->prefix_vltime -= (uint32_t)n.tv_sec;
}
syslog(ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG,
"%s: adding address %s", ap->iface->name, ap->saddr);
if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
ipv6_iffindaddr(ap->iface, &ap->addr))
ap->flags |= IPV6_AF_DADCOMPLETED;
if (if_addaddress6(ap) == -1) {
syslog(LOG_ERR, "if_addaddress6: %m");
#if 0
syslog(LOG_DEBUG,
"%s: adj pltime %"PRIu32" seconds, "
"vltime %"PRIu32" seconds",
ap->iface->name, ap->prefix_pltime, ap->prefix_vltime);
#endif
/* Restore real pltime and vltime */
ap->prefix_pltime = pltime;
ap->prefix_vltime = vltime;
return -1;
}
#ifdef IPV6_MANAGETEMPADDR
/* RFC4941 Section 3.4 */
if (ap->flags & IPV6_AF_TEMPORARY &&
ap->prefix_pltime &&
ap->prefix_vltime &&
ap->iface->options->options & DHCPCD_IPV6RA_OWN &&
ip6_use_tempaddr(ap->iface->name))
eloop_timeout_add_sec(ap->iface->ctx->eloop,
(time_t)ap->prefix_pltime - REGEN_ADVANCE,
ipv6_regentempaddr, ap);
#endif
/* Restore real pltime and vltime */
ap->prefix_pltime = pltime;
ap->prefix_vltime = vltime;
ap->flags &= ~IPV6_AF_NEW;
ap->flags |= IPV6_AF_ADDED;
if (ap->delegating_iface)
@ -669,23 +731,6 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now)
if (ap->iface->options->options & DHCPCD_IPV6RA_OWN &&
ipv6_removesubnet(ap->iface, ap) == -1)
syslog(LOG_ERR,"ipv6_removesubnet: %m");
if (ap->prefix_pltime == ND6_INFINITE_LIFETIME &&
ap->prefix_vltime == ND6_INFINITE_LIFETIME)
syslog(LOG_DEBUG,
"%s: vltime infinity, pltime infinity",
ap->iface->name);
else if (ap->prefix_pltime == ND6_INFINITE_LIFETIME)
syslog(LOG_DEBUG,
"%s: vltime %"PRIu32" seconds, pltime infinity",
ap->iface->name, ap->prefix_vltime);
else if (ap->prefix_vltime == ND6_INFINITE_LIFETIME)
syslog(LOG_DEBUG,
"%s: vltime infinity, pltime %"PRIu32"seconds",
ap->iface->name, ap->prefix_pltime);
else
syslog(LOG_DEBUG,
"%s: vltime %"PRIu32" seconds, pltime %"PRIu32" seconds",
ap->iface->name, ap->prefix_vltime, ap->prefix_pltime);
#ifdef IPV6_POLLADDRFLAG
eloop_timeout_delete(ap->iface->ctx->eloop,
@ -793,13 +838,16 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
if (ifd && ap->delegating_iface != ifd)
continue;
TAILQ_REMOVE(addrs, ap, next);
if (drop != 2)
TAILQ_REMOVE(addrs, ap, next);
eloop_q_timeout_delete(ap->iface->ctx->eloop, 0, NULL, ap);
if (drop && ap->flags & IPV6_AF_ADDED &&
(ap->iface->options->options &
(DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
(DHCPCD_EXITING | DHCPCD_PERSISTENT))
{
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 ||
@ -813,8 +861,11 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
get_monotonic(&now);
ipv6_addaddr(apf, &now);
}
if (drop == 2)
free(ap);
}
free(ap);
if (drop != 2)
free(ap);
}
}
@ -825,7 +876,7 @@ ipv6_getstate(struct interface *ifp)
state = IPV6_STATE(ifp);
if (state == NULL) {
ifp->if_data[IF_DATA_IPV6] = malloc(sizeof(*state));
ifp->if_data[IF_DATA_IPV6] = calloc(1, sizeof(*state));
state = IPV6_STATE(ifp);
if (state == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
@ -833,6 +884,12 @@ ipv6_getstate(struct interface *ifp)
}
TAILQ_INIT(&state->addrs);
TAILQ_INIT(&state->ll_callbacks);
/* Regenerate new ids */
if (ifp->options &&
ifp->options->options & DHCPCD_IPV6RA_OWN &&
ip6_use_tempaddr(ifp->name))
ipv6_regentempifid(ifp);
}
return state;
}
@ -840,7 +897,7 @@ ipv6_getstate(struct interface *ifp)
void
ipv6_handleifa(struct dhcpcd_ctx *ctx,
int cmd, struct if_head *ifs, const char *ifname,
const struct in6_addr *addr, int flags)
const struct in6_addr *addr, uint8_t prefix_len, int flags)
{
struct interface *ifp;
struct ipv6_state *state;
@ -888,16 +945,50 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
break;
case RTM_NEWADDR:
if (ap == NULL) {
char buf[INET6_ADDRSTRLEN];
const char *cbp;
ap = calloc(1, sizeof(*ap));
ap->iface = ifp;
ap->addr = *addr;
inet_ntop(AF_INET6, &addr->s6_addr,
ap->saddr, sizeof(ap->saddr));
ap->prefix_len = prefix_len;
ipv6_makeprefix(&ap->prefix, &ap->addr,
ap->prefix_len);
cbp = inet_ntop(AF_INET6, &addr->s6_addr,
buf, sizeof(buf));
if (cbp)
snprintf(ap->saddr, sizeof(ap->saddr),
"%s/%d", cbp, prefix_len);
if (if_getlifetime6(ap) == -1) {
/* No support or address vanished.
* Either way, just set a deprecated
* infinite time lifetime and continue.
* This is fine because we only want
* to know this when trying to extend
* temporary addresses.
* As we can't extend infinite, we'll
* create a new temporary address. */
ap->prefix_pltime = 0;
ap->prefix_vltime =
ND6_INFINITE_LIFETIME;
}
/* This is a minor regression against RFC 4941
* because the kernel only knows when the
* lifetimes were last updated, not when the
* address was initially created.
* Provided dhcpcd is not restarted, this
* won't be a problem.
* If we don't like it, we can always
* pretend lifetimes are infinite and always
* generate a new temporary address on
* restart. */
ap->acquired = ap->created;
TAILQ_INSERT_TAIL(&state->addrs,
ap, next);
}
ap->addr_flags = flags;
if (ap->addr_flags & IN6_IFF_TEMPORARY)
ap->flags |= IPV6_AF_TEMPORARY;
if (IN6_IS_ADDR_LINKLOCAL(&ap->addr)) {
#ifdef IPV6_POLLADDRFLAG
if (ap->addr_flags & IN6_IFF_TENTATIVE) {
@ -953,7 +1044,8 @@ ipv6_iffindaddr(const struct interface *ifp, const struct in6_addr *addr)
return NULL;
}
int ipv6_addlinklocalcallback(struct interface *ifp,
int
ipv6_addlinklocalcallback(struct interface *ifp,
void (*callback)(void *), void *arg)
{
struct ipv6_state *state;
@ -977,21 +1069,6 @@ int ipv6_addlinklocalcallback(struct interface *ifp,
return 0;
}
void
ipv6_free_ll_callbacks(struct interface *ifp)
{
struct ipv6_state *state;
struct ll_callback *cb;
state = IPV6_STATE(ifp);
if (state) {
while ((cb = TAILQ_FIRST(&state->ll_callbacks))) {
TAILQ_REMOVE(&state->ll_callbacks, cb, next);
free(cb);
}
}
}
static struct ipv6_addr *
ipv6_newlinklocal(struct interface *ifp)
{
@ -1141,6 +1218,10 @@ ipv6_start(struct interface *ifp)
!(ap->addr_flags & IN6_IFF_DUPLICATED))
break;
}
/* Regenerate new ids */
if (ifp->options->options & DHCPCD_IPV6RA_OWN &&
ip6_use_tempaddr(ifp->name))
ipv6_regentempifid(ifp);
} else
ap = NULL;
@ -1150,32 +1231,44 @@ ipv6_start(struct interface *ifp)
}
void
ipv6_free(struct interface *ifp)
ipv6_freedrop(struct interface *ifp, int drop)
{
struct ipv6_state *state;
struct ipv6_addr *ap;
struct ll_callback *cb;
if (ifp) {
ipv6_free_ll_callbacks(ifp);
state = IPV6_STATE(ifp);
if (state) {
while ((ap = TAILQ_FIRST(&state->addrs))) {
TAILQ_REMOVE(&state->addrs, ap, next);
free(ap);
}
free(state);
ifp->if_data[IF_DATA_IPV6] = NULL;
if (ifp == NULL)
return;
if ((state = IPV6_STATE(ifp)) == NULL)
return;
ipv6_freedrop_addrs(&state->addrs, drop ? 2 : 0, NULL);
/* Becuase we need to cache the addresses we don't control,
* we only free the state on when NOT dropping addresses. */
if (drop == 0) {
while ((cb = TAILQ_FIRST(&state->ll_callbacks))) {
TAILQ_REMOVE(&state->ll_callbacks, cb, next);
free(cb);
}
free(state);
ifp->if_data[IF_DATA_IPV6] = NULL;
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
}
}
void
ipv6_ctxfree(struct dhcpcd_ctx *ctx)
{
struct rt6 *rt;
if (ctx->ipv6 == NULL)
return;
while ((rt = TAILQ_FIRST(ctx->ipv6->routes))) {
TAILQ_REMOVE(ctx->ipv6->routes, rt, next);
free(rt);
}
free(ctx->ipv6->routes);
free(ctx->ipv6->ra_routers);
free(ctx->ipv6);
@ -1228,6 +1321,373 @@ ipv6_handleifa_addrs(int cmd,
return alldadcompleted ? found : 0;
}
#ifdef IPV6_MANAGETEMPADDR
static const struct ipv6_addr *
ipv6_findaddrid(struct dhcpcd_ctx *ctx, uint8_t *addr)
{
const struct interface *ifp;
const struct ipv6_state *state;
const struct ipv6_addr *ia;
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
if ((state = IPV6_CSTATE(ifp))) {
TAILQ_FOREACH(ia, &state->addrs, next) {
if (memcmp(&ia->addr.s6_addr[8], addr, 8) == 0)
return ia;
}
}
}
return NULL;
}
static const uint8_t nullid[8];
static const uint8_t anycastid[8] = {
0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 };
static const uint8_t isatapid[4] = { 0x00, 0x00, 0x5e, 0xfe };
static void
ipv6_regen_desync(struct interface *ifp, int force)
{
struct ipv6_state *state;
time_t max;
state = IPV6_STATE(ifp);
/* RFC4941 Section 5 states that DESYNC_FACTOR must never be
* greater than TEMP_VALID_LIFETIME - REGEN_ADVANCE.
* I believe this is an error and it should be never be greateter than
* TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE. */
max = ip6_temp_preferred_lifetime(ifp->name) - REGEN_ADVANCE;
if (state->desync_factor && !force && state->desync_factor < max)
return;
if (state->desync_factor == 0)
state->desync_factor =
(time_t)arc4random_uniform(MIN(MAX_DESYNC_FACTOR,
(uint32_t)max));
max = ip6_temp_preferred_lifetime(ifp->name) -
state->desync_factor - REGEN_ADVANCE;
eloop_timeout_add_sec(ifp->ctx->eloop, max, ipv6_regentempifid, ifp);
}
void
ipv6_gentempifid(struct interface *ifp)
{
struct ipv6_state *state;
MD5_CTX md5;
uint8_t seed[16], digest[16];
int retry;
state = IPV6_STATE(ifp);
retry = 0;
if (memcmp(nullid, state->randomseed0, sizeof(nullid)) == 0) {
uint32_t r;
r = arc4random();
memcpy(seed, &r, sizeof(r));
r = arc4random();
memcpy(seed + sizeof(r), &r, sizeof(r));
} else
memcpy(seed, state->randomseed0, sizeof(state->randomseed0));
memcpy(seed + sizeof(state->randomseed0),
state->randomseed1, sizeof(state->randomseed1));
again:
/* RFC4941 Section 3.2.1.1
* Take the left-most 64bits and set bit 6 to zero */
MD5Init(&md5);
MD5Update(&md5, seed, sizeof(seed));
MD5Final(digest, &md5);
/* RFC4941 Section 3.2.1.1
* Take the left-most 64bits and set bit 6 to zero */
memcpy(state->randomid, digest, sizeof(state->randomid));
state->randomid[0] &= ~EUI64_UBIT;
/* RFC4941 Section 3.2.1.4
* Reject reserved or existing id's */
if (memcmp(nullid, state->randomid, sizeof(nullid)) == 0 ||
(memcmp(anycastid, state->randomid, 7) == 0 &&
(anycastid[7] & state->randomid[7]) == anycastid[7]) ||
memcmp(isatapid, state->randomid, sizeof(isatapid)) == 0 ||
ipv6_findaddrid(ifp->ctx, state->randomid))
{
if (++retry < GEN_TEMPID_RETRY_MAX) {
memcpy(seed, digest + 8, 8);
goto again;
}
memset(state->randomid, 0, sizeof(state->randomid));
}
/* RFC4941 Section 3.2.1.6
* Save the right-most 64bits of the digest */
memcpy(state->randomseed0, digest + 8,
sizeof(state->randomseed0));
}
/* RFC4941 Section 3.3.7 */
static void
ipv6_tempdadcallback(void *arg)
{
struct ipv6_addr *ia = arg;
if (ia->flags & IPV6_AF_DUPLICATED) {
struct ipv6_addr *ia1;
struct timeval tv;
if (++ia->dadcounter == TEMP_IDGEN_RETRIES) {
syslog(LOG_ERR,
"%s: too many duplicate temporary addresses",
ia->iface->name);
return;
}
get_monotonic(&tv);
if ((ia1 = ipv6_createtempaddr(ia, &tv)) == NULL)
syslog(LOG_ERR, "ipv6_createtempaddr: %m");
else
ia1->dadcounter = ia->dadcounter;
ipv6_deleteaddr(ia);
if (ia1)
ipv6_addaddr(ia1, &ia1->acquired);
}
}
struct ipv6_addr *
ipv6_createtempaddr(struct ipv6_addr *ia0, const struct timeval *now)
{
struct ipv6_state *state;
const struct ipv6_state *cstate;
int genid;
struct in6_addr addr, mask;
uint32_t randid[2];
const struct interface *ifp;
const struct ipv6_addr *ap;
struct ipv6_addr *ia;
uint32_t i, trylimit;
char buf[INET6_ADDRSTRLEN];
const char *cbp;
trylimit = TEMP_IDGEN_RETRIES;
state = IPV6_STATE(ia0->iface);
genid = 0;
addr = ia0->addr;
ipv6_mask(&mask, ia0->prefix_len);
/* clear the old ifid */
for (i = 0; i < 4; i++)
addr.s6_addr32[i] &= mask.s6_addr32[i];
again:
if (memcmp(state->randomid, nullid, sizeof(nullid)) == 0)
genid = 1;
if (genid) {
memcpy(state->randomseed1, &ia0->addr.s6_addr[8],
sizeof(state->randomseed1));
ipv6_gentempifid(ia0->iface);
if (memcmp(state->randomid, nullid, sizeof(nullid)) == 0) {
errno = EFAULT;
return NULL;
}
}
memcpy(&randid[0], state->randomid, sizeof(randid[0]));
memcpy(&randid[1], state->randomid + sizeof(randid[1]),
sizeof(randid[2]));
addr.s6_addr32[2] |= randid[0] & ~mask.s6_addr32[2];
addr.s6_addr32[3] |= randid[1] & ~mask.s6_addr32[3];
/* Ensure we don't already have it */
TAILQ_FOREACH(ifp, ia0->iface->ctx->ifaces, next) {
cstate = IPV6_CSTATE(ifp);
if (cstate) {
TAILQ_FOREACH(ap, &cstate->addrs, next) {
if (IN6_ARE_ADDR_EQUAL(&ap->addr, &addr)) {
if (--trylimit == 0) {
errno = EEXIST;
return NULL;
}
genid = 1;
goto again;
}
}
}
}
if ((ia = calloc(1, sizeof(*ia))) == NULL)
return NULL;
ia->iface = ia0->iface;
ia->addr = addr;
/* Must be made tentative, for our DaD to work */
ia->addr_flags = IN6_IFF_TENTATIVE;
ia->dadcallback = ipv6_tempdadcallback;
ia->flags = IPV6_AF_NEW | IPV6_AF_AUTOCONF | IPV6_AF_TEMPORARY;
ia->prefix = ia0->prefix;
ia->prefix_len = ia0->prefix_len;
ia->created = ia->acquired = now ? *now : ia0->acquired;
/* Ensure desync is still valid */
ipv6_regen_desync(ia->iface, 0);
/* RFC4941 Section 3.3.4 */
i = (uint32_t)(ip6_temp_preferred_lifetime(ia0->iface->name) -
state->desync_factor);
ia->prefix_pltime = MIN(ia0->prefix_pltime, i);
i = (uint32_t)ip6_temp_valid_lifetime(ia0->iface->name);
ia->prefix_vltime = MIN(ia0->prefix_vltime, i);
if (ia->prefix_pltime <= REGEN_ADVANCE ||
ia->prefix_pltime > ia0->prefix_vltime)
{
errno = EINVAL;
free(ia);
return NULL;
}
cbp = inet_ntop(AF_INET6, &ia->addr, buf, sizeof(buf));
if (cbp)
snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
cbp, ia->prefix_len);
else
ia->saddr[0] = '\0';
TAILQ_INSERT_TAIL(&state->addrs, ia, next);
return ia;
}
void
ipv6_settempstale(struct interface *ifp)
{
struct ipv6_state *state;
struct ipv6_addr *ia;
state = IPV6_STATE(ifp);
TAILQ_FOREACH(ia, &state->addrs, next) {
if (ia->flags & IPV6_AF_TEMPORARY)
ia->flags |= IPV6_AF_STALE;
}
}
struct ipv6_addr *
ipv6_settemptime(struct ipv6_addr *ia, int flags)
{
struct ipv6_state *state;
struct ipv6_addr *ap, *first;
state = IPV6_STATE(ia->iface);
first = NULL;
TAILQ_FOREACH_REVERSE(ap, &state->addrs, ipv6_addrhead, next) {
if (ap->flags & IPV6_AF_TEMPORARY &&
ap->prefix_pltime &&
IN6_ARE_ADDR_EQUAL(&ia->prefix, &ap->prefix))
{
time_t max, ext;
if (flags == 0) {
if (ap->prefix_pltime -
(uint32_t)(ia->acquired.tv_sec -
ap->acquired.tv_sec)
< REGEN_ADVANCE)
continue;
return ap;
}
if (!(ap->flags & IPV6_AF_ADDED))
ap->flags |= IPV6_AF_NEW | IPV6_AF_AUTOCONF;
ap->flags &= ~IPV6_AF_STALE;
/* RFC4941 Section 3.4
* Deprecated prefix, deprecate the temporary address */
if (ia->prefix_pltime == 0) {
ap->prefix_pltime = 0;
goto valid;
}
/* Ensure desync is still valid */
ipv6_regen_desync(ap->iface, 0);
/* RFC4941 Section 3.3.2
* Extend temporary times, but ensure that they
* never last beyond the system limit. */
ext = ia->acquired.tv_sec + (time_t)ia->prefix_pltime;
max = ap->created.tv_sec +
ip6_temp_preferred_lifetime(ap->iface->name) -
state->desync_factor;
if (ext < max)
ap->prefix_pltime = ia->prefix_pltime;
else
ap->prefix_pltime =
(uint32_t)(max - ia->acquired.tv_sec);
valid:
ext = ia->acquired.tv_sec + (time_t)ia->prefix_vltime;
max = ap->created.tv_sec +
ip6_temp_valid_lifetime(ap->iface->name);
if (ext < max)
ap->prefix_vltime = ia->prefix_vltime;
else
ap->prefix_vltime =
(uint32_t)(max - ia->acquired.tv_sec);
/* Just extend the latest matching prefix */
ap->acquired = ia->acquired;
/* If extending return the last match as
* it's the most current.
* If deprecating, deprecate any other addresses we
* may have, although this should not be needed */
if (ia->prefix_pltime)
return ap;
if (first == NULL)
first = ap;
}
}
return first;
}
void
ipv6_addtempaddrs(struct interface *ifp, const struct timeval *now)
{
struct ipv6_state *state;
struct ipv6_addr *ia;
state = IPV6_STATE(ifp);
TAILQ_FOREACH(ia, &state->addrs, next) {
if (ia->flags & IPV6_AF_TEMPORARY &&
!(ia->flags & IPV6_AF_STALE))
ipv6_addaddr(ia, now);
}
}
static void
ipv6_regentempaddr(void *arg)
{
struct ipv6_addr *ia = arg, *ia1;
struct timeval tv;
syslog(LOG_DEBUG, "%s: regen temp addr %s",
ia->iface->name, ia->saddr);
get_monotonic(&tv);
ia1 = ipv6_createtempaddr(ia, &tv);
if (ia1)
ipv6_addaddr(ia1, &tv);
else
syslog(LOG_ERR, "ipv6_createtempaddr: %m");
}
static void
ipv6_regentempifid(void *arg)
{
struct interface *ifp = arg;
struct ipv6_state *state;
state = IPV6_STATE(ifp);
if (memcmp(state->randomid, nullid, sizeof(state->randomid)))
ipv6_gentempifid(ifp);
ipv6_regen_desync(ifp, 1);
}
#endif /* IPV6_MANAGETEMPADDR */
static struct rt6 *
find_route6(struct rt6_head *rts, const struct rt6 *r)
{

View File

@ -1,8 +1,8 @@
/* $NetBSD: ipv6.h,v 1.8 2014/12/17 20:50:08 roy Exp $ */
/* $NetBSD: ipv6.h,v 1.9 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -56,6 +56,15 @@
# define ND6_INFINITE_LIFETIME ((uint32_t)~0)
#endif
/* RFC4941 constants */
#define TEMP_VALID_LIFETIME 604800 /* 1 week */
#define TEMP_PREFERRED_LIFETIME 86400 /* 1 day */
#define REGEN_ADVANCE 5 /* seconds */
#define MAX_DESYNC_FACTOR 600 /* 10 minutes */
#define TEMP_IDGEN_RETRIES 3
#define GEN_TEMPID_RETRY_MAX 5
/* RFC7217 constants */
#define IDGEN_RETRIES 3
#define IDGEN_DELAY 1 /* second */
@ -78,6 +87,13 @@
# undef IPV6_POLLADDRFLAG
#endif
/* Linux-3.18 can manage temporary addresses even with RA
* processing disabled. */
//#undef IFA_F_MANAGETEMPADDR
#ifndef IFA_F_MANAGETEMPADDR
#define IPV6_MANAGETEMPADDR
#endif
struct ipv6_addr {
TAILQ_ENTRY(ipv6_addr) next;
struct interface *iface;
@ -85,6 +101,7 @@ struct ipv6_addr {
uint8_t prefix_len;
uint32_t prefix_vltime;
uint32_t prefix_pltime;
struct timeval created;
struct timeval acquired;
struct in6_addr addr;
int addr_flags;
@ -115,6 +132,7 @@ TAILQ_HEAD(ipv6_addrhead, ipv6_addr);
#define IPV6_AF_DELEGATEDPFX 0x0100
#define IPV6_AF_DELEGATEDZERO 0x0200
#define IPV6_AF_REQUEST 0x0400
#define IPV6_AF_TEMPORARY 0X0800
struct rt6 {
TAILQ_ENTRY(rt6) next;
@ -138,6 +156,13 @@ TAILQ_HEAD(ll_callback_head, ll_callback);
struct ipv6_state {
struct ipv6_addrhead addrs;
struct ll_callback_head ll_callbacks;
#ifdef IPV6_MANAGETEMPADDR
time_t desync_factor;
uint8_t randomseed0[8]; /* upper 64 bits of MD5 digest */
uint8_t randomseed1[8]; /* lower 64 bits */
uint8_t randomid[8];
#endif
};
#define IPV6_STATE(ifp) \
@ -145,6 +170,21 @@ struct ipv6_state {
#define IPV6_CSTATE(ifp) \
((const struct ipv6_state *)(ifp)->if_data[IF_DATA_IPV6])
/* dhcpcd requires CMSG_SPACE to evaluate to a compile time constant. */
#ifdef __QNX__
#undef CMSG_SPACE
#endif
#ifndef ALIGNBYTES
#define ALIGNBYTES (sizeof(int) - 1)
#endif
#ifndef ALIGN
#define ALIGN(p) (((unsigned int)(p) + ALIGNBYTES) & ~ALIGNBYTES)
#endif
#ifndef CMSG_SPACE
#define CMSG_SPACE(len) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(len))
#endif
#define IP6BUFLEN (CMSG_SPACE(sizeof(struct in6_pktinfo)) + \
CMSG_SPACE(sizeof(int)))
@ -188,7 +228,7 @@ ssize_t ipv6_addaddrs(struct ipv6_addrhead *addrs);
void ipv6_freedrop_addrs(struct ipv6_addrhead *, int,
const struct interface *);
void ipv6_handleifa(struct dhcpcd_ctx *ctx, int, struct if_head *,
const char *, const struct in6_addr *, int);
const char *, const struct in6_addr *, uint8_t, int);
int ipv6_handleifa_addrs(int, struct ipv6_addrhead *,
const struct in6_addr *, int);
const struct ipv6_addr *ipv6_iffindaddr(const struct interface *,
@ -197,20 +237,35 @@ struct ipv6_addr *ipv6_findaddr(struct dhcpcd_ctx *,
const struct in6_addr *, short);
#define ipv6_linklocal(ifp) (ipv6_iffindaddr((ifp), NULL))
int ipv6_addlinklocalcallback(struct interface *, void (*)(void *), void *);
void ipv6_free_ll_callbacks(struct interface *);
void ipv6_freedrop(struct interface *, int);
#define ipv6_free(ifp) ipv6_freedrop(ifp, 0)
#define ipv6_drop(ifp) ipv6_freedrop(ifp, 2)
#ifdef IPV6_MANAGETEMPADDR
void ipv6_gentempifid(struct interface *);
void ipv6_settempstale(struct interface *);
struct ipv6_addr *ipv6_createtempaddr(struct ipv6_addr *,
const struct timeval *);
struct ipv6_addr *ipv6_settemptime(struct ipv6_addr *, int);
void ipv6_addtempaddrs(struct interface *, const struct timeval *);
#else
#define ipv6_gentempifid(a) {}
#define ipv6_settempstale(a) {}
#endif
int ipv6_start(struct interface *);
void ipv6_free(struct interface *);
void ipv6_ctxfree(struct dhcpcd_ctx *);
int ipv6_routedeleted(struct dhcpcd_ctx *, const struct rt6 *);
int ipv6_removesubnet(struct interface *, struct ipv6_addr *);
void ipv6_buildroutes(struct dhcpcd_ctx *);
#else
#define ipv6_init(a) NULL
#define ipv6_init(a) (NULL)
#define ipv6_start(a) (-1)
#define ipv6_free_ll_callbacks(a)
#define ipv6_free(a)
#define ipv6_ctxfree(a)
#define ipv6_free_ll_callbacks(a) {}
#define ipv6_free(a) {}
#define ipv6_drop(a) {}
#define ipv6_ctxfree(a) {}
#endif
#endif

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: ipv6nd.c,v 1.19 2014/12/17 20:50:08 roy Exp $");
__RCSID("$NetBSD: ipv6nd.c,v 1.20 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -497,8 +497,8 @@ ipv6nd_scriptrun(struct ra *rap)
hasaddress = 0;
/* If all addresses have completed DAD run the script */
TAILQ_FOREACH(ap, &rap->addrs, next) {
if ((ap->flags & (IPV6_AF_ONLINK | IPV6_AF_AUTOCONF)) ==
(IPV6_AF_ONLINK | IPV6_AF_AUTOCONF))
if ((ap->flags & (IPV6_AF_AUTOCONF | IPV6_AF_ADDED)) ==
(IPV6_AF_AUTOCONF | IPV6_AF_ADDED))
{
hasaddress = 1;
if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
@ -566,8 +566,9 @@ ipv6nd_dadcompleted(const struct interface *ifp)
continue;
TAILQ_FOREACH(ap, &rap->addrs, next) {
if (ap->flags & IPV6_AF_AUTOCONF &&
ap->flags & IPV6_AF_ADDED &&
!(ap->flags & IPV6_AF_DADCOMPLETED))
return 0;
return 0;
}
}
return 1;
@ -650,6 +651,7 @@ try_script:
found = 0;
TAILQ_FOREACH(rapap, &rap->addrs, next) {
if (rapap->flags & IPV6_AF_AUTOCONF &&
rapap->flags & IPV6_AF_ADDED &&
(rapap->flags & IPV6_AF_DADCOMPLETED) == 0)
{
wascompleted = 0;
@ -693,6 +695,9 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
char *opt, *opt2, *tmp;
struct timeval expire;
uint8_t new_rap, new_data;
#ifdef IPV6_MANAGETEMPADDR
uint8_t new_ap;
#endif
if (len < sizeof(struct nd_router_advert)) {
syslog(LOG_ERR, "IPv6 RA packet too short from %s", ctx->sfrom);
@ -728,6 +733,12 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
return;
}
if (ipv6_iffindaddr(ifp, &ctx->from.sin6_addr)) {
syslog(LOG_DEBUG, "%s: ignoring RA from ourself %s",
ifp->name, ctx->sfrom);
return;
}
TAILQ_FOREACH(rap, ctx->ra_routers, next) {
if (ifp == rap->iface &&
IN6_ARE_ADDR_EQUAL(&rap->from, &ctx->from.sin6_addr))
@ -794,6 +805,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
if (rap->lifetime)
rap->expired = 0;
ipv6_settempstale(ifp);
TAILQ_FOREACH(ap, &rap->addrs, next) {
ap->flags |= IPV6_AF_STALE;
}
@ -867,7 +879,9 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
ap->prefix_len = pi->nd_opt_pi_prefix_len;
ap->prefix = pi->nd_opt_pi_prefix;
if (pi->nd_opt_pi_flags_reserved &
ND_OPT_PI_FLAG_AUTO)
ND_OPT_PI_FLAG_AUTO &&
ap->iface->options->options &
DHCPCD_IPV6RA_AUTOCONF)
{
ap->flags |= IPV6_AF_AUTOCONF;
ap->dadcounter =
@ -893,13 +907,31 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
ap->saddr[0] = '\0';
}
ap->dadcallback = ipv6nd_dadcallback;
ap->created = ap->acquired = rap->received;
TAILQ_INSERT_TAIL(&rap->addrs, ap, next);
} else
#ifdef IPV6_MANAGETEMPADDR
/* New address to dhcpcd RA handling.
* If the address already exists and a valid
* temporary address also exists then
* extend the existing one rather than
* create a new one */
if (ipv6_iffindaddr(ifp, &ap->addr) &&
ipv6_settemptime(ap, 0))
new_ap = 0;
else
new_ap = 1;
#endif
} else {
#ifdef IPV6_MANAGETEMPADDR
new_ap = 0;
#endif
ap->flags &= ~IPV6_AF_STALE;
ap->acquired = rap->received;
}
if (pi->nd_opt_pi_flags_reserved &
ND_OPT_PI_FLAG_ONLINK)
ap->flags |= IPV6_AF_ONLINK;
ap->acquired = rap->received;
ap->prefix_vltime =
ntohl(pi->nd_opt_pi_valid_time);
ap->prefix_pltime =
@ -915,6 +947,26 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
opt2 = strdup(ap->saddr);
}
}
#ifdef IPV6_MANAGETEMPADDR
/* RFC4941 Section 3.3.3 */
if (ap->flags & IPV6_AF_AUTOCONF &&
ap->iface->options->options & DHCPCD_IPV6RA_OWN &&
ip6_use_tempaddr(ap->iface->name))
{
if (!new_ap) {
if (ipv6_settemptime(ap, 1) == NULL)
new_ap = 1;
}
if (new_ap && ap->prefix_pltime) {
if (ipv6_createtempaddr(ap,
&ap->acquired) == NULL)
syslog(LOG_ERR,
"ipv6_createtempaddr: %m");
}
}
#endif
lifetime = ap->prefix_vltime;
break;
@ -1066,6 +1118,9 @@ extra_opt:
goto handle_flag;
}
ipv6_addaddrs(&rap->addrs);
#ifdef IPV6_MANAGETEMPADDR
ipv6_addtempaddrs(ifp, &rap->received);
#endif
ipv6_buildroutes(ifp->ctx);
if (ipv6nd_scriptrun(rap))
return;

View File

@ -1,8 +1,8 @@
/* $NetBSD: ipv6nd.h,v 1.8 2014/12/17 20:50:08 roy Exp $ */
/* $NetBSD: ipv6nd.h,v 1.9 2015/01/30 09:47:05 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -103,10 +103,10 @@ void ipv6nd_neighbour(struct dhcpcd_ctx *, struct in6_addr *, int);
#else
#define ipv6nd_startrs(a) {}
#define ipv6nd_findaddr(a, b, c) (0)
#define ipv6nd_free(a)
#define ipv6nd_free(a) {}
#define ipv6nd_hasra(a) (0)
#define ipv6nd_dadcompleted(a) (0)
#define ipv6nd_drop(a)
#define ipv6nd_drop(a) {}
#endif
#endif

View File

@ -1,9 +1,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: script.c,v 1.16 2014/12/09 20:21:05 roy Exp $");
__RCSID("$NetBSD: script.c,v 1.17 2015/01/30 09:47:05 roy Exp $");
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
* Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@ -232,7 +232,9 @@ make_env(const struct interface *ifp, const char *reason, char ***argv)
{
char **env, **nenv, *p;
size_t e, elen, l;
#if defined(INET) || defined(INET6)
ssize_t n;
#endif
const struct if_options *ifo = ifp->options;
const struct interface *ifp2;
#ifdef INET
@ -277,7 +279,9 @@ make_env(const struct interface *ifp, const char *reason, char ***argv)
strcmp(reason, "UNKNOWN") == 0 ||
strcmp(reason, "DEPARTED") == 0 ||
strcmp(reason, "STOPPED") == 0)
;
{
/* This space left intentionally blank */
}
#ifdef INET
else
dhcp = 1;