.devel
filtertest
findalldevstest
+opentest
+valgrindtest
grammar.c
libpcap.a
libpcap.*.dylib
--- /dev/null
+#!/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
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
+ # 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
+ Summary for 1.7.0 libpcap release
+ Fix handling of zones for BPF on Solaris
+
+ 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.
+
+ Summary for 1.6.1 libpcap release
+ some fixes for the any device
+ changes for how --enable-XXX works
+
+ 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!
+
Summary for 1.5.3 libpcap release
Don't let packets that don't match the current filter get to the
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
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
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
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
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.
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.
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
-1.6.0-PRE-GIT
+1.7.0-PRE-GIT
}
#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;
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;
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;
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;
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;
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;
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;
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;
A |= X;
continue;
+ case BPF_ALU|BPF_XOR|BPF_X:
+ A ^= X;
+ continue;
+
case BPF_ALU|BPF_LSH|BPF_X:
A <<= X;
continue;
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;
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;
}
}
+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
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;
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";
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";
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";
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";
#! /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
# 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
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."
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
fi
;;
*)
- os=netbsd
+ os=netbsd
;;
esac
# The OS release
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
# 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
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}
# 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 ;;
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 ] || \
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
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
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
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 ;;
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}
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*:*)
*: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 ;;
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 ;;
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}
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
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
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
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.
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:*:*)
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 ;;
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 ;;
/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 \
echo ns32k-sni-sysv
fi
exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- echo i586-unisys-sysv4
- exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ echo i586-unisys-sysv4
+ exit ;;
*:UNIX_System_V:4*:FTX*)
# How about differentiating between stratus architectures? -djm
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 ;;
*: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 ;;
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 ;;
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
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
- "4"
+ "4"
#else
- ""
+ ""
#endif
- ); exit (0);
+ ); exit (0);
#endif
#endif
#! /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
# 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
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."
# 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 ]
os=
basic_machine=$1
;;
- -bluegene*)
- os=-cnk
+ -bluegene*)
+ os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
os=-chorusos
basic_machine=$1
;;
- -chorusrdb)
- os=-chorusrdb
+ -chorusrdb)
+ os=-chorusrdb
basic_machine=$1
- ;;
+ ;;
-hiux*)
os=-hiuxwe2
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
-lynx*)
os=-lynxos
;;
# 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 \
| 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
;;
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.
# 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-* \
| 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-*)
basic_machine=a29k-amd
os=-udi
;;
- abacus)
+ abacus)
basic_machine=abacus-unknown
;;
adobe68k)
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
;;
basic_machine=craynv-cray
os=-unicosmp
;;
- cr16)
+ cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
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
basic_machine=ns32k-utek
os=-sysv
;;
- microblaze)
+ microblaze)
basic_machine=microblaze-xilinx
;;
mingw32)
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
np1)
basic_machine=np1-gould
;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
nsr-tandem)
basic_machine=nsr-tandem
;;
;;
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
basic_machine=i860-stratus
os=-sysv4
;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
sun2)
basic_machine=m68000-sun
;;
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)
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
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|'`
| -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* \
-opened*)
os=-openedition
;;
- -os400*)
+ -os400*)
os=-os400
;;
-wince*)
-sinix*)
os=-sysv4
;;
- -tpf*)
+ -tpf*)
os=-tpf
;;
-triton*)
-dicos*)
os=-dicos
;;
- -nacl*)
- ;;
+ -nacl*)
+ ;;
-none)
;;
*)
# system, and we'll never get to this point.
case $basic_machine in
- score-*)
+ score-*)
os=-elf
;;
- spu-*)
+ spu-*)
os=-elf
;;
*-acorn)
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-*)
;;
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)
*-ibm)
os=-aix
;;
- *-knuth)
+ *-knuth)
os=-mmixware
;;
*-wec)
if test "${enable_bluetooth+set}" = set; then :
enableval=$enable_bluetooth;
else
- enable_bluetooth=yes
+ enable_bluetooth=ifsupportavailable
fi
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
if test "${enable_canusb+set}" = set; then :
enableval=$enable_canusb;
else
- enable_canusb=yes
+ enable_canusb=ifsupportavailable
fi
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
if test "${enable_can+set}" = set; then :
enableval=$enable_can;
else
- enable_can=yes
+ enable_can=ifsupportavailable
fi
"
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
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; }
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 ()
{
_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
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
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)
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
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)
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)
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)
/* 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 */
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
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) {
#endif
lex_cleanup();
freechunks();
- return (-1);
+ rc = -1;
+ goto quit;
}
netmask = mask;
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 : "");
lex_cleanup();
freechunks();
- return (0);
+
+ rc = 0; /* We're all okay */
+
+quit:
+
+#ifdef WIN32
+ LeaveCriticalSection(&g_PcapCompileCriticalSection);
+#endif
+
+ return (rc);
}
/*
* 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.
orig_linktype = -1;
orig_nl = -1;
label_stack_depth = 0;
+ vlan_stack_depth = 0;
reg_off_ll = -1;
reg_off_macpl = -1;
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
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.
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
* 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
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.
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.
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.
register int proto;
{
struct block *b0, *b1, *b2;
+ const char *description;
/* are we checking MPLS-encapsulated packets? */
if (label_stack_depth > 0) {
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");
case DLT_FDDI:
/*
- * XXX - check for asynchronous frames, as per RFC 1103.
+ * XXX - check for LLC frames.
*/
return gen_llc_linktype(proto);
/*NOTREACHED*/
* 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;
+ }
}
/*
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.
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);
b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x60, 0xf0);
gen_and(b0, b1);
return b1;
-
+
default:
abort();
}
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;
}
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;
}
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;
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)
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);
/* 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
*/
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)
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);
}
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
* 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);
return b1;
}
-/*
+/*
* Filtering for MTP2 messages based on li value
* FISU, length is null
* LSSU, length is 1 or 2
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);
#include <net/pfvar.h>
#include <net/if_pflog.h>
#endif
+#include "llc.h"
#include "ieee80211.h"
#include <pcap/namedb.h>
{ 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;
%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
| PPPOES { $$ = gen_pppoes(-1); }
| pfvar { $$ = $1; }
| pqual p80211 { $$ = $2; }
+ | pllc { $$ = $1; }
;
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); }
}
;
+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;
| 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); }
| paren pnum ')' { $$ = $2; }
;
atmtype: LANE { $$ = A_LANE; }
- | LLC { $$ = A_LLC; }
| METAC { $$ = A_METAC; }
| BCC { $$ = A_BCC; }
| OAMF4EC { $$ = A_OAMF4EC; }
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) {
* 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))
* 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
a /= b;
break;
+ case BPF_MOD:
+ if (b == 0)
+ bpf_error("modulus by zero");
+ a %= b;
+ break;
+
case BPF_AND:
a &= b;
break;
a |= b;
break;
+ case BPF_XOR:
+ a ^= b;
+ break;
+
case BPF_LSH:
a <<= b;
break;
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);
* 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;
}
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);
*/
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;
{
struct pcap_bpf *pb = p->priv;
int status = 0;
+#ifdef HAVE_BSD_IEEE80211
+ int retv;
+#endif
int fd;
#ifdef LIFNAMSIZ
char *zonesep;
#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;
}
if (ioctl(fd, BIOCGETZMAX, (caddr_t)&zbufmax) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGETZMAX: %s",
pcap_strerror(errno));
+ status = PCAP_ERROR;
goto bad;
}
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() */
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);
/*
* 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;
}
*/
#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
+
+/*
+ */
+#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;
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);
}
/*
- * 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);
}
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)
}
/*
- * 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;
}
.\" 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
#ifdef DL_HP_RAWDLS
struct pcap_dlpi *pd = p->priv;
#endif
+ int status = 0;
+ int retv;
register char *cp;
int ppa;
#ifdef HAVE_SOLARIS
#ifndef HAVE_DEV_DLPI
char dname2[100];
#endif
- int status = PCAP_ERROR;
#ifdef HAVE_DEV_DLPI
/*
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;
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;
} 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));
}
** 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
}
*/
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 */
/*
** 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 */
** 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;
/*
** 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;
}
** 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
}
/* 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 */
** 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
** 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
** 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
/*
** 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;
#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.
*/
.\" 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
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"
.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
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).
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
#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 */
/* 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.
*/
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
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;
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;
* 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
* 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
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
.\" 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
/*
* 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
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);
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)
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);
* 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,
/*
* 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.
* 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,
*/
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) {
/*
* 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) {
/*
{
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;
* 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.
/*
* 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;
}
}
/*
* 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.
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
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;
}
}
*
* 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.
*/
/* 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;
}
/*
* 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 */
/*
* 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);
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;
}
* 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)) {
* 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()".
*
* 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
#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
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 ||
/*
* It doesn't support monitor mode.
*/
+ close(sock_fd);
return PCAP_ERROR_RFMON_NOTSUP;
}
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;
* 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
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) {
/* 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;
}
}
{
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.
* 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))
int pkts = 0;
int ret;
+again:
if (handlep->current_packet == NULL) {
/* wait for frames availability.*/
ret = pcap_wait_for_frames_mmap(handle);
}
}
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 */
return PCAP_ERROR_BREAK;
}
}
+ if (pkts == 0 && handlep->timeout == 0) {
+ /* Block until we see a packet. */
+ goto again;
+ }
return pkts;
}
#endif /* HAVE_TPACKET3 */
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,
{
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,
* 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;
/*
* 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.
* 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.
* 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));
/*
* 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) {
/*
* 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)
* 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)
* 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);
* 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);
* 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,
* 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));
* 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);
* 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);
* 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;
* 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);
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.
*
*/
#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;
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)
#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)
* 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)
#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)
* 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)
/* 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;
}
* 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);
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));
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));
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,
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,
* 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;
* "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;
}
}
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;
}
}
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;
.\" 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
#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"
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;
};
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;
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);
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?
}
}
- 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;
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);
}
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
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,
/* 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;
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;
}
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.
#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 */
.\" 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
return handlep->mmapbuf != MAP_FAILED;
}
+#ifdef HAVE_LINUX_USBDEVICE_FS_H
+
#define CTRL_TIMEOUT (5*1000) /* milliseconds */
#define USB_DIR_IN 0x80
}
closedir(dir);
}
+#endif /* HAVE_LINUX_USBDEVICE_FS_H */
pcap_t *
usb_create(const char *device, char *ebuf, int *is_ours)
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
/* 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 */
}
/* 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;
}
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
{
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)
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) {
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;
/*
* 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;
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
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)
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
.\" 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
.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
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
.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;
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
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
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
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 {
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);
}
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"),
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
};
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);
}
*/
#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
+
+/*
+ */
+#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
/*
* The instruction encodings.
+ *
+ * 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
#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
#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)
#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
/* 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.
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.
*/
#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
/*
.\" 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
.\" 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
.\" 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
.\" 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
.\" 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
.\" 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
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
(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;
.\" 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
.\" 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
.\" 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
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
.\" 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
.\" 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
.\" 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
.\" 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
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
.\" 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
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
.\" 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
*/
p->oneshot_callback = pcap_oneshot;
+ /*
+ * Savefiles never require special BPF code generation.
+ */
+ p->bpf_codegen_flags = 0;
+
p->activated = 1;
return (p);
hsls return HSLS;
[ \r\n\t] ;
-[+\-*/:\[\]!<>()&|=] return yytext[0];
+[+\-*/%:\[\]!<>()&|\^=] return yytext[0];
">=" return GEQ;
"<=" return LEQ;
"!=" return NEQ;
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.
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?
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;
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) {
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);
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;
/* 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.
*/
char *infile;
int Oflag;
long snaplen;
+ char *p;
int dlt;
bpf_u_int32 netmask = PCAP_NETMASK_UNKNOWN;
char *cmdbuf;
}
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);
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);