1132451Sroberto/* 2132451Sroberto * socktoa - return a numeric host name from a sockaddr_storage structure 3132451Sroberto */ 4285612Sdelphij#include <config.h> 5132451Sroberto#include <sys/types.h> 6285612Sdelphij#ifdef HAVE_SYS_SOCKET_H 7132451Sroberto#include <sys/socket.h> 8285612Sdelphij#endif 9285612Sdelphij#ifdef HAVE_NETINET_IN_H 10132451Sroberto#include <netinet/in.h> 11285612Sdelphij#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" 21285612Sdelphij#include "ntp_debug.h" 22132451Sroberto 23132451Sroberto 24285612Sdelphijconst char * 25132451Srobertosocktohost( 26285612Sdelphij const sockaddr_u *sock 27132451Sroberto ) 28132451Sroberto{ 29285612Sdelphij const char svc[] = "ntp"; 30285612Sdelphij char * pbuf; 31285612Sdelphij char * pliar; 32285612Sdelphij int gni_flags; 33285612Sdelphij struct addrinfo hints; 34285612Sdelphij struct addrinfo * alist; 35285612Sdelphij struct addrinfo * ai; 36285612Sdelphij sockaddr_u addr; 37285612Sdelphij size_t octets; 38285612Sdelphij int a_info; 39293650Sglebius int saved_errno; 40132451Sroberto 41293650Sglebius saved_errno = socket_errno(); 42293650Sglebius 43285612Sdelphij /* reverse the address to purported DNS name */ 44285612Sdelphij LIB_GETBUF(pbuf); 45285612Sdelphij gni_flags = NI_DGRAM | NI_NAMEREQD; 46285612Sdelphij if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH, 47293650Sglebius NULL, 0, gni_flags)) { 48293650Sglebius errno = saved_errno; 49285612Sdelphij return stoa(sock); /* use address */ 50293650Sglebius } 51132451Sroberto 52285612Sdelphij TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf)); 53285612Sdelphij 54285612Sdelphij /* 55285612Sdelphij * Resolve the reversed name and make sure the reversed address 56285612Sdelphij * is among the results. 57285612Sdelphij */ 58285612Sdelphij ZERO(hints); 59285612Sdelphij hints.ai_family = AF(sock); 60285612Sdelphij hints.ai_protocol = IPPROTO_UDP; 61285612Sdelphij hints.ai_socktype = SOCK_DGRAM; 62285612Sdelphij hints.ai_flags = 0; 63285612Sdelphij alist = NULL; 64285612Sdelphij 65285612Sdelphij a_info = getaddrinfo(pbuf, svc, &hints, &alist); 66285612Sdelphij if (a_info == EAI_NONAME 67285612Sdelphij#ifdef EAI_NODATA 68285612Sdelphij || a_info == EAI_NODATA 69285612Sdelphij#endif 70285612Sdelphij ) { 71285612Sdelphij hints.ai_flags = AI_CANONNAME; 72285612Sdelphij#ifdef AI_ADDRCONFIG 73285612Sdelphij hints.ai_flags |= AI_ADDRCONFIG; 74285612Sdelphij#endif 75285612Sdelphij a_info = getaddrinfo(pbuf, svc, &hints, &alist); 76285612Sdelphij } 77285612Sdelphij#ifdef AI_ADDRCONFIG 78285612Sdelphij /* Some older implementations don't like AI_ADDRCONFIG. */ 79285612Sdelphij if (a_info == EAI_BADFLAGS) { 80285612Sdelphij hints.ai_flags &= ~AI_ADDRCONFIG; 81285612Sdelphij a_info = getaddrinfo(pbuf, svc, &hints, &alist); 82285612Sdelphij } 83285612Sdelphij#endif 84285612Sdelphij if (a_info) 85285612Sdelphij goto forward_fail; 86285612Sdelphij 87289997Sglebius INSIST(alist != NULL); 88285612Sdelphij 89285612Sdelphij for (ai = alist; ai != NULL; ai = ai->ai_next) { 90285612Sdelphij /* 91285612Sdelphij * Make a convenience sockaddr_u copy from ai->ai_addr 92285612Sdelphij * because casting from sockaddr * to sockaddr_u * is 93285612Sdelphij * risking alignment problems on platforms where 94285612Sdelphij * sockaddr_u has stricter alignment than sockaddr, 95285612Sdelphij * such as sparc. 96285612Sdelphij */ 97285612Sdelphij ZERO_SOCK(&addr); 98285612Sdelphij octets = min(sizeof(addr), ai->ai_addrlen); 99285612Sdelphij memcpy(&addr, ai->ai_addr, octets); 100285612Sdelphij if (SOCK_EQ(sock, &addr)) 101285612Sdelphij break; 102285612Sdelphij } 103285612Sdelphij freeaddrinfo(alist); 104285612Sdelphij 105293650Sglebius if (ai != NULL) { 106293650Sglebius errno = saved_errno; 107285612Sdelphij return pbuf; /* forward check passed */ 108293650Sglebius } 109285612Sdelphij 110285612Sdelphij forward_fail: 111285612Sdelphij TRACE(1, ("%s forward check lookup fail: %s\n", pbuf, 112285612Sdelphij gai_strerror(a_info))); 113285612Sdelphij LIB_GETBUF(pliar); 114285612Sdelphij snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf); 115285612Sdelphij 116293650Sglebius errno = saved_errno; 117285612Sdelphij return pliar; 118132451Sroberto} 119