From 7dded571de1b2f0548a2f4a81ad79d864bdec3be Mon Sep 17 00:00:00 2001 From: Dominick Meglio Date: Sat, 14 May 2005 18:35:20 +0000 Subject: [PATCH] Added an inet_ntop function from BIND for systems that do not have it --- ares/CHANGES | 4 + ares/Makefile.inc | 34 +-- ares/configure.ac | 512 +++++++++++++++++++++++++--------------------- ares/inet_ntop.c | 210 +++++++++++++++++++ ares/inet_ntop.h | 26 +++ 5 files changed, 531 insertions(+), 255 deletions(-) create mode 100644 ares/inet_ntop.c create mode 100644 ares/inet_ntop.h diff --git a/ares/CHANGES b/ares/CHANGES index 8acbf0811..eb38613c1 100644 --- a/ares/CHANGES +++ b/ares/CHANGES @@ -1,5 +1,9 @@ Changelog for the c-ares project +* May 14 + +- Added an inet_ntop function from BIND for systems that do not have it. + * April 9 - Made sortlist support IPv6 (this can probably use some testing). diff --git a/ares/Makefile.inc b/ares/Makefile.inc index 0d05c7bc5..121fa6bb7 100644 --- a/ares/Makefile.inc +++ b/ares/Makefile.inc @@ -1,17 +1,17 @@ -CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c \ -ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c \ -ares_gethostbyaddr.c ares_send.c ares__read_line.c ares_gethostbyname.c \ -ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c \ -ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c \ -windows_port.c ares_expand_string.c ares_parse_ptr_reply.c \ -ares_parse_aaaa_reply.c inet_net_pton.c bitncmp.c - -HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h nameser.h \ - inet_net_pton.h ares_ipv6.h bitncmp.h - -MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \ - ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \ - ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3 \ - ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \ - ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \ - ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 +CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c \ +ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c \ +ares_gethostbyaddr.c ares_send.c ares__read_line.c ares_gethostbyname.c \ +ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c \ +ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c \ +windows_port.c ares_expand_string.c ares_parse_ptr_reply.c \ +ares_parse_aaaa_reply.c inet_net_pton.c bitncmp.c inet_ntop.c + +HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h nameser.h \ + inet_net_pton.h ares_ipv6.h bitncmp.h + +MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \ + ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \ + ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3 \ + ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \ + ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \ + ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 diff --git a/ares/configure.ac b/ares/configure.ac index b4774d9bf..411ca0c0e 100644 --- a/ares/configure.ac +++ b/ares/configure.ac @@ -1,238 +1,274 @@ -dnl Process this file with autoconf to produce a configure script. -AC_INIT(ares_init.c) -AM_CONFIG_HEADER(config.h) -AM_MAINTAINER_MODE -AM_INIT_AUTOMAKE(c-ares, CVS) - -AC_PROG_CC -AC_PROG_INSTALL - -case $host_os in -solaris*) - AC_DEFINE(ETC_INET, 1, [if a /etc/inet dir is being used]) - ;; -esac - -# check for ssize_t -AC_CHECK_TYPE(ssize_t, , - AC_DEFINE(ssize_t, int, [the signed version of size_t])) - -AC_SEARCH_LIBS(gethostbyname, nsl) -AC_SEARCH_LIBS(socket, socket) - -dnl ************************************************************ -dnl Option to switch on debug options. This makes an assumption that -dnl this is built as an 'ares' subdir in the curl source tree. Subject for -dnl improval in the future! -dnl -AC_MSG_CHECKING([whether to enable debug options]) -AC_ARG_ENABLE(debug, -AC_HELP_STRING([--enable-debug],[Enable pedantic debug options]) -AC_HELP_STRING([--disable-debug],[Disable debug options]), -[ case "$enableval" in - no) - AC_MSG_RESULT(no) - ;; - *) AC_MSG_RESULT(yes) - - dnl when doing the debug stuff, use static library only - AC_DISABLE_SHARED - - dnl Checks for standard header files, to make memdebug.h inclusions bettter - AC_HEADER_STDC - - dnl the entire --enable-debug is a hack that lives and runs on top of - dnl libcurl stuff so this BUILDING_LIBCURL is not THAT much uglier - AC_DEFINE(BUILDING_LIBCURL, 1, [when building as static part of libcurl]) - - CPPFLAGS="$CPPFLAGS -DCURLDEBUG -I$srcdir/../include" - CFLAGS="$CFLAGS -g" - - dnl set compiler "debug" options to become more picky, and remove - dnl optimize options from CFLAGS - CURL_CC_DEBUG_OPTS - - ;; - esac ], - AC_MSG_RESULT(no) -) - -AC_PROG_LIBTOOL - -dnl check for a few basic system headers we need -AC_CHECK_HEADERS( - sys/types.h \ - sys/time.h \ - sys/select.h \ - sys/socket.h \ - winsock.h \ - netinet/in.h \ - arpa/nameser.h \ - arpa/nameser_compat.h \ - arpa/inet.h, , , -[ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -dnl We do this default-include simply to make sure that the nameser_compat.h -dnl header *REALLY* can be include after the new nameser.h. It seems AIX 5.1 -dnl (and others?) is not designed to allow this. -#ifdef HAVE_ARPA_NAMESER_H -#include -#endif -] - ) - -dnl check for AF_INET6 -CARES_CHECK_CONSTANT( - [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif - - ], [PF_INET6], - AC_DEFINE_UNQUOTED(HAVE_PF_INET6,1,[Define to 1 if you have PF_INET6.]) -) - -dnl check for PF_INET6 -CARES_CHECK_CONSTANT( - [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif - - ], [AF_INET6], - AC_DEFINE_UNQUOTED(HAVE_AF_INET6,1,[Define to 1 if you have AF_INET6.]) -) - - -dnl check for the in6_addr structure -CARES_CHECK_STRUCT( - [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif - ], [in6_addr], - AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.]) -) - -dnl check for inet_pton -AC_CHECK_FUNCS(inet_pton) -dnl Some systems have it, but not IPv6 -if test "$ac_cv_func_inet_pton" = "yes" ; then -AC_MSG_CHECKING(if inet_pton supports IPv6) -AC_TRY_RUN( - [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -int main() - { - struct in6_addr addr6; - if (inet_pton(AF_INET6, "::1", &addr6) < 1) - exit(1); - else - exit(0); - } - ], [ - AC_MSG_RESULT(yes) - AC_DEFINE_UNQUOTED(HAVE_INET_PTON_IPV6,1,[Define to 1 if inet_pton supports IPv6.]) - ], AC_MSG_RESULT(no),AC_MSG_RESULT(no)) -fi -dnl Check for inet_net_pton -AC_CHECK_FUNCS(inet_net_pton) -dnl Again, some systems have it, but not IPv6 -if test "$ac_cv_func_inet_net_pton" = "yes" ; then -AC_MSG_CHECKING(if inet_net_pton supports IPv6) -AC_TRY_RUN( - [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -int main() - { - struct in6_addr addr6; - if (inet_net_pton(AF_INET6, "::1", &addr6, sizeof(addr6)) < 1) - exit(1); - else - exit(0); - } - ], [ - AC_MSG_RESULT(yes) - AC_DEFINE_UNQUOTED(HAVE_INET_NET_PTON_IPV6,1,[Define to 1 if inet_net_pton supports IPv6.]) - ], AC_MSG_RESULT(no),AC_MSG_RESULT(no)) -fi - -AC_CHECK_SIZEOF(struct in6_addr, , -[ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -] -) -AC_CHECK_SIZEOF(struct in_addr, , -[ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -] -) - -AC_CHECK_FUNCS(bitncmp) - - -AC_OUTPUT(Makefile) +dnl Process this file with autoconf to produce a configure script. +AC_INIT(ares_init.c) +AM_CONFIG_HEADER(config.h) +AM_MAINTAINER_MODE +AM_INIT_AUTOMAKE(c-ares, CVS) + +AC_PROG_CC +AC_PROG_INSTALL + +case $host_os in +solaris*) + AC_DEFINE(ETC_INET, 1, [if a /etc/inet dir is being used]) + ;; +esac + +# check for ssize_t +AC_CHECK_TYPE(ssize_t, , + AC_DEFINE(ssize_t, int, [the signed version of size_t])) + +AC_SEARCH_LIBS(gethostbyname, nsl) +AC_SEARCH_LIBS(socket, socket) + +dnl ************************************************************ +dnl Option to switch on debug options. This makes an assumption that +dnl this is built as an 'ares' subdir in the curl source tree. Subject for +dnl improval in the future! +dnl +AC_MSG_CHECKING([whether to enable debug options]) +AC_ARG_ENABLE(debug, +AC_HELP_STRING([--enable-debug],[Enable pedantic debug options]) +AC_HELP_STRING([--disable-debug],[Disable debug options]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + ;; + *) AC_MSG_RESULT(yes) + + dnl when doing the debug stuff, use static library only + AC_DISABLE_SHARED + + dnl Checks for standard header files, to make memdebug.h inclusions bettter + AC_HEADER_STDC + + dnl the entire --enable-debug is a hack that lives and runs on top of + dnl libcurl stuff so this BUILDING_LIBCURL is not THAT much uglier + AC_DEFINE(BUILDING_LIBCURL, 1, [when building as static part of libcurl]) + + CPPFLAGS="$CPPFLAGS -DCURLDEBUG -I$srcdir/../include" + CFLAGS="$CFLAGS -g" + + dnl set compiler "debug" options to become more picky, and remove + dnl optimize options from CFLAGS + CURL_CC_DEBUG_OPTS + + ;; + esac ], + AC_MSG_RESULT(no) +) + +AC_PROG_LIBTOOL + +dnl check for a few basic system headers we need +AC_CHECK_HEADERS( + sys/types.h \ + sys/time.h \ + sys/select.h \ + sys/socket.h \ + winsock.h \ + netinet/in.h \ + arpa/nameser.h \ + arpa/nameser_compat.h \ + arpa/inet.h, , , +[ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +dnl We do this default-include simply to make sure that the nameser_compat.h +dnl header *REALLY* can be include after the new nameser.h. It seems AIX 5.1 +dnl (and others?) is not designed to allow this. +#ifdef HAVE_ARPA_NAMESER_H +#include +#endif +] + ) + +dnl check for AF_INET6 +CARES_CHECK_CONSTANT( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif + + ], [PF_INET6], + AC_DEFINE_UNQUOTED(HAVE_PF_INET6,1,[Define to 1 if you have PF_INET6.]) +) + +dnl check for PF_INET6 +CARES_CHECK_CONSTANT( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif + + ], [AF_INET6], + AC_DEFINE_UNQUOTED(HAVE_AF_INET6,1,[Define to 1 if you have AF_INET6.]) +) + + +dnl check for the in6_addr structure +CARES_CHECK_STRUCT( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif + ], [in6_addr], + AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.]) +) + +dnl check for inet_pton +AC_CHECK_FUNCS(inet_pton) +dnl Some systems have it, but not IPv6 +if test "$ac_cv_func_inet_pton" = "yes" ; then +AC_MSG_CHECKING(if inet_pton supports IPv6) +AC_TRY_RUN( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +int main() + { + struct in6_addr addr6; + if (inet_pton(AF_INET6, "::1", &addr6) < 1) + exit(1); + else + exit(0); + } + ], [ + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_INET_PTON_IPV6,1,[Define to 1 if inet_pton supports IPv6.]) + ], AC_MSG_RESULT(no),AC_MSG_RESULT(no)) +fi +dnl Check for inet_net_pton +AC_CHECK_FUNCS(inet_net_pton) +dnl Again, some systems have it, but not IPv6 +if test "$ac_cv_func_inet_net_pton" = "yes" ; then +AC_MSG_CHECKING(if inet_net_pton supports IPv6) +AC_TRY_RUN( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +int main() + { + struct in6_addr addr6; + if (inet_net_pton(AF_INET6, "::1", &addr6, sizeof(addr6)) < 1) + exit(1); + else + exit(0); + } + ], [ + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_INET_NET_PTON_IPV6,1,[Define to 1 if inet_net_pton supports IPv6.]) + ], AC_MSG_RESULT(no),AC_MSG_RESULT(no)) +fi + + +dnl Check for inet_ntop +AC_CHECK_FUNCS(inet_ntop) +dnl Again, some systems have it, but not IPv6 +if test "$ac_cv_func_inet_ntop" = "yes" ; then +AC_MSG_CHECKING(if inet_ntop supports IPv6) +AC_TRY_RUN( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#include +int main() + { + struct in6_addr addr6; + char buf[128]; + if (inet_ntop(AF_INET6, &addr6, buf, 128) == 0 && errno == EAFNOSUPPORT) + exit(1); + else + exit(0); + } + ], [ + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6,1,[Define to 1 if inet_ntop supports IPv6.]) + ], AC_MSG_RESULT(no),AC_MSG_RESULT(no)) +fi + +AC_CHECK_SIZEOF(struct in6_addr, , +[ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +] +) +AC_CHECK_SIZEOF(struct in_addr, , +[ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +] +) + +AC_CHECK_FUNCS(bitncmp) + + +AC_OUTPUT(Makefile) diff --git a/ares/inet_ntop.c b/ares/inet_ntop.c new file mode 100644 index 000000000..ff44f82b0 --- /dev/null +++ b/ares/inet_ntop.c @@ -0,0 +1,210 @@ +/* Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include "setup.h" + +#include + +#if defined(WIN32) && !defined(WATT32) +#include "nameser.h" +#else +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_NAMESER_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#endif + +#include +#include +#include +#include +#include + +#include "ares_ipv6.h" +#include "inet_ntop.h" + + +#if !defined(HAVE_INET_NTOP) || !defined(HAVE_INET_NTOP_IPV6) + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size); +static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size); + +/* char * + * inet_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +inet_ntop(int af, const void *src, char *dst, size_t size) +{ + + switch (af) { + case AF_INET: + return (inet_ntop4(src, dst, size)); +#ifdef INET6 + case AF_INET6: + return (inet_ntop6(src, dst, size)); +#endif + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address, more or less like inet_ntoa() + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a unsigned char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop4(const unsigned char *src, char *dst, size_t size) +{ + static const char fmt[] = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + + if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} + +#ifdef INET6 +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop6(const unsigned char *src, char *dst, size_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best, cur; + unsigned int words[IN6ADDRSZ / INT16SZ]; + int i; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; + } + tp += SPRINTF((tp, "%x", words[i])); + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} +#endif + +#endif diff --git a/ares/inet_ntop.h b/ares/inet_ntop.h new file mode 100644 index 000000000..f9a1d92f7 --- /dev/null +++ b/ares/inet_ntop.h @@ -0,0 +1,26 @@ +/* $Id$ */ + +/* + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#ifndef INET_NTOP_H +#define INET_NTOP_H + +#ifdef HAVE_INET_NTOP +#define ares_inet_ntop(w,x,y,z) inet_ntop(w,x,y,z) +#else +const char *ares_inet_ntop(int af, const void *src, char *dst, size_t size); +#endif + +#endif /* INET_NET_NTOP_H */