1*90b80121SDavid van Moolenbroek /* $NetBSD: util.c,v 1.17 2013/10/19 00:35:30 christos Exp $ */
2*90b80121SDavid van Moolenbroek
3*90b80121SDavid van Moolenbroek /*-
4*90b80121SDavid van Moolenbroek * Copyright (c) 2008 David Young. All rights reserved.
5*90b80121SDavid van Moolenbroek *
6*90b80121SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
7*90b80121SDavid van Moolenbroek * modification, are permitted provided that the following conditions
8*90b80121SDavid van Moolenbroek * are met:
9*90b80121SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
10*90b80121SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
11*90b80121SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
12*90b80121SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
13*90b80121SDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
14*90b80121SDavid van Moolenbroek *
15*90b80121SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16*90b80121SDavid van Moolenbroek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*90b80121SDavid van Moolenbroek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*90b80121SDavid van Moolenbroek * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19*90b80121SDavid van Moolenbroek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20*90b80121SDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21*90b80121SDavid van Moolenbroek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22*90b80121SDavid van Moolenbroek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23*90b80121SDavid van Moolenbroek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24*90b80121SDavid van Moolenbroek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25*90b80121SDavid van Moolenbroek * SUCH DAMAGE.
26*90b80121SDavid van Moolenbroek */
27*90b80121SDavid van Moolenbroek
28*90b80121SDavid van Moolenbroek #include <sys/cdefs.h>
29*90b80121SDavid van Moolenbroek #ifndef lint
30*90b80121SDavid van Moolenbroek __RCSID("$NetBSD: util.c,v 1.17 2013/10/19 00:35:30 christos Exp $");
31*90b80121SDavid van Moolenbroek #endif /* not lint */
32*90b80121SDavid van Moolenbroek
33*90b80121SDavid van Moolenbroek #include <ctype.h>
34*90b80121SDavid van Moolenbroek #include <err.h>
35*90b80121SDavid van Moolenbroek #include <errno.h>
36*90b80121SDavid van Moolenbroek #include <netdb.h>
37*90b80121SDavid van Moolenbroek #include <stddef.h>
38*90b80121SDavid van Moolenbroek #include <stdio.h>
39*90b80121SDavid van Moolenbroek #include <stdlib.h>
40*90b80121SDavid van Moolenbroek #include <string.h>
41*90b80121SDavid van Moolenbroek #include <unistd.h>
42*90b80121SDavid van Moolenbroek #include <util.h>
43*90b80121SDavid van Moolenbroek
44*90b80121SDavid van Moolenbroek #include <sys/param.h>
45*90b80121SDavid van Moolenbroek #include <sys/types.h>
46*90b80121SDavid van Moolenbroek #include <sys/socket.h>
47*90b80121SDavid van Moolenbroek #include <ifaddrs.h>
48*90b80121SDavid van Moolenbroek
49*90b80121SDavid van Moolenbroek #include <sys/ioctl.h>
50*90b80121SDavid van Moolenbroek #include <net/if.h>
51*90b80121SDavid van Moolenbroek #include <net/if_dl.h>
52*90b80121SDavid van Moolenbroek #include <netinet/in.h> /* XXX */
53*90b80121SDavid van Moolenbroek
54*90b80121SDavid van Moolenbroek #include "env.h"
55*90b80121SDavid van Moolenbroek #include "extern.h"
56*90b80121SDavid van Moolenbroek #include "util.h"
57*90b80121SDavid van Moolenbroek #include "prog_ops.h"
58*90b80121SDavid van Moolenbroek
59*90b80121SDavid van Moolenbroek int
getsock(int naf)60*90b80121SDavid van Moolenbroek getsock(int naf)
61*90b80121SDavid van Moolenbroek {
62*90b80121SDavid van Moolenbroek static int oaf = -1, s;
63*90b80121SDavid van Moolenbroek
64*90b80121SDavid van Moolenbroek if (oaf == naf || (oaf != -1 && naf == AF_UNSPEC))
65*90b80121SDavid van Moolenbroek return s;
66*90b80121SDavid van Moolenbroek
67*90b80121SDavid van Moolenbroek if (oaf != -1)
68*90b80121SDavid van Moolenbroek prog_close(s);
69*90b80121SDavid van Moolenbroek
70*90b80121SDavid van Moolenbroek if (naf == AF_UNSPEC)
71*90b80121SDavid van Moolenbroek naf = AF_INET;
72*90b80121SDavid van Moolenbroek
73*90b80121SDavid van Moolenbroek s = prog_socket(naf, SOCK_DGRAM, 0);
74*90b80121SDavid van Moolenbroek if (s == -1)
75*90b80121SDavid van Moolenbroek oaf = -1;
76*90b80121SDavid van Moolenbroek else
77*90b80121SDavid van Moolenbroek oaf = naf;
78*90b80121SDavid van Moolenbroek return s;
79*90b80121SDavid van Moolenbroek }
80*90b80121SDavid van Moolenbroek
81*90b80121SDavid van Moolenbroek const char *
get_string(const char * val,const char * sep,u_int8_t * buf,int * lenp,bool hexok)82*90b80121SDavid van Moolenbroek get_string(const char *val, const char *sep, u_int8_t *buf, int *lenp,
83*90b80121SDavid van Moolenbroek bool hexok)
84*90b80121SDavid van Moolenbroek {
85*90b80121SDavid van Moolenbroek int len;
86*90b80121SDavid van Moolenbroek bool hexstr;
87*90b80121SDavid van Moolenbroek u_int8_t *p;
88*90b80121SDavid van Moolenbroek
89*90b80121SDavid van Moolenbroek len = *lenp;
90*90b80121SDavid van Moolenbroek p = buf;
91*90b80121SDavid van Moolenbroek hexstr = hexok && val[0] == '0' && tolower((u_char)val[1]) == 'x';
92*90b80121SDavid van Moolenbroek if (hexstr)
93*90b80121SDavid van Moolenbroek val += 2;
94*90b80121SDavid van Moolenbroek for (;;) {
95*90b80121SDavid van Moolenbroek if (*val == '\0')
96*90b80121SDavid van Moolenbroek break;
97*90b80121SDavid van Moolenbroek if (sep != NULL && strchr(sep, *val) != NULL) {
98*90b80121SDavid van Moolenbroek val++;
99*90b80121SDavid van Moolenbroek break;
100*90b80121SDavid van Moolenbroek }
101*90b80121SDavid van Moolenbroek if (hexstr) {
102*90b80121SDavid van Moolenbroek if (!isxdigit((u_char)val[0]) ||
103*90b80121SDavid van Moolenbroek !isxdigit((u_char)val[1])) {
104*90b80121SDavid van Moolenbroek warnx("bad hexadecimal digits");
105*90b80121SDavid van Moolenbroek return NULL;
106*90b80121SDavid van Moolenbroek }
107*90b80121SDavid van Moolenbroek }
108*90b80121SDavid van Moolenbroek if (p >= buf + len) {
109*90b80121SDavid van Moolenbroek if (hexstr)
110*90b80121SDavid van Moolenbroek warnx("hexadecimal digits too long");
111*90b80121SDavid van Moolenbroek else
112*90b80121SDavid van Moolenbroek warnx("strings too long");
113*90b80121SDavid van Moolenbroek return NULL;
114*90b80121SDavid van Moolenbroek }
115*90b80121SDavid van Moolenbroek if (hexstr) {
116*90b80121SDavid van Moolenbroek #define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10)
117*90b80121SDavid van Moolenbroek *p++ = (tohex((u_char)val[0]) << 4) |
118*90b80121SDavid van Moolenbroek tohex((u_char)val[1]);
119*90b80121SDavid van Moolenbroek #undef tohex
120*90b80121SDavid van Moolenbroek val += 2;
121*90b80121SDavid van Moolenbroek } else
122*90b80121SDavid van Moolenbroek *p++ = *val++;
123*90b80121SDavid van Moolenbroek }
124*90b80121SDavid van Moolenbroek len = p - buf;
125*90b80121SDavid van Moolenbroek if (len < *lenp)
126*90b80121SDavid van Moolenbroek memset(p, 0, *lenp - len);
127*90b80121SDavid van Moolenbroek *lenp = len;
128*90b80121SDavid van Moolenbroek return val;
129*90b80121SDavid van Moolenbroek }
130*90b80121SDavid van Moolenbroek
131*90b80121SDavid van Moolenbroek void
print_string(const u_int8_t * buf,int len)132*90b80121SDavid van Moolenbroek print_string(const u_int8_t *buf, int len)
133*90b80121SDavid van Moolenbroek {
134*90b80121SDavid van Moolenbroek int i;
135*90b80121SDavid van Moolenbroek bool hasspc;
136*90b80121SDavid van Moolenbroek
137*90b80121SDavid van Moolenbroek i = 0;
138*90b80121SDavid van Moolenbroek hasspc = false;
139*90b80121SDavid van Moolenbroek if (len < 2 || buf[0] != '0' || tolower(buf[1]) != 'x') {
140*90b80121SDavid van Moolenbroek for (; i < len; i++) {
141*90b80121SDavid van Moolenbroek if (!isprint(buf[i]))
142*90b80121SDavid van Moolenbroek break;
143*90b80121SDavid van Moolenbroek if (isspace(buf[i]))
144*90b80121SDavid van Moolenbroek hasspc = true;
145*90b80121SDavid van Moolenbroek }
146*90b80121SDavid van Moolenbroek }
147*90b80121SDavid van Moolenbroek if (i == len) {
148*90b80121SDavid van Moolenbroek if (hasspc || len == 0)
149*90b80121SDavid van Moolenbroek printf("\"%.*s\"", len, buf);
150*90b80121SDavid van Moolenbroek else
151*90b80121SDavid van Moolenbroek printf("%.*s", len, buf);
152*90b80121SDavid van Moolenbroek } else {
153*90b80121SDavid van Moolenbroek printf("0x");
154*90b80121SDavid van Moolenbroek for (i = 0; i < len; i++)
155*90b80121SDavid van Moolenbroek printf("%02x", buf[i]);
156*90b80121SDavid van Moolenbroek }
157*90b80121SDavid van Moolenbroek }
158*90b80121SDavid van Moolenbroek
159*90b80121SDavid van Moolenbroek struct paddr_prefix *
prefixlen_to_mask(int af,int plen)160*90b80121SDavid van Moolenbroek prefixlen_to_mask(int af, int plen)
161*90b80121SDavid van Moolenbroek {
162*90b80121SDavid van Moolenbroek union {
163*90b80121SDavid van Moolenbroek struct sockaddr sa;
164*90b80121SDavid van Moolenbroek struct sockaddr_in sin;
165*90b80121SDavid van Moolenbroek struct sockaddr_in6 sin6;
166*90b80121SDavid van Moolenbroek } u;
167*90b80121SDavid van Moolenbroek struct paddr_prefix *pfx;
168*90b80121SDavid van Moolenbroek size_t addrlen;
169*90b80121SDavid van Moolenbroek uint8_t *addr;
170*90b80121SDavid van Moolenbroek int nbit;
171*90b80121SDavid van Moolenbroek
172*90b80121SDavid van Moolenbroek memset(&u, 0, sizeof(u));
173*90b80121SDavid van Moolenbroek
174*90b80121SDavid van Moolenbroek switch (af) {
175*90b80121SDavid van Moolenbroek case AF_INET:
176*90b80121SDavid van Moolenbroek addrlen = sizeof(u.sin.sin_addr);
177*90b80121SDavid van Moolenbroek addr = (uint8_t *)&u.sin.sin_addr;
178*90b80121SDavid van Moolenbroek u.sa.sa_len = sizeof(u.sin);
179*90b80121SDavid van Moolenbroek break;
180*90b80121SDavid van Moolenbroek case AF_INET6:
181*90b80121SDavid van Moolenbroek addrlen = sizeof(u.sin6.sin6_addr);
182*90b80121SDavid van Moolenbroek addr = (uint8_t *)&u.sin6.sin6_addr;
183*90b80121SDavid van Moolenbroek u.sa.sa_len = sizeof(u.sin6);
184*90b80121SDavid van Moolenbroek break;
185*90b80121SDavid van Moolenbroek default:
186*90b80121SDavid van Moolenbroek errno = EINVAL;
187*90b80121SDavid van Moolenbroek return NULL;
188*90b80121SDavid van Moolenbroek }
189*90b80121SDavid van Moolenbroek u.sa.sa_family = af;
190*90b80121SDavid van Moolenbroek
191*90b80121SDavid van Moolenbroek if (plen < 0 || (size_t)plen > addrlen * NBBY) {
192*90b80121SDavid van Moolenbroek errno = EINVAL;
193*90b80121SDavid van Moolenbroek return NULL;
194*90b80121SDavid van Moolenbroek }
195*90b80121SDavid van Moolenbroek
196*90b80121SDavid van Moolenbroek if (plen == 0)
197*90b80121SDavid van Moolenbroek plen = addrlen * NBBY;
198*90b80121SDavid van Moolenbroek
199*90b80121SDavid van Moolenbroek memset(addr, 0xff, (plen + NBBY - 1) / NBBY);
200*90b80121SDavid van Moolenbroek
201*90b80121SDavid van Moolenbroek nbit = plen % NBBY;
202*90b80121SDavid van Moolenbroek if (nbit != 0)
203*90b80121SDavid van Moolenbroek addr[plen / NBBY] &= ~((uint8_t)0xff >> nbit);
204*90b80121SDavid van Moolenbroek pfx = malloc(offsetof(struct paddr_prefix, pfx_addr) + u.sa.sa_len);
205*90b80121SDavid van Moolenbroek if (pfx == NULL)
206*90b80121SDavid van Moolenbroek return NULL;
207*90b80121SDavid van Moolenbroek pfx->pfx_len = plen;
208*90b80121SDavid van Moolenbroek memcpy(&pfx->pfx_addr, &u.sa, u.sa.sa_len);
209*90b80121SDavid van Moolenbroek
210*90b80121SDavid van Moolenbroek return pfx;
211*90b80121SDavid van Moolenbroek }
212*90b80121SDavid van Moolenbroek
213*90b80121SDavid van Moolenbroek int
direct_ioctl(prop_dictionary_t env,unsigned long cmd,void * data)214*90b80121SDavid van Moolenbroek direct_ioctl(prop_dictionary_t env, unsigned long cmd, void *data)
215*90b80121SDavid van Moolenbroek {
216*90b80121SDavid van Moolenbroek const char *ifname;
217*90b80121SDavid van Moolenbroek int s;
218*90b80121SDavid van Moolenbroek
219*90b80121SDavid van Moolenbroek if ((s = getsock(AF_UNSPEC)) == -1)
220*90b80121SDavid van Moolenbroek err(EXIT_FAILURE, "getsock");
221*90b80121SDavid van Moolenbroek
222*90b80121SDavid van Moolenbroek if ((ifname = getifname(env)) == NULL)
223*90b80121SDavid van Moolenbroek err(EXIT_FAILURE, "getifname");
224*90b80121SDavid van Moolenbroek
225*90b80121SDavid van Moolenbroek estrlcpy(data, ifname, IFNAMSIZ);
226*90b80121SDavid van Moolenbroek
227*90b80121SDavid van Moolenbroek return prog_ioctl(s, cmd, data);
228*90b80121SDavid van Moolenbroek }
229*90b80121SDavid van Moolenbroek
230*90b80121SDavid van Moolenbroek int
indirect_ioctl(prop_dictionary_t env,unsigned long cmd,void * data)231*90b80121SDavid van Moolenbroek indirect_ioctl(prop_dictionary_t env, unsigned long cmd, void *data)
232*90b80121SDavid van Moolenbroek {
233*90b80121SDavid van Moolenbroek struct ifreq ifr;
234*90b80121SDavid van Moolenbroek
235*90b80121SDavid van Moolenbroek memset(&ifr, 0, sizeof(ifr));
236*90b80121SDavid van Moolenbroek
237*90b80121SDavid van Moolenbroek ifr.ifr_data = data;
238*90b80121SDavid van Moolenbroek
239*90b80121SDavid van Moolenbroek return direct_ioctl(env, cmd, &ifr);
240*90b80121SDavid van Moolenbroek }
241*90b80121SDavid van Moolenbroek
242*90b80121SDavid van Moolenbroek void
print_link_addresses(prop_dictionary_t env,bool print_active_only)243*90b80121SDavid van Moolenbroek print_link_addresses(prop_dictionary_t env, bool print_active_only)
244*90b80121SDavid van Moolenbroek {
245*90b80121SDavid van Moolenbroek char hbuf[NI_MAXHOST];
246*90b80121SDavid van Moolenbroek const char *ifname;
247*90b80121SDavid van Moolenbroek int s;
248*90b80121SDavid van Moolenbroek struct ifaddrs *ifa, *ifap;
249*90b80121SDavid van Moolenbroek const struct sockaddr_dl *sdl;
250*90b80121SDavid van Moolenbroek struct if_laddrreq iflr;
251*90b80121SDavid van Moolenbroek
252*90b80121SDavid van Moolenbroek if ((ifname = getifname(env)) == NULL)
253*90b80121SDavid van Moolenbroek err(EXIT_FAILURE, "%s: getifname", __func__);
254*90b80121SDavid van Moolenbroek
255*90b80121SDavid van Moolenbroek if ((s = getsock(AF_LINK)) == -1)
256*90b80121SDavid van Moolenbroek err(EXIT_FAILURE, "%s: getsock", __func__);
257*90b80121SDavid van Moolenbroek
258*90b80121SDavid van Moolenbroek if (getifaddrs(&ifap) == -1)
259*90b80121SDavid van Moolenbroek err(EXIT_FAILURE, "%s: getifaddrs", __func__);
260*90b80121SDavid van Moolenbroek
261*90b80121SDavid van Moolenbroek memset(&iflr, 0, sizeof(iflr));
262*90b80121SDavid van Moolenbroek
263*90b80121SDavid van Moolenbroek strlcpy(iflr.iflr_name, ifname, sizeof(iflr.iflr_name));
264*90b80121SDavid van Moolenbroek
265*90b80121SDavid van Moolenbroek for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
266*90b80121SDavid van Moolenbroek if (strcmp(ifname, ifa->ifa_name) != 0)
267*90b80121SDavid van Moolenbroek continue;
268*90b80121SDavid van Moolenbroek if (ifa->ifa_addr->sa_family != AF_LINK)
269*90b80121SDavid van Moolenbroek continue;
270*90b80121SDavid van Moolenbroek
271*90b80121SDavid van Moolenbroek sdl = satocsdl(ifa->ifa_addr);
272*90b80121SDavid van Moolenbroek
273*90b80121SDavid van Moolenbroek memcpy(&iflr.addr, ifa->ifa_addr, MIN(ifa->ifa_addr->sa_len,
274*90b80121SDavid van Moolenbroek sizeof(iflr.addr)));
275*90b80121SDavid van Moolenbroek iflr.flags = IFLR_PREFIX;
276*90b80121SDavid van Moolenbroek iflr.prefixlen = sdl->sdl_alen * NBBY;
277*90b80121SDavid van Moolenbroek
278*90b80121SDavid van Moolenbroek if (prog_ioctl(s, SIOCGLIFADDR, &iflr) == -1)
279*90b80121SDavid van Moolenbroek err(EXIT_FAILURE, "%s: ioctl", __func__);
280*90b80121SDavid van Moolenbroek
281*90b80121SDavid van Moolenbroek if (((iflr.flags & IFLR_ACTIVE) != 0) != print_active_only)
282*90b80121SDavid van Moolenbroek continue;
283*90b80121SDavid van Moolenbroek
284*90b80121SDavid van Moolenbroek if (getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len,
285*90b80121SDavid van Moolenbroek hbuf, sizeof(hbuf), NULL, 0,
286*90b80121SDavid van Moolenbroek Nflag ? 0 : NI_NUMERICHOST) == 0 &&
287*90b80121SDavid van Moolenbroek hbuf[0] != '\0') {
288*90b80121SDavid van Moolenbroek printf("\t%s %s\n",
289*90b80121SDavid van Moolenbroek print_active_only ? "address:" : "link", hbuf);
290*90b80121SDavid van Moolenbroek }
291*90b80121SDavid van Moolenbroek }
292*90b80121SDavid van Moolenbroek freeifaddrs(ifap);
293*90b80121SDavid van Moolenbroek }
294*90b80121SDavid van Moolenbroek
295*90b80121SDavid van Moolenbroek int16_t
ifa_get_preference(const char * ifname,const struct sockaddr * sa)296*90b80121SDavid van Moolenbroek ifa_get_preference(const char *ifname, const struct sockaddr *sa)
297*90b80121SDavid van Moolenbroek {
298*90b80121SDavid van Moolenbroek struct if_addrprefreq ifap;
299*90b80121SDavid van Moolenbroek int s;
300*90b80121SDavid van Moolenbroek
301*90b80121SDavid van Moolenbroek if ((s = getsock(sa->sa_family)) == -1) {
302*90b80121SDavid van Moolenbroek if (errno == EPROTONOSUPPORT)
303*90b80121SDavid van Moolenbroek return 0;
304*90b80121SDavid van Moolenbroek err(EXIT_FAILURE, "socket");
305*90b80121SDavid van Moolenbroek }
306*90b80121SDavid van Moolenbroek memset(&ifap, 0, sizeof(ifap));
307*90b80121SDavid van Moolenbroek estrlcpy(ifap.ifap_name, ifname, sizeof(ifap.ifap_name));
308*90b80121SDavid van Moolenbroek memcpy(&ifap.ifap_addr, sa, MIN(sizeof(ifap.ifap_addr), sa->sa_len));
309*90b80121SDavid van Moolenbroek if (prog_ioctl(s, SIOCGIFADDRPREF, &ifap) == -1) {
310*90b80121SDavid van Moolenbroek if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT)
311*90b80121SDavid van Moolenbroek return 0;
312*90b80121SDavid van Moolenbroek warn("SIOCGIFADDRPREF");
313*90b80121SDavid van Moolenbroek }
314*90b80121SDavid van Moolenbroek return ifap.ifap_preference;
315*90b80121SDavid van Moolenbroek }
316*90b80121SDavid van Moolenbroek
317*90b80121SDavid van Moolenbroek void
ifa_print_preference(const char * ifname,const struct sockaddr * sa)318*90b80121SDavid van Moolenbroek ifa_print_preference(const char *ifname, const struct sockaddr *sa)
319*90b80121SDavid van Moolenbroek {
320*90b80121SDavid van Moolenbroek int16_t preference;
321*90b80121SDavid van Moolenbroek
322*90b80121SDavid van Moolenbroek if (lflag)
323*90b80121SDavid van Moolenbroek return;
324*90b80121SDavid van Moolenbroek
325*90b80121SDavid van Moolenbroek preference = ifa_get_preference(ifname, sa);
326*90b80121SDavid van Moolenbroek printf(" preference %" PRId16, preference);
327*90b80121SDavid van Moolenbroek }
328*90b80121SDavid van Moolenbroek
329*90b80121SDavid van Moolenbroek bool
ifa_any_preferences(const char * ifname,struct ifaddrs * ifap,int family)330*90b80121SDavid van Moolenbroek ifa_any_preferences(const char *ifname, struct ifaddrs *ifap, int family)
331*90b80121SDavid van Moolenbroek {
332*90b80121SDavid van Moolenbroek struct ifaddrs *ifa;
333*90b80121SDavid van Moolenbroek
334*90b80121SDavid van Moolenbroek /* Print address preference numbers if any address has a non-zero
335*90b80121SDavid van Moolenbroek * preference assigned.
336*90b80121SDavid van Moolenbroek */
337*90b80121SDavid van Moolenbroek for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
338*90b80121SDavid van Moolenbroek if (strcmp(ifname, ifa->ifa_name) != 0)
339*90b80121SDavid van Moolenbroek continue;
340*90b80121SDavid van Moolenbroek if (ifa->ifa_addr->sa_family != family)
341*90b80121SDavid van Moolenbroek continue;
342*90b80121SDavid van Moolenbroek if (ifa_get_preference(ifa->ifa_name, ifa->ifa_addr) != 0)
343*90b80121SDavid van Moolenbroek return true;
344*90b80121SDavid van Moolenbroek }
345*90b80121SDavid van Moolenbroek return false;
346*90b80121SDavid van Moolenbroek }
347