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