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