]> The Tcpdump Group git mirrors - libpcap/commitdiff
Work around an annoying Snow Leopard BPF bug that causes sub-second
authorGuy Harris <[email protected]>
Sun, 11 Oct 2009 18:05:46 +0000 (11:05 -0700)
committerGuy Harris <[email protected]>
Sun, 11 Oct 2009 18:05:46 +0000 (11:05 -0700)
timeouts not to work in 64-bit userland code (Snow Leopard's GCC builds
64-bit by default on 64-bit machines).

config.h.in
configure
configure.in
pcap-bpf.c

index 66fe69ccfe604c17eab5076b7d612cb43ec6e54c..46a725dec633d23a71748b694b030b6761c8b809 100644 (file)
 /* Define to 1 if you have the `strlcpy' function. */
 #undef HAVE_STRLCPY
 
+/* Define to 1 if the system has the type `struct BPF_TIMEVAL'. */
+#undef HAVE_STRUCT_BPF_TIMEVAL
+
 /* Define to 1 if the system has the type `struct ether_addr'. */
 #undef HAVE_STRUCT_ETHER_ADDR
 
index ca72f9eb653dd01d702ba33084f6ba8de435d661..5876cda1cc15d3aa0c3a6b91841a20fac337cb8c 100755 (executable)
--- a/configure
+++ b/configure
@@ -5144,13 +5144,11 @@ _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <sys/types.h> /* for off_t */
-     #include <stdio.h>
+#include <stdio.h>
 int
 main ()
 {
-int (*fp) (FILE *, off_t, int) = fseeko;
-     return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
   ;
   return 0;
 }
@@ -5190,13 +5188,11 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #define _LARGEFILE_SOURCE 1
-#include <sys/types.h> /* for off_t */
-     #include <stdio.h>
+#include <stdio.h>
 int
 main ()
 {
-int (*fp) (FILE *, off_t, int) = fseeko;
-     return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
   ;
   return 0;
 }
@@ -7697,6 +7693,80 @@ echo "${ECHO_T}no" >&6; }
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+           #
+           # Check whether we have struct BPF_TIMEVAL.
+           #
+           { echo "$as_me:$LINENO: checking for struct BPF_TIMEVAL" >&5
+echo $ECHO_N "checking for struct BPF_TIMEVAL... $ECHO_C" >&6; }
+if test "${ac_cv_type_struct_BPF_TIMEVAL+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#include <net/bpf.h>
+
+
+typedef struct BPF_TIMEVAL ac__type_new_;
+int
+main ()
+{
+if ((ac__type_new_ *) 0)
+  return 0;
+if (sizeof (ac__type_new_))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+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_compile") 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_objext; then
+  ac_cv_type_struct_BPF_TIMEVAL=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_type_struct_BPF_TIMEVAL=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_type_struct_BPF_TIMEVAL" >&5
+echo "${ECHO_T}$ac_cv_type_struct_BPF_TIMEVAL" >&6; }
+if test $ac_cv_type_struct_BPF_TIMEVAL = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_BPF_TIMEVAL 1
+_ACEOF
+
+
+fi
+
        ;;
 
 dag)
index 390a3602643f3fb6cede27b6ed3b4fcc949113d3..43cd323951b5c60ff4ade715271fc939e60824ce 100644 (file)
@@ -474,6 +474,19 @@ bpf)
                [define if the system supports zerocopy BPF])
            ],
            AC_MSG_RESULT(no))
+
+           #
+           # Check whether we have struct BPF_TIMEVAL.
+           #
+           AC_CHECK_TYPES(struct BPF_TIMEVAL,,,
+               [
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#include <net/bpf.h>
+                   ])
        ;;
 
 dag)
index dd8ed93bb75495f3f8f7c1209f0823277c6f6131..6577a20b5b56983fcefcff4b0e719ce6252b064f 100644 (file)
@@ -1914,16 +1914,45 @@ pcap_activate_bpf(pcap_t *p)
                 * XXX - is this seconds/nanoseconds in AIX?
                 * (Treating it as such doesn't fix the timeout
                 * problem described below.)
+                *
+                * XXX - Mac OS X 10.6 mishandles BIOCSRTIMEOUT in
+                * 64-bit userland - it takes, as an argument, a
+                * "struct BPF_TIMEVAL", which has 32-bit tv_sec
+                * and tv_usec, rather than a "struct timeval".
+                *
+                * If this platform defines "struct BPF_TIMEVAL",
+                * we check whether the structure size in BIOCSRTIMEOUT
+                * is that of a "struct timeval" and, if not, we use
+                * a "struct BPF_TIMEVAL" rather than a "struct timeval".
+                * (That way, if the bug is fixed in a future release,
+                * we will still do the right thing.)
                 */
                struct timeval to;
-               to.tv_sec = p->md.timeout / 1000;
-               to.tv_usec = (p->md.timeout * 1000) % 1000000;
-               if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
-                       snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
-                           pcap_strerror(errno));
-                       status = PCAP_ERROR;
-                       goto bad;
+#ifdef HAVE_STRUCT_BPF_TIMEVAL
+               struct BPF_TIMEVAL bpf_to;
+
+               if (IOCPARM_LEN(BIOCSRTIMEOUT) != sizeof(struct timeval)) {
+                       bpf_to.tv_sec = p->md.timeout / 1000;
+                       bpf_to.tv_usec = (p->md.timeout * 1000) % 1000000;
+                       if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&bpf_to) < 0) {
+                               snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+                                   "BIOCSRTIMEOUT: %s", pcap_strerror(errno));
+                               status = PCAP_ERROR;
+                               goto bad;
+                       }
+               } else {
+#endif
+                       to.tv_sec = p->md.timeout / 1000;
+                       to.tv_usec = (p->md.timeout * 1000) % 1000000;
+                       if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
+                               snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+                                   "BIOCSRTIMEOUT: %s", pcap_strerror(errno));
+                               status = PCAP_ERROR;
+                               goto bad;
+                       }
+#ifdef HAVE_STRUCT_BPF_TIMEVAL
                }
+#endif
        }
 
 #ifdef _AIX