Module Name: src Committed By: roy Date: Fri Jan 30 09:47:05 UTC 2015
Modified Files: src/external/bsd/dhcpcd/dist: arp.c arp.h auth.c auth.h common.c common.h control.c control.h defs.h dev.h dhcp-common.c dhcp-common.h dhcp.c dhcp.h dhcp6.c dhcp6.h dhcpcd-definitions.conf dhcpcd-embedded.c dhcpcd-embedded.h dhcpcd-run-hooks.8.in dhcpcd.8.in dhcpcd.c dhcpcd.conf.5.in dhcpcd.h duid.c duid.h eloop.c eloop.h if-bsd.c if-options.c if-options.h if.c if.h ipv4.c ipv4.h ipv4ll.c ipv6.c ipv6.h ipv6nd.c ipv6nd.h script.c src/external/bsd/dhcpcd/dist/crypt: crypt.h hmac_md5.c Log Message: Sync To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/external/bsd/dhcpcd/dist/arp.c \ src/external/bsd/dhcpcd/dist/dhcp6.c \ src/external/bsd/dhcpcd/dist/dhcpcd.h src/external/bsd/dhcpcd/dist/ipv6.h \ src/external/bsd/dhcpcd/dist/ipv6nd.h cvs rdiff -u -r1.7 -r1.8 src/external/bsd/dhcpcd/dist/arp.h \ src/external/bsd/dhcpcd/dist/auth.c src/external/bsd/dhcpcd/dist/auth.h \ src/external/bsd/dhcpcd/dist/common.c \ src/external/bsd/dhcpcd/dist/eloop.c \ src/external/bsd/dhcpcd/dist/if-options.h \ src/external/bsd/dhcpcd/dist/if.h src/external/bsd/dhcpcd/dist/ipv4.h \ src/external/bsd/dhcpcd/dist/ipv4ll.c src/external/bsd/dhcpcd/dist/ipv6.c cvs rdiff -u -r1.6 -r1.7 src/external/bsd/dhcpcd/dist/common.h \ src/external/bsd/dhcpcd/dist/control.c \ src/external/bsd/dhcpcd/dist/control.h src/external/bsd/dhcpcd/dist/dev.h \ src/external/bsd/dhcpcd/dist/dhcp-common.c \ src/external/bsd/dhcpcd/dist/dhcp-common.h \ src/external/bsd/dhcpcd/dist/dhcp.h src/external/bsd/dhcpcd/dist/dhcp6.h \ src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf \ src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c \ src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h \ src/external/bsd/dhcpcd/dist/duid.c src/external/bsd/dhcpcd/dist/duid.h \ src/external/bsd/dhcpcd/dist/eloop.h cvs rdiff -u -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/defs.h \ src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in cvs rdiff -u -r1.26 -r1.27 src/external/bsd/dhcpcd/dist/dhcp.c cvs rdiff -u -r1.39 -r1.40 src/external/bsd/dhcpcd/dist/dhcpcd.8.in cvs rdiff -u -r1.21 -r1.22 src/external/bsd/dhcpcd/dist/dhcpcd.c cvs rdiff -u -r1.17 -r1.18 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in cvs rdiff -u -r1.16 -r1.17 src/external/bsd/dhcpcd/dist/if-bsd.c \ src/external/bsd/dhcpcd/dist/script.c cvs rdiff -u -r1.19 -r1.20 src/external/bsd/dhcpcd/dist/if-options.c \ src/external/bsd/dhcpcd/dist/ipv6nd.c cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/if.c \ src/external/bsd/dhcpcd/dist/ipv4.c cvs rdiff -u -r1.5 -r1.6 src/external/bsd/dhcpcd/dist/crypt/crypt.h \ src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/bsd/dhcpcd/dist/arp.c diff -u src/external/bsd/dhcpcd/dist/arp.c:1.8 src/external/bsd/dhcpcd/dist/arp.c:1.9 --- src/external/bsd/dhcpcd/dist/arp.c:1.8 Wed Nov 26 13:43:06 2014 +++ src/external/bsd/dhcpcd/dist/arp.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/dhcp6.c diff -u src/external/bsd/dhcpcd/dist/dhcp6.c:1.8 src/external/bsd/dhcpcd/dist/dhcp6.c:1.9 --- src/external/bsd/dhcpcd/dist/dhcp6.c:1.8 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/dhcp6.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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, uint 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, cons } 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 *i 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 *i /* 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, in 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); Index: src/external/bsd/dhcpcd/dist/dhcpcd.h diff -u src/external/bsd/dhcpcd/dist/dhcpcd.h:1.8 src/external/bsd/dhcpcd/dist/dhcpcd.h:1.9 --- src/external/bsd/dhcpcd/dist/dhcpcd.h:1.8 Wed Nov 26 13:43:06 2014 +++ src/external/bsd/dhcpcd/dist/dhcpcd.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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; Index: src/external/bsd/dhcpcd/dist/ipv6.h diff -u src/external/bsd/dhcpcd/dist/ipv6.h:1.8 src/external/bsd/dhcpcd/dist/ipv6.h:1.9 --- src/external/bsd/dhcpcd/dist/ipv6.h:1.8 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/ipv6.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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_addrhe 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 d 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 Index: src/external/bsd/dhcpcd/dist/ipv6nd.h diff -u src/external/bsd/dhcpcd/dist/ipv6nd.h:1.8 src/external/bsd/dhcpcd/dist/ipv6nd.h:1.9 --- src/external/bsd/dhcpcd/dist/ipv6nd.h:1.8 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/ipv6nd.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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 #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 Index: src/external/bsd/dhcpcd/dist/arp.h diff -u src/external/bsd/dhcpcd/dist/arp.h:1.7 src/external/bsd/dhcpcd/dist/arp.h:1.8 --- src/external/bsd/dhcpcd/dist/arp.h:1.7 Fri Dec 19 10:54:08 2014 +++ src/external/bsd/dhcpcd/dist/arp.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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 Index: src/external/bsd/dhcpcd/dist/auth.c diff -u src/external/bsd/dhcpcd/dist/auth.c:1.7 src/external/bsd/dhcpcd/dist/auth.c:1.8 --- src/external/bsd/dhcpcd/dist/auth.c:1.7 Fri Nov 14 12:00:54 2014 +++ src/external/bsd/dhcpcd/dist/auth.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/auth.h diff -u src/external/bsd/dhcpcd/dist/auth.h:1.7 src/external/bsd/dhcpcd/dist/auth.h:1.8 --- src/external/bsd/dhcpcd/dist/auth.h:1.7 Fri Nov 14 12:00:54 2014 +++ src/external/bsd/dhcpcd/dist/auth.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/common.c diff -u src/external/bsd/dhcpcd/dist/common.c:1.7 src/external/bsd/dhcpcd/dist/common.c:1.8 --- src/external/bsd/dhcpcd/dist/common.c:1.7 Fri Nov 14 12:00:54 2014 +++ src/external/bsd/dhcpcd/dist/common.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/eloop.c diff -u src/external/bsd/dhcpcd/dist/eloop.c:1.7 src/external/bsd/dhcpcd/dist/eloop.c:1.8 --- src/external/bsd/dhcpcd/dist/eloop.c:1.7 Fri Nov 14 12:00:54 2014 +++ src/external/bsd/dhcpcd/dist/eloop.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/if-options.h diff -u src/external/bsd/dhcpcd/dist/if-options.h:1.7 src/external/bsd/dhcpcd/dist/if-options.h:1.8 --- src/external/bsd/dhcpcd/dist/if-options.h:1.7 Wed Nov 26 13:43:06 2014 +++ src/external/bsd/dhcpcd/dist/if-options.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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; Index: src/external/bsd/dhcpcd/dist/if.h diff -u src/external/bsd/dhcpcd/dist/if.h:1.7 src/external/bsd/dhcpcd/dist/if.h:1.8 --- src/external/bsd/dhcpcd/dist/if.h:1.7 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/if.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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) Index: src/external/bsd/dhcpcd/dist/ipv4.h diff -u src/external/bsd/dhcpcd/dist/ipv4.h:1.7 src/external/bsd/dhcpcd/dist/ipv4.h:1.8 --- src/external/bsd/dhcpcd/dist/ipv4.h:1.7 Wed Nov 26 13:43:06 2014 +++ src/external/bsd/dhcpcd/dist/ipv4.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/ipv4ll.c diff -u src/external/bsd/dhcpcd/dist/ipv4ll.c:1.7 src/external/bsd/dhcpcd/dist/ipv4ll.c:1.8 --- src/external/bsd/dhcpcd/dist/ipv4ll.c:1.7 Fri Nov 14 12:00:54 2014 +++ src/external/bsd/dhcpcd/dist/ipv4ll.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/ipv6.c diff -u src/external/bsd/dhcpcd/dist/ipv6.c:1.7 src/external/bsd/dhcpcd/dist/ipv6.c:1.8 --- src/external/bsd/dhcpcd/dist/ipv6.c:1.7 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/ipv6.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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) -# endif -# ifdef IF_F_DADFAILED -# define IN6_IFF_DUPLICATED IFA_F_DADFAILED -# else -# define IN6_IFF_DUPLICATED 0x08 +#ifndef __linux__ +# ifndef __QNX__ +# include <sys/endian.h> # 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 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 } } + 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 (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 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 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 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 * 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 int 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) { Index: src/external/bsd/dhcpcd/dist/common.h diff -u src/external/bsd/dhcpcd/dist/common.h:1.6 src/external/bsd/dhcpcd/dist/common.h:1.7 --- src/external/bsd/dhcpcd/dist/common.h:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/common.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/control.c diff -u src/external/bsd/dhcpcd/dist/control.c:1.6 src/external/bsd/dhcpcd/dist/control.c:1.7 --- src/external/bsd/dhcpcd/dist/control.c:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/control.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/control.h diff -u src/external/bsd/dhcpcd/dist/control.h:1.6 src/external/bsd/dhcpcd/dist/control.h:1.7 --- src/external/bsd/dhcpcd/dist/control.h:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/control.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/dev.h diff -u src/external/bsd/dhcpcd/dist/dev.h:1.6 src/external/bsd/dhcpcd/dist/dev.h:1.7 --- src/external/bsd/dhcpcd/dist/dev.h:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/dev.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions Index: src/external/bsd/dhcpcd/dist/dhcp-common.c diff -u src/external/bsd/dhcpcd/dist/dhcp-common.c:1.6 src/external/bsd/dhcpcd/dist/dhcp-common.c:1.7 --- src/external/bsd/dhcpcd/dist/dhcp-common.c:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/dhcp-common.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/dhcp-common.h diff -u src/external/bsd/dhcpcd/dist/dhcp-common.h:1.6 src/external/bsd/dhcpcd/dist/dhcp-common.h:1.7 --- src/external/bsd/dhcpcd/dist/dhcp-common.h:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/dhcp-common.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/dhcp.h diff -u src/external/bsd/dhcpcd/dist/dhcp.h:1.6 src/external/bsd/dhcpcd/dist/dhcp.h:1.7 --- src/external/bsd/dhcpcd/dist/dhcp.h:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/dhcp.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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 Index: src/external/bsd/dhcpcd/dist/dhcp6.h diff -u src/external/bsd/dhcpcd/dist/dhcp6.h:1.6 src/external/bsd/dhcpcd/dist/dhcp6.h:1.7 --- src/external/bsd/dhcpcd/dist/dhcp6.h:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/dhcp6.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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 *, cons 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 Index: src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf diff -u src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.6 src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.7 --- src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf Fri Jan 30 09:47:05 2015 @@ -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) Index: src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c diff -u src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.6 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.7 --- src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h diff -u src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h:1.6 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h:1.7 --- src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/duid.c diff -u src/external/bsd/dhcpcd/dist/duid.c:1.6 src/external/bsd/dhcpcd/dist/duid.c:1.7 --- src/external/bsd/dhcpcd/dist/duid.c:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/duid.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/duid.h diff -u src/external/bsd/dhcpcd/dist/duid.h:1.6 src/external/bsd/dhcpcd/dist/duid.h:1.7 --- src/external/bsd/dhcpcd/dist/duid.h:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/duid.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/eloop.h diff -u src/external/bsd/dhcpcd/dist/eloop.h:1.6 src/external/bsd/dhcpcd/dist/eloop.h:1.7 --- src/external/bsd/dhcpcd/dist/eloop.h:1.6 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/eloop.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/defs.h diff -u src/external/bsd/dhcpcd/dist/defs.h:1.12 src/external/bsd/dhcpcd/dist/defs.h:1.13 --- src/external/bsd/dhcpcd/dist/defs.h:1.12 Fri Dec 19 10:54:08 2014 +++ src/external/bsd/dhcpcd/dist/defs.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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" Index: src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in diff -u src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.12 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.13 --- src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.12 Fri Nov 7 20:51:02 2014 +++ src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in Fri Jan 30 09:47:05 2015 @@ -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 Index: src/external/bsd/dhcpcd/dist/dhcp.c diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.26 src/external/bsd/dhcpcd/dist/dhcp.c:1.27 --- src/external/bsd/dhcpcd/dist/dhcp.c:1.26 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/dhcp.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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, /* 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, 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, 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, Index: src/external/bsd/dhcpcd/dist/dhcpcd.8.in diff -u src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.39 src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.40 --- src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.39 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/dhcpcd.8.in Fri Jan 30 09:47:05 2015 @@ -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\ 213 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 r...@marples.name .Sh BUGS Index: src/external/bsd/dhcpcd/dist/dhcpcd.c diff -u src/external/bsd/dhcpcd/dist/dhcpcd.c:1.21 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.22 --- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.21 Sat Dec 20 13:15:48 2014 +++ src/external/bsd/dhcpcd/dist/dhcpcd.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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 *i 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 * 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 * #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 ac 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, in 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 Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.17 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.18 --- src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.17 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in Fri Jan 30 09:47:05 2015 @@ -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 i .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 Index: src/external/bsd/dhcpcd/dist/if-bsd.c diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.16 src/external/bsd/dhcpcd/dist/if-bsd.c:1.17 --- src/external/bsd/dhcpcd/dist/if-bsd.c:1.16 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/if-bsd.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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, con 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, i 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 *add } 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 acti } #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, con 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, con 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; Index: src/external/bsd/dhcpcd/dist/script.c diff -u src/external/bsd/dhcpcd/dist/script.c:1.16 src/external/bsd/dhcpcd/dist/script.c:1.17 --- src/external/bsd/dhcpcd/dist/script.c:1.16 Tue Dec 9 20:21:05 2014 +++ src/external/bsd/dhcpcd/dist/script.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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, co { 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, co strcmp(reason, "UNKNOWN") == 0 || strcmp(reason, "DEPARTED") == 0 || strcmp(reason, "STOPPED") == 0) - ; + { + /* This space left intentionally blank */ + } #ifdef INET else dhcp = 1; Index: src/external/bsd/dhcpcd/dist/if-options.c diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.19 src/external/bsd/dhcpcd/dist/if-options.c:1.20 --- src/external/bsd/dhcpcd/dist/if-options.c:1.19 Wed Nov 26 13:43:06 2014 +++ src/external/bsd/dhcpcd/dist/if-options.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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, con 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, con 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, con 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, con 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, con 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, con 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; Index: src/external/bsd/dhcpcd/dist/ipv6nd.c diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.19 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.20 --- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.19 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/ipv6nd.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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 interfa 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, st 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, st 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, st 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, st 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, st 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, st 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; Index: src/external/bsd/dhcpcd/dist/if.c diff -u src/external/bsd/dhcpcd/dist/if.c:1.10 src/external/bsd/dhcpcd/dist/if.c:1.11 --- src/external/bsd/dhcpcd/dist/if.c:1.10 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/if.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@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 { 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 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 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 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 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 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, 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; } Index: src/external/bsd/dhcpcd/dist/ipv4.c diff -u src/external/bsd/dhcpcd/dist/ipv4.c:1.10 src/external/bsd/dhcpcd/dist/ipv4.c:1.11 --- src/external/bsd/dhcpcd/dist/ipv4.c:1.10 Wed Dec 17 20:50:08 2014 +++ src/external/bsd/dhcpcd/dist/ipv4.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/crypt/crypt.h diff -u src/external/bsd/dhcpcd/dist/crypt/crypt.h:1.5 src/external/bsd/dhcpcd/dist/crypt/crypt.h:1.6 --- src/external/bsd/dhcpcd/dist/crypt/crypt.h:1.5 Fri Nov 7 20:51:03 2014 +++ src/external/bsd/dhcpcd/dist/crypt/crypt.h Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without Index: src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c diff -u src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c:1.5 src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c:1.6 --- src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c:1.5 Fri Nov 7 20:51:03 2014 +++ src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c Fri Jan 30 09:47:05 2015 @@ -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 <r...@marples.name> + * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without