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
8int 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
57out_err2:
58	close(fd2);
59out_err1:
60	close(fd1);
61	return -1;
62}
63