1118e757roberto/*
2118e757roberto * socktoa - return a numeric host name from a sockaddr_storage structure
3118e757roberto */
4047f369cy#include <config.h>
5118e757roberto#include <sys/types.h>
6d54cfbdroberto#ifdef HAVE_SYS_SOCKET_H
7118e757roberto#include <sys/socket.h>
8d54cfbdroberto#endif
9d54cfbdroberto#ifdef HAVE_NETINET_IN_H
10118e757roberto#include <netinet/in.h>
11d54cfbdroberto#endif
12118e757roberto
13118e757roberto#include <arpa/inet.h>
14118e757roberto
15118e757roberto#include <stdio.h>
16118e757roberto
17118e757roberto#include "ntp_fp.h"
18118e757roberto#include "lib_strbuf.h"
19118e757roberto#include "ntp_stdlib.h"
20118e757roberto#include "ntp.h"
21047f369cy#include "ntp_debug.h"
22118e757roberto
23118e757roberto
24047f369cyconst char *
25118e757robertosocktohost(
26d54cfbdroberto	const sockaddr_u *sock
27118e757roberto	)
28118e757roberto{
29047f369cy	const char		svc[] = "ntp";
30047f369cy	char *			pbuf;
31047f369cy	char *			pliar;
32047f369cy	int			gni_flags;
33047f369cy	struct addrinfo		hints;
34047f369cy	struct addrinfo *	alist;
35047f369cy	struct addrinfo *	ai;
36047f369cy	sockaddr_u		addr;
37047f369cy	size_t			octets;
38047f369cy	int			a_info;
398518518delphij	int			saved_errno;
408518518delphij
418518518delphij	saved_errno = socket_errno();
42118e757roberto
43047f369cy	/* reverse the address to purported DNS name */
44047f369cy	LIB_GETBUF(pbuf);
45047f369cy	gni_flags = NI_DGRAM | NI_NAMEREQD;
46047f369cy	if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH,
478518518delphij			NULL, 0, gni_flags)) {
488518518delphij		errno = saved_errno;
49047f369cy		return stoa(sock);	/* use address */
508518518delphij	}
51118e757roberto
52047f369cy	TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf));
53047f369cy
54047f369cy	/*
55047f369cy	 * Resolve the reversed name and make sure the reversed address
56047f369cy	 * is among the results.
57047f369cy	 */
58047f369cy	ZERO(hints);
59047f369cy	hints.ai_family = AF(sock);
60047f369cy	hints.ai_protocol = IPPROTO_UDP;
61047f369cy	hints.ai_socktype = SOCK_DGRAM;
62047f369cy	hints.ai_flags = 0;
63047f369cy	alist = NULL;
64047f369cy
65047f369cy	a_info = getaddrinfo(pbuf, svc, &hints, &alist);
66047f369cy	if (a_info == EAI_NONAME
67047f369cy#ifdef EAI_NODATA
68047f369cy	    || a_info == EAI_NODATA
69047f369cy#endif
70047f369cy	   ) {
71047f369cy		hints.ai_flags = AI_CANONNAME;
72047f369cy#ifdef AI_ADDRCONFIG
73047f369cy		hints.ai_flags |= AI_ADDRCONFIG;
74047f369cy#endif
75047f369cy		a_info = getaddrinfo(pbuf, svc, &hints, &alist);
76047f369cy	}
77047f369cy#ifdef AI_ADDRCONFIG
78047f369cy	/* Some older implementations don't like AI_ADDRCONFIG. */
79047f369cy	if (a_info == EAI_BADFLAGS) {
80047f369cy		hints.ai_flags &= ~AI_ADDRCONFIG;
81047f369cy		a_info = getaddrinfo(pbuf, svc, &hints, &alist);
82047f369cy	}
83047f369cy#endif
84047f369cy	if (a_info)
85047f369cy		goto forward_fail;
86047f369cy
87aae1e7dglebius	INSIST(alist != NULL);
88047f369cy
89047f369cy	for (ai = alist; ai != NULL; ai = ai->ai_next) {
90047f369cy		/*
91047f369cy		 * Make a convenience sockaddr_u copy from ai->ai_addr
92047f369cy		 * because casting from sockaddr * to sockaddr_u * is
93047f369cy		 * risking alignment problems on platforms where
94047f369cy		 * sockaddr_u has stricter alignment than sockaddr,
95047f369cy		 * such as sparc.
96047f369cy		 */
97047f369cy		ZERO_SOCK(&addr);
98047f369cy		octets = min(sizeof(addr), ai->ai_addrlen);
99047f369cy		memcpy(&addr, ai->ai_addr, octets);
100047f369cy		if (SOCK_EQ(sock, &addr))
101047f369cy			break;
102047f369cy	}
103047f369cy	freeaddrinfo(alist);
104047f369cy
1058518518delphij	if (ai != NULL) {
1068518518delphij		errno = saved_errno;
107047f369cy		return pbuf;	/* forward check passed */
1088518518delphij	}
109047f369cy
110047f369cy    forward_fail:
111047f369cy	TRACE(1, ("%s forward check lookup fail: %s\n", pbuf,
112047f369cy		  gai_strerror(a_info)));
113047f369cy	LIB_GETBUF(pliar);
114047f369cy	snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf);
115047f369cy
1168518518delphij	errno = saved_errno;
117047f369cy	return pliar;
118118e757roberto}
119