]> The Tcpdump Group git mirrors - libpcap/commitdiff
Merge branch 'master' of git+ssh://bpf.tcpdump.org/tcpdump/master/git/libpcap
authorMichael Richardson <[email protected]>
Thu, 13 Nov 2014 08:34:02 +0000 (22:34 -1000)
committerMichael Richardson <[email protected]>
Thu, 13 Nov 2014 08:34:02 +0000 (22:34 -1000)
58 files changed:
.gitignore
.travis-coverity-scan-build.sh [new file with mode: 0644]
.travis.yml
CHANGES
README.aix
VERSION
bpf/net/bpf_filter.c
bpf_image.c
config.guess
config.sub
configure
configure.in
gencode.c
gencode.h
grammar.y
inet.c
llc.h
optimize.c
pcap-bpf.c
pcap-common.c
pcap-config.1
pcap-dlpi.c
pcap-filter.manmisc.in
pcap-int.h
pcap-libdlpi.c
pcap-linktype.manmisc.in
pcap-linux.c
pcap-netfilter-linux.c
pcap-savefile.manfile.in
pcap-snf.c
pcap-stdinc.h
pcap-tstamp.manmisc.in
pcap-usb-linux.c
pcap-win32.c
pcap.3pcap.in
pcap.c
pcap/bpf.h
pcap_activate.3pcap
pcap_compile.3pcap.in
pcap_datalink.3pcap.in
pcap_fileno.3pcap
pcap_findalldevs.3pcap
pcap_get_selectable_fd.3pcap
pcap_is_swapped.3pcap
pcap_list_datalinks.3pcap.in
pcap_loop.3pcap
pcap_major_version.3pcap
pcap_next_ex.3pcap
pcap_offline_filter.3pcap
pcap_set_timeout.3pcap
pcap_setfilter.3pcap
pcap_setnonblock.3pcap
pcap_snapshot.3pcap
savefile.c
scanner.l
sf-pcap-ng.c
sf-pcap.c
tests/filtertest.c

index d91491a4c1bc5085728802e6c04ee1ddbd20b4ee..55f4ba536d2390ccffe14ad3701dcd3125f3c2af 100644 (file)
@@ -13,6 +13,8 @@ autom4te.cache/
 .devel
 filtertest
 findalldevstest
+opentest
+valgrindtest
 grammar.c
 libpcap.a
 libpcap.*.dylib
diff --git a/.travis-coverity-scan-build.sh b/.travis-coverity-scan-build.sh
new file mode 100644 (file)
index 0000000..92e3f65
--- /dev/null
@@ -0,0 +1,109 @@
+#!/bin/sh
+
+set -e
+
+# Environment check
+echo -e "\033[33;1mNote: PROJECT_NAME and COVERITY_SCAN_TOKEN are available on Project Settings page on scan.coverity.com\033[0m"
+[ -z "$COVERITY_SCAN_PROJECT_NAME" ] && echo "ERROR: COVERITY_SCAN_PROJECT_NAME must be set" && exit 1
+#[ -z "$COVERITY_SCAN_NOTIFICATION_EMAIL" ] && echo "ERROR: COVERITY_SCAN_NOTIFICATION_EMAIL must be set" && exit 1
+[ -z "$COVERITY_SCAN_BRANCH_PATTERN" ] && echo "ERROR: COVERITY_SCAN_BRANCH_PATTERN must be set" && exit 1
+[ -z "$COVERITY_SCAN_BUILD_COMMAND" ] && echo "ERROR: COVERITY_SCAN_BUILD_COMMAND must be set" && exit 1
+[ -z "$COVERITY_SCAN_TOKEN" ] && echo "ERROR: COVERITY_SCAN_TOKEN must be set" && exit 1
+
+PLATFORM=`uname`
+TOOL_ARCHIVE=/tmp/cov-analysis-${PLATFORM}.tgz
+TOOL_URL=https://scan.coverity.com/download/${PLATFORM}
+TOOL_BASE=/tmp/coverity-scan-analysis
+UPLOAD_URL="http://scan5.coverity.com/cgi-bin/travis_upload.py"
+SCAN_URL="https://scan.coverity.com"
+
+# Verify Coverity Scan run condition
+COVERITY_SCAN_RUN_CONDITION=${coverity_scan_run_condition:-true}
+echo -ne "\033[33;1mTesting '${COVERITY_SCAN_RUN_CONDITION}' condition... "
+if eval [ $COVERITY_SCAN_RUN_CONDITION ]; then
+  echo -e "True.\033[0m"
+else
+  echo -e "False. Exit.\033[0m"
+  exit 1
+fi
+
+# Do not run on pull requests
+if [ "${TRAVIS_PULL_REQUEST}" = "true" ]; then
+  echo -e "\033[33;1mINFO: Skipping Coverity Analysis: branch is a pull request.\033[0m"
+  exit 0
+fi
+
+# Verify this branch should run
+IS_COVERITY_SCAN_BRANCH=`ruby -e "puts '${TRAVIS_BRANCH}' =~ /\\A$COVERITY_SCAN_BRANCH_PATTERN\\z/ ? 1 : 0"`
+if [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then
+  echo -e "\033[33;1mCoverity Scan configured to run on branch ${TRAVIS_BRANCH}\033[0m"
+else
+  echo -e "\033[33;1mCoverity Scan NOT configured to run on branch ${TRAVIS_BRANCH}\033[0m"
+  exit 1
+fi
+
+# Verify upload is permitted
+AUTH_RES=`curl -s --form project="$COVERITY_SCAN_PROJECT_NAME" --form token="$COVERITY_SCAN_TOKEN" $SCAN_URL/api/upload_permitted`
+if [ "$AUTH_RES" = "Access denied" ]; then
+  echo -e "\033[33;1mCoverity Scan API access denied. Check COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN.\033[0m"
+  exit 1
+else
+  AUTH=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['upload_permitted']"`
+  if [ "$AUTH" = "true" ]; then
+    echo -e "\033[33;1mCoverity Scan analysis authorized per quota.\033[0m"
+  else
+    WHEN=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['next_upload_permitted_at']"`
+    echo -e "\033[33;1mCoverity Scan analysis NOT authorized until $WHEN.\033[0m"
+    exit 1
+  fi
+fi
+
+if [ ! -d $TOOL_BASE ]; then
+  # Download Coverity Scan Analysis Tool
+  if [ ! -e $TOOL_ARCHIVE ]; then
+    echo -e "\033[33;1mDownloading Coverity Scan Analysis Tool...\033[0m"
+    wget -nv -O $TOOL_ARCHIVE $TOOL_URL --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN"
+  fi
+
+  # Extract Coverity Scan Analysis Tool
+  echo -e "\033[33;1mExtracting Coverity Scan Analysis Tool...\033[0m"
+  mkdir -p $TOOL_BASE
+  pushd $TOOL_BASE
+  tar xzf $TOOL_ARCHIVE
+  popd
+fi
+
+TOOL_DIR=`find $TOOL_BASE -type d -name 'cov-analysis*'`
+export PATH=$TOOL_DIR/bin:$PATH
+
+# Build
+echo -e "\033[33;1mRunning Coverity Scan Analysis Tool...\033[0m"
+COV_BUILD_OPTIONS=""
+#COV_BUILD_OPTIONS="--return-emit-failures 8 --parse-error-threshold 85"
+RESULTS_DIR="cov-int"
+eval "${COVERITY_SCAN_BUILD_COMMAND_PREPEND}"
+COVERITY_UNSUPPORTED=1 cov-build --dir $RESULTS_DIR $COV_BUILD_OPTIONS $COVERITY_SCAN_BUILD_COMMAND
+
+# Upload results
+echo -e "\033[33;1mTarring Coverity Scan Analysis results...\033[0m"
+RESULTS_ARCHIVE=analysis-results.tgz
+tar czf $RESULTS_ARCHIVE $RESULTS_DIR
+SHA=`git rev-parse --short HEAD`
+VERSION_SHA=$(cat VERSION)#$SHA
+
+# Verify Coverity Scan script test mode
+if [ "$coverity_scan_script_test_mode" = true ]; then
+  echo -e "\033[33;1mCoverity Scan configured in script test mode. Exit.\033[0m"
+  exit 1
+fi
+
+echo -e "\033[33;1mUploading Coverity Scan Analysis results...\033[0m"
+curl \
+  --progress-bar \
+  --form project=$COVERITY_SCAN_PROJECT_NAME \
+  --form token=$COVERITY_SCAN_TOKEN \
+  --form email=$COVERITY_SCAN_NOTIFICATION_EMAIL \
+  --form file=@$RESULTS_ARCHIVE \
+  --form version=$SHA \
+  --form description="$VERSION_SHA" \
+  $UPLOAD_URL
index 8ed44b0c355901fbc222e59dca39caf991149c57..2d4b1e73f6c33b08199f3387c0eeb3b515a15088 100644 (file)
@@ -1,9 +1,56 @@
 language: c
 
+os:
+  - linux
+  - osx
+
 compiler:
   - gcc
   - clang
 
+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="
+    # 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'
+    # Coverity script test mode (if true no uploading, avoid reaching the quota)
+    # usual processing: false.
+    - coverity_scan_script_test_mode=false
+
+addons:
+  coverity_scan:
+    # customized build script URL
+    # TRAVIS_REPO_SLUG: owner_name/repo_name of repository currently being built
+    # TRAVIS_BRANCH: name of the branch currently being built
+    build_script_url: https://raw.githubusercontent.com/$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH/.travis-coverity-scan-build.sh
+    # project metadata
+    project:
+      name: $TRAVIS_REPO_SLUG
+    # Where email notification of build analysis results will be sent
+    #notification_email: [email protected]
+    # Commands to prepare for build_command
+    build_command_prepend: ./configure
+    # This command will be added as an argument to "cov-build" to compile
+    # the project for analysis
+    build_command: make
+    # Pattern to match selecting branches that will run analysis
+    branch_pattern: coverity_scan
+
+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
+
+install:
+  - if [ "$TRAVIS_OS_NAME" = linux ]; then sudo apt-get install libusb-1.0-0-dev libdbus-1-dev; fi
+
+before_script:
+
 script:
-  - ./configure
-  - make
+  - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then touch .devel configure; fi
+  - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ./configure; fi
+  - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make -s; fi
diff --git a/CHANGES b/CHANGES
index 64734b5d77125206abed3d3ef96ff44795eb0ec6..ecda66b8892640a323bfebcad4777e610ea347b2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,29 @@
+Friday Sep. 5, 2014 [email protected]
+  Summary for 1.7.0 libpcap release
+       Fix handling of zones for BPF on Solaris
+
+Monday Aug. 12, 2014 [email protected]
+  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
+           capture.
+       Fix timestamps when reading pcap-ng files on big-endian
+           machines.
+
+Saturday  Jul. 19, 2014 [email protected]
+  Summary for 1.6.1 libpcap release
+       some fixes for the any device
+       changes for how --enable-XXX works
+
+Wednesday Jul. 2, 2014 [email protected]
+  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().
+        on platforms where you can not capture on down interfaces, do not list them
+        but: do list interfaces which are down, if you can capture on them!
+
 Wednesday December 18, 2013 [email protected]
 Summary for 1.5.3 libpcap release
        Don't let packets that don't match the current filter get to the
@@ -244,7 +270,7 @@ Mon.    October 27, 2008.  [email protected].  Summary for 1.0.0 libpcap rele
        DLT: Add JUNIPER_ST
        802.15.4 support
        Variable length 802.11 header support
-       X2E data type support 
+       X2E data type support
        SITA ACN Interface support - see README.sita
        Support for memory-mapped capture on Linux
        Support for zerocopy BPF on platforms that support it
@@ -256,7 +282,7 @@ Mon.    October 27, 2008.  [email protected].  Summary for 1.0.0 libpcap rele
         can print better diagnostic information
        Return PCAP_ERROR_PERM_DENIED if we don't have permission to open a device, so
         applications can tell the user they need to go play with permissions
-       On Linux, ignore ENETDOWN so we can continue to capture packets if the 
+       On Linux, ignore ENETDOWN so we can continue to capture packets if the
         interface goes down and comes back up again.
        On Linux, support new tpacket frame headers (2.6.27+)
        On Mac OS X, add scripts for changing permissions on /dev/bpf* and launchd plist
@@ -269,14 +295,14 @@ Mon.    September 10, 2007.  [email protected].  Summary for 0.9.8 libpcap relea
         Change build process to put public libpcap headers into pcap subir
         DLT: Add value for IPMI IPMB packets
         DLT: Add value for u10 Networks boards
-        Require <net/pfvar.h> for pf definitions - allows reading of pflog formatted 
+        Require <net/pfvar.h> for pf definitions - allows reading of pflog formatted
          libpcap files on an OS other than where the file was generated
 
 Wed.   April 25, 2007.  [email protected].  Summary for 0.9.6 libpcap release
 
        Put the public libpcap headers into a pcap subdirectory in both the
         source directory and the target include directory, and have include
-        files at the top-level directory to include those headers, for 
+        files at the top-level directory to include those headers, for
         backwards compatibility.
        Add Bluetooth support
        Add USB capturing support on Linux
@@ -284,30 +310,30 @@ Wed.      April 25, 2007.  [email protected].  Summary for 0.9.6 libpcap release
        Add support for new FreeBSD BIOCSDIRECTION ioctl
        Add additional filter operations for 802.11 frame types
        Add support for filtering on MTP2 frame types
-       Propagate some changes from the main branch, so the x.9 branch has 
+       Propagate some changes from the main branch, so the x.9 branch has
         all the DLT_ and LINKTYPE_ values that the main branch does
-       Reserved a DLT_ and SAVEFILE_ value for PPI (Per Packet Info) 
+       Reserved a DLT_ and SAVEFILE_ value for PPI (Per Packet Info)
         encapsulated packets
-       Add LINKTYPE_ for IEEE 802.15.4, with address fields padded as done 
+       Add LINKTYPE_ for IEEE 802.15.4, with address fields padded as done
         by Linux drivers
        Add LINKTYPE_ value corresponding to DLT_IEEE802_16_MAC_CPS.
        Add DLT for IEEE 802.16 (WiMAX) MAC Common Part Sublayer
        Add DLT for Bluetooth HCI UART transport layer
        When building a shared library, build with "-fPIC" on Linux to support x86_64
-       Link with "$(CC) -shared" rather than "ld -shared" when building a 
+       Link with "$(CC) -shared" rather than "ld -shared" when building a
         ".so" shared library
        Add support for autoconf 2.60
        Fixes to discard unread packets when changing filters
-       Changes to handle name changes in the DAG library resulting from 
+       Changes to handle name changes in the DAG library resulting from
         switching to libtool.
        Add support for new DAG ERF types.
-        Add an explicit "-ldag" when building the shared library, so the DAG 
+        Add an explicit "-ldag" when building the shared library, so the DAG
         library dependency is explicit.
        Mac OSX fixes for dealing with "wlt" devices
        Fixes in add_or_find_if() & pcap_findalldevs() to optimize generating
         device lists
        Fixed a bug in pcap_open_live(). The return value of PacketSetHwFilter
-        was not checked. 
+        was not checked.
 
 Tue.   September 19, 2006. [email protected]. Summary for 0.9.5 libpcap release
 
@@ -319,19 +345,19 @@ Tue.      September 19, 2006. [email protected]. Summary for 0.9.5 libpcap release
        OP_PACKET now matches the beginning of the packet, instead of
         beginning+link-layer
        Add DLT/LINKTYPE for carrying FRF.16 Multi-link Frame Relay
-       Fix allocation of buffer for list of link-layer types  
+       Fix allocation of buffer for list of link-layer types
        Added a new DLT and LINKTYPE value for ARINC 653 Interpartition Communcation Messages
        Fixed a typo in a DLT value: it should start with DLT_ and not LINKTYPE_
        Redefined DLT_CAN20B and LINKTYPE_CAN20B as #190 (as this is the right value for CAN).
        Added definition for DLT_A429 and LINKTYPE_A429 as #184.
        Added a new DLT and LINKTYPE value for CAN v2.0B frames.
        Add support for DLT_JUNIPER_VP.
-       Don't double-count received packets on Linux systems that 
-        support the PACKET_STATISTICS getsockopt() argument on 
+       Don't double-count received packets on Linux systems that
+        support the PACKET_STATISTICS getsockopt() argument on
         PF_PACKET sockets.
-       Add support for DLT_IEEE802_11 and DLT_IEEE802_11_RADIO link 
+       Add support for DLT_IEEE802_11 and DLT_IEEE802_11_RADIO link
         layers in Windows
-       Add support to build libpcap.lib and wpcap.dll under Cygnus and 
+       Add support to build libpcap.lib and wpcap.dll under Cygnus and
         MingW32.
 
 Mon.   September 5, 2005.  [email protected]. Summary for 0.9.4 libpcap release
index 74cd9af65146eacad39f53fbf4b2be575a4b224b..f457df3217024df00a43b901eee8ba1c6ec30784 100644 (file)
@@ -11,6 +11,11 @@ Using BPF:
     same, and the configure script should detect that it's on an AIX
     system and choose BPF even if the devices aren't there.
 
+    Also note that tcpdump _binary_ compiled on AIX 4 may have a problem
+    doing the initial loading of the BPF driver if copied to AIX 5 and
+    run there (GH #52). tcpdump binary natively compiled on AIX 5 should
+    not have this issue.
+
 (2) If libpcap doesn't compile on your machine when configured to use
     BPF, or if the workarounds fail to make it work correctly, you
     should send to [email protected] a detailed bug
diff --git a/VERSION b/VERSION
index 56395c493ca2f6b1141e9e8e29ee1e461cb4fd79..f040e5ee97e09767394e4db67af78cda959e2336 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.6.0-PRE-GIT
+1.7.0-PRE-GIT
index 28c6df7c445cee9b59757b9d59eaea26221b8404..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;
@@ -464,6 +510,12 @@ bpf_filter(pc, p, wirelen, buflen)
                        A /= X;
                        continue;
 
+               case BPF_ALU|BPF_MOD|BPF_X:
+                       if (X == 0)
+                               return 0;
+                       A %= X;
+                       continue;
+
                case BPF_ALU|BPF_AND|BPF_X:
                        A &= X;
                        continue;
@@ -472,6 +524,10 @@ bpf_filter(pc, p, wirelen, buflen)
                        A |= X;
                        continue;
 
+               case BPF_ALU|BPF_XOR|BPF_X:
+                       A ^= X;
+                       continue;
+
                case BPF_ALU|BPF_LSH|BPF_X:
                        A <<= X;
                        continue;
@@ -496,6 +552,10 @@ bpf_filter(pc, p, wirelen, buflen)
                        A /= pc->k;
                        continue;
 
+               case BPF_ALU|BPF_MOD|BPF_K:
+                       A %= pc->k;
+                       continue;
+
                case BPF_ALU|BPF_AND|BPF_K:
                        A &= pc->k;
                        continue;
@@ -504,6 +564,10 @@ bpf_filter(pc, p, wirelen, buflen)
                        A |= pc->k;
                        continue;
 
+               case BPF_ALU|BPF_XOR|BPF_K:
+                       A ^= pc->k;
+                       continue;
+
                case BPF_ALU|BPF_LSH|BPF_K:
                        A <<= pc->k;
                        continue;
@@ -527,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
@@ -606,13 +681,16 @@ bpf_validate(f, len)
                        case BPF_MUL:
                        case BPF_OR:
                        case BPF_AND:
+                       case BPF_XOR:
                        case BPF_LSH:
                        case BPF_RSH:
                        case BPF_NEG:
                                break;
                        case BPF_DIV:
+                       case BPF_MOD:
                                /*
-                                * Check for constant division by 0.
+                                * Check for constant division or modulus
+                                * by 0.
                                 */
                                if (BPF_SRC(p->code) == BPF_K && p->k == 0)
                                        return 0;
index 2f16c453a9a867f367f1729bcb928a042738c3fd..3e9a23f51b4cd871e873085f18f8307372989274 100644 (file)
@@ -211,6 +211,11 @@ bpf_image(p, n)
                fmt = "x";
                break;
 
+       case BPF_ALU|BPF_MOD|BPF_X:
+               op = "mod";
+               fmt = "x";
+               break;
+
        case BPF_ALU|BPF_AND|BPF_X:
                op = "and";
                fmt = "x";
@@ -221,6 +226,11 @@ bpf_image(p, n)
                fmt = "x";
                break;
 
+       case BPF_ALU|BPF_XOR|BPF_X:
+               op = "xor";
+               fmt = "x";
+               break;
+
        case BPF_ALU|BPF_LSH|BPF_X:
                op = "lsh";
                fmt = "x";
@@ -251,6 +261,11 @@ bpf_image(p, n)
                fmt = "#%d";
                break;
 
+       case BPF_ALU|BPF_MOD|BPF_K:
+               op = "mod";
+               fmt = "#%d";
+               break;
+
        case BPF_ALU|BPF_AND|BPF_K:
                op = "and";
                fmt = "#0x%x";
@@ -261,6 +276,11 @@ bpf_image(p, n)
                fmt = "#0x%x";
                break;
 
+       case BPF_ALU|BPF_XOR|BPF_K:
+               op = "xor";
+               fmt = "#0x%x";
+               break;
+
        case BPF_ALU|BPF_LSH|BPF_K:
                op = "lsh";
                fmt = "#%d";
index c2246a4f7f4c78281ccfc4238a54cf7d83c4f421..d622a44e551f209d5e8c5462b3fe53a162f7b330 100755 (executable)
@@ -1,10 +1,10 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-#   Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011, 2012 Free Software Foundation, Inc.
 
-timestamp='2009-12-30'
+timestamp='2012-02-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -17,9 +17,7 @@ timestamp='2009-12-30'
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -57,8 +55,8 @@ GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
-Software Foundation, Inc.
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -145,7 +143,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:NetBSD:*:*)
        # NetBSD (nbsd) targets should (where applicable) match one or
-       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
        # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
        # switched to ELF, *-*-netbsd* would select the old
        # object file format.  This provides both forward
@@ -181,7 +179,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
                fi
                ;;
            *)
-               os=netbsd
+               os=netbsd
                ;;
        esac
        # The OS release
@@ -224,7 +222,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
                UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
                ;;
        *5.*)
-               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
                ;;
        esac
        # According to Compaq, /usr/sbin/psrinfo has been available on
@@ -270,7 +268,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        # A Xn.n version is an unreleased experimental baselevel.
        # 1.2 uses "1.2" for uname -r.
        echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-       exit ;;
+       # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+       exitcode=$?
+       trap '' 0
+       exit $exitcode ;;
     Alpha\ *:Windows_NT*:*)
        # How do we know it's Interix rather than the generic POSIX subsystem?
        # Should we change UNAME_MACHINE based on the output of uname instead
@@ -296,7 +297,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        echo s390-ibm-zvmoe
        exit ;;
     *:OS400:*:*)
-        echo powerpc-ibm-os400
+       echo powerpc-ibm-os400
        exit ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
        echo arm-acorn-riscix${UNAME_RELEASE}
@@ -395,23 +396,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     # MiNT.  But MiNT is downward compatible to TOS, so this should
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
+       echo m68k-atari-mint${UNAME_RELEASE}
        exit ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
        echo m68k-atari-mint${UNAME_RELEASE}
-        exit ;;
+       exit ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
+       echo m68k-atari-mint${UNAME_RELEASE}
        exit ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-        echo m68k-milan-mint${UNAME_RELEASE}
