/* * socktoa - return a numeric host name from a sockaddr_storage structure */ #include #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #include #include #include "ntp_fp.h" #include "ntp_stdlib.h" #include "ntp.h" #include "ntp_debug.h" const char * socktohost( const sockaddr_u *sock ) { const char svc[] = "ntp"; char * pbuf; char * pliar; int gni_flags; struct addrinfo hints; struct addrinfo * alist; struct addrinfo * ai; sockaddr_u addr; size_t octets; int a_info; int saved_errno; saved_errno = socket_errno(); /* reverse the address to purported DNS name */ LIB_GETBUF(pbuf); gni_flags = NI_DGRAM | NI_NAMEREQD; if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH, NULL, 0, gni_flags)) { errno = saved_errno; return stoa(sock); /* use address */ } TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf)); /* * Resolve the reversed name and make sure the reversed address * is among the results. */ ZERO(hints); hints.ai_family = AF(sock); hints.ai_protocol = IPPROTO_UDP; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = 0; alist = NULL; a_info = getaddrinfo(pbuf, svc, &hints, &alist); if (a_info == EAI_NONAME #ifdef EAI_NODATA || a_info == EAI_NODATA #endif ) { hints.ai_flags = AI_CANONNAME; #ifdef AI_ADDRCONFIG hints.ai_flags |= AI_ADDRCONFIG; #endif a_info = getaddrinfo(pbuf, svc, &hints, &alist); } #ifdef AI_ADDRCONFIG /* Some older implementations don't like AI_ADDRCONFIG. */ if (a_info == EAI_BADFLAGS) { hints.ai_flags &= ~AI_ADDRCONFIG; a_info = getaddrinfo(pbuf, svc, &hints, &alist); } #endif if (a_info) goto forward_fail; INSIST(alist != NULL); for (ai = alist; ai != NULL; ai = ai->ai_next) { /* * Make a convenience sockaddr_u copy from ai->ai_addr * because casting from sockaddr * to sockaddr_u * is * risking alignment problems on platforms where * sockaddr_u has stricter alignment than sockaddr, * such as sparc. */ ZERO_SOCK(&addr); octets = min(sizeof(addr), ai->ai_addrlen); memcpy(&addr, ai->ai_addr, octets); if (SOCK_EQ(sock, &addr)) break; } freeaddrinfo(alist); if (ai != NULL) { errno = saved_errno; return pbuf; /* forward check passed */ } forward_fail: TRACE(1, ("%s forward check lookup fail: %s\n", pbuf, gai_strerror(a_info))); LIB_GETBUF(pliar); snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf); errno = saved_errno; return pliar; }