socktohost.c revision 289997
12061Sjkh/* 250479Speter * socktoa - return a numeric host name from a sockaddr_storage structure 32061Sjkh */ 438666Sjb#include <config.h> 532427Sjb#include <sys/types.h> 6111131Sru#ifdef HAVE_SYS_SOCKET_H 7111131Sru#include <sys/socket.h> 8217733Sbz#endif 9217733Sbz#ifdef HAVE_NETINET_IN_H 1038666Sjb#include <netinet/in.h> 1138666Sjb#endif 1238666Sjb 13159363Strhodes#include <arpa/inet.h> 1464049Salex 1564049Salex#include <stdio.h> 16116679Ssimokawa 1766071Smarkm#include "ntp_fp.h" 18116679Ssimokawa#include "lib_strbuf.h" 1973504Sobrien#include "ntp_stdlib.h" 20204661Simp#include "ntp.h" 21232907Sjmallett#include "ntp_debug.h" 22158962Snetchild 23223148Sru 24169597Sdesconst char * 25169597Sdessocktohost( 26169597Sdes const sockaddr_u *sock 27169597Sdes ) 28231821Spluknet{ 29169597Sdes const char svc[] = "ntp"; 30169597Sdes char * pbuf; 31169597Sdes char * pliar; 32217815Sbz int gni_flags; 33217815Sbz struct addrinfo hints; 34218524Sjhb struct addrinfo * alist; 35253002Salfred struct addrinfo * ai; 36253002Salfred sockaddr_u addr; 37253002Salfred size_t octets; 38253002Salfred int a_info; 39253002Salfred 40253003Salfred /* reverse the address to purported DNS name */ 4132427Sjb LIB_GETBUF(pbuf); 4238666Sjb gni_flags = NI_DGRAM | NI_NAMEREQD; 43108451Sschweikh if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH, 4438666Sjb NULL, 0, gni_flags)) 4538666Sjb return stoa(sock); /* use address */ 4638666Sjb 4738666Sjb TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf)); 4817308Speter 49217273Simp /* 50217294Simp * Resolve the reversed name and make sure the reversed address 5119175Sbde * is among the results. 5296205Sjwd */ 53217297Simp ZERO(hints); 54217297Simp hints.ai_family = AF(sock); 5538042Sbde hints.ai_protocol = IPPROTO_UDP; 5696205Sjwd hints.ai_socktype = SOCK_DGRAM; 5796205Sjwd hints.ai_flags = 0; 5838042Sbde alist = NULL; 5996205Sjwd 60159363Strhodes a_info = getaddrinfo(pbuf, svc, &hints, &alist); 61159363Strhodes if (a_info == EAI_NONAME 6217308Speter#ifdef EAI_NODATA 6396205Sjwd || a_info == EAI_NODATA 6496205Sjwd#endif 6517308Speter ) { 66148330Snetchild hints.ai_flags = AI_CANONNAME; 67148330Snetchild#ifdef AI_ADDRCONFIG 68148330Snetchild hints.ai_flags |= AI_ADDRCONFIG; 69148330Snetchild#endif 70159831Sobrien a_info = getaddrinfo(pbuf, svc, &hints, &alist); 71148330Snetchild } 72148330Snetchild#ifdef AI_ADDRCONFIG 73148330Snetchild /* Some older implementations don't like AI_ADDRCONFIG. */ 74251107Screes if (a_info == EAI_BADFLAGS) { 75251107Screes hints.ai_flags &= ~AI_ADDRCONFIG; 76148330Snetchild a_info = getaddrinfo(pbuf, svc, &hints, &alist); 77148330Snetchild } 7896205Sjwd#endif 7996205Sjwd if (a_info) 8096205Sjwd goto forward_fail; 81162147Sru 82162147Sru INSIST(alist != NULL); 8398723Sdillon 8498723Sdillon for (ai = alist; ai != NULL; ai = ai->ai_next) { 8598723Sdillon /* 8638666Sjb * Make a convenience sockaddr_u copy from ai->ai_addr 8738666Sjb * because casting from sockaddr * to sockaddr_u * is 8817308Speter * risking alignment problems on platforms where 89123311Speter * sockaddr_u has stricter alignment than sockaddr, 90123311Speter * such as sparc. 91123311Speter */ 92123311Speter ZERO_SOCK(&addr); 93175833Sjhb octets = min(sizeof(addr), ai->ai_addrlen); 94175833Sjhb memcpy(&addr, ai->ai_addr, octets); 95169597Sdes if (SOCK_EQ(sock, &addr)) 96169597Sdes break; 97169597Sdes } 98169597Sdes freeaddrinfo(alist); 99219177Snwhitehorn 100219177Snwhitehorn if (ai != NULL) 101238051Sobrien return pbuf; /* forward check passed */ 102219177Snwhitehorn 103219177Snwhitehorn forward_fail: 104158962Snetchild TRACE(1, ("%s forward check lookup fail: %s\n", pbuf, 105156840Sru gai_strerror(a_info))); 106123311Speter LIB_GETBUF(pliar); 107137288Speter snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf); 108209128Sraj 109209128Sraj return pliar; 110156740Sru} 1112061Sjkh