Upgrade to libpcap-1.10.4
This a breaking change and depends on changes to fuchsia.git found in
https://fuchsia-review.googlesource.com/c/fuchsia/+/917279
(change ID is Ib87596690d5fa272a00803af06e67e9e1746a6d0).
Bug: 133434
Change-Id: Ibd8fca1ab0bd8498121dae9586a905e7bad2c3b5
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/github.com/the-tcpdump-group/libpcap/+/916389
Reviewed-by: Chris Lewis <cflewis@google.com>
Reviewed-by: Brian Bosak <bbosak@google.com>
diff --git a/CREDITS b/CREDITS
index d01e832..4b820ee 100644
--- a/CREDITS
+++ b/CREDITS
@@ -33,6 +33,7 @@
Baptiste Peugnez <baptiste dot peugnez at cea dot fr>
Baruch Siach <baruch at tkos dot co dot il>
Bill Parker <wp02855 at gmail dot com>
+ Biswapriyo Nath <nathbappai at gmail dot com>
blazeable <blazeable at blazeable dot eu>
bleader <bleader at ratonland dot org>
Brent Cook <brent at boundary dot com>
@@ -58,6 +59,7 @@
Dave Barach <dave at barachs dot net>
David Clark <david dot clark at datasoft dot com>
David Kaelbling <drk at sgi dot com>
+ David Karoly <david dot karoly at outlook dot com>
David Ward <david dot ward at ll dot mit dot edu>
David Young <dyoung at ojctech dot com>
Dean Gaudet <dean at arctic dot org>
@@ -68,11 +70,13 @@
Dustin Spicuzza <dustin at virtualroadside dot com>
dzejarczech <dzejarczech at sourceforge dot net>
Edward Sheldrake <ejs1920 at sourceforge dot net>
+ Eli Schwartz <eschwartz93 at gmail dot com>
Eric Anderson <anderse at hpl dot hp dot com>
Erik de Castro Lopo <erik dot de dot castro dot lopo at sensorynetworks dot com>
Fedor Sakharov <fedor dot sakharov at gmail dot com>
Felix Janda <felix dot janda at posteo dot de>
Felix Obenhuber <felix at obenhuber dot de>
+ fghzxm <fghzxm at outlook dot com>
Florent Drouin <Florent dot Drouin at alcatel-lucent dot fr>
Florian Fainelli <f dot fainelli at gmail dot com>
François Revol <revol at free dot fr>
@@ -132,6 +136,7 @@
Kris Katterjohn <katterjohn at gmail dot com>
Krzysztof Halasa <khc at pm dot waw dot pl>
Lennert Buytenhek <buytenh at wantstofly dot org>
+ Li kunyu <kunyu at nfschina dot com>
lixiaoyan <lixiaoyan at google dot com>
Lorenzo Cavallaro <sullivan at sikurezza dot org>
Loris Degioanni <loris at netgroup-serv dot polito dot it>
@@ -157,6 +162,7 @@
Max Laier <max at love2party dot net>
Michal Kubecek <mkubecek at suse dot cz>
Michal Labedzki <michal dot labedzki at tieto dot com>
+ Michal Ruprich <michalruprich at gmail dot com>
Michal Sekletar <msekleta at redhat dot com>
Mike Frysinger <vapier at gmail dot com>
Mike Kershaw <dragorn at kismetwireless dot net>
@@ -166,6 +172,7 @@
Monroe Williams <monroe at pobox dot com>
Myricom Help <myri at users dot noreply dot github dot com>
Nan Xiao <nan at chinadtrace dot org>
+ nic-kaczinsky <68271784+nic-kaczinsky at users dot noreply dot github dot com>
Nick Kelsey <nickk at silicondust dot com>
Nicolas Dade <ndade at nsd dot dyndns dot org>
Niko Delarich <niko dot delarich at gmail dot com>
@@ -181,7 +188,7 @@
Ørjan Malde <red at foxi dot me>
Paolo Abeni <pabeni at redhat dot com>
Patrick Marie <mycroft at virgaria dot org>
- Patrick McHardy <kaber at trash not net>
+ Patrick McHardy <kaber at trash dot net>
Paul Mundt <lethal at linux-sh dot org>
Pavel Kankovsky <kan at dcit dot cz>
Pawel Brzezinski <pawel dot brzezinski at harman dot com>
@@ -193,6 +200,7 @@
Philippe Antoine <contact at catenacyber dot fr>
Phil Wood <cpw at lanl dot gov>
Rafal Maszkowski <rzm at icm dot edu dot pl>
+ ramin <lordrasmus at gmail dot com>
<rcb-isis at users dot sourceforge dot net>
Richard Stearn <richard at rns-stearn dot demon dot co dot uk>
Rick Jones <raj at cup dot hp dot com>
@@ -208,6 +216,7 @@
Sebastian Krahmer <krahmer at cs dot uni-potsdam dot de>
Sebastien Roy <Sebastien dot Roy at Sun dot COM>
Sepherosa Ziehau <sepherosa at gmail dot com>
+ Shane Kerr <shane at time-travellers dot org>
Shaun Clowes <delius at progsoc dot uts dot edu dot au>
solofox <wensg100 at sina dot com>
Solomon Peachy <pizza at shaftnet dot org>
diff --git a/README.md b/README.md
index d89e3bb..e38b9a1 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@
system-dependent packet capture modules in each application.
```text
-formerly from Lawrence Berkeley National Laboratory
+formerly from Lawrence Berkeley National Laboratory
Network Research Group <libpcap@ee.lbl.gov>
ftp://ftp.ee.lbl.gov/old/libpcap-0.4a7.tar.Z
```
@@ -52,12 +52,10 @@
with the underlying kernel subsystem, but this is not yet implemented.
BPF is standard in 4.4BSD, BSD/OS, NetBSD, FreeBSD, OpenBSD, DragonFly
-BSD, and macOS; an older, modified and undocumented version is standard
-in AIX. {DEC OSF/1, Digital UNIX, Tru64 UNIX} uses the packetfilter
-interface but has been extended to accept BPF filters (which libpcap
-utilizes). Also, you can add BPF filter support to Ultrix using the
-kernel source and/or object patches available
-[here](https://www.tcpdump.org/other/bpfext42.tar.Z).
+BSD, macOS, and Solaris 11; an older, modified and undocumented version
+is standard in AIX. {DEC OSF/1, Digital UNIX, Tru64 UNIX} uses the
+packetfilter interface but has been extended to accept BPF filters
+(which libpcap utilizes).
Linux has a number of BPF based systems, and libpcap does not support
any of the eBPF mechanisms as yet, although it supports many of the
diff --git a/RELEASE_VERSION b/RELEASE_VERSION
index 4dae298..18b3114 100644
--- a/RELEASE_VERSION
+++ b/RELEASE_VERSION
@@ -1 +1 @@
-1.10.1
+1.10.4
diff --git a/charconv.h b/charconv.h
index a37d424..93103d4 100644
--- a/charconv.h
+++ b/charconv.h
@@ -32,8 +32,8 @@
* SUCH DAMAGE.
*/
-#ifndef charonv_h
-#define charonv_h
+#ifndef charconv_h
+#define charconv_h
#ifdef _WIN32
extern wchar_t *cp_to_utf_16le(UINT codepage, const char *cp_string, DWORD flags);
@@ -41,4 +41,4 @@
extern void utf_8_to_acp_truncated(char *);
#endif
-#endif
+#endif /* charconv_h */
diff --git a/config.h.in b/config.h.in
index a1e371a..282a955 100644
--- a/config.h.in
+++ b/config.h.in
@@ -72,8 +72,8 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
-/* Define to 1 if you have the `dag' library (-ldag). */
-#undef HAVE_LIBDAG
+/* Define to 1 if you have the `bsd' library (-lbsd). */
+#undef HAVE_LIBBSD
/* if libdlpi exists */
#undef HAVE_LIBDLPI
@@ -132,9 +132,6 @@
/* Define to 1 if you have the <net/pfilt.h> header file. */
#undef HAVE_NET_PFILT_H
-/* Define to 1 if you have the <net/pfvar.h> header file. */
-#undef HAVE_NET_PFVAR_H
-
/* Define to 1 if you have the <net/raw.h> header file. */
#undef HAVE_NET_RAW_H
@@ -144,9 +141,6 @@
/* if there's an os_proto.h for this platform, to use additional prototypes */
#undef HAVE_OS_PROTO_H
-/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
-#undef HAVE_PF_NAT_THROUGH_PF_NORDR
-
/* Define to 1 if you have a POSIX-style `strerror_r' function. */
#undef HAVE_POSIX_STRERROR_R
@@ -271,9 +265,6 @@
/* IPv6 */
#undef INET6
-/* path for device for USB sniffing */
-#undef LINUX_USB_MON_DEV
-
/* Define to 1 if netinet/ether.h declares `ether_hostton' */
#undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
@@ -328,6 +319,12 @@
/* target host supports RDMA sniffing */
#undef PCAP_SUPPORT_RDMASNIFF
+/* The size of `const void *', as computed by sizeof. */
+#undef SIZEOF_CONST_VOID_P
+
+/* The size of `void *', as computed by sizeof. */
+#undef SIZEOF_VOID_P
+
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
diff --git a/diag-control.h b/diag-control.h
index 47d31b9..ae2641b 100644
--- a/diag-control.h
+++ b/diag-control.h
@@ -37,12 +37,12 @@
#include "pcap/compiler-tests.h"
-#ifndef _MSC_VER
+#if PCAP_IS_AT_LEAST_CLANG_VERSION(2,8) || PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
/*
* Clang and GCC both support this way of putting pragmas into #defines.
- * We don't use it unless we have a compiler that supports it; the
- * warning-suppressing pragmas differ between Clang and GCC, so we test
- * for both of those separately.
+ * We use it only if we have a compiler that supports it; see below
+ * for the code that uses it and the #defines that control whether
+ * that code is used.
*/
#define PCAP_DO_PRAGMA(x) _Pragma (#x)
#endif
@@ -86,7 +86,51 @@
/*
* Suppress Flex, narrowing, and deprecation warnings.
*/
-#if defined(_MSC_VER)
+#if PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
+ /*
+ * This is Clang 2.8 or later; we can use "clang diagnostic
+ * ignored -Wxxx" and "clang diagnostic push/pop".
+ *
+ * Suppress -Wdocumentation warnings; GCC doesn't support -Wdocumentation,
+ * at least according to the GCC 7.3 documentation. Apparently, Flex
+ * generates code that upsets at least some versions of Clang's
+ * -Wdocumentation.
+ *
+ * (This could be clang-cl, which defines _MSC_VER, so test this
+ * before testing _MSC_VER.)
+ */
+ #define DIAG_OFF_FLEX \
+ PCAP_DO_PRAGMA(clang diagnostic push) \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wsign-compare") \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wdocumentation") \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshorten-64-to-32") \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wmissing-noreturn") \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunused-parameter") \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
+ #define DIAG_ON_FLEX \
+ PCAP_DO_PRAGMA(clang diagnostic pop)
+
+ /*
+ * Suppress the only narrowing warnings you get from Clang.
+ */
+ #define DIAG_OFF_NARROWING \
+ PCAP_DO_PRAGMA(clang diagnostic push) \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshorten-64-to-32")
+
+ #define DIAG_ON_NARROWING \
+ PCAP_DO_PRAGMA(clang diagnostic pop)
+
+ /*
+ * Suppress deprecation warnings.
+ */
+ #define DIAG_OFF_DEPRECATION \
+ PCAP_DO_PRAGMA(clang diagnostic push) \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wdeprecated-declarations")
+ #define DIAG_ON_DEPRECATION \
+ PCAP_DO_PRAGMA(clang diagnostic pop)
+ #define DIAG_OFF_FORMAT_TRUNCATION
+ #define DIAG_ON_FORMAT_TRUNCATION
+#elif defined(_MSC_VER)
/*
* This is Microsoft Visual Studio; we can use __pragma(warning(disable:XXXX))
* and __pragma(warning(push/pop)).
@@ -121,45 +165,8 @@
__pragma(warning(disable:4996))
#define DIAG_ON_DEPRECATION \
__pragma(warning(pop))
-#elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
- /*
- * This is Clang 2.8 or later; we can use "clang diagnostic
- * ignored -Wxxx" and "clang diagnostic push/pop".
- *
- * Suppress -Wdocumentation warnings; GCC doesn't support -Wdocumentation,
- * at least according to the GCC 7.3 documentation. Apparently, Flex
- * generates code that upsets at least some versions of Clang's
- * -Wdocumentation.
- */
- #define DIAG_OFF_FLEX \
- PCAP_DO_PRAGMA(clang diagnostic push) \
- PCAP_DO_PRAGMA(clang diagnostic ignored "-Wsign-compare") \
- PCAP_DO_PRAGMA(clang diagnostic ignored "-Wdocumentation") \
- PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshorten-64-to-32") \
- PCAP_DO_PRAGMA(clang diagnostic ignored "-Wmissing-noreturn") \
- PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunused-parameter") \
- PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
- #define DIAG_ON_FLEX \
- PCAP_DO_PRAGMA(clang diagnostic pop)
-
- /*
- * Suppress the only narrowing warnings you get from Clang.
- */
- #define DIAG_OFF_NARROWING \
- PCAP_DO_PRAGMA(clang diagnostic push) \
- PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshorten-64-to-32")
-
- #define DIAG_ON_NARROWING \
- PCAP_DO_PRAGMA(clang diagnostic pop)
-
- /*
- * Suppress deprecation warnings.
- */
- #define DIAG_OFF_DEPRECATION \
- PCAP_DO_PRAGMA(clang diagnostic push) \
- PCAP_DO_PRAGMA(clang diagnostic ignored "-Wdeprecated-declarations")
- #define DIAG_ON_DEPRECATION \
- PCAP_DO_PRAGMA(clang diagnostic pop)
+ #define DIAG_OFF_FORMAT_TRUNCATION
+ #define DIAG_ON_FORMAT_TRUNCATION
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
/*
* This is GCC 4.6 or later, or a compiler claiming to be that.
@@ -188,6 +195,22 @@
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wdeprecated-declarations")
#define DIAG_ON_DEPRECATION \
PCAP_DO_PRAGMA(GCC diagnostic pop)
+
+ /*
+ * Suppress format-truncation= warnings.
+ * GCC 7.1 had introduced this warning option. Earlier versions (at least
+ * one particular copy of GCC 4.6.4) treat the request as a warning.
+ */
+ #if PCAP_IS_AT_LEAST_GNUC_VERSION(7,1)
+ #define DIAG_OFF_FORMAT_TRUNCATION \
+ PCAP_DO_PRAGMA(GCC diagnostic push) \
+ PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wformat-truncation=")
+ #define DIAG_ON_FORMAT_TRUNCATION \
+ PCAP_DO_PRAGMA(GCC diagnostic pop)
+ #else
+ #define DIAG_OFF_FORMAT_TRUNCATION
+ #define DIAG_ON_FORMAT_TRUNCATION
+ #endif
#else
/*
* Neither Visual Studio, nor Clang 2.8 or later, nor GCC 4.6 or later
@@ -200,6 +223,8 @@
#define DIAG_ON_NARROWING
#define DIAG_OFF_DEPRECATION
#define DIAG_ON_DEPRECATION
+ #define DIAG_OFF_FORMAT_TRUNCATION
+ #define DIAG_ON_FORMAT_TRUNCATION
#endif
#ifdef YYBYACC
@@ -219,21 +244,21 @@
* In addition, the generated code may have functions with unreachable
* code, so suppress warnings about those.
*/
- #if defined(_MSC_VER)
+ #if PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
+ /*
+ * This is Clang 2.8 or later (including clang-cl, so test this
+ * before _MSC_VER); we can use "clang diagnostic ignored -Wxxx".
+ */
+ #define DIAG_OFF_BISON_BYACC \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshadow") \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
+ #elif defined(_MSC_VER)
/*
* This is Microsoft Visual Studio; we can use
* __pragma(warning(disable:XXXX)).
*/
#define DIAG_OFF_BISON_BYACC \
__pragma(warning(disable:4702))
- #elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
- /*
- * This is Clang 2.8 or later; we can use "clang diagnostic
- * ignored -Wxxx".
- */
- #define DIAG_OFF_BISON_BYACC \
- PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshadow") \
- PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
/*
* This is GCC 4.6 or later, or a compiler claiming to be that.
@@ -257,7 +282,14 @@
* The generated code may have functions with unreachable code and
* switches with only a default case, so suppress warnings about those.
*/
- #if defined(_MSC_VER)
+ #if PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
+ /*
+ * This is Clang 2.8 or later (including clang-cl, so test this
+ * before _MSC_VER); we can use "clang diagnostic ignored -Wxxx".
+ */
+ #define DIAG_OFF_BISON_BYACC \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
+ #elif defined(_MSC_VER)
/*
* This is Microsoft Visual Studio; we can use
* __pragma(warning(disable:XXXX)).
@@ -270,13 +302,6 @@
__pragma(warning(disable:4242)) \
__pragma(warning(disable:4244)) \
__pragma(warning(disable:4702))
- #elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
- /*
- * This is Clang 2.8 or later; we can use "clang diagnostic
- * ignored -Wxxx".
- */
- #define DIAG_OFF_BISON_BYACC \
- PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
/*
* This is GCC 4.6 or later, or a compiler claiming to be that.
@@ -294,4 +319,20 @@
#endif
#endif
+/*
+ * GCC needs this on AIX for longjmp().
+ */
+#if PCAP_IS_AT_LEAST_GNUC_VERSION(5,1)
+ /*
+ * Beware that the effect of this builtin is more than just squelching the
+ * warning! GCC trusts it enough for the process to segfault if the control
+ * flow reaches the builtin (an infinite empty loop in the same context would
+ * squelch the warning and ruin the process too, albeit in a different way).
+ * So please remember to use this very carefully.
+ */
+ #define PCAP_UNREACHABLE __builtin_unreachable();
+#else
+ #define PCAP_UNREACHABLE
+#endif
+
#endif /* _diag_control_h */
diff --git a/doc/README.capture-module b/doc/README.capture-module
deleted file mode 100644
index e13eaf3..0000000
--- a/doc/README.capture-module
+++ /dev/null
@@ -1,353 +0,0 @@
- How to write a libpcap module
-
-WARNING: this document describes an unstable interface; future releases
-of libpcap may, and some probably will, change the interface in an
-incompatible fashion. If you submit your module to the libpcap
-developers for inclusion in libpcap, not only does that make it more
-likely that it will be available in the libpcap provided by operating
-system vendors (such as Linux distributions), but it also means that we
-will attempt to update it to handle future changes to this interface.
-If we add new capabilities, we may have to ask you how to provide those
-additional capabilities if you're using an underlying mechanism for
-which we have neither the source code nor the documentation.
-
-NOTE: this document assumes familiarity with the entire libpcap API.
-
-TODO: more routines, more stuff that the activate routine has to do
-(such as setting the list of DLT_s), convert to Markdown?
-
-On Linux, *BSD, macOS, Solaris, AIX, HP-UX, IRIX, and Tru64 UNIX,
-Libpcap supports capturing on network interfaces as supported by the
-operating system networking stack, using the native packet capture
-mechanism provided by the OS. On Windows, it supports it with the help
-of the driver and library supplied by WinPcap and Npcap.
-
-In addition, it also supports capturing on other types of devices, such
-as:
-
- specialized capture cards, such as Endace DAG cards;
-
- network adapters that provide special high-performance code
- paths, such as CSPI Myricom adapters;
-
- buses such as USB;
-
- software communication channels such as D-Bus and Linux netlink;
-
- etc..
-
-Support for those devices is provided by modules compiled into libpcap.
-
-If you want to add such a module, you would first have to check the list
-of link-layer header types supported by libpcap, to see if one of those
-would be sufficient for your device. The current version of the list
-can be found at
-
- https://www.tcpdump.org/linktypes.html
-
-If none of those would work for your device, please read
-doc/DLT_ALLOCATE_HOWTO.md and the introductory paragraphs on the Web
-page mentioned above, and then send a request for the new link-layer
-header type to tcpdump-workers@lists.tcpdump.org.
-
-Once you have a link-layer header type value or values that you can use,
-you can add new module.
-
-The module should be a C source file, with a name of the form
-pcap-{MOD}.c, where {MOD} is a name appropriate for your device; for
-example, the support for DAG cards is in pcap-dag.c, and the support for
-capturing USB traffic on Linux is pcap-usb-linux.c.
-
-Your module is assumed to support one or more named devices. The names
-should be relatively short names, containing only lower-case
-alphanumeric characters, consisting of a prefix that ends with an
-alphabetic character and, if there can be more than one device instance,
-possibly followed by a numerical device ID, such as "mydevice" or
-"mydevice0"/"mydevice1"/.... If you have more than one type of device
-that you can support, you can have more than one prefix, each of which
-can be followed by a numerical device ID.
-
-The two exported functions that your module must provide are routines to
-provide a list of device instances and a program to initialize a
-created-but-not-activated pcap_t for an instance of one of your devices.
-
-The "list of device instances" routine takes, as arguments:
-
- a pointer to a pcap_if_list_t;
-
- a pointer to an error message buffer.
-
-The error message buffer may be assumed to be PCAP_ERRBUF_SIZE bytes
-large, but must not be assumed to be larger. By convention, the routine
-typically has a name containing "findalldevs".
-
-The routine should attempt to determine what device instances are
-available and add them to the list pointed to by the first argument;
-this may be impossible for some modules, but, for those modules, it may
-be difficult to capture on the devices using Wirehshark (although it
-should be possible to capture on them using tcpdump, TShark, or other
-programs that take a device name on the command line), so we recommend
-that your routine provide the list of devices if possible. If it
-cannot, it should just immediately return 0.
-
-The routine should add devices to the list by calling the add_dev()
-routine in libpcap, declared in the pcap-int.h header. It takes, as
-arguments:
-
- the pointer to the pcap_if_list_t passed as an argument to the
- routine;
-
- the device name, as described above;
-
- a 32-bit word of flags, as provided by pcap_findalldevs();
-
- a text description of the device, or NULL if there is no
- description;
-
- the error message buffer pointer provided to the routine.
-
-add_dev() will, if it succeeds, return a pointer to a pcap_if_t that was
-added to the list of devices. If it fails, it will return NULL; in this
-case, the error message buffer has been filled in with an error string,
-and your routine must return -1 to indicate the error.
-
-If your routine succeeds, it must return 0. If it fails, it must fill
-in the error message buffer with an error string and return -1.
-
-The "initialize the pcap_t" routine takes, as arguments:
-
- a pointer to a device name;
-
- a pointer to an error message buffer;
-
- a pointer to an int.
-
-It returns a pointer to a pcap_t.
-
-Your module will probably need, for each pcap_t for an opened device, a
-private data structure to maintain its own information about the opened
-device. These should be allocated per opened instance, not per device;
-if, for example, mydevice0 can be captured on by more than one program
-at the same time, there will be more than one pcap_t opened for
-mydevice0, and so there will be separate private data structures for
-each pcap_t. If you need to maintain per-device, rather than per-opened
-instance information, you will have to maintain that yourself.
-
-The routine should first check the device to see whether it looks like a
-device that this module would handle; for example, it should begin with
-one of the device name prefixes for your module and, if your devices
-have instance numbers, be followed by a number. If it is not one of
-those devices, you must set the integer pointed to by the third
-argument to 0, to indicate that this is *not* one of the devices for
-your module, and return NULL.
-
-If it *is* one of those devices, it should call pcap_create_common,
-passing to it the error message buffer as the first argument and the
-size of the per-opened instance data structure as the second argument.
-If it fails, it will return NULL; you must return NULL in this case.
-
-If it succeeds, the pcap_t pointed to by the return value has been
-partially initialized, but you will need to complete the process. It
-has a "priv" member, which is a void * that points to the private data
-structure attached to it; that structure has been initialized to zeroes.
-
-What you need to set are some function pointers to your routines to
-handle certain operations:
-
- activate_op
- the routine called when pcap_activate() is done on the
- pcap_t
-
- can_set_rfmon_op
- the routine called when pcap_can_set_rfmon() is done on
- the pcap_t - if your device doesn't support 802.11
- monitor mode, you can leave this as initialized by
- pcap_create_common(), as that routine will return "no,
- monitor mode isn't supported".
-
-Once you've set the activate_op and, if necessary, the can_set_rfmon_op,
-you must return the pcap_t * that was returned to you.
-
-Your activate routine takes, as an argument, a pointer to the pcap_t
-being activated, and returns an int.
-
-The perameters set for the device in the pcap_create() call, and after
-that call(), are mostly in the opt member of the pcap_t:
-
- device
- the name of the device
-
- timeout
- the buffering timeout, in milliseconds
-
- buffer_size
- the buffer size to use
-
- promisc
- 1 if promiscuous mode is to be used, 0 otherwise
-
- rfmon
- 1 if monitor mode is to be used, 0 otherwise
-
- immediate
- 1 if the device should be in immediate mode, 0 otherwise
-
- nonblock
- 1 if the device should be in non-blocking mode, 0
- otherwise
-
- tstamp_type
- the type of time stamp to supply
-
- tstamp_precision
- the time stamp precision to supply
-
-The snapshot member of the pcap_t structure will contain the snapshot
-length to be used.
-
-Your routine should attempt to set up the device for capturing. If it
-fails, it must return an error indication which is one of the PCAP_ERROR
-values. For PCAP_ERROR, it must also set the errbuf member of the
-pcap_t to an error string. For PCAP_ERROR_NO_SUCH_DEVICE and
-PCAP_ERROR_PERM_DENIED, it may set it to an error string providing
-additional information that may be useful for debugging, or may just
-leave it as a null string.
-
-If it succeeds, it must set certain function pointers in the pcap_t
-structure:
-
- read_op
- called whenever packets are to be read
-
- inject_op
- called whenever packets are to be injected
-
- setfilter_op
- called whenever pcap_setfilter() is called
-
- setdirection_op
- called whenever pcap_setdirection() is called
-
- set_datalink_op
- called whnever pcap_set_datalink() is called
-
- getnonblock_op
- called whenever pcap_getnonblock() is called
-
- setnonblock_op
- called whenever pcap_setnonblock() is called
-
- stats_op
- called whenever pcap_stats() is called
-
- cleanup_op
- called if the activate routine fails or pcap_close() is
- called
-
-and must also set the linktype member to the DLT_ value for the device.
-
-On UN*Xes, if the device supports waiting for packets to arrive with
-select()/poll()/epoll()/kqueues etc., it should set the selectable_fd
-member of the structure to the descriptor you would use with those
-calls. If it does not, then, if that's because the device polls for
-packets rather than receiving interrupts or other signals when packets
-arrive, it should have a struct timeval in the private data structure,
-set the value of that struct timeval to the poll timeout, and set the
-required_select_timeout member of the pcap_t to point to the struct
-timeval.
-
-The read_op routine is called when pcap_dispatch(), pcap_loop(),
-pcap_next(), or pcap_next_ex() is called. It is passed the same
-arguments as pcap_dispatch() is called.
-
-The routine should first check if the break_loop member of the pcap_t is
-non-zero and, if so, set that member to zero and return
-PCAP_ERROR_BREAK.
-
-Then, if the pcap_t is in blocking mode (as opposed to non-blocking
-mode), and there are no packets immediately available to be passed to
-the callback, it should block waiting for packets to arrive, using the
-buffering timeout, first, and read packets from the device if necessary.
-
-Then it should loop through the available packets, calling the callback
-routine for each packet:
-
- If the PACKET_COUNT_IS_UNLIMITED() macro evaluates to true when
- passed the packet count argument, the loop should continue until
- there are no more packets immediately available or the
- break_loop member of the pcap_t is non-zero. If the break_loop
- member is fount to be non-zero, it should set that member to
- zero and return PCAP_ERROR_BREAK.
-
- If it doesn't evaluat to true, then the loop should also
- terminate if the specified number of packets have been delivered
- to the callback.
-
-Note that there is *NO* requirement that the packet header or data
-provided to the callback remain available, or valid, after the callback
-routine returns; if the callback needs to save the data for other code
-to use, it must make a copy of that data. This means that the module is
-free to, for example, overwrite the buffer into which it read the
-packet, or release back to the kernel a packet in a memory-mapped
-buffer shared between the kernel and userland, after the callback
-returns.
-
-If an error occurs when reading packets from the device, it must set the
-errbuf member of the pcap_t to an error string and return PCAP_ERROR.
-
-If no error occurs, it must return the number of packets that were
-supplied to the callback routine.
-
-The inject routine is passed a pointer to the pcap_t, a buffer
-containing the contents of the packet to inject, and the number of bytes
-in the packet. If the device doesn't support packet injection, the
-routine must set the errbuf member of the pcap_t to a message indicating
-that packet injection isn't supported and return PCAP_ERROR. Otherwise,
-it should attempt to inject the packet; if the attempt fails, it must
-set the errbuf member of the pcap_t to an error message and return
-PCAP_ERROR. Otherwise, it should return the number of bytes injected.
-
-The setfilter routine is passed a pointer to the pcap_t and a pointer
-to a struct bpf_program containing a BPF program to be used as a filter.
-If the mechanism used by your module can perform filtering with a BPF
-program, it would attempt to set that filter to the specified program.
-
-If that failed because the program was too large, or used BPF features
-not supported by that mechanism, the module should fall back on
-filtering in userland by saving a copy of the filter with a call to
-install_bpf_program(), setting a flag in the private data instructure
-indicating that filtering is being done by the module and, in the read
-routine's main loop, checking the flag and, if it's set, calling
-pcap_filter(), passing it the fcode.bf_insns member of the pcap_t, the
-raw packet data, the on-the-wire length of the packet, and the captured
-length of the packet, and only passing the packet to the callback
-routine, and counting it, if pcap_filter() returns a non-zero value.
-(If the flag is not set, all packets should be passed to the callback
-routine and counted, as the filtering is being done by the mechanism
-used by the module.) If install_bpf_program() returns a negative value,
-the routine should return PCAP_ERROR.
-
-If the attempt to set the filter failed for any other reason, the
-routine must set the errbuf member of the pcap_t to an error message and
-return PCAP_ERROR.
-
-If the attempt to set the filter succeeded, or it failed because the
-mechanism used by the module rejected it and the call to
-install_bpf_program() succeeded, the routine should return 0.
-
-If the mechanism the module uses doesn't support filtering, the pointer
-to the setfilter routine can just be set to point to
-install_bpf_program; the module does not need a routine of its own to
-handle that.
-
-The setdirection routine is passed a pointer to the pcap_t and a
-pcap_direction_t indicating which packet directions should be accepted.
-If the module can't arrange to handle only incoming packets or only
-outgoing packets, it can set the pointer to the setdirection routine to
-NULL, and calls to pcap_setdirection() will fail with an error message
-indicating that setting the direction isn't supported.
-
-XXX describe set_datalink, including what the activate routine has to do
-XXX
-
-XXX describe the rest of the routines XXX
diff --git a/extract.h b/extract.h
index e776a9e..33579b1 100644
--- a/extract.h
+++ b/extract.h
@@ -127,7 +127,7 @@
* cast the pointer to point to one of those, and fetch through it;
* the GCC manual doesn't appear to explicitly say that
* __attribute__((packed)) causes the compiler to generate unaligned-safe
- * code, but it apppears to do so.
+ * code, but it appears to do so.
*
* We do this in case the compiler can generate code using those
* instructions to do an unaligned load and pass stuff to "ntohs()" or
diff --git a/fmtutils.c b/fmtutils.c
index 5c7ddad..2d35762 100644
--- a/fmtutils.c
+++ b/fmtutils.c
@@ -270,13 +270,21 @@
const char *fmt, ...)
{
va_list ap;
+
+ va_start(ap, fmt);
+ pcap_vfmt_errmsg_for_errno(errbuf, errbuflen, errnum, fmt, ap);
+ va_end(ap);
+}
+
+void
+pcap_vfmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
+ const char *fmt, va_list ap)
+{
size_t msglen;
char *p;
size_t errbuflen_remaining;
- va_start(ap, fmt);
- vsnprintf(errbuf, errbuflen, fmt, ap);
- va_end(ap);
+ (void)vsnprintf(errbuf, errbuflen, fmt, ap);
msglen = strlen(errbuf);
/*
@@ -378,6 +386,16 @@
const char *fmt, ...)
{
va_list ap;
+
+ va_start(ap, fmt);
+ pcap_vfmt_errmsg_for_win32_err(errbuf, errbuflen, errnum, fmt, ap);
+ va_end(ap);
+}
+
+void
+pcap_vfmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum,
+ const char *fmt, va_list ap)
+{
size_t msglen;
char *p;
size_t errbuflen_remaining;
@@ -385,9 +403,7 @@
wchar_t utf_16_errbuf[PCAP_ERRBUF_SIZE];
size_t utf_8_len;
- va_start(ap, fmt);
vsnprintf(errbuf, errbuflen, fmt, ap);
- va_end(ap);
msglen = strlen(errbuf);
/*
diff --git a/fmtutils.h b/fmtutils.h
index ba0f66c..4fa3448 100644
--- a/fmtutils.h
+++ b/fmtutils.h
@@ -34,6 +34,8 @@
#ifndef fmtutils_h
#define fmtutils_h
+#include <stdarg.h> /* we declare varargs functions */
+
#include "pcap/funcattrs.h"
#ifdef __cplusplus
@@ -44,10 +46,14 @@
void pcap_fmt_errmsg_for_errno(char *, size_t, int,
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
+void pcap_vfmt_errmsg_for_errno(char *, size_t, int,
+ PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(4, 0);
#ifdef _WIN32
void pcap_fmt_errmsg_for_win32_err(char *, size_t, DWORD,
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
+void pcap_vfmt_errmsg_for_win32_err(char *, size_t, DWORD,
+ PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(4, 0);
#endif
#ifdef __cplusplus
diff --git a/ftmacros.h b/ftmacros.h
index 3cd7505..7975463 100644
--- a/ftmacros.h
+++ b/ftmacros.h
@@ -45,7 +45,12 @@
* namespace to the maximum extent possible"?
*/
#if defined(sun) || defined(__sun)
- #define __EXTENSIONS__
+ /*
+ * On Solaris Clang defines __EXTENSIONS__ automatically.
+ */
+ #ifndef __EXTENSIONS__
+ #define __EXTENSIONS__
+ #endif
/*
* We also need to define _XPG4_2 in order to get
diff --git a/gencode.c b/gencode.c
index efdcb98..496e02f 100644
--- a/gencode.c
+++ b/gencode.c
@@ -1,4 +1,3 @@
-/*#define CHASE_CHAIN*/
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
* The Regents of the University of California. All rights reserved.
@@ -24,7 +23,6 @@
#include <config.h>
#endif
-#include <pcap-types.h>
#ifdef _WIN32
#include <ws2tcpip.h>
#else
@@ -43,25 +41,12 @@
#include <memory.h>
#include <setjmp.h>
#include <stdarg.h>
+#include <stdio.h>
#ifdef MSDOS
#include "pcap-dos.h"
#endif
-#ifdef HAVE_NET_PFVAR_H
-/*
- * In NetBSD <net/if.h> includes <net/dlt.h>, which is an older version of
- * "pcap/dlt.h" with a lower value of DLT_MATCHING_MAX. Include the headers
- * below before "pcap-int.h", which eventually includes "pcap/dlt.h", which
- * redefines DLT_MATCHING_MAX from what this version of NetBSD has to what
- * this version of libpcap has.
- */
-#include <sys/socket.h>
-#include <net/if.h>
-#include <net/pfvar.h>
-#include <net/if_pflog.h>
-#endif /* HAVE_NET_PFVAR_H */
-
#include "pcap-int.h"
#include "extract.h"
@@ -73,12 +58,13 @@
#include "ieee80211.h"
#include "atmuni31.h"
#include "sunatmpos.h"
+#include "pflog.h"
#include "ppp.h"
#include "pcap/sll.h"
#include "pcap/ipnet.h"
#include "arcnet.h"
+#include "diag-control.h"
-#include "grammar.h"
#include "scanner.h"
#if defined(linux)
@@ -475,6 +461,9 @@
va_end(ap);
longjmp(cstate->top_ctx, 1);
/*NOTREACHED*/
+#ifdef _AIX
+ PCAP_UNREACHABLE
+#endif /* _AIX */
}
static int init_linktype(compiler_state_t *, pcap_t *);
@@ -521,6 +510,7 @@
static struct block *gen_ether_linktype(compiler_state_t *, bpf_u_int32);
static struct block *gen_ipnet_linktype(compiler_state_t *, bpf_u_int32);
static struct block *gen_linux_sll_linktype(compiler_state_t *, bpf_u_int32);
+static struct slist *gen_load_pflog_llprefixlen(compiler_state_t *);
static struct slist *gen_load_prism_llprefixlen(compiler_state_t *);
static struct slist *gen_load_avs_llprefixlen(compiler_state_t *);
static struct slist *gen_load_radiotap_llprefixlen(compiler_state_t *);
@@ -574,7 +564,9 @@
bpf_u_int32, int);
static struct block *gen_portrange6(compiler_state_t *, u_int, u_int, int, int);
static int lookup_proto(compiler_state_t *, const char *, int);
+#if !defined(NO_PROTOCHAIN)
static struct block *gen_protochain(compiler_state_t *, bpf_u_int32, int);
+#endif /* !defined(NO_PROTOCHAIN) */
static struct block *gen_proto(compiler_state_t *, bpf_u_int32, int, int);
static struct slist *xfer_to_x(compiler_state_t *, struct arth *);
static struct slist *xfer_to_a(compiler_state_t *, struct arth *);
@@ -741,7 +733,7 @@
if (!p->activated) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"not-yet-activated pcap_t passed to pcap_compile");
- return (-1);
+ return (PCAP_ERROR);
}
#ifdef _WIN32
@@ -789,7 +781,7 @@
if (cstate.snaplen == 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snaplen of 0 rejects all packets");
- rc = -1;
+ rc = PCAP_ERROR;
goto quit;
}
@@ -805,7 +797,7 @@
pcap_set_extra(&cstate, scanner);
if (init_linktype(&cstate, p) == -1) {
- rc = -1;
+ rc = PCAP_ERROR;
goto quit;
}
if (pcap_parse(scanner, &cstate) != 0) {
@@ -815,7 +807,7 @@
#endif
if (cstate.e != NULL)
free(cstate.e);
- rc = -1;
+ rc = PCAP_ERROR;
goto quit;
}
@@ -824,7 +816,7 @@
* Catch errors reported by gen_retblk().
*/
if (setjmp(cstate.top_ctx)) {
- rc = -1;
+ rc = PCAP_ERROR;
goto quit;
}
cstate.ic.root = gen_retblk(&cstate, cstate.snaplen);
@@ -833,14 +825,14 @@
if (optimize && !cstate.no_optimize) {
if (bpf_optimize(&cstate.ic, p->errbuf) == -1) {
/* Failure */
- rc = -1;
+ rc = PCAP_ERROR;
goto quit;
}
if (cstate.ic.root == NULL ||
(cstate.ic.root->s.code == (BPF_RET|BPF_K) && cstate.ic.root->s.k == 0)) {
(void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"expression rejects all packets");
- rc = -1;
+ rc = PCAP_ERROR;
goto quit;
}
}
@@ -848,7 +840,7 @@
cstate.ic.root, &len, p->errbuf);
if (program->bf_insns == NULL) {
/* Failure */
- rc = -1;
+ rc = PCAP_ERROR;
goto quit;
}
program->bf_len = len;
@@ -886,7 +878,7 @@
p = pcap_open_dead(linktype_arg, snaplen_arg);
if (p == NULL)
- return (-1);
+ return (PCAP_ERROR);
ret = pcap_compile(p, program, buf, optimize, mask);
pcap_close(p);
return (ret);
@@ -1265,6 +1257,7 @@
case DLT_PPP:
case DLT_PPP_PPPD:
case DLT_C_HDLC: /* BSD/OS Cisco HDLC */
+ case DLT_HDLC: /* NetBSD (Cisco) HDLC */
case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */
cstate->off_linktype.constant_part = 2; /* skip HDLC-like framing */
cstate->off_linkpl.constant_part = 4; /* skip HDLC-like framing and protocol field */
@@ -1513,14 +1506,13 @@
cstate->off_nl_nosnap = 0; /* XXX - what does it do with 802.3 packets? */
break;
-#ifdef HAVE_NET_PFVAR_H
case DLT_PFLOG:
cstate->off_linktype.constant_part = 0;
- cstate->off_linkpl.constant_part = PFLOG_HDRLEN;
+ cstate->off_linkpl.constant_part = 0; /* link-layer header is variable-length */
+ cstate->off_linkpl.is_variable = 1;
cstate->off_nl = 0;
cstate->off_nl_nosnap = 0; /* no 802.2 LLC */
break;
-#endif
case DLT_JUNIPER_MFR:
case DLT_JUNIPER_MLFR:
@@ -1722,7 +1714,8 @@
cstate->off_nl = OFFSET_NOT_SET;
cstate->off_nl_nosnap = OFFSET_NOT_SET;
} else {
- bpf_set_error(cstate, "unknown data link type %d", cstate->linktype);
+ bpf_set_error(cstate, "unknown data link type %d (min %d, max %d)",
+ cstate->linktype, DLT_MATCHING_MIN, DLT_MATCHING_MAX);
return (-1);
}
break;
@@ -2344,6 +2337,59 @@
}
}
+/*
+ * Load a value relative to the beginning of the link-layer header after the
+ * pflog header.
+ */
+static struct slist *
+gen_load_pflog_llprefixlen(compiler_state_t *cstate)
+{
+ struct slist *s1, *s2;
+
+ /*
+ * Generate code to load the length of the pflog header into
+ * the register assigned to hold that length, if one has been
+ * assigned. (If one hasn't been assigned, no code we've
+ * generated uses that prefix, so we don't need to generate any
+ * code to load it.)
+ */
+ if (cstate->off_linkpl.reg != -1) {
+ /*
+ * The length is in the first byte of the header.
+ */
+ s1 = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
+ s1->s.k = 0;
+
+ /*
+ * Round it up to a multiple of 4.
+ * Add 3, and clear the lower 2 bits.
+ */
+ s2 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K);
+ s2->s.k = 3;
+ sappend(s1, s2);
+ s2 = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_K);
+ s2->s.k = 0xfffffffc;
+ sappend(s1, s2);
+
+ /*
+ * Now allocate a register to hold that value and store
+ * it.
+ */
+ s2 = new_stmt(cstate, BPF_ST);
+ s2->s.k = cstate->off_linkpl.reg;
+ sappend(s1, s2);
+
+ /*
+ * Now move it into the X register.
+ */
+ s2 = new_stmt(cstate, BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ return (s1);
+ } else
+ return (NULL);
+}
+
static struct slist *
gen_load_prism_llprefixlen(compiler_state_t *cstate)
{
@@ -2931,6 +2977,10 @@
case DLT_PPI:
s = gen_load_802_11_header_len(cstate, s, b->stmts);
break;
+
+ case DLT_PFLOG:
+ s = gen_load_pflog_llprefixlen(cstate);
+ break;
}
/*
@@ -3166,6 +3216,7 @@
/*NOTREACHED*/
case DLT_C_HDLC:
+ case DLT_HDLC:
switch (ll_proto) {
case LLCSAP_ISONS:
@@ -3395,7 +3446,6 @@
return gen_false(cstate);
}
-#ifdef HAVE_NET_PFVAR_H
case DLT_PFLOG:
/*
* af field is host byte order in contrast to the rest of
@@ -3410,7 +3460,6 @@
else
return gen_false(cstate);
/*NOTREACHED*/
-#endif /* HAVE_NET_PFVAR_H */
case DLT_ARCNET:
case DLT_ARCNET_LINUX:
@@ -5310,21 +5359,15 @@
switch (proto) {
case Q_SCTP:
- b1 = gen_proto(cstate, IPPROTO_SCTP, Q_IP, Q_DEFAULT);
- b0 = gen_proto(cstate, IPPROTO_SCTP, Q_IPV6, Q_DEFAULT);
- gen_or(b0, b1);
+ b1 = gen_proto(cstate, IPPROTO_SCTP, Q_DEFAULT, Q_DEFAULT);
break;
case Q_TCP:
- b1 = gen_proto(cstate, IPPROTO_TCP, Q_IP, Q_DEFAULT);
- b0 = gen_proto(cstate, IPPROTO_TCP, Q_IPV6, Q_DEFAULT);
- gen_or(b0, b1);
+ b1 = gen_proto(cstate, IPPROTO_TCP, Q_DEFAULT, Q_DEFAULT);
break;
case Q_UDP:
- b1 = gen_proto(cstate, IPPROTO_UDP, Q_IP, Q_DEFAULT);
- b0 = gen_proto(cstate, IPPROTO_UDP, Q_IPV6, Q_DEFAULT);
- gen_or(b0, b1);
+ b1 = gen_proto(cstate, IPPROTO_UDP, Q_DEFAULT, Q_DEFAULT);
break;
case Q_ICMP:
@@ -5351,9 +5394,7 @@
#endif
case Q_PIM:
- b1 = gen_proto(cstate, IPPROTO_PIM, Q_IP, Q_DEFAULT);
- b0 = gen_proto(cstate, IPPROTO_PIM, Q_IPV6, Q_DEFAULT);
- gen_or(b0, b1);
+ b1 = gen_proto(cstate, IPPROTO_PIM, Q_DEFAULT, Q_DEFAULT);
break;
#ifndef IPPROTO_VRRP
@@ -5430,18 +5471,14 @@
#define IPPROTO_AH 51
#endif
case Q_AH:
- b1 = gen_proto(cstate, IPPROTO_AH, Q_IP, Q_DEFAULT);
- b0 = gen_proto(cstate, IPPROTO_AH, Q_IPV6, Q_DEFAULT);
- gen_or(b0, b1);
+ b1 = gen_proto(cstate, IPPROTO_AH, Q_DEFAULT, Q_DEFAULT);
break;
#ifndef IPPROTO_ESP
#define IPPROTO_ESP 50
#endif
case Q_ESP:
- b1 = gen_proto(cstate, IPPROTO_ESP, Q_IP, Q_DEFAULT);
- b0 = gen_proto(cstate, IPPROTO_ESP, Q_IPV6, Q_DEFAULT);
- gen_or(b0, b1);
+ b1 = gen_proto(cstate, IPPROTO_ESP, Q_DEFAULT, Q_DEFAULT);
break;
case Q_ISO:
@@ -6035,20 +6072,10 @@
return v;
}
-#if 0
-struct stmt *
-gen_joinsp(struct stmt **s, int n)
-{
- return NULL;
-}
-#endif
-
+#if !defined(NO_PROTOCHAIN)
static struct block *
gen_protochain(compiler_state_t *cstate, bpf_u_int32 v, int proto)
{
-#ifdef NO_PROTOCHAIN
- return gen_proto(cstate, v, proto);
-#else
struct block *b0, *b;
struct slist *s[100];
int fix2, fix3, fix4, fix5;
@@ -6342,8 +6369,8 @@
gen_and(b0, b);
return b;
-#endif
}
+#endif /* !defined(NO_PROTOCHAIN) */
static struct block *
gen_check_802_11_data_frame(compiler_state_t *cstate)
@@ -6384,9 +6411,7 @@
gen_proto(compiler_state_t *cstate, bpf_u_int32 v, int proto, int dir)
{
struct block *b0, *b1;
-#ifndef CHASE_CHAIN
struct block *b2;
-#endif
if (dir != Q_DEFAULT)
bpf_error(cstate, "direction applied to 'proto'");
@@ -6418,11 +6443,7 @@
* So we always check for ETHERTYPE_IP.
*/
b0 = gen_linktype(cstate, ETHERTYPE_IP);
-#ifndef CHASE_CHAIN
b1 = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, v);
-#else
- b1 = gen_protochain(cstate, v, Q_IP);
-#endif
gen_and(b0, b1);
return b1;
@@ -6484,7 +6505,6 @@
case Q_IPV6:
b0 = gen_linktype(cstate, ETHERTYPE_IPV6);
-#ifndef CHASE_CHAIN
/*
* Also check for a fragment header before the final
* header.
@@ -6494,9 +6514,6 @@
gen_and(b2, b1);
b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, v);
gen_or(b2, b1);
-#else
- b1 = gen_protochain(cstate, v, Q_IPV6);
-#endif
gen_and(b0, b1);
return b1;
@@ -6550,6 +6567,7 @@
/*NOTREACHED*/
case DLT_C_HDLC:
+ case DLT_HDLC:
/*
* Cisco uses an Ethertype lookalike - for OSI,
* it's 0xfefe.
@@ -6935,12 +6953,14 @@
else
bpf_error(cstate, "unknown protocol: %s", name);
+#if !defined(NO_PROTOCHAIN)
case Q_PROTOCHAIN:
real_proto = lookup_proto(cstate, name, proto);
if (real_proto >= 0)
return gen_protochain(cstate, real_proto, proto);
else
bpf_error(cstate, "unknown protocol: %s", name);
+#endif /* !defined(NO_PROTOCHAIN) */
case Q_UNDEF:
syntax(cstate);
@@ -7113,8 +7133,10 @@
case Q_PROTO:
return gen_proto(cstate, v, proto, dir);
+#if !defined(NO_PROTOCHAIN)
case Q_PROTOCHAIN:
return gen_protochain(cstate, v, proto);
+#endif
case Q_UNDEF:
syntax(cstate);
@@ -7968,7 +7990,7 @@
default:
bpf_error(cstate, "not a broadcast link");
}
- /*NOTREACHED*/
+ /*NOTREACHED*/
case Q_IP:
/*
@@ -8300,12 +8322,10 @@
}
break;
-#ifdef HAVE_NET_PFVAR_H
case DLT_PFLOG:
b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, dir), BPF_B,
((dir == 0) ? PF_IN : PF_OUT));
break;
-#endif
case DLT_PPP_PPPD:
if (dir) {
@@ -8396,7 +8416,6 @@
return (b0);
}
-#ifdef HAVE_NET_PFVAR_H
/* PF firewall log matched interface */
struct block *
gen_pf_ifname(compiler_state_t *cstate, const char *ifname)
@@ -8547,91 +8566,6 @@
(bpf_u_int32)action);
return (b0);
}
-#else /* !HAVE_NET_PFVAR_H */
-struct block *
-gen_pf_ifname(compiler_state_t *cstate, const char *ifname _U_)
-{
- /*
- * Catch errors reported by us and routines below us, and return NULL
- * on an error.
- */
- if (setjmp(cstate->top_ctx))
- return (NULL);
-
- bpf_error(cstate, "libpcap was compiled without pf support");
- /*NOTREACHED*/
-}
-
-struct block *
-gen_pf_ruleset(compiler_state_t *cstate, char *ruleset _U_)
-{
- /*
- * Catch errors reported by us and routines below us, and return NULL
- * on an error.
- */
- if (setjmp(cstate->top_ctx))
- return (NULL);
-
- bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /*NOTREACHED*/
-}
-
-struct block *
-gen_pf_rnr(compiler_state_t *cstate, int rnr _U_)
-{
- /*
- * Catch errors reported by us and routines below us, and return NULL
- * on an error.
- */
- if (setjmp(cstate->top_ctx))
- return (NULL);
-
- bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /*NOTREACHED*/
-}
-
-struct block *
-gen_pf_srnr(compiler_state_t *cstate, int srnr _U_)
-{
- /*
- * Catch errors reported by us and routines below us, and return NULL
- * on an error.
- */
- if (setjmp(cstate->top_ctx))
- return (NULL);
-
- bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /*NOTREACHED*/
-}
-
-struct block *
-gen_pf_reason(compiler_state_t *cstate, int reason _U_)
-{
- /*
- * Catch errors reported by us and routines below us, and return NULL
- * on an error.
- */
- if (setjmp(cstate->top_ctx))
- return (NULL);
-
- bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /*NOTREACHED*/
-}
-
-struct block *
-gen_pf_action(compiler_state_t *cstate, int action _U_)
-{
- /*
- * Catch errors reported by us and routines below us, and return NULL
- * on an error.
- */
- if (setjmp(cstate->top_ctx))
- return (NULL);
-
- bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /*NOTREACHED*/
-}
-#endif /* HAVE_NET_PFVAR_H */
/* IEEE 802.11 wireless header */
struct block *
@@ -8721,7 +8655,7 @@
return (b);
} else
bpf_error(cstate, "ARCnet address used in non-arc expression");
- /*NOTREACHED*/
+ /*NOTREACHED*/
default:
bpf_error(cstate, "aid supported only on ARCnet");
@@ -8757,27 +8691,27 @@
case Q_ADDR1:
bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
- /*NOTREACHED*/
+ /*NOTREACHED*/
case Q_ADDR2:
bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
- /*NOTREACHED*/
+ /*NOTREACHED*/
case Q_ADDR3:
bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
- /*NOTREACHED*/
+ /*NOTREACHED*/
case Q_ADDR4:
bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
- /*NOTREACHED*/
+ /*NOTREACHED*/
case Q_RA:
bpf_error(cstate, "'ra' is only supported on 802.11");
- /*NOTREACHED*/
+ /*NOTREACHED*/
case Q_TA:
bpf_error(cstate, "'ta' is only supported on 802.11");
- /*NOTREACHED*/
+ /*NOTREACHED*/
}
abort();
/*NOTREACHED*/
@@ -8788,7 +8722,7 @@
{
struct block *b0, *b1;
- /* check for VLAN, including QinQ */
+ /* check for VLAN, including 802.1ad and QinQ */
b0 = gen_linktype(cstate, ETHERTYPE_8021Q);
b1 = gen_linktype(cstate, ETHERTYPE_8021AD);
gen_or(b0,b1);
@@ -9095,6 +9029,7 @@
switch (cstate->linktype) {
case DLT_C_HDLC: /* fall through */
+ case DLT_HDLC:
case DLT_EN10MB:
case DLT_NETANALYZER:
case DLT_NETANALYZER_TRANSPARENT:
diff --git a/gencode.h b/gencode.h
index 053e85f..93ca521 100644
--- a/gencode.h
+++ b/gencode.h
@@ -19,7 +19,19 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#ifndef gencode_h
+#define gencode_h
+
#include "pcap/funcattrs.h"
+/*
+ * pcap/bpf.h (a public header) needs u_char, u_short and u_int, which can be
+ * made available via either pcap-types.h (a private header) or pcap/pcap.h
+ * (a public header), none of which pcap/bpf.h includes. Include the private
+ * header to keep things simple, this way this private header should compile
+ * even if included early from another file.
+ */
+#include "pcap-types.h"
+#include "pcap/bpf.h" /* bpf_u_int32 and BPF_MEMWORDS */
/*
* ATM support:
@@ -400,3 +412,5 @@
/* XXX */
#define JT(b) ((b)->et.succ)
#define JF(b) ((b)->ef.succ)
+
+#endif /* gencode_h */
diff --git a/grammar.c b/grammar.c
index 6bfb96c..8a1caeb 100644
--- a/grammar.c
+++ b/grammar.c
@@ -3,9 +3,9 @@
/* (use YYMAJOR/YYMINOR for ifdefs dependent on parser version) */
#define YYBYACC 1
-#define YYMAJOR 1
-#define YYMINOR 9
-#define YYPATCH 20140715
+#define YYMAJOR 2
+#define YYMINOR 0
+#define YYPATCH 20221106
#define YYEMPTY (-1)
#define yyclearin (yychar = YYEMPTY)
@@ -13,6 +13,9 @@
#define YYRECOVERING() (yyerrflag != 0)
#define YYENOMEM (-2)
#define YYEOF 0
+#undef YYBTYACC
+#define YYBTYACC 0
+#define YYDEBUGSTR YYPREFIX "debug"
#ifndef yyparse
#define yyparse pcap_parse
@@ -62,6 +65,10 @@
#define yydefred pcap_defred
#endif /* yydefred */
+#ifndef yystos
+#define yystos pcap_stos
+#endif /* yystos */
+
#ifndef yydgoto
#define yydgoto pcap_dgoto
#endif /* yydgoto */
@@ -93,6 +100,19 @@
#ifndef yyrule
#define yyrule pcap_rule
#endif /* yyrule */
+
+#if YYBTYACC
+
+#ifndef yycindex
+#define yycindex pcap_cindex
+#endif /* yycindex */
+
+#ifndef yyctable
+#define yyctable pcap_ctable
+#endif /* yyctable */
+
+#endif /* YYBTYACC */
+
#define YYPREFIX "pcap_"
#define YYPURE 1
@@ -124,6 +144,13 @@
#include <config.h>
#endif
+/*
+ * grammar.h requires gencode.h and sometimes breaks in a polluted namespace
+ * (see ftmacros.h), so include it early.
+ */
+#include "gencode.h"
+#include "grammar.h"
+
#include <stdlib.h>
#ifndef _WIN32
@@ -145,17 +172,11 @@
#include "pcap-int.h"
-#include "gencode.h"
-#include "grammar.h"
#include "scanner.h"
-#ifdef HAVE_NET_PFVAR_H
-#include <net/if.h>
-#include <net/pfvar.h>
-#include <net/if_pflog.h>
-#endif
#include "llc.h"
#include "ieee80211.h"
+#include "pflog.h"
#include <pcap/namedb.h>
#ifdef HAVE_OS_PROTO_H
@@ -307,60 +328,87 @@
bpf_set_error(cstate, "can't parse filter expression: %s", msg);
}
-#ifdef HAVE_NET_PFVAR_H
+static const struct tok pflog_reasons[] = {
+ { PFRES_MATCH, "match" },
+ { PFRES_BADOFF, "bad-offset" },
+ { PFRES_FRAG, "fragment" },
+ { PFRES_SHORT, "short" },
+ { PFRES_NORM, "normalize" },
+ { PFRES_MEMORY, "memory" },
+ { PFRES_TS, "bad-timestamp" },
+ { PFRES_CONGEST, "congestion" },
+ { PFRES_IPOPTIONS, "ip-option" },
+ { PFRES_PROTCKSUM, "proto-cksum" },
+ { PFRES_BADSTATE, "state-mismatch" },
+ { PFRES_STATEINS, "state-insert" },
+ { PFRES_MAXSTATES, "state-limit" },
+ { PFRES_SRCLIMIT, "src-limit" },
+ { PFRES_SYNPROXY, "synproxy" },
+#if defined(__FreeBSD__)
+ { PFRES_MAPFAILED, "map-failed" },
+#elif defined(__NetBSD__)
+ { PFRES_STATELOCKED, "state-locked" },
+#elif defined(__OpenBSD__)
+ { PFRES_TRANSLATE, "translate" },
+ { PFRES_NOROUTE, "no-route" },
+#elif defined(__APPLE__)
+ { PFRES_DUMMYNET, "dummynet" },
+#endif
+ { 0, NULL }
+};
+
static int
pfreason_to_num(compiler_state_t *cstate, const char *reason)
{
- const char *reasons[] = PFRES_NAMES;
int i;
- for (i = 0; reasons[i]; i++) {
- if (pcap_strcasecmp(reason, reasons[i]) == 0)
- return (i);
- }
- bpf_set_error(cstate, "unknown PF reason \"%s\"", reason);
- return (-1);
+ i = str2tok(reason, pflog_reasons);
+ if (i == -1)
+ bpf_set_error(cstate, "unknown PF reason \"%s\"", reason);
+ return (i);
}
+static const struct tok pflog_actions[] = {
+ { PF_PASS, "pass" },
+ { PF_PASS, "accept" }, /* alias for "pass" */
+ { PF_DROP, "drop" },
+ { PF_DROP, "block" }, /* alias for "drop" */
+ { PF_SCRUB, "scrub" },
+ { PF_NOSCRUB, "noscrub" },
+ { PF_NAT, "nat" },
+ { PF_NONAT, "nonat" },
+ { PF_BINAT, "binat" },
+ { PF_NOBINAT, "nobinat" },
+ { PF_RDR, "rdr" },
+ { PF_NORDR, "nordr" },
+ { PF_SYNPROXY_DROP, "synproxy-drop" },
+#if defined(__FreeBSD__)
+ { PF_DEFER, "defer" },
+#elif defined(__OpenBSD__)
+ { PF_DEFER, "defer" },
+ { PF_MATCH, "match" },
+ { PF_DIVERT, "divert" },
+ { PF_RT, "rt" },
+ { PF_AFRT, "afrt" },
+#elif defined(__APPLE__)
+ { PF_DUMMYNET, "dummynet" },
+ { PF_NODUMMYNET, "nodummynet" },
+ { PF_NAT64, "nat64" },
+ { PF_NONAT64, "nonat64" },
+#endif
+ { 0, NULL },
+};
+
static int
pfaction_to_num(compiler_state_t *cstate, const char *action)
{
- if (pcap_strcasecmp(action, "pass") == 0 ||
- pcap_strcasecmp(action, "accept") == 0)
- return (PF_PASS);
- else if (pcap_strcasecmp(action, "drop") == 0 ||
- pcap_strcasecmp(action, "block") == 0)
- return (PF_DROP);
-#if HAVE_PF_NAT_THROUGH_PF_NORDR
- else if (pcap_strcasecmp(action, "rdr") == 0)
- return (PF_RDR);
- else if (pcap_strcasecmp(action, "nat") == 0)
- return (PF_NAT);
- else if (pcap_strcasecmp(action, "binat") == 0)
- return (PF_BINAT);
- else if (pcap_strcasecmp(action, "nordr") == 0)
- return (PF_NORDR);
-#endif
- else {
- bpf_set_error(cstate, "unknown PF action \"%s\"", action);
- return (-1);
- }
-}
-#else /* !HAVE_NET_PFVAR_H */
-static int
-pfreason_to_num(compiler_state_t *cstate, const char *reason _U_)
-{
- bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
- return (-1);
-}
+ int i;
-static int
-pfaction_to_num(compiler_state_t *cstate, const char *action _U_)
-{
- bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
- return (-1);
+ i = str2tok(action, pflog_actions);
+ if (i == -1)
+ bpf_set_error(cstate, "unknown PF action \"%s\"", action);
+ return (i);
}
-#endif /* HAVE_NET_PFVAR_H */
/*
* For calls that might return an "an error occurred" value.
@@ -369,14 +417,14 @@
#define CHECK_PTR_VAL(val) if (val == NULL) YYABORT
DIAG_OFF_BISON_BYACC
-#line 321 "grammar.y"
#ifdef YYSTYPE
#undef YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_DECLARED 1
#endif
#ifndef YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_DECLARED 1
-typedef union {
+#line 349 "grammar.y"
+typedef union YYSTYPE {
int i;
bpf_u_int32 h;
char *s;
@@ -391,7 +439,7 @@
struct block *rblk;
} YYSTYPE;
#endif /* !YYSTYPE_IS_DECLARED */
-#line 395 "grammar.c"
+#line 443 "grammar.c"
/* compatibility with bison */
#ifdef YYPARSE_PARAM
@@ -402,7 +450,7 @@
# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)
# endif
#else
-# define YYPARSE_DECL() yyparse(void * yyscanner, compiler_state_t * cstate)
+# define YYPARSE_DECL() yyparse(void *yyscanner, compiler_state_t *cstate)
#endif
/* Parameters sent to lex. */
@@ -414,13 +462,13 @@
# endif
# define YYLEX yylex(&yylval, YYLEX_PARAM)
#else
-# define YYLEX_DECL() yylex(YYSTYPE *yylval, void * yyscanner)
+# define YYLEX_DECL() yylex(YYSTYPE *yylval, void *yyscanner)
# define YYLEX yylex(&yylval, yyscanner)
#endif
/* Parameters sent to yyerror. */
#ifndef YYERROR_DECL
-#define YYERROR_DECL() yyerror(void * yyscanner, compiler_state_t * cstate, const char *s)
+#define YYERROR_DECL() yyerror(void *yyscanner, compiler_state_t *cstate, const char *s)
#endif
#ifndef YYERROR_CALL
#define YYERROR_CALL(msg) yyerror(yyscanner, cstate, msg)
@@ -550,7 +598,7 @@
#define AND 376
#define UMINUS 377
#define YYERRCODE 256
-typedef short YYINT;
+typedef int YYINT;
static const YYINT pcap_lhs[] = { -1,
0, 0, 24, 1, 1, 1, 1, 1, 20, 21,
2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
@@ -631,6 +679,40 @@
0, 196, 0, 217, 0, 26, 27, 139, 140, 133,
0, 199, 220, 159,
};
+#if defined(YYDESTRUCT_CALL) || defined(YYSTYPE_TOSTRING)
+static const YYINT pcap_stos[] = { 0,
+ 379, 403, 265, 266, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 291, 292, 293, 294, 295, 296,
+ 297, 298, 299, 300, 310, 321, 322, 323, 324, 325,
+ 326, 327, 328, 329, 330, 331, 332, 333, 334, 335,
+ 336, 337, 338, 339, 340, 341, 342, 343, 344, 345,
+ 346, 347, 348, 349, 350, 351, 352, 353, 354, 355,
+ 356, 357, 358, 359, 360, 361, 362, 363, 364, 365,
+ 366, 367, 368, 369, 370, 371, 372, 373, 33, 45,
+ 40, 380, 384, 385, 387, 388, 392, 393, 395, 398,
+ 401, 402, 404, 405, 407, 408, 409, 410, 414, 415,
+ 291, 291, 291, 291, 314, 314, 291, 291, 291, 314,
+ 420, 314, 419, 398, 401, 398, 398, 398, 297, 314,
+ 392, 395, 401, 375, 376, 399, 400, 314, 315, 316,
+ 317, 318, 381, 382, 398, 401, 402, 257, 258, 259,
+ 260, 261, 263, 264, 267, 268, 289, 290, 301, 302,
+ 303, 304, 305, 306, 307, 308, 309, 389, 390, 391,
+ 406, 311, 312, 313, 319, 320, 124, 38, 43, 45,
+ 42, 47, 62, 61, 60, 37, 94, 396, 397, 91,
+ 380, 393, 398, 384, 291, 396, 397, 401, 411, 412,
+ 291, 396, 397, 401, 416, 417, 124, 38, 62, 61,
+ 60, 394, 398, 392, 381, 384, 398, 401, 402, 381,
+ 384, 262, 47, 47, 382, 383, 386, 398, 381, 375,
+ 376, 375, 376, 291, 314, 421, 314, 423, 291, 314,
+ 424, 390, 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 41, 41, 41, 291, 291,
+ 411, 413, 291, 291, 416, 418, 291, 398, 316, 291,
+ 291, 41, 399, 400, 258, 258, 257, 257, 302, 93,
+ 58, 41, 400, 41, 400, 381, 381, 291, 314, 422,
+ 291, 411, 416, 93,
+};
+#endif /* YYDESTRUCT_CALL || YYSTYPE_TOSTRING */
static const YYINT pcap_dgoto[] = { 1,
191, 229, 144, 226, 93, 94, 227, 95, 96, 168,
169, 170, 97, 98, 212, 132, 188, 189, 100, 136,
@@ -702,6 +784,40 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
};
+#if YYBTYACC
+static const YYINT pcap_cindex[] = { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+};
+#endif
static const YYINT pcap_gindex[] = { 0,
211, 10, -115, 0, 102, 0, 0, 0, 0, 0,
46, 0, 1026, -90, 0, 261, -87, -81, 1063, -2,
@@ -984,6 +1100,145 @@
-1, -1, -1, -1, -1, 273, 274, -1, 301, 302,
303, 304, 305, 306, 307, 308, 309,
};
+#if YYBTYACC
+static const YYINT pcap_ctable[] = { -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+};
+#endif
#define YYFINAL 1
#ifndef YYDEBUG
#define YYDEBUG 0
@@ -994,14 +1249,14 @@
#if YYDEBUG
static const char *const pcap_name[] = {
-"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-"'!'",0,0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0,
-0,0,0,"':'",0,"'<'","'='","'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,"'['",0,"']'","'^'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,"'|'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"$end",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'!'",0,
+0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0,0,0,0,
+"':'",0,"'<'","'='","'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,"'['",0,"']'","'^'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"'|'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"DST","SRC","HOST","GATEWAY","NET",
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,"error","DST","SRC","HOST","GATEWAY","NET",
"NETMASK","PORT","PORTRANGE","LESS","GREATER","PROTO","PROTOCHAIN","CBYTE",
"ARP","RARP","IP","SCTP","TCP","UDP","ICMP","IGMP","IGRP","PIM","VRRP","CARP",
"ATALK","AARP","DECNET","LAT","SCA","MOPRC","MOPDL","TK_BROADCAST",
@@ -1013,9 +1268,13 @@
"SNP","CSNP","PSNP","STP","IPX","NETBEUI","LANE","LLC","METAC","BCC","SC",
"ILMIC","OAMF4EC","OAMF4SC","OAM","OAMF4","CONNECTMSG","METACONNECT","VPI",
"VCI","RADIO","FISU","LSSU","MSU","HFISU","HLSSU","HMSU","SIO","OPC","DPC",
-"SLS","HSIO","HOPC","HDPC","HSLS","LEX_ERROR","OR","AND","UMINUS",0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-"illegal-symbol",
+"SLS","HSIO","HOPC","HDPC","HSLS","LEX_ERROR","OR","AND","UMINUS","$accept",
+"prog","expr","id","nid","pid","term","rterm","qid","head","pqual","dqual",
+"aqual","ndaqual","arth","narth","byteop","pname","relop","irelop","pnum","and",
+"or","paren","not","null","other","pfvar","p80211","pllc","atmtype",
+"atmmultitype","atmfield","atmfieldvalue","atmvalue","atmlistvalue","mtp2type",
+"mtp3field","mtp3fieldvalue","mtp3value","mtp3listvalue","action","reason",
+"type","subtype","type_subtype","dir","illegal-symbol",
};
static const char *const pcap_rule[] = {
"$accept : prog",
@@ -1243,8 +1502,38 @@
};
#endif
+#if YYDEBUG
int yydebug;
-int yynerrs;
+#endif
+
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+#ifndef YYLLOC_DEFAULT
+#define YYLLOC_DEFAULT(loc, rhs, n) \
+do \
+{ \
+ if (n == 0) \
+ { \
+ (loc).first_line = YYRHSLOC(rhs, 0).last_line; \
+ (loc).first_column = YYRHSLOC(rhs, 0).last_column; \
+ (loc).last_line = YYRHSLOC(rhs, 0).last_line; \
+ (loc).last_column = YYRHSLOC(rhs, 0).last_column; \
+ } \
+ else \
+ { \
+ (loc).first_line = YYRHSLOC(rhs, 1).first_line; \
+ (loc).first_column = YYRHSLOC(rhs, 1).first_column; \
+ (loc).last_line = YYRHSLOC(rhs, n).last_line; \
+ (loc).last_column = YYRHSLOC(rhs, n).last_column; \
+ } \
+} while (0)
+#endif /* YYLLOC_DEFAULT */
+#endif /* defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED) */
+#if YYBTYACC
+
+#ifndef YYLVQUEUEGROWTH
+#define YYLVQUEUEGROWTH 32
+#endif
+#endif /* YYBTYACC */
/* define the initial stack-sizes */
#ifdef YYSTACKSIZE
@@ -1259,7 +1548,9 @@
#endif
#endif
+#ifndef YYINITSTACKSIZE
#define YYINITSTACKSIZE 200
+#endif
typedef struct {
unsigned stacksize;
@@ -1268,10 +1559,33 @@
YYINT *s_last;
YYSTYPE *l_base;
YYSTYPE *l_mark;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ YYLTYPE *p_base;
+ YYLTYPE *p_mark;
+#endif
} YYSTACKDATA;
+#if YYBTYACC
+
+struct YYParseState_s
+{
+ struct YYParseState_s *save; /* Previously saved parser state */
+ YYSTACKDATA yystack; /* saved parser stack */
+ int state; /* saved parser state */
+ int errflag; /* saved error recovery status */
+ int lexeme; /* saved index of the conflict lexeme in the lexical queue */
+ YYINT ctry; /* saved index in yyctable[] for this conflict */
+};
+typedef struct YYParseState_s YYParseState;
+#endif /* YYBTYACC */
+
+/* For use in generated program */
+#define yydepth (int)(yystack.s_mark - yystack.s_base)
+#if YYBTYACC
+#define yytrial (yyps->save)
+#endif /* YYBTYACC */
#if YYDEBUG
-#include <stdio.h> /* needed for printf */
+#include <stdio.h> /* needed for printf */
#endif
#include <stdlib.h> /* needed for malloc, etc */
@@ -1284,6 +1598,9 @@
unsigned newsize;
YYINT *newss;
YYSTYPE *newvs;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ YYLTYPE *newps;
+#endif
if ((newsize = data->stacksize) == 0)
newsize = YYINITSTACKSIZE;
@@ -1307,8 +1624,22 @@
data->l_base = newvs;
data->l_mark = newvs + i;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ newps = (YYLTYPE *)realloc(data->p_base, newsize * sizeof(*newps));
+ if (newps == 0)
+ return YYENOMEM;
+
+ data->p_base = newps;
+ data->p_mark = newps + i;
+#endif
+
data->stacksize = newsize;
data->s_last = data->s_base + newsize - 1;
+
+#if YYDEBUG
+ if (yydebug)
+ fprintf(stderr, "%sdebug: stack size increased to %d\n", YYPREFIX, newsize);
+#endif
return 0;
}
@@ -1317,16 +1648,63 @@
{
free(data->s_base);
free(data->l_base);
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ free(data->p_base);
+#endif
memset(data, 0, sizeof(*data));
}
#else
#define yyfreestack(data) /* nothing */
+#endif /* YYPURE || defined(YY_NO_LEAKS) */
+#if YYBTYACC
+
+static YYParseState *
+yyNewState(unsigned size)
+{
+ YYParseState *p = (YYParseState *) malloc(sizeof(YYParseState));
+ if (p == NULL) return NULL;
+
+ p->yystack.stacksize = size;
+ if (size == 0)
+ {
+ p->yystack.s_base = NULL;
+ p->yystack.l_base = NULL;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ p->yystack.p_base = NULL;
#endif
+ return p;
+ }
+ p->yystack.s_base = (YYINT *) malloc(size * sizeof(YYINT));
+ if (p->yystack.s_base == NULL) return NULL;
+ p->yystack.l_base = (YYSTYPE *) malloc(size * sizeof(YYSTYPE));
+ if (p->yystack.l_base == NULL) return NULL;
+ memset(p->yystack.l_base, 0, size * sizeof(YYSTYPE));
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ p->yystack.p_base = (YYLTYPE *) malloc(size * sizeof(YYLTYPE));
+ if (p->yystack.p_base == NULL) return NULL;
+ memset(p->yystack.p_base, 0, size * sizeof(YYLTYPE));
+#endif
+
+ return p;
+}
+
+static void
+yyFreeState(YYParseState *p)
+{
+ yyfreestack(&p->yystack);
+ free(p);
+}
+#endif /* YYBTYACC */
#define YYABORT goto yyabort
#define YYREJECT goto yyabort
#define YYACCEPT goto yyaccept
#define YYERROR goto yyerrlab
+#if YYBTYACC
+#define YYVALID do { if (yyps->save) goto yyvalid; } while(0)
+#define YYVALID_NESTED do { if (yyps->save && \
+ yyps->save->save == 0) goto yyvalid; } while(0)
+#endif /* YYBTYACC */
int
YYPARSE_DECL()
@@ -1335,10 +1713,62 @@
int yychar;
YYSTYPE yyval;
YYSTYPE yylval;
+ int yynerrs;
+
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ YYLTYPE yyloc; /* position returned by actions */
+ YYLTYPE yylloc; /* position from the lexer */
+#endif
/* variables for the parser stack */
YYSTACKDATA yystack;
- int yym, yyn, yystate;
+#if YYBTYACC
+
+ /* Current parser state */
+ static YYParseState *yyps = 0;
+
+ /* yypath != NULL: do the full parse, starting at *yypath parser state. */
+ static YYParseState *yypath = 0;
+
+ /* Base of the lexical value queue */
+ static YYSTYPE *yylvals = 0;
+
+ /* Current position at lexical value queue */
+ static YYSTYPE *yylvp = 0;
+
+ /* End position of lexical value queue */
+ static YYSTYPE *yylve = 0;
+
+ /* The last allocated position at the lexical value queue */
+ static YYSTYPE *yylvlim = 0;
+
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ /* Base of the lexical position queue */
+ static YYLTYPE *yylpsns = 0;
+
+ /* Current position at lexical position queue */
+ static YYLTYPE *yylpp = 0;
+
+ /* End position of lexical position queue */
+ static YYLTYPE *yylpe = 0;
+
+ /* The last allocated position at the lexical position queue */
+ static YYLTYPE *yylplim = 0;
+#endif
+
+ /* Current position at lexical token queue */
+ static YYINT *yylexp = 0;
+
+ static YYINT *yylexemes = 0;
+#endif /* YYBTYACC */
+ int yym, yyn, yystate, yyresult;
+#if YYBTYACC
+ int yynewerrflag;
+ YYParseState *yyerrctx = NULL;
+#endif /* YYBTYACC */
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ YYLTYPE yyerror_loc_range[3]; /* position of error start/end (0 unused) */
+#endif
#if YYDEBUG
const char *yys;
@@ -1348,8 +1778,28 @@
if (yyn >= '0' && yyn <= '9')
yydebug = yyn - '0';
}
+ if (yydebug)
+ fprintf(stderr, "%sdebug[<# of symbols on state stack>]\n", YYPREFIX);
+#endif
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ memset(yyerror_loc_range, 0, sizeof(yyerror_loc_range));
#endif
+ yyerrflag = 0;
+ yychar = 0;
+ memset(&yyval, 0, sizeof(yyval));
+ memset(&yylval, 0, sizeof(yylval));
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ memset(&yyloc, 0, sizeof(yyloc));
+ memset(&yylloc, 0, sizeof(yylloc));
+#endif
+
+#if YYBTYACC
+ yyps = yyNewState(0); if (yyps == 0) goto yyenomem;
+ yyps->save = 0;
+#endif /* YYBTYACC */
+ yym = 0;
+ /* yyn is set below */
yynerrs = 0;
yyerrflag = 0;
yychar = YYEMPTY;
@@ -1362,6 +1812,9 @@
if (yystack.s_base == NULL && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow;
yystack.s_mark = yystack.s_base;
yystack.l_mark = yystack.l_base;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yystack.p_mark = yystack.p_base;
+#endif
yystate = 0;
*yystack.s_mark = 0;
@@ -1369,48 +1822,358 @@
if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
if (yychar < 0)
{
- if ((yychar = YYLEX) < 0) yychar = YYEOF;
+#if YYBTYACC
+ do {
+ if (yylvp < yylve)
+ {
+ /* we're currently re-reading tokens */
+ yylval = *yylvp++;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylloc = *yylpp++;
+#endif
+ yychar = *yylexp++;
+ break;
+ }
+ if (yyps->save)
+ {
+ /* in trial mode; save scanner results for future parse attempts */
+ if (yylvp == yylvlim)
+ { /* Enlarge lexical value queue */
+ size_t p = (size_t) (yylvp - yylvals);
+ size_t s = (size_t) (yylvlim - yylvals);
+
+ s += YYLVQUEUEGROWTH;
+ if ((yylexemes = (YYINT *)realloc(yylexemes, s * sizeof(YYINT))) == NULL) goto yyenomem;
+ if ((yylvals = (YYSTYPE *)realloc(yylvals, s * sizeof(YYSTYPE))) == NULL) goto yyenomem;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ if ((yylpsns = (YYLTYPE *)realloc(yylpsns, s * sizeof(YYLTYPE))) == NULL) goto yyenomem;
+#endif
+ yylvp = yylve = yylvals + p;
+ yylvlim = yylvals + s;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylpp = yylpe = yylpsns + p;
+ yylplim = yylpsns + s;
+#endif
+ yylexp = yylexemes + p;
+ }
+ *yylexp = (YYINT) YYLEX;
+ *yylvp++ = yylval;
+ yylve++;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ *yylpp++ = yylloc;
+ yylpe++;
+#endif
+ yychar = *yylexp++;
+ break;
+ }
+ /* normal operation, no conflict encountered */
+#endif /* YYBTYACC */
+ yychar = YYLEX;
+#if YYBTYACC
+ } while (0);
+#endif /* YYBTYACC */
+ if (yychar < 0) yychar = YYEOF;
#if YYDEBUG
if (yydebug)
{
- yys = yyname[YYTRANSLATE(yychar)];
- printf("%sdebug: state %d, reading %d (%s)\n",
- YYPREFIX, yystate, yychar, yys);
+ if ((yys = yyname[YYTRANSLATE(yychar)]) == NULL) yys = yyname[YYUNDFTOKEN];
+ fprintf(stderr, "%s[%d]: state %d, reading token %d (%s)",
+ YYDEBUGSTR, yydepth, yystate, yychar, yys);
+#ifdef YYSTYPE_TOSTRING
+#if YYBTYACC
+ if (!yytrial)
+#endif /* YYBTYACC */
+ fprintf(stderr, " <%s>", YYSTYPE_TOSTRING(yychar, yylval));
+#endif
+ fputc('\n', stderr);
}
#endif
}
- if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+#if YYBTYACC
+
+ /* Do we have a conflict? */
+ if (((yyn = yycindex[yystate]) != 0) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) yychar)
+ {
+ YYINT ctry;
+
+ if (yypath)
+ {
+ YYParseState *save;
+#if YYDEBUG
+ if (yydebug)
+ fprintf(stderr, "%s[%d]: CONFLICT in state %d: following successful trial parse\n",
+ YYDEBUGSTR, yydepth, yystate);
+#endif
+ /* Switch to the next conflict context */
+ save = yypath;
+ yypath = save->save;
+ save->save = NULL;
+ ctry = save->ctry;
+ if (save->state != yystate) YYABORT;
+ yyFreeState(save);
+
+ }
+ else
+ {
+
+ /* Unresolved conflict - start/continue trial parse */
+ YYParseState *save;
+#if YYDEBUG
+ if (yydebug)
+ {
+ fprintf(stderr, "%s[%d]: CONFLICT in state %d. ", YYDEBUGSTR, yydepth, yystate);
+ if (yyps->save)
+ fputs("ALREADY in conflict, continuing trial parse.\n", stderr);
+ else
+ fputs("Starting trial parse.\n", stderr);
+ }
+#endif
+ save = yyNewState((unsigned)(yystack.s_mark - yystack.s_base + 1));
+ if (save == NULL) goto yyenomem;
+ save->save = yyps->save;
+ save->state = yystate;
+ save->errflag = yyerrflag;
+ save->yystack.s_mark = save->yystack.s_base + (yystack.s_mark - yystack.s_base);
+ memcpy (save->yystack.s_base, yystack.s_base, (size_t) (yystack.s_mark - yystack.s_base + 1) * sizeof(YYINT));
+ save->yystack.l_mark = save->yystack.l_base + (yystack.l_mark - yystack.l_base);
+ memcpy (save->yystack.l_base, yystack.l_base, (size_t) (yystack.l_mark - yystack.l_base + 1) * sizeof(YYSTYPE));
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ save->yystack.p_mark = save->yystack.p_base + (yystack.p_mark - yystack.p_base);
+ memcpy (save->yystack.p_base, yystack.p_base, (size_t) (yystack.p_mark - yystack.p_base + 1) * sizeof(YYLTYPE));
+#endif
+ ctry = yytable[yyn];
+ if (yyctable[ctry] == -1)
+ {
+#if YYDEBUG
+ if (yydebug && yychar >= YYEOF)
+ fprintf(stderr, "%s[%d]: backtracking 1 token\n", YYDEBUGSTR, yydepth);
+#endif
+ ctry++;
+ }
+ save->ctry = ctry;
+ if (yyps->save == NULL)
+ {
+ /* If this is a first conflict in the stack, start saving lexemes */
+ if (!yylexemes)
+ {
+ yylexemes = (YYINT *) malloc((YYLVQUEUEGROWTH) * sizeof(YYINT));
+ if (yylexemes == NULL) goto yyenomem;
+ yylvals = (YYSTYPE *) malloc((YYLVQUEUEGROWTH) * sizeof(YYSTYPE));
+ if (yylvals == NULL) goto yyenomem;
+ yylvlim = yylvals + YYLVQUEUEGROWTH;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylpsns = (YYLTYPE *) malloc((YYLVQUEUEGROWTH) * sizeof(YYLTYPE));
+ if (yylpsns == NULL) goto yyenomem;
+ yylplim = yylpsns + YYLVQUEUEGROWTH;
+#endif
+ }
+ if (yylvp == yylve)
+ {
+ yylvp = yylve = yylvals;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylpp = yylpe = yylpsns;
+#endif
+ yylexp = yylexemes;
+ if (yychar >= YYEOF)
+ {
+ *yylve++ = yylval;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ *yylpe++ = yylloc;
+#endif
+ *yylexp = (YYINT) yychar;
+ yychar = YYEMPTY;
+ }
+ }
+ }
+ if (yychar >= YYEOF)
+ {
+ yylvp--;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylpp--;
+#endif
+ yylexp--;
+ yychar = YYEMPTY;
+ }
+ save->lexeme = (int) (yylvp - yylvals);
+ yyps->save = save;
+ }
+ if (yytable[yyn] == ctry)
+ {
+#if YYDEBUG
+ if (yydebug)
+ fprintf(stderr, "%s[%d]: state %d, shifting to state %d\n",
+ YYDEBUGSTR, yydepth, yystate, yyctable[ctry]);
+#endif
+ if (yychar < 0)
+ {
+ yylvp++;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylpp++;
+#endif
+ yylexp++;
+ }
+ if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM)
+ goto yyoverflow;
+ yystate = yyctable[ctry];
+ *++yystack.s_mark = (YYINT) yystate;
+ *++yystack.l_mark = yylval;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ *++yystack.p_mark = yylloc;
+#endif
+ yychar = YYEMPTY;
+ if (yyerrflag > 0) --yyerrflag;
+ goto yyloop;
+ }
+ else
+ {
+ yyn = yyctable[ctry];
+ goto yyreduce;
+ }
+ } /* End of code dealing with conflicts */
+#endif /* YYBTYACC */
+ if (((yyn = yysindex[yystate]) != 0) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) yychar)
{
#if YYDEBUG
if (yydebug)
- printf("%sdebug: state %d, shifting to state %d\n",
- YYPREFIX, yystate, yytable[yyn]);
+ fprintf(stderr, "%s[%d]: state %d, shifting to state %d\n",
+ YYDEBUGSTR, yydepth, yystate, yytable[yyn]);
#endif
- if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM)
- {
- goto yyoverflow;
- }
+ if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow;
yystate = yytable[yyn];
*++yystack.s_mark = yytable[yyn];
*++yystack.l_mark = yylval;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ *++yystack.p_mark = yylloc;
+#endif
yychar = YYEMPTY;
if (yyerrflag > 0) --yyerrflag;
goto yyloop;
}
- if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ if (((yyn = yyrindex[yystate]) != 0) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) yychar)
{
yyn = yytable[yyn];
goto yyreduce;
}
- if (yyerrflag) goto yyinrecovery;
+ if (yyerrflag != 0) goto yyinrecovery;
+#if YYBTYACC
- YYERROR_CALL("syntax error");
-
- goto yyerrlab;
+ yynewerrflag = 1;
+ goto yyerrhandler;
+ goto yyerrlab; /* redundant goto avoids 'unused label' warning */
yyerrlab:
+ /* explicit YYERROR from an action -- pop the rhs of the rule reduced
+ * before looking for error recovery */
+ yystack.s_mark -= yym;
+ yystate = *yystack.s_mark;
+ yystack.l_mark -= yym;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yystack.p_mark -= yym;
+#endif
+
+ yynewerrflag = 0;
+yyerrhandler:
+ while (yyps->save)
+ {
+ int ctry;
+ YYParseState *save = yyps->save;
+#if YYDEBUG
+ if (yydebug)
+ fprintf(stderr, "%s[%d]: ERROR in state %d, CONFLICT BACKTRACKING to state %d, %d tokens\n",
+ YYDEBUGSTR, yydepth, yystate, yyps->save->state,
+ (int)(yylvp - yylvals - yyps->save->lexeme));
+#endif
+ /* Memorize most forward-looking error state in case it's really an error. */
+ if (yyerrctx == NULL || yyerrctx->lexeme < yylvp - yylvals)
+ {
+ /* Free old saved error context state */
+ if (yyerrctx) yyFreeState(yyerrctx);
+ /* Create and fill out new saved error context state */
+ yyerrctx = yyNewState((unsigned)(yystack.s_mark - yystack.s_base + 1));
+ if (yyerrctx == NULL) goto yyenomem;
+ yyerrctx->save = yyps->save;
+ yyerrctx->state = yystate;
+ yyerrctx->errflag = yyerrflag;
+ yyerrctx->yystack.s_mark = yyerrctx->yystack.s_base + (yystack.s_mark - yystack.s_base);
+ memcpy (yyerrctx->yystack.s_base, yystack.s_base, (size_t) (yystack.s_mark - yystack.s_base + 1) * sizeof(YYINT));
+ yyerrctx->yystack.l_mark = yyerrctx->yystack.l_base + (yystack.l_mark - yystack.l_base);
+ memcpy (yyerrctx->yystack.l_base, yystack.l_base, (size_t) (yystack.l_mark - yystack.l_base + 1) * sizeof(YYSTYPE));
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yyerrctx->yystack.p_mark = yyerrctx->yystack.p_base + (yystack.p_mark - yystack.p_base);
+ memcpy (yyerrctx->yystack.p_base, yystack.p_base, (size_t) (yystack.p_mark - yystack.p_base + 1) * sizeof(YYLTYPE));
+#endif
+ yyerrctx->lexeme = (int) (yylvp - yylvals);
+ }
+ yylvp = yylvals + save->lexeme;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylpp = yylpsns + save->lexeme;
+#endif
+ yylexp = yylexemes + save->lexeme;
+ yychar = YYEMPTY;
+ yystack.s_mark = yystack.s_base + (save->yystack.s_mark - save->yystack.s_base);
+ memcpy (yystack.s_base, save->yystack.s_base, (size_t) (yystack.s_mark - yystack.s_base + 1) * sizeof(YYINT));
+ yystack.l_mark = yystack.l_base + (save->yystack.l_mark - save->yystack.l_base);
+ memcpy (yystack.l_base, save->yystack.l_base, (size_t) (yystack.l_mark - yystack.l_base + 1) * sizeof(YYSTYPE));
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yystack.p_mark = yystack.p_base + (save->yystack.p_mark - save->yystack.p_base);
+ memcpy (yystack.p_base, save->yystack.p_base, (size_t) (yystack.p_mark - yystack.p_base + 1) * sizeof(YYLTYPE));
+#endif
+ ctry = ++save->ctry;
+ yystate = save->state;
+ /* We tried shift, try reduce now */
+ if ((yyn = yyctable[ctry]) >= 0) goto yyreduce;
+ yyps->save = save->save;
+ save->save = NULL;
+ yyFreeState(save);
+
+ /* Nothing left on the stack -- error */
+ if (!yyps->save)
+ {
+#if YYDEBUG
+ if (yydebug)
+ fprintf(stderr, "%sdebug[%d,trial]: trial parse FAILED, entering ERROR mode\n",
+ YYPREFIX, yydepth);
+#endif
+ /* Restore state as it was in the most forward-advanced error */
+ yylvp = yylvals + yyerrctx->lexeme;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylpp = yylpsns + yyerrctx->lexeme;
+#endif
+ yylexp = yylexemes + yyerrctx->lexeme;
+ yychar = yylexp[-1];
+ yylval = yylvp[-1];
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylloc = yylpp[-1];
+#endif
+ yystack.s_mark = yystack.s_base + (yyerrctx->yystack.s_mark - yyerrctx->yystack.s_base);
+ memcpy (yystack.s_base, yyerrctx->yystack.s_base, (size_t) (yystack.s_mark - yystack.s_base + 1) * sizeof(YYINT));
+ yystack.l_mark = yystack.l_base + (yyerrctx->yystack.l_mark - yyerrctx->yystack.l_base);
+ memcpy (yystack.l_base, yyerrctx->yystack.l_base, (size_t) (yystack.l_mark - yystack.l_base + 1) * sizeof(YYSTYPE));
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yystack.p_mark = yystack.p_base + (yyerrctx->yystack.p_mark - yyerrctx->yystack.p_base);
+ memcpy (yystack.p_base, yyerrctx->yystack.p_base, (size_t) (yystack.p_mark - yystack.p_base + 1) * sizeof(YYLTYPE));
+#endif
+ yystate = yyerrctx->state;
+ yyFreeState(yyerrctx);
+ yyerrctx = NULL;
+ }
+ yynewerrflag = 1;
+ }
+ if (yynewerrflag == 0) goto yyinrecovery;
+#endif /* YYBTYACC */
+
+ YYERROR_CALL("syntax error");
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yyerror_loc_range[1] = yylloc; /* lookahead position is error start position */
+#endif
+
+#if !YYBTYACC
+ goto yyerrlab; /* redundant goto avoids 'unused label' warning */
+yyerrlab:
+#endif
++yynerrs;
yyinrecovery:
@@ -1419,33 +2182,55 @@
yyerrflag = 3;
for (;;)
{
- if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+ if (((yyn = yysindex[*yystack.s_mark]) != 0) && (yyn += YYERRCODE) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) YYERRCODE)
{
#if YYDEBUG
if (yydebug)
- printf("%sdebug: state %d, error recovery shifting\
- to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]);
+ fprintf(stderr, "%s[%d]: state %d, error recovery shifting to state %d\n",
+ YYDEBUGSTR, yydepth, *yystack.s_mark, yytable[yyn]);
#endif
- if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM)
- {
- goto yyoverflow;
- }
+ if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow;
yystate = yytable[yyn];
*++yystack.s_mark = yytable[yyn];
*++yystack.l_mark = yylval;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ /* lookahead position is error end position */
+ yyerror_loc_range[2] = yylloc;
+ YYLLOC_DEFAULT(yyloc, yyerror_loc_range, 2); /* position of error span */
+ *++yystack.p_mark = yyloc;
+#endif
goto yyloop;
}
else
{
#if YYDEBUG
if (yydebug)
- printf("%sdebug: error recovery discarding state %d\n",
- YYPREFIX, *yystack.s_mark);
+ fprintf(stderr, "%s[%d]: error recovery discarding state %d\n",
+ YYDEBUGSTR, yydepth, *yystack.s_mark);
#endif
if (yystack.s_mark <= yystack.s_base) goto yyabort;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ /* the current TOS position is the error start position */
+ yyerror_loc_range[1] = *yystack.p_mark;
+#endif
+#if defined(YYDESTRUCT_CALL)
+#if YYBTYACC
+ if (!yytrial)
+#endif /* YYBTYACC */
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ YYDESTRUCT_CALL("error: discarding state",
+ yystos[*yystack.s_mark], yystack.l_mark, yystack.p_mark);
+#else
+ YYDESTRUCT_CALL("error: discarding state",
+ yystos[*yystack.s_mark], yystack.l_mark);
+#endif /* defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED) */
+#endif /* defined(YYDESTRUCT_CALL) */
--yystack.s_mark;
--yystack.l_mark;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ --yystack.p_mark;
+#endif
}
}
}
@@ -1455,87 +2240,145 @@
#if YYDEBUG
if (yydebug)
{
- yys = yyname[YYTRANSLATE(yychar)];
- printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
- YYPREFIX, yystate, yychar, yys);
+ if ((yys = yyname[YYTRANSLATE(yychar)]) == NULL) yys = yyname[YYUNDFTOKEN];
+ fprintf(stderr, "%s[%d]: state %d, error recovery discarding token %d (%s)\n",
+ YYDEBUGSTR, yydepth, yystate, yychar, yys);
}
#endif
+#if defined(YYDESTRUCT_CALL)
+#if YYBTYACC
+ if (!yytrial)
+#endif /* YYBTYACC */
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ YYDESTRUCT_CALL("error: discarding token", yychar, &yylval, &yylloc);
+#else
+ YYDESTRUCT_CALL("error: discarding token", yychar, &yylval);
+#endif /* defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED) */
+#endif /* defined(YYDESTRUCT_CALL) */
yychar = YYEMPTY;
goto yyloop;
}
yyreduce:
+ yym = yylen[yyn];
#if YYDEBUG
if (yydebug)
- printf("%sdebug: state %d, reducing by rule %d (%s)\n",
- YYPREFIX, yystate, yyn, yyrule[yyn]);
+ {
+ fprintf(stderr, "%s[%d]: state %d, reducing by rule %d (%s)",
+ YYDEBUGSTR, yydepth, yystate, yyn, yyrule[yyn]);
+#ifdef YYSTYPE_TOSTRING
+#if YYBTYACC
+ if (!yytrial)
+#endif /* YYBTYACC */
+ if (yym > 0)
+ {
+ int i;
+ fputc('<', stderr);
+ for (i = yym; i > 0; i--)
+ {
+ if (i != yym) fputs(", ", stderr);
+ fputs(YYSTYPE_TOSTRING(yystos[yystack.s_mark[1-i]],
+ yystack.l_mark[1-i]), stderr);
+ }
+ fputc('>', stderr);
+ }
#endif
- yym = yylen[yyn];
- if (yym)
+ fputc('\n', stderr);
+ }
+#endif
+ if (yym > 0)
yyval = yystack.l_mark[1-yym];
else
memset(&yyval, 0, sizeof yyval);
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+
+ /* Perform position reduction */
+ memset(&yyloc, 0, sizeof(yyloc));
+#if YYBTYACC
+ if (!yytrial)
+#endif /* YYBTYACC */
+ {
+ YYLLOC_DEFAULT(yyloc, &yystack.p_mark[-yym], yym);
+ /* just in case YYERROR is invoked within the action, save
+ the start of the rhs as the error start position */
+ yyerror_loc_range[1] = yystack.p_mark[1-yym];
+ }
+#endif
+
switch (yyn)
{
case 1:
-#line 396 "grammar.y"
+#line 424 "grammar.y"
{
CHECK_INT_VAL(finish_parse(cstate, yystack.l_mark[0].blk.b));
}
+#line 2316 "grammar.c"
break;
case 3:
-#line 401 "grammar.y"
+#line 429 "grammar.y"
{ yyval.blk.q = qerr; }
+#line 2321 "grammar.c"
break;
case 5:
-#line 404 "grammar.y"
+#line 432 "grammar.y"
{ gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+#line 2326 "grammar.c"
break;
case 6:
-#line 405 "grammar.y"
+#line 433 "grammar.y"
{ gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+#line 2331 "grammar.c"
break;
case 7:
-#line 406 "grammar.y"
+#line 434 "grammar.y"
{ gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+#line 2336 "grammar.c"
break;
case 8:
-#line 407 "grammar.y"
+#line 435 "grammar.y"
{ gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+#line 2341 "grammar.c"
break;
case 9:
-#line 409 "grammar.y"
+#line 437 "grammar.y"
{ yyval.blk = yystack.l_mark[-1].blk; }
+#line 2346 "grammar.c"
break;
case 10:
-#line 411 "grammar.y"
+#line 439 "grammar.y"
{ yyval.blk = yystack.l_mark[-1].blk; }
+#line 2351 "grammar.c"
break;
case 12:
-#line 414 "grammar.y"
+#line 442 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_ncode(cstate, NULL, yystack.l_mark[0].h,
yyval.blk.q = yystack.l_mark[-1].blk.q))); }
+#line 2357 "grammar.c"
break;
case 13:
-#line 416 "grammar.y"
+#line 444 "grammar.y"
{ yyval.blk = yystack.l_mark[-1].blk; }
+#line 2362 "grammar.c"
break;
case 14:
-#line 418 "grammar.y"
+#line 446 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_PTR_VAL((yyval.blk.b = gen_scode(cstate, yystack.l_mark[0].s, yyval.blk.q = yystack.l_mark[-1].blk.q))); }
+#line 2367 "grammar.c"
break;
case 15:
-#line 419 "grammar.y"
+#line 447 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[-2].s); CHECK_PTR_VAL((yyval.blk.b = gen_mcode(cstate, yystack.l_mark[-2].s, NULL, yystack.l_mark[0].h,
yyval.blk.q = yystack.l_mark[-3].blk.q))); }
+#line 2373 "grammar.c"
break;
case 16:
-#line 421 "grammar.y"
+#line 449 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[-2].s); CHECK_PTR_VAL((yyval.blk.b = gen_mcode(cstate, yystack.l_mark[-2].s, yystack.l_mark[0].s, 0,
yyval.blk.q = yystack.l_mark[-3].blk.q))); }
+#line 2379 "grammar.c"
break;
case 17:
-#line 423 "grammar.y"
+#line 451 "grammar.y"
{
CHECK_PTR_VAL(yystack.l_mark[0].s);
/* Decide how to parse HID based on proto */
@@ -1555,9 +2398,10 @@
}
CHECK_PTR_VAL((yyval.blk.b = gen_ncode(cstate, yystack.l_mark[0].s, 0, yyval.blk.q)));
}
+#line 2402 "grammar.c"
break;
case 18:
-#line 442 "grammar.y"
+#line 470 "grammar.y"
{
CHECK_PTR_VAL(yystack.l_mark[-2].s);
#ifdef INET6
@@ -1569,9 +2413,10 @@
YYABORT;
#endif /*INET6*/
}
+#line 2417 "grammar.c"
break;
case 19:
-#line 453 "grammar.y"
+#line 481 "grammar.y"
{
CHECK_PTR_VAL(yystack.l_mark[0].s);
#ifdef INET6
@@ -1583,62 +2428,76 @@
YYABORT;
#endif /*INET6*/
}
+#line 2432 "grammar.c"
break;
case 20:
-#line 464 "grammar.y"
+#line 492 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_PTR_VAL((yyval.blk.b = gen_ecode(cstate, yystack.l_mark[0].s, yyval.blk.q = yystack.l_mark[-1].blk.q))); }
+#line 2437 "grammar.c"
break;
case 21:
-#line 465 "grammar.y"
+#line 493 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_PTR_VAL((yyval.blk.b = gen_acode(cstate, yystack.l_mark[0].s, yyval.blk.q = yystack.l_mark[-1].blk.q))); }
+#line 2442 "grammar.c"
break;
case 22:
-#line 466 "grammar.y"
+#line 494 "grammar.y"
{ gen_not(yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+#line 2447 "grammar.c"
break;
case 23:
-#line 468 "grammar.y"
+#line 496 "grammar.y"
{ yyval.blk = yystack.l_mark[-1].blk; }
+#line 2452 "grammar.c"
break;
case 24:
-#line 470 "grammar.y"
+#line 498 "grammar.y"
{ yyval.blk = yystack.l_mark[-1].blk; }
+#line 2457 "grammar.c"
break;
case 26:
-#line 473 "grammar.y"
+#line 501 "grammar.y"
{ gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+#line 2462 "grammar.c"
break;
case 27:
-#line 474 "grammar.y"
+#line 502 "grammar.y"
{ gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+#line 2467 "grammar.c"
break;
case 28:
-#line 476 "grammar.y"
+#line 504 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_ncode(cstate, NULL, yystack.l_mark[0].h,
yyval.blk.q = yystack.l_mark[-1].blk.q))); }
+#line 2473 "grammar.c"
break;
case 31:
-#line 481 "grammar.y"
+#line 509 "grammar.y"
{ gen_not(yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+#line 2478 "grammar.c"
break;
case 32:
-#line 483 "grammar.y"
+#line 511 "grammar.y"
{ QSET(yyval.blk.q, yystack.l_mark[-2].i, yystack.l_mark[-1].i, yystack.l_mark[0].i); }
+#line 2483 "grammar.c"
break;
case 33:
-#line 484 "grammar.y"
+#line 512 "grammar.y"
{ QSET(yyval.blk.q, yystack.l_mark[-1].i, yystack.l_mark[0].i, Q_DEFAULT); }
+#line 2488 "grammar.c"
break;
case 34:
-#line 485 "grammar.y"
+#line 513 "grammar.y"
{ QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, yystack.l_mark[0].i); }
+#line 2493 "grammar.c"
break;
case 35:
-#line 486 "grammar.y"
+#line 514 "grammar.y"
{ QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, Q_PROTO); }
+#line 2498 "grammar.c"
break;
case 36:
-#line 487 "grammar.y"
+#line 515 "grammar.y"
{
#ifdef NO_PROTOCHAIN
bpf_set_error(cstate, "protochain not supported");
@@ -1647,424 +2506,525 @@
QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, Q_PROTOCHAIN);
#endif
}
+#line 2510 "grammar.c"
break;
case 37:
-#line 495 "grammar.y"
+#line 523 "grammar.y"
{ QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, yystack.l_mark[0].i); }
+#line 2515 "grammar.c"
break;
case 38:
-#line 497 "grammar.y"
+#line 525 "grammar.y"
{ yyval.blk = yystack.l_mark[0].blk; }
+#line 2520 "grammar.c"
break;
case 39:
-#line 498 "grammar.y"
+#line 526 "grammar.y"
{ yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = yystack.l_mark[-2].blk.q; }
+#line 2525 "grammar.c"
break;
case 40:
-#line 499 "grammar.y"
+#line 527 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_proto_abbrev(cstate, yystack.l_mark[0].i))); yyval.blk.q = qerr; }
+#line 2530 "grammar.c"
break;
case 41:
-#line 500 "grammar.y"
+#line 528 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_relation(cstate, yystack.l_mark[-1].i, yystack.l_mark[-2].a, yystack.l_mark[0].a, 0)));
yyval.blk.q = qerr; }
+#line 2536 "grammar.c"
break;
case 42:
-#line 502 "grammar.y"
+#line 530 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_relation(cstate, yystack.l_mark[-1].i, yystack.l_mark[-2].a, yystack.l_mark[0].a, 1)));
yyval.blk.q = qerr; }
+#line 2542 "grammar.c"
break;
case 43:
-#line 504 "grammar.y"
+#line 532 "grammar.y"
{ yyval.blk.b = yystack.l_mark[0].rblk; yyval.blk.q = qerr; }
+#line 2547 "grammar.c"
break;
case 44:
-#line 505 "grammar.y"
+#line 533 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_atmtype_abbrev(cstate, yystack.l_mark[0].i))); yyval.blk.q = qerr; }
+#line 2552 "grammar.c"
break;
case 45:
-#line 506 "grammar.y"
+#line 534 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_atmmulti_abbrev(cstate, yystack.l_mark[0].i))); yyval.blk.q = qerr; }
+#line 2557 "grammar.c"
break;
case 46:
-#line 507 "grammar.y"
+#line 535 "grammar.y"
{ yyval.blk.b = yystack.l_mark[0].blk.b; yyval.blk.q = qerr; }
+#line 2562 "grammar.c"
break;
case 47:
-#line 508 "grammar.y"
+#line 536 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_mtp2type_abbrev(cstate, yystack.l_mark[0].i))); yyval.blk.q = qerr; }
+#line 2567 "grammar.c"
break;
case 48:
-#line 509 "grammar.y"
+#line 537 "grammar.y"
{ yyval.blk.b = yystack.l_mark[0].blk.b; yyval.blk.q = qerr; }
+#line 2572 "grammar.c"
break;
case 50:
-#line 513 "grammar.y"
+#line 541 "grammar.y"
{ yyval.i = Q_DEFAULT; }
+#line 2577 "grammar.c"
break;
case 51:
-#line 516 "grammar.y"
+#line 544 "grammar.y"
{ yyval.i = Q_SRC; }
+#line 2582 "grammar.c"
break;
case 52:
-#line 517 "grammar.y"
+#line 545 "grammar.y"
{ yyval.i = Q_DST; }
+#line 2587 "grammar.c"
break;
case 53:
-#line 518 "grammar.y"
+#line 546 "grammar.y"
{ yyval.i = Q_OR; }
+#line 2592 "grammar.c"
break;
case 54:
-#line 519 "grammar.y"
+#line 547 "grammar.y"
{ yyval.i = Q_OR; }
+#line 2597 "grammar.c"
break;
case 55:
-#line 520 "grammar.y"
+#line 548 "grammar.y"
{ yyval.i = Q_AND; }
+#line 2602 "grammar.c"
break;
case 56:
-#line 521 "grammar.y"
+#line 549 "grammar.y"
{ yyval.i = Q_AND; }
+#line 2607 "grammar.c"
break;
case 57:
-#line 522 "grammar.y"
+#line 550 "grammar.y"
{ yyval.i = Q_ADDR1; }
+#line 2612 "grammar.c"
break;
case 58:
-#line 523 "grammar.y"
+#line 551 "grammar.y"
{ yyval.i = Q_ADDR2; }
+#line 2617 "grammar.c"
break;
case 59:
-#line 524 "grammar.y"
+#line 552 "grammar.y"
{ yyval.i = Q_ADDR3; }
+#line 2622 "grammar.c"
break;
case 60:
-#line 525 "grammar.y"
+#line 553 "grammar.y"
{ yyval.i = Q_ADDR4; }
+#line 2627 "grammar.c"
break;
case 61:
-#line 526 "grammar.y"
+#line 554 "grammar.y"
{ yyval.i = Q_RA; }
+#line 2632 "grammar.c"
break;
case 62:
-#line 527 "grammar.y"
+#line 555 "grammar.y"
{ yyval.i = Q_TA; }
+#line 2637 "grammar.c"
break;
case 63:
-#line 530 "grammar.y"
+#line 558 "grammar.y"
{ yyval.i = Q_HOST; }
+#line 2642 "grammar.c"
break;
case 64:
-#line 531 "grammar.y"
+#line 559 "grammar.y"
{ yyval.i = Q_NET; }
+#line 2647 "grammar.c"
break;
case 65:
-#line 532 "grammar.y"
+#line 560 "grammar.y"
{ yyval.i = Q_PORT; }
+#line 2652 "grammar.c"
break;
case 66:
-#line 533 "grammar.y"
+#line 561 "grammar.y"
{ yyval.i = Q_PORTRANGE; }
+#line 2657 "grammar.c"
break;
case 67:
-#line 536 "grammar.y"
+#line 564 "grammar.y"
{ yyval.i = Q_GATEWAY; }
+#line 2662 "grammar.c"
break;
case 68:
-#line 538 "grammar.y"
+#line 566 "grammar.y"
{ yyval.i = Q_LINK; }
+#line 2667 "grammar.c"
break;
case 69:
-#line 539 "grammar.y"
+#line 567 "grammar.y"
{ yyval.i = Q_IP; }
+#line 2672 "grammar.c"
break;
case 70:
-#line 540 "grammar.y"
+#line 568 "grammar.y"
{ yyval.i = Q_ARP; }
+#line 2677 "grammar.c"
break;
case 71:
-#line 541 "grammar.y"
+#line 569 "grammar.y"
{ yyval.i = Q_RARP; }
+#line 2682 "grammar.c"
break;
case 72:
-#line 542 "grammar.y"
+#line 570 "grammar.y"
{ yyval.i = Q_SCTP; }
+#line 2687 "grammar.c"
break;
case 73:
-#line 543 "grammar.y"
+#line 571 "grammar.y"
{ yyval.i = Q_TCP; }
+#line 2692 "grammar.c"
break;
case 74:
-#line 544 "grammar.y"
+#line 572 "grammar.y"
{ yyval.i = Q_UDP; }
+#line 2697 "grammar.c"
break;
case 75:
-#line 545 "grammar.y"
+#line 573 "grammar.y"
{ yyval.i = Q_ICMP; }
+#line 2702 "grammar.c"
break;
case 76:
-#line 546 "grammar.y"
+#line 574 "grammar.y"
{ yyval.i = Q_IGMP; }
+#line 2707 "grammar.c"
break;
case 77:
-#line 547 "grammar.y"
+#line 575 "grammar.y"
{ yyval.i = Q_IGRP; }
+#line 2712 "grammar.c"
break;
case 78:
-#line 548 "grammar.y"
+#line 576 "grammar.y"
{ yyval.i = Q_PIM; }
+#line 2717 "grammar.c"
break;
case 79:
-#line 549 "grammar.y"
+#line 577 "grammar.y"
{ yyval.i = Q_VRRP; }
+#line 2722 "grammar.c"
break;
case 80:
-#line 550 "grammar.y"
+#line 578 "grammar.y"
{ yyval.i = Q_CARP; }
+#line 2727 "grammar.c"
break;
case 81:
-#line 551 "grammar.y"
+#line 579 "grammar.y"
{ yyval.i = Q_ATALK; }
+#line 2732 "grammar.c"
break;
case 82:
-#line 552 "grammar.y"
+#line 580 "grammar.y"
{ yyval.i = Q_AARP; }
+#line 2737 "grammar.c"
break;
case 83:
-#line 553 "grammar.y"
+#line 581 "grammar.y"
{ yyval.i = Q_DECNET; }
+#line 2742 "grammar.c"
break;
case 84:
-#line 554 "grammar.y"
+#line 582 "grammar.y"
{ yyval.i = Q_LAT; }
+#line 2747 "grammar.c"
break;
case 85:
-#line 555 "grammar.y"
+#line 583 "grammar.y"
{ yyval.i = Q_SCA; }
+#line 2752 "grammar.c"
break;
case 86:
-#line 556 "grammar.y"
+#line 584 "grammar.y"
{ yyval.i = Q_MOPDL; }
+#line 2757 "grammar.c"
break;
case 87:
-#line 557 "grammar.y"
+#line 585 "grammar.y"
{ yyval.i = Q_MOPRC; }
+#line 2762 "grammar.c"
break;
case 88:
-#line 558 "grammar.y"
+#line 586 "grammar.y"
{ yyval.i = Q_IPV6; }
+#line 2767 "grammar.c"
break;
case 89:
-#line 559 "grammar.y"
+#line 587 "grammar.y"
{ yyval.i = Q_ICMPV6; }
+#line 2772 "grammar.c"
break;
case 90:
-#line 560 "grammar.y"
+#line 588 "grammar.y"
{ yyval.i = Q_AH; }
+#line 2777 "grammar.c"
break;
case 91:
-#line 561 "grammar.y"
+#line 589 "grammar.y"
{ yyval.i = Q_ESP; }
+#line 2782 "grammar.c"
break;
case 92:
-#line 562 "grammar.y"
+#line 590 "grammar.y"
{ yyval.i = Q_ISO; }
+#line 2787 "grammar.c"
break;
case 93:
-#line 563 "grammar.y"
+#line 591 "grammar.y"
{ yyval.i = Q_ESIS; }
+#line 2792 "grammar.c"
break;
case 94:
-#line 564 "grammar.y"
+#line 592 "grammar.y"
{ yyval.i = Q_ISIS; }
+#line 2797 "grammar.c"
break;
case 95:
-#line 565 "grammar.y"
+#line 593 "grammar.y"
{ yyval.i = Q_ISIS_L1; }
+#line 2802 "grammar.c"
break;
case 96:
-#line 566 "grammar.y"
+#line 594 "grammar.y"
{ yyval.i = Q_ISIS_L2; }
+#line 2807 "grammar.c"
break;
case 97:
-#line 567 "grammar.y"
+#line 595 "grammar.y"
{ yyval.i = Q_ISIS_IIH; }
+#line 2812 "grammar.c"
break;
case 98:
-#line 568 "grammar.y"
+#line 596 "grammar.y"
{ yyval.i = Q_ISIS_LSP; }
+#line 2817 "grammar.c"
break;
case 99:
-#line 569 "grammar.y"
+#line 597 "grammar.y"
{ yyval.i = Q_ISIS_SNP; }
+#line 2822 "grammar.c"
break;
case 100:
-#line 570 "grammar.y"
+#line 598 "grammar.y"
{ yyval.i = Q_ISIS_PSNP; }
+#line 2827 "grammar.c"
break;
case 101:
-#line 571 "grammar.y"
+#line 599 "grammar.y"
{ yyval.i = Q_ISIS_CSNP; }
+#line 2832 "grammar.c"
break;
case 102:
-#line 572 "grammar.y"
+#line 600 "grammar.y"
{ yyval.i = Q_CLNP; }
+#line 2837 "grammar.c"
break;
case 103:
-#line 573 "grammar.y"
+#line 601 "grammar.y"
{ yyval.i = Q_STP; }
+#line 2842 "grammar.c"
break;
case 104:
-#line 574 "grammar.y"
+#line 602 "grammar.y"
{ yyval.i = Q_IPX; }
+#line 2847 "grammar.c"
break;
case 105:
-#line 575 "grammar.y"
+#line 603 "grammar.y"
{ yyval.i = Q_NETBEUI; }
+#line 2852 "grammar.c"
break;
case 106:
-#line 576 "grammar.y"
+#line 604 "grammar.y"
{ yyval.i = Q_RADIO; }
+#line 2857 "grammar.c"
break;
case 107:
-#line 578 "grammar.y"
+#line 606 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_broadcast(cstate, yystack.l_mark[-1].i))); }
+#line 2862 "grammar.c"
break;
case 108:
-#line 579 "grammar.y"
+#line 607 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_multicast(cstate, yystack.l_mark[-1].i))); }
+#line 2867 "grammar.c"
break;
case 109:
-#line 580 "grammar.y"
+#line 608 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_less(cstate, yystack.l_mark[0].h))); }
+#line 2872 "grammar.c"
break;
case 110:
-#line 581 "grammar.y"
+#line 609 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_greater(cstate, yystack.l_mark[0].h))); }
+#line 2877 "grammar.c"
break;
case 111:
-#line 582 "grammar.y"
+#line 610 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_byteop(cstate, yystack.l_mark[-1].i, yystack.l_mark[-2].h, yystack.l_mark[0].h))); }
+#line 2882 "grammar.c"
break;
case 112:
-#line 583 "grammar.y"
+#line 611 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_inbound(cstate, 0))); }
+#line 2887 "grammar.c"
break;
case 113:
-#line 584 "grammar.y"
+#line 612 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_inbound(cstate, 1))); }
+#line 2892 "grammar.c"
break;
case 114:
-#line 585 "grammar.y"
+#line 613 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_ifindex(cstate, yystack.l_mark[0].h))); }
+#line 2897 "grammar.c"
break;
case 115:
-#line 586 "grammar.y"
+#line 614 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_vlan(cstate, yystack.l_mark[0].h, 1))); }
+#line 2902 "grammar.c"
break;
case 116:
-#line 587 "grammar.y"
+#line 615 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_vlan(cstate, 0, 0))); }
+#line 2907 "grammar.c"
break;
case 117:
-#line 588 "grammar.y"
+#line 616 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_mpls(cstate, yystack.l_mark[0].h, 1))); }
+#line 2912 "grammar.c"
break;
case 118:
-#line 589 "grammar.y"
+#line 617 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_mpls(cstate, 0, 0))); }
+#line 2917 "grammar.c"
break;
case 119:
-#line 590 "grammar.y"
+#line 618 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_pppoed(cstate))); }
+#line 2922 "grammar.c"
break;
case 120:
-#line 591 "grammar.y"
+#line 619 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_pppoes(cstate, yystack.l_mark[0].h, 1))); }
+#line 2927 "grammar.c"
break;
case 121:
-#line 592 "grammar.y"
+#line 620 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_pppoes(cstate, 0, 0))); }
+#line 2932 "grammar.c"
break;
case 122:
-#line 593 "grammar.y"
+#line 621 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_geneve(cstate, yystack.l_mark[0].h, 1))); }
+#line 2937 "grammar.c"
break;
case 123:
-#line 594 "grammar.y"
+#line 622 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_geneve(cstate, 0, 0))); }
+#line 2942 "grammar.c"
break;
case 124:
-#line 595 "grammar.y"
+#line 623 "grammar.y"
{ yyval.rblk = yystack.l_mark[0].rblk; }
+#line 2947 "grammar.c"
break;
case 125:
-#line 596 "grammar.y"
+#line 624 "grammar.y"
{ yyval.rblk = yystack.l_mark[0].rblk; }
+#line 2952 "grammar.c"
break;
case 126:
-#line 597 "grammar.y"
+#line 625 "grammar.y"
{ yyval.rblk = yystack.l_mark[0].rblk; }
+#line 2957 "grammar.c"
break;
case 127:
-#line 600 "grammar.y"
+#line 628 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_PTR_VAL((yyval.rblk = gen_pf_ifname(cstate, yystack.l_mark[0].s))); }
+#line 2962 "grammar.c"
break;
case 128:
-#line 601 "grammar.y"
+#line 629 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_PTR_VAL((yyval.rblk = gen_pf_ruleset(cstate, yystack.l_mark[0].s))); }
+#line 2967 "grammar.c"
break;
case 129:
-#line 602 "grammar.y"
+#line 630 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_pf_rnr(cstate, yystack.l_mark[0].h))); }
+#line 2972 "grammar.c"
break;
case 130:
-#line 603 "grammar.y"
+#line 631 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_pf_srnr(cstate, yystack.l_mark[0].h))); }
+#line 2977 "grammar.c"
break;
case 131:
-#line 604 "grammar.y"
+#line 632 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_pf_reason(cstate, yystack.l_mark[0].i))); }
+#line 2982 "grammar.c"
break;
case 132:
-#line 605 "grammar.y"
+#line 633 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_pf_action(cstate, yystack.l_mark[0].i))); }
+#line 2987 "grammar.c"
break;
case 133:
-#line 609 "grammar.y"
+#line 637 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_p80211_type(cstate, yystack.l_mark[-2].i | yystack.l_mark[0].i,
IEEE80211_FC0_TYPE_MASK |
IEEE80211_FC0_SUBTYPE_MASK)));
}
+#line 2995 "grammar.c"
break;
case 134:
-#line 613 "grammar.y"
+#line 641 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_p80211_type(cstate, yystack.l_mark[0].i,
IEEE80211_FC0_TYPE_MASK)));
}
+#line 3002 "grammar.c"
break;
case 135:
-#line 616 "grammar.y"
+#line 644 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_p80211_type(cstate, yystack.l_mark[0].i,
IEEE80211_FC0_TYPE_MASK |
IEEE80211_FC0_SUBTYPE_MASK)));
}
+#line 3010 "grammar.c"
break;
case 136:
-#line 620 "grammar.y"
+#line 648 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_p80211_fcdir(cstate, yystack.l_mark[0].i))); }
+#line 3015 "grammar.c"
break;
case 137:
-#line 623 "grammar.y"
+#line 651 "grammar.y"
{ if ((yystack.l_mark[0].h & (~IEEE80211_FC0_TYPE_MASK)) != 0) {
bpf_set_error(cstate, "invalid 802.11 type value 0x%02x", yystack.l_mark[0].h);
YYABORT;
}
yyval.i = (int)yystack.l_mark[0].h;
}
+#line 3025 "grammar.c"
break;
case 138:
-#line 629 "grammar.y"
+#line 657 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[0].s);
yyval.i = str2tok(yystack.l_mark[0].s, ieee80211_types);
if (yyval.i == -1) {
@@ -2072,18 +3032,20 @@
YYABORT;
}
}
+#line 3036 "grammar.c"
break;
case 139:
-#line 638 "grammar.y"
+#line 666 "grammar.y"
{ if ((yystack.l_mark[0].h & (~IEEE80211_FC0_SUBTYPE_MASK)) != 0) {
bpf_set_error(cstate, "invalid 802.11 subtype value 0x%02x", yystack.l_mark[0].h);
YYABORT;
}
yyval.i = (int)yystack.l_mark[0].h;
}
+#line 3046 "grammar.c"
break;
case 140:
-#line 644 "grammar.y"
+#line 672 "grammar.y"
{ const struct tok *types = NULL;
int i;
CHECK_PTR_VAL(yystack.l_mark[0].s);
@@ -2105,9 +3067,10 @@
YYABORT;
}
}
+#line 3071 "grammar.c"
break;
case 141:
-#line 667 "grammar.y"
+#line 695 "grammar.y"
{ int i;
CHECK_PTR_VAL(yystack.l_mark[0].s);
for (i = 0;; i++) {
@@ -2123,13 +3086,15 @@
}
}
}
+#line 3090 "grammar.c"
break;
case 142:
-#line 684 "grammar.y"
+#line 712 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_llc(cstate))); }
+#line 3095 "grammar.c"
break;
case 143:
-#line 685 "grammar.y"
+#line 713 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[0].s);
if (pcap_strcasecmp(yystack.l_mark[0].s, "i") == 0) {
CHECK_PTR_VAL((yyval.rblk = gen_llc_i(cstate)));
@@ -2153,17 +3118,20 @@
}
}
}
+#line 3122 "grammar.c"
break;
case 144:
-#line 709 "grammar.y"
+#line 737 "grammar.y"
{ CHECK_PTR_VAL((yyval.rblk = gen_llc_s_subtype(cstate, LLC_RNR))); }
+#line 3127 "grammar.c"
break;
case 145:
-#line 712 "grammar.y"
+#line 740 "grammar.y"
{ yyval.i = (int)yystack.l_mark[0].h; }
+#line 3132 "grammar.c"
break;
case 146:
-#line 713 "grammar.y"
+#line 741 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[0].s);
if (pcap_strcasecmp(yystack.l_mark[0].s, "nods") == 0)
yyval.i = IEEE80211_FC1_DIR_NODS;
@@ -2178,278 +3146,345 @@
YYABORT;
}
}
+#line 3150 "grammar.c"
break;
case 147:
-#line 729 "grammar.y"
+#line 757 "grammar.y"
{ yyval.i = yystack.l_mark[0].h; }
+#line 3155 "grammar.c"
break;
case 148:
-#line 730 "grammar.y"
+#line 758 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_INT_VAL((yyval.i = pfreason_to_num(cstate, yystack.l_mark[0].s))); }
+#line 3160 "grammar.c"
break;
case 149:
-#line 733 "grammar.y"
+#line 761 "grammar.y"
{ CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_INT_VAL((yyval.i = pfaction_to_num(cstate, yystack.l_mark[0].s))); }
+#line 3165 "grammar.c"
break;
case 150:
-#line 736 "grammar.y"
+#line 764 "grammar.y"
{ yyval.i = BPF_JGT; }
+#line 3170 "grammar.c"
break;
case 151:
-#line 737 "grammar.y"
+#line 765 "grammar.y"
{ yyval.i = BPF_JGE; }
+#line 3175 "grammar.c"
break;
case 152:
-#line 738 "grammar.y"
+#line 766 "grammar.y"
{ yyval.i = BPF_JEQ; }
+#line 3180 "grammar.c"
break;
case 153:
-#line 740 "grammar.y"
+#line 768 "grammar.y"
{ yyval.i = BPF_JGT; }
+#line 3185 "grammar.c"
break;
case 154:
-#line 741 "grammar.y"
+#line 769 "grammar.y"
{ yyval.i = BPF_JGE; }
+#line 3190 "grammar.c"
break;
case 155:
-#line 742 "grammar.y"
+#line 770 "grammar.y"
{ yyval.i = BPF_JEQ; }
+#line 3195 "grammar.c"
break;
case 156:
-#line 744 "grammar.y"
+#line 772 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_loadi(cstate, yystack.l_mark[0].h))); }
+#line 3200 "grammar.c"
break;
case 158:
-#line 747 "grammar.y"
+#line 775 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_load(cstate, yystack.l_mark[-3].i, yystack.l_mark[-1].a, 1))); }
+#line 3205 "grammar.c"
break;
case 159:
-#line 748 "grammar.y"
+#line 776 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_load(cstate, yystack.l_mark[-5].i, yystack.l_mark[-3].a, yystack.l_mark[-1].h))); }
+#line 3210 "grammar.c"
break;
case 160:
-#line 749 "grammar.y"
+#line 777 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_ADD, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
+#line 3215 "grammar.c"
break;
case 161:
-#line 750 "grammar.y"
+#line 778 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_SUB, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
+#line 3220 "grammar.c"
break;
case 162:
-#line 751 "grammar.y"
+#line 779 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_MUL, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
+#line 3225 "grammar.c"
break;
case 163:
-#line 752 "grammar.y"
+#line 780 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_DIV, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
+#line 3230 "grammar.c"
break;
case 164:
-#line 753 "grammar.y"
+#line 781 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_MOD, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
+#line 3235 "grammar.c"
break;
case 165:
-#line 754 "grammar.y"
+#line 782 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_AND, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
+#line 3240 "grammar.c"
break;
case 166:
-#line 755 "grammar.y"
+#line 783 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_OR, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
+#line 3245 "grammar.c"
break;
case 167:
-#line 756 "grammar.y"
+#line 784 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_XOR, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
+#line 3250 "grammar.c"
break;
case 168:
-#line 757 "grammar.y"
+#line 785 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_LSH, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
+#line 3255 "grammar.c"
break;
case 169:
-#line 758 "grammar.y"
+#line 786 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_RSH, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
+#line 3260 "grammar.c"
break;
case 170:
-#line 759 "grammar.y"
+#line 787 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_neg(cstate, yystack.l_mark[0].a))); }
+#line 3265 "grammar.c"
break;
case 171:
-#line 760 "grammar.y"
+#line 788 "grammar.y"
{ yyval.a = yystack.l_mark[-1].a; }
+#line 3270 "grammar.c"
break;
case 172:
-#line 761 "grammar.y"
+#line 789 "grammar.y"
{ CHECK_PTR_VAL((yyval.a = gen_loadlen(cstate))); }
+#line 3275 "grammar.c"
break;
case 173:
-#line 763 "grammar.y"
+#line 791 "grammar.y"
{ yyval.i = '&'; }
+#line 3280 "grammar.c"
break;
case 174:
-#line 764 "grammar.y"
+#line 792 "grammar.y"
{ yyval.i = '|'; }
+#line 3285 "grammar.c"
break;
case 175:
-#line 765 "grammar.y"
+#line 793 "grammar.y"
{ yyval.i = '<'; }
+#line 3290 "grammar.c"
break;
case 176:
-#line 766 "grammar.y"
+#line 794 "grammar.y"
{ yyval.i = '>'; }
+#line 3295 "grammar.c"
break;
case 177:
-#line 767 "grammar.y"
+#line 795 "grammar.y"
{ yyval.i = '='; }
+#line 3300 "grammar.c"
break;
case 179:
-#line 770 "grammar.y"
+#line 798 "grammar.y"
{ yyval.h = yystack.l_mark[-1].h; }
+#line 3305 "grammar.c"
break;
case 180:
-#line 772 "grammar.y"
+#line 800 "grammar.y"
{ yyval.i = A_LANE; }
+#line 3310 "grammar.c"
break;
case 181:
-#line 773 "grammar.y"
+#line 801 "grammar.y"
{ yyval.i = A_METAC; }
+#line 3315 "grammar.c"
break;
case 182:
-#line 774 "grammar.y"
+#line 802 "grammar.y"
{ yyval.i = A_BCC; }
+#line 3320 "grammar.c"
break;
case 183:
-#line 775 "grammar.y"
+#line 803 "grammar.y"
{ yyval.i = A_OAMF4EC; }
+#line 3325 "grammar.c"
break;
case 184:
-#line 776 "grammar.y"
+#line 804 "grammar.y"
{ yyval.i = A_OAMF4SC; }
+#line 3330 "grammar.c"
break;
case 185:
-#line 777 "grammar.y"
+#line 805 "grammar.y"
{ yyval.i = A_SC; }
+#line 3335 "grammar.c"
break;
case 186:
-#line 778 "grammar.y"
+#line 806 "grammar.y"
{ yyval.i = A_ILMIC; }
+#line 3340 "grammar.c"
break;
case 187:
-#line 780 "grammar.y"
+#line 808 "grammar.y"
{ yyval.i = A_OAM; }
+#line 3345 "grammar.c"
break;
case 188:
-#line 781 "grammar.y"
+#line 809 "grammar.y"
{ yyval.i = A_OAMF4; }
+#line 3350 "grammar.c"
break;
case 189:
-#line 782 "grammar.y"
+#line 810 "grammar.y"
{ yyval.i = A_CONNECTMSG; }
+#line 3355 "grammar.c"
break;
case 190:
-#line 783 "grammar.y"
+#line 811 "grammar.y"
{ yyval.i = A_METACONNECT; }
+#line 3360 "grammar.c"
break;
case 191:
-#line 786 "grammar.y"
+#line 814 "grammar.y"
{ yyval.blk.atmfieldtype = A_VPI; }
+#line 3365 "grammar.c"
break;
case 192:
-#line 787 "grammar.y"
+#line 815 "grammar.y"
{ yyval.blk.atmfieldtype = A_VCI; }
+#line 3370 "grammar.c"
break;
case 194:
-#line 790 "grammar.y"
+#line 818 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_atmfield_code(cstate, yystack.l_mark[-2].blk.atmfieldtype, yystack.l_mark[0].h, yystack.l_mark[-1].i, 0))); }
+#line 3375 "grammar.c"
break;
case 195:
-#line 791 "grammar.y"
+#line 819 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_atmfield_code(cstate, yystack.l_mark[-2].blk.atmfieldtype, yystack.l_mark[0].h, yystack.l_mark[-1].i, 1))); }
+#line 3380 "grammar.c"
break;
case 196:
-#line 792 "grammar.y"
+#line 820 "grammar.y"
{ yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = qerr; }
+#line 3385 "grammar.c"
break;
case 197:
-#line 794 "grammar.y"
+#line 822 "grammar.y"
{
yyval.blk.atmfieldtype = yystack.l_mark[-1].blk.atmfieldtype;
if (yyval.blk.atmfieldtype == A_VPI ||
yyval.blk.atmfieldtype == A_VCI)
CHECK_PTR_VAL((yyval.blk.b = gen_atmfield_code(cstate, yyval.blk.atmfieldtype, yystack.l_mark[0].h, BPF_JEQ, 0)));
}
+#line 3395 "grammar.c"
break;
case 199:
-#line 802 "grammar.y"
+#line 830 "grammar.y"
{ gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+#line 3400 "grammar.c"
break;
case 200:
-#line 805 "grammar.y"
+#line 833 "grammar.y"
{ yyval.i = M_FISU; }
+#line 3405 "grammar.c"
break;
case 201:
-#line 806 "grammar.y"
+#line 834 "grammar.y"
{ yyval.i = M_LSSU; }
+#line 3410 "grammar.c"
break;
case 202:
-#line 807 "grammar.y"
+#line 835 "grammar.y"
{ yyval.i = M_MSU; }
+#line 3415 "grammar.c"
break;
case 203:
-#line 808 "grammar.y"
+#line 836 "grammar.y"
{ yyval.i = MH_FISU; }
+#line 3420 "grammar.c"
break;
case 204:
-#line 809 "grammar.y"
+#line 837 "grammar.y"
{ yyval.i = MH_LSSU; }
+#line 3425 "grammar.c"
break;
case 205:
-#line 810 "grammar.y"
+#line 838 "grammar.y"
{ yyval.i = MH_MSU; }
+#line 3430 "grammar.c"
break;
case 206:
-#line 813 "grammar.y"
+#line 841 "grammar.y"
{ yyval.blk.mtp3fieldtype = M_SIO; }
+#line 3435 "grammar.c"
break;
case 207:
-#line 814 "grammar.y"
+#line 842 "grammar.y"
{ yyval.blk.mtp3fieldtype = M_OPC; }
+#line 3440 "grammar.c"
break;
case 208:
-#line 815 "grammar.y"
+#line 843 "grammar.y"
{ yyval.blk.mtp3fieldtype = M_DPC; }
+#line 3445 "grammar.c"
break;
case 209:
-#line 816 "grammar.y"
+#line 844 "grammar.y"
{ yyval.blk.mtp3fieldtype = M_SLS; }
+#line 3450 "grammar.c"
break;
case 210:
-#line 817 "grammar.y"
+#line 845 "grammar.y"
{ yyval.blk.mtp3fieldtype = MH_SIO; }
+#line 3455 "grammar.c"
break;
case 211:
-#line 818 "grammar.y"
+#line 846 "grammar.y"
{ yyval.blk.mtp3fieldtype = MH_OPC; }
+#line 3460 "grammar.c"
break;
case 212:
-#line 819 "grammar.y"
+#line 847 "grammar.y"
{ yyval.blk.mtp3fieldtype = MH_DPC; }
+#line 3465 "grammar.c"
break;
case 213:
-#line 820 "grammar.y"
+#line 848 "grammar.y"
{ yyval.blk.mtp3fieldtype = MH_SLS; }
+#line 3470 "grammar.c"
break;
case 215:
-#line 823 "grammar.y"
+#line 851 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_mtp3field_code(cstate, yystack.l_mark[-2].blk.mtp3fieldtype, yystack.l_mark[0].h, yystack.l_mark[-1].i, 0))); }
+#line 3475 "grammar.c"
break;
case 216:
-#line 824 "grammar.y"
+#line 852 "grammar.y"
{ CHECK_PTR_VAL((yyval.blk.b = gen_mtp3field_code(cstate, yystack.l_mark[-2].blk.mtp3fieldtype, yystack.l_mark[0].h, yystack.l_mark[-1].i, 1))); }
+#line 3480 "grammar.c"
break;
case 217:
-#line 825 "grammar.y"
+#line 853 "grammar.y"
{ yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = qerr; }
+#line 3485 "grammar.c"
break;
case 218:
-#line 827 "grammar.y"
+#line 855 "grammar.y"
{
yyval.blk.mtp3fieldtype = yystack.l_mark[-1].blk.mtp3fieldtype;
if (yyval.blk.mtp3fieldtype == M_SIO ||
@@ -2462,68 +3497,245 @@
yyval.blk.mtp3fieldtype == MH_SLS)
CHECK_PTR_VAL((yyval.blk.b = gen_mtp3field_code(cstate, yyval.blk.mtp3fieldtype, yystack.l_mark[0].h, BPF_JEQ, 0)));
}
+#line 3501 "grammar.c"
break;
case 220:
-#line 841 "grammar.y"
+#line 869 "grammar.y"
{ gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+#line 3506 "grammar.c"
break;
-#line 2471 "grammar.c"
+#line 3508 "grammar.c"
+ default:
+ break;
}
yystack.s_mark -= yym;
yystate = *yystack.s_mark;
yystack.l_mark -= yym;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yystack.p_mark -= yym;
+#endif
yym = yylhs[yyn];
if (yystate == 0 && yym == 0)
{
#if YYDEBUG
if (yydebug)
- printf("%sdebug: after reduction, shifting from state 0 to\
- state %d\n", YYPREFIX, YYFINAL);
+ {
+ fprintf(stderr, "%s[%d]: after reduction, ", YYDEBUGSTR, yydepth);
+#ifdef YYSTYPE_TOSTRING
+#if YYBTYACC
+ if (!yytrial)
+#endif /* YYBTYACC */
+ fprintf(stderr, "result is <%s>, ", YYSTYPE_TOSTRING(yystos[YYFINAL], yyval));
+#endif
+ fprintf(stderr, "shifting from state 0 to final state %d\n", YYFINAL);
+ }
#endif
yystate = YYFINAL;
*++yystack.s_mark = YYFINAL;
*++yystack.l_mark = yyval;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ *++yystack.p_mark = yyloc;
+#endif
if (yychar < 0)
{
- if ((yychar = YYLEX) < 0) yychar = YYEOF;
+#if YYBTYACC
+ do {
+ if (yylvp < yylve)
+ {
+ /* we're currently re-reading tokens */
+ yylval = *yylvp++;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylloc = *yylpp++;
+#endif
+ yychar = *yylexp++;
+ break;
+ }
+ if (yyps->save)
+ {
+ /* in trial mode; save scanner results for future parse attempts */
+ if (yylvp == yylvlim)
+ { /* Enlarge lexical value queue */
+ size_t p = (size_t) (yylvp - yylvals);
+ size_t s = (size_t) (yylvlim - yylvals);
+
+ s += YYLVQUEUEGROWTH;
+ if ((yylexemes = (YYINT *)realloc(yylexemes, s * sizeof(YYINT))) == NULL)
+ goto yyenomem;
+ if ((yylvals = (YYSTYPE *)realloc(yylvals, s * sizeof(YYSTYPE))) == NULL)
+ goto yyenomem;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ if ((yylpsns = (YYLTYPE *)realloc(yylpsns, s * sizeof(YYLTYPE))) == NULL)
+ goto yyenomem;
+#endif
+ yylvp = yylve = yylvals + p;
+ yylvlim = yylvals + s;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylpp = yylpe = yylpsns + p;
+ yylplim = yylpsns + s;
+#endif
+ yylexp = yylexemes + p;
+ }
+ *yylexp = (YYINT) YYLEX;
+ *yylvp++ = yylval;
+ yylve++;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ *yylpp++ = yylloc;
+ yylpe++;
+#endif
+ yychar = *yylexp++;
+ break;
+ }
+ /* normal operation, no conflict encountered */
+#endif /* YYBTYACC */
+ yychar = YYLEX;
+#if YYBTYACC
+ } while (0);
+#endif /* YYBTYACC */
+ if (yychar < 0) yychar = YYEOF;
#if YYDEBUG
if (yydebug)
{
- yys = yyname[YYTRANSLATE(yychar)];
- printf("%sdebug: state %d, reading %d (%s)\n",
- YYPREFIX, YYFINAL, yychar, yys);
+ if ((yys = yyname[YYTRANSLATE(yychar)]) == NULL) yys = yyname[YYUNDFTOKEN];
+ fprintf(stderr, "%s[%d]: state %d, reading token %d (%s)\n",
+ YYDEBUGSTR, yydepth, YYFINAL, yychar, yys);
}
#endif
}
if (yychar == YYEOF) goto yyaccept;
goto yyloop;
}
- if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+ if (((yyn = yygindex[yym]) != 0) && (yyn += yystate) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) yystate)
yystate = yytable[yyn];
else
yystate = yydgoto[yym];
#if YYDEBUG
if (yydebug)
- printf("%sdebug: after reduction, shifting from state %d \
-to state %d\n", YYPREFIX, *yystack.s_mark, yystate);
-#endif
- if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM)
{
- goto yyoverflow;
+ fprintf(stderr, "%s[%d]: after reduction, ", YYDEBUGSTR, yydepth);
+#ifdef YYSTYPE_TOSTRING
+#if YYBTYACC
+ if (!yytrial)
+#endif /* YYBTYACC */
+ fprintf(stderr, "result is <%s>, ", YYSTYPE_TOSTRING(yystos[yystate], yyval));
+#endif
+ fprintf(stderr, "shifting from state %d to state %d\n", *yystack.s_mark, yystate);
}
+#endif
+ if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow;
*++yystack.s_mark = (YYINT) yystate;
*++yystack.l_mark = yyval;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ *++yystack.p_mark = yyloc;
+#endif
goto yyloop;
+#if YYBTYACC
+
+ /* Reduction declares that this path is valid. Set yypath and do a full parse */
+yyvalid:
+ if (yypath) YYABORT;
+ while (yyps->save)
+ {
+ YYParseState *save = yyps->save;
+ yyps->save = save->save;
+ save->save = yypath;
+ yypath = save;
+ }
+#if YYDEBUG
+ if (yydebug)
+ fprintf(stderr, "%s[%d]: state %d, CONFLICT trial successful, backtracking to state %d, %d tokens\n",
+ YYDEBUGSTR, yydepth, yystate, yypath->state, (int)(yylvp - yylvals - yypath->lexeme));
+#endif
+ if (yyerrctx)
+ {
+ yyFreeState(yyerrctx);
+ yyerrctx = NULL;
+ }
+ yylvp = yylvals + yypath->lexeme;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yylpp = yylpsns + yypath->lexeme;
+#endif
+ yylexp = yylexemes + yypath->lexeme;
+ yychar = YYEMPTY;
+ yystack.s_mark = yystack.s_base + (yypath->yystack.s_mark - yypath->yystack.s_base);
+ memcpy (yystack.s_base, yypath->yystack.s_base, (size_t) (yystack.s_mark - yystack.s_base + 1) * sizeof(YYINT));
+ yystack.l_mark = yystack.l_base + (yypath->yystack.l_mark - yypath->yystack.l_base);
+ memcpy (yystack.l_base, yypath->yystack.l_base, (size_t) (yystack.l_mark - yystack.l_base + 1) * sizeof(YYSTYPE));
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ yystack.p_mark = yystack.p_base + (yypath->yystack.p_mark - yypath->yystack.p_base);
+ memcpy (yystack.p_base, yypath->yystack.p_base, (size_t) (yystack.p_mark - yystack.p_base + 1) * sizeof(YYLTYPE));
+#endif
+ yystate = yypath->state;
+ goto yyloop;
+#endif /* YYBTYACC */
yyoverflow:
YYERROR_CALL("yacc stack overflow");
+#if YYBTYACC
+ goto yyabort_nomem;
+yyenomem:
+ YYERROR_CALL("memory exhausted");
+yyabort_nomem:
+#endif /* YYBTYACC */
+ yyresult = 2;
+ goto yyreturn;
yyabort:
- yyfreestack(&yystack);
- return (1);
+ yyresult = 1;
+ goto yyreturn;
yyaccept:
+#if YYBTYACC
+ if (yyps->save) goto yyvalid;
+#endif /* YYBTYACC */
+ yyresult = 0;
+
+yyreturn:
+#if defined(YYDESTRUCT_CALL)
+ if (yychar != YYEOF && yychar != YYEMPTY)
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ YYDESTRUCT_CALL("cleanup: discarding token", yychar, &yylval, &yylloc);
+#else
+ YYDESTRUCT_CALL("cleanup: discarding token", yychar, &yylval);
+#endif /* defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED) */
+
+ {
+ YYSTYPE *pv;
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+ YYLTYPE *pp;
+
+ for (pv = yystack.l_base, pp = yystack.p_base; pv <= yystack.l_mark; ++pv, ++pp)
+ YYDESTRUCT_CALL("cleanup: discarding state",
+ yystos[*(yystack.s_base + (pv - yystack.l_base))], pv, pp);
+#else
+ for (pv = yystack.l_base; pv <= yystack.l_mark; ++pv)
+ YYDESTRUCT_CALL("cleanup: discarding state",
+ yystos[*(yystack.s_base + (pv - yystack.l_base))], pv);
+#endif /* defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED) */
+ }
+#endif /* defined(YYDESTRUCT_CALL) */
+
+#if YYBTYACC
+ if (yyerrctx)
+ {
+ yyFreeState(yyerrctx);
+ yyerrctx = NULL;
+ }
+ while (yyps)
+ {
+ YYParseState *save = yyps;
+ yyps = save->save;
+ save->save = NULL;
+ yyFreeState(save);
+ }
+ while (yypath)
+ {
+ YYParseState *save = yypath;
+ yypath = save->save;
+ save->save = NULL;
+ yyFreeState(save);
+ }
+#endif /* YYBTYACC */
yyfreestack(&yystack);
- return (0);
+ return (yyresult);
}
diff --git a/grammar.h b/grammar.h
index 77af815..3326637 100644
--- a/grammar.h
+++ b/grammar.h
@@ -1,3 +1,6 @@
+#ifndef _pcap__defines_h_
+#define _pcap__defines_h_
+
#define DST 257
#define SRC 258
#define HOST 259
@@ -125,7 +128,7 @@
#endif
#ifndef YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_DECLARED 1
-typedef union {
+typedef union YYSTYPE {
int i;
bpf_u_int32 h;
char *s;
@@ -140,4 +143,5 @@
struct block *rblk;
} YYSTYPE;
#endif /* !YYSTYPE_IS_DECLARED */
-extern YYSTYPE pcap_lval;
+
+#endif /* _pcap__defines_h_ */
diff --git a/grammar.y.in b/grammar.y.in
index 2fbd861..b6a3d18 100644
--- a/grammar.y.in
+++ b/grammar.y.in
@@ -71,6 +71,13 @@
#include <config.h>
#endif
+/*
+ * grammar.h requires gencode.h and sometimes breaks in a polluted namespace
+ * (see ftmacros.h), so include it early.
+ */
+#include "gencode.h"
+#include "grammar.h"
+
#include <stdlib.h>
#ifndef _WIN32
@@ -92,17 +99,11 @@
#include "pcap-int.h"
-#include "gencode.h"
-#include "grammar.h"
#include "scanner.h"
-#ifdef HAVE_NET_PFVAR_H
-#include <net/if.h>
-#include <net/pfvar.h>
-#include <net/if_pflog.h>
-#endif
#include "llc.h"
#include "ieee80211.h"
+#include "pflog.h"
#include <pcap/namedb.h>
#ifdef HAVE_OS_PROTO_H
@@ -254,60 +255,87 @@
bpf_set_error(cstate, "can't parse filter expression: %s", msg);
}
-#ifdef HAVE_NET_PFVAR_H
+static const struct tok pflog_reasons[] = {
+ { PFRES_MATCH, "match" },
+ { PFRES_BADOFF, "bad-offset" },
+ { PFRES_FRAG, "fragment" },
+ { PFRES_SHORT, "short" },
+ { PFRES_NORM, "normalize" },
+ { PFRES_MEMORY, "memory" },
+ { PFRES_TS, "bad-timestamp" },
+ { PFRES_CONGEST, "congestion" },
+ { PFRES_IPOPTIONS, "ip-option" },
+ { PFRES_PROTCKSUM, "proto-cksum" },
+ { PFRES_BADSTATE, "state-mismatch" },
+ { PFRES_STATEINS, "state-insert" },
+ { PFRES_MAXSTATES, "state-limit" },
+ { PFRES_SRCLIMIT, "src-limit" },
+ { PFRES_SYNPROXY, "synproxy" },
+#if defined(__FreeBSD__)
+ { PFRES_MAPFAILED, "map-failed" },
+#elif defined(__NetBSD__)
+ { PFRES_STATELOCKED, "state-locked" },
+#elif defined(__OpenBSD__)
+ { PFRES_TRANSLATE, "translate" },
+ { PFRES_NOROUTE, "no-route" },
+#elif defined(__APPLE__)
+ { PFRES_DUMMYNET, "dummynet" },
+#endif
+ { 0, NULL }
+};
+
static int
pfreason_to_num(compiler_state_t *cstate, const char *reason)
{
- const char *reasons[] = PFRES_NAMES;
int i;
- for (i = 0; reasons[i]; i++) {
- if (pcap_strcasecmp(reason, reasons[i]) == 0)
- return (i);
- }
- bpf_set_error(cstate, "unknown PF reason \"%s\"", reason);
- return (-1);
+ i = str2tok(reason, pflog_reasons);
+ if (i == -1)
+ bpf_set_error(cstate, "unknown PF reason \"%s\"", reason);
+ return (i);
}
+static const struct tok pflog_actions[] = {
+ { PF_PASS, "pass" },
+ { PF_PASS, "accept" }, /* alias for "pass" */
+ { PF_DROP, "drop" },
+ { PF_DROP, "block" }, /* alias for "drop" */
+ { PF_SCRUB, "scrub" },
+ { PF_NOSCRUB, "noscrub" },
+ { PF_NAT, "nat" },
+ { PF_NONAT, "nonat" },
+ { PF_BINAT, "binat" },
+ { PF_NOBINAT, "nobinat" },
+ { PF_RDR, "rdr" },
+ { PF_NORDR, "nordr" },
+ { PF_SYNPROXY_DROP, "synproxy-drop" },
+#if defined(__FreeBSD__)
+ { PF_DEFER, "defer" },
+#elif defined(__OpenBSD__)
+ { PF_DEFER, "defer" },
+ { PF_MATCH, "match" },
+ { PF_DIVERT, "divert" },
+ { PF_RT, "rt" },
+ { PF_AFRT, "afrt" },
+#elif defined(__APPLE__)
+ { PF_DUMMYNET, "dummynet" },
+ { PF_NODUMMYNET, "nodummynet" },
+ { PF_NAT64, "nat64" },
+ { PF_NONAT64, "nonat64" },
+#endif
+ { 0, NULL },
+};
+
static int
pfaction_to_num(compiler_state_t *cstate, const char *action)
{
- if (pcap_strcasecmp(action, "pass") == 0 ||
- pcap_strcasecmp(action, "accept") == 0)
- return (PF_PASS);
- else if (pcap_strcasecmp(action, "drop") == 0 ||
- pcap_strcasecmp(action, "block") == 0)
- return (PF_DROP);
-#if HAVE_PF_NAT_THROUGH_PF_NORDR
- else if (pcap_strcasecmp(action, "rdr") == 0)
- return (PF_RDR);
- else if (pcap_strcasecmp(action, "nat") == 0)
- return (PF_NAT);
- else if (pcap_strcasecmp(action, "binat") == 0)
- return (PF_BINAT);
- else if (pcap_strcasecmp(action, "nordr") == 0)
- return (PF_NORDR);
-#endif
- else {
- bpf_set_error(cstate, "unknown PF action \"%s\"", action);
- return (-1);
- }
-}
-#else /* !HAVE_NET_PFVAR_H */
-static int
-pfreason_to_num(compiler_state_t *cstate, const char *reason _U_)
-{
- bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
- return (-1);
-}
+ int i;
-static int
-pfaction_to_num(compiler_state_t *cstate, const char *action _U_)
-{
- bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
- return (-1);
+ i = str2tok(action, pflog_actions);
+ if (i == -1)
+ bpf_set_error(cstate, "unknown PF action \"%s\"", action);
+ return (i);
}
-#endif /* HAVE_NET_PFVAR_H */
/*
* For calls that might return an "an error occurred" value.
diff --git a/nametoaddr.c b/nametoaddr.c
index c944ad3..7a04a61 100644
--- a/nametoaddr.c
+++ b/nametoaddr.c
@@ -267,7 +267,7 @@
* *not* always get set if getnetbyname_r() succeeds.
*/
np = NULL;
- err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
+ err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
&h_errnoval);
if (err != 0) {
/*
@@ -296,16 +296,16 @@
else
np = &result_buf;
#else
- /*
- * We don't have any getnetbyname_r(); either we have a
- * getnetbyname() that uses thread-specific data, in which
- * case we're thread-safe (sufficiently recent FreeBSD,
- * sufficiently recent Darwin-based OS, sufficiently recent
- * HP-UX, sufficiently recent Tru64 UNIX), or we have the
- * traditional getnetbyname() (everything else, including
- * current NetBSD and OpenBSD), in which case we're not
- * thread-safe.
- */
+ /*
+ * We don't have any getnetbyname_r(); either we have a
+ * getnetbyname() that uses thread-specific data, in which
+ * case we're thread-safe (sufficiently recent FreeBSD,
+ * sufficiently recent Darwin-based OS, sufficiently recent
+ * HP-UX, sufficiently recent Tru64 UNIX), or we have the
+ * traditional getnetbyname() (everything else, including
+ * current NetBSD and OpenBSD), in which case we're not
+ * thread-safe.
+ */
np = getnetbyname(name);
#endif
if (np != NULL)
@@ -552,16 +552,16 @@
else
p = &result_buf;
#else
- /*
- * We don't have any getprotobyname_r(); either we have a
- * getprotobyname() that uses thread-specific data, in which
- * case we're thread-safe (sufficiently recent FreeBSD,
- * sufficiently recent Darwin-based OS, sufficiently recent
- * HP-UX, sufficiently recent Tru64 UNIX, Windows), or we have
+ /*
+ * We don't have any getprotobyname_r(); either we have a
+ * getprotobyname() that uses thread-specific data, in which
+ * case we're thread-safe (sufficiently recent FreeBSD,
+ * sufficiently recent Darwin-based OS, sufficiently recent
+ * HP-UX, sufficiently recent Tru64 UNIX, Windows), or we have
* the traditional getprotobyname() (everything else, including
- * current NetBSD and OpenBSD), in which case we're not
- * thread-safe.
- */
+ * current NetBSD and OpenBSD), in which case we're not
+ * thread-safe.
+ */
p = getprotobyname(str);
#endif
if (p != 0)
@@ -785,9 +785,14 @@
{
register u_char *ap;
u_char a[6];
+ char namebuf[1024];
+ /*
+ * In AIX 7.1 and 7.2: int ether_hostton(char *, struct ether_addr *);
+ */
+ pcap_strlcpy(namebuf, name, sizeof(namebuf));
ap = NULL;
- if (ether_hostton(name, (struct ether_addr *)a) == 0) {
+ if (ether_hostton(namebuf, (struct ether_addr *)a) == 0) {
ap = (u_char *)malloc(6);
if (ap != NULL)
memcpy((char *)ap, (char *)a, 6);
diff --git a/optimize.c b/optimize.c
index 610a030..9af4c15 100644
--- a/optimize.c
+++ b/optimize.c
@@ -32,13 +32,14 @@
#include <memory.h>
#include <setjmp.h>
#include <string.h>
-
+#include <limits.h> /* for SIZE_MAX */
#include <errno.h>
#include "pcap-int.h"
#include "gencode.h"
#include "optimize.h"
+#include "diag-control.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
@@ -2098,7 +2099,7 @@
* versions of the machine code, eventually returning
* to the first version. (We're really not doing a
* full loop detection, we're just testing for two
- * passes in a row where where we do nothing but
+ * passes in a row where we do nothing but
* move branches.)
*/
return;
@@ -2421,6 +2422,9 @@
}
longjmp(opt_state->top_ctx, 1);
/* NOTREACHED */
+#ifdef _AIX
+ PCAP_UNREACHABLE
+#endif /* _AIX */
}
/*
@@ -2606,7 +2610,7 @@
}
/*
- * Make sure the total memory required for both of them dosn't
+ * Make sure the total memory required for both of them doesn't
* overflow.
*/
if (block_memsize > SIZE_MAX - edge_memsize) {
@@ -2895,7 +2899,6 @@
if (fp == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc");
- free(fp);
return NULL;
}
memset((char *)fp, 0, sizeof(*fp) * n);
@@ -2925,6 +2928,9 @@
va_end(ap);
longjmp(conv_state->top_ctx, 1);
/* NOTREACHED */
+#ifdef _AIX
+ PCAP_UNREACHABLE
+#endif /* _AIX */
}
/*
@@ -3023,14 +3029,14 @@
*
* example DOT for BPF `ip src host 1.1.1.1' is:
digraph BPF {
- block0 [shape=ellipse, id="block-0" label="BLOCK0\n\n(000) ldh [12]\n(001) jeq #0x800 jt 2 jf 5" tooltip="val[A]=0 val[X]=0"];
- block1 [shape=ellipse, id="block-1" label="BLOCK1\n\n(002) ld [26]\n(003) jeq #0x1010101 jt 4 jf 5" tooltip="val[A]=0 val[X]=0"];
- block2 [shape=ellipse, id="block-2" label="BLOCK2\n\n(004) ret #68" tooltip="val[A]=0 val[X]=0", peripheries=2];
- block3 [shape=ellipse, id="block-3" label="BLOCK3\n\n(005) ret #0" tooltip="val[A]=0 val[X]=0", peripheries=2];
- "block0":se -> "block1":n [label="T"];
- "block0":sw -> "block3":n [label="F"];
- "block1":se -> "block2":n [label="T"];
- "block1":sw -> "block3":n [label="F"];
+ block0 [shape=ellipse, id="block-0" label="BLOCK0\n\n(000) ldh [12]\n(001) jeq #0x800 jt 2 jf 5" tooltip="val[A]=0 val[X]=0"];
+ block1 [shape=ellipse, id="block-1" label="BLOCK1\n\n(002) ld [26]\n(003) jeq #0x1010101 jt 4 jf 5" tooltip="val[A]=0 val[X]=0"];
+ block2 [shape=ellipse, id="block-2" label="BLOCK2\n\n(004) ret #68" tooltip="val[A]=0 val[X]=0", peripheries=2];
+ block3 [shape=ellipse, id="block-3" label="BLOCK3\n\n(005) ret #0" tooltip="val[A]=0 val[X]=0", peripheries=2];
+ "block0":se -> "block1":n [label="T"];
+ "block0":sw -> "block3":n [label="F"];
+ "block1":se -> "block2":n [label="T"];
+ "block1":sw -> "block3":n [label="F"];
}
*
* After install graphviz on https://www.graphviz.org/, save it as bpf.dot
diff --git a/pcap-common.c b/pcap-common.c
index 51d0666..75461b1 100644
--- a/pcap-common.c
+++ b/pcap-common.c
@@ -28,11 +28,6 @@
#include <pcap-types.h>
#include "pcap-int.h"
-#include "extract.h"
-#include "pcap/sll.h"
-#include "pcap/usb.h"
-#include "pcap/nflog.h"
-#include "pcap/can_socketcan.h"
#include "pcap-common.h"
@@ -168,11 +163,20 @@
#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */
/*
- * These three types are reserved for future use.
+ * These two types are reserved for future use.
*/
#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */
#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */
-#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */
+
+/*
+ * Used for NetBSD DLT_HDLC; from looking at the one driver in NetBSD
+ * that uses it, it's Cisco HDLC, so it's the same as DLT_C_HDLC/
+ * LINKTYPE_C_HDLC, but we define a separate value to avoid some
+ * compatibility issues with programs on NetBSD.
+ *
+ * All code should treat LINKTYPE_NETBSD_HDLC and LINKTYPE_C_HDLC the same.
+ */
+#define LINKTYPE_NETBSD_HDLC 112 /* NetBSD HDLC framing */
#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */
#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */
@@ -405,7 +409,7 @@
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
* Every frame contains a 32bit A429 label.
* More documentation on Arinc 429 can be found at
- * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
+ * https://web.archive.org/web/20040616233302/https://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
*/
#define LINKTYPE_A429 184
@@ -956,13 +960,15 @@
/*
* Link-layer header type for upper-protocol layer PDU saves from wireshark.
*
- * the actual contents are determined by two TAGs stored with each
- * packet:
- * EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the
- * original packet.
+ * the actual contents are determined by two TAGs, one or more of
+ * which is stored with each packet:
*
- * EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector
- * that can make sense of the data stored.
+ * EXP_PDU_TAG_DISSECTOR_NAME the name of the Wireshark dissector
+ * that can make sense of the data stored.
+ *
+ * EXP_PDU_TAG_HEUR_DISSECTOR_NAME the name of the Wireshark heuristic
+ * dissector that can make sense of the
+ * data stored.
*/
#define LINKTYPE_WIRESHARK_UPPER_PDU 252
@@ -1234,10 +1240,11 @@
{ DLT_FR, LINKTYPE_FRELAY },
#endif
- { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
+ { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
{ DLT_RAW, LINKTYPE_RAW },
{ DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS },
{ DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS },
+ { DLT_HDLC, LINKTYPE_NETBSD_HDLC },
/* BSD/OS Cisco HDLC */
{ DLT_C_HDLC, LINKTYPE_C_HDLC },
@@ -1391,286 +1398,3 @@
return MAXIMUM_SNAPLEN;
}
}
-
-/*
- * DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
- * LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload,
- * with the CAN ID being in host byte order.
- *
- * When reading a DLT_LINUX_SLL capture file, we need to check for those
- * packets and convert the CAN ID from the byte order of the host that
- * wrote the file to this host's byte order.
- */
-static void
-swap_linux_sll_header(const struct pcap_pkthdr *hdr, u_char *buf)
-{
- u_int caplen = hdr->caplen;
- u_int length = hdr->len;
- struct sll_header *shdr = (struct sll_header *)buf;
- uint16_t protocol;
- pcap_can_socketcan_hdr *chdr;
-
- if (caplen < (u_int) sizeof(struct sll_header) ||
- length < (u_int) sizeof(struct sll_header)) {
- /* Not enough data to have the protocol field */
- return;
- }
-
- protocol = EXTRACT_BE_U_2(&shdr->sll_protocol);
- if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD)
- return;
-
- /*
- * SocketCAN packet; fix up the packet's header.
- */
- chdr = (pcap_can_socketcan_hdr *)(buf + sizeof(struct sll_header));
- if (caplen < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id) ||
- length < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id)) {
- /* Not enough data to have the CAN ID */
- return;
- }
- chdr->can_id = SWAPLONG(chdr->can_id);
-}
-
-/*
- * The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
- * byte order when capturing (it's supplied directly from a
- * memory-mapped buffer shared by the kernel).
- *
- * When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED capture file,
- * we need to convert it from the byte order of the host that wrote
- * the file to this host's byte order.
- */
-static void
-swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
- int header_len_64_bytes)
-{
- pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
- bpf_u_int32 offset = 0;
-
- /*
- * "offset" is the offset *past* the field we're swapping;
- * we skip the field *before* checking to make sure
- * the captured data length includes the entire field.
- */
-
- /*
- * The URB id is a totally opaque value; do we really need to
- * convert it to the reading host's byte order???
- */
- offset += 8; /* skip past id */
- if (hdr->caplen < offset)
- return;
- uhdr->id = SWAPLL(uhdr->id);
-
- offset += 4; /* skip past various 1-byte fields */
-
- offset += 2; /* skip past bus_id */
- if (hdr->caplen < offset)
- return;
- uhdr->bus_id = SWAPSHORT(uhdr->bus_id);
-
- offset += 2; /* skip past various 1-byte fields */
-
- offset += 8; /* skip past ts_sec */
- if (hdr->caplen < offset)
- return;
- uhdr->ts_sec = SWAPLL(uhdr->ts_sec);
-
- offset += 4; /* skip past ts_usec */
- if (hdr->caplen < offset)
- return;
- uhdr->ts_usec = SWAPLONG(uhdr->ts_usec);
-
- offset += 4; /* skip past status */
- if (hdr->caplen < offset)
- return;
- uhdr->status = SWAPLONG(uhdr->status);
-
- offset += 4; /* skip past urb_len */
- if (hdr->caplen < offset)
- return;
- uhdr->urb_len = SWAPLONG(uhdr->urb_len);
-
- offset += 4; /* skip past data_len */
- if (hdr->caplen < offset)
- return;
- uhdr->data_len = SWAPLONG(uhdr->data_len);
-
- if (uhdr->transfer_type == URB_ISOCHRONOUS) {
- offset += 4; /* skip past s.iso.error_count */
- if (hdr->caplen < offset)
- return;
- uhdr->s.iso.error_count = SWAPLONG(uhdr->s.iso.error_count);
-
- offset += 4; /* skip past s.iso.numdesc */
- if (hdr->caplen < offset)
- return;
- uhdr->s.iso.numdesc = SWAPLONG(uhdr->s.iso.numdesc);
- } else
- offset += 8; /* skip USB setup header */
-
- /*
- * With the old header, there are no isochronous descriptors
- * after the header.
- *
- * With the new header, the actual number of descriptors in
- * the header is not s.iso.numdesc, it's ndesc - only the
- * first N descriptors, for some value of N, are put into
- * the header, and ndesc is set to the actual number copied.
- * In addition, if s.iso.numdesc is negative, no descriptors
- * are captured, and ndesc is set to 0.
- */
- if (header_len_64_bytes) {
- /*
- * This is either the "version 1" header, with
- * 16 bytes of additional fields at the end, or
- * a "version 0" header from a memory-mapped
- * capture, with 16 bytes of zeroed-out padding
- * at the end. Byte swap them as if this were
- * a "version 1" header.
- */
- offset += 4; /* skip past interval */
- if (hdr->caplen < offset)
- return;
- uhdr->interval = SWAPLONG(uhdr->interval);
-
- offset += 4; /* skip past start_frame */
- if (hdr->caplen < offset)
- return;
- uhdr->start_frame = SWAPLONG(uhdr->start_frame);
-
- offset += 4; /* skip past xfer_flags */
- if (hdr->caplen < offset)
- return;
- uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags);
-
- offset += 4; /* skip past ndesc */
- if (hdr->caplen < offset)
- return;
- uhdr->ndesc = SWAPLONG(uhdr->ndesc);
-
- if (uhdr->transfer_type == URB_ISOCHRONOUS) {
- /* swap the values in struct linux_usb_isodesc */
- usb_isodesc *pisodesc;
- uint32_t i;
-
- pisodesc = (usb_isodesc *)(void *)(buf+offset);
- for (i = 0; i < uhdr->ndesc; i++) {
- offset += 4; /* skip past status */
- if (hdr->caplen < offset)
- return;
- pisodesc->status = SWAPLONG(pisodesc->status);
-
- offset += 4; /* skip past offset */
- if (hdr->caplen < offset)
- return;
- pisodesc->offset = SWAPLONG(pisodesc->offset);
-
- offset += 4; /* skip past len */
- if (hdr->caplen < offset)
- return;
- pisodesc->len = SWAPLONG(pisodesc->len);
-
- offset += 4; /* skip past padding */
-
- pisodesc++;
- }
- }
- }
-}
-
-/*
- * The DLT_NFLOG "packets" have a mixture of big-endian and host-byte-order
- * data. They begin with a fixed-length header with big-endian fields,
- * followed by a set of TLVs, where the type and length are in host
- * byte order but the values are either big-endian or are a raw byte
- * sequence that's the same regardless of the host's byte order.
- *
- * When reading a DLT_NFLOG capture file, we need to convert the type
- * and length values from the byte order of the host that wrote the
- * file to the byte order of this host.
- */
-static void
-swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
-{
- u_char *p = buf;
- nflog_hdr_t *nfhdr = (nflog_hdr_t *)buf;
- nflog_tlv_t *tlv;
- u_int caplen = hdr->caplen;
- u_int length = hdr->len;
- uint16_t size;
-
- if (caplen < (u_int) sizeof(nflog_hdr_t) ||
- length < (u_int) sizeof(nflog_hdr_t)) {
- /* Not enough data to have any TLVs. */
- return;
- }
-
- if (nfhdr->nflog_version != 0) {
- /* Unknown NFLOG version */
- return;
- }
-
- length -= sizeof(nflog_hdr_t);
- caplen -= sizeof(nflog_hdr_t);
- p += sizeof(nflog_hdr_t);
-
- while (caplen >= sizeof(nflog_tlv_t)) {
- tlv = (nflog_tlv_t *) p;
-
- /* Swap the type and length. */
- tlv->tlv_type = SWAPSHORT(tlv->tlv_type);
- tlv->tlv_length = SWAPSHORT(tlv->tlv_length);
-
- /* Get the length of the TLV. */
- size = tlv->tlv_length;
- if (size % 4 != 0)
- size += 4 - size % 4;
-
- /* Is the TLV's length less than the minimum? */
- if (size < sizeof(nflog_tlv_t)) {
- /* Yes. Give up now. */
- return;
- }
-
- /* Do we have enough data for the full TLV? */
- if (caplen < size || length < size) {
- /* No. */
- return;
- }
-
- /* Skip over the TLV. */
- length -= size;
- caplen -= size;
- p += size;
- }
-}
-
-void
-swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
-{
- /*
- * Convert pseudo-headers from the byte order of
- * the host on which the file was saved to our
- * byte order, as necessary.
- */
- switch (linktype) {
-
- case DLT_LINUX_SLL:
- swap_linux_sll_header(hdr, data);
- break;
-
- case DLT_USB_LINUX:
- swap_linux_usb_header(hdr, data, 0);
- break;
-
- case DLT_USB_LINUX_MMAPPED:
- swap_linux_usb_header(hdr, data, 1);
- break;
-
- case DLT_NFLOG:
- swap_nflog_header(hdr, data);
- break;
- }
-}
diff --git a/pcap-common.h b/pcap-common.h
index 8795a82..d765c94 100644
--- a/pcap-common.h
+++ b/pcap-common.h
@@ -21,33 +21,8 @@
* pcap-common.h - common code for pcap and pcapng files
*/
-/*
- * We use the "receiver-makes-right" approach to byte order,
- * because time is at a premium when we are writing the file.
- * In other words, the pcap_file_header and pcap_pkthdr,
- * records are written in host byte order.
- * Note that the bytes of packet data are written out in the order in
- * which they were received, so multi-byte fields in packets are not
- * written in host byte order, they're written in whatever order the
- * sending machine put them in.
- *
- * ntoh[ls] aren't sufficient because we might need to swap on a big-endian
- * machine (if the file was written in little-end order).
- */
-#define SWAPLONG(y) \
- (((((u_int)(y))&0xff)<<24) | \
- ((((u_int)(y))&0xff00)<<8) | \
- ((((u_int)(y))&0xff0000)>>8) | \
- ((((u_int)(y))>>24)&0xff))
-#define SWAPSHORT(y) \
- ((u_short)(((((u_int)(y))&0xff)<<8) | \
- ((((u_int)(y))&0xff00)>>8)))
-
extern int dlt_to_linktype(int dlt);
extern int linktype_to_dlt(int linktype);
-extern void swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr,
- u_char *data);
-
extern u_int max_snaplen_for_dlt(int dlt);
diff --git a/pcap-int.h b/pcap-int.h
index dc18d50..894e74a 100644
--- a/pcap-int.h
+++ b/pcap-int.h
@@ -53,6 +53,24 @@
#include "portability.h"
/*
+ * If we're compiling with Visual Studio, make sure we have at least
+ * VS 2015 or later, so we have sufficient C99 support.
+ *
+ * XXX - verify that we have at least C99 support on UN*Xes?
+ *
+ * What about MinGW or various DOS toolchains? We're currently assuming
+ * sufficient C99 support there.
+ */
+#if defined(_MSC_VER)
+ /*
+ * Compiler is MSVC. Make sure we have VS 2015 or later.
+ */
+ #if _MSC_VER < 1900
+ #error "Building libpcap requires VS 2015 or later"
+ #endif
+#endif
+
+/*
* Version string.
* Uses PACKAGE_VERSION from config.h.
*/
@@ -467,7 +485,7 @@
/*
* This wrapper takes an error buffer pointer and a type to use for the
* private data, and calls pcap_create_common(), passing it the error
- * buffer pointer, the size fo the private data type, in bytes, and the
+ * buffer pointer, the size for the private data type, in bytes, and the
* offset of the private data from the beginning of the structure, in
* bytes.
*/
@@ -551,7 +569,7 @@
/*
* This wrapper takes an error buffer pointer and a type to use for the
* private data, and calls pcap_create_common(), passing it the error
- * buffer pointer, the size fo the private data type, in bytes, and the
+ * buffer pointer, the size for the private data type, in bytes, and the
* offset of the private data from the beginning of the structure, in
* bytes.
*/
diff --git a/pcap-usb-linux-common.c b/pcap-usb-linux-common.c
new file mode 100644
index 0000000..fb4a8c1
--- /dev/null
+++ b/pcap-usb-linux-common.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * pcap-usb-linux-common.c - common code for everything that needs to
+ * deal with Linux USB captures.
+ */
+
+#include "pcap/pcap.h"
+#include "pcap/usb.h"
+
+#include "pcap-usb-linux-common.h"
+
+/*
+ * Compute, from the data provided by the Linux USB memory-mapped capture
+ * mechanism, the amount of packet data that would have been provided
+ * had the capture mechanism not chopped off any data at the end, if, in
+ * fact, it did so.
+ *
+ * Set the "unsliced length" field of the packet header to that value.
+ */
+void
+fix_linux_usb_mmapped_length(struct pcap_pkthdr *pkth, const u_char *bp)
+{
+ const pcap_usb_header_mmapped *hdr;
+ u_int bytes_left;
+
+ /*
+ * All callers of this routine must ensure that pkth->caplen is
+ * >= sizeof (pcap_usb_header_mmapped).
+ */
+ bytes_left = pkth->caplen;
+ bytes_left -= sizeof (pcap_usb_header_mmapped);
+
+ hdr = (const pcap_usb_header_mmapped *) bp;
+ if (!hdr->data_flag && hdr->transfer_type == URB_ISOCHRONOUS &&
+ hdr->event_type == URB_COMPLETE &&
+ (hdr->endpoint_number & URB_TRANSFER_IN) &&
+ pkth->len == sizeof(pcap_usb_header_mmapped) +
+ (hdr->ndesc * sizeof (usb_isodesc)) + hdr->urb_len) {
+ usb_isodesc *descs;
+ u_int pre_truncation_data_len, pre_truncation_len;
+
+ descs = (usb_isodesc *) (bp + sizeof(pcap_usb_header_mmapped));
+
+ /*
+ * We have data (yes, data_flag is 0 if we *do* have data),
+ * and this is a "this is complete" incoming isochronous
+ * transfer event, and the length was calculated based
+ * on the URB length.
+ *
+ * That's not correct, because the data isn't contiguous,
+ * and the isochronous descriptos show how it's scattered.
+ *
+ * Find the end of the last chunk of data in the buffer
+ * referred to by the isochronous descriptors; that indicates
+ * how far into the buffer the data would have gone.
+ *
+ * Make sure we don't run past the end of the captured data
+ * while processing the isochronous descriptors.
+ */
+ pre_truncation_data_len = 0;
+ for (uint32_t desc = 0;
+ desc < hdr->ndesc && bytes_left >= sizeof (usb_isodesc);
+ desc++, bytes_left -= sizeof (usb_isodesc)) {
+ u_int desc_end;
+
+ if (descs[desc].len != 0) {
+ desc_end = descs[desc].offset + descs[desc].len;
+ if (desc_end > pre_truncation_data_len)
+ pre_truncation_data_len = desc_end;
+ }
+ }
+
+ /*
+ * Now calculate the total length based on that data
+ * length.
+ */
+ pre_truncation_len = sizeof(pcap_usb_header_mmapped) +
+ (hdr->ndesc * sizeof (usb_isodesc)) +
+ pre_truncation_data_len;
+
+ /*
+ * If that's greater than or equal to the captured length,
+ * use that as the length.
+ */
+ if (pre_truncation_len >= pkth->caplen)
+ pkth->len = pre_truncation_len;
+
+ /*
+ * If the captured length is greater than the length,
+ * use the captured length.
+ *
+ * For completion events for incoming isochronous transfers,
+ * it's based on data_len, which is calculated the same way
+ * we calculated pre_truncation_data_len above, except that
+ * it has access to all the isochronous descriptors, not
+ * just the ones that the kernel were able to provide us or,
+ * for a capture file, that weren't sliced off by a snapshot
+ * length.
+ *
+ * However, it might have been reduced by the USB capture
+ * mechanism arbitrarily limiting the amount of data it
+ * provides to userland, or by the libpcap capture code
+ * limiting it to being no more than the snapshot, so
+ * we don't want to just use it all the time; we only
+ * do so to try to get a better estimate of the actual
+ * length - and to make sure the on-the-network length
+ * is always >= the captured length.
+ */
+ if (pkth->caplen > pkth->len)
+ pkth->len = pkth->caplen;
+ }
+}
diff --git a/pcap-usb-linux-common.h b/pcap-usb-linux-common.h
new file mode 100644
index 0000000..8cff7ba
--- /dev/null
+++ b/pcap-usb-linux-common.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * pcap-usb-linux-common.h - common code for everything that needs to
+ * deal with Linux USB captures.
+ */
+
+extern void fix_linux_usb_mmapped_length(struct pcap_pkthdr *pkth,
+ const u_char *bp);
diff --git a/pcap-util.c b/pcap-util.c
new file mode 100644
index 0000000..8b5669e
--- /dev/null
+++ b/pcap-util.c
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * pcap-common.c - common code for pcap and pcapng files
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pcap-types.h>
+
+#include "pcap-int.h"
+#include "extract.h"
+#include "pcap-usb-linux-common.h"
+
+#include "pcap-util.h"
+
+#include "pflog.h"
+#include "pcap/can_socketcan.h"
+#include "pcap/sll.h"
+#include "pcap/usb.h"
+#include "pcap/nflog.h"
+
+/*
+ * Most versions of the DLT_PFLOG pseudo-header have UID and PID fields
+ * that are saved in host byte order.
+ *
+ * When reading a DLT_PFLOG packet, we need to convert those fields from
+ * the byte order of the host that wrote the file to this host's byte
+ * order.
+ */
+static void
+swap_pflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
+{
+ u_int caplen = hdr->caplen;
+ u_int length = hdr->len;
+ u_int pfloghdr_length;
+ struct pfloghdr *pflhdr = (struct pfloghdr *)buf;
+
+ if (caplen < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid) ||
+ length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) {
+ /* Not enough data to have the uid field */
+ return;
+ }
+
+ pfloghdr_length = pflhdr->length;
+
+ if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) {
+ /* Header doesn't include uid field */
+ return;
+ }
+ pflhdr->uid = SWAPLONG(pflhdr->uid);
+
+ if (caplen < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid) ||
+ length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) {
+ /* Not enough data to have the pid field */
+ return;
+ }
+ if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) {
+ /* Header doesn't include pid field */
+ return;
+ }
+ pflhdr->pid = SWAPLONG(pflhdr->pid);
+
+ if (caplen < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid) ||
+ length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) {
+ /* Not enough data to have the rule_uid field */
+ return;
+ }
+ if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) {
+ /* Header doesn't include rule_uid field */
+ return;
+ }
+ pflhdr->rule_uid = SWAPLONG(pflhdr->rule_uid);
+
+ if (caplen < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid) ||
+ length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) {
+ /* Not enough data to have the rule_pid field */
+ return;
+ }
+ if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) {
+ /* Header doesn't include rule_pid field */
+ return;
+ }
+ pflhdr->rule_pid = SWAPLONG(pflhdr->rule_pid);
+}
+
+/*
+ * DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
+ * LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload,
+ * with the CAN ID being in host byte order.
+ *
+ * When reading a DLT_LINUX_SLL packet, we need to check for those
+ * packets and convert the CAN ID from the byte order of the host that
+ * wrote the file to this host's byte order.
+ */
+static void
+swap_linux_sll_header(const struct pcap_pkthdr *hdr, u_char *buf)
+{
+ u_int caplen = hdr->caplen;
+ u_int length = hdr->len;
+ struct sll_header *shdr = (struct sll_header *)buf;
+ uint16_t protocol;
+ pcap_can_socketcan_hdr *chdr;
+
+ if (caplen < (u_int) sizeof(struct sll_header) ||
+ length < (u_int) sizeof(struct sll_header)) {
+ /* Not enough data to have the protocol field */
+ return;
+ }
+
+ protocol = EXTRACT_BE_U_2(&shdr->sll_protocol);
+ if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD)
+ return;
+
+ /*
+ * SocketCAN packet; fix up the packet's header.
+ */
+ chdr = (pcap_can_socketcan_hdr *)(buf + sizeof(struct sll_header));
+ if (caplen < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id) ||
+ length < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id)) {
+ /* Not enough data to have the CAN ID */
+ return;
+ }
+ chdr->can_id = SWAPLONG(chdr->can_id);
+}
+
+/*
+ * The same applies for DLT_LINUX_SLL2.
+ */
+static void
+swap_linux_sll2_header(const struct pcap_pkthdr *hdr, u_char *buf)
+{
+ u_int caplen = hdr->caplen;
+ u_int length = hdr->len;
+ struct sll2_header *shdr = (struct sll2_header *)buf;
+ uint16_t protocol;
+ pcap_can_socketcan_hdr *chdr;
+
+ if (caplen < (u_int) sizeof(struct sll2_header) ||
+ length < (u_int) sizeof(struct sll2_header)) {
+ /* Not enough data to have the protocol field */
+ return;
+ }
+
+ protocol = EXTRACT_BE_U_2(&shdr->sll2_protocol);
+ if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD)
+ return;
+
+ /*
+ * SocketCAN packet; fix up the packet's header.
+ */
+ chdr = (pcap_can_socketcan_hdr *)(buf + sizeof(struct sll2_header));
+ if (caplen < (u_int) sizeof(struct sll2_header) + sizeof(chdr->can_id) ||
+ length < (u_int) sizeof(struct sll2_header) + sizeof(chdr->can_id)) {
+ /* Not enough data to have the CAN ID */
+ return;
+ }
+ chdr->can_id = SWAPLONG(chdr->can_id);
+}
+
+/*
+ * The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
+ * byte order when capturing (it's supplied directly from a
+ * memory-mapped buffer shared by the kernel).
+ *
+ * When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED packet, we
+ * need to convert it from the byte order of the host that wrote the
+ * file to this host's byte order.
+ */
+static void
+swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
+ int header_len_64_bytes)
+{
+ pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
+ bpf_u_int32 offset = 0;
+
+ /*
+ * "offset" is the offset *past* the field we're swapping;
+ * we skip the field *before* checking to make sure
+ * the captured data length includes the entire field.
+ */
+
+ /*
+ * The URB id is a totally opaque value; do we really need to
+ * convert it to the reading host's byte order???
+ */
+ offset += 8; /* skip past id */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->id = SWAPLL(uhdr->id);
+
+ offset += 4; /* skip past various 1-byte fields */
+
+ offset += 2; /* skip past bus_id */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->bus_id = SWAPSHORT(uhdr->bus_id);
+
+ offset += 2; /* skip past various 1-byte fields */
+
+ offset += 8; /* skip past ts_sec */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->ts_sec = SWAPLL(uhdr->ts_sec);
+
+ offset += 4; /* skip past ts_usec */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->ts_usec = SWAPLONG(uhdr->ts_usec);
+
+ offset += 4; /* skip past status */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->status = SWAPLONG(uhdr->status);
+
+ offset += 4; /* skip past urb_len */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->urb_len = SWAPLONG(uhdr->urb_len);
+
+ offset += 4; /* skip past data_len */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->data_len = SWAPLONG(uhdr->data_len);
+
+ if (uhdr->transfer_type == URB_ISOCHRONOUS) {
+ offset += 4; /* skip past s.iso.error_count */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->s.iso.error_count = SWAPLONG(uhdr->s.iso.error_count);
+
+ offset += 4; /* skip past s.iso.numdesc */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->s.iso.numdesc = SWAPLONG(uhdr->s.iso.numdesc);
+ } else
+ offset += 8; /* skip USB setup header */
+
+ /*
+ * With the old header, there are no isochronous descriptors
+ * after the header.
+ *
+ * With the new header, the actual number of descriptors in
+ * the header is not s.iso.numdesc, it's ndesc - only the
+ * first N descriptors, for some value of N, are put into
+ * the header, and ndesc is set to the actual number copied.
+ * In addition, if s.iso.numdesc is negative, no descriptors
+ * are captured, and ndesc is set to 0.
+ */
+ if (header_len_64_bytes) {
+ /*
+ * This is either the "version 1" header, with
+ * 16 bytes of additional fields at the end, or
+ * a "version 0" header from a memory-mapped
+ * capture, with 16 bytes of zeroed-out padding
+ * at the end. Byte swap them as if this were
+ * a "version 1" header.
+ */
+ offset += 4; /* skip past interval */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->interval = SWAPLONG(uhdr->interval);
+
+ offset += 4; /* skip past start_frame */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->start_frame = SWAPLONG(uhdr->start_frame);
+
+ offset += 4; /* skip past xfer_flags */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags);
+
+ offset += 4; /* skip past ndesc */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->ndesc = SWAPLONG(uhdr->ndesc);
+
+ if (uhdr->transfer_type == URB_ISOCHRONOUS) {
+ /* swap the values in struct linux_usb_isodesc */
+ usb_isodesc *pisodesc;
+ uint32_t i;
+
+ pisodesc = (usb_isodesc *)(void *)(buf+offset);
+ for (i = 0; i < uhdr->ndesc; i++) {
+ offset += 4; /* skip past status */
+ if (hdr->caplen < offset)
+ return;
+ pisodesc->status = SWAPLONG(pisodesc->status);
+
+ offset += 4; /* skip past offset */
+ if (hdr->caplen < offset)
+ return;
+ pisodesc->offset = SWAPLONG(pisodesc->offset);
+
+ offset += 4; /* skip past len */
+ if (hdr->caplen < offset)
+ return;
+ pisodesc->len = SWAPLONG(pisodesc->len);
+
+ offset += 4; /* skip past padding */
+
+ pisodesc++;
+ }
+ }
+ }
+}
+
+/*
+ * The DLT_NFLOG "packets" have a mixture of big-endian and host-byte-order
+ * data. They begin with a fixed-length header with big-endian fields,
+ * followed by a set of TLVs, where the type and length are in host
+ * byte order but the values are either big-endian or are a raw byte
+ * sequence that's the same regardless of the host's byte order.
+ *
+ * When reading a DLT_NFLOG packet, we need to convert the type and
+ * length values from the byte order of the host that wrote the file
+ * to the byte order of this host.
+ */
+static void
+swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
+{
+ u_char *p = buf;
+ nflog_hdr_t *nfhdr = (nflog_hdr_t *)buf;
+ nflog_tlv_t *tlv;
+ u_int caplen = hdr->caplen;
+ u_int length = hdr->len;
+ uint16_t size;
+
+ if (caplen < (u_int) sizeof(nflog_hdr_t) ||
+ length < (u_int) sizeof(nflog_hdr_t)) {
+ /* Not enough data to have any TLVs. */
+ return;
+ }
+
+ if (nfhdr->nflog_version != 0) {
+ /* Unknown NFLOG version */
+ return;
+ }
+
+ length -= sizeof(nflog_hdr_t);
+ caplen -= sizeof(nflog_hdr_t);
+ p += sizeof(nflog_hdr_t);
+
+ while (caplen >= sizeof(nflog_tlv_t)) {
+ tlv = (nflog_tlv_t *) p;
+
+ /* Swap the type and length. */
+ tlv->tlv_type = SWAPSHORT(tlv->tlv_type);
+ tlv->tlv_length = SWAPSHORT(tlv->tlv_length);
+
+ /* Get the length of the TLV. */
+ size = tlv->tlv_length;
+ if (size % 4 != 0)
+ size += 4 - size % 4;
+
+ /* Is the TLV's length less than the minimum? */
+ if (size < sizeof(nflog_tlv_t)) {
+ /* Yes. Give up now. */
+ return;
+ }
+
+ /* Do we have enough data for the full TLV? */
+ if (caplen < size || length < size) {
+ /* No. */
+ return;
+ }
+
+ /* Skip over the TLV. */
+ length -= size;
+ caplen -= size;
+ p += size;
+ }
+}
+
+static void
+swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
+{
+ /*
+ * Convert pseudo-headers from the byte order of
+ * the host on which the file was saved to our
+ * byte order, as necessary.
+ */
+ switch (linktype) {
+
+ case DLT_PFLOG:
+ swap_pflog_header(hdr, data);
+ break;
+
+ case DLT_LINUX_SLL:
+ swap_linux_sll_header(hdr, data);
+ break;
+
+ case DLT_LINUX_SLL2:
+ swap_linux_sll2_header(hdr, data);
+ break;
+
+ case DLT_USB_LINUX:
+ swap_linux_usb_header(hdr, data, 0);
+ break;
+
+ case DLT_USB_LINUX_MMAPPED:
+ swap_linux_usb_header(hdr, data, 1);
+ break;
+
+ case DLT_NFLOG:
+ swap_nflog_header(hdr, data);
+ break;
+ }
+}
+
+void
+pcap_post_process(int linktype, int swapped, struct pcap_pkthdr *hdr,
+ u_char *data)
+{
+ if (swapped)
+ swap_pseudo_headers(linktype, hdr, data);
+
+ fixup_pcap_pkthdr(linktype, hdr, data);
+}
+
+void
+fixup_pcap_pkthdr(int linktype, struct pcap_pkthdr *hdr, const u_char *data)
+{
+ const pcap_usb_header_mmapped *usb_hdr;
+
+ usb_hdr = (const pcap_usb_header_mmapped *) data;
+ if (linktype == DLT_USB_LINUX_MMAPPED &&
+ hdr->caplen >= sizeof (pcap_usb_header_mmapped)) {
+ /*
+ * In older versions of libpcap, in memory-mapped captures,
+ * the "on-the-bus length" for completion events for
+ * incoming isochronous transfers was miscalculated; it
+ * needed to be calculated based on the* offsets and lengths
+ * in the descriptors, not on the raw URB length, but it
+ * wasn't.
+ *
+ * If this packet contains transferred data (yes, data_flag
+ * is 0 if we *do* have data), and the total on-the-network
+ * length is equal to the value calculated from the raw URB
+ * length, then it might be one of those transfers.
+ *
+ * We only do this if we have the full USB pseudo-header.
+ */
+ if (!usb_hdr->data_flag &&
+ hdr->len == sizeof(pcap_usb_header_mmapped) +
+ (usb_hdr->ndesc * sizeof (usb_isodesc)) + usb_hdr->urb_len) {
+ /*
+ * It might need fixing; fix it if it's a completion
+ * event for an incoming isochronous transfer.
+ */
+ fix_linux_usb_mmapped_length(hdr, data);
+ }
+ }
+}
diff --git a/pcap-util.h b/pcap-util.h
new file mode 100644
index 0000000..de95819
--- /dev/null
+++ b/pcap-util.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * pcap-util.h - common code for various files
+ */
+
+/*
+ * We use the "receiver-makes-right" approach to byte order;
+ * because time is at a premium when we are writing the file.
+ * In other words, the pcap_file_header and pcap_pkthdr,
+ * records are written in host byte order.
+ * Note that the bytes of packet data are written out in the order in
+ * which they were received, so multi-byte fields in packets are not
+ * written in host byte order, they're written in whatever order the
+ * sending machine put them in.
+ *
+ * We also use this for fixing up packet data headers from a remote
+ * capture, where the server may have a different byte order from the
+ * client.
+ *
+ * ntoh[ls] aren't sufficient because we might need to swap on a big-endian
+ * machine (if the file was written in little-end order).
+ */
+#define SWAPLONG(y) \
+ (((((u_int)(y))&0xff)<<24) | \
+ ((((u_int)(y))&0xff00)<<8) | \
+ ((((u_int)(y))&0xff0000)>>8) | \
+ ((((u_int)(y))>>24)&0xff))
+#define SWAPSHORT(y) \
+ ((u_short)(((((u_int)(y))&0xff)<<8) | \
+ ((((u_int)(y))&0xff00)>>8)))
+
+extern void pcap_post_process(int linktype, int swapped,
+ struct pcap_pkthdr *hdr, u_char *data);
+
+extern void fixup_pcap_pkthdr(int linktype, struct pcap_pkthdr *hdr,
+ const u_char *data);
+
diff --git a/pcap.c b/pcap.c
index ed8570a..ef1bbb7 100644
--- a/pcap.c
+++ b/pcap.c
@@ -131,8 +131,6 @@
#ifdef _WIN32
/*
- * DllMain(), required when built as a Windows DLL.
- *
* To quote the WSAStartup() documentation:
*
* The WSAStartup function typically leads to protocol-specific helper
@@ -147,19 +145,12 @@
* be called from the DllMain function in a application DLL. This can
* potentially cause deadlocks.
*
- * So we don't initialize Winsock here. pcap_init() should be called
- * to initialize pcap on both UN*X and Windows; it will initialize
- * Winsock on Windows. (It will also be initialized as needed if
- * pcap_init() hasn't been called.)
+ * So we don't initialize Winsock in a DllMain() routine.
+ *
+ * pcap_init() should be called to initialize pcap on both UN*X and
+ * Windows; it will initialize Winsock on Windows. (It will also be
+ * initialized as needed if pcap_init() hasn't been called.)
*/
-BOOL WINAPI DllMain(
- HANDLE hinstDLL _U_,
- DWORD dwReason _U_,
- LPVOID lpvReserved _U_
-)
-{
- return (TRUE);
-}
/*
* Start Winsock.
@@ -259,7 +250,7 @@
if (pcap_utf_8_mode) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Multiple pcap_init calls with different character encodings");
- return (-1);
+ return (PCAP_ERROR);
}
}
break;
@@ -270,7 +261,7 @@
if (!pcap_utf_8_mode) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Multiple pcap_init calls with different character encodings");
- return (-1);
+ return (PCAP_ERROR);
}
}
pcap_utf_8_mode = 1;
@@ -278,7 +269,7 @@
default:
snprintf(errbuf, PCAP_ERRBUF_SIZE, "Unknown options specified");
- return (-1);
+ return (PCAP_ERROR);
}
/*
@@ -303,7 +294,7 @@
*/
if (internal_wsockinit(errbuf) == -1) {
/* Failed. */
- return (-1);
+ return (PCAP_ERROR);
}
#endif
@@ -622,7 +613,9 @@
* Return codes for pcap_offline_read() are:
* - 0: EOF
* - -1: error
- * - >1: OK
+ * - >0: OK - result is number of packets read, so
+ * it will be 1 in this case, as we've passed
+ * a maximum packet count of 1
* The first one ('0') conflicts with the return code of
* 0 from pcap_read() meaning "no packets arrived before
* the timeout expired", so we map it to -2 so you can
@@ -641,7 +634,9 @@
* - 0: timeout
* - -1: error
* - -2: loop was broken out of with pcap_breakloop()
- * - >1: OK
+ * - >0: OK, result is number of packets captured, so
+ * it will be 1 in this case, as we've passed
+ * a maximum packet count of 1
* The first one ('0') conflicts with the return code of 0 from
* pcap_offline_read() meaning "end of file".
*/
@@ -2849,17 +2844,41 @@
goto fail;
return (p);
fail:
- if (status == PCAP_ERROR)
+ if (status == PCAP_ERROR) {
+ /*
+ * Another buffer is a bit cumbersome, but it avoids
+ * -Wformat-truncation.
+ */
+ char trimbuf[PCAP_ERRBUF_SIZE - 5]; /* 2 bytes shorter */
+
+ pcap_strlcpy(trimbuf, p->errbuf, sizeof(trimbuf));
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %.*s", device,
- PCAP_ERRBUF_SIZE - 3, p->errbuf);
- else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
+ PCAP_ERRBUF_SIZE - 3, trimbuf);
+ } else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
status == PCAP_ERROR_PERM_DENIED ||
- status == PCAP_ERROR_PROMISC_PERM_DENIED)
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%.*s)", device,
- pcap_statustostr(status), PCAP_ERRBUF_SIZE - 6, p->errbuf);
- else
+ status == PCAP_ERROR_PROMISC_PERM_DENIED) {
+ /*
+ * Only show the additional message if it's not
+ * empty.
+ */
+ if (p->errbuf[0] != '\0') {
+ /*
+ * Idem.
+ */
+ char trimbuf[PCAP_ERRBUF_SIZE - 8]; /* 2 bytes shorter */
+
+ pcap_strlcpy(trimbuf, p->errbuf, sizeof(trimbuf));
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%.*s)",
+ device, pcap_statustostr(status),
+ PCAP_ERRBUF_SIZE - 6, trimbuf);
+ } else {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
+ device, pcap_statustostr(status));
+ }
+ } else {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
pcap_statustostr(status));
+ }
pcap_close(p);
return (NULL);
}
@@ -3350,7 +3369,7 @@
if (description != NULL) {
return description;
} else {
- (void)snprintf(unkbuf, sizeof(unkbuf), "DLT %u", dlt);
+ (void)snprintf(unkbuf, sizeof(unkbuf), "DLT %d", dlt);
return unkbuf;
}
}
@@ -3461,14 +3480,14 @@
/*
* This is a bogus and now-deprecated API; we
* squelch the narrowing warning for the cast
- * from HANDLE to DWORD. If Windows programmmers
+ * from HANDLE to intptr_t. If Windows programmmers
* need to get at the HANDLE for a pcap_t, *if*
* there is one, they should request such a
* routine (and be prepared for it to return
* INVALID_HANDLE_VALUE).
*/
DIAG_OFF_NARROWING
- return ((int)(DWORD)p->handle);
+ return ((int)(intptr_t)p->handle);
DIAG_ON_NARROWING
} else
return (PCAP_ERROR);
@@ -3644,7 +3663,7 @@
return ("That operation is supported only in monitor mode");
case PCAP_ERROR_PERM_DENIED:
- return ("You don't have permission to capture on that device");
+ return ("You don't have permission to perform this capture on that device");
case PCAP_ERROR_IFACE_NOT_UP:
return ("That device is not up");
@@ -3986,6 +4005,10 @@
void
pcap_cleanup_live_common(pcap_t *p)
{
+ if (p->opt.device != NULL) {
+ free(p->opt.device);
+ p->opt.device = NULL;
+ }
if (p->buffer != NULL) {
free(p->buffer);
p->buffer = NULL;
@@ -4064,14 +4087,12 @@
void
pcap_close(pcap_t *p)
{
- if (p->opt.device != NULL)
- free(p->opt.device);
p->cleanup_op(p);
free(p);
}
/*
- * Helpers for safely loding code at run time.
+ * Helpers for safely loading code at run time.
* Currently Windows-only.
*/
#ifdef _WIN32
@@ -4180,6 +4201,20 @@
return (-1);
}
+static void
+pcap_breakloop_dead(pcap_t *p _U_)
+{
+ /*
+ * A "dead" pcap_t is just a placeholder to use in order to
+ * compile a filter to BPF code or to open a savefile for
+ * writing. It doesn't support any operations, including
+ * capturing or reading packets, so there will never be a
+ * get-packets loop in progress to break out *of*.
+ *
+ * As such, this routine doesn't need to do anything.
+ */
+}
+
static int
pcap_inject_dead(pcap_t *p, const void *buf _U_, int size _U_)
{
@@ -4393,6 +4428,7 @@
p->live_dump_ended_op = pcap_live_dump_ended_dead;
p->get_airpcap_handle_op = pcap_get_airpcap_handle_dead;
#endif
+ p->breakloop_op = pcap_breakloop_dead;
p->cleanup_op = pcap_cleanup_dead;
/*
diff --git a/pcap/bpf.h b/pcap/bpf.h
index 54373af..3970d0a 100644
--- a/pcap/bpf.h
+++ b/pcap/bpf.h
@@ -80,7 +80,6 @@
#define lib_pcap_bpf_h
#include <pcap/funcattrs.h>
-
#include <pcap/dlt.h>
#ifdef __cplusplus
@@ -150,7 +149,7 @@
#define BPF_B 0x10
/* 0x18 reserved; used by BSD/OS */
#define BPF_MODE(code) ((code) & 0xe0)
-#define BPF_IMM 0x00
+#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
@@ -244,8 +243,8 @@
*/
struct bpf_insn {
u_short code;
- u_char jt;
- u_char jf;
+ u_char jt;
+ u_char jf;
bpf_u_int32 k;
};
diff --git a/pcap/can_socketcan.h b/pcap/can_socketcan.h
index 332d9ff..0cb3584 100644
--- a/pcap/can_socketcan.h
+++ b/pcap/can_socketcan.h
@@ -48,9 +48,14 @@
typedef struct {
uint32_t can_id;
uint8_t payload_length;
- uint8_t pad;
+ uint8_t fd_flags;
uint8_t reserved1;
uint8_t reserved2;
} pcap_can_socketcan_hdr;
+/* Bits in the fd_flags field */
+#define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */
+#define CANFD_ESI 0x02 /* error state indicator of the transmitting node */
+#define CANFD_FDF 0x04 /* mark CAN FD for dual use of CAN format */
+
#endif
diff --git a/pcap/compiler-tests.h b/pcap/compiler-tests.h
index a69c2b0..2d98a70 100644
--- a/pcap/compiler-tests.h
+++ b/pcap/compiler-tests.h
@@ -80,9 +80,11 @@
*/
#if ! defined(__GNUC__)
-#define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) 0
+ /* Not GCC and not "just like GCC" */
+ #define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) 0
#else
-#define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) \
+ /* GCC or "just like GCC" */
+ #define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) \
(__GNUC__ > (major) || \
(__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
#endif
@@ -92,9 +94,11 @@
*/
#if !defined(__clang__)
-#define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) 0
+ /* Not Clang */
+ #define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) 0
#else
-#define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) \
+ /* Clang */
+ #define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) \
(__clang_major__ > (major) || \
(__clang_major__ == (major) && __clang_minor__ >= (minor)))
#endif
@@ -118,13 +122,15 @@
*/
#if ! defined(__SUNPRO_C)
-#define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) 0
+ /* Not Sun/Oracle C */
+ #define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) 0
#else
-#define PCAP_SUNPRO_VERSION_TO_BCD(major, minor) \
+ /* Sun/Oracle C */
+ #define PCAP_SUNPRO_VERSION_TO_BCD(major, minor) \
(((minor) >= 10) ? \
(((major) << 12) | (((minor)/10) << 8) | (((minor)%10) << 4)) : \
(((major) << 8) | ((minor) << 4)))
-#define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) \
+ #define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) \
(__SUNPRO_C >= PCAP_SUNPRO_VERSION_TO_BCD((major), (minor)))
#endif
@@ -133,13 +139,31 @@
*
* The version number in __xlC__ has the major version in the
* upper 8 bits and the minor version in the lower 8 bits.
+ * On AIX __xlC__ is always defined, __ibmxl__ becomes defined in XL C 16.1.
+ * On Linux since XL C 13.1.6 __xlC__ is not defined by default anymore, but
+ * __ibmxl__ is defined since at least XL C 13.1.1.
*/
-#if ! defined(__xlC__)
-#define PCAP_IS_AT_LEAST_XL_C_VERSION(major,minor) 0
+#if ! defined(__xlC__) && ! defined(__ibmxl__)
+ /* Not XL C */
+ #define PCAP_IS_AT_LEAST_XL_C_VERSION(major,minor) 0
#else
-#define PCAP_IS_AT_LEAST_XL_C_VERSION(major, minor) \
+ /* XL C */
+ #if defined(__ibmxl__)
+ /*
+ * Later Linux version of XL C; use __ibmxl_version__ to test
+ * the version.
+ */
+ #define PCAP_IS_AT_LEAST_XL_C_VERSION(major, minor) \
+ (__ibmxl_version__ > (major) || \
+ (__ibmxl_version__ == (major) && __ibmxl_release__ >= (minor)))
+ #else /* __ibmxl__ */
+ /*
+ * __ibmxl__ not defined; use __xlC__ to test the version.
+ */
+ #define PCAP_IS_AT_LEAST_XL_C_VERSION(major, minor) \
(__xlC__ >= (((major) << 8) | (minor)))
+ #endif /* __ibmxl__ */
#endif
/*
@@ -154,9 +178,11 @@
*/
#if ! defined(__HP_aCC)
-#define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) 0
+ /* Not HP C */
+ #define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) 0
#else
-#define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) \
+ /* HP C */
+ #define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) \
(__HP_aCC >= ((major)*10000 + (minor)*100))
#endif
diff --git a/pcap/dlt.h b/pcap/dlt.h
index eaba34f..0da6de2 100644
--- a/pcap/dlt.h
+++ b/pcap/dlt.h
@@ -105,6 +105,67 @@
#endif
/*
+ * NetBSD uses 15 for HIPPI.
+ *
+ * From a quick look at sys/net/if_hippi.h and sys/net/if_hippisubr.c
+ * in an older version of NetBSD , the header appears to be:
+ *
+ * a 1-byte ULP field (ULP-id)?
+ *
+ * a 1-byte flags field;
+ *
+ * a 2-byte "offsets" field;
+ *
+ * a 4-byte "D2 length" field (D2_Size?);
+ *
+ * a 4-byte "destination switch" field (or a 1-byte field
+ * containing the Forwarding Class, Double_Wide, and Message_Type
+ * sub fields, followed by a 3-byte Destination_Switch_Address
+ * field?, HIPPI-LE 3.4-style?);
+ *
+ * a 4-byte "source switch" field (or a 1-byte field containing the
+ * Destination_Address_type and Source_Address_Type fields, followed
+ * by a 3-byte Source_Switch_Address field, HIPPI-LE 3.4-style?);
+ *
+ * a 2-byte reserved field;
+ *
+ * a 6-byte destination address field;
+ *
+ * a 2-byte "local admin" field;
+ *
+ * a 6-byte source address field;
+ *
+ * followed by an 802.2 LLC header.
+ *
+ * This looks somewhat like something derived from the HIPPI-FP 4.4
+ * Header_Area, followed an HIPPI-FP 4.4 D1_Area containing a D1 data set
+ * with the header in HIPPI-LE 3.4 (ANSI X3.218-1993), followed by an
+ * HIPPI-FP 4.4 D2_Area (with no Offset) containing the 802.2 LLC header
+ * and payload? Or does the "offsets" field contain the D2_Offset,
+ * with that many bytes of offset before the payload?
+ *
+ * See http://wotug.org/parallel/standards/hippi/ for an archive of
+ * HIPPI specifications.
+ *
+ * RFC 2067 imposes some additional restrictions. It says that the
+ * Offset is always zero
+ *
+ * HIPPI is long-gone, and the source files found in an older version
+ * of NetBSD don't appear to be in the main CVS branch, so we may never
+ * see a capture with this link-layer type.
+ */
+#if defined(__NetBSD__)
+#define DLT_HIPPI 15 /* HIPPI */
+#endif
+
+/*
+ * NetBSD uses 16 for DLT_HDLC; see below.
+ * BSD/OS uses it for PPP; see above.
+ * As far as I know, no other OS uses it for anything; don't use it
+ * for anything else.
+ */
+
+/*
* 17 was used for DLT_PFLOG in OpenBSD; it no longer is.
*
* It was DLT_LANE8023 in SuSE 6.3, so we defined LINKTYPE_PFLOG
@@ -219,7 +280,8 @@
* that the AF_ type in the link-layer header is in network byte order.
*
* DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so
- * we don't use 12 for it in OSes other than OpenBSD.
+ * we don't use 12 for it in OSes other than OpenBSD; instead, we
+ * use the same value as LINKTYPE_LOOP.
*/
#ifdef __OpenBSD__
#define DLT_LOOP 12
@@ -230,7 +292,7 @@
/*
* Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's
* DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other
- * than OpenBSD.
+ * than OpenBSD; instead, we use the same value as LINKTYPE_ENC.
*/
#ifdef __OpenBSD__
#define DLT_ENC 13
@@ -239,13 +301,23 @@
#endif
/*
- * Values between 110 and 112 are reserved for use in capture file headers
+ * Values 110 and 111 are reserved for use in capture file headers
* as link-layer types corresponding to DLT_ types that might differ
* between platforms; don't use those values for new DLT_ types
* other than the corresponding DLT_ types.
*/
/*
+ * NetBSD uses 16 for (Cisco) "HDLC framing". For other platforms,
+ * we define it to have the same value as LINKTYPE_NETBSD_HDLC.
+ */
+#if defined(__NetBSD__)
+#define DLT_HDLC 16 /* Cisco HDLC */
+#else
+#define DLT_HDLC 112
+#endif
+
+/*
* Linux cooked sockets.
*/
#define DLT_LINUX_SLL 113
@@ -651,7 +723,7 @@
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
* Every frame contains a 32bit A429 label.
* More documentation on Arinc 429 can be found at
- * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
+ * https://web.archive.org/web/20040616233302/https://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
*/
#define DLT_A429 184
@@ -1214,15 +1286,17 @@
#define DLT_BLUETOOTH_LE_LL 251
/*
- * DLT type for upper-protocol layer PDU saves from wireshark.
+ * DLT type for upper-protocol layer PDU saves from Wireshark.
*
- * the actual contents are determined by two TAGs stored with each
- * packet:
- * EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the
- * original packet.
+ * the actual contents are determined by two TAGs, one or more of
+ * which is stored with each packet:
*
- * EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector
- * that can make sense of the data stored.
+ * EXP_PDU_TAG_DISSECTOR_NAME the name of the Wireshark dissector
+ * that can make sense of the data stored.
+ *
+ * EXP_PDU_TAG_HEUR_DISSECTOR_NAME the name of the Wireshark heuristic
+ * dissector that can make sense of the
+ * data stored.
*/
#define DLT_WIRESHARK_UPPER_PDU 252
diff --git a/pcap/funcattrs.h b/pcap/funcattrs.h
index a2ca542..3740949 100644
--- a/pcap/funcattrs.h
+++ b/pcap/funcattrs.h
@@ -118,14 +118,14 @@
#if PCAP_IS_AT_LEAST_GNUC_VERSION(3,4) \
|| PCAP_IS_AT_LEAST_XL_C_VERSION(12,0)
/*
- * GCC 3.4 or later, or some compiler asserting compatibility with
- * GCC 3.4 or later, or XL C 13.0 or later, so we have
+ * GCC 3.4 and later, or some compiler asserting compatibility with
+ * GCC 3.4 and later, or XL C 13.0 and later, so we have
* __attribute__((visibility()).
*/
#define PCAP_API_DEF __attribute__((visibility("default")))
#elif PCAP_IS_AT_LEAST_SUNC_VERSION(5,5)
/*
- * Sun C 5.5 or later, so we have __global.
+ * Sun C 5.5 and later, so we have __global.
* (Sun C 5.9 and later also have __attribute__((visibility()),
* but there's no reason to prefer it with Sun C.)
*/
@@ -161,6 +161,15 @@
* provided by Apple, so each release can come with a version compiled
* to use the APIs present in that release.)
*
+ * The non-macOS versioning is based on
+ *
+ * https://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history
+ *
+ * If there are any corrections, please submit it upstream to the
+ * libpcap maintainers, preferably as a pull request on
+ *
+ * https://github.com/the-tcpdump-group/libpcap
+ *
* We don't define it ourselves because, if you're building and
* installing libpcap on macOS yourself, the APIs will be available
* no matter what OS version you're installing it on.
@@ -172,25 +181,32 @@
* I've never seen earlier releases.
*/
#ifdef __APPLE__
-#define PCAP_AVAILABLE_MACOS(v) /* define to say "first appears in v" */
-#define PCAP_AVAILABLE_0_4 PCAP_AVAILABLE_MACOS(10.0) /* Did any version of Mac OS X ship with this? */
-#define PCAP_AVAILABLE_0_5 PCAP_AVAILABLE_MACOS(10.0) /* Did any version of Mac OS X ship with this? */
-#define PCAP_AVAILABLE_0_6 PCAP_AVAILABLE_MACOS(10.1)
-#define PCAP_AVAILABLE_0_7 PCAP_AVAILABLE_MACOS(10.4)
-#define PCAP_AVAILABLE_0_8 PCAP_AVAILABLE_MACOS(10.4)
-#define PCAP_AVAILABLE_0_9 PCAP_AVAILABLE_MACOS(10.5)
-#define PCAP_AVAILABLE_1_0 PCAP_AVAILABLE_MACOS(10.6)
+#include <Availability.h>
+/*
+ * When building as part of macOS, define this as __API_AVAILABLE(__VA_ARGS__).
+ *
+ * XXX - if there's some #define to indicate that this is being built
+ * as part of the macOS build process, we could make that Just Work.
+ */
+#define PCAP_AVAILABLE(...)
+#define PCAP_AVAILABLE_0_4 PCAP_AVAILABLE(macos(10.0)) /* Did any version of Mac OS X ship with this? */
+#define PCAP_AVAILABLE_0_5 PCAP_AVAILABLE(macos(10.0)) /* Did any version of Mac OS X ship with this? */
+#define PCAP_AVAILABLE_0_6 PCAP_AVAILABLE(macos(10.1))
+#define PCAP_AVAILABLE_0_7 PCAP_AVAILABLE(macos(10.4))
+#define PCAP_AVAILABLE_0_8 PCAP_AVAILABLE(macos(10.4))
+#define PCAP_AVAILABLE_0_9 PCAP_AVAILABLE(macos(10.5), ios(1.0))
+#define PCAP_AVAILABLE_1_0 PCAP_AVAILABLE(macos(10.6), ios(4.0))
/* #define PCAP_AVAILABLE_1_1 no routines added to the API */
-#define PCAP_AVAILABLE_1_2 PCAP_AVAILABLE_MACOS(10.9)
+#define PCAP_AVAILABLE_1_2 PCAP_AVAILABLE(macos(10.9), ios(6.0))
/* #define PCAP_AVAILABLE_1_3 no routines added to the API */
/* #define PCAP_AVAILABLE_1_4 no routines added to the API */
-#define PCAP_AVAILABLE_1_5 PCAP_AVAILABLE_MACOS(10.10)
+#define PCAP_AVAILABLE_1_5 PCAP_AVAILABLE(macos(10.10), ios(7.0), watchos(1.0))
/* #define PCAP_AVAILABLE_1_6 no routines added to the API */
-#define PCAP_AVAILABLE_1_7 PCAP_AVAILABLE_MACOS(10.12)
-#define PCAP_AVAILABLE_1_8 PCAP_AVAILABLE_MACOS(10.13) /* only Windows adds routines to the API; XXX - what version first had it? */
-#define PCAP_AVAILABLE_1_9 PCAP_AVAILABLE_MACOS(10.13)
+#define PCAP_AVAILABLE_1_7 PCAP_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
+#define PCAP_AVAILABLE_1_8 PCAP_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)) /* only Windows adds routines to the API; XXX - what version first had it? */
+#define PCAP_AVAILABLE_1_9 PCAP_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
#define PCAP_AVAILABLE_1_10 /* not in macOS yet */
-#define PCAP_AVAILABLE_1_11 /* not released yet, so not in macOS yet */
+#define PCAP_AVAILABLE_1_11 /* not released yet, so not in macOS yet */
#else /* __APPLE__ */
#define PCAP_AVAILABLE_0_4
#define PCAP_AVAILABLE_0_5
@@ -230,11 +246,11 @@
|| PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10)
/*
- * Compiler with support for __attribute((noreturn)), or GCC 2.5 or
- * later, or some compiler asserting compatibility with GCC 2.5 or
- * later, or Solaris Studio 12 (Sun C 5.9) or later, or IBM XL C 10.1
- * or later (do any earlier versions of XL C support this?), or HP aCC
- * A.06.10 or later.
+ * Compiler with support for __attribute((noreturn)), or GCC 2.5 and
+ * later, or some compiler asserting compatibility with GCC 2.5 and
+ * later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1
+ * and later (do any earlier versions of XL C support this?), or HP aCC
+ * A.06.10 and later.
*/
#define PCAP_NORETURN __attribute((noreturn))
#define PCAP_NORETURN_DEF __attribute((noreturn))
@@ -260,8 +276,8 @@
|| PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10)
/*
- * Compiler with support for it, or GCC 2.3 or later, or some compiler
- * asserting compatibility with GCC 2.3 or later, or IBM XL C 10.1
+ * Compiler with support for it, or GCC 2.3 and later, or some compiler
+ * asserting compatibility with GCC 2.3 and later, or IBM XL C 10.1
* and later (do any earlier versions of XL C support this?),
* or HP aCC A.06.10 and later.
*/
@@ -274,23 +290,21 @@
* PCAP_DEPRECATED(func, msg), after a function declaration, marks the
* function as deprecated.
*
- * The first argument is the name of the function; the second argument is
- * a string giving the warning message to use if the compiler supports that.
- *
- * (Thank you, Microsoft, for requiring the function name.)
+ * The argument is a string giving the warning message to use if the
+ * compiler supports that.
*/
#if __has_attribute(deprecated) \
|| PCAP_IS_AT_LEAST_GNUC_VERSION(4,5) \
|| PCAP_IS_AT_LEAST_SUNC_VERSION(5,13)
/*
* Compiler that supports __has_attribute and __attribute__((deprecated)),
- * or GCC 4.5 or later, or Sun/Oracle C 12.4 (Sun C 5.13) or later.
+ * or GCC 4.5 and later, or Sun/Oracle C 12.4 (Sun C 5.13) and later.
*
* Those support __attribute__((deprecated(msg))) (we assume, perhaps
* incorrectly, that anything that supports __has_attribute() is
* recent enough to support __attribute__((deprecated(msg)))).
*/
- #define PCAP_DEPRECATED(func, msg) __attribute__((deprecated(msg)))
+ #define PCAP_DEPRECATED(msg) __attribute__((deprecated(msg)))
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(3,1)
/*
* GCC 3.1 through 4.4.
@@ -298,18 +312,18 @@
* Those support __attribute__((deprecated)) but not
* __attribute__((deprecated(msg))).
*/
- #define PCAP_DEPRECATED(func, msg) __attribute__((deprecated))
+ #define PCAP_DEPRECATED(msg) __attribute__((deprecated))
#elif defined(_MSC_VER) && !defined(BUILDING_PCAP)
/*
* MSVC, and we're not building libpcap itself; it's VS 2015
- * or later, so we have the deprecated pragma.
+ * and later, so we have __declspec(deprecated(...)).
*
* If we *are* building libpcap, we don't want this, as it'll warn
* us even if we *define* the function.
*/
- #define PCAP_DEPRECATED(func, msg) __pragma(deprecated(func))
+ #define PCAP_DEPRECATED(msg) _declspec(deprecated(msg))
#else
- #define PCAP_DEPRECATED(func, msg)
+ #define PCAP_DEPRECATED(msg)
#endif
/*
diff --git a/pcap/namedb.h b/pcap/namedb.h
index 34a0ae7..51d1e31 100644
--- a/pcap/namedb.h
+++ b/pcap/namedb.h
@@ -59,8 +59,9 @@
PCAP_API u_char *pcap_ether_hostton(const char*);
PCAP_API u_char *pcap_ether_aton(const char *);
-PCAP_API bpf_u_int32 **pcap_nametoaddr(const char *)
-PCAP_DEPRECATED(pcap_nametoaddr, "this is not reentrant; use 'pcap_nametoaddrinfo' instead");
+PCAP_API
+PCAP_DEPRECATED("this is not reentrant; use 'pcap_nametoaddrinfo' instead")
+bpf_u_int32 **pcap_nametoaddr(const char *);
PCAP_API struct addrinfo *pcap_nametoaddrinfo(const char *);
PCAP_API bpf_u_int32 pcap_nametonetaddr(const char *);
diff --git a/pcap/pcap-inttypes.h b/pcap/pcap-inttypes.h
index 1cfa0bf..8c7b4f6 100644
--- a/pcap/pcap-inttypes.h
+++ b/pcap/pcap-inttypes.h
@@ -32,8 +32,8 @@
#define pcap_pcap_inttypes_h
/*
- * If we're compiling with Visual Studio, make sure we have at least
- * VS 2015 or later, so we have sufficient C99 support.
+ * If we're compiling with Visual Studio, make sure the C99 integer
+ * types are defined, by hook or by crook.
*
* XXX - verify that we have at least C99 support on UN*Xes?
*
@@ -42,39 +42,60 @@
*/
#if defined(_MSC_VER)
/*
- * Compiler is MSVC. Make sure we have VS 2015 or later.
+ * Compiler is MSVC.
*/
- #if _MSC_VER < 1900
- #error "Building libpcap requires VS 2015 or later"
+ #if _MSC_VER >= 1800
+ /*
+ * VS 2013 or newer; we have <inttypes.h>.
+ */
+ #include <inttypes.h>
+ #else
+ /*
+ * Earlier VS; we have to define this stuff ourselves.
+ * We don't support building libpcap with earlier versions of VS,
+ * but SDKs for Npcap have to support building applications using
+ * earlier versions of VS, so we work around this by defining
+ * those types ourselves, as some files use them.
+ */
+ typedef unsigned char uint8_t;
+ typedef signed char int8_t;
+ typedef unsigned short uint16_t;
+ typedef signed short int16_t;
+ typedef unsigned int uint32_t;
+ typedef signed int int32_t;
+ #ifdef _MSC_EXTENSIONS
+ typedef unsigned _int64 uint64_t;
+ typedef _int64 int64_t;
+ #else /* _MSC_EXTENSIONS */
+ typedef unsigned long long uint64_t;
+ typedef long long int64_t;
+ #endif
#endif
-#endif
+#else /* defined(_MSC_VER) */
+ /*
+ * Not Visual Studio.
+ * Include <inttypes.h> to get the integer types and PRi[doux]64 values
+ * defined.
+ *
+ * If the compiler is MinGW, we assume we have <inttypes.h> - and
+ * support for %zu in the formatted printing functions.
+ *
+ * If the target is UN*X, we assume we have a C99-or-later development
+ * environment, and thus have <inttypes.h> - and support for %zu in
+ * the formatted printing functions.
+ *
+ * If the target is MS-DOS, we assume we have <inttypes.h> - and support
+ * for %zu in the formatted printing functions.
+ *
+ * I.e., assume we have <inttypes.h> and that it suffices.
+ */
-/*
- * Include <inttypes.h> to get the integer types and PRi[doux]64 values
- * defined.
- *
- * If the compiler is MSVC, we require VS 2015 or newer, so we
- * have <inttypes.h> - and support for %zu in the formatted
- * printing functions.
- *
- * If the compiler is MinGW, we assume we have <inttypes.h> - and
- * support for %zu in the formatted printing functions.
- *
- * If the target is UN*X, we assume we have a C99-or-later development
- * environment, and thus have <inttypes.h> - and support for %zu in
- * the formatted printing functions.
- *
- * If the target is MS-DOS, we assume we have <inttypes.h> - and support
- * for %zu in the formatted printing functions.
- *
- * I.e., assume we have <inttypes.h> and that it suffices.
- */
+ /*
+ * XXX - somehow make sure we have enough C99 support with other
+ * compilers and support libraries?
+ */
-/*
- * XXX - somehow make sure we have enough C99 support with other
- * compilers and support libraries?
- */
-
-#include <inttypes.h>
+ #include <inttypes.h>
+#endif /* defined(_MSC_VER) */
#endif /* pcap/pcap-inttypes.h */
diff --git a/pcap/pcap.h b/pcap/pcap.h
index 8182bef..6894b3c 100644
--- a/pcap/pcap.h
+++ b/pcap/pcap.h
@@ -71,7 +71,7 @@
/*
* Some software that uses libpcap/WinPcap/Npcap defines _MSC_VER before
- * includeing pcap.h if it's not defined - and it defines it to 1500.
+ * including pcap.h if it's not defined - and it defines it to 1500.
* (I'm looking at *you*, lwIP!)
*
* Attempt to detect this, and undefine _MSC_VER so that we can *reliably*
@@ -391,8 +391,8 @@
* should use pcap_findalldevs() and use the first device.
*/
PCAP_AVAILABLE_0_4
-PCAP_API char *pcap_lookupdev(char *)
-PCAP_DEPRECATED(pcap_lookupdev, "use 'pcap_findalldevs' and use the first device");
+PCAP_DEPRECATED("use 'pcap_findalldevs' and use the first device")
+PCAP_API char *pcap_lookupdev(char *);
PCAP_AVAILABLE_0_4
PCAP_API int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
@@ -571,7 +571,7 @@
PCAP_API const u_char *pcap_next(pcap_t *, struct pcap_pkthdr *);
PCAP_AVAILABLE_0_8
-PCAP_API int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
+PCAP_API int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
PCAP_AVAILABLE_0_8
PCAP_API void pcap_breakloop(pcap_t *);
@@ -583,7 +583,7 @@
PCAP_API int pcap_setfilter(pcap_t *, struct bpf_program *);
PCAP_AVAILABLE_0_9
-PCAP_API int pcap_setdirection(pcap_t *, pcap_direction_t);
+PCAP_API int pcap_setdirection(pcap_t *, pcap_direction_t);
PCAP_AVAILABLE_0_7
PCAP_API int pcap_getnonblock(pcap_t *, char *);
@@ -614,6 +614,7 @@
bpf_u_int32);
PCAP_AVAILABLE_0_5
+PCAP_DEPRECATED("use pcap_open_dead(), pcap_compile() and pcap_close()")
PCAP_API int pcap_compile_nopcap(int, int, struct bpf_program *,
const char *, int, bpf_u_int32);
@@ -680,8 +681,8 @@
* a Windows-only pcap_handle() API that returns the HANDLE.
*/
PCAP_AVAILABLE_0_4
-PCAP_API int pcap_fileno(pcap_t *)
-PCAP_DEPRECATED(pcap_fileno, "use 'pcap_handle'");
+PCAP_DEPRECATED("request a 'pcap_handle' that returns a HANDLE if you need it")
+PCAP_API int pcap_fileno(pcap_t *);
#else /* _WIN32 */
PCAP_AVAILABLE_0_4
PCAP_API int pcap_fileno(pcap_t *);
@@ -878,7 +879,7 @@
/*
* The formats allowed by pcap_open() are the following:
* - file://path_and_filename [opens a local file]
- * - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol]
+ * - rpcap://devicename [opens the selected device available on the local host, without using the RPCAP protocol]
* - rpcap://host/devicename [opens the selected device available on a remote host]
* - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP]
* - adaptername [to open a local adapter; kept for compatibility, but it is strongly discouraged]
@@ -1013,10 +1014,11 @@
* authentication is successful (and the user has the right to open network
* devices) the RPCAP connection will continue; otherwise it will be dropped.
*
- * *******NOTE********: the username and password are sent over the network
- * to the capture server *IN CLEAR TEXT*. Don't use this on a network
- * that you don't completely control! (And be *really* careful in your
- * definition of "completely"!)
+ * *******NOTE********: unless TLS is being used, the username and password
+ * are sent over the network to the capture server *IN CLEAR TEXT*. Don't
+ * use this, without TLS (i.e., with rpcap:// rather than rpcaps://) on
+ * a network that you don't completely control! (And be *really* careful
+ * in your definition of "completely"!)
*/
#define RPCAP_RMTAUTH_PWD 1
diff --git a/pflog.h b/pflog.h
new file mode 100644
index 0000000..b49d04f
--- /dev/null
+++ b/pflog.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * pflog headers, at least as they exist now.
+ */
+#define PFLOG_IFNAMSIZ 16
+#define PFLOG_RULESET_NAME_SIZE 16
+
+/*
+ * Direction values.
+ */
+#define PF_INOUT 0
+#define PF_IN 1
+#define PF_OUT 2
+#if defined(__OpenBSD__)
+#define PF_FWD 3
+#endif
+
+/*
+ * Reason values.
+ */
+#define PFRES_MATCH 0
+#define PFRES_BADOFF 1
+#define PFRES_FRAG 2
+#define PFRES_SHORT 3
+#define PFRES_NORM 4
+#define PFRES_MEMORY 5
+#define PFRES_TS 6
+#define PFRES_CONGEST 7
+#define PFRES_IPOPTIONS 8
+#define PFRES_PROTCKSUM 9
+#define PFRES_BADSTATE 10
+#define PFRES_STATEINS 11
+#define PFRES_MAXSTATES 12
+#define PFRES_SRCLIMIT 13
+#define PFRES_SYNPROXY 14
+#if defined(__FreeBSD__)
+#define PFRES_MAPFAILED 15
+#elif defined(__NetBSD__)
+#define PFRES_STATELOCKED 15
+#elif defined(__OpenBSD__)
+#define PFRES_TRANSLATE 15
+#define PFRES_NOROUTE 16
+#elif defined(__APPLE__)
+#define PFRES_DUMMYNET 15
+#endif
+
+/*
+ * Action values.
+ */
+#define PF_PASS 0
+#define PF_DROP 1
+#define PF_SCRUB 2
+#define PF_NOSCRUB 3
+#define PF_NAT 4
+#define PF_NONAT 5
+#define PF_BINAT 6
+#define PF_NOBINAT 7
+#define PF_RDR 8
+#define PF_NORDR 9
+#define PF_SYNPROXY_DROP 10
+#if defined(__FreeBSD__)
+#define PF_DEFER 11
+#elif defined(__OpenBSD__)
+#define PF_DEFER 11
+#define PF_MATCH 12
+#define PF_DIVERT 13
+#define PF_RT 14
+#define PF_AFRT 15
+#elif defined(__APPLE__)
+#define PF_DUMMYNET 11
+#define PF_NODUMMYNET 12
+#define PF_NAT64 13
+#define PF_NONAT64 14
+#endif
+
+struct pf_addr {
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ uint8_t addr8[16];
+ uint16_t addr16[8];
+ uint32_t addr32[4];
+ } pfa; /* 128-bit address */
+#define v4 pfa.v4
+#define v6 pfa.v6
+#define addr8 pfa.addr8
+#define addr16 pfa.addr16
+#define addr32 pfa.addr32
+};
+
+struct pfloghdr {
+ uint8_t length;
+ uint8_t af;
+ uint8_t action;
+ uint8_t reason;
+ char ifname[PFLOG_IFNAMSIZ];
+ char ruleset[PFLOG_RULESET_NAME_SIZE];
+ uint32_t rulenr;
+ uint32_t subrulenr;
+ uint32_t uid;
+ int32_t pid;
+ uint32_t rule_uid;
+ int32_t rule_pid;
+ uint8_t dir;
+#if defined(__OpenBSD__)
+ uint8_t rewritten;
+ uint8_t naf;
+ uint8_t pad[1];
+#else
+ uint8_t pad[3];
+#endif
+#if defined(__FreeBSD__)
+ uint32_t ridentifier;
+ uint8_t reserve;
+ uint8_t pad2[3];
+#elif defined(__OpenBSD__)
+ struct pf_addr saddr;
+ struct pf_addr daddr;
+ uint16_t sport;
+ uint16_t dport;
+#endif
+};
+
+
+
diff --git a/savefile.c b/savefile.c
index d04b917..db8a3aa 100644
--- a/savefile.c
+++ b/savefile.c
@@ -112,6 +112,16 @@
}
static int
+sf_cant_set_rfmon(pcap_t *p _U_)
+{
+ /*
+ * This is a savefile, not a device on which you can capture,
+ * so never say it supports being put into monitor mode.
+ */
+ return (0);
+}
+
+static int
sf_stats(pcap_t *p, struct pcap_stat *ps _U_)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
@@ -350,7 +360,7 @@
if (fname[0] == '-' && fname[1] == '\0')
{
fp = stdin;
- if (stdin == NULL) {
+ if (fp == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"The standard input is not open");
return (NULL);
@@ -551,6 +561,7 @@
p->selectable_fd = fileno(fp);
#endif
+ p->can_set_rfmon_op = sf_cant_set_rfmon;
p->read_op = pcap_offline_read;
p->inject_op = sf_inject;
p->setfilter_op = install_bpf_program;
@@ -618,12 +629,27 @@
pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
struct bpf_insn *fcode;
- int status = 0;
int n = 0;
u_char *data;
- while (status == 0) {
+ /*
+ * This can conceivably process more than INT_MAX packets,
+ * which would overflow the packet count, causing it either
+ * to look like a negative number, and thus cause us to
+ * return a value that looks like an error, or overflow
+ * back into positive territory, and thus cause us to
+ * return a too-low count.
+ *
+ * Therefore, if the packet count is unlimited, we clip
+ * it at INT_MAX; this routine is not expected to
+ * process packets indefinitely, so that's not an issue.
+ */
+ if (PACKET_COUNT_IS_UNLIMITED(cnt))
+ cnt = INT_MAX;
+
+ for (;;) {
struct pcap_pkthdr h;
+ int status;
/*
* Has "pcap_breakloop()" been called?
@@ -643,16 +669,28 @@
}
status = p->next_packet_op(p, &h, &data);
- if (status) {
- if (status == 1)
- return (0);
+ if (status < 0) {
+ /*
+ * Error. Pass it back to the caller.
+ */
return (status);
}
+ if (status == 0) {
+ /*
+ * EOF. Nothing more to process;
+ */
+ break;
+ }
+ /*
+ * OK, we've read a packet; run it through the filter
+ * and, if it passes, process it.
+ */
if ((fcode = p->fcode.bf_insns) == NULL ||
pcap_filter(fcode, data, h.len, h.caplen)) {
(*callback)(user, &h, data);
- if (++n >= cnt && cnt > 0)
+ n++; /* count the packet */
+ if (n >= cnt)
break;
}
}
diff --git a/scanner.c b/scanner.c
index 4c12a2d..bbb2b46 100644
--- a/scanner.c
+++ b/scanner.c
@@ -24,9 +24,16 @@
*/
#include <pcap/pcap-inttypes.h>
+/*
+ * grammar.h requires gencode.h and sometimes breaks in a polluted namespace
+ * (see ftmacros.h), so include it early.
+ */
+#include "gencode.h"
+#include "grammar.h"
+
#include "diag-control.h"
-#line 30 "scanner.c"
+#line 37 "scanner.c"
#define YY_INT_ALIGNED short int
@@ -3092,7 +3099,7 @@
* We want to generate code that can be used by a reentrant parser
* generated by Bison or Berkeley YACC.
*/
-#line 67 "scanner.l"
+#line 74 "scanner.l"
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
@@ -3118,10 +3125,6 @@
#include "pcap-int.h"
-#include "gencode.h"
-
-#include "grammar.h"
-
/*
* Earlier versions of Flex don't declare these, so we declare them
* ourselves to squelch warnings.
@@ -3182,8 +3185,8 @@
*/
DIAG_OFF_FLEX
-#line 3186 "scanner.c"
-#line 3187 "scanner.c"
+#line 3189 "scanner.c"
+#line 3190 "scanner.c"
#define INITIAL 0
@@ -3453,9 +3456,9 @@
}
{
-#line 252 "scanner.l"
+#line 255 "scanner.l"
-#line 3459 "scanner.c"
+#line 3462 "scanner.c"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
@@ -3510,634 +3513,634 @@
case 1:
YY_RULE_SETUP
-#line 253 "scanner.l"
+#line 256 "scanner.l"
return DST;
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 254 "scanner.l"
+#line 257 "scanner.l"
return SRC;
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 256 "scanner.l"
+#line 259 "scanner.l"
return LINK;
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 257 "scanner.l"
+#line 260 "scanner.l"
return LINK;
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 258 "scanner.l"
+#line 261 "scanner.l"
return ARP;
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 259 "scanner.l"
+#line 262 "scanner.l"
return RARP;
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 260 "scanner.l"
+#line 263 "scanner.l"
return IP;
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 261 "scanner.l"
+#line 264 "scanner.l"
return SCTP;
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 262 "scanner.l"
+#line 265 "scanner.l"
return TCP;
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 263 "scanner.l"
+#line 266 "scanner.l"
return UDP;
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 264 "scanner.l"
+#line 267 "scanner.l"
return ICMP;
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 265 "scanner.l"
+#line 268 "scanner.l"
return IGMP;
YY_BREAK
case 13:
YY_RULE_SETUP
-#line 266 "scanner.l"
+#line 269 "scanner.l"
return IGRP;
YY_BREAK
case 14:
YY_RULE_SETUP
-#line 267 "scanner.l"
+#line 270 "scanner.l"
return PIM;
YY_BREAK
case 15:
YY_RULE_SETUP
-#line 268 "scanner.l"
+#line 271 "scanner.l"
return VRRP;
YY_BREAK
case 16:
YY_RULE_SETUP
-#line 269 "scanner.l"
+#line 272 "scanner.l"
return CARP;
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 270 "scanner.l"
+#line 273 "scanner.l"
return RADIO;
YY_BREAK
case 18:
YY_RULE_SETUP
-#line 272 "scanner.l"
+#line 275 "scanner.l"
return IPV6;
YY_BREAK
case 19:
YY_RULE_SETUP
-#line 273 "scanner.l"
+#line 276 "scanner.l"
return ICMPV6;
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 274 "scanner.l"
+#line 277 "scanner.l"
return AH;
YY_BREAK
case 21:
YY_RULE_SETUP
-#line 275 "scanner.l"
+#line 278 "scanner.l"
return ESP;
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 277 "scanner.l"
+#line 280 "scanner.l"
return ATALK;
YY_BREAK
case 23:
YY_RULE_SETUP
-#line 278 "scanner.l"
+#line 281 "scanner.l"
return AARP;
YY_BREAK
case 24:
YY_RULE_SETUP
-#line 279 "scanner.l"
+#line 282 "scanner.l"
return DECNET;
YY_BREAK
case 25:
YY_RULE_SETUP
-#line 280 "scanner.l"
+#line 283 "scanner.l"
return LAT;
YY_BREAK
case 26:
YY_RULE_SETUP
-#line 281 "scanner.l"
+#line 284 "scanner.l"
return SCA;
YY_BREAK
case 27:
YY_RULE_SETUP
-#line 282 "scanner.l"
+#line 285 "scanner.l"
return MOPRC;
YY_BREAK
case 28:
YY_RULE_SETUP
-#line 283 "scanner.l"
+#line 286 "scanner.l"
return MOPDL;
YY_BREAK
case 29:
YY_RULE_SETUP
-#line 285 "scanner.l"
+#line 288 "scanner.l"
return ISO;
YY_BREAK
case 30:
YY_RULE_SETUP
-#line 286 "scanner.l"
+#line 289 "scanner.l"
return ESIS;
YY_BREAK
case 31:
YY_RULE_SETUP
-#line 287 "scanner.l"
+#line 290 "scanner.l"
return ESIS;
YY_BREAK
case 32:
YY_RULE_SETUP
-#line 288 "scanner.l"
+#line 291 "scanner.l"
return ISIS;
YY_BREAK
case 33:
YY_RULE_SETUP
-#line 289 "scanner.l"
+#line 292 "scanner.l"
return ISIS;
YY_BREAK
case 34:
YY_RULE_SETUP
-#line 290 "scanner.l"
+#line 293 "scanner.l"
return L1;
YY_BREAK
case 35:
YY_RULE_SETUP
-#line 291 "scanner.l"
+#line 294 "scanner.l"
return L2;
YY_BREAK
case 36:
YY_RULE_SETUP
-#line 292 "scanner.l"
+#line 295 "scanner.l"
return IIH;
YY_BREAK
case 37:
YY_RULE_SETUP
-#line 293 "scanner.l"
+#line 296 "scanner.l"
return LSP;
YY_BREAK
case 38:
YY_RULE_SETUP
-#line 294 "scanner.l"
+#line 297 "scanner.l"
return SNP;
YY_BREAK
case 39:
YY_RULE_SETUP
-#line 295 "scanner.l"
+#line 298 "scanner.l"
return CSNP;
YY_BREAK
case 40:
YY_RULE_SETUP
-#line 296 "scanner.l"
+#line 299 "scanner.l"
return PSNP;
YY_BREAK
case 41:
YY_RULE_SETUP
-#line 298 "scanner.l"
+#line 301 "scanner.l"
return CLNP;
YY_BREAK
case 42:
YY_RULE_SETUP
-#line 300 "scanner.l"
+#line 303 "scanner.l"
return STP;
YY_BREAK
case 43:
YY_RULE_SETUP
-#line 302 "scanner.l"
+#line 305 "scanner.l"
return IPX;
YY_BREAK
case 44:
YY_RULE_SETUP
-#line 304 "scanner.l"
+#line 307 "scanner.l"
return NETBEUI;
YY_BREAK
case 45:
YY_RULE_SETUP
-#line 306 "scanner.l"
+#line 309 "scanner.l"
return HOST;
YY_BREAK
case 46:
YY_RULE_SETUP
-#line 307 "scanner.l"
+#line 310 "scanner.l"
return NET;
YY_BREAK
case 47:
YY_RULE_SETUP
-#line 308 "scanner.l"
+#line 311 "scanner.l"
return NETMASK;
YY_BREAK
case 48:
YY_RULE_SETUP
-#line 309 "scanner.l"
+#line 312 "scanner.l"
return PORT;
YY_BREAK
case 49:
YY_RULE_SETUP
-#line 310 "scanner.l"
+#line 313 "scanner.l"
return PORTRANGE;
YY_BREAK
case 50:
YY_RULE_SETUP
-#line 311 "scanner.l"
+#line 314 "scanner.l"
return PROTO;
YY_BREAK
case 51:
YY_RULE_SETUP
-#line 312 "scanner.l"
+#line 315 "scanner.l"
return PROTOCHAIN;
YY_BREAK
case 52:
YY_RULE_SETUP
-#line 314 "scanner.l"
+#line 317 "scanner.l"
return GATEWAY;
YY_BREAK
case 53:
YY_RULE_SETUP
-#line 316 "scanner.l"
+#line 319 "scanner.l"
return TYPE;
YY_BREAK
case 54:
YY_RULE_SETUP
-#line 317 "scanner.l"
+#line 320 "scanner.l"
return SUBTYPE;
YY_BREAK
case 55:
YY_RULE_SETUP
-#line 318 "scanner.l"
+#line 321 "scanner.l"
return DIR;
YY_BREAK
case 56:
YY_RULE_SETUP
-#line 319 "scanner.l"
+#line 322 "scanner.l"
return ADDR1;
YY_BREAK
case 57:
YY_RULE_SETUP
-#line 320 "scanner.l"
+#line 323 "scanner.l"
return ADDR2;
YY_BREAK
case 58:
YY_RULE_SETUP
-#line 321 "scanner.l"
+#line 324 "scanner.l"
return ADDR3;
YY_BREAK
case 59:
YY_RULE_SETUP
-#line 322 "scanner.l"
+#line 325 "scanner.l"
return ADDR4;
YY_BREAK
case 60:
YY_RULE_SETUP
-#line 323 "scanner.l"
+#line 326 "scanner.l"
return RA;
YY_BREAK
case 61:
YY_RULE_SETUP
-#line 324 "scanner.l"
+#line 327 "scanner.l"
return TA;
YY_BREAK
case 62:
YY_RULE_SETUP
-#line 326 "scanner.l"
+#line 329 "scanner.l"
return LESS;
YY_BREAK
case 63:
YY_RULE_SETUP
-#line 327 "scanner.l"
+#line 330 "scanner.l"
return GREATER;
YY_BREAK
case 64:
YY_RULE_SETUP
-#line 328 "scanner.l"
+#line 331 "scanner.l"
return CBYTE;
YY_BREAK
case 65:
YY_RULE_SETUP
-#line 329 "scanner.l"
+#line 332 "scanner.l"
return TK_BROADCAST;
YY_BREAK
case 66:
YY_RULE_SETUP
-#line 330 "scanner.l"
+#line 333 "scanner.l"
return TK_MULTICAST;
YY_BREAK
case 67:
YY_RULE_SETUP
-#line 332 "scanner.l"
+#line 335 "scanner.l"
return AND;
YY_BREAK
case 68:
YY_RULE_SETUP
-#line 333 "scanner.l"
+#line 336 "scanner.l"
return OR;
YY_BREAK
case 69:
YY_RULE_SETUP
-#line 334 "scanner.l"
+#line 337 "scanner.l"
return '!';
YY_BREAK
case 70:
YY_RULE_SETUP
-#line 336 "scanner.l"
+#line 339 "scanner.l"
return LEN;
YY_BREAK
case 71:
YY_RULE_SETUP
-#line 337 "scanner.l"
+#line 340 "scanner.l"
return INBOUND;
YY_BREAK
case 72:
YY_RULE_SETUP
-#line 338 "scanner.l"
+#line 341 "scanner.l"
return OUTBOUND;
YY_BREAK
case 73:
YY_RULE_SETUP
-#line 340 "scanner.l"
+#line 343 "scanner.l"
return IFINDEX;
YY_BREAK
case 74:
YY_RULE_SETUP
-#line 342 "scanner.l"
+#line 345 "scanner.l"
return VLAN;
YY_BREAK
case 75:
YY_RULE_SETUP
-#line 343 "scanner.l"
+#line 346 "scanner.l"
return MPLS;
YY_BREAK
case 76:
YY_RULE_SETUP
-#line 344 "scanner.l"
+#line 347 "scanner.l"
return PPPOED;
YY_BREAK
case 77:
YY_RULE_SETUP
-#line 345 "scanner.l"
+#line 348 "scanner.l"
return PPPOES;
YY_BREAK
case 78:
YY_RULE_SETUP
-#line 346 "scanner.l"
+#line 349 "scanner.l"
return GENEVE;
YY_BREAK
case 79:
YY_RULE_SETUP
-#line 348 "scanner.l"
+#line 351 "scanner.l"
return LANE;
YY_BREAK
case 80:
YY_RULE_SETUP
-#line 349 "scanner.l"
+#line 352 "scanner.l"
return LLC;
YY_BREAK
case 81:
YY_RULE_SETUP
-#line 350 "scanner.l"
+#line 353 "scanner.l"
return METAC;
YY_BREAK
case 82:
YY_RULE_SETUP
-#line 351 "scanner.l"
+#line 354 "scanner.l"
return BCC;
YY_BREAK
case 83:
YY_RULE_SETUP
-#line 352 "scanner.l"
+#line 355 "scanner.l"
return OAM;
YY_BREAK
case 84:
YY_RULE_SETUP
-#line 353 "scanner.l"
+#line 356 "scanner.l"
return OAMF4;
YY_BREAK
case 85:
YY_RULE_SETUP
-#line 354 "scanner.l"
+#line 357 "scanner.l"
return OAMF4EC;
YY_BREAK
case 86:
YY_RULE_SETUP
-#line 355 "scanner.l"
+#line 358 "scanner.l"
return OAMF4SC;
YY_BREAK
case 87:
YY_RULE_SETUP
-#line 356 "scanner.l"
+#line 359 "scanner.l"
return SC;
YY_BREAK
case 88:
YY_RULE_SETUP
-#line 357 "scanner.l"
+#line 360 "scanner.l"
return ILMIC;
YY_BREAK
case 89:
YY_RULE_SETUP
-#line 358 "scanner.l"
+#line 361 "scanner.l"
return VPI;
YY_BREAK
case 90:
YY_RULE_SETUP
-#line 359 "scanner.l"
+#line 362 "scanner.l"
return VCI;
YY_BREAK
case 91:
YY_RULE_SETUP
-#line 360 "scanner.l"
+#line 363 "scanner.l"
return CONNECTMSG;
YY_BREAK
case 92:
YY_RULE_SETUP
-#line 361 "scanner.l"
+#line 364 "scanner.l"
return METACONNECT;
YY_BREAK
case 93:
YY_RULE_SETUP
-#line 363 "scanner.l"
+#line 366 "scanner.l"
return PF_IFNAME;
YY_BREAK
case 94:
YY_RULE_SETUP
-#line 364 "scanner.l"
+#line 367 "scanner.l"
return PF_RSET;
YY_BREAK
case 95:
YY_RULE_SETUP
-#line 365 "scanner.l"
+#line 368 "scanner.l"
return PF_RNR;
YY_BREAK
case 96:
YY_RULE_SETUP
-#line 366 "scanner.l"
+#line 369 "scanner.l"
return PF_SRNR;
YY_BREAK
case 97:
YY_RULE_SETUP
-#line 367 "scanner.l"
+#line 370 "scanner.l"
return PF_REASON;
YY_BREAK
case 98:
YY_RULE_SETUP
-#line 368 "scanner.l"
+#line 371 "scanner.l"
return PF_ACTION;
YY_BREAK
case 99:
YY_RULE_SETUP
-#line 370 "scanner.l"
+#line 373 "scanner.l"
return FISU;
YY_BREAK
case 100:
YY_RULE_SETUP
-#line 371 "scanner.l"
+#line 374 "scanner.l"
return LSSU;
YY_BREAK
case 101:
YY_RULE_SETUP
-#line 372 "scanner.l"
+#line 375 "scanner.l"
return LSSU;
YY_BREAK
case 102:
YY_RULE_SETUP
-#line 373 "scanner.l"
+#line 376 "scanner.l"
return MSU;
YY_BREAK
case 103:
YY_RULE_SETUP
-#line 374 "scanner.l"
+#line 377 "scanner.l"
return HFISU;
YY_BREAK
case 104:
YY_RULE_SETUP
-#line 375 "scanner.l"
+#line 378 "scanner.l"
return HLSSU;
YY_BREAK
case 105:
YY_RULE_SETUP
-#line 376 "scanner.l"
+#line 379 "scanner.l"
return HMSU;
YY_BREAK
case 106:
YY_RULE_SETUP
-#line 377 "scanner.l"
+#line 380 "scanner.l"
return SIO;
YY_BREAK
case 107:
YY_RULE_SETUP
-#line 378 "scanner.l"
+#line 381 "scanner.l"
return OPC;
YY_BREAK
case 108:
YY_RULE_SETUP
-#line 379 "scanner.l"
+#line 382 "scanner.l"
return DPC;
YY_BREAK
case 109:
YY_RULE_SETUP
-#line 380 "scanner.l"
+#line 383 "scanner.l"
return SLS;
YY_BREAK
case 110:
YY_RULE_SETUP
-#line 381 "scanner.l"
+#line 384 "scanner.l"
return HSIO;
YY_BREAK
case 111:
YY_RULE_SETUP
-#line 382 "scanner.l"
+#line 385 "scanner.l"
return HOPC;
YY_BREAK
case 112:
YY_RULE_SETUP
-#line 383 "scanner.l"
+#line 386 "scanner.l"
return HDPC;
YY_BREAK
case 113:
YY_RULE_SETUP
-#line 384 "scanner.l"
+#line 387 "scanner.l"
return HSLS;
YY_BREAK
case 114:
/* rule 114 can match eol */
YY_RULE_SETUP
-#line 386 "scanner.l"
+#line 389 "scanner.l"
;
YY_BREAK
case 115:
YY_RULE_SETUP
-#line 387 "scanner.l"
+#line 390 "scanner.l"
return yytext[0];
YY_BREAK
case 116:
YY_RULE_SETUP
-#line 388 "scanner.l"
+#line 391 "scanner.l"
return GEQ;
YY_BREAK
case 117:
YY_RULE_SETUP
-#line 389 "scanner.l"
+#line 392 "scanner.l"
return LEQ;
YY_BREAK
case 118:
YY_RULE_SETUP
-#line 390 "scanner.l"
+#line 393 "scanner.l"
return NEQ;
YY_BREAK
case 119:
YY_RULE_SETUP
-#line 391 "scanner.l"
+#line 394 "scanner.l"
return '=';
YY_BREAK
case 120:
YY_RULE_SETUP
-#line 392 "scanner.l"
+#line 395 "scanner.l"
return LSH;
YY_BREAK
case 121:
YY_RULE_SETUP
-#line 393 "scanner.l"
+#line 396 "scanner.l"
return RSH;
YY_BREAK
case 122:
YY_RULE_SETUP
-#line 394 "scanner.l"
+#line 397 "scanner.l"
{ yylval->s = sdup(yyextra, yytext); return AID; }
YY_BREAK
case 123:
YY_RULE_SETUP
-#line 395 "scanner.l"
+#line 398 "scanner.l"
{ yylval->s = sdup(yyextra, yytext); return EID; }
YY_BREAK
case 124:
YY_RULE_SETUP
-#line 396 "scanner.l"
+#line 399 "scanner.l"
{ return stou(yytext, yylval, yyextra); }
YY_BREAK
case 125:
YY_RULE_SETUP
-#line 397 "scanner.l"
+#line 400 "scanner.l"
{
yylval->s = sdup(yyextra, (char *)yytext); return HID; }
YY_BREAK
case 126:
YY_RULE_SETUP
-#line 399 "scanner.l"
+#line 402 "scanner.l"
{
#ifdef INET6
struct addrinfo hints, *res;
@@ -4160,316 +4163,316 @@
YY_BREAK
case 127:
YY_RULE_SETUP
-#line 418 "scanner.l"
+#line 421 "scanner.l"
{ bpf_set_error(yyextra, "bogus ethernet address %s", yytext); yylval->s = NULL; return EID; }
YY_BREAK
case 128:
YY_RULE_SETUP
-#line 419 "scanner.l"
+#line 422 "scanner.l"
{ yylval->h = 0; return NUM; }
YY_BREAK
case 129:
YY_RULE_SETUP
-#line 420 "scanner.l"
+#line 423 "scanner.l"
{ yylval->h = 1; return NUM; }
YY_BREAK
case 130:
YY_RULE_SETUP
-#line 421 "scanner.l"
+#line 424 "scanner.l"
{ yylval->h = 0; return NUM; }
YY_BREAK
case 131:
YY_RULE_SETUP
-#line 422 "scanner.l"
+#line 425 "scanner.l"
{ yylval->h = 3; return NUM; }
YY_BREAK
case 132:
YY_RULE_SETUP
-#line 423 "scanner.l"
+#line 426 "scanner.l"
{ yylval->h = 4; return NUM; }
YY_BREAK
case 133:
YY_RULE_SETUP
-#line 424 "scanner.l"
+#line 427 "scanner.l"
{ yylval->h = 5; return NUM; }
YY_BREAK
case 134:
YY_RULE_SETUP
-#line 425 "scanner.l"
+#line 428 "scanner.l"
{ yylval->h = 8; return NUM; }
YY_BREAK
case 135:
YY_RULE_SETUP
-#line 426 "scanner.l"
+#line 429 "scanner.l"
{ yylval->h = 9; return NUM; }
YY_BREAK
case 136:
YY_RULE_SETUP
-#line 427 "scanner.l"
+#line 430 "scanner.l"
{ yylval->h = 10; return NUM; }
YY_BREAK
case 137:
YY_RULE_SETUP
-#line 428 "scanner.l"
+#line 431 "scanner.l"
{ yylval->h = 11; return NUM; }
YY_BREAK
case 138:
YY_RULE_SETUP
-#line 429 "scanner.l"
+#line 432 "scanner.l"
{ yylval->h = 12; return NUM; }
YY_BREAK
case 139:
YY_RULE_SETUP
-#line 430 "scanner.l"
+#line 433 "scanner.l"
{ yylval->h = 13; return NUM; }
YY_BREAK
case 140:
YY_RULE_SETUP
-#line 431 "scanner.l"
+#line 434 "scanner.l"
{ yylval->h = 14; return NUM; }
YY_BREAK
case 141:
YY_RULE_SETUP
-#line 432 "scanner.l"
+#line 435 "scanner.l"
{ yylval->h = 15; return NUM; }
YY_BREAK
case 142:
YY_RULE_SETUP
-#line 433 "scanner.l"
+#line 436 "scanner.l"
{ yylval->h = 16; return NUM; }
YY_BREAK
case 143:
YY_RULE_SETUP
-#line 434 "scanner.l"
+#line 437 "scanner.l"
{ yylval->h = 17; return NUM; }
YY_BREAK
case 144:
YY_RULE_SETUP
-#line 435 "scanner.l"
+#line 438 "scanner.l"
{ yylval->h = 18; return NUM; }
YY_BREAK
case 145:
YY_RULE_SETUP
-#line 437 "scanner.l"
+#line 440 "scanner.l"
{ yylval->h = 0; return NUM; }
YY_BREAK
case 146:
YY_RULE_SETUP
-#line 438 "scanner.l"
+#line 441 "scanner.l"
{ yylval->h = 1; return NUM; }
YY_BREAK
case 147:
YY_RULE_SETUP
-#line 440 "scanner.l"
+#line 443 "scanner.l"
{ yylval->h = 1; return NUM; }
YY_BREAK
case 148:
YY_RULE_SETUP
-#line 441 "scanner.l"
+#line 444 "scanner.l"
{ yylval->h = 2; return NUM; }
YY_BREAK
case 149:
YY_RULE_SETUP
-#line 442 "scanner.l"
+#line 445 "scanner.l"
{ yylval->h = 3; return NUM; }
YY_BREAK
case 150:
YY_RULE_SETUP
-#line 443 "scanner.l"
+#line 446 "scanner.l"
{ yylval->h = 4; return NUM; }
YY_BREAK
case 151:
YY_RULE_SETUP
-#line 444 "scanner.l"
+#line 447 "scanner.l"
{ yylval->h = 128; return NUM; }
YY_BREAK
case 152:
YY_RULE_SETUP
-#line 445 "scanner.l"
+#line 448 "scanner.l"
{ yylval->h = 129; return NUM; }
YY_BREAK
case 153:
YY_RULE_SETUP
-#line 446 "scanner.l"
+#line 449 "scanner.l"
{ yylval->h = 130; return NUM; }
YY_BREAK
case 154:
YY_RULE_SETUP
-#line 447 "scanner.l"
+#line 450 "scanner.l"
{ yylval->h = 131; return NUM; }
YY_BREAK
case 155:
YY_RULE_SETUP
-#line 448 "scanner.l"
+#line 451 "scanner.l"
{ yylval->h = 132; return NUM; }
YY_BREAK
case 156:
YY_RULE_SETUP
-#line 449 "scanner.l"
+#line 452 "scanner.l"
{ yylval->h = 133; return NUM; }
YY_BREAK
case 157:
YY_RULE_SETUP
-#line 450 "scanner.l"
+#line 453 "scanner.l"
{ yylval->h = 134; return NUM; }
YY_BREAK
case 158:
YY_RULE_SETUP
-#line 451 "scanner.l"
+#line 454 "scanner.l"
{ yylval->h = 135; return NUM; }
YY_BREAK
case 159:
YY_RULE_SETUP
-#line 452 "scanner.l"
+#line 455 "scanner.l"
{ yylval->h = 136; return NUM; }
YY_BREAK
case 160:
YY_RULE_SETUP
-#line 453 "scanner.l"
+#line 456 "scanner.l"
{ yylval->h = 137; return NUM; }
YY_BREAK
case 161:
YY_RULE_SETUP
-#line 454 "scanner.l"
+#line 457 "scanner.l"
{ yylval->h = 138; return NUM; }
YY_BREAK
case 162:
YY_RULE_SETUP
-#line 455 "scanner.l"
+#line 458 "scanner.l"
{ yylval->h = 139; return NUM; }
YY_BREAK
case 163:
YY_RULE_SETUP
-#line 456 "scanner.l"
+#line 459 "scanner.l"
{ yylval->h = 140; return NUM; }
YY_BREAK
case 164:
YY_RULE_SETUP
-#line 457 "scanner.l"
+#line 460 "scanner.l"
{ yylval->h = 141; return NUM; }
YY_BREAK
case 165:
YY_RULE_SETUP
-#line 458 "scanner.l"
+#line 461 "scanner.l"
{ yylval->h = 142; return NUM; }
YY_BREAK
case 166:
YY_RULE_SETUP
-#line 459 "scanner.l"
+#line 462 "scanner.l"
{ yylval->h = 143; return NUM; }
YY_BREAK
case 167:
YY_RULE_SETUP
-#line 460 "scanner.l"
+#line 463 "scanner.l"
{ yylval->h = 144; return NUM; }
YY_BREAK
case 168:
YY_RULE_SETUP
-#line 461 "scanner.l"
+#line 464 "scanner.l"
{ yylval->h = 145; return NUM; }
YY_BREAK
case 169:
YY_RULE_SETUP
-#line 462 "scanner.l"
+#line 465 "scanner.l"
{ yylval->h = 146; return NUM; }
YY_BREAK
case 170:
YY_RULE_SETUP
-#line 463 "scanner.l"
+#line 466 "scanner.l"
{ yylval->h = 147; return NUM; }
YY_BREAK
case 171:
YY_RULE_SETUP
-#line 464 "scanner.l"
+#line 467 "scanner.l"
{ yylval->h = 148; return NUM; }
YY_BREAK
case 172:
YY_RULE_SETUP
-#line 465 "scanner.l"
+#line 468 "scanner.l"
{ yylval->h = 149; return NUM; }
YY_BREAK
case 173:
YY_RULE_SETUP
-#line 466 "scanner.l"
+#line 469 "scanner.l"
{ yylval->h = 151; return NUM; }
YY_BREAK
case 174:
YY_RULE_SETUP
-#line 467 "scanner.l"
+#line 470 "scanner.l"
{ yylval->h = 152; return NUM; }
YY_BREAK
case 175:
YY_RULE_SETUP
-#line 468 "scanner.l"
+#line 471 "scanner.l"
{ yylval->h = 153; return NUM; }
YY_BREAK
case 176:
YY_RULE_SETUP
-#line 470 "scanner.l"
+#line 473 "scanner.l"
{ yylval->h = 13; return NUM; }
YY_BREAK
case 177:
YY_RULE_SETUP
-#line 471 "scanner.l"
+#line 474 "scanner.l"
{ yylval->h = 0x01; return NUM; }
YY_BREAK
case 178:
YY_RULE_SETUP
-#line 472 "scanner.l"
+#line 475 "scanner.l"
{ yylval->h = 0x02; return NUM; }
YY_BREAK
case 179:
YY_RULE_SETUP
-#line 473 "scanner.l"
+#line 476 "scanner.l"
{ yylval->h = 0x04; return NUM; }
YY_BREAK
case 180:
YY_RULE_SETUP
-#line 474 "scanner.l"
+#line 477 "scanner.l"
{ yylval->h = 0x08; return NUM; }
YY_BREAK
case 181:
YY_RULE_SETUP
-#line 475 "scanner.l"
+#line 478 "scanner.l"
{ yylval->h = 0x10; return NUM; }
YY_BREAK
case 182:
YY_RULE_SETUP
-#line 476 "scanner.l"
+#line 479 "scanner.l"
{ yylval->h = 0x20; return NUM; }
YY_BREAK
case 183:
YY_RULE_SETUP
-#line 477 "scanner.l"
+#line 480 "scanner.l"
{ yylval->h = 0x40; return NUM; }
YY_BREAK
case 184:
YY_RULE_SETUP
-#line 478 "scanner.l"
+#line 481 "scanner.l"
{ yylval->h = 0x80; return NUM; }
YY_BREAK
case 185:
YY_RULE_SETUP
-#line 479 "scanner.l"
+#line 482 "scanner.l"
{
yylval->s = sdup(yyextra, (char *)yytext); return ID; }
YY_BREAK
case 186:
YY_RULE_SETUP
-#line 481 "scanner.l"
+#line 484 "scanner.l"
{ yylval->s = sdup(yyextra, (char *)yytext + 1); return ID; }
YY_BREAK
case 187:
YY_RULE_SETUP
-#line 482 "scanner.l"
+#line 485 "scanner.l"
{ return LEX_ERROR; }
YY_BREAK
case 188:
YY_RULE_SETUP
-#line 483 "scanner.l"
+#line 486 "scanner.l"
ECHO;
YY_BREAK
-#line 4473 "scanner.c"
+#line 4476 "scanner.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -5613,7 +5616,7 @@
#define YYTABLES_NAME "yytables"
-#line 483 "scanner.l"
+#line 486 "scanner.l"
/*
diff --git a/scanner.h b/scanner.h
index fce23fa..9f406ed 100644
--- a/scanner.h
+++ b/scanner.h
@@ -28,9 +28,16 @@
*/
#include <pcap/pcap-inttypes.h>
+/*
+ * grammar.h requires gencode.h and sometimes breaks in a polluted namespace
+ * (see ftmacros.h), so include it early.
+ */
+#include "gencode.h"
+#include "grammar.h"
+
#include "diag-control.h"
-#line 34 "scanner.h"
+#line 41 "scanner.h"
#define YY_INT_ALIGNED short int
@@ -736,9 +743,9 @@
#undef yyTABLES_NAME
#endif
-#line 483 "scanner.l"
+#line 486 "scanner.l"
-#line 743 "scanner.h"
+#line 750 "scanner.h"
#undef pcap_IN_HEADER
#endif /* pcap_HEADER_H */
diff --git a/scanner.l b/scanner.l
index 06b9acc..85fe395 100644
--- a/scanner.l
+++ b/scanner.l
@@ -24,6 +24,13 @@
*/
#include <pcap/pcap-inttypes.h>
+/*
+ * grammar.h requires gencode.h and sometimes breaks in a polluted namespace
+ * (see ftmacros.h), so include it early.
+ */
+#include "gencode.h"
+#include "grammar.h"
+
#include "diag-control.h"
}
@@ -89,10 +96,6 @@
#include "pcap-int.h"
-#include "gencode.h"
-
-#include "grammar.h"
-
/*
* Earlier versions of Flex don't declare these, so we declare them
* ourselves to squelch warnings.
diff --git a/sf-pcap.c b/sf-pcap.c
index d8443e9..4294933 100644
--- a/sf-pcap.c
+++ b/sf-pcap.c
@@ -46,6 +46,7 @@
#include <limits.h> /* for INT_MAX */
#include "pcap-int.h"
+#include "pcap-util.h"
#include "pcap-common.h"
@@ -70,6 +71,10 @@
/*
* Standard libpcap format.
+ *
+ * The same value is used in the rpcap protocol as an indication of
+ * the server byte order, to let the client know whether it needs to
+ * byte-swap some host-byte-order metadata.
*/
#define TCPDUMP_MAGIC 0xa1b2c3d4
@@ -434,7 +439,7 @@
/*
* Read and return the next packet from the savefile. Return the header
- * in hdr and a pointer to the contents in data. Return 0 on success, 1
+ * in hdr and a pointer to the contents in data. Return 1 on success, 0
* if there were no more packets, and -1 on an error.
*/
static int
@@ -467,7 +472,7 @@
return (-1);
}
/* EOF */
- return (1);
+ return (0);
}
}
@@ -579,7 +584,7 @@
* userland.
*
* However, perhaps some versions of libpcap failed to
- * set the snapshot length currectly in the file header
+ * set the snapshot length correctly in the file header
* or the per-packet header, or perhaps this is a
* corrupted safefile or a savefile built/modified by a
* fuzz tester, so we check anyway. We grow the buffer
@@ -622,7 +627,7 @@
* the read finished.
*/
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file; tried to read %u captured bytes, only got %zu",
+ "truncated dump file; tried to read %d captured bytes, only got %zu",
p->snapshot, amt_read);
}
return (-1);
@@ -706,10 +711,9 @@
}
*data = p->buffer;
- if (p->swapped)
- swap_pseudo_headers(p->linktype, hdr, *data);
+ pcap_post_process(p->linktype, p->swapped, hdr, *data);
- return (0);
+ return (1);
}
static int
@@ -749,6 +753,24 @@
f = (FILE *)user;
/*
+ * If the output file handle is in an error state, don't write
+ * anything.
+ *
+ * While in principle a file handle can return from an error state
+ * to a normal state (for example if a disk that is full has space
+ * freed), we have possibly left a broken file already, and won't
+ * be able to clean it up. The safest option is to do nothing.
+ *
+ * Note that if we could guarantee that fwrite() was atomic we
+ * might be able to insure that we don't produce a corrupted file,
+ * but the standard defines fwrite() as a series of fputc() calls,
+ * so we really have no insurance that things are not fubared.
+ *
+ * http://pubs.opengroup.org/onlinepubs/009695399/functions/fwrite.html
+ */
+ if (ferror(f))
+ return;
+ /*
* Better not try writing pcap files after
* 2038-01-19 03:14:07 UTC; switch to pcapng.
*/
@@ -756,9 +778,17 @@
sf_hdr.ts.tv_usec = (bpf_int32)h->ts.tv_usec;
sf_hdr.caplen = h->caplen;
sf_hdr.len = h->len;
- /* XXX we should check the return status */
- (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f);
- (void)fwrite(sp, h->caplen, 1, f);
+ /*
+ * We only write the packet if we can write the header properly.
+ *
+ * This doesn't prevent us from having corrupted output, and if we
+ * for some reason don't get a complete write we don't have any
+ * way to set ferror() to prevent future writes from being
+ * attempted, but it is better than nothing.
+ */
+ if (fwrite(&sf_hdr, sizeof(sf_hdr), 1, f) == 1) {
+ (void)fwrite(sp, h->caplen, 1, f);
+ }
}
static pcap_dumper_t *
diff --git a/sf-pcapng.c b/sf-pcapng.c
index 3fd366c..058a724 100644
--- a/sf-pcapng.c
+++ b/sf-pcapng.c
@@ -34,6 +34,7 @@
#include <string.h>
#include "pcap-int.h"
+#include "pcap-util.h"
#include "pcap-common.h"
@@ -1094,7 +1095,7 @@
/*
* Read and return the next packet from the savefile. Return the header
- * in hdr and a pointer to the contents in data. Return 0 on success, 1
+ * in hdr and a pointer to the contents in data. Return 1 on success, 0
* if there were no more packets, and -1 on an error.
*/
static int
@@ -1123,7 +1124,7 @@
*/
status = read_block(fp, p, &cursor, p->errbuf);
if (status == 0)
- return (1); /* EOF */
+ return (0); /* EOF */
if (status == -1)
return (-1); /* error */
switch (cursor.block_type) {
@@ -1511,8 +1512,7 @@
if (*data == NULL)
return (-1);
- if (p->swapped)
- swap_pseudo_headers(p->linktype, hdr, *data);
+ pcap_post_process(p->linktype, p->swapped, hdr, *data);
- return (0);
+ return (1);
}