-        exit ;;
+       echo m68k-milan-mint${UNAME_RELEASE}
+       exit ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-        echo m68k-hades-mint${UNAME_RELEASE}
-        exit ;;
+       echo m68k-hades-mint${UNAME_RELEASE}
+       exit ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-        echo m68k-unknown-mint${UNAME_RELEASE}
-        exit ;;
+       echo m68k-unknown-mint${UNAME_RELEASE}
+       exit ;;
     m68k:machten:*:*)
        echo m68k-apple-machten${UNAME_RELEASE}
        exit ;;
@@ -481,8 +482,8 @@ EOF
        echo m88k-motorola-sysv3
        exit ;;
     AViiON:dgux:*:*)
-        # DG/UX returns AViiON for all architectures
-        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       # DG/UX returns AViiON for all architectures
+       UNAME_PROCESSOR=`/usr/bin/uname -p`
        if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
        then
            if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@@ -495,7 +496,7 @@ EOF
        else
            echo i586-dg-dgux${UNAME_RELEASE}
        fi
-       exit ;;
+       exit ;;
     M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
        echo m88k-dolphin-sysv3
        exit ;;
@@ -552,7 +553,7 @@ EOF
                echo rs6000-ibm-aix3.2
        fi
        exit ;;
-    *:AIX:*:[456])
+    *:AIX:*:[4567])
        IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
        if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
                IBM_ARCH=rs6000
@@ -595,52 +596,52 @@ EOF
            9000/[678][0-9][0-9])
                if [ -x /usr/bin/getconf ]; then
                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
-                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-                    case "${sc_cpu_version}" in
-                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
-                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
-                      532)                      # CPU_PA_RISC2_0
-                        case "${sc_kernel_bits}" in
-                          32) HP_ARCH="hppa2.0n" ;;
-                          64) HP_ARCH="hppa2.0w" ;;
+                   sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                   case "${sc_cpu_version}" in
+                     523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                     528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                     532)                      # CPU_PA_RISC2_0
+                       case "${sc_kernel_bits}" in
+                         32) HP_ARCH="hppa2.0n" ;;
+                         64) HP_ARCH="hppa2.0w" ;;
                          '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
-                        esac ;;
-                    esac
+                       esac ;;
+                   esac
                fi
                if [ "${HP_ARCH}" = "" ]; then
                    eval $set_cc_for_build
-                   sed 's/^              //' << EOF >$dummy.c
+                   sed 's/^            //' << EOF >$dummy.c
 
-              #define _HPUX_SOURCE
-              #include <stdlib.h>
-              #include <unistd.h>
+               #define _HPUX_SOURCE
+               #include <stdlib.h>
+               #include <unistd.h>
 
-              int main ()
-              {
-              #if defined(_SC_KERNEL_BITS)
-                  long bits = sysconf(_SC_KERNEL_BITS);
-              #endif
-                  long cpu  = sysconf (_SC_CPU_VERSION);
+               int main ()
+               {
+               #if defined(_SC_KERNEL_BITS)
+                   long bits = sysconf(_SC_KERNEL_BITS);
+               #endif
+                   long cpu  = sysconf (_SC_CPU_VERSION);
 
-                  switch (cpu)
-               {
-               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
-               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
-               case CPU_PA_RISC2_0:
-              #if defined(_SC_KERNEL_BITS)
-                   switch (bits)
-                       {
-                       case 64: puts ("hppa2.0w"); break;
-                       case 32: puts ("hppa2.0n"); break;
-                       default: puts ("hppa2.0"); break;
-                       } break;
-              #else  /* !defined(_SC_KERNEL_BITS) */
-                   puts ("hppa2.0"); break;
-              #endif
-               default: puts ("hppa1.0"); break;
-               }
-                  exit (0);
-              }
+                   switch (cpu)
+                       {
+                       case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+                       case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+                       case CPU_PA_RISC2_0:
+               #if defined(_SC_KERNEL_BITS)
+                           switch (bits)
+                               {
+                               case 64: puts ("hppa2.0w"); break;
+                               case 32: puts ("hppa2.0n"); break;
+                               default: puts ("hppa2.0"); break;
+                               } break;
+               #else  /* !defined(_SC_KERNEL_BITS) */
+                           puts ("hppa2.0"); break;
+               #endif
+                       default: puts ("hppa1.0"); break;
+                       }
+                   exit (0);
+               }
 EOF
                    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
                    test -z "$HP_ARCH" && HP_ARCH=hppa
@@ -731,22 +732,22 @@ EOF
        exit ;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
        echo c1-convex-bsd
-        exit ;;
+       exit ;;
     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
        if getsysinfo -f scalar_acc
        then echo c32-convex-bsd
        else echo c2-convex-bsd
        fi
-        exit ;;
+       exit ;;
     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
        echo c34-convex-bsd
-        exit ;;
+       exit ;;
     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
        echo c38-convex-bsd
-        exit ;;
+       exit ;;
     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
        echo c4-convex-bsd
-        exit ;;
+       exit ;;
     CRAY*Y-MP:*:*:*)
        echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
        exit ;;
@@ -770,14 +771,14 @@ EOF
        exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
        FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
-        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-        exit ;;
+       FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+       FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+       echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+       exit ;;
     5000:UNIX_System_V:4.*:*)
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
-        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+       FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+       FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+       echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
        exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
        echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@@ -789,13 +790,12 @@ EOF
        echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
        exit ;;
     *:FreeBSD:*:*)
-       case ${UNAME_MACHINE} in
-           pc98)
-               echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+       UNAME_PROCESSOR=`/usr/bin/uname -p`
+       case ${UNAME_PROCESSOR} in
            amd64)
                echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
            *)
-               echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+               echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
        esac
        exit ;;
     i*:CYGWIN*:*)
@@ -804,15 +804,18 @@ EOF
     *:MINGW*:*)
        echo ${UNAME_MACHINE}-pc-mingw32
        exit ;;
+    i*:MSYS*:*)
+       echo ${UNAME_MACHINE}-pc-msys
+       exit ;;
     i*:windows32*:*)
-       # uname -m includes "-pc" on this system.
-       echo ${UNAME_MACHINE}-mingw32
+       # uname -m includes "-pc" on this system.
+       echo ${UNAME_MACHINE}-mingw32
        exit ;;
     i*:PW*:*)
        echo ${UNAME_MACHINE}-pc-pw32
        exit ;;
     *:Interix*:*)
-       case ${UNAME_MACHINE} in
+       case ${UNAME_MACHINE} in
            x86)
                echo i586-pc-interix${UNAME_RELEASE}
                exit ;;
@@ -858,6 +861,13 @@ EOF
     i*86:Minix:*:*)
        echo ${UNAME_MACHINE}-pc-minix
        exit ;;
+    aarch64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    aarch64_be:Linux:*:*)
+       UNAME_MACHINE=aarch64_be
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
     alpha:Linux:*:*)
        case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
          EV5)   UNAME_MACHINE=alphaev5 ;;
@@ -867,7 +877,7 @@ EOF
          EV6)   UNAME_MACHINE=alphaev6 ;;
          EV67)  UNAME_MACHINE=alphaev67 ;;
          EV68*) UNAME_MACHINE=alphaev68 ;;
-        esac
+       esac
        objdump --private-headers /bin/sh | grep -q ld.so.1
        if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
        echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
@@ -879,20 +889,29 @@ EOF
        then
            echo ${UNAME_MACHINE}-unknown-linux-gnu
        else
-           echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+           if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+               | grep -q __ARM_PCS_VFP
+           then
+               echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+           else
+               echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+           fi
        fi
        exit ;;
     avr32*:Linux:*:*)
        echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     cris:Linux:*:*)
-       echo cris-axis-linux-gnu
+       echo ${UNAME_MACHINE}-axis-linux-gnu
        exit ;;
     crisv32:Linux:*:*)
-       echo crisv32-axis-linux-gnu
+       echo ${UNAME_MACHINE}-axis-linux-gnu
        exit ;;
     frv:Linux:*:*)
-       echo frv-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    hexagon:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     i*86:Linux:*:*)
        LIBC=gnu
@@ -934,7 +953,7 @@ EOF
        test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
        ;;
     or32:Linux:*:*)
-       echo or32-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     padre:Linux:*:*)
        echo sparc-unknown-linux-gnu
@@ -960,7 +979,7 @@ EOF
        echo ${UNAME_MACHINE}-ibm-linux
        exit ;;
     sh64*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     sh*:Linux:*:*)
        echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -968,14 +987,17 @@ EOF
     sparc:Linux:*:* | sparc64:Linux:*:*)
        echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
+    tile*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
     vax:Linux:*:*)
        echo ${UNAME_MACHINE}-dec-linux-gnu
        exit ;;
     x86_64:Linux:*:*)
-       echo x86_64-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     xtensa*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     i*86:DYNIX/ptx:4*:*)
        # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -984,11 +1006,11 @@ EOF
        echo i386-sequent-sysv4
        exit ;;
     i*86:UNIX_SV:4.2MP:2.*)
-        # Unixware is an offshoot of SVR4, but it has its own version
-        # number series starting with 2...
-        # I am not positive that other SVR4 systems won't match this,
+       # Unixware is an offshoot of SVR4, but it has its own version
+       # number series starting with 2...
+       # I am not positive that other SVR4 systems won't match this,
        # I just have to hope.  -- rms.
-        # Use sysv4.2uw... so that sysv4* matches it.
+       # Use sysv4.2uw... so that sysv4* matches it.
        echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
        exit ;;
     i*86:OS/2:*:*)
@@ -1020,7 +1042,7 @@ EOF
        fi
        exit ;;
     i*86:*:5:[678]*)
-       # UnixWare 7.x, OpenUNIX and OpenServer 6.
+       # UnixWare 7.x, OpenUNIX and OpenServer 6.
        case `/bin/uname -X | grep "^Machine"` in
            *486*)           UNAME_MACHINE=i486 ;;
            *Pentium)        UNAME_MACHINE=i586 ;;
@@ -1048,13 +1070,13 @@ EOF
        exit ;;
     pc:*:*:*)
        # Left here for compatibility:
-        # uname -m prints for DJGPP always 'pc', but it prints nothing about
-        # the processor, so we play safe by assuming i586.
+       # uname -m prints for DJGPP always 'pc', but it prints nothing about
+       # the processor, so we play safe by assuming i586.
        # Note: whatever this is, it MUST be the same as what config.sub
        # prints for the "djgpp" host, or else GDB configury will decide that
        # this is a cross-build.
        echo i586-pc-msdosdjgpp
-        exit ;;
+       exit ;;
     Intel:Mach:3*:*)
        echo i386-pc-mach3
        exit ;;
@@ -1089,8 +1111,8 @@ EOF
        /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
          && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
-        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-          && { echo i486-ncr-sysv4; exit; } ;;
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && { echo i486-ncr-sysv4; exit; } ;;
     NCR*:*:4.2:* | MPRAS*:*:4.2:*)
        OS_REL='.3'
        test -r /etc/.relid \
@@ -1133,10 +1155,10 @@ EOF
                echo ns32k-sni-sysv
        fi
        exit ;;
-    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
-                      # says <[email protected]>
-        echo i586-unisys-sysv4
-        exit ;;
+    PENTIUM:*:4.0*:*)  # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                       # says <[email protected]>
+       echo i586-unisys-sysv4
+       exit ;;
     *:UNIX_System_V:4*:FTX*)
        # From Gerald Hewes <[email protected]>.
        # How about differentiating between stratus architectures? -djm
@@ -1162,11 +1184,11 @@ EOF
        exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
        if [ -d /usr/nec ]; then
-               echo mips-nec-sysv${UNAME_RELEASE}
+               echo mips-nec-sysv${UNAME_RELEASE}
        else
-               echo mips-unknown-sysv${UNAME_RELEASE}
+               echo mips-unknown-sysv${UNAME_RELEASE}
        fi
-        exit ;;
+       exit ;;
     BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
        echo powerpc-be-beos
        exit ;;
@@ -1231,6 +1253,9 @@ EOF
     *:QNX:*:4*)
        echo i386-pc-qnx
        exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+       echo neo-tandem-nsk${UNAME_RELEASE}
+       exit ;;
     NSE-?:NONSTOP_KERNEL:*:*)
        echo nse-tandem-nsk${UNAME_RELEASE}
        exit ;;
@@ -1276,13 +1301,13 @@ EOF
        echo pdp10-unknown-its
        exit ;;
     SEI:*:*:SEIUX)
-        echo mips-sei-seiux${UNAME_RELEASE}
+       echo mips-sei-seiux${UNAME_RELEASE}
        exit ;;
     *:DragonFly:*:*)
        echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
        exit ;;
     *:*VMS:*:*)
-       UNAME_MACHINE=`(uname -p) 2>/dev/null`
+       UNAME_MACHINE=`(uname -p) 2>/dev/null`
        case "${UNAME_MACHINE}" in
            A*) echo alpha-dec-vms ; exit ;;
            I*) echo ia64-dec-vms ; exit ;;
@@ -1300,6 +1325,9 @@ EOF
     i*86:AROS:*:*)
        echo ${UNAME_MACHINE}-pc-aros
        exit ;;
+    x86_64:VMkernel:*:*)
+       echo ${UNAME_MACHINE}-unknown-esx
+       exit ;;
 esac
 
 #echo '(No uname command or uname output not recognized.)' 1>&2
@@ -1322,11 +1350,11 @@ main ()
 #include <sys/param.h>
   printf ("m68k-sony-newsos%s\n",
 #ifdef NEWSOS4
-          "4"
+       "4"
 #else
-         ""
+       ""
 #endif
-         ); exit (0);
+       ); exit (0);
 #endif
 #endif
 
index 85186096a9e1c6953474b9294f9d5c6041d648cf..59bb593f109c8d795df4cbb96b015222eed91c07 100755 (executable)
@@ -1,10 +1,10 @@
 #! /bin/sh
 # Configuration validation subroutine script.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-#   Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011, 2012 Free Software Foundation, Inc.
 
-timestamp='2009-12-31'
+timestamp='2012-04-18'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -21,9 +21,7 @@ timestamp='2009-12-31'
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -76,8 +74,8 @@ version="\
 GNU config.sub ($timestamp)
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
-Software Foundation, Inc.
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -124,13 +122,18 @@ esac
 # Here we must recognize all the valid KERNEL-OS combinations.
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
-  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
   kopensolaris*-gnu* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
+  android-linux)
+    os=-linux-android
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    ;;
   *)
     basic_machine=`echo $1 | sed 's/-[^-]*$//'`
     if [ $basic_machine != $1 ]
@@ -157,8 +160,8 @@ case $os in
                os=
                basic_machine=$1
                ;;
-        -bluegene*)
-               os=-cnk
+       -bluegene*)
+               os=-cnk
                ;;
        -sim | -cisco | -oki | -wec | -winbond)
                os=
@@ -174,10 +177,10 @@ case $os in
                os=-chorusos
                basic_machine=$1
                ;;
-       -chorusrdb)
-               os=-chorusrdb
+       -chorusrdb)
+               os=-chorusrdb
                basic_machine=$1
-               ;;
+               ;;
        -hiux*)
                os=-hiuxwe2
                ;;
@@ -222,6 +225,12 @@ case $os in
        -isc*)
                basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
                ;;
+       -lynx*178)
+               os=-lynxos178
+               ;;
+       -lynx*5)
+               os=-lynxos5
+               ;;
        -lynx*)
                os=-lynxos
                ;;
@@ -246,17 +255,22 @@ case $basic_machine in
        # Some are omitted here because they have special meanings below.
        1750a | 580 \
        | a29k \
+       | aarch64 | aarch64_be \
        | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
        | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
        | am33_2.0 \
        | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+        | be32 | be64 \
        | bfin \
        | c4x | clipper \
        | d10v | d30v | dlx | dsp16xx \
+       | epiphany \
        | fido | fr30 | frv \
        | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | hexagon \
        | i370 | i860 | i960 | ia64 \
        | ip2k | iq2000 \
+       | le32 | le64 \
        | lm32 \
        | m32c | m32r | m32rle | m68000 | m68k | m88k \
        | maxq | mb | microblaze | mcore | mep | metag \
@@ -282,29 +296,39 @@ case $basic_machine in
        | moxie \
        | mt \
        | msp430 \
+       | nds32 | nds32le | nds32be \
        | nios | nios2 \
        | ns16k | ns32k \
+       | open8 \
        | or32 \
        | pdp10 | pdp11 | pj | pjl \
-       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | powerpc | powerpc64 | powerpc64le | powerpcle \
        | pyramid \
-       | rx \
+       | rl78 | rx \
        | score \
        | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
        | sh64 | sh64le \
        | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
        | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-       | spu | strongarm \
-       | tahoe | thumb | tic4x | tic80 | tron \
+       | spu \
+       | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
        | ubicom32 \
-       | v850 | v850e \
+       | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
        | we32k \
-       | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+       | x86 | xc16x | xstormy16 | xtensa \
        | z8k | z80)
                basic_machine=$basic_machine-unknown
                ;;
-       m6811 | m68hc11 | m6812 | m68hc12 | picochip)
-               # Motorola 68HC11/12.
+       c54x)
+               basic_machine=tic54x-unknown
+               ;;
+       c55x)
+               basic_machine=tic55x-unknown
+               ;;
+       c6x)
+               basic_machine=tic6x-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
                basic_machine=$basic_machine-unknown
                os=-none
                ;;
@@ -314,6 +338,21 @@ case $basic_machine in
                basic_machine=mt-unknown
                ;;
 
+       strongarm | thumb | xscale)
+               basic_machine=arm-unknown
+               ;;
+       xgate)
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       xscaleeb)
+               basic_machine=armeb-unknown
+               ;;
+
+       xscaleel)
+               basic_machine=armel-unknown
+               ;;
+
        # We use `pc' rather than `unknown'
        # because (1) that's what they normally are, and
        # (2) the word "unknown" tends to confuse beginning users.
@@ -328,21 +367,25 @@ case $basic_machine in
        # Recognize the basic CPU types with company name.
        580-* \
        | a29k-* \
+       | aarch64-* | aarch64_be-* \
        | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
        | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
        | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
        | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
        | avr-* | avr32-* \
+       | be32-* | be64-* \
        | bfin-* | bs2000-* \
-       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+       | c[123]* | c30-* | [cjt]90-* | c4x-* \
        | clipper-* | craynv-* | cydra-* \
        | d10v-* | d30v-* | dlx-* \
        | elxsi-* \
        | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
        | h8300-* | h8500-* \
        | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | hexagon-* \
        | i*86-* | i860-* | i960-* | ia64-* \
        | ip2k-* | iq2000-* \
+       | le32-* | le64-* \
        | lm32-* \
        | m32c-* | m32r-* | m32rle-* \
        | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
@@ -368,25 +411,29 @@ case $basic_machine in
        | mmix-* \
        | mt-* \
        | msp430-* \
+       | nds32-* | nds32le-* | nds32be-* \
        | nios-* | nios2-* \
        | none-* | np1-* | ns16k-* | ns32k-* \
+       | open8-* \
        | orion-* \
        | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
        | pyramid-* \
-       | romp-* | rs6000-* | rx-* \
+       | rl78-* | romp-* | rs6000-* | rx-* \
        | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
        | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
        | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
        | sparclite-* \
-       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
-       | tahoe-* | thumb-* \
-       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+       | tahoe-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+       | tile*-* \
        | tron-* \
        | ubicom32-* \
-       | v850-* | v850e-* | vax-* \
+       | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+       | vax-* \
        | we32k-* \
-       | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+       | x86-* | x86_64-* | xc16x-* | xps100-* \
        | xstormy16-* | xtensa*-* \
        | ymp-* \
        | z8k-* | z80-*)
@@ -411,7 +458,7 @@ case $basic_machine in
                basic_machine=a29k-amd
                os=-udi
                ;;
-       abacus)
+       abacus)
                basic_machine=abacus-unknown
                ;;
        adobe68k)
@@ -481,11 +528,20 @@ case $basic_machine in
                basic_machine=powerpc-ibm
                os=-cnk
                ;;
+       c54x-*)
+               basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       c55x-*)
+               basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       c6x-*)
+               basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
        c90)
                basic_machine=c90-cray
                os=-unicos
                ;;
-        cegcc)
+       cegcc)
                basic_machine=arm-unknown
                os=-cegcc
                ;;
@@ -517,7 +573,7 @@ case $basic_machine in
                basic_machine=craynv-cray
                os=-unicosmp
                ;;
-       cr16)
+       cr16 | cr16-*)
                basic_machine=cr16-unknown
                os=-elf
                ;;
@@ -675,7 +731,6 @@ case $basic_machine in
        i370-ibm* | ibm*)
                basic_machine=i370-ibm
                ;;
-# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
        i*86v32)
                basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
                os=-sysv32
@@ -733,7 +788,7 @@ case $basic_machine in
                basic_machine=ns32k-utek
                os=-sysv
                ;;
-        microblaze)
+       microblaze)
                basic_machine=microblaze-xilinx
                ;;
        mingw32)
@@ -772,10 +827,18 @@ case $basic_machine in
        ms1-*)
                basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
                ;;
+       msys)
+               basic_machine=i386-pc
+               os=-msys
+               ;;
        mvs)
                basic_machine=i370-ibm
                os=-mvs
                ;;
+       nacl)
+               basic_machine=le32-unknown
+               os=-nacl
+               ;;
        ncr3000)
                basic_machine=i486-ncr
                os=-sysv4
@@ -840,6 +903,12 @@ case $basic_machine in
        np1)
                basic_machine=np1-gould
                ;;
+       neo-tandem)
+               basic_machine=neo-tandem
+               ;;
+       nse-tandem)
+               basic_machine=nse-tandem
+               ;;
        nsr-tandem)
                basic_machine=nsr-tandem
                ;;
@@ -922,9 +991,10 @@ case $basic_machine in
                ;;
        power)  basic_machine=power-ibm
                ;;
-       ppc)    basic_machine=powerpc-unknown
+       ppc | ppcbe)    basic_machine=powerpc-unknown
                ;;
-       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+       ppc-* | ppcbe-*)
+               basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
                ;;
        ppcle | powerpclittle | ppc-le | powerpc-little)
                basic_machine=powerpcle-unknown
@@ -1018,6 +1088,9 @@ case $basic_machine in
                basic_machine=i860-stratus
                os=-sysv4
                ;;
+       strongarm-* | thumb-*)
+               basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
        sun2)
                basic_machine=m68000-sun
                ;;
@@ -1074,20 +1147,8 @@ case $basic_machine in
                basic_machine=t90-cray
                os=-unicos
                ;;
-       tic54x | c54x*)
-               basic_machine=tic54x-unknown
-               os=-coff
-               ;;
-       tic55x | c55x*)
-               basic_machine=tic55x-unknown
-               os=-coff
-               ;;
-       tic6x | c6x*)
-               basic_machine=tic6x-unknown
-               os=-coff
-               ;;
        tile*)
-               basic_machine=tile-unknown
+               basic_machine=$basic_machine-unknown
                os=-linux-gnu
                ;;
        tx39)
@@ -1157,6 +1218,9 @@ case $basic_machine in
        xps | xps100)
                basic_machine=xps100-honeywell
                ;;
+       xscale-* | xscalee[bl]-*)
+               basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+               ;;
        ymp)
                basic_machine=ymp-cray
                os=-unicos
@@ -1254,11 +1318,11 @@ esac
 if [ x"$os" != x"" ]
 then
 case $os in
