]> The Tcpdump Group git mirrors - libpcap/commitdiff
Merge pull request #378 from sfd/master
authorGuy Harris <[email protected]>
Mon, 26 Jan 2015 00:27:18 +0000 (16:27 -0800)
committerGuy Harris <[email protected]>
Mon, 26 Jan 2015 00:27:18 +0000 (16:27 -0800)
Add tstamp_type/precision support for DAG capture

33 files changed:
.travis.yml
CHANGES
CREDITS
INSTALL.txt
Makefile.in
bpf/net/bpf_filter.c
configure
configure.in
gencode.c
inet.c
mkdep
packaging/pcap.spec.in [deleted file]
pcap-bpf.c
pcap-bt-monitor-linux.c
pcap-can-linux.c
pcap-canusb-linux.c
pcap-common.c
pcap-int.h
pcap-linux.c
pcap-netfilter-linux.c
pcap-snf.c
pcap.3pcap.in
pcap.c
pcap/bpf.h
pcap/pcap.h
pcap_datalink_name_to_val.3pcap
pcap_get_selectable_fd.3pcap
pcap_loop.3pcap
pcap_set_tstamp_type.3pcap.in
pcap_setnonblock.3pcap
pcap_tstamp_type_name_to_val.3pcap
savefile.c
sf-pcap-ng.c

index 2d4b1e73f6c33b08199f3387c0eeb3b515a15088..d74d940654f5ca2906f6ebf47ae599ab95fd4d98 100644 (file)
@@ -12,7 +12,7 @@ env:
   global:
     # encrypted COVERITY_SCAN_TOKEN from
     # https://scan.coverity.com/projects/<project_id>/submit_build?tab=travis_ci
-    - secure: "E7nrxhoBrST9SOy6PM+IN89k1EznzXWgsKSvB+fK2oNdLxAD+jaFCbG4JGwYzFzSwmBgd7NEQGSJi4uYotsvBPSxPBwiA/tQPniPvUd/dahTQxB1eJlYb+/hMYuumCHHK09zmPbTNU/v7qLc+NgMUM5bTCUG62dErFkx03WeHPM="
+    - secure: "WnSilJ28kIEu9GID24PgRz6T0xC0VGNFGRPmoWRN3DEj/lPcMqb8HxNcdWpaDt4tQi2PVOIujV5ApHr0xJrw8A9Ix7nBTaZRedrLvsA2uugCTZZMH0OHWJDus7/m6zcdsp3D12ddJIHeqabVe790EfkeSQGDtSBeHlpilQ0BuYU="
     # Coverity run condition (avoid matrix multiple runs), need customized
     # build script. Need an update if new matrix cases.
     - coverity_scan_run_condition='"$TRAVIS_OS_NAME" = linux -a "$CC" = gcc'
@@ -39,14 +39,16 @@ addons:
     # Pattern to match selecting branches that will run analysis
     branch_pattern: coverity_scan
 
+git:
+  quiet: true
+
 before_install:
   - uname -a
-  - env | sort -f
-  - if [ "$TRAVIS_OS_NAME" = linux ]; then sudo apt-get update; fi
-  - if [ "$TRAVIS_OS_NAME" = osx ]; then brew update; fi
+  - date
+  - if [ "$TRAVIS_OS_NAME" = linux ]; then sudo apt-get -qq update; fi
 
 install:
-  - if [ "$TRAVIS_OS_NAME" = linux ]; then sudo apt-get install libusb-1.0-0-dev libdbus-1-dev; fi
+  - if [ "$TRAVIS_OS_NAME" = linux ]; then sudo apt-get -qq install libusb-1.0-0-dev libdbus-1-dev libbluetooth-dev; fi
 
 before_script:
 
diff --git a/CHANGES b/CHANGES
index eb73e28d77f0eeff7de045a70f1ded5f33d6e1c3..27fa0d247c3adbbb67495c81f1ff359881ab51b9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,14 @@
+Wednesday Nov. 12, 2014 [email protected]/[email protected]
+  Summary for 1.7.0 libpcap release
+       Fix handling of zones for BPF on Solaris
+       new DLT for ZWAVE
+       clarifications for read timeouts.
+       added bpf_filter1() with extensions
+       some fixes to compilation without stdint.h
+       EBUSY can now be returned by SNFv3 code.
+
 Monday Aug. 12, 2014 [email protected]
-  Summary for 1.6.2 tcpdump release
+  Summary for 1.6.2 libpcap release
        Don't crash on filters testing a non-existent link-layer type
            field.
        Fix sending in non-blocking mode on Linux with memory-mapped
@@ -8,12 +17,12 @@ Monday Aug. 12, 2014 [email protected]
            machines.
 
 Saturday  Jul. 19, 2014 [email protected]
-  Summary for 1.6.1 tcpdump release
+  Summary for 1.6.1 libpcap release
        some fixes for the any device
-       changes for how --enable-XXX works
+       changes for how --enable-XXX (--enable-sniffing, --enable-can) works
 
 Wednesday Jul. 2, 2014 [email protected]
-  Summary for 1.6.0 tcpdump release
+  Summary for 1.6.0 libpcap release
         Don't support D-Bus sniffing on OS X
         fixes for byte order issues with NFLOG captures
         Handle using cooked mode for DLT_NETLINK in activate_new().
diff --git a/CREDITS b/CREDITS
index dfc4e411036d14a7276e5744a47b12aa32626e24..a648fd932b07f26b9fd807900661c001d77bbd46 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -2,11 +2,12 @@ This file lists people who have contributed to libpcap:
 
 The current maintainers:
     Bill Fenner                   <fenner at research dot att dot com>
-    Denis Ovsienko                <infrastation at yandex dot ru>
+    Denis Ovsienko                <denis at ovsienko dot info>
     Fulvio Risso                  <risso at polito dot it>
     Guy Harris                    <guy at alum dot mit dot edu>
     Hannes Gredler                <hannes at juniper dot net>
     Michael Richardson            <mcr at sandelman dot ottawa dot on dot ca>
+    Francois-Xavier Le Bail       <fx dot lebail at yahoo dot com>
 
 Additional people who have contributed patches:
 
index 7bbbf0cb8e1c0ce2e22c83207ca83b5dd38b2b92..12f19ccd91bd5d7eeb4c1a0c333e176862fd1e42 100644 (file)
@@ -345,7 +345,6 @@ nametoaddr.c        - hostname to address routines
 nlpid.h                - OSI network layer protocol identifier definitions
 net            - symlink to bpf/net
 optimize.c     - BPF optimization routines
-packaging      - packaging information for building libpcap RPMs
 pcap/bluetooth.h - public definition of DLT_BLUETOOTH_HCI_H4_WITH_PHDR header
 pcap/bpf.h     - BPF definitions
 pcap/namedb.h  - public libpcap name database definitions
index 1c2d7459943f977ec0874418c743ded5146c529d..749345b263d50624522de89ab31310a2ab29251f 100644 (file)
@@ -291,7 +291,6 @@ EXTRA_DIST = \
        msdos/pktdrvr.h \
        msdos/readme.dos \
        org.tcpdump.chmod_bpf.plist \
-       packaging/pcap.spec.in \
        pcap-bpf.c \
        pcap-bt-linux.c \
        pcap-bt-linux.h \
@@ -731,10 +730,6 @@ distclean: clean
 tags: $(TAGFILES)
        ctags -wtd $(TAGFILES)
 
-packaging/pcap.spec: packaging/pcap.spec.in VERSION
-       RPMVERSION=`cat VERSION | sed s/-.*//g`; \
-               sed -e s/@VERSION@/$$RPMVERSION/ -e s/@NAME@/libpcap-`cat VERSION`/ $<   > $@
-
 releasetar:
        @cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \
           mkdir $$name; \
index ad689e16a91232bc45572d5cfbe3b5eb1d44a4a1..ffe04ce358fccb353503c14774061c2833a1ec43 100644 (file)
@@ -195,23 +195,39 @@ m_xhalf(m, k, err)
 }
 #endif
 
+#ifdef __linux__
+#include <linux/types.h>
+#include <linux/if_packet.h>
+#include <linux/filter.h>
+#endif
+
+enum {
+        BPF_S_ANC_NONE,
+        BPF_S_ANC_VLAN_TAG,
+        BPF_S_ANC_VLAN_TAG_PRESENT,
+};
+
 /*
  * Execute the filter program starting at pc on the packet p
  * wirelen is the length of the original packet
  * buflen is the amount of data present
+ * aux_data is auxiliary data, currently used only when interpreting
+ * filters intended for the Linux kernel in cases where the kernel
+ * rejects the filter; it contains VLAN tag information
  * For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0,
  * in all other cases, p is a pointer to a buffer and buflen is its size.
  */
 u_int
-bpf_filter(pc, p, wirelen, buflen)
+bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
        register const struct bpf_insn *pc;
        register const u_char *p;
        u_int wirelen;
        register u_int buflen;
