socktohost.c revision 293894
1130561Sobrien/* 2130561Sobrien * socktoa - return a numeric host name from a sockaddr_storage structure 3130561Sobrien */ 4130561Sobrien#include <config.h> 5130561Sobrien#include <sys/types.h> 6130561Sobrien#ifdef HAVE_SYS_SOCKET_H 7130561Sobrien#include <sys/socket.h> 8130561Sobrien#endif 9130561Sobrien#ifdef HAVE_NETINET_IN_H 10130561Sobrien#include <netinet/in.h> 11130561Sobrien#endif 12130561Sobrien 13130561Sobrien#include <arpa/inet.h> 14130561Sobrien 15130561Sobrien#include <stdio.h> 16130561Sobrien 17130561Sobrien#include "ntp_fp.h" 18218822Sdim#include "lib_strbuf.h" 19130561Sobrien#include "ntp_stdlib.h" 20130561Sobrien#include "ntp.h" 21130561Sobrien#include "ntp_debug.h" 22130561Sobrien 23130561Sobrien 24130561Sobrienconst char * 25130561Sobriensocktohost( 26130561Sobrien const sockaddr_u *sock 27130561Sobrien ) 28130561Sobrien{ 29130561Sobrien const char svc[] = "ntp"; 30130561Sobrien char * pbuf; 31130561Sobrien char * pliar; 32130561Sobrien int gni_flags; 33130561Sobrien struct addrinfo hints; 34130561Sobrien struct addrinfo * alist; 35130561Sobrien struct addrinfo * ai; 36130561Sobrien sockaddr_u addr; 37130561Sobrien size_t octets; 38130561Sobrien int a_info; 39130561Sobrien int saved_errno; 40130561Sobrien 41130561Sobrien saved_errno = socket_errno(); 42130561Sobrien 43130561Sobrien /* reverse the address to purported DNS name */ 44130561Sobrien LIB_GETBUF(pbuf); 45130561Sobrien gni_flags = NI_DGRAM | NI_NAMEREQD; 46130561Sobrien if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH, 47130561Sobrien NULL, 0, gni_flags)) { 48130561Sobrien errno = saved_errno; 49130561Sobrien return stoa(sock); /* use address */ 50130561Sobrien } 51130561Sobrien 52130561Sobrien TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf)); 53130561Sobrien 54130561Sobrien /* 55130561Sobrien * Resolve the reversed name and make sure the reversed address 56130561Sobrien * is among the results. 57130561Sobrien */ 58130561Sobrien ZERO(hints); 59130561Sobrien hints.ai_family = AF(sock); 60130561Sobrien hints.ai_protocol = IPPROTO_UDP; 61130561Sobrien hints.ai_socktype = SOCK_DGRAM; 62130561Sobrien hints.ai_flags = 0; 63130561Sobrien alist = NULL; 64130561Sobrien 65130561Sobrien a_info = getaddrinfo(pbuf, svc, &hints, &alist); 66130561Sobrien if (a_info == EAI_NONAME 67130561Sobrien#ifdef EAI_NODATA 68130561Sobrien || a_info == EAI_NODATA 69130561Sobrien#endif 70130561Sobrien ) { 71130561Sobrien hints.ai_flags = AI_CANONNAME; 72130561Sobrien#ifdef AI_ADDRCONFIG 73130561Sobrien hints.ai_flags |= AI_ADDRCONFIG; 74130561Sobrien#endif 75130561Sobrien a_info = getaddrinfo(pbuf, svc, &hints, &alist); 76130561Sobrien } 77130561Sobrien#ifdef AI_ADDRCONFIG 78130561Sobrien /* Some older implementations don't like AI_ADDRCONFIG. */ 79130561Sobrien if (a_info == EAI_BADFLAGS) { 80130561Sobrien hints.ai_flags &= ~AI_ADDRCONFIG; 81130561Sobrien a_info = getaddrinfo(pbuf, svc, &hints, &alist); 82130561Sobrien } 83130561Sobrien#endif 84130561Sobrien if (a_info) 85130561Sobrien goto forward_fail; 86130561Sobrien 87130561Sobrien INSIST(alist != NULL); 88130561Sobrien 89130561Sobrien for (ai = alist; ai != NULL; ai = ai->ai_next) { 90130561Sobrien /* 91130561Sobrien * Make a convenience sockaddr_u copy from ai->ai_addr 92130561Sobrien * because casting from sockaddr * to sockaddr_u * is 93130561Sobrien * risking alignment problems on platforms where 94130561Sobrien * sockaddr_u has stricter alignment than sockaddr, 95130561Sobrien * such as sparc. 96130561Sobrien */ 97130561Sobrien ZERO_SOCK(&addr); 98130561Sobrien octets = min(sizeof(addr), ai->ai_addrlen); 99130561Sobrien memcpy(&addr, ai->ai_addr, octets); 100130561Sobrien if (SOCK_EQ(sock, &addr)) 101130561Sobrien break; 102130561Sobrien } 103130561Sobrien freeaddrinfo(alist); 104130561Sobrien 105130561Sobrien if (ai != NULL) { 106130561Sobrien errno = saved_errno; 107130561Sobrien return pbuf; /* forward check passed */ 108130561Sobrien } 109130561Sobrien 110130561Sobrien forward_fail: 111130561Sobrien TRACE(1, ("%s forward check lookup fail: %s\n", pbuf, 112130561Sobrien gai_strerror(a_info))); 113130561Sobrien LIB_GETBUF(pliar); 114130561Sobrien snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf); 115130561Sobrien 116130561Sobrien errno = saved_errno; 117130561Sobrien return pliar; 118130561Sobrien} 119130561Sobrien