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