1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <arpa/inet.h>
4 #include <error.h>
5 #include <errno.h>
6 #include <unistd.h>
7 
8 int main(void)
9 {
10 	int fd1, fd2, one = 1;
11 	struct sockaddr_in6 bind_addr = {
12 		.sin6_family = AF_INET6,
13 		.sin6_port = htons(20000),
14 		.sin6_flowinfo = htonl(0),
15 		.sin6_addr = {},
16 		.sin6_scope_id = 0,
17 	};
18 
19 	inet_pton(AF_INET6, "::", &bind_addr.sin6_addr);
20 
21 	fd1 = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP);
22 	if (fd1 < 0) {
23 		error(1, errno, "socket fd1");
24 		return -1;
25 	}
26 
27 	if (setsockopt(fd1, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
28 		error(1, errno, "setsockopt(SO_REUSEADDR) fd1");
29 		goto out_err1;
30 	}
31 
32 	if (bind(fd1, (struct sockaddr *)&bind_addr, sizeof(bind_addr))) {
33 		error(1, errno, "bind fd1");
34 		goto out_err1;
35 	}
36 
37 	if (listen(fd1, 0)) {
38 		error(1, errno, "listen");
39 		goto out_err1;
40 	}
41 
42 	fd2 = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP);
43 	if (fd2 < 0) {
44 		error(1, errno, "socket fd2");
45 		goto out_err1;
46 	}
47 
48 	if (connect(fd2, (struct sockaddr *)&bind_addr, sizeof(bind_addr))) {
49 		error(1, errno, "bind fd2");
50 		goto out_err2;
51 	}
52 
53 	close(fd2);
54 	close(fd1);
55 	return 0;
56 
57 out_err2:
58 	close(fd2);
59 out_err1:
60 	close(fd1);
61 	return -1;
62 }
63