1*5c2921b0SApple OSS Distributions /*
2*5c2921b0SApple OSS Distributions * Copyright (c) 2020-2022 Apple Inc. All rights reserved.
3*5c2921b0SApple OSS Distributions *
4*5c2921b0SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*5c2921b0SApple OSS Distributions *
6*5c2921b0SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*5c2921b0SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*5c2921b0SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*5c2921b0SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*5c2921b0SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*5c2921b0SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*5c2921b0SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*5c2921b0SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*5c2921b0SApple OSS Distributions *
15*5c2921b0SApple OSS Distributions * Please obtain a copy of the License at
16*5c2921b0SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*5c2921b0SApple OSS Distributions *
18*5c2921b0SApple OSS Distributions * The Original Code and all software distributed under the License are
19*5c2921b0SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*5c2921b0SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*5c2921b0SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*5c2921b0SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*5c2921b0SApple OSS Distributions * Please see the License for the specific language governing rights and
24*5c2921b0SApple OSS Distributions * limitations under the License.
25*5c2921b0SApple OSS Distributions *
26*5c2921b0SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*5c2921b0SApple OSS Distributions */
28*5c2921b0SApple OSS Distributions
29*5c2921b0SApple OSS Distributions /* -*- compile-command: "xcrun --sdk iphoneos.internal make sioc-if-addr-bounds" -*- */
30*5c2921b0SApple OSS Distributions
31*5c2921b0SApple OSS Distributions #include <sys/ioctl.h>
32*5c2921b0SApple OSS Distributions #include <sys/socket.h>
33*5c2921b0SApple OSS Distributions #include <sys/sockio.h>
34*5c2921b0SApple OSS Distributions
35*5c2921b0SApple OSS Distributions #include <net/if.h>
36*5c2921b0SApple OSS Distributions #include <net/if_dl.h>
37*5c2921b0SApple OSS Distributions
38*5c2921b0SApple OSS Distributions #include <netinet/in.h>
39*5c2921b0SApple OSS Distributions #include <netinet/in_var.h>
40*5c2921b0SApple OSS Distributions
41*5c2921b0SApple OSS Distributions #include <string.h>
42*5c2921b0SApple OSS Distributions #include <unistd.h>
43*5c2921b0SApple OSS Distributions
44*5c2921b0SApple OSS Distributions #include <arpa/inet.h>
45*5c2921b0SApple OSS Distributions
46*5c2921b0SApple OSS Distributions #include <darwintest.h>
47*5c2921b0SApple OSS Distributions #include <darwintest_utils.h>
48*5c2921b0SApple OSS Distributions
49*5c2921b0SApple OSS Distributions #include <uuid/uuid.h>
50*5c2921b0SApple OSS Distributions
51*5c2921b0SApple OSS Distributions #include <ifaddrs.h>
52*5c2921b0SApple OSS Distributions
53*5c2921b0SApple OSS Distributions #include <arpa/inet.h>
54*5c2921b0SApple OSS Distributions
55*5c2921b0SApple OSS Distributions #include "ioc_str.h"
56*5c2921b0SApple OSS Distributions
57*5c2921b0SApple OSS Distributions T_GLOBAL_META(T_META_NAMESPACE("xnu.net"));
58*5c2921b0SApple OSS Distributions
59*5c2921b0SApple OSS Distributions #ifndef STRINGIFY
60*5c2921b0SApple OSS Distributions #define __STR(x) #x /* just a helper macro */
61*5c2921b0SApple OSS Distributions #define STRINGIFY(x) __STR(x)
62*5c2921b0SApple OSS Distributions #endif /* STRINGIFY */
63*5c2921b0SApple OSS Distributions
64*5c2921b0SApple OSS Distributions #define IF_NAME "bridge"
65*5c2921b0SApple OSS Distributions
66*5c2921b0SApple OSS Distributions /* On some platforms with DEBUG kernel, we need to wait a while */
67*5c2921b0SApple OSS Distributions #define SIFCREATE_RETRY 600
68*5c2921b0SApple OSS Distributions
69*5c2921b0SApple OSS Distributions #define PATTERN_SIZE 8
70*5c2921b0SApple OSS Distributions
71*5c2921b0SApple OSS Distributions static int
ifnet_destroy(int s,const char * ifname,bool fail_on_error)72*5c2921b0SApple OSS Distributions ifnet_destroy(int s, const char * ifname, bool fail_on_error)
73*5c2921b0SApple OSS Distributions {
74*5c2921b0SApple OSS Distributions int err;
75*5c2921b0SApple OSS Distributions struct ifreq ifr;
76*5c2921b0SApple OSS Distributions
77*5c2921b0SApple OSS Distributions bzero(&ifr, sizeof(ifr));
78*5c2921b0SApple OSS Distributions strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
79*5c2921b0SApple OSS Distributions err = ioctl(s, SIOCIFDESTROY, &ifr);
80*5c2921b0SApple OSS Distributions if (fail_on_error) {
81*5c2921b0SApple OSS Distributions T_QUIET;
82*5c2921b0SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(err, "SIOCSIFDESTROY %s", ifr.ifr_name);
83*5c2921b0SApple OSS Distributions }
84*5c2921b0SApple OSS Distributions if (err < 0) {
85*5c2921b0SApple OSS Distributions T_LOG("SIOCSIFDESTROY %s", ifr.ifr_name);
86*5c2921b0SApple OSS Distributions }
87*5c2921b0SApple OSS Distributions return err;
88*5c2921b0SApple OSS Distributions }
89*5c2921b0SApple OSS Distributions
90*5c2921b0SApple OSS Distributions static int
ifnet_set_flags(int s,const char * ifname,uint16_t flags_set,uint16_t flags_clear)91*5c2921b0SApple OSS Distributions ifnet_set_flags(int s, const char * ifname,
92*5c2921b0SApple OSS Distributions uint16_t flags_set, uint16_t flags_clear)
93*5c2921b0SApple OSS Distributions {
94*5c2921b0SApple OSS Distributions uint16_t flags_after;
95*5c2921b0SApple OSS Distributions uint16_t flags_before;
96*5c2921b0SApple OSS Distributions struct ifreq ifr;
97*5c2921b0SApple OSS Distributions int ret;
98*5c2921b0SApple OSS Distributions
99*5c2921b0SApple OSS Distributions bzero(&ifr, sizeof(ifr));
100*5c2921b0SApple OSS Distributions strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
101*5c2921b0SApple OSS Distributions ret = ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr);
102*5c2921b0SApple OSS Distributions if (ret != 0) {
103*5c2921b0SApple OSS Distributions T_LOG("SIOCGIFFLAGS %s", ifr.ifr_name);
104*5c2921b0SApple OSS Distributions return ret;
105*5c2921b0SApple OSS Distributions }
106*5c2921b0SApple OSS Distributions flags_before = (uint16_t)ifr.ifr_flags;
107*5c2921b0SApple OSS Distributions ifr.ifr_flags |= flags_set;
108*5c2921b0SApple OSS Distributions ifr.ifr_flags &= ~(flags_clear);
109*5c2921b0SApple OSS Distributions flags_after = (uint16_t)ifr.ifr_flags;
110*5c2921b0SApple OSS Distributions if (flags_before == flags_after) {
111*5c2921b0SApple OSS Distributions /* nothing to do */
112*5c2921b0SApple OSS Distributions ret = 0;
113*5c2921b0SApple OSS Distributions } else {
114*5c2921b0SApple OSS Distributions /* issue the ioctl */
115*5c2921b0SApple OSS Distributions T_QUIET;
116*5c2921b0SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(ioctl(s, SIOCSIFFLAGS, &ifr),
117*5c2921b0SApple OSS Distributions "SIOCSIFFLAGS %s 0x%x",
118*5c2921b0SApple OSS Distributions ifr.ifr_name, (uint16_t)ifr.ifr_flags);
119*5c2921b0SApple OSS Distributions }
120*5c2921b0SApple OSS Distributions return ret;
121*5c2921b0SApple OSS Distributions }
122*5c2921b0SApple OSS Distributions
123*5c2921b0SApple OSS Distributions static int
ifnet_create(int s,char * ifname,size_t ifname_size)124*5c2921b0SApple OSS Distributions ifnet_create(int s, char * ifname, size_t ifname_size)
125*5c2921b0SApple OSS Distributions {
126*5c2921b0SApple OSS Distributions int error = 0;
127*5c2921b0SApple OSS Distributions struct ifreq ifr;
128*5c2921b0SApple OSS Distributions
129*5c2921b0SApple OSS Distributions bzero(&ifr, sizeof(ifr));
130*5c2921b0SApple OSS Distributions strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
131*5c2921b0SApple OSS Distributions
132*5c2921b0SApple OSS Distributions for (int i = 0; i < SIFCREATE_RETRY; i++) {
133*5c2921b0SApple OSS Distributions if (ioctl(s, SIOCIFCREATE, &ifr) < 0) {
134*5c2921b0SApple OSS Distributions error = errno;
135*5c2921b0SApple OSS Distributions T_LOG("SIOCSIFCREATE %s: %s", ifname,
136*5c2921b0SApple OSS Distributions strerror(error));
137*5c2921b0SApple OSS Distributions if (error == EBUSY) {
138*5c2921b0SApple OSS Distributions /* interface is tearing down, try again */
139*5c2921b0SApple OSS Distributions usleep(10000);
140*5c2921b0SApple OSS Distributions } else if (error == EEXIST) {
141*5c2921b0SApple OSS Distributions /* interface exists, try destroying it */
142*5c2921b0SApple OSS Distributions (void)ifnet_destroy(s, ifname, false);
143*5c2921b0SApple OSS Distributions } else {
144*5c2921b0SApple OSS Distributions /* unexpected failure */
145*5c2921b0SApple OSS Distributions break;
146*5c2921b0SApple OSS Distributions }
147*5c2921b0SApple OSS Distributions } else {
148*5c2921b0SApple OSS Distributions error = 0;
149*5c2921b0SApple OSS Distributions break;
150*5c2921b0SApple OSS Distributions }
151*5c2921b0SApple OSS Distributions }
152*5c2921b0SApple OSS Distributions if (error == 0) {
153*5c2921b0SApple OSS Distributions /* Copy back the interface name with unit number */
154*5c2921b0SApple OSS Distributions strlcpy(ifname, ifr.ifr_name, ifname_size);
155*5c2921b0SApple OSS Distributions error = ifnet_set_flags(s, ifname, IFF_UP, 0);
156*5c2921b0SApple OSS Distributions }
157*5c2921b0SApple OSS Distributions return error;
158*5c2921b0SApple OSS Distributions }
159*5c2921b0SApple OSS Distributions
160*5c2921b0SApple OSS Distributions #define MAXBUF 32
161*5c2921b0SApple OSS Distributions
162*5c2921b0SApple OSS Distributions static void
HexDump(void * data,size_t len)163*5c2921b0SApple OSS Distributions HexDump(void *data, size_t len)
164*5c2921b0SApple OSS Distributions {
165*5c2921b0SApple OSS Distributions size_t i, j, k;
166*5c2921b0SApple OSS Distributions unsigned char *ptr = (unsigned char *)data;
167*5c2921b0SApple OSS Distributions unsigned char buf[3 * MAXBUF + 1];
168*5c2921b0SApple OSS Distributions
169*5c2921b0SApple OSS Distributions for (i = 0; i < len; i += MAXBUF) {
170*5c2921b0SApple OSS Distributions for (j = i, k = 0; j < i + MAXBUF && j < len; j++) {
171*5c2921b0SApple OSS Distributions unsigned char msnbl = ptr[j] >> 4;
172*5c2921b0SApple OSS Distributions unsigned char lsnbl = ptr[j] & 0x0f;
173*5c2921b0SApple OSS Distributions
174*5c2921b0SApple OSS Distributions buf[k++] = msnbl < 10 ? msnbl + '0' : msnbl + 'a' - 10;
175*5c2921b0SApple OSS Distributions buf[k++] = lsnbl < 10 ? lsnbl + '0' : lsnbl + 'a' - 10;
176*5c2921b0SApple OSS Distributions if ((j % 2) == 1) {
177*5c2921b0SApple OSS Distributions buf[k++] = ' ';
178*5c2921b0SApple OSS Distributions }
179*5c2921b0SApple OSS Distributions if ((j % MAXBUF) == MAXBUF - 1) {
180*5c2921b0SApple OSS Distributions buf[k++] = ' ';
181*5c2921b0SApple OSS Distributions }
182*5c2921b0SApple OSS Distributions }
183*5c2921b0SApple OSS Distributions buf[k] = 0;
184*5c2921b0SApple OSS Distributions T_LOG("%5zd: %s\n", i, buf);
185*5c2921b0SApple OSS Distributions }
186*5c2921b0SApple OSS Distributions }
187*5c2921b0SApple OSS Distributions
188*5c2921b0SApple OSS Distributions static size_t
snprint_dottedhex(char * str,size_t strsize,const void * data,const size_t datasize)189*5c2921b0SApple OSS Distributions snprint_dottedhex(char *str, size_t strsize, const void *data, const size_t datasize)
190*5c2921b0SApple OSS Distributions {
191*5c2921b0SApple OSS Distributions size_t is = 0, ip = 0;
192*5c2921b0SApple OSS Distributions const unsigned char *ptr = (const unsigned char *)data;
193*5c2921b0SApple OSS Distributions
194*5c2921b0SApple OSS Distributions for (is = 0, ip = 0; is + 3 < strsize - 1 && ip < datasize; ip++) {
195*5c2921b0SApple OSS Distributions unsigned char msnbl = ptr[ip] >> 4;
196*5c2921b0SApple OSS Distributions unsigned char lsnbl = ptr[ip] & 0x0f;
197*5c2921b0SApple OSS Distributions
198*5c2921b0SApple OSS Distributions if (ip > 0) {
199*5c2921b0SApple OSS Distributions str[is++] = '.';
200*5c2921b0SApple OSS Distributions }
201*5c2921b0SApple OSS Distributions str[is++] = (char)(msnbl + (msnbl < 10 ? '0' : 'a' - 10));
202*5c2921b0SApple OSS Distributions str[is++] = (char)(lsnbl + (lsnbl < 10 ? '0' : 'a' - 10));
203*5c2921b0SApple OSS Distributions }
204*5c2921b0SApple OSS Distributions str[is] = 0;
205*5c2921b0SApple OSS Distributions return is;
206*5c2921b0SApple OSS Distributions }
207*5c2921b0SApple OSS Distributions
208*5c2921b0SApple OSS Distributions static void
print_sockaddr_dl(const char * pre,const struct sockaddr * sa,const char * post)209*5c2921b0SApple OSS Distributions print_sockaddr_dl(const char *pre, const struct sockaddr *sa, const char *post)
210*5c2921b0SApple OSS Distributions {
211*5c2921b0SApple OSS Distributions char nbuffer[256];
212*5c2921b0SApple OSS Distributions char abuffer[256];
213*5c2921b0SApple OSS Distributions char sbuffer[256];
214*5c2921b0SApple OSS Distributions struct sockaddr_dl sdl = {};
215*5c2921b0SApple OSS Distributions
216*5c2921b0SApple OSS Distributions if (sa == NULL) {
217*5c2921b0SApple OSS Distributions return;
218*5c2921b0SApple OSS Distributions }
219*5c2921b0SApple OSS Distributions memcpy(&sdl, sa, MIN(sizeof(sdl), sa->sa_len));
220*5c2921b0SApple OSS Distributions strlcpy(nbuffer, sdl.sdl_data, sdl.sdl_nlen);
221*5c2921b0SApple OSS Distributions snprint_dottedhex(abuffer, sizeof(abuffer), sdl.sdl_data + sdl.sdl_nlen, sdl.sdl_alen);
222*5c2921b0SApple OSS Distributions snprint_dottedhex(sbuffer, sizeof(sbuffer), sdl.sdl_data + sdl.sdl_nlen + sdl.sdl_alen, sdl.sdl_slen);
223*5c2921b0SApple OSS Distributions
224*5c2921b0SApple OSS Distributions T_LOG("%ssdl_len %u sdl_family %u sdl_index %u sdl_type %u sdl_nlen %u (%s) sdl_alen %u (%s) sdl_slen %u (%s)%s",
225*5c2921b0SApple OSS Distributions pre != NULL ? pre : "",
226*5c2921b0SApple OSS Distributions sdl.sdl_len, sdl.sdl_family, sdl.sdl_index, sdl.sdl_type,
227*5c2921b0SApple OSS Distributions sdl.sdl_nlen, nbuffer, sdl.sdl_alen, abuffer, sdl.sdl_slen, sbuffer,
228*5c2921b0SApple OSS Distributions post != NULL ? post : "");
229*5c2921b0SApple OSS Distributions }
230*5c2921b0SApple OSS Distributions
231*5c2921b0SApple OSS Distributions static void
print_sockaddr_in(const char * pre,const struct sockaddr * sa,const char * post)232*5c2921b0SApple OSS Distributions print_sockaddr_in(const char *pre, const struct sockaddr *sa, const char *post)
233*5c2921b0SApple OSS Distributions {
234*5c2921b0SApple OSS Distributions char abuffer[256];
235*5c2921b0SApple OSS Distributions char zbuffer[256];
236*5c2921b0SApple OSS Distributions struct sockaddr_in sin = {};
237*5c2921b0SApple OSS Distributions
238*5c2921b0SApple OSS Distributions if (sa == NULL) {
239*5c2921b0SApple OSS Distributions return;
240*5c2921b0SApple OSS Distributions }
241*5c2921b0SApple OSS Distributions
242*5c2921b0SApple OSS Distributions memcpy(&sin, sa, MIN(sizeof(sin), sa->sa_len));
243*5c2921b0SApple OSS Distributions inet_ntop(AF_INET, &sin.sin_addr, abuffer, sizeof(abuffer));
244*5c2921b0SApple OSS Distributions snprint_dottedhex(zbuffer, sizeof(zbuffer), sin.sin_zero, sizeof(sin.sin_zero));
245*5c2921b0SApple OSS Distributions
246*5c2921b0SApple OSS Distributions T_LOG("%ssin_len %u sin_family %u sin_port %u sin_addr %s sin_zero %s%s",
247*5c2921b0SApple OSS Distributions pre != NULL ? pre : "",
248*5c2921b0SApple OSS Distributions sin.sin_len, sin.sin_family, htons(sin.sin_port), abuffer, zbuffer,
249*5c2921b0SApple OSS Distributions post != NULL ? post : "");
250*5c2921b0SApple OSS Distributions }
251*5c2921b0SApple OSS Distributions
252*5c2921b0SApple OSS Distributions static void
print_sockaddr_in6(const char * pre,const struct sockaddr * sa,const char * post)253*5c2921b0SApple OSS Distributions print_sockaddr_in6(const char *pre, const struct sockaddr *sa, const char *post)
254*5c2921b0SApple OSS Distributions {
255*5c2921b0SApple OSS Distributions char abuffer[256];
256*5c2921b0SApple OSS Distributions struct sockaddr_in6 sin6 = {};
257*5c2921b0SApple OSS Distributions
258*5c2921b0SApple OSS Distributions if (sa == NULL) {
259*5c2921b0SApple OSS Distributions return;
260*5c2921b0SApple OSS Distributions }
261*5c2921b0SApple OSS Distributions
262*5c2921b0SApple OSS Distributions memcpy(&sin6, sa, MIN(sizeof(sin6), sa->sa_len));
263*5c2921b0SApple OSS Distributions inet_ntop(AF_INET6, &sin6.sin6_addr, abuffer, sizeof(abuffer));
264*5c2921b0SApple OSS Distributions
265*5c2921b0SApple OSS Distributions T_LOG("%ssin6_len %u sin6_family %u sin6_port %u sin6_flowinfo %u sin6_addr %s sin6_scope_id %u%s",
266*5c2921b0SApple OSS Distributions pre != NULL ? pre : "",
267*5c2921b0SApple OSS Distributions sin6.sin6_len, sin6.sin6_family, htons(sin6.sin6_port), sin6.sin6_flowinfo, abuffer, sin6.sin6_scope_id,
268*5c2921b0SApple OSS Distributions post != NULL ? post : "");
269*5c2921b0SApple OSS Distributions }
270*5c2921b0SApple OSS Distributions
271*5c2921b0SApple OSS Distributions static void
print_sockaddr(const char * pre,const struct sockaddr * sa,const char * post)272*5c2921b0SApple OSS Distributions print_sockaddr(const char *pre, const struct sockaddr *sa, const char *post)
273*5c2921b0SApple OSS Distributions {
274*5c2921b0SApple OSS Distributions char buffer[256];
275*5c2921b0SApple OSS Distributions
276*5c2921b0SApple OSS Distributions if (sa == NULL) {
277*5c2921b0SApple OSS Distributions return;
278*5c2921b0SApple OSS Distributions }
279*5c2921b0SApple OSS Distributions
280*5c2921b0SApple OSS Distributions snprint_dottedhex(buffer, sizeof(buffer), sa->sa_data, sa->sa_len - 2);
281*5c2921b0SApple OSS Distributions
282*5c2921b0SApple OSS Distributions T_LOG("%ssa_len %u sa_family %u sa_data %s%s",
283*5c2921b0SApple OSS Distributions pre != NULL ? pre : "",
284*5c2921b0SApple OSS Distributions sa->sa_len, sa->sa_family, buffer,
285*5c2921b0SApple OSS Distributions post != NULL ? post : "");
286*5c2921b0SApple OSS Distributions }
287*5c2921b0SApple OSS Distributions
288*5c2921b0SApple OSS Distributions
289*5c2921b0SApple OSS Distributions #define ROUNDUP(a, size) (((a) & ((size) - 1)) ? (1 + ((a)|(size - 1))) : (a))
290*5c2921b0SApple OSS Distributions
291*5c2921b0SApple OSS Distributions #define NEXT_SA(p) (struct sockaddr *) \
292*5c2921b0SApple OSS Distributions ((caddr_t)p + (p->sa_len ? ROUNDUP(p->sa_len, sizeof(u_int32_t)) : \
293*5c2921b0SApple OSS Distributions sizeof(u_long)))
294*5c2921b0SApple OSS Distributions
295*5c2921b0SApple OSS Distributions static size_t
get_rti_info(int addrs,struct sockaddr * sa,struct sockaddr ** rti_info)296*5c2921b0SApple OSS Distributions get_rti_info(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
297*5c2921b0SApple OSS Distributions {
298*5c2921b0SApple OSS Distributions int i;
299*5c2921b0SApple OSS Distributions size_t len = 0;
300*5c2921b0SApple OSS Distributions
301*5c2921b0SApple OSS Distributions for (i = 0; i < RTAX_MAX; i++) {
302*5c2921b0SApple OSS Distributions if (addrs & (1 << i)) {
303*5c2921b0SApple OSS Distributions rti_info[i] = sa;
304*5c2921b0SApple OSS Distributions if (sa->sa_len < sizeof(struct sockaddr)) {
305*5c2921b0SApple OSS Distributions len += sizeof(struct sockaddr);
306*5c2921b0SApple OSS Distributions } else {
307*5c2921b0SApple OSS Distributions len += sa->sa_len;
308*5c2921b0SApple OSS Distributions }
309*5c2921b0SApple OSS Distributions sa = NEXT_SA(sa);
310*5c2921b0SApple OSS Distributions } else {
311*5c2921b0SApple OSS Distributions rti_info[i] = NULL;
312*5c2921b0SApple OSS Distributions }
313*5c2921b0SApple OSS Distributions }
314*5c2921b0SApple OSS Distributions return len;
315*5c2921b0SApple OSS Distributions }
316*5c2921b0SApple OSS Distributions
317*5c2921b0SApple OSS Distributions static void
print_address(const char * pre,const struct sockaddr * sa,const char * post,u_char asFamily)318*5c2921b0SApple OSS Distributions print_address(const char *pre, const struct sockaddr *sa, const char *post, u_char asFamily)
319*5c2921b0SApple OSS Distributions {
320*5c2921b0SApple OSS Distributions if (sa == NULL) {
321*5c2921b0SApple OSS Distributions T_LOG("%s(NULL)%s",
322*5c2921b0SApple OSS Distributions pre != NULL ? pre : "",
323*5c2921b0SApple OSS Distributions post != NULL ? post : "");
324*5c2921b0SApple OSS Distributions return;
325*5c2921b0SApple OSS Distributions }
326*5c2921b0SApple OSS Distributions if (sa->sa_len == 0) {
327*5c2921b0SApple OSS Distributions T_LOG("%ssa_len 0%s",
328*5c2921b0SApple OSS Distributions pre != NULL ? pre : "",
329*5c2921b0SApple OSS Distributions post != NULL ? post : "");
330*5c2921b0SApple OSS Distributions return;
331*5c2921b0SApple OSS Distributions }
332*5c2921b0SApple OSS Distributions if (sa->sa_len == 1) {
333*5c2921b0SApple OSS Distributions T_LOG("%ssa_len 1%s",
334*5c2921b0SApple OSS Distributions pre != NULL ? pre : "",
335*5c2921b0SApple OSS Distributions post != NULL ? post : "");
336*5c2921b0SApple OSS Distributions return;
337*5c2921b0SApple OSS Distributions }
338*5c2921b0SApple OSS Distributions
339*5c2921b0SApple OSS Distributions // If not forced
340*5c2921b0SApple OSS Distributions if (asFamily == AF_UNSPEC) {
341*5c2921b0SApple OSS Distributions asFamily = sa->sa_family;
342*5c2921b0SApple OSS Distributions }
343*5c2921b0SApple OSS Distributions switch (asFamily) {
344*5c2921b0SApple OSS Distributions case AF_INET: {
345*5c2921b0SApple OSS Distributions print_sockaddr_in(pre, sa, post);
346*5c2921b0SApple OSS Distributions break;
347*5c2921b0SApple OSS Distributions }
348*5c2921b0SApple OSS Distributions case AF_INET6: {
349*5c2921b0SApple OSS Distributions print_sockaddr_in6(pre, sa, post);
350*5c2921b0SApple OSS Distributions break;
351*5c2921b0SApple OSS Distributions }
352*5c2921b0SApple OSS Distributions case AF_LINK: {
353*5c2921b0SApple OSS Distributions print_sockaddr_dl(pre, sa, post);
354*5c2921b0SApple OSS Distributions break;
355*5c2921b0SApple OSS Distributions }
356*5c2921b0SApple OSS Distributions default:
357*5c2921b0SApple OSS Distributions print_sockaddr(pre, sa, post);
358*5c2921b0SApple OSS Distributions break;
359*5c2921b0SApple OSS Distributions }
360*5c2921b0SApple OSS Distributions }
361*5c2921b0SApple OSS Distributions
362*5c2921b0SApple OSS Distributions static void
print_rti_info(struct sockaddr * rti_info[])363*5c2921b0SApple OSS Distributions print_rti_info(struct sockaddr *rti_info[])
364*5c2921b0SApple OSS Distributions {
365*5c2921b0SApple OSS Distributions struct sockaddr *sa;
366*5c2921b0SApple OSS Distributions u_char asFamily = 0;
367*5c2921b0SApple OSS Distributions
368*5c2921b0SApple OSS Distributions if ((sa = rti_info[RTAX_IFA])) {
369*5c2921b0SApple OSS Distributions asFamily = sa->sa_family;
370*5c2921b0SApple OSS Distributions print_address(" RTAX_IFA ", sa, "\n", 0);
371*5c2921b0SApple OSS Distributions }
372*5c2921b0SApple OSS Distributions if ((sa = rti_info[RTAX_DST])) {
373*5c2921b0SApple OSS Distributions asFamily = sa->sa_family;
374*5c2921b0SApple OSS Distributions print_address(" RTAX_DST ", sa, "\n", 0);
375*5c2921b0SApple OSS Distributions }
376*5c2921b0SApple OSS Distributions if ((sa = rti_info[RTAX_BRD])) {
377*5c2921b0SApple OSS Distributions print_address(" RTAX_BRD ", sa, "\n", asFamily);
378*5c2921b0SApple OSS Distributions }
379*5c2921b0SApple OSS Distributions
380*5c2921b0SApple OSS Distributions if ((sa = rti_info[RTAX_NETMASK])) {
381*5c2921b0SApple OSS Distributions print_address(" RTAX_NETMASK ", sa, "\n", asFamily);
382*5c2921b0SApple OSS Distributions }
383*5c2921b0SApple OSS Distributions
384*5c2921b0SApple OSS Distributions if ((sa = rti_info[RTAX_GATEWAY])) {
385*5c2921b0SApple OSS Distributions print_address(" RTAX_GATEWAY ", sa, "\n", 0);
386*5c2921b0SApple OSS Distributions }
387*5c2921b0SApple OSS Distributions
388*5c2921b0SApple OSS Distributions if ((sa = rti_info[RTAX_GENMASK])) {
389*5c2921b0SApple OSS Distributions print_address(" RTAX_GENMASK ", sa, "\n", asFamily);
390*5c2921b0SApple OSS Distributions }
391*5c2921b0SApple OSS Distributions
392*5c2921b0SApple OSS Distributions if ((sa = rti_info[RTAX_AUTHOR])) {
393*5c2921b0SApple OSS Distributions print_address(" RTAX_AUTHOR ", sa, "\n", asFamily);
394*5c2921b0SApple OSS Distributions }
395*5c2921b0SApple OSS Distributions
396*5c2921b0SApple OSS Distributions if ((sa = rti_info[RTAX_IFP])) {
397*5c2921b0SApple OSS Distributions print_address(" RTAX_IFP ", sa, "\n", 0);
398*5c2921b0SApple OSS Distributions }
399*5c2921b0SApple OSS Distributions }
400*5c2921b0SApple OSS Distributions
401*5c2921b0SApple OSS Distributions static void
print_rt_iflist2(const char * label)402*5c2921b0SApple OSS Distributions print_rt_iflist2(const char *label)
403*5c2921b0SApple OSS Distributions {
404*5c2921b0SApple OSS Distributions size_t len;
405*5c2921b0SApple OSS Distributions int mib[6] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0 };
406*5c2921b0SApple OSS Distributions unsigned char *buf = NULL;
407*5c2921b0SApple OSS Distributions unsigned char *lim, *next;
408*5c2921b0SApple OSS Distributions struct if_msghdr *ifmsg;
409*5c2921b0SApple OSS Distributions
410*5c2921b0SApple OSS Distributions T_LOG("interface address list for %s", label);
411*5c2921b0SApple OSS Distributions
412*5c2921b0SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(sysctl(mib, 6, NULL, &len, NULL, 0), "sysctl NET_RT_IFLIST2");
413*5c2921b0SApple OSS Distributions
414*5c2921b0SApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(buf = calloc(1, len), "rt_if_list_buf calloc(1, %zd)", len);
415*5c2921b0SApple OSS Distributions
416*5c2921b0SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(sysctl(mib, 6, buf, &len, NULL, 0), "sysctl NET_RT_IFLIST2");
417*5c2921b0SApple OSS Distributions
418*5c2921b0SApple OSS Distributions lim = buf + len;
419*5c2921b0SApple OSS Distributions for (next = buf; next < lim; next += ifmsg->ifm_msglen) {
420*5c2921b0SApple OSS Distributions ifmsg = (struct if_msghdr *)(void *)next;
421*5c2921b0SApple OSS Distributions char ifname[IF_NAMESIZE + 1];
422*5c2921b0SApple OSS Distributions
423*5c2921b0SApple OSS Distributions if (ifmsg->ifm_type == RTM_IFINFO2) {
424*5c2921b0SApple OSS Distributions struct if_msghdr2 *ifm = (struct if_msghdr2 *)ifmsg;
425*5c2921b0SApple OSS Distributions struct sockaddr *sa = (struct sockaddr *)(ifm + 1);
426*5c2921b0SApple OSS Distributions
427*5c2921b0SApple OSS Distributions (void)if_indextoname(ifm->ifm_index, ifname);
428*5c2921b0SApple OSS Distributions T_LOG("interface: %s", ifname);
429*5c2921b0SApple OSS Distributions print_address(" PRIMARY ", sa, "", 0);
430*5c2921b0SApple OSS Distributions } else if (ifmsg->ifm_type == RTM_NEWADDR) {
431*5c2921b0SApple OSS Distributions struct sockaddr *rti_info[RTAX_MAX];
432*5c2921b0SApple OSS Distributions struct ifa_msghdr *ifam = (struct ifa_msghdr *)ifmsg;
433*5c2921b0SApple OSS Distributions
434*5c2921b0SApple OSS Distributions (void) get_rti_info(ifam->ifam_addrs, (struct sockaddr *)(ifam + 1), rti_info);
435*5c2921b0SApple OSS Distributions
436*5c2921b0SApple OSS Distributions print_rti_info(rti_info);
437*5c2921b0SApple OSS Distributions }
438*5c2921b0SApple OSS Distributions }
439*5c2921b0SApple OSS Distributions free(buf);
440*5c2921b0SApple OSS Distributions }
441*5c2921b0SApple OSS Distributions
442*5c2921b0SApple OSS Distributions static int
check_rt_if_list_for_pattern(const char * label,unsigned char pattern,size_t pattern_size)443*5c2921b0SApple OSS Distributions check_rt_if_list_for_pattern(const char *label, unsigned char pattern, size_t pattern_size)
444*5c2921b0SApple OSS Distributions {
445*5c2921b0SApple OSS Distributions size_t i;
446*5c2921b0SApple OSS Distributions size_t len;
447*5c2921b0SApple OSS Distributions int mib[6] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
448*5c2921b0SApple OSS Distributions unsigned char *rt_if_list_buf = NULL;
449*5c2921b0SApple OSS Distributions int count = 0;
450*5c2921b0SApple OSS Distributions unsigned char *pattern_buf = NULL;
451*5c2921b0SApple OSS Distributions
452*5c2921b0SApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(pattern_buf = calloc(1, pattern_size), "pattern_buf calloc(1, %zd)", pattern_size);
453*5c2921b0SApple OSS Distributions memset(pattern_buf, pattern, pattern_size);
454*5c2921b0SApple OSS Distributions
455*5c2921b0SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(sysctl(mib, 6, NULL, &len, NULL, 0), "sysctl NET_RT_IFLIST");
456*5c2921b0SApple OSS Distributions
457*5c2921b0SApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(rt_if_list_buf = calloc(1, len), "rt_if_list_buf calloc(1, %zd)", len);
458*5c2921b0SApple OSS Distributions
459*5c2921b0SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(sysctl(mib, 6, rt_if_list_buf, &len, NULL, 0), "sysctl NET_RT_IFLIST");
460*5c2921b0SApple OSS Distributions
461*5c2921b0SApple OSS Distributions if (label != NULL) {
462*5c2921b0SApple OSS Distributions T_LOG("%s sysctl NET_RT_IFLIST buffer length %zd\n", label, len);
463*5c2921b0SApple OSS Distributions }
464*5c2921b0SApple OSS Distributions
465*5c2921b0SApple OSS Distributions count = 0;
466*5c2921b0SApple OSS Distributions for (i = 0; i < len - pattern_size; i++) {
467*5c2921b0SApple OSS Distributions if (memcmp(rt_if_list_buf + i, pattern_buf, pattern_size) == 0) {
468*5c2921b0SApple OSS Distributions count++;
469*5c2921b0SApple OSS Distributions i += pattern_size - 1;
470*5c2921b0SApple OSS Distributions }
471*5c2921b0SApple OSS Distributions }
472*5c2921b0SApple OSS Distributions
473*5c2921b0SApple OSS Distributions if (label != NULL) {
474*5c2921b0SApple OSS Distributions if (label != NULL && count > 0) {
475*5c2921b0SApple OSS Distributions T_LOG("%s found pattern at %zd count %d times\n", label, i, count);
476*5c2921b0SApple OSS Distributions HexDump(rt_if_list_buf, len);
477*5c2921b0SApple OSS Distributions }
478*5c2921b0SApple OSS Distributions }
479*5c2921b0SApple OSS Distributions
480*5c2921b0SApple OSS Distributions free(rt_if_list_buf);
481*5c2921b0SApple OSS Distributions free(pattern_buf);
482*5c2921b0SApple OSS Distributions
483*5c2921b0SApple OSS Distributions return count;
484*5c2921b0SApple OSS Distributions }
485*5c2921b0SApple OSS Distributions
486*5c2921b0SApple OSS Distributions static bool
find_unused_pattern_in_rt_if_list(unsigned char * pattern,size_t pattern_size)487*5c2921b0SApple OSS Distributions find_unused_pattern_in_rt_if_list(unsigned char *pattern, size_t pattern_size)
488*5c2921b0SApple OSS Distributions {
489*5c2921b0SApple OSS Distributions bool found_pattern = false;
490*5c2921b0SApple OSS Distributions unsigned char i;
491*5c2921b0SApple OSS Distributions unsigned char *pattern_buf = NULL;
492*5c2921b0SApple OSS Distributions
493*5c2921b0SApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(pattern_buf = calloc(1, pattern_size), "pattern_buf calloc(1, %zd)", pattern_size);
494*5c2921b0SApple OSS Distributions
495*5c2921b0SApple OSS Distributions /* Try 10 times to find an unused pattern */
496*5c2921b0SApple OSS Distributions for (i = 1; i < 255; i++) {
497*5c2921b0SApple OSS Distributions if (check_rt_if_list_for_pattern(NULL, i, pattern_size) == 0) {
498*5c2921b0SApple OSS Distributions found_pattern = true;
499*5c2921b0SApple OSS Distributions *pattern = i;
500*5c2921b0SApple OSS Distributions memset(pattern_buf, i, pattern_size);
501*5c2921b0SApple OSS Distributions T_LOG("PATTERN: ");
502*5c2921b0SApple OSS Distributions HexDump(pattern_buf, pattern_size);
503*5c2921b0SApple OSS Distributions break;
504*5c2921b0SApple OSS Distributions }
505*5c2921b0SApple OSS Distributions }
506*5c2921b0SApple OSS Distributions free(pattern_buf);
507*5c2921b0SApple OSS Distributions
508*5c2921b0SApple OSS Distributions return found_pattern;
509*5c2921b0SApple OSS Distributions }
510*5c2921b0SApple OSS Distributions
511*5c2921b0SApple OSS Distributions static const char *
ioc_str(unsigned long cmd)512*5c2921b0SApple OSS Distributions ioc_str(unsigned long cmd)
513*5c2921b0SApple OSS Distributions {
514*5c2921b0SApple OSS Distributions #define X(a) case a: return #a;
515*5c2921b0SApple OSS Distributions
516*5c2921b0SApple OSS Distributions switch (cmd) {
517*5c2921b0SApple OSS Distributions SIOC_LIST
518*5c2921b0SApple OSS Distributions
519*5c2921b0SApple OSS Distributions default:
520*5c2921b0SApple OSS Distributions break;
521*5c2921b0SApple OSS Distributions }
522*5c2921b0SApple OSS Distributions return "";
523*5c2921b0SApple OSS Distributions }
524*5c2921b0SApple OSS Distributions
525*5c2921b0SApple OSS Distributions struct ioc_ifreq {
526*5c2921b0SApple OSS Distributions unsigned long ioc_cmd;
527*5c2921b0SApple OSS Distributions uint8_t salen;
528*5c2921b0SApple OSS Distributions uint8_t safamily;
529*5c2921b0SApple OSS Distributions const char *sastr;
530*5c2921b0SApple OSS Distributions int error; // 0 means no error, -1, end of list, otherwise expected errno
531*5c2921b0SApple OSS Distributions };
532*5c2921b0SApple OSS Distributions
533*5c2921b0SApple OSS Distributions static struct ioc_ifreq ioc_list[] = {
534*5c2921b0SApple OSS Distributions { SIOCSIFADDR, sizeof(struct sockaddr_in), AF_INET6, "10.2.3.1", EINVAL },
535*5c2921b0SApple OSS Distributions { SIOCDIFADDR, sizeof(struct sockaddr_in), AF_INET6, "10.2.3.1", EADDRNOTAVAIL },
536*5c2921b0SApple OSS Distributions { SIOCDIFADDR, sizeof(struct sockaddr_in6), AF_INET, "10.2.3.1", EADDRNOTAVAIL },
537*5c2921b0SApple OSS Distributions { SIOCDIFADDR, sizeof(struct sockaddr_in), AF_INET, "10.2.3.1", EADDRNOTAVAIL },
538*5c2921b0SApple OSS Distributions
539*5c2921b0SApple OSS Distributions { SIOCSIFADDR, 0xf0, AF_INET6, "10.2.3.1", EINVAL },
540*5c2921b0SApple OSS Distributions { SIOCDIFADDR, 0xf0, AF_INET6, "10.2.3.1", EADDRNOTAVAIL },
541*5c2921b0SApple OSS Distributions { SIOCDIFADDR, 0xf0, AF_INET, "10.2.3.1", EADDRNOTAVAIL },
542*5c2921b0SApple OSS Distributions { SIOCDIFADDR, 0xf0, AF_INET, "10.2.3.1", EADDRNOTAVAIL },
543*5c2921b0SApple OSS Distributions
544*5c2921b0SApple OSS Distributions { SIOCSIFADDR, 0, AF_INET6, "10.2.3.1", EINVAL },
545*5c2921b0SApple OSS Distributions { SIOCDIFADDR, 0, AF_INET6, "10.2.3.1", EADDRNOTAVAIL },
546*5c2921b0SApple OSS Distributions { SIOCDIFADDR, 0, AF_INET, "10.2.3.1", EADDRNOTAVAIL },
547*5c2921b0SApple OSS Distributions { SIOCDIFADDR, 0, AF_INET, "10.2.3.1", EADDRNOTAVAIL },
548*5c2921b0SApple OSS Distributions
549*5c2921b0SApple OSS Distributions { SIOCSIFADDR, sizeof(struct sockaddr_in6), AF_INET, "10.2.3.2", 0 },
550*5c2921b0SApple OSS Distributions { SIOCDIFADDR, sizeof(struct sockaddr_in), AF_INET6, "10.2.3.2", 0 },
551*5c2921b0SApple OSS Distributions
552*5c2921b0SApple OSS Distributions { SIOCSIFADDR, sizeof(struct sockaddr_in), AF_INET, "10.2.3.3", 0 },
553*5c2921b0SApple OSS Distributions { SIOCDIFADDR, sizeof(struct sockaddr_in6), AF_INET, "10.2.3.3", 0 },
554*5c2921b0SApple OSS Distributions
555*5c2921b0SApple OSS Distributions { SIOCSIFADDR, sizeof(struct sockaddr_in6), AF_INET6, "10.2.3.4", EINVAL },
556*5c2921b0SApple OSS Distributions { SIOCDIFADDR, sizeof(struct sockaddr_in6), AF_INET, "10.2.3.4", EADDRNOTAVAIL },
557*5c2921b0SApple OSS Distributions
558*5c2921b0SApple OSS Distributions { SIOCSIFADDR, sizeof(struct sockaddr_in), AF_INET, "10.2.3.5", 0 },
559*5c2921b0SApple OSS Distributions { SIOCDIFADDR, sizeof(struct sockaddr_in), AF_INET, "0.0.0.0", EADDRNOTAVAIL },
560*5c2921b0SApple OSS Distributions { SIOCDIFADDR, sizeof(struct sockaddr_in), AF_INET, "10.2.3.5", 0 },
561*5c2921b0SApple OSS Distributions
562*5c2921b0SApple OSS Distributions { SIOCSIFADDR, sizeof(struct sockaddr_in), AF_INET, "10.2.3.6", 0 },
563*5c2921b0SApple OSS Distributions
564*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, sizeof(struct sockaddr_in), 0, "ff.00.00.00", 0 },
565*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, sizeof(struct sockaddr_in), AF_INET, "ff.00.00.00", 0 },
566*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, sizeof(struct sockaddr_in), AF_INET6, "ff.f.00.00", 0 },
567*5c2921b0SApple OSS Distributions
568*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, sizeof(struct sockaddr_in6), 0, "ff.ff.00.00", 0 },
569*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, sizeof(struct sockaddr_in6), AF_INET, "ff.ff.00.00", 0 },
570*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, sizeof(struct sockaddr_in6), AF_INET6, "ff.ff.f0.00", 0 },
571*5c2921b0SApple OSS Distributions
572*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, 0, 0, "ff.ff.00.00", 0 },
573*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, 0, AF_INET, "ff.ff.00.00", 0 },
574*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, 0, AF_INET6, "ff.ff.f0.00", 0 },
575*5c2921b0SApple OSS Distributions
576*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, 0xf0, 0, "ff.ff.00.00", 0 },
577*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, 0xf0, AF_INET, "ff.ff.00.00", 0 },
578*5c2921b0SApple OSS Distributions { SIOCSIFNETMASK, 0xf0, AF_INET6, "ff.ff.f0.00", 0 },
579*5c2921b0SApple OSS Distributions
580*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, sizeof(struct sockaddr_in), 0, "10.255.255.255", 0 },
581*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, sizeof(struct sockaddr_in), AF_INET, "10.255.255.255", 0 },
582*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, sizeof(struct sockaddr_in), AF_INET6, "10.255.255.255", 0 },
583*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, sizeof(struct sockaddr_in6), AF_INET, "10.255.255.255", 0 },
584*5c2921b0SApple OSS Distributions
585*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, 0xf0, 0, "10.255.255.255", 0 },
586*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, 0xf0, AF_INET, "10.255.255.255", 0 },
587*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, 0xf0, AF_INET6, "10.255.255.255", 0 },
588*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, 0xf0, AF_INET, "10.255.255.255", 0 },
589*5c2921b0SApple OSS Distributions
590*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, 0, 0, "10.255.255.255", 0 },
591*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, 0, AF_INET, "10.255.255.255", 0 },
592*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, 0, AF_INET6, "10.255.255.255", 0 },
593*5c2921b0SApple OSS Distributions { SIOCSIFBRDADDR, 0, AF_INET, "10.255.255.255", 0 },
594*5c2921b0SApple OSS Distributions
595*5c2921b0SApple OSS Distributions { 0, 0, 0, "", -1 },
596*5c2921b0SApple OSS Distributions };
597*5c2921b0SApple OSS Distributions
598*5c2921b0SApple OSS Distributions static void
test_sioc_ifr_bounds(struct ioc_ifreq * ioc_ifreq,int s,const char * ifname)599*5c2921b0SApple OSS Distributions test_sioc_ifr_bounds(struct ioc_ifreq *ioc_ifreq, int s, const char *ifname)
600*5c2921b0SApple OSS Distributions {
601*5c2921b0SApple OSS Distributions struct ifreq ifr = {};
602*5c2921b0SApple OSS Distributions unsigned char pattern;
603*5c2921b0SApple OSS Distributions struct sockaddr_in *sin;
604*5c2921b0SApple OSS Distributions
605*5c2921b0SApple OSS Distributions T_LOG("");
606*5c2921b0SApple OSS Distributions T_LOG("TEST CASE: %s ioctl(%s, sa_len %u, sa_family %u, %s) -> %d", __func__,
607*5c2921b0SApple OSS Distributions ioc_str(ioc_ifreq->ioc_cmd), ioc_ifreq->salen, ioc_ifreq->safamily, ioc_ifreq->sastr, ioc_ifreq->error);
608*5c2921b0SApple OSS Distributions
609*5c2921b0SApple OSS Distributions
610*5c2921b0SApple OSS Distributions if (find_unused_pattern_in_rt_if_list(&pattern, PATTERN_SIZE) == false) {
611*5c2921b0SApple OSS Distributions T_SKIP("Could not find unused pattern");
612*5c2921b0SApple OSS Distributions }
613*5c2921b0SApple OSS Distributions
614*5c2921b0SApple OSS Distributions strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
615*5c2921b0SApple OSS Distributions memset(&ifr.ifr_addr.sa_data, pattern, sizeof(ifr.ifr_dstaddr.sa_data));
616*5c2921b0SApple OSS Distributions
617*5c2921b0SApple OSS Distributions sin = (struct sockaddr_in *)(void *)&ifr.ifr_addr;
618*5c2921b0SApple OSS Distributions sin->sin_len = ioc_ifreq->salen;
619*5c2921b0SApple OSS Distributions sin->sin_family = ioc_ifreq->safamily;
620*5c2921b0SApple OSS Distributions sin->sin_addr.s_addr = inet_addr(ioc_ifreq->sastr);
621*5c2921b0SApple OSS Distributions
622*5c2921b0SApple OSS Distributions int retval;
623*5c2921b0SApple OSS Distributions if (ioc_ifreq->error == 0) {
624*5c2921b0SApple OSS Distributions T_EXPECT_POSIX_SUCCESS(retval = ioctl(s, ioc_ifreq->ioc_cmd, &ifr),
625*5c2921b0SApple OSS Distributions "%s, %s: retval %d", ioc_str(ioc_ifreq->ioc_cmd), ioc_ifreq->sastr, retval);
626*5c2921b0SApple OSS Distributions } else {
627*5c2921b0SApple OSS Distributions T_EXPECT_POSIX_FAILURE(retval = ioctl(s, ioc_ifreq->ioc_cmd, &ifr), ioc_ifreq->error,
628*5c2921b0SApple OSS Distributions "%s, %s: retval %d errno %s", ioc_str(ioc_ifreq->ioc_cmd), ioc_ifreq->sastr, retval, strerror(errno));
629*5c2921b0SApple OSS Distributions }
630*5c2921b0SApple OSS Distributions
631*5c2921b0SApple OSS Distributions T_EXPECT_EQ(check_rt_if_list_for_pattern("test_sioc_ifr_bounds", pattern, PATTERN_SIZE), 0, "pattern should not be found");
632*5c2921b0SApple OSS Distributions
633*5c2921b0SApple OSS Distributions
634*5c2921b0SApple OSS Distributions fflush(stdout);
635*5c2921b0SApple OSS Distributions fflush(stderr);
636*5c2921b0SApple OSS Distributions }
637*5c2921b0SApple OSS Distributions
638*5c2921b0SApple OSS Distributions T_DECL(sioc_ifr_bounds, "test bound checks on struct ifreq addresses passed to interface ioctls",
639*5c2921b0SApple OSS Distributions T_META_ASROOT(true))
640*5c2921b0SApple OSS Distributions {
641*5c2921b0SApple OSS Distributions int s = -1;
642*5c2921b0SApple OSS Distributions char ifname[IFNAMSIZ];
643*5c2921b0SApple OSS Distributions
644*5c2921b0SApple OSS Distributions T_LOG("%s", __func__);
645*5c2921b0SApple OSS Distributions
646*5c2921b0SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, 0), "socket");
647*5c2921b0SApple OSS Distributions
648*5c2921b0SApple OSS Distributions strlcpy(ifname, IF_NAME, sizeof(ifname));
649*5c2921b0SApple OSS Distributions
650*5c2921b0SApple OSS Distributions int error = 0;
651*5c2921b0SApple OSS Distributions if ((error = ifnet_create(s, ifname, sizeof(ifname))) != 0) {
652*5c2921b0SApple OSS Distributions if (error == EINVAL) {
653*5c2921b0SApple OSS Distributions T_SKIP("The system does not support the %s cloning interface", IF_NAME);
654*5c2921b0SApple OSS Distributions }
655*5c2921b0SApple OSS Distributions T_SKIP("This test failed creating a %s cloning interface", IF_NAME);
656*5c2921b0SApple OSS Distributions }
657*5c2921b0SApple OSS Distributions T_LOG("created clone interface '%s'", ifname);
658*5c2921b0SApple OSS Distributions
659*5c2921b0SApple OSS Distributions struct ioc_ifreq *ioc_ifreq;
660*5c2921b0SApple OSS Distributions for (ioc_ifreq = ioc_list; ioc_ifreq->error != -1; ioc_ifreq++) {
661*5c2921b0SApple OSS Distributions test_sioc_ifr_bounds(ioc_ifreq, s, ifname);
662*5c2921b0SApple OSS Distributions }
663*5c2921b0SApple OSS Distributions print_rt_iflist2(__func__);
664*5c2921b0SApple OSS Distributions (void)ifnet_destroy(s, ifname, true);
665*5c2921b0SApple OSS Distributions
666*5c2921b0SApple OSS Distributions close(s);
667*5c2921b0SApple OSS Distributions }
668*5c2921b0SApple OSS Distributions
669*5c2921b0SApple OSS Distributions struct ioc_ifra {
670*5c2921b0SApple OSS Distributions const char *description;
671*5c2921b0SApple OSS Distributions
672*5c2921b0SApple OSS Distributions uint8_t addr_len;
673*5c2921b0SApple OSS Distributions uint8_t addr_fam;
674*5c2921b0SApple OSS Distributions const char *addr_str;
675*5c2921b0SApple OSS Distributions
676*5c2921b0SApple OSS Distributions uint8_t broad_len;
677*5c2921b0SApple OSS Distributions uint8_t broad_fam;
678*5c2921b0SApple OSS Distributions const char *broad_str;
679*5c2921b0SApple OSS Distributions
680*5c2921b0SApple OSS Distributions uint8_t mask_len;
681*5c2921b0SApple OSS Distributions uint8_t mask_fam;
682*5c2921b0SApple OSS Distributions const char *mask_str;
683*5c2921b0SApple OSS Distributions
684*5c2921b0SApple OSS Distributions int error; // 0 means no error, -1, end of list, otherwise expected errno
685*5c2921b0SApple OSS Distributions };
686*5c2921b0SApple OSS Distributions
687*5c2921b0SApple OSS Distributions static struct ioc_ifra ioc_ifra_list[] = {
688*5c2921b0SApple OSS Distributions {
689*5c2921b0SApple OSS Distributions .description = "fully formed",
690*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.1.1.1",
691*5c2921b0SApple OSS Distributions .broad_len = sizeof(struct sockaddr_in), .broad_fam = AF_INET, .broad_str = "1.1.1.255",
692*5c2921b0SApple OSS Distributions .mask_len = sizeof(struct sockaddr_in), .mask_fam = AF_INET, .mask_str = "255.255.0.0",
693*5c2921b0SApple OSS Distributions .error = 0
694*5c2921b0SApple OSS Distributions },
695*5c2921b0SApple OSS Distributions {
696*5c2921b0SApple OSS Distributions .description = "addr_len 0",
697*5c2921b0SApple OSS Distributions .addr_len = 0, .addr_fam = AF_INET, .addr_str = "10.2.2.0",
698*5c2921b0SApple OSS Distributions .broad_len = sizeof(struct sockaddr_in), .broad_fam = AF_INET, .broad_str = "10.2.2.255",
699*5c2921b0SApple OSS Distributions .mask_len = sizeof(struct sockaddr_in), .mask_fam = AF_INET, .mask_str = "255.0.0.0",
700*5c2921b0SApple OSS Distributions .error = 0
701*5c2921b0SApple OSS Distributions },
702*5c2921b0SApple OSS Distributions {
703*5c2921b0SApple OSS Distributions .description = "addr_len 1",
704*5c2921b0SApple OSS Distributions .addr_len = 1, .addr_fam = AF_INET, .addr_str = "10.2.2.1",
705*5c2921b0SApple OSS Distributions .broad_len = sizeof(struct sockaddr_in), .broad_fam = AF_INET, .broad_str = "10.2.2.255",
706*5c2921b0SApple OSS Distributions .mask_len = sizeof(struct sockaddr_in), .mask_fam = AF_INET, .mask_str = "255.0.0.0",
707*5c2921b0SApple OSS Distributions .error = 0
708*5c2921b0SApple OSS Distributions },
709*5c2921b0SApple OSS Distributions {
710*5c2921b0SApple OSS Distributions .description = "addr_len 250",
711*5c2921b0SApple OSS Distributions .addr_len = 250, .addr_fam = AF_INET, .addr_str = "10.2.2.250",
712*5c2921b0SApple OSS Distributions .broad_len = sizeof(struct sockaddr_in), .broad_fam = AF_INET, .broad_str = "10.2.2.255",
713*5c2921b0SApple OSS Distributions .mask_len = sizeof(struct sockaddr_in), .mask_fam = AF_INET, .mask_str = "255.0.0.0",
714*5c2921b0SApple OSS Distributions .error = 0
715*5c2921b0SApple OSS Distributions },
716*5c2921b0SApple OSS Distributions {
717*5c2921b0SApple OSS Distributions .description = "addr_family AF_INET6",
718*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET6, .addr_str = "10.3.3.3",
719*5c2921b0SApple OSS Distributions .broad_len = sizeof(struct sockaddr_in), .broad_fam = AF_INET, .broad_str = "10.3.255.255",
720*5c2921b0SApple OSS Distributions .mask_len = sizeof(struct sockaddr_in), .mask_fam = AF_INET, .mask_str = "255.255.255.0",
721*5c2921b0SApple OSS Distributions .error = EINVAL
722*5c2921b0SApple OSS Distributions },
723*5c2921b0SApple OSS Distributions {
724*5c2921b0SApple OSS Distributions .description = "broadcast_len 0xf0",
725*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.4.4.4",
726*5c2921b0SApple OSS Distributions .broad_len = 0xf0, .broad_fam = AF_INET, .broad_str = "10.4.4.255",
727*5c2921b0SApple OSS Distributions .mask_len = sizeof(struct sockaddr_in), .mask_fam = AF_INET, .mask_str = "255.255.255.0",
728*5c2921b0SApple OSS Distributions .error = 0
729*5c2921b0SApple OSS Distributions },
730*5c2921b0SApple OSS Distributions {
731*5c2921b0SApple OSS Distributions .description = "broadcast_family AF_INET6",
732*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.5.5.5",
733*5c2921b0SApple OSS Distributions .broad_len = sizeof(struct sockaddr_in), .broad_fam = AF_INET6, .broad_str = "10.5.5.255",
734*5c2921b0SApple OSS Distributions .mask_len = sizeof(struct sockaddr_in), .mask_fam = AF_INET, .mask_str = "255.255.0.0",
735*5c2921b0SApple OSS Distributions .error = 0
736*5c2921b0SApple OSS Distributions },
737*5c2921b0SApple OSS Distributions {
738*5c2921b0SApple OSS Distributions .description = "mask_len 0xf0",
739*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.6.6.6",
740*5c2921b0SApple OSS Distributions .broad_len = sizeof(struct sockaddr_in), .broad_fam = AF_INET, .broad_str = "1.6.6.255",
741*5c2921b0SApple OSS Distributions .mask_len = 0xf0, .mask_fam = AF_INET, .mask_str = "255.255.0.0",
742*5c2921b0SApple OSS Distributions .error = 0
743*5c2921b0SApple OSS Distributions },
744*5c2921b0SApple OSS Distributions {
745*5c2921b0SApple OSS Distributions .description = "mask_family AF_INET6",
746*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.7.7.7",
747*5c2921b0SApple OSS Distributions .broad_len = sizeof(struct sockaddr_in), .broad_fam = AF_INET, .broad_str = "10.7.7.255",
748*5c2921b0SApple OSS Distributions .mask_len = sizeof(struct sockaddr_in), .mask_fam = AF_INET6, .mask_str = "255.255.0.0",
749*5c2921b0SApple OSS Distributions .error = 0
750*5c2921b0SApple OSS Distributions },
751*5c2921b0SApple OSS Distributions {
752*5c2921b0SApple OSS Distributions .description = "ifra address only",
753*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.8.8.8",
754*5c2921b0SApple OSS Distributions .broad_len = 0, .broad_str = NULL,
755*5c2921b0SApple OSS Distributions .mask_len = 0, .mask_str = NULL,
756*5c2921b0SApple OSS Distributions .error = 0
757*5c2921b0SApple OSS Distributions },
758*5c2921b0SApple OSS Distributions {
759*5c2921b0SApple OSS Distributions .description = "ifra mask len 1",
760*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.9.9.1",
761*5c2921b0SApple OSS Distributions .broad_len = 0, .broad_str = NULL,
762*5c2921b0SApple OSS Distributions .mask_len = 1, .mask_fam = AF_INET, .mask_str = "255.255.255.0",
763*5c2921b0SApple OSS Distributions .error = 0
764*5c2921b0SApple OSS Distributions },
765*5c2921b0SApple OSS Distributions {
766*5c2921b0SApple OSS Distributions .description = "ifra mask len 3",
767*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.9.9.3",
768*5c2921b0SApple OSS Distributions .broad_len = 0, .broad_str = NULL,
769*5c2921b0SApple OSS Distributions .mask_len = 1, .mask_fam = AF_INET, .mask_str = "255.255.255.0",
770*5c2921b0SApple OSS Distributions .error = 0
771*5c2921b0SApple OSS Distributions },
772*5c2921b0SApple OSS Distributions {
773*5c2921b0SApple OSS Distributions .description = "ifra mask len 5",
774*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.9.9.5",
775*5c2921b0SApple OSS Distributions .broad_len = 0, .broad_str = NULL,
776*5c2921b0SApple OSS Distributions .mask_len = 1, .mask_fam = AF_INET, .mask_str = "255.255.255.0",
777*5c2921b0SApple OSS Distributions .error = 0
778*5c2921b0SApple OSS Distributions },
779*5c2921b0SApple OSS Distributions {
780*5c2921b0SApple OSS Distributions .description = "ifra mask len 7",
781*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.9.9.7",
782*5c2921b0SApple OSS Distributions .broad_len = 0, .broad_str = NULL,
783*5c2921b0SApple OSS Distributions .mask_len = 1, .mask_fam = AF_INET, .mask_str = "255.255.255.0",
784*5c2921b0SApple OSS Distributions .error = 0
785*5c2921b0SApple OSS Distributions },
786*5c2921b0SApple OSS Distributions {
787*5c2921b0SApple OSS Distributions .description = "ifra mask len 9",
788*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.9.9.9",
789*5c2921b0SApple OSS Distributions .broad_len = 0, .broad_str = NULL,
790*5c2921b0SApple OSS Distributions .mask_len = 1, .mask_fam = AF_INET, .mask_str = "255.255.255.0",
791*5c2921b0SApple OSS Distributions .error = 0
792*5c2921b0SApple OSS Distributions },
793*5c2921b0SApple OSS Distributions {
794*5c2921b0SApple OSS Distributions .description = "ifra mask len 11",
795*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.9.9.11",
796*5c2921b0SApple OSS Distributions .broad_len = 0, .broad_str = NULL,
797*5c2921b0SApple OSS Distributions .mask_len = 1, .mask_fam = AF_INET, .mask_str = "255.255.255.0",
798*5c2921b0SApple OSS Distributions .error = 0
799*5c2921b0SApple OSS Distributions },
800*5c2921b0SApple OSS Distributions {
801*5c2921b0SApple OSS Distributions .description = "ifra mask len 13",
802*5c2921b0SApple OSS Distributions .addr_len = sizeof(struct sockaddr_in), .addr_fam = AF_INET, .addr_str = "10.9.9.13",
803*5c2921b0SApple OSS Distributions .broad_len = 0, .broad_str = NULL,
804*5c2921b0SApple OSS Distributions .mask_len = 1, .mask_fam = AF_INET, .mask_str = "255.255.255.0",
805*5c2921b0SApple OSS Distributions .error = 0
806*5c2921b0SApple OSS Distributions },
807*5c2921b0SApple OSS Distributions {
808*5c2921b0SApple OSS Distributions .description = NULL,
809*5c2921b0SApple OSS Distributions .error = -1
810*5c2921b0SApple OSS Distributions }
811*5c2921b0SApple OSS Distributions };
812*5c2921b0SApple OSS Distributions
813*5c2921b0SApple OSS Distributions T_DECL(sioc_ifra_addr_bounds, "test bound checks on socket address passed to interface ioctls",
814*5c2921b0SApple OSS Distributions T_META_ASROOT(true))
815*5c2921b0SApple OSS Distributions {
816*5c2921b0SApple OSS Distributions int s = -1;
817*5c2921b0SApple OSS Distributions
818*5c2921b0SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, 0), "socket");
819*5c2921b0SApple OSS Distributions
820*5c2921b0SApple OSS Distributions char ifname[IFNAMSIZ];
821*5c2921b0SApple OSS Distributions strlcpy(ifname, IF_NAME, sizeof(ifname));
822*5c2921b0SApple OSS Distributions int error = 0;
823*5c2921b0SApple OSS Distributions if ((error = ifnet_create(s, ifname, sizeof(ifname))) != 0) {
824*5c2921b0SApple OSS Distributions if (error == EINVAL) {
825*5c2921b0SApple OSS Distributions T_SKIP("The system does not support the %s cloning interface", IF_NAME);
826*5c2921b0SApple OSS Distributions }
827*5c2921b0SApple OSS Distributions T_SKIP("This test failed creating a %s cloning interface", IF_NAME);
828*5c2921b0SApple OSS Distributions }
829*5c2921b0SApple OSS Distributions T_LOG("created clone interface '%s'", ifname);
830*5c2921b0SApple OSS Distributions
831*5c2921b0SApple OSS Distributions struct ioc_ifra *ioc_ifra;
832*5c2921b0SApple OSS Distributions
833*5c2921b0SApple OSS Distributions for (ioc_ifra = ioc_ifra_list; ioc_ifra->error != -1; ioc_ifra++) {
834*5c2921b0SApple OSS Distributions struct in_aliasreq ifra = {};
835*5c2921b0SApple OSS Distributions unsigned char pattern;
836*5c2921b0SApple OSS Distributions int retval;
837*5c2921b0SApple OSS Distributions
838*5c2921b0SApple OSS Distributions T_LOG("");
839*5c2921b0SApple OSS Distributions T_LOG("TEST CASE: %s, ioctl(SIOCAIFADDR, %s)", ioc_ifra->description, ioc_ifra->addr_str != NULL ? ioc_ifra->addr_str : "");
840*5c2921b0SApple OSS Distributions
841*5c2921b0SApple OSS Distributions if (find_unused_pattern_in_rt_if_list(&pattern, PATTERN_SIZE) == false) {
842*5c2921b0SApple OSS Distributions T_SKIP("Could not find unused pattern in rt_if_list");
843*5c2921b0SApple OSS Distributions return;
844*5c2921b0SApple OSS Distributions }
845*5c2921b0SApple OSS Distributions
846*5c2921b0SApple OSS Distributions memset(&ifra, pattern, sizeof(ifra));
847*5c2921b0SApple OSS Distributions
848*5c2921b0SApple OSS Distributions strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
849*5c2921b0SApple OSS Distributions
850*5c2921b0SApple OSS Distributions ifra.ifra_addr.sin_len = ioc_ifra->addr_len;
851*5c2921b0SApple OSS Distributions ifra.ifra_addr.sin_family = ioc_ifra->addr_fam;
852*5c2921b0SApple OSS Distributions if (ioc_ifra->addr_str != NULL) {
853*5c2921b0SApple OSS Distributions ifra.ifra_addr.sin_addr.s_addr = inet_addr(ioc_ifra->addr_str);
854*5c2921b0SApple OSS Distributions }
855*5c2921b0SApple OSS Distributions
856*5c2921b0SApple OSS Distributions ifra.ifra_broadaddr.sin_len = ioc_ifra->broad_len;
857*5c2921b0SApple OSS Distributions ifra.ifra_broadaddr.sin_family = ioc_ifra->broad_fam;
858*5c2921b0SApple OSS Distributions if (ioc_ifra->broad_str != NULL) {
859*5c2921b0SApple OSS Distributions ifra.ifra_broadaddr.sin_addr.s_addr = inet_addr(ioc_ifra->broad_str);
860*5c2921b0SApple OSS Distributions }
861*5c2921b0SApple OSS Distributions
862*5c2921b0SApple OSS Distributions ifra.ifra_mask.sin_len = ioc_ifra->mask_len;
863*5c2921b0SApple OSS Distributions ifra.ifra_mask.sin_family = ioc_ifra->mask_fam;
864*5c2921b0SApple OSS Distributions if (ioc_ifra->mask_str != NULL) {
865*5c2921b0SApple OSS Distributions ifra.ifra_mask.sin_addr.s_addr = inet_addr(ioc_ifra->mask_str);
866*5c2921b0SApple OSS Distributions }
867*5c2921b0SApple OSS Distributions
868*5c2921b0SApple OSS Distributions if (ioc_ifra->error == 0) {
869*5c2921b0SApple OSS Distributions T_EXPECT_POSIX_SUCCESS(retval = ioctl(s, SIOCAIFADDR, &ifra), "SIOCAIFADDR retval %d", retval);
870*5c2921b0SApple OSS Distributions } else {
871*5c2921b0SApple OSS Distributions T_EXPECT_POSIX_FAILURE(retval = ioctl(s, SIOCAIFADDR, &ifra), EINVAL, "SIOCAIFADDR retval %d, %s", retval, strerror(errno));
872*5c2921b0SApple OSS Distributions }
873*5c2921b0SApple OSS Distributions
874*5c2921b0SApple OSS Distributions T_EXPECT_EQ(check_rt_if_list_for_pattern("after ioctl SIOCAIFADDR", pattern, PATTERN_SIZE), 0, "pattern should not be found");
875*5c2921b0SApple OSS Distributions }
876*5c2921b0SApple OSS Distributions
877*5c2921b0SApple OSS Distributions print_rt_iflist2(__func__);
878*5c2921b0SApple OSS Distributions
879*5c2921b0SApple OSS Distributions (void)ifnet_destroy(s, ifname, true);
880*5c2921b0SApple OSS Distributions
881*5c2921b0SApple OSS Distributions close(s);
882*5c2921b0SApple OSS Distributions }
883*5c2921b0SApple OSS Distributions
884*5c2921b0SApple OSS Distributions T_DECL(sioc_ifr_dstaddr_leak, "test bound checks on socket address passed to interface ioctls",
885*5c2921b0SApple OSS Distributions T_META_ASROOT(true))
886*5c2921b0SApple OSS Distributions {
887*5c2921b0SApple OSS Distributions int s = -1;
888*5c2921b0SApple OSS Distributions struct ifreq ifr = {};
889*5c2921b0SApple OSS Distributions unsigned char pattern;
890*5c2921b0SApple OSS Distributions struct ifaddrs *ifap = NULL, *ifa;
891*5c2921b0SApple OSS Distributions bool found_gif0 = false;
892*5c2921b0SApple OSS Distributions
893*5c2921b0SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(getifaddrs(&ifap), "getifaddrs");
894*5c2921b0SApple OSS Distributions for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
895*5c2921b0SApple OSS Distributions if (strcmp(ifa->ifa_name, "gif0") == 0) {
896*5c2921b0SApple OSS Distributions found_gif0 = true;
897*5c2921b0SApple OSS Distributions break;
898*5c2921b0SApple OSS Distributions }
899*5c2921b0SApple OSS Distributions }
900*5c2921b0SApple OSS Distributions freeifaddrs(ifap);
901*5c2921b0SApple OSS Distributions ifap = NULL;
902*5c2921b0SApple OSS Distributions if (found_gif0 == false) {
903*5c2921b0SApple OSS Distributions T_SKIP("gif0 does not exists");
904*5c2921b0SApple OSS Distributions }
905*5c2921b0SApple OSS Distributions
906*5c2921b0SApple OSS Distributions if (find_unused_pattern_in_rt_if_list(&pattern, PATTERN_SIZE) == false) {
907*5c2921b0SApple OSS Distributions T_SKIP("Could not find unused pattern");
908*5c2921b0SApple OSS Distributions return;
909*5c2921b0SApple OSS Distributions }
910*5c2921b0SApple OSS Distributions
911*5c2921b0SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, 0), "socket");
912*5c2921b0SApple OSS Distributions
913*5c2921b0SApple OSS Distributions strlcpy(ifr.ifr_name, "gif0", sizeof(ifr.ifr_name));
914*5c2921b0SApple OSS Distributions ifr.ifr_dstaddr.sa_family = AF_INET6;
915*5c2921b0SApple OSS Distributions ifr.ifr_dstaddr.sa_len = 0xf0;
916*5c2921b0SApple OSS Distributions memset(&ifr.ifr_dstaddr.sa_data, pattern, PATTERN_SIZE);
917*5c2921b0SApple OSS Distributions
918*5c2921b0SApple OSS Distributions T_EXPECT_POSIX_SUCCESS(ioctl(s, SIOCSIFDSTADDR, &ifr), "ioctl(SIOCSIFDSTADDR)");
919*5c2921b0SApple OSS Distributions
920*5c2921b0SApple OSS Distributions print_rt_iflist2(__func__);
921*5c2921b0SApple OSS Distributions
922*5c2921b0SApple OSS Distributions close(s);
923*5c2921b0SApple OSS Distributions
924*5c2921b0SApple OSS Distributions T_EXPECT_EQ(check_rt_if_list_for_pattern("AFTER", pattern, PATTERN_SIZE), 0, "pattern should not be found");
925*5c2921b0SApple OSS Distributions }
926*5c2921b0SApple OSS Distributions
927*5c2921b0SApple OSS Distributions static struct ioc_ifreq ioc_list_config[] = {
928*5c2921b0SApple OSS Distributions { SIOCSIFADDR, sizeof(struct sockaddr_in), AF_INET, "0.0.0.0", EINVAL },
929*5c2921b0SApple OSS Distributions { SIOCSIFADDR, sizeof(struct sockaddr_in), AF_INET, "255.255.255.255", EINVAL },
930*5c2921b0SApple OSS Distributions { SIOCSIFADDR, sizeof(struct sockaddr_in), AF_INET, "238.207.49.91", EINVAL },
931*5c2921b0SApple OSS Distributions
932*5c2921b0SApple OSS Distributions { SIOCAIFADDR_IN6, sizeof(struct sockaddr_in6), AF_INET6, "::", EINVAL },
933*5c2921b0SApple OSS Distributions { SIOCAIFADDR_IN6, sizeof(struct sockaddr_in6), AF_INET6, "ff33:40:fd25:549c:675b::1", EINVAL },
934*5c2921b0SApple OSS Distributions { SIOCAIFADDR_IN6, sizeof(struct sockaddr_in6), AF_INET6, "::ffff:0a0a:0a0a", EINVAL },
935*5c2921b0SApple OSS Distributions { SIOCAIFADDR_IN6, sizeof(struct sockaddr_in6), AF_INET6, "::0a0a:0a0a", EINVAL },
936*5c2921b0SApple OSS Distributions
937*5c2921b0SApple OSS Distributions { 0, 0, 0, "", -1 },
938*5c2921b0SApple OSS Distributions };
939*5c2921b0SApple OSS Distributions
940*5c2921b0SApple OSS Distributions static void
test_sioc_ifr_addr_config_v4(struct ioc_ifreq * ioc_ifreq,int s,const char * ifname)941*5c2921b0SApple OSS Distributions test_sioc_ifr_addr_config_v4(struct ioc_ifreq *ioc_ifreq, int s, const char *ifname)
942*5c2921b0SApple OSS Distributions {
943*5c2921b0SApple OSS Distributions struct ifreq ifr = {};
944*5c2921b0SApple OSS Distributions struct sockaddr_in *sin;
945*5c2921b0SApple OSS Distributions
946*5c2921b0SApple OSS Distributions T_LOG("");
947*5c2921b0SApple OSS Distributions T_LOG("TEST CASE: %s ioctl(%s, sa_len %u, sa_family %u, %s) -> %d", __func__,
948*5c2921b0SApple OSS Distributions ioc_str(ioc_ifreq->ioc_cmd), ioc_ifreq->salen, ioc_ifreq->safamily, ioc_ifreq->sastr, ioc_ifreq->error);
949*5c2921b0SApple OSS Distributions
950*5c2921b0SApple OSS Distributions
951*5c2921b0SApple OSS Distributions strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
952*5c2921b0SApple OSS Distributions
953*5c2921b0SApple OSS Distributions sin = (struct sockaddr_in *)(void *)&ifr.ifr_addr;
954*5c2921b0SApple OSS Distributions sin->sin_len = ioc_ifreq->salen;
955*5c2921b0SApple OSS Distributions sin->sin_family = ioc_ifreq->safamily;
956*5c2921b0SApple OSS Distributions sin->sin_addr.s_addr = inet_addr(ioc_ifreq->sastr);
957*5c2921b0SApple OSS Distributions
958*5c2921b0SApple OSS Distributions int retval;
959*5c2921b0SApple OSS Distributions if (ioc_ifreq->error == 0) {
960*5c2921b0SApple OSS Distributions T_EXPECT_POSIX_SUCCESS(retval = ioctl(s, ioc_ifreq->ioc_cmd, &ifr),
961*5c2921b0SApple OSS Distributions "%s, %s: retval %d", ioc_str(ioc_ifreq->ioc_cmd), ioc_ifreq->sastr, retval);
962*5c2921b0SApple OSS Distributions } else {
963*5c2921b0SApple OSS Distributions T_EXPECT_POSIX_FAILURE(retval = ioctl(s, ioc_ifreq->ioc_cmd, &ifr), ioc_ifreq->error,
964*5c2921b0SApple OSS Distributions "%s, %s: retval %d errno %s", ioc_str(ioc_ifreq->ioc_cmd), ioc_ifreq->sastr, retval, strerror(errno));
965*5c2921b0SApple OSS Distributions }
966*5c2921b0SApple OSS Distributions
967*5c2921b0SApple OSS Distributions fflush(stdout);
968*5c2921b0SApple OSS Distributions fflush(stderr);
969*5c2921b0SApple OSS Distributions }
970*5c2921b0SApple OSS Distributions
971*5c2921b0SApple OSS Distributions static void
test_sioc_ifr_addr_config_v6(struct ioc_ifreq * ioc_ifreq,int s,const char * ifname)972*5c2921b0SApple OSS Distributions test_sioc_ifr_addr_config_v6(struct ioc_ifreq *ioc_ifreq, int s, const char *ifname)
973*5c2921b0SApple OSS Distributions {
974*5c2921b0SApple OSS Distributions struct in6_aliasreq ifra = {{ 0 }, { 0 }, { 0 }, { 0 }, 0, { 0, 0, ND6_INFINITE_LIFETIME, ND6_INFINITE_LIFETIME }};
975*5c2921b0SApple OSS Distributions struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)(void *)&ifra.ifra_addr;
976*5c2921b0SApple OSS Distributions struct sockaddr_in6 *mask6 = (struct sockaddr_in6 *)(void *)&ifra.ifra_prefixmask;
977*5c2921b0SApple OSS Distributions T_LOG("");
978*5c2921b0SApple OSS Distributions T_LOG("TEST CASE: %s ioctl(%s, sa_len %u, sa_family %u, %s) -> %d", __func__,
979*5c2921b0SApple OSS Distributions ioc_str(ioc_ifreq->ioc_cmd), ioc_ifreq->salen, ioc_ifreq->safamily, ioc_ifreq->sastr, ioc_ifreq->error);
980*5c2921b0SApple OSS Distributions
981*5c2921b0SApple OSS Distributions strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
982*5c2921b0SApple OSS Distributions
983*5c2921b0SApple OSS Distributions sin6->sin6_len = ioc_ifreq->salen;
984*5c2921b0SApple OSS Distributions sin6->sin6_family = ioc_ifreq->safamily;
985*5c2921b0SApple OSS Distributions T_ASSERT_EQ(inet_pton(AF_INET6, ioc_ifreq->sastr, &sin6->sin6_addr), 1, NULL);
986*5c2921b0SApple OSS Distributions sin6->sin6_scope_id = if_nametoindex(ifname);
987*5c2921b0SApple OSS Distributions
988*5c2921b0SApple OSS Distributions mask6->sin6_len = ioc_ifreq->salen;
989*5c2921b0SApple OSS Distributions mask6->sin6_family = ioc_ifreq->safamily;
990*5c2921b0SApple OSS Distributions T_ASSERT_EQ(inet_pton(AF_INET6, "ffff:ffff:ffff:ffff::", &mask6->sin6_addr), 1, NULL);
991*5c2921b0SApple OSS Distributions
992*5c2921b0SApple OSS Distributions ifra.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
993*5c2921b0SApple OSS Distributions ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
994*5c2921b0SApple OSS Distributions
995*5c2921b0SApple OSS Distributions int retval;
996*5c2921b0SApple OSS Distributions if (ioc_ifreq->error == 0) {
997*5c2921b0SApple OSS Distributions T_EXPECT_POSIX_SUCCESS(retval = ioctl(s, ioc_ifreq->ioc_cmd, &ifra),
998*5c2921b0SApple OSS Distributions "%s, %s: retval %d", ioc_str(ioc_ifreq->ioc_cmd), ioc_ifreq->sastr, retval);
999*5c2921b0SApple OSS Distributions } else {
1000*5c2921b0SApple OSS Distributions T_EXPECT_POSIX_FAILURE(retval = ioctl(s, ioc_ifreq->ioc_cmd, &ifra), ioc_ifreq->error,
1001*5c2921b0SApple OSS Distributions "%s, %s: retval %d errno %s", ioc_str(ioc_ifreq->ioc_cmd), ioc_ifreq->sastr, retval, strerror(errno));
1002*5c2921b0SApple OSS Distributions }
1003*5c2921b0SApple OSS Distributions
1004*5c2921b0SApple OSS Distributions fflush(stdout);
1005*5c2921b0SApple OSS Distributions fflush(stderr);
1006*5c2921b0SApple OSS Distributions }
1007*5c2921b0SApple OSS Distributions
1008*5c2921b0SApple OSS Distributions
1009*5c2921b0SApple OSS Distributions T_DECL(sioc_ifr_addr_config, "test failure cases for interface address configuration ioctls",
1010*5c2921b0SApple OSS Distributions T_META_ASROOT(true))
1011*5c2921b0SApple OSS Distributions {
1012*5c2921b0SApple OSS Distributions int s = -1;
1013*5c2921b0SApple OSS Distributions int s6 = -1;
1014*5c2921b0SApple OSS Distributions char ifname[IFNAMSIZ];
1015*5c2921b0SApple OSS Distributions
1016*5c2921b0SApple OSS Distributions T_LOG("%s", __func__);
1017*5c2921b0SApple OSS Distributions
1018*5c2921b0SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, 0), "socket");
1019*5c2921b0SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(s6 = socket(AF_INET6, SOCK_DGRAM, 0), "socket");
1020*5c2921b0SApple OSS Distributions
1021*5c2921b0SApple OSS Distributions strlcpy(ifname, IF_NAME, sizeof(ifname));
1022*5c2921b0SApple OSS Distributions
1023*5c2921b0SApple OSS Distributions int error = 0;
1024*5c2921b0SApple OSS Distributions if ((error = ifnet_create(s, ifname, sizeof(ifname))) != 0) {
1025*5c2921b0SApple OSS Distributions if (error == EINVAL) {
1026*5c2921b0SApple OSS Distributions T_SKIP("The system does not support the %s cloning interface", IF_NAME);
1027*5c2921b0SApple OSS Distributions }
1028*5c2921b0SApple OSS Distributions T_SKIP("This test failed creating a %s cloning interface", IF_NAME);
1029*5c2921b0SApple OSS Distributions }
1030*5c2921b0SApple OSS Distributions T_LOG("created clone interface '%s'", ifname);
1031*5c2921b0SApple OSS Distributions
1032*5c2921b0SApple OSS Distributions struct ioc_ifreq *ioc_ifreq;
1033*5c2921b0SApple OSS Distributions for (ioc_ifreq = ioc_list_config; ioc_ifreq->error != -1; ioc_ifreq++) {
1034*5c2921b0SApple OSS Distributions if (ioc_ifreq->safamily == AF_INET) {
1035*5c2921b0SApple OSS Distributions test_sioc_ifr_addr_config_v4(ioc_ifreq, s, ifname);
1036*5c2921b0SApple OSS Distributions } else if (ioc_ifreq->safamily == AF_INET6) {
1037*5c2921b0SApple OSS Distributions test_sioc_ifr_addr_config_v6(ioc_ifreq, s6, ifname);
1038*5c2921b0SApple OSS Distributions }
1039*5c2921b0SApple OSS Distributions }
1040*5c2921b0SApple OSS Distributions print_rt_iflist2(__func__);
1041*5c2921b0SApple OSS Distributions (void)ifnet_destroy(s, ifname, true);
1042*5c2921b0SApple OSS Distributions
1043*5c2921b0SApple OSS Distributions close(s);
1044*5c2921b0SApple OSS Distributions close(s6);
1045*5c2921b0SApple OSS Distributions }
1046*5c2921b0SApple OSS Distributions
1047*5c2921b0SApple OSS Distributions /**
1048*5c2921b0SApple OSS Distributions ** Test SIOCPROTOATTACH, SIOCPROTOATTACH_IN6
1049*5c2921b0SApple OSS Distributions **/
1050*5c2921b0SApple OSS Distributions static int S_socket = -1;
1051*5c2921b0SApple OSS Distributions
1052*5c2921b0SApple OSS Distributions static int
get_inet_dgram_socket(void)1053*5c2921b0SApple OSS Distributions get_inet_dgram_socket(void)
1054*5c2921b0SApple OSS Distributions {
1055*5c2921b0SApple OSS Distributions if (S_socket >= 0) {
1056*5c2921b0SApple OSS Distributions return S_socket;
1057*5c2921b0SApple OSS Distributions }
1058*5c2921b0SApple OSS Distributions S_socket = socket(AF_INET, SOCK_DGRAM, 0);
1059*5c2921b0SApple OSS Distributions T_QUIET;
1060*5c2921b0SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(S_socket, "socket(AF_INET, SOCK_DGRAM, 0)");
1061*5c2921b0SApple OSS Distributions return S_socket;
1062*5c2921b0SApple OSS Distributions }
1063*5c2921b0SApple OSS Distributions
1064*5c2921b0SApple OSS Distributions static void
close_inet_dgram_socket(void)1065*5c2921b0SApple OSS Distributions close_inet_dgram_socket(void)
1066*5c2921b0SApple OSS Distributions {
1067*5c2921b0SApple OSS Distributions if (S_socket >= 0) {
1068*5c2921b0SApple OSS Distributions close(S_socket);
1069*5c2921b0SApple OSS Distributions S_socket = -1;
1070*5c2921b0SApple OSS Distributions }
1071*5c2921b0SApple OSS Distributions }
1072*5c2921b0SApple OSS Distributions
1073*5c2921b0SApple OSS Distributions static int S_socket_6 = -1;
1074*5c2921b0SApple OSS Distributions
1075*5c2921b0SApple OSS Distributions static int
get_inet6_dgram_socket(void)1076*5c2921b0SApple OSS Distributions get_inet6_dgram_socket(void)
1077*5c2921b0SApple OSS Distributions {
1078*5c2921b0SApple OSS Distributions if (S_socket_6 >= 0) {
1079*5c2921b0SApple OSS Distributions return S_socket_6;
1080*5c2921b0SApple OSS Distributions }
1081*5c2921b0SApple OSS Distributions S_socket_6 = socket(AF_INET6, SOCK_DGRAM, 0);
1082*5c2921b0SApple OSS Distributions T_QUIET;
1083*5c2921b0SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(S_socket_6, "socket(AF_INET6, SOCK_DGRAM, 0)");
1084*5c2921b0SApple OSS Distributions return S_socket_6;
1085*5c2921b0SApple OSS Distributions }
1086*5c2921b0SApple OSS Distributions
1087*5c2921b0SApple OSS Distributions static void
close_inet6_dgram_socket(void)1088*5c2921b0SApple OSS Distributions close_inet6_dgram_socket(void)
1089*5c2921b0SApple OSS Distributions {
1090*5c2921b0SApple OSS Distributions if (S_socket_6 >= 0) {
1091*5c2921b0SApple OSS Distributions close(S_socket_6);
1092*5c2921b0SApple OSS Distributions S_socket_6 = -1;
1093*5c2921b0SApple OSS Distributions }
1094*5c2921b0SApple OSS Distributions }
1095*5c2921b0SApple OSS Distributions
1096*5c2921b0SApple OSS Distributions static char ifname[IFNAMSIZ];
1097*5c2921b0SApple OSS Distributions
1098*5c2921b0SApple OSS Distributions static void
test_proto_attach_cleanup(void)1099*5c2921b0SApple OSS Distributions test_proto_attach_cleanup(void)
1100*5c2921b0SApple OSS Distributions {
1101*5c2921b0SApple OSS Distributions if (ifname[0] != '\0') {
1102*5c2921b0SApple OSS Distributions int s;
1103*5c2921b0SApple OSS Distributions
1104*5c2921b0SApple OSS Distributions s = get_inet_dgram_socket();
1105*5c2921b0SApple OSS Distributions (void)ifnet_destroy(s, ifname, false);
1106*5c2921b0SApple OSS Distributions T_LOG("Destroyed '%s'", ifname);
1107*5c2921b0SApple OSS Distributions ifname[0] = '\0';
1108*5c2921b0SApple OSS Distributions }
1109*5c2921b0SApple OSS Distributions }
1110*5c2921b0SApple OSS Distributions
1111*5c2921b0SApple OSS Distributions static void
test_proto_attach_atend(void)1112*5c2921b0SApple OSS Distributions test_proto_attach_atend(void)
1113*5c2921b0SApple OSS Distributions {
1114*5c2921b0SApple OSS Distributions test_proto_attach_cleanup();
1115*5c2921b0SApple OSS Distributions close_inet_dgram_socket();
1116*5c2921b0SApple OSS Distributions close_inet6_dgram_socket();
1117*5c2921b0SApple OSS Distributions }
1118*5c2921b0SApple OSS Distributions
1119*5c2921b0SApple OSS Distributions static void
test_proto_attach(void)1120*5c2921b0SApple OSS Distributions test_proto_attach(void)
1121*5c2921b0SApple OSS Distributions {
1122*5c2921b0SApple OSS Distributions int error;
1123*5c2921b0SApple OSS Distributions struct ifreq ifr;
1124*5c2921b0SApple OSS Distributions int s;
1125*5c2921b0SApple OSS Distributions int s6;
1126*5c2921b0SApple OSS Distributions
1127*5c2921b0SApple OSS Distributions T_ATEND(test_proto_attach_atend);
1128*5c2921b0SApple OSS Distributions s = get_inet_dgram_socket();
1129*5c2921b0SApple OSS Distributions strlcpy(ifname, "feth", sizeof(ifname));
1130*5c2921b0SApple OSS Distributions error = ifnet_create(s, ifname, sizeof(ifname));
1131*5c2921b0SApple OSS Distributions if (error != 0) {
1132*5c2921b0SApple OSS Distributions if (error == EINVAL) {
1133*5c2921b0SApple OSS Distributions T_SKIP("%s cloning interface not supported", ifname);
1134*5c2921b0SApple OSS Distributions }
1135*5c2921b0SApple OSS Distributions T_SKIP("%s cloning interface failed", ifname);
1136*5c2921b0SApple OSS Distributions }
1137*5c2921b0SApple OSS Distributions T_LOG("Created '%s'", ifname);
1138*5c2921b0SApple OSS Distributions
1139*5c2921b0SApple OSS Distributions /* first proto attach should succeed */
1140*5c2921b0SApple OSS Distributions bzero(&ifr, sizeof(ifr));
1141*5c2921b0SApple OSS Distributions strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1142*5c2921b0SApple OSS Distributions error = ioctl(s, SIOCPROTOATTACH, &ifr);
1143*5c2921b0SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(error, "SIOCPROTOATTACH %s succeeded",
1144*5c2921b0SApple OSS Distributions ifr.ifr_name);
1145*5c2921b0SApple OSS Distributions
1146*5c2921b0SApple OSS Distributions /* second proto attach should fail with EEXIST */
1147*5c2921b0SApple OSS Distributions error = ioctl(s, SIOCPROTOATTACH, &ifr);
1148*5c2921b0SApple OSS Distributions T_ASSERT_POSIX_FAILURE(error, EEXIST,
1149*5c2921b0SApple OSS Distributions "SIOCPROTOATTACH %s failed as expected",
1150*5c2921b0SApple OSS Distributions ifr.ifr_name);
1151*5c2921b0SApple OSS Distributions
1152*5c2921b0SApple OSS Distributions /* first proto attach should succeed */
1153*5c2921b0SApple OSS Distributions s6 = get_inet6_dgram_socket();
1154*5c2921b0SApple OSS Distributions bzero(&ifr, sizeof(ifr));
1155*5c2921b0SApple OSS Distributions strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1156*5c2921b0SApple OSS Distributions error = ioctl(s6, SIOCPROTOATTACH_IN6, &ifr);
1157*5c2921b0SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(error,
1158*5c2921b0SApple OSS Distributions "SIOCPROTOATTACH_IN6 %s succeeded",
1159*5c2921b0SApple OSS Distributions ifr.ifr_name);
1160*5c2921b0SApple OSS Distributions
1161*5c2921b0SApple OSS Distributions /* second proto attach should fail with EEXIST */
1162*5c2921b0SApple OSS Distributions error = ioctl(s6, SIOCPROTOATTACH_IN6, &ifr);
1163*5c2921b0SApple OSS Distributions T_ASSERT_POSIX_FAILURE(error, EEXIST,
1164*5c2921b0SApple OSS Distributions "SIOCPROTOATTACH_IN6 %s failed as expected",
1165*5c2921b0SApple OSS Distributions ifr.ifr_name);
1166*5c2921b0SApple OSS Distributions test_proto_attach_cleanup();
1167*5c2921b0SApple OSS Distributions }
1168*5c2921b0SApple OSS Distributions
1169*5c2921b0SApple OSS Distributions T_DECL(sioc_proto_attach, "test protocol attachment",
1170*5c2921b0SApple OSS Distributions T_META_ASROOT(true))
1171*5c2921b0SApple OSS Distributions {
1172*5c2921b0SApple OSS Distributions test_proto_attach();
1173*5c2921b0SApple OSS Distributions }
1174