Import dhcpcd-7.2.1 with the following changes:

*  auth: Use consttime_memequal to avoid latency attack
*  DHCP: Fix a potential 1 byte read overflow with DHO_OPTSOVERLOADED
*  DHCPv6: Fix a potential buffer overflow reading NA/TA addresses
This commit is contained in:
roy 2019-04-26 14:32:27 +00:00
parent 583ae9ed45
commit cdfaff8fa4
13 changed files with 249 additions and 116 deletions

View File

@ -0,0 +1,28 @@
/*
* Written by Matthias Drochner <drochner@NetBSD.org>.
* Public domain.
*/
#ifndef CONSTTIME_MEMEQUAL_H
#define CONSTTIME_MEMEQUAL_H
inline static int
consttime_memequal(const void *b1, const void *b2, size_t len)
{
const unsigned char *c1 = b1, *c2 = b2;
unsigned int res = 0;
while (len--)
res |= *c1++ ^ *c2++;
/*
* Map 0 to 1 and [1, 256) to 0 using only constant-time
* arithmetic.
*
* This is not simply `!res' because although many CPUs support
* branchless conditional moves and many compilers will take
* advantage of them, certain compilers generate branches on
* certain CPUs for `!res'.
*/
return (1 & ((res - 1) >> 8));
}
#endif /* CONSTTIME_MEMEQUAL_H */

View File

@ -13,6 +13,7 @@ IPV4LL=
INET6=
ARC4RANDOM=
CLOSEFROM=
CONSTTIME_MEMEQUAL=
STRLCPY=
UDEV=
OS=
@ -846,6 +847,27 @@ if [ "$STRTOI" = no ]; then
echo "#include \"compat/strtoi.h\"" >>$CONFIG_H
fi
if [ -z "$CONSTTIME_MEMEQUAL" ]; then
printf "Testing for consttime_memequal ... "
cat <<EOF >_consttime_memequal.c
#include <string.h>
int main(void) {
return consttime_memequal("deadbeef", "deadbeef", 8);
}
EOF
if $XCC _consttime_memequal.c -o _consttime_memequal 2>&3; then
CONSTTIME_MEMEQUAL=yes
else
CONSTTIME_MEMEQUAL=no
fi
echo "$CONSTTIME_MEMEQUAL"
rm -f _consttime_memequal.c _consttime_memequal
fi
if [ "$CONSTTIME_MEMEQUAL" = no ]; then
echo "#include \"compat/consttime_memequal.h\"" \
>>$CONFIG_H
fi
if [ -z "$DPRINTF" ]; then
printf "Testing for dprintf ... "
cat <<EOF >_dprintf.c

View File

