]> granicus.if.org Git - curl/commitdiff
Added ares_getnameinfo which mimics the getnameinfo API
authorDominick Meglio <dcm5151@esu.edu>
Mon, 16 May 2005 18:06:54 +0000 (18:06 +0000)
committerDominick Meglio <dcm5151@esu.edu>
Mon, 16 May 2005 18:06:54 +0000 (18:06 +0000)
ares/CHANGES
ares/Makefile.inc
ares/acinclude.m4
ares/ares.h
ares/ares_getnameinfo.3 [new file with mode: 0644]
ares/ares_getnameinfo.c [new file with mode: 0644]
ares/ares_ipv6.h
ares/ares_strerror.c
ares/configure.ac
ares/setup.h

index eb38613c1786b4b23c022e78a1b46ce122975843..858804065db6985636935463b51d5bd30e97bfb7 100644 (file)
@@ -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.
index 121fa6bb7c0f6eb10379bcb100b939d3487a568e..80ad621e47d0cc711c432de27f12a2657de4ce2c 100644 (file)
@@ -1,17 +1,18 @@
-CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c     \\r
-ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c \\r
-ares_gethostbyaddr.c ares_send.c ares__read_line.c ares_gethostbyname.c           \\r
-ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c           \\r
-ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c     \\r
-windows_port.c ares_expand_string.c ares_parse_ptr_reply.c                 \\r
-ares_parse_aaaa_reply.c inet_net_pton.c bitncmp.c inet_ntop.c\r
+CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c      \\r
+ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c  \\r
+ares_gethostbyaddr.c ares_send.c ares__read_line.c ares_gethostbyname.c            \\r
+ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c            \\r
+ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c      \\r
+windows_port.c ares_expand_string.c ares_parse_ptr_reply.c                  \\r
+ares_parse_aaaa_reply.c ares_getnameinfo.c inet_net_pton.c bitncmp.c        \\r
+inet_ntop.c\r
 \r
-HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h nameser.h \\r
-           inet_net_pton.h ares_ipv6.h bitncmp.h\r
+HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h          \\r
+           nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h\r
 \r
 MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \\r
  ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3               \\r
  ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3       \\r
  ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3                \\r
  ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3     \\r
- ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3\r
+ ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3\r
index 2d4aa918f6a39852e4e13013d581ad11ad3c11bc..1b197f0a064508c246b4b6ef4caea5db87d24912 100644 (file)
-
-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
-])
-
-
+\r
+dnl We create a function for detecting which compiler we use and then set as\r
+dnl pendantic compiler options as possible for that particular compiler. The\r
+dnl options are only used for debug-builds.\r
+\r
+dnl This is a copy of the original found in curl's configure script. Don't\r
+dnl modify this one, edit the one in curl and copy it back here when that one\r
+dnl is changed.\r
+\r
+AC_DEFUN([CURL_CC_DEBUG_OPTS],\r
+[\r
+    if test "$GCC" = "yes"; then\r
+\r
+       dnl figure out gcc version!\r
+       AC_MSG_CHECKING([gcc version])\r
+       gccver=`$CC -dumpversion`\r
+       num1=`echo $gccver | cut -d . -f1`\r
+       num2=`echo $gccver | cut -d . -f2`\r
+       gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null`\r
+       AC_MSG_RESULT($gccver)\r
+\r
+       AC_MSG_CHECKING([if this is icc in disguise])\r
+       AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER],\r
+         dnl action if the text is found, this it has not been replaced by the\r
+         dnl cpp\r
+         ICC="no"\r
+         AC_MSG_RESULT([no]),\r
+         dnl the text was not found, it was replaced by the cpp\r
+         ICC="yes"\r
+         AC_MSG_RESULT([yes])\r
+       )\r
+\r
+       if test "$ICC" = "yes"; then\r
+         dnl this is icc, not gcc.\r
+\r
+         dnl ICC warnings we ignore:\r
+         dnl * 279 warns on static conditions in while expressions\r
+         dnl * 269 warns on our "%Od" printf formatters for curl_off_t output:\r
+         dnl   "invalid format string conversion"\r
+\r
+         WARN="-wd279,269"\r
+\r
+         if test "$gccnum" -gt "600"; then\r
+            dnl icc 6.0 and older doesn't have the -Wall flag\r
+            WARN="-Wall $WARN"\r
+         fi\r
+       else dnl $ICC = yes\r
+         dnl \r
+         WARN="-W -Wall -Wwrite-strings -pedantic -Wno-long-long -Wundef -Wpointer-arith -Wnested-externs -Winline -Wmissing-declarations -Wmissing-prototypes -Wsign-compare"\r
+\r
+         dnl -Wcast-align is a bit too annoying ;-)\r
+\r
+         if test "$gccnum" -ge "296"; then\r
+           dnl gcc 2.96 or later\r
+           WARN="$WARN -Wfloat-equal"\r
+\r
+           if test "$gccnum" -gt "296"; then\r
+             dnl this option does not exist in 2.96\r
+             WARN="$WARN -Wno-format-nonliteral"\r
+           fi\r
+\r
+           dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on\r
+           dnl on i686-Linux as it gives us heaps with false positives\r
+           if test "$gccnum" -ge "303"; then\r
+             dnl gcc 3.3 and later\r
+             WARN="$WARN -Wendif-labels -Wstrict-prototypes"\r
+           fi\r
+         fi\r
+\r
+         for flag in $CPPFLAGS; do\r
+           case "$flag" in\r
+            -I*)\r
+              dnl include path\r
+              add=`echo $flag | sed 's/^-I/-isystem /g'`\r
+              WARN="$WARN $add"\r
+              ;;\r
+           esac\r
+         done\r
+\r
+       fi dnl $ICC = no\r
+\r
+       CFLAGS="$CFLAGS $WARN"\r
+\r
+    fi dnl $GCC = yes\r
+\r
+    dnl strip off optimizer flags\r
+    NEWFLAGS=""\r
+    for flag in $CFLAGS; do\r
+      case "$flag" in\r
+      -O*)\r
+        dnl echo "cut off $flag"\r
+        ;;\r
+      *)\r
+        NEWFLAGS="$NEWFLAGS $flag"\r
+        ;;\r
+      esac\r
+    done\r
+    CFLAGS=$NEWFLAGS\r
+\r
+]) dnl end of AC_DEFUN()\r
+\r
+\r
+dnl This macro determines if the specified struct exists in the specified file\r
+dnl Syntax:\r
+dnl CARES_CHECK_STRUCT(headers, struct name, if found, [if not found])\r
+\r
+AC_DEFUN([CARES_CHECK_STRUCT], [\r
+  AC_MSG_CHECKING([for struct $2])\r
+  AC_TRY_COMPILE([$1], \r
+    [\r
+      struct $2 struct_instance;\r
+    ], ac_struct="yes", ac_found="no")\r
+  if test "$ac_struct" = "yes" ; then\r
+    AC_MSG_RESULT(yes)\r
+    $3\r
+  else\r
+    AC_MSG_RESULT(no)\r
+    $4\r
+  fi\r
+])\r
+\r
+dnl This macro determins if the specified struct contains a specific member.\r
+dnl Syntax:\r
+dnl CARES_CHECK_STRUCT_MEMBER(headers, struct name, member name, if found, [if not found])\r
+\r
+AC_DEFUN([CARES_CHECK_STRUCT_MEMBER], [\r
+  AC_MSG_CHECKING([if struct $2 has member $3])\r
+  AC_TRY_COMPILE([$1], \r
+    [\r
+      struct $2 struct_instance;\r
+      struct_instance.$3 = 0;\r
+    ], ac_struct="yes", ac_found="no")\r
+  if test "$ac_struct" = "yes" ; then\r
+    AC_MSG_RESULT(yes)\r
+    $4\r
+  else\r
+    AC_MSG_RESULT(no)\r
+    $5\r
+  fi\r
+])\r
+\r
+dnl This macro determines if the specified constant exists in the specified file\r
+dnl Syntax:\r
+dnl CARES_CHECK_CONSTANT(headers, constant name, if found, [if not found])\r
+\r
+AC_DEFUN([CARES_CHECK_CONSTANT], [\r
+  AC_MSG_CHECKING([for $2])\r
+  AC_EGREP_CPP(VARIABLEWASDEFINED,\r
+   [\r
+      $1\r
+\r
+      #ifdef $2\r
+        VARIABLEWASDEFINED\r
+      #else\r
+        NJET\r
+      #endif\r
+    ], ac_constant="yes", ac_constant="no"\r
+  )\r
+  if test "$ac_constant" = "yes" ; then\r
+    AC_MSG_RESULT(yes)\r
+    $3\r
+  else\r
+    AC_MSG_RESULT(no)\r
+    $4\r
+  fi\r
+])\r
+\r
+\r
index d032de43409afdb73a12a8a6dc32d86314055159..01a6b8ac38252a2e22d54f0857b04aebe4c5971b 100644 (file)
 
 #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 (file)
index 0000000..9b6bd73
--- /dev/null
@@ -0,0 +1,145 @@
+.\" $Id$\r
+.\"\r
+.\" Copyright 2005 by Dominick Meglio.\r
+.\"\r
+.\" Permission to use, copy, modify, and distribute this\r
+.\" software and its documentation for any purpose and without\r
+.\" fee is hereby granted, provided that the above copyright\r
+.\" notice appear in all copies and that both that copyright\r
+.\" notice and this permission notice appear in supporting\r
+.\" documentation, and that the name of M.I.T. not be used in\r
+.\" advertising or publicity pertaining to distribution of the\r
+.\" software without specific, written prior permission.\r
+.\" M.I.T. makes no representations about the suitability of\r
+.\" this software for any purpose.  It is provided "as is"\r
+.\" without express or implied warranty.\r
+.\"\r
+.TH ARES_GETNAMEINFO 3 "16 May 2005"\r
+.SH NAME\r
+ares_getnameinfo \- Address-to-nodename translation in protocol-independent manner\r
+.SH SYNOPSIS\r
+.nf\r
+.B #include <ares.h>\r
+.PP\r
+.B typedef void (*ares_nameinfo_callback)(void *\fIarg\fP, int \fIstatus\fP,\r
+.B     char *\fInode\fP, char *\fIservice\fP)\r
+.PP\r
+.B void ares_getnameinfo(ares_channel \fIchannel\fP, const struct sockaddr *\fIsa\fP,\r
+.B     socklen_t \fIsalen\fP, int \fIflags\fP, ares_nameinfo_callback \fIcallback\fP,\r
+.B     void *\fIarg\fP)\r
+.fi\r
+.SH DESCRIPTION\r
+The\r
+.B ares_getnameinfo\r
+function is defined for protocol-independent address translation. The function\r
+is a combination of \fIares_gethostbyaddr(3)\fP and \fIgetservbyport(3)\fP. The function will\r
+translate the address either by executing a host query on the name service channel\r
+identified by\r
+.IR channel \r
+or it will attempt to resolve it locally if possible.\r
+The parameters\r
+.I sa\r
+and\r
+.I len\r
+give the address as a sockaddr structure, and\r
+.I flags\r
+gives the options that the function will use.  Valid flags are listed below:\r
+.TP 19\r
+.B ARES_NI_NOFQDN\r
+Only the nodename portion of the FQDN is returned for local hosts.\r
+.TP 19\r
+.B ARES_NI_NUMERICHOST\r
+The numeric form of the hostname is returned rather than the name.\r
+.TP 19\r
+.B ARES_NI_NAMEREQD\r
+An error is returned if the hostname cannot be found in the DNS.\r
+.TP 19\r
+.B ARES_NI_NUMERICSERV\r
+The numeric form of the service is returned rather than the name.\r
+.TP 19\r
+.B ARES_NI_TCP\r
+The service name is to be looked up for the TCP protocol.\r
+.TP 19\r
+.B ARES_NI_UDP\r
+The service name is to be looked up for the UDP protocol.\r
+.TP 19\r
+.B ARES_NI_SCTP\r
+The service name is to be looked up for the SCTP protocol.\r
+.TP 19\r
+.B ARES_NI_DCCP\r
+The service name is to be looked up for the DCCP protocol.\r
+.TP 19\r
+.B ARES_NI_NUMERICSCOPE\r
+The numeric form of the scope ID is returned rather than the name.\r
+.TP 19\r
+.B ARES_NI_LOOKUPHOST\r
+A hostname lookup is being requested.\r
+.TP 19\r
+.B ARES_NI_LOOKUPSERVICE\r
+A service name lookup is being requested.\r
+.PP\r
+When the query\r
+is complete or has \r
+failed, the ares library will invoke \fIcallback\fP.  Completion or failure of \r
+the query may happen immediately, or may happen during a later call to\r
+\fIares_process(3)\fP, \fIares_destroy(3)\fP or \fIares_cancel(3)\fP.\r
+.PP\r
+The callback argument\r
+.I arg\r
+is copied from the\r
+.B ares_getnameinfo\r
+argument\r
+.IR arg .\r
+The callback argument\r
+.I status\r
+indicates whether the query succeeded and, if not, how it failed.  It\r
+may have any of the following values:\r
+.TP 19\r
+.B ARES_SUCCESS\r
+The host lookup completed successfully.\r
+.TP 19\r
+.B ARES_ENOTIMP\r
+The ares library does not know how to look up addresses of type\r
+.IR family .\r
+.TP 19\r
+.B ARES_ENOTFOUND\r
+The address\r
+.I addr\r
+was not found.\r
+.TP 19\r
+.B ARES_ENOMEM\r
+Memory was exhausted.\r
+.TP 19\r
+.B ARES_EDESTRUCTION\r
+The name service channel\r
+.I channel\r
+is being destroyed; the query will not be completed.\r
+.TP 19\r
+.B ARES_EBADFLAGS\r
+The\r
+.I flags\r
+parameter contains an illegal value.\r
+.PP\r
+On successful completion of the query, the callback argument\r
+.I node\r
+contains a string representing the hostname (assuming \r
+.B ARES_NI_LOOKUPHOST\r
+was specified). Additionally, \r
+.I service\r
+contains a string representing the service name (assuming\r
+.B ARES_NI_LOOKUPSERVICE\r
+was specified).\r
+If the query did not complete successfully, or one of the values\r
+was not requested, \r
+.I node\r
+or\r
+.I service\r
+will be \r
+.BR NULL .\r
+.SH SEE ALSO\r
+.BR ares_process (3),\r
+.BR ares_getaddrinfo (3)\r
+.SH AUTHOR\r
+Dominick Meglio\r
+.br\r
+Copyright 2005 by Dominick Meglio.\r
diff --git a/ares/ares_getnameinfo.c b/ares/ares_getnameinfo.c
new file mode 100644 (file)
index 0000000..955207a
--- /dev/null
@@ -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;
+}
index 3a5bd069954f4cffa122033ed125e60dbcae7656..79a37c4012aac442495d8fe5cb1c56e1864ee59d 100644 (file)
@@ -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 */
index 5681b93ca9829754e0afd6fc4777d189409367f6..6e9fa0edd47a25c3df3a6d32022530b1b6e5a1e4 100644 (file)
@@ -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)));
index 9239957da9e85f89d65c10ee3db6269f22ec87d1..1201198125806ba296ff387a5fa3b153903e8ad0 100644 (file)
-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.\r
+AC_INIT(ares_init.c)\r
+AM_CONFIG_HEADER(config.h)\r
+AM_MAINTAINER_MODE\r
+AM_INIT_AUTOMAKE(c-ares, CVS)\r
+\r
+AC_PROG_CC\r
+AC_PROG_INSTALL\r
+\r
+case $host_os in\r
+solaris*)\r
+       AC_DEFINE(ETC_INET, 1, [if a /etc/inet dir is being used])\r
+       ;;\r
+esac\r
+\r
+# check for ssize_t\r
+AC_CHECK_TYPE(ssize_t, ,\r
+   AC_DEFINE(ssize_t, int, [the signed version of size_t]))\r
+\r
+AC_SEARCH_LIBS(gethostbyname, nsl)\r
+AC_SEARCH_LIBS(socket, socket)\r
+\r
+dnl ************************************************************\r
+dnl Option to switch on debug options. This makes an assumption that\r
+dnl this is built as an 'ares' subdir in the curl source tree. Subject for\r
+dnl improval in the future!\r
+dnl\r
+AC_MSG_CHECKING([whether to enable debug options])\r
+AC_ARG_ENABLE(debug,\r
+AC_HELP_STRING([--enable-debug],[Enable pedantic debug options])\r
+AC_HELP_STRING([--disable-debug],[Disable debug options]),\r
+[ case "$enableval" in\r
+  no)\r
+       AC_MSG_RESULT(no)\r
+       ;;\r
+  *)   AC_MSG_RESULT(yes)\r
+\r
+    dnl when doing the debug stuff, use static library only\r
+    AC_DISABLE_SHARED\r
+\r
+    dnl Checks for standard header files, to make memdebug.h inclusions bettter\r
+    AC_HEADER_STDC\r
+\r
+    dnl the entire --enable-debug is a hack that lives and runs on top of\r
+    dnl libcurl stuff so this BUILDING_LIBCURL is not THAT much uglier\r
+    AC_DEFINE(BUILDING_LIBCURL, 1, [when building as static part of libcurl])\r
+\r
+    CPPFLAGS="$CPPFLAGS -DCURLDEBUG -I$srcdir/../include"\r
+    CFLAGS="$CFLAGS -g" \r
+\r
+    dnl set compiler "debug" options to become more picky, and remove\r
+    dnl optimize options from CFLAGS\r
+    CURL_CC_DEBUG_OPTS\r
+\r
+       ;;\r
+  esac ],\r
+       AC_MSG_RESULT(no)\r
+)\r
+\r
+AC_PROG_LIBTOOL\r
+\r
+dnl check for a few basic system headers we need\r
+AC_CHECK_HEADERS(\r
+       sys/types.h \\r
+       sys/time.h \\r
+       sys/select.h \\r
+       sys/socket.h \\r
+       winsock.h \\r
+       netinet/in.h \\r
+       net/if.h \\r
+       arpa/nameser.h \\r
+       arpa/nameser_compat.h \\r
+       arpa/inet.h, , ,\r
+[\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+dnl We do this default-include simply to make sure that the nameser_compat.h\r
+dnl header *REALLY* can be include after the new nameser.h. It seems AIX 5.1\r
+dnl (and others?) is not designed to allow this.\r
+#ifdef HAVE_ARPA_NAMESER_H\r
+#include <arpa/nameser.h>\r
+#endif\r
+\r
+dnl *Sigh* these are needed in order for net/if.h to get properly detected.\r
+#ifdef HAVE_SYS_SOCKET_H\r
+#include <sys/socket.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+]\r
+  )\r
+\r
+AC_CHECK_TYPE(socklen_t, ,\r
+   AC_DEFINE(socklen_t, int, [the length of a socket address]), \r
+   [\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+#ifdef HAVE_SYS_SOCKET_H\r
+#include <sys/socket.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+   ])\r
+\r
+dnl check for AF_INET6\r
+CARES_CHECK_CONSTANT(\r
+  [\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+#ifdef HAVE_SYS_SOCKET_H\r
+#include <sys/socket.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+\r
+  ], [PF_INET6], \r
+     AC_DEFINE_UNQUOTED(HAVE_PF_INET6,1,[Define to 1 if you have PF_INET6.])\r
+)\r
+\r
+dnl check for PF_INET6\r
+CARES_CHECK_CONSTANT(\r
+  [\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+#ifdef HAVE_SYS_SOCKET_H\r
+#include <sys/socket.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+\r
+  ], [AF_INET6], \r
+     AC_DEFINE_UNQUOTED(HAVE_AF_INET6,1,[Define to 1 if you have AF_INET6.])\r
+)\r
+\r
+\r
+dnl check for the in6_addr structure\r
+CARES_CHECK_STRUCT(\r
+  [\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+#ifdef HAVE_NETINET_IN_H\r
+#include <netinet/in.h>\r
+#endif\r
+  ], [in6_addr], \r
+     AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.])\r
+)\r
+\r
+dnl check for the sockaddr_in6 structure\r
+CARES_CHECK_STRUCT(\r
+  [\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+#ifdef HAVE_NETINET_IN_H\r
+#include <netinet/in.h>\r
+#endif\r
+  ], [sockaddr_in6], \r
+     AC_DEFINE_UNQUOTED(HAVE_STRUCT_SOCKADDR_IN6,1,\r
+       [Define to 1 if you have struct sockaddr_in6.]) ac_have_sockaddr_in6=yes\r
+)\r
+\r
+if test "$ac_have_sockaddr_in6" = "yes" ; then\r
+CARES_CHECK_STRUCT_MEMBER(\r
+  [\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+#ifdef HAVE_NETINET_IN_H\r
+#include <netinet/in.h>\r
+#endif\r
+  ], [sockaddr_in6], [sin6_scope_id],\r
+     AC_DEFINE_UNQUOTED(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID,1,\r
+       [Define to 1 if your struct sockaddr_in6 has sin6_scope_id.])\r
+)\r
+fi\r
+\r
+dnl check for inet_pton\r
+AC_CHECK_FUNCS(inet_pton)\r
+dnl Some systems have it, but not IPv6\r
+if test "$ac_cv_func_inet_pton" = "yes" ; then\r
+AC_MSG_CHECKING(if inet_pton supports IPv6)\r
+AC_TRY_RUN(\r
+  [\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+#ifdef HAVE_SYS_SOCKET_H\r
+#include <sys/socket.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+#ifdef HAVE_NETINET_IN_H\r
+#include <netinet/in.h>\r
+#endif\r
+int main()\r
+  {\r
+    struct in6_addr addr6;\r
+    if (inet_pton(AF_INET6, "::1", &addr6) < 1)\r
+      exit(1);\r
+    else\r
+      exit(0);\r
+  }\r
+  ], [\r
+       AC_MSG_RESULT(yes)\r
+       AC_DEFINE_UNQUOTED(HAVE_INET_PTON_IPV6,1,[Define to 1 if inet_pton supports IPv6.])\r
+     ], AC_MSG_RESULT(no),AC_MSG_RESULT(no))\r
+fi\r
+dnl Check for inet_net_pton\r
+AC_CHECK_FUNCS(inet_net_pton)\r
+dnl Again, some systems have it, but not IPv6\r
+if test "$ac_cv_func_inet_net_pton" = "yes" ; then\r
+AC_MSG_CHECKING(if inet_net_pton supports IPv6)\r
+AC_TRY_RUN(\r
+  [\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+#ifdef HAVE_SYS_SOCKET_H\r
+#include <sys/socket.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+#ifdef HAVE_NETINET_IN_H\r
+#include <netinet/in.h>\r
+#endif\r
+int main()\r
+  {\r
+    struct in6_addr addr6;\r
+    if (inet_net_pton(AF_INET6, "::1", &addr6, sizeof(addr6)) < 1)\r
+      exit(1);\r
+    else\r
+      exit(0);\r
+  }\r
+  ], [\r
+       AC_MSG_RESULT(yes)\r
+       AC_DEFINE_UNQUOTED(HAVE_INET_NET_PTON_IPV6,1,[Define to 1 if inet_net_pton supports IPv6.])\r
+     ], AC_MSG_RESULT(no),AC_MSG_RESULT(no))\r
+fi\r
+\r
+\r
+dnl Check for inet_ntop\r
+AC_CHECK_FUNCS(inet_ntop)\r
+dnl Again, some systems have it, but not IPv6\r
+if test "$ac_cv_func_inet_ntop" = "yes" ; then\r
+AC_MSG_CHECKING(if inet_ntop supports IPv6)\r
+AC_TRY_RUN(\r
+  [\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+#ifdef HAVE_SYS_SOCKET_H\r
+#include <sys/socket.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+#ifdef HAVE_NETINET_IN_H\r
+#include <netinet/in.h>\r
+#endif\r
+#include <errno.h>\r
+int main()\r
+  {\r
+    struct in6_addr addr6;\r
+    char buf[128];\r
+    if (inet_ntop(AF_INET6, &addr6, buf, 128) == 0 && errno == EAFNOSUPPORT)\r
+      exit(1);\r
+    else\r
+      exit(0);\r
+  }\r
+  ], [\r
+       AC_MSG_RESULT(yes)\r
+       AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6,1,[Define to 1 if inet_ntop supports IPv6.])\r
+     ], AC_MSG_RESULT(no),AC_MSG_RESULT(no))\r
+fi\r
+\r
+AC_CHECK_SIZEOF(struct in6_addr, ,\r
+[\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+#ifdef HAVE_SYS_SOCKET_H\r
+#include <sys/socket.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+#ifdef HAVE_NETINET_IN_H\r
+#include <netinet/in.h>\r
+#endif\r
+]\r
+)\r
+AC_CHECK_SIZEOF(struct in_addr, ,\r
+[\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+#ifdef HAVE_SYS_SOCKET_H\r
+#include <sys/socket.h>\r
+#endif\r
+#ifdef HAVE_WINSOCK_H\r
+#include <winsock.h>\r
+#endif\r
+#ifdef HAVE_NETINET_IN_H\r
+#include <netinet/in.h>\r
+#endif\r
+]\r
+)\r
+\r
+AC_CHECK_FUNCS([bitncmp if_indextoname])\r
+\r
+\r
+AC_OUTPUT(Makefile)\r
index e972702d55911cffd1b25e036c512b516f26f255..619a285d2bda9406aacfb934490355b5b98a299b 100644 (file)
@@ -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