1 /*
2 * Copyright (c) 2022-2024 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <sys/fcntl.h>
30 #include <sys/socket.h>
31
32 #include <net/if.h>
33 #include <net/route.h>
34
35 #include <netinet/in.h>
36
37 #include <stdbool.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41
42 #include <arpa/inet.h>
43
44 #include <darwintest.h>
45
46 #include "net_test_lib.h"
47
48 T_GLOBAL_META(
49 T_META_NAMESPACE("xnu.net"),
50 T_META_RADAR_COMPONENT_NAME("xnu"),
51 T_META_RADAR_COMPONENT_VERSION("networking")
52 );
53
54 #define MAX_IPv6_STR_LEN 64
55
56 static char l_addr_str[MAX_IPv6_STR_LEN];
57 static char f_addr_str[MAX_IPv6_STR_LEN];
58
59 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
60 #define s6_addr32 __u6_addr.__u6_addr32
61
62
63 static void
init_sin_address(struct sockaddr_in * sin)64 init_sin_address(struct sockaddr_in *sin)
65 {
66 memset(sin, 0, sizeof(struct sockaddr_in));
67 sin->sin_len = sizeof(struct sockaddr_in);
68 sin->sin_family = AF_INET;
69 }
70
71 static void
init_sin6_address(struct sockaddr_in6 * sin6)72 init_sin6_address(struct sockaddr_in6 *sin6)
73 {
74 memset(sin6, 0, sizeof(struct sockaddr_in6));
75 sin6->sin6_len = sizeof(struct sockaddr_in6);
76 sin6->sin6_family = AF_INET6;
77 }
78
79 static void
udp_connect_v4(int client_fd,struct sockaddr_in * sin_to,int expected_error)80 udp_connect_v4(int client_fd, struct sockaddr_in *sin_to, int expected_error)
81 {
82 int listen_fd = -1;
83 socklen_t socklen;
84 struct sockaddr_in sin_local = { 0 };
85 struct sockaddr_in sin_peer = { 0 };
86 struct sockaddr_in sin;
87
88 init_sin_address(&sin);
89 init_sin_address(&sin_local);
90 init_sin_address(&sin_peer);
91
92 T_ASSERT_POSIX_SUCCESS(listen_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
93
94 T_ASSERT_POSIX_SUCCESS(bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)), NULL);
95
96 socklen = sizeof(sin);
97 T_ASSERT_POSIX_SUCCESS(getsockname(listen_fd, (struct sockaddr *)&sin, &socklen), NULL);
98
99 T_LOG("listening on port: %u", ntohs(sin.sin_port));
100 sin_to->sin_port = sin.sin_port;
101
102 T_LOG("connect with sin_len: %u sin_family: %u sin_port: %u sin_addr: 0x%08x expected_error: %d",
103 sin_to->sin_len, sin_to->sin_family, ntohs(sin_to->sin_port), ntohl(sin_to->sin_addr.s_addr), expected_error);
104
105 if (expected_error == 0) {
106 T_EXPECT_POSIX_SUCCESS(connect(client_fd, (struct sockaddr *)sin_to, sizeof(struct sockaddr_in)), NULL);
107
108 socklen = sizeof(sin_local);
109 T_ASSERT_POSIX_SUCCESS(getsockname(client_fd, (struct sockaddr *)&sin_local, &socklen), NULL);
110 (void)inet_ntop(AF_INET, &sin_local.sin_addr, l_addr_str, sizeof(l_addr_str));
111
112 socklen = sizeof(sin_peer);
113 T_ASSERT_POSIX_SUCCESS(getpeername(client_fd, (struct sockaddr *)&sin_peer, &socklen), NULL);
114 (void)inet_ntop(AF_INET, &sin_peer.sin_addr, f_addr_str, sizeof(f_addr_str));
115
116 T_LOG("connected from %s:%u to %s:%u",
117 l_addr_str, ntohs(sin_local.sin_port),
118 f_addr_str, ntohs(sin_peer.sin_port));
119 } else {
120 T_EXPECT_POSIX_FAILURE(connect(client_fd, (struct sockaddr *)sin_to, sizeof(struct sockaddr_in)), expected_error, NULL);
121 }
122 T_ASSERT_POSIX_SUCCESS(close(listen_fd), NULL);
123 }
124
125 static void
udp_connect_v6(int client_fd,struct sockaddr_in6 * sin6_to,int expected_error)126 udp_connect_v6(int client_fd, struct sockaddr_in6 *sin6_to, int expected_error)
127 {
128 int listen_fd = -1;
129 socklen_t socklen;
130 int off = 0;
131 struct sockaddr_in6 sin6_local = { 0 };
132 struct sockaddr_in6 sin6_peer = { 0 };
133 struct sockaddr_in6 sin6;
134
135 init_sin6_address(&sin6);
136 init_sin6_address(&sin6_local);
137 init_sin6_address(&sin6_peer);
138
139 T_ASSERT_POSIX_SUCCESS(listen_fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
140
141 T_ASSERT_POSIX_SUCCESS(setsockopt(listen_fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off)), NULL);
142
143 T_ASSERT_POSIX_SUCCESS(bind(listen_fd, (struct sockaddr *)&sin6, sizeof(sin6)), NULL);
144
145 socklen = sizeof(sin6);
146 T_ASSERT_POSIX_SUCCESS(getsockname(listen_fd, (struct sockaddr *)&sin6, &socklen), NULL);
147
148 T_LOG("listening on port: %u", ntohs(sin6.sin6_port));
149 sin6_to->sin6_port = sin6.sin6_port;
150
151 (void)inet_ntop(AF_INET6, &sin6_to->sin6_addr, l_addr_str, sizeof(l_addr_str));
152 T_LOG("connect with sin6_len: %u sin6_family: %u sin6_port: %u sin6_addr: %s expected_error: %d",
153 sin6_to->sin6_len, sin6_to->sin6_family, ntohs(sin6_to->sin6_port), l_addr_str, expected_error);
154
155 if (expected_error == 0) {
156 T_EXPECT_POSIX_SUCCESS(connect(client_fd, (struct sockaddr *)sin6_to, sizeof(struct sockaddr_in6)), NULL);
157
158 socklen = sizeof(sin6_local);
159 T_ASSERT_POSIX_SUCCESS(getsockname(client_fd, (struct sockaddr *)&sin6_local, &socklen), NULL);
160 (void)inet_ntop(AF_INET6, &sin6_local.sin6_addr, l_addr_str, sizeof(l_addr_str));
161
162 socklen = sizeof(sin6_peer);
163 T_ASSERT_POSIX_SUCCESS(getpeername(client_fd, (struct sockaddr *)&sin6_peer, &socklen), NULL);
164 (void)inet_ntop(AF_INET6, &sin6_peer.sin6_addr, f_addr_str, sizeof(f_addr_str));
165
166 T_LOG("connected from %s:%u to %s:%u",
167 l_addr_str, ntohs(sin6_local.sin6_port),
168 f_addr_str, ntohs(sin6_peer.sin6_port));
169 } else {
170 T_EXPECT_POSIX_FAILURE(connect(client_fd, (struct sockaddr *)sin6_to, sizeof(struct sockaddr_in6)), expected_error, NULL);
171 }
172 T_ASSERT_POSIX_SUCCESS(close(listen_fd), NULL);
173 }
174
175 T_DECL(udp_bind_ipv4_loopback, "UDP bind with a IPv4 loopback address", T_META_TAG_VM_PREFERRED)
176 {
177 int s = -1;
178 struct sockaddr_in sin = { 0 };
179
180 init_sin_address(&sin);
181 T_ASSERT_EQ(inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr), 1, NULL);
182
183 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
184
185 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin, sizeof(sin)), 0, NULL);
186
187 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
188 }
189
190 T_DECL(udp_connect_ipv4_loopback, "UDP connect with a IPv4 loopback address", T_META_TAG_VM_PREFERRED)
191 {
192 int s = -1;
193 struct sockaddr_in sin = { 0 };
194
195 init_sin_address(&sin);
196 T_ASSERT_EQ(inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr), 1, NULL);
197
198 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
199
200 udp_connect_v4(s, &sin, 0);
201
202 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
203 }
204
205 T_DECL(udp_bind_ipv4_multicast, "UDP bind with a IPv4 multicast address", T_META_TAG_VM_PREFERRED)
206 {
207 int s = -1;
208 struct sockaddr_in sin = { 0 };
209
210 init_sin_address(&sin);
211 T_ASSERT_EQ(inet_pton(AF_INET, "224.0.0.1", &sin.sin_addr), 1, NULL);
212
213 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
214
215 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin, sizeof(sin)), NULL);
216
217 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
218 }
219
220 T_DECL(udp_connect_ipv4_multicast, "UDP connect with an IPv4 multicast address", T_META_TAG_VM_PREFERRED)
221 {
222 if (!has_ipv4_default_route()) {
223 T_SKIP("test require IPv4 default route");
224 }
225
226 int s = -1;
227 struct sockaddr_in sin = { 0 };
228
229 init_sin_address(&sin);
230 T_ASSERT_EQ(inet_pton(AF_INET, "224.0.0.1", &sin.sin_addr), 1, NULL);
231
232 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
233
234 udp_connect_v4(s, &sin, 0);
235
236 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
237 }
238
239 T_DECL(udp_bind_ipv4_broadcast, "UDP bind with the IPv4 broadcast address", T_META_TAG_VM_PREFERRED)
240 {
241 int s = -1;
242 struct sockaddr_in sin = { 0 };
243
244 init_sin_address(&sin);
245 T_ASSERT_EQ(inet_pton(AF_INET, "255.255.255.255", &sin.sin_addr), 1, NULL);
246
247 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
248
249 T_EXPECT_POSIX_FAILURE(bind(s, (const struct sockaddr *)&sin, sizeof(sin)), EADDRNOTAVAIL, NULL);
250
251 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
252 }
253
254 T_DECL(udp_connect_ipv4_broadcast, "UDP connect with the IPv4 broadcast address", T_META_TAG_VM_PREFERRED)
255 {
256 if (!has_ipv4_default_route()) {
257 T_SKIP("test require IPv4 default route");
258 }
259
260 int s = -1;
261 struct sockaddr_in sin = { 0 };
262
263 init_sin_address(&sin);
264 T_ASSERT_EQ(inet_pton(AF_INET, "255.255.255.255", &sin.sin_addr), 1, NULL);
265
266 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
267
268 udp_connect_v4(s, &sin, 0);
269
270 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
271 }
272
273 T_DECL(udp_bind_ipv4_null, "UDP bind with the null IPv4 address", T_META_TAG_VM_PREFERRED)
274 {
275 int s = -1;
276 struct sockaddr_in sin = { 0 };
277
278 init_sin_address(&sin);
279 T_ASSERT_EQ(inet_pton(AF_INET, "0.0.0.0", &sin.sin_addr), 1, NULL);
280
281 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
282
283 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin, sizeof(sin)), NULL);
284
285 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
286 }
287
288 T_DECL(udp_connect_ipv4_null, "UDP connect with the null IPv4 address", T_META_TAG_VM_PREFERRED)
289 {
290 if (!has_ipv4_default_route()) {
291 T_SKIP("test require IPv4 default route");
292 }
293
294 int s = -1;
295 struct sockaddr_in sin = { 0 };
296
297 init_sin_address(&sin);
298 T_ASSERT_EQ(inet_pton(AF_INET, "0.0.0.0", &sin.sin_addr), 1, NULL);
299
300 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
301
302 udp_connect_v4(s, &sin, 0);
303
304 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
305 }
306
307 T_DECL(udp_bind_ipv6_loopback, "UDP bind with the IPv6 loopback address", T_META_TAG_VM_PREFERRED)
308 {
309 int s = -1;
310 struct sockaddr_in6 sin6 = { 0 };
311
312 sin6.sin6_scope_id = if_nametoindex("lo0");
313 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6.sin6_addr), 1, NULL);
314
315 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
316
317 init_sin6_address(&sin6);
318 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), NULL);
319
320 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
321 }
322
323 T_DECL(udp_connect_ipv6_loopback, "UDP connect with the IPv6 loopback address", T_META_TAG_VM_PREFERRED)
324 {
325 int s = -1;
326 struct sockaddr_in6 sin6 = { 0 };
327
328 init_sin6_address(&sin6);
329 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6.sin6_addr), 1, NULL);
330
331 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
332
333 udp_connect_v6(s, &sin6, 0);
334
335 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
336 }
337
338 T_DECL(udp_bind_ipv6_multicast, "UDP bind with a IPv6 multicast address", T_META_TAG_VM_PREFERRED)
339 {
340 int s = -1;
341 struct sockaddr_in6 sin6 = { 0 };
342
343 init_sin6_address(&sin6);
344 sin6.sin6_scope_id = if_nametoindex("lo0");
345 T_ASSERT_EQ(inet_pton(AF_INET6, "ff01::1", &sin6.sin6_addr), 1, NULL);
346
347 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
348
349 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), NULL);
350
351 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
352 }
353
354 T_DECL(udp_connect_ipv6_multicast, "UDP connect with a IPv6 multicast address", T_META_TAG_VM_PREFERRED)
355 {
356 int s = -1;
357 struct sockaddr_in6 sin6 = { 0 };
358
359 init_sin6_address(&sin6);
360 sin6.sin6_scope_id = if_nametoindex("lo0");
361 T_ASSERT_EQ(inet_pton(AF_INET6, "ff01::1", &sin6.sin6_addr), 1, NULL);
362
363 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
364
365 udp_connect_v6(s, &sin6, 0);
366
367 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
368 }
369
370 T_DECL(udp_bind_null_ipv6, "UDP bind with the IPv6 null address", T_META_TAG_VM_PREFERRED)
371 {
372 int s = -1;
373 struct sockaddr_in6 sin6 = { 0 };
374
375 init_sin6_address(&sin6);
376 T_ASSERT_EQ(inet_pton(AF_INET6, "::", &sin6.sin6_addr), 1, NULL);
377
378 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
379
380 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), NULL);
381
382 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
383 }
384
385 T_DECL(udp_connect_null_ipv6, "UDP connect with the IPv6 null address", T_META_TAG_VM_PREFERRED)
386 {
387 int s = -1;
388 struct sockaddr_in6 sin6 = { 0 };
389
390 init_sin6_address(&sin6);
391 T_ASSERT_EQ(inet_pton(AF_INET6, "::", &sin6.sin6_addr), 1, NULL);
392
393 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
394
395 udp_connect_v6(s, &sin6, 0);
396
397 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
398 }
399
400 T_DECL(udp_bind_ipv4_multicast_mapped_ipv6, "UDP bind with IPv4 multicast mapped IPv6 address", T_META_TAG_VM_PREFERRED)
401 {
402 int s = -1;
403 struct sockaddr_in6 sin6 = { 0 };
404
405 init_sin6_address(&sin6);
406 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:224.0.0.1", &sin6.sin6_addr), 1, NULL);
407
408 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
409
410 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), NULL);
411
412 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
413 }
414
415 T_DECL(udp_connect_ipv4_multicast_mapped_ipv6, "UDP connect with IPv4 multicast mapped IPv6 address", T_META_TAG_VM_PREFERRED)
416 {
417 if (!has_ipv4_default_route()) {
418 T_SKIP("test require IPv4 default route");
419 }
420
421 int s = -1;
422 struct sockaddr_in6 sin6 = { 0 };
423
424 init_sin6_address(&sin6);
425 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:224.0.0.1", &sin6.sin6_addr), 1, NULL);
426
427 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
428
429 udp_connect_v6(s, &sin6, 0);
430
431 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
432 }
433
434 T_DECL(udp_bind_ipv4_broadcast_mapped_ipv6, "UDP bind with IPv4 broadcast mapped IPv6 address", T_META_TAG_VM_PREFERRED)
435 {
436 int s = -1;
437 struct sockaddr_in6 sin6 = { 0 };
438
439 init_sin6_address(&sin6);
440 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:255.255.255.255", &sin6.sin6_addr), 1, NULL);
441
442 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
443
444 T_EXPECT_POSIX_FAILURE(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), EADDRNOTAVAIL, NULL);
445
446 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
447 }
448
449 T_DECL(udp_connect_ipv4_broadcast_mapped_ipv6, "UDP connect with IPv4 broadcast mapped IPv6 address", T_META_TAG_VM_PREFERRED)
450 {
451 if (!has_ipv4_default_route()) {
452 T_SKIP("test require IPv4 default route");
453 }
454
455 int s = -1;
456 struct sockaddr_in6 sin6 = { 0 };
457
458 init_sin6_address(&sin6);
459 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:255.255.255.255", &sin6.sin6_addr), 1, NULL);
460
461 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
462
463 udp_connect_v6(s, &sin6, 0);
464
465 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
466 }
467
468 T_DECL(udp_bind_ipv4_null_mapped_ipv6, "UDP bind with IPv4 null mapped IPv6 address", T_META_TAG_VM_PREFERRED)
469 {
470 int s = -1;
471 struct sockaddr_in6 sin6 = { 0 };
472
473 init_sin6_address(&sin6);
474 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:0.0.0.0", &sin6.sin6_addr), 1, NULL);
475
476 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
477
478 udp_connect_v6(s, &sin6, 0);
479
480 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
481 }
482
483 T_DECL(udp_connect_ipv4_null_mapped_ipv6, "UDP connect with IPv4 null mapped IPv6 address", T_META_TAG_VM_PREFERRED)
484 {
485 if (!has_ipv4_default_route()) {
486 T_SKIP("test require IPv4 default route");
487 }
488
489 int s = -1;
490 struct sockaddr_in6 sin6 = { 0 };
491
492 init_sin6_address(&sin6);
493 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:0.0.0.0", &sin6.sin6_addr), 1, NULL);
494
495 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
496
497 udp_connect_v6(s, &sin6, 0);
498
499 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
500 }
501
502 T_DECL(udp_bind_ipv4_multicast_compatible_ipv6, "UDP bind with IPv4 multicast compatible IPv6 address", T_META_TAG_VM_PREFERRED)
503 {
504 int s = -1;
505 struct sockaddr_in6 sin6 = { 0 };
506
507 init_sin6_address(&sin6);
508 T_ASSERT_EQ(inet_pton(AF_INET6, "::224.0.0.1", &sin6.sin6_addr), 1, NULL);
509
510 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
511
512 T_EXPECT_POSIX_FAILURE(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), EADDRNOTAVAIL, NULL);
513
514 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
515 }
516
517 T_DECL(udp_connect_ipv4_multicast_compatible_ipv6, "UDP connect with IPv4 multicast compatible IPv6 address", T_META_TAG_VM_PREFERRED)
518 {
519 if (!has_ipv6_default_route()) {
520 T_SKIP("test require IPv6 default route");
521 }
522
523 int s = -1;
524 struct sockaddr_in6 sin6 = { 0 };
525
526 init_sin6_address(&sin6);
527 T_ASSERT_EQ(inet_pton(AF_INET6, "::224.0.0.1", &sin6.sin6_addr), 1, NULL);
528
529 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
530
531 udp_connect_v6(s, &sin6, 0);
532
533 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
534 }
535
536 T_DECL(udp_bind_ipv4_broadcast_compatible_ipv6, "UDP bind with IPv4 broadcast compatible IPv6 address", T_META_TAG_VM_PREFERRED)
537 {
538 int s = -1;
539 struct sockaddr_in6 sin6 = { 0 };
540
541 init_sin6_address(&sin6);
542 T_ASSERT_EQ(inet_pton(AF_INET6, "::255.255.255.255", &sin6.sin6_addr), 1, NULL);
543
544 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
545
546 T_EXPECT_POSIX_FAILURE(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), EADDRNOTAVAIL, NULL);
547
548 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
549 }
550
551 T_DECL(udp_connect_ipv4_broadcast_compatible_ipv6, "UDP connect with IPv4 broadcast compatible IPv6 address", T_META_TAG_VM_PREFERRED)
552 {
553 if (!has_ipv6_default_route()) {
554 T_SKIP("test require IPv6 default route");
555 }
556
557 int s = -1;
558 struct sockaddr_in6 sin6 = { 0 };
559
560 init_sin6_address(&sin6);
561 T_ASSERT_EQ(inet_pton(AF_INET6, "::255.255.255.255", &sin6.sin6_addr), 1, NULL);
562
563 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
564
565 udp_connect_v6(s, &sin6, 0);
566
567 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
568 }
569
570 T_DECL(udp_bind_ipv4_null_compatible_ipv6, "UDP bind with IPv4 null compatible IPv6 address", T_META_TAG_VM_PREFERRED)
571 {
572 int s = -1;
573 struct sockaddr_in6 sin6 = { 0 };
574
575 init_sin6_address(&sin6);
576 T_ASSERT_EQ(inet_pton(AF_INET6, "::0.0.0.0", &sin6.sin6_addr), 1, NULL);
577
578 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
579
580 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), NULL);
581
582 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
583 }
584
585 T_DECL(udp_connect_ipv4_null_compatible_ipv6, "UDP connect with IPv4 null compatible IPv6 address", T_META_TAG_VM_PREFERRED)
586 {
587 if (!has_ipv6_default_route()) {
588 T_SKIP("test require IPv6 default route");
589 }
590
591 int s = -1;
592 struct sockaddr_in6 sin6 = { 0 };
593
594 init_sin6_address(&sin6);
595 T_ASSERT_EQ(inet_pton(AF_INET6, "::0.0.0.0", &sin6.sin6_addr), 1, NULL);
596
597 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
598
599 udp_connect_v6(s, &sin6, 0);
600
601 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
602 }
603