Fri Sep 30 16:47:56 2016 UTC ()
ifaddrs has more data than just the address.
Use it instead of making pointless ioctl calls.


(roy)
diff -r1.20 -r1.21 src/sbin/ifconfig/af_inet.c
diff -r1.36 -r1.37 src/sbin/ifconfig/af_inet6.c

cvs diff -r1.20 -r1.21 src/sbin/ifconfig/af_inet.c (expand / switch to unified diff)

--- src/sbin/ifconfig/af_inet.c 2016/09/13 00:20:51 1.20
+++ src/sbin/ifconfig/af_inet.c 2016/09/30 16:47:56 1.21
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: af_inet.c,v 1.20 2016/09/13 00:20:51 christos Exp $ */ 1/* $NetBSD: af_inet.c,v 1.21 2016/09/30 16:47:56 roy Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1983, 1993 4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34__RCSID("$NetBSD: af_inet.c,v 1.20 2016/09/13 00:20:51 christos Exp $"); 34__RCSID("$NetBSD: af_inet.c,v 1.21 2016/09/30 16:47:56 roy Exp $");
35#endif /* not lint */ 35#endif /* not lint */
36 36
37#include <sys/param.h>  37#include <sys/param.h>
38#include <sys/ioctl.h>  38#include <sys/ioctl.h>
39#include <sys/socket.h> 39#include <sys/socket.h>
40 40
41#include <net/if.h>  41#include <net/if.h>
42#include <netinet/in.h> 42#include <netinet/in.h>
43#include <netinet/in_var.h> 43#include <netinet/in_var.h>
44 44
45#include <arpa/inet.h> 45#include <arpa/inet.h>
46 46
47#include <assert.h> 47#include <assert.h>
@@ -52,149 +52,99 @@ __RCSID("$NetBSD: af_inet.c,v 1.20 2016/ @@ -52,149 +52,99 @@ __RCSID("$NetBSD: af_inet.c,v 1.20 2016/
52#include <string.h> 52#include <string.h>
53#include <stdlib.h> 53#include <stdlib.h>
54#include <stdio.h> 54#include <stdio.h>
55#include <util.h> 55#include <util.h>
56 56
57#include "env.h" 57#include "env.h"
58#include "extern.h" 58#include "extern.h"
59#include "af_inetany.h" 59#include "af_inetany.h"
60#include "prog_ops.h" 60#include "prog_ops.h"
61 61
62static void in_constructor(void) __attribute__((constructor)); 62static void in_constructor(void) __attribute__((constructor));
63static void in_status(prop_dictionary_t, prop_dictionary_t, bool); 63static void in_status(prop_dictionary_t, prop_dictionary_t, bool);
64static void in_commit_address(prop_dictionary_t, prop_dictionary_t); 64static void in_commit_address(prop_dictionary_t, prop_dictionary_t);
65static bool in_addr_flags(struct ifaddrs *, int); 
66static bool in_addr_tentative(struct ifaddrs *); 65static bool in_addr_tentative(struct ifaddrs *);
67static bool in_addr_tentative_or_detached(struct ifaddrs *); 66static bool in_addr_tentative_or_detached(struct ifaddrs *);
68static void in_alias(const char *, prop_dictionary_t, prop_dictionary_t, 67static void in_alias(struct ifaddrs *, prop_dictionary_t, prop_dictionary_t,
69 struct in_aliasreq *); 68 bool);
70 69
71static struct afswtch af = { 70static struct afswtch af = {
72 .af_name = "inet", .af_af = AF_INET, .af_status = in_status, 71 .af_name = "inet", .af_af = AF_INET, .af_status = in_status,
73 .af_addr_commit = in_commit_address, 72 .af_addr_commit = in_commit_address,
74 .af_addr_tentative = in_addr_tentative, 73 .af_addr_tentative = in_addr_tentative,
75 .af_addr_tentative_or_detached = in_addr_tentative_or_detached 74 .af_addr_tentative_or_detached = in_addr_tentative_or_detached
76}; 75};
77 76
78static void 77static void
79in_alias(const char *ifname, prop_dictionary_t env, prop_dictionary_t oenv, 78in_alias(struct ifaddrs *ifa, prop_dictionary_t env, prop_dictionary_t oenv,
80 struct in_aliasreq *creq) 79 bool alias)
81{ 80{
82 struct ifreq ifr; 81 struct sockaddr_in sin;
83 bool alias; 
84 int s; 
85 unsigned short flags; 
86 struct in_aliasreq in_addreq; 
87 const struct sockaddr_in * const asin = &in_addreq.ifra_addr; 
88 const struct sockaddr_in * const dsin = &in_addreq.ifra_dstaddr; 
89 const struct sockaddr_in * const bsin = &in_addreq.ifra_broadaddr; 
90 char hbuf[NI_MAXHOST]; 82 char hbuf[NI_MAXHOST];
91 const int niflag = Nflag ? 0 : NI_NUMERICHOST; 83 const int niflag = Nflag ? 0 : NI_NUMERICHOST;
 84 char fbuf[1024];
92 85
93 if (lflag) 86 if (lflag)
94 return; 87 return;
95 88
96 alias = true; 89 if (getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len,
97 
98 /* Get the non-alias address for this interface. */ 
99 if ((s = getsock(AF_INET)) == -1) { 
100 if (errno == EAFNOSUPPORT) 
101 return; 
102 err(EXIT_FAILURE, "socket"); 
103 } 
104 memset(&ifr, 0, sizeof(ifr)); 
105 estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 
106 if (prog_ioctl(s, SIOCGIFADDR, &ifr) == -1) { 
107 if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) 
108 return; 
109 warn("SIOCGIFADDR"); 
110 } 
111 /* If creq and ifr are the same address, this is not an alias. */ 
112 if (memcmp(&ifr.ifr_addr, &creq->ifra_addr, sizeof(ifr.ifr_addr)) == 0) 
113 alias = false; 
114 in_addreq = *creq; 
115 if (prog_ioctl(s, SIOCGIFALIAS, &in_addreq) == -1) { 
116 if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { 
117 return; 
118 } else 
119 warn("SIOCGIFALIAS"); 
120 } 
121 
122 if (getnameinfo((const struct sockaddr *)asin, asin->sin_len, 
123 hbuf, sizeof(hbuf), NULL, 0, niflag)) 90 hbuf, sizeof(hbuf), NULL, 0, niflag))
124 strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ 91 strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */
125 printf("\tinet %s%s", alias ? "alias " : "", hbuf); 92 printf("\tinet %s%s", alias ? "alias " : "", hbuf);
126 93
127 if (getifflags(env, oenv, &flags) == -1) 94 if (ifa->ifa_flags & IFF_POINTOPOINT) {
128 err(EXIT_FAILURE, "%s: getifflags", __func__); 95 if (getnameinfo(ifa->ifa_dstaddr, ifa->ifa_dstaddr->sa_len,
129 
130 if (flags & IFF_POINTOPOINT) { 
131 if (getnameinfo((const struct sockaddr *)dsin, dsin->sin_len, 
132 hbuf, sizeof(hbuf), NULL, 0, niflag)) 96 hbuf, sizeof(hbuf), NULL, 0, niflag))
133 strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ 97 strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */
134 printf(" -> %s", hbuf); 98 printf(" -> %s", hbuf);
135 } 99 }
136 100
137 printf(" netmask 0x%x", ntohl(in_addreq.ifra_mask.sin_addr.s_addr)); 101 memcpy(&sin, ifa->ifa_netmask, ifa->ifa_netmask->sa_len);
 102 printf(" netmask 0x%x", ntohl(sin.sin_addr.s_addr));
138 103
139 if (flags & IFF_BROADCAST) { 104 if (ifa->ifa_flags & IFF_BROADCAST) {
140 if (getnameinfo((const struct sockaddr *)bsin, bsin->sin_len, 105 if (getnameinfo(ifa->ifa_broadaddr, ifa->ifa_broadaddr->sa_len,
141 hbuf, sizeof(hbuf), NULL, 0, niflag)) 106 hbuf, sizeof(hbuf), NULL, 0, niflag))
142 strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ 107 strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */
143 printf(" broadcast %s", hbuf); 108 printf(" broadcast %s", hbuf);
144 } 109 }
145 110
146#ifdef IN_IFF_TENTATIVE 111 (void)snprintb(fbuf, sizeof(fbuf), IN_IFFBITS, ifa->ifa_addrflags);
147 memcpy(&ifr.ifr_addr, &creq->ifra_addr, creq->ifra_addr.sin_len); 112 printf(" flags %s", fbuf);
148 if (prog_ioctl(s, SIOCGIFAFLAG_IN, &ifr) == -1) { 
149 if (errno != EADDRNOTAVAIL) 
150 warn("SIOCGIFAFLAG_IN"); 
151 } else { 
152 char fbuf[1024]; 
153 (void)snprintb(fbuf, sizeof(fbuf), IN_IFFBITS, 
154 ifr.ifr_addrflags); 
155 printf(" flags %s", fbuf); 
156 } 
157#endif 
158} 113}
159 114
160static void 115static void
161in_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force) 116in_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force)
162{ 117{
163 struct ifaddrs *ifap, *ifa; 118 struct ifaddrs *ifap, *ifa;
164 struct in_aliasreq ifra; 
165 bool printprefs = false; 119 bool printprefs = false;
166 const char *ifname; 120 const char *ifname;
 121 int alias = 0;
167 122
168 if ((ifname = getifname(env)) == NULL) 123 if ((ifname = getifname(env)) == NULL)
169 err(EXIT_FAILURE, "%s: getifname", __func__); 124 err(EXIT_FAILURE, "%s: getifname", __func__);
170 125
171 if (getifaddrs(&ifap) != 0) 126 if (getifaddrs(&ifap) != 0)
172 err(EXIT_FAILURE, "getifaddrs"); 127 err(EXIT_FAILURE, "getifaddrs");
173 128
174 printprefs = ifa_any_preferences(ifname, ifap, AF_INET); 129 printprefs = ifa_any_preferences(ifname, ifap, AF_INET);
175 130
176 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { 131 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
177 if (strcmp(ifname, ifa->ifa_name) != 0) 132 if (strcmp(ifname, ifa->ifa_name) != 0)
178 continue; 133 continue;
179 if (ifa->ifa_addr->sa_family != AF_INET) 134 if (ifa->ifa_addr->sa_family != AF_INET)
180 continue; 135 continue;
181 if (sizeof(ifra.ifra_addr) < ifa->ifa_addr->sa_len) 136 /* The first address is not an alias. */
182 continue; 137 in_alias(ifa, env, oenv, alias++);
183 
184 memset(&ifra, 0, sizeof(ifra)); 
185 estrlcpy(ifra.ifra_name, ifa->ifa_name, sizeof(ifra.ifra_name)); 
186 memcpy(&ifra.ifra_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len); 
187 in_alias(ifa->ifa_name, env, oenv, &ifra); 
188 if (printprefs) 138 if (printprefs)
189 ifa_print_preference(ifa->ifa_name, ifa->ifa_addr); 139 ifa_print_preference(ifa->ifa_name, ifa->ifa_addr);
190 printf("\n"); 140 printf("\n");
191 } 141 }
192 freeifaddrs(ifap); 142 freeifaddrs(ifap);
193} 143}
194 144
195static void 145static void
196in_commit_address(prop_dictionary_t env, prop_dictionary_t oenv) 146in_commit_address(prop_dictionary_t env, prop_dictionary_t oenv)
197{ 147{
198 struct ifreq in_ifr; 148 struct ifreq in_ifr;
199 struct in_aliasreq in_ifra; 149 struct in_aliasreq in_ifra;
200 struct afparam inparam = { 150 struct afparam inparam = {
@@ -234,36 +184,36 @@ in_addr_flags(struct ifaddrs *ifa, int f @@ -234,36 +184,36 @@ in_addr_flags(struct ifaddrs *ifa, int f
234 if ((s = getsock(AF_INET)) == -1) 184 if ((s = getsock(AF_INET)) == -1)
235 err(EXIT_FAILURE, "%s: getsock", __func__); 185 err(EXIT_FAILURE, "%s: getsock", __func__);
236 if (prog_ioctl(s, SIOCGIFAFLAG_IN, &ifr) == -1) 186 if (prog_ioctl(s, SIOCGIFAFLAG_IN, &ifr) == -1)
237 err(EXIT_FAILURE, "SIOCGIFAFLAG_IN"); 187 err(EXIT_FAILURE, "SIOCGIFAFLAG_IN");
238 return ifr.ifr_addrflags & flags ? true : false; 188 return ifr.ifr_addrflags & flags ? true : false;
239 return false; 189 return false;
240} 190}
241#endif 191#endif
242 192
243static bool 193static bool
244in_addr_tentative(struct ifaddrs *ifa) 194in_addr_tentative(struct ifaddrs *ifa)
245{ 195{
246 196
247#ifdef IN_IFF_TENTATIVE 197#ifdef SIOCGIFAFLAG_IN
248 return in_addr_flags(ifa, IN_IFF_TENTATIVE); 198 return in_addr_flags(ifa, IN_IFF_TENTATIVE);
249#else 199#else
250 return false; 200 return false;
251#endif 201#endif
252} 202}
253 203
254static bool 204static bool
255in_addr_tentative_or_detached(struct ifaddrs *ifa) 205in_addr_tentative_or_detached(struct ifaddrs *ifa)
256{ 206{
257 207
258#ifdef IN_IFF_TENTATIVE 208#ifdef SIOCGIFAFLAG_IN
259 return in_addr_flags(ifa, IN_IFF_TENTATIVE | IN_IFF_DETACHED); 209 return in_addr_flags(ifa, IN_IFF_TENTATIVE | IN_IFF_DETACHED);
260#else 210#else
261 return false; 211 return false;
262#endif 212#endif
263} 213}
264 214
265static void 215static void
266in_constructor(void) 216in_constructor(void)
267{ 217{
268 register_family(&af); 218 register_family(&af);
269} 219}

cvs diff -r1.36 -r1.37 src/sbin/ifconfig/af_inet6.c (expand / switch to unified diff)

--- src/sbin/ifconfig/af_inet6.c 2016/09/13 00:20:51 1.36
+++ src/sbin/ifconfig/af_inet6.c 2016/09/30 16:47:56 1.37
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: af_inet6.c,v 1.36 2016/09/13 00:20:51 christos Exp $ */ 1/* $NetBSD: af_inet6.c,v 1.37 2016/09/30 16:47:56 roy Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1983, 1993 4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34__RCSID("$NetBSD: af_inet6.c,v 1.36 2016/09/13 00:20:51 christos Exp $"); 34__RCSID("$NetBSD: af_inet6.c,v 1.37 2016/09/30 16:47:56 roy Exp $");
35#endif /* not lint */ 35#endif /* not lint */
36 36
37#include <sys/param.h>  37#include <sys/param.h>
38#include <sys/ioctl.h>  38#include <sys/ioctl.h>
39#include <sys/socket.h> 39#include <sys/socket.h>
40 40
41#include <net/if.h>  41#include <net/if.h>
42#include <netinet/in.h> 42#include <netinet/in.h>
43#include <netinet/in_var.h> 43#include <netinet/in_var.h>
44#include <netinet6/nd6.h> 44#include <netinet6/nd6.h>
45 45
46#include <err.h> 46#include <err.h>
47#include <errno.h> 47#include <errno.h>
@@ -50,39 +50,37 @@ __RCSID("$NetBSD: af_inet6.c,v 1.36 2016 @@ -50,39 +50,37 @@ __RCSID("$NetBSD: af_inet6.c,v 1.36 2016
50#include <string.h> 50#include <string.h>
51#include <stdlib.h> 51#include <stdlib.h>
52#include <stdio.h> 52#include <stdio.h>
53#include <util.h> 53#include <util.h>
54 54
55#include "env.h" 55#include "env.h"
56#include "extern.h" 56#include "extern.h"
57#include "parse.h" 57#include "parse.h"
58#include "extern.h" 58#include "extern.h"
59#include "af_inetany.h" 59#include "af_inetany.h"
60#include "prog_ops.h" 60#include "prog_ops.h"
61 61
62static void in6_constructor(void) __attribute__((constructor)); 62static void in6_constructor(void) __attribute__((constructor));
63static void in6_alias(const char *, prop_dictionary_t, prop_dictionary_t, 63static void in6_alias(struct ifaddrs *, prop_dictionary_t, prop_dictionary_t);
64 struct in6_ifreq *); 
65static void in6_commit_address(prop_dictionary_t, prop_dictionary_t); 64static void in6_commit_address(prop_dictionary_t, prop_dictionary_t);
66 65
67static int setia6eui64_impl(prop_dictionary_t, struct in6_aliasreq *); 66static int setia6eui64_impl(prop_dictionary_t, struct in6_aliasreq *);
68static int setia6flags_impl(prop_dictionary_t, struct in6_aliasreq *); 67static int setia6flags_impl(prop_dictionary_t, struct in6_aliasreq *);
69static int setia6pltime_impl(prop_dictionary_t, struct in6_aliasreq *); 68static int setia6pltime_impl(prop_dictionary_t, struct in6_aliasreq *);
70static int setia6vltime_impl(prop_dictionary_t, struct in6_aliasreq *); 69static int setia6vltime_impl(prop_dictionary_t, struct in6_aliasreq *);
71 70
72static int setia6lifetime(prop_dictionary_t, int64_t, time_t *, uint32_t *); 71static int setia6lifetime(prop_dictionary_t, int64_t, time_t *, uint32_t *);
73 72
74static void in6_status(prop_dictionary_t, prop_dictionary_t, bool); 73static void in6_status(prop_dictionary_t, prop_dictionary_t, bool);
75static bool in6_addr_flags(struct ifaddrs *ifa, int); 
76static bool in6_addr_tentative(struct ifaddrs *ifa); 74static bool in6_addr_tentative(struct ifaddrs *ifa);
77static bool in6_addr_tentative_or_detached(struct ifaddrs *ifa); 75static bool in6_addr_tentative_or_detached(struct ifaddrs *ifa);
78 76
79static struct usage_func usage; 77static struct usage_func usage;
80static cmdloop_branch_t branch[2]; 78static cmdloop_branch_t branch[2];
81 79
82static const struct kwinst ia6flagskw[] = { 80static const struct kwinst ia6flagskw[] = {
83 IFKW("anycast", IN6_IFF_ANYCAST) 81 IFKW("anycast", IN6_IFF_ANYCAST)
84 , IFKW("deprecated", IN6_IFF_DEPRECATED) 82 , IFKW("deprecated", IN6_IFF_DEPRECATED)
85}; 83};
86 84
87static struct pinteger parse_pltime = PINTEGER_INITIALIZER(&parse_pltime, 85static struct pinteger parse_pltime = PINTEGER_INITIALIZER(&parse_pltime,
88 "pltime", 0, NULL, "pltime", &command_root.pb_parser); 86 "pltime", 0, NULL, "pltime", &command_root.pb_parser);
@@ -252,101 +250,77 @@ setia6eui64_impl(prop_dictionary_t env,  @@ -252,101 +250,77 @@ setia6eui64_impl(prop_dictionary_t env,
252 } 250 }
253 } 251 }
254 if (lladdr == NULL) 252 if (lladdr == NULL)
255 errx(EXIT_FAILURE, "could not determine link local address");  253 errx(EXIT_FAILURE, "could not determine link local address");
256 254
257 memcpy(&in6->s6_addr[8], &lladdr->s6_addr[8], 8); 255 memcpy(&in6->s6_addr[8], &lladdr->s6_addr[8], 8);
258 256
259 freeifaddrs(ifap); 257 freeifaddrs(ifap);
260 return 0; 258 return 0;
261} 259}
262 260
263/* XXX not really an alias */ 261/* XXX not really an alias */
264void 262void
265in6_alias(const char *ifname, prop_dictionary_t env, prop_dictionary_t oenv, 263in6_alias(struct ifaddrs *ifa, prop_dictionary_t env, prop_dictionary_t oenv)
266 struct in6_ifreq *creq) 
267{ 264{
268 struct in6_ifreq ifr6; 
269 struct sockaddr_in6 *sin6; 265 struct sockaddr_in6 *sin6;
270 char hbuf[NI_MAXHOST]; 266 char hbuf[NI_MAXHOST];
271 u_int32_t scopeid; 267 u_int32_t scopeid;
272 int s; 
273 const int niflag = Nflag ? 0 : NI_NUMERICHOST; 268 const int niflag = Nflag ? 0 : NI_NUMERICHOST;
274 unsigned short flags; 269 char fbuf[1024];
275 
276 /* Get the non-alias address for this interface. */ 
277 if ((s = getsock(AF_INET6)) == -1) { 
278 if (errno == EAFNOSUPPORT) 
279 return; 
280 err(EXIT_FAILURE, "socket"); 
281 } 
282 
283 sin6 = &creq->ifr_addr; 
284 270
 271 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
285 inet6_getscopeid(sin6, INET6_IS_ADDR_LINKLOCAL); 272 inet6_getscopeid(sin6, INET6_IS_ADDR_LINKLOCAL);
286 scopeid = sin6->sin6_scope_id; 273 scopeid = sin6->sin6_scope_id;
287 if (getnameinfo((const struct sockaddr *)sin6, sin6->sin6_len, 274 if (getnameinfo((const struct sockaddr *)sin6, sin6->sin6_len,
288 hbuf, sizeof(hbuf), NULL, 0, niflag)) 275 hbuf, sizeof(hbuf), NULL, 0, niflag))
289 strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ 276 strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */
290 printf("\tinet6 %s", hbuf); 277 printf("\tinet6 %s", hbuf);
 278 inet6_putscopeid(sin6, INET6_IS_ADDR_LINKLOCAL);
291 279
292 if (getifflags(env, oenv, &flags) == -1) 280 if (ifa->ifa_flags & IFF_POINTOPOINT) {
293 err(EXIT_FAILURE, "%s: getifflags", __func__); 281 sin6 = (struct sockaddr_in6 *)ifa->ifa_dstaddr;
294 
295 if (flags & IFF_POINTOPOINT) { 
296 ifr6 = *creq; 
297 if (prog_ioctl(s, SIOCGIFDSTADDR_IN6, &ifr6) == -1) { 
298 if (errno != EADDRNOTAVAIL) 
299 warn("SIOCGIFDSTADDR_IN6"); 
300 memset(&ifr6.ifr_addr, 0, sizeof(ifr6.ifr_addr)); 
301 ifr6.ifr_addr.sin6_family = AF_INET6; 
302 ifr6.ifr_addr.sin6_len = sizeof(struct sockaddr_in6); 
303 } 
304 sin6 = &ifr6.ifr_addr; 
305 inet6_getscopeid(sin6, INET6_IS_ADDR_LINKLOCAL); 282 inet6_getscopeid(sin6, INET6_IS_ADDR_LINKLOCAL);
306 hbuf[0] = '\0'; 283 hbuf[0] = '\0';
307 if (getnameinfo((struct sockaddr *)sin6, sin6->sin6_len, 284 if (getnameinfo((struct sockaddr *)sin6, sin6->sin6_len,
308 hbuf, sizeof(hbuf), NULL, 0, niflag)) 285 hbuf, sizeof(hbuf), NULL, 0, niflag))
309 strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ 286 strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */
310 printf(" -> %s", hbuf); 287 printf(" -> %s", hbuf);
311 } 288 }
312 289
313 ifr6 = *creq; 290 sin6 = (struct sockaddr_in6 *)ifa->ifa_netmask;
314 if (prog_ioctl(s, SIOCGIFNETMASK_IN6, &ifr6) == -1) { 291 printf(" prefixlen %d", prefix(&sin6->sin6_addr,
315 if (errno != EADDRNOTAVAIL) 292 sizeof(struct in6_addr)));
316 warn("SIOCGIFNETMASK_IN6"); 293
317 } else { 294 (void)snprintb(fbuf, sizeof(fbuf), IN6_IFFBITS, ifa->ifa_addrflags);
318 sin6 = &ifr6.ifr_addr; 295 printf(" flags %s", fbuf);
319 printf(" prefixlen %d", prefix(&sin6->sin6_addr, 
320 sizeof(struct in6_addr))); 
321 } 
322 
323 ifr6 = *creq; 
324 if (prog_ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) == -1) { 
325 if (errno != EADDRNOTAVAIL) 
326 warn("SIOCGIFAFLAG_IN6"); 
327 } else { 
328 char fbuf[1024]; 
329 (void)snprintb(fbuf, sizeof(fbuf), IN6_IFFBITS, 
330 ifr6.ifr_ifru.ifru_flags6); 
331 printf(" flags %s", fbuf); 
332 } 
333 296
334 if (scopeid) 297 if (scopeid)
335 printf(" scopeid 0x%x", scopeid); 298 printf(" scopeid 0x%x", scopeid);
336 299
337 if (get_flag('L')) { 300 if (get_flag('L')) {
 301 int s;
 302 struct in6_ifreq ifr6;
338 struct in6_addrlifetime *lifetime; 303 struct in6_addrlifetime *lifetime;
339 ifr6 = *creq; 304
 305 if ((s = getsock(AF_INET6)) == -1) {
 306 if (errno == EAFNOSUPPORT)
 307 return;
 308 err(EXIT_FAILURE, "socket");
 309 }
 310
 311 memset(&ifr6, 0, sizeof(ifr6));
 312 estrlcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
 313 memcpy(&ifr6.ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len);
340 lifetime = &ifr6.ifr_ifru.ifru_lifetime; 314 lifetime = &ifr6.ifr_ifru.ifru_lifetime;
341 if (prog_ioctl(s, SIOCGIFALIFETIME_IN6, &ifr6) == -1) { 315 if (prog_ioctl(s, SIOCGIFALIFETIME_IN6, &ifr6) == -1) {
342 if (errno != EADDRNOTAVAIL) 316 if (errno != EADDRNOTAVAIL)
343 warn("SIOCGIFALIFETIME_IN6"); 317 warn("SIOCGIFALIFETIME_IN6");
344 } else if (lifetime->ia6t_preferred || lifetime->ia6t_expire) { 318 } else if (lifetime->ia6t_preferred || lifetime->ia6t_expire) {
345 time_t t = time(NULL); 319 time_t t = time(NULL);
346 printf(" pltime "); 320 printf(" pltime ");
347 if (lifetime->ia6t_preferred) { 321 if (lifetime->ia6t_preferred) {
348 printf("%lu", 322 printf("%lu",
349 (unsigned long)(lifetime->ia6t_preferred - 323 (unsigned long)(lifetime->ia6t_preferred -
350 MIN(t, lifetime->ia6t_preferred))); 324 MIN(t, lifetime->ia6t_preferred)));
351 } else 325 } else
352 printf("infty"); 326 printf("infty");
@@ -356,48 +330,41 @@ in6_alias(const char *ifname, prop_dicti @@ -356,48 +330,41 @@ in6_alias(const char *ifname, prop_dicti
356 printf("%lu", 330 printf("%lu",
357 (unsigned long)(lifetime->ia6t_expire - 331 (unsigned long)(lifetime->ia6t_expire -
358 MIN(t, lifetime->ia6t_expire))); 332 MIN(t, lifetime->ia6t_expire)));
359 } else 333 } else
360 printf("infty"); 334 printf("infty");
361 } 335 }
362 } 336 }
363} 337}
364 338
365static void 339static void
366in6_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force) 340in6_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force)
367{ 341{
368 struct ifaddrs *ifap, *ifa; 342 struct ifaddrs *ifap, *ifa;
369 struct in6_ifreq ifr; 
370 const char *ifname; 343 const char *ifname;
371 bool printprefs = false; 344 bool printprefs = false;
372 345
373 if ((ifname = getifname(env)) == NULL) 346 if ((ifname = getifname(env)) == NULL)
374 err(EXIT_FAILURE, "%s: getifname", __func__); 347 err(EXIT_FAILURE, "%s: getifname", __func__);
375 348
376 if (getifaddrs(&ifap) != 0) 349 if (getifaddrs(&ifap) != 0)
377 err(EXIT_FAILURE, "getifaddrs"); 350 err(EXIT_FAILURE, "getifaddrs");
378 printprefs = ifa_any_preferences(ifname, ifap, AF_INET6); 351 printprefs = ifa_any_preferences(ifname, ifap, AF_INET6);
379 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 352 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
380 if (strcmp(ifname, ifa->ifa_name) != 0) 353 if (strcmp(ifname, ifa->ifa_name) != 0)
381 continue; 354 continue;
382 if (ifa->ifa_addr->sa_family != AF_INET6) 355 if (ifa->ifa_addr->sa_family != AF_INET6)
383 continue; 356 continue;
384 if (sizeof(ifr.ifr_addr) < ifa->ifa_addr->sa_len) 357 in6_alias(ifa, env, oenv);
385 continue; 
386 
387 memset(&ifr, 0, sizeof(ifr)); 
388 estrlcpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); 
389 memcpy(&ifr.ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len); 
390 in6_alias(ifname, env, oenv, &ifr); 
391 if (printprefs) 358 if (printprefs)
392 ifa_print_preference(ifa->ifa_name, ifa->ifa_addr); 359 ifa_print_preference(ifa->ifa_name, ifa->ifa_addr);
393 printf("\n"); 360 printf("\n");
394 } 361 }
395 freeifaddrs(ifap); 362 freeifaddrs(ifap);
396} 363}
397 364
398static int 365static int
399in6_pre_aifaddr(prop_dictionary_t env, const struct afparam *param) 366in6_pre_aifaddr(prop_dictionary_t env, const struct afparam *param)
400{ 367{
401 struct in6_aliasreq *ifra = param->req.buf; 368 struct in6_aliasreq *ifra = param->req.buf;
402 369
403 setia6eui64_impl(env, ifra); 370 setia6eui64_impl(env, ifra);