aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominick Meglio <dcm5151@esu.edu>2005-05-16 18:06:54 +0000
committerDominick Meglio <dcm5151@esu.edu>2005-05-16 18:06:54 +0000
commit645729e94388d1db0f1b4b60b3b861a224b8c498 (patch)
tree0b328b0413d27ac3964650f2cf73d645107e9714
parentf425a25c988205d1ca6df8c02f87abe23f28b067 (diff)
Added ares_getnameinfo which mimics the getnameinfo API
-rw-r--r--ares/CHANGES5
-rw-r--r--ares/Makefile.inc21
-rw-r--r--ares/acinclude.m4316
-rw-r--r--ares/ares.h30
-rw-r--r--ares/ares_getnameinfo.3145
-rw-r--r--ares/ares_getnameinfo.c322
-rw-r--r--ares/ares_ipv6.h19
-rw-r--r--ares/ares_strerror.c3
-rw-r--r--ares/configure.ac606
-rw-r--r--ares/setup.h1
10 files changed, 1034 insertions, 434 deletions
diff --git a/ares/CHANGES b/ares/CHANGES
index eb38613c1..858804065 100644
--- a/ares/CHANGES
+++ b/ares/CHANGES
@@ -1,5 +1,10 @@
Changelog for the c-ares project
+* May 16
+
+- Added ares_getnameinfo which mimics the getnameinfo API (another feature
+ that could use testing).
+
* May 14
- Added an inet_ntop function from BIND for systems that do not have it.
diff --git a/ares/Makefile.inc b/ares/Makefile.inc
index 121fa6bb7..80ad621e4 100644
--- a/ares/Makefile.inc
+++ b/ares/Makefile.inc
@@ -1,17 +1,18 @@
-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
+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 ares_getnameinfo.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
+HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h \
+ nameser.h inet_net_pton.h inet_ntop.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
+ ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3
diff --git a/ares/acinclude.m4 b/ares/acinclude.m4
index 2d4aa918f..1b197f0a0 100644
--- a/ares/acinclude.m4
+++ b/ares/acinclude.m4
@@ -1,148 +1,168 @@
-
-dnl We create a function for detecting which compiler we use and then set as
-dnl pendantic compiler options as possible for that particular compiler. The
-dnl options are only used for debug-builds.
-
-dnl This is a copy of the original found in curl's configure script. Don't
-dnl modify this one, edit the one in curl and copy it back here when that one
-dnl is changed.
-
-AC_DEFUN([CURL_CC_DEBUG_OPTS],
-[
- if test "$GCC" = "yes"; then
-
- dnl figure out gcc version!
- AC_MSG_CHECKING([gcc version])
- gccver=`$CC -dumpversion`
- num1=`echo $gccver | cut -d . -f1`
- num2=`echo $gccver | cut -d . -f2`
- gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null`
- AC_MSG_RESULT($gccver)
-
- AC_MSG_CHECKING([if this is icc in disguise])
- AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER],
- dnl action if the text is found, this it has not been replaced by the
- dnl cpp
- ICC="no"
- AC_MSG_RESULT([no]),
- dnl the text was not found, it was replaced by the cpp
- ICC="yes"
- AC_MSG_RESULT([yes])
- )
-
- if test "$ICC" = "yes"; then
- dnl this is icc, not gcc.
-
- dnl ICC warnings we ignore:
- dnl * 279 warns on static conditions in while expressions
- dnl * 269 warns on our "%Od" printf formatters for curl_off_t output:
- dnl "invalid format string conversion"
-
- WARN="-wd279,269"
-
- if test "$gccnum" -gt "600"; then
- dnl icc 6.0 and older doesn't have the -Wall flag
- WARN="-Wall $WARN"
- fi
- else dnl $ICC = yes
- dnl
- WARN="-W -Wall -Wwrite-strings -pedantic -Wno-long-long -Wundef -Wpointer-arith -Wnested-externs -Winline -Wmissing-declarations -Wmissing-prototypes -Wsign-compare"
-
- dnl -Wcast-align is a bit too annoying ;-)
-
- if test "$gccnum" -ge "296"; then
- dnl gcc 2.96 or later
- WARN="$WARN -Wfloat-equal"
-
- if test "$gccnum" -gt "296"; then
- dnl this option does not exist in 2.96
- WARN="$WARN -Wno-format-nonliteral"
- fi
-
- dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on
- dnl on i686-Linux as it gives us heaps with false positives
- if test "$gccnum" -ge "303"; then
- dnl gcc 3.3 and later
- WARN="$WARN -Wendif-labels -Wstrict-prototypes"
- fi
- fi
-
- for flag in $CPPFLAGS; do
- case "$flag" in
- -I*)
- dnl include path
- add=`echo $flag | sed 's/^-I/-isystem /g'`
- WARN="$WARN $add"
- ;;
- esac
- done
-
- fi dnl $ICC = no
-
- CFLAGS="$CFLAGS $WARN"
-
- fi dnl $GCC = yes
-
- dnl strip off optimizer flags
- NEWFLAGS=""
- for flag in $CFLAGS; do
- case "$flag" in
- -O*)
- dnl echo "cut off $flag"
- ;;
- *)
- NEWFLAGS="$NEWFLAGS $flag"
- ;;
- esac
- done
- CFLAGS=$NEWFLAGS
-
-]) dnl end of AC_DEFUN()
-
-
-dnl This macro determines if the specified struct exists in the specified file
-dnl Syntax:
-dnl CARES_CHECK_STRUCT(headers, struct name, if found, [if not found])
-
-AC_DEFUN([CARES_CHECK_STRUCT], [
- AC_MSG_CHECKING([for struct $2])
- AC_TRY_COMPILE([$1],
- [
- struct $2 struct_instance;
- ], ac_struct="yes", ac_found="no")
- if test "$ac_struct" = "yes" ; then
- AC_MSG_RESULT(yes)
- $3
- else
- AC_MSG_RESULT(no)
- $4
- fi
-])
-
-dnl This macro determines if the specified constant exists in the specified file
-dnl Syntax:
-dnl CARES_CHECK_CONSTANT(headers, constant name, if found, [if not found])
-
-AC_DEFUN([CARES_CHECK_CONSTANT], [
- AC_MSG_CHECKING([for $2])
- AC_EGREP_CPP(VARIABLEWASDEFINED,
- [
- $1
-
- #ifdef $2
- VARIABLEWASDEFINED
- #else
- NJET
- #endif
- ], ac_constant="yes", ac_constant="no"
- )
- if test "$ac_constant" = "yes" ; then
- AC_MSG_RESULT(yes)
- $3
- else
- AC_MSG_RESULT(no)
- $4
- fi
-])
-
-
+
+dnl We create a function for detecting which compiler we use and then set as
+dnl pendantic compiler options as possible for that particular compiler. The
+dnl options are only used for debug-builds.
+
+dnl This is a copy of the original found in curl's configure script. Don't
+dnl modify this one, edit the one in curl and copy it back here when that one
+dnl is changed.
+
+AC_DEFUN([CURL_CC_DEBUG_OPTS],
+[
+ if test "$GCC" = "yes"; then
+
+ dnl figure out gcc version!
+ AC_MSG_CHECKING([gcc version])
+ gccver=`$CC -dumpversion`
+ num1=`echo $gccver | cut -d . -f1`
+ num2=`echo $gccver | cut -d . -f2`
+ gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null`
+ AC_MSG_RESULT($gccver)
+
+ AC_MSG_CHECKING([if this is icc in disguise])
+ AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER],
+ dnl action if the text is found, this it has not been replaced by the
+ dnl cpp
+ ICC="no"
+ AC_MSG_RESULT([no]),
+ dnl the text was not found, it was replaced by the cpp
+ ICC="yes"
+ AC_MSG_RESULT([yes])
+ )
+
+ if test "$ICC" = "yes"; then
+ dnl this is icc, not gcc.
+
+ dnl ICC warnings we ignore:
+ dnl * 279 warns on static conditions in while expressions
+ dnl * 269 warns on our "%Od" printf formatters for curl_off_t output:
+ dnl "invalid format string conversion"
+
+ WARN="-wd279,269"
+
+ if test "$gccnum" -gt "600"; then
+ dnl icc 6.0 and older doesn't have the -Wall flag
+ WARN="-Wall $WARN"
+ fi
+ else dnl $ICC = yes
+ dnl
+ WARN="-W -Wall -Wwrite-strings -pedantic -Wno-long-long -Wundef -Wpointer-arith -Wnested-externs -Winline -Wmissing-declarations -Wmissing-prototypes -Wsign-compare"
+
+ dnl -Wcast-align is a bit too annoying ;-)
+
+ if test "$gccnum" -ge "296"; then
+ dnl gcc 2.96 or later
+ WARN="$WARN -Wfloat-equal"
+
+ if test "$gccnum" -gt "296"; then
+ dnl this option does not exist in 2.96
+ WARN="$WARN -Wno-format-nonliteral"
+ fi
+
+ dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on
+ dnl on i686-Linux as it gives us heaps with false positives
+ if test "$gccnum" -ge "303"; then
+ dnl gcc 3.3 and later
+ WARN="$WARN -Wendif-labels -Wstrict-prototypes"
+ fi
+ fi
+
+ for flag in $CPPFLAGS; do
+ case "$flag" in
+ -I*)
+ dnl include path
+ add=`echo $flag | sed 's/^-I/-isystem /g'`
+ WARN="$WARN $add"
+ ;;
+ esac
+ done
+
+ fi dnl $ICC = no
+
+ CFLAGS="$CFLAGS $WARN"
+
+ fi dnl $GCC = yes
+
+ dnl strip off optimizer flags
+ NEWFLAGS=""
+ for flag in $CFLAGS; do
+ case "$flag" in
+ -O*)
+ dnl echo "cut off $flag"
+ ;;
+ *)
+ NEWFLAGS="$NEWFLAGS $flag"
+ ;;
+ esac
+ done
+ CFLAGS=$NEWFLAGS
+
+]) dnl end of AC_DEFUN()
+
+
+dnl This macro determines if the specified struct exists in the specified file
+dnl Syntax:
+dnl CARES_CHECK_STRUCT(headers, struct name, if found, [if not found])
+
+AC_DEFUN([CARES_CHECK_STRUCT], [
+ AC_MSG_CHECKING([for struct $2])
+ AC_TRY_COMPILE([$1],
+ [
+ struct $2 struct_instance;
+ ], ac_struct="yes", ac_found="no")
+ if test "$ac_struct" = "yes" ; then
+ AC_MSG_RESULT(yes)
+ $3
+ else
+ AC_MSG_RESULT(no)
+ $4
+ fi
+])
+
+dnl This macro determins if the specified struct contains a specific member.
+dnl Syntax:
+dnl CARES_CHECK_STRUCT_MEMBER(headers, struct name, member name, if found, [if not found])
+
+AC_DEFUN([CARES_CHECK_STRUCT_MEMBER], [
+ AC_MSG_CHECKING([if struct $2 has member $3])
+ AC_TRY_COMPILE([$1],
+ [
+ struct $2 struct_instance;
+ struct_instance.$3 = 0;
+ ], ac_struct="yes", ac_found="no")
+ if test "$ac_struct" = "yes" ; then
+ AC_MSG_RESULT(yes)
+ $4
+ else
+ AC_MSG_RESULT(no)
+ $5
+ fi
+])
+
+dnl This macro determines if the specified constant exists in the specified file
+dnl Syntax:
+dnl CARES_CHECK_CONSTANT(headers, constant name, if found, [if not found])
+
+AC_DEFUN([CARES_CHECK_CONSTANT], [
+ AC_MSG_CHECKING([for $2])
+ AC_EGREP_CPP(VARIABLEWASDEFINED,
+ [
+ $1
+
+ #ifdef $2
+ VARIABLEWASDEFINED
+ #else
+ NJET
+ #endif
+ ], ac_constant="yes", ac_constant="no"
+ )
+ if test "$ac_constant" = "yes" ; then
+ AC_MSG_RESULT(yes)
+ $3
+ else
+ AC_MSG_RESULT(no)
+ $4
+ fi
+])
+
+
diff --git a/ares/ares.h b/ares/ares.h
index d032de434..01a6b8ac3 100644
--- a/ares/ares.h
+++ b/ares/ares.h
@@ -29,12 +29,14 @@
#if defined(WATT32)
#include <netinet/in.h>
+ #include <sys/socket.h>
#include <tcp.h>
#elif defined(WIN32)
#include <winsock.h>
#include <windows.h>
#else
#include <netinet/in.h>
+ #include <sys/socket.h>
#endif
#ifdef __cplusplus
@@ -64,6 +66,9 @@ extern "C" {
#define ARES_EDESTRUCTION 16
#define ARES_EBADSTR 17
+/* ares_getnameinfo error codes */
+#define ARES_EBADFLAGS 18
+
/* Flag values */
#define ARES_FLAG_USEVC (1 << 0)
#define ARES_FLAG_PRIMARY (1 << 1)
@@ -85,6 +90,24 @@ extern "C" {
#define ARES_OPT_DOMAINS (1 << 7)
#define ARES_OPT_LOOKUPS (1 << 8)
+/* Nameinfo flag values */
+#define ARES_NI_NOFQDN (1 << 0)
+#define ARES_NI_NUMERICHOST (1 << 1)
+#define ARES_NI_NAMEREQD (1 << 2)
+#define ARES_NI_NUMERICSERV (1 << 3)
+#define ARES_NI_DGRAM (1 << 4)
+#define ARES_NI_TCP 0
+#define ARES_NI_UDP ARES_NI_DGRAM
+#define ARES_NI_SCTP (1 << 5)
+#define ARES_NI_DCCP (1 << 6)
+#define ARES_NI_NUMERICSCOPE (1 << 7)
+#define ARES_NI_LOOKUPHOST (1 << 8)
+#define ARES_NI_LOOKUPSERVICE (1 << 9)
+/* Reserved for future use */
+#define ARES_NI_IDN (1 << 10)
+#define ARES_NI_ALLOW_UNASSIGNED (1 << 11)
+#define ARES_NI_USE_STD3_ASCII_RULES (1 << 12)
+
struct ares_options {
int flags;
int timeout;
@@ -101,12 +124,15 @@ struct ares_options {
struct hostent;
struct timeval;
+struct sockaddr;
struct ares_channeldata;
typedef struct ares_channeldata *ares_channel;
typedef void (*ares_callback)(void *arg, int status, unsigned char *abuf,
int alen);
typedef void (*ares_host_callback)(void *arg, int status,
struct hostent *hostent);
+typedef void (*ares_nameinfo_callback)(void *arg, int status,
+ char *node, char *service);
int ares_init(ares_channel *channelptr);
int ares_init_options(ares_channel *channelptr, struct ares_options *options,
@@ -123,7 +149,9 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
ares_host_callback callback, void *arg);
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
int family, ares_host_callback callback, void *arg);
-
+void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
+ socklen_t salen, int flags, ares_nameinfo_callback callback,
+ void *arg);
int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
struct timeval *tv);
diff --git a/ares/ares_getnameinfo.3 b/ares/ares_getnameinfo.3
new file mode 100644
index 000000000..9b6bd73a9
--- /dev/null
+++ b/ares/ares_getnameinfo.3
@@ -0,0 +1,145 @@
+.\" $Id$
+.\"
+.\" Copyright 2005 by Dominick Meglio.
+.\"
+.\" 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.
+.\"
+.TH ARES_GETNAMEINFO 3 "16 May 2005"
+.SH NAME
+ares_getnameinfo \- Address-to-nodename translation in protocol-independent manner
+.SH SYNOPSIS
+.nf
+.B #include <ares.h>
+.PP
+.B typedef void (*ares_nameinfo_callback)(void *\fIarg\fP, int \fIstatus\fP,
+.B char *\fInode\fP, char *\fIservice\fP)
+.PP
+.B void ares_getnameinfo(ares_channel \fIchannel\fP, const struct sockaddr *\fIsa\fP,
+.B socklen_t \fIsalen\fP, int \fIflags\fP, ares_nameinfo_callback \fIcallback\fP,
+.B void *\fIarg\fP)
+.fi
+.SH DESCRIPTION
+The
+.B ares_getnameinfo
+function is defined for protocol-independent address translation. The function
+is a combination of \fIares_gethostbyaddr(3)\fP and \fIgetservbyport(3)\fP. The function will
+translate the address either by executing a host query on the name service channel
+identified by
+.IR channel
+or it will attempt to resolve it locally if possible.
+The parameters
+.I sa
+and
+.I len
+give the address as a sockaddr structure, and
+.I flags
+gives the options that the function will use. Valid flags are listed below:
+.TP 19
+.B ARES_NI_NOFQDN
+Only the nodename portion of the FQDN is returned for local hosts.
+.TP 19
+.B ARES_NI_NUMERICHOST
+The numeric form of the hostname is returned rather than the name.
+.TP 19
+.B ARES_NI_NAMEREQD
+An error is returned if the hostname cannot be found in the DNS.
+.TP 19
+.B ARES_NI_NUMERICSERV
+The numeric form of the service is returned rather than the name.
+.TP 19
+.B ARES_NI_TCP
+The service name is to be looked up for the TCP protocol.
+.TP 19
+.B ARES_NI_UDP
+The service name is to be looked up for the UDP protocol.
+.TP 19
+.B ARES_NI_SCTP
+The service name is to be looked up for the SCTP protocol.
+.TP 19
+.B ARES_NI_DCCP
+The service name is to be looked up for the DCCP protocol.
+.TP 19
+.B ARES_NI_NUMERICSCOPE
+The numeric form of the scope ID is returned rather than the name.
+.TP 19
+.B ARES_NI_LOOKUPHOST
+A hostname lookup is being requested.
+.TP 19
+.B ARES_NI_LOOKUPSERVICE
+A service name lookup is being requested.
+.PP
+When the query
+is complete or has
+failed, the ares library will invoke \fIcallback\fP. Completion or failure of
+the query may happen immediately, or may happen during a later call to
+\fIares_process(3)\fP, \fIares_destroy(3)\fP or \fIares_cancel(3)\fP.
+.PP
+The callback argument
+.I arg
+is copied from the
+.B ares_getnameinfo
+argument
+.IR arg .
+The callback argument
+.I status
+indicates whether the query succeeded and, if not, how it failed. It
+may have any of the following values:
+.TP 19
+.B ARES_SUCCESS
+The host lookup completed successfully.
+.TP 19
+.B ARES_ENOTIMP
+The ares library does not know how to look up addresses of type
+.IR family .
+.TP 19
+.B ARES_ENOTFOUND
+The address
+.I addr
+was not found.
+.TP 19
+.B ARES_ENOMEM
+Memory was exhausted.
+.TP 19
+.B ARES_EDESTRUCTION
+The name service channel
+.I channel
+is being destroyed; the query will not be completed.
+.TP 19
+.B ARES_EBADFLAGS
+The
+.I flags
+parameter contains an illegal value.
+.PP
+On successful completion of the query, the callback argument
+.I node
+contains a string representing the hostname (assuming
+.B ARES_NI_LOOKUPHOST
+was specified). Additionally,
+.I service
+contains a string representing the service name (assuming
+.B ARES_NI_LOOKUPSERVICE
+was specified).
+If the query did not complete successfully, or one of the values
+was not requested,
+.I node
+or
+.I service
+will be
+.BR NULL .
+.SH SEE ALSO
+.BR ares_process (3),
+.BR ares_getaddrinfo (3)
+.SH AUTHOR
+Dominick Meglio
+.br
+Copyright 2005 by Dominick Meglio.
diff --git a/ares/ares_getnameinfo.c b/ares/ares_getnameinfo.c
new file mode 100644
index 000000000..955207a2e
--- /dev/null
+++ b/ares/ares_getnameinfo.c
@@ -0,0 +1,322 @@
+/* Copyright 2005 by Dominick Meglio
+ *
+ * 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.
+ */
+#include "setup.h"
+#include <sys/types.h>
+
+#if defined(WIN32) && !defined(WATT32)
+#include "nameser.h"
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/nameser.h>
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#include <arpa/nameser_compat.h>
+#endif
+#endif
+
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ares.h"
+#include "ares_private.h"
+#include "ares_ipv6.h"
+#include "inet_ntop.h"
+
+#ifdef WATT32
+#undef WIN32
+#endif
+
+struct nameinfo_query {
+ ares_nameinfo_callback callback;
+ void *arg;
+ union {
+ struct sockaddr_in addr4;
+ struct sockaddr_in6 addr6;
+ } addr;
+ int family;
+ int flags;
+};
+
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+#define IPBUFSIZ 40+IF_NAMESIZE
+#else
+#define IPBUFSIZ 40
+#endif
+
+static void nameinfo_callback(void *arg, int status, struct hostent *host);
+static char *lookup_service(unsigned short port, int flags, char *buf);
+static char *append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid, char *buf);
+static char *ares_striendstr(const char *s1, const char *s2);
+
+void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t salen,
+ int flags, ares_nameinfo_callback callback, void *arg)
+{
+ struct sockaddr_in *addr;
+ struct sockaddr_in6 *addr6;
+ struct nameinfo_query *niquery;
+
+ /* Verify the buffer size */
+ if (salen == sizeof(struct sockaddr_in))
+ addr = (struct sockaddr_in *)sa;
+ else if (salen == sizeof(struct sockaddr_in6))
+ addr6 = (struct sockaddr_in6 *)sa;
+ else
+ {
+ callback(arg, ARES_ENOTIMP, NULL, NULL);
+ return;
+ }
+
+ /* If neither, assume they want a host */
+ if (!(flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST))
+ flags |= ARES_NI_LOOKUPHOST;
+
+ /* All they want is a service, no need for DNS */
+ if ((flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST))
+ {
+ char buf[33], *service;
+ unsigned int port = 0;
+
+ if (salen == sizeof(struct sockaddr_in))
+ port = addr->sin_port;
+ else
+ port = addr6->sin6_port;
+ service = lookup_service(port, flags, buf);
+ callback(arg, ARES_SUCCESS, NULL, service);
+ return;
+ }
+
+ /* They want a host lookup */
+ if ((flags & ARES_NI_LOOKUPHOST))
+ {
+ /* A numeric host can be handled without DNS */
+ if ((flags & ARES_NI_NUMERICHOST))
+ {
+ unsigned int port = 0;
+ char ipbuf[IPBUFSIZ];
+ char srvbuf[32];
+ char *service = NULL;
+ ipbuf[0] = 0;
+
+ /* Specifying not to lookup a host, but then saying a host
+ * is required has to be illegal.
+ */
+ if (flags & ARES_NI_NAMEREQD)
+ {
+ callback(arg, ARES_EBADFLAGS, NULL, NULL);
+ return;
+ }
+ if (salen == sizeof(struct sockaddr_in6))
+ {
+ ares_inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, IPBUFSIZ);
+ port = addr6->sin6_port;
+ /* If the system supports scope IDs, use it */
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+ append_scopeid(addr6, flags, ipbuf);
+#endif
+ }
+ else
+ {
+ ares_inet_ntop(AF_INET, &addr->sin_addr, ipbuf, IPBUFSIZ);
+ port = addr->sin_port;
+ }
+ /* They also want a service */
+ if (flags & ARES_NI_LOOKUPSERVICE)
+ service = lookup_service(port, flags, srvbuf);
+ callback(arg, ARES_SUCCESS, ipbuf, service);
+ return;
+ }
+ /* This is where a DNS lookup becomes necessary */
+ else
+ {
+ niquery = malloc(sizeof(struct nameinfo_query));
+ if (!niquery)
+ {
+ callback(arg, ARES_ENOMEM, NULL, NULL);
+ return;
+ }
+ niquery->callback = callback;
+ niquery->arg = arg;
+ niquery->flags = flags;
+ if (sa->sa_family == AF_INET)
+ {
+ niquery->family = AF_INET;
+ memcpy(&niquery->addr.addr4, addr, sizeof(addr));
+ ares_gethostbyaddr(channel, &addr->sin_addr, sizeof(struct in_addr), AF_INET,
+ nameinfo_callback, niquery);
+ }
+ else
+ {
+ niquery->family = AF_INET6;
+ memcpy(&niquery->addr.addr6, addr6, sizeof(addr6));
+ ares_gethostbyaddr(channel, &addr6->sin6_addr, sizeof(struct in6_addr), AF_INET6,
+ nameinfo_callback, niquery);
+ }
+ }
+ }
+}
+
+static void nameinfo_callback(void *arg, int status, struct hostent *host)
+{
+ struct nameinfo_query *niquery = (struct nameinfo_query *) arg;
+ char srvbuf[33];
+ char *service = NULL;
+
+
+ if (status == ARES_SUCCESS)
+ {
+ /* They want a service too */
+ if (niquery->flags & ARES_NI_LOOKUPSERVICE)
+ {
+ if (niquery->family == AF_INET)
+ service = lookup_service(niquery->addr.addr4.sin_port, niquery->flags, srvbuf);
+ else
+ service = lookup_service(niquery->addr.addr6.sin6_port, niquery->flags, srvbuf);
+ }
+ /* NOFQDN means we have to strip off the domain name portion.
+ We do this by determining our own domain name, then searching the string
+ for this domain name and removing it.
+ */
+ if (niquery->flags & ARES_NI_NOFQDN)
+ {
+ char buf[255];
+ char *domain;
+ gethostname(buf, 255);
+ if ((domain = strchr(buf, '.')))
+ {
+ char *end = ares_striendstr(host->h_name, domain);
+ if (end)
+ *end = 0;
+ }
+ }
+ callback(niquery->arg, ARES_SUCCESS, host->h_name, service);
+ return;
+ }
+ /* We couldn't find the host, but it's OK, we can use the IP */
+ else if (status == ARES_ENOTFOUND && !(niquery->flags & ARES_NI_NAMEREQD))
+ {
+ char ipbuf[IPBUFSIZ];
+ if (niquery->family == AF_INET)
+ ares_inet_ntop(AF_INET, &niquery->addr.addr4.sin_addr, ipbuf, IPBUFSIZ);
+ else
+ {
+ ares_inet_ntop(AF_INET6, &niquery->addr.addr6.sin6_addr, ipbuf, IPBUFSIZ);
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+ append_scopeid(&niquery->addr.addr6, niquery->flags, ipbuf);
+#endif
+ }
+ /* They want a service too */
+ if (niquery->flags & ARES_NI_LOOKUPSERVICE)
+ {
+ if (niquery->family == AF_INET)
+ service = lookup_service(niquery->addr.addr4.sin_port, niquery->flags, srvbuf);
+ else
+ service = lookup_service(niquery->addr.addr6.sin6_port, niquery->flags, srvbuf);
+ }
+ callback(niquery->arg, ARES_SUCCESS, ipbuf, service);
+ return;
+ }
+ callback(niquery->arg, status, NULL, NULL);
+ free(niquery);
+}
+
+static char *lookup_service(unsigned short port, int flags, char *buf)
+{
+ if (port)
+ {
+ /* Just return the port as a string */
+ if (flags & ARES_NI_NUMERICSERV)
+ sprintf(buf, "%u", ntohs(port));
+ else
+ {
+ struct servent *se;
+ char *proto;
+
+ if (flags & ARES_NI_UDP)
+ proto = "udp";
+ else if (flags & ARES_NI_SCTP)
+ proto = "sctp";
+ else if (flags & ARES_NI_DCCP)
+ proto = "dccp";
+ else
+ proto = "tcp";
+ se = getservbyport(port, proto);
+ if (se && se->s_name)
+ strcpy(buf, se->s_name);
+ else
+ sprintf(buf, "%u", ntohs(port));
+ }
+ return buf;
+ }
+ return NULL;
+}
+
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+static char *append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags, char *buf)
+{
+ char tmpbuf[IF_NAMESIZE + 1];
+
+ tmpbuf[0] = '%';
+#ifdef HAVE_IF_INDEXTONAME
+ if ((flags & ARES_NI_NUMERICSCOPE) || (!IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)
+ && !IN6_IS_ADDR_MC_LINKLOCAL(&addr6->sin6_addr)))
+ {
+ sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id);
+ }
+ else
+ {
+ if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL)
+ sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id);
+ }
+#else
+ sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id);
+#endif
+ strcat(buf, tmpbuf);
+ return buf;
+}
+#endif
+
+/* Determines if s1 ends with the string in s2 (case-insensitive) */
+static char *ares_striendstr(const char *s1, const char *s2)
+{
+ const char *c1, *c2, *c1_begin;
+ size_t s1_len = strlen(s1), s2_len = strlen(s2);
+
+ /* If the substr is longer than the full str, it can't match */
+ if (s2_len > s1_len)
+ return NULL;
+
+ /* Jump to the end of s1 minus the length of s2 */
+ c1 = (const char *)c1_begin = s1+s1_len-s2_len;
+ c2 = s2;
+ while (c2 < s2+s2_len)
+ {
+ if (tolower(*c1) != tolower(*c2))
+ return NULL;
+ else
+ {
+ c1++;
+ c2++;
+ }
+ }
+ if (c2 == c1 == NULL)
+ return c1_begin;
+ return NULL;
+}
diff --git a/ares/ares_ipv6.h b/ares/ares_ipv6.h
index 3a5bd0699..79a37c401 100644
--- a/ares/ares_ipv6.h
+++ b/ares/ares_ipv6.h
@@ -28,6 +28,17 @@ struct in6_addr
};
#endif
+#ifndef HAVE_STRUCT_SOCKADDR_IN6
+struct sockaddr_in6
+{
+ unsigned short sin6_family;
+ unsigned short sin6_port;
+ unsigned long sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ unsigned int sin6_scope_id;
+};
+#endif
+
#ifndef NS_IN6ADDRSZ
#if SIZEOF_STRUCT_IN6_ADDR == 0
/* We cannot have it set to zero, so we pick a fixed value here */
@@ -45,4 +56,12 @@ struct in6_addr
#define NS_INT16SZ 2
#endif
+#ifndef IF_NAMESIZE
+#ifdef IFNAMSIZ
+#define IF_NAMESIZE IFNAMSIZ
+#else
+#define IF_NAMESIZE 256
+#endif
+#endif
+
#endif /* ARES_IPV6_H */
diff --git a/ares/ares_strerror.c b/ares/ares_strerror.c
index 5681b93ca..6e9fa0edd 100644
--- a/ares/ares_strerror.c
+++ b/ares/ares_strerror.c
@@ -38,7 +38,8 @@ const char *ares_strerror(int code)
"Error reading file",
"Out of memory",
"Channel is being destroyed",
- "Misformatted string"
+ "Misformatted string",
+ "Illegal flags specified"
};
assert(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext)));
diff --git a/ares/configure.ac b/ares/configure.ac
index 9239957da..120119812 100644
--- a/ares/configure.ac
+++ b/ares/configure.ac
@@ -1,274 +1,332 @@
-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 <sys/types.h>
-#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 <arpa/nameser.h>
-#endif
-]
- )
-
-dnl check for AF_INET6
-CARES_CHECK_CONSTANT(
- [
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_WINSOCK_H
-#include <winsock.h>
-#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 <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_WINSOCK_H
-#include <winsock.h>
-#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 <sys/types.h>
-#endif
-#ifdef HAVE_WINSOCK_H
-#include <winsock.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#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 <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_WINSOCK_H
-#include <winsock.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#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 <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_WINSOCK_H
-#include <winsock.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#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 <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_WINSOCK_H
-#include <winsock.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#include <errno.h>
-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 <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_WINSOCK_H
-#include <winsock.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-]
-)
-AC_CHECK_SIZEOF(struct in_addr, ,
-[
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_WINSOCK_H
-#include <winsock.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#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 \
+ net/if.h \
+ arpa/nameser.h \
+ arpa/nameser_compat.h \
+ arpa/inet.h, , ,
+[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#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 <arpa/nameser.h>
+#endif
+
+dnl *Sigh* these are needed in order for net/if.h to get properly detected.
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+]
+ )
+
+AC_CHECK_TYPE(socklen_t, ,
+ AC_DEFINE(socklen_t, int, [the length of a socket address]),
+ [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+ ])
+
+dnl check for AF_INET6
+CARES_CHECK_CONSTANT(
+ [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#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 <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#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 <sys/types.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+ ], [in6_addr],
+ AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.])
+)
+
+dnl check for the sockaddr_in6 structure
+CARES_CHECK_STRUCT(
+ [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+ ], [sockaddr_in6],
+ AC_DEFINE_UNQUOTED(HAVE_STRUCT_SOCKADDR_IN6,1,
+ [Define to 1 if you have struct sockaddr_in6.]) ac_have_sockaddr_in6=yes
+)
+
+if test "$ac_have_sockaddr_in6" = "yes" ; then
+CARES_CHECK_STRUCT_MEMBER(
+ [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+ ], [sockaddr_in6], [sin6_scope_id],
+ AC_DEFINE_UNQUOTED(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID,1,
+ [Define to 1 if your struct sockaddr_in6 has sin6_scope_id.])
+)
+fi
+
+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 <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#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 <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#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 <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <errno.h>
+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 <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+]
+)
+AC_CHECK_SIZEOF(struct in_addr, ,
+[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+]
+)
+
+AC_CHECK_FUNCS([bitncmp if_indextoname])
+
+
+AC_OUTPUT(Makefile)
diff --git a/ares/setup.h b/ares/setup.h
index e972702d5..619a285d2 100644
--- a/ares/setup.h
+++ b/ares/setup.h
@@ -19,6 +19,7 @@
#else
/* simple work-around for now, for systems without configure support */
#define ssize_t int
+#define socklen_t int
#endif
/* Recent autoconf versions define these symbols in config.h. We don't want