1 /* Tests for network interfaces and routing (LWIP) - by D.C. van Moolenbroek */ 2 /* This test needs to be run as root: it manipulates network settings. */ 3 /* 4 * TODO: due to time constraints, this test is currently absolutely minimal. 5 * It does not yet test by far most of the service code it is supposed to test, 6 * in particular interface management code, interface address assignment code, 7 * routing sockets code, and routing code. The second subtest (test93b) in this 8 * file serves as a reasonable example of how many of the future subtests 9 * should operate, though: by issuing interface IOCTLs and routing commands on 10 * a loopback interface created for the occasion. 11 */ 12 #include <stdlib.h> 13 #include <string.h> 14 #include <stddef.h> 15 #include <sys/socket.h> 16 #include <sys/ioctl.h> 17 #include <net/if.h> 18 #include <net/if_dl.h> 19 #include <net/route.h> 20 #include <netinet/in.h> 21 #include <netinet6/in6_var.h> 22 #include <arpa/inet.h> 23 24 #include "common.h" 25 #include "socklib.h" 26 27 #define TEST_IFNAME "lo93" 28 29 #define ITERATIONS 2 30 31 static const enum state rtlnk_states[] = { 32 S_NEW, S_N_SHUT_R, S_N_SHUT_W, S_N_SHUT_RW, 33 }; 34 35 static const int rt_results[][__arraycount(rtlnk_states)] = { 36 [C_ACCEPT] = { 37 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, 38 }, 39 [C_BIND] = { 40 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, 41 }, 42 [C_CONNECT] = { 43 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, 44 }, 45 [C_GETPEERNAME] = { 46 0, 0, 0, 0, 47 }, 48 [C_GETSOCKNAME] = { 49 0, 0, 0, 0, 50 }, 51 [C_GETSOCKOPT_ERR] = { 52 0, 0, 0, 0, 53 }, 54 [C_GETSOCKOPT_KA] = { 55 0, 0, 0, 0, 56 }, 57 [C_GETSOCKOPT_RB] = { 58 0, 0, 0, 0, 59 }, 60 [C_IOCTL_NREAD] = { 61 0, 0, 0, 0, 62 }, 63 [C_LISTEN] = { 64 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, 65 }, 66 [C_RECV] = { 67 -EAGAIN, 0, -EAGAIN, 0, 68 }, 69 [C_RECVFROM] = { 70 -EAGAIN, 0, -EAGAIN, 0, 71 }, 72 [C_SEND] = { 73 -ENOBUFS, -ENOBUFS, -EPIPE, -EPIPE, 74 }, 75 [C_SENDTO] = { 76 -EISCONN, -EISCONN, -EPIPE, -EPIPE, 77 }, 78 [C_SELECT_R] = { 79 0, 1, 0, 1, 80 }, 81 [C_SELECT_W] = { 82 1, 1, 1, 1, 83 }, 84 [C_SELECT_X] = { 85 0, 0, 0, 0, 86 }, 87 [C_SETSOCKOPT_BC] = { 88 0, 0, 0, 0, 89 }, 90 [C_SETSOCKOPT_KA] = { 91 0, 0, 0, 0, 92 }, 93 [C_SETSOCKOPT_L] = { 94 0, 0, 0, 0, 95 }, 96 [C_SETSOCKOPT_RA] = { 97 0, 0, 0, 0, 98 }, 99 [C_SHUTDOWN_R] = { 100 0, 0, 0, 0, 101 }, 102 [C_SHUTDOWN_RW] = { 103 0, 0, 0, 0, 104 }, 105 [C_SHUTDOWN_W] = { 106 0, 0, 0, 0, 107 }, 108 }; 109 110 static const int lnk_results[][__arraycount(rtlnk_states)] = { 111 [C_ACCEPT] = { 112 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, 113 }, 114 [C_BIND] = { 115 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, 116 }, 117 [C_CONNECT] = { 118 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, 119 }, 120 [C_GETPEERNAME] = { 121 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, 122 }, 123 [C_GETSOCKNAME] = { 124 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, 125 }, 126 [C_GETSOCKOPT_ERR] = { 127 0, 0, 0, 0, 128 }, 129 [C_GETSOCKOPT_KA] = { 130 0, 0, 0, 0, 131 }, 132 [C_GETSOCKOPT_RB] = { 133 -ENOPROTOOPT, -ENOPROTOOPT, -ENOPROTOOPT, -ENOPROTOOPT, 134 }, 135 [C_IOCTL_NREAD] = { 136 0, 0, 0, 0, 137 }, 138 [C_LISTEN] = { 139 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, 140 }, 141 [C_RECV] = { 142 -EOPNOTSUPP, 0, -EOPNOTSUPP, 0, 143 }, 144 [C_RECVFROM] = { 145 -EOPNOTSUPP, 0, -EOPNOTSUPP, 0, 146 }, 147 [C_SEND] = { 148 -EOPNOTSUPP, -EOPNOTSUPP, -EPIPE, -EPIPE, 149 }, 150 [C_SENDTO] = { 151 -EOPNOTSUPP, -EOPNOTSUPP, -EPIPE, -EPIPE, 152 }, 153 [C_SELECT_R] = { 154 1, 1, 1, 1, 155 }, 156 [C_SELECT_W] = { 157 1, 1, 1, 1, 158 }, 159 [C_SELECT_X] = { 160 0, 0, 0, 0, 161 }, 162 [C_SETSOCKOPT_BC] = { 163 0, 0, 0, 0, 164 }, 165 [C_SETSOCKOPT_KA] = { 166 0, 0, 0, 0, 167 }, 168 [C_SETSOCKOPT_L] = { 169 0, 0, 0, 0, 170 }, 171 [C_SETSOCKOPT_RA] = { 172 0, 0, 0, 0, 173 }, 174 [C_SHUTDOWN_R] = { 175 0, 0, 0, 0, 176 }, 177 [C_SHUTDOWN_RW] = { 178 0, 0, 0, 0, 179 }, 180 [C_SHUTDOWN_W] = { 181 0, 0, 0, 0, 182 }, 183 }; 184 185 /* 186 * Set up a routing or link socket file descriptor in the requested state and 187 * pass it to socklib_sweep_call() along with local and remote addresses and 188 * their lengths. 189 */ 190 static int 191 rtlnk_sweep(int domain, int type, int protocol, enum state state, 192 enum call call) 193 { 194 struct sockaddr sa; 195 int r, fd; 196 197 memset(&sa, 0, sizeof(sa)); 198 sa.sa_family = domain; 199 200 if ((fd = socket(domain, type | SOCK_NONBLOCK, protocol)) < 0) e(0); 201 202 switch (state) { 203 case S_NEW: break; 204 case S_N_SHUT_R: if (shutdown(fd, SHUT_RD)) e(0); break; 205 case S_N_SHUT_W: if (shutdown(fd, SHUT_WR)) e(0); break; 206 case S_N_SHUT_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break; 207 default: e(0); 208 } 209 210 r = socklib_sweep_call(call, fd, &sa, &sa, 211 offsetof(struct sockaddr, sa_data)); 212 213 if (close(fd) != 0) e(0); 214 215 return r; 216 } 217 218 /* 219 * Sweep test for socket calls versus socket states of routing and link 220 * sockets. 221 */ 222 static void 223 test93a(void) 224 { 225 226 subtest = 1; 227 228 socklib_sweep(AF_ROUTE, SOCK_RAW, 0, rtlnk_states, 229 __arraycount(rtlnk_states), (const int *)rt_results, rtlnk_sweep); 230 231 /* 232 * Our implementation of link sockets currently serves only one 233 * purpose, and that is to pass on ioctl() calls issued on the socket. 234 * As such, the results here are not too important. The test mostly 235 * ensures that all calls actually complete--for example, that there is 236 * no function pointer NULL check missing in libsockevent. 237 */ 238 socklib_sweep(AF_LINK, SOCK_DGRAM, 0, rtlnk_states, 239 __arraycount(rtlnk_states), (const int *)lnk_results, rtlnk_sweep); 240 } 241 242 /* 243 * Attempt to destroy the test loopback interface. Return 0 if destruction was 244 * successful, or -1 if no such interface existed. 245 */ 246 static int 247 test93_destroy_if(void) 248 { 249 struct ifreq ifr; 250 int r, fd; 251 252 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0); 253 254 memset(&ifr, 0, sizeof(ifr)); 255 strlcpy(ifr.ifr_name, TEST_IFNAME, sizeof(ifr.ifr_name)); 256 257 r = ioctl(fd, SIOCIFDESTROY, &ifr); 258 if (r != 0 && (r != -1 || errno != ENXIO)) e(0); 259 260 if (close(fd) != 0) e(0); 261 262 return r; 263 } 264 265 /* 266 * Destroy the test interface at exit. It is always safe to do so as its name 267 * is sufficiently unique, and we do not want to leave it around. 268 */ 269 static void 270 test93_destroy_if_atexit(void) 271 { 272 static int atexit_set = 0; 273 274 if (!atexit_set) { 275 (void)test93_destroy_if(); 276 277 atexit_set = 1; 278 } 279 } 280 281 /* 282 * Attempt to create a test loopback interface. Return 0 if creation was 283 * successful, or -1 if no more interfaces could be created. 284 */ 285 static int 286 test93_create_if(void) 287 { 288 struct ifreq ifr; 289 int r, fd; 290 291 (void)test93_destroy_if(); 292 293 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0); 294 295 memset(&ifr, 0, sizeof(ifr)); 296 strlcpy(ifr.ifr_name, TEST_IFNAME, sizeof(ifr.ifr_name)); 297 298 r = ioctl(fd, SIOCIFCREATE, &ifr); 299 if (r != 0 && (r != -1 || errno != ENOBUFS)) e(0); 300 301 if (close(fd) != 0) e(0); 302 303 atexit(test93_destroy_if_atexit); 304 305 return r; 306 } 307 308 /* 309 * Set the interface-up value for an interface to the given boolean value. 310 */ 311 static void 312 test93_set_if_up(const char * ifname, int up) 313 { 314 struct ifreq ifr; 315 int fd; 316 317 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0); 318 319 memset(&ifr, 0, sizeof(ifr)); 320 strlcpy(ifr.ifr_name, TEST_IFNAME, sizeof(ifr.ifr_name)); 321 322 if (ioctl(fd, SIOCGIFFLAGS, &ifr) != 0) e(0); 323 324 if (up) 325 ifr.ifr_flags |= IFF_UP; 326 else 327 ifr.ifr_flags &= ~IFF_UP; 328 329 if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0) e(0); 330 331 if (close(fd) != 0) e(0); 332 } 333 334 /* 335 * Construct an IPv6 network mask for a certain prefix length. 336 */ 337 static void 338 test93_make_netmask6(struct sockaddr_in6 * sin6, unsigned int prefix) 339 { 340 unsigned int byte, bit; 341 342 if (prefix > 128) e(0); 343 memset(sin6, 0, sizeof(*sin6)); 344 sin6->sin6_family = AF_INET6; 345 346 byte = prefix / NBBY; 347 bit = prefix % NBBY; 348 349 if (byte > 0) 350 memset(sin6->sin6_addr.s6_addr, 0xff, byte); 351 if (bit != 0) 352 sin6->sin6_addr.s6_addr[byte] = 0xff << (NBBY - bit); 353 } 354 355 /* 356 * Issue a modifying routing command, which must be one of RTM_ADD, RTM_CHANGE, 357 * RTM_DELETE, or RTM_LOCK. The destination address (IPv4 or IPv6) and netmask 358 * prefix are required. The flags (RTF_), interface name, and gateway are 359 * optional depending on the command (and flags) being issued. Return 0 on 360 * success, and -1 with errno set on failure. 361 */ 362 static int 363 test93_route_cmd(int cmd, const struct sockaddr * dest, socklen_t dest_len, 364 unsigned int prefix, int flags, const char * ifname, 365 const struct sockaddr * gw, socklen_t gw_len) 366 { 367 static unsigned int seq = 0; 368 struct sockaddr_storage destss, maskss, ifpss, gwss; 369 struct sockaddr_in mask4; 370 struct sockaddr_in6 mask6; 371 struct sockaddr_dl ifp; 372 struct rt_msghdr rtm; 373 struct iovec iov[5]; 374 struct msghdr msg; 375 unsigned int i, iovlen; 376 int r, fd, err; 377 378 memset(&rtm, 0, sizeof(rtm)); 379 rtm.rtm_version = RTM_VERSION; 380 rtm.rtm_type = cmd; 381 rtm.rtm_flags = flags; 382 rtm.rtm_addrs = RTA_DST | RTA_NETMASK; 383 rtm.rtm_seq = ++seq; 384 385 iovlen = 0; 386 iov[iovlen].iov_base = &rtm; 387 iov[iovlen++].iov_len = sizeof(rtm); 388 389 memset(&destss, 0, sizeof(destss)); 390 memcpy(&destss, dest, dest_len); 391 destss.ss_len = dest_len; 392 393 iov[iovlen].iov_base = &destss; 394 iov[iovlen++].iov_len = RT_ROUNDUP(dest_len); 395 396 /* Do this in RTA order. */ 397 memset(&gwss, 0, sizeof(gwss)); 398 if (gw != NULL) { 399 memcpy(&gwss, gw, gw_len); 400 gwss.ss_len = gw_len; 401 402 rtm.rtm_addrs |= RTA_GATEWAY; 403 iov[iovlen].iov_base = &gwss; 404 iov[iovlen++].iov_len = RT_ROUNDUP(gwss.ss_len); 405 } 406 407 memset(&maskss, 0, sizeof(maskss)); 408 switch (dest->sa_family) { 409 case AF_INET: 410 if (prefix > 32) e(0); 411 memset(&mask4, 0, sizeof(mask4)); 412 mask4.sin_family = AF_INET; 413 if (prefix < 32) 414 mask4.sin_addr.s_addr = htonl(0xffffffffUL << prefix); 415 416 memcpy(&maskss, &mask4, sizeof(mask4)); 417 maskss.ss_len = sizeof(mask4); 418 419 break; 420 421 case AF_INET6: 422 test93_make_netmask6(&mask6, prefix); 423 424 memcpy(&maskss, &mask6, sizeof(mask6)); 425 maskss.ss_len = sizeof(mask6); 426 427 break; 428 429 default: 430 e(0); 431 } 432 433 iov[iovlen].iov_base = &maskss; 434 iov[iovlen++].iov_len = RT_ROUNDUP(maskss.ss_len); 435 436 if (ifname != NULL) { 437 memset(&ifp, 0, sizeof(ifp)); 438 ifp.sdl_nlen = strlen(ifname); 439 ifp.sdl_len = offsetof(struct sockaddr_dl, sdl_data) + 440 ifp.sdl_nlen; 441 ifp.sdl_family = AF_LINK; 442 443 memset(&ifpss, 0, sizeof(ifpss)); 444 memcpy(&ifpss, &ifp, ifp.sdl_len); 445 memcpy(&((struct sockaddr_dl *)&ifpss)->sdl_data, ifname, 446 ifp.sdl_nlen); 447 448 rtm.rtm_addrs |= RTA_IFP; 449 iov[iovlen].iov_base = &ifpss; 450 iov[iovlen++].iov_len = RT_ROUNDUP(ifpss.ss_len); 451 } 452 453 memset(&msg, 0, sizeof(msg)); 454 msg.msg_iov = iov; 455 msg.msg_iovlen = iovlen; 456 457 if ((fd = socket(AF_ROUTE, SOCK_RAW, 0)) < 0) e(0); 458 459 for (i = 0; i < iovlen; i++) 460 rtm.rtm_msglen += iov[i].iov_len; 461 462 r = sendmsg(fd, &msg, 0); 463 if (r != rtm.rtm_msglen && r != -1) e(0); 464 err = errno; 465 466 /* 467 * We could just shut down the socket for reading, but this is just an 468 * extra test we can do basically for free. 469 */ 470 rtm.rtm_seq = 0; 471 do { 472 iov[0].iov_base = &rtm; 473 iov[0].iov_len = sizeof(rtm); 474 475 if (recvmsg(fd, &msg, 0) <= 0) e(0); 476 } while (rtm.rtm_pid != getpid() || rtm.rtm_seq != seq); 477 478 if (r == -1) { 479 if (rtm.rtm_errno != err) e(0); 480 if (rtm.rtm_flags & RTF_DONE) e(0); 481 } else { 482 if (rtm.rtm_errno != 0) e(0); 483 if (!(rtm.rtm_flags & RTF_DONE)) e(0); 484 } 485 486 if (close(fd) != 0) e(0); 487 488 errno = err; 489 return (r > 0) ? 0 : -1; 490 } 491 492 /* 493 * Add or delete an IPv6 address to or from an interface. The interface name, 494 * address, and prefix length must always be given. When adding, a set of 495 * flags (IN6_IFF) and lifetimes must be given as well. 496 */ 497 static void 498 test93_ipv6_addr(int add, const char * ifname, 499 const struct sockaddr_in6 * sin6, unsigned int prefix, int flags, 500 uint32_t valid_life, uint32_t pref_life) 501 { 502 struct in6_aliasreq ifra; 503 int fd; 504 505 memset(&ifra, 0, sizeof(ifra)); 506 strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); 507 memcpy(&ifra.ifra_addr, sin6, sizeof(ifra.ifra_addr)); 508 /* leave ifra_dstaddr blank */ 509 test93_make_netmask6(&ifra.ifra_prefixmask, prefix); 510 ifra.ifra_flags = flags; 511 ifra.ifra_lifetime.ia6t_vltime = valid_life; 512 ifra.ifra_lifetime.ia6t_pltime = pref_life; 513 514 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0); 515 516 if (ioctl(fd, (add) ? SIOCAIFADDR_IN6 : SIOCDIFADDR_IN6, &ifra) != 0) 517 e(0); 518 519 if (close(fd) != 0) e(0); 520 } 521 522 static const struct { 523 int result; /* 0..2 = prefer srcN, -1 = no preference */ 524 const char *dest_addr; 525 const char *src0_addr; 526 unsigned int src0_prefix; 527 int src0_flags; 528 const char *src1_addr; 529 unsigned int src1_prefix; 530 int src1_flags; 531 const char *src2_addr; 532 unsigned int src2_prefix; 533 int src2_flags; 534 } test93b_table[] = { 535 /* 536 * These are all the applicable tests from RFC 6724 Sec. 10.1, slightly 537 * changed not to use the default link-local address of lo0. 538 */ 539 /* Prefer appropriate scope: */ 540 { 0, "2001:db8:1::1", "2001:db8:3::1", 64, 0, "fe80::93:1", 64, 0 }, 541 /* Prefer appropriate scope: */ 542 { 0, "ff05::1", "2001:db8:3::1", 64, 0, "fe80::93:1", 64, 0 }, 543 /* Prefer same address: */ 544 { 0, "2001:db8:1::1", "2001:db8:1::1", 64, IN6_IFF_DEPRECATED, 545 "2001:db8:2::1", 64, 0 }, 546 /* Prefer appropriate scope: */ 547 { 0, "fe80::93:1", "fe80::93:2", 64, IN6_IFF_DEPRECATED, 548 "2001:db8:2::1", 64, 0 }, 549 /* Longest matching prefix: */ 550 { 0, "2001:db8:1::1", "2001:db8:1::2", 64, 0, "2001:db8:3::2", 64, 0 }, 551 /* Prefer matching label: */ 552 { 0, "2002:c633:6401::1", "2002:c633:6401::d5e3:7953:13eb:22e8", 64, 553 IN6_IFF_TEMPORARY, "2001:db8:1::2", 64, 0 }, 554 /* Prefer temporary address: */ 555 { 1, "2001:db8:1::d5e3:0:0:1", "2001:db8:1::2", 64, 0, 556 "2001:db8:1::d5e3:7953:13eb:22e8", 64, IN6_IFF_TEMPORARY }, 557 /* 558 * Our own additional tests. 559 */ 560 /* Prefer same address: */ 561 { 1, "4000:93::1", "2001:db8:3::1", 64, 0, "4000:93::1", 64, 0 }, 562 { 2, "2001:db8:1::1", "2001:db8:3::1", 64, 0, "fe80::93:1", 64, 0, 563 "2001:db8:1::1", 64, 0 }, 564 /* Prefer appropriate scope: */ 565 { 1, "ff01::1", "2001:db8:3::1", 64, 0, "fe80::93:1", 64, 0 }, 566 { 1, "ff02::1", "2001:db8:3::1", 64, 0, "fe80::93:1", 64, 0 }, 567 { 0, "ff0e::1", "2001:db8:3::1", 64, 0, "fe80::93:1", 64, 0 }, 568 { 1, "fd00:93::1", "2001:db8:3::1", 64, 0, "fd00::93:2", 64, 0 }, 569 { 1, "fd00:93::1", "fe80::93:1", 64, 0, "fd00::93:2", 64, 0 }, 570 { 0, "fd00:93::1", "2001:db8:3::1", 64, 0, "fe80::93:1", 64, 0 }, 571 { 1, "2001:db8:1::1", "fe80::93:1", 64, 0, "fd00::93:2", 64, 0 }, 572 { 0, "2001:db8:1::1", "2001:db8:3::1", 64, 0, "4000:93::1", 64, 0 }, 573 { 0, "4000:93::2", "2001:db8:3::1", 64, 0, "4000:93::1", 64, 0 }, 574 { 2, "2001:db8:1::1", "fe80::93:1", 64, 0, "fd00::93:1", 64, 0, 575 "2001:db8:3::1", 64, 0 }, 576 { 2, "2001:db8:1::1", "fe80::93:1", 64, IN6_IFF_DEPRECATED, 577 "fe80::93:2", 64, 0, "2001:db8:3::1", 64, 0 }, 578 /* Avoid deprecated address: */ 579 { 1, "2002:c633:6401::1", "2002:c633:6401::d5e3:7953:13eb:22e8", 64, 580 IN6_IFF_DEPRECATED, "2001:db8:1::2", 64, 0 }, 581 { 2, "2001:db8:1::1", "2001:db8:1::3", 64, IN6_IFF_DEPRECATED, 582 "2001:db8:2::1", 64, IN6_IFF_DEPRECATED, "2001:db8:3::1", 64, 0 }, 583 { 2, "2001:db8:1::1", "2002:db8:1::3", 64, IN6_IFF_DEPRECATED, 584 "2001:db8:2::1", 64, IN6_IFF_DEPRECATED, "2001:db8:3::1", 64, 0 }, 585 /* Prefer matching label: */ 586 { 0, "2002:c633:6401::1", "2002:c633:6401::d5e3:7953:13eb:22e8", 64, 0, 587 "2001:db8:1::2", 64, IN6_IFF_TEMPORARY }, 588 { 2, "2002:c633:6401::1", "2001:db8:3::2", 64, 0, "2001:db8:1::2", 64, 589 IN6_IFF_TEMPORARY, "2002:c633:6401::d5e3:7953:13eb:22e8", 64, 0 }, 590 { 2, "2001:db8:1::1", "2003:db8::1", 64, 0, "3ffe:db8::1", 64, 0, 591 "2001:db8:3::1", 64, 0 }, 592 /* Prefer temporary address: */ 593 { 0, "2001:db8:1::d5e3:0:0:1", "2001:db8:1::2", 96, IN6_IFF_TEMPORARY, 594 "2001:db8:1::d5e3:7953:13eb:22e8", 96, 0 }, 595 { 2, "2002:c633:6401::1", "2001:db8:3::2", 64, 0, "2002:c633:6401::2", 596 64, 0, "2002:c633:6401::d5e3:7953:13eb:22e8", 64, 597 IN6_IFF_TEMPORARY }, 598 /* Longest matching prefix: */ 599 { 1, "2001:db8:1::d5e3:0:0:1", "2001:db8:1::2", 96, 0, 600 "2001:db8:1::d5e3:7953:13eb:22e8", 96, 0 }, 601 { 2, "2001:db8:1:1::1", "2001:db8:2:1::2", 64, 0, "2001:db8:1:2::2", 602 64, 0, "2001:db8:1:1::2", 64, 0 }, 603 { 0, "2001:db8:1::1", "2001:db8:1::2", 47, 0, "2001:db8:3::2", 47, 0 }, 604 /* No preference (a tie): */ 605 { -1, "2001:db8:1::1", "2001:db8:1::2", 46, 0, "2001:db8:3::2", 46, 606 0 }, 607 { -1, "2001:db8::1:0:0:1", "2001:db8::1:0:0:2", 64, 0, 608 "2001:db8::2:0:0:2", 64, 0, "2001:db8::3:0:0:2", 64, 0 }, 609 }; 610 611 struct src_addr { 612 struct sockaddr_in6 addr; 613 unsigned int prefix; 614 int flags; 615 }; 616 617 /* 618 * Test source address selection with a particular destination address and two 619 * or three source addresses. 620 */ 621 static void 622 sub93b(int result, const struct sockaddr_in6 * dest, unsigned int ifindex, 623 const struct src_addr * src0, const struct src_addr * src1, 624 const struct src_addr * src2) 625 { 626 struct sockaddr_in6 dest_copy, src; 627 socklen_t len; 628 int fd, rt_res; 629 630 /* Add the candidate source addresses. */ 631 test93_ipv6_addr(1, TEST_IFNAME, &src0->addr, src0->prefix, 632 src0->flags, 0xffffffffUL, 0xffffffffUL); 633 634 test93_ipv6_addr(1, TEST_IFNAME, &src1->addr, src1->prefix, 635 src1->flags, 0xffffffffUL, 0xffffffffUL); 636 637 if (src2 != NULL) 638 test93_ipv6_addr(1, TEST_IFNAME, &src2->addr, src2->prefix, 639 src2->flags, 0xffffffffUL, 0xffffffffUL); 640 641 /* 642 * We need to make sure that packets to the destination are routed to 643 * our test interface at all, so create a route for it. Creating the 644 * route may fail if the destination address is equal to either of the 645 * source addresses, but that is fine. We use a blackhole route here, 646 * but this test should not generate any traffic anyway. 647 */ 648 rt_res = test93_route_cmd(RTM_ADD, (struct sockaddr *)dest, 649 sizeof(*dest), 128, RTF_UP | RTF_BLACKHOLE | RTF_STATIC, 650 TEST_IFNAME, NULL, 0); 651 if (rt_res != 0 && (rt_res != -1 || errno != EEXIST)) e(0); 652 653 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0); 654 655 /* Set a scope ID if necessary. */ 656 memcpy(&dest_copy, dest, sizeof(dest_copy)); 657 dest_copy.sin6_port = 1; /* anything that is not zero */ 658 if (IN6_IS_ADDR_LINKLOCAL(&dest_copy.sin6_addr) || 659 IN6_IS_ADDR_MC_NODELOCAL(&dest_copy.sin6_addr) || 660 IN6_IS_ADDR_MC_LINKLOCAL(&dest_copy.sin6_addr)) 661 dest_copy.sin6_scope_id = ifindex; 662 663 /* Connecting also selects a source address. */ 664 if (connect(fd, (struct sockaddr *)&dest_copy, sizeof(dest_copy)) != 0) 665 e(0); 666 667 /* Obtain the selected source address. */ 668 len = sizeof(src); 669 if (getsockname(fd, (struct sockaddr *)&src, &len) != 0) e(0); 670 671 /* 672 * If the chosen destination address has a scope ID, it must be for our 673 * test interface. 674 */ 675 if (src.sin6_scope_id != 0 && src.sin6_scope_id != ifindex) e(0); 676 677 /* Is it the expected candidate source address? */ 678 if (!memcmp(&src.sin6_addr, &src0->addr.sin6_addr, 679 sizeof(src.sin6_addr))) { 680 if (result != 0) e(0); 681 } else if (!memcmp(&src.sin6_addr, &src1->addr.sin6_addr, 682 sizeof(src.sin6_addr))) { 683 if (result != 1) e(0); 684 } else if (src2 != NULL && !memcmp(&src.sin6_addr, 685 &src2->addr.sin6_addr, sizeof(src.sin6_addr))) { 686 if (result != 2) e(0); 687 } else 688 e(0); 689 690 /* Clean up. */ 691 if (close(fd) != 0) e(0); 692 693 if (rt_res == 0) { 694 if (test93_route_cmd(RTM_DELETE, (struct sockaddr *)dest, 695 sizeof(*dest), 128, 0, NULL, NULL, 0) != 0) e(0); 696 } 697 698 if (src2 != NULL) 699 test93_ipv6_addr(0, TEST_IFNAME, &src2->addr, src2->prefix, 0, 700 0, 0); 701 702 test93_ipv6_addr(0, TEST_IFNAME, &src1->addr, src1->prefix, 0, 0, 0); 703 704 test93_ipv6_addr(0, TEST_IFNAME, &src0->addr, src0->prefix, 0, 0, 0); 705 } 706 707 /* 708 * IPv6 source address selection algorithm test. 709 */ 710 static void 711 test93b(void) 712 { 713 static const int order[][3] = { 714 { 0, 1, 2 }, 715 { 1, 0, 2 }, 716 { 0, 2, 1 }, 717 { 1, 2, 0 }, 718 { 2, 0, 1 }, 719 { 2, 1, 0 } 720 }; 721 struct sockaddr_in6 dest; 722 struct src_addr src[3]; 723 unsigned int i, j, k, count, ifindex; 724 int result; 725 726 subtest = 2; 727 728 if (test93_create_if() != 0) 729 return; /* skip this test */ 730 731 if ((ifindex = if_nametoindex(TEST_IFNAME)) == 0) e(0); 732 733 test93_set_if_up(TEST_IFNAME, 1); 734 735 for (i = 0; i < __arraycount(test93b_table); i++) { 736 memset(&dest, 0, sizeof(dest)); 737 dest.sin6_family = AF_INET6; 738 if (inet_pton(AF_INET6, test93b_table[i].dest_addr, 739 &dest.sin6_addr) != 1) e(0); 740 741 memset(&src[0].addr, 0, sizeof(src[0].addr)); 742 src[0].addr.sin6_family = AF_INET6; 743 if (inet_pton(AF_INET6, test93b_table[i].src0_addr, 744 &src[0].addr.sin6_addr) != 1) e(0); 745 src[0].prefix = test93b_table[i].src0_prefix; 746 src[0].flags = test93b_table[i].src0_flags; 747 748 memset(&src[1].addr, 0, sizeof(src[1].addr)); 749 src[1].addr.sin6_family = AF_INET6; 750 if (inet_pton(AF_INET6, test93b_table[i].src1_addr, 751 &src[1].addr.sin6_addr) != 1) e(0); 752 src[1].prefix = test93b_table[i].src1_prefix; 753 src[1].flags = test93b_table[i].src1_flags; 754 755 if (test93b_table[i].src2_addr != NULL) { 756 memset(&src[2].addr, 0, sizeof(src[2].addr)); 757 src[2].addr.sin6_family = AF_INET6; 758 if (inet_pton(AF_INET6, test93b_table[i].src2_addr, 759 &src[2].addr.sin6_addr) != 1) e(0); 760 src[2].prefix = test93b_table[i].src2_prefix; 761 src[2].flags = test93b_table[i].src2_flags; 762 763 count = 6; 764 } else 765 count = 2; 766 767 result = test93b_table[i].result; 768 769 /* 770 * Try all orders for the source addresses. The permutation 771 * part can be done much better, but it really does not matter. 772 */ 773 for (j = 0; j < count; j++) { 774 for (k = 0; k < count; k++) 775 if (result == -1 || order[j][k] == result) 776 break; 777 778 sub93b((result != -1) ? k : 0, &dest, ifindex, 779 &src[order[j][0]], &src[order[j][1]], 780 (count > 2) ? &src[order[j][2]] : NULL); 781 } 782 } 783 784 if (test93_destroy_if() != 0) e(0); 785 } 786 787 /* 788 * Interface index number wrapping test. 789 */ 790 static void 791 test93c(void) 792 { 793 unsigned int i; 794 795 subtest = 3; 796 797 /* There might not be an available loopback interface at all. */ 798 if (test93_create_if() != 0) 799 return; /* skip this test */ 800 801 if (test93_destroy_if() != 0) e(0); 802 803 /* 804 * During the development of the LWIP service, the lwIP library's 805 * interface index assignment was still in its infancy. This test aims 806 * to ensure that future changes in the library do not break our 807 * service. 808 */ 809 for (i = 0; i < UINT8_MAX + 1; i++) { 810 if (test93_create_if() != 0) e(0); 811 812 if (test93_destroy_if() != 0) e(0); 813 } 814 } 815 816 /* 817 * Test program for LWIP interface and routing management. 818 */ 819 int 820 main(int argc, char ** argv) 821 { 822 int i, m; 823 824 start(93); 825 826 if (argc == 2) 827 m = atoi(argv[1]); 828 else 829 m = 0xFF; 830 831 for (i = 0; i < ITERATIONS; i++) { 832 if (m & 0x01) test93a(); 833 if (m & 0x02) test93b(); 834 if (m & 0x04) test93c(); 835 } 836 837 quit(); 838 /* NOTREACHED */ 839 } 840