]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2342. [func] Use getifaddrs() if available under Linux. [RT #17224]
authorMark Andrews <marka@isc.org>
Thu, 20 Mar 2008 04:51:00 +0000 (04:51 +0000)
committerMark Andrews <marka@isc.org>
Thu, 20 Mar 2008 04:51:00 +0000 (04:51 +0000)
CHANGES
bin/tests/inter_test.c
configure
configure.in
lib/isc/unix/ifiter_getifaddrs.c
lib/isc/unix/ifiter_ioctl.c
lib/isc/unix/interfaceiter.c

diff --git a/CHANGES b/CHANGES
index 19e35a41f50c86daf7f359a5ff931ab90164dbdf..36a4813b2d672b8b684ca1344a91cd30726449b5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+2342.  [func]          Use getifaddrs() if available under Linux. [RT #17224]
+
 2341.  [bug]           libbind: add missing -I../include for off source
                        tree builds. [RT #17606]
 
index 4dc19a801b1f48f0b87464418cb803ac43b7fd3e..ffc9c36045b748b7fc31a30c41f715b279f3d0cc 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: inter_test.c,v 1.14 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: inter_test.c,v 1.15 2008/03/20 04:50:02 marka Exp $ */
 
 /*! \file */
 #include <config.h>
@@ -83,6 +83,53 @@ main(int argc, char **argv) {
                }
        }
        isc_interfaceiter_destroy(&iter);
+
+       fprintf(stdout, "\nPass 2\n\n");
+
+       result = isc_interfaceiter_create(mctx, &iter);
+       if (result != ISC_R_SUCCESS)
+               goto cleanup;
+       result = isc_interfaceiter_first(iter);
+       while (result == ISC_R_SUCCESS) {
+               result = isc_interfaceiter_current(iter, &ifdata);
+               if (result != ISC_R_SUCCESS) {
+                       fprintf(stdout, "isc_interfaceiter_current: %s",
+                               isc_result_totext(result));
+                       continue;
+               }
+               fprintf(stdout, "%s %d %x\n", ifdata.name, ifdata.af,
+                       ifdata.flags);
+               INSIST(ifdata.af == AF_INET || ifdata.af == AF_INET6);
+               res = inet_ntop(ifdata.af, &ifdata.address.type, buf,
+                               sizeof(buf));
+               if (ifdata.address.zone != 0)
+                       fprintf(stdout, "address = %s (zone %u)\n",
+                               res == NULL ? "BAD" : res,
+                               ifdata.address.zone);
+               else
+                       fprintf(stdout, "address = %s\n",
+                               res == NULL ? "BAD" : res);
+               INSIST(ifdata.address.family == ifdata.af);
+               res = inet_ntop(ifdata.af, &ifdata.netmask.type, buf,
+                               sizeof(buf));
+               fprintf(stdout, "netmask = %s\n", res == NULL ? "BAD" : res);
+               INSIST(ifdata.netmask.family == ifdata.af);
+               if ((ifdata.flags & INTERFACE_F_POINTTOPOINT) != 0) {
+                       res = inet_ntop(ifdata.af, &ifdata.dstaddress.type,
+                                        buf, sizeof(buf));
+                       fprintf(stdout, "dstaddress = %s\n",
+                               res == NULL ? "BAD" : res);
+
+                       INSIST(ifdata.dstaddress.family == ifdata.af);
+               }
+               result = isc_interfaceiter_next(iter);
+               if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) {
+                       fprintf(stdout, "isc_interfaceiter_next: %s",
+                               isc_result_totext(result));
+                       continue;
+               }
+       }
+       isc_interfaceiter_destroy(&iter);
  cleanup:
        isc_mem_destroy(&mctx);
 
index 0df76dc03ebc93d50a37ce956c089c2688b4223c..1e879639c9bd5bac36ea59ab32bf4f1b50d456a6 100755 (executable)
--- a/configure
+++ b/configure
@@ -14,7 +14,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 #
-# $Id: configure,v 1.423 2008/01/30 04:49:59 marka Exp $
+# $Id: configure,v 1.424 2008/03/20 04:51:00 marka Exp $
 #
 # Portions Copyright (C) 1996-2001  Nominum, Inc.
 #
@@ -29,7 +29,7 @@
 # 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.
-# From configure.in Revision: 1.438 .
+# From configure.in Revision: 1.439 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.61.
 #
@@ -1632,8 +1632,7 @@ Optional Features:
   --disable-libtool-lock  avoid locking (might break parallel builds)
   --enable-libbind             build libbind default=no
   --enable-ipv6                use IPv6 default=autodetect
-  --enable-getifaddrs    Enable the use of getifaddrs() [yes|no|glibc].
-            glibc: Use getifaddrs() in glibc if you know it supports IPv6.
+  --enable-getifaddrs    Enable the use of getifaddrs() [yes|no].
   --disable-isc-spnego         use SPNEGO from GSSAPI library
   --disable-linux-caps disable linux capabilities
   --enable-atomic      enable machine specific atomic operations
@@ -9581,7 +9580,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 9584 "configure"' > conftest.$ac_ext
+  echo '#line 9583 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -11703,11 +11702,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11706: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11705: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:11710: \$? = $ac_status" >&5
+   echo "$as_me:11709: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -11946,11 +11945,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11949: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11948: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:11953: \$? = $ac_status" >&5
+   echo "$as_me:11952: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -12006,11 +12005,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:12009: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:12008: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:12013: \$? = $ac_status" >&5
+   echo "$as_me:12012: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -14154,7 +14153,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 14157 "configure"
+#line 14156 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -14252,7 +14251,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 14255 "configure"
+#line 14254 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -16445,11 +16444,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16448: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16447: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:16452: \$? = $ac_status" >&5
+   echo "$as_me:16451: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -16505,11 +16504,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16508: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16507: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:16512: \$? = $ac_status" >&5
+   echo "$as_me:16511: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -17833,7 +17832,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 17836 "configure"
+#line 17835 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -17931,7 +17930,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 17934 "configure"
+#line 17933 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -18768,11 +18767,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:18771: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:18770: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:18775: \$? = $ac_status" >&5
+   echo "$as_me:18774: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -18828,11 +18827,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:18831: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:18830: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:18835: \$? = $ac_status" >&5
+   echo "$as_me:18834: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -20862,11 +20861,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:20865: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:20864: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:20869: \$? = $ac_status" >&5
+   echo "$as_me:20868: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -21105,11 +21104,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:21108: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:21107: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:21112: \$? = $ac_status" >&5
+   echo "$as_me:21111: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -21165,11 +21164,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:21168: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:21167: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:21172: \$? = $ac_status" >&5
+   echo "$as_me:21171: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -23313,7 +23312,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 23316 "configure"
+#line 23315 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -23411,7 +23410,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 23414 "configure"
+#line 23413 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -26300,21 +26299,16 @@ else
 fi
 
 
-case $want_getifaddrs in
-yes|glibc)
 #
