1 /* 2 * Copyright (c) 2015 Fujitsu Ltd. 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 * Author: David L Stevens 19 */ 20 21 #include <unistd.h> 22 #include <errno.h> 23 24 #include <sys/socket.h> 25 #include <netdb.h> 26 #include <arpa/inet.h> 27 28 #include "test.h" 29 30 #ifndef AI_V4MAPPED 31 #define AI_V4MAPPED 0x0008 /* IPv4 mapped addresses are acceptable. */ 32 #endif 33 34 static void setup(void); 35 static void gaiv4(void); 36 static void gaiv6(void); 37 38 char *TCID = "getaddrinfo_01"; 39 int TST_TOTAL = 22; 40 41 int main(int argc, char *argv[]) 42 { 43 int lc; 44 45 tst_parse_opts(argc, argv, NULL, NULL); 46 47 setup(); 48 49 for (lc = 0; TEST_LOOPING(lc); ++lc) { 50 tst_count = 0; 51 52 gaiv4(); 53 gaiv6(); 54 } 55 56 tst_exit(); 57 } 58 59 static void setup(void) 60 { 61 TEST_PAUSE; 62 } 63 64 /* getaddrinfo tests (v4) */ 65 static void gaiv4(void) 66 { 67 struct addrinfo *aires, hints, *pai; 68 char hostname[MAXHOSTNAMELEN + 1]; 69 char shortname[MAXHOSTNAMELEN + 1]; 70 char service[NI_MAXSERV + 1]; 71 int servnum; 72 char *p; 73 74 if (gethostname(hostname, sizeof(hostname)) < 0) 75 tst_brkm(TBROK | TERRNO, NULL, "gethostname failed"); 76 strncpy(shortname, hostname, MAXHOSTNAMELEN); 77 shortname[MAXHOSTNAMELEN] = '\0'; 78 p = strchr(shortname, '.'); 79 if (p) 80 *p = '\0'; 81 82 /* test 1, IPv4 basic lookup */ 83 memset(&hints, 0, sizeof(hints)); 84 hints.ai_family = AF_INET; 85 TEST(getaddrinfo(hostname, 0, &hints, &aires)); 86 if (!TEST_RETURN) { 87 struct sockaddr_in *psin = 0; 88 int err = 0; 89 90 for (pai = aires; pai; pai = pai->ai_next) { 91 err |= pai->ai_family != AF_INET; 92 err |= pai->ai_addrlen != sizeof(struct sockaddr_in); 93 err |= pai->ai_addr == 0; 94 psin = (struct sockaddr_in *)pai->ai_addr; 95 if (pai->ai_addr) { 96 err |= psin->sin_family != AF_INET; 97 err |= psin->sin_port != 0; 98 } 99 if (err) 100 break; 101 } 102 if (err) { 103 tst_resm(TFAIL, "getaddrinfo IPv4 basic lookup: " 104 "fam %d alen %d addr 0x%p addr/fam %d " 105 "addr/port %d H[%d]", 106 pai->ai_family, pai->ai_addrlen, psin, 107 psin ? psin->sin_family : 0, 108 psin ? psin->sin_port : 0, 109 psin ? htons(psin->sin_port) : 0); 110 freeaddrinfo(aires); 111 return; 112 } 113 tst_resm(TPASS, "getaddrinfo IPv4 basic lookup"); 114 freeaddrinfo(aires); 115 } else { 116 tst_resm(TFAIL, "getaddrinfo IPv4 basic " 117 "lookup (\"%s\") returns %ld (\"%s\")", hostname, 118 TEST_RETURN, gai_strerror(TEST_RETURN)); 119 return; 120 } 121 122 /* test 2, IPv4 canonical name */ 123 memset(&hints, 0, sizeof(hints)); 124 hints.ai_family = AF_INET; 125 hints.ai_flags = AI_CANONNAME; 126 TEST(getaddrinfo(shortname, 0, &hints, &aires)); 127 if (!TEST_RETURN) { 128 for (pai = aires; pai; pai = pai->ai_next) 129 if (pai->ai_canonname) 130 break; 131 if (!pai) { 132 tst_resm(TFAIL, "getaddrinfo IPv4 canonical name: no " 133 "entries with canonical name set"); 134 freeaddrinfo(aires); 135 return; 136 } else if (strcasecmp(hostname, pai->ai_canonname)) { 137 tst_resm(TFAIL, "getaddrinfo IPv4 canonical name " 138 "(\"%s\") doesn't match hostname (\"%s\")", 139 pai->ai_canonname, hostname); 140 freeaddrinfo(aires); 141 return; 142 } 143 tst_resm(TPASS, "getaddrinfo IPv4 canonical name"); 144 freeaddrinfo(aires); 145 } else { 146 tst_resm(TFAIL, "getaddrinfo IPv4 " 147 "canonical name (\"%s\") returns %ld (\"%s\")", 148 shortname, TEST_RETURN, gai_strerror(TEST_RETURN)); 149 return; 150 } 151 152 /* test 3, IPv4 host+service name */ 153 memset(&hints, 0, sizeof(hints)); 154 /* 155 * These are hard-coded for echo/7 to avoid using getservbyname(), 156 * since it isn't thread-safe and these tests may be re-used 157 * multithreaded. Sigh. 158 */ 159 strcpy(service, "echo"); 160 servnum = 7; 161 hints.ai_family = AF_INET; 162 TEST(getaddrinfo(hostname, service, &hints, &aires)); 163 if (!TEST_RETURN) { 164 struct sockaddr_in *psin = 0; 165 int err = 0; 166 167 for (pai = aires; pai; pai = pai->ai_next) { 168 err |= pai->ai_family != AF_INET; 169 err |= pai->ai_addrlen != sizeof(struct sockaddr_in); 170 err |= pai->ai_addr == 0; 171 psin = (struct sockaddr_in *)pai->ai_addr; 172 if (pai->ai_addr) { 173 err |= psin->sin_family != AF_INET; 174 err |= psin->sin_port != htons(servnum); 175 } 176 if (err) 177 break; 178 } 179 if (err) { 180 tst_resm(TFAIL, "getaddrinfo IPv4 host+service: " 181 "fam %d alen %d addr 0x%p addr/fam %d " 182 "addr/port %d H[%d]", 183 pai->ai_family, pai->ai_addrlen, psin, 184 psin ? psin->sin_family : 0, 185 psin ? psin->sin_port : 0, 186 psin ? htons(psin->sin_port) : 0); 187 freeaddrinfo(aires); 188 return; 189 } 190 tst_resm(TPASS, "getaddrinfo IPv4 host+service"); 191 freeaddrinfo(aires); 192 } else { 193 tst_resm(TFAIL, "getaddrinfo IPv4 host+" 194 "service returns %ld (\"%s\")", TEST_RETURN, 195 gai_strerror(TEST_RETURN)); 196 return; 197 } 198 199 /* test 4, IPv4 hostname+service, AI_PASSIVE */ 200 memset(&hints, 0, sizeof(hints)); 201 hints.ai_family = AF_INET; 202 hints.ai_flags = AI_PASSIVE; 203 hints.ai_socktype = SOCK_STREAM; 204 strcpy(service, "9462"); 205 servnum = htons(9462); 206 TEST(getaddrinfo(hostname, service, &hints, &aires)); 207 if (!TEST_RETURN) { 208 struct sockaddr_in *psin = 0; 209 int err = 0; 210 211 for (pai = aires; pai; pai = pai->ai_next) { 212 err |= pai->ai_family != AF_INET; 213 err |= pai->ai_addrlen != sizeof(struct sockaddr_in); 214 err |= pai->ai_addr == 0; 215 psin = (struct sockaddr_in *)pai->ai_addr; 216 if (pai->ai_addr) { 217 /* AI_PASSIVE is ignored if hostname is 218 * non-null; address must be set 219 */ 220 err |= psin->sin_addr.s_addr == 0; 221 err |= psin->sin_family != AF_INET; 222 err |= psin->sin_port != servnum; 223 } 224 if (err) 225 break; 226 } 227 if (err) { 228 tst_resm(TFAIL, "getaddrinfo IPv4 host+service, PASSIVE" 229 ": fam %d alen %d addr 0x%p addr/fam %d " 230 "addr/port %d H[%d]", 231 pai->ai_family, pai->ai_addrlen, psin, 232 psin ? psin->sin_family : 0, 233 psin ? psin->sin_port : 0, 234 psin ? htons(psin->sin_port) : 0); 235 freeaddrinfo(aires); 236 return; 237 } 238 tst_resm(TPASS, "getaddrinfo IPv4 host+service PASSIVE"); 239 freeaddrinfo(aires); 240 } else { 241 tst_resm(TFAIL, "getaddrinfo IPv4 host+" 242 "service, PASSIVE (\"%s\", \"%s\") returns %ld (\"%s\")", 243 hostname, service, TEST_RETURN, 244 gai_strerror(TEST_RETURN)); 245 return; 246 } 247 248 /* test 5, IPv4 host+service w/ AI_NUMERICHOST */ 249 memset(&hints, 0, sizeof(hints)); 250 strcpy(service, "echo"); 251 servnum = 7; 252 hints.ai_family = AF_INET; 253 hints.ai_flags = AI_NUMERICHOST; 254 TEST(getaddrinfo(hostname, service, &hints, &aires)); 255 if (TEST_RETURN != EAI_NONAME) { 256 tst_resm(TFAIL, "getaddrinfo IPv4 AI_NUMERICHOST w/ hostname: " 257 "returns %ld expected %d (EAI_NONAME)", 258 TEST_RETURN, EAI_NONAME); 259 if (!TEST_RETURN) 260 freeaddrinfo(aires); 261 return; 262 } 263 tst_resm(TPASS, "getaddrinfo IPv4 AI_NUMERICHOST w/ hostname"); 264 if (!TEST_RETURN) 265 freeaddrinfo(aires); 266 267 /* test 6, IPv4 0+service, AI_PASSIVE */ 268 memset(&hints, 0, sizeof(hints)); 269 hints.ai_family = AF_INET; 270 hints.ai_flags = AI_PASSIVE; 271 hints.ai_socktype = SOCK_STREAM; 272 strcpy(service, "9462"); 273 servnum = htons(9462); 274 TEST(getaddrinfo(0, service, &hints, &aires)); 275 if (!TEST_RETURN) { 276 struct sockaddr_in *psin = 0; 277 int err = 0; 278 279 for (pai = aires; pai; pai = pai->ai_next) { 280 err |= pai->ai_family != AF_INET; 281 err |= pai->ai_addrlen != sizeof(struct sockaddr_in); 282 err |= pai->ai_addr == 0; 283 psin = (struct sockaddr_in *)pai->ai_addr; 284 if (pai->ai_addr) { 285 286 /* AI_PASSIVE means addr must be INADDR_ANY */ 287 err |= psin->sin_addr.s_addr != 0; 288 err |= psin->sin_family != AF_INET; 289 err |= psin->sin_port != servnum; 290 } 291 if (err) 292 break; 293 } 294 if (err) { 295 tst_resm(TFAIL, "getaddrinfo IPv4 0+service, PASSIVE:" 296 " fam %d alen %d addr 0x%p addr/fam %d " 297 "addr/port %d H[%d]", 298 pai->ai_family, pai->ai_addrlen, psin, 299 psin ? psin->sin_family : 0, 300 psin ? psin->sin_port : 0, 301 psin ? htons(psin->sin_port) : 0); 302 freeaddrinfo(aires); 303 return; 304 } 305 tst_resm(TPASS, "getaddrinfo IPv4 0+service, PASSIVE"); 306 freeaddrinfo(aires); 307 } else { 308 if (TEST_RETURN == EAI_BADFLAGS) { 309 tst_resm(TPASS, "getaddrinfo IPv4 0+service," 310 " PASSIVE (\"\", \"%s\") returns %ld (\"%s\")", 311 service, TEST_RETURN, 312 gai_strerror(TEST_RETURN)); 313 } else { 314 tst_resm(TFAIL, "getaddrinfo IPv4 0+service," 315 " PASSIVE (\"\", \"%s\") returns %ld (\"%s\")", 316 service, TEST_RETURN, 317 gai_strerror(TEST_RETURN)); 318 return; 319 } 320 } 321 322 /* test 7, IPv4 0+service */ 323 memset(&hints, 0, sizeof(hints)); 324 hints.ai_family = AF_INET; 325 hints.ai_socktype = SOCK_STREAM; 326 strcpy(service, "9462"); 327 servnum = htons(9462); 328 TEST(getaddrinfo(0, service, &hints, &aires)); 329 if (!TEST_RETURN) { 330 struct sockaddr_in *psin = 0; 331 int err = 0; 332 333 for (pai = aires; pai; pai = pai->ai_next) { 334 err |= pai->ai_family != AF_INET; 335 err |= pai->ai_addrlen != sizeof(struct sockaddr_in); 336 err |= pai->ai_addr == 0; 337 psin = (struct sockaddr_in *)pai->ai_addr; 338 if (pai->ai_addr) { 339 /* hostname not set; addr should be loopback */ 340 err |= psin->sin_addr.s_addr != 341 htonl(INADDR_LOOPBACK); 342 err |= psin->sin_family != AF_INET; 343 err |= psin->sin_port != servnum; 344 } 345 if (err) 346 break; 347 } 348 if (err) { 349 tst_resm(TFAIL, "getaddrinfo IPv4 0+service: " 350 "fam %d alen %d addr 0x%p addr/fam %d " 351 "addr/port %d H[%d]", 352 pai->ai_family, pai->ai_addrlen, psin, 353 psin ? psin->sin_family : 0, 354 psin ? psin->sin_port : 0, 355 psin ? htons(psin->sin_port) : 0); 356 freeaddrinfo(aires); 357 return; 358 } 359 tst_resm(TPASS, "getaddrinfo IPv4 0+service"); 360 freeaddrinfo(aires); 361 } else { 362 if (TEST_RETURN == EAI_BADFLAGS) { 363 tst_resm(TPASS, "getaddrinfo IPv4 " 364 "0+service (\"\", \"%s\") returns %ld (\"%s\")", 365 service, TEST_RETURN, 366 gai_strerror(TEST_RETURN)); 367 } else { 368 tst_resm(TFAIL, "getaddrinfo IPv4 " 369 "0+service (\"\", \"%s\") returns %ld (\"%s\")", 370 service, TEST_RETURN, 371 gai_strerror(TEST_RETURN)); 372 return; 373 } 374 } 375 376 /* test 8, IPv4 host+service, AI_NUMERICSERV */ 377 #ifndef AI_NUMERICSERV 378 tst_resm(TCONF, "getaddrinfo IPv4 host+service, AI_NUMERICSERV: flag " 379 "not implemented"); 380 #else 381 memset(&hints, 0, sizeof(hints)); 382 strcpy(service, "echo"); 383 servnum = 7; 384 hints.ai_family = AF_INET; 385 hints.ai_flags = AI_NUMERICSERV; 386 TEST(getaddrinfo(hostname, service, &hints, &aires)); 387 if (TEST_RETURN != EAI_NONAME) { 388 tst_resm(TFAIL, 389 "getaddrinfo IPv4 host+service, AI_NUMERICSERV: " 390 "returns %ld (\"%s\") expected %d (EAI_NONAME)", 391 TEST_RETURN, gai_strerror(TEST_RETURN), EAI_NONAME); 392 if (!TEST_RETURN) 393 freeaddrinfo(aires); 394 return; 395 } 396 tst_resm(TPASS, "getaddrinfo IPv4 host+service, AI_NUMERICSERV"); 397 if (!TEST_RETURN) 398 freeaddrinfo(aires); 399 #endif /* AI_NUMERICSERV */ 400 401 /* test 9, IPv4 SOCK_STREAM/IPPROTO_UDP hints */ 402 memset(&hints, 0, sizeof(hints)); 403 hints.ai_family = AF_INET; 404 hints.ai_socktype = SOCK_STREAM; 405 hints.ai_protocol = IPPROTO_UDP; 406 strcpy(service, "9462"); 407 servnum = htons(9462); 408 TEST(getaddrinfo(0, service, &hints, &aires)); 409 if (!TEST_RETURN) { 410 tst_resm(TFAIL, "getaddrinfo IPv4 SOCK_STREAM/IPPROTO_UDP " 411 "hints"); 412 freeaddrinfo(aires); 413 return; 414 } 415 tst_resm(TPASS, "getaddrinfo IPv4 SOCK_STREAM/IPPROTO_UDP hints"); 416 417 /* test 10, IPv4 socktype 0, 513 */ 418 memset(&hints, 0, sizeof(hints)); 419 hints.ai_family = AF_INET; 420 hints.ai_socktype = 0; 421 strcpy(service, "513"); 422 servnum = htons(513); 423 TEST(getaddrinfo(0, service, &hints, &aires)); 424 if (!TEST_RETURN) { 425 struct sockaddr_in *psin = 0; 426 int got_tcp, got_udp; 427 int err = 0; 428 429 got_tcp = got_udp = 0; 430 for (pai = aires; pai; pai = pai->ai_next) { 431 err |= pai->ai_family != AF_INET; 432 err |= pai->ai_addrlen != sizeof(struct sockaddr_in); 433 err |= pai->ai_addr == 0; 434 got_tcp |= pai->ai_socktype == SOCK_STREAM; 435 got_udp |= pai->ai_socktype == SOCK_DGRAM; 436 psin = (struct sockaddr_in *)pai->ai_addr; 437 if (pai->ai_addr) { 438 /* hostname not set; addr should be loopback */ 439 err |= psin->sin_addr.s_addr != 440 htonl(INADDR_LOOPBACK); 441 err |= psin->sin_family != AF_INET; 442 err |= psin->sin_port != servnum; 443 } 444 if (err) 445 break; 446 } 447 if (err) { 448 tst_resm(TFAIL, "getaddrinfo IPv4 socktype 0,513: " 449 "fam %d alen %d addr 0x%p addr/fam %d " 450 "addr/port %d H[%d]", 451 pai->ai_family, pai->ai_addrlen, psin, 452 psin ? psin->sin_family : 0, 453 psin ? psin->sin_port : 0, 454 psin ? htons(psin->sin_port) : 0); 455 freeaddrinfo(aires); 456 return; 457 } else if (got_tcp && got_udp) { 458 tst_resm(TPASS, "getaddrinfo IPv4 socktype 0,513"); 459 freeaddrinfo(aires); 460 } else { 461 tst_resm(TFAIL, "getaddrinfo IPv4 socktype 0,513 TCP %d" 462 " UDP %d", got_tcp, got_udp); 463 freeaddrinfo(aires); 464 return; 465 } 466 } else { 467 if (TEST_RETURN == EAI_BADFLAGS) { 468 tst_resm(TPASS, "getaddrinfo IPv4 socktype 0,513" 469 " (\"\", \"%s\") returns %ld (\"%s\")", service, 470 TEST_RETURN, gai_strerror(TEST_RETURN)); 471 } else { 472 tst_resm(TFAIL, "getaddrinfo IPv4 socktype 0,513" 473 " (\"\", \"%s\") returns %ld (\"%s\")", service, 474 TEST_RETURN, gai_strerror(TEST_RETURN)); 475 return; 476 } 477 } 478 479 /* test 11, IPv4 AI_V4MAPPED */ 480 /* AI_V4MAPPED should be ignored because family != AF_INET6 */ 481 memset(&hints, 0, sizeof(hints)); 482 hints.ai_family = AF_INET; 483 hints.ai_flags = AI_V4MAPPED; 484 TEST(getaddrinfo(hostname, 0, &hints, &aires)); 485 if (!TEST_RETURN) { 486 struct sockaddr_in *psin = 0; 487 int err = 0; 488 489 for (pai = aires; pai; pai = pai->ai_next) { 490 err |= pai->ai_family != AF_INET; 491 err |= pai->ai_addrlen != sizeof(struct sockaddr_in); 492 err |= pai->ai_addr == 0; 493 psin = (struct sockaddr_in *)pai->ai_addr; 494 if (pai->ai_addr) { 495 err |= psin->sin_family != AF_INET; 496 err |= psin->sin_port != 0; 497 } 498 if (err) 499 break; 500 } 501 if (err) { 502 tst_resm(TFAIL, "getaddrinfo IPv4 AI_V4MAPPED: " 503 "fam %d alen %d addr 0x%p addr/fam %d " 504 "addr/port %d H[%d]", 505 pai->ai_family, pai->ai_addrlen, psin, 506 psin ? psin->sin_family : 0, 507 psin ? psin->sin_port : 0, 508 psin ? htons(psin->sin_port) : 0); 509 freeaddrinfo(aires); 510 return; 511 } 512 tst_resm(TPASS, "getaddrinfo IPv4 AI_V4MAPPED"); 513 freeaddrinfo(aires); 514 } else { 515 tst_resm(TFAIL, "getaddrinfo IPv4 " 516 "AI_V4MAPPED (\"%s\") returns %ld (\"%s\")", hostname, 517 TEST_RETURN, gai_strerror(TEST_RETURN)); 518 return; 519 } 520 } 521 522 /* getaddrinfo tests (v6) */ 523 static void gaiv6(void) 524 { 525 struct addrinfo *aires, hints, *pai; 526 char hostname[MAXHOSTNAMELEN + 1]; 527 char shortname[MAXHOSTNAMELEN + 1]; 528 char service[NI_MAXSERV + 1]; 529 int servnum; 530 char *p; 531 532 if (gethostname(hostname, sizeof(hostname)) < 0) 533 tst_brkm(TBROK, NULL, "gethostname failed - %s", 534 strerror(errno)); 535 strncpy(shortname, hostname, MAXHOSTNAMELEN); 536 shortname[MAXHOSTNAMELEN] = '\0'; 537 p = strchr(shortname, '.'); 538 if (p) 539 *p = '\0'; 540 541 /* test 12, IPv6 basic lookup */ 542 memset(&hints, 0, sizeof(hints)); 543 hints.ai_family = AF_INET6; 544 TEST(getaddrinfo(hostname, 0, &hints, &aires)); 545 if (!TEST_RETURN) { 546 struct sockaddr_in6 *psin6 = 0; 547 int err = 0; 548 549 for (pai = aires; pai; pai = pai->ai_next) { 550 err |= pai->ai_family != AF_INET6; 551 err |= pai->ai_addrlen != sizeof(struct sockaddr_in6); 552 err |= pai->ai_addr == 0; 553 psin6 = (struct sockaddr_in6 *)pai->ai_addr; 554 if (pai->ai_addr) { 555 err |= psin6->sin6_family != AF_INET6; 556 err |= psin6->sin6_port != 0; 557 } 558 if (err) 559 break; 560 } 561 if (err) { 562 tst_resm(TFAIL, "getaddrinfo IPv6 basic lookup: " 563 "fam %d alen %d addr 0x%p addr/fam %d " 564 "addr/port %d H[%d]", 565 pai->ai_family, pai->ai_addrlen, psin6, 566 psin6 ? psin6->sin6_family : 0, 567 psin6 ? psin6->sin6_port : 0, 568 psin6 ? htons(psin6->sin6_port) : 0); 569 freeaddrinfo(aires); 570 return; 571 } 572 tst_resm(TPASS, "getaddrinfo IPv6 basic lookup"); 573 freeaddrinfo(aires); 574 } else { 575 tst_resm(TFAIL, "getaddrinfo IPv6 basic " 576 "lookup (\"%s\") returns %ld (\"%s\")", hostname, 577 TEST_RETURN, gai_strerror(TEST_RETURN)); 578 return; 579 } 580 581 /* test 13, IPv6 canonical name */ 582 memset(&hints, 0, sizeof(hints)); 583 hints.ai_family = AF_INET6; 584 hints.ai_flags = AI_CANONNAME; 585 TEST(getaddrinfo(shortname, 0, &hints, &aires)); 586 if (!TEST_RETURN) { 587 for (pai = aires; pai; pai = pai->ai_next) 588 if (pai->ai_canonname) 589 break; 590 if (!pai) { 591 tst_resm(TFAIL, "getaddrinfo IPv6 canonical name: no " 592 "entries with canonical name set"); 593 freeaddrinfo(aires); 594 return; 595 } else if (strcasecmp(hostname, pai->ai_canonname)) { 596 tst_resm(TFAIL, "getaddrinfo IPv6 canonical name " 597 "(\"%s\") doesn't match hostname (\"%s\")", 598 pai->ai_canonname, hostname); 599 freeaddrinfo(aires); 600 return; 601 } 602 tst_resm(TPASS, "getaddrinfo IPv6 canonical name"); 603 freeaddrinfo(aires); 604 } else { 605 tst_resm(TFAIL, "getaddrinfo IPv6 " 606 "canonical name (\"%s\") returns %ld (\"%s\")", 607 shortname, TEST_RETURN, gai_strerror(TEST_RETURN)); 608 return; 609 } 610 611 /* test 14, IPv6 host+service name */ 612 memset(&hints, 0, sizeof(hints)); 613 /* 614 * These are hard-coded for echo/7 to avoid using getservbyname(), 615 * since it isn't thread-safe and these tests may be re-used 616 * multithreaded. Sigh. 617 */ 618 strcpy(service, "echo"); 619 servnum = 7; 620 hints.ai_family = AF_INET6; 621 TEST(getaddrinfo(hostname, service, &hints, &aires)); 622 if (!TEST_RETURN) { 623 struct sockaddr_in6 *psin6 = 0; 624 int err = 0; 625 626 for (pai = aires; pai; pai = pai->ai_next) { 627 err |= pai->ai_family != AF_INET6; 628 err |= pai->ai_addrlen != sizeof(struct sockaddr_in6); 629 err |= pai->ai_addr == 0; 630 psin6 = (struct sockaddr_in6 *)pai->ai_addr; 631 if (pai->ai_addr) { 632 err |= psin6->sin6_family != AF_INET6; 633 err |= psin6->sin6_port != htons(servnum); 634 } 635 if (err) 636 break; 637 } 638 if (err) { 639 tst_resm(TFAIL, "getaddrinfo IPv6 host+service: " 640 "fam %d alen %d addr 0x%p addr/fam %d " 641 "addr/port %d H[%d]", 642 pai->ai_family, pai->ai_addrlen, psin6, 643 psin6 ? psin6->sin6_family : 0, 644 psin6 ? psin6->sin6_port : 0, 645 psin6 ? htons(psin6->sin6_port) : 0); 646 freeaddrinfo(aires); 647 return; 648 } 649 tst_resm(TPASS, "getaddrinfo IPv6 host+service"); 650 freeaddrinfo(aires); 651 } else { 652 tst_resm(TFAIL, "getaddrinfo IPv6 host+" 653 "service returns %ld (\"%s\")", TEST_RETURN, 654 gai_strerror(TEST_RETURN)); 655 return; 656 } 657 658 /* test 15, IPv6 hostname+service, AI_PASSIVE */ 659 memset(&hints, 0, sizeof(hints)); 660 hints.ai_family = AF_INET6; 661 hints.ai_flags = AI_PASSIVE; 662 hints.ai_socktype = SOCK_STREAM; 663 strcpy(service, "9462"); 664 servnum = htons(9462); 665 TEST(getaddrinfo(hostname, service, &hints, &aires)); 666 if (!TEST_RETURN) { 667 struct sockaddr_in6 *psin6 = 0; 668 int err = 0; 669 670 for (pai = aires; pai; pai = pai->ai_next) { 671 err |= pai->ai_family != AF_INET6; 672 err |= pai->ai_addrlen != sizeof(struct sockaddr_in6); 673 err |= pai->ai_addr == 0; 674 psin6 = (struct sockaddr_in6 *)pai->ai_addr; 675 if (pai->ai_addr) { 676 /* AI_PASSIVE is ignored if hostname is 677 * non-null; address must be set 678 */ 679 err |= memcmp(&psin6->sin6_addr, &in6addr_any, 680 sizeof(struct in6_addr)) == 0; 681 err |= psin6->sin6_family != AF_INET6; 682 err |= psin6->sin6_port != servnum; 683 } 684 if (err) 685 break; 686 } 687 if (err) { 688 tst_resm(TFAIL, "getaddrinfo IPv6 host+service, PASSIVE" 689 ": fam %d alen %d addr 0x%p addr/fam %d " 690 "addr/port %d H[%d]", 691 pai->ai_family, pai->ai_addrlen, psin6, 692 psin6 ? psin6->sin6_family : 0, 693 psin6 ? psin6->sin6_port : 0, 694 psin6 ? htons(psin6->sin6_port) : 0); 695 freeaddrinfo(aires); 696 return; 697 } 698 tst_resm(TPASS, "getaddrinfo IPv6 host+service PASSIVE"); 699 freeaddrinfo(aires); 700 } else { 701 tst_resm(TFAIL, "getaddrinfo IPv6 host+" 702 "service, PASSIVE (\"%s\", \"%s\") returns %ld (\"%s\")", 703 hostname, service, TEST_RETURN, 704 gai_strerror(TEST_RETURN)); 705 return; 706 } 707 708 /* test 16, IPv6 host+service w/ AI_NUMERICHOST */ 709 memset(&hints, 0, sizeof(hints)); 710 strcpy(service, "echo"); 711 servnum = 7; 712 hints.ai_family = AF_INET6; 713 hints.ai_flags = AI_NUMERICHOST; 714 TEST(getaddrinfo(hostname, service, &hints, &aires)); 715 if (TEST_RETURN != EAI_NONAME) { 716 tst_resm(TFAIL, "getaddrinfo IPv6 AI_NUMERICHOST w/ hostname: " 717 "returns %ld expected %d (EAI_NONAME)", 718 TEST_RETURN, EAI_NONAME); 719 if (!TEST_RETURN) 720 freeaddrinfo(aires); 721 return; 722 } 723 tst_resm(TPASS, "getaddrinfo IPv6 AI_NUMERICHOST w/ hostname"); 724 if (!TEST_RETURN) 725 freeaddrinfo(aires); 726 727 /* test 17, IPv6 0+service, AI_PASSIVE */ 728 memset(&hints, 0, sizeof(hints)); 729 hints.ai_family = AF_INET6; 730 hints.ai_flags = AI_PASSIVE; 731 hints.ai_socktype = SOCK_STREAM; 732 strcpy(service, "9462"); 733 servnum = htons(9462); 734 TEST(getaddrinfo(0, service, &hints, &aires)); 735 if (!TEST_RETURN) { 736 struct sockaddr_in6 *psin6 = 0; 737 int err = 0; 738 739 for (pai = aires; pai; pai = pai->ai_next) { 740 err |= pai->ai_family != AF_INET6; 741 err |= pai->ai_addrlen != sizeof(struct sockaddr_in6); 742 err |= pai->ai_addr == 0; 743 psin6 = (struct sockaddr_in6 *)pai->ai_addr; 744 if (pai->ai_addr) { 745 746 /* AI_PASSIVE means addr must be INADDR_ANY */ 747 err |= memcmp(&psin6->sin6_addr, &in6addr_any, 748 sizeof(struct in6_addr)) != 0; 749 err |= psin6->sin6_family != AF_INET6; 750 err |= psin6->sin6_port != servnum; 751 } 752 if (err) 753 break; 754 } 755 if (err) { 756 tst_resm(TFAIL, "getaddrinfo IPv6 0+service, PASSIVE:" 757 " fam %d alen %d addr 0x%p addr/fam %d " 758 "addr/port %d H[%d]", 759 pai->ai_family, pai->ai_addrlen, psin6, 760 psin6 ? psin6->sin6_family : 0, 761 psin6 ? psin6->sin6_port : 0, 762 psin6 ? htons(psin6->sin6_port) : 0); 763 freeaddrinfo(aires); 764 return; 765 } 766 tst_resm(TPASS, "getaddrinfo IPv6 0+service, PASSIVE"); 767 freeaddrinfo(aires); 768 } else { 769 if (TEST_RETURN == EAI_BADFLAGS) { 770 tst_resm(TPASS, "getaddrinfo IPv6 0+service, PASSIVE" 771 " (\"\", \"%s\") returns %ld (\"%s\")", service, 772 TEST_RETURN, gai_strerror(TEST_RETURN)); 773 } else { 774 tst_resm(TFAIL, "getaddrinfo IPv6 0+service, PASSIVE" 775 " (\"\", \"%s\") returns %ld (\"%s\")", service, 776 TEST_RETURN, gai_strerror(TEST_RETURN)); 777 return; 778 } 779 } 780 781 /* test 18, IPv6 0+service */ 782 memset(&hints, 0, sizeof(hints)); 783 hints.ai_family = AF_INET6; 784 hints.ai_socktype = SOCK_STREAM; 785 strcpy(service, "9462"); 786 servnum = htons(9462); 787 TEST(getaddrinfo(0, service, &hints, &aires)); 788 if (!TEST_RETURN) { 789 struct sockaddr_in6 *psin6 = 0; 790 int err = 0; 791 792 for (pai = aires; pai; pai = pai->ai_next) { 793 err |= pai->ai_family != AF_INET6; 794 err |= pai->ai_addrlen != sizeof(struct sockaddr_in6); 795 err |= pai->ai_addr == 0; 796 psin6 = (struct sockaddr_in6 *)pai->ai_addr; 797 if (pai->ai_addr) { 798 /* hostname not set; addr should be loopback */ 799 err |= memcmp(&psin6->sin6_addr, 800 &in6addr_loopback, 801 sizeof(struct in6_addr)) != 0; 802 err |= psin6->sin6_family != AF_INET6; 803 err |= psin6->sin6_port != servnum; 804 } 805 if (err) 806 break; 807 } 808 if (err) { 809 tst_resm(TFAIL, "getaddrinfo IPv6 0+service: " 810 "fam %d alen %d addr 0x%p addr/fam %d " 811 "addr/port %d H[%d]", 812 pai->ai_family, pai->ai_addrlen, psin6, 813 psin6 ? psin6->sin6_family : 0, 814 psin6 ? psin6->sin6_port : 0, 815 psin6 ? htons(psin6->sin6_port) : 0); 816 freeaddrinfo(aires); 817 return; 818 } 819 tst_resm(TPASS, "getaddrinfo IPv6 0+service"); 820 freeaddrinfo(aires); 821 } else { 822 if (TEST_RETURN == EAI_BADFLAGS) { 823 tst_resm(TPASS, "getaddrinfo IPv6 0+service" 824 " (\"\", \"%s\") returns %ld (\"%s\")", service, 825 TEST_RETURN, gai_strerror(TEST_RETURN)); 826 } else { 827 tst_resm(TFAIL, "getaddrinfo IPv6 0+service" 828 " (\"\", \"%s\") returns %ld (\"%s\")", service, 829 TEST_RETURN, gai_strerror(TEST_RETURN)); 830 return; 831 } 832 } 833 834 /* test 19, IPv6 host+service, AI_NUMERICSERV */ 835 #ifndef AI_NUMERICSERV 836 tst_resm(TCONF, "getaddrinfo IPv6 host+service, AI_NUMERICSERV: flag " 837 "not implemented"); 838 #else 839 memset(&hints, 0, sizeof(hints)); 840 strcpy(service, "echo"); 841 servnum = 7; 842 hints.ai_family = AF_INET6; 843 hints.ai_flags = AI_NUMERICSERV; 844 TEST(getaddrinfo(hostname, service, &hints, &aires)); 845 if (TEST_RETURN != EAI_NONAME) { 846 tst_resm(TFAIL, 847 "getaddrinfo IPv6 host+service, AI_NUMERICSERV: " 848 "returns %ld (\"%s\") expected %d (EAI_NONAME)", 849 TEST_RETURN, gai_strerror(TEST_RETURN), EAI_NONAME); 850 if (!TEST_RETURN) 851 freeaddrinfo(aires); 852 return; 853 } 854 tst_resm(TPASS, "getaddrinfo IPv6 host+service, AI_NUMERICSERV"); 855 if (!TEST_RETURN) 856 freeaddrinfo(aires); 857 #endif /* AI_NUMERICSERV */ 858 859 /* test 20, IPv6 SOCK_STREAM/IPPROTO_UDP hints */ 860 memset(&hints, 0, sizeof(hints)); 861 hints.ai_family = AF_INET6; 862 hints.ai_socktype = SOCK_STREAM; 863 hints.ai_protocol = IPPROTO_UDP; 864 strcpy(service, "9462"); 865 servnum = htons(9462); 866 TEST(getaddrinfo(0, service, &hints, &aires)); 867 if (!TEST_RETURN) { 868 tst_resm(TFAIL, "getaddrinfo IPv6 SOCK_STREAM/IPPROTO_UDP " 869 "hints"); 870 freeaddrinfo(aires); 871 return; 872 } 873 tst_resm(TPASS, "getaddrinfo IPv6 SOCK_STREAM/IPPROTO_UDP hints"); 874 875 /* test 21, IPv6 socktype 0, 513 */ 876 memset(&hints, 0, sizeof(hints)); 877 hints.ai_family = AF_INET6; 878 hints.ai_socktype = 0; 879 strcpy(service, "513"); 880 servnum = htons(513); 881 TEST(getaddrinfo(0, service, &hints, &aires)); 882 if (!TEST_RETURN) { 883 struct sockaddr_in6 *psin6 = 0; 884 int got_tcp, got_udp; 885 int err = 0; 886 887 got_tcp = got_udp = 0; 888 for (pai = aires; pai; pai = pai->ai_next) { 889 err |= pai->ai_family != AF_INET6; 890 err |= pai->ai_addrlen != sizeof(struct sockaddr_in6); 891 err |= pai->ai_addr == 0; 892 got_tcp |= pai->ai_socktype == SOCK_STREAM; 893 got_udp |= pai->ai_socktype == SOCK_DGRAM; 894 psin6 = (struct sockaddr_in6 *)pai->ai_addr; 895 if (pai->ai_addr) { 896 /* hostname not set; addr should be loopback */ 897 err |= memcmp(&psin6->sin6_addr, 898 &in6addr_loopback, 899 sizeof(struct in6_addr)) != 0; 900 err |= psin6->sin6_family != AF_INET6; 901 err |= psin6->sin6_port != servnum; 902 } 903 if (err) 904 break; 905 } 906 if (err) { 907 tst_resm(TFAIL, "getaddrinfo IPv6 socktype 0,513: " 908 "fam %d alen %d addr 0x%p addr/fam %d " 909 "addr/port %d H[%d]", 910 pai->ai_family, pai->ai_addrlen, psin6, 911 psin6 ? psin6->sin6_family : 0, 912 psin6 ? psin6->sin6_port : 0, 913 psin6 ? htons(psin6->sin6_port) : 0); 914 freeaddrinfo(aires); 915 return; 916 } else if (got_tcp && got_udp) { 917 tst_resm(TPASS, "getaddrinfo IPv6 socktype 0,513"); 918 freeaddrinfo(aires); 919 } else { 920 tst_resm(TFAIL, "getaddrinfo IPv6 socktype 0,513 TCP %d" 921 " UDP %d", got_tcp, got_udp); 922 freeaddrinfo(aires); 923 return; 924 } 925 } else { 926 if (TEST_RETURN == EAI_BADFLAGS) { 927 tst_resm(TPASS, "getaddrinfo IPv6 socktype 0,513" 928 " (\"\", \"%s\") returns %ld (\"%s\")", service, 929 TEST_RETURN, gai_strerror(TEST_RETURN)); 930 } else { 931 tst_resm(TFAIL, "getaddrinfo IPv6 socktype 0,513" 932 " (\"\", \"%s\") returns %ld (\"%s\")", service, 933 TEST_RETURN, gai_strerror(TEST_RETURN)); 934 return; 935 } 936 } 937 938 /* test 22, IPv6 AI_V4MAPPED */ 939 memset(&hints, 0, sizeof(hints)); 940 hints.ai_family = AF_INET6; 941 hints.ai_flags = AI_V4MAPPED; 942 TEST(getaddrinfo(hostname, 0, &hints, &aires)); 943 if (!TEST_RETURN) { 944 struct sockaddr_in6 *psin6 = 0; 945 int err = 0; 946 947 for (pai = aires; pai; pai = pai->ai_next) { 948 err |= pai->ai_family != AF_INET6; 949 err |= pai->ai_addrlen != sizeof(struct sockaddr_in6); 950 err |= pai->ai_addr == 0; 951 psin6 = (struct sockaddr_in6 *)pai->ai_addr; 952 if (pai->ai_addr) { 953 err |= psin6->sin6_family != AF_INET6; 954 err |= psin6->sin6_port != 0; 955 } 956 if (err) 957 break; 958 } 959 if (err) { 960 tst_resm(TFAIL, "getaddrinfo IPv6 AI_V4MAPPED: " 961 "fam %d alen %d addr 0x%p addr/fam %d " 962 "addr/port %d H[%d]", 963 pai->ai_family, pai->ai_addrlen, psin6, 964 psin6 ? psin6->sin6_family : 0, 965 psin6 ? psin6->sin6_port : 0, 966 psin6 ? htons(psin6->sin6_port) : 0); 967 freeaddrinfo(aires); 968 return; 969 } 970 tst_resm(TPASS, "getaddrinfo IPv6 AI_V4MAPPED"); 971 freeaddrinfo(aires); 972 } else { 973 tst_resm(TFAIL, "getaddrinfo IPv6 " 974 "AI_V4MAPPED (\"%s\") returns %ld (\"%s\")", hostname, 975 TEST_RETURN, gai_strerror(TEST_RETURN)); 976 return; 977 } 978 } 979