* Locate canonical hostname and its IP address. */
| 661 | * Locate canonical hostname and its IP address. |
| 662 | */ |
| 663 | static void lookup_hostname(struct hostinfo *hi) |
| 664 | { |
| 665 | if (!hi->hostname_lookup_done && hi->hostname.len) { |
| 666 | #ifndef NO_IPV6 |
| 667 | struct addrinfo hints; |
| 668 | struct addrinfo *ai; |
| 669 | int gai; |
| 670 | static char addrbuf[HOST_NAME_MAX + 1]; |
| 671 | |
| 672 | memset(&hints, 0, sizeof(hints)); |
| 673 | hints.ai_flags = AI_CANONNAME; |
| 674 | |
| 675 | gai = getaddrinfo(hi->hostname.buf, NULL, &hints, &ai); |
| 676 | if (!gai) { |
| 677 | void *addr; |
| 678 | |
| 679 | if (ai->ai_family == AF_INET) { |
| 680 | struct sockaddr_in *sa = (void *)ai->ai_addr; |
| 681 | addr = &sa->sin_addr; |
| 682 | } else if (ai->ai_family == AF_INET6) { |
| 683 | struct sockaddr_in6 *sa6 = (void *)ai->ai_addr; |
| 684 | addr = &sa6->sin6_addr; |
| 685 | } else { |
| 686 | die("unexpected address family: %d", |
| 687 | ai->ai_family); |
| 688 | } |
| 689 | |
| 690 | inet_ntop(ai->ai_family, addr, |
| 691 | addrbuf, sizeof(addrbuf)); |
| 692 | strbuf_addstr(&hi->ip_address, addrbuf); |
| 693 | |
| 694 | if (ai->ai_canonname) |
| 695 | sanitize_client(&hi->canon_hostname, |
| 696 | ai->ai_canonname); |
| 697 | else |
| 698 | strbuf_addbuf(&hi->canon_hostname, |
| 699 | &hi->ip_address); |
| 700 | |
| 701 | freeaddrinfo(ai); |
| 702 | } |
| 703 | #else |
| 704 | struct hostent *hent; |
| 705 | struct sockaddr_in sa; |
| 706 | char **ap; |
| 707 | static char addrbuf[HOST_NAME_MAX + 1]; |
| 708 | |
| 709 | hent = gethostbyname(hi->hostname.buf); |
| 710 | if (hent) { |
| 711 | ap = hent->h_addr_list; |
| 712 | memset(&sa, 0, sizeof sa); |
| 713 | sa.sin_family = hent->h_addrtype; |
| 714 | sa.sin_port = htons(0); |
| 715 | memcpy(&sa.sin_addr, *ap, hent->h_length); |
| 716 | |
| 717 | inet_ntop(hent->h_addrtype, &sa.sin_addr, |
| 718 | addrbuf, sizeof(addrbuf)); |
| 719 | |
| 720 | sanitize_client(&hi->canon_hostname, hent->h_name); |
no test coverage detected