-# Do we have getifaddrs() ?
+# This interface iteration code for getifaddrs() will fall back to using
+# /proc/net/if_inet6 if getifaddrs() in glibc doesn't return any IPv6
+# addresses.
 #
-case $host in
-*-linux*)
-       # Some recent versions of glibc support getifaddrs() which does not
-       # provide AF_INET6 addresses while the function provided by the USAGI
-       # project handles the AF_INET6 case correctly.  We need to avoid
-       # using the former but prefer the latter unless overridden by
-       # --enable-getifaddrs=glibc.
-       if test $want_getifaddrs = glibc
-       then
-               { echo "$as_me:$LINENO: checking for getifaddrs" >&5
+case $want_getifaddrs in
+glibc)
+{ echo "$as_me:$LINENO: WARNING: \"--enable-getifaddrs=glibc is no longer required\"" >&5
+echo "$as_me: WARNING: \"--enable-getifaddrs=glibc is no longer required\"" >&2;}
+{ echo "$as_me:$LINENO: checking for getifaddrs" >&5
 echo $ECHO_N "checking for getifaddrs... $ECHO_C" >&6; }
 if test "${ac_cv_func_getifaddrs+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -26402,84 +26396,9 @@ _ACEOF
 
 fi
 
-       else
-               save_LIBS="$LIBS"
-               LIBS="-L/usr/local/v6/lib $LIBS"
-               { echo "$as_me:$LINENO: checking for getifaddrs in -linet6" >&5
-echo $ECHO_N "checking for getifaddrs in -linet6... $ECHO_C" >&6; }
-if test "${ac_cv_lib_inet6_getifaddrs+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-linet6  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char getifaddrs ();
-int
-main ()
-{
-return getifaddrs ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_inet6_getifaddrs=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_cv_lib_inet6_getifaddrs=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_inet6_getifaddrs" >&5
-echo "${ECHO_T}$ac_cv_lib_inet6_getifaddrs" >&6; }
-if test $ac_cv_lib_inet6_getifaddrs = yes; then
-  LIBS="$LIBS -linet6"
-                       cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETIFADDRS 1
-_ACEOF
-
-else
-  LIBS=${save_LIBS}
-fi
-
-       fi
-       ;;
-*)
-       { echo "$as_me:$LINENO: checking for getifaddrs" >&5
+;;
+yes)
+{ echo "$as_me:$LINENO: checking for getifaddrs" >&5
 echo $ECHO_N "checking for getifaddrs... $ECHO_C" >&6; }
 if test "${ac_cv_func_getifaddrs+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -26567,8 +26486,6 @@ _ACEOF
 
 fi
 
