1132451Sroberto/* 2132451Sroberto * socktoa - return a numeric host name from a sockaddr_storage structure 3132451Sroberto */ 4290001Sglebius#include <config.h> 5132451Sroberto#include <sys/types.h> 6290001Sglebius#ifdef HAVE_SYS_SOCKET_H 7132451Sroberto#include <sys/socket.h> 8290001Sglebius#endif 9290001Sglebius#ifdef HAVE_NETINET_IN_H 10132451Sroberto#include <netinet/in.h> 11290001Sglebius#endif 12132451Sroberto 13132451Sroberto#include <arpa/inet.h> 14132451Sroberto 15132451Sroberto#include <stdio.h> 16132451Sroberto 17132451Sroberto#include "ntp_fp.h" 18132451Sroberto#include "lib_strbuf.h" 19132451Sroberto#include "ntp_stdlib.h" 20132451Sroberto#include "ntp.h" 21290001Sglebius#include "ntp_debug.h" 22132451Sroberto 23132451Sroberto 24290001Sglebiusconst char * 25132451Srobertosocktohost( 26290001Sglebius const sockaddr_u *sock 27132451Sroberto ) 28132451Sroberto{ 29290001Sglebius const char svc[] = "ntp"; 30290001Sglebius char * pbuf; 31290001Sglebius char * pliar; 32290001Sglebius int gni_flags; 33290001Sglebius struct addrinfo hints; 34290001Sglebius struct addrinfo * alist; 35290001Sglebius struct addrinfo * ai; 36290001Sglebius sockaddr_u addr; 37290001Sglebius size_t octets; 38290001Sglebius int a_info; 39293896Sglebius int saved_errno; 40132451Sroberto 41293896Sglebius saved_errno = socket_errno(); 42293896Sglebius 43290001Sglebius /* reverse the address to purported DNS name */ 44290001Sglebius LIB_GETBUF(pbuf); 45290001Sglebius gni_flags = NI_DGRAM | NI_NAMEREQD; 46290001Sglebius if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH, 47293896Sglebius NULL, 0, gni_flags)) { 48293896Sglebius errno = saved_errno; 49290001Sglebius return stoa(sock); /* use address */ 50293896Sglebius } 51132451Sroberto 52290001Sglebius TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf)); 53290001Sglebius 54290001Sglebius /* 55290001Sglebius * Resolve the reversed name and make sure the reversed address 56290001Sglebius * is among the results. 57290001Sglebius */ 58290001Sglebius ZERO(hints); 59290001Sglebius hints.ai_family = AF(sock); 60290001Sglebius hints.ai_protocol = IPPROTO_UDP; 61290001Sglebius hints.ai_socktype = SOCK_DGRAM; 62290001Sglebius hints.ai_flags = 0; 63290001Sglebius alist = NULL; 64290001Sglebius 65290001Sglebius a_info = getaddrinfo(pbuf, svc, &hints, &alist); 66290001Sglebius if (a_info == EAI_NONAME 67290001Sglebius#ifdef EAI_NODATA 68290001Sglebius || a_info == EAI_NODATA 69290001Sglebius#endif 70290001Sglebius ) { 71290001Sglebius hints.ai_flags = AI_CANONNAME; 72290001Sglebius#ifdef AI_ADDRCONFIG 73290001Sglebius hints.ai_flags |= AI_ADDRCONFIG; 74290001Sglebius#endif 75290001Sglebius a_info = getaddrinfo(pbuf, svc, &hints, &alist); 76290001Sglebius } 77290001Sglebius#ifdef AI_ADDRCONFIG 78290001Sglebius /* Some older implementations don't like AI_ADDRCONFIG. */ 79290001Sglebius if (a_info == EAI_BADFLAGS) { 80290001Sglebius hints.ai_flags &= ~AI_ADDRCONFIG; 81290001Sglebius a_info = getaddrinfo(pbuf, svc, &hints, &alist); 82290001Sglebius } 83290001Sglebius#endif 84290001Sglebius if (a_info) 85290001Sglebius goto forward_fail; 86290001Sglebius 87290001Sglebius INSIST(alist != NULL); 88290001Sglebius 89290001Sglebius for (ai = alist; ai != NULL; ai = ai->ai_next) { 90290001Sglebius /* 91290001Sglebius * Make a convenience sockaddr_u copy from ai->ai_addr 92290001Sglebius * because casting from sockaddr * to sockaddr_u * is 93290001Sglebius * risking alignment problems on platforms where 94290001Sglebius * sockaddr_u has stricter alignment than sockaddr, 95290001Sglebius * such as sparc. 96290001Sglebius */ 97290001Sglebius ZERO_SOCK(&addr); 98290001Sglebius octets = min(sizeof(addr), ai->ai_addrlen); 99290001Sglebius memcpy(&addr, ai->ai_addr, octets); 100290001Sglebius if (SOCK_EQ(sock, &addr)) 101290001Sglebius break; 102290001Sglebius } 103290001Sglebius freeaddrinfo(alist); 104290001Sglebius 105293896Sglebius if (ai != NULL) { 106293896Sglebius errno = saved_errno; 107290001Sglebius return pbuf; /* forward check passed */ 108293896Sglebius } 109290001Sglebius 110290001Sglebius forward_fail: 111290001Sglebius TRACE(1, ("%s forward check lookup fail: %s\n", pbuf, 112290001Sglebius gai_strerror(a_info))); 113290001Sglebius LIB_GETBUF(pliar); 114290001Sglebius snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf); 115290001Sglebius 116293896Sglebius errno = saved_errno; 117290001Sglebius return pliar; 118132451Sroberto} 119