diff options
author | hrs <hrs@FreeBSD.org> | 2009-12-07 06:05:36 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2009-12-07 06:05:36 +0000 |
commit | fe3b78cf51d0fd2bd1d7bcf8f228db2990c87704 (patch) | |
tree | df30bfa350c7056b412912e444fecefc88bc35ee /sbin | |
parent | 474d50676beda16b58d9b04cf350f9d2e3daf0bd (diff) | |
download | FreeBSD-src-fe3b78cf51d0fd2bd1d7bcf8f228db2990c87704.zip FreeBSD-src-fe3b78cf51d0fd2bd1d7bcf8f228db2990c87704.tar.gz |
MFC:
r197138:
- The ifconfig(8) command now supports NDP flags which are handled by ndp(8).
r198006:
- Use printb() to display the "nd6 options=" line.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/ifconfig/Makefile | 1 | ||||
-rw-r--r-- | sbin/ifconfig/af_inet6.c | 13 | ||||
-rw-r--r-- | sbin/ifconfig/af_nd6.c | 229 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.8 | 34 |
4 files changed, 276 insertions, 1 deletions
diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile index e5b78af..367ad9c 100644 --- a/sbin/ifconfig/Makefile +++ b/sbin/ifconfig/Makefile @@ -18,6 +18,7 @@ SRCS+= af_link.c # LLC support SRCS+= af_inet.c # IPv4 support SRCS+= af_inet6.c # IPv6 support SRCS+= af_atalk.c # AppleTalk support +SRCS+= af_nd6.c # ND6 support SRCS+= ifclone.c # clone device support SRCS+= ifmac.c # MAC support diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c index 13789dc..e091ac7 100644 --- a/sbin/ifconfig/af_inet6.c +++ b/sbin/ifconfig/af_inet6.c @@ -67,6 +67,9 @@ static int prefix(void *, int); static char *sec2str(time_t); static int explicit_prefix = 0; +extern void setnd6flags(const char *, int, int, const struct afswtch *); +extern void setnd6defif(const char *, int, int, const struct afswtch *); + static char addr_buf[MAXHOSTNAMELEN *2 + 1]; /*for getnameinfo()*/ static void @@ -493,6 +496,16 @@ static struct cmd inet6_cmds[] = { DEF_CMD("-deprecated", -IN6_IFF_DEPRECATED, setip6flags), DEF_CMD("autoconf", IN6_IFF_AUTOCONF, setip6flags), DEF_CMD("-autoconf", -IN6_IFF_AUTOCONF, setip6flags), + DEF_CMD("accept_rtadv", ND6_IFF_ACCEPT_RTADV, setnd6flags), + DEF_CMD("-accept_rtadv",-ND6_IFF_ACCEPT_RTADV, setnd6flags), + DEF_CMD("defaultif", 1, setnd6defif), + DEF_CMD("-defaultif", -1, setnd6defif), + DEF_CMD("ifdisabled", ND6_IFF_IFDISABLED, setnd6flags), + DEF_CMD("-ifdisabled", -ND6_IFF_IFDISABLED, setnd6flags), + DEF_CMD("nud", ND6_IFF_PERFORMNUD, setnd6flags), + DEF_CMD("-nud", -ND6_IFF_PERFORMNUD, setnd6flags), + DEF_CMD("prefer_source",ND6_IFF_PREFER_SOURCE, setnd6flags), + DEF_CMD("-prefer_source",-ND6_IFF_PREFER_SOURCE,setnd6flags), DEF_CMD_ARG("pltime", setip6pltime), DEF_CMD_ARG("vltime", setip6vltime), DEF_CMD("eui64", 0, setip6eui64), diff --git a/sbin/ifconfig/af_nd6.c b/sbin/ifconfig/af_nd6.c new file mode 100644 index 0000000..e6b920a --- /dev/null +++ b/sbin/ifconfig/af_nd6.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2009 Hiroki Sato. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#include <sys/param.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/sysctl.h> +#include <net/if.h> +#include <net/route.h> + +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <ifaddrs.h> + +#include <arpa/inet.h> + +#include <netinet/in.h> +#include <net/if_var.h> +#include <netinet/in_var.h> +#include <arpa/inet.h> +#include <netdb.h> + +#include <netinet6/nd6.h> + +#include "ifconfig.h" + +#define MAX_SYSCTL_TRY 5 +#define ND6BITS "\020\001PERFORMNUD\002ACCEPT_RTADV\003PREFER_SOURCE" \ + "\004IFDISABLED\005DONT_SET_IFROUTE\006AUTO_LINKLOCAL" \ + "\020DEFAULTIF" + +static int isnd6defif(int); +void setnd6flags(const char *, int, int, const struct afswtch *); +void setnd6defif(const char *, int, int, const struct afswtch *); + +void +setnd6flags(const char *dummyaddr __unused, + int d, int s, + const struct afswtch *afp) +{ + struct in6_ndireq nd; + int error; + + memset(&nd, 0, sizeof(nd)); + strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname)); + error = ioctl(s, SIOCGIFINFO_IN6, &nd); + if (error) { + warn("ioctl(SIOCGIFINFO_IN6)"); + return; + } + if (d < 0) + nd.ndi.flags &= ~(-d); + else + nd.ndi.flags |= d; + error = ioctl(s, SIOCSIFINFO_IN6, (caddr_t)&nd); + if (error) + warn("ioctl(SIOCSIFINFO_IN6)"); +} + +void +setnd6defif(const char *dummyaddr __unused, + int d, int s, + const struct afswtch *afp) +{ + struct in6_ndifreq ndifreq; + int ifindex; + int error; + + memset(&ndifreq, 0, sizeof(ndifreq)); + strncpy(ndifreq.ifname, ifr.ifr_name, sizeof(ndifreq.ifname)); + + if (d < 0) { + if (isnd6defif(s)) { + /* ifindex = 0 means to remove default if */ + ifindex = 0; + } else + return; + } else if ((ifindex = if_nametoindex(ndifreq.ifname)) == 0) { + warn("if_nametoindex(%s)", ndifreq.ifname); + return; + } + + ndifreq.ifindex = ifindex; + error = ioctl(s, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq); + if (error) + warn("ioctl(SIOCSDEFIFACE_IN6)"); +} + +static int +isnd6defif(int s) +{ + struct in6_ndifreq ndifreq; + unsigned int ifindex; + int error; + + memset(&ndifreq, 0, sizeof(ndifreq)); + strncpy(ndifreq.ifname, ifr.ifr_name, sizeof(ndifreq.ifname)); + + ifindex = if_nametoindex(ndifreq.ifname); + error = ioctl(s, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq); + if (error) { + warn("ioctl(SIOCGDEFIFACE_IN6)"); + return (error); + } + return (ndifreq.ifindex == ifindex); +} + +static void +nd6_status(int s) +{ + struct in6_ndireq nd; + struct rt_msghdr *rtm; + size_t needed; + char *buf, *next; + int mib[6], ntry; + int s6; + int error; + int isinet6, isdefif; + + /* Check if the interface has at least one IPv6 address. */ + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = AF_INET6; + mib[4] = NET_RT_IFLIST; + mib[5] = if_nametoindex(ifr.ifr_name); + + /* Try to prevent a race between two sysctls. */ + ntry = 0; + do { + error = sysctl(mib, 6, NULL, &needed, NULL, 0); + if (error) { + warn("sysctl(NET_RT_IFLIST)/estimate"); + return; + } + buf = malloc(needed); + if (buf == NULL) { + warn("malloc for sysctl(NET_RT_IFLIST) failed"); + return; + } + if ((error = sysctl(mib, 6, buf, &needed, NULL, 0)) < 0) { + if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) { + warn("sysctl(NET_RT_IFLIST)/get"); + free(buf); + return; + } + free(buf); + buf = NULL; + } + } while (buf == NULL); + + isinet6 = 0; + for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)next; + + if (rtm->rtm_version != RTM_VERSION) + continue; + if (rtm->rtm_type == RTM_NEWADDR) { + isinet6 = 1; + break; + } + } + free(buf); + if (!isinet6) + return; + + memset(&nd, 0, sizeof(nd)); + strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname)); + if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + warn("socket(AF_INET6, SOCK_DGRAM)"); + return; + } + error = ioctl(s6, SIOCGIFINFO_IN6, &nd); + if (error) { + warn("ioctl(SIOCGIFINFO_IN6)"); + close(s6); + return; + } + isdefif = isnd6defif(s6); + close(s6); + if (nd.ndi.flags == 0 && !isdefif) + return; + printb("\tnd6 options", + (unsigned int)(nd.ndi.flags | (isdefif << 15)), ND6BITS); + putchar('\n'); +} + +static struct afswtch af_nd6 = { + .af_name = "nd6", + .af_af = AF_LOCAL, + .af_other_status= nd6_status, +}; + +static __constructor void +nd6_ctor(void) +{ + af_register(&af_nd6); +} diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 2b0d7d6..c372a08 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -28,7 +28,7 @@ .\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 .\" $FreeBSD$ .\" -.Dd July 8, 2009 +.Dd December 7, 2009 .Dt IFCONFIG 8 .Os .Sh NAME @@ -598,6 +598,38 @@ If the interface was reset when previously marked down, the hardware will be re-initialized. .El .Pp +The following parameters are for ICMPv6 Neightbor Discovery Protocol: +.Bl -tag -width indent +.It Cm accept_rtadv +Set a flag to enable accepting ICMPv6 Router Advertisement messages. +.It Cm -accept_rtadv +Clear a flag +.Cm accept_rtadv . +.It Cm defaultif +Set the specified interface as the default route when there is no +default router. +.It Cm -defaultif +Clear a flag +.Cm defaultif . +.It Cm ifdisabled +Set a flag to disable all of IPv6 network communications on the +specified interface. +.It Cm -ifdisabled +Clear a flag +.Cm ifdisabled . +.It Cm nud +Set a flag to enable Neighbor Unreachability Detection. +.It Cm -nud +Clear a flag +.Cm nud . +.It Cm prefer_source +Set a flag to prefer addesses on the interface as candidates of the +source address for outgoing packets. +.It Cm -prefer_source +Clear a flag +.Cm prefer_source . +.El +.Pp The following parameters are specific to cloning IEEE 802.11 wireless interfaces with the .Cm create |