xref: /xnu-8792.81.2/tests/udp_bind_connect.c (revision 19c3b8c28c31cb8130e034cfb5df6bf9ba342d90)
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