+       register const struct bpf_aux_data *aux_data;
 {
        register u_int32 A, X;
-       register int k;
-       int32 mem[BPF_MEMWORDS];
+       register bpf_u_int32 k;
+       u_int32 mem[BPF_MEMWORDS];
 #if defined(KERNEL) || defined(_KERNEL)
        struct mbuf *m, *n;
        int merr, len;
@@ -250,7 +266,7 @@ bpf_filter(pc, p, wirelen, buflen)
 
                case BPF_LD|BPF_W|BPF_ABS:
                        k = pc->k;
-                       if (k + sizeof(int32) > buflen) {
+                       if (k > buflen || sizeof(int32_t) > buflen - k) {
 #if defined(KERNEL) || defined(_KERNEL)
                                if (m == NULL)
                                        return 0;
@@ -267,7 +283,7 @@ bpf_filter(pc, p, wirelen, buflen)
 
                case BPF_LD|BPF_H|BPF_ABS:
                        k = pc->k;
-                       if (k + sizeof(short) > buflen) {
+                       if (k > buflen || sizeof(int16_t) > buflen - k) {
 #if defined(KERNEL) || defined(_KERNEL)
                                if (m == NULL)
                                        return 0;
@@ -283,22 +299,50 @@ bpf_filter(pc, p, wirelen, buflen)
                        continue;
 
                case BPF_LD|BPF_B|BPF_ABS:
-                       k = pc->k;
-                       if (k >= buflen) {
+                       {
+#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
+                               int code = BPF_S_ANC_NONE;
+#define ANCILLARY(CODE) case SKF_AD_OFF + SKF_AD_##CODE:               \
+                               code = BPF_S_ANC_##CODE;                \
+                                        if (!aux_data)                  \
+                                                return 0;               \
+                                        break;
+
+                               switch (pc->k) {
+                                       ANCILLARY(VLAN_TAG);
+                                       ANCILLARY(VLAN_TAG_PRESENT);
+                               default :
+#endif
+                                       k = pc->k;
+                                       if (k >= buflen) {
 #if defined(KERNEL) || defined(_KERNEL)
-                               if (m == NULL)
-                                       return 0;
-                               n = m;
-                               MINDEX(len, n, k);
-                               A = mtod(n, u_char *)[k];
-                               continue;
+                                               if (m == NULL)
+                                                       return 0;
+                                               n = m;
+                                               MINDEX(len, n, k);
+                                               A = mtod(n, u_char *)[k];
+                                               continue;
 #else
-                               return 0;
+                                               return 0;
+#endif
+                                       }
+                                       A = p[k];
+#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
+                               }
+                               switch (code) {
+                               case BPF_S_ANC_VLAN_TAG:
+                                       if (aux_data)
+                                               A = aux_data->vlan_tag;
+                                       break;
+
+                               case BPF_S_ANC_VLAN_TAG_PRESENT:
+                                       if (aux_data)
+                                               A = aux_data->vlan_tag_present;
+                                       break;
+                               }
 #endif
+                               continue;
                        }
-                       A = p[k];
-                       continue;
-
                case BPF_LD|BPF_W|BPF_LEN:
                        A = wirelen;
                        continue;
@@ -309,7 +353,8 @@ bpf_filter(pc, p, wirelen, buflen)
 
                case BPF_LD|BPF_W|BPF_IND:
                        k = X + pc->k;
-                       if (k + sizeof(int32) > buflen) {
+                       if (pc->k > buflen || X > buflen - pc->k ||
+                           sizeof(int32_t) > buflen - k) {
 #if defined(KERNEL) || defined(_KERNEL)
                                if (m == NULL)
                                        return 0;
@@ -326,7 +371,8 @@ bpf_filter(pc, p, wirelen, buflen)
 
                case BPF_LD|BPF_H|BPF_IND:
                        k = X + pc->k;
-                       if (k + sizeof(short) > buflen) {
+                       if (X > buflen || pc->k > buflen - X ||
+                           sizeof(int16_t) > buflen - k) {
 #if defined(KERNEL) || defined(_KERNEL)
                                if (m == NULL)
                                        return 0;
@@ -343,7 +389,7 @@ bpf_filter(pc, p, wirelen, buflen)
 
                case BPF_LD|BPF_B|BPF_IND:
                        k = X + pc->k;
-                       if (k >= buflen) {
+                       if (pc->k >= buflen || X >= buflen - pc->k) {
 #if defined(KERNEL) || defined(_KERNEL)
                                if (m == NULL)
                                        return 0;
@@ -545,6 +591,17 @@ bpf_filter(pc, p, wirelen, buflen)
        }
 }
 
+u_int
+bpf_filter(pc, p, wirelen, buflen)
+       register const struct bpf_insn *pc;
+       register const u_char *p;
+       u_int wirelen;
+       register u_int buflen;
+{
+       return bpf_filter_with_aux_data(pc, p, wirelen, buflen, NULL);
+}
+
+
 /*
  * Return true if the 'fcode' is a valid filter program.
  * The constraints are that each jump be forward and to a valid
index e665cb9bbc0ca4ad8286077060c90a347c4c6a9b..1a800f57bd8239b42d988a7fb62b73eb4ee1209c 100755 (executable)
--- a/configure
+++ b/configure
@@ -745,6 +745,7 @@ with_flex
 with_bison
 enable_universal
 enable_shared
+enable_usb
 enable_bluetooth
 enable_canusb
 enable_can
@@ -1380,6 +1381,8 @@ Optional Features:
   --disable-universal     don't build universal on OS X
   --enable-shared         build shared libraries [default=yes, if support
                           available]
+  --enable-usb            enable nusb support [default=yes, if support
+                          available]
   --enable-bluetooth      enable Bluetooth support [default=yes, if support
                           available]
   --enable-canusb         enable canusb support [default=yes, if support
@@ -7807,10 +7810,19 @@ ln -s ${srcdir}/bpf/net net
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for USB sniffing support" >&5
+# Check whether --enable-usb was given.
+if test "${enable_usb+set}" = set; then :
+  enableval=$enable_usb;
+else
+  enable_usb=yes
+fi
+
+
+if test "x$enable_usb" != "xno" ; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for USB sniffing support" >&5
 $as_echo_n "checking for USB sniffing support... " >&6; }
-case "$host_os" in
-linux*)
+   case "$host_os" in
+   linux*)
 
 $as_echo "#define PCAP_SUPPORT_USB 1" >>confdefs.h
 
@@ -7923,11 +7935,12 @@ $as_echo "#define HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1" >>confdefs.h
            fi
        fi
        ;;
-*)
+    *)
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
        ;;
 esac
+fi
 
 
 
@@ -8283,23 +8296,35 @@ if test "x$enable_dbus" != "xno"; then
                case "$host_os" in
 
                darwin*)
+                       #
+                       # We don't support D-Bus sniffing on OS X; see
                        #
                        # https://bugs.freedesktop.org/show_bug.cgi?id=74029
                        #
+                       # The user requested it, so fail.
+                       #
                        as_fn_error $? "Due to freedesktop.org bug 74029, D-Bus capture support is not available on OS X" "$LINENO" 5
-                       ;;
                esac
        else
                case "$host_os" in
 
                darwin*)
+                       #
+                       # We don't support D-Bus sniffing on OS X; see
                        #
                        # https://bugs.freedesktop.org/show_bug.cgi?id=74029
                        #
+                       # The user dind't explicitly request it, so just
+                       # silently refuse to enable it.
+                       #
+                       enable_dbus="no"
                        ;;
+               esac
+       fi
+fi
 
-               *)
-                       # Extract the first word of "pkg-config", so it can be a program name with args.
+if test "x$enable_dbus" != "xno"; then
+       # Extract the first word of "pkg-config", so it can be a program name with args.
 set dummy pkg-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
@@ -8337,28 +8362,28 @@ $as_echo "no" >&6; }
 fi
 
 
-                       if test "x$PKGCONFIG" != "xno"; then
-                               { $as_echo "$as_me:${as_lineno-$LINENO}: checking for D-Bus" >&5
+       if test "x$PKGCONFIG" != "xno"; then
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking for D-Bus" >&5
 $as_echo_n "checking for D-Bus... " >&6; }
-                               if "$PKGCONFIG" dbus-1; then
-                                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+               if "$PKGCONFIG" dbus-1; then
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
-                                       DBUS_CFLAGS=`"$PKGCONFIG" --cflags dbus-1`
-                                       DBUS_LIBS=`"$PKGCONFIG" --libs dbus-1`
-                                       save_CFLAGS="$CFLAGS"
-                                       save_LIBS="$LIBS"
-                                       CFLAGS="$CFLAGS $DBUS_CFLAGS"
-                                       LIBS="$LIBS $DBUS_LIBS"
-                                       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the D-Bus library defines dbus_connection_read_write" >&5
+                       DBUS_CFLAGS=`"$PKGCONFIG" --cflags dbus-1`
+                       DBUS_LIBS=`"$PKGCONFIG" --libs dbus-1`
+                       save_CFLAGS="$CFLAGS"
+                       save_LIBS="$LIBS"
+                       CFLAGS="$CFLAGS $DBUS_CFLAGS"
+                       LIBS="$LIBS $DBUS_LIBS"
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the D-Bus library defines dbus_connection_read_write" >&5
 $as_echo_n "checking whether the D-Bus library defines dbus_connection_read_write... " >&6; }
-                                       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+                       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <string.h>
 
-                                            #include <time.h>
-                                            #include <sys/time.h>
+                            #include <time.h>
+                            #include <sys/time.h>
 
-                                            #include <dbus/dbus.h>
+                            #include <dbus/dbus.h>
 int
 main ()
 {
@@ -8369,37 +8394,34 @@ return dbus_connection_read_write(NULL, 0);
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
 
-                                               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+                               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
 $as_echo "#define PCAP_SUPPORT_DBUS 1" >>confdefs.h
 
-                                               DBUS_SRC=pcap-dbus.c
-                                               V_INCLS="$V_INCLS $DBUS_CFLAGS"
+                               DBUS_SRC=pcap-dbus.c
+                               V_INCLS="$V_INCLS $DBUS_CFLAGS"
 
 else
 
-                                               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+                               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-                                               if test "x$enable_dbus" = "xyes"; then
-                                                   as_fn_error $? "--enable-dbus was given, but the D-Bus library doesn't define dbus_connection_read_write()" "$LINENO" 5
-                                               fi
-                                               LIBS="$save_LIBS"
+                               if test "x$enable_dbus" = "xyes"; then
+                                   as_fn_error $? "--enable-dbus was given, but the D-Bus library doesn't define dbus_connection_read_write()" "$LINENO" 5
+                               fi
+                               LIBS="$save_LIBS"
 
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-                                       CFLAGS="$save_CFLAGS"
-                               else
-                                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+                       CFLAGS="$save_CFLAGS"
+               else
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-                                       if test "x$enable_dbus" = "xyes"; then
-                                               as_fn_error $? "--enable-dbus was given, but the dbus-1 package is not installed" "$LINENO" 5
-                                       fi
-                               fi
+                       if test "x$enable_dbus" = "xyes"; then
+                               as_fn_error $? "--enable-dbus was given, but the dbus-1 package is not installed" "$LINENO" 5
                        fi
-                       ;;
-               esac
+               fi
        fi
 
 
index 4530aed3a7d02980cff98801a0e63378b89ec1c0..063c645235c755f6f41459ff6333fb1fac8c8e99 100644 (file)
@@ -1348,10 +1348,16 @@ AC_SUBST(DYEXT)
 AC_SUBST(MAN_FILE_FORMATS)
 AC_SUBST(MAN_MISC_INFO)
 
-dnl check for USB sniffing support
-AC_MSG_CHECKING(for USB sniffing support)
-case "$host_os" in
-linux*)
+AC_ARG_ENABLE([usb],
+[AC_HELP_STRING([--enable-usb],[enable nusb support @<:@default=yes, if support available@:>@])],
+    [],
+    [enable_usb=yes])
+
+if test "x$enable_usb" != "xno" ; then
+   dnl check for USB sniffing support
+   AC_MSG_CHECKING(for USB sniffing support)
+   case "$host_os" in
+   linux*)
        AC_DEFINE(PCAP_SUPPORT_USB, 1, [target host supports USB sniffing])
        USB_SRC=pcap-usb-linux.c
        AC_MSG_RESULT(yes)
@@ -1402,10 +1408,11 @@ AC_INCLUDES_DEFAULT
            fi
        fi
        ;;
-*)
+    *)
        AC_MSG_RESULT(no)
        ;;
 esac
+fi
 AC_SUBST(PCAP_SUPPORT_USB)
 AC_SUBST(USB_SRC)
 
@@ -1623,65 +1630,74 @@ if test "x$enable_dbus" != "xno"; then
                case "$host_os" in
 
                darwin*)
+                       #
+                       # We don't support D-Bus sniffing on OS X; see
                        #
                        # https://bugs.freedesktop.org/show_bug.cgi?id=74029
                        #
+                       # The user requested it, so fail.
+                       #
                        AC_MSG_ERROR([Due to freedesktop.org bug 74029, D-Bus capture support is not available on OS X])
-                       ;;
                esac
        else            
                case "$host_os" in
 
                darwin*)
+                       #
+                       # We don't support D-Bus sniffing on OS X; see
                        #
                        # https://bugs.freedesktop.org/show_bug.cgi?id=74029
                        #
+                       # The user dind't explicitly request it, so just
+                       # silently refuse to enable it.
+                       #
+                       enable_dbus="no"
                        ;;
+               esac
+       fi
+fi
 
-               *)
-                       AC_CHECK_PROG([PKGCONFIG], [pkg-config], [pkg-config], [no])
-                       if test "x$PKGCONFIG" != "xno"; then
-                               AC_MSG_CHECKING([for D-Bus])
-                               if "$PKGCONFIG" dbus-1; then
-                                       AC_MSG_RESULT([yes])
-                                       DBUS_CFLAGS=`"$PKGCONFIG" --cflags dbus-1`
-                                       DBUS_LIBS=`"$PKGCONFIG" --libs dbus-1`
-                                       save_CFLAGS="$CFLAGS"
-                                       save_LIBS="$LIBS"
-                                       CFLAGS="$CFLAGS $DBUS_CFLAGS"
-                                       LIBS="$LIBS $DBUS_LIBS"
-                                       AC_MSG_CHECKING(whether the D-Bus library defines dbus_connection_read_write)
-                                       AC_TRY_LINK(
-                                           [#include <string.h>
-
-                                            #include <time.h>
-                                            #include <sys/time.h>
-
-                                            #include <dbus/dbus.h>],
-                                           [return dbus_connection_read_write(NULL, 0);],
-                                           [
-                                               AC_MSG_RESULT([yes])
-                                               AC_DEFINE(PCAP_SUPPORT_DBUS, 1, [support D-Bus sniffing])
-                                               DBUS_SRC=pcap-dbus.c
-                                               V_INCLS="$V_INCLS $DBUS_CFLAGS"
-                                           ],
-                                           [
-                                               AC_MSG_RESULT([no])
-                                               if test "x$enable_dbus" = "xyes"; then
-                                                   AC_MSG_ERROR([--enable-dbus was given, but the D-Bus library doesn't define dbus_connection_read_write()])
-                                               fi
-                                               LIBS="$save_LIBS"
-                                            ])
-                                       CFLAGS="$save_CFLAGS"
-                               else
-                                       AC_MSG_RESULT([no])
-                                       if test "x$enable_dbus" = "xyes"; then
-                                               AC_MSG_ERROR([--enable-dbus was given, but the dbus-1 package is not installed])
-                                       fi
+if test "x$enable_dbus" != "xno"; then
+       AC_CHECK_PROG([PKGCONFIG], [pkg-config], [pkg-config], [no])
+       if test "x$PKGCONFIG" != "xno"; then
+               AC_MSG_CHECKING([for D-Bus])
+               if "$PKGCONFIG" dbus-1; then
+                       AC_MSG_RESULT([yes])
+                       DBUS_CFLAGS=`"$PKGCONFIG" --cflags dbus-1`
+                       DBUS_LIBS=`"$PKGCONFIG" --libs dbus-1`
+                       save_CFLAGS="$CFLAGS"
+                       save_LIBS="$LIBS"
+                       CFLAGS="$CFLAGS $DBUS_CFLAGS"
+                       LIBS="$LIBS $DBUS_LIBS"
+                       AC_MSG_CHECKING(whether the D-Bus library defines dbus_connection_read_write)
+                       AC_TRY_LINK(
+                           [#include <string.h>
+
+                            #include <time.h>
+                            #include <sys/time.h>
+
+                            #include <dbus/dbus.h>],
+                           [return dbus_connection_read_write(NULL, 0);],
+                           [
+                               AC_MSG_RESULT([yes])
+                               AC_DEFINE(PCAP_SUPPORT_DBUS, 1, [support D-Bus sniffing])
+                               DBUS_SRC=pcap-dbus.c
+                               V_INCLS="$V_INCLS $DBUS_CFLAGS"
+                           ],
+                           [
+                               AC_MSG_RESULT([no])
+                               if test "x$enable_dbus" = "xyes"; then
+                                   AC_MSG_ERROR([--enable-dbus was given, but the D-Bus library doesn't define dbus_connection_read_write()])
                                fi
+                               LIBS="$save_LIBS"
+                            ])
+                       CFLAGS="$save_CFLAGS"
+               else
+                       AC_MSG_RESULT([no])
+                       if test "x$enable_dbus" = "xyes"; then
+                               AC_MSG_ERROR([--enable-dbus was given, but the dbus-1 package is not installed])
                        fi
-                       ;;      
-               esac
+               fi
        fi
        AC_SUBST(PCAP_SUPPORT_DBUS)
        AC_SUBST(DBUS_SRC)
index 4a97aba46d2c877e63e446eb43bd1d6fffdc5ea8..aefd38b6ab84838d82c1a0f6710088d80ea759f1 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -131,9 +131,9 @@ static pcap_t *bpf_pcap;
 
 /* Hack for updating VLAN, MPLS, and PPPoE offsets. */
 #ifdef WIN32
-static u_int   orig_linktype = (u_int)-1, orig_nl = (u_int)-1, label_stack_depth = (u_int)-1;
+static u_int   orig_linktype = (u_int)-1, orig_nl = (u_int)-1, label_stack_depth = (u_int)-1, vlan_stack_depth = (u_int)-1;
 #else
-static u_int   orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U;
+static u_int   orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U, vlan_stack_depth = -1U;
 #endif
 
 /* XXX */
@@ -963,6 +963,7 @@ init_linktype(p)
        orig_linktype = -1;
        orig_nl = -1;
         label_stack_depth = 0;
+        vlan_stack_depth = 0;
 
        reg_off_ll = -1;
        reg_off_macpl = -1;
@@ -8045,6 +8046,65 @@ gen_ahostop(eaddr, dir)
        /* NOTREACHED */
 }
 
+#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
+static struct block *
+gen_vlan_bpf_extensions(int vlan_num)
+{
+        struct block *b0, *b1;
+        struct slist *s;
+
+        /* generate new filter code based on extracting packet
+         * metadata */
+        s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+        s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT;
+
+        b0 = new_block(JMP(BPF_JEQ));
+        b0->stmts = s;
+        b0->s.k = 1;
+
+        if (vlan_num >= 0) {
+                s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+                s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG;
+
+                b1 = new_block(JMP(BPF_JEQ));
+                b1->stmts = s;
+                b1->s.k = (bpf_int32) vlan_num;
+
+                gen_and(b0,b1);
+                b0 = b1;
+        }
+
+        return b0;
+}
+#endif
+
+static struct block *
+gen_vlan_no_bpf_extensions(int vlan_num)
+{
+        struct block *b0, *b1;
+
+        /* check for VLAN, including QinQ */
+        b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+                     (bpf_int32)ETHERTYPE_8021Q);
+        b1 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+                     (bpf_int32)ETHERTYPE_8021QINQ);
+        gen_or(b0,b1);
+        b0 = b1;
+
+        /* If a specific VLAN is requested, check VLAN id */
+        if (vlan_num >= 0) {
+                b1 = gen_mcmp(OR_MACPL, 0, BPF_H,
+                              (bpf_int32)vlan_num, 0x0fff);
+                gen_and(b0, b1);
+                b0 = b1;
+        }
+
+        off_macpl += 4;
+        off_linktype += 4;
+
+        return b0;
+}
+
 /*
  * support IEEE 802.1Q VLAN trunk over ethernet
  */
@@ -8052,7 +8112,7 @@ struct block *
 gen_vlan(vlan_num)
        int vlan_num;
 {
-       struct  block   *b0, *b1;
+       struct  block   *b0;
 
        /* can't check for VLAN-encapsulated packets inside MPLS */
        if (label_stack_depth > 0)
@@ -8096,36 +8156,27 @@ gen_vlan(vlan_num)
        case DLT_EN10MB:
        case DLT_NETANALYZER:
        case DLT_NETANALYZER_TRANSPARENT:
-               /* check for VLAN, including QinQ */
-               b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
-                   (bpf_int32)ETHERTYPE_8021Q);
-               b1 = gen_cmp(OR_LINK, off_linktype, BPF_H,
-                   (bpf_int32)ETHERTYPE_8021QINQ);
-               gen_or(b0,b1);
-               b0 = b1;
-
-               /* If a specific VLAN is requested, check VLAN id */
-               if (vlan_num >= 0) {
-                       b1 = gen_mcmp(OR_MACPL, 0, BPF_H,
-                           (bpf_int32)vlan_num, 0x0fff);
-                       gen_and(b0, b1);
-                       b0 = b1;
-               }
-
-               off_macpl += 4;
-               off_linktype += 4;
-#if 0
-               off_nl_nosnap += 4;
-               off_nl += 4;
+#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
+               if (vlan_stack_depth == 0) {
+                       /*
+                        * Do we need special VLAN handling?
+                        */
+                       if (bpf_pcap->bpf_codegen_flags & BPF_SPECIAL_VLAN_HANDLING)
+                               b0 = gen_vlan_bpf_extensions(vlan_num);
+                       else
+                               b0 = gen_vlan_no_bpf_extensions(vlan_num);
+               } else
 #endif
-               break;
-
+                       b0 = gen_vlan_no_bpf_extensions(vlan_num);
+                break;
        default:
                bpf_error("no VLAN support for data link type %d",
                      linktype);
                /*NOTREACHED*/
        }
 
+        vlan_stack_depth++;
+
        return (b0);
 }
 
@@ -8136,7 +8187,7 @@ struct block *
 gen_mpls(label_num)
        int label_num;
 {
-       struct  block   *b0,*b1;
+       struct  block   *b0, *b1;
 
        /*
         * Change the offsets to point to the type and data fields within
diff --git a/inet.c b/inet.c
index 036b2db316d6b4084a5dc76d59a416e07db786f2..fad7e25bcab1c9fb025b54ce555eb34bcfeb3e51 100644 (file)
--- a/inet.c
+++ b/inet.c
@@ -905,7 +905,7 @@ pcap_lookupnet(device, netp, maskp, errbuf)
        /* XXX Work around Linux kernel bug */
        ifr.ifr_addr.sa_family = AF_INET;
 #endif
-       (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+       (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
        if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
                if (errno == EADDRNOTAVAIL) {
                        (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
@@ -925,7 +925,7 @@ pcap_lookupnet(device, netp, maskp, errbuf)
        /* XXX Work around Linux kernel bug */
        ifr.ifr_addr.sa_family = AF_INET;
 #endif
-       (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+       (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
        if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
                (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
                    "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
diff --git a/mkdep b/mkdep
index bfe4a2614a4f02d2c2c18c23cdd8df7d031158e0..1486b185aa4341c22f88fbc60755284b6ac25442 100755 (executable)
--- a/mkdep
+++ b/mkdep
@@ -13,9 +13,6 @@
 #      @(#)mkdep.sh    5.11 (Berkeley) 5/5/88
 #
 
-PATH=/bin:/usr/bin:/usr/ucb:/usr/local:/usr/local/bin:/usr/sfw/bin
-export PATH
-
 MAKE=Makefile                  # default makefile name is "Makefile"
 CC=cc                          # default C compiler is "cc"
 DEPENDENCY_CFLAG=-M            # default dependency-generation flag is -M
diff --git a/packaging/pcap.spec.in b/packaging/pcap.spec.in
deleted file mode 100644 (file)
index ff7b996..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-%define prefix   /usr
-%define version @VERSION@
-
-Summary: A system-independent interface for user-level packet capture
-Name: libpcap
-Version: %version
-Release: 1
-Group: Development/Libraries
-License: BSD with advertising
-BuildRoot: /tmp/%{name}-buildroot
-URL: http://www.tcpdump.org
-
-Source: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz
-
-%description
-Libpcap provides a portable framework for low-level network
-monitoring.  Libpcap can provide network statistics collection,
-security monitoring and network debugging.  Since almost every system
-vendor provides a different interface for packet capture, the libpcap
-authors created this system-independent API to ease in porting and to
-alleviate the need for several system-dependent packet capture modules
-in each application.
-
-Install libpcap if you need to do low-level network traffic monitoring
-on your network.
-
-%package devel
-Summary: Libraries and header files for the libpcap library
-Group: Development/Libraries
-
-%description devel
-Libpcap provides a portable framework for low-level network
-monitoring.  Libpcap can provide network statistics collection,
-security monitoring and network debugging.  Since almost every system
-vendor provides a different interface for packet capture, the libpcap
-authors created this system-independent API to ease in porting and to
-alleviate the need for several system-dependent packet capture modules
-in each application.
-
-This package provides the libraries, include files, and other 
-resources needed for developing libpcap applications.
-%prep
-%setup -q
-
-%build
-export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
-%configure
-make %{?_smp_mflags}
-
-%install
-rm -rf $RPM_BUILD_ROOT
-
-make DESTDIR=$RPM_BUILD_ROOT install
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root)
-%doc LICENSE README CHANGES INSTALL.txt README.linux TODO VERSION CREDITS packaging/pcap.spec
-%{_libdir}/libpcap.so.*
-%{_mandir}/man7/pcap*.7*
-
-%files devel
-%defattr(-,root,root)
-%{_bindir}/pcap-config
-%{_includedir}/pcap/*.h
-%{_includedir}/pcap.h
-%{_includedir}/pcap-bpf.h
-%{_includedir}/pcap-namedb.h
-%{_libdir}/libpcap.so
-%{_libdir}/libpcap.a
-%{_mandir}/man1/pcap-config.1*
-%{_mandir}/man3/pcap*.3*
-%{_mandir}/man5/pcap*.5*
index 9a994c4aa3037017661851d4b31a06bd6ea92ff0..2dedd4ad02fe94953973037299f45371a3e68fba 100644 (file)
@@ -1538,22 +1538,43 @@ pcap_activate_bpf(pcap_t *p)
 
 #if defined(LIFNAMSIZ) && defined(ZONENAME_MAX) && defined(lifr_zoneid)
        /*
-        * Check if the given source network device has a '/' separated
-        * zonename prefix string. The zonename prefixed source device
-        * can be used by libpcap consumers to capture network traffic
-        * in non-global zones from the global zone on Solaris 11 and
-        * above. If the zonename prefix is present then we strip the
-        * prefix and pass the zone ID as part of lifr_zoneid.
+        * Retrieve the zoneid of the zone we are currently executing in.
+        */
+       if ((ifr.lifr_zoneid = getzoneid()) == -1) {
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "getzoneid(): %s",
+                   pcap_strerror(errno));
+               status = PCAP_ERROR;
+               goto bad;
+       }
+       /*
+        * Check if the given source datalink name has a '/' separated
+        * zonename prefix string.  The zonename prefixed source datalink can
+        * be used by pcap consumers in the Solaris global zone to capture
+        * traffic on datalinks in non-global zones.  Non-global zones
+        * do not have access to datalinks outside of their own namespace.
         */
        if ((zonesep = strchr(p->opt.source, '/')) != NULL) {
-               char zonename[ZONENAME_MAX];
+               char path_zname[ZONENAME_MAX];
                int  znamelen;
                char *lnamep;
 
+               if (ifr.lifr_zoneid != GLOBAL_ZONEID) {
+                       snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+                           "zonename/linkname only valid in global zone.");
+                       status = PCAP_ERROR;
+                       goto bad;
+               }
                znamelen = zonesep - p->opt.source;
-               (void) strlcpy(zonename, p->opt.source, znamelen + 1);
+               (void) strlcpy(path_zname, p->opt.source, znamelen + 1);
+               ifr.lifr_zoneid = getzoneidbyname(path_zname);
+               if (ifr.lifr_zoneid == -1) {
+                       snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+                           "getzoneidbyname(%s): %s", path_zname,
+                       pcap_strerror(errno));
+                       status = PCAP_ERROR;
+                       goto bad;
+               }
                lnamep = strdup(zonesep + 1);
-               ifr.lifr_zoneid = getzoneidbyname(zonename);
                free(p->opt.source);
                p->opt.source = lnamep;
        }
index 76c9ee34a4e1d89dfcd05cf262070111805bfc9b..f193e26362f04a957ce38f1e8490de9daf3635e3 100644 (file)
@@ -44,6 +44,8 @@
 #include "pcap/bluetooth.h"
 #include "pcap-int.h"
 
+#include "pcap-bt-monitor-linux.h"
+
 #define BT_CONTROL_SIZE 32
 #define INTERFACE_NAME "bluetooth-monitor"
 
@@ -71,7 +73,6 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
     struct pcap_pkthdr pkth;
     pcap_bluetooth_linux_monitor_header *bthdr;
     struct mgmt_hdr hdr;
-    int in = 0;
 
     bthdr = (pcap_bluetooth_linux_monitor_header*) &handle->buffer[handle->offset];
 
index 3a9e8cbeef21d14614a8d7c41474be4d6ae344e2..a8e1e355ef5ec6cccf9e1652fc35846225124e0c 100644 (file)
@@ -171,7 +171,7 @@ can_activate(pcap_t* handle)
 
        /* get interface index */
        memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, handle->opt.source, sizeof(ifr.ifr_name));
+       strlcpy(ifr.ifr_name, handle->opt.source, sizeof(ifr.ifr_name));
        if (ioctl(handle->fd, SIOCGIFINDEX, &ifr) < 0)
        {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
index a72f4697fa4d7a0972cc9ba56b973fd8b42220e1..99776f4dde3badd1bd3763006214889b926c6c5e 100644 (file)
@@ -41,6 +41,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <errno.h>
 #include <string.h>
 #include <pthread.h>
 
@@ -277,7 +278,8 @@ static void* canusb_capture_thread(void *arg)
         for(i = 0; i<status.rxsz; i++)
         {
             libusb_bulk_transfer(canusb->dev, 0x85, (unsigned char*)&msg, sizeof(msg), &sz, 100);      
-            write(canusb->wrpipe, &msg, sizeof(msg));
+            if(write(canusb->wrpipe, &msg, sizeof(msg)) < 0)
+                fprintf(stderr,"write() error: %s\n", strerror(errno));
         }
 
     }
index a68e03221528905fe9c167347b6ddc3e0f2d7113..bb657c89b9aa3c09ca77bfe23dfe4cf52e8c8186 100644 (file)
  */
 #define LINKTYPE_IPMI_HPM_2    260
 
-#define LINKTYPE_MATCHING_MAX  260             /* highest value in the "matching" range */
+/*
+ * per  Joshua Wright <[email protected]>, formats for Zwave captures.
+ */
+#define LINKTYPE_ZWAVE_R1_R2   261
+#define LINKTYPE_ZWAVE_R3      262
+
+#define LINKTYPE_MATCHING_MAX  262             /* highest value in the "matching" range */
 
 static struct linktype_map {
        int     dlt;
index 5a20444617a9d8d061ddf9d1ff7ae06815145b26..2f71e1152676aa8c949b3aff06dea27a2ad6697e 100644 (file)
@@ -202,6 +202,11 @@ struct pcap {
        /* We're accepting only packets in this direction/these directions. */
        pcap_direction_t direction;
 
+       /*
+        * Flags to affect BPF code generation.
+        */
+       int bpf_codegen_flags;
+
        /*
         * Placeholder for filter code if bpf not in kernel.
         */
@@ -248,6 +253,11 @@ struct pcap {
        cleanup_op_t cleanup_op;
 };
 
+/*
+ * BPF code generation flags.
+ */
+#define BPF_SPECIAL_VLAN_HANDLING      0x00000001      /* special VLAN handling for Linux */
+
 /*
  * This is a timeval as stored in a savefile.
  * It has to use the same types everywhere, independent of the actual
index 5fd564dee333b88407aac43b1e9e90046b4e5483..6cf12329d207a2caa29248238931d322589b852e 100644 (file)
@@ -382,6 +382,9 @@ static int  has_wext(int sock_fd, const char *device, char *ebuf);
 static int     enter_rfmon_mode(pcap_t *handle, int sock_fd,
     const char *device);
 #endif /* HAVE_PF_PACKET_SOCKETS */
+#if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP)
+static int     iface_ethtool_get_ts_info(pcap_t *handle, char *ebuf);
+#endif
 static int     iface_get_offload(pcap_t *handle);
 static int     iface_bind_old(int fd, const char *device, char *ebuf);
 
@@ -409,28 +412,15 @@ pcap_create_interface(const char *device, char *ebuf)
 
        handle->activate_op = pcap_activate_linux;
        handle->can_set_rfmon_op = pcap_can_set_rfmon_linux;
+
 #if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP)
        /*
-        * We claim that we support:
-        *
-        *      software time stamps, with no details about their precision;
-        *      hardware time stamps, synced to the host time;
-        *      hardware time stamps, not synced to the host time.
-        *
-        * XXX - we can't ask a device whether it supports
-        * hardware time stamps, so we just claim all devices do.
+        * See what time stamp types we support.
         */
-       handle->tstamp_type_count = 3;
-       handle->tstamp_type_list = malloc(3 * sizeof(u_int));
-       if (handle->tstamp_type_list == NULL) {
-               snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
-                   pcap_strerror(errno));
+       if (iface_ethtool_get_ts_info(handle, ebuf) == -1) {
                free(handle);
                return NULL;
        }
-       handle->tstamp_type_list[0] = PCAP_TSTAMP_HOST;
-       handle->tstamp_type_list[1] = PCAP_TSTAMP_ADAPTER;
-       handle->tstamp_type_list[2] = PCAP_TSTAMP_ADAPTER_UNSYNCED;
 #endif
 
 #if defined(SIOCGSTAMPNS) && defined(SO_TIMESTAMPNS)
@@ -1494,6 +1484,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
        int                     packet_len, caplen;
        struct pcap_pkthdr      pcap_header;
 
+        struct bpf_aux_data     aux_data;
 #ifdef HAVE_PF_PACKET_SOCKETS
        /*
         * If this is a cooked device, leave extra room for a
@@ -1677,6 +1668,11 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
                        tag->vlan_tpid = htons(ETH_P_8021Q);
                        tag->vlan_tci = htons(aux->tp_vlan_tci);
 
+                        /* store vlan tci to bpf_aux_data struct for userland bpf filter */
+#if defined(TP_STATUS_VLAN_VALID)
+                        aux_data.vlan_tag = htons(aux->tp_vlan_tci) & 0x0fff;
+                        aux_data.vlan_tag_present = (aux->tp_status & TP_STATUS_VLAN_VALID);
+#endif
                        packet_len += VLAN_TAG_LEN;
                }
        }
@@ -1721,9 +1717,8 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
 
        /* Run the packet filter if not using kernel filter */
        if (handlep->filter_in_userland && handle->fcode.bf_insns) {
-               if (bpf_filter(handle->fcode.bf_insns, bp,
-                               packet_len, caplen) == 0)
-               {
+               if (bpf_filter_with_aux_data(handle->fcode.bf_insns, bp,
+                   packet_len, caplen, &aux_data) == 0) {
                        /* rejected by filter */
                        return 0;
                }
@@ -3020,6 +3015,10 @@ activate_new(pcap_t *handle)
 #endif
        int                     err = 0;
        struct packet_mreq      mr;
+#ifdef SO_BPF_EXTENSIONS
+       int                     bpf_extensions;
+       socklen_t               len;
+#endif
 
        /*
         * Open a socket with protocol family packet. If the
@@ -3350,6 +3349,23 @@ activate_new(pcap_t *handle)
         */
        handle->fd = sock_fd;
 
+#ifdef SO_BPF_EXTENSIONS
+       /*
+        * Can we generate special code for VLAN checks?
+        * (XXX - what if we need the special code but it's not supported
+        * by the OS?  Is that possible?)
+        */
+       if (getsockopt(sock_fd, SOL_SOCKET, SO_BPF_EXTENSIONS,
+           &bpf_extensions, &len) == 0) {
+               if (bpf_extensions >= SKF_AD_VLAN_TAG_PRESENT) {
+                       /*
+                        * Yes, we can.  Request that we do so.
+                        */
+                       handle->bpf_codegen_flags |= BPF_SPECIAL_VLAN_HANDLING;
+               }
+       }
+#endif /* SO_BPF_EXTENSIONS */
+
        return 1;
 #else /* HAVE_PF_PACKET_SOCKETS */
        strlcpy(ebuf,
@@ -4235,10 +4251,16 @@ static int pcap_handle_packet_mmap(
         * the filter when the ring became empty, but it can possibly
         * happen a lot later... */
        bp = frame + tp_mac;
-       if (handlep->filter_in_userland && handle->fcode.bf_insns &&
-                       (bpf_filter(handle->fcode.bf_insns, bp,
-                               tp_len, tp_snaplen) == 0))
-               return 0;
+       if (handlep->filter_in_userland && handle->fcode.bf_insns) {
+               struct bpf_aux_data aux_data;
+
+               aux_data.vlan_tag = tp_vlan_tci & 0x0fff;
+               aux_data.vlan_tag_present = tp_vlan_tci_valid;
+
+               if (bpf_filter_with_aux_data(handle->fcode.bf_insns, bp,
+                   tp_len, tp_snaplen, &aux_data) == 0)
+                       return 0;
+       }
 
        sll = (void *)frame + TPACKET_ALIGN(handlep->tp_hdrlen);
        if (!linux_check_direction(handle, sll))
@@ -5459,6 +5481,116 @@ enter_rfmon_mode(pcap_t *handle, int sock_fd, const char *device)
        return 0;
 }
 
+#if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP)
+/*
+ * Map SOF_TIMESTAMPING_ values to PCAP_TSTAMP_ values.
+ */
+static const struct {
+       int soft_timestamping_val;
+       int pcap_tstamp_val;
+} sof_ts_type_map[3] = {
+       { SOF_TIMESTAMPING_SOFTWARE, PCAP_TSTAMP_HOST },
+       { SOF_TIMESTAMPING_SYS_HARDWARE, PCAP_TSTAMP_ADAPTER },
+       { SOF_TIMESTAMPING_RAW_HARDWARE, PCAP_TSTAMP_ADAPTER_UNSYNCED }
+};
+#define NUM_SOF_TIMESTAMPING_TYPES     (sizeof sof_ts_type_map / sizeof sof_ts_type_map[0])
+
+static void
+iface_set_default_ts_types(pcap_t *handle)
+{
+       int i;
+
+       handle->tstamp_type_count = NUM_SOF_TIMESTAMPING_TYPES;
+       handle->tstamp_type_list = malloc(NUM_SOF_TIMESTAMPING_TYPES * sizeof(u_int));
+       for (i = 0; i < NUM_SOF_TIMESTAMPING_TYPES; i++)
+               handle->tstamp_type_list[i] = sof_ts_type_map[i].pcap_tstamp_val;
+}
+
+#ifdef ETHTOOL_GET_TS_INFO
+/*
+ * Get a list of time stamping capabilities.
+ */
+static int
+iface_ethtool_get_ts_info(pcap_t *handle, char *ebuf)
+{
+       int fd;
+       struct ifreq ifr;
+       struct ethtool_ts_info info;
+       int num_ts_types;
+       int i, j;
+
+       /* ioctl() will fail for the "any" pseudo-device with ENODEV. */
+       if (! strcmp(handle->opt.source, "any")) {
+                       iface_set_default_ts_types(handle);
+                       return 0;
+       }
+
+       /*
+        * Create a socket from which to fetch time stamping capabilities.
+        */
+       fd = socket(AF_INET, SOCK_DGRAM, 0);
+       if (fd < 0) {
+               (void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
+                   "socket for SIOCETHTOOL(ETHTOOL_GET_TS_INFO): %s", pcap_strerror(errno));
+               return -1;
+       }
+
+       memset(&ifr, 0, sizeof(ifr));
+       strlcpy(ifr.ifr_name, handle->opt.source, sizeof(ifr.ifr_name));
+       memset(&info, 0, sizeof(info));
+       info.cmd = ETHTOOL_GET_TS_INFO;
+       ifr.ifr_data = (caddr_t)&info;
+       if (ioctl(fd, SIOCETHTOOL, &ifr) == -1) {
+               if (errno == EOPNOTSUPP || errno == EINVAL) {
+                       /*
+                        * OK, let's just return all the possible time
+                        * stamping types.
+                        */
+                       iface_set_default_ts_types(handle);
+                       return 0;
+               }
+               snprintf(ebuf, PCAP_ERRBUF_SIZE,
+                   "%s: SIOCETHTOOL(ETHTOOL_GET_TS_INFO) ioctl failed: %s", handle->opt.source,
+                   strerror(errno));
+               close(fd);
+               return -1;
+       }
+       close(fd);
+
+       num_ts_types = 0;
+       for (i = 0; i < NUM_SOF_TIMESTAMPING_TYPES; i++) {
+               if (info.so_timestamping & sof_ts_type_map[i].soft_timestamping_val)
+                       num_ts_types++;
+       }
+       handle->tstamp_type_count = num_ts_types;
+       if (num_ts_types != 0) {
+               handle->tstamp_type_list = malloc(num_ts_types * sizeof(u_int));
+               for (i = 0, j = 0; i < NUM_SOF_TIMESTAMPING_TYPES; i++) {
+                       if (info.so_timestamping & sof_ts_type_map[i].soft_timestamping_val) {
+                               handle->tstamp_type_list[j] = sof_ts_type_map[i].pcap_tstamp_val;
+                               j++;
+                       }
+               }
+       } else
+               handle->tstamp_type_list = NULL;
+
+       return 0;
+}
+#else /* ETHTOOL_GET_TS_INFO */
+static int
+iface_ethtool_get_ts_info(pcap_t *handle, char *ebuf _U_)
+{
+       /*
+        * We don't have an ioctl to use to ask what's supported,
+        * so say we support everything.
+        */
+       iface_set_default_ts_types(handle);
+       return 0;
+}
+#endif /* ETHTOOL_GET_TS_INFO */
+
+#endif /* defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP) */
+
 /*
  * Find out if we have any form of fragmentation/reassembly offloading.
  *
@@ -5469,7 +5601,7 @@ enter_rfmon_mode(pcap_t *handle, int sock_fd, const char *device)
  */
 #if defined(SIOCETHTOOL) && (defined(ETHTOOL_GTSO) || defined(ETHTOOL_GUFO) || defined(ETHTOOL_GGSO) || defined(ETHTOOL_GFLAGS) || defined(ETHTOOL_GGRO))
 static int
-iface_ethtool_ioctl(pcap_t *handle, int cmd, const char *cmdname)
+iface_ethtool_flag_ioctl(pcap_t *handle, int cmd, const char *cmdname)
 {
        struct ifreq    ifr;
        struct ethtool_value eval;
@@ -5490,7 +5622,7 @@ iface_ethtool_ioctl(pcap_t *handle, int cmd, const char *cmdname)
                        return 0;
                }
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
-                   "%s: SIOETHTOOL(%s) ioctl failed: %s", handle->opt.source,
+                   "%s: SIOCETHTOOL(%s) ioctl failed: %s", handle->opt.source,
                    cmdname, strerror(errno));
                return -1;
        }
@@ -5503,7 +5635,7 @@ iface_get_offload(pcap_t *handle)
        int ret;
 
 #ifdef ETHTOOL_GTSO
-       ret = iface_ethtool_ioctl(handle, ETHTOOL_GTSO, "ETHTOOL_GTSO");
+       ret = iface_ethtool_flag_ioctl(handle, ETHTOOL_GTSO, "ETHTOOL_GTSO");
        if (ret == -1)
                return -1;
        if (ret)
@@ -5511,7 +5643,7 @@ iface_get_offload(pcap_t *handle)
 #endif
 
 #ifdef ETHTOOL_GUFO
-       ret = iface_ethtool_ioctl(handle, ETHTOOL_GUFO, "ETHTOOL_GUFO");
+       ret = iface_ethtool_flag_ioctl(handle, ETHTOOL_GUFO, "ETHTOOL_GUFO");
        if (ret == -1)
                return -1;
        if (ret)
@@ -5524,7 +5656,7 @@ iface_get_offload(pcap_t *handle)
         * handed to PF_PACKET sockets on transmission?  If not,
         * this need not be checked.
         */
-       ret = iface_ethtool_ioctl(handle, ETHTOOL_GGSO, "ETHTOOL_GGSO");
+       ret = iface_ethtool_flag_ioctl(handle, ETHTOOL_GGSO, "ETHTOOL_GGSO");
        if (ret == -1)
                return -1;
        if (ret)
@@ -5532,7 +5664,7 @@ iface_get_offload(pcap_t *handle)
 #endif
 
 #ifdef ETHTOOL_GFLAGS
-       ret = iface_ethtool_ioctl(handle, ETHTOOL_GFLAGS, "ETHTOOL_GFLAGS");
+       ret = iface_ethtool_flag_ioctl(handle, ETHTOOL_GFLAGS, "ETHTOOL_GFLAGS");
        if (ret == -1)
                return -1;
        if (ret & ETH_FLAG_LRO)
@@ -5545,7 +5677,7 @@ iface_get_offload(pcap_t *handle)
         * handed to PF_PACKET sockets on receipt?  If not,
         * this need not be checked.
         */
-       ret = iface_ethtool_ioctl(handle, ETHTOOL_GGRO, "ETHTOOL_GGRO");
+       ret = iface_ethtool_flag_ioctl(handle, ETHTOOL_GGRO, "ETHTOOL_GGRO");
        if (ret == -1)
                return -1;
        if (ret)
index 2a5812b273afb0272c124cfdd61a9ebb6bf02884..9e61e455dbfefd34f5fd6d898ab5bb0f97def081 100644 (file)
@@ -127,7 +127,7 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
                        const unsigned char *payload = NULL;
                        struct pcap_pkthdr pkth;
 
-                       const struct nfgenmsg *nfg;
+                       const struct nfgenmsg *nfg = NULL;
                        int id = 0;
 
                        if (handle->linktype != DLT_NFLOG) {
@@ -194,7 +194,10 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
 
                        if (type == NFQUEUE) {
                                /* XXX, possible responses: NF_DROP, NF_ACCEPT, NF_STOLEN, NF_QUEUE, NF_REPEAT, NF_STOP */
-                               nfqueue_send_verdict(handle, ntohs(nfg->res_id), id, NF_ACCEPT);
+                               /* if type == NFQUEUE, handle->linktype is always != DLT_NFLOG,
+                                  so nfg is always initialized to NLMSG_DATA(nlh). */
+                               if (nfg != NULL)
+                                       nfqueue_send_verdict(handle, ntohs(nfg->res_id), id, NF_ACCEPT);
                        }
                }
 
index ee6ffa4dcc6ec225bcb205d17bc52cc71809a2de..db5900005e97c8779b443ef0915e6c34a119e6ab 100644 (file)
@@ -16,6 +16,9 @@
 #include <unistd.h>
 
 #include <snf.h>
+#if SNF_VERSION_API >= 0x0003
+#define SNF_HAVE_INJECT_API
+#endif
 
 #include "pcap-int.h"
 #include "pcap-snf.h"
@@ -26,6 +29,9 @@
 struct pcap_snf {
        snf_handle_t snf_handle; /* opaque device handle */
        snf_ring_t   snf_ring;   /* opaque device ring handle */
+#ifdef SNF_HAVE_INJECT_API
+        snf_inject_t snf_inj;    /* inject handle, if inject is used */
+#endif
         int          snf_timeout;
         int          snf_boardnum;
 };
@@ -41,9 +47,10 @@ static int
 snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
 {
        struct snf_ring_stats stats;
+       struct pcap_snf *snfps = p->priv;
        int rc;
 
-       if ((rc = snf_ring_getstats(ps->snf_ring, &stats))) {
+       if ((rc = snf_ring_getstats(snfps->snf_ring, &stats))) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_get_stats: %s",
                         pcap_strerror(rc));
                return -1;
@@ -62,6 +69,10 @@ snf_platform_cleanup(pcap_t *p)
        if (p == NULL)
                return;
 
+#ifdef SNF_HAVE_INJECT_API
+        if (ps->snf_inj)
+                snf_inject_close(ps->snf_inj);
+#endif
        snf_ring_close(ps->snf_ring);
        snf_close(ps->snf_handle);
        pcap_cleanup_live_common(p);
@@ -113,11 +124,13 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
        struct pcap_pkthdr hdr;
        int i, flags, err, caplen, n;
        struct snf_recv_req req;
+       int nonblock, timeout;
 
-       if (!p || cnt == 0)
+       if (!p)
                return -1;
 
        n = 0;
+       timeout = ps->snf_timeout;
        while (n < cnt || PACKET_COUNT_IS_UNLIMITED(cnt)) {
                /*
                 * Has "pcap_breakloop()" been called?
@@ -131,14 +144,17 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        }
                }
 
-               err = snf_ring_recv(ps->snf_ring, ps->snf_timeout, &req);
+               err = snf_ring_recv(ps->snf_ring, timeout, &req);
 
                if (err) {
-                       if (err == EBUSY || err == EAGAIN)
-                               return (0);
-                       if (err == EINTR)
+                       if (err == EBUSY || err == EAGAIN) {
+                               return (n);
+                       }
+                       else if (err == EINTR) {
+                               timeout = 0;
                                continue;
-                       if (err != 0) {
+                       }
+                       else {
                                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_read: %s",
                                         pcap_strerror(err));
                                return -1;
@@ -157,6 +173,11 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        callback(user, &hdr, req.pkt_addr);
                }
                n++;
+
+               /* After one successful packet is received, we won't block
+               * again for that timeout. */
+               if (timeout != 0)
+                       timeout = 0;
        }
        return (n);
 }
@@ -183,9 +204,32 @@ snf_setfilter(pcap_t *p, struct bpf_program *fp)
 static int
 snf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
 {
-       strlcpy(p->errbuf, "Sending packets isn't supported with snf",
+#ifdef SNF_HAVE_INJECT_API
+       struct pcap_snf *ps = p->priv;
+        int rc;
+        if (ps->snf_inj == NULL) {
+                rc = snf_inject_open(ps->snf_boardnum, 0, &ps->snf_inj);
+                if (rc) {
+                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+                                "snf_inject_open: %s", pcap_strerror(rc));
+                        return (-1);
+                }
+        }
+
+        rc = snf_inject_send(ps->snf_inj, -1, 0, buf, size);
+        if (!rc) {
+                return (size);
+        }
+        else {
+                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_inject_send: %s",
+                         pcap_strerror(rc));
+                return (-1);
+        }
+#else
+       strlcpy(p->errbuf, "Sending packets isn't supported with this snf version",
            PCAP_ERRBUF_SIZE);
        return (-1);
+#endif
 }
 
 static int
@@ -195,7 +239,7 @@ snf_activate(pcap_t* p)
        char *device = p->opt.source;
        const char *nr = NULL;
        int err;
-       int flags = 0;
+       int flags = -1, ring_id = -1;
 
        if (device == NULL) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
@@ -205,8 +249,10 @@ snf_activate(pcap_t* p)
 
        /* In Libpcap, we set pshared by default if NUM_RINGS is set to > 1.
         * Since libpcap isn't thread-safe */
-       if ((nr = getenv("SNF_NUM_RINGS")) && *nr && atoi(nr) > 1)
-               flags |= SNF_F_PSHARED;
+       if ((nr = getenv("SNF_FLAGS")) && *nr)
+               flags = strtol(nr, NULL, 0);
+       else if ((nr = getenv("SNF_NUM_RINGS")) && *nr && atoi(nr) > 1)
+               flags = SNF_F_PSHARED;
        else
                nr = NULL;
 
@@ -222,10 +268,14 @@ snf_activate(pcap_t* p)
                return -1;
        }
 
-       err = snf_ring_open(ps->snf_handle, &ps->snf_ring);
+       if ((nr = getenv("SNF_PCAP_RING_ID")) && *nr) {
+               ring_id = (int) strtol(nr, NULL, 0);
+       }
+       err = snf_ring_open_id(ps->snf_handle, ring_id, &ps->snf_ring);
        if (err != 0) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
-                        "snf_ring_open failed: %s", pcap_strerror(err));
+                        "snf_ring_open_id(ring=%d) failed: %s",
+                        ring_id, pcap_strerror(err));
                return -1;
        }
 
@@ -255,12 +305,104 @@ snf_activate(pcap_t* p)
        p->setnonblock_op = snf_setnonblock;
        p->stats_op = snf_pcap_stats;
        p->cleanup_op = snf_platform_cleanup;
+#ifdef SNF_HAVE_INJECT_API
+        ps->snf_inj = NULL;
+#endif
        return 0;
 }
 
+#define MAX_DESC_LENGTH 128
 int
 snf_findalldevs(pcap_if_t **devlistp, char *errbuf)
 {
+       pcap_if_t *devlist = NULL,*curdev,*prevdev;
+       pcap_addr_t *curaddr;
+       struct snf_ifaddrs *ifaddrs, *ifa;
+       char desc[MAX_DESC_LENGTH];
+       int ret;
+
+       if (snf_init(SNF_VERSION_API))
+               return (-1);
+
+       if (snf_getifaddrs(&ifaddrs) || ifaddrs == NULL)
+       {
+               (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+                       "snf_getifaddrs: %s", pcap_strerror(errno));
+               return (-1);
+       }
+       ifa = ifaddrs;
+       while (ifa)
+       {
+               /*
+                * Allocate a new entry
+                */
+               curdev = (pcap_if_t *)malloc(sizeof(pcap_if_t));
+               if (curdev == NULL) {
+               (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+                       "snf_findalldevs malloc: %s", pcap_strerror(errno));
+                       return (-1);
+               }
+               if (devlist == NULL) /* save first entry */
+                       devlist = curdev;
+               else
+                       prevdev->next = curdev;
+               /*
+                * Fill in the entry.
+                */
+               curdev->next = NULL;
+               curdev->name = strdup(ifa->snf_ifa_name);
+               if (curdev->name == NULL) {
+                       (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+                           "snf_findalldevs strdup: %s", pcap_strerror(errno));
+                       free(curdev);
+                       return (-1);
+               }
+               (void)snprintf(desc,MAX_DESC_LENGTH,"Myricom snf%d",
+                               ifa->snf_ifa_portnum);
+               curdev->description = strdup(desc);
+               if (curdev->description == NULL) {
+                       (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+                       "snf_findalldevs strdup1: %s", pcap_strerror(errno));
+                       free(curdev->name);
+                       free(curdev);
+                       return (-1);
+               }
+               curdev->addresses = NULL;
+               curdev->flags = 0;
+
+               curaddr = (pcap_addr_t *)malloc(sizeof(pcap_addr_t));
+               if (curaddr == NULL) {
+                       (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+                            "snf_findalldevs malloc1: %s", pcap_strerror(errno));
+                       free(curdev->description);
+                       free(curdev->name);
+                       free(curdev);
+                       return (-1);
+               }
+               curdev->addresses = curaddr;
+               curaddr->next = NULL;
+               curaddr->addr = (struct sockaddr*)malloc(sizeof(struct sockaddr_storage));
+               if (curaddr->addr == NULL) {
+                       (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+                           "malloc2: %s", pcap_strerror(errno));
+                       free(curdev->description);
+                       free(curdev->name);
+                       free(curaddr);
+                       free(curdev);
+                       return (-1);
+               }
+               curaddr->addr->sa_family = AF_INET;
+               curaddr->netmask = NULL;
+               curaddr->broadaddr = NULL;
+               curaddr->dstaddr = NULL;
+               curaddr->next = NULL;
+
+               prevdev = curdev;
+               ifa = ifa->snf_ifa_next;
+       }
+       snf_freeifaddrs(ifaddrs);
+       *devlistp = devlist;
+
        /*
         * There are no platform-specific devices since each device
         * exists as a regular Ethernet device.
index f5a7e0ca217ad738d60f66fec34629acc8a2dec9..85a2f5b3a581679e8d049c8580dce9a56255e05b 100644 (file)
@@ -580,7 +580,9 @@ for packets to become available.  On some, but
 all, platforms, if a read timeout was specified, the wait will terminate
 after the read timeout expires; applications should be prepared for
 this, as it happens on some platforms, but should not rely on it, as it
-does not happen on other platforms.
+does not happen on other platforms.  Note that the wait might, or might
+not, terminate even if no packets are available; applications should be
+prepared for this to happen, but must not rely on it happening.
 .PP
 A handle can be put into ``non-blocking mode'', so that those routines
 will, rather than blocking, return an indication that no packets are
@@ -596,8 +598,8 @@ Non-blocking mode is often combined with routines such as
 .BR select (2)
 or
 .BR poll (2)
-or other routines a platform offers to wait for the availability of data
-on any of a set of descriptors.  To obtain, for a handle, a descriptor
+or other routines a platform offers to wait for any of a set of
+descriptors to be ready to read.  To obtain, for a handle, a descriptor
 that can be used in those routines, call
 .BR pcap_get_selectable_fd ().
 Not all handles have such a descriptor available;
@@ -606,7 +608,14 @@ will return \-1 if no such descriptor exists.  In addition, for various
 reasons, one or more of those routines will not work properly with the
 descriptor; the documentation for
 .BR pcap_get_selectable_fd ()
-gives details.
+gives details.  Note that, just as an attempt to read packets from a
+.B pcap_t
+may not return any packets if the read timeout expires, a
+.BR select (),
+.BR poll (),
+or other such call may, if the read timeout expires, indicate that a
+descriptor is ready to read even if there are no packets available to
+read.
 .TP
 .B Routines
 .RS
diff --git a/pcap.c b/pcap.c
index badc312b804ad8a63b02cabe3fad0a6b4480c5d6..4e9c94a72bd3a5d7c66bc59e683da5ab57863c8e 100644 (file)
--- a/pcap.c
+++ b/pcap.c
@@ -280,7 +280,8 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
 pcap_t *
 pcap_create(const char *source, char *errbuf)
 {
-       return (dag_create(source, errbuf));
+       int is_ours;
+       return (dag_create(source, errbuf, &is_ours));
 }
 #elif defined(SEPTEL_ONLY)
 int
@@ -292,7 +293,8 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
 pcap_t *
 pcap_create(const char *source, char *errbuf)
 {
-       return (septel_create(source, errbuf));
+       int is_ours;
+       return (septel_create(source, errbuf, &is_ours));
 }
 #elif defined(SNF_ONLY)
 int
@@ -304,7 +306,8 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
 pcap_t *
 pcap_create(const char *source, char *errbuf)
 {
-       return (snf_create(source, errbuf));
+       int is_ours;
+       return (snf_create(source, errbuf, &is_ours));
 }
 #else /* regular pcap */
 struct capture_source_type {
@@ -561,6 +564,12 @@ pcap_create_common(const char *source, char *ebuf, size_t size)
        p->opt.immediate = 0;
        p->opt.tstamp_type = -1;        /* default to not setting time stamp type */
        p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
+
+       /*
+        * Start out with no BPF code generation flags set.
+        */
+       p->bpf_codegen_flags = 0;
+
        return (p);
 }
 
@@ -1831,6 +1840,12 @@ pcap_open_dead_with_tstamp_precision(int linktype, int snaplen, u_int precision)
        p->setmintocopy_op = pcap_setmintocopy_dead;
 #endif
        p->cleanup_op = pcap_cleanup_dead;
+
+       /*
+        * A "dead" pcap_t never requires special BPF code generation.
+        */
+       p->bpf_codegen_flags = 0;
+
        p->activated = 1;
        return (p);
 }
index ff88fd0f4fa70943a1dc556f409ff8e04af8e08e..8b116cd9df64e3dd8803370e983f70aa6e74aed2 100644 (file)
@@ -59,7 +59,8 @@
  * or Tru64 UNIX-style multiple-include protection (or, at least,
  * Tru64 UNIX 5.x-style; I don't have earlier versions available to check),
  * or AIX-style multiple-include protection (or, at least, AIX 5.x-style;
- * I don't have earlier versions available to check).
+ * I don't have earlier versions available to check), or QNX-style
+ * multiple-include protection (as per GitHub pull request #394).
  *
  * We do not check for BPF_MAJOR_VERSION, as that's defined by
  * <linux/filter.h>, which is directly or indirectly included in some
@@ -68,7 +69,7 @@
  *
  * This also provides our own multiple-include protection.
  */
-#if !defined(_NET_BPF_H_) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h)
+#if !defined(_NET_BPF_H_) && !defined(_NET_BPF_H_INCLUDED) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h)
 #define lib_pcap_bpf_h
 
 #ifdef __cplusplus
@@ -1311,7 +1312,13 @@ struct bpf_program {
  */
 #define DLT_IPMI_HPM_2 260
 
-#define DLT_MATCHING_MAX       260     /* highest value in the "matching" range */
+/*
+ * per  Joshua Wright <[email protected]>, formats for Zwave captures.
+ */
+#define DLT_ZWAVE_R1_R2  261
+#define DLT_ZWAVE_R3     262
+
+#define DLT_MATCHING_MAX       262     /* highest value in the "matching" range */
 
 /*
  * DLT and savefile link type values are split into a class and
@@ -1463,6 +1470,16 @@ struct bpf_insn {
        bpf_u_int32 k;
 };
 
+/*
+ * Auxiliary data, for use when interpreting a filter intended for the
+ * Linux kernel when the kernel rejects the filter (requiring us to
+ * run it in userland).  It contains VLAN tag information.
+ */
+struct bpf_aux_data {
+       u_short vlan_tag_present;
+       u_short vlan_tag;
+};
+
 /*
  * Macros for insn array initializers.
  */
@@ -1472,9 +1489,11 @@ struct bpf_insn {
 #if __STDC__ || defined(__cplusplus)
 extern int bpf_validate(const struct bpf_insn *, int);
 extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
+extern u_int bpf_filter_with_aux_data(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *);        
 #else
 extern int bpf_validate();
 extern u_int bpf_filter();
+extern u_int bpf_filter();
 #endif
 
 /*
index 7e1f2cd2a6091322302d18725465792250f46085..e4a42603b34e982ac3a6c635352e4a652b414bf8 100644 (file)
@@ -424,13 +424,13 @@ void      pcap_freealldevs(pcap_if_t *);
 const char *pcap_lib_version(void);
 
 /*
- * On at least some versions of NetBSD, we don't want to declare
+ * On at least some versions of NetBSD and QNX, we don't want to declare
  * bpf_filter() here, as it's also be declared in <net/bpf.h>, with a
  * different signature, but, on other BSD-flavored UN*Xes, it's not
  * declared in <net/bpf.h>, so we *do* want to declare it here, so it's
  * declared when we build pcap-bpf.c.
  */
-#ifndef __NetBSD__
+#if !defined(__NetBSD__) && !defined(__QNX__)
 u_int  bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
 #endif
 int    bpf_validate(const struct bpf_insn *f, int len);
index c61e91e3f91eb71a6d9b87d8439d64f2fb28b91c..4bc1728a0051f0b23e2adc56b8bbebfc789088bc 100644 (file)
@@ -41,6 +41,6 @@ removed, to the corresponding link-layer header type value.  The
 translation is case-insensitive.
 .SH RETURN VALUE
 .B pcap_datalink_name_to_val()
-returns 0 on success and \-1 on failure.
+returns type value on success and \-1 on failure.
 .SH SEE ALSO
 pcap(3PCAP)
index 6ae06a1bc429172109fcee47115f265ddc419780..6640577eaabd0fe0e6b802b86a6560d478fa1dd8 100644 (file)
@@ -36,9 +36,9 @@ int pcap_get_selectable_fd(pcap_t *p);
 returns, on UNIX, a file descriptor number for a file descriptor on
 which one can
 do a
-.B select()
-or
-.B poll()
+.BR select() ,
+.BR poll() ,
+or other such call
 to wait for it to be possible to read packets without blocking, if such
 a descriptor exists, or \-1, if no such descriptor exists.  Some network
 devices opened with
@@ -54,6 +54,12 @@ or
 (for example, regular network devices on FreeBSD 4.3 and 4.4, and Endace
 DAG devices), so \-1 is returned for those devices.
 .PP
+Note that a descriptor on which a read can be done without blocking may,
+on some platforms, not have any packets to read if the read timeout has
+expired.  A call to
+.B pcap_dispatch()
+will return 0 in this case, but will not block.
+.PP
 Note that in:
 .IP
 FreeBSD prior to FreeBSD 4.6;
index d18dc06c28b8c11159d21e9906d03ca22202df42..011d85c72587305e39f4ddf44b6e625ffb87123e 100644 (file)
@@ -77,6 +77,13 @@ causes all the packets received in one buffer to be processed when
 reading a live capture, and causes all the packets in the file to be
 processed when reading a ``savefile''.
 .PP
+Note that, when doing a live capture on some platforms, if the read
+timeout expires when there are no packets available,
+.B pcap_dispatch()
+will return 0, even when not in non-blocking mode, as there are no
+packets to process.  Applications should be prepared for this to happen,
+but must not rely on it happening.
+.PP
 .ft B
 (In older versions of libpcap, the behavior when
 \fIcnt\fP
index 261c315200c01c2f25feec8a719569e9f565ef02..fd673bd4f92a49dd666c45d6df60b559601c69a4 100644 (file)
@@ -52,7 +52,7 @@ for a list of all the time stamp types.
 returns 0 on success if the specified time stamp type is expected to be
 supported by the capture device,
 .B PCAP_WARNING_TSTAMP_TYPE_NOTSUP
-on success if the specified time stamp type is not supported by the
+if the specified time stamp type is not supported by the
 capture device,
 .B PCAP_ERROR_ACTIVATED
 if called on a capture handle that has been activated, and
index 37b22031d451a4afc171c3daadef95598bbafe16..a99ea076ed9cce221980ac27cc381f04de97068d 100644 (file)
@@ -57,6 +57,14 @@ immediately rather than blocking waiting for packets to arrive.
 and
 .B pcap_next()
 will not work in ``non-blocking'' mode.
+.PP
+When first activated with
+.B pcap_activate()
+or opened with
+.B pcap_open_live() ,
+a capture handle is not in ``non-blocking mode''; a call to
+.B pcap_setnonblock()
+is required in order to put it into ``non-blocking'' mode.
 .SH RETURN VALUE
 .B pcap_getnonblock()
 returns the current ``non-blocking'' state of the capture descriptor; it
index 8fcc4d75c00facb5ecb4d679c3a50e3427b1d05c..22dd15fff13fbcd18ffbfa1a79e0f5ebca4cbef4 100644 (file)
@@ -38,7 +38,7 @@ translates a time stamp type name to the corresponding time stamp type
 value.  The translation is case-insensitive.
 .SH RETURN VALUE
 .B pcap_tstamp_type_name_to_val()
-returns 0 on success and
+returns time stamp type value on success and
 .B PCAP_ERROR
 on failure.
 .SH SEE ALSO
index 0ab2fdefb201ee91be5a342b5e0cc13c14e6e658..abe1d2dd63b50de5d3b1f5c071a7324902f419cd 100644 (file)
@@ -344,6 +344,11 @@ found:
         */
        p->oneshot_callback = pcap_oneshot;
 
+       /*
+        * Savefiles never require special BPF code generation.
+        */
+       p->bpf_codegen_flags = 0;
+
        p->activated = 1;
 
        return (p);
index fae408679a5d0326694841c7a2e0024b4a1cef3c..ea6215703f7f1445b601174b44893703cb2e7a0b 100644 (file)
@@ -1210,10 +1210,16 @@ found:
        }
 
        /*
-        * Convert the time stamp to a struct timeval.
+        * Convert the time stamp to seconds and fractions of a second,
+        * with the fractions being in units of the file-supplied resolution.
         */
        sec = t / ps->ifaces[interface_id].tsresol + ps->ifaces[interface_id].tsoffset;
        frac = t % ps->ifaces[interface_id].tsresol;
+
+       /*
+        * Convert the fractions from units of the file-supplied resolution
+        * to units of the user-requested resolution.
+        */
        switch (ps->ifaces[interface_id].scale_type) {
 
        case PASS_THROUGH:
@@ -1227,21 +1233,28 @@ found:
        case SCALE_DOWN:
                /*
                 * The interface resolution is different from what the
-                * user wants; scale up or down to that resolution.
+                * user wants; convert the fractions to units of the
+                * resolution the user requested by multiplying by the
+                * quotient of the user-requested resolution and the
+                * file-supplied resolution.  We do that by multiplying
+                * by the user-requested resolution and dividing by the
+                * file-supplied resolution, as the quotient might not
+                * fit in an integer.
                 *
                 * XXX - if ps->ifaces[interface_id].tsresol is a power
                 * of 10, we could just multiply by the quotient of
-                * ps->ifaces[interface_id].tsresol and ps->user_tsresol
-                * in the scale-up case, and divide by the quotient of
                 * ps->user_tsresol and ps->ifaces[interface_id].tsresol
-                * in the scale-down case, as we know those are integers,
-                * which would involve fewer arithmetic operations.
+                * in the scale-up case, and divide by the quotient of
+                * ps->ifaces[interface_id].tsresol and ps->user_tsresol
+                * in the scale-down case, as we know those will be integers.
+                * That would involve fewer arithmetic operations, and
+                * would run less risk of overflow.
                 *
                 * Is there something clever we could do if
                 * ps->ifaces[interface_id].tsresol is a power of 2?
                 */
-               frac *= ps->ifaces[interface_id].tsresol;
-               frac /= ps->user_tsresol;
+               frac *= ps->user_tsresol;
+               frac /= ps->ifaces[interface_id].tsresol;
                break;
        }
        hdr->ts.tv_sec = sec;