@ -117,7 +117,11 @@ dhcp_auth_validate(struct authstate *state, const struct auth *auth,
m = vm;
data = vdata;
/* Ensure that d is inside m which *may* not be the case for DHPCPv4 */
/* Ensure that d is inside m which *may* not be the case for DHCPv4.
* This can occur if the authentication option is split using
* DHCP long option from RFC 3399. Section 9 which does infact note that
* implementations should take this into account.
* Fixing this would be problematic, patches welcome. */
if (data < m || data > m + mlen || data + dlen > m + mlen) {
errno = ERANGE;
return NULL;
@ -354,7 +358,7 @@ gottoken:
}
free(mm);
if (memcmp(d, &hmac_code, dlen)) {
if (!consttime_memequal(d, &hmac_code, dlen)) {
errno = EPERM;
return NULL;
}

View File

@ -318,7 +318,7 @@ control_open(const char *ifname)
if ((fd = make_sock(&sa, ifname, 0)) != -1) {
socklen_t len;
len = (socklen_t)SUN_LEN(&sa);
if (connect(fd, (struct sockaddr *)&sa, len) == -1) {
close(fd);

View File

@ -28,7 +28,7 @@
#define CONFIG_H
#define PACKAGE "dhcpcd"
#define VERSION "7.2.0"
#define VERSION "7.2.1"
#ifndef CONFIG
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"

View File

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd September 15, 2018
.Dd April 24, 2019
.Dt DHCPCD.CONF 5
.Os
.Sh NAME
@ -376,8 +376,7 @@ IPv6 address configuration for the internal network.
noipv6rs # disable routing solicitation
denyinterfaces eth2 # Don't touch eth2 at all
interface eth0
ipv6rs # enable routing solicitation get the
# default IPv6 route
ipv6rs # enable routing solicitation for eth0
ia_na 1 # request an IPv6 address
ia_pd 2 eth1/0 # request a PD and assign it to eth1
ia_pd 3 eth2/1 eth3/2 # req a PD and assign it to eth2 and eth3

View File

@ -180,7 +180,9 @@ struct dhcpcd_ctx {
uint8_t *secret;
size_t secret_len;
#ifndef __sun
int nd_fd;
#endif
struct ra_head *ra_routers;
int dhcp6_fd;

View File

@ -74,9 +74,9 @@ extern int getallifaddrs(sa_family_t, struct ifaddrs **, int64_t);
#endif
#ifndef RT_ROUNDUP
#define RT_ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
#define RT_ADVANCE(x, n) (x += RT_ROUNDUP(salen(n)))
#define RT_ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(int32_t) - 1))) : sizeof(int32_t))
#define RT_ADVANCE(x, n) ((x) += RT_ROUNDUP(salen((n))))
#endif
#define COPYOUT(sin, sa) do { \
@ -268,6 +268,7 @@ static boolean_t
if_newaddr(const char *ifname, void *arg)
{
struct linkwalk *lw = arg;
int error;
struct ifaddrs *ifa;
dlpi_handle_t dh;
dlpi_info_t dlinfo;
@ -276,7 +277,10 @@ if_newaddr(const char *ifname, void *arg)
struct sockaddr_dl *sdl;
ifa = NULL;
if (dlpi_open(ifname, &dh, 0) != DLPI_SUCCESS)
error = dlpi_open(ifname, &dh, 0);
if (error == DLPI_ENOLINK) /* Just vanished or in global zone */
return B_FALSE;
if (error != DLPI_SUCCESS)
goto failed1;
if (dlpi_info(dh, &dlinfo, 0) != DLPI_SUCCESS)
goto failed;
@ -317,7 +321,7 @@ if_newaddr(const char *ifname, void *arg)
ifa->ifa_next = lw->lw_ifa;
lw->lw_ifa = ifa;
dlpi_close(dh);
return (B_FALSE);
return B_FALSE;
failed:
dlpi_close(dh);
@ -328,7 +332,7 @@ failed:
}
failed1:
lw->lw_error = errno;
return (B_TRUE);
return B_TRUE;
}
/* Creates an empty sockaddr_dl for lo0. */
@ -423,14 +427,16 @@ get_addrs(int type, const void *data, const struct sockaddr **sa)
{
const char *cp;
int i;
const struct sockaddr **sap;
cp = data;
for (i = 0; i < RTAX_MAX; i++) {
sap = &sa[i];
if (type & (1 << i)) {
sa[i] = (const struct sockaddr *)cp;
RT_ADVANCE(cp, sa[i]);
*sap = (const struct sockaddr *)cp;
RT_ADVANCE(cp, *sap);
} else
sa[i] = NULL;
*sap = NULL;
}
return 0;
}
@ -520,6 +526,7 @@ if_route0(struct dhcpcd_ctx *ctx, struct rtm *rtmsg,
struct rt_msghdr *rtm;
char *bp = rtmsg->buffer;
socklen_t sl;
bool gateway_unspec;
/* WARNING: Solaris will not allow you to delete RTF_KERNEL routes.
* This includes subnet/prefix routes. */
@ -538,25 +545,28 @@ if_route0(struct dhcpcd_ctx *ctx, struct rtm *rtmsg,
rtm->rtm_flags = rt->rt_flags;
rtm->rtm_addrs = RTA_DST | RTA_GATEWAY;
gateway_unspec = sa_is_unspecified(&rt->rt_gateway);
if (cmd == RTM_ADD || cmd == RTM_CHANGE) {
bool netmask_bcast = sa_is_allones(&rt->rt_netmask);
rtm->rtm_flags |= RTF_UP;
if (!(rtm->rtm_flags & RTF_REJECT) &&
!sa_is_loopback(&rt->rt_gateway) &&
/* Solaris doesn't like interfaces on default routes. */
!sa_is_unspecified(&rt->rt_dest))
!sa_is_loopback(&rt->rt_gateway))
{
rtm->rtm_addrs |= RTA_IFP;
#if 0
/* RTA_IFA is currently ignored by the kernel.
* RTA_SRC and RTF_SETSRC look like what we want,
* but they don't work with RTF_GATEWAY.
* We set RTA_IFA just in the hope that the
* kernel will one day support this. */
if (!sa_is_unspecified(&rt->rt_ifa))
rtm->rtm_addrs |= RTA_IFA;
#endif
}
if (netmask_bcast)
rtm->rtm_flags |= RTF_HOST;
else
else if (!gateway_unspec)
rtm->rtm_flags |= RTF_GATEWAY;
/* Emulate the kernel by marking address generated
@ -575,7 +585,7 @@ if_route0(struct dhcpcd_ctx *ctx, struct rtm *rtmsg,
ADDSA(&rt->rt_dest);
if (sa_is_unspecified(&rt->rt_gateway))
if (gateway_unspec)
ADDSA(&rt->rt_ifa);
else
ADDSA(&rt->rt_gateway);
@ -590,14 +600,13 @@ if_route0(struct dhcpcd_ctx *ctx, struct rtm *rtmsg,
ADDSA((struct sockaddr *)&sdl);
}
if (rtm->rtm_addrs & RTA_IFA) {
ADDSA(&rt->rt_ifa);
rtm->rtm_addrs |= RTA_SRC;
}
if (rtm->rtm_addrs & RTA_SRC)
if (rtm->rtm_addrs & RTA_IFA)
ADDSA(&rt->rt_ifa);
#undef ADDSA
#if 0
if (rtm->rtm_addrs & RTA_SRC)
ADDSA(&rt->rt_ifa);
#endif
rtm->rtm_msglen = (unsigned short)(bp - (char *)rtm);
}
@ -747,15 +756,19 @@ if_finishrt(struct dhcpcd_ctx *ctx, struct rt *rt)
rt->rt_mtu = 0;
}
static int
if_addrflags0(int fd, const char *ifname)
static uint64_t
if_addrflags0(int fd, const char *ifname, const struct sockaddr *sa)
{
struct lifreq lifr;
memset(&lifr, 0, sizeof(lifr));
strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
if (ioctl(fd, SIOCGLIFFLAGS, &lifr) == -1)
return -1;
return 0;
if (ioctl(fd, SIOCGLIFADDR, &lifr) == -1)
return 0;
if (sa_cmp(sa, (struct sockaddr *)&lifr.lifr_addr) != 0)
return 0;
return lifr.lifr_flags;
}
@ -804,13 +817,56 @@ if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm)
}
}
static bool
if_getalias(struct interface *ifp, const struct sockaddr *sa, char *alias)
{
struct ifaddrs *ifaddrs, *ifa;
struct interface *ifpx;
bool found;
ifaddrs = NULL;
if (getallifaddrs(sa->sa_family, &ifaddrs, 0) == -1)
return false;
found = false;
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL)
continue;
if (sa_cmp(sa, ifa->ifa_addr) != 0)
continue;
/* Check it's for the right interace. */
ifpx = if_find(ifp->ctx->ifaces, ifa->ifa_name);
if (ifp == ifpx) {
strlcpy(alias, ifa->ifa_name, IF_NAMESIZE);
found = true;
break;
}
}
freeifaddrs(ifaddrs);
return found;
}
static int
if_getbrdaddr(struct dhcpcd_ctx *ctx, const char *ifname, struct in_addr *brd)
{
struct lifreq lifr = { 0 };
int r;
memset(&lifr, 0, sizeof(lifr));
strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
errno = 0;
r = ioctl(ctx->pf_inet_fd, SIOCGLIFBRDADDR, &lifr, sizeof(lifr));
if (r != -1)
COPYOUT(*brd, (struct sockaddr *)&lifr.lifr_broadaddr);
return r;
}
static void
if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
{
struct interface *ifp;
const struct sockaddr *sa, *rti_info[RTAX_MAX];
int flags;
const char *ifalias;
char ifalias[IF_NAMESIZE];
/* XXX We have no way of knowing who generated these
* messages wich truely sucks because we want to
@ -819,6 +875,7 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
return;
sa = (const void *)(ifam + 1);
get_addrs(ifam->ifam_addrs, sa, rti_info);
if ((sa = rti_info[RTAX_IFA]) == NULL)
return;
@ -835,31 +892,8 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
* ifam_alias
* ifam_pid
*/
ifalias = ifp->name;
if (ifam->ifam_type != RTM_DELADDR && sa->sa_family != AF_LINK) {
struct ifaddrs *ifaddrs, *ifa;
ifaddrs = NULL;
if (getallifaddrs(sa->sa_family, &ifaddrs, 0) == -1)
return;
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr != NULL) {
if (sa_cmp(sa, ifa->ifa_addr) == 0) {
/* Check it's for the right interace. */
struct interface *ifpx;
ifpx = if_find(ctx->ifaces,
ifa->ifa_name);
if (ifp == ifpx) {
ifalias = ifa->ifa_name;
break;
}
}
}
}
freeifaddrs(ifaddrs);
}
if (ifam->ifam_type != RTM_DELADDR && !if_getalias(ifp, sa, ifalias))
return;
switch (sa->sa_family) {
case AF_LINK:
@ -882,12 +916,25 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
COPYOUT(mask, rti_info[RTAX_NETMASK]);
COPYOUT(bcast, rti_info[RTAX_BRD]);
if (ifam->ifam_type != RTM_DELADDR) {
flags = if_addrflags0(ctx->pf_inet_fd, ifalias);
if (flags == -1)
break;
} else
flags = 0;
if (ifam->ifam_type == RTM_DELADDR) {
struct ipv4_addr *ia;
ia = ipv4_iffindaddr(ifp, &addr, &mask);
if (ia == NULL)
return;
strlcpy(ifalias, ia->alias, sizeof(ifalias));
} else if (bcast.s_addr == INADDR_ANY) {
/* Work around a bug where broadcast
* address is not correctly reported. */
if (if_getbrdaddr(ctx, ifalias, &bcast) == -1)
return;
}
flags = if_addrflags(ifp, &addr, ifalias);
if (ifam->ifam_type == RTM_DELADDR) {
if (flags != -1)
return;
} else if (flags == -1)
return;
ipv4_handleifa(ctx,
ifam->ifam_type == RTM_CHGADDR ?
@ -907,15 +954,20 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
sin6 = (const void *)rti_info[RTAX_NETMASK];
mask6 = sin6->sin6_addr;
if (ifam->ifam_type != RTM_DELADDR) {
const struct priv *priv;
if (ifam->ifam_type == RTM_DELADDR) {
struct ipv6_addr *ia;
priv = (struct priv *)ctx->priv;
flags = if_addrflags0(priv->pf_inet6_fd, ifalias);
if (flags == -1)
break;
} else
flags = 0;
ia = ipv6_iffindaddr(ifp, &addr6, 0);
if (ia == NULL)
return;
strlcpy(ifalias, ia->alias, sizeof(ifalias));
}
flags = if_addrflags6(ifp, &addr6, ifalias);
if (ifam->ifam_type == RTM_DELADDR) {
if (flags != -1)
return;
} else if (flags == -1)
return;
ipv6_handleifa(ctx,
ifam->ifam_type == RTM_CHGADDR ?
@ -1003,7 +1055,8 @@ if_octetstr(char *buf, const Octet_t *o, ssize_t len)
static int
if_addaddr(int fd, const char *ifname,
struct sockaddr_storage *addr, struct sockaddr_storage *mask)
struct sockaddr_storage *addr, struct sockaddr_storage *mask,
struct sockaddr_storage *brd)
{
struct lifreq lifr;
@ -1020,6 +1073,13 @@ if_addaddr(int fd, const char *ifname,
if (ioctl(fd, SIOCSLIFADDR, &lifr) == -1)
return -1;
/* Then assign the broadcast address. */
if (brd != NULL) {
lifr.lifr_broadaddr = *brd;
if (ioctl(fd, SIOCSLIFBRDADDR, &lifr) == -1)
return -1;
}
/* Now bring it up. */
if (ioctl(fd, SIOCGLIFFLAGS, &lifr) == -1)
return -1;
@ -1173,15 +1233,11 @@ out:
static int
if_unplumbif(const struct dhcpcd_ctx *ctx, int af, const char *ifname)
{
struct sockaddr_storage addr, mask;
struct sockaddr_storage addr = { .ss_family = af };
int fd;
/* For the time being, don't unplumb the interface, just
* set the address to zero. */
memset(&addr, 0, sizeof(addr));
addr.ss_family = af;
memset(&mask, 0, sizeof(mask));
mask.ss_family = af;
switch (af) {
#ifdef INET
case AF_INET:
@ -1202,7 +1258,8 @@ if_unplumbif(const struct dhcpcd_ctx *ctx, int af, const char *ifname)
errno = EAFNOSUPPORT;
return -1;
}
return if_addaddr(fd, ifname, &addr, &mask);
return if_addaddr(fd, ifname, &addr, &addr,
af == AF_INET ? &addr : NULL);
}
static int
@ -1306,6 +1363,7 @@ if_walkrt6(struct dhcpcd_ctx *ctx, char *data, size_t len)
ipv6_mask(&in6, re->ipv6RoutePfxLength);
sa_in6_init(&rt.rt_netmask, &in6);
sa_in6_init(&rt.rt_gateway, &re->ipv6RouteNextHop);
sa_in6_init(&rt.rt_ifa, &re->ipv6RouteInfo.re_src_addr);
rt.rt_mtu = re->ipv6RouteInfo.re_max_frag;
if_octetstr(ifname, &re->ipv6RouteIfIndex, sizeof(ifname));
rt.rt_ifp = if_find(ctx->ifaces, ifname);
@ -1456,8 +1514,10 @@ bpf_send(const struct interface *ifp, __unused int fd, uint16_t protocol,
int
if_address(unsigned char cmd, const struct ipv4_addr *ia)
{
struct sockaddr_storage ss_addr, ss_mask;
struct sockaddr_in *sin_addr, *sin_mask;
union {
struct sockaddr sa;
struct sockaddr_storage ss;
} addr, mask, brd;
/* Either remove the alias or ensure it exists. */
if (if_plumb(cmd, ia->iface->ctx, AF_INET, ia->alias) == -1)
@ -1474,24 +1534,24 @@ if_address(unsigned char cmd, const struct ipv4_addr *ia)
/* We need to update the index now */
ia->iface->index = if_nametoindex(ia->alias);
sin_addr = (struct sockaddr_in *)&ss_addr;
sin_addr->sin_family = AF_INET;
sin_addr->sin_addr = ia->addr;
sin_mask = (struct sockaddr_in *)&ss_mask;
sin_mask->sin_family = AF_INET;
sin_mask->sin_addr = ia->mask;
return if_addaddr(ia->iface->ctx->pf_inet_fd,
ia->alias, &ss_addr, &ss_mask);
sa_in_init(&addr.sa, &ia->addr);
sa_in_init(&mask.sa, &ia->mask);
sa_in_init(&brd.sa, &ia->brd);
return if_addaddr(ia->iface->ctx->pf_inet_fd, ia->alias,
&addr.ss, &mask.ss, &brd.ss);
}
int
if_addrflags(const struct interface *ifp, __unused const struct in_addr *addr,
if_addrflags(const struct interface *ifp, const struct in_addr *addr,
const char *alias)
{
int flags, aflags;
union sa_ss ss;
uint64_t aflags;
int flags;
aflags = if_addrflags0(ifp->ctx->pf_inet_fd, alias);
if (aflags == -1)
sa_in_init(&ss.sa, addr);
aflags = if_addrflags0(ifp->ctx->pf_inet_fd, alias, &ss.sa);
if (aflags == 0)
return -1;
flags = 0;
if (aflags & IFF_DUPLICATE)
@ -1505,9 +1565,12 @@ if_addrflags(const struct interface *ifp, __unused const struct in_addr *addr,
int
if_address6(unsigned char cmd, const struct ipv6_addr *ia)
{
struct sockaddr_storage ss_addr, ss_mask;
struct sockaddr_in6 *sin6_addr, *sin6_mask;
struct priv *priv;
union {
struct sockaddr sa;
struct sockaddr_in6 sin6;
struct sockaddr_storage ss;
} addr, mask;
const struct priv *priv;
int r;
/* Either remove the alias or ensure it exists. */
@ -1522,29 +1585,30 @@ if_address6(unsigned char cmd, const struct ipv6_addr *ia)
return -1;
}
priv = (struct priv *)ia->iface->ctx->priv;
sin6_addr = (struct sockaddr_in6 *)&ss_addr;
sin6_addr->sin6_family = AF_INET6;
sin6_addr->sin6_addr = ia->addr;
sin6_mask = (struct sockaddr_in6 *)&ss_mask;
sin6_mask->sin6_family = AF_INET6;
ipv6_mask(&sin6_mask->sin6_addr, ia->prefix_len);
r = if_addaddr(priv->pf_inet6_fd,
ia->alias, &ss_addr, &ss_mask);
sa_in6_init(&addr.sa, &ia->addr);
mask.sin6.sin6_family = AF_INET6;
ipv6_mask(&mask.sin6.sin6_addr, ia->prefix_len);
priv = (const struct priv *)ia->iface->ctx->priv;
r = if_addaddr(priv->pf_inet6_fd, ia->alias, &addr.ss, &mask.ss, NULL);
if (r == -1 && errno == EEXIST)
return 0;
return r;
}
int
if_addrflags6(const struct interface *ifp, __unused const struct in6_addr *addr,
if_addrflags6(const struct interface *ifp, const struct in6_addr *addr,
const char *alias)
{
struct priv *priv;
int aflags, flags;
union sa_ss ss;
uint64_t aflags;
int flags;
priv = (struct priv *)ifp->ctx->priv;
aflags = if_addrflags0(priv->pf_inet6_fd, alias);
sa_in6_init(&ss.sa, addr);
aflags = if_addrflags0(priv->pf_inet6_fd, alias, &ss.sa);
if (aflags == 0)
return -1;
flags = 0;
if (aflags & IFF_DUPLICATE)
flags |= IN6_IFF_DUPLICATED;

View File

@ -62,9 +62,8 @@
* While it supports DaD, to seems to only expose IFF_DUPLICATE
* so we have no way of knowing if it's tentative or not.
* I don't even know if Solaris has any special treatment for tentative. */
# define IN_IFF_TENTATIVE 0
# define IN_IFF_DUPLICATED 0x02
# define IN_IFF_DETACHED 0
# define IN_IFF_NOTUSEABLE IN_IFF_DUPLICATED
#endif
#ifdef IN_IFF_TENTATIVE

View File

@ -232,7 +232,7 @@ static void
ipv4ll_probe(void *arg)
{
#ifdef IN_IFF_TENTATIVE
#ifdef IN_IFF_DUPLICATED
ipv4ll_probed(arg);
#else
arp_probe(arg);
@ -404,7 +404,7 @@ ipv4ll_start(void *arg)
if (ia == NULL)
ia = ipv4_iffindlladdr(ifp);
#ifdef IN_IFF_TENTATIVE
#ifdef IN_IFF_DUPLICATED
if (ia != NULL && ia->addr_flags & IN_IFF_DUPLICATED) {
ipv4_deladdr(ia, 0);
ia = NULL;
@ -419,6 +419,8 @@ ipv4ll_start(void *arg)
ifp->name, inet_ntoa(ia->addr));
return;
}
#endif
#ifdef IN_IFF_DUPLICATED
loginfox("%s: using IPv4LL address %s", ifp->name, ia->saddr);
#endif
ipv4ll_probed(astate);
@ -429,7 +431,7 @@ ipv4ll_start(void *arg)
if (state->pickedaddr.s_addr == INADDR_ANY)
state->pickedaddr.s_addr = ipv4ll_pickaddr(astate);
astate->addr = state->pickedaddr;
#ifdef IN_IFF_TENTATIVE
#ifdef IN_IFF_DUPLICATED
ipv4ll_probed(astate);
#else
arp_probe(astate);

View File

@ -137,7 +137,9 @@ ipv6_init(struct dhcpcd_ctx *ctx)
return -1;
TAILQ_INIT(ctx->ra_routers);
#ifndef __sun
ctx->nd_fd = -1;
#endif
ctx->dhcp6_fd = -1;
return 0;
}

View File

@ -44,9 +44,6 @@
# endif
#endif
#define ALLNODES "ff02::1"
#define ALLROUTERS "ff02::2"
#define EUI64_GBIT 0x01
#define EUI64_UBIT 0x02
#define EUI64_TO_IFID(in6) do {(in6)->s6_addr[8] ^= EUI64_UBIT; } while (0)
@ -77,6 +74,17 @@
(((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 )
#endif
#ifndef IN6ADDR_LINKLOCAL_ALLNODES_INIT
#define IN6ADDR_LINKLOCAL_ALLNODES_INIT \
{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
#endif
#ifndef IN6ADDR_LINKLOCAL_ALLROUTERS_INIT
#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \
{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
#endif
/*
* BSD kernels don't inform userland of DAD results.
* See the discussion here:

View File

@ -61,6 +61,9 @@ struct rs_state {
size_t rslen;
int rsprobes;
uint32_t retrans;
#ifdef __sun
int nd_fd;
#endif
};
#define RS_STATE(a) ((struct rs_state *)(ifp)->if_data[IF_DATA_IPV6ND])