/*
- * Copyright (c) 2009-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2017, 2020 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* SUCH DAMAGE.
*/
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD: src/sbin/ifconfig/af_inet6.c,v 1.6.6.1 2008/11/25 02:59:29 kensmith Exp $";
-#endif /* not lint */
#include <sys/param.h>
#include <sys/ioctl.h>
#define ND6BITS "\020\001PERFORMNUD\002ACCEPT_RTADV\003PREFER_SOURCE" \
"\004IFDISABLED\005DONT_SET_IFROUTE\006PROXY_PREFIXES" \
- "\007IGNORE_NA\010INSECURE"
+ "\007IGNORE_NA\010INSECURE\011REPLICATED\012DAD"
static struct in6_ifreq in6_ridreq;
static struct in6_aliasreq in6_addreq =
int error;
memset(&nd, 0, sizeof(nd));
- strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname));
+ strlcpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname));
error = ioctl(s, SIOCGIFINFO_IN6, &nd);
if (error) {
warn("ioctl(SIOCGIFINFO_IN6)");
if (sin == NULL)
return;
- strncpy(ifr6.ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name));
+ strlcpy(ifr6.ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name));
if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
warn("socket(AF_INET6,SOCK_DGRAM)");
return;
printf("autoconf ");
if ((flags6 & IN6_IFF_TEMPORARY) != 0)
printf("temporary ");
+ if ((flags6 & IN6_IFF_DYNAMIC) != 0)
+ printf("dynamic ");
if ((flags6 & IN6_IFF_SECURED) != 0)
printf("secured ");
+ if ((flags6 & IN6_IFF_CLAT46) != 0)
+ printf("clat46 ");
if (scopeid)
printf("scopeid 0x%x ", scopeid);
const struct sockaddr *sa = (const struct sockaddr *) &in6_ifr.ifr_addr;
memset(&in6_ifr, 0, sizeof(in6_ifr));
- strncpy(in6_ifr.ifr_name, name, IFNAMSIZ);
+ strlcpy(in6_ifr.ifr_name, name, sizeof(in6_ifr.ifr_name));
if (ioctl(s, SIOCGIFPSRCADDR_IN6, (caddr_t)&in6_ifr) < 0)
return;
int error;
memset(&nd, 0, sizeof(nd));
- strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname));
+ strlcpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname));
if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
if (errno != EPROTONOSUPPORT)
warn("socket(AF_INET6, SOCK_DGRAM)");
struct in6_aliasreq in6_addreq;
memset(&in6_addreq, 0, sizeof(in6_addreq));
- strncpy(in6_addreq.ifra_name, name, IFNAMSIZ);
+ strlcpy(in6_addreq.ifra_name, name, sizeof(in6_addreq.ifra_name));
memcpy(&in6_addreq.ifra_addr, srcres->ai_addr, srcres->ai_addr->sa_len);
memcpy(&in6_addreq.ifra_dstaddr, dstres->ai_addr,
dstres->ai_addr->sa_len);
warn("SIOCSIFPHYADDR_IN6");
}
+#ifndef IPV6_ROUTER_MODE_EXCLUSIVE
+#define IPV6_ROUTER_MODE_DISABLED 0
+#define IPV6_ROUTER_MODE_EXCLUSIVE 1
+#define IPV6_ROUTER_MODE_HYBRID 2
+#endif /* IPV6_ROUTER_MODE_EXCLUSIVE */
+
static void
in6_set_router(int s, int enable)
{
struct ifreq ifr;
bzero(&ifr, sizeof (ifr));
- strncpy(ifr.ifr_name, name, IFNAMSIZ);
- ifr.ifr_intval = enable;
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ ifr.ifr_intval = (enable == 0)
+ ? IPV6_ROUTER_MODE_DISABLED
+ : IPV6_ROUTER_MODE_EXCLUSIVE;
if (ioctl(s, SIOCSETROUTERMODE_IN6, &ifr) < 0)
warn("SIOCSETROUTERMODE_IN6");
}
+static int
+routermode_from_string(char * str, int *mode_p)
+{
+ int success = 1;
+
+ if (strcasecmp(str, "exclusive") == 0 ||
+ strcasecmp(str, "enabled") == 0) {
+ *mode_p = IPV6_ROUTER_MODE_EXCLUSIVE;
+ } else if (strcasecmp(str, "hybrid") == 0) {
+ *mode_p = IPV6_ROUTER_MODE_HYBRID;
+ } else if (strcasecmp(str, "disabled") == 0) {
+ *mode_p = IPV6_ROUTER_MODE_DISABLED;
+ } else {
+ success = 0;
+ }
+ return (success);
+}
+
+static const char *
+routermode_string(int mode)
+{
+ const char * str;
+
+ switch (mode) {
+ case IPV6_ROUTER_MODE_EXCLUSIVE:
+ str = "enabled";
+ break;
+ case IPV6_ROUTER_MODE_HYBRID:
+ str = "hybrid";
+ break;
+ case IPV6_ROUTER_MODE_DISABLED:
+ str = "disabled";
+ break;
+ default:
+ str = "<unknown>";
+ break;
+ }
+ return str;
+}
+
+static int
+in6_routermode(int s, int argc, char *const*argv)
+{
+ struct in6_ifreq ifr;
+ int ret;
+
+ bzero(&ifr, sizeof (ifr));
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ if (argc == 0) {
+ ret = 0;
+#ifndef SIOCGETROUTERMODE_IN6
+#define SIOCGETROUTERMODE_IN6 _IOWR('i', 137, struct in6_ifreq)
+#endif /* SIOCGETROUTERMODE_IN6 */
+ if (ioctl(s, SIOCGETROUTERMODE_IN6, &ifr) < 0) {
+ if (argv != NULL) {
+ warn("SIOCGETROUTERMODE_IN6");
+ }
+ } else {
+ /* argv is NULL if we're called from status() */
+ printf("%s%s\n",
+ (argv == NULL) ? "\troutermode6: " : "",
+ routermode_string(ifr.ifr_intval));
+ }
+ ret = 0;
+ } else {
+ int mode;
+
+ if (routermode_from_string(argv[0], &mode) == 0) {
+ errx(EXIT_FAILURE,
+ "mode '%s' invalid, must be one of "
+ "disabled, exclusive, or hybrid",
+ argv[0]);
+ }
+ ifr.ifr_intval = mode;
+ if (ioctl(s, SIOCSETROUTERMODE_IN6, &ifr) < 0) {
+ warn("SIOCSETROUTERMODE_IN6");
+ }
+ ret = 1;
+ }
+ return ret;
+}
+
static struct cmd inet6_cmds[] = {
DEF_CMD_ARG("prefixlen", setifprefixlen),
DEF_CMD("anycast", IN6_IFF_ANYCAST, setip6flags),
/* RFC 4429, section 3.1, says:
* "Optimistic DAD SHOULD NOT be used for manually entered
* addresses."
- *
- * DEF_CMD("optimistic", IN6_IFF_OPTIMISTIC, setip6flags),
- * DEF_CMD("-optimistic", -IN6_IFF_OPTIMISTIC, setip6flags),
+ * it's not a MUST...
*/
+ DEF_CMD("optimistic", IN6_IFF_OPTIMISTIC, setip6flags),
+ DEF_CMD("-optimistic", -IN6_IFF_OPTIMISTIC, setip6flags),
DEF_CMD("deprecated", IN6_IFF_DEPRECATED, setip6flags),
DEF_CMD("-deprecated", -IN6_IFF_DEPRECATED, setip6flags),
DEF_CMD("autoconf", IN6_IFF_AUTOCONF, setip6flags),
DEF_CMD("-nud", -ND6_IFF_PERFORMNUD, setnd6flags),
DEF_CMD("ifdisabled", ND6_IFF_IFDISABLED, setnd6flags),
DEF_CMD("-ifdisabled", -ND6_IFF_IFDISABLED, setnd6flags),
- DEF_CMD("ignore_na", ND6_IFF_IGNORE_NA, setnd6flags),
- DEF_CMD("-ignore_na", -ND6_IFF_IGNORE_NA, setnd6flags),
+ DEF_CMD("replicated", ND6_IFF_REPLICATED, setnd6flags),
+ DEF_CMD("-replicated", -ND6_IFF_REPLICATED, setnd6flags),
DEF_CMD("proxy_prefixes", ND6_IFF_PROXY_PREFIXES, setnd6flags),
DEF_CMD("-proxy_prefixes", -ND6_IFF_PROXY_PREFIXES, setnd6flags),
DEF_CMD("insecure", ND6_IFF_INSECURE, setnd6flags),
DEF_CMD("eui64", 0, setip6eui64),
DEF_CMD("secured", IN6_IFF_SECURED, setip6flags),
DEF_CMD("-secured", -IN6_IFF_SECURED, setip6flags),
+ DEF_CMD("dad", ND6_IFF_DAD, setnd6flags),
+ DEF_CMD("-dad", -ND6_IFF_DAD, setnd6flags),
};
static struct afswtch af_inet6 = {
.af_status_tunnel = in6_status_tunnel,
.af_settunnel = in6_set_tunnel,
.af_setrouter = in6_set_router,
+ .af_routermode = in6_routermode,
.af_difaddr = SIOCDIFADDR_IN6,
.af_aifaddr = SIOCAIFADDR_IN6,
.af_ridreq = &in6_ridreq,