-       ;;
-esac
 ;;
 no)
 ;;
index a05b7f8e1d13e95d3f9f92408fae5213eb4deab4..91d8ba1b84b4ced286c249ae03413d19d0b34763 100644 (file)
@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
 esyscmd([sed "s/^/# /" COPYRIGHT])dnl
 AC_DIVERT_POP()dnl
 
-AC_REVISION($Revision: 1.438 $)
+AC_REVISION($Revision: 1.439 $)
 
 AC_INIT(lib/dns/name.c)
 AC_PREREQ(2.59)
@@ -1669,38 +1669,21 @@ AC_SUBST(ISC_LWRES_GETADDRINFOPROTO)
 AC_SUBST(ISC_LWRES_GETNAMEINFOPROTO)
 
 AC_ARG_ENABLE(getifaddrs,
-[  --enable-getifaddrs    Enable the use of getifaddrs() [[yes|no|glibc]].
-            glibc: Use getifaddrs() in glibc if you know it supports IPv6.],
+[  --enable-getifaddrs    Enable the use of getifaddrs() [[yes|no]].],
     want_getifaddrs="$enableval",  want_getifaddrs="yes")
 
-case $want_getifaddrs in
-yes|glibc)
-#
-# Do we have getifaddrs() ?
 #
-case $host in
-*-linux*)
-       # Some recent versions of glibc support getifaddrs() which does not
-       # provide AF_INET6 addresses while the function provided by the USAGI
-       # project handles the AF_INET6 case correctly.  We need to avoid
-       # using the former but prefer the latter unless overridden by
-       # --enable-getifaddrs=glibc.
-       if test $want_getifaddrs = glibc
-       then
-               AC_CHECK_FUNC(getifaddrs, AC_DEFINE(HAVE_GETIFADDRS))
-       else
-               save_LIBS="$LIBS"
-               LIBS="-L/usr/local/v6/lib $LIBS"
-               AC_CHECK_LIB(inet6, getifaddrs,
-                       LIBS="$LIBS -linet6"
-                       AC_DEFINE(HAVE_GETIFADDRS),
-                       LIBS=${save_LIBS})
-       fi
-       ;;
-*)
-       AC_CHECK_FUNC(getifaddrs, AC_DEFINE(HAVE_GETIFADDRS))
-       ;;
-esac
+# This interface iteration code for getifaddrs() will fall back to using
+# /proc/net/if_inet6 if getifaddrs() in glibc doesn't return any IPv6
+# addresses.
+# 
+case $want_getifaddrs in
+glibc)
+AC_MSG_WARN("--enable-getifaddrs=glibc is no longer required")
+AC_CHECK_FUNC(getifaddrs, AC_DEFINE(HAVE_GETIFADDRS))
+;;
+yes)
+AC_CHECK_FUNC(getifaddrs, AC_DEFINE(HAVE_GETIFADDRS))
 ;;
 no)
 ;;
