]> git.saurik.com Git - apple/xnu.git/blob - tests/net_tuntests.c
xnu-4903.221.2.tar.gz
[apple/xnu.git] / tests / net_tuntests.c
1
2 #include <inttypes.h>
3 #include <stdbool.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <time.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <poll.h>
10 #include <sys/event.h>
11 #include <uuid/uuid.h>
12 #include <arpa/inet.h>
13 #include <sys/types.h>
14 #include <sys/sysctl.h>
15 #include <sys/kern_control.h>
16 #include <sys/ioctl.h>
17 #include <sys/socket.h>
18 #include <sys/kern_control.h>
19 #include <sys/sys_domain.h>
20
21 #include <net/if.h>
22 #include <net/if_ipsec.h>
23 #include <net/if_utun.h>
24 #include <netinet/in.h>
25 #include <netinet/in_var.h>
26 #include <net/pfkeyv2.h>
27 #include <netinet6/ipsec.h>
28
29 #include <darwintest.h>
30 #include <darwintest_utils.h>
31
32 #include <skywalk/os_skywalk_private.h> // for SK_FEATURE_*
33
34 T_GLOBAL_META(T_META_NAMESPACE("xnu.net.tun"));
35
36 #if 0
37 static void
38 log_hexdump(const void *inp, size_t len)
39 {
40 unsigned i, off = 0;
41 char buf[9+16*3+1];
42 for (i = 0; i < len; i++) {
43 if (i % 16 == 0)
44 off = (unsigned)snprintf(buf, sizeof(buf), "%08x:", i);
45 off += (unsigned)snprintf(buf+off, sizeof(buf)-off, " %02x", (((const uint8_t *)inp)[i]) & 0xff);
46 if (i % 16 == 15)
47 T_LOG("%s", buf);
48 }
49 if (len % 16)
50 T_LOG("%s", buf);
51 }
52 #endif
53
54 static uint64_t
55 get_skywalk_features(void)
56 {
57 uint64_t features = 0;
58 size_t len = sizeof(features);
59 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(sysctlbyname("kern.skywalk.features", &features, &len, NULL, 0), NULL);
60 T_QUIET; T_ASSERT_EQ(len, sizeof(features), NULL);
61 T_QUIET; T_ASSERT_TRUE(features & SK_FEATURE_SKYWALK, NULL);
62 return features;
63 }
64
65 static bool g_is_ipsec_test;
66 static bool g_is_utun_test;
67 static int g_OPT_ENABLE_NETIF = -1;
68 static int g_OPT_ENABLE_FLOWSWITCH = -1;
69 static int g_OPT_ENABLE_CHANNEL = -1;
70 static int g_OPT_GET_CHANNEL_UUID = -1;
71 static int g_OPT_IFNAME = -1;
72 static char *g_CONTROL_NAME = NULL;
73
74 static void
75 setup_ipsec_test(void)
76 {
77 T_LOG("Configuring for ipsec tests");
78 g_OPT_ENABLE_NETIF = IPSEC_OPT_ENABLE_NETIF;
79 g_OPT_ENABLE_FLOWSWITCH = IPSEC_OPT_ENABLE_FLOWSWITCH;
80 g_OPT_ENABLE_CHANNEL = IPSEC_OPT_ENABLE_CHANNEL;
81 g_OPT_GET_CHANNEL_UUID = IPSEC_OPT_GET_CHANNEL_UUID;
82 g_OPT_IFNAME = IPSEC_OPT_IFNAME;
83 g_CONTROL_NAME = IPSEC_CONTROL_NAME;
84 g_is_ipsec_test = true;
85 }
86
87 static void
88 setup_utun_test(void)
89 {
90 T_LOG("Configuring for utun tests");
91 g_OPT_ENABLE_NETIF = UTUN_OPT_ENABLE_NETIF;
92 g_OPT_ENABLE_FLOWSWITCH = UTUN_OPT_ENABLE_FLOWSWITCH;
93 g_OPT_ENABLE_CHANNEL = UTUN_OPT_ENABLE_CHANNEL;
94 g_OPT_GET_CHANNEL_UUID = UTUN_OPT_GET_CHANNEL_UUID;
95 g_OPT_IFNAME = UTUN_OPT_IFNAME;
96 g_CONTROL_NAME = UTUN_CONTROL_NAME;
97 g_is_utun_test = true;
98 }
99
100 static void
101 check_enables(int tunsock, int enable_netif, int enable_flowswitch, int enable_channel, uuid_t uuid)
102 {
103 int scratch;
104 socklen_t scratchlen, uuidlen;
105 uuid_t scratchuuid;
106 if (!uuid) {
107 uuid = scratchuuid;
108 }
109
110 //T_LOG("checking tunsock %d", tunsock);
111
112 scratchlen = sizeof(scratch);
113 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
114 &scratch, &scratchlen), NULL);
115 T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )scratchlen, sizeof(scratch), NULL);
116 T_QUIET; T_EXPECT_EQ(scratch, enable_netif, NULL);
117
118 scratchlen = sizeof(scratch);
119 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
120 &scratch, &scratchlen), NULL);
121 T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )scratchlen, sizeof(scratch), NULL);
122 if (get_skywalk_features() & SK_FEATURE_NETNS) {
123 if (enable_netif) {
124 T_QUIET; T_EXPECT_EQ(scratch, enable_flowswitch, NULL);
125 } else {
126 T_QUIET; T_EXPECT_EQ(scratch, 0, NULL);
127 }
128 } else {
129 T_QUIET; T_EXPECT_EQ(scratch, 0, NULL);
130 }
131
132 scratchlen = sizeof(scratch);
133 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
134 &scratch, &scratchlen), NULL);
135 T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )scratchlen, sizeof(scratch), NULL);
136 if (g_is_ipsec_test && !enable_netif) {
137 T_QUIET; T_EXPECT_EQ(scratch, 0, NULL);
138 } else {
139 T_QUIET; T_EXPECT_EQ(scratch, enable_channel, NULL);
140 }
141
142 if (scratch) {
143 uuid_clear(uuid);
144 uuidlen = sizeof(uuid_t);
145 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
146 uuid, &uuidlen), NULL);
147 T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
148 T_QUIET; T_EXPECT_FALSE(uuid_is_null(uuid), NULL);
149 } else {
150 uuid_clear(uuid);
151 uuidlen = sizeof(uuid_t);
152 T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
153 uuid, &uuidlen), ENXIO, NULL);
154 T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
155 T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid), NULL);
156 }
157 }
158
159 static void
160 tunsock_get_ifname(int s, char ifname[IFXNAMSIZ])
161 {
162 socklen_t optlen = IFXNAMSIZ;
163 T_QUIET; T_WITH_ERRNO; T_ASSERT_POSIX_ZERO(getsockopt(s, SYSPROTO_CONTROL, g_OPT_IFNAME, ifname, &optlen), NULL);
164 T_QUIET; T_ASSERT_TRUE(optlen > 0, NULL);
165 T_QUIET; T_ASSERT_TRUE(ifname[optlen-1] == '\0', NULL);
166 T_QUIET; T_ASSERT_TRUE(strlen(ifname)+1 == optlen, "got ifname \"%s\" len %zd expected %u", ifname, strlen(ifname), optlen);
167 }
168
169 static short
170 ifnet_get_flags(int s, const char ifname[IFNAMSIZ])
171 {
172 struct ifreq ifr;
173 memset(&ifr, 0, sizeof(ifr));
174 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
175 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr), NULL);
176 return ifr.ifr_flags;
177 }
178
179 static void
180 ifnet_add_addr4(const char ifname[IFNAMSIZ], struct in_addr *addr, struct in_addr *mask, struct in_addr *broadaddr)
181 {
182 struct sockaddr_in *sin;
183 struct in_aliasreq ifra;
184 int s;
185
186 T_QUIET; T_EXPECT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, 0), NULL);
187
188 memset(&ifra, 0, sizeof(ifra));
189 strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
190
191 if (addr != NULL) {
192 sin = &ifra.ifra_addr;
193 sin->sin_len = sizeof(*sin);
194 sin->sin_family = AF_INET;
195 sin->sin_addr = *addr;
196 }
197
198 if (mask != NULL) {
199 sin = &ifra.ifra_mask;
200 sin->sin_len = sizeof(*sin);
201 sin->sin_family = AF_INET;
202 sin->sin_addr = *mask;
203 }
204
205 if (broadaddr != NULL || (addr != NULL &&
206 (ifnet_get_flags(s, ifname) & IFF_POINTOPOINT) != 0)) {
207 sin = &ifra.ifra_broadaddr;
208 sin->sin_len = sizeof(*sin);
209 sin->sin_family = AF_INET;
210 sin->sin_addr = (broadaddr != NULL) ? *broadaddr : *addr;
211 }
212
213 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(ioctl(s, SIOCAIFADDR, &ifra), NULL);
214
215 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(s), NULL);
216 }
217
218 static int g_pfkeyso = -1;
219 static struct in_addr g_addr1, g_addr2;
220
221 static void
222 create_sa(const char ifname[IFXNAMSIZ], uint8_t type, uint32_t spi, struct in_addr *src, struct in_addr *dst)
223 {
224 if (g_pfkeyso == -1) {
225 T_QUIET; T_EXPECT_POSIX_SUCCESS(g_pfkeyso = socket(PF_KEY, SOCK_RAW, PF_KEY_V2), NULL);
226 }
227
228 /*
229 <base, SA, (lifetime(HS),) address(SD), (address(P),)
230 key(AE), (identity(SD),) (sensitivity)>
231 */
232
233 struct {
234 struct sadb_msg msg __attribute((aligned(sizeof (uint64_t))));
235 struct sadb_key key __attribute((aligned(sizeof (uint64_t))));
236 struct sadb_sa sa __attribute((aligned(sizeof (uint64_t))));
237 struct sadb_x_sa2 sa2 __attribute((aligned(sizeof (uint64_t))));
238 struct sadb_x_ipsecif ipsecif __attribute((aligned(sizeof (uint64_t))));
239 struct {
240 struct sadb_address addr __attribute((aligned(sizeof (uint64_t))));
241 struct sockaddr_in saddr __attribute((aligned(sizeof (uint64_t))));
242 } src;
243 struct {
244 struct sadb_address addr __attribute((aligned(sizeof (uint64_t))));
245 struct sockaddr_in saddr __attribute((aligned(sizeof (uint64_t))));
246 } dst;
247 } addcmd;
248
249 memset(&addcmd, 0, sizeof(addcmd));
250
251 addcmd.msg.sadb_msg_version = PF_KEY_V2;
252 addcmd.msg.sadb_msg_type = type;
253 addcmd.msg.sadb_msg_errno = 0;
254 addcmd.msg.sadb_msg_satype = SADB_SATYPE_ESP;
255 addcmd.msg.sadb_msg_len = PFKEY_UNIT64(sizeof(addcmd));
256 addcmd.msg.sadb_msg_reserved = 0;
257 addcmd.msg.sadb_msg_seq = 0;
258 addcmd.msg.sadb_msg_pid = (unsigned)getpid();
259
260 addcmd.key.sadb_key_len = PFKEY_UNIT64(sizeof(addcmd.key));
261 addcmd.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
262 addcmd.key.sadb_key_bits = 0;
263 addcmd.key.sadb_key_reserved = 0;
264
265 addcmd.sa.sadb_sa_len = PFKEY_UNIT64(sizeof(addcmd.sa));
266 addcmd.sa.sadb_sa_exttype = SADB_EXT_SA;
267 addcmd.sa.sadb_sa_spi = htonl(spi);
268 addcmd.sa.sadb_sa_replay = 0;
269 addcmd.sa.sadb_sa_state = 0;
270 addcmd.sa.sadb_sa_auth = SADB_AALG_NONE;
271 addcmd.sa.sadb_sa_encrypt = SADB_EALG_NULL;
272 addcmd.sa.sadb_sa_flags = SADB_X_EXT_CYCSEQ;
273
274 addcmd.sa2.sadb_x_sa2_len = PFKEY_UNIT64(sizeof(addcmd.sa2));
275 addcmd.sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
276 addcmd.sa2.sadb_x_sa2_mode = IPSEC_MODE_ANY;
277 addcmd.sa2.sadb_x_sa2_alwaysexpire = 1;
278 addcmd.sa2.sadb_x_sa2_flags = SADB_X_EXT_SA2_DELETE_ON_DETACH;
279 addcmd.sa2.sadb_x_sa2_sequence = 0;
280 addcmd.sa2.sadb_x_sa2_reqid = 0;
281
282 addcmd.ipsecif.sadb_x_ipsecif_len = PFKEY_UNIT64(sizeof(addcmd.ipsecif));
283 addcmd.ipsecif.sadb_x_ipsecif_exttype = SADB_X_EXT_IPSECIF;
284 memset(addcmd.ipsecif.sadb_x_ipsecif_internal_if, 0, sizeof(addcmd.ipsecif.sadb_x_ipsecif_internal_if));
285 memset(addcmd.ipsecif.sadb_x_ipsecif_outgoing_if, 0, sizeof(addcmd.ipsecif.sadb_x_ipsecif_outgoing_if));
286 strlcpy(addcmd.ipsecif.sadb_x_ipsecif_ipsec_if, ifname, sizeof(addcmd.ipsecif.sadb_x_ipsecif_ipsec_if));
287 addcmd.ipsecif.sadb_x_ipsecif_init_disabled = 0;
288 addcmd.ipsecif.reserved = 0;
289
290 addcmd.src.addr.sadb_address_len = PFKEY_UNIT64(sizeof(addcmd.src));
291 addcmd.src.addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
292 addcmd.src.addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
293 addcmd.src.addr.sadb_address_prefixlen = sizeof(struct in_addr) << 3; //XXX Why?
294 addcmd.src.addr.sadb_address_reserved = 0;
295 addcmd.src.saddr.sin_len = sizeof(addcmd.src.saddr);
296 addcmd.src.saddr.sin_family = AF_INET;
297 addcmd.src.saddr.sin_port = htons(0);
298 addcmd.src.saddr.sin_addr = *src;
299
300 addcmd.dst.addr.sadb_address_len = PFKEY_UNIT64(sizeof(addcmd.dst));
301 addcmd.dst.addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
302 addcmd.dst.addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
303 addcmd.dst.addr.sadb_address_prefixlen = sizeof(struct in_addr) << 3; //XXX Why?
304 addcmd.dst.addr.sadb_address_reserved = 0;
305 addcmd.dst.saddr.sin_len = sizeof(addcmd.dst.saddr);
306 addcmd.dst.saddr.sin_family = AF_INET;
307 addcmd.dst.saddr.sin_port = htons(0);
308 addcmd.dst.saddr.sin_addr = *dst;
309
310 //log_hexdump(&addcmd, sizeof(addcmd));
311
312 ssize_t slen;
313 T_QUIET; T_EXPECT_POSIX_SUCCESS(slen = send(g_pfkeyso, &addcmd, sizeof(addcmd), 0), NULL);
314 T_QUIET; T_EXPECT_EQ(slen, (ssize_t)sizeof(addcmd), NULL);
315 }
316
317 static int
318 create_tunsock(int enable_netif, int enable_flowswitch, int enable_channel)
319 {
320 int tunsock;
321 struct ctl_info kernctl_info;
322 struct sockaddr_ctl kernctl_addr;
323 uuid_t uuid;
324 socklen_t uuidlen;
325
326 startover:
327
328 T_QUIET; T_EXPECT_POSIX_SUCCESS(tunsock = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL), NULL);
329
330 memset(&kernctl_info, 0, sizeof(kernctl_info));
331 strlcpy(kernctl_info.ctl_name, g_CONTROL_NAME, sizeof(kernctl_info.ctl_name));
332 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(ioctl(tunsock, CTLIOCGINFO, &kernctl_info), NULL);
333
334 memset(&kernctl_addr, 0, sizeof(kernctl_addr));
335 kernctl_addr.sc_len = sizeof(kernctl_addr);
336 kernctl_addr.sc_family = AF_SYSTEM;
337 kernctl_addr.ss_sysaddr = AF_SYS_CONTROL;
338 kernctl_addr.sc_id = kernctl_info.ctl_id;
339 kernctl_addr.sc_unit = 0;
340
341 //T_LOG("enable_netif = %d, enable_flowswitch = %d, enable_channel = %d",
342 //enable_netif, enable_channel, enable_flowswitch);
343
344 T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
345 &enable_netif, sizeof(enable_netif)), EINVAL, NULL);
346 T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
347 &enable_flowswitch, sizeof(enable_flowswitch)), EINVAL, NULL);
348 T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
349 &enable_channel, sizeof(enable_channel)), EINVAL, NULL);
350 uuid_clear(uuid);
351 uuidlen = sizeof(uuid_t);
352 T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
353 uuid, &uuidlen), EINVAL, NULL);
354 T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
355 T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid), NULL);
356
357 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(bind(tunsock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr)), NULL);
358
359 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
360 &enable_netif, sizeof(enable_netif)), NULL);
361 T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
362 &enable_flowswitch, sizeof(enable_flowswitch)), EINVAL, NULL);
363 T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
364 &enable_channel, sizeof(enable_channel)), EINVAL, NULL);
365 uuid_clear(uuid);
366 uuidlen = sizeof(uuid_t);
367 T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
368 uuid, &uuidlen), ENXIO, NULL);
369 T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
370 T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid), NULL);
371
372 int error = connect(tunsock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr));
373 if (error == -1 && errno == EBUSY) {
374 /* XXX remove this retry nonsense when this is fixed:
375 * <rdar://problem/37340313> creating an interface without specifying specific interface name should not return EBUSY
376 */
377 close(tunsock);
378 T_LOG("connect got EBUSY, sleeping 1 second before retry");
379 sleep(1);
380 goto startover;
381 }
382 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(error, "connect()");
383
384 T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
385 &enable_netif, sizeof(enable_netif)), EINVAL, NULL);
386
387 if (get_skywalk_features() & SK_FEATURE_NETNS) {
388 if (enable_netif) {
389 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
390 &enable_flowswitch, sizeof(enable_flowswitch)), NULL);
391 } else {
392 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
393 &enable_flowswitch, sizeof(enable_flowswitch)), ENOENT, NULL);
394 }
395 } else {
396 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
397 &enable_flowswitch, sizeof(enable_flowswitch)), ENOTSUP, NULL);
398 }
399
400 if (enable_channel) {
401 if (g_is_ipsec_test && !enable_netif) {
402 /* ipsec doesn't support channels without a netif */
403 T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
404 &enable_channel, sizeof(enable_channel)), EOPNOTSUPP, NULL);
405 uuid_clear(uuid);
406 uuidlen = sizeof(uuid_t);
407 T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
408 uuid, &uuidlen), ENXIO, NULL);
409 T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
410 T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid), NULL);
411 } else {
412 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
413 &enable_channel, sizeof(enable_channel)), NULL);
414 uuid_clear(uuid);
415 uuidlen = sizeof(uuid_t);
416 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
417 uuid, &uuidlen), NULL);
418 T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
419 T_QUIET; T_EXPECT_FALSE(uuid_is_null(uuid), NULL);
420 }
421 } else {
422 T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
423 &enable_channel, sizeof(enable_channel)), ENXIO, NULL);
424 uuid_clear(uuid);
425 uuidlen = sizeof(uuid_t);
426 T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
427 uuid, &uuidlen), ENXIO, NULL);
428 T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
429 T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid), NULL);
430 }
431
432 check_enables(tunsock, enable_netif, enable_flowswitch, enable_channel, uuid);
433
434 //T_LOG("Returning tunsock %d", tunsock);
435
436 return tunsock;
437 }
438
439 #if 0
440 static void
441 ipsec_stats(void)
442 {
443 struct ifmibdata ifmd;
444
445 len = sizeof(struct ifmibdata);
446 name[3] = IFMIB_IFDATA;
447 name[4] = interesting_row;
448 name[5] = IpFDATA_GENERAL;
449 if (sysctl(name, 6, &ifmd, &len, (void *)0, 0) == -1)
450 err(1, "sysctl IFDATA_GENERAL %d", interesting_row);
451 }
452 #endif
453
454 static void
455 permute_enables(void)
456 {
457 int tunsock;
458 T_EXPECT_GE(tunsock = create_tunsock(false, false, false), 0, NULL);
459 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
460 T_EXPECT_GE(tunsock = create_tunsock(false, false, true), 0, NULL);
461 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
462 T_EXPECT_GE(tunsock = create_tunsock(false, true, false), 0, NULL);
463 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
464 T_EXPECT_GE(tunsock = create_tunsock(false, true, true), 0, NULL);
465 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
466 T_EXPECT_GE(tunsock = create_tunsock(true, false, false), 0, NULL);
467 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
468 T_EXPECT_GE(tunsock = create_tunsock(true, false, true), 0, NULL);
469 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
470 T_EXPECT_GE(tunsock = create_tunsock(true, true, false), 0, NULL);
471 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
472 T_EXPECT_GE(tunsock = create_tunsock(true, true, true), 0, NULL);
473 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
474 }
475
476 T_DECL(ipsec_enables, "This test checks combinations of netif/channel/flowswitch on ipsec")
477 {
478 setup_ipsec_test();
479 permute_enables();
480 }
481
482 T_DECL(utun_enables, "This test checks combinations of netif/channel/flowswitch on utun")
483 {
484 setup_utun_test();
485 permute_enables();
486 }
487
488 static int g_tunsock = -1;
489
490 static void
491 cleanup_tunsock(void)
492 {
493 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(g_tunsock), NULL);
494 T_QUIET; T_EXPECT_POSIX_FAILURE(close(g_tunsock), EBADF, NULL);
495 if (g_is_ipsec_test) {
496 T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(g_pfkeyso), NULL);
497 T_QUIET; T_EXPECT_POSIX_FAILURE(close(g_pfkeyso), EBADF, NULL);
498 }
499 }
500
501 static void
502 setup_tunsock(void)
503 {
504 T_ASSERT_GE(g_tunsock = create_tunsock(true, false, true), 0, NULL);
505 T_ATEND(cleanup_tunsock);
506
507 char ifname[IFXNAMSIZ];
508 tunsock_get_ifname(g_tunsock, ifname);
509
510 T_LOG("Created interface %s", ifname);
511
512 uint32_t ifaddr = (10 << 24) | ((unsigned)getpid()&0xffff) << 8 | 160;
513 struct in_addr mask;
514 g_addr1.s_addr = htonl(ifaddr);
515 g_addr2.s_addr = htonl(ifaddr+1);
516 mask.s_addr = htonl(0xffffffff);
517
518 ifnet_add_addr4(ifname, &g_addr1, &mask, &g_addr2);
519
520 if (g_is_ipsec_test) {
521 create_sa(ifname, SADB_ADD, 12345, &g_addr1, &g_addr2);
522 create_sa(ifname, SADB_ADD, 12346, &g_addr2, &g_addr1);
523 }
524 }
525
526 T_DECL(setup_ipsec, "This test sets up an ipsec interface")
527 {
528 setup_ipsec_test();
529 setup_tunsock();
530 }
531
532 T_DECL(setup_utun, "This test sets up a utun interface")
533 {
534 setup_utun_test();
535 setup_tunsock();
536 }