-        # First match some system type aliases
-        # that might get confused with valid system types.
+       # First match some system type aliases
+       # that might get confused with valid system types.
        # -solaris* is a basic system type, with this one exception.
-        -auroraux)
-               os=-auroraux
+       -auroraux)
+               os=-auroraux
                ;;
        -solaris1 | -solaris1.*)
                os=`echo $os | sed -e 's|solaris1|sunos4|'`
@@ -1294,8 +1358,9 @@ case $os in
              | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
              | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
              | -chorusos* | -chorusrdb* | -cegcc* \
-             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+             | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -linux-android* \
+             | -linux-newlib* | -linux-uclibc* \
              | -uxpv* | -beos* | -mpeix* | -udk* \
              | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
              | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1342,7 +1407,7 @@ case $os in
        -opened*)
                os=-openedition
                ;;
-        -os400*)
+       -os400*)
                os=-os400
                ;;
        -wince*)
@@ -1391,7 +1456,7 @@ case $os in
        -sinix*)
                os=-sysv4
                ;;
-        -tpf*)
+       -tpf*)
                os=-tpf
                ;;
        -triton*)
@@ -1436,8 +1501,8 @@ case $os in
        -dicos*)
                os=-dicos
                ;;
-        -nacl*)
-               ;;
+       -nacl*)
+               ;;
        -none)
                ;;
        *)
@@ -1460,10 +1525,10 @@ else
 # system, and we'll never get to this point.
 
 case $basic_machine in
-        score-*)
+       score-*)
                os=-elf
                ;;
-        spu-*)
+       spu-*)
                os=-elf
                ;;
        *-acorn)
@@ -1475,8 +1540,17 @@ case $basic_machine in
        arm*-semi)
                os=-aout
                ;;
-        c4x-* | tic4x-*)
-               os=-coff
+       c4x-* | tic4x-*)
+               os=-coff
+               ;;
+       tic54x-*)
+               os=-coff
+               ;;
+       tic55x-*)
+               os=-coff
+               ;;
+       tic6x-*)
+               os=-coff
                ;;
        # This must come before the *-dec entry.
        pdp10-*)
@@ -1496,14 +1570,11 @@ case $basic_machine in
                ;;
        m68000-sun)
                os=-sunos3
-               # This also exists in the configure program, but was not the
-               # default.
-               # os=-sunos4
                ;;
        m68*-cisco)
                os=-aout
                ;;
-        mep-*)
+       mep-*)
                os=-elf
                ;;
        mips*-cisco)
@@ -1530,7 +1601,7 @@ case $basic_machine in
        *-ibm)
                os=-aix
                ;;
-       *-knuth)
+       *-knuth)
                os=-mmixware
                ;;
        *-wec)
index 13d1e6a71e1651da13dfbfd71506e7b7437db0d1..1a800f57bd8239b42d988a7fb62b73eb4ee1209c 100755 (executable)
--- a/configure
+++ b/configure
@@ -8013,7 +8013,7 @@ esac
 if test "${enable_bluetooth+set}" = set; then :
   enableval=$enable_bluetooth;
 else
-  enable_bluetooth=yes
+  enable_bluetooth=ifsupportavailable
 fi
 
 
@@ -8107,18 +8107,30 @@ $as_echo "#define PCAP_SUPPORT_BT_MONITOR /**/" >>confdefs.h
                        BT_MONITOR_SRC=pcap-bt-monitor-linux.c
                      fi
                    fi
+                   ac_lbl_bluetooth_available=yes
 
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&5
-$as_echo "$as_me: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&6;}
+  ac_lbl_bluetooth_available=no
 
 fi
 
 
+               if test "x$ac_lbl_bluetooth_available" == "xno" ; then
+                   if test "x$enable_bluetooth" = "xyes" ; then
+                       as_fn_error $? "Bluetooth sniffing is not supported; install bluez-lib devel to enable it" "$LINENO" 5
+                   else
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&5
+$as_echo "$as_me: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&6;}
+                   fi
+               fi
                ;;
        *)
-               { $as_echo "$as_me:${as_lineno-$LINENO}: no Bluetooth sniffing support implemented for $host_os" >&5
+               if test "x$enable_bluetooth" = "xyes" ; then
+                   as_fn_error $? "no Bluetooth sniffing support implemented for $host_os" "$LINENO" 5
+               else
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: no Bluetooth sniffing support implemented for $host_os" >&5
 $as_echo "$as_me: no Bluetooth sniffing support implemented for $host_os" >&6;}
+               fi
                ;;
        esac
 
@@ -8130,7 +8142,7 @@ fi
 if test "${enable_canusb+set}" = set; then :
   enableval=$enable_canusb;
 else
-  enable_canusb=yes
+  enable_canusb=ifsupportavailable
 fi
 
 
@@ -8140,25 +8152,82 @@ if test "x$enable_canusb" != "xno" ; then
                ac_fn_c_check_header_mongrel "$LINENO" "libusb-1.0/libusb.h" "ac_cv_header_libusb_1_0_libusb_h" "$ac_includes_default"
 if test "x$ac_cv_header_libusb_1_0_libusb_h" = xyes; then :
 
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libusb_init in -lusb-1.0" >&5
+$as_echo_n "checking for libusb_init in -lusb-1.0... " >&6; }
+if ${ac_cv_lib_usb_1_0_libusb_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lusb-1.0  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 libusb_init ();
+int
+main ()
+{
+return libusb_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_usb_1_0_libusb_init=yes
+else
+  ac_cv_lib_usb_1_0_libusb_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_usb_1_0_libusb_init" >&5
+$as_echo "$ac_cv_lib_usb_1_0_libusb_init" >&6; }
+if test "x$ac_cv_lib_usb_1_0_libusb_init" = xyes; then :
+
 
 $as_echo "#define PCAP_SUPPORT_CANUSB 1" >>confdefs.h
 
-                   CANUSB_SRC=pcap-canusb-linux.c
-                   LIBS="-lusb-1.0 -lpthread $LIBS"
-                   { $as_echo "$as_me:${as_lineno-$LINENO}: canusb sniffing is supported" >&5
-$as_echo "$as_me: canusb sniffing is supported" >&6;}
+                       CANUSB_SRC=pcap-canusb-linux.c
+                       LIBS="-lusb-1.0 -lpthread $LIBS"
+                       ac_lbl_has_libusb=yes
 
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: canusb sniffing is not supported; install libusb1.0 lib devel to enable it" >&5
-$as_echo "$as_me: canusb sniffing is not supported; install libusb1.0 lib devel to enable it" >&6;}
+  ac_lbl_has_libusb=no
 
 fi
 
 
+else
+  ac_lbl_has_libusb=no
+
+fi
+
+
+               if test "x$ac_lbl_has_libusb" = "xyes" ; then
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: canusb sniffing is supported" >&5
+$as_echo "$as_me: canusb sniffing is supported" >&6;}
+               else
+                   if test "x$enable_canusb" = "xyes" ; then
+                       as_fn_error $? "canusb sniffing is not supported; install libusb1.0 lib devel to enable it" "$LINENO" 5
+                   else
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: canusb sniffing is not supported; install libusb1.0 lib devel to enable it" >&5
+$as_echo "$as_me: canusb sniffing is not supported; install libusb1.0 lib devel to enable it" >&6;}
+                   fi
+               fi
                ;;
        *)
-               { $as_echo "$as_me:${as_lineno-$LINENO}: no canusb support implemented for $host_os" >&5
+               if test "x$enable_canusb" = "xyes" ; then
+                   as_fn_error $? "no canusb support implemented for $host_os" "$LINENO" 5
+               else
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: no canusb support implemented for $host_os" >&5
 $as_echo "$as_me: no canusb support implemented for $host_os" >&6;}
+               fi
                ;;
        esac
 
@@ -8169,7 +8238,7 @@ fi
 if test "${enable_can+set}" = set; then :
   enableval=$enable_can;
 else
-  enable_can=yes
+  enable_can=ifsupportavailable
 fi
 
 
@@ -8181,21 +8250,33 @@ if test "x$enable_can" != "xno" ; then
 "
 if test "x$ac_cv_header_linux_can_h" = xyes; then :
 
+
 $as_echo "#define PCAP_SUPPORT_CAN 1" >>confdefs.h
 
-                       CAN_SRC=pcap-can-linux.c
-                       { $as_echo "$as_me:${as_lineno-$LINENO}: CAN sniffing is supported" >&5
+                           CAN_SRC=pcap-can-linux.c
+                           { $as_echo "$as_me:${as_lineno-$LINENO}: CAN sniffing is supported" >&5
 $as_echo "$as_me: CAN sniffing is supported" >&6;}
+
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: CAN sniffing is not supported" >&5
+
+                           if test "x$enable_can" = "xyes" ; then
+                               as_fn_error $? "CAN sniffing is not supported" "$LINENO" 5
+                           else
+                               { $as_echo "$as_me:${as_lineno-$LINENO}: CAN sniffing is not supported" >&5
 $as_echo "$as_me: CAN sniffing is not supported" >&6;}
+                           fi
+
 fi
 
 
                ;;
        *)
-               { $as_echo "$as_me:${as_lineno-$LINENO}: no CAN sniffing support implemented for $host_os" >&5
+               if test "x$enable_can" = "xyes" ; then
+                   as_fn_error $? "no CAN sniffing support implemented for $host_os" "$LINENO" 5
+               else
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: no CAN sniffing support implemented for $host_os" >&5
 $as_echo "$as_me: no CAN sniffing support implemented for $host_os" >&6;}
+               fi
                ;;
        esac
 
@@ -8215,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; }
@@ -8269,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 ()
 {
@@ -8301,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 af3c36ab24e4aeb3c8066bba0558036a4f0723f8..063c645235c755f6f41459ff6333fb1fac8c8e99 100644 (file)
@@ -1462,7 +1462,7 @@ AC_SUBST(NETFILTER_SRC)
 AC_ARG_ENABLE([bluetooth],
 [AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])],
     [],
-    [enable_bluetooth=yes])
+    [enable_bluetooth=ifsupportavailable])
 
 if test "x$enable_bluetooth" != "xno" ; then
        dnl check for Bluetooth sniffing support
@@ -1513,12 +1513,24 @@ if test "x$enable_bluetooth" != "xno" ; then
                        BT_MONITOR_SRC=pcap-bt-monitor-linux.c
                      fi
                    fi
+                   ac_lbl_bluetooth_available=yes
                ],
-               AC_MSG_NOTICE(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
+               ac_lbl_bluetooth_available=no
                )
+               if test "x$ac_lbl_bluetooth_available" == "xno" ; then
+                   if test "x$enable_bluetooth" = "xyes" ; then
+                       AC_MSG_ERROR(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
+                   else
+                       AC_MSG_NOTICE(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
+                   fi
+               fi
                ;;
        *)
-               AC_MSG_NOTICE(no Bluetooth sniffing support implemented for $host_os)
+               if test "x$enable_bluetooth" = "xyes" ; then
+                   AC_MSG_ERROR(no Bluetooth sniffing support implemented for $host_os)
+               else
+                   AC_MSG_NOTICE(no Bluetooth sniffing support implemented for $host_os)
+               fi
                ;;
        esac
        AC_SUBST(PCAP_SUPPORT_BT)
@@ -1529,7 +1541,7 @@ fi
 AC_ARG_ENABLE([canusb],
 [AC_HELP_STRING([--enable-canusb],[enable canusb support @<:@default=yes, if support available@:>@])],
     [],
-    [enable_canusb=yes])
+    [enable_canusb=ifsupportavailable])
 
 if test "x$enable_canusb" != "xno" ; then
        dnl check for canusb support
@@ -1537,16 +1549,34 @@ if test "x$enable_canusb" != "xno" ; then
        linux*)
                AC_CHECK_HEADER(libusb-1.0/libusb.h,
                [
-                   AC_DEFINE(PCAP_SUPPORT_CANUSB, 1, [target host supports canusb])
-                   CANUSB_SRC=pcap-canusb-linux.c
-                   LIBS="-lusb-1.0 -lpthread $LIBS"
-                   AC_MSG_NOTICE(canusb sniffing is supported)
+                   AC_CHECK_LIB(usb-1.0, libusb_init,
+                   [
+                       AC_DEFINE(PCAP_SUPPORT_CANUSB, 1, [target host supports canusb])
+                       CANUSB_SRC=pcap-canusb-linux.c
+                       LIBS="-lusb-1.0 -lpthread $LIBS"
+                       ac_lbl_has_libusb=yes
+                   ],
+                   ac_lbl_has_libusb=no
+                   )
                ],
-               AC_MSG_NOTICE(canusb sniffing is not supported; install libusb1.0 lib devel to enable it)
+               ac_lbl_has_libusb=no
                )
+               if test "x$ac_lbl_has_libusb" = "xyes" ; then
+                   AC_MSG_NOTICE(canusb sniffing is supported)
+               else
+                   if test "x$enable_canusb" = "xyes" ; then
+                       AC_MSG_ERROR(canusb sniffing is not supported; install libusb1.0 lib devel to enable it)
+                   else
+                       AC_MSG_NOTICE(canusb sniffing is not supported; install libusb1.0 lib devel to enable it)
+                   fi
+               fi
                ;;
        *)
-               AC_MSG_NOTICE(no canusb support implemented for $host_os)
+               if test "x$enable_canusb" = "xyes" ; then
+                   AC_MSG_ERROR(no canusb support implemented for $host_os)
+               else
+                   AC_MSG_NOTICE(no canusb support implemented for $host_os)
+               fi
                ;;
        esac
        AC_SUBST(PCAP_SUPPORT_CANUSB)
@@ -1556,22 +1586,34 @@ fi
 AC_ARG_ENABLE([can],
 [AC_HELP_STRING([--enable-can],[enable CAN support @<:@default=yes, if support available@:>@])],
     [],
-    [enable_can=yes])
+    [enable_can=ifsupportavailable])
 
 if test "x$enable_can" != "xno" ; then
        dnl check for CAN sniffing support
        case "$host_os" in
        linux*)
                AC_CHECK_HEADER(linux/can.h,
-                       [ AC_DEFINE(PCAP_SUPPORT_CAN, 1, [target host supports CAN sniffing])
-                       CAN_SRC=pcap-can-linux.c
-                       AC_MSG_NOTICE(CAN sniffing is supported)],
-                       AC_MSG_NOTICE(CAN sniffing is not supported),
+                       [
+                           AC_DEFINE(PCAP_SUPPORT_CAN, 1, [target host supports CAN sniffing])
+                           CAN_SRC=pcap-can-linux.c
+                           AC_MSG_NOTICE(CAN sniffing is supported)
+                       ],
+                       [
+                           if test "x$enable_can" = "xyes" ; then
+                               AC_MSG_ERROR(CAN sniffing is not supported)
+                           else
+                               AC_MSG_NOTICE(CAN sniffing is not supported)
+                           fi
+                       ],
                        [#include <sys/socket.h>]
                   )
                ;;
        *)
-               AC_MSG_NOTICE(no CAN sniffing support implemented for $host_os)
+               if test "x$enable_can" = "xyes" ; then
+                   AC_MSG_ERROR(no CAN sniffing support implemented for $host_os)
+               else
+                   AC_MSG_NOTICE(no CAN sniffing support implemented for $host_os)
+               fi
                ;;
        esac
        AC_SUBST(PCAP_SUPPORT_CAN)
@@ -1588,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 81524590fcb0c84474a310b38a99c8e5766274d2..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 */
@@ -394,38 +394,30 @@ syntax()
 static bpf_u_int32 netmask;
 static int snaplen;
 int no_optimize;
-#ifdef WIN32
-static int
-pcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
-            const char *buf, int optimize, bpf_u_int32 mask);
 
 int
 pcap_compile(pcap_t *p, struct bpf_program *program,
             const char *buf, int optimize, bpf_u_int32 mask)
-{
-       int result;
-
-       EnterCriticalSection(&g_PcapCompileCriticalSection);
-
-       result = pcap_compile_unsafe(p, program, buf, optimize, mask);
-
-       LeaveCriticalSection(&g_PcapCompileCriticalSection);
-       
-       return result;
-}
-
-static int
-pcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
-            const char *buf, int optimize, bpf_u_int32 mask)
-#else /* WIN32 */
-int
-pcap_compile(pcap_t *p, struct bpf_program *program,
-            const char *buf, int optimize, bpf_u_int32 mask)
-#endif /* WIN32 */
 {
        extern int n_errors;
        const char * volatile xbuf = buf;
        u_int len;
+       int  rc;
+
+       /*
+        * XXX - single-thread this code path with pthread calls on
+        * UN*X, if the platform supports pthreads?  If that requires
+        * a separate -lpthread, we might not want to do that.
+        */
+#ifdef WIN32
+       extern int wsockinit (void);
+       static int done = 0;
+
+       if (!done)
+               wsockinit();
+       done = 1;
+       EnterCriticalSection(&g_PcapCompileCriticalSection);
+#endif
 
        /*
         * If this pcap_t hasn't been activated, it doesn't have a
@@ -434,13 +426,15 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
        if (!p->activated) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                    "not-yet-activated pcap_t passed to pcap_compile");
-               return (-1);
+               rc = -1;
+               goto quit;
        }
        no_optimize = 0;
        n_errors = 0;
        root = NULL;
        bpf_pcap = p;
        init_regs();
+
        if (setjmp(top_ctx)) {
 #ifdef INET6
                if (ai != NULL) {
@@ -450,7 +444,8 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
 #endif
                lex_cleanup();
                freechunks();
-               return (-1);
+               rc = -1;
+               goto quit;
        }
 
        netmask = mask;
@@ -459,7 +454,8 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
        if (snaplen == 0) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                         "snaplen of 0 rejects all packets");
-               return -1;
+               rc = -1;
+               goto quit;
        }
 
        lex_init(xbuf ? xbuf : "");
@@ -483,7 +479,16 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
 
        lex_cleanup();
        freechunks();
-       return (0);
+
+       rc = 0;  /* We're all okay */
+
+quit:
+
+#ifdef WIN32
+       LeaveCriticalSection(&g_PcapCompileCriticalSection);
+#endif
+
+       return (rc);
 }
 
 /*
@@ -588,7 +593,7 @@ finish_parse(p)
         * worth the effort.
         */
        insert_compute_vloffsets(p->head);
-       
+
        /*
         * For DLT_PPI captures, generate a check of the per-packet
         * DLT value to make sure it's DLT_IEEE802_11.
@@ -958,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;
@@ -1124,7 +1130,7 @@ init_linktype(p)
                return;
 
        case DLT_PPI:
-               /* 
+               /*
                 * At the moment we treat PPI the same way that we treat
                 * normal Radiotap encoded packets. The difference is in
                 * the function that generates the code at the beginning
@@ -2299,7 +2305,7 @@ gen_load_radiotap_llprefixlen()
                return (NULL);
 }
 
-/* 
+/*
  * At the moment we treat PPI as normal Radiotap encoded
  * packets. The difference is in the function that generates
  * the code at the beginning to compute the header length.
@@ -2312,7 +2318,7 @@ static struct slist *
 gen_load_ppi_llprefixlen()
 {
        struct slist *s1, *s2;
-       
+
        /*
         * Generate code to load the length of the radiotap header
         * into the register assigned to hold that length, if one has
@@ -2402,7 +2408,7 @@ gen_load_802_11_header_len(struct slist *s, struct slist *snext)
         * slist of instructions
         */
        no_optimize = 1;
-       
+
        /*
         * If "s" is non-null, it has code to arrange that the X register
         * contains the length of the prefix preceding the link-layer
@@ -2453,7 +2459,7 @@ gen_load_802_11_header_len(struct slist *s, struct slist *snext)
        sjset_data_frame_1 = new_stmt(JMP(BPF_JSET));
        sjset_data_frame_1->s.k = 0x08;
        sappend(s, sjset_data_frame_1);
-               
+
        /*
         * If b3 is set, test b2, otherwise go to the first statement of
         * the rest of the program.
@@ -2472,7 +2478,7 @@ gen_load_802_11_header_len(struct slist *s, struct slist *snext)
        sjset_data_frame_2->s.jf = sjset_qos = new_stmt(JMP(BPF_JSET));
        sjset_qos->s.k = 0x80;  /* QoS bit */
        sappend(s, sjset_qos);
-               
+
        /*
         * If it's set, add 2 to reg_off_macpl, to skip the QoS
         * field.
@@ -2743,7 +2749,7 @@ gen_radiotap_llprefixlen(void)
        return s;
 }
 
-/* 
+/*
  * At the moment we treat PPI as normal Radiotap encoded
  * packets. The difference is in the function that generates
  * the code at the beginning to compute the header length.
@@ -2897,6 +2903,7 @@ gen_linktype(proto)
        register int proto;
 {
        struct block *b0, *b1, *b2;
+       const char *description;
 
        /* are we checking MPLS-encapsulated packets? */
        if (label_stack_depth > 0) {
@@ -2904,12 +2911,12 @@ gen_linktype(proto)
                case ETHERTYPE_IP:
                case PPP_IP:
                        /* FIXME add other L3 proto IDs */
-                       return gen_mpls_linktype(Q_IP); 
+                       return gen_mpls_linktype(Q_IP);
 
                case ETHERTYPE_IPV6:
                case PPP_IPV6:
                        /* FIXME add other L3 proto IDs */
-                       return gen_mpls_linktype(Q_IPV6); 
+                       return gen_mpls_linktype(Q_IPV6);
 
                default:
                        bpf_error("unsupported protocol over mpls");
@@ -2981,7 +2988,7 @@ gen_linktype(proto)
 
        case DLT_FDDI:
                /*
-                * XXX - check for asynchronous frames, as per RFC 1103.
+                * XXX - check for LLC frames.
                 */
                return gen_llc_linktype(proto);
                /*NOTREACHED*/
@@ -3413,26 +3420,36 @@ gen_linktype(proto)
                 * either missing or behind TLVs.
                 */
                bpf_error("NFLOG link-layer type filtering not implemented");
-       }
 
