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