1 /*
2 * Copyright (c) 2022 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 T_GLOBAL_META(
47 T_META_NAMESPACE("xnu.net"),
48 T_META_RADAR_COMPONENT_NAME("xnu"),
49 T_META_RADAR_COMPONENT_VERSION("networking")
50 );
51
52 #define MAX_IPv6_STR_LEN 64
53
54 static char l_addr_str[MAX_IPv6_STR_LEN];
55 static char f_addr_str[MAX_IPv6_STR_LEN];
56
57 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
58 #define s6_addr32 __u6_addr.__u6_addr32
59
60 #define RTM_BUFLEN (sizeof(struct rt_msghdr) + 6 * SOCK_MAXADDRLEN)
61
62 #define ROUNDUP(a) \
63 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
64 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
65
66 static bool
has_v4_default_route(void)67 has_v4_default_route(void)
68 {
69 bool result = false;
70 struct rt_msghdr *rtm = NULL;
71 struct sockaddr_in sin = {};
72
73 sin.sin_len = sizeof(struct sockaddr_in);
74 sin.sin_family = AF_INET;
75 sin.sin_addr.s_addr = INADDR_ANY;
76
77 T_QUIET; T_ASSERT_NOTNULL(rtm = (struct rt_msghdr *)calloc(1, RTM_BUFLEN), NULL);
78
79 rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
80 rtm->rtm_version = RTM_VERSION;
81 rtm->rtm_type = RTM_GET;
82 rtm->rtm_flags = RTF_UP | RTF_STATIC | RTF_GATEWAY | RTF_HOST;
83 rtm->rtm_addrs = RTA_DST;
84 rtm->rtm_pid = getpid();
85 rtm->rtm_seq = 1;
86
87 uint8_t *cp = (unsigned char *)(rtm + 1);
88
89 bcopy(&sin, cp, sin.sin_len);
90 cp += ROUNDUP(sin.sin_len);
91
92 u_short len = (u_short)(cp - (uint8_t *)rtm);
93
94 rtm->rtm_msglen = len;
95
96 int fd;
97 T_QUIET; T_ASSERT_POSIX_SUCCESS(fd = socket(PF_ROUTE, SOCK_RAW, 0), NULL);
98
99 ssize_t sent = send(fd, rtm, len, 0);
100 if (sent == len) {
101 result = true;
102 } else {
103 result = false;
104 }
105
106 (void) close(fd);
107 free(rtm);
108
109 return result;
110 }
111
112 static void
init_sin_address(struct sockaddr_in * sin)113 init_sin_address(struct sockaddr_in *sin)
114 {
115 memset(sin, 0, sizeof(struct sockaddr_in));
116 sin->sin_len = sizeof(struct sockaddr_in);
117 sin->sin_family = AF_INET;
118 }
119
120 static void
init_sin6_address(struct sockaddr_in6 * sin6)121 init_sin6_address(struct sockaddr_in6 *sin6)
122 {
123 memset(sin6, 0, sizeof(struct sockaddr_in6));
124 sin6->sin6_len = sizeof(struct sockaddr_in6);
125 sin6->sin6_family = AF_INET6;
126 }
127
128 static void
udp_connect_v4(int client_fd,struct sockaddr_in * sin_to,int expected_error)129 udp_connect_v4(int client_fd, struct sockaddr_in *sin_to, int expected_error)
130 {
131 int listen_fd = -1;
132 socklen_t socklen;
133 struct sockaddr_in sin_local = {};
134 struct sockaddr_in sin_peer = {};
135 struct sockaddr_in sin;
136
137 init_sin_address(&sin);
138 init_sin_address(&sin_local);
139 init_sin_address(&sin_peer);
140
141 T_ASSERT_POSIX_SUCCESS(listen_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
142
143 T_ASSERT_POSIX_SUCCESS(bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)), NULL);
144
145 socklen = sizeof(sin);
146 T_ASSERT_POSIX_SUCCESS(getsockname(listen_fd, (struct sockaddr *)&sin, &socklen), NULL);
147
148 T_LOG("listening on port: %u", ntohs(sin.sin_port));
149 sin_to->sin_port = sin.sin_port;
150
151 T_LOG("connect with sin_len: %u sin_family: %u sin_port: %u sin_addr: 0x%08x expected_error: %d",
152 sin_to->sin_len, sin_to->sin_family, ntohs(sin_to->sin_port), ntohl(sin_to->sin_addr.s_addr), expected_error);
153
154 if (expected_error == 0) {
155 T_EXPECT_POSIX_SUCCESS(connect(client_fd, (struct sockaddr *)sin_to, sizeof(struct sockaddr_in)), NULL);
156
157 socklen = sizeof(sin_local);
158 T_ASSERT_POSIX_SUCCESS(getsockname(client_fd, (struct sockaddr *)&sin_local, &socklen), NULL);
159 (void)inet_ntop(AF_INET, &sin_local.sin_addr, l_addr_str, sizeof(l_addr_str));
160
161 socklen = sizeof(sin_peer);
162 T_ASSERT_POSIX_SUCCESS(getpeername(client_fd, (struct sockaddr *)&sin_peer, &socklen), NULL);
163 (void)inet_ntop(AF_INET, &sin_peer.sin_addr, f_addr_str, sizeof(f_addr_str));
164
165 T_LOG("connected from %s:%u to %s:%u",
166 l_addr_str, ntohs(sin_local.sin_port),
167 f_addr_str, ntohs(sin_peer.sin_port));
168 } else {
169 T_EXPECT_POSIX_FAILURE(connect(client_fd, (struct sockaddr *)sin_to, sizeof(struct sockaddr_in)), expected_error, NULL);
170 }
171 T_ASSERT_POSIX_SUCCESS(close(listen_fd), NULL);
172 }
173
174 static void
udp_connect_v6(int client_fd,struct sockaddr_in6 * sin6_to,int expected_error)175 udp_connect_v6(int client_fd, struct sockaddr_in6 *sin6_to, int expected_error)
176 {
177 int listen_fd = -1;
178 socklen_t socklen;
179 int off = 0;
180 struct sockaddr_in6 sin6_local = {};
181 struct sockaddr_in6 sin6_peer = {};
182 struct sockaddr_in6 sin6;
183
184 init_sin6_address(&sin6);
185 init_sin6_address(&sin6_local);
186 init_sin6_address(&sin6_peer);
187
188 T_ASSERT_POSIX_SUCCESS(listen_fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
189
190 T_ASSERT_POSIX_SUCCESS(setsockopt(listen_fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off)), NULL);
191
192 T_ASSERT_POSIX_SUCCESS(bind(listen_fd, (struct sockaddr *)&sin6, sizeof(sin6)), NULL);
193
194 socklen = sizeof(sin6);
195 T_ASSERT_POSIX_SUCCESS(getsockname(listen_fd, (struct sockaddr *)&sin6, &socklen), NULL);
196
197 T_LOG("listening on port: %u", ntohs(sin6.sin6_port));
198 sin6_to->sin6_port = sin6.sin6_port;
199
200 (void)inet_ntop(AF_INET6, &sin6_to->sin6_addr, l_addr_str, sizeof(l_addr_str));
201 T_LOG("connect with sin6_len: %u sin6_family: %u sin6_port: %u sin6_addr: %s expected_error: %d",
202 sin6_to->sin6_len, sin6_to->sin6_family, ntohs(sin6_to->sin6_port), l_addr_str, expected_error);
203
204 if (expected_error == 0) {
205 T_EXPECT_POSIX_SUCCESS(connect(client_fd, (struct sockaddr *)sin6_to, sizeof(struct sockaddr_in6)), NULL);
206
207 socklen = sizeof(sin6_local);
208 T_ASSERT_POSIX_SUCCESS(getsockname(client_fd, (struct sockaddr *)&sin6_local, &socklen), NULL);
209 (void)inet_ntop(AF_INET6, &sin6_local.sin6_addr, l_addr_str, sizeof(l_addr_str));
210
211 socklen = sizeof(sin6_peer);
212 T_ASSERT_POSIX_SUCCESS(getpeername(client_fd, (struct sockaddr *)&sin6_peer, &socklen), NULL);
213 (void)inet_ntop(AF_INET6, &sin6_peer.sin6_addr, f_addr_str, sizeof(f_addr_str));
214
215 T_LOG("connected from %s:%u to %s:%u",
216 l_addr_str, ntohs(sin6_local.sin6_port),
217 f_addr_str, ntohs(sin6_peer.sin6_port));
218 } else {
219 T_EXPECT_POSIX_FAILURE(connect(client_fd, (struct sockaddr *)sin6_to, sizeof(struct sockaddr_in6)), expected_error, NULL);
220 }
221 T_ASSERT_POSIX_SUCCESS(close(listen_fd), NULL);
222 }
223
224 T_DECL(udp_bind_ipv4_loopback, "UDP bind with a IPv4 loopback address")
225 {
226 int s = -1;
227 struct sockaddr_in sin = {};
228
229 init_sin_address(&sin);
230 T_ASSERT_EQ(inet_pton(AF_INET, "127.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 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin, sizeof(sin)), 0, NULL);
235
236 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
237 }
238
239 T_DECL(udp_connect_ipv4_loopback, "UDP connect with a IPv4 loopback address")
240 {
241 int s = -1;
242 struct sockaddr_in sin = {};
243
244 init_sin_address(&sin);
245 T_ASSERT_EQ(inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr), 1, NULL);
246
247 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
248
249 udp_connect_v4(s, &sin, 0);
250
251 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
252 }
253
254 T_DECL(udp_bind_ipv4_multicast, "UDP bind with a IPv4 multicast address")
255 {
256 int s = -1;
257 struct sockaddr_in sin = {};
258
259 init_sin_address(&sin);
260 T_ASSERT_EQ(inet_pton(AF_INET, "224.0.0.1", &sin.sin_addr), 1, NULL);
261
262 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
263
264 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin, sizeof(sin)), NULL);
265
266 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
267 }
268
269 T_DECL(udp_connect_ipv4_multicast, "UDP connect with an IPv4 multicast address")
270 {
271 if (!has_v4_default_route()) {
272 T_SKIP("test require IPv4 default route");
273 }
274
275 int s = -1;
276 struct sockaddr_in sin = {};
277
278 init_sin_address(&sin);
279 T_ASSERT_EQ(inet_pton(AF_INET, "224.0.0.1", &sin.sin_addr), 1, NULL);
280
281 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
282
283 udp_connect_v4(s, &sin, 0);
284
285 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
286 }
287
288 T_DECL(udp_bind_ipv4_broadcast, "UDP bind with the IPv4 broadcast address")
289 {
290 int s = -1;
291 struct sockaddr_in sin = {};
292
293 init_sin_address(&sin);
294 T_ASSERT_EQ(inet_pton(AF_INET, "255.255.255.255", &sin.sin_addr), 1, NULL);
295
296 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
297
298 T_EXPECT_POSIX_FAILURE(bind(s, (const struct sockaddr *)&sin, sizeof(sin)), EADDRNOTAVAIL, NULL);
299
300 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
301 }
302
303 T_DECL(udp_connect_ipv4_broadcast, "UDP connect with the IPv4 broadcast address")
304 {
305 if (!has_v4_default_route()) {
306 T_SKIP("test require IPv4 default route");
307 }
308
309 int s = -1;
310 struct sockaddr_in sin = {};
311
312 init_sin_address(&sin);
313 T_ASSERT_EQ(inet_pton(AF_INET, "255.255.255.255", &sin.sin_addr), 1, NULL);
314
315 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
316
317 udp_connect_v4(s, &sin, 0);
318
319 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
320 }
321
322 T_DECL(udp_bind_ipv4_null, "UDP bind with the null IPv4 address")
323 {
324 int s = -1;
325 struct sockaddr_in sin = {};
326
327 init_sin_address(&sin);
328 T_ASSERT_EQ(inet_pton(AF_INET, "0.0.0.0", &sin.sin_addr), 1, NULL);
329
330 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
331
332 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin, sizeof(sin)), NULL);
333
334 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
335 }
336
337 T_DECL(udp_connect_ipv4_null, "UDP connect with the null IPv4 address")
338 {
339 if (!has_v4_default_route()) {
340 T_SKIP("test require IPv4 default route");
341 }
342
343 int s = -1;
344 struct sockaddr_in sin = {};
345
346 init_sin_address(&sin);
347 T_ASSERT_EQ(inet_pton(AF_INET, "0.0.0.0", &sin.sin_addr), 1, NULL);
348
349 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP), NULL);
350
351 udp_connect_v4(s, &sin, 0);
352
353 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
354 }
355
356 T_DECL(udp_bind_ipv6_loopback, "UDP bind with the IPv6 loopback address")
357 {
358 int s = -1;
359 struct sockaddr_in6 sin6 = {};
360
361 sin6.sin6_scope_id = if_nametoindex("lo0");
362 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6.sin6_addr), 1, NULL);
363
364 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
365
366 init_sin6_address(&sin6);
367 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), NULL);
368
369 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
370 }
371
372 T_DECL(udp_connect_ipv6_loopback, "UDP connect with the IPv6 loopback address")
373 {
374 int s = -1;
375 struct sockaddr_in6 sin6 = {};
376
377 init_sin6_address(&sin6);
378 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6.sin6_addr), 1, NULL);
379
380 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
381
382 udp_connect_v6(s, &sin6, 0);
383
384 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
385 }
386
387 T_DECL(udp_bind_ipv6_multicast, "UDP bind with a IPv6 multicast address")
388 {
389 int s = -1;
390 struct sockaddr_in6 sin6 = {};
391
392 init_sin6_address(&sin6);
393 sin6.sin6_scope_id = if_nametoindex("lo0");
394 T_ASSERT_EQ(inet_pton(AF_INET6, "ff01::1", &sin6.sin6_addr), 1, NULL);
395
396 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
397
398 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), NULL);
399
400 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
401 }
402
403 T_DECL(udp_connect_ipv6_multicast, "UDP connect with a IPv6 multicast address")
404 {
405 int s = -1;
406 struct sockaddr_in6 sin6 = {};
407
408 init_sin6_address(&sin6);
409 sin6.sin6_scope_id = if_nametoindex("lo0");
410 T_ASSERT_EQ(inet_pton(AF_INET6, "ff01::1", &sin6.sin6_addr), 1, NULL);
411
412 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
413
414 udp_connect_v6(s, &sin6, 0);
415
416 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
417 }
418
419 T_DECL(udp_bind_null_ipv6, "UDP bind with the IPv6 null address")
420 {
421 int s = -1;
422 struct sockaddr_in6 sin6 = {};
423
424 init_sin6_address(&sin6);
425 T_ASSERT_EQ(inet_pton(AF_INET6, "::", &sin6.sin6_addr), 1, NULL);
426
427 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
428
429 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), NULL);
430
431 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
432 }
433
434 T_DECL(udp_connect_null_ipv6, "UDP connect with the IPv6 null address")
435 {
436 int s = -1;
437 struct sockaddr_in6 sin6 = {};
438
439 init_sin6_address(&sin6);
440 T_ASSERT_EQ(inet_pton(AF_INET6, "::", &sin6.sin6_addr), 1, NULL);
441
442 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
443
444 udp_connect_v6(s, &sin6, 0);
445
446 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
447 }
448
449 T_DECL(udp_bind_ipv4_multicast_mapped_ipv6, "UDP bind with IPv4 multicast mapped IPv6 address")
450 {
451 int s = -1;
452 struct sockaddr_in6 sin6 = {};
453
454 init_sin6_address(&sin6);
455 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:224.0.0.1", &sin6.sin6_addr), 1, NULL);
456
457 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
458
459 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), NULL);
460
461 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
462 }
463
464 T_DECL(udp_connect_ipv4_multicast_mapped_ipv6, "UDP connect with IPv4 multicast mapped IPv6 address")
465 {
466 if (!has_v4_default_route()) {
467 T_SKIP("test require IPv4 default route");
468 }
469
470 int s = -1;
471 struct sockaddr_in6 sin6 = {};
472
473 init_sin6_address(&sin6);
474 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:224.0.0.1", &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_bind_ipv4_broadcast_mapped_ipv6, "UDP bind with IPv4 broadcast mapped IPv6 address")
484 {
485 int s = -1;
486 struct sockaddr_in6 sin6 = {};
487
488 init_sin6_address(&sin6);
489 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:255.255.255.255", &sin6.sin6_addr), 1, NULL);
490
491 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
492
493 T_EXPECT_POSIX_FAILURE(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), EADDRNOTAVAIL, NULL);
494
495 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
496 }
497
498 T_DECL(udp_connect_ipv4_broadcast_mapped_ipv6, "UDP connect with IPv4 broadcast mapped IPv6 address")
499 {
500 if (!has_v4_default_route()) {
501 T_SKIP("test require IPv4 default route");
502 }
503
504 int s = -1;
505 struct sockaddr_in6 sin6 = {};
506
507 init_sin6_address(&sin6);
508 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:255.255.255.255", &sin6.sin6_addr), 1, NULL);
509
510 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
511
512 udp_connect_v6(s, &sin6, 0);
513
514 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
515 }
516
517 T_DECL(udp_bind_ipv4_null_mapped_ipv6, "UDP bind with IPv4 null mapped IPv6 address")
518 {
519 int s = -1;
520 struct sockaddr_in6 sin6 = {};
521
522 init_sin6_address(&sin6);
523 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:0.0.0.0", &sin6.sin6_addr), 1, NULL);
524
525 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
526
527 udp_connect_v6(s, &sin6, 0);
528
529 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
530 }
531
532 T_DECL(udp_connect_ipv4_null_mapped_ipv6, "UDP connect with IPv4 null mapped IPv6 address")
533 {
534 if (!has_v4_default_route()) {
535 T_SKIP("test require IPv4 default route");
536 }
537
538 int s = -1;
539 struct sockaddr_in6 sin6 = {};
540
541 init_sin6_address(&sin6);
542 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:0.0.0.0", &sin6.sin6_addr), 1, NULL);
543
544 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
545
546 udp_connect_v6(s, &sin6, 0);
547
548 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
549 }
550
551 T_DECL(udp_bind_ipv4_multicast_compatible_ipv6, "UDP bind with IPv4 multicast compatible IPv6 address")
552 {
553 int s = -1;
554 struct sockaddr_in6 sin6 = {};
555
556 init_sin6_address(&sin6);
557 T_ASSERT_EQ(inet_pton(AF_INET6, "::224.0.0.1", &sin6.sin6_addr), 1, NULL);
558
559 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
560
561 T_EXPECT_POSIX_FAILURE(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), EADDRNOTAVAIL, NULL);
562
563 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
564 }
565
566 T_DECL(udp_connect_ipv4_multicast_compatible_ipv6, "UDP connect with IPv4 multicast compatible IPv6 address")
567 {
568 if (!has_v4_default_route()) {
569 T_SKIP("test require IPv4 default route");
570 }
571
572 int s = -1;
573 struct sockaddr_in6 sin6 = {};
574
575 init_sin6_address(&sin6);
576 T_ASSERT_EQ(inet_pton(AF_INET6, "::224.0.0.1", &sin6.sin6_addr), 1, NULL);
577
578 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
579
580 udp_connect_v6(s, &sin6, 0);
581
582 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
583 }
584
585 T_DECL(udp_bind_ipv4_broadcast_compatible_ipv6, "UDP bind with IPv4 broadcast compatible IPv6 address")
586 {
587 int s = -1;
588 struct sockaddr_in6 sin6 = {};
589
590 init_sin6_address(&sin6);
591 T_ASSERT_EQ(inet_pton(AF_INET6, "::255.255.255.255", &sin6.sin6_addr), 1, NULL);
592
593 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
594
595 T_EXPECT_POSIX_FAILURE(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), EADDRNOTAVAIL, NULL);
596
597 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
598 }
599
600 T_DECL(udp_connect_ipv4_broadcast_compatible_ipv6, "UDP connect with IPv4 broadcast compatible IPv6 address")
601 {
602 if (!has_v4_default_route()) {
603 T_SKIP("test require IPv4 default route");
604 }
605
606 int s = -1;
607 struct sockaddr_in6 sin6 = {};
608
609 init_sin6_address(&sin6);
610 T_ASSERT_EQ(inet_pton(AF_INET6, "::255.255.255.255", &sin6.sin6_addr), 1, NULL);
611
612 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
613
614 udp_connect_v6(s, &sin6, 0);
615
616 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
617 }
618
619 T_DECL(udp_bind_ipv4_null_compatible_ipv6, "UDP bind with IPv4 null compatible IPv6 address")
620 {
621 int s = -1;
622 struct sockaddr_in6 sin6 = {};
623
624 init_sin6_address(&sin6);
625 T_ASSERT_EQ(inet_pton(AF_INET6, "::0.0.0.0", &sin6.sin6_addr), 1, NULL);
626
627 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
628
629 T_ASSERT_POSIX_SUCCESS(bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)), NULL);
630
631 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
632 }
633
634 T_DECL(udp_connect_ipv4_null_compatible_ipv6, "UDP connect with IPv4 null compatible IPv6 address")
635 {
636 if (!has_v4_default_route()) {
637 T_SKIP("test require IPv4 default route");
638 }
639
640 int s = -1;
641 struct sockaddr_in6 sin6 = {};
642
643 init_sin6_address(&sin6);
644 T_ASSERT_EQ(inet_pton(AF_INET6, "::0.0.0.0", &sin6.sin6_addr), 1, NULL);
645
646 T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), NULL);
647
648 udp_connect_v6(s, &sin6, 0);
649
650 T_ASSERT_POSIX_SUCCESS(close(s), NULL);
651 }
652