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 * 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