-       /*
-        * All the types that have no encapsulation should either be
-        * handled as DLT_SLIP, DLT_SLIP_BSDOS, and DLT_RAW are, if
-        * all packets are IP packets, or should be handled in some
-        * special case, if none of them are (if some are and some
-        * aren't, the lack of encapsulation is a problem, as we'd
-        * have to find some other way of determining the packet type).
-        *
-        * Therefore, if "off_linktype" is -1, there's an error.
-        */
-       if (off_linktype == (u_int)-1)
-               abort();
-
-       /*
-        * Any type not handled above should always have an Ethernet
-        * type at an offset of "off_linktype".
-        */
-       return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+       default:
+               /*
+                * Does this link-layer header type have a field
+                * indicating the type of the next protocol?  If
+                * so, off_linktype will be the offset of that
+                * field in the packet; if not, it will be -1.
+                */
+               if (off_linktype != (u_int)-1) {
+                       /*
+                        * Yes; assume it's an Ethernet type.  (If
+                        * it's not, it needs to be handled specially
+                        * above.)
+                        */
+                       return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+               } else {
+                       /*
+                        * No; report an error.
+                        */
+                       description = pcap_datalink_val_to_description(linktype);
+                       if (description != NULL) {
+                               bpf_error("%s link-layer type filtering not implemented",
+                                   description);
+                       } else {
+                               bpf_error("DLT %u link-layer type filtering not implemented",
+                                   linktype);
+                       }
+               }
+               break;
+       }
 }
 
 /*
@@ -3460,6 +3477,178 @@ gen_snap(orgcode, ptype)
        return gen_bcmp(OR_MACPL, 0, 8, snapblock);
 }
 
+/*
+ * Generate code to match frames with an LLC header.
+ */
+struct block *
+gen_llc(void)
+{
+       struct block *b0, *b1;
+
+       switch (linktype) {
+
+       case DLT_EN10MB:
+               /*
+                * We check for an Ethernet type field less than
+                * 1500, which means it's an 802.3 length field.
+                */
+               b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
+               gen_not(b0);
+
+               /*
+                * Now check for the purported DSAP and SSAP not being
+                * 0xFF, to rule out NetWare-over-802.3.
+                */
+               b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)0xFFFF);
+               gen_not(b1);
+               gen_and(b0, b1);
+               return b1;
+
+       case DLT_SUNATM:
+               /*
+                * We check for LLC traffic.
+                */
+               b0 = gen_atmtype_abbrev(A_LLC);
+               return b0;
+
+       case DLT_IEEE802:       /* Token Ring */
+               /*
+                * XXX - check for LLC frames.
+                */
+               return gen_true();
+
+       case DLT_FDDI:
+               /*
+                * XXX - check for LLC frames.
+                */
+               return gen_true();
+
+       case DLT_ATM_RFC1483:
+               /*
+                * For LLC encapsulation, these are defined to have an
+                * 802.2 LLC header.
+                *
+                * For VC encapsulation, they don't, but there's no
+                * way to check for that; the protocol used on the VC
+                * is negotiated out of band.
+                */
+               return gen_true();
+
+       case DLT_IEEE802_11:
+       case DLT_PRISM_HEADER:
+       case DLT_IEEE802_11_RADIO:
+       case DLT_IEEE802_11_RADIO_AVS:
+       case DLT_PPI:
+               /*
+                * Check that we have a data frame.
+                */
+               b0 = gen_check_802_11_data_frame();
+               return b0;
+
+       default:
+               bpf_error("'llc' not supported for linktype %d", linktype);
+               /* NOTREACHED */
+       }
+}
+
+struct block *
+gen_llc_i(void)
+{
+       struct block *b0, *b1;
+       struct slist *s;
+
+       /*
+        * Check whether this is an LLC frame.
+        */
+       b0 = gen_llc();
+
+       /*
+        * Load the control byte and test the low-order bit; it must
+        * be clear for I frames.
+        */
+       s = gen_load_a(OR_MACPL, 2, BPF_B);
+       b1 = new_block(JMP(BPF_JSET));
+       b1->s.k = 0x01;
+       b1->stmts = s;
+       gen_not(b1);
+       gen_and(b0, b1);
+       return b1;
+}
+
+struct block *
+gen_llc_s(void)
+{
+       struct block *b0, *b1;
+
+       /*
+        * Check whether this is an LLC frame.
+        */
+       b0 = gen_llc();
+
+       /*
+        * Now compare the low-order 2 bit of the control byte against
+        * the appropriate value for S frames.
+        */
+       b1 = gen_mcmp(OR_MACPL, 2, BPF_B, LLC_S_FMT, 0x03);
+       gen_and(b0, b1);
+       return b1;
+}
+
+struct block *
+gen_llc_u(void)
+{
+       struct block *b0, *b1;
+
+       /*
+        * Check whether this is an LLC frame.
+        */
+       b0 = gen_llc();
+
+       /*
+        * Now compare the low-order 2 bit of the control byte against
+        * the appropriate value for U frames.
+        */
+       b1 = gen_mcmp(OR_MACPL, 2, BPF_B, LLC_U_FMT, 0x03);
+       gen_and(b0, b1);
+       return b1;
+}
+
+struct block *
+gen_llc_s_subtype(bpf_u_int32 subtype)
+{
+       struct block *b0, *b1;
+
+       /*
+        * Check whether this is an LLC frame.
+        */
+       b0 = gen_llc();
+
+       /*
+        * Now check for an S frame with the appropriate type.
+        */
+       b1 = gen_mcmp(OR_MACPL, 2, BPF_B, subtype, LLC_S_CMD_MASK);
+       gen_and(b0, b1);
+       return b1;
+}
+
+struct block *
+gen_llc_u_subtype(bpf_u_int32 subtype)
+{
+       struct block *b0, *b1;
+
+       /*
+        * Check whether this is an LLC frame.
+        */
+       b0 = gen_llc();
+
+       /*
+        * Now check for a U frame with the appropriate type.
+        */
+       b1 = gen_mcmp(OR_MACPL, 2, BPF_B, subtype, LLC_U_CMD_MASK);
+       gen_and(b0, b1);
+       return b1;
+}
+
 /*
  * Generate code to match a particular packet type, for link-layer types
  * using 802.2 LLC headers.
@@ -4410,7 +4599,7 @@ gen_mpls_linktype(proto)
                 b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x40, 0xf0);
                 gen_and(b0, b1);
                 return b1;
+
        case Q_IPV6:
                 /* match the bottom-of-stack bit */
                 b0 = gen_mcmp(OR_NET, -2, BPF_B, 0x01, 0x01);
@@ -4418,7 +4607,7 @@ gen_mpls_linktype(proto)
                 b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x60, 0xf0);
                 gen_and(b0, b1);
                 return b1;
+
        default:
                 abort();
         }
@@ -5225,7 +5414,7 @@ gen_portrangeatom(off, v1, v2)
        b1 = gen_cmp_ge(OR_TRAN_IPV4, off, BPF_H, v1);
        b2 = gen_cmp_le(OR_TRAN_IPV4, off, BPF_H, v2);
 
-       gen_and(b1, b2); 
+       gen_and(b1, b2);
 
        return b2;
 }
@@ -5327,7 +5516,7 @@ gen_portrangeatom6(off, v1, v2)
        b1 = gen_cmp_ge(OR_TRAN_IPV6, off, BPF_H, v1);
        b2 = gen_cmp_le(OR_TRAN_IPV6, off, BPF_H, v2);
 
-       gen_and(b1, b2); 
+       gen_and(b1, b2);
 
        return b2;
 }
@@ -5777,7 +5966,7 @@ gen_check_802_11_data_frame()
        b0 = new_block(JMP(BPF_JSET));
        b0->s.k = 0x08;
        b0->stmts = s;
-       
+
        s = gen_load_a(OR_LINK, 0, BPF_B);
        b1 = new_block(JMP(BPF_JSET));
        b1->s.k = 0x04;
@@ -6253,7 +6442,7 @@ gen_scode(name, q)
                if (proto != Q_DEFAULT &&
                    proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP)
                        bpf_error("illegal qualifier of 'portrange'");
-               if (pcap_nametoportrange(name, &port1, &port2, &real_proto) == 0) 
+               if (pcap_nametoportrange(name, &port1, &port2, &real_proto) == 0)
                        bpf_error("unknown port in range '%s'", name);
                if (proto == Q_UDP) {
                        if (real_proto == IPPROTO_TCP)
@@ -6280,7 +6469,7 @@ gen_scode(name, q)
                                bpf_error("port in range '%s' is tcp", name);
                        else
                                /* override PROTO_UNDEF */
-                               real_proto = IPPROTO_SCTP;      
+                               real_proto = IPPROTO_SCTP;
                }
                if (port1 < 0)
                        bpf_error("illegal port number %d < 0", port1);
@@ -7857,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
  */
@@ -7864,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)
@@ -7908,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);
 }
 
@@ -7948,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
@@ -7972,22 +8211,22 @@ gen_mpls(label_num)
              * etc.
              */
             switch (linktype) {
-                
+
             case DLT_C_HDLC: /* fall through */
             case DLT_EN10MB:
             case DLT_NETANALYZER:
             case DLT_NETANALYZER_TRANSPARENT:
                     b0 = gen_linktype(ETHERTYPE_MPLS);
                     break;
-                
+
             case DLT_PPP:
                     b0 = gen_linktype(PPP_MPLS_UCAST);
                     break;
-                
+
                     /* FIXME add other DLT_s ...
                      * for Frame-Relay/and ATM this may get messy due to SNAP headers
                      * leave it for now */
-                
+
             default:
                     bpf_error("no MPLS support for data link type %d",
                           linktype);
@@ -8258,7 +8497,7 @@ gen_atmtype_abbrev(type)
        return b1;
 }
 
-/* 
+/*
  * Filtering for MTP2 messages based on li value
  * FISU, length is null
  * LSSU, length is 1 or 2
index ee0f9eea9fb337548ad17279584cd4d574c16b3d..e6b3a71ea0dbbd347fdb293efae50894da640a3a 100644 (file)
--- a/gencode.h
+++ b/gencode.h
@@ -308,6 +308,13 @@ struct block *gen_broadcast(int);
 struct block *gen_multicast(int);
 struct block *gen_inbound(int);
 
+struct block *gen_llc(void);
+struct block *gen_llc_i(void);
+struct block *gen_llc_s(void);
+struct block *gen_llc_u(void);
+struct block *gen_llc_s_subtype(bpf_u_int32);
+struct block *gen_llc_u_subtype(bpf_u_int32);
+
 struct block *gen_vlan(int);
 struct block *gen_mpls(int);
 
index 05785bbfa2b89ab6c96ea0749d40a969578e5c1c..b269d27173e9c59d6a6fb45545f98e63ab01fe91 100644 (file)
--- a/grammar.y
+++ b/grammar.y
@@ -54,6 +54,7 @@ struct rtentry;
 #include <net/pfvar.h>
 #include <net/if_pflog.h>
 #endif
+#include "llc.h"
 #include "ieee80211.h"
 #include <pcap/namedb.h>
 
@@ -128,6 +129,23 @@ static const struct tok ieee80211_data_subtypes[] = {
        { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
        { 0, NULL }
 };
+static const struct tok llc_s_subtypes[] = {
+       { LLC_RR, "rr" },
+       { LLC_RNR, "rnr" },
+       { LLC_REJ, "rej" },
+       { 0, NULL }
+};
+static const struct tok llc_u_subtypes[] = {
+       { LLC_UI, "ui" },
+       { LLC_UA, "ua" },
+       { LLC_DISC, "disc" },
+       { LLC_DM, "dm" },
+       { LLC_SABME, "sabme" },
+       { LLC_TEST, "test" },
+       { LLC_XID, "xid" },
+       { LLC_FRMR, "frmr" },
+       { 0, NULL }
+};
 struct type2tok {
        int type;
        const struct tok *tok;
@@ -257,7 +275,7 @@ pfaction_to_num(const char *action)
 %type  <a>     arth narth
 %type  <i>     byteop pname pnum relop irelop
 %type  <blk>   and or paren not null prog
-%type  <rblk>  other pfvar p80211
+%type  <rblk>  other pfvar p80211 pllc
 %type  <i>     atmtype atmmultitype
 %type  <blk>   atmfield
 %type  <blk>   atmfieldvalue atmvalue atmlistvalue
@@ -507,6 +525,7 @@ other:        pqual TK_BROADCAST    { $$ = gen_broadcast($1); }
        | PPPOES                { $$ = gen_pppoes(-1); }
        | pfvar                 { $$ = $1; }
        | pqual p80211          { $$ = $2; }
+       | pllc                  { $$ = $1; }
        ;
 
 pfvar:   PF_IFNAME ID          { $$ = gen_pf_ifname($2); }
@@ -576,6 +595,31 @@ type_subtype:      ID              { int i;
                                }
                ;
 
+pllc:  LLC                     { $$ = gen_llc(); }
+       | LLC ID                { if (pcap_strcasecmp($2, "i") == 0)
+                                       $$ = gen_llc_i();
+                                 else if (pcap_strcasecmp($2, "s") == 0)
+                                       $$ = gen_llc_s();
+                                 else if (pcap_strcasecmp($2, "u") == 0)
+                                       $$ = gen_llc_u();
+                                 else {
+                                       u_int subtype;
+
+                                       subtype = str2tok($2, llc_s_subtypes);
+                                       if (subtype != -1)
+                                               $$ = gen_llc_s_subtype(subtype);
+                                       else {
+                                               subtype = str2tok($2, llc_u_subtypes);
+                                               if (subtype == -1)
+                                                       bpf_error("unknown LLC type name \"%s\"", $2);
+                                               $$ = gen_llc_u_subtype(subtype);
+                                       }
+                                 }
+                               }
+                               /* sigh, "rnr" is already a keyword for PF */
+       | LLC PF_RNR            { $$ = gen_llc_s_subtype(LLC_RNR); }
+       ;
+
 dir:     NUM
        | ID                    { if (pcap_strcasecmp($1, "nods") == 0)
                                        $$ = IEEE80211_FC1_DIR_NODS;
@@ -614,8 +658,10 @@ narth:       pname '[' arth ']'            { $$ = gen_load($1, $3, 1); }
        | arth '-' arth                 { $$ = gen_arth(BPF_SUB, $1, $3); }
        | arth '*' arth                 { $$ = gen_arth(BPF_MUL, $1, $3); }
        | arth '/' arth                 { $$ = gen_arth(BPF_DIV, $1, $3); }
+       | arth '%' arth                 { $$ = gen_arth(BPF_MOD, $1, $3); }
        | arth '&' arth                 { $$ = gen_arth(BPF_AND, $1, $3); }
        | arth '|' arth                 { $$ = gen_arth(BPF_OR, $1, $3); }
+       | arth '^' arth                 { $$ = gen_arth(BPF_XOR, $1, $3); }
        | arth LSH arth                 { $$ = gen_arth(BPF_LSH, $1, $3); }
        | arth RSH arth                 { $$ = gen_arth(BPF_RSH, $1, $3); }
        | '-' arth %prec UMINUS         { $$ = gen_neg($2); }
@@ -632,7 +678,6 @@ pnum:         NUM
        | paren pnum ')'        { $$ = $2; }
        ;
 atmtype: LANE                  { $$ = A_LANE; }
-       | LLC                   { $$ = A_LLC; }
        | METAC                 { $$ = A_METAC; }
        | BCC                   { $$ = A_BCC; }
        | OAMF4EC               { $$ = A_OAMF4EC; }
diff --git a/inet.c b/inet.c
index c699658ef2d401b80abc40252e40147141cb439c..036b2db316d6b4084a5dc76d59a416e07db786f2 100644 (file)
--- a/inet.c
+++ b/inet.c
@@ -128,7 +128,7 @@ dup_sockaddr(struct sockaddr *sa, size_t sa_length)
 static u_int
 get_figure_of_merit(pcap_if_t *dev)
 {
-       const char *cp, *endcp;
+       const char *cp;
        u_int n;
 
        if (strcmp(dev->name, "any") == 0) {
@@ -138,16 +138,19 @@ get_figure_of_merit(pcap_if_t *dev)
                 * interfaces.
                 */
                n = 0x1FFFFFFF; /* 29 all-1 bits */
+       } else {
+               /*
+                * A number at the end of the device name string is
+                * assumed to be a unit number.
+                */
+               cp = dev->name + strlen(dev->name) - 1;
+               while (cp-1 >= dev->name && *(cp-1) >= '0' && *(cp-1) <= '9')
+                       cp--;
+               if (*cp >= '0' && *cp <= '9')
+                       n = atoi(cp);
+               else
+                       n = 0;
        }
-
-       endcp = dev->name + strlen(dev->name);
-       for (cp = dev->name; cp < endcp && !isdigit((unsigned char)*cp); ++cp)
-               continue;
-
-       if (isdigit((unsigned char)*cp))
-               n = atoi(cp);
-       else
-               n = 0;
        if (!(dev->flags & PCAP_IF_RUNNING))
                n |= 0x80000000;
        if (!(dev->flags & PCAP_IF_UP))
diff --git a/llc.h b/llc.h
index a02d1587de108e2e613dfe4c1d2345694743a433..b0cf881ca1dde908b06c50e460ebe9a712c463db 100644 (file)
--- a/llc.h
+++ b/llc.h
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+/*
+ * Definitions for information in the LLC header.
+ */
+
+#define        LLC_U_FMT       3
+#define        LLC_GSAP        1
+#define        LLC_IG          1 /* Individual / Group */
+#define LLC_S_FMT      1
+
+#define        LLC_U_POLL      0x10
+#define        LLC_IS_POLL     0x0100
+#define        LLC_XID_FI      0x81
+
+#define LLC_U_CMD_MASK 0xef
+#define        LLC_UI          0x03
+#define        LLC_UA          0x63
+#define        LLC_DISC        0x43
+#define        LLC_DM          0x0f
+#define        LLC_SABME       0x6f
+#define        LLC_TEST        0xe3
+#define        LLC_XID         0xaf
+#define        LLC_FRMR        0x87
+
+#define LLC_S_CMD_MASK 0x0f
+#define        LLC_RR          0x0001
+#define        LLC_RNR         0x0005
+#define        LLC_REJ         0x0009
+
+#define LLC_IS_NR(is)  (((is) >> 9) & 0x7f)
+#define LLC_I_NS(is)   (((is) >> 1) & 0x7f)
+
 /*
  * 802.2 LLC SAP values.
  */
 #ifndef LLCSAP_GLOBAL
 #define        LLCSAP_GLOBAL           0xff
 #endif
-#ifndef LLCSAP_8021B
+#ifndef LLCSAP_8021B_I
 #define        LLCSAP_8021B_I          0x02
 #endif
-#ifndef LLCSAP_8021B
+#ifndef LLCSAP_8021B_G
 #define        LLCSAP_8021B_G          0x03
 #endif
 #ifndef LLCSAP_IP
index d9bb4ee5d15cf016d2956e563b67b19e4c68c757..feaf2017213ae09ed3a01a574b3865951cb59dac 100644 (file)
@@ -606,6 +606,12 @@ fold_op(struct stmt *s, int v0, int v1)
                a /= b;
                break;
 
+       case BPF_MOD:
+               if (b == 0)
+                       bpf_error("modulus by zero");
+               a %= b;
+               break;
+
        case BPF_AND:
                a &= b;
                break;
@@ -614,6 +620,10 @@ fold_op(struct stmt *s, int v0, int v1)
                a |= b;
                break;
 
+       case BPF_XOR:
+               a ^= b;
+               break;
+
        case BPF_LSH:
                a <<= b;
                break;
@@ -974,8 +984,10 @@ opt_stmt(struct stmt *s, int val[], int alter)
        case BPF_ALU|BPF_SUB|BPF_K:
        case BPF_ALU|BPF_MUL|BPF_K:
        case BPF_ALU|BPF_DIV|BPF_K:
+       case BPF_ALU|BPF_MOD|BPF_K:
        case BPF_ALU|BPF_AND|BPF_K:
        case BPF_ALU|BPF_OR|BPF_K:
+       case BPF_ALU|BPF_XOR|BPF_K:
        case BPF_ALU|BPF_LSH|BPF_K:
        case BPF_ALU|BPF_RSH|BPF_K:
                op = BPF_OP(s->code);
@@ -986,7 +998,7 @@ opt_stmt(struct stmt *s, int val[], int alter)
                                 * fixup the generated math code */
                                if (op == BPF_ADD ||
                                    op == BPF_LSH || op == BPF_RSH ||
-                                   op == BPF_OR) {
+                                   op == BPF_OR || op == BPF_XOR) {
                                        s->code = NOP;
                                        break;
                                }
@@ -1009,8 +1021,10 @@ opt_stmt(struct stmt *s, int val[], int alter)
        case BPF_ALU|BPF_SUB|BPF_X:
        case BPF_ALU|BPF_MUL|BPF_X:
        case BPF_ALU|BPF_DIV|BPF_X:
+       case BPF_ALU|BPF_MOD|BPF_X:
        case BPF_ALU|BPF_AND|BPF_X:
        case BPF_ALU|BPF_OR|BPF_X:
+       case BPF_ALU|BPF_XOR|BPF_X:
        case BPF_ALU|BPF_LSH|BPF_X:
        case BPF_ALU|BPF_RSH|BPF_X:
                op = BPF_OP(s->code);
@@ -1037,12 +1051,12 @@ opt_stmt(struct stmt *s, int val[], int alter)
                 */
                if (alter && vmap[val[A_ATOM]].is_const
                    && vmap[val[A_ATOM]].const_val == 0) {
-                       if (op == BPF_ADD || op == BPF_OR) {
+                       if (op == BPF_ADD || op == BPF_OR || op == BPF_XOR) {
                                s->code = BPF_MISC|BPF_TXA;
                                vstore(s, &val[A_ATOM], val[X_ATOM], alter);
                                break;
                        }
-                       else if (op == BPF_MUL || op == BPF_DIV ||
+                       else if (op == BPF_MUL || op == BPF_DIV || op == BPF_MOD ||
                                 op == BPF_AND || op == BPF_LSH || op == BPF_RSH) {
                                s->code = BPF_LD|BPF_IMM;
                                s->k = 0;
index ad897b768fcb5f95343be40ca18184a9fae8766e..2dedd4ad02fe94953973037299f45371a3e68fba 100644 (file)
@@ -1476,6 +1476,9 @@ pcap_activate_bpf(pcap_t *p)
 {
        struct pcap_bpf *pb = p->priv;
        int status = 0;
+#ifdef HAVE_BSD_IEEE80211
+       int retv;
+#endif
        int fd;
 #ifdef LIFNAMSIZ
        char *zonesep;
@@ -1535,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;
        }
@@ -1679,6 +1703,7 @@ pcap_activate_bpf(pcap_t *p)
                if (ioctl(fd, BIOCGETZMAX, (caddr_t)&zbufmax) < 0) {
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGETZMAX: %s",
                            pcap_strerror(errno));
+                       status = PCAP_ERROR;
                        goto bad;
                }
 
@@ -1705,6 +1730,7 @@ pcap_activate_bpf(pcap_t *p)
                if (pb->zbuf1 == MAP_FAILED || pb->zbuf2 == MAP_FAILED) {
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "mmap: %s",
                            pcap_strerror(errno));
+                       status = PCAP_ERROR;
                        goto bad;
                }
                memset(&bz, 0, sizeof(bz)); /* bzero() deprecated, replaced with memset() */
@@ -1714,12 +1740,14 @@ pcap_activate_bpf(pcap_t *p)
                if (ioctl(fd, BIOCSETZBUF, (caddr_t)&bz) < 0) {
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETZBUF: %s",
                            pcap_strerror(errno));
+                       status = PCAP_ERROR;
                        goto bad;
                }
                (void)strncpy(ifrname, p->opt.source, ifnamsiz);
                if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
                            p->opt.source, pcap_strerror(errno));
+                       status = PCAP_ERROR;
                        goto bad;
                }
                v = pb->zbufsize - sizeof(struct bpf_zbuf_header);
@@ -1973,11 +2001,12 @@ pcap_activate_bpf(pcap_t *p)
                /*
                 * Try to put the interface into monitor mode.
                 */
-               status = monitor_mode(p, 1);
-               if (status != 0) {
+               retv = monitor_mode(p, 1);
+               if (retv != 0) {
                        /*
                         * We failed.
                         */
+                       status = retv;
                        goto bad;
                }
 
index 5fb760a302ba3b755475b842fb53b3b60c918edb..bb657c89b9aa3c09ca77bfe23dfe4cf52e8c8186 100644 (file)
  */
 #define LINKTYPE_PROFIBUS_DL           257
 
-#define LINKTYPE_MATCHING_MAX  257             /* highest value in the "matching" range */
+
+/*
+ * Apple's DLT_PKTAP headers.
+ *
+ * Sadly, the folks at Apple either had no clue that the DLT_USERn values
+ * are for internal use within an organization and partners only, and
+ * didn't know that the right way to get a link-layer header type is to
+ * ask tcpdump.org for one, or knew and didn't care, so they just
+ * used DLT_USER2, which causes problems for everything except for
+ * their version of tcpdump.
+ *
+ * So I'll just give them one; hopefully this will show up in a
+ * libpcap release in time for them to get this into 10.10 Big Sur
+ * or whatever Mavericks' successor is called.  LINKTYPE_PKTAP
+ * will be 258 *even on OS X*; that is *intentional*, so that
+ * PKTAP files look the same on *all* OSes (different OSes can have
+ * different numerical values for a given DLT_, but *MUST NOT* have
+ * different values for what goes in a file, as files can be moved
+ * between OSes!).
+ */
+#define LINKTYPE_PKTAP         258
+
+/*
+ * Ethernet packets preceded by a header giving the last 6 octets
+ * of the preamble specified by 802.3-2012 Clause 65, section
+ * 65.1.3.2 "Transmit".
+ */
+#define LINKTYPE_EPON          259
+
+/*
+ * IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format"
+ * in the PICMG HPM.2 specification.
+ */
+#define LINKTYPE_IPMI_HPM_2    260
+
+/*
+ * 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;
@@ -1032,13 +1073,20 @@ dlt_to_linktype(int dlt)
        int i;
 
        /*
-        * Map DLT_PFSYNC, whatever it might be, to LINKTYPE_PFSYNC.
+        * DLTs that, on some platforms, have values in the matching range
+        * but that *don't* have the same value as the corresponding
+        * LINKTYPE because, for some reason, not all OSes have the
+        * same value for that DLT (note that the DLT's value might be
+        * outside the matching range on some of those OSes).
         */
        if (dlt == DLT_PFSYNC)
                return (LINKTYPE_PFSYNC);
+       if (dlt == DLT_PKTAP)
+               return (LINKTYPE_PKTAP);
 
        /*
-        * Map the values in the matching range.
+        * For all other values in the matching range, the DLT
+        * value is the same as the LINKTYPE value.
         */
        if (dlt >= DLT_MATCHING_MIN && dlt <= DLT_MATCHING_MAX)
                return (dlt);
@@ -1052,9 +1100,9 @@ dlt_to_linktype(int dlt)
        }
 
        /*
-        * If we don't have a mapping for this DLT_ code, return an
+        * If we don't have a mapping for this DLT, return an
         * error; that means that this is a value with no corresponding
-        * LINKTYPE_ code, and we need to assign one.
+        * LINKTYPE, and we need to assign one.
         */
        return (-1);
 }
