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