1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/*
* socktoa.c socktoa(), sockporttoa(), and sock_hash()
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#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 <stdio.h>
#include <arpa/inet.h>
#include <isc/result.h>
#include <isc/netaddr.h>
#include <isc/sockaddr.h>
#include "ntp_fp.h"
#include "lib_strbuf.h"
#include "ntp_stdlib.h"
#include "ntp.h"
/*
* socktoa - return a numeric host name from a sockaddr_storage structure
*/
const char *
socktoa(
const sockaddr_u *sock
)
{
int saved_errno;
char * res;
char * addr;
u_long scope;
saved_errno = socket_errno();
LIB_GETBUF(res);
if (NULL == sock) {
strlcpy(res, "(null)", LIB_BUFLENGTH);
} else {
switch(AF(sock)) {
case AF_INET:
case AF_UNSPEC:
inet_ntop(AF_INET, PSOCK_ADDR4(sock), res,
LIB_BUFLENGTH);
break;
case AF_INET6:
inet_ntop(AF_INET6, PSOCK_ADDR6(sock), res,
LIB_BUFLENGTH);
scope = SCOPE_VAR(sock);
if (0 != scope && !strchr(res, '%')) {
addr = res;
LIB_GETBUF(res);
snprintf(res, LIB_BUFLENGTH, "%s%%%lu",
addr, scope);
res[LIB_BUFLENGTH - 1] = '\0';
}
break;
default:
snprintf(res, LIB_BUFLENGTH,
"(socktoa unknown family %d)",
AF(sock));
}
}
errno = saved_errno;
return res;
}
const char *
sockporttoa(
const sockaddr_u *sock
)
{
int saved_errno;
const char * atext;
char * buf;
saved_errno = socket_errno();
atext = socktoa(sock);
LIB_GETBUF(buf);
snprintf(buf, LIB_BUFLENGTH,
(IS_IPV6(sock))
? "[%s]:%hu"
: "%s:%hu",
atext, SRCPORT(sock));
errno = saved_errno;
return buf;
}
/*
* sock_hash - hash a sockaddr_u structure
*/
u_short
sock_hash(
const sockaddr_u *addr
)
{
u_int hashVal;
u_int j;
size_t len;
const u_char *pch;
hashVal = 0;
len = 0;
/*
* We can't just hash the whole thing because there are hidden
* fields in sockaddr_in6 that might be filled in by recvfrom(),
* so just use the family, port and address.
*/
pch = (const void *)&AF(addr);
hashVal = 37 * hashVal + *pch;
if (sizeof(AF(addr)) > 1) {
pch++;
hashVal = 37 * hashVal + *pch;
}
switch(AF(addr)) {
case AF_INET:
pch = (const void *)&SOCK_ADDR4(addr);
len = sizeof(SOCK_ADDR4(addr));
break;
case AF_INET6:
pch = (const void *)&SOCK_ADDR6(addr);
len = sizeof(SOCK_ADDR6(addr));
break;
}
for (j = 0; j < len ; j++)
hashVal = 37 * hashVal + pch[j];
return (u_short)(hashVal & USHRT_MAX);
}
int
sockaddr_masktoprefixlen(
const sockaddr_u * psa
)
{
isc_netaddr_t isc_na;
isc_sockaddr_t isc_sa;
u_int pfxlen;
isc_result_t result;
int rc;
ZERO(isc_sa);
memcpy(&isc_sa.type, psa,
min(sizeof(isc_sa.type), sizeof(*psa)));
isc_netaddr_fromsockaddr(&isc_na, &isc_sa);
result = isc_netaddr_masktoprefixlen(&isc_na, &pfxlen);
rc = (ISC_R_SUCCESS == result)
? (int)pfxlen
: -1;
return rc;
}
|