1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright Amazon.com Inc. or its affiliates. */ 3 4 #include <sys/socket.h> 5 #include <netinet/in.h> 6 7 #include "../kselftest_harness.h" 8 9 static const __u32 in4addr_any = INADDR_ANY; 10 static const __u32 in4addr_loopback = INADDR_LOOPBACK; 11 static const struct in6_addr in6addr_v4mapped_any = { 12 .s6_addr = { 13 0, 0, 0, 0, 14 0, 0, 0, 0, 15 0, 0, 255, 255, 16 0, 0, 0, 0 17 } 18 }; 19 static const struct in6_addr in6addr_v4mapped_loopback = { 20 .s6_addr = { 21 0, 0, 0, 0, 22 0, 0, 0, 0, 23 0, 0, 255, 255, 24 127, 0, 0, 1 25 } 26 }; 27 28 FIXTURE(bind_wildcard) 29 { 30 socklen_t addrlen[2]; 31 union { 32 struct sockaddr addr; 33 struct sockaddr_in addr4; 34 struct sockaddr_in6 addr6; 35 } addr[2]; 36 }; 37 38 FIXTURE_VARIANT(bind_wildcard) 39 { 40 sa_family_t family[2]; 41 const void *addr[2]; 42 int expected_errno; 43 }; 44 45 /* (IPv4, IPv6) */ 46 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_any) 47 { 48 .family = {AF_INET, AF_INET6}, 49 .addr = {&in4addr_any, &in6addr_any}, 50 .expected_errno = EADDRINUSE, 51 }; 52 53 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_local) 54 { 55 .family = {AF_INET, AF_INET6}, 56 .addr = {&in4addr_any, &in6addr_loopback}, 57 .expected_errno = 0, 58 }; 59 60 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_v4mapped_any) 61 { 62 .family = {AF_INET, AF_INET6}, 63 .addr = {&in4addr_any, &in6addr_v4mapped_any}, 64 .expected_errno = EADDRINUSE, 65 }; 66 67 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_v4mapped_local) 68 { 69 .family = {AF_INET, AF_INET6}, 70 .addr = {&in4addr_any, &in6addr_v4mapped_loopback}, 71 .expected_errno = EADDRINUSE, 72 }; 73 74 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_any) 75 { 76 .family = {AF_INET, AF_INET6}, 77 .addr = {&in4addr_loopback, &in6addr_any}, 78 .expected_errno = EADDRINUSE, 79 }; 80 81 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_local) 82 { 83 .family = {AF_INET, AF_INET6}, 84 .addr = {&in4addr_loopback, &in6addr_loopback}, 85 .expected_errno = 0, 86 }; 87 88 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_v4mapped_any) 89 { 90 .family = {AF_INET, AF_INET6}, 91 .addr = {&in4addr_loopback, &in6addr_v4mapped_any}, 92 .expected_errno = EADDRINUSE, 93 }; 94 95 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_v4mapped_local) 96 { 97 .family = {AF_INET, AF_INET6}, 98 .addr = {&in4addr_loopback, &in6addr_v4mapped_loopback}, 99 .expected_errno = EADDRINUSE, 100 }; 101 102 /* (IPv6, IPv4) */ 103 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v4_any) 104 { 105 .family = {AF_INET6, AF_INET}, 106 .addr = {&in6addr_any, &in4addr_any}, 107 .expected_errno = EADDRINUSE, 108 }; 109 110 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v4_local) 111 { 112 .family = {AF_INET6, AF_INET}, 113 .addr = {&in6addr_any, &in4addr_loopback}, 114 .expected_errno = EADDRINUSE, 115 }; 116 117 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v4_any) 118 { 119 .family = {AF_INET6, AF_INET}, 120 .addr = {&in6addr_loopback, &in4addr_any}, 121 .expected_errno = 0, 122 }; 123 124 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v4_local) 125 { 126 .family = {AF_INET6, AF_INET}, 127 .addr = {&in6addr_loopback, &in4addr_loopback}, 128 .expected_errno = 0, 129 }; 130 131 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v4_any) 132 { 133 .family = {AF_INET6, AF_INET}, 134 .addr = {&in6addr_v4mapped_any, &in4addr_any}, 135 .expected_errno = EADDRINUSE, 136 }; 137 138 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v4_local) 139 { 140 .family = {AF_INET6, AF_INET}, 141 .addr = {&in6addr_v4mapped_any, &in4addr_loopback}, 142 .expected_errno = EADDRINUSE, 143 }; 144 145 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_local_v4_any) 146 { 147 .family = {AF_INET6, AF_INET}, 148 .addr = {&in6addr_v4mapped_loopback, &in4addr_any}, 149 .expected_errno = EADDRINUSE, 150 }; 151 152 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_local_v4_local) 153 { 154 .family = {AF_INET6, AF_INET}, 155 .addr = {&in6addr_v4mapped_loopback, &in4addr_loopback}, 156 .expected_errno = EADDRINUSE, 157 }; 158 159 static void setup_addr(FIXTURE_DATA(bind_wildcard) *self, int i, 160 int family, const void *addr_const) 161 { 162 if (family == AF_INET) { 163 struct sockaddr_in *addr4 = &self->addr[i].addr4; 164 const __u32 *addr4_const = addr_const; 165 166 addr4->sin_family = AF_INET; 167 addr4->sin_port = htons(0); 168 addr4->sin_addr.s_addr = htonl(*addr4_const); 169 170 self->addrlen[i] = sizeof(struct sockaddr_in); 171 } else { 172 struct sockaddr_in6 *addr6 = &self->addr[i].addr6; 173 const struct in6_addr *addr6_const = addr_const; 174 175 addr6->sin6_family = AF_INET6; 176 addr6->sin6_port = htons(0); 177 addr6->sin6_addr = *addr6_const; 178 179 self->addrlen[i] = sizeof(struct sockaddr_in6); 180 } 181 } 182 183 FIXTURE_SETUP(bind_wildcard) 184 { 185 setup_addr(self, 0, variant->family[0], variant->addr[0]); 186 setup_addr(self, 1, variant->family[1], variant->addr[1]); 187 } 188 189 FIXTURE_TEARDOWN(bind_wildcard) 190 { 191 } 192 193 void bind_sockets(struct __test_metadata *_metadata, 194 FIXTURE_DATA(bind_wildcard) *self, 195 int expected_errno, 196 struct sockaddr *addr1, socklen_t addrlen1, 197 struct sockaddr *addr2, socklen_t addrlen2) 198 { 199 int fd[2]; 200 int ret; 201 202 fd[0] = socket(addr1->sa_family, SOCK_STREAM, 0); 203 ASSERT_GT(fd[0], 0); 204 205 ret = bind(fd[0], addr1, addrlen1); 206 ASSERT_EQ(ret, 0); 207 208 ret = getsockname(fd[0], addr1, &addrlen1); 209 ASSERT_EQ(ret, 0); 210 211 ((struct sockaddr_in *)addr2)->sin_port = ((struct sockaddr_in *)addr1)->sin_port; 212 213 fd[1] = socket(addr2->sa_family, SOCK_STREAM, 0); 214 ASSERT_GT(fd[1], 0); 215 216 ret = bind(fd[1], addr2, addrlen2); 217 if (expected_errno) { 218 ASSERT_EQ(ret, -1); 219 ASSERT_EQ(errno, expected_errno); 220 } else { 221 ASSERT_EQ(ret, 0); 222 } 223 224 close(fd[1]); 225 close(fd[0]); 226 } 227 228 TEST_F(bind_wildcard, plain) 229 { 230 bind_sockets(_metadata, self, variant->expected_errno, 231 &self->addr[0].addr, self->addrlen[0], 232 &self->addr[1].addr, self->addrlen[1]); 233 } 234 235 TEST_HARNESS_MAIN 236