1 /* $NetBSD: socktohost.c,v 1.7 2024/08/18 20:47:13 christos Exp $ */
2
3 /*
4 * socktoa - return a numeric host name from a sockaddr_storage structure
5 */
6 #include <config.h>
7 #include <sys/types.h>
8 #ifdef HAVE_SYS_SOCKET_H
9 #include <sys/socket.h>
10 #endif
11 #ifdef HAVE_NETINET_IN_H
12 #include <netinet/in.h>
13 #endif
14
15 #include <arpa/inet.h>
16
17 #include <stdio.h>
18
19 #include "ntp_fp.h"
20 #include "ntp_stdlib.h"
21 #include "ntp.h"
22 #include "ntp_debug.h"
23
24
25 const char *
socktohost(const sockaddr_u * sock)26 socktohost(
27 const sockaddr_u *sock
28 )
29 {
30 const char svc[] = "ntp";
31 char * pbuf;
32 char * pliar;
33 int gni_flags;
34 struct addrinfo hints;
35 struct addrinfo * alist;
36 struct addrinfo * ai;
37 sockaddr_u addr;
38 size_t octets;
39 int a_info;
40 int saved_errno;
41
42 saved_errno = socket_errno();
43
44 /* reverse the address to purported DNS name */
45 LIB_GETBUF(pbuf);
46 gni_flags = NI_DGRAM | NI_NAMEREQD;
47 if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH,
48 NULL, 0, gni_flags)) {
49 errno = saved_errno;
50 return stoa(sock); /* use address */
51 }
52
53 TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf));
54
55 /*
56 * Resolve the reversed name and make sure the reversed address
57 * is among the results.
58 */
59 ZERO(hints);
60 hints.ai_family = AF(sock);
61 hints.ai_protocol = IPPROTO_UDP;
62 hints.ai_socktype = SOCK_DGRAM;
63 hints.ai_flags = 0;
64 alist = NULL;
65
66 a_info = getaddrinfo(pbuf, svc, &hints, &alist);
67 if (a_info == EAI_NONAME
68 #ifdef EAI_NODATA
69 || a_info == EAI_NODATA
70 #endif
71 ) {
72 hints.ai_flags = AI_CANONNAME;
73 #ifdef AI_ADDRCONFIG
74 hints.ai_flags |= AI_ADDRCONFIG;
75 #endif
76 a_info = getaddrinfo(pbuf, svc, &hints, &alist);
77 }
78 #ifdef AI_ADDRCONFIG
79 /* Some older implementations don't like AI_ADDRCONFIG. */
80 if (a_info == EAI_BADFLAGS) {
81 hints.ai_flags &= ~AI_ADDRCONFIG;
82 a_info = getaddrinfo(pbuf, svc, &hints, &alist);
83 }
84 #endif
85 if (a_info)
86 goto forward_fail;
87
88 INSIST(alist != NULL);
89
90 for (ai = alist; ai != NULL; ai = ai->ai_next) {
91 /*
92 * Make a convenience sockaddr_u copy from ai->ai_addr
93 * because casting from sockaddr * to sockaddr_u * is
94 * risking alignment problems on platforms where
95 * sockaddr_u has stricter alignment than sockaddr,
96 * such as sparc.
97 */
98 ZERO_SOCK(&addr);
99 octets = min(sizeof(addr), ai->ai_addrlen);
100 memcpy(&addr, ai->ai_addr, octets);
101 if (SOCK_EQ(sock, &addr))
102 break;
103 }
104 freeaddrinfo(alist);
105
106 if (ai != NULL) {
107 errno = saved_errno;
108 return pbuf; /* forward check passed */
109 }
110
111 forward_fail:
112 TRACE(1, ("%s forward check lookup fail: %s\n", pbuf,
113 gai_strerror(a_info)));
114 LIB_GETBUF(pliar);
115 snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf);
116
117 errno = saved_errno;
118 return pliar;
119 }
120