1 /* $NetBSD: socktohost.c,v 1.5 2016/01/08 21:35:38 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 int saved_errno; 42 43 saved_errno = socket_errno(); 44 45 /* reverse the address to purported DNS name */ 46 LIB_GETBUF(pbuf); 47 gni_flags = NI_DGRAM | NI_NAMEREQD; 48 if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH, 49 NULL, 0, gni_flags)) { 50 errno = saved_errno; 51 return stoa(sock); /* use address */ 52 } 53 54 TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf)); 55 56 /* 57 * Resolve the reversed name and make sure the reversed address 58 * is among the results. 59 */ 60 ZERO(hints); 61 hints.ai_family = AF(sock); 62 hints.ai_protocol = IPPROTO_UDP; 63 hints.ai_socktype = SOCK_DGRAM; 64 hints.ai_flags = 0; 65 alist = NULL; 66 67 a_info = getaddrinfo(pbuf, svc, &hints, &alist); 68 if (a_info == EAI_NONAME 69 #ifdef EAI_NODATA 70 || a_info == EAI_NODATA 71 #endif 72 ) { 73 hints.ai_flags = AI_CANONNAME; 74 #ifdef AI_ADDRCONFIG 75 hints.ai_flags |= AI_ADDRCONFIG; 76 #endif 77 a_info = getaddrinfo(pbuf, svc, &hints, &alist); 78 } 79 #ifdef AI_ADDRCONFIG 80 /* Some older implementations don't like AI_ADDRCONFIG. */ 81 if (a_info == EAI_BADFLAGS) { 82 hints.ai_flags &= ~AI_ADDRCONFIG; 83 a_info = getaddrinfo(pbuf, svc, &hints, &alist); 84 } 85 #endif 86 if (a_info) 87 goto forward_fail; 88 89 INSIST(alist != NULL); 90 91 for (ai = alist; ai != NULL; ai = ai->ai_next) { 92 /* 93 * Make a convenience sockaddr_u copy from ai->ai_addr 94 * because casting from sockaddr * to sockaddr_u * is 95 * risking alignment problems on platforms where 96 * sockaddr_u has stricter alignment than sockaddr, 97 * such as sparc. 98 */ 99 ZERO_SOCK(&addr); 100 octets = min(sizeof(addr), ai->ai_addrlen); 101 memcpy(&addr, ai->ai_addr, octets); 102 if (SOCK_EQ(sock, &addr)) 103 break; 104 } 105 freeaddrinfo(alist); 106 107 if (ai != NULL) { 108 errno = saved_errno; 109 return pbuf; /* forward check passed */ 110 } 111 112 forward_fail: 113 TRACE(1, ("%s forward check lookup fail: %s\n", pbuf, 114 gai_strerror(a_info))); 115 LIB_GETBUF(pliar); 116 snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf); 117 118 errno = saved_errno; 119 return pliar; 120 } 121