1132451Sroberto/* 2132451Sroberto * socktoa - return a numeric host name from a sockaddr_storage structure 3132451Sroberto */ 4290000Sglebius#include <config.h> 5132451Sroberto#include <sys/types.h> 6290000Sglebius#ifdef HAVE_SYS_SOCKET_H 7132451Sroberto#include <sys/socket.h> 8290000Sglebius#endif 9290000Sglebius#ifdef HAVE_NETINET_IN_H 10132451Sroberto#include <netinet/in.h> 11290000Sglebius#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" 21290000Sglebius#include "ntp_debug.h" 22132451Sroberto 23132451Sroberto 24290000Sglebiusconst char * 25132451Srobertosocktohost( 26290000Sglebius const sockaddr_u *sock 27132451Sroberto ) 28132451Sroberto{ 29290000Sglebius const char svc[] = "ntp"; 30290000Sglebius char * pbuf; 31290000Sglebius char * pliar; 32290000Sglebius int gni_flags; 33290000Sglebius struct addrinfo hints; 34290000Sglebius struct addrinfo * alist; 35290000Sglebius struct addrinfo * ai; 36290000Sglebius sockaddr_u addr; 37290000Sglebius size_t octets; 38290000Sglebius int a_info; 39293894Sglebius int saved_errno; 40132451Sroberto 41293894Sglebius saved_errno = socket_errno(); 42293894Sglebius 43290000Sglebius /* reverse the address to purported DNS name */ 44290000Sglebius LIB_GETBUF(pbuf); 45290000Sglebius gni_flags = NI_DGRAM | NI_NAMEREQD; 46290000Sglebius if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH, 47293894Sglebius NULL, 0, gni_flags)) { 48293894Sglebius errno = saved_errno; 49290000Sglebius return stoa(sock); /* use address */ 50293894Sglebius } 51132451Sroberto 52290000Sglebius TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf)); 53290000Sglebius 54290000Sglebius /* 55290000Sglebius * Resolve the reversed name and make sure the reversed address 56290000Sglebius * is among the results. 57290000Sglebius */ 58290000Sglebius ZERO(hints); 59290000Sglebius hints.ai_family = AF(sock); 60290000Sglebius hints.ai_protocol = IPPROTO_UDP; 61290000Sglebius hints.ai_socktype = SOCK_DGRAM; 62290000Sglebius hints.ai_flags = 0; 63290000Sglebius alist = NULL; 64290000Sglebius 65290000Sglebius a_info = getaddrinfo(pbuf, svc, &hints, &alist); 66290000Sglebius if (a_info == EAI_NONAME 67290000Sglebius#ifdef EAI_NODATA 68290000Sglebius || a_info == EAI_NODATA 69290000Sglebius#endif 70290000Sglebius ) { 71290000Sglebius hints.ai_flags = AI_CANONNAME; 72290000Sglebius#ifdef AI_ADDRCONFIG 73290000Sglebius hints.ai_flags |= AI_ADDRCONFIG; 74290000Sglebius#endif 75290000Sglebius a_info = getaddrinfo(pbuf, svc, &hints, &alist); 76290000Sglebius } 77290000Sglebius#ifdef AI_ADDRCONFIG 78290000Sglebius /* Some older implementations don't like AI_ADDRCONFIG. */ 79290000Sglebius if (a_info == EAI_BADFLAGS) { 80290000Sglebius hints.ai_flags &= ~AI_ADDRCONFIG; 81290000Sglebius a_info = getaddrinfo(pbuf, svc, &hints, &alist); 82290000Sglebius } 83290000Sglebius#endif 84290000Sglebius if (a_info) 85290000Sglebius goto forward_fail; 86290000Sglebius 87290000Sglebius INSIST(alist != NULL); 88290000Sglebius 89290000Sglebius for (ai = alist; ai != NULL; ai = ai->ai_next) { 90290000Sglebius /* 91290000Sglebius * Make a convenience sockaddr_u copy from ai->ai_addr 92290000Sglebius * because casting from sockaddr * to sockaddr_u * is 93290000Sglebius * risking alignment problems on platforms where 94290000Sglebius * sockaddr_u has stricter alignment than sockaddr, 95290000Sglebius * such as sparc. 96290000Sglebius */ 97290000Sglebius ZERO_SOCK(&addr); 98290000Sglebius octets = min(sizeof(addr), ai->ai_addrlen); 99290000Sglebius memcpy(&addr, ai->ai_addr, octets); 100290000Sglebius if (SOCK_EQ(sock, &addr)) 101290000Sglebius break; 102290000Sglebius } 103290000Sglebius freeaddrinfo(alist); 104290000Sglebius 105293894Sglebius if (ai != NULL) { 106293894Sglebius errno = saved_errno; 107290000Sglebius return pbuf; /* forward check passed */ 108293894Sglebius } 109290000Sglebius 110290000Sglebius forward_fail: 111290000Sglebius TRACE(1, ("%s forward check lookup fail: %s\n", pbuf, 112290000Sglebius gai_strerror(a_info))); 113290000Sglebius LIB_GETBUF(pliar); 114290000Sglebius snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf); 115290000Sglebius 116293894Sglebius errno = saved_errno; 117290000Sglebius return pliar; 118132451Sroberto} 119