1154133Sharti/* $NetBSD: socktoa.c,v 1.6 2020/05/25 20:47:24 christos Exp $ */ 2154133Sharti 3154133Sharti/* 4154133Sharti * socktoa.c socktoa(), sockporttoa(), and sock_hash() 5154133Sharti */ 6154133Sharti 7154133Sharti#ifdef HAVE_CONFIG_H 8154133Sharti#include <config.h> 9154133Sharti#endif 10154133Sharti 11154133Sharti#include <sys/types.h> 12154133Sharti#ifdef HAVE_SYS_SOCKET_H 13154133Sharti#include <sys/socket.h> 14154133Sharti#endif 15154133Sharti#ifdef HAVE_NETINET_IN_H 16154133Sharti#include <netinet/in.h> 17154133Sharti#endif 18154133Sharti 19154133Sharti#include <stdio.h> 20154133Sharti#include <arpa/inet.h> 21154133Sharti#include <isc/result.h> 22154133Sharti#include <isc/netaddr.h> 23154133Sharti#include <isc/sockaddr.h> 24154133Sharti 25154133Sharti#include "ntp_fp.h" 26154133Sharti#include "lib_strbuf.h" 27154133Sharti#include "ntp_stdlib.h" 28154133Sharti#include "ntp.h" 29154133Sharti 30154133Sharti/* 31154133Sharti * socktoa - return a numeric host name from a sockaddr_storage structure 32154133Sharti */ 33154133Sharticonst char * 34154133Shartisocktoa( 35154133Sharti const sockaddr_u *sock 36154133Sharti ) 37154133Sharti{ 38154133Sharti int saved_errno; 39154133Sharti char * res; 40154133Sharti char * addr; 41154133Sharti u_long scope; 42154133Sharti 43154133Sharti saved_errno = socket_errno(); 44154133Sharti LIB_GETBUF(res); 45154133Sharti 46154133Sharti if (NULL == sock) { 47154133Sharti strlcpy(res, "(null)", LIB_BUFLENGTH); 48154133Sharti } else { 49154133Sharti switch(AF(sock)) { 50154133Sharti 51154133Sharti case AF_INET: 52160341Sharti case AF_UNSPEC: 53160341Sharti inet_ntop(AF_INET, PSOCK_ADDR4(sock), res, 54154133Sharti LIB_BUFLENGTH); 55154133Sharti break; 56154133Sharti 57154133Sharti case AF_INET6: 58154133Sharti inet_ntop(AF_INET6, PSOCK_ADDR6(sock), res, 59160341Sharti LIB_BUFLENGTH); 60160341Sharti scope = SCOPE_VAR(sock); 61160341Sharti if (0 != scope && !strchr(res, '%')) { 62154133Sharti addr = res; 63154133Sharti LIB_GETBUF(res); 64154133Sharti snprintf(res, LIB_BUFLENGTH, "%s%%%lu", 65154133Sharti addr, scope); 66154133Sharti res[LIB_BUFLENGTH - 1] = '\0'; 67154133Sharti } 68160341Sharti break; 69160341Sharti 70154133Sharti default: 71154133Sharti snprintf(res, LIB_BUFLENGTH, 72154133Sharti "(socktoa unknown family %d)", 73154133Sharti AF(sock)); 74160341Sharti } 75154133Sharti } 76154133Sharti errno = saved_errno; 77154133Sharti 78154133Sharti return res; 79154133Sharti} 80154133Sharti 81154133Sharti 82154133Sharticonst char * 83154133Shartisockporttoa( 84154133Sharti const sockaddr_u *sock 85154133Sharti ) 86154133Sharti{ 87160341Sharti int saved_errno; 88154133Sharti const char * atext; 89160341Sharti char * buf; 90160341Sharti 91154133Sharti saved_errno = socket_errno(); 92154133Sharti atext = socktoa(sock); 93160341Sharti LIB_GETBUF(buf); 94154133Sharti snprintf(buf, LIB_BUFLENGTH, 95154133Sharti (IS_IPV6(sock)) 96154133Sharti ? "[%s]:%u" 97154133Sharti : "%s:%u", 98154133Sharti atext, SRCPORT(sock)); 99154133Sharti errno = saved_errno; 100154133Sharti 101154133Sharti return buf; 102154133Sharti} 103154133Sharti 104154133Sharti 105154133Sharti/* 106154133Sharti * sock_hash - hash a sockaddr_u structure 107154133Sharti */ 108154133Shartiu_short 109154133Shartisock_hash( 110154133Sharti const sockaddr_u *addr 111154133Sharti ) 112154133Sharti{ 113154133Sharti u_int hashVal; 114154133Sharti u_int j; 115154133Sharti size_t len; 116154133Sharti const u_char *pch; 117154133Sharti 118154133Sharti hashVal = 0; 119154133Sharti len = 0; 120154133Sharti 121154133Sharti /* 122154133Sharti * We can't just hash the whole thing because there are hidden 123154133Sharti * fields in sockaddr_in6 that might be filled in by recvfrom(), 124154133Sharti * so just use the family, port and address. 125154133Sharti */ 126154133Sharti pch = (const void *)&AF(addr); 127154133Sharti hashVal = 37 * hashVal + *pch; 128154133Sharti if (sizeof(AF(addr)) > 1) { 129154133Sharti pch++; 130154133Sharti hashVal = 37 * hashVal + *pch; 131154133Sharti } 132154133Sharti switch(AF(addr)) { 133154133Sharti case AF_INET: 134154133Sharti pch = (const void *)&SOCK_ADDR4(addr); 135154133Sharti len = sizeof(SOCK_ADDR4(addr)); 136228990Suqs break; 137154133Sharti 138154133Sharti case AF_INET6: 139154133Sharti pch = (const void *)&SOCK_ADDR6(addr); 140154133Sharti len = sizeof(SOCK_ADDR6(addr)); 141154133Sharti break; 142154133Sharti } 143154133Sharti 144160341Sharti for (j = 0; j < len ; j++) 145154133Sharti hashVal = 37 * hashVal + pch[j]; 146160341Sharti 147160341Sharti return (u_short)(hashVal & USHRT_MAX); 148154133Sharti} 149154133Sharti 150160341Sharti 151154133Shartiint 152154133Shartisockaddr_masktoprefixlen( 153154133Sharti const sockaddr_u * psa 154154133Sharti ) 155154133Sharti{ 156154133Sharti isc_netaddr_t isc_na; 157154133Sharti isc_sockaddr_t isc_sa; 158160341Sharti u_int pfxlen; 159154133Sharti isc_result_t result; 160154133Sharti int rc; 161154133Sharti 162154133Sharti ZERO(isc_sa); 163154133Sharti memcpy(&isc_sa.type, psa, 164154133Sharti min(sizeof(isc_sa.type), sizeof(*psa))); 165154133Sharti isc_netaddr_fromsockaddr(&isc_na, &isc_sa); 166160341Sharti result = isc_netaddr_masktoprefixlen(&isc_na, &pfxlen); 167160341Sharti rc = (ISC_R_SUCCESS == result) 168160341Sharti ? (int)pfxlen 169154133Sharti : -1; 170160341Sharti 171160341Sharti return rc; 172160341Sharti} 173160341Sharti