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, IPv4) */ 46 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v4_local) 47 { 48 .family = {AF_INET, AF_INET}, 49 .addr = {&in4addr_any, &in4addr_loopback}, 50 .expected_errno = EADDRINUSE, 51 }; 52 53 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v4_any) 54 { 55 .family = {AF_INET, AF_INET}, 56 .addr = {&in4addr_loopback, &in4addr_any}, 57 .expected_errno = EADDRINUSE, 58 }; 59 60 /* (IPv4, IPv6) */ 61 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_any) 62 { 63 .family = {AF_INET, AF_INET6}, 64 .addr = {&in4addr_any, &in6addr_any}, 65 .expected_errno = EADDRINUSE, 66 }; 67 68 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_local) 69 { 70 .family = {AF_INET, AF_INET6}, 71 .addr = {&in4addr_any, &in6addr_loopback}, 72 .expected_errno = 0, 73 }; 74 75 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_v4mapped_any) 76 { 77 .family = {AF_INET, AF_INET6}, 78 .addr = {&in4addr_any, &in6addr_v4mapped_any}, 79 .expected_errno = EADDRINUSE, 80 }; 81 82 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_v4mapped_local) 83 { 84 .family = {AF_INET, AF_INET6}, 85 .addr = {&in4addr_any, &in6addr_v4mapped_loopback}, 86 .expected_errno = EADDRINUSE, 87 }; 88 89 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_any) 90 { 91 .family = {AF_INET, AF_INET6}, 92 .addr = {&in4addr_loopback, &in6addr_any}, 93 .expected_errno = EADDRINUSE, 94 }; 95 96 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_local) 97 { 98 .family = {AF_INET, AF_INET6}, 99 .addr = {&in4addr_loopback, &in6addr_loopback}, 100 .expected_errno = 0, 101 }; 102 103 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_v4mapped_any) 104 { 105 .family = {AF_INET, AF_INET6}, 106 .addr = {&in4addr_loopback, &in6addr_v4mapped_any}, 107 .expected_errno = EADDRINUSE, 108 }; 109 110 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_v4mapped_local) 111 { 112 .family = {AF_INET, AF_INET6}, 113 .addr = {&in4addr_loopback, &in6addr_v4mapped_loopback}, 114 .expected_errno = EADDRINUSE, 115 }; 116 117 /* (IPv6, IPv4) */ 118 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v4_any) 119 { 120 .family = {AF_INET6, AF_INET}, 121 .addr = {&in6addr_any, &in4addr_any}, 122 .expected_errno = EADDRINUSE, 123 }; 124 125 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v4_local) 126 { 127 .family = {AF_INET6, AF_INET}, 128 .addr = {&in6addr_any, &in4addr_loopback}, 129 .expected_errno = EADDRINUSE, 130 }; 131 132 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v4_any) 133 { 134 .family = {AF_INET6, AF_INET}, 135 .addr = {&in6addr_loopback, &in4addr_any}, 136 .expected_errno = 0, 137 }; 138 139 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v4_local) 140 { 141 .family = {AF_INET6, AF_INET}, 142 .addr = {&in6addr_loopback, &in4addr_loopback}, 143 .expected_errno = 0, 144 }; 145 146 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v4_any) 147 { 148 .family = {AF_INET6, AF_INET}, 149 .addr = {&in6addr_v4mapped_any, &in4addr_any}, 150 .expected_errno = EADDRINUSE, 151 }; 152 153 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v4_local) 154 { 155 .family = {AF_INET6, AF_INET}, 156 .addr = {&in6addr_v4mapped_any, &in4addr_loopback}, 157 .expected_errno = EADDRINUSE, 158 }; 159 160 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_local_v4_any) 161 { 162 .family = {AF_INET6, AF_INET}, 163 .addr = {&in6addr_v4mapped_loopback, &in4addr_any}, 164 .expected_errno = EADDRINUSE, 165 }; 166 167 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_local_v4_local) 168 { 169 .family = {AF_INET6, AF_INET}, 170 .addr = {&in6addr_v4mapped_loopback, &in4addr_loopback}, 171 .expected_errno = EADDRINUSE, 172 }; 173 174 /* (IPv6, IPv6) */ 175 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v6_local) 176 { 177 .family = {AF_INET6, AF_INET6}, 178 .addr = {&in6addr_any, &in6addr_loopback}, 179 .expected_errno = EADDRINUSE, 180 }; 181 182 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v6_v4mapped_any) 183 { 184 .family = {AF_INET6, AF_INET6}, 185 .addr = {&in6addr_any, &in6addr_v4mapped_any}, 186 .expected_errno = EADDRINUSE, 187 }; 188 189 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v6_v4mapped_local) 190 { 191 .family = {AF_INET6, AF_INET6}, 192 .addr = {&in6addr_any, &in6addr_v4mapped_loopback}, 193 .expected_errno = EADDRINUSE, 194 }; 195 196 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v6_any) 197 { 198 .family = {AF_INET6, AF_INET6}, 199 .addr = {&in6addr_loopback, &in6addr_any}, 200 .expected_errno = EADDRINUSE, 201 }; 202 203 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v6_v4mapped_any) 204 { 205 .family = {AF_INET6, AF_INET6}, 206 .addr = {&in6addr_loopback, &in6addr_v4mapped_any}, 207 .expected_errno = 0, 208 }; 209 210 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v6_v4mapped_local) 211 { 212 .family = {AF_INET6, AF_INET6}, 213 .addr = {&in6addr_loopback, &in6addr_v4mapped_loopback}, 214 .expected_errno = 0, 215 }; 216 217 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v6_any) 218 { 219 .family = {AF_INET6, AF_INET6}, 220 .addr = {&in6addr_v4mapped_any, &in6addr_any}, 221 .expected_errno = EADDRINUSE, 222 }; 223 224 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v6_local) 225 { 226 .family = {AF_INET6, AF_INET6}, 227 .addr = {&in6addr_v4mapped_any, &in6addr_loopback}, 228 .expected_errno = 0, 229 }; 230 231 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v6_v4mapped_local) 232 { 233 .family = {AF_INET6, AF_INET6}, 234 .addr = {&in6addr_v4mapped_any, &in6addr_v4mapped_loopback}, 235 .expected_errno = EADDRINUSE, 236 }; 237 238 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_loopback_v6_any) 239 { 240 .family = {AF_INET6, AF_INET6}, 241 .addr = {&in6addr_v4mapped_loopback, &in6addr_any}, 242 .expected_errno = EADDRINUSE, 243 }; 244 245 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_loopback_v6_local) 246 { 247 .family = {AF_INET6, AF_INET6}, 248 .addr = {&in6addr_v4mapped_loopback, &in6addr_loopback}, 249 .expected_errno = 0, 250 }; 251 252 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_loopback_v6_v4mapped_any) 253 { 254 .family = {AF_INET6, AF_INET6}, 255 .addr = {&in6addr_v4mapped_loopback, &in6addr_v4mapped_any}, 256 .expected_errno = EADDRINUSE, 257 }; 258 259 static void setup_addr(FIXTURE_DATA(bind_wildcard) *self, int i, 260 int family, const void *addr_const) 261 { 262 if (family == AF_INET) { 263 struct sockaddr_in *addr4 = &self->addr[i].addr4; 264 const __u32 *addr4_const = addr_const; 265 266 addr4->sin_family = AF_INET; 267 addr4->sin_port = htons(0); 268 addr4->sin_addr.s_addr = htonl(*addr4_const); 269 270 self->addrlen[i] = sizeof(struct sockaddr_in); 271 } else { 272 struct sockaddr_in6 *addr6 = &self->addr[i].addr6; 273 const struct in6_addr *addr6_const = addr_const; 274 275 addr6->sin6_family = AF_INET6; 276 addr6->sin6_port = htons(0); 277 addr6->sin6_addr = *addr6_const; 278 279 self->addrlen[i] = sizeof(struct sockaddr_in6); 280 } 281 } 282 283 FIXTURE_SETUP(bind_wildcard) 284 { 285 setup_addr(self, 0, variant->family[0], variant->addr[0]); 286 setup_addr(self, 1, variant->family[1], variant->addr[1]); 287 } 288 289 FIXTURE_TEARDOWN(bind_wildcard) 290 { 291 } 292 293 void bind_sockets(struct __test_metadata *_metadata, 294 FIXTURE_DATA(bind_wildcard) *self, 295 int expected_errno, 296 struct sockaddr *addr1, socklen_t addrlen1, 297 struct sockaddr *addr2, socklen_t addrlen2) 298 { 299 int fd[2]; 300 int ret; 301 302 fd[0] = socket(addr1->sa_family, SOCK_STREAM, 0); 303 ASSERT_GT(fd[0], 0); 304 305 ret = bind(fd[0], addr1, addrlen1); 306 ASSERT_EQ(ret, 0); 307 308 ret = getsockname(fd[0], addr1, &addrlen1); 309 ASSERT_EQ(ret, 0); 310 311 ((struct sockaddr_in *)addr2)->sin_port = ((struct sockaddr_in *)addr1)->sin_port; 312 313 fd[1] = socket(addr2->sa_family, SOCK_STREAM, 0); 314 ASSERT_GT(fd[1], 0); 315 316 ret = bind(fd[1], addr2, addrlen2); 317 if (expected_errno) { 318 ASSERT_EQ(ret, -1); 319 ASSERT_EQ(errno, expected_errno); 320 } else { 321 ASSERT_EQ(ret, 0); 322 } 323 324 close(fd[1]); 325 close(fd[0]); 326 } 327 328 TEST_F(bind_wildcard, plain) 329 { 330 bind_sockets(_metadata, self, variant->expected_errno, 331 &self->addr[0].addr, self->addrlen[0], 332 &self->addr[1].addr, self->addrlen[1]); 333 } 334 335 TEST_HARNESS_MAIN 336