index 4eaba33979304fb5c4a0d1fb50f44c94dffa2c2f..3a5a029f4ca20cbbf08e1a78689d15250ef7c0f1 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: ifiter_getifaddrs.c,v 1.9 2007/06/18 23:47:48 tbox Exp $ */
+/* $Id: ifiter_getifaddrs.c,v 1.10 2008/03/20 04:50:02 marka Exp $ */
 
 /*! \file
  * \brief
 /*% Valid Iterator */
 #define VALID_IFITER(t)                ISC_MAGIC_VALID(t, IFITER_MAGIC)
 
+#ifdef __linux
+static isc_boolean_t seenv6 = ISC_FALSE;
+#endif
+
 /*% Iterator structure */
 struct isc_interfaceiter {
        unsigned int            magic;          /*%< Magic number. */
@@ -39,9 +43,13 @@ struct isc_interfaceiter {
        struct ifaddrs          *pos;           /*%< Ptr to current ifaddr */
        isc_interface_t         current;        /*%< Current interface data. */
        isc_result_t            result;         /*%< Last result code. */
+#ifdef  __linux
+        FILE *                  proc;
+        char                    entry[ISC_IF_INET6_SZ];
+        isc_result_t            valid;
+#endif
 };
 
-
 isc_result_t
 isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
        isc_interfaceiter_t *iter;
@@ -60,6 +68,17 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
        iter->buf = NULL;
        iter->bufsize = 0;
        iter->ifaddrs = NULL;
+#ifdef __linux
+       /*
+        * Only open "/proc/net/if_inet6" if we have never seen a IPv6
+        * address returned by getifaddrs().
+        */
+       if (!seenv6)
+               iter->proc = fopen("/proc/net/if_inet6", "r");
+       else
+               iter->proc = NULL;
+       iter->valid = ISC_R_FAILURE;
+#endif
 
        if (getifaddrs(&iter->ifaddrs) < 0) {
                isc__strerror(errno, strbuf, sizeof(strbuf));
@@ -86,6 +105,10 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
        return (ISC_R_SUCCESS);
 
  failure:
+#ifdef __linux
+       if (iter->proc != NULL)
+               fclose(iter->proc);
+#endif
        if (iter->ifaddrs != NULL) /* just in case */
                freeifaddrs(iter->ifaddrs);
        isc_mem_put(mctx, iter, sizeof(*iter));
@@ -109,6 +132,11 @@ internal_current(isc_interfaceiter_t *iter) {
 
        ifa = iter->pos;
 
+#ifdef __linux
+       if (iter->pos == NULL)
+               return (linux_if_inet6_current(iter));
+#endif
+
        INSIST(ifa != NULL);
        INSIST(ifa->ifa_name != NULL);
 
@@ -119,6 +147,11 @@ internal_current(isc_interfaceiter_t *iter) {
        if (family != AF_INET && family != AF_INET6)
                return (ISC_R_IGNORE);
 
+#ifdef __linux
+       if (family == AF_INET6)
+               seenv6 = ISC_TRUE;
+#endif
+
        memset(&iter->current, 0, sizeof(iter->current));
 
        namelen = strlen(ifa->ifa_name);
@@ -164,16 +197,28 @@ internal_current(isc_interfaceiter_t *iter) {
  */
 static isc_result_t
 internal_next(isc_interfaceiter_t *iter) {
-       iter->pos = iter->pos->ifa_next;
 
-       if (iter->pos == NULL)
+       if (iter->pos != NULL)
+               iter->pos = iter->pos->ifa_next;
+       if (iter->pos == NULL) {
+#ifdef __linux
+               if (!seenv6)
+                       return (linux_if_inet6_next(iter));
+#endif
                return (ISC_R_NOMORE);
+       }
 
        return (ISC_R_SUCCESS);
 }
 
 static void
 internal_destroy(isc_interfaceiter_t *iter) {
+
+#ifdef __linux
+       if (iter->proc != NULL)
+               fclose(iter->proc);
+       iter->proc = NULL;
+#endif
        if (iter->ifaddrs)
                freeifaddrs(iter->ifaddrs);
        iter->ifaddrs = NULL;
@@ -181,5 +226,9 @@ internal_destroy(isc_interfaceiter_t *iter) {
 
 static
 void internal_first(isc_interfaceiter_t *iter) {
+
+#ifdef __linux
+       linux_if_inet6_first(iter);
+#endif
        iter->pos = iter->ifaddrs;
 }
index 46949e8f3c6fbb0cc9508db3b5892c21bc67c3ae..6ea9a674cb84528c808fb9617b225387a633f5c3 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: ifiter_ioctl.c,v 1.58 2007/08/30 06:02:28 marka Exp $ */
+/* $Id: ifiter_ioctl.c,v 1.59 2008/03/20 04:50:02 marka Exp $ */
 
 /*! \file
  * \brief
@@ -50,9 +50,6 @@
 #define IFITER_MAGIC           ISC_MAGIC('I', 'F', 'I', 'T')
 #define VALID_IFITER(t)                ISC_MAGIC_VALID(t, IFITER_MAGIC)
 
-#define ISC_IF_INET6_SZ \
-    sizeof("00000000000000000000000000000001 01 80 10 80 XXXXXXloXXXXXXXX\n")
-
 struct isc_interfaceiter {
        unsigned int            magic;          /* Magic number. */
        isc_mem_t               *mctx;
@@ -82,7 +79,6 @@ struct isc_interfaceiter {
        FILE *                  proc;
        char                    entry[ISC_IF_INET6_SZ];
        isc_result_t            valid;
-       isc_boolean_t           first;
 #endif
        isc_interface_t         current;        /* Current interface data. */
        isc_result_t            result;         /* Last result code. */
@@ -372,7 +368,6 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
 #ifdef __linux
        iter->proc = fopen("/proc/net/if_inet6", "r");
        iter->valid = ISC_R_FAILURE;
-       iter->first = ISC_FALSE;
 #endif
        iter->result = ISC_R_FAILURE;
 
@@ -422,89 +417,6 @@ internal_current_clusteralias(isc_interfaceiter_t *iter) {
 }
 #endif
 
-#ifdef __linux
-static isc_result_t
-linux_if_inet6_next(isc_interfaceiter_t *iter) {
-       if (iter->proc != NULL &&
-           fgets(iter->entry, sizeof(iter->entry), iter->proc) != NULL)
-               iter->valid = ISC_R_SUCCESS;
-       else
-               iter->valid = ISC_R_NOMORE;
-       return (iter->valid);
-}
-
-static void
-linux_if_inet6_first(isc_interfaceiter_t *iter) {
-       if (iter->proc != NULL) {
-               rewind(iter->proc);
-               (void)linux_if_inet6_next(iter);
-       } else
-               iter->valid = ISC_R_NOMORE;
-       iter->first = ISC_FALSE;
-}
-
-static isc_result_t
-linux_if_inet6_current(isc_interfaceiter_t *iter) {
-       char address[33];
-       char name[IF_NAMESIZE+1];
-       struct in6_addr addr6;
-       int ifindex, prefix, flag3, flag4;
-       int res;
-       unsigned int i;
-
-       if (iter->valid != ISC_R_SUCCESS)
-               return (iter->valid);
-       if (iter->proc == NULL) {
-               isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
-                             ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
-                             "/proc/net/if_inet6:iter->proc == NULL");
-               return (ISC_R_FAILURE);
-       }
-
-       res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n",
-                    address, &ifindex, &prefix, &flag3, &flag4, name);
-       if (res != 6) {
-               isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
-                             ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
-                             "/proc/net/if_inet6:sscanf() -> %d (expected 6)",
-                             res);
-               return (ISC_R_FAILURE);
-       }
-       if (strlen(address) != 32) {
-               isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
-                             ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
-                             "/proc/net/if_inet6:strlen(%s) != 32", address);
-               return (ISC_R_FAILURE);
-       }
-       for (i = 0; i < 16; i++) {
-               unsigned char byte;
-               static const char hex[] = "0123456789abcdef";
-               byte = ((index(hex, address[i * 2]) - hex) << 4) |
-                      (index(hex, address[i * 2 + 1]) - hex);
-               addr6.s6_addr[i] = byte;
-       }
-       iter->current.af = AF_INET6;
-       iter->current.flags = INTERFACE_F_UP;
-       isc_netaddr_fromin6(&iter->current.address, &addr6);
-       if (isc_netaddr_islinklocal(&iter->current.address)) {
-               isc_netaddr_setzone(&iter->current.address,
-                                   (isc_uint32_t)ifindex);
-       }
-       for (i = 0; i < 16; i++) {
-               if (prefix > 8) {
-                       addr6.s6_addr[i] = 0xff;
-                       prefix -= 8;
-               } else {
-                       addr6.s6_addr[i] = (0xff << (8 - prefix)) & 0xff;
-                       prefix = 0;
-               }
-       }
-       isc_netaddr_fromin6(&iter->current.netmask, &addr6);
-       strncpy(iter->current.name, name, sizeof(iter->current.name));
-       return (ISC_R_SUCCESS);
-}
-#endif
-
 /*
  * Get information about the current interface to iter->current.
  * If successful, return ISC_R_SUCCESS.
@@ -525,23 +437,19 @@ internal_current4(isc_interfaceiter_t *iter) {
        char sabuf[256];
 #endif
        int i, bits, prefixlen;
-#ifdef __linux
-       isc_result_t result;
-#endif
 
        REQUIRE(VALID_IFITER(iter));
-       REQUIRE(iter->ifc.ifc_len == 0 ||
-               iter->pos < (unsigned int) iter->ifc.ifc_len);
 
+       if (iter->ifc.ifc_len == 0 ||
+           iter->pos == (unsigned int)iter->ifc.ifc_len) {
 #ifdef __linux
-       result = linux_if_inet6_current(iter);
-       if (result != ISC_R_NOMORE)
-               return (result);
-       iter->first = ISC_TRUE;
+               return (linux_if_inet6_current(iter));
+#else
+               return (ISC_R_NOMORE);
 #endif
+       }
 
-       if (iter->ifc.ifc_len == 0)
-               return (ISC_R_NOMORE);
+       INSIST( iter->pos < (unsigned int) iter->ifc.ifc_len);
 
        ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos);
 
@@ -905,31 +813,25 @@ internal_next4(isc_interfaceiter_t *iter) {
        struct ifreq *ifrp;
 #endif
 
-       REQUIRE(iter->ifc.ifc_len == 0 ||
-               iter->pos < (unsigned int) iter->ifc.ifc_len);
-
-#ifdef __linux
-       if (linux_if_inet6_next(iter) == ISC_R_SUCCESS)
-               return (ISC_R_SUCCESS);
-       if (!iter->first)
-               return (ISC_R_SUCCESS);
-#endif
-
-       if (iter->ifc.ifc_len == 0)
-               return (ISC_R_NOMORE);
-
+       if (iter->pos < (unsigned int) iter->ifc.ifc_len) {
 #ifdef ISC_PLATFORM_HAVESALEN
-       ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos);
+               ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos);
 
-       if (ifrp->ifr_addr.sa_len > sizeof(struct sockaddr))
-               iter->pos += sizeof(ifrp->ifr_name) + ifrp->ifr_addr.sa_len;
-       else
+               if (ifrp->ifr_addr.sa_len > sizeof(struct sockaddr))
+                       iter->pos += sizeof(ifrp->ifr_name) +
+                                    ifrp->ifr_addr.sa_len;
+               else
 #endif
-               iter->pos += sizeof(struct ifreq);
+                       iter->pos += sizeof(struct ifreq);
 
-       if (iter->pos >= (unsigned int) iter->ifc.ifc_len)
+       } else {
+               INSIST(iter->pos == (unsigned int) iter->ifc.ifc_len);
+#ifdef __linux
+               return (linux_if_inet6_next(iter));
+#else
                return (ISC_R_NOMORE);
-
+#endif
+       }
        return (ISC_R_SUCCESS);
 }
 
index 359e363a983ad4c37dc2c4d18147fd8e50e19ea3..8321e7a375dbaa416a6278d996626cf1665bf619 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: interfaceiter.c,v 1.42 2007/06/19 23:47:18 tbox Exp $ */
+/* $Id: interfaceiter.c,v 1.43 2008/03/20 04:50:02 marka Exp $ */
 
 /*! \file */
 
@@ -145,6 +145,14 @@ get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src,
  * Include system-dependent code.
  */
 
+#ifdef __linux
+#define ISC_IF_INET6_SZ \
+    sizeof("00000000000000000000000000000001 01 80 10 80 XXXXXXloXXXXXXXX\n")
+static isc_result_t linux_if_inet6_next(isc_interfaceiter_t *);
+static isc_result_t linux_if_inet6_current(isc_interfaceiter_t *);
+static void linux_if_inet6_first(isc_interfaceiter_t *iter);
+#endif
+
 #if HAVE_GETIFADDRS
 #include "ifiter_getifaddrs.c"
 #elif HAVE_IFLIST_SYSCTL
@@ -153,6 +161,88 @@ get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src,
 #include "ifiter_ioctl.c"
 #endif
 
+#ifdef __linux
+static void
+linux_if_inet6_first(isc_interfaceiter_t *iter) {
+       if (iter->proc != NULL) {
+               rewind(iter->proc);
+               (void)linux_if_inet6_next(iter);
+       } else
+               iter->valid = ISC_R_NOMORE;
+}
+
+static isc_result_t
+linux_if_inet6_next(isc_interfaceiter_t *iter) {
+       if (iter->proc != NULL &&
+           fgets(iter->entry, sizeof(iter->entry), iter->proc) != NULL)
+               iter->valid = ISC_R_SUCCESS;
+       else
+               iter->valid = ISC_R_NOMORE;
+       return (iter->valid);
+}
+
+static isc_result_t
+linux_if_inet6_current(isc_interfaceiter_t *iter) {
+       char address[33];
+       char name[IF_NAMESIZE+1];
+       struct in6_addr addr6;
+       int ifindex, prefix, flag3, flag4;
+       int res;
+       unsigned int i;
+
+       if (iter->valid != ISC_R_SUCCESS)
+               return (iter->valid);
+       if (iter->proc == NULL) {
+               isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+                             ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+                             "/proc/net/if_inet6:iter->proc == NULL");
+               return (ISC_R_FAILURE);
+       }
+
+       res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n",
+                    address, &ifindex, &prefix, &flag3, &flag4, name);
+       if (res != 6) {
+               isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+                             ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+                             "/proc/net/if_inet6:sscanf() -> %d (expected 6)",
+                             res);
+               return (ISC_R_FAILURE);
+       }
+       if (strlen(address) != 32) {
+               isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+                             ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+                             "/proc/net/if_inet6:strlen(%s) != 32", address);
+               return (ISC_R_FAILURE);
+       }
+       for (i = 0; i < 16; i++) {
+               unsigned char byte;
+               static const char hex[] = "0123456789abcdef";
+               byte = ((index(hex, address[i * 2]) - hex) << 4) |
+                      (index(hex, address[i * 2 + 1]) - hex);
+               addr6.s6_addr[i] = byte;
+       }
+       iter->current.af = AF_INET6;
+       iter->current.flags = INTERFACE_F_UP;
+       isc_netaddr_fromin6(&iter->current.address, &addr6);
+       if (isc_netaddr_islinklocal(&iter->current.address)) {
+               isc_netaddr_setzone(&iter->current.address,
+                                   (isc_uint32_t)ifindex);
+       }
+       for (i = 0; i < 16; i++) {
+               if (prefix > 8) {
+                       addr6.s6_addr[i] = 0xff;
+                       prefix -= 8;
+               } else {
+                       addr6.s6_addr[i] = (0xff << (8 - prefix)) & 0xff;
+                       prefix = 0;
+               }
+       }
+       isc_netaddr_fromin6(&iter->current.netmask, &addr6);
+       strncpy(iter->current.name, name, sizeof(iter->current.name));
+       return (ISC_R_SUCCESS);
+}
+#endif
+
 /*
  * The remaining code is common to the sysctl and ioctl case.
  */