diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-12-02 09:01:21 +0000 |
---|---|---|
committer | <> | 2014-12-04 16:11:25 +0000 |
commit | bdab5265fcbf3f472545073a23f8999749a9f2b9 (patch) | |
tree | c6018dd03dea906f8f1fb5f105f05b71a7dc250a /libntp/socktoa.c | |
download | ntp-bdab5265fcbf3f472545073a23f8999749a9f2b9.tar.gz |
Imported from /home/lorry/working-area/delta_ntp/ntp-dev-4.2.7p482.tar.gz.ntp-dev-4.2.7p482
Diffstat (limited to 'libntp/socktoa.c')
-rw-r--r-- | libntp/socktoa.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/libntp/socktoa.c b/libntp/socktoa.c new file mode 100644 index 0000000..98abe7c --- /dev/null +++ b/libntp/socktoa.c @@ -0,0 +1,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; +} |