@@ -1065,16 +1113,19 @@ linktype_to_dlt(int linktype)
        int i;
 
        /*
-        * Map LINKTYPE_PFSYNC to DLT_PFSYNC, whatever it might be.
-        * LINKTYPE_PFSYNC is in the matching range, to make sure
-        * it's as safe from reuse as we can arrange, so we do
-        * this test first.
+        * LINKTYPEs in the matching range that *don't*
+        * have the same value as the corresponding DLTs
+        * because, for some reason, not all OSes have the
+        * same value for that DLT.
         */
        if (linktype == LINKTYPE_PFSYNC)
                return (DLT_PFSYNC);
+       if (linktype == LINKTYPE_PKTAP)
+               return (DLT_PKTAP);
 
        /*
-        * Map the values in the matching range.
+        * For all other values in the matching range, the LINKTYPE
+        * value is the same as the DLT value.
         */
        if (linktype >= LINKTYPE_MATCHING_MIN &&
            linktype <= LINKTYPE_MATCHING_MAX)
@@ -1089,9 +1140,9 @@ linktype_to_dlt(int linktype)
        }
 
        /*
-        * If we don't have an entry for this link type, return
-        * the link type value; it may be a DLT_ value from an
-        * older version of libpcap.
+        * If we don't have an entry for this LINKTYPE, return
+        * the link type value; it may be a DLT from an older
+        * version of libpcap.
         */
        return linktype;
 }
index 82373ee7bb955f13d3095e4cf56a5bf92839221f..2a2272b38f1d1ab9dffd2654f11b63991a6983f0 100644 (file)
@@ -18,7 +18,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP-CONFIG 1 "26 March 2009"
+.TH PCAP-CONFIG 1 "22 May 2009"
 .SH NAME
 pcap-config \- write libpcap compiler and linker flags to standard output
 .SH SYNOPSIS
index 22053bfb6915d9212b1f270aaebe4f42253ebfea..459860066eb660f9ed482001c61dc979489c6ef0 100644 (file)
@@ -336,6 +336,8 @@ pcap_activate_dlpi(pcap_t *p)
 #ifdef DL_HP_RAWDLS
        struct pcap_dlpi *pd = p->priv;
 #endif
+       int status = 0;
+       int retv;
        register char *cp;
        int ppa;
 #ifdef HAVE_SOLARIS
@@ -354,7 +356,6 @@ pcap_activate_dlpi(pcap_t *p)
 #ifndef HAVE_DEV_DLPI
        char dname2[100];
 #endif
-       int status = PCAP_ERROR;
 
 #ifdef HAVE_DEV_DLPI
        /*
@@ -392,6 +393,8 @@ pcap_activate_dlpi(pcap_t *p)
        if ((p->fd = open(cp, O_RDWR)) < 0) {
                if (errno == EPERM || errno == EACCES)
                        status = PCAP_ERROR_PERM_DENIED;
+               else
+                       status = PCAP_ERROR;
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: %s", cp, pcap_strerror(errno));
                goto bad;
@@ -456,6 +459,8 @@ pcap_activate_dlpi(pcap_t *p)
                if (errno != ENOENT) {
                        if (errno == EPERM || errno == EACCES)
                                status = PCAP_ERROR_PERM_DENIED;
+                       else
+                               status = PCAP_ERROR;
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
                            pcap_strerror(errno));
                        goto bad;
@@ -492,6 +497,8 @@ pcap_activate_dlpi(pcap_t *p)
                        } else {
                                if (errno == EPERM || errno == EACCES)
                                        status = PCAP_ERROR_PERM_DENIED;
+                               else
+                                       status = PCAP_ERROR;
                                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
                                    dname2, pcap_strerror(errno));
                        }
@@ -506,21 +513,28 @@ pcap_activate_dlpi(pcap_t *p)
        ** Attach if "style 2" provider
        */
        if (dlinforeq(p->fd, p->errbuf) < 0 ||
-           dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
+           dlinfoack(p->fd, (char *)buf, p->errbuf) < 0) {
+               status = PCAP_ERROR;
                goto bad;
+       }
        infop = &(MAKE_DL_PRIMITIVES(buf))->info_ack;
 #ifdef HAVE_SOLARIS
        if (infop->dl_mac_type == DL_IPATM)
                isatm = 1;
 #endif
        if (infop->dl_provider_style == DL_STYLE2) {
-               status = dl_doattach(p->fd, ppa, p->errbuf);
-               if (status < 0)
+               retv = dl_doattach(p->fd, ppa, p->errbuf);
+               if (retv < 0) {
+                       status = retv;
                        goto bad;
+               }
 #ifdef DL_HP_RAWDLS
                if (pd->send_fd >= 0) {
-                       if (dl_doattach(pd->send_fd, ppa, p->errbuf) < 0)
+                       retv = dl_doattach(pd->send_fd, ppa, p->errbuf);
+                       if (retv < 0) {
+                               status = retv;
                                goto bad;
+                       }
                }
 #endif
        }
@@ -567,22 +581,28 @@ pcap_activate_dlpi(pcap_t *p)
        */
        if ((dlbindreq(p->fd, 1537, p->errbuf) < 0 &&
             dlbindreq(p->fd, 2, p->errbuf) < 0) ||
-            dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
+            dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0) {
+               status = PCAP_ERROR;
                goto bad;
+       }
 #elif defined(DL_HP_RAWDLS)
        /*
        ** HP-UX 10.0x and 10.1x.
        */
-       if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
+       if (dl_dohpuxbind(p->fd, p->errbuf) < 0) {
+               status = PCAP_ERROR;
                goto bad;
+       }
        if (pd->send_fd >= 0) {
                /*
                ** XXX - if this fails, just close send_fd and
                ** set it to -1, so that you can't send but can
                ** still receive?
                */
-               if (dl_dohpuxbind(pd->send_fd, p->errbuf) < 0)
+               if (dl_dohpuxbind(pd->send_fd, p->errbuf) < 0) {
+                       status = PCAP_ERROR;
                        goto bad;
+               }
        }
 #else /* neither AIX nor HP-UX */
        /*
@@ -590,8 +610,10 @@ pcap_activate_dlpi(pcap_t *p)
        ** OS using DLPI.
        **/
        if (dlbindreq(p->fd, 0, p->errbuf) < 0 ||
-           dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
+           dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0) {
+               status = PCAP_ERROR;
                goto bad;
+       }
 #endif /* AIX vs. HP-UX vs. other */
 #endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */
 
@@ -604,6 +626,7 @@ pcap_activate_dlpi(pcap_t *p)
                ** help, and may break things.
                */
                if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
+                       status = PCAP_ERROR;
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                            "A_PROMISCON_REQ: %s", pcap_strerror(errno));
                        goto bad;
@@ -614,10 +637,12 @@ pcap_activate_dlpi(pcap_t *p)
                /*
                ** Enable promiscuous (not necessary on send FD)
                */
-               status = dlpromiscon(p, DL_PROMISC_PHYS);
-               if (status < 0) {
-                       if (status == PCAP_ERROR_PERM_DENIED)
+               retv = dlpromiscon(p, DL_PROMISC_PHYS);
+               if (retv < 0) {
+                       if (retv == PCAP_ERROR_PERM_DENIED)
                                status = PCAP_ERROR_PROMISC_PERM_DENIED;
+                       else
+                               status = retv;
                        goto bad;
                }
 
@@ -627,8 +652,8 @@ pcap_activate_dlpi(pcap_t *p)
                ** HP-UX or SINIX) (Not necessary on send FD)
                */
 #if !defined(__hpux) && !defined(sinix)
-               status = dlpromiscon(p, DL_PROMISC_MULTI);
-               if (status < 0)
+               retv = dlpromiscon(p, DL_PROMISC_MULTI);
+               if (retv < 0)
                        status = PCAP_WARNING;
 #endif
        }
@@ -648,16 +673,23 @@ pcap_activate_dlpi(pcap_t *p)
        /* Everything else (except for SINIX) - always do this */
        {
 #endif
-               status = dlpromiscon(p, DL_PROMISC_SAP);
-               if (status < 0) {
-                       /*
-                        * Not fatal, since the DL_PROMISC_PHYS mode worked.
-                        * Report it as a warning, however.
-                        */
-                       if (p->opt.promisc)
+               retv = dlpromiscon(p, DL_PROMISC_SAP);
+               if (retv < 0) {
+                       if (p->opt.promisc) {
+                               /*
+                                * Not fatal, since the DL_PROMISC_PHYS mode
+                                * worked.
+                                *
+                                * Report it as a warning, however.
+                                */
                                status = PCAP_WARNING;
-                       else
+                       } else {
+                               /*
+                                * Fatal.
+                                */
+                               status = retv;
                                goto bad;
+                       }
                }
        }
 #endif /* sinix */
@@ -667,8 +699,10 @@ pcap_activate_dlpi(pcap_t *p)
        ** promiscuous options.
        */
 #if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER)
-       if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
+       if (dl_dohpuxbind(p->fd, p->errbuf) < 0) {
+               status = PCAP_ERROR;
                goto bad;
+       }
        /*
        ** We don't set promiscuous mode on the send FD, but we'll defer
        ** binding it anyway, just to keep the HP-UX 9/10.20 or later
@@ -680,8 +714,10 @@ pcap_activate_dlpi(pcap_t *p)
                ** set it to -1, so that you can't send but can
                ** still receive?
                */
-               if (dl_dohpuxbind(pd->send_fd, p->errbuf) < 0)
+               if (dl_dohpuxbind(pd->send_fd, p->errbuf) < 0) {
+                       status = PCAP_ERROR;
                        goto bad;
+               }
        }
 #endif
 
@@ -691,12 +727,16 @@ pcap_activate_dlpi(pcap_t *p)
        ** when sending packets.
        */
        if (dlinforeq(p->fd, p->errbuf) < 0 ||
-           dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
+           dlinfoack(p->fd, (char *)buf, p->errbuf) < 0) {
+               status = PCAP_ERROR;
                goto bad;
+       }
 
        infop = &(MAKE_DL_PRIMITIVES(buf))->info_ack;
-       if (pcap_process_mactype(p, infop->dl_mac_type) != 0)
+       if (pcap_process_mactype(p, infop->dl_mac_type) != 0) {
+               status = PCAP_ERROR;
                goto bad;
+       }
 
 #ifdef DLIOCRAW
        /*
@@ -704,6 +744,7 @@ pcap_activate_dlpi(pcap_t *p)
        ** header.
        */
        if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
+               status = PCAP_ERROR;
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
                    pcap_strerror(errno));
                goto bad;
@@ -734,28 +775,31 @@ pcap_activate_dlpi(pcap_t *p)
 #endif
 
        /* Push and configure bufmod. */
-       if (pcap_conf_bufmod(p, ss) != 0)
+       if (pcap_conf_bufmod(p, ss) != 0) {
+               status = PCAP_ERROR;
                goto bad;
+       }
 #endif
 
        /*
        ** As the last operation flush the read side.
        */
        if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
+               status = PCAP_ERROR;
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
                    pcap_strerror(errno));
                goto bad;
        }
 
        /* Allocate data buffer. */
-       if (pcap_alloc_databuf(p) != 0)
+       if (pcap_alloc_databuf(p) != 0) {
+               status = PCAP_ERROR;
                goto bad;
-
-       /* Success - but perhaps with a warning */
-       if (status < 0)
-               status = 0;
+       }
 
        /*
+        * Success.
+        *
         * "p->fd" is an FD for a STREAMS device, so "select()" and
         * "poll()" should work on it.
         */
index 41046c1938f7cd130e8d92c53901961debe0b71f..f65a6a95f75fedb7581870454b65d3945163d349 100644 (file)
@@ -18,7 +18,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP-FILTER @MAN_MISC_INFO@ "6 January 2008"
+.TH PCAP-FILTER @MAN_MISC_INFO@ "17 May 2013"
 .SH NAME
 pcap-filter \- packet filter syntax
 .br
@@ -330,8 +330,9 @@ The packet may contain, for example,
 authentication header, routing header, or hop-by-hop option header,
 between IPv6 header and TCP header.
 The BPF code emitted by this primitive is complex and
-cannot be optimized by the BPF optimizer code, so this can be somewhat
-slow.
+cannot be optimized by the BPF optimizer code, and is not supported by
+filter engines in the kernel, so this can be somewhat slow, and may
+cause more packets to be dropped.
 .IP "\fBip protochain \fIprotocol\fR"
 Equivalent to \fBip6 protochain \fIprotocol\fR, but this is for IPv4.
 .IP "\fBprotochain \fIprotocol\fR"
@@ -451,6 +452,67 @@ True if the DECNET destination address is
 .IP "\fBdecnet host \fIhost\fR"
 True if either the DECNET source or destination address is
 .IR host .
