1*eabc0478Schristos /* $NetBSD: socktohost.c,v 1.7 2024/08/18 20:47:13 christos Exp $ */ 2abb0f93cSkardel 3abb0f93cSkardel /* 4abb0f93cSkardel * socktoa - return a numeric host name from a sockaddr_storage structure 5abb0f93cSkardel */ 68585484eSchristos #include <config.h> 7abb0f93cSkardel #include <sys/types.h> 8abb0f93cSkardel #ifdef HAVE_SYS_SOCKET_H 9abb0f93cSkardel #include <sys/socket.h> 10abb0f93cSkardel #endif 11abb0f93cSkardel #ifdef HAVE_NETINET_IN_H 12abb0f93cSkardel #include <netinet/in.h> 13abb0f93cSkardel #endif 14abb0f93cSkardel 15abb0f93cSkardel #include <arpa/inet.h> 16abb0f93cSkardel 17abb0f93cSkardel #include <stdio.h> 18abb0f93cSkardel 19abb0f93cSkardel #include "ntp_fp.h" 20abb0f93cSkardel #include "ntp_stdlib.h" 21abb0f93cSkardel #include "ntp.h" 228585484eSchristos #include "ntp_debug.h" 23abb0f93cSkardel 24abb0f93cSkardel 258585484eSchristos const char * 26abb0f93cSkardel socktohost( 27f003fb54Skardel const sockaddr_u *sock 28abb0f93cSkardel ) 29abb0f93cSkardel { 308585484eSchristos const char svc[] = "ntp"; 318585484eSchristos char * pbuf; 328585484eSchristos char * pliar; 338585484eSchristos int gni_flags; 348585484eSchristos struct addrinfo hints; 358585484eSchristos struct addrinfo * alist; 368585484eSchristos struct addrinfo * ai; 378585484eSchristos sockaddr_u addr; 388585484eSchristos size_t octets; 398585484eSchristos int a_info; 408b8da087Schristos int saved_errno; 418b8da087Schristos 428b8da087Schristos saved_errno = socket_errno(); 43abb0f93cSkardel 448585484eSchristos /* reverse the address to purported DNS name */ 458585484eSchristos LIB_GETBUF(pbuf); 468585484eSchristos gni_flags = NI_DGRAM | NI_NAMEREQD; 478585484eSchristos if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH, 488b8da087Schristos NULL, 0, gni_flags)) { 498b8da087Schristos errno = saved_errno; 508585484eSchristos return stoa(sock); /* use address */ 518b8da087Schristos } 52abb0f93cSkardel 538585484eSchristos TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf)); 548585484eSchristos 558585484eSchristos /* 568585484eSchristos * Resolve the reversed name and make sure the reversed address 578585484eSchristos * is among the results. 588585484eSchristos */ 598585484eSchristos ZERO(hints); 608585484eSchristos hints.ai_family = AF(sock); 618585484eSchristos hints.ai_protocol = IPPROTO_UDP; 628585484eSchristos hints.ai_socktype = SOCK_DGRAM; 638585484eSchristos hints.ai_flags = 0; 648585484eSchristos alist = NULL; 658585484eSchristos 668585484eSchristos a_info = getaddrinfo(pbuf, svc, &hints, &alist); 678585484eSchristos if (a_info == EAI_NONAME 688585484eSchristos #ifdef EAI_NODATA 698585484eSchristos || a_info == EAI_NODATA 708585484eSchristos #endif 718585484eSchristos ) { 728585484eSchristos hints.ai_flags = AI_CANONNAME; 738585484eSchristos #ifdef AI_ADDRCONFIG 748585484eSchristos hints.ai_flags |= AI_ADDRCONFIG; 758585484eSchristos #endif 768585484eSchristos a_info = getaddrinfo(pbuf, svc, &hints, &alist); 778585484eSchristos } 788585484eSchristos #ifdef AI_ADDRCONFIG 798585484eSchristos /* Some older implementations don't like AI_ADDRCONFIG. */ 808585484eSchristos if (a_info == EAI_BADFLAGS) { 818585484eSchristos hints.ai_flags &= ~AI_ADDRCONFIG; 828585484eSchristos a_info = getaddrinfo(pbuf, svc, &hints, &alist); 838585484eSchristos } 848585484eSchristos #endif 858585484eSchristos if (a_info) 868585484eSchristos goto forward_fail; 878585484eSchristos 88af12ab5eSchristos INSIST(alist != NULL); 898585484eSchristos 908585484eSchristos for (ai = alist; ai != NULL; ai = ai->ai_next) { 918585484eSchristos /* 928585484eSchristos * Make a convenience sockaddr_u copy from ai->ai_addr 938585484eSchristos * because casting from sockaddr * to sockaddr_u * is 948585484eSchristos * risking alignment problems on platforms where 958585484eSchristos * sockaddr_u has stricter alignment than sockaddr, 968585484eSchristos * such as sparc. 978585484eSchristos */ 988585484eSchristos ZERO_SOCK(&addr); 998585484eSchristos octets = min(sizeof(addr), ai->ai_addrlen); 1008585484eSchristos memcpy(&addr, ai->ai_addr, octets); 1018585484eSchristos if (SOCK_EQ(sock, &addr)) 1028585484eSchristos break; 1038585484eSchristos } 1048585484eSchristos freeaddrinfo(alist); 1058585484eSchristos 1068b8da087Schristos if (ai != NULL) { 1078b8da087Schristos errno = saved_errno; 1088585484eSchristos return pbuf; /* forward check passed */ 1098b8da087Schristos } 1108585484eSchristos 1118585484eSchristos forward_fail: 1128585484eSchristos TRACE(1, ("%s forward check lookup fail: %s\n", pbuf, 1138585484eSchristos gai_strerror(a_info))); 1148585484eSchristos LIB_GETBUF(pliar); 1158585484eSchristos snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf); 1168585484eSchristos 1178b8da087Schristos errno = saved_errno; 1188585484eSchristos return pliar; 119abb0f93cSkardel } 120