1 /* 2 * socktoa - return a numeric host name from a sockaddr_storage structure 3 */ 4 #include <config.h> 5 #include <sys/types.h> 6 #ifdef HAVE_SYS_SOCKET_H 7 #include <sys/socket.h> 8 #endif 9 #ifdef HAVE_NETINET_IN_H 10 #include <netinet/in.h> 11 #endif 12 13 #include <arpa/inet.h> 14 15 #include <stdio.h> 16 17 #include "ntp_fp.h" 18 #include "lib_strbuf.h" 19 #include "ntp_stdlib.h" 20 #include "ntp.h" 21 #include "ntp_debug.h" 22 23 24 const char * 25 socktohost( 26 const sockaddr_u *sock 27 ) 28 { 29 const char svc[] = "ntp"; 30 char * pbuf; 31 char * pliar; 32 int gni_flags; 33 struct addrinfo hints; 34 struct addrinfo * alist; 35 struct addrinfo * ai; 36 sockaddr_u addr; 37 size_t octets; 38 int a_info; 39 40 /* reverse the address to purported DNS name */ 41 LIB_GETBUF(pbuf); 42 gni_flags = NI_DGRAM | NI_NAMEREQD; 43 if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH, 44 NULL, 0, gni_flags)) 45 return stoa(sock); /* use address */ 46 47 TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf)); 48 49 /* 50 * Resolve the reversed name and make sure the reversed address 51 * is among the results. 52 */ 53 ZERO(hints); 54 hints.ai_family = AF(sock); 55 hints.ai_protocol = IPPROTO_UDP; 56 hints.ai_socktype = SOCK_DGRAM; 57 hints.ai_flags = 0; 58 alist = NULL; 59 60 a_info = getaddrinfo(pbuf, svc, &hints, &alist); 61 if (a_info == EAI_NONAME 62 #ifdef EAI_NODATA 63 || a_info == EAI_NODATA 64 #endif 65 ) { 66 hints.ai_flags = AI_CANONNAME; 67 #ifdef AI_ADDRCONFIG 68 hints.ai_flags |= AI_ADDRCONFIG; 69 #endif 70 a_info = getaddrinfo(pbuf, svc, &hints, &alist); 71 } 72 #ifdef AI_ADDRCONFIG 73 /* Some older implementations don't like AI_ADDRCONFIG. */ 74 if (a_info == EAI_BADFLAGS) { 75 hints.ai_flags &= ~AI_ADDRCONFIG; 76 a_info = getaddrinfo(pbuf, svc, &hints, &alist); 77 } 78 #endif 79 if (a_info) 80 goto forward_fail; 81 82 INSIST(alist != NULL); 83 84 for (ai = alist; ai != NULL; ai = ai->ai_next) { 85 /* 86 * Make a convenience sockaddr_u copy from ai->ai_addr 87 * because casting from sockaddr * to sockaddr_u * is 88 * risking alignment problems on platforms where 89 * sockaddr_u has stricter alignment than sockaddr, 90 * such as sparc. 91 */ 92 ZERO_SOCK(&addr); 93 octets = min(sizeof(addr), ai->ai_addrlen); 94 memcpy(&addr, ai->ai_addr, octets); 95 if (SOCK_EQ(sock, &addr)) 96 break; 97 } 98 freeaddrinfo(alist); 99 100 if (ai != NULL) 101 return pbuf; /* forward check passed */ 102 103 forward_fail: 104 TRACE(1, ("%s forward check lookup fail: %s\n", pbuf, 105 gai_strerror(a_info))); 106 LIB_GETBUF(pliar); 107 snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf); 108 109 return pliar; 110 } 111