summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/libntp/socktohost.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/libntp/socktohost.c')
-rw-r--r--contrib/ntp/libntp/socktohost.c95
1 files changed, 87 insertions, 8 deletions
diff --git a/contrib/ntp/libntp/socktohost.c b/contrib/ntp/libntp/socktohost.c
index 7aafdc7..c61e571 100644
--- a/contrib/ntp/libntp/socktohost.c
+++ b/contrib/ntp/libntp/socktohost.c
@@ -1,9 +1,14 @@
/*
* socktoa - return a numeric host name from a sockaddr_storage structure
*/
+#include <config.h>
#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
+#endif
#include <arpa/inet.h>
@@ -13,19 +18,93 @@
#include "lib_strbuf.h"
#include "ntp_stdlib.h"
#include "ntp.h"
+#include "ntp_debug.h"
-char *
+const char *
socktohost(
- struct sockaddr_storage* sock
+ const sockaddr_u *sock
)
{
- register char *buffer;
+ const char svc[] = "ntp";
+ char * pbuf;
+ char * pliar;
+ int gni_flags;
+ struct addrinfo hints;
+ struct addrinfo * alist;
+ struct addrinfo * ai;
+ sockaddr_u addr;
+ size_t octets;
+ int a_info;
- LIB_GETBUF(buffer);
- if (getnameinfo((struct sockaddr *)sock, SOCKLEN(sock), buffer,
- LIB_BUFLENGTH /* NI_MAXHOST*/, NULL, 0, 0))
- return stoa(sock);
+ /* reverse the address to purported DNS name */
+ LIB_GETBUF(pbuf);
+ gni_flags = NI_DGRAM | NI_NAMEREQD;
+ if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH,
+ NULL, 0, gni_flags))
+ return stoa(sock); /* use address */
- return buffer;
+ TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf));
+
+ /*
+ * Resolve the reversed name and make sure the reversed address
+ * is among the results.
+ */
+ ZERO(hints);
+ hints.ai_family = AF(sock);
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = 0;
+ alist = NULL;
+
+ a_info = getaddrinfo(pbuf, svc, &hints, &alist);
+ if (a_info == EAI_NONAME
+#ifdef EAI_NODATA
+ || a_info == EAI_NODATA
+#endif
+ ) {
+ hints.ai_flags = AI_CANONNAME;
+#ifdef AI_ADDRCONFIG
+ hints.ai_flags |= AI_ADDRCONFIG;
+#endif
+ a_info = getaddrinfo(pbuf, svc, &hints, &alist);
+ }
+#ifdef AI_ADDRCONFIG
+ /* Some older implementations don't like AI_ADDRCONFIG. */
+ if (a_info == EAI_BADFLAGS) {
+ hints.ai_flags &= ~AI_ADDRCONFIG;
+ a_info = getaddrinfo(pbuf, svc, &hints, &alist);
+ }
+#endif
+ if (a_info)
+ goto forward_fail;
+
+ NTP_INSIST(alist != NULL);
+
+ for (ai = alist; ai != NULL; ai = ai->ai_next) {
+ /*
+ * Make a convenience sockaddr_u copy from ai->ai_addr
+ * because casting from sockaddr * to sockaddr_u * is
+ * risking alignment problems on platforms where
+ * sockaddr_u has stricter alignment than sockaddr,
+ * such as sparc.
+ */
+ ZERO_SOCK(&addr);
+ octets = min(sizeof(addr), ai->ai_addrlen);
+ memcpy(&addr, ai->ai_addr, octets);
+ if (SOCK_EQ(sock, &addr))
+ break;
+ }
+ freeaddrinfo(alist);
+
+ if (ai != NULL)
+ return pbuf; /* forward check passed */
+
+ forward_fail:
+ TRACE(1, ("%s forward check lookup fail: %s\n", pbuf,
+ gai_strerror(a_info)));
+ LIB_GETBUF(pliar);
+ snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf);
+
+ return pliar;
}
OpenPOWER on IntegriCloud