1197138Shrs/* 2197138Shrs * Copyright (c) 2009 Hiroki Sato. All rights reserved. 3197138Shrs * 4197138Shrs * Redistribution and use in source and binary forms, with or without 5197138Shrs * modification, are permitted provided that the following conditions 6197138Shrs * are met: 7197138Shrs * 1. Redistributions of source code must retain the above copyright 8197138Shrs * notice, this list of conditions and the following disclaimer. 9197138Shrs * 2. Redistributions in binary form must reproduce the above copyright 10197138Shrs * notice, this list of conditions and the following disclaimer in the 11197138Shrs * documentation and/or other materials provided with the distribution. 12197138Shrs * 13197138Shrs * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 14197138Shrs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15197138Shrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16197138Shrs * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 17197138Shrs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18197138Shrs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19197138Shrs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20197138Shrs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21197138Shrs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22197138Shrs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23197138Shrs * SUCH DAMAGE. 24197138Shrs */ 25197138Shrs 26197138Shrs#ifndef lint 27197138Shrsstatic const char rcsid[] = 28197138Shrs "$FreeBSD: releng/10.3/sbin/ifconfig/af_nd6.c 282622 2015-05-08 08:35:06Z hiren $"; 29197138Shrs#endif /* not lint */ 30197138Shrs 31197138Shrs#include <sys/param.h> 32197138Shrs#include <sys/ioctl.h> 33197138Shrs#include <sys/socket.h> 34197138Shrs#include <sys/sysctl.h> 35197138Shrs#include <net/if.h> 36197138Shrs#include <net/route.h> 37197138Shrs 38197138Shrs#include <err.h> 39197138Shrs#include <errno.h> 40197138Shrs#include <stdio.h> 41197138Shrs#include <stdlib.h> 42197138Shrs#include <string.h> 43197138Shrs#include <unistd.h> 44197138Shrs#include <ifaddrs.h> 45197138Shrs 46197138Shrs#include <arpa/inet.h> 47197138Shrs 48197138Shrs#include <netinet/in.h> 49197138Shrs#include <net/if_var.h> 50197138Shrs#include <netinet/in_var.h> 51197138Shrs#include <arpa/inet.h> 52197138Shrs#include <netdb.h> 53197138Shrs 54197138Shrs#include <netinet6/nd6.h> 55197138Shrs 56197138Shrs#include "ifconfig.h" 57197138Shrs 58197138Shrs#define MAX_SYSCTL_TRY 5 59198006Shrs#define ND6BITS "\020\001PERFORMNUD\002ACCEPT_RTADV\003PREFER_SOURCE" \ 60198006Shrs "\004IFDISABLED\005DONT_SET_IFROUTE\006AUTO_LINKLOCAL" \ 61282622Shiren "\007NO_RADR\010NO_PREFER_IFACE\011IGNORELOOP\012NO_DAD" \ 62282622Shiren "\020DEFAULTIF" 63197138Shrs 64197138Shrsstatic int isnd6defif(int); 65197138Shrsvoid setnd6flags(const char *, int, int, const struct afswtch *); 66197138Shrsvoid setnd6defif(const char *, int, int, const struct afswtch *); 67222711Shrsvoid nd6_status(int); 68197138Shrs 69197138Shrsvoid 70197138Shrssetnd6flags(const char *dummyaddr __unused, 71197138Shrs int d, int s, 72197138Shrs const struct afswtch *afp) 73197138Shrs{ 74197138Shrs struct in6_ndireq nd; 75197138Shrs int error; 76197138Shrs 77197138Shrs memset(&nd, 0, sizeof(nd)); 78197138Shrs strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname)); 79197138Shrs error = ioctl(s, SIOCGIFINFO_IN6, &nd); 80197138Shrs if (error) { 81197138Shrs warn("ioctl(SIOCGIFINFO_IN6)"); 82197138Shrs return; 83197138Shrs } 84197138Shrs if (d < 0) 85197138Shrs nd.ndi.flags &= ~(-d); 86197138Shrs else 87197138Shrs nd.ndi.flags |= d; 88197138Shrs error = ioctl(s, SIOCSIFINFO_IN6, (caddr_t)&nd); 89197138Shrs if (error) 90197138Shrs warn("ioctl(SIOCSIFINFO_IN6)"); 91197138Shrs} 92197138Shrs 93197138Shrsvoid 94197138Shrssetnd6defif(const char *dummyaddr __unused, 95197138Shrs int d, int s, 96197138Shrs const struct afswtch *afp) 97197138Shrs{ 98197138Shrs struct in6_ndifreq ndifreq; 99197138Shrs int ifindex; 100197138Shrs int error; 101197138Shrs 102197138Shrs memset(&ndifreq, 0, sizeof(ndifreq)); 103197138Shrs strncpy(ndifreq.ifname, ifr.ifr_name, sizeof(ndifreq.ifname)); 104197138Shrs 105197138Shrs if (d < 0) { 106197138Shrs if (isnd6defif(s)) { 107197138Shrs /* ifindex = 0 means to remove default if */ 108197138Shrs ifindex = 0; 109197138Shrs } else 110197138Shrs return; 111197138Shrs } else if ((ifindex = if_nametoindex(ndifreq.ifname)) == 0) { 112197138Shrs warn("if_nametoindex(%s)", ndifreq.ifname); 113197138Shrs return; 114197138Shrs } 115197138Shrs 116197138Shrs ndifreq.ifindex = ifindex; 117197138Shrs error = ioctl(s, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq); 118197138Shrs if (error) 119197138Shrs warn("ioctl(SIOCSDEFIFACE_IN6)"); 120197138Shrs} 121197138Shrs 122197138Shrsstatic int 123197138Shrsisnd6defif(int s) 124197138Shrs{ 125197138Shrs struct in6_ndifreq ndifreq; 126197138Shrs unsigned int ifindex; 127197138Shrs int error; 128197138Shrs 129197138Shrs memset(&ndifreq, 0, sizeof(ndifreq)); 130197138Shrs strncpy(ndifreq.ifname, ifr.ifr_name, sizeof(ndifreq.ifname)); 131197138Shrs 132197138Shrs ifindex = if_nametoindex(ndifreq.ifname); 133197138Shrs error = ioctl(s, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq); 134197138Shrs if (error) { 135197138Shrs warn("ioctl(SIOCGDEFIFACE_IN6)"); 136197138Shrs return (error); 137197138Shrs } 138197138Shrs return (ndifreq.ifindex == ifindex); 139197138Shrs} 140197138Shrs 141222711Shrsvoid 142197138Shrsnd6_status(int s) 143197138Shrs{ 144197138Shrs struct in6_ndireq nd; 145197138Shrs int s6; 146198006Shrs int error; 147222711Shrs int isdefif; 148197138Shrs 149197138Shrs memset(&nd, 0, sizeof(nd)); 150197138Shrs strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname)); 151197138Shrs if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 152252557Shrs if (errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) 153235285Shrs warn("socket(AF_INET6, SOCK_DGRAM)"); 154197138Shrs return; 155197138Shrs } 156197138Shrs error = ioctl(s6, SIOCGIFINFO_IN6, &nd); 157197138Shrs if (error) { 158235285Shrs if (errno != EPFNOSUPPORT) 159235285Shrs warn("ioctl(SIOCGIFINFO_IN6)"); 160197138Shrs close(s6); 161197138Shrs return; 162197138Shrs } 163197138Shrs isdefif = isnd6defif(s6); 164197138Shrs close(s6); 165197138Shrs if (nd.ndi.flags == 0 && !isdefif) 166197138Shrs return; 167198006Shrs printb("\tnd6 options", 168198006Shrs (unsigned int)(nd.ndi.flags | (isdefif << 15)), ND6BITS); 169198006Shrs putchar('\n'); 170197138Shrs} 171