1132451Sroberto/* 2280849Scy * socktoa.c socktoa(), sockporttoa(), and sock_hash() 3132451Sroberto */ 4132451Sroberto 5280849Scy#ifdef HAVE_CONFIG_H 6132451Sroberto#include <config.h> 7280849Scy#endif 8132451Sroberto 9132451Sroberto#include <sys/types.h> 10280849Scy#ifdef HAVE_SYS_SOCKET_H 11132451Sroberto#include <sys/socket.h> 12280849Scy#endif 13280849Scy#ifdef HAVE_NETINET_IN_H 14132451Sroberto#include <netinet/in.h> 15132451Sroberto#endif 16132451Sroberto 17132451Sroberto#include <stdio.h> 18280849Scy#include <arpa/inet.h> 19280849Scy#include <isc/result.h> 20280849Scy#include <isc/netaddr.h> 21280849Scy#include <isc/sockaddr.h> 22132451Sroberto 23132451Sroberto#include "ntp_fp.h" 24132451Sroberto#include "lib_strbuf.h" 25132451Sroberto#include "ntp_stdlib.h" 26132451Sroberto#include "ntp.h" 27132451Sroberto 28280849Scy/* 29280849Scy * socktoa - return a numeric host name from a sockaddr_storage structure 30280849Scy */ 31280849Scyconst char * 32132451Srobertosocktoa( 33280849Scy const sockaddr_u *sock 34132451Sroberto ) 35132451Sroberto{ 36280849Scy int saved_errno; 37280849Scy char * res; 38280849Scy char * addr; 39280849Scy u_long scope; 40132451Sroberto 41280849Scy saved_errno = socket_errno(); 42280849Scy LIB_GETBUF(res); 43132451Sroberto 44280849Scy if (NULL == sock) { 45280849Scy strlcpy(res, "(null)", LIB_BUFLENGTH); 46280849Scy } else { 47280849Scy switch(AF(sock)) { 48132451Sroberto 49280849Scy case AF_INET: 50280849Scy case AF_UNSPEC: 51280849Scy inet_ntop(AF_INET, PSOCK_ADDR4(sock), res, 52280849Scy LIB_BUFLENGTH); 53280849Scy break; 54132451Sroberto 55280849Scy case AF_INET6: 56280849Scy inet_ntop(AF_INET6, PSOCK_ADDR6(sock), res, 57280849Scy LIB_BUFLENGTH); 58280849Scy scope = SCOPE_VAR(sock); 59280849Scy if (0 != scope && !strchr(res, '%')) { 60280849Scy addr = res; 61280849Scy LIB_GETBUF(res); 62280849Scy snprintf(res, LIB_BUFLENGTH, "%s%%%lu", 63280849Scy addr, scope); 64280849Scy res[LIB_BUFLENGTH - 1] = '\0'; 65280849Scy } 66132451Sroberto break; 67132451Sroberto 68182007Sroberto default: 69280849Scy snprintf(res, LIB_BUFLENGTH, 70280849Scy "(socktoa unknown family %d)", 71280849Scy AF(sock)); 72182007Sroberto } 73132451Sroberto } 74280849Scy errno = saved_errno; 75280849Scy 76280849Scy return res; 77132451Sroberto} 78280849Scy 79280849Scy 80280849Scyconst char * 81280849Scysockporttoa( 82280849Scy const sockaddr_u *sock 83280849Scy ) 84280849Scy{ 85280849Scy int saved_errno; 86280849Scy const char * atext; 87280849Scy char * buf; 88280849Scy 89280849Scy saved_errno = socket_errno(); 90280849Scy atext = socktoa(sock); 91280849Scy LIB_GETBUF(buf); 92280849Scy snprintf(buf, LIB_BUFLENGTH, 93280849Scy (IS_IPV6(sock)) 94280849Scy ? "[%s]:%hu" 95280849Scy : "%s:%hu", 96280849Scy atext, SRCPORT(sock)); 97280849Scy errno = saved_errno; 98280849Scy 99280849Scy return buf; 100280849Scy} 101280849Scy 102280849Scy 103280849Scy/* 104280849Scy * sock_hash - hash a sockaddr_u structure 105280849Scy */ 106280849Scyu_short 107280849Scysock_hash( 108280849Scy const sockaddr_u *addr 109280849Scy ) 110280849Scy{ 111280849Scy u_int hashVal; 112280849Scy u_int j; 113280849Scy size_t len; 114280849Scy const u_char *pch; 115280849Scy 116280849Scy hashVal = 0; 117280849Scy len = 0; 118280849Scy 119280849Scy /* 120280849Scy * We can't just hash the whole thing because there are hidden 121280849Scy * fields in sockaddr_in6 that might be filled in by recvfrom(), 122280849Scy * so just use the family, port and address. 123280849Scy */ 124280849Scy pch = (const void *)&AF(addr); 125280849Scy hashVal = 37 * hashVal + *pch; 126280849Scy if (sizeof(AF(addr)) > 1) { 127280849Scy pch++; 128280849Scy hashVal = 37 * hashVal + *pch; 129280849Scy } 130280849Scy switch(AF(addr)) { 131280849Scy case AF_INET: 132280849Scy pch = (const void *)&SOCK_ADDR4(addr); 133280849Scy len = sizeof(SOCK_ADDR4(addr)); 134280849Scy break; 135280849Scy 136280849Scy case AF_INET6: 137280849Scy pch = (const void *)&SOCK_ADDR6(addr); 138280849Scy len = sizeof(SOCK_ADDR6(addr)); 139280849Scy break; 140280849Scy } 141280849Scy 142280849Scy for (j = 0; j < len ; j++) 143280849Scy hashVal = 37 * hashVal + pch[j]; 144280849Scy 145280849Scy return (u_short)(hashVal & USHRT_MAX); 146280849Scy} 147280849Scy 148280849Scy 149280849Scyint 150280849Scysockaddr_masktoprefixlen( 151280849Scy const sockaddr_u * psa 152280849Scy ) 153280849Scy{ 154280849Scy isc_netaddr_t isc_na; 155280849Scy isc_sockaddr_t isc_sa; 156280849Scy u_int pfxlen; 157280849Scy isc_result_t result; 158280849Scy int rc; 159280849Scy 160280849Scy ZERO(isc_sa); 161280849Scy memcpy(&isc_sa.type, psa, 162280849Scy min(sizeof(isc_sa.type), sizeof(*psa))); 163280849Scy isc_netaddr_fromsockaddr(&isc_na, &isc_sa); 164280849Scy result = isc_netaddr_masktoprefixlen(&isc_na, &pfxlen); 165280849Scy rc = (ISC_R_SUCCESS == result) 166280849Scy ? (int)pfxlen 167280849Scy : -1; 168280849Scy 169280849Scy return rc; 170280849Scy} 171