+.IP \fBllc\fP
+True if the packet has an 802.2 LLC header.  This includes:
+.IP
+Ethernet packets with a length field rather than a type field that
+aren't raw NetWare-over-802.3 packets;
+.IP
+IEEE 802.11 data packets;
+.IP
+Token Ring packets (no check is done for LLC frames);
+.IP
+FDDI packets (no check is done for LLC frames);
+.IP
+LLC-encapsulated ATM packets, for SunATM on Solaris.
+.IP
+
+.IP "\fBllc\fP \Fitype\fR"
+True if the packet has an 802.2 LLC header and has the specified
+.IR type .
+.I type
+can be one of:
+.RS
+.TP
+\fBi\fR
+Information (I) PDUs
+.TP
+\fBs\fR
+Supervisory (S) PDUs
+.TP
+\fBu\fR
+Unnumbered (U) PDUs
+.TP
+\fBrr\fR
+Receiver Ready (RR) S PDUs
+.TP
+\fBrnr\fR
+Receiver Not Ready (RNR) S PDUs
+.TP
+\fBrej\fR
+Reject (REJ) S PDUs
+.TP
+\fBui\fR
+Unnumbered Information (UI) U PDUs
+.TP
+\fBua\fR
+Unnumbered Acknowledgment (UA) U PDUs
+.TP
+\fBdisc\fR
+Disconnect (DISC) U PDUs
+.TP
+\fBsabme\fR
+Set Asynchronous Balanced Mode Extended (SABME) U PDUs
+.TP
+\fBtest\fR
+Test (TEST) U PDUs
+.TP
+\fBxid\fR
+Exchange Identification (XID) U PDUs
+.TP
+\fBfrmr\fR
+Frame Reject (FRMR) U PDUs
+.RE
 .IP "\fBifname \fIinterface\fR"
 True if the packet was logged as coming from the specified interface (applies
 only to packets logged by OpenBSD's or FreeBSD's
@@ -702,9 +764,6 @@ on the assumption that the packet is either a LANE emulated Ethernet
 packet or a LANE LE Control packet.  If \fBlane\fR isn't specified, the
 tests are done under the assumption that the packet is an
 LLC-encapsulated packet.
-.IP \fBllc\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-an LLC-encapsulated packet.
 .IP \fBoamf4s\fP
 True if the packet is an ATM packet, for SunATM on Solaris, and is
 a segment OAM F4 flow cell (VPI=0 & VCI=3).
@@ -741,11 +800,17 @@ Release, or Release Done message.
 True if the relation holds, where \fIrelop\fR is one of >, <, >=, <=, =,
 !=, and \fIexpr\fR is an arithmetic expression composed of integer
 constants (expressed in standard C syntax), the normal binary operators
-[+, -, *, /, &, |, <<, >>], a length operator, and special packet data
+[+, -, *, /, %, &, |, ^, <<, >>], a length operator, and special packet data
 accessors.  Note that all comparisons are unsigned, so that, for example,
 0x80000000 and 0xffffffff are > 0.
-To access
-data inside the packet, use the following syntax:
+.IP
+The % and ^ operators are currently only supported for filtering in the
+kernel on Linux with 3.7 and later kernels; on all other systems, if
+those operators are used, filtering will be done in user mode, which
+will increase the overhead of capturing packets and may cause more
+packets to be dropped.
+.IP
+To access data inside the packet, use the following syntax:
 .in +.5i
 .nf
 \fIproto\fB [ \fIexpr\fB : \fIsize\fB ]\fR
index 6d6febe96a3f539a4aeff399659dbf58bd1cc301..2f71e1152676aa8c949b3aff06dea27a2ad6697e 100644 (file)
@@ -82,6 +82,29 @@ extern CRITICAL_SECTION g_PcapCompileCriticalSection;
 
 #endif /* _MSC_VER */
 
+/*
+ * Maximum snapshot length.
+ *
+ * Somewhat arbitrary, but chosen to be:
+ *
+ *    1) big enough for maximum-size Linux loopback packets (65549)
+ *       and some USB packets captured with USBPcap:
+ *
+ *           http://desowin.org/usbpcap/
+ *
+ *       (> 131072, < 262144)
+ *
+ * and
+ *
+ *    2) small enough not to cause attempts to allocate huge amounts of
+ *       memory; some applications might use the snapshot length in a
+ *       savefile header to control the size of the buffer they allocate,
+ *       so a size of, say, 2^31-1 might not work well.
+ *
+ * We don't enforce this in pcap_set_snaplen(), but we use it internally.
+ */
+#define MAXIMUM_SNAPLEN                262144
+
 struct pcap_opt {
        char    *source;
        int     timeout;        /* timeout for buffering */
@@ -179,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.
         */
@@ -225,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 93d90210c069fd2763dc3b5218e5a9efa5f3be2d..333e532b765a99fbe2413b6307763c8977cd1c51 100644 (file)
@@ -96,10 +96,10 @@ static int
 pcap_activate_libdlpi(pcap_t *p)
 {
        struct pcap_dlpi *pd = p->priv;
+       int status = 0;
        int retv;
        dlpi_handle_t dh;
        dlpi_info_t dlinfo;
-       int err = PCAP_ERROR;
 
        /*
         * Enable Solaris raw and passive DLPI extensions;
@@ -109,13 +109,15 @@ pcap_activate_libdlpi(pcap_t *p)
        retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE);
        if (retv != DLPI_SUCCESS) {
                if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
-                       err = PCAP_ERROR_NO_SUCH_DEVICE;
+                       status = PCAP_ERROR_NO_SUCH_DEVICE;
                else if (retv == DL_SYSERR &&
                    (errno == EPERM || errno == EACCES))
-                       err = PCAP_ERROR_PERM_DENIED;
+                       status = PCAP_ERROR_PERM_DENIED;
+               else
+                       status = PCAP_ERROR;
                pcap_libdlpi_err(p->opt.source, "dlpi_open", retv,
                    p->errbuf);
-               return (err);
+               return (status);
        }
        pd->dlpi_hd = dh;
 
@@ -124,20 +126,21 @@ pcap_activate_libdlpi(pcap_t *p)
                 * This device exists, but we don't support monitor mode
                 * any platforms that support DLPI.
                 */
-               err = PCAP_ERROR_RFMON_NOTSUP;
+               status = PCAP_ERROR_RFMON_NOTSUP;
                goto bad;
        }
 
        /* Bind with DLPI_ANY_SAP. */
        if ((retv = dlpi_bind(pd->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
+               status = PCAP_ERROR;
                pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
                goto bad;
        }
 
        /* Enable promiscuous mode. */
        if (p->opt.promisc) {
-               err = dlpromiscon(p, DL_PROMISC_PHYS);
-               if (err < 0) {
+               retv = dlpromiscon(p, DL_PROMISC_PHYS);
+               if (retv < 0) {
                        /*
                         * "You don't have permission to capture on
                         * this device" and "you don't have permission
@@ -151,57 +154,71 @@ pcap_activate_libdlpi(pcap_t *p)
                         * XXX - you might have to capture in
                         * promiscuous mode to see outgoing packets.
                         */
-                       if (err == PCAP_ERROR_PERM_DENIED)
-                               err = PCAP_ERROR_PROMISC_PERM_DENIED;
+                       if (retv == PCAP_ERROR_PERM_DENIED)
+                               status = PCAP_ERROR_PROMISC_PERM_DENIED;
+                       else
+                               status = retv;
                        goto bad;
                }
        } else {
                /* Try to enable multicast. */
-               err = dlpromiscon(p, DL_PROMISC_MULTI);
-               if (err < 0)
+               retv = dlpromiscon(p, DL_PROMISC_MULTI);
+               if (retv < 0) {
+                       status = retv;
                        goto bad;
+               }
        }
 
        /* Try to enable SAP promiscuity. */
-       err = dlpromiscon(p, DL_PROMISC_SAP);
-       if (err < 0) {
+       retv = dlpromiscon(p, DL_PROMISC_SAP);
+       if (retv < 0) {
                /*
                 * Not fatal, since the DL_PROMISC_PHYS mode worked.
                 * Report it as a warning, however.
                 */
                if (p->opt.promisc)
-                       err = PCAP_WARNING;
-               else
+                       status = PCAP_WARNING;
+               else {
+                       status = retv;
                        goto bad;
+               }
        }
 
        /* Determine link type.  */
        if ((retv = dlpi_info(pd->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
+               status = PCAP_ERROR;
                pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf);
                goto bad;
        }
 
-       if (pcap_process_mactype(p, dlinfo.di_mactype) != 0)
+       if (pcap_process_mactype(p, dlinfo.di_mactype) != 0) {
+               status = PCAP_ERROR;
                goto bad;
+       }
 
        p->fd = dlpi_fd(pd->dlpi_hd);
 
        /* Push and configure bufmod. */
-       if (pcap_conf_bufmod(p, p->snapshot) != 0)
+       if (pcap_conf_bufmod(p, p->snapshot) != 0) {
+               status = PCAP_ERROR;
                goto bad;
+       }
 
        /*
         * Flush the read side.
         */
        if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
+               status = PCAP_ERROR;
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
                    pcap_strerror(errno));
                goto bad;
        }
 
        /* Allocate data buffer. */
-       if (pcap_alloc_databuf(p) != 0)
+       if (pcap_alloc_databuf(p) != 0) {
+               status = PCAP_ERROR;
                goto bad;
+       }
 
        /*
         * "p->fd" is a FD for a STREAMS device, so "select()" and
@@ -219,10 +236,10 @@ pcap_activate_libdlpi(pcap_t *p)
        p->stats_op = pcap_stats_dlpi;
        p->cleanup_op = pcap_cleanup_libdlpi;
 
-       return (0);
+       return (status);
 bad:
        pcap_cleanup_libdlpi(p);
-       return (err);
+       return (status);
 }
 
 #define STRINGIFY(n)   #n
index 05341466c8d94bdb9d5777b63d29cf9e9f4db944..e42c5b367f3bdf1b78a40dd7c5655e1829bec5cf 100644 (file)
@@ -18,7 +18,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP-LINKTYPE @MAN_MISC_INFO@ "23 October 2008"
+.TH PCAP-LINKTYPE @MAN_MISC_INFO@ "12 March 2011"
 .SH NAME
 pcap-linktype \- link-layer header types supported by libpcap
 .SH DESCRIPTION
index a15a8b1fa0174e9e214ff2b4ac2deaf6fe755316..8561c97ed37daf74e5c838c32c3c207b119b8c4e 100644 (file)
@@ -316,7 +316,7 @@ struct pcap_linux {
 /*
  * Prototypes for internal functions and methods.
  */
-static void map_arphrd_to_dlt(pcap_t *, int, int);
+static void map_arphrd_to_dlt(pcap_t *, int, const char *, int);
 #ifdef HAVE_PF_PACKET_SOCKETS
 static short int map_packet_type_to_sll_type(short int);
 #endif
@@ -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,26 +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) {
+       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)
@@ -443,6 +435,8 @@ pcap_create_interface(const char *device, char *ebuf)
        handle->tstamp_precision_count = 2;
        handle->tstamp_precision_list = malloc(2 * sizeof(u_int));
        if (handle->tstamp_precision_list == NULL) {
+               snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+                   pcap_strerror(errno));
                if (handle->tstamp_type_list != NULL)
                        free(handle->tstamp_type_list);
                free(handle);
@@ -866,7 +860,7 @@ added:
         * Now configure the monitor interface up.
         */
        memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, handlep->mondevice, sizeof(ifr.ifr_name));
+       strlcpy(ifr.ifr_name, handlep->mondevice, sizeof(ifr.ifr_name));
        if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: Can't get flags for %s: %s", device,
@@ -968,9 +962,8 @@ pcap_can_set_rfmon_linux(pcap_t *handle)
        /*
         * Attempt to get the current mode.
         */
-       strncpy(ireq.ifr_ifrn.ifrn_name, handle->opt.source,
+       strlcpy(ireq.ifr_ifrn.ifrn_name, handle->opt.source,
            sizeof ireq.ifr_ifrn.ifrn_name);
-       ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
        if (ioctl(sock_fd, SIOCGIWMODE, &ireq) != -1) {
                /*
                 * Well, we got the mode; assume we can set it.
@@ -1092,7 +1085,7 @@ static void       pcap_cleanup_linux( pcap_t *handle )
                         * in 2.0[.x] kernels.
                         */
                        memset(&ifr, 0, sizeof(ifr));
-                       strncpy(ifr.ifr_name, handlep->device,
+                       strlcpy(ifr.ifr_name, handlep->device,
                            sizeof(ifr.ifr_name));
                        if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) {
                                fprintf(stderr,
@@ -1156,7 +1149,7 @@ static void       pcap_cleanup_linux( pcap_t *handle )
                         */
                        oldflags = 0;
                        memset(&ifr, 0, sizeof(ifr));
-                       strncpy(ifr.ifr_name, handlep->device,
+                       strlcpy(ifr.ifr_name, handlep->device,
                            sizeof(ifr.ifr_name));
                        if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) != -1) {
                                if (ifr.ifr_flags & IFF_UP) {
@@ -1170,10 +1163,8 @@ static void      pcap_cleanup_linux( pcap_t *handle )
                        /*
                         * Now restore the mode.
                         */
-                       strncpy(ireq.ifr_ifrn.ifrn_name, handlep->device,
+                       strlcpy(ireq.ifr_ifrn.ifrn_name, handlep->device,
                            sizeof ireq.ifr_ifrn.ifrn_name);
-                       ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1]
-                           = 0;
                        ireq.u.mode = handlep->oldmode;
                        if (ioctl(handle->fd, SIOCSIWMODE, &ireq) == -1) {
                                /*
@@ -1232,10 +1223,28 @@ pcap_activate_linux(pcap_t *handle)
 {
        struct pcap_linux *handlep = handle->priv;
        const char      *device;
+       struct ifreq    ifr;
        int             status = 0;
+       int             ret;
 
        device = handle->opt.source;
 
+       /*
+        * Make sure the name we were handed will fit into the ioctls we
+        * might perform on the device; if not, return a "No such device"
+        * indication, as the Linux kernel shouldn't support creating
+        * a device whose name won't fit into those ioctls.
+        *
+        * "Will fit" means "will fit, complete with a null terminator",
+        * so if the length, which does *not* include the null terminator,
+        * is greater than *or equal to* the size of the field into which
+        * we'll be copying it, that won't fit.
+        */
+       if (strlen(device) >= sizeof(ifr.ifr_name)) {
+               status = PCAP_ERROR_NO_SUCH_DEVICE;
+               goto fail;
+       }
+
        handle->inject_op = pcap_inject_linux;
        handle->setfilter_op = pcap_setfilter_linux;
        handle->setdirection_op = pcap_setdirection_linux;
@@ -1288,16 +1297,17 @@ pcap_activate_linux(pcap_t *handle)
         * to be compatible with older kernels for a while so we are
         * trying both methods with the newer method preferred.
         */
-       status = activate_new(handle);
-       if (status < 0) {
+       ret = activate_new(handle);
+       if (ret < 0) {
                /*
                 * Fatal error with the new way; just fail.
-                * status has the error return; if it's PCAP_ERROR,
+                * ret has the error return; if it's PCAP_ERROR,
                 * handle->errbuf has been set appropriately.
                 */
+               status = ret;
                goto fail;
        }
-       if (status == 1) {
+       if (ret == 1) {
                /*
                 * Success.
                 * Try to use memory-mapped access.
@@ -1324,21 +1334,23 @@ pcap_activate_linux(pcap_t *handle)
                        /*
                         * We failed to set up to use it, or the kernel
                         * supports it, but we failed to enable it.
-                        * status has been set to the error status to
+                        * ret has been set to the error status to
                         * return and, if it's PCAP_ERROR, handle->errbuf
                         * contains the error message.
                         */
+                       status = ret;
                        goto fail;
                }
        }
-       else if (status == 0) {
+       else if (ret == 0) {
                /* Non-fatal error; try old way */
-               if ((status = activate_old(handle)) != 1) {
+               if ((ret = activate_old(handle)) != 1) {
                        /*
                         * Both methods to open the packet socket failed.
                         * Tidy up and report our failure (handle->errbuf
                         * is expected to be set by the functions above).
                         */
+                       status = ret;
                        goto fail;
                }
        }
@@ -1346,7 +1358,6 @@ pcap_activate_linux(pcap_t *handle)
        /*
         * We set up the socket, but not with memory-mapped access.
         */
-       status = 0;
        if (handle->opt.buffer_size != 0) {
                /*
                 * Set the socket buffer size to the specified value.
@@ -1473,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
@@ -1656,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;
                }
        }
@@ -1689,8 +1706,8 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
         *
         * We currently handle this by making a copy of the filter
         * program, fixing all "ret" instructions with non-zero
-        * operands to have an operand of 65535 so that the filter
-        * doesn't truncate the packet, and supplying that modified
+        * operands to have an operand of MAXIMUM_SNAPLEN so that the
+        * filter doesn't truncate the packet, and supplying that modified
         * filter to the kernel.
         */
 
@@ -1700,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;
                }
@@ -2024,7 +2040,7 @@ add_linux_if(pcap_if_t **devlistp, const char *ifname, int fd, char *errbuf)
        /*
         * Get the flags for this interface.
         */
-       strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name));
+       strlcpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name));
        if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
                if (errno == ENXIO || errno == ENODEV)
                        return (0);     /* device doesn't actually exist - ignore it */
@@ -2298,7 +2314,8 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
        /*
         * Add the "any" device.
         */
-       if (pcap_add_if(alldevsp, "any", 0, any_descr, errbuf) < 0)
+       if (pcap_add_if(alldevsp, "any", IFF_UP|IFF_RUNNING,
+           any_descr, errbuf) < 0)
                return (-1);
 
        return (0);
@@ -2321,7 +2338,7 @@ pcap_setfilter_linux_common(pcap_t *handle, struct bpf_program *filter,
        if (!handle)
                return -1;
        if (!filter) {
-               strncpy(handle->errbuf, "setfilter: No filter specified",
+               strlcpy(handle->errbuf, "setfilter: No filter specified",
                        PCAP_ERRBUF_SIZE);
                return -1;
        }
@@ -2364,12 +2381,13 @@ pcap_setfilter_linux_common(pcap_t *handle, struct bpf_program *filter,
                 * of different size. Pointed out by Sebastian
                 *
                 * Oh, and we also need to fix it up so that all "ret"
-                * instructions with non-zero operands have 65535 as the
-                * operand if we're not capturing in memory-mapped modee,
-                * and so that, if we're in cooked mode, all memory-reference
-                * instructions use special magic offsets in references to
-                * the link-layer header and assume that the link-layer
-                * payload begins at 0; "fix_program()" will do that.
+                * instructions with non-zero operands have MAXIMUM_SNAPLEN
+                * as the operand if we're not capturing in memory-mapped
+                * mode, and so that, if we're in cooked mode, all memory-
+                * reference instructions use special magic offsets in
+                * references to the link-layer header and assume that the
+                * link-layer payload begins at 0; "fix_program()" will do
+                * that.
                 */
                switch (fix_program(handle, &fcode, is_mmapped)) {
 
@@ -2455,8 +2473,14 @@ pcap_setfilter_linux_common(pcap_t *handle, struct bpf_program *filter,
         * calling "pcap_setfilter()".  Otherwise, the kernel filter may
         * filter out packets that would pass the new userland filter.
         */
-       if (handlep->filter_in_userland)
-               reset_kernel_filter(handle);
+       if (handlep->filter_in_userland) {
+               if (reset_kernel_filter(handle) == -1) {
+                       snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+                           "can't remove kernel filter: %s",
+                           pcap_strerror(errno));
+                       err = -2;       /* fatal error */
+               }
+       }
 
        /*
         * Free up the copy of the filter that was made by "fix_program()".
@@ -2556,11 +2580,31 @@ map_packet_type_to_sll_type(short int sll_pkttype)
  *
  *  Sets the link type to -1 if unable to map the type.
  */
-static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok)
+static void map_arphrd_to_dlt(pcap_t *handle, int arptype, const char *device,
+                             int cooked_ok)
 {
+       static const char cdma_rmnet[] = "cdma_rmnet";
+
        switch (arptype) {
 
        case ARPHRD_ETHER:
+               /*
+                * For various annoying reasons having to do with DHCP
+                * software, some versions of Android give the mobile-
+                * phone-network interface an ARPHRD_ value of
+                * ARPHRD_ETHER, even though the packet supplied by
+                * that interface have no link-layer header, and begin
+                * with an IP header, so that the ARPHRD_ value should
+                * be ARPHRD_NONE.
+                *
+                * Detect those devices by checking the device name, and
+                * use DLT_RAW for them.
+                */
+               if (strncmp(device, cdma_rmnet, sizeof cdma_rmnet - 1) == 0) {
+                       handle->linktype = DLT_RAW;
+                       return;
+               }
+       
                /*
                 * This is (presumably) a real Ethernet capture; give it a
                 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
@@ -2971,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
@@ -3074,7 +3122,7 @@ activate_new(pcap_t *handle)
                        close(sock_fd);
                        return arptype;
                }
-               map_arphrd_to_dlt(handle, arptype, 1);
+               map_arphrd_to_dlt(handle, arptype, device, 1);
                if (handle->linktype == -1 ||
                    handle->linktype == DLT_LINUX_SLL ||
                    handle->linktype == DLT_LINUX_IRDA ||
@@ -3177,6 +3225,7 @@ activate_new(pcap_t *handle)
                        /*
                         * It doesn't support monitor mode.
                         */
+                       close(sock_fd);
                        return PCAP_ERROR_RFMON_NOTSUP;
                }
 
@@ -3283,23 +3332,43 @@ activate_new(pcap_t *handle)
                break;
        }
 
-       /* Save the socket FD in the pcap structure */
-       handle->fd = sock_fd;
-
 #if defined(SIOCGSTAMPNS) && defined(SO_TIMESTAMPNS)
        if (handle->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) {
                int nsec_tstamps = 1;
 
-               if (setsockopt(handle->fd, SOL_SOCKET, SO_TIMESTAMPNS, &nsec_tstamps, sizeof(nsec_tstamps)) < 0) {
+               if (setsockopt(sock_fd, SOL_SOCKET, SO_TIMESTAMPNS, &nsec_tstamps, sizeof(nsec_tstamps)) < 0) {
                        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "setsockopt: unable to set SO_TIMESTAMPNS");
+                       close(sock_fd);
                        return PCAP_ERROR;
                }
        }
 #endif /* defined(SIOCGSTAMPNS) && defined(SO_TIMESTAMPNS) */
 
+       /*
+        * We've succeeded. Save the socket FD in the pcap structure.
+        */
+       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 */
-       strncpy(ebuf,
+       strlcpy(ebuf,
                "New packet capturing interface not supported by build "
                "environment", PCAP_ERRBUF_SIZE);
        return 0;
@@ -3685,7 +3754,7 @@ create_ring(pcap_t *handle, int *status)
                 * We pick a "frame" size of 128K to leave enough
                 * room for at least one reasonably-sized packet
                 * in the "frame". */
-               req.tp_frame_size = 131072;
+               req.tp_frame_size = MAXIMUM_SNAPLEN;
                req.tp_frame_nr = handle->opt.buffer_size/req.tp_frame_size;
                break;
 #endif
@@ -3737,7 +3806,7 @@ create_ring(pcap_t *handle, int *status)
                hwconfig.rx_filter = HWTSTAMP_FILTER_ALL;
 
                memset(&ifr, 0, sizeof(ifr));
-               strcpy(ifr.ifr_name, handle->opt.source);
+               strlcpy(ifr.ifr_name, handle->opt.source, sizeof(ifr.ifr_name));
                ifr.ifr_data = (void *)&hwconfig;
 
                if (ioctl(handle->fd, SIOCSHWTSTAMP, &ifr) < 0) {
@@ -3902,13 +3971,14 @@ destroy_ring(pcap_t *handle)
        /* tell the kernel to destroy the ring*/
        struct tpacket_req req;
        memset(&req, 0, sizeof(req));
-       setsockopt(handle->fd, SOL_PACKET, PACKET_RX_RING,
+       /* do not test for setsockopt failure, as we can't recover from any error */
+       (void)setsockopt(handle->fd, SOL_PACKET, PACKET_RX_RING,
                                (void *) &req, sizeof(req));
 
        /* if ring is mapped, unmap it*/
        if (handlep->mmapbuf) {
                /* do not test for mmap failure, as we can't recover from any error */
-               munmap(handlep->mmapbuf, handlep->mmapbuflen);
+               (void)munmap(handlep->mmapbuf, handlep->mmapbuflen);
                handlep->mmapbuf = NULL;
        }
 }
@@ -3971,6 +4041,13 @@ pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf)
 {
        struct pcap_linux *handlep = p->priv;
 
+       /*
+        * Set the file descriptor to non-blocking mode, as we use
+        * it for sending packets.
+        */
+       if (pcap_setnonblock_fd(p, nonblock, errbuf) == -1)
+               return -1;
+
        /*
         * Map each value to their corresponding negation to
         * preserve the timeout value provided with pcap_set_timeout.
@@ -4174,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))
@@ -4432,6 +4515,7 @@ pcap_read_linux_mmap_v3(pcap_t *handle, int max_packets, pcap_handler callback,
        int pkts = 0;
        int ret;
 
+again:
        if (handlep->current_packet == NULL) {
                /* wait for frames availability.*/
                ret = pcap_wait_for_frames_mmap(handle);
@@ -4440,8 +4524,13 @@ pcap_read_linux_mmap_v3(pcap_t *handle, int max_packets, pcap_handler callback,
                }
        }
        h.raw = pcap_get_ring_frame(handle, TP_STATUS_USER);
-       if (!h.raw)
+       if (!h.raw) {
+               if (pkts == 0 && handlep->timeout == 0) {
+                       /* Block until we see a packet. */
+                       goto again;
+               }
                return pkts;
+       }
 
        /* non-positive values of max_packets are used to require all
         * packets currently available in the ring */
@@ -4522,6 +4611,10 @@ pcap_read_linux_mmap_v3(pcap_t *handle, int max_packets, pcap_handler callback,
                        return PCAP_ERROR_BREAK;
                }
        }
+       if (pkts == 0 && handlep->timeout == 0) {
+               /* Block until we see a packet. */
+               goto again;
+       }
        return pkts;
 }
 #endif /* HAVE_TPACKET3 */
@@ -4619,7 +4712,7 @@ iface_get_id(int fd, const char *device, char *ebuf)
        struct ifreq    ifr;
 
        memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+       strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
 
        if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) {
                snprintf(ebuf, PCAP_ERRBUF_SIZE,
@@ -4701,9 +4794,8 @@ has_wext(int sock_fd, const char *device, char *ebuf)
 {
        struct iwreq ireq;
 
-       strncpy(ireq.ifr_ifrn.ifrn_name, device,
+       strlcpy(ireq.ifr_ifrn.ifrn_name, device,
            sizeof ireq.ifr_ifrn.ifrn_name);
-       ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
        if (ioctl(sock_fd, SIOCGIWNAME, &ireq) >= 0)
                return 1;       /* yes */
        snprintf(ebuf, PCAP_ERRBUF_SIZE,
@@ -4839,9 +4931,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
         * return EOPNOTSUPP.
         */
        memset(&ireq, 0, sizeof ireq);
-       strncpy(ireq.ifr_ifrn.ifrn_name, device,
+       strlcpy(ireq.ifr_ifrn.ifrn_name, device,
            sizeof ireq.ifr_ifrn.ifrn_name);
-       ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
        ireq.u.data.pointer = (void *)args;
        ireq.u.data.length = 0;
        ireq.u.data.flags = 0;
@@ -5042,9 +5133,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
        /*
         * Get the old mode.
         */
-       strncpy(ireq.ifr_ifrn.ifrn_name, device,
+       strlcpy(ireq.ifr_ifrn.ifrn_name, device,
            sizeof ireq.ifr_ifrn.ifrn_name);
-       ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
        if (ioctl(sock_fd, SIOCGIWMODE, &ireq) == -1) {
                /*
                 * We probably won't be able to set the mode, either.
@@ -5099,12 +5189,11 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                 * If it fails, just fall back on SIOCSIWMODE.
                 */
                memset(&ireq, 0, sizeof ireq);
-               strncpy(ireq.ifr_ifrn.ifrn_name, device,
+               strlcpy(ireq.ifr_ifrn.ifrn_name, device,
                    sizeof ireq.ifr_ifrn.ifrn_name);
-               ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
                ireq.u.data.length = 1; /* 1 argument */
                args[0] = 3;    /* request Prism header */
-               memcpy(ireq.u.name, args, IFNAMSIZ);
+               memcpy(ireq.u.name, args, sizeof (int));
                if (ioctl(sock_fd, cmd, &ireq) != -1) {
                        /*
                         * Success.
@@ -5132,7 +5221,7 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
         * might get EBUSY.
         */
        memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+       strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
        if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: Can't get flags: %s", device, strerror(errno));
@@ -5152,9 +5241,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
        /*
         * Then turn monitor mode on.
         */
-       strncpy(ireq.ifr_ifrn.ifrn_name, device,
+       strlcpy(ireq.ifr_ifrn.ifrn_name, device,
            sizeof ireq.ifr_ifrn.ifrn_name);
-       ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
        ireq.u.mode = IW_MODE_MONITOR;
        if (ioctl(sock_fd, SIOCSIWMODE, &ireq) == -1) {
                /*
@@ -5192,9 +5280,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                 * Try to select the radiotap header.
                 */
                memset(&ireq, 0, sizeof ireq);
-               strncpy(ireq.ifr_ifrn.ifrn_name, device,
+               strlcpy(ireq.ifr_ifrn.ifrn_name, device,
                    sizeof ireq.ifr_ifrn.ifrn_name);
-               ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
                args[0] = 3;    /* request radiotap header */
                memcpy(ireq.u.name, args, sizeof (int));
                if (ioctl(sock_fd, cmd, &ireq) != -1)
@@ -5204,9 +5291,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                 * That failed.  Try to select the AVS header.
                 */
                memset(&ireq, 0, sizeof ireq);
-               strncpy(ireq.ifr_ifrn.ifrn_name, device,
+               strlcpy(ireq.ifr_ifrn.ifrn_name, device,
                    sizeof ireq.ifr_ifrn.ifrn_name);
-               ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
                args[0] = 2;    /* request AVS header */
                memcpy(ireq.u.name, args, sizeof (int));
                if (ioctl(sock_fd, cmd, &ireq) != -1)
@@ -5216,9 +5302,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                 * That failed.  Try to select the Prism header.
                 */
                memset(&ireq, 0, sizeof ireq);
-               strncpy(ireq.ifr_ifrn.ifrn_name, device,
+               strlcpy(ireq.ifr_ifrn.ifrn_name, device,
                    sizeof ireq.ifr_ifrn.ifrn_name);
-               ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
                args[0] = 1;    /* request Prism header */
                memcpy(ireq.u.name, args, sizeof (int));
                ioctl(sock_fd, cmd, &ireq);
@@ -5235,9 +5320,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                 * Select the Prism header.
                 */
                memset(&ireq, 0, sizeof ireq);
-               strncpy(ireq.ifr_ifrn.ifrn_name, device,
+               strlcpy(ireq.ifr_ifrn.ifrn_name, device,
                    sizeof ireq.ifr_ifrn.ifrn_name);
-               ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
                args[0] = 3;    /* request Prism header */
                memcpy(ireq.u.name, args, sizeof (int));
                ioctl(sock_fd, cmd, &ireq);
@@ -5248,9 +5332,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                 * Get the current channel.
                 */
                memset(&ireq, 0, sizeof ireq);
-               strncpy(ireq.ifr_ifrn.ifrn_name, device,
+               strlcpy(ireq.ifr_ifrn.ifrn_name, device,
                    sizeof ireq.ifr_ifrn.ifrn_name);
-               ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
                if (ioctl(sock_fd, SIOCGIWFREQ, &ireq) == -1) {
                        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                            "%s: SIOCGIWFREQ: %s", device,
@@ -5264,9 +5347,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                 * current value.
                 */
                memset(&ireq, 0, sizeof ireq);
-               strncpy(ireq.ifr_ifrn.ifrn_name, device,
+               strlcpy(ireq.ifr_ifrn.ifrn_name, device,
                    sizeof ireq.ifr_ifrn.ifrn_name);
-               ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
                args[0] = 1;            /* request Prism header */
                args[1] = channel;      /* set channel */
                memcpy(ireq.u.name, args, 2*sizeof (int));
@@ -5279,9 +5361,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                 * Prism header.
                 */
                memset(&ireq, 0, sizeof ireq);
-               strncpy(ireq.ifr_ifrn.ifrn_name, device,
+               strlcpy(ireq.ifr_ifrn.ifrn_name, device,
                    sizeof ireq.ifr_ifrn.ifrn_name);
-               ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
                args[0] = 0;    /* disallow transmitting */
                memcpy(ireq.u.name, args, sizeof (int));
                ioctl(sock_fd, cmd, &ireq);
@@ -5292,9 +5373,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                 * Force the Prism header.
                 */
                memset(&ireq, 0, sizeof ireq);
-               strncpy(ireq.ifr_ifrn.ifrn_name, device,
+               strlcpy(ireq.ifr_ifrn.ifrn_name, device,
                    sizeof ireq.ifr_ifrn.ifrn_name);
-               ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
                args[0] = 1;    /* request Prism header */
                memcpy(ireq.u.name, args, sizeof (int));
                ioctl(sock_fd, cmd, &ireq);
@@ -5305,9 +5385,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                 * Force the Prism header.
                 */
                memset(&ireq, 0, sizeof ireq);
-               strncpy(ireq.ifr_ifrn.ifrn_name, device,
+               strlcpy(ireq.ifr_ifrn.ifrn_name, device,
                    sizeof ireq.ifr_ifrn.ifrn_name);
-               ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
                ireq.u.data.length = 1; /* 1 argument */
                ireq.u.data.pointer = "1";
                ireq.u.data.flags = 0;
@@ -5319,9 +5398,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                 * Force the Prism header.
                 */
                memset(&ireq, 0, sizeof ireq);
-               strncpy(ireq.ifr_ifrn.ifrn_name, device,
+               strlcpy(ireq.ifr_ifrn.ifrn_name, device,
                    sizeof ireq.ifr_ifrn.ifrn_name);
-               ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
                args[0] = 1;    /* request Prism header */
                memcpy(ireq.u.name, args, sizeof (int));
                ioctl(sock_fd, cmd, &ireq);
@@ -5403,6 +5481,103 @@ 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])
+
+#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;
+
+       /*
+        * 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.
+                        */
+                       return SOF_TIMESTAMPING_SOFTWARE|SOF_TIMESTAMPING_SYS_HARDWARE|SOF_TIMESTAMPING_RAW_HARDWARE;
+               }
+               snprintf(ebuf, PCAP_ERRBUF_SIZE,
+                   "%s: SIOETHTOOL(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_)
+{
+       int i;
+
+       /*
+        * We don't have an ioctl to use to ask what's supported,
+        * so say we support everything.
+        */
+       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;
+       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.
  *
@@ -5413,13 +5588,13 @@ 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;
 
        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));
        eval.cmd = cmd;
        eval.data = 0;
        ifr.ifr_data = (caddr_t)&eval;
@@ -5447,7 +5622,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)
@@ -5455,7 +5630,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)
@@ -5468,7 +5643,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)
@@ -5476,7 +5651,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)
@@ -5489,7 +5664,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)
@@ -5557,7 +5732,7 @@ activate_old(pcap_t *handle)
        /* Bind to the given device */
 
        if (strcmp(device, "any") == 0) {
-               strncpy(handle->errbuf, "pcap_activate: The \"any\" device isn't supported on 2.0[.x]-kernel systems",
+               strlcpy(handle->errbuf, "pcap_activate: The \"any\" device isn't supported on 2.0[.x]-kernel systems",
                        PCAP_ERRBUF_SIZE);
                return PCAP_ERROR;
        }
@@ -5575,7 +5750,7 @@ activate_old(pcap_t *handle)
         * Try to find the DLT_ type corresponding to that
         * link-layer type.
         */
-       map_arphrd_to_dlt(handle, arptype, 0);
+       map_arphrd_to_dlt(handle, arptype, device, 0);
        if (handle->linktype == -1) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                         "unknown arptype %d", arptype);
@@ -5586,7 +5761,7 @@ activate_old(pcap_t *handle)
 
        if (handle->opt.promisc) {
                memset(&ifr, 0, sizeof(ifr));
-               strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+               strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
                if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) {
                        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                                 "SIOCGIFFLAGS: %s", pcap_strerror(errno));
@@ -5724,7 +5899,7 @@ iface_bind_old(int fd, const char *device, char *ebuf)
        socklen_t       errlen = sizeof(err);
 
        memset(&saddr, 0, sizeof(saddr));
-       strncpy(saddr.sa_data, device, sizeof(saddr.sa_data));
+       strlcpy(saddr.sa_data, device, sizeof(saddr.sa_data));
        if (bind(fd, &saddr, sizeof(saddr)) == -1) {
                snprintf(ebuf, PCAP_ERRBUF_SIZE,
                         "bind: %s", pcap_strerror(errno));
@@ -5763,7 +5938,7 @@ iface_get_mtu(int fd, const char *device, char *ebuf)
                return BIGGER_THAN_ALL_MTUS;
 
        memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+       strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
 
        if (ioctl(fd, SIOCGIFMTU, &ifr) == -1) {
                snprintf(ebuf, PCAP_ERRBUF_SIZE,
@@ -5783,7 +5958,7 @@ iface_get_arptype(int fd, const char *device, char *ebuf)
        struct ifreq    ifr;
 
        memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+       strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
 
        if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
                snprintf(ebuf, PCAP_ERRBUF_SIZE,
@@ -5850,18 +6025,19 @@ fix_program(pcap_t *handle, struct sock_fprog *fcode, int is_mmapped)
                                         * Yes - if the value to be returned,
                                         * i.e. the snapshot length, is
                                         * anything other than 0, make it
-                                        * 65535, so that the packet is
-                                        * truncated by "recvfrom()",
+                                        * MAXIMUM_SNAPLEN, so that the packet
+                                        * is truncated by "recvfrom()",
                                         * not by the filter.
                                         *
                                         * XXX - there's nothing we can
                                         * easily do if it's getting the
                                         * value from the accumulator; we'd
                                         * have to insert code to force
-                                        * non-zero values to be 65535.
+                                        * non-zero values to be
+                                        * MAXIMUM_SNAPLEN.
                                         */
                                        if (p->k != 0)
-                                               p->k = 65535;
+                                               p->k = MAXIMUM_SNAPLEN;
                                }
                        }
                        break;
@@ -5994,20 +6170,40 @@ set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode)
                 * "nothing more to be read" error).
                 */
                save_mode = fcntl(handle->fd, F_GETFL, 0);
-               if (save_mode != -1 &&
-                   fcntl(handle->fd, F_SETFL, save_mode | O_NONBLOCK) >= 0) {
-                       while (recv(handle->fd, &drain, sizeof drain,
-                              MSG_TRUNC) >= 0)
-                               ;
-                       save_errno = errno;
-                       fcntl(handle->fd, F_SETFL, save_mode);
-                       if (save_errno != EAGAIN) {
-                               /* Fatal error */
-                               reset_kernel_filter(handle);
-                               snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
-                                "recv: %s", pcap_strerror(save_errno));
-                               return -2;
-                       }
+               if (save_mode == -1) {
+                       snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+                           "can't get FD flags when changing filter: %s",
+                           pcap_strerror(errno));
+                       return -2;
+               }
+               if (fcntl(handle->fd, F_SETFL, save_mode | O_NONBLOCK) < 0) {
+                       snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+                           "can't set nonblocking mode when changing filter: %s",
+                           pcap_strerror(errno));
+                       return -2;
+               }
+               while (recv(handle->fd, &drain, sizeof drain, MSG_TRUNC) >= 0)
+                       ;
+               save_errno = errno;
+               if (save_errno != EAGAIN) {
+                       /*
+                        * Fatal error.
+                        *
+                        * If we can't restore the mode or reset the
+                        * kernel filter, there's nothing we can do.
+                        */
+                       (void)fcntl(handle->fd, F_SETFL, save_mode);
+                       (void)reset_kernel_filter(handle);
+                       snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+                           "recv failed when changing filter: %s",
+                           pcap_strerror(save_errno));
+                       return -2;
+               }
+               if (fcntl(handle->fd, F_SETFL, save_mode) == -1) {
+                       snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+                           "can't restore FD flags when changing filter: %s",
+                           pcap_strerror(save_errno));
+                       return -2;
                }
        }
 
@@ -6030,11 +6226,16 @@ set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode)
                save_errno = errno;
 
                /*
-                * XXX - if this fails, we're really screwed;
-                * we have the total filter on the socket,
-                * and it won't come off.  What do we do then?
+                * If this fails, we're really screwed; we have the
+                * total filter on the socket, and it won't come off.
+                * Report it as a fatal error.
                 */
-               reset_kernel_filter(handle);
+               if (reset_kernel_filter(handle) == -1) {
+                       snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+                           "can't remove kernel total filter: %s",
+                           pcap_strerror(errno));
+                       return -2;      /* fatal error */
+               }
 
                errno = save_errno;
        }
index aa8edbba777234de947ce8e89a59286947ff8b19..2a5812b273afb0272c124cfdd61a9ebb6bf02884 100644 (file)
@@ -117,12 +117,11 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
                }
 
                if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_ULOG && 
-                       NFNL_MSG_TYPE(nlh->nlmsg_type) == NFULNL_MSG_PACKET) 
-                               type = NFLOG;
-
-               if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_QUEUE && 
-                       NFNL_MSG_TYPE(nlh->nlmsg_type) == NFQNL_MSG_PACKET)
-                               type = NFQUEUE;
+                   NFNL_MSG_TYPE(nlh->nlmsg_type) == NFULNL_MSG_PACKET) 
+                       type = NFLOG;
+               else if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_QUEUE && 
+                        NFNL_MSG_TYPE(nlh->nlmsg_type) == NFQNL_MSG_PACKET)
+                       type = NFQUEUE;
 
                if (type != OTHER) {
                        const unsigned char *payload = NULL;
index 75716469bc9da59e91833b081e9d71b49493e0e2..2b93c143781d3aae68d1d06bf3f3163090b1f105 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "21 October 2008"
+.TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "29 July 2013"
 .SH NAME
 pcap-savefile \- libpcap savefile format
 .SH DESCRIPTION
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 cbf9abf6427503547fa6ecf8692bbe5df523a657..f70dcce86bed2d9d1c33cc3d1d6945789a43268c 100644 (file)
 #define pcap_stdinc_h
 
 /*
- * Avoids a compiler warning in case this was already defined      
+ * Avoids a compiler warning in case this was already defined
  * (someone defined _WINSOCKAPI_ when including 'windows.h', in order
  * to prevent it from including 'winsock.h')
  */
 #ifdef _WINSOCKAPI_
 #undef _WINSOCKAPI_
 #endif
-#include <winsock2.h>
 
+#include <winsock2.h>
 #include <fcntl.h>
-
-#include "bittypes.h"
 #include <time.h>
 #include <io.h>
 
-#ifndef __MINGW32__
+#include "bittypes.h"
 #include "IP6_misc.h"
-#endif
 
 #define caddr_t char*
 
-#if _MSC_VER < 1500
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#define strdup _strdup
+#if defined(_MSC_VER)
+  #define snprintf  _snprintf
+  #define vsnprintf _vsnprintf
+  #define strdup    _strdup
 #endif
 
-#define inline __inline 
+#define inline __inline
 
 #ifdef __MINGW32__
-#include <stdint.h>
-#else /*__MINGW32__*/
-/* MSVC compiler */
-#ifndef _UINTPTR_T_DEFINED
-#ifdef  _WIN64
-typedef unsigned __int64    uintptr_t;
+  #include <stdint.h>
 #else
-typedef _W64 unsigned int   uintptr_t;
-#endif
-#define _UINTPTR_T_DEFINED
-#endif
-
-#ifndef _INTPTR_T_DEFINED
-#ifdef  _WIN64
-typedef __int64    intptr_t;
-#else
-typedef _W64 int   intptr_t;
-#endif
-#define _INTPTR_T_DEFINED
-#endif 
+  #ifndef _UINTPTR_T_DEFINED
+    #ifdef  _WIN64
+      typedef unsigned __int64    uintptr_t;
+    #else
+      typedef _W64 unsigned int   uintptr_t;
+    #endif
+    #define _UINTPTR_T_DEFINED
+  #endif
 
+  #ifndef _INTPTR_T_DEFINED
+    #ifdef  _WIN64
+      typedef __int64    intptr_t;
+    #else
+      typedef _W64 int   intptr_t;
+    #endif
+    #define _INTPTR_T_DEFINED
+  #endif
 #endif /*__MINGW32__*/
+
 #endif /* pcap_stdinc_h */
index fec49ee25f43cf8ccdf8edfe45e6efa814f085fa..f86f83324a57c606aea84eab1a04fd00a4662e41 100644 (file)
@@ -19,7 +19,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP-TSTAMP @MAN_MISC_INFO@ "22 August 2010"
+.TH PCAP-TSTAMP @MAN_MISC_INFO@ "21 December 2013"
 .SH NAME
 pcap-tstamp \- packet time stamps in libpcap
 .SH DESCRIPTION
index 675c8b12a282175f48f4c8b99c63dc8c730eb5d8..63eb11eba2456428b05c94fc07bd909bec91287e 100644 (file)
@@ -221,6 +221,8 @@ int usb_mmap(pcap_t* handle)
        return handlep->mmapbuf != MAP_FAILED;
 }
 
+#ifdef HAVE_LINUX_USBDEVICE_FS_H
+
 #define CTRL_TIMEOUT    (5*1000)        /* milliseconds */
 
 #define USB_DIR_IN             0x80
@@ -289,6 +291,7 @@ probe_devices(int bus)
        }
        closedir(dir);
 }
+#endif /* HAVE_LINUX_USBDEVICE_FS_H */
 
 pcap_t *
 usb_create(const char *device, char *ebuf, int *is_ours)
@@ -378,7 +381,9 @@ usb_activate(pcap_t* handle)
                        handle->stats_op = usb_stats_linux_bin;
                        handle->read_op = usb_read_linux_mmap;
                        handle->cleanup_op = usb_cleanup_linux_mmap;
+#ifdef HAVE_LINUX_USBDEVICE_FS_H
                        probe_devices(handlep->bus_index);
+#endif
 
                        /*
                         * "handle->fd" is a real file, so "select()" and
@@ -391,7 +396,9 @@ usb_activate(pcap_t* handle)
                /* can't mmap, use plain binary interface access */
                handle->stats_op = usb_stats_linux_bin;
                handle->read_op = usb_read_linux_bin;
+#ifdef HAVE_LINUX_USBDEVICE_FS_H
                probe_devices(handlep->bus_index);
+#endif
        }
        else {
                /*Binary interface not available, try open text interface */
@@ -910,7 +917,11 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
        }
 
        /* flush pending events*/
-       ioctl(handle->fd, MON_IOCH_MFLUSH, nflush);
+       if (ioctl(handle->fd, MON_IOCH_MFLUSH, nflush) == -1) {
+               snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+                   "Can't mflush fd %d: %s", handle->fd, strerror(errno));
+               return -1;
+       }
        return packets;
 }
 
index e7ed84951e4449c26a4daa8c416875cf0ea37e98..f63b5c472b93d692ec8c93676cdf55d2aa894c38 100644 (file)
@@ -72,6 +72,8 @@ static int pcap_setnonblock_win32(pcap_t *, int, char *);
 struct pcap_win {
        int nonblock;
 
+       int filtering_in_kernel; /* using kernel filter */
+
 #ifdef HAVE_DAG_API
        int     dag_fcs_bits;   /* Number of checksum bits from link layer */
 #endif
@@ -111,16 +113,27 @@ wsockinit()
 {
        WORD wVersionRequested;
        WSADATA wsaData;
-       int err;
+       static int err = -1;
+       static int done = 0;
+
+       if (done)
+               return err;
+       
        wVersionRequested = MAKEWORD( 1, 1); 
        err = WSAStartup( wVersionRequested, &wsaData );
+       atexit ((void(*)(void))WSACleanup);
+       InitializeCriticalSection(&g_PcapCompileCriticalSection);
+       done = 1;
+       
        if ( err != 0 )
-       {
-               return -1;
-       }
-       return 0;
+               err = -1;
+       return err;
 }
 
+int pcap_wsockinit()
+{
+       return wsockinit();
+}
 
 static int
 pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
@@ -184,6 +197,8 @@ pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
        int cc;
        int n = 0;
        register u_char *bp, *ep;
+       u_char *datap;
+       struct pcap_win *pw = p->priv;
 
        cc = p->cc;
        if (p->cc == 0) {
@@ -193,17 +208,17 @@ pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                if (p->break_loop) {
                        /*
                         * Yes - clear the flag that indicates that it
-                        * has, and return -2 to indicate that we were
-                        * told to break out of the loop.
+                        * has, and return PCAP_ERROR_BREAK to indicate
+                        * that we were told to break out of the loop.
                         */
                        p->break_loop = 0;
-                       return (-2);
+                       return (PCAP_ERROR_BREAK);
                }
 
            /* capture the packets */
                if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
-                       return (-1);
+                       return (PCAP_ERROR);
                }
                        
                cc = p->Packet->ulBytesReceived;
@@ -224,16 +239,17 @@ pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                /*
                 * Has "pcap_breakloop()" been called?
                 * If so, return immediately - if we haven't read any
-                * packets, clear the flag and return -2 to indicate
-                * that we were told to break out of the loop, otherwise
-                * leave the flag set, so that the *next* call will break
-                * out of the loop without having read any packets, and
-                * return the number of packets we've processed so far.
+                * packets, clear the flag and return PCAP_ERROR_BREAK
+                * to indicate that we were told to break out of the loop,
+                * otherwise leave the flag set, so that the *next* call
+                * will break out of the loop without having read any
+                * packets, and return the number of packets we've
+                * processed so far.
                 */
                if (p->break_loop) {
                        if (n == 0) {
                                p->break_loop = 0;
-                               return (-2);
+                               return (PCAP_ERROR_BREAK);
                        } else {
                                p->bp = bp;
                                p->cc = ep - bp;
@@ -245,16 +261,35 @@ pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 
                caplen = bhp->bh_caplen;
                hdrlen = bhp->bh_hdrlen;
+               datap = bp + hdrlen;
 
                /*
-                * XXX A bpf_hdr matches a pcap_pkthdr.
+                * Short-circuit evaluation: if using BPF filter
+                * in kernel, no need to do it now - we already know
+                * the packet passed the filter.
+                *
+                * XXX - bpf_filter() should always return TRUE if
+                * handed a null pointer for the program, but it might
+                * just try to "run" the filter, so we check here.
                 */
-               (*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
-               bp += Packet_WORDALIGN(caplen + hdrlen);
-               if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) {
-                       p->bp = bp;
-                       p->cc = ep - bp;
-                       return (n);
+               if (pw->filtering_in_kernel ||
+                   p->fcode.bf_insns == NULL ||
+                   bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
+                       /*
+                        * XXX A bpf_hdr matches a pcap_pkthdr.
+                        */
+                       (*callback)(user, (struct pcap_pkthdr*)bp, datap);
+                       bp += Packet_WORDALIGN(caplen + hdrlen);
+                       if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) {
+                               p->bp = bp;
+                               p->cc = ep - bp;
+                               return (n);
+                       }
+               } else {
+                       /*
+                        * Skip this packet.
+                        */
+                       bp += Packet_WORDALIGN(caplen + hdrlen);
                }
        }
 #undef bhp
@@ -637,7 +672,7 @@ pcap_activate_win32(pcap_t *p)
                
                PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
                
-               if (p-opt.immediate)
+               if (p->opt.immediate)
                {
                        /* tell the driver to copy the buffer as soon as data arrives */
                        if(PacketSetMinToCopy(p->adapter,0)==FALSE)
@@ -789,16 +824,51 @@ pcap_create_interface(const char *device, char *ebuf)
 static int
 pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
 {
+       struct pcap_win *pw = p->priv;
+
        if(PacketSetBpf(p->adapter,fp)==FALSE){
                /*
                 * Kernel filter not installed.
-                * XXX - fall back on userland filtering, as is done
-                * on other platforms?
+                *
+                * XXX - we don't know whether this failed because:
+                *
+                *  the kernel rejected the filter program as invalid,
+                *  in which case we should fall back on userland
+                *  filtering;
+                *
+                *  the kernel rejected the filter program as too big,
+                *  in which case we should again fall back on
+                *  userland filtering;
+                *
+                *  there was some other problem, in which case we
+                *  should probably report an error.
+                *
+                * For NPF devices, the Win32 status will be
+                * STATUS_INVALID_DEVICE_REQUEST for invalid
+                * filters, but I don't know what it'd be for
+                * other problems, and for some other devices
+                * it might not be set at all.
+                *
+                * So we just fall back on userland filtering in
+                * all cases.
                 */
-               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror());
-               return (-1);
+
+               /*
+                * install_bpf_program() validates the program.
+                *
+                * XXX - what if we already have a filter in the kernel?
+                */
+               if (install_bpf_program(p, fp) < 0)
+                       return (-1);
+               pw->filtering_in_kernel = 0;    /* filtering in userland */
+               return (0);
        }
 
+       /*
+        * It worked.
+        */
+       pw->filtering_in_kernel = 1;    /* filtering in the kernel */
+
        /*
         * Discard any previously-received packets, as they might have
         * passed whatever filter was formerly in effect, but might
index 7d234c9a629ff23ac14301196517867b57a51717..85a2f5b3a581679e8d049c8580dce9a56255e05b 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP 3PCAP "1 July 2013"
+.TH PCAP 3PCAP "16 April 2014"
 .SH NAME
 pcap \- Packet Capture library
 .SH SYNOPSIS
@@ -172,11 +172,9 @@ arbitrarily long period of time.
 .IP
 Not all platforms support a read timeout; on platforms that
 don't, the read timeout is ignored.  A zero value for the timeout,
-on platforms that support a read timeout, has platform-dependent
-behavior that could cause a read to wait for an unlimited amount
-of time until the capture buffer fills up or could cause a read timeout
-of 1 millisecond to be used.  We recommend that a value of zero not be
-used.
+on platforms that support a read timeout,
+will cause a read to wait forever to allow enough packets to
+arrive, with no timeout.
 .IP
 .BR NOTE :
 the read timeout cannot be used to cause calls that read
@@ -582,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
@@ -598,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;
@@ -608,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 f8292895ae6d8e6ef10074f4f3a97fee0c2c126d..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 {
@@ -553,14 +556,20 @@ pcap_create_common(const char *source, char *ebuf, size_t size)
        initialize_ops(p);
 
        /* put in some defaults*/
-       pcap_set_snaplen(p, 65535);     /* max packet size */
-       p->opt.timeout = 0;             /* no timeout specified */
-       p->opt.buffer_size = 0;         /* use the platform's default */
+       pcap_set_snaplen(p, MAXIMUM_SNAPLEN);   /* max packet size */
+       p->opt.timeout = 0;                     /* no timeout specified */
+       p->opt.buffer_size = 0;                 /* use the platform's default */
        p->opt.promisc = 0;
        p->opt.rfmon = 0;
        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);
 }
 
@@ -1185,6 +1194,7 @@ static struct dlt_choice dlt_choices[] = {
        DLT_CHOICE(DLT_AX25_KISS, "AX.25 with KISS header"),
        DLT_CHOICE(DLT_IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
        DLT_CHOICE(DLT_MPLS, "MPLS with label as link-layer header"),
+       DLT_CHOICE(DLT_LINUX_EVDEV, "Linux evdev events"),
        DLT_CHOICE(DLT_USB_LINUX_MMAPPED, "USB with padded Linux header"),
        DLT_CHOICE(DLT_DECT, "DECT"),
        DLT_CHOICE(DLT_AOS, "AOS Space Data Link protocol"),
@@ -1196,18 +1206,33 @@ static struct dlt_choice dlt_choices[] = {
        DLT_CHOICE(DLT_IPV4, "Raw IPv4"),
        DLT_CHOICE(DLT_IPV6, "Raw IPv6"),
        DLT_CHOICE(DLT_IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"),
+       DLT_CHOICE(DLT_DBUS, "D-Bus"),
        DLT_CHOICE(DLT_JUNIPER_VS, "Juniper Virtual Server"),
        DLT_CHOICE(DLT_JUNIPER_SRX_E2E, "Juniper SRX E2E"),
        DLT_CHOICE(DLT_JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"),
        DLT_CHOICE(DLT_DVB_CI, "DVB-CI"),
+       DLT_CHOICE(DLT_MUX27010, "MUX27010"),
+       DLT_CHOICE(DLT_STANAG_5066_D_PDU, "STANAG 5066 D_PDUs"),
        DLT_CHOICE(DLT_JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"),
        DLT_CHOICE(DLT_NFLOG, "Linux netfilter log messages"),
        DLT_CHOICE(DLT_NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"),
        DLT_CHOICE(DLT_NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"),
        DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"),
-       DLT_CHOICE(DLT_DBUS, "D-Bus"),
+       DLT_CHOICE(DLT_MPEG_2_TS, "MPEG-2 transport stream"),
+       DLT_CHOICE(DLT_NG40, "ng40 protocol tester Iub/Iur"),
+       DLT_CHOICE(DLT_NFC_LLCP, "NFC LLCP PDUs with pseudo-header"),
+       DLT_CHOICE(DLT_INFINIBAND, "InfiniBand"),
+       DLT_CHOICE(DLT_SCTP, "SCTP"),
+       DLT_CHOICE(DLT_USBPCAP, "USB with USBPcap header"),
+       DLT_CHOICE(DLT_RTAC_SERIAL, "Schweitzer Engineering Laboratories RTAC packets"),
+       DLT_CHOICE(DLT_BLUETOOTH_LE_LL, "Bluetooth Low Energy air interface"),
        DLT_CHOICE(DLT_NETLINK, "Linux netlink"),
        DLT_CHOICE(DLT_BLUETOOTH_LINUX_MONITOR, "Bluetooth Linux Monitor"),
+       DLT_CHOICE(DLT_BLUETOOTH_BREDR_BB, "Bluetooth Basic Rate/Enhanced Data Rate baseband packets"),
+       DLT_CHOICE(DLT_BLUETOOTH_LE_LL_WITH_PHDR, "Bluetooth Low Energy air interface with pseudo-header"),
+       DLT_CHOICE(DLT_PROFIBUS_DL, "PROFIBUS data link layer"),
+       DLT_CHOICE(DLT_PKTAP, "Apple DLT_PKTAP"),
+       DLT_CHOICE(DLT_EPON, "Ethernet with 802.3 Clause 65 EPON preamble"),
        DLT_CHOICE_SENTINEL
 };
 
@@ -1815,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 7017d1374dfed379001b9cd5ab2448d7a78849c4..48805087e86b9dc731a317aa775d2bc2597ff981 100644 (file)
@@ -1248,7 +1248,76 @@ struct bpf_program {
  */
 #define DLT_PROFIBUS_DL                257
 
-#define DLT_MATCHING_MAX       257     /* highest value in the "matching" range */
+/*
+ * Apple's DLT_PKTAP headers.
+ *
+ * Sadly, the folks at Apple either had no clue that the DLT_USERn values
+ * are for internal use within an organization and partners only, and
+ * didn't know that the right way to get a link-layer header type is to
+ * ask tcpdump.org for one, or knew and didn't care, so they just
+ * used DLT_USER2, which causes problems for everything except for
+ * their version of tcpdump.
+ *
+ * So I'll just give them one; hopefully this will show up in a
+ * libpcap release in time for them to get this into 10.10 Big Sur
+ * or whatever Mavericks' successor is called.  LINKTYPE_PKTAP
+ * will be 258 *even on OS X*; that is *intentional*, so that
+ * PKTAP files look the same on *all* OSes (different OSes can have
+ * different numerical values for a given DLT_, but *MUST NOT* have
+ * different values for what goes in a file, as files can be moved
+ * between OSes!).
+ *
+ * When capturing, on a system with a Darwin-based OS, on a device
+ * that returns 149 (DLT_USER2 and Apple's DLT_PKTAP) with this
+ * version of libpcap, the DLT_ value for the pcap_t  will be DLT_PKTAP,
+ * and that will continue to be DLT_USER2 on Darwin-based OSes. That way,
+ * binary compatibility with Mavericks is preserved for programs using
+ * this version of libpcap.  This does mean that if you were using
+ * DLT_USER2 for some capture device on OS X, you can't do so with
+ * this version of libpcap, just as you can't with Apple's libpcap -
+ * on OS X, they define DLT_PKTAP to be DLT_USER2, so programs won't
+ * be able to distinguish between PKTAP and whatever you were using
+ * DLT_USER2 for.
+ *
+ * If the program saves the capture to a file using this version of
+ * libpcap's pcap_dump code, the LINKTYPE_ value in the file will be
+ * LINKTYPE_PKTAP, which will be 258, even on Darwin-based OSes.
+ * That way, the file will *not* be a DLT_USER2 file.  That means
+ * that the latest version of tcpdump, when built with this version
+ * of libpcap, and sufficiently recent versions of Wireshark will
+ * be able to read those files and interpret them correctly; however,
+ * Apple's version of tcpdump in OS X 10.9 won't be able to handle
+ * them.  (Hopefully, Apple will pick up this version of libpcap,
+ * and the corresponding version of tcpdump, so that tcpdump will
+ * be able to handle the old LINKTYPE_USER2 captures *and* the new
+ * LINKTYPE_PKTAP captures.)
+ */
+#ifdef __APPLE__
+#define DLT_PKTAP      DLT_USER2
+#else
+#define DLT_PKTAP      258
+#endif
+
+/*
+ * Ethernet packets preceded by a header giving the last 6 octets
+ * of the preamble specified by 802.3-2012 Clause 65, section
+ * 65.1.3.2 "Transmit".
+ */
+#define DLT_EPON       259
+
+/*
+ * IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format"
+ * in the PICMG HPM.2 specification.
+ */
+#define DLT_IPMI_HPM_2 260
+
+/*
+ * 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
@@ -1272,7 +1341,17 @@ struct bpf_program {
 
 /*
  * The instruction encodings.
+ *
+ * Please inform [email protected] if you use any
+ * of the reserved values, so that we can note that they're used
+ * (and perhaps implement it in the reference BPF implementation
+ * and encourage its implementation elsewhere).
+ */
+
+/*
+ * The upper 8 bits of the opcode aren't used. BSD/OS used 0x8000.
  */
+
 /* instruction classes */
 #define BPF_CLASS(code) ((code) & 0x07)
 #define                BPF_LD          0x00
@@ -1289,6 +1368,7 @@ struct bpf_program {
 #define                BPF_W           0x00
 #define                BPF_H           0x08
 #define                BPF_B           0x10
+/*                             0x18    reserved; used by BSD/OS */
 #define BPF_MODE(code) ((code) & 0xe0)
 #define                BPF_IMM         0x00
 #define                BPF_ABS         0x20
@@ -1296,6 +1376,8 @@ struct bpf_program {
 #define                BPF_MEM         0x60
 #define                BPF_LEN         0x80
 #define                BPF_MSH         0xa0
+/*                             0xc0    reserved; used by BSD/OS */
+/*                             0xe0    reserved; used by BSD/OS */
 
 /* alu/jmp fields */
 #define BPF_OP(code)   ((code) & 0xf0)
@@ -1308,11 +1390,30 @@ struct bpf_program {
 #define                BPF_LSH         0x60
 #define                BPF_RSH         0x70
 #define                BPF_NEG         0x80
+#define                BPF_MOD         0x90
+#define                BPF_XOR         0xa0
+/*                             0xb0    reserved */
+/*                             0xc0    reserved */
+/*                             0xd0    reserved */
+/*                             0xe0    reserved */
+/*                             0xf0    reserved */
+
 #define                BPF_JA          0x00
 #define                BPF_JEQ         0x10
 #define                BPF_JGT         0x20
 #define                BPF_JGE         0x30
 #define                BPF_JSET        0x40
+/*                             0x50    reserved; used on BSD/OS */
+/*                             0x60    reserved */
+/*                             0x70    reserved */
+/*                             0x80    reserved */
+/*                             0x90    reserved */
+/*                             0xa0    reserved */
+/*                             0xb0    reserved */
+/*                             0xc0    reserved */
+/*                             0xd0    reserved */
+/*                             0xe0    reserved */
+/*                             0xf0    reserved */
 #define BPF_SRC(code)  ((code) & 0x08)
 #define                BPF_K           0x00
 #define                BPF_X           0x08
@@ -1320,11 +1421,43 @@ struct bpf_program {
 /* ret - BPF_K and BPF_X also apply */
 #define BPF_RVAL(code) ((code) & 0x18)
 #define                BPF_A           0x10
+/*                             0x18    reserved */
 
 /* misc */
 #define BPF_MISCOP(code) ((code) & 0xf8)
 #define                BPF_TAX         0x00
+/*                             0x08    reserved */
+/*                             0x10    reserved */
+/*                             0x18    reserved */
+/* #define     BPF_COP         0x20    NetBSD "coprocessor" extensions */
+/*                             0x28    reserved */
+/*                             0x30    reserved */
+/*                             0x38    reserved */
+/* #define     BPF_COPX        0x40    NetBSD "coprocessor" extensions */
+/*                                     also used on BSD/OS */
+/*                             0x48    reserved */
+/*                             0x50    reserved */
+/*                             0x58    reserved */
+/*                             0x60    reserved */
+/*                             0x68    reserved */
+/*                             0x70    reserved */
+/*                             0x78    reserved */
 #define                BPF_TXA         0x80
+/*                             0x88    reserved */
+/*                             0x90    reserved */
+/*                             0x98    reserved */
+/*                             0xa0    reserved */
+/*                             0xa8    reserved */
+/*                             0xb0    reserved */
+/*                             0xb8    reserved */
+/*                             0xc0    reserved; used on BSD/OS */
+/*                             0xc8    reserved */
+/*                             0xd0    reserved */
+/*                             0xd8    reserved */
+/*                             0xe0    reserved */
+/*                             0xe8    reserved */
+/*                             0xf0    reserved */
+/*                             0xf8    reserved */
 
 /*
  * The instruction data structure.
@@ -1336,6 +1469,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.
  */
@@ -1345,9 +1488,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 12bcddcebf518cb4be444359edafbabea3325be7..61887a7bead3428157239c81b98aae8b4ee5454b 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_ACTIVATE 3PCAP "5 April 2008"
+.TH PCAP_ACTIVATE 3PCAP "21 September 2010"
 .SH NAME
 pcap_activate \- activate a capture handle
 .SH SYNOPSIS
index e3adb299f2ea927404f4a7c4c490379e1dbdd343..0e5276a165c76fa4540dd379057ac3dd467d36ed 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_COMPILE 3PCAP "5 April 2008"
+.TH PCAP_COMPILE 3PCAP "1 December 2009"
 .SH NAME
 pcap_compile \- compile a filter expression
 .SH SYNOPSIS
index 82f4651079a86658159fec52325af38285a6e031..b07fc28f0982ee20f0dc59ae536d55c4de8f883f 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_DATALINK 3PCAP "22 August 2010"
+.TH PCAP_DATALINK 3PCAP "13 October 2013"
 .SH NAME
 pcap_datalink \- get the link-layer header type
 .SH SYNOPSIS
index e9e7eb7399b0ca27b29ba81d2223fbb7788df3be..39d068b44ece537a82e7bc9dda60e44080f1fd69 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_FILENO 3PCAP "5 April 2008"
+.TH PCAP_FILENO 3PCAP "3 November 2009"
 .SH NAME
 pcap_fileno \- get the file descriptor for a live capture
 .SH SYNOPSIS
index 1e5caca803c4c90a204f3596624dbe8ba2f52061..00bb911f9132960a54debe90fe7b8d2e561615af 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_FINDALLDEVS 3PCAP "22 August 2010"
+.TH PCAP_FINDALLDEVS 3PCAP "10 January 2014"
 .SH NAME
 pcap_findalldevs, pcap_freealldevs \- get a list of capture devices, and
 free that list
index 8b5a2da18279c56d2e73da1e7b09024fca820a58..6640577eaabd0fe0e6b802b86a6560d478fa1dd8 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_GET_SELECTABLE_FD 3PCAP "5 April 2008"
+.TH PCAP_GET_SELECTABLE_FD 3PCAP "22 July 2011"
 .SH NAME
 pcap_get_selectable_fd \- get a file descriptor on which a select() can
 be done for a live capture
@@ -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 2eb68b4a6c1e34f11877b32c130795b83e7743e9..a120616d3291bc82e2df545c8a4916a634adced3 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_IS_SWAPPED 3PCAP "5 April 2008"
+.TH PCAP_IS_SWAPPED 3PCAP "17 September 2013"
 .SH NAME
 pcap_is_swapped \- find out whether a savefile has the native byte order
 .SH SYNOPSIS
index aca0b64e3b3504159fce42cc29c97f86d6975ca1..607efdecafc07cde95f3ca92908330d27663c86a 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_LIST_DATALINKS 3PCAP "22 August 2010"
+.TH PCAP_LIST_DATALINKS 3PCAP "17 September 2013"
 .SH NAME
 pcap_list_datalinks, pcap_free_datalinks \- get a list of link-layer header
 types supported by a capture device, and free that list
index a644e5553f10337ddf97eabea80251b92a737d05..011d85c72587305e39f4ddf44b6e625ffb87123e 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_LOOP 3PCAP "24 December 2008"
+.TH PCAP_LOOP 3PCAP "13 October 2013"
 .SH NAME
 pcap_loop, pcap_dispatch \- process packets from a live capture or savefile
 .SH SYNOPSIS
@@ -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 bf8643fe1a78a49a81b08419654b3e35563bc0bc..a0858380cb145fcc6a98c0bbe4d4e36e352accbc 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_MAJOR_VERSION 3PCAP "5 April 2008"
+.TH PCAP_MAJOR_VERSION 3PCAP "21 December 2011"
 .SH NAME
 pcap_major_version, pcap_minor_version \- get the version number of a savefile
 .SH SYNOPSIS
index 5fa83b4bcef7f654cfb25b7b0aa3741f4759b94b..c310c2f004b57f290534ac2be28e0d7904b8e26a 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_NEXT_EX 3PCAP "5 April 2008"
+.TH PCAP_NEXT_EX 3PCAP "13 October 2013"
 .SH NAME
 pcap_next_ex, pcap_next \- read the next packet from a pcap_t
 .SH SYNOPSIS
index 3c379b82e4a93c266701c89a253abbaa2dbd24f8..b471c6a7403e2981104e2513878a1d0d9fcb5f45 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_OFFLINE_FILTER 3PCAP "13 May 2008"
+.TH PCAP_OFFLINE_FILTER 3PCAP "25 November 2012"
 .SH NAME
 pcap_offline_filter \- check whether a filter matches a packet
 .SH SYNOPSIS
index 2b78df03010786f1c0ab79f2e10c884c4844291c..b7282037b3e7cf94e8434cdc3156e893154cdf92 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_SET_TIMEOUT 3PCAP "5 April 2008"
+.TH PCAP_SET_TIMEOUT 3PCAP "16 April 2014"
 .SH NAME
 pcap_set_timeout \- set the read timeout for a not-yet-activated
 capture handle
@@ -36,9 +36,6 @@ sets the read timeout that will be used on a capture handle when
 the handle is activated to
 .IR to_ms ,
 which is in units of milliseconds.
-.LP
-The behavior, if the timeout isn't specified, is undefined.  We
-recommend always setting the timeout to a non-zero value.
 .SH RETURN VALUE
 .B pcap_set_timeout()
 returns 0 on success or
index 58044c52e279eb5b9a4ce8c036c90197b055b1c1..c737797f3108c360925abbcfdfa9fbb903da5757 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_SETFILTER 3PCAP "5 April 2008"
+.TH PCAP_SETFILTER 3PCAP "13 May 2008"
 .SH NAME
 pcap_setfilter \- set the filter
 .SH SYNOPSIS
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 a7040f020cad09d43e5b308c547d1649361046a6..47eb42a3843f185f4bec2ce8799c0738bf5178eb 100644 (file)
@@ -17,7 +17,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH PCAP_SNAPSHOT 3PCAP "5 April 2008"
+.TH PCAP_SNAPSHOT 3PCAP "17 September 2013"
 .SH NAME
 pcap_snapshot \- get the snapshot length
 .SH SYNOPSIS
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 73f426bd0a9851f5b92eda4f25caa42711b1acfd..a247c993fb75311a3aeb531b5e50bb432e408372 100644 (file)
--- a/scanner.l
+++ b/scanner.l
@@ -319,7 +319,7 @@ hdpc                return HDPC;
 hsls           return HSLS;
 
 [ \r\n\t]              ;
-[+\-*/:\[\]!<>()&|=]   return yytext[0];
+[+\-*/%:\[\]!<>()&|\^=]        return yytext[0];
 ">="                   return GEQ;
 "<="                   return LEQ;
 "!="                   return NEQ;
index e0c1fb1b10f6b85608e5bf3bc8b386d601ba8746..fae408679a5d0326694841c7a2e0024b4a1cef3c 100644 (file)
@@ -459,7 +459,7 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
                                return (-1);
                        }
                        saw_tsresol = 1;
-                       tsresol_opt = *(u_int *)optvalue;
+                       memcpy(&tsresol_opt, optvalue, sizeof(tsresol_opt));
                        if (tsresol_opt & 0x80) {
                                /*
                                 * Resolution is negative power of 2.
@@ -1224,15 +1224,18 @@ found:
                break;
 
        case SCALE_UP:
+       case SCALE_DOWN:
                /*
-                * The interface resolution is less than what the user
-                * wants; scale up to that resolution.
+                * The interface resolution is different from what the
+                * user wants; scale up or down to that resolution.
                 *
                 * 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,
-                * as we know that's an integer.  That runs less risk of
-                * overflow.
+                * 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.
                 *
                 * Is there something clever we could do if
                 * ps->ifaces[interface_id].tsresol is a power of 2?
@@ -1240,24 +1243,6 @@ found:
                frac *= ps->ifaces[interface_id].tsresol;
                frac /= ps->user_tsresol;
                break;
-
-       case SCALE_DOWN:
-               /*
-                * The interface resolution is greater than what the user
-                * wants; scale down to that resolution.
-                *
-                * XXX - if ps->ifaces[interface_id].tsresol is a power
-                * of 10, we could just divide by the quotient of
-                * ps->user_tsresol and ps->ifaces[interface_id].tsresol,
-                * as we know that's an integer.  That runs less risk of
-                * overflow.
-                *
-                * Is there something clever we could do if
-                * ps->ifaces[interface_id].tsresol is a power of 2?
-                */
-               frac *= ps->user_tsresol;
-               frac /= ps->ifaces[interface_id].tsresol;
-               break;
        }
        hdr->ts.tv_sec = sec;
        hdr->ts.tv_usec = frac;
index b298131aa06f7de54269f61b14d43506a6cbc0eb..8180bc9d8da9184a6650c286689ce00337fdb5cb 100644 (file)
--- a/sf-pcap.c
+++ b/sf-pcap.c
@@ -371,9 +371,9 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
        p->bufsize = p->snapshot;
        if (p->bufsize <= 0) {
                /*
-                * Bogus snapshot length; use 64KiB as a fallback.
+                * Bogus snapshot length; use the maximum as a fallback.
                 */
-               p->bufsize = 65536;
+               p->bufsize = MAXIMUM_SNAPLEN;
        }
        p->buffer = malloc(p->bufsize);
        if (p->buffer == NULL) {
@@ -500,7 +500,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                static u_char *tp = NULL;
                static size_t tsize = 0;
 
-               if (hdr->caplen > 65535) {
+               if (hdr->caplen > MAXIMUM_SNAPLEN) {
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                            "bogus savefile header");
                        return (-1);
index 94773ad21c0a3d459df2734617eb0c6977233d71..a36490d4c58efccbc9098a63f6600e412fa2e411 100644 (file)
@@ -51,6 +51,8 @@ static char *program_name;
 static void usage(void) __attribute__((noreturn));
 static void error(const char *, ...)
     __attribute__((noreturn, format (printf, 1, 2)));
+static void warn(const char *, ...)
+    __attribute__((format (printf, 1, 2)));
 
 extern int optind;
 extern int opterr;
@@ -120,6 +122,23 @@ error(const char *fmt, ...)
        /* NOTREACHED */
 }
 
+/* VARARGS */
+static void
+warn(const char *fmt, ...)
+{
+       va_list ap;
+
+       (void)fprintf(stderr, "%s: WARNING: ", program_name);
+       va_start(ap, fmt);
+       (void)vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       if (*fmt) {
+               fmt += strlen(fmt);
+               if (fmt[-1] != '\n')
+                       (void)fputc('\n', stderr);
+       }
+}
+
 /*
  * Copy arg vector into a new buffer, concatenating arguments with spaces.
  */
@@ -163,6 +182,7 @@ main(int argc, char **argv)
        char *infile;
        int Oflag;
        long snaplen;
+       char *p;
        int dlt;
        bpf_u_int32 netmask = PCAP_NETMASK_UNKNOWN;
        char *cmdbuf;
@@ -233,8 +253,11 @@ main(int argc, char **argv)
        }
 
        dlt = pcap_datalink_name_to_val(argv[optind]);
-       if (dlt < 0)
-               error("invalid data link type %s", argv[optind]);
+       if (dlt < 0) {
+               dlt = (int)strtol(argv[optind], &p, 10);
+               if (p == argv[optind] || *p != '\0')
+                       error("invalid data link type %s", argv[optind]);
+       }
        
        if (infile)
                cmdbuf = read_infile(infile);
@@ -247,6 +270,8 @@ main(int argc, char **argv)
 
        if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
                error("%s", pcap_geterr(pd));
+       if (!bpf_validate(fcode.bf_insns, fcode.bf_len))
+               warn("Filter doesn't pass validation");
        bpf_dump(&fcode, dflag);
        pcap_close(pd);
        exit(0);