aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge V. Neville-Neil <gnn@FreeBSD.org>2012-01-31 17:22:07 +0000
committerGeorge V. Neville-Neil <gnn@FreeBSD.org>2012-01-31 17:22:07 +0000
commit59f06eaa08f055b60a0ee4e9694cce270b4bb6d8 (patch)
treecac3a63d544b5c02184599b87bac2f129eb67b9c
parente89167f07a9ca239491071320fd6d010e183107e (diff)
downloadsrc-59f06eaa08f055b60a0ee4e9694cce270b4bb6d8.tar.gz
src-59f06eaa08f055b60a0ee4e9694cce270b4bb6d8.zip
Update sources to 1.2.1
Submitted by: wxs@
Notes
Notes: svn path=/vendor/libpcap/dist/; revision=230828
-rw-r--r--CHANGES74
-rw-r--r--CREDITS279
-rw-r--r--Makefile.in115
-rw-r--r--README15
-rw-r--r--README.linux10
-rw-r--r--VERSION2
-rw-r--r--Win32/Include/bittypes.h60
-rw-r--r--Win32/Prj/libpcap.dsp4
-rw-r--r--Win32/Src/gai_strerror.c2
-rw-r--r--Win32/Src/getaddrinfo.c11
-rw-r--r--aclocal.m422
-rw-r--r--bpf/net/bpf_filter.c13
-rw-r--r--config.h.in30
-rwxr-xr-xconfigure1383
-rwxr-xr-xconfigure.in399
-rw-r--r--ethertype.h3
-rw-r--r--fad-getad.c12
-rw-r--r--gencode.c521
-rw-r--r--gencode.h4
-rw-r--r--grammar.y7
-rw-r--r--inet.c60
-rw-r--r--packaging/pcap.spec.in83
-rw-r--r--pcap-bpf.c288
-rw-r--r--pcap-bt-linux.c76
-rw-r--r--pcap-common.c595
-rw-r--r--pcap-config.in31
-rw-r--r--pcap-dag.c11
-rw-r--r--pcap-dlpi.c103
-rw-r--r--pcap-filter.manmisc.in15
-rw-r--r--pcap-int.h3
-rw-r--r--pcap-libdlpi.c72
-rw-r--r--pcap-linktype.manmisc.in238
-rw-r--r--pcap-linux.c1346
-rw-r--r--pcap-stdinc.h7
-rw-r--r--pcap-usb-linux.c51
-rw-r--r--pcap-win32.c7
-rw-r--r--pcap.3pcap.in569
-rw-r--r--pcap.c402
-rw-r--r--pcap/bpf.h189
-rw-r--r--pcap/pcap.h66
-rw-r--r--pcap_activate.3pcap8
-rw-r--r--pcap_can_set_rfmon.3pcap10
-rw-r--r--pcap_compile.3pcap.in2
-rw-r--r--pcap_datalink.3pcap.in4
-rw-r--r--pcap_datalink_name_to_val.3pcap8
-rw-r--r--pcap_datalink_val_to_name.3pcap10
-rw-r--r--pcap_fileno.3pcap2
-rw-r--r--pcap_findalldevs.3pcap62
-rw-r--r--pcap_free_datalinks.3pcap41
-rw-r--r--pcap_freealldevs.3pcap40
-rw-r--r--pcap_get_selectable_fd.3pcap18
-rw-r--r--pcap_list_datalinks.3pcap.in26
-rw-r--r--pcap_loop.3pcap7
-rw-r--r--pcap_major_version.3pcap10
-rw-r--r--pcap_next_ex.3pcap25
-rw-r--r--pcap_open_live.3pcap2
-rw-r--r--pcap_set_datalink.3pcap7
-rw-r--r--savefile.c15
-rw-r--r--scanner.l6
-rw-r--r--sf-pcap-ng.c8
-rw-r--r--sf-pcap.c8
61 files changed, 5105 insertions, 2392 deletions
diff --git a/CHANGES b/CHANGES
index de3ac954f434..3c82052df058 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,77 @@
+Friday December 9, 2011. guy@alum.mit.edu.
+Summary for 1.2.1 libpcap release
+ Update README file.
+ Fix typoes in README.linux file.
+ Clean up some compiler warnings.
+ Fix Linux compile problems and tests for ethtool.h.
+ Treat Debian/kFreeBSD and GNU/Hurd as systems with GNU
+ toolchains.
+ Support 802.1 QinQ as a form of VLAN in filters.
+ Treat "carp" as equivalent to "vrrp" in filters.
+ Fix code generated for "ip6 protochain".
+ Add some new link-layer header types.
+ Support capturing NetFilter log messages on Linux.
+ Clean up some error messages.
+ Turn off monitor mode on exit for mac80211 interfaces on Linux.
+ Fix problems turning monitor mode on for non-mac80211 interfaces
+ on Linux.
+ Properly fail if /sys/class/net or /proc/net/dev exist but can't
+ be opened.
+ Fail if pcap_activate() is called on an already-activated
+ pcap_t, and add a test program for that.
+ Fix filtering in pcap-ng files.
+ Don't build for PowerPC on Mac OS X Lion.
+ Simplify handling of new DLT_/LINKTYPE_ values.
+ Expand pcap(3PCAP) man page.
+
+Sunday July 24, 2011. mcr@sandelman.ca.
+Summary for 1.2 libpcap release
+ All of the changes listed below for 1.1.1 and 1.1.2.
+ Changes to error handling for pcap_findalldevs().
+ Fix the calculation of the frame size in memory-mapped captures.
+ Add a link-layer header type for STANAG 5066 D_PDUs.
+ Add a link-layer type for a variant of 3GPP TS 27.010.
+ Noted real nature of LINKTYPE_ARCNET.
+ Add a link-layer type for DVB-CI.
+ Fix configure-script discovery of VLAN acceleration support.
+ see http://netoptimizer.blogspot.com/2010/09/tcpdump-vs-vlan-tags.html
+ Linux, HP-UX, AIX, NetBSD and OpenBSD compilation/conflict fixes.
+ Protect against including AIX 5.x's <net/bpf.h> having been included.
+ Add DLT_DBUS, for raw D-Bus messages.
+ Treat either EPERM or EACCES as "no soup for you".
+ Changes to permissions on DLPI systems.
+ Add DLT_IEEE802_15_4_NOFCS for 802.15.4 interfaces.
+
+Fri. August 6, 2010. guy@alum.mit.edu.
+Summary for 1.1.2 libpcap release
+ Return DLT_ values, not raw LINKTYPE_ values from
+ pcap_datalink() when reading pcap-ng files
+ Add support for "wlan ra" and "wlan ta", to check the RA and TA
+ of WLAN frames that have them
+ Don't crash if "wlan addr{1,2,3,4}" are used without 802.11
+ headers
+ Do filtering on USB and Bluetooth capturing
+ On FreeBSD/SPARC64, use -fPIC - it's apparently necessary
+ Check for valid port numbers (fit in a 16-bit unsigned field) in
+ "port" filters
+ Reject attempts to put savefiles into non-blocking mode
+ Check for "no such device" for the "get the media types" ioctl
+ in *BSD
+ Improve error messages from bpf_open(), and let it do the error
+ handling
+ Return more specific errors from pcap_can_set_rfmon(); fix
+ documentation
+ Update description fetching code for FreeBSD, fix code for
+ OpenBSD
+ Ignore /sys/net/dev files if we get ENODEV for them, not just
+ ENXIO; fixes handling of bonding devices on Linux
+ Fix check for a constant 0 argument to BPF_DIV
+ Use the right version of ar when cross-building
+ Free any filter set on a savefile when the savefile is closed
+ Include the CFLAGS setting when configure was run in the
+ compiler flags
+ Add support for 802.15.4 interfaces on Linux
+
Thu. April 1, 2010. guy@alum.mit.edu.
Summary for 1.1.1 libpcap release
Update CHANGES to reflect more of the changes in 1.1.0.
diff --git a/CREDITS b/CREDITS
index 2d7c09e9d0a8..68b283fd8d7b 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1,145 +1,154 @@
This file lists people who have contributed to libpcap:
The current maintainers:
- Bill Fenner <fenner at research dot att dot com>
- Fulvio Risso <risso at polito dot it>
- Guy Harris <guy at alum dot mit dot edu>
- Hannes Gredler <hannes at juniper dot net>
- Michael Richardson <mcr at sandelman dot ottawa dot on dot ca>
+ Bill Fenner <fenner at research dot att dot com>
+ Fulvio Risso <risso at polito dot it>
+ Guy Harris <guy at alum dot mit dot edu>
+ Hannes Gredler <hannes at juniper dot net>
+ Michael Richardson <mcr at sandelman dot ottawa dot on dot ca>
Additional people who have contributed patches:
- Alan Bawden <Alan at LCS dot MIT dot EDU>
- Albert Chin <china at thewrittenword dot com>
- Alexander 'Leo' Bergolth <Leo dot Bergolth at wu-wien dot ac dot at>
- Alexey Kuznetsov <kuznet at ms2 dot inr dot ac dot ru>
- Alon Bar-Lev <alonbl at sourceforge dot net>
- Andrew Brown <atatat at atatdot dot net>
- Antti Kantee <pooka at netbsd dot org>
- Arien Vijn <arienvijn at sourceforge dot net>
- Arkadiusz Miskiewicz <misiek at pld dot org dot pl>
- Armando L. Caro Jr. <acaro at mail dot eecis dot udel dot edu>
- Assar Westerlund <assar at sics dot se>
- Brian Ginsbach <ginsbach at cray dot com>
- Charles M. Hannum <mycroft at netbsd dot org>
- Chris G. Demetriou <cgd at netbsd dot org>
- Chris Lightfoot <cwrl at users dot sourceforge dot net>
- Chris Maynard <Chris dot Maynard at gtech dot com>
- Chris Pepper <pepper at mail dot reppep dot com>
- Christian Bell <csbell at myri dot com>
- Christian Peron <csjp at freebsd dot org>
- Daniele Orlandi <daniele at orlandi dot com>
- Darren Reed <darrenr at sun dot com>
- David Kaelbling <drk at sgi dot com>
- David Young <dyoung at ojctech dot com>
- Dean Gaudet <dean at arctic dot org>
- Don Ebright <Don dot Ebright at compuware dot com>
- Dug Song <dugsong at monkey dot org>
- Dustin Spicuzza <dustin at virtualroadside 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>
- Felix Obenhuber <felix at obenhuber dot de>
- Florent Drouin <Florent dot Drouin at alcatel-lucent dot fr>
- Franz Schaefer <schaefer at mond dot at>
- Fulko Hew <fulko dot hew at gmail dot com>
- Fumiyuki Shimizu <fumifumi at abacustech dot jp>
- Gianluca Varenni <varenni at netgroup-serv dot polito dot it>
- Gilbert Hoyek <gil_hoyek at hotmail dot com>
- Gisle Vanem <gvanem at broadpark dot no>
- Graeme Hewson <ghewson at cix dot compulink dot co dot uk>
- Greg Stark <gsstark at mit dot edu>
- Greg Troxel <gdt at ir dot bbn dot com>
- Gregor Maier <gregor at net dot in dot tum dot de>
- Guillaume Pelat <endymion_ at users dot sourceforge dot net>
- Hagen Paul Pfeifer <hagen at jauu dot net>
- Hyung Sik Yoon <hsyn at kr dot ibm dot com>
- Igor Khristophorov <igor at atdot dot org>
- Jan-Philip Velders <jpv at veldersjes dot net>
- Jason R. Thorpe <thorpej at netbsd dot org>
- Javier Achirica <achirica at ttd dot net>
- Jean Tourrilhes <jt at hpl dot hp dot com>
- Jean-Louis Charton <Jean-Louis.CHARTON at oikialog dot com>
- Jefferson Ogata <jogata at nodc dot noaa dot gov>
- Jesper Peterson <jesper at endace dot com>
- Joerg Mayer <jmayer at loplof dot de>
- John Bankier <jbankier at rainfinity dot com>
- Jon Lindgren <jonl at yubyub dot net>
- Jon Smirl <jonsmirl at gmail dot com>
- Juergen Schoenwaelder <schoenw at ibr dot cs dot tu-bs dot de>
- Jung-uk Kim <jkim at FreeBSD dot org>
- Kazushi Sugyo <sugyo at pb dot jp dot nec dot com>
- Klaus Klein <kleink at netbsd dot org>
- Koryn Grant <koryn at endace dot com>
- Kris Katterjohn <katterjohn at gmail dot com>
- Krzysztof Halasa <khc at pm dot waw dot pl>
- Lorenzo Cavallaro <sullivan at sikurezza dot org>
- Loris Degioanni <loris at netgroup-serv dot polito dot it>
- Love Hörnquist-Åstrand <lha at stacken dot kth dot se>
- Luis Martin Garcia <luis dot mgarc at gmail dot com>
- Maciej W. Rozycki <macro at ds2 dot pg dot gda dot pl>
- Marcus Felipe Pereira <marcus at task dot com dot br>
- Mark C. Brown <mbrown at hp dot com>
- Mark Pizzolato <List-tcpdump-workers at subscriptions dot pizzolato dot net>
- Markus Mayer <markus_mayer at sourceforge dot net>
- Martin Husemann <martin at netbsd dot org>
- Márton Németh <nm127 at freemail dot hu>
- Matthew Luckie <mjl at luckie dot org dot nz>
- Max Laier <max at love2party dot net>
- Mike Frysinger <vapier at gmail dot com>
- Mike Kershaw <dragorn at kismetwireless dot net>
- Mike Wiacek <mike at iroot dot net>
- Monroe Williams <monroe at pobox dot com>
- N. Leiten <nleiten at sourceforge dot net>
- Nicolas Dade <ndade at nsd dot dyndns dot org>
- Octavian Cerna <tavy at ylabs dot com>
- Olaf Kirch <okir at caldera dot de>
- Ollie Wild <aaw at users dot sourceforge dot net>
- Onno van der Linden <onno at simplex dot nl>
- Paolo Abeni <paolo dot abeni at email dot it>
- Patrick Marie <mycroft at virgaria dot org>
- Patrick McHardy <kaber at trash not net>
- Paul Mundt <lethal at linux-sh dot org>
- Pavel Kankovsky <kan at dcit dot cz>
- Pawel Pokrywka <publicpp at gmail dot com>
- Peter Fales <peter at fales-lorenz dot net>
- Peter Jeremy <peter dot jeremy at alcatel dot com dot au>
- Peter Volkov <pva at gentoo dot org>
- Phil Wood <cpw at lanl dot gov>
- Rafal Maszkowski <rzm at icm dot edu dot pl>
- <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>
- Robert Edmonds <stu-42 at sourceforge dot net>
- Roberto Mariani <jelot-tcpdump at jelot dot it>
- Romain Francoise <rfrancoise at debian dot org>
- Sagun Shakya <sagun dot shakya at sun dot com>
- Scott Barron <sb125499 at ohiou dot edu>
- Scott Gifford <sgifford at tir dot com>
- 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>
- Shaun Clowes <delius at progsoc dot uts dot edu dot au>
- Solomon Peachy <pizza at shaftnet dot org>
- Stefan Hudson <hudson at mbay dot net>
- Stephen Donnelly <stephen at endace dot com>
- Takashi Yamamoto <yamt at mwd dot biglobe dot ne dot jp>
- Tanaka Shin-ya <zstanaka at archer dot livedoor dot com>
- Tobias Poschwatta <posch at sourceforge dot net>
- Tony Li <tli at procket dot com>
- Torsten Landschoff <torsten at debian dot org>
- Uns Lider <unslider at miranda dot org>
- Uwe Girlich <Uwe dot Girlich at philosys dot de>
- Wesley Shields <wxs at FreeBSD dot org>
- Xianjie Zhang <xzhang at cup dot hp dot com>
- Xin Li <delphij at FreeBSD dot org>
- Yen Yen Lim
- Yvan Vanhullebus <vanhu at sourceforge dot net>
- Yoann Vandoorselaere <yoann at prelude-ids dot org>
+ Alan Bawden <Alan at LCS dot MIT dot EDU>
+ Albert Chin <china at thewrittenword dot com>
+ Alexander 'Leo' Bergolth <Leo dot Bergolth at wu-wien dot ac dot at>
+ Alexey Kuznetsov <kuznet at ms2 dot inr dot ac dot ru>
+ Alon Bar-Lev <alonbl at sourceforge dot net>
+ Andrew Brown <atatat at atatdot dot net>
+ <andy-1 at sourceforge dot net>
+ Antti Kantee <pooka at netbsd dot org>
+ Arien Vijn <arienvijn at sourceforge dot net>
+ Arkadiusz Miskiewicz <misiek at pld dot org dot pl>
+ Armando L. Caro Jr. <acaro at mail dot eecis dot udel dot edu>
+ Assar Westerlund <assar at sics dot se>
+ Brian Ginsbach <ginsbach at cray dot com>
+ Charles M. Hannum <mycroft at netbsd dot org>
+ Chris G. Demetriou <cgd at netbsd dot org>
+ Chris Lightfoot <cwrl at users dot sourceforge dot net>
+ Chris Maynard <Chris dot Maynard at gtech dot com>
+ Chris Pepper <pepper at mail dot reppep dot com>
+ Christian Bell <csbell at myri dot com>
+ Christian Peron <csjp at freebsd dot org>
+ Daniele Orlandi <daniele at orlandi dot com>
+ Darren Reed <darrenr at sun dot com>
+ David Kaelbling <drk at sgi dot com>
+ David Young <dyoung at ojctech dot com>
+ Dean Gaudet <dean at arctic dot org>
+ Don Ebright <Don dot Ebright at compuware dot com>
+ Dug Song <dugsong at monkey dot org>
+ Dustin Spicuzza <dustin at virtualroadside 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>
+ Felix Obenhuber <felix at obenhuber dot de>
+ Florent Drouin <Florent dot Drouin at alcatel-lucent dot fr>
+ Franz Schaefer <schaefer at mond dot at>
+ frederich <frederich at sourceforge dot net>
+ Fulko Hew <fulko dot hew at gmail dot com>
+ Fumiyuki Shimizu <fumifumi at abacustech dot jp>
+ Garrett Cooper <yaberauneya at sourceforge dot net>
+ Gianluca Varenni <gianluca dot varenni at gmail dot com>
+ Gilbert Hoyek <gil_hoyek at hotmail dot com>
+ Gisle Vanem <gvanem at broadpark dot no>
+ Graeme Hewson <ghewson at cix dot compulink dot co dot uk>
+ Greg Stark <gsstark at mit dot edu>
+ Greg Troxel <gdt at ir dot bbn dot com>
+ Gregor Maier <gregor at net dot in dot tum dot de>
+ Guillaume Pelat <endymion_ at users dot sourceforge dot net>
+ Hagen Paul Pfeifer <hagen at jauu dot net>
+ Henri Doreau <hdoreau at sourceforge dot net>
+ Hyung Sik Yoon <hsyn at kr dot ibm dot com>
+ Igor Khristophorov <igor at atdot dot org>
+ Jan-Philip Velders <jpv at veldersjes dot net>
+ Jason R. Thorpe <thorpej at netbsd dot org>
+ Javier Achirica <achirica at ttd dot net>
+ Jean Tourrilhes <jt at hpl dot hp dot com>
+ Jean-Louis Charton <Jean-Louis.CHARTON at oikialog dot com>
+ Jefferson Ogata <jogata at nodc dot noaa dot gov>
+ Jesper Dangaard Brouer <hawk at comx dot dk>
+ Jesper Peterson <jesper at endace dot com>
+ Joerg Mayer <jmayer at loplof dot de>
+ John Bankier <jbankier at rainfinity dot com>
+ Jon Lindgren <jonl at yubyub dot net>
+ Jon Smirl <jonsmirl at gmail dot com>
+ Juergen Schoenwaelder <schoenw at ibr dot cs dot tu-bs dot de>
+ Julien Moutinho <julm at savines dot alpes dot fr dot eu dot org>
+ Jung-uk Kim <jkim at FreeBSD dot org>
+ Kazushi Sugyo <sugyo at pb dot jp dot nec dot com>
+ Klaus Klein <kleink at netbsd dot org>
+ Koryn Grant <koryn at endace dot com>
+ Kris Katterjohn <katterjohn at gmail dot com>
+ Krzysztof Halasa <khc at pm dot waw dot pl>
+ Lorenzo Cavallaro <sullivan at sikurezza dot org>
+ Loris Degioanni <loris at netgroup-serv dot polito dot it>
+ Love Hörnquist-Åstrand <lha at stacken dot kth dot se>
+ Luis MartinGarcia <luis dot mgarc at gmail dot com>
+ Maciej W. Rozycki <macro at ds2 dot pg dot gda dot pl>
+ Marcus Felipe Pereira <marcus at task dot com dot br>
+ Mark C. Brown <mbrown at hp dot com>
+ Mark Pizzolato <List-tcpdump-workers at subscriptions dot pizzolato dot net>
+ Markus Mayer <markus_mayer at sourceforge dot net>
+ Martin Husemann <martin at netbsd dot org>
+ Márton Németh <nm127 at freemail dot hu>
+ Matthew Luckie <mjl at luckie dot org dot nz>
+ Max Laier <max at love2party dot net>
+ Mike Frysinger <vapier at gmail dot com>
+ Mike Kershaw <dragorn at kismetwireless dot net>
+ Mike Wiacek <mike at iroot dot net>
+ Miroslav Lichvar <mlichvar at redhat dot com>
+ Monroe Williams <monroe at pobox dot com>
+ <nvercamm at sourceforge dot net>
+ N. Leiten <nleiten at sourceforge dot net>
+ Nicolas Dade <ndade at nsd dot dyndns dot org>
+ Octavian Cerna <tavy at ylabs dot com>
+ Olaf Kirch <okir at caldera dot de>
+ Ollie Wild <aaw at users dot sourceforge dot net>
+ Onno van der Linden <onno at simplex dot nl>
+ Paolo Abeni <paolo dot abeni at email dot it>
+ Patrick Marie <mycroft at virgaria dot org>
+ Patrick McHardy <kaber at trash not net>
+ Paul Mundt <lethal at linux-sh dot org>
+ Pavel Kankovsky <kan at dcit dot cz>
+ Pawel Pokrywka <publicpp at gmail dot com>
+ Peter Fales <peter at fales-lorenz dot net>
+ Peter Jeremy <peter dot jeremy at alcatel dot com dot au>
+ Peter Volkov <pva at gentoo dot org>
+ Phil Wood <cpw at lanl dot gov>
+ Rafal Maszkowski <rzm at icm dot edu dot pl>
+ <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>
+ Robert Edmonds <stu-42 at sourceforge dot net>
+ Roberto Mariani <jelot-tcpdump at jelot dot it>
+ Romain Francoise <rfrancoise at debian dot org>
+ Sagun Shakya <sagun dot shakya at sun dot com>
+ Scott Barron <sb125499 at ohiou dot edu>
+ Scott Gifford <sgifford at tir dot com>
+ Scott Mcmillan <scott dot a dot mcmillan at intel dot com>
+ 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>
+ Shaun Clowes <delius at progsoc dot uts dot edu dot au>
+ Solomon Peachy <pizza at shaftnet dot org>
+ Stefan Hudson <hudson at mbay dot net>
+ Stephen Donnelly <stephen at endace dot com>
+ Takashi Yamamoto <yamt at mwd dot biglobe dot ne dot jp>
+ Tanaka Shin-ya <zstanaka at archer dot livedoor dot com>
+ Tobias Poschwatta <posch at sourceforge dot net>
+ Tony Li <tli at procket dot com>
+ Torsten Landschoff <torsten at debian dot org>
+ Uns Lider <unslider at miranda dot org>
+ Uwe Girlich <Uwe dot Girlich at philosys dot de>
+ Wesley Shields <wxs at FreeBSD dot org>
+ Xianjie Zhang <xzhang at cup dot hp dot com>
+ Xin Li <delphij at FreeBSD dot org>
+ Yen Yen Lim
+ Yvan Vanhullebus <vanhu at sourceforge dot net>
+ Yoann Vandoorselaere <yoann at prelude-ids dot org>
The original LBL crew:
- Steve McCanne
- Craig Leres
- Van Jacobson
+ Steve McCanne
+ Craig Leres
+ Van Jacobson
Past maintainers:
- Jun-ichiro itojun Hagino <itojun at iijlab dot net>
+ Jun-ichiro itojun Hagino <itojun at iijlab dot net>
diff --git a/Makefile.in b/Makefile.in
index f576462d44fa..912b7e3d57cf 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -46,19 +46,21 @@ VPATH = @srcdir@
LD = /usr/bin/ld
CC = @CC@
+AR = @AR@
CCOPT = @V_CCOPT@
INCLS = -I. @V_INCLS@
DEFS = @DEFS@ @V_DEFS@
ADDLOBJS = @ADDLOBJS@
ADDLARCHIVEOBJS = @ADDLARCHIVEOBJS@
LIBS = @LIBS@
+CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
DYEXT = @DYEXT@
V_RPATH_OPT = @V_RPATH_OPT@
PROG=libpcap
# Standard CFLAGS
-CFLAGS = $(CCOPT) $(INCLS) $(DEFS)
+FULL_CFLAGS = $(CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -78,9 +80,9 @@ YACC = @V_YACC@
# problem if you don't own the file but can write to the directory.
.c.o:
@rm -f $@
- $(CC) $(CFLAGS) -c $(srcdir)/$*.c
+ $(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
-PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @CAN_SRC@
+PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @CAN_SRC@ @NETFILTER_SRC@
FSRC = fad-@V_FINDALLDEVS@.c
SSRC = @SSRC@
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c etherent.c \
@@ -123,14 +125,29 @@ HDR = $(PUBHDR) \
sf-pcap-ng.h \
sunatmpos.h
+TESTS = \
+ filtertest \
+ findalldevstest \
+ nonblocktest \
+ opentest \
+ selpolltest
+
+TESTS_SRC = \
+ tests/filtertest.c \
+ tests/findalldevstest.c \
+ tests/nonblocktest.c \
+ tests/opentest.c \
+ tests/reactivatetest.c \
+ tests/selpolltest.c
+
GENHDR = \
scanner.h tokdefs.h version.h
TAGFILES = \
$(SRC) $(HDR)
-CLEANFILES = $(OBJ) libpcap.* filtertest findalldevstest selpolltest \
- opentest $(PROG)-`cat $(srcdir)/VERSION`.tar.gz $(GENSRC) $(GENHDR) \
+CLEANFILES = $(OBJ) libpcap.* $(TESTS) \
+ $(PROG)-`cat $(srcdir)/VERSION`.tar.gz $(GENSRC) $(GENHDR) \
lex.yy.c pcap-config
MAN1 = pcap-config.1
@@ -141,8 +158,10 @@ MAN3PCAP_EXPAND = \
pcap_datalink.3pcap.in \
pcap_dump_open.3pcap.in \
pcap_list_datalinks.3pcap.in \
+ pcap_list_tstamp_types.3pcap.in \
pcap_open_dead.3pcap.in \
- pcap_open_offline.3pcap.in
+ pcap_open_offline.3pcap.in \
+ pcap_set_tstamp_type.3pcap.in
MAN3PCAP_NOEXPAND = \
pcap_activate.3pcap \
@@ -160,9 +179,7 @@ MAN3PCAP_NOEXPAND = \
pcap_file.3pcap \
pcap_fileno.3pcap \
pcap_findalldevs.3pcap \
- pcap_freealldevs.3pcap \
pcap_freecode.3pcap \
- pcap_free_datalinks.3pcap \
pcap_get_selectable_fd.3pcap \
pcap_geterr.3pcap \
pcap_inject.3pcap \
@@ -187,7 +204,9 @@ MAN3PCAP_NOEXPAND = \
pcap_snapshot.3pcap \
pcap_stats.3pcap \
pcap_statustostr.3pcap \
- pcap_strerror.3pcap
+ pcap_strerror.3pcap \
+ pcap_tstamp_type_name_to_val.3pcap \
+ pcap_tstamp_type_val_to_name.3pcap
MAN3PCAP = $(MAN3PCAP_NOEXPAND) $(MAN3PCAP_EXPAND:.in=)
@@ -196,9 +215,11 @@ MANFILE = \
MANMISC = \
pcap-filter.manmisc.in \
- pcap-linktype.manmisc.in
+ pcap-linktype.manmisc.in \
+ pcap-tstamp.manmisc.in
EXTRA_DIST = \
+ $(TESTS_SRC) \
CHANGES \
ChmodBPF/ChmodBPF \
ChmodBPF/StartupParameters.plist \
@@ -237,8 +258,6 @@ EXTRA_DIST = \
fad-null.c \
fad-sita.c \
fad-win32.c \
- filtertest.c \
- findalldevstest.c \
grammar.y \
install-sh \
lbl/os-aix4.h \
@@ -263,7 +282,6 @@ EXTRA_DIST = \
msdos/pktdrvr.c \
msdos/pktdrvr.h \
msdos/readme.dos \
- opentest.c \
org.tcpdump.chmod_bpf.plist \
packaging/pcap.spec.in \
pcap-bpf.c \
@@ -282,6 +300,8 @@ EXTRA_DIST = \
pcap-libdlpi.c \
pcap-linux.c \
pcap-namedb.h \
+ pcap-netfilter-linux.c \
+ pcap-netfilter-linux.h \
pcap-nit.c \
pcap-null.c \
pcap-pf.c \
@@ -299,7 +319,6 @@ EXTRA_DIST = \
pcap-win32.c \
runlex.sh \
scanner.l \
- selpolltest.c \
Win32/Include/Gnuc.h \
Win32/Include/addrinfo.h \
Win32/Include/bittypes.h \
@@ -328,7 +347,7 @@ all: libpcap.a shared pcap-config
libpcap.a: $(OBJ)
@rm -f $@
- ar rc $@ $(OBJ) $(ADDLARCHIVEOBJS)
+ $(AR) rc $@ $(OBJ) $(ADDLARCHIVEOBJS)
$(RANLIB) $@
shared: libpcap.$(DYEXT)
@@ -401,7 +420,7 @@ libpcap.sl: $(OBJ)
libpcap.shareda: $(OBJ)
@rm -f $@ shr.o
$(CC) @V_SHLIB_OPT@ -o shr.o $(OBJ) $(ADDLOBJS) $(LDFLAGS) $(LIBS)
- ar rc $@ shr.o
+ $(AR) rc $@ shr.o
#
# For platforms that don't support shared libraries (or on which we
@@ -414,7 +433,7 @@ scanner.c: $(srcdir)/scanner.l
$(srcdir)/runlex.sh $(LEX) -o$@ $<
scanner.o: scanner.c tokdefs.h
- $(CC) $(CFLAGS) -c scanner.c
+ $(CC) $(FULL_CFLAGS) -c scanner.c
pcap.o: version.h
@@ -427,13 +446,13 @@ grammar.c: $(srcdir)/grammar.y
grammar.o: grammar.c
@rm -f $@
- $(CC) $(CFLAGS) -Dyylval=pcap_lval -c grammar.c
+ $(CC) $(FULL_CFLAGS) -Dyylval=pcap_lval -c grammar.c
version.o: version.c
- $(CC) $(CFLAGS) -c version.c
+ $(CC) $(FULL_CFLAGS) -c version.c
snprintf.o: $(srcdir)/missing/snprintf.c
- $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
+ $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
version.c: $(srcdir)/VERSION
@rm -f $@
@@ -467,35 +486,47 @@ bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c
ln -s $(srcdir)/bpf/net/bpf_filter.c bpf_filter.c
bpf_filter.o: bpf_filter.c
- $(CC) $(CFLAGS) -c bpf_filter.c
+ $(CC) $(FULL_CFLAGS) -c bpf_filter.c
#
# Generate the pcap-config script.
#
-pcap-config: $(srcdir)/pcap-config.in
+# Some Makes, e.g. AIX Make and Solaris Make, can't handle "--file=$@.tmp:$<";
+# for example, the Solaris 9 make man page says
+#
+# Because make assigns $< and $* as it would for implicit rules
+# (according to the suffixes list and the directory contents),
+# they may be unreliable when used within explicit target entries.
+#
+# and this is an explicit target entry.
+#
+# Therefore, instead of using $<, we explicitly put in $(srcdir)/pcap-config.in.
+#
+pcap-config: $(srcdir)/pcap-config.in ./config.status
@rm -f $@ $@.tmp
- sed -e 's|@includedir[@]|$(includedir)|g' \
- -e 's|@libdir[@]|$(libdir)|g' \
- -e 's|@LIBS[@]|$(LIBS)|g' \
- -e 's|@V_RPATH_OPT[@]|$(V_RPATH_OPT)|g' \
- $(srcdir)/pcap-config.in >$@.tmp
+ ./config.status --file=$@.tmp:$(srcdir)/pcap-config.in
mv $@.tmp $@
chmod a+x $@
#
# Test programs - not built by default, and not installed.
#
-filtertest: filtertest.c libpcap.a
- $(CC) $(CFLAGS) -I. -L. -o filtertest $(srcdir)/filtertest.c libpcap.a $(LIBS)
+tests: $(TESTS)
+
+filtertest: tests/filtertest.c libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o filtertest $(srcdir)/tests/filtertest.c libpcap.a $(LIBS)
+
+findalldevstest: tests/findalldevstest.c libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o findalldevstest $(srcdir)/tests/findalldevstest.c libpcap.a $(LIBS)
-findalldevstest: findalldevstest.c libpcap.a
- $(CC) $(CFLAGS) -I. -L. -o findalldevstest $(srcdir)/findalldevstest.c libpcap.a $(LIBS)
+nonblocktest: tests/nonblocktest.c libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o nonblocktest $(srcdir)/tests/nonblocktest.c libpcap.a $(LIBS)
-selpolltest: selpolltest.c libpcap.a
- $(CC) $(CFLAGS) -I. -L. -o selpolltest $(srcdir)/selpolltest.c libpcap.a $(LIBS)
+opentest: tests/opentest.c libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o opentest $(srcdir)/tests/opentest.c libpcap.a $(LIBS)
-opentest: opentest.c libpcap.a
- $(CC) $(CFLAGS) -I. -L. -o opentest $(srcdir)/opentest.c libpcap.a $(LIBS)
+selpolltest: tests/selpolltest.c libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o selpolltest $(srcdir)/tests/selpolltest.c libpcap.a $(LIBS)
install: install-shared install-archive pcap-config
[ -d $(DESTDIR)$(libdir) ] || \
@@ -533,12 +564,21 @@ install: install-shared install-archive pcap-config
rm -f $(DESTDIR)$(mandir)/man3/pcap_dump_fopen.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_dump_open.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_dump_fopen.3pcap
+ rm -f $(DESTDIR)$(mandir)/man3/pcap_freealldevs.3pcap
+ ln $(DESTDIR)$(mandir)/man3/pcap_findalldevs.3pcap \
+ $(DESTDIR)$(mandir)/man3/pcap_freealldevs.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_perror.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_geterr.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_perror.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_sendpacket.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_inject.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_sendpacket.3pcap
+ rm -f $(DESTDIR)$(mandir)/man3/pcap_free_datalinks.3pcap
+ ln $(DESTDIR)$(mandir)/man3/pcap_list_datalinks.3pcap \
+ $(DESTDIR)$(mandir)/man3/pcap_free_datalinks.3pcap
+ rm -f $(DESTDIR)$(mandir)/man3/pcap_free_tstamp_types.3pcap
+ ln $(DESTDIR)$(mandir)/man3/pcap_list_tstamp_types.3pcap \
+ $(DESTDIR)$(mandir)/man3/pcap_free_tstamp_types.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_dispatch.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_loop.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_dispatch.3pcap
@@ -622,8 +662,11 @@ uninstall: uninstall-shared
rm -f $(DESTDIR)$(mandir)/man3/$$i; done
rm -f $(DESTDIR)$(mandir)/man3/pcap_datalink_val_to_description.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_dump_fopen.3pcap
+ rm -f $(DESTDIR)$(mandir)/man3/pcap_freealldevs.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_perror.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_sendpacket.3pcap
+ rm -f $(DESTDIR)$(mandir)/man3/pcap_free_datalinks.3pcap
+ rm -f $(DESTDIR)$(mandir)/man3/pcap_free_tstamp_types.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_dispatch.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_minor_version.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_next.3pcap
@@ -660,7 +703,7 @@ clean:
distclean: clean
rm -f Makefile config.cache config.log config.status \
- config.h gnuc.h os-proto.h bpf_filter.c pcap-config \
+ config.h gnuc.h net os-proto.h bpf_filter.c pcap-config \
stamp-h stamp-h.in
rm -f $(MAN3PCAP_EXPAND:.in=) $(MANFILE:.in=) $(MANMISC:.in=)
rm -rf autom4te.cache
diff --git a/README b/README
index 47944d7a72ab..a206474aa195 100644
--- a/README
+++ b/README
@@ -63,13 +63,14 @@ added overhead (especially, for selective filters). Ideally, libpcap
would translate BPF filters into a filter program that is compatible
with the underlying kernel subsystem, but this is not yet implemented.
-BPF is standard in 4.4BSD, BSD/OS, NetBSD, FreeBSD, and OpenBSD. 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 in:
-
- ftp://gatekeeper.dec.com/pub/DEC/net/bpfext42.tar.Z.
+BPF is standard in 4.4BSD, BSD/OS, NetBSD, FreeBSD, OpenBSD, DragonFly
+BSD, and Mac OS X; 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 in:
+
+ http://www.tcpdump.org/other/bpfext42.tar.Z
Linux, in the 2.2 kernel and later kernels, has a "Socket Filter"
mechanism that accepts BPF filters; see the README.linux file for
diff --git a/README.linux b/README.linux
index 226b2438b4f1..f92cd22b9e91 100644
--- a/README.linux
+++ b/README.linux
@@ -97,12 +97,12 @@ reported by pcap_stats on Linux are as follows:
2.2.x
=====
ps_recv Number of packets that were accepted by the pcap filter
-ps_drops Always 0, this statistic is not gatherd on this platform
+ps_drop Always 0, this statistic is not gatherd on this platform
2.4.x
=====
-ps_rec Number of packets that were accepted by the pcap filter
-ps_drops Number of packets that had passed filtering but were not
+ps_recv Number of packets that were accepted by the pcap filter
+ps_drop Number of packets that had passed filtering but were not
passed on to pcap due to things like buffer shortage, etc.
- This is useful because these are packets you are interested in
- but won't be reported by, for example, tcpdump output.
+ This is useful because these are packets you are interested in
+ but won't be reported by, for example, tcpdump output.
diff --git a/VERSION b/VERSION
index 524cb55242b5..6085e946503a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.1.1
+1.2.1
diff --git a/Win32/Include/bittypes.h b/Win32/Include/bittypes.h
index 8c3f69fb29ba..7c0cbdeb5f3b 100644
--- a/Win32/Include/bittypes.h
+++ b/Win32/Include/bittypes.h
@@ -30,78 +30,28 @@
#define _BITTYPES_H
#ifndef HAVE_U_INT8_T
-
-#if SIZEOF_CHAR == 1
typedef unsigned char u_int8_t;
typedef signed char int8_t;
-#elif SIZEOF_INT == 1
-typedef unsigned int u_int8_t;
-typedef signed int int8_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int8_t"
-#endif
-#define HAVE_U_INT8_T 1
-#define HAVE_INT8_T 1
-
#endif /* HAVE_U_INT8_T */
#ifndef HAVE_U_INT16_T
-
-#if SIZEOF_SHORT == 2
typedef unsigned short u_int16_t;
typedef signed short int16_t;
-#elif SIZEOF_INT == 2
-typedef unsigned int u_int16_t;
-typedef signed int int16_t;
-#elif SIZEOF_CHAR == 2
-typedef unsigned char u_int16_t;
-typedef signed char int16_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int16_t"
-#endif
-#define HAVE_U_INT16_T 1
-#define HAVE_INT16_T 1
-
#endif /* HAVE_U_INT16_T */
#ifndef HAVE_U_INT32_T
-
-#if SIZEOF_INT == 4
typedef unsigned int u_int32_t;
typedef signed int int32_t;
-#elif SIZEOF_LONG == 4
-typedef unsigned long u_int32_t;
-typedef signed long int32_t;
-#elif SIZEOF_SHORT == 4
-typedef unsigned short u_int32_t;
-typedef signed short int32_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int32_t"
-#endif
-#define HAVE_U_INT32_T 1
-#define HAVE_INT32_T 1
-
#endif /* HAVE_U_INT32_T */
#ifndef HAVE_U_INT64_T
-#if SIZEOF_LONG_LONG == 8
-typedef unsigned long long u_int64_t;
-typedef long long int64_t;
-#elif defined(_MSC_EXTENSIONS)
+#ifdef _MSC_EXTENSIONS
typedef unsigned _int64 u_int64_t;
typedef _int64 int64_t;
-#elif SIZEOF_INT == 8
-typedef unsigned int u_int64_t;
-#elif SIZEOF_LONG == 8
-typedef unsigned long u_int64_t;
-#elif SIZEOF_SHORT == 8
-typedef unsigned short u_int64_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int64_t"
-#endif
-#define HAVE_U_INT64_T 1
-#define HAVE_INT64_T 1
-
+#else /* _MSC_EXTENSIONS */
+typedef unsigned long long u_int64_t;
+typedef long long int64_t;
+#endif /* _MSC_EXTENSIONS */
#endif /* HAVE_U_INT64_T */
#ifndef PRId64
diff --git a/Win32/Prj/libpcap.dsp b/Win32/Prj/libpcap.dsp
index e5168f72f3d1..17e5a7037d41 100644
--- a/Win32/Prj/libpcap.dsp
+++ b/Win32/Prj/libpcap.dsp
@@ -41,7 +41,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "NDEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "NDEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -64,7 +64,7 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "_DEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "_DEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
diff --git a/Win32/Src/gai_strerror.c b/Win32/Src/gai_strerror.c
index e90245ad2bd0..f3afb80725c6 100644
--- a/Win32/Src/gai_strerror.c
+++ b/Win32/Src/gai_strerror.c
@@ -80,4 +80,4 @@ WSAAPI gai_strerrorA(int ecode)
return "Unknown error";
}
-#endif /* gai_strerror */ \ No newline at end of file
+#endif /* gai_strerror */
diff --git a/Win32/Src/getaddrinfo.c b/Win32/Src/getaddrinfo.c
index 8e8ad85d656a..ebfe8c2c95a0 100644
--- a/Win32/Src/getaddrinfo.c
+++ b/Win32/Src/getaddrinfo.c
@@ -45,6 +45,12 @@
* in ai_flags?
*/
+/*
+ * Mingw64 has its own implementation of getaddrinfo, mingw32 no
+ */
+#ifndef __MINGW64__
+
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -85,7 +91,7 @@ static const char rcsid[] _U_ =
#ifdef NEED_ADDRINFO_H
#include "addrinfo.h"
#ifdef WIN32
-#include "IP6_misc.h"
+#include "ip6_misc.h"
#endif
#endif
@@ -1118,3 +1124,6 @@ find_afd(af)
}
return NULL;
}
+
+
+#endif /*__MING64__*/
diff --git a/aclocal.m4 b/aclocal.m4
index e5841edf07fd..20db44fa592b 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -245,7 +245,24 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
# or accepts command-line arguments like
# those the GNU linker accepts.
#
- V_CCOPT="$V_CCOPT -fpic"
+ # Some instruction sets require -fPIC on some
+ # operating systems. Check for them. If you
+ # have a combination that requires it, add it
+ # here.
+ #
+ PIC_OPT=-fpic
+ case "$host_cpu" in
+
+ sparc64*)
+ case "$host_os" in
+
+ freebsd*)
+ PIC_OPT=-fPIC
+ ;;
+ esac
+ ;;
+ esac
+ V_CCOPT="$V_CCOPT $PIC_OPT"
V_SONAME_OPT="-Wl,-soname,"
V_RPATH_OPT="-Wl,-rpath,"
;;
@@ -978,8 +995,9 @@ dnl code that would use that member, or we wouldn't compile in any case).
dnl
AC_DEFUN(AC_LBL_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI,
[AC_MSG_CHECKING(if tpacket_auxdata struct has tp_vlan_tci member)
- AC_CACHE_VAL(ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1,
+ AC_CACHE_VAL(ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci,
AC_TRY_COMPILE([
+# include <sys/types.h>
# include <linux/if_packet.h>],
[u_int i = sizeof(((struct tpacket_auxdata *)0)->tp_vlan_tci)],
ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci=yes,
diff --git a/bpf/net/bpf_filter.c b/bpf/net/bpf_filter.c
index a51ed78756d4..0c4fb006165f 100644
--- a/bpf/net/bpf_filter.c
+++ b/bpf/net/bpf_filter.c
@@ -405,7 +405,18 @@ bpf_filter(pc, p, wirelen, buflen)
continue;
case BPF_JMP|BPF_JA:
+#if defined(KERNEL) || defined(_KERNEL)
+ /*
+ * No backward jumps allowed.
+ */
pc += pc->k;
+#else
+ /*
+ * XXX - we currently implement "ip6 protochain"
+ * with backward jumps, so sign-extend pc->k.
+ */
+ pc += (bpf_int32)pc->k;
+#endif
continue;
case BPF_JMP|BPF_JGT|BPF_K:
@@ -608,7 +619,7 @@ bpf_validate(f, len)
/*
* Check for constant division by 0.
*/
- if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
+ if (BPF_SRC(p->code) == BPF_K && p->k == 0)
return 0;
break;
default:
diff --git a/config.h.in b/config.h.in
index 55e13dad7af1..fb5ae0962927 100644
--- a/config.h.in
+++ b/config.h.in
@@ -18,6 +18,9 @@
/* define if you have streams capable DAG API */
#undef HAVE_DAG_STREAMS_API
+/* define if you have vdag_set_device_info() */
+#undef HAVE_DAG_VDAG
+
/* Define to 1 if you have the declaration of `ether_hostton', and to 0 if you
don't. */
#undef HAVE_DECL_ETHER_HOSTTON
@@ -52,12 +55,30 @@
/* if libnl exists */
#undef HAVE_LIBNL
+/* if libnl exists and is version 2.x */
+#undef HAVE_LIBNL_2_x
+
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
+/* Define to 1 if you have the <linux/compiler.h> header file. */
+#undef HAVE_LINUX_COMPILER_H
+
+/* Define to 1 if you have the <linux/ethtool.h> header file. */
+#undef HAVE_LINUX_ETHTOOL_H
+
+/* Define to 1 if you have the <linux/if_packet.h> header file. */
+#undef HAVE_LINUX_IF_PACKET_H
+
+/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
+#undef HAVE_LINUX_NET_TSTAMP_H
+
/* if tp_vlan_tci exists */
#undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
+/* Define to 1 if you have the <linux/types.h> header file. */
+#undef HAVE_LINUX_TYPES_H
+
/* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */
#undef HAVE_LINUX_USBDEVICE_FS_H
@@ -73,6 +94,12 @@
/* Define to 1 if you have the <netinet/if_ether.h> header file. */
#undef HAVE_NETINET_IF_ETHER_H
+/* Define to 1 if you have the <netpacket/if_packet.h> header file. */
+#undef HAVE_NETPACKET_IF_PACKET_H
+
+/* Define to 1 if you have the <netpacket/packet.h> header file. */
+#undef HAVE_NETPACKET_PACKET_H
+
/* Define to 1 if you have the <net/if_media.h> header file. */
#undef HAVE_NET_IF_MEDIA_H
@@ -217,6 +244,9 @@
/* target host supports CAN sniffing */
#undef PCAP_SUPPORT_CAN
+/* target host supports netfilter sniffing */
+#undef PCAP_SUPPORT_NETFILTER
+
/* target host supports USB sniffing */
#undef PCAP_SUPPORT_USB
diff --git a/configure b/configure
index 390aba00e5bc..e40facff5047 100755
--- a/configure
+++ b/configure
@@ -679,6 +679,7 @@ HAVE_LINUX_TPACKET_AUXDATA
V_LEX
V_YACC
RANLIB
+AR
V_CCOPT
V_DEFS
V_FINDALLDEVS
@@ -696,6 +697,8 @@ MAN_FILE_FORMATS
MAN_MISC_INFO
PCAP_SUPPORT_USB
USB_SRC
+PCAP_SUPPORT_NETFILTER
+NETFILTER_SRC
PCAP_SUPPORT_BT
BT_SRC
PCAP_SUPPORT_CAN
@@ -1293,6 +1296,7 @@ Optional Features:
getaddrinfo available]
--enable-optimizer-dbg build optimizer debugging code
--enable-yydebug build parser debugging code
+ --disable-universal don't build universal on OS X
--enable-bluetooth enable Bluetooth support [default=yes, if support
available]
--enable-can enable CAN support [default=yes, if support
@@ -3229,7 +3233,24 @@ _ACEOF
# or accepts command-line arguments like
# those the GNU linker accepts.
#
- V_CCOPT="$V_CCOPT -fpic"
+ # Some instruction sets require -fPIC on some
+ # operating systems. Check for them. If you
+ # have a combination that requires it, add it
+ # here.
+ #
+ PIC_OPT=-fpic
+ case "$host_cpu" in
+
+ sparc64*)
+ case "$host_os" in
+
+ freebsd*)
+ PIC_OPT=-fPIC
+ ;;
+ esac
+ ;;
+ esac
+ V_CCOPT="$V_CCOPT $PIC_OPT"
V_SONAME_OPT="-Wl,-soname,"
V_RPATH_OPT="-Wl,-rpath,"
;;
@@ -5425,6 +5446,288 @@ fi
done
+for ac_header in linux/types.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+for ac_header in linux/if_packet.h netpacket/packet.h netpacket/if_packet.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
for ac_header in net/pfvar.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@ -7214,37 +7517,6 @@ _ACEOF
;;
linux)
- { echo "$as_me:$LINENO: checking Linux kernel version" >&5
-echo $ECHO_N "checking Linux kernel version... $ECHO_C" >&6; }
- if test "$cross_compiling" = yes; then
- if test "${ac_cv_linux_vers+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_linux_vers=unknown
-fi
-
- else
- if test "${ac_cv_linux_vers+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_linux_vers=`uname -r 2>&1 | \
- sed -n -e '$s/.* //' -e '$s/\..*//p'`
-fi
-
- fi
- { echo "$as_me:$LINENO: result: $ac_cv_linux_vers" >&5
-echo "${ECHO_T}$ac_cv_linux_vers" >&6; }
- if test $ac_cv_linux_vers = unknown ; then
- { { echo "$as_me:$LINENO: error: cannot determine linux version when cross-compiling" >&5
-echo "$as_me: error: cannot determine linux version when cross-compiling" >&2;}
- { (exit 1); exit 1; }; }
- fi
- if test $ac_cv_linux_vers -lt 2 ; then
- { { echo "$as_me:$LINENO: error: version 2 or higher required; see the INSTALL doc for more info" >&5
-echo "$as_me: error: version 2 or higher required; see the INSTALL doc for more info" >&2;}
- { (exit 1); exit 1; }; }
- fi
-
#
# Do we have the wireless extensions?
#
@@ -7322,7 +7594,93 @@ fi
if test x$with_libnl != xno ; then
- { echo "$as_me:$LINENO: checking for nl_handle_alloc in -lnl" >&5
+ #
+ # Try libnl 2.x first.
+ #
+ { echo "$as_me:$LINENO: checking for nl_socket_alloc in -lnl" >&5
+echo $ECHO_N "checking for nl_socket_alloc in -lnl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_nl_nl_socket_alloc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char nl_socket_alloc ();
+int
+main ()
+{
+return nl_socket_alloc ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_lib_nl_nl_socket_alloc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_nl_nl_socket_alloc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_nl_nl_socket_alloc" >&5
+echo "${ECHO_T}$ac_cv_lib_nl_nl_socket_alloc" >&6; }
+if test $ac_cv_lib_nl_nl_socket_alloc = yes; then
+
+ #
+ # Yes, we have libnl 2.x.
+ #
+ LIBS="-lnl-genl -lnl $LIBS"
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBNL 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBNL_2_x 1
+_ACEOF
+
+
+else
+
+ #
+ # No, we don't; do we have libnl 1.x?
+ #
+ { echo "$as_me:$LINENO: checking for nl_handle_alloc in -lnl" >&5
echo $ECHO_N "checking for nl_handle_alloc in -lnl... $ECHO_C" >&6; }
if test "${ac_cv_lib_nl_nl_handle_alloc+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -7384,23 +7742,96 @@ fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_nl_nl_handle_alloc" >&5
echo "${ECHO_T}$ac_cv_lib_nl_nl_handle_alloc" >&6; }
if test $ac_cv_lib_nl_nl_handle_alloc = yes; then
- LIBS="-lnl $LIBS"
+
+ #
+ # Yes.
+ #
+ LIBS="-lnl $LIBS"
cat >>confdefs.h <<\_ACEOF
#define HAVE_LIBNL 1
_ACEOF
+
else
- if test x$with_libnl = xyes ; then
- { { echo "$as_me:$LINENO: error: libnl support requested but libnl not found" >&5
+
+ #
+ # No, we don't have libnl at all.
+ #
+ if test x$with_libnl = xyes ; then
+ { { echo "$as_me:$LINENO: error: libnl support requested but libnl not found" >&5
echo "$as_me: error: libnl support requested but libnl not found" >&2;}
{ (exit 1); exit 1; }; }
- fi
+ fi
+
+fi
+
fi
fi
+
+for ac_header in linux/ethtool.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+$ac_includes_default
+#include <linux/types.h>
+
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
{ echo "$as_me:$LINENO: checking if if_packet.h has tpacket_stats defined" >&5
echo $ECHO_N "checking if if_packet.h has tpacket_stats defined... $ECHO_C" >&6; }
if test "${ac_cv_lbl_tpacket_stats+set}" = set; then
@@ -7461,7 +7892,7 @@ _ACEOF
fi
{ echo "$as_me:$LINENO: checking if tpacket_auxdata struct has tp_vlan_tci member" >&5
echo $ECHO_N "checking if tpacket_auxdata struct has tp_vlan_tci member... $ECHO_C" >&6; }
- if test "${ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1+set}" = set; then
+ if test "${ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
@@ -7471,6 +7902,7 @@ cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
+# include <sys/types.h>
# include <linux/if_packet.h>
int
main ()
@@ -8602,7 +9034,7 @@ echo $ECHO_N "checking whether we have DAG API headers... $ECHO_C" >&6; }
if test -z "$dag_tools_dir"; then
dag_tools_dir="$dag_root/tools"
- fi
+ fi
if test -r $dag_include_dir/dagapi.h; then
ac_cv_lbl_dag_api=yes
@@ -8612,142 +9044,8 @@ echo "${ECHO_T}$ac_cv_lbl_dag_api ($dag_include_dir)" >&6; }
fi
if test $ac_cv_lbl_dag_api = yes; then
-
- { echo "$as_me:$LINENO: checking dagapi.o" >&5
-echo $ECHO_N "checking dagapi.o... $ECHO_C" >&6; }
- dagapi_obj=no
- if test -r $dag_tools_dir/dagapi.o; then
- # 2.4.x.
- dagapi_obj=$dag_tools_dir/dagapi.o
- elif test -r $dag_lib_dir/dagapi.o; then
- # 2.5.x.
- dagapi_obj=$dag_lib_dir/dagapi.o
- elif test -r $dag_lib_dir/libdag.a; then
- # 2.5.x.
- ar x $dag_lib_dir/libdag.a dagapi.o 2>/dev/null
- if test -r ./dagapi.o; then
- dagapi_obj=./dagapi.o
- else
- ar x $dag_lib_dir/libdag.a libdag_la-dagapi.o 2>/dev/null
- if test -r ./libdag_la-dagapi.o; then
- dagapi_obj=./libdag_la-dagapi.o
- fi
- fi
- fi
-
- if test $dagapi_obj = no; then
- { echo "$as_me:$LINENO: result: no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&5
-echo "${ECHO_T}no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&6; }
- ac_cv_lbl_dag_api=no
- else
- { echo "$as_me:$LINENO: result: yes ($dagapi_obj)" >&5
-echo "${ECHO_T}yes ($dagapi_obj)" >&6; }
- fi
-fi
-
-if test $ac_cv_lbl_dag_api = yes; then
-
- { echo "$as_me:$LINENO: checking dagopts.o" >&5
-echo $ECHO_N "checking dagopts.o... $ECHO_C" >&6; }
- dagopts_obj=no
- if test -r $dag_tools_dir/dagopts.o; then
- # 2.4.x.
- dagopts_obj=$dag_tools_dir/dagopts.o
- elif test -r $dag_lib_dir/dagopts.o; then
- # 2.5.x.
- dagopts_obj=$dag_lib_dir/dagopts.o
- elif test -r $dag_lib_dir/libdag.a; then
- # 2.5.x.
- ar x $dag_lib_dir/libdag.a dagopts.o 2>/dev/null
- if test -r ./dagopts.o; then
- dagopts_obj=./dagopts.o
- else
- ar x $dag_lib_dir/libdag.a libdag_la-dagopts.o 2>/dev/null
- if test -r ./libdag_la-dagopts.o; then
- dagopts_obj=./libdag_la-dagopts.o
- fi
- fi
- fi
-
- if test $dagopts_obj = no; then
- { echo "$as_me:$LINENO: result: no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&5
-echo "${ECHO_T}no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&6; }
- ac_cv_lbl_dag_api=no
- else
- { echo "$as_me:$LINENO: result: yes ($dagopts_obj)" >&5
-echo "${ECHO_T}yes ($dagopts_obj)" >&6; }
- fi
-fi
-
-if test $ac_cv_lbl_dag_api = yes; then
- # Under 2.5.x only we need to add dagreg.o.
- if test -r $dag_include_dir/dagreg.h; then
- { echo "$as_me:$LINENO: checking dagreg.o" >&5
-echo $ECHO_N "checking dagreg.o... $ECHO_C" >&6; }
- dagreg_obj=no
- if test -r $dag_lib_dir/dagreg.o; then
- # Object file is ready and waiting.
- dagreg_obj=$dag_lib_dir/dagreg.o
- elif test -r $dag_lib_dir/libdag.a; then
- # Extract from libdag.a.
- ar x $dag_lib_dir/libdag.a dagreg.o 2>/dev/null
- if test -r ./dagreg.o; then
- dagreg_obj=./dagreg.o
- else
- ar x $dag_lib_dir/libdag.a libdag_la-dagreg.o 2>/dev/null
- if test -r ./libdag_la-dagreg.o; then
- dagreg_obj=./libdag_la-dagreg.o
- fi
- fi
- fi
-
- if test $dagreg_obj = no; then
- { echo "$as_me:$LINENO: result: no (checked $dag_lib_dir $dag_lib_dir/libdag.a)" >&5
-echo "${ECHO_T}no (checked $dag_lib_dir $dag_lib_dir/libdag.a)" >&6; }
- ac_cv_lbl_dag_api=no
- else
- { echo "$as_me:$LINENO: result: yes ($dagreg_obj)" >&5
-echo "${ECHO_T}yes ($dagreg_obj)" >&6; }
- fi
- fi
-fi
-
-if test $ac_cv_lbl_dag_api = yes; then
- # Under 2.5.x only we need to add dagutil.o.
- if test -r $dag_include_dir/dagutil.h; then
- { echo "$as_me:$LINENO: checking dagutil.o" >&5
-echo $ECHO_N "checking dagutil.o... $ECHO_C" >&6; }
- dagutil_obj=no
- if test -r $dag_lib_dir/dagutil.o; then
- # Object file is ready and waiting.
- dagutil_obj=$dag_lib_dir/dagutil.o
- elif test -r $dag_lib_dir/libdag.a; then
- # Extract from libdag.a.
- ar x $dag_lib_dir/libdag.a dagutil.o 2>/dev/null
- if test -r ./dagutil.o; then
- dagutil_obj=./dagutil.o
- else
- ar x $dag_lib_dir/libdag.a libdag_la-dagutil.o 2>/dev/null
- if test -r ./libdag_la-dagutil.o; then
- dagutil_obj=./libdag_la-dagutil.o
- fi
- fi
- fi
-
- if test $dagutil_obj = no; then
- { echo "$as_me:$LINENO: result: no (checked $dag_lib_dir $dag_lib_dir/libdag.a)" >&5
-echo "${ECHO_T}no (checked $dag_lib_dir $dag_lib_dir/libdag.a)" >&6; }
- ac_cv_lbl_dag_api=no
- else
- { echo "$as_me:$LINENO: result: yes ($dagutil_obj)" >&5
-echo "${ECHO_T}yes ($dagutil_obj)" >&6; }
- fi
- fi
-fi
-
-if test $ac_cv_lbl_dag_api = yes; then
V_INCLS="$V_INCLS -I$dag_include_dir"
- ADDLARCHIVEOBJS="$ADDLARCHIVEOBJS $dagapi_obj $dagopts_obj $dagreg_obj $dagutil_obj"
+
if test $V_PCAP != dag ; then
SSRC="pcap-dag.c"
fi
@@ -8964,6 +9262,7 @@ _ACEOF
fi
+
LDFLAGS=$saved_ldflags
if test "$dag_streams" = 1; then
@@ -8973,6 +9272,83 @@ cat >>confdefs.h <<\_ACEOF
_ACEOF
LIBS="$LIBS -ldag"
+ LDFLAGS="$LDFLAGS -L$dag_lib_dir"
+
+ { echo "$as_me:$LINENO: checking for vdag_set_device_info in -lvdag" >&5
+echo $ECHO_N "checking for vdag_set_device_info in -lvdag... $ECHO_C" >&6; }
+if test "${ac_cv_lib_vdag_vdag_set_device_info+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lvdag $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char vdag_set_device_info ();
+int
+main ()
+{
+return vdag_set_device_info ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_lib_vdag_vdag_set_device_info=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_vdag_vdag_set_device_info=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_vdag_vdag_set_device_info" >&5
+echo "${ECHO_T}$ac_cv_lib_vdag_vdag_set_device_info" >&6; }
+if test $ac_cv_lib_vdag_vdag_set_device_info = yes; then
+ ac_dag_have_vdag="1"
+else
+ ac_dag_have_vdag="0"
+fi
+
+ if test "$ac_dag_have_vdag" = 1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DAG_VDAG 1
+_ACEOF
+
+ LIBS="$LIBS -lpthread"
+ fi
fi
@@ -9540,6 +9916,49 @@ echo "${ECHO_T}yes" >&6; }
darwin*)
DYEXT="dylib"
V_CCOPT="$V_CCOPT -fno-common"
+ # Check whether --enable-universal was given.
+if test "${enable_universal+set}" = set; then
+ enableval=$enable_universal;
+fi
+
+ if test "$enable_universal" != "no"; then
+ case "$host_os" in
+
+ darwin9.*)
+ #
+ # Leopard. Build for 32-bit PowerPC, 64-bit
+ # PowerPC, x86, and x86-64, with 32-bit PowerPC
+ # first. (That's what Apple does.)
+ #
+ V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386 -arch x86_64"
+ LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386 -arch x86_64"
+ ;;
+
+ darwin10.*)
+ #
+ # Snow Leopard. Build for x86-64, x86, and
+ # 32-bit PowerPC, with x86-64 first. (That's
+ # what Apple does, even though Snow Leopard
+ # doesn't run on PPC, so PPC libpcap runs under
+ # Rosetta, and Rosetta doesn't support BPF
+ # ioctls, so PPC programs can't do live
+ # captures.)
+ #
+ V_CCOPT="$V_CCOPT -arch x86_64 -arch i386 -arch ppc"
+ LDFLAGS="$LDFLAGS -arch x86_64 -arch i386 -arch ppc"
+ ;;
+
+ darwin11.*)
+ #
+ # Lion. Build for x86-64 and x86, with x86-64
+ # first. (That's probably what Apple does,
+ # given that Rosetta is gone.)
+ #
+ V_CCOPT="$V_CCOPT -arch x86_64 -arch i386"
+ LDFLAGS="$LDFLAGS -arch x86_64 -arch i386"
+ ;;
+ esac
+ fi
;;
hpux9*)
@@ -9607,7 +10026,7 @@ irix*)
MAN_MISC_INFO=5
;;
-linux*|freebsd*|netbsd*|openbsd*|dragonfly*)
+linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*)
DYEXT="so"
#
@@ -9801,6 +10220,102 @@ else
RANLIB="$ac_cv_prog_RANLIB"
fi
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_AR="ar"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+echo "${ECHO_T}$ac_ct_AR" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
rm -f os-proto.h
if test "${LBL_CFLAGS+set}" = set; then
@@ -10161,20 +10676,227 @@ cat >>confdefs.h <<\_ACEOF
#define PCAP_SUPPORT_USB 1
_ACEOF
- USB_SRC=pcap-usb-linux.c
- { echo "$as_me:$LINENO: result: yes" >&5
+ USB_SRC=pcap-usb-linux.c
+ { echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
- ac_usb_dev_name=`udevinfo -q name -p /sys/class/usb_device/usbmon 2>/dev/null`
- if test $? -ne 0 ; then
- ac_usb_dev_name="usbmon"
- fi
+ ac_usb_dev_name=`udevinfo -q name -p /sys/class/usb_device/usbmon 2>/dev/null`
+ if test $? -ne 0 ; then
+ ac_usb_dev_name="usbmon"
+ fi
cat >>confdefs.h <<_ACEOF
#define LINUX_USB_MON_DEV "/dev/$ac_usb_dev_name"
_ACEOF
- { echo "$as_me:$LINENO: Device for USB sniffing is /dev/$ac_usb_dev_name" >&5
+ { echo "$as_me:$LINENO: Device for USB sniffing is /dev/$ac_usb_dev_name" >&5
echo "$as_me: Device for USB sniffing is /dev/$ac_usb_dev_name" >&6;}
+ #
+ # Do we have a version of <linux/compiler.h> available?
+ # If so, we might need it for <linux/usbdevice_fs.h>.
+ #
+
+for ac_header in linux/compiler.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ if test "$ac_cv_header_linux_compiler_h" = yes; then
+ #
+ # Yes - include it when testing for <linux/usbdevice_fs.h>.
+ #
+
+for ac_header in linux/usbdevice_fs.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <linux/compiler.h>
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ else
for ac_header in linux/usbdevice_fs.h
do
@@ -10315,16 +11037,17 @@ fi
done
- if test "$ac_cv_header_linux_usbdevice_fs_h" = yes; then
- #
- # OK, does it define bRequestType? Older versions of the kernel
- # define fields with names like "requesttype, "request", and
- # "value", rather than "bRequestType", "bRequest", and
- # "wValue".
- #
- { echo "$as_me:$LINENO: checking if usbdevfs_ctrltransfer struct has bRequestType member" >&5
+ fi
+ if test "$ac_cv_header_linux_usbdevice_fs_h" = yes; then
+ #
+ # OK, does it define bRequestType? Older versions of the kernel
+ # define fields with names like "requesttype, "request", and
+ # "value", rather than "bRequestType", "bRequest", and
+ # "wValue".
+ #
+ { echo "$as_me:$LINENO: checking if usbdevfs_ctrltransfer struct has bRequestType member" >&5
echo $ECHO_N "checking if usbdevfs_ctrltransfer struct has bRequestType member... $ECHO_C" >&6; }
- if test "${ac_cv_usbdevfs_ctrltransfer_has_bRequestType+set}" = set; then
+ if test "${ac_cv_usbdevfs_ctrltransfer_has_bRequestType+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
@@ -10338,7 +11061,10 @@ $ac_includes_default
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
#endif
-# include <linux/usbdevice_fs.h>
+#ifdef HAVE_LINUX_COMPILER_H
+#include <linux/compiler.h>
+#endif
+#include <linux/usbdevice_fs.h>
int
main ()
{
@@ -10375,21 +11101,109 @@ fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
- { echo "$as_me:$LINENO: result: $ac_cv_usbdevfs_ctrltransfer_has_bRequestType" >&5
+ { echo "$as_me:$LINENO: result: $ac_cv_usbdevfs_ctrltransfer_has_bRequestType" >&5
echo "${ECHO_T}$ac_cv_usbdevfs_ctrltransfer_has_bRequestType" >&6; }
- if test $ac_cv_usbdevfs_ctrltransfer_has_bRequestType = yes ; then
+ if test $ac_cv_usbdevfs_ctrltransfer_has_bRequestType = yes ; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1
_ACEOF
- fi
- fi
- ;;
+ fi
+ fi
+ ;;
*)
- { echo "$as_me:$LINENO: result: no" >&5
+ { echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
- ;;
+ ;;
+esac
+
+
+
+{ echo "$as_me:$LINENO: checking whether the platform could support netfilter sniffing" >&5
+echo $ECHO_N "checking whether the platform could support netfilter sniffing... $ECHO_C" >&6; }
+case "$host_os" in
+linux*)
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ #
+ # Life's too short to deal with trying to get this to compile
+ # if you don't get the right types defined with
+ # __KERNEL_STRICT_NAMES getting defined by some other include.
+ #
+ # Check whether the includes Just Work. If not, don't turn on
+ # netfilter support.
+ #
+ { echo "$as_me:$LINENO: checking whether we can compile the netfilter support" >&5
+echo $ECHO_N "checking whether we can compile the netfilter support... $ECHO_C" >&6; }
+ if test "${ac_cv_netfilter_can_compile+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+$ac_includes_default
+#include <sys/socket.h>
+#include <linux/types.h>
+
+#include <linux/netlink.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_log.h>
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_netfilter_can_compile=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_netfilter_can_compile=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ { echo "$as_me:$LINENO: result: $ac_cv_netfilter_can_compile" >&5
+echo "${ECHO_T}$ac_cv_netfilter_can_compile" >&6; }
+ if test $ac_cv_netfilter_can_compile = yes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define PCAP_SUPPORT_NETFILTER 1
+_ACEOF
+
+ NETFILTER_SRC=pcap-netfilter-linux.c
+ fi
+ ;;
+*)
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ ;;
esac
@@ -10405,7 +11219,7 @@ fi
if test "x$enable_bluetooth" != "xno" ; then
case "$host_os" in
linux*)
- if test "${ac_cv_header_bluetooth_bluetooth_h+set}" = set; then
+ if test "${ac_cv_header_bluetooth_bluetooth_h+set}" = set; then
{ echo "$as_me:$LINENO: checking for bluetooth/bluetooth.h" >&5
echo $ECHO_N "checking for bluetooth/bluetooth.h... $ECHO_C" >&6; }
if test "${ac_cv_header_bluetooth_bluetooth_h+set}" = set; then
@@ -10537,8 +11351,8 @@ cat >>confdefs.h <<\_ACEOF
#define PCAP_SUPPORT_BT 1
_ACEOF
- BT_SRC=pcap-bt-linux.c
- { echo "$as_me:$LINENO: Bluetooth sniffing is supported" >&5
+ BT_SRC=pcap-bt-linux.c
+ { echo "$as_me:$LINENO: Bluetooth sniffing is supported" >&5
echo "$as_me: Bluetooth sniffing is supported" >&6;}
else
@@ -10548,11 +11362,11 @@ echo "$as_me: Bluetooth sniffing is not supported; install bluez-lib devel to en
fi
- ;;
+ ;;
*)
- { echo "$as_me:$LINENO: no Bluetooth sniffing support implemented for $host_os" >&5
+ { echo "$as_me:$LINENO: no Bluetooth sniffing support implemented for $host_os" >&5
echo "$as_me: no Bluetooth sniffing support implemented for $host_os" >&6;}
- ;;
+ ;;
esac
@@ -10639,6 +11453,155 @@ echo "$as_me: no CAN sniffing support implemented for $host_os" >&6;}
fi
+case "$host_os" in
+linux*)
+
+for ac_header in linux/net_tstamp.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ ;;
+*)
+ { echo "$as_me:$LINENO: no hardware timestamp support implemented for $host_os" >&5
+echo "$as_me: no hardware timestamp support implemented for $host_os" >&6;}
+ ;;
+esac
+
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
@@ -10723,7 +11686,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
ac_config_headers="$ac_config_headers config.h"
-ac_config_files="$ac_config_files Makefile pcap-filter.manmisc pcap-linktype.manmisc pcap-savefile.manfile pcap.3pcap pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap pcap_list_datalinks.3pcap pcap_open_dead.3pcap pcap_open_offline.3pcap"
+ac_config_files="$ac_config_files Makefile pcap-filter.manmisc pcap-linktype.manmisc pcap-tstamp.manmisc pcap-savefile.manfile pcap.3pcap pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap pcap_list_datalinks.3pcap pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap pcap_open_offline.3pcap pcap_set_tstamp_type.3pcap"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -11282,14 +12245,17 @@ do
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"pcap-filter.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-filter.manmisc" ;;
"pcap-linktype.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-linktype.manmisc" ;;
+ "pcap-tstamp.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-tstamp.manmisc" ;;
"pcap-savefile.manfile") CONFIG_FILES="$CONFIG_FILES pcap-savefile.manfile" ;;
"pcap.3pcap") CONFIG_FILES="$CONFIG_FILES pcap.3pcap" ;;
"pcap_compile.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_compile.3pcap" ;;
"pcap_datalink.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_datalink.3pcap" ;;
"pcap_dump_open.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_dump_open.3pcap" ;;
"pcap_list_datalinks.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_list_datalinks.3pcap" ;;
+ "pcap_list_tstamp_types.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_list_tstamp_types.3pcap" ;;
"pcap_open_dead.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_open_dead.3pcap" ;;
"pcap_open_offline.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_open_offline.3pcap" ;;
+ "pcap_set_tstamp_type.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_set_tstamp_type.3pcap" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
@@ -11416,6 +12382,7 @@ HAVE_LINUX_TPACKET_AUXDATA!$HAVE_LINUX_TPACKET_AUXDATA$ac_delim
V_LEX!$V_LEX$ac_delim
V_YACC!$V_YACC$ac_delim
RANLIB!$RANLIB$ac_delim
+AR!$AR$ac_delim
V_CCOPT!$V_CCOPT$ac_delim
V_DEFS!$V_DEFS$ac_delim
V_FINDALLDEVS!$V_FINDALLDEVS$ac_delim
@@ -11433,6 +12400,8 @@ MAN_FILE_FORMATS!$MAN_FILE_FORMATS$ac_delim
MAN_MISC_INFO!$MAN_MISC_INFO$ac_delim
PCAP_SUPPORT_USB!$PCAP_SUPPORT_USB$ac_delim
USB_SRC!$USB_SRC$ac_delim
+PCAP_SUPPORT_NETFILTER!$PCAP_SUPPORT_NETFILTER$ac_delim
+NETFILTER_SRC!$NETFILTER_SRC$ac_delim
PCAP_SUPPORT_BT!$PCAP_SUPPORT_BT$ac_delim
BT_SRC!$BT_SRC$ac_delim
PCAP_SUPPORT_CAN!$PCAP_SUPPORT_CAN$ac_delim
@@ -11443,7 +12412,7 @@ INSTALL_DATA!$INSTALL_DATA$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 90; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 93; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.in b/configure.in
index 794da275805f..6a146cad996f 100755
--- a/configure.in
+++ b/configure.in
@@ -103,6 +103,8 @@ dnl and set "HAVE_SYS_IOCCOM_H" if we have it, otherwise
dnl "AC_LBL_FIXINCLUDES" wouldn't work on some platforms such as Solaris.
dnl
AC_CHECK_HEADERS(sys/ioccom.h sys/sockio.h limits.h paths.h)
+AC_CHECK_HEADERS(linux/types.h)
+AC_CHECK_HEADERS(linux/if_packet.h netpacket/packet.h netpacket/if_packet.h)
AC_CHECK_HEADERS(net/pfvar.h, , , [#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>])
@@ -152,7 +154,7 @@ needsnprintf=no
AC_CHECK_FUNCS(vsnprintf snprintf,,
[needsnprintf=yes])
if test $needsnprintf = yes; then
- AC_LIBOBJ(snprintf)
+ AC_LIBOBJ([snprintf])
fi
#
@@ -410,23 +412,6 @@ dlpi)
;;
linux)
- AC_MSG_CHECKING(Linux kernel version)
- if test "$cross_compiling" = yes; then
- AC_CACHE_VAL(ac_cv_linux_vers,
- ac_cv_linux_vers=unknown)
- else
- AC_CACHE_VAL(ac_cv_linux_vers,
- ac_cv_linux_vers=`uname -r 2>&1 | \
- sed -n -e '$s/.* //' -e '$s/\..*//p'`)
- fi
- AC_MSG_RESULT($ac_cv_linux_vers)
- if test $ac_cv_linux_vers = unknown ; then
- AC_MSG_ERROR(cannot determine linux version when cross-compiling)
- fi
- if test $ac_cv_linux_vers -lt 2 ; then
- AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info)
- fi
-
#
# Do we have the wireless extensions?
#
@@ -445,15 +430,46 @@ linux)
with_libnl=$withval,,)
if test x$with_libnl != xno ; then
- AC_CHECK_LIB(nl, nl_handle_alloc,
- LIBS="-lnl $LIBS"
- AC_DEFINE(HAVE_LIBNL,1,[if libnl exists]),
- if test x$with_libnl = xyes ; then
- AC_MSG_ERROR([libnl support requested but libnl not found])
- fi
- )
+ #
+ # Try libnl 2.x first.
+ #
+ AC_CHECK_LIB(nl, nl_socket_alloc,
+ [
+ #
+ # Yes, we have libnl 2.x.
+ #
+ LIBS="-lnl-genl -lnl $LIBS"
+ AC_DEFINE(HAVE_LIBNL,1,[if libnl exists])
+ AC_DEFINE(HAVE_LIBNL_2_x,1,[if libnl exists and is version 2.x])
+ ],
+ [
+ #
+ # No, we don't; do we have libnl 1.x?
+ #
+ AC_CHECK_LIB(nl, nl_handle_alloc,
+ [
+ #
+ # Yes.
+ #
+ LIBS="-lnl $LIBS"
+ AC_DEFINE(HAVE_LIBNL,1,[if libnl exists])
+ ],
+ [
+ #
+ # No, we don't have libnl at all.
+ #
+ if test x$with_libnl = xyes ; then
+ AC_MSG_ERROR([libnl support requested but libnl not found])
+ fi
+ ])
+ ])
fi
+ AC_CHECK_HEADERS(linux/ethtool.h,,,
+ [
+AC_INCLUDES_DEFAULT
+#include <linux/types.h>
+ ])
AC_LBL_TPACKET_STATS
AC_LBL_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
;;
@@ -727,7 +743,7 @@ if test "$want_dag" != no; then
if test -z "$dag_tools_dir"; then
dag_tools_dir="$dag_root/tools"
- fi
+ fi
if test -r $dag_include_dir/dagapi.h; then
ac_cv_lbl_dag_api=yes
@@ -736,130 +752,8 @@ if test "$want_dag" != no; then
fi
if test $ac_cv_lbl_dag_api = yes; then
-
- AC_MSG_CHECKING([dagapi.o])
- dagapi_obj=no
- if test -r $dag_tools_dir/dagapi.o; then
- # 2.4.x.
- dagapi_obj=$dag_tools_dir/dagapi.o
- elif test -r $dag_lib_dir/dagapi.o; then
- # 2.5.x.
- dagapi_obj=$dag_lib_dir/dagapi.o
- elif test -r $dag_lib_dir/libdag.a; then
- # 2.5.x.
- ar x $dag_lib_dir/libdag.a dagapi.o 2>/dev/null
- if test -r ./dagapi.o; then
- dagapi_obj=./dagapi.o
- else
- ar x $dag_lib_dir/libdag.a libdag_la-dagapi.o 2>/dev/null
- if test -r ./libdag_la-dagapi.o; then
- dagapi_obj=./libdag_la-dagapi.o
- fi
- fi
- fi
-
- if test $dagapi_obj = no; then
- AC_MSG_RESULT([no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)])
- ac_cv_lbl_dag_api=no
- else
- AC_MSG_RESULT([yes ($dagapi_obj)])
- fi
-fi
-
-if test $ac_cv_lbl_dag_api = yes; then
-
- AC_MSG_CHECKING([dagopts.o])
- dagopts_obj=no
- if test -r $dag_tools_dir/dagopts.o; then
- # 2.4.x.
- dagopts_obj=$dag_tools_dir/dagopts.o
- elif test -r $dag_lib_dir/dagopts.o; then
- # 2.5.x.
- dagopts_obj=$dag_lib_dir/dagopts.o
- elif test -r $dag_lib_dir/libdag.a; then
- # 2.5.x.
- ar x $dag_lib_dir/libdag.a dagopts.o 2>/dev/null
- if test -r ./dagopts.o; then
- dagopts_obj=./dagopts.o
- else
- ar x $dag_lib_dir/libdag.a libdag_la-dagopts.o 2>/dev/null
- if test -r ./libdag_la-dagopts.o; then
- dagopts_obj=./libdag_la-dagopts.o
- fi
- fi
- fi
-
- if test $dagopts_obj = no; then
- AC_MSG_RESULT([no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)])
- ac_cv_lbl_dag_api=no
- else
- AC_MSG_RESULT([yes ($dagopts_obj)])
- fi
-fi
-
-if test $ac_cv_lbl_dag_api = yes; then
- # Under 2.5.x only we need to add dagreg.o.
- if test -r $dag_include_dir/dagreg.h; then
- AC_MSG_CHECKING([dagreg.o])
- dagreg_obj=no
- if test -r $dag_lib_dir/dagreg.o; then
- # Object file is ready and waiting.
- dagreg_obj=$dag_lib_dir/dagreg.o
- elif test -r $dag_lib_dir/libdag.a; then
- # Extract from libdag.a.
- ar x $dag_lib_dir/libdag.a dagreg.o 2>/dev/null
- if test -r ./dagreg.o; then
- dagreg_obj=./dagreg.o
- else
- ar x $dag_lib_dir/libdag.a libdag_la-dagreg.o 2>/dev/null
- if test -r ./libdag_la-dagreg.o; then
- dagreg_obj=./libdag_la-dagreg.o
- fi
- fi
- fi
-
- if test $dagreg_obj = no; then
- AC_MSG_RESULT([no (checked $dag_lib_dir $dag_lib_dir/libdag.a)])
- ac_cv_lbl_dag_api=no
- else
- AC_MSG_RESULT([yes ($dagreg_obj)])
- fi
- fi
-fi
-
-if test $ac_cv_lbl_dag_api = yes; then
- # Under 2.5.x only we need to add dagutil.o.
- if test -r $dag_include_dir/dagutil.h; then
- AC_MSG_CHECKING([dagutil.o])
- dagutil_obj=no
- if test -r $dag_lib_dir/dagutil.o; then
- # Object file is ready and waiting.
- dagutil_obj=$dag_lib_dir/dagutil.o
- elif test -r $dag_lib_dir/libdag.a; then
- # Extract from libdag.a.
- ar x $dag_lib_dir/libdag.a dagutil.o 2>/dev/null
- if test -r ./dagutil.o; then
- dagutil_obj=./dagutil.o
- else
- ar x $dag_lib_dir/libdag.a libdag_la-dagutil.o 2>/dev/null
- if test -r ./libdag_la-dagutil.o; then
- dagutil_obj=./libdag_la-dagutil.o
- fi
- fi
- fi
-
- if test $dagutil_obj = no; then
- AC_MSG_RESULT([no (checked $dag_lib_dir $dag_lib_dir/libdag.a)])
- ac_cv_lbl_dag_api=no
- else
- AC_MSG_RESULT([yes ($dagutil_obj)])
- fi
- fi
-fi
-
-if test $ac_cv_lbl_dag_api = yes; then
V_INCLS="$V_INCLS -I$dag_include_dir"
- ADDLARCHIVEOBJS="$ADDLARCHIVEOBJS $dagapi_obj $dagopts_obj $dagreg_obj $dagutil_obj"
+
if test $V_PCAP != dag ; then
SSRC="pcap-dag.c"
fi
@@ -874,11 +768,19 @@ if test $ac_cv_lbl_dag_api = yes; then
AC_DEFINE(HAVE_DAG_GET_ERF_TYPES, 1, [define if you have dag_get_erf_types()])])
AC_CHECK_LIB([dag],[dag_get_stream_erf_types], [
AC_DEFINE(HAVE_DAG_GET_STREAM_ERF_TYPES, 1, [define if you have dag_get_stream_erf_types()])])
+
LDFLAGS=$saved_ldflags
if test "$dag_streams" = 1; then
AC_DEFINE(HAVE_DAG_STREAMS_API, 1, [define if you have streams capable DAG API])
LIBS="$LIBS -ldag"
+ LDFLAGS="$LDFLAGS -L$dag_lib_dir"
+
+ AC_CHECK_LIB([vdag],[vdag_set_device_info], [ac_dag_have_vdag="1"], [ac_dag_have_vdag="0"])
+ if test "$ac_dag_have_vdag" = 1; then
+ AC_DEFINE(HAVE_DAG_VDAG, 1, [define if you have vdag_set_device_info()])
+ LIBS="$LIBS -lpthread"
+ fi
fi
AC_DEFINE(HAVE_DAG_API, 1, [define if you have the DAG API])
@@ -1169,6 +1071,46 @@ aix*)
darwin*)
DYEXT="dylib"
V_CCOPT="$V_CCOPT -fno-common"
+ AC_ARG_ENABLE(universal,
+ AC_HELP_STRING([--disable-universal],[don't build universal on OS X]))
+ if test "$enable_universal" != "no"; then
+ case "$host_os" in
+
+ darwin9.*)
+ #
+ # Leopard. Build for 32-bit PowerPC, 64-bit
+ # PowerPC, x86, and x86-64, with 32-bit PowerPC
+ # first. (That's what Apple does.)
+ #
+ V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386 -arch x86_64"
+ LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386 -arch x86_64"
+ ;;
+
+ darwin10.*)
+ #
+ # Snow Leopard. Build for x86-64, x86, and
+ # 32-bit PowerPC, with x86-64 first. (That's
+ # what Apple does, even though Snow Leopard
+ # doesn't run on PPC, so PPC libpcap runs under
+ # Rosetta, and Rosetta doesn't support BPF
+ # ioctls, so PPC programs can't do live
+ # captures.)
+ #
+ V_CCOPT="$V_CCOPT -arch x86_64 -arch i386 -arch ppc"
+ LDFLAGS="$LDFLAGS -arch x86_64 -arch i386 -arch ppc"
+ ;;
+
+ darwin11.*)
+ #
+ # Lion. Build for x86-64 and x86, with x86-64
+ # first. (That's probably what Apple does,
+ # given that Rosetta is gone.)
+ #
+ V_CCOPT="$V_CCOPT -arch x86_64 -arch i386"
+ LDFLAGS="$LDFLAGS -arch x86_64 -arch i386"
+ ;;
+ esac
+ fi
;;
hpux9*)
@@ -1234,7 +1176,7 @@ irix*)
MAN_MISC_INFO=5
;;
-linux*|freebsd*|netbsd*|openbsd*|dragonfly*)
+linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*)
DYEXT="so"
#
@@ -1283,6 +1225,7 @@ solaris*)
esac
AC_PROG_RANLIB
+AC_CHECK_TOOL([AR], [ar])
AC_LBL_DEVEL(V_CCOPT)
@@ -1325,48 +1268,103 @@ dnl check for USB sniffing support
AC_MSG_CHECKING(for USB sniffing support)
case "$host_os" in
linux*)
- AC_DEFINE(PCAP_SUPPORT_USB, 1, [target host supports USB sniffing])
- USB_SRC=pcap-usb-linux.c
- AC_MSG_RESULT(yes)
- ac_usb_dev_name=`udevinfo -q name -p /sys/class/usb_device/usbmon 2>/dev/null`
- if test $? -ne 0 ; then
- ac_usb_dev_name="usbmon"
- fi
- AC_DEFINE_UNQUOTED(LINUX_USB_MON_DEV, "/dev/$ac_usb_dev_name", [path for device for USB sniffing])
- AC_MSG_NOTICE(Device for USB sniffing is /dev/$ac_usb_dev_name)
- AC_CHECK_HEADERS(linux/usbdevice_fs.h)
- if test "$ac_cv_header_linux_usbdevice_fs_h" = yes; then
- #
- # OK, does it define bRequestType? Older versions of the kernel
- # define fields with names like "requesttype, "request", and
- # "value", rather than "bRequestType", "bRequest", and
- # "wValue".
- #
- AC_MSG_CHECKING(if usbdevfs_ctrltransfer struct has bRequestType member)
- AC_CACHE_VAL(ac_cv_usbdevfs_ctrltransfer_has_bRequestType,
- AC_TRY_COMPILE([
+ AC_DEFINE(PCAP_SUPPORT_USB, 1, [target host supports USB sniffing])
+ USB_SRC=pcap-usb-linux.c
+ AC_MSG_RESULT(yes)
+ ac_usb_dev_name=`udevinfo -q name -p /sys/class/usb_device/usbmon 2>/dev/null`
+ if test $? -ne 0 ; then
+ ac_usb_dev_name="usbmon"
+ fi
+ AC_DEFINE_UNQUOTED(LINUX_USB_MON_DEV, "/dev/$ac_usb_dev_name", [path for device for USB sniffing])
+ AC_MSG_NOTICE(Device for USB sniffing is /dev/$ac_usb_dev_name)
+ #
+ # Do we have a version of <linux/compiler.h> available?
+ # If so, we might need it for <linux/usbdevice_fs.h>.
+ #
+ AC_CHECK_HEADERS(linux/compiler.h)
+ if test "$ac_cv_header_linux_compiler_h" = yes; then
+ #
+ # Yes - include it when testing for <linux/usbdevice_fs.h>.
+ #
+ AC_CHECK_HEADERS(linux/usbdevice_fs.h,,,[#include <linux/compiler.h>])
+ else
+ AC_CHECK_HEADERS(linux/usbdevice_fs.h)
+ fi
+ if test "$ac_cv_header_linux_usbdevice_fs_h" = yes; then
+ #
+ # OK, does it define bRequestType? Older versions of the kernel
+ # define fields with names like "requesttype, "request", and
+ # "value", rather than "bRequestType", "bRequest", and
+ # "wValue".
+ #
+ AC_MSG_CHECKING(if usbdevfs_ctrltransfer struct has bRequestType member)
+ AC_CACHE_VAL(ac_cv_usbdevfs_ctrltransfer_has_bRequestType,
+ AC_TRY_COMPILE([
AC_INCLUDES_DEFAULT
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
#endif
-# include <linux/usbdevice_fs.h>],
- [u_int i = sizeof(((struct usbdevfs_ctrltransfer *)0)->bRequestType)],
- ac_cv_usbdevfs_ctrltransfer_has_bRequestType=yes,
- ac_cv_usbdevfs_ctrltransfer_has_bRequestType=no))
- AC_MSG_RESULT($ac_cv_usbdevfs_ctrltransfer_has_bRequestType)
- if test $ac_cv_usbdevfs_ctrltransfer_has_bRequestType = yes ; then
- AC_DEFINE(HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE,1,
- [if struct usbdevfs_ctrltransfer has bRequestType])
- fi
- fi
- ;;
+#ifdef HAVE_LINUX_COMPILER_H
+#include <linux/compiler.h>
+#endif
+#include <linux/usbdevice_fs.h>],
+ [u_int i = sizeof(((struct usbdevfs_ctrltransfer *)0)->bRequestType)],
+ ac_cv_usbdevfs_ctrltransfer_has_bRequestType=yes,
+ ac_cv_usbdevfs_ctrltransfer_has_bRequestType=no))
+ AC_MSG_RESULT($ac_cv_usbdevfs_ctrltransfer_has_bRequestType)
+ if test $ac_cv_usbdevfs_ctrltransfer_has_bRequestType = yes ; then
+ AC_DEFINE(HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE,1,
+ [if struct usbdevfs_ctrltransfer has bRequestType])
+ fi
+ fi
+ ;;
*)
- AC_MSG_RESULT(no)
- ;;
+ AC_MSG_RESULT(no)
+ ;;
esac
AC_SUBST(PCAP_SUPPORT_USB)
AC_SUBST(USB_SRC)
+dnl check for netfilter sniffing support
+AC_MSG_CHECKING(whether the platform could support netfilter sniffing)
+case "$host_os" in
+linux*)
+ AC_MSG_RESULT(yes)
+ #
+ # Life's too short to deal with trying to get this to compile
+ # if you don't get the right types defined with
+ # __KERNEL_STRICT_NAMES getting defined by some other include.
+ #
+ # Check whether the includes Just Work. If not, don't turn on
+ # netfilter support.
+ #
+ AC_MSG_CHECKING(whether we can compile the netfilter support)
+ AC_CACHE_VAL(ac_cv_netfilter_can_compile,
+ AC_TRY_COMPILE([
+AC_INCLUDES_DEFAULT
+#include <sys/socket.h>
+#include <linux/types.h>
+
+#include <linux/netlink.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_log.h>],
+ [],
+ ac_cv_netfilter_can_compile=yes,
+ ac_cv_netfilter_can_compile=no))
+ AC_MSG_RESULT($ac_cv_netfilter_can_compile)
+ if test $ac_cv_netfilter_can_compile = yes ; then
+ AC_DEFINE(PCAP_SUPPORT_NETFILTER, 1,
+ [target host supports netfilter sniffing])
+ NETFILTER_SRC=pcap-netfilter-linux.c
+ fi
+ ;;
+*)
+ AC_MSG_RESULT(no)
+ ;;
+esac
+AC_SUBST(PCAP_SUPPORT_NETFILTER)
+AC_SUBST(NETFILTER_SRC)
+
AC_ARG_ENABLE([bluetooth],
[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])],
,enable_bluetooth=yes)
@@ -1375,18 +1373,18 @@ if test "x$enable_bluetooth" != "xno" ; then
dnl check for Bluetooth sniffing support
case "$host_os" in
linux*)
- AC_CHECK_HEADER(bluetooth/bluetooth.h,
- [
+ AC_CHECK_HEADER(bluetooth/bluetooth.h,
+ [
AC_DEFINE(PCAP_SUPPORT_BT, 1, [target host supports Bluetooth sniffing])
- BT_SRC=pcap-bt-linux.c
- AC_MSG_NOTICE(Bluetooth sniffing is supported)
+ BT_SRC=pcap-bt-linux.c
+ AC_MSG_NOTICE(Bluetooth sniffing is supported)
],
AC_MSG_NOTICE(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
- )
- ;;
+ )
+ ;;
*)
- AC_MSG_NOTICE(no Bluetooth sniffing support implemented for $host_os)
- ;;
+ AC_MSG_NOTICE(no Bluetooth sniffing support implemented for $host_os)
+ ;;
esac
AC_SUBST(PCAP_SUPPORT_BT)
AC_SUBST(BT_SRC)
@@ -1416,15 +1414,26 @@ if test "x$enable_can" != "xno" ; then
AC_SUBST(CAN_SRC)
fi
+dnl check for hardware timestamp support
+case "$host_os" in
+linux*)
+ AC_CHECK_HEADERS([linux/net_tstamp.h])
+ ;;
+*)
+ AC_MSG_NOTICE(no hardware timestamp support implemented for $host_os)
+ ;;
+esac
+
AC_PROG_INSTALL
AC_CONFIG_HEADER(config.h)
AC_OUTPUT(Makefile pcap-filter.manmisc pcap-linktype.manmisc
- pcap-savefile.manfile pcap.3pcap pcap_compile.3pcap
- pcap_datalink.3pcap pcap_dump_open.3pcap
- pcap_list_datalinks.3pcap pcap_open_dead.3pcap
- pcap_open_offline.3pcap)
+ pcap-tstamp.manmisc pcap-savefile.manfile pcap.3pcap
+ pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap
+ pcap_list_datalinks.3pcap pcap_list_tstamp_types.3pcap
+ pcap_open_dead.3pcap pcap_open_offline.3pcap
+ pcap_set_tstamp_type.3pcap)
if test -f .devel ; then
make depend
diff --git a/ethertype.h b/ethertype.h
index d22b92778e22..2d6bbebddd5a 100644
--- a/ethertype.h
+++ b/ethertype.h
@@ -117,3 +117,6 @@
#ifndef ETHERTYPE_LOOPBACK
#define ETHERTYPE_LOOPBACK 0x9000
#endif
+#ifndef ETHERTYPE_8021QINQ
+#define ETHERTYPE_8021QINQ 0x9100
+#endif
diff --git a/fad-getad.c b/fad-getad.c
index 831ddae7aa8d..742ae1facb17 100644
--- a/fad-getad.c
+++ b/fad-getad.c
@@ -61,15 +61,21 @@ static const char rcsid[] _U_ =
#endif
#ifdef AF_PACKET
+# ifdef HAVE_NETPACKET_PACKET_H
+/* Solaris 11 and later, Linux distributions with newer glibc */
+# include <netpacket/packet.h>
+# else /* HAVE_NETPACKET_PACKET_H */
+/* LynxOS, Linux distributions with older glibc */
# ifdef __Lynx__
/* LynxOS */
# include <netpacket/if_packet.h>
-# else
+# else /* __Lynx__ */
/* Linux */
# include <linux/types.h>
# include <linux/if_packet.h>
-# endif
-#endif
+# endif /* __Lynx__ */
+# endif /* HAVE_NETPACKET_PACKET_H */
+#endif /* AF_PACKET */
/*
* This is fun.
diff --git a/gencode.c b/gencode.c
index 14f4b7509591..60458062152d 100644
--- a/gencode.c
+++ b/gencode.c
@@ -47,7 +47,7 @@ static const char rcsid[] _U_ =
* XXX - why was this included even on UNIX?
*/
#ifdef __MINGW32__
-#include "IP6_misc.h"
+#include "ip6_misc.h"
#endif
#ifndef WIN32
@@ -772,7 +772,8 @@ static int reg_off_ll;
* This is the offset of the beginning of the MAC-layer header from
* the beginning of the link-layer header.
* It's usually 0, except for ATM LANE, where it's the offset, relative
- * to the beginning of the raw packet data, of the Ethernet header.
+ * to the beginning of the raw packet data, of the Ethernet header, and
+ * for Ethernet with various additional information.
*/
static u_int off_mac;
@@ -1238,26 +1239,6 @@ init_linktype(p)
off_nl_nosnap = 0; /* no 802.2 LLC */
return;
- case DLT_LINUX_IRDA:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_DOCSIS:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
case DLT_SYMANTEC_FIREWALL:
off_linktype = 6;
off_macpl = 44;
@@ -1366,6 +1347,16 @@ init_linktype(p)
off_nl_nosnap = -1;
return;
+ case DLT_JUNIPER_VS:
+ case DLT_JUNIPER_SRX_E2E:
+ case DLT_JUNIPER_FIBRECHANNEL:
+ case DLT_JUNIPER_ATM_CEMIC:
+ off_linktype = 8;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
case DLT_MTP2:
off_li = 2;
off_sio = 3;
@@ -1411,126 +1402,6 @@ init_linktype(p)
return;
#endif
- case DLT_LINUX_LAPD:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_USB:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_BLUETOOTH_HCI_H4:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_USB_LINUX:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_CAN20B:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_IEEE802_15_4_LINUX:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_IEEE802_16_MAC_CPS_RADIO:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_IEEE802_15_4:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_SITA:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_RAIF1:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_IPMB:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
- case DLT_BLUETOOTH_HCI_H4_WITH_PHDR:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
-
case DLT_AX25_KISS:
/*
* Currently, only raw "link[N:M]" filtering is supported.
@@ -1542,52 +1413,43 @@ init_linktype(p)
off_mac = 1; /* step over the kiss length byte */
return;
- case DLT_IEEE802_15_4_NONASK_PHY:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
+ case DLT_IPNET:
+ off_linktype = 1;
+ off_macpl = 24; /* ipnet header length */
+ off_nl = 0;
off_nl_nosnap = -1;
return;
- case DLT_MPLS:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
+ case DLT_NETANALYZER:
+ off_mac = 4; /* MAC header is past 4-byte pseudo-header */
+ off_linktype = 16; /* includes 4-byte pseudo-header */
+ off_macpl = 18; /* pseudo-header+Ethernet header length */
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 3; /* 802.3+802.2 */
return;
- case DLT_USB_LINUX_MMAPPED:
- /*
- * Currently, only raw "link[N:M]" filtering is supported.
- */
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
+ case DLT_NETANALYZER_TRANSPARENT:
+ off_mac = 12; /* MAC header is past 4-byte pseudo-header, preamble, and SFD */
+ off_linktype = 24; /* includes 4-byte pseudo-header+preamble+SFD */
+ off_macpl = 26; /* pseudo-header+preamble+SFD+Ethernet header length */
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 3; /* 802.3+802.2 */
return;
- case DLT_CAN_SOCKETCAN:
+ default:
/*
- * Currently, only raw "link[N:M]" filtering is supported.
+ * For values in the range in which we've assigned new
+ * DLT_ values, only raw "link[N:M]" filtering is supported.
*/
- off_linktype = -1;
- off_macpl = -1;
- off_nl = -1;
- off_nl_nosnap = -1;
- return;
+ if (linktype >= DLT_MATCHING_MIN &&
+ linktype <= DLT_MATCHING_MAX) {
+ off_linktype = -1;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+ }
- case DLT_IPNET:
- off_linktype = 1;
- off_macpl = 24; /* ipnet header length */
- off_nl = 0;
- off_nl_nosnap = -1;
- return;
}
bpf_error("unknown data link type %d", linktype);
/* NOTREACHED */
@@ -3059,6 +2921,8 @@ gen_linktype(proto)
switch (linktype) {
case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
return gen_ether_linktype(proto);
/*NOTREACHED*/
break;
@@ -3462,6 +3326,11 @@ gen_linktype(proto)
case DLT_JUNIPER_VP:
case DLT_JUNIPER_ST:
case DLT_JUNIPER_ISM:
+ case DLT_JUNIPER_VS:
+ case DLT_JUNIPER_SRX_E2E:
+ case DLT_JUNIPER_FIBRECHANNEL:
+ case DLT_JUNIPER_ATM_CEMIC:
+
/* just lets verify the magic number for now -
* on ATM we may have up to 6 different encapsulations on the wire
* and need a lot of heuristics to figure out that the payload
@@ -3511,6 +3380,7 @@ gen_linktype(proto)
case DLT_IEEE802_15_4:
case DLT_IEEE802_15_4_LINUX:
case DLT_IEEE802_15_4_NONASK_PHY:
+ case DLT_IEEE802_15_4_NOFCS:
bpf_error("IEEE 802.15.4 link-layer type filtering not implemented");
case DLT_IEEE802_16_MAC_CPS_RADIO:
@@ -3785,6 +3655,30 @@ gen_ehostop(eaddr, dir)
b1 = gen_ehostop(eaddr, Q_DST);
gen_or(b0, b1);
return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11 with 802.11 headers");
+ break;
}
abort();
/* NOTREACHED */
@@ -3827,6 +3721,30 @@ gen_fhostop(eaddr, dir)
b1 = gen_fhostop(eaddr, Q_DST);
gen_or(b0, b1);
return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
}
abort();
/* NOTREACHED */
@@ -3861,6 +3779,30 @@ gen_thostop(eaddr, dir)
b1 = gen_thostop(eaddr, Q_DST);
gen_or(b0, b1);
return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
}
abort();
/* NOTREACHED */
@@ -4154,8 +4096,79 @@ gen_wlanhostop(eaddr, dir)
gen_and(b1, b0);
return b0;
+ case Q_RA:
+ /*
+ * Not present in management frames; addr1 in other
+ * frames.
+ */
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * Check addr1.
+ */
+ b0 = gen_bcmp(OR_LINK, 4, 6, eaddr);
+
+ /*
+ * AND that with the check of addr1.
+ */
+ gen_and(b1, b0);
+ return (b0);
+
+ case Q_TA:
+ /*
+ * Not present in management frames; addr2, if present,
+ * in other frames.
+ */
+
+ /*
+ * Not present in CTS or ACK control frames.
+ */
+ b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+ IEEE80211_FC0_TYPE_MASK);
+ gen_not(b0);
+ b1 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b1);
+ b2 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b2);
+ gen_and(b1, b2);
+ gen_or(b0, b2);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the check for frames other than
+ * CTS and ACK frames.
+ */
+ gen_and(b1, b2);
+
+ /*
+ * Check addr2.
+ */
+ b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
+ gen_and(b2, b1);
+ return b1;
+
/*
- * XXX - add RA, TA, and BSSID keywords?
+ * XXX - add BSSID keyword?
*/
case Q_ADDR1:
return (gen_bcmp(OR_LINK, 4, 6, eaddr));
@@ -4251,6 +4264,30 @@ gen_ipfchostop(eaddr, dir)
b1 = gen_ipfchostop(eaddr, Q_DST);
gen_or(b0, b1);
return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
}
abort();
/* NOTREACHED */
@@ -4444,6 +4481,9 @@ gen_host(addr, mask, proto, dir, type)
case Q_VRRP:
bpf_error("'vrrp' modifier applied to %s", typestr);
+ case Q_CARP:
+ bpf_error("'carp' modifier applied to %s", typestr);
+
case Q_ATALK:
bpf_error("ATALK host filtering not implemented");
@@ -4563,6 +4603,9 @@ gen_host6(addr, mask, proto, dir, type)
case Q_VRRP:
bpf_error("'vrrp' modifier applied to %s", typestr);
+ case Q_CARP:
+ bpf_error("'carp' modifier applied to %s", typestr);
+
case Q_ATALK:
bpf_error("ATALK host filtering not implemented");
@@ -4647,6 +4690,8 @@ gen_gateway(eaddr, alist, proto, dir)
case Q_RARP:
switch (linktype) {
case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
b0 = gen_ehostop(eaddr, Q_OR);
break;
case DLT_FDDI:
@@ -4776,6 +4821,14 @@ gen_proto_abbrev(proto)
b1 = gen_proto(IPPROTO_VRRP, Q_IP, Q_DEFAULT);
break;
+#ifndef IPPROTO_CARP
+#define IPPROTO_CARP 112
+#endif
+
+ case Q_CARP:
+ b1 = gen_proto(IPPROTO_CARP, Q_IP, Q_DEFAULT);
+ break;
+
case Q_IP:
b1 = gen_linktype(ETHERTYPE_IP);
break;
@@ -4957,7 +5010,7 @@ gen_ipfrag()
struct slist *s;
struct block *b;
- /* not ip frag */
+ /* not IPv4 frag other than the first frag */
s = gen_load_a(OR_NET, 6, BPF_H);
b = new_block(JMP(BPF_JSET));
b->s.k = 0x1fff;
@@ -5000,7 +5053,7 @@ gen_portop(port, proto, dir)
{
struct block *b0, *b1, *tmp;
- /* ip proto 'proto' */
+ /* ip proto 'proto' and not a fragment other than the first fragment */
tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto);
b0 = gen_ipfrag();
gen_and(tmp, b0);
@@ -5092,6 +5145,7 @@ gen_portop6(port, proto, dir)
struct block *b0, *b1, *tmp;
/* ip6 proto 'proto' */
+ /* XXX - catch the first fragment of a fragmented packet? */
b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto);
switch (dir) {
@@ -5193,7 +5247,7 @@ gen_portrangeop(port1, port2, proto, dir)
{
struct block *b0, *b1, *tmp;
- /* ip proto 'proto' */
+ /* ip proto 'proto' and not a fragment other than the first fragment */
tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto);
b0 = gen_ipfrag();
gen_and(tmp, b0);
@@ -5297,6 +5351,7 @@ gen_portrangeop6(port1, port2, proto, dir)
struct block *b0, *b1, *tmp;
/* ip6 proto 'proto' */
+ /* XXX - catch the first fragment of a fragmented packet? */
b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto);
switch (dir) {
@@ -5574,12 +5629,9 @@ gen_protochain(v, proto, dir)
/*
* in short,
- * A = P[X];
- * X = X + (P[X + 1] + 1) * 8;
+ * A = P[X + packet head];
+ * X = X + (P[X + packet head + 1] + 1) * 8;
*/
- /* A = X */
- s[i] = new_stmt(BPF_MISC|BPF_TXA);
- i++;
/* A = P[X + packet head] */
s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
s[i]->s.k = off_macpl + off_nl;
@@ -5588,19 +5640,9 @@ gen_protochain(v, proto, dir)
s[i] = new_stmt(BPF_ST);
s[i]->s.k = reg2;
i++;
- /* A = X */
- s[i] = new_stmt(BPF_MISC|BPF_TXA);
- i++;
- /* A += 1 */
- s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
- s[i]->s.k = 1;
- i++;
- /* X = A */
- s[i] = new_stmt(BPF_MISC|BPF_TAX);
- i++;
- /* A = P[X + packet head]; */
+ /* A = P[X + packet head + 1]; */
s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
- s[i]->s.k = off_macpl + off_nl;
+ s[i]->s.k = off_macpl + off_nl + 1;
i++;
/* A += 1 */
s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
@@ -5610,6 +5652,10 @@ gen_protochain(v, proto, dir)
s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
s[i]->s.k = 8;
i++;
+ /* A += X */
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_X);
+ s[i]->s.k = 0;
+ i++;
/* X = A; */
s[i] = new_stmt(BPF_MISC|BPF_TAX);
i++;
@@ -5933,6 +5979,10 @@ gen_proto(v, proto, dir)
bpf_error("'vrrp proto' is bogus");
/* NOTREACHED */
+ case Q_CARP:
+ bpf_error("'carp proto' is bogus");
+ /* NOTREACHED */
+
#ifdef INET6
case Q_IPV6:
b0 = gen_linktype(ETHERTYPE_IPV6);
@@ -6016,6 +6066,8 @@ gen_scode(name, q)
switch (linktype) {
case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
eaddr = pcap_ether_hostton(name);
if (eaddr == NULL)
bpf_error(
@@ -6197,6 +6249,10 @@ gen_scode(name, q)
/* override PROTO_UNDEF */
real_proto = IPPROTO_SCTP;
}
+ if (port < 0)
+ bpf_error("illegal port number %d < 0", port);
+ if (port > 65535)
+ bpf_error("illegal port number %d > 65535", port);
#ifndef INET6
return gen_port(port, real_proto, dir);
#else
@@ -6238,6 +6294,15 @@ gen_scode(name, q)
/* override PROTO_UNDEF */
real_proto = IPPROTO_SCTP;
}
+ if (port1 < 0)
+ bpf_error("illegal port number %d < 0", port1);
+ if (port1 > 65535)
+ bpf_error("illegal port number %d > 65535", port1);
+ if (port2 < 0)
+ bpf_error("illegal port number %d < 0", port2);
+ if (port2 > 65535)
+ bpf_error("illegal port number %d > 65535", port2);
+
#ifndef INET6
return gen_portrange(port1, port2, real_proto, dir);
#else
@@ -6389,6 +6454,9 @@ gen_ncode(s, v, q)
else
bpf_error("illegal qualifier of 'port'");
+ if (v > 65535)
+ bpf_error("illegal port number %u > 65535", v);
+
#ifndef INET6
return gen_port((int)v, proto, dir);
#else
@@ -6412,6 +6480,9 @@ gen_ncode(s, v, q)
else
bpf_error("illegal qualifier of 'portrange'");
+ if (v > 65535)
+ bpf_error("illegal port number %u > 65535", v);
+
#ifndef INET6
return gen_portrange((int)v, (int)v, proto, dir);
#else
@@ -6516,6 +6587,8 @@ gen_ecode(eaddr, q)
if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
switch (linktype) {
case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
return gen_ehostop(eaddr, (int)q.dir);
case DLT_FDDI:
return gen_fhostop(eaddr, (int)q.dir);
@@ -6645,7 +6718,7 @@ gen_load(proto, inst, size)
/*
* Load into the X register the offset computed into the
- * register specifed by "index".
+ * register specified by "index".
*/
s = xfer_to_x(inst);
@@ -6677,7 +6750,7 @@ gen_load(proto, inst, size)
* the link-layer header. Add to it the offset computed
* into the register specified by "index", and move that
* into the X register. Otherwise, just load into the X
- * register the offset computed into the register specifed
+ * register the offset computed into the register specified
* by "index".
*/
if (s != NULL) {
@@ -6726,7 +6799,7 @@ gen_load(proto, inst, size)
* payload. Add to it the offset computed into the
* register specified by "index", and move that into
* the X register. Otherwise, just load into the X
- * register the offset computed into the register specifed
+ * register the offset computed into the register specified
* by "index".
*/
if (s != NULL) {
@@ -6771,6 +6844,7 @@ gen_load(proto, inst, size)
case Q_IGRP:
case Q_PIM:
case Q_VRRP:
+ case Q_CARP:
/*
* The offset is relative to the beginning of
* the transport-layer header.
@@ -7119,6 +7193,8 @@ gen_broadcast(proto)
case DLT_ARCNET_LINUX:
return gen_ahostop(abroadcast, Q_DST);
case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
return gen_ehostop(ebroadcast, Q_DST);
case DLT_FDDI:
return gen_fhostop(ebroadcast, Q_DST);
@@ -7214,6 +7290,8 @@ gen_multicast(proto)
/* all ARCnet multicasts use the same address */
return gen_ahostop(abroadcast, Q_DST);
case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
/* ether[0] & 1 != 0 */
return gen_mac_multicast(0);
case DLT_FDDI:
@@ -7477,6 +7555,11 @@ gen_inbound(dir)
case DLT_JUNIPER_VP:
case DLT_JUNIPER_ST:
case DLT_JUNIPER_ISM:
+ case DLT_JUNIPER_VS:
+ case DLT_JUNIPER_SRX_E2E:
+ case DLT_JUNIPER_FIBRECHANNEL:
+ case DLT_JUNIPER_ATM_CEMIC:
+
/* juniper flags (including direction) are stored
* the byte after the 3-byte magic number */
if (dir) {
@@ -7757,6 +7840,30 @@ gen_ahostop(eaddr, dir)
b1 = gen_ahostop(eaddr, Q_DST);
gen_or(b0, b1);
return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
}
abort();
/* NOTREACHED */
@@ -7811,9 +7918,15 @@ gen_vlan(vlan_num)
switch (linktype) {
case DLT_EN10MB:
- /* check for VLAN */
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ /* check for VLAN, including QinQ */
b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
(bpf_int32)ETHERTYPE_8021Q);
+ b1 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)ETHERTYPE_8021QINQ);
+ gen_or(b0,b1);
+ b0 = b1;
/* If a specific VLAN is requested, check VLAN id */
if (vlan_num >= 0) {
@@ -7874,6 +7987,8 @@ gen_mpls(label_num)
case DLT_C_HDLC: /* fall through */
case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
b0 = gen_linktype(ETHERTYPE_MPLS);
break;
diff --git a/gencode.h b/gencode.h
index e2388b78c424..e8b0593da9a3 100644
--- a/gencode.h
+++ b/gencode.h
@@ -126,6 +126,8 @@
#define Q_RADIO 40
+#define Q_CARP 41
+
/* Directional qualifiers. */
#define Q_SRC 1
@@ -136,6 +138,8 @@
#define Q_ADDR2 6
#define Q_ADDR3 7
#define Q_ADDR4 8
+#define Q_RA 9
+#define Q_TA 10
#define Q_DEFAULT 0
#define Q_UNDEF 255
diff --git a/grammar.y b/grammar.y
index 4c52579ba3e4..f2ba28b1e5f7 100644
--- a/grammar.y
+++ b/grammar.y
@@ -272,12 +272,12 @@ pfaction_to_num(const char *action)
%token DST SRC HOST GATEWAY
%token NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
-%token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP
+%token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
%token ATALK AARP DECNET LAT SCA MOPRC MOPDL
%token TK_BROADCAST TK_MULTICAST
%token NUM INBOUND OUTBOUND
%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
-%token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4
+%token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
%token LINK
%token GEQ LEQ NEQ
%token ID EID HID HID6 AID
@@ -442,6 +442,8 @@ dqual: SRC { $$ = Q_SRC; }
| ADDR2 { $$ = Q_ADDR2; }
| ADDR3 { $$ = Q_ADDR3; }
| ADDR4 { $$ = Q_ADDR4; }
+ | RA { $$ = Q_RA; }
+ | TA { $$ = Q_TA; }
;
/* address type qualifiers */
aqual: HOST { $$ = Q_HOST; }
@@ -464,6 +466,7 @@ pname: LINK { $$ = Q_LINK; }
| IGRP { $$ = Q_IGRP; }
| PIM { $$ = Q_PIM; }
| VRRP { $$ = Q_VRRP; }
+ | CARP { $$ = Q_CARP; }
| ATALK { $$ = Q_ATALK; }
| AARP { $$ = Q_AARP; }
| DECNET { $$ = Q_DECNET; }
diff --git a/inet.c b/inet.c
index 0b16a659072d..6ae46ef87623 100644
--- a/inet.c
+++ b/inet.c
@@ -133,6 +133,7 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
pcap_t *p;
pcap_if_t *curdev, *prevdev, *nextdev;
int this_instance;
+ char open_errbuf[PCAP_ERRBUF_SIZE];
/*
* Is there already an entry in the list for this interface?
@@ -192,11 +193,11 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
}
strcpy(en_name, "en");
strcat(en_name, name + 3);
- p = pcap_open_live(en_name, 68, 0, 0, errbuf);
+ p = pcap_open_live(en_name, 68, 0, 0, open_errbuf);
free(en_name);
} else
#endif /* __APPLE */
- p = pcap_open_live(name, 68, 0, 0, errbuf);
+ p = pcap_open_live(name, 68, 0, 0, open_errbuf);
if (p == NULL) {
/*
* No. Don't bother including it.
@@ -431,26 +432,53 @@ add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s >= 0) {
+#ifdef __FreeBSD__
+ /*
+ * On FreeBSD, if the buffer isn't big enough for the
+ * description, the ioctl succeeds, but the description
+ * isn't copied, ifr_buffer.length is set to the description
+ * length, and ifr_buffer.buffer is set to NULL.
+ */
for (;;) {
free(description);
if ((description = malloc(descrlen)) != NULL) {
-#ifdef __FreeBSD__
ifrdesc.ifr_buffer.buffer = description;
ifrdesc.ifr_buffer.length = descrlen;
-#else /* __FreeBSD__ */
- ifrdesc.ifr_data = (caddr_t)description;
-#endif /* __FreeBSD__ */
- if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0)
- break;
-#ifdef __FreeBSD__
- else if (errno == ENAMETOOLONG)
- descrlen = ifrdesc.ifr_buffer.length;
-#endif /* __FreeBSD__ */
- else
+ if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
+ if (ifrdesc.ifr_buffer.buffer ==
+ description)
+ break;
+ else
+ descrlen = ifrdesc.ifr_buffer.length;
+ } else {
+ /*
+ * Failed to get interface description.
+ */
+ free(description);
+ description = NULL;
break;
+ }
} else
break;
}
+#else /* __FreeBSD__ */
+ /*
+ * The only other OS that currently supports
+ * SIOCGIFDESCR is OpenBSD, and it has no way
+ * to get the description length - it's clamped
+ * to a maximum of IFDESCRSIZE.
+ */
+ if ((description = malloc(descrlen)) != NULL) {
+ ifrdesc.ifr_data = (caddr_t)description;
+ if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
+ /*
+ * Failed to get interface description.
+ */
+ free(description);
+ description = NULL;
+ }
+ }
+#endif /* __FreeBSD__ */
close(s);
if (description != NULL && strlen(description) == 0) {
free(description);
@@ -850,8 +878,10 @@ pcap_lookupdev(errbuf)
*/
while(NAdapts--)
{
- strcpy((char*)tUstr, tAstr);
- (char*)tUstr += strlen(tAstr) + 1;;
+ char* tmp = (char*)tUstr;
+ strcpy(tmp, tAstr);
+ tmp += strlen(tAstr) + 1;
+ tUstr = (WCHAR*)tmp;
tAstr += strlen(tAstr) + 1;
}
diff --git a/packaging/pcap.spec.in b/packaging/pcap.spec.in
index 9e63dac296a4..4a7a82271ef2 100644
--- a/packaging/pcap.spec.in
+++ b/packaging/pcap.spec.in
@@ -1,58 +1,75 @@
%define prefix /usr
%define version @VERSION@
-Summary: packet capture library
+Summary: A system-independent interface for user-level packet capture
Name: libpcap
Version: %version
Release: 1
Group: Development/Libraries
-Copyright: BSD
+License: BSD with advertising
Source: @NAME@.tar.gz
BuildRoot: /tmp/%{name}-buildroot
URL: http://www.tcpdump.org
+Source: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz
+
%description
-Packet-capture library LIBPCAP @VERSION@
-Now maintained by "The Tcpdump Group"
-See http://www.tcpdump.org
-Please send inquiries/comments/reports to tcpdump-workers@lists.tcpdump.org
+Libpcap provides a portable framework for low-level network
+monitoring. Libpcap can provide network statistics collection,
+security monitoring and network debugging. Since almost every system
+vendor provides a different interface for packet capture, the libpcap
+authors created this system-independent API to ease in porting and to
+alleviate the need for several system-dependent packet capture modules
+in each application.
-%prep
-%setup
+Install libpcap if you need to do low-level network traffic monitoring
+on your network.
-%post
-ldconfig
+%package devel
+Summary: Libraries and header files for the libpcap library
+Group: Development/Libraries
+
+%description devel
+Libpcap provides a portable framework for low-level network
+monitoring. Libpcap can provide network statistics collection,
+security monitoring and network debugging. Since almost every system
+vendor provides a different interface for packet capture, the libpcap
+authors created this system-independent API to ease in porting and to
+alleviate the need for several system-dependent packet capture modules
+in each application.
+
+This package provides the libraries, include files, and other
+resources needed for developing libpcap applications.
+
+%prep
+%setup -q
%build
-CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix
-make
+export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
+%configure
+make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
-make install DESTDIR=$RPM_BUILD_ROOT mandir=/usr/share/man
-cd $RPM_BUILD_ROOT/usr/lib
-V1=`echo @VERSION@ | sed 's/\\.[^\.]*$//g'`
-V2=`echo @VERSION@ | sed 's/\\.[^\.]*\.[^\.]*$//g'`
-ln -sf libpcap.so.@VERSION@ libpcap.so.$V1
-if test "$V2" -ne "$V1"; then
- ln -sf libpcap.so.$V1 libpcap.so.$V2
- ln -sf libpcap.so.$V2 libpcap.so
-else
- ln -sf libpcap.so.$V1 libpcap.so
-fi
+
+make DESTDIR=$RPM_BUILD_ROOT install
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
-%doc LICENSE CHANGES INSTALL.txt README.linux TODO VERSION CREDITS packaging/pcap.spec
-/usr/lib/libpcap.a
-/usr/share/man/man3/*
-/usr/share/man/man5/*
-/usr/share/man/man7/*
-/usr/include/pcap.h
-/usr/include/pcap/*.h
-/usr/include/pcap-bpf.h
-/usr/include/pcap-namedb.h
-/usr/lib/libpcap.so*
+%doc LICENSE README CHANGES INSTALL.txt README.linux TODO VERSION CREDITS packaging/pcap.spec
+%{_libdir}/libpcap.so.*
+%{_mandir}/man7/pcap*.7*
+
+%files devel
+%defattr(-,root,root)
+%{_bindir}/pcap-config
+%{_includedir}/pcap*.h
+%{_includedir}/pcap.h
+%{_libdir}/libpcap.so
+%{_libdir}/libpcap.a
+%{_mandir}/man1/pcap-config.1*
+%{_mandir}/man3/pcap*.3*
+%{_mandir}/man5/pcap*.5*
diff --git a/pcap-bpf.c b/pcap-bpf.c
index b4482e9f1cc0..1d3c8cb4f0ec 100644
--- a/pcap-bpf.c
+++ b/pcap-bpf.c
@@ -31,8 +31,8 @@ static const char rcsid[] _U_ =
#ifdef HAVE_ZEROCOPY_BPF
#include <sys/mman.h>
#endif
-#include <sys/time.h>
#include <sys/socket.h>
+#include <time.h>
/*
* <net/bpf.h> defines ioctls, but doesn't include <sys/ioccom.h>.
*
@@ -186,77 +186,67 @@ static int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp);
static int pcap_setdirection_bpf(pcap_t *, pcap_direction_t);
static int pcap_set_datalink_bpf(pcap_t *p, int dlt);
-#ifdef HAVE_ZEROCOPY_BPF
/*
- * For zerocopy bpf, we need to override the setnonblock/getnonblock routines
- * so we don't call select(2) if the pcap handle is in non-blocking mode. We
- * preserve the timeout supplied by pcap_open functions to make sure it
- * does not get clobbered if the pcap handle moves between blocking and non-
- * blocking mode.
+ * For zerocopy bpf, the setnonblock/getnonblock routines need to modify
+ * p->md.timeout so we don't call select(2) if the pcap handle is in non-
+ * blocking mode. We preserve the timeout supplied by pcap_open functions
+ * to make sure it does not get clobbered if the pcap handle moves between
+ * blocking and non-blocking mode.
*/
static int
-pcap_getnonblock_zbuf(pcap_t *p, char *errbuf)
+pcap_getnonblock_bpf(pcap_t *p, char *errbuf)
{
- /*
- * Use a negative value for the timeout to represent that the
- * pcap handle is in non-blocking mode.
- */
- return (p->md.timeout < 0);
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.zerocopy) {
+ /*
+ * Use a negative value for the timeout to represent that the
+ * pcap handle is in non-blocking mode.
+ */
+ return (p->md.timeout < 0);
+ }
+#endif
+ return (pcap_getnonblock_fd(p, errbuf));
}
static int
-pcap_setnonblock_zbuf(pcap_t *p, int nonblock, char *errbuf)
+pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
{
- /*
- * Map each value to the corresponding 2's complement, to
- * preserve the timeout value provided with pcap_set_timeout.
- * (from pcap-linux.c).
- */
- if (nonblock) {
- if (p->md.timeout >= 0) {
- /*
- * Timeout is non-negative, so we're not already
- * in non-blocking mode; set it to the 2's
- * complement, to make it negative, as an
- * indication that we're in non-blocking mode.
- */
- p->md.timeout = p->md.timeout * -1 - 1;
- }
- } else {
- if (p->md.timeout < 0) {
- /*
- * Timeout is negative, so we're not already
- * in blocking mode; reverse the previous
- * operation, to make the timeout non-negative
- * again.
- */
- p->md.timeout = (p->md.timeout + 1) * -1;
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.zerocopy) {
+ /*
+ * Map each value to the corresponding 2's complement, to
+ * preserve the timeout value provided with pcap_set_timeout.
+ * (from pcap-linux.c).
+ */
+ if (nonblock) {
+ if (p->md.timeout >= 0) {
+ /*
+ * Timeout is non-negative, so we're not
+ * currently in non-blocking mode; set it
+ * to the 2's complement, to make it
+ * negative, as an indication that we're
+ * in non-blocking mode.
+ */
+ p->md.timeout = p->md.timeout * -1 - 1;
+ }
+ } else {
+ if (p->md.timeout < 0) {
+ /*
+ * Timeout is negative, so we're currently
+ * in blocking mode; reverse the previous
+ * operation, to make the timeout non-negative
+ * again.
+ */
+ p->md.timeout = (p->md.timeout + 1) * -1;
+ }
}
+ return (0);
}
- return (0);
-}
-
-/*
- * Zero-copy specific close method. Un-map the shared buffers then call
- * pcap_cleanup_live_common.
- */
-static void
-pcap_cleanup_zbuf(pcap_t *p)
-{
- /*
- * Delete the mappings. Note that p->buffer gets initialized to one
- * of the mmapped regions in this case, so do not try and free it
- * directly; null it out so that pcap_cleanup_live_common() doesn't
- * try to free it.
- */
- if (p->md.zbuf1 != MAP_FAILED && p->md.zbuf1 != NULL)
- (void) munmap(p->md.zbuf1, p->md.zbufsize);
- if (p->md.zbuf2 != MAP_FAILED && p->md.zbuf2 != NULL)
- (void) munmap(p->md.zbuf2, p->md.zbufsize);
- p->buffer = NULL;
- pcap_cleanup_live_common(p);
+#endif
+ return (pcap_setnonblock_fd(p, nonblock, errbuf));
}
+#ifdef HAVE_ZEROCOPY_BPF
/*
* Zero-copy BPF buffer routines to check for and acknowledge BPF data in
* shared memory buffers.
@@ -410,7 +400,7 @@ pcap_ack_zbuf(pcap_t *p)
p->buffer = NULL;
return (0);
}
-#endif
+#endif /* HAVE_ZEROCOPY_BPF */
pcap_t *
pcap_create(const char *device, char *ebuf)
@@ -435,6 +425,10 @@ pcap_create(const char *device, char *ebuf)
return (p);
}
+/*
+ * On success, returns a file descriptor for a BPF device.
+ * On failure, returns a PCAP_ERROR_ value, and sets p->errbuf.
+ */
static int
bpf_open(pcap_t *p)
{
@@ -495,12 +489,52 @@ bpf_open(pcap_t *p)
* XXX better message for all minors used
*/
if (fd < 0) {
- if (errno == EACCES)
+ switch (errno) {
+
+ case ENOENT:
+ fd = PCAP_ERROR;
+ if (n == 1) {
+ /*
+ * /dev/bpf0 doesn't exist, which
+ * means we probably have no BPF
+ * devices.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(there are no BPF devices)");
+ } else {
+ /*
+ * We got EBUSY on at least one
+ * BPF device, so we have BPF
+ * devices, but all the ones
+ * that exist are busy.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(all BPF devices are busy)");
+ }
+ break;
+
+ case EACCES:
+ /*
+ * Got EACCES on the last device we tried,
+ * and EBUSY on all devices before that,
+ * if any.
+ */
fd = PCAP_ERROR_PERM_DENIED;
- else
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(cannot open BPF device) %s: %s", device,
+ pcap_strerror(errno));
+ break;
+
+ default:
+ /*
+ * Some other problem.
+ */
fd = PCAP_ERROR;
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s",
- device, pcap_strerror(errno));
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(cannot open BPF device) %s: %s", device,
+ pcap_strerror(errno));
+ break;
+ }
}
#endif
@@ -673,14 +707,23 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
*/
fd = bpf_open(p);
if (fd < 0)
- return (fd);
+ return (fd); /* fd is the appropriate error code */
/*
* Now bind to the device.
*/
(void)strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
- if (errno == ENETDOWN) {
+ switch (errno) {
+
+ case ENXIO:
+ /*
+ * There's no such device.
+ */
+ close(fd);
+ return (PCAP_ERROR_NO_SUCH_DEVICE);
+
+ case ENETDOWN:
/*
* Return a "network down" indication, so that
* the application can report that rather than
@@ -690,7 +733,8 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
*/
close(fd);
return (PCAP_ERROR_IFACE_NOT_UP);
- } else {
+
+ default:
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"BIOCSETIF: %s: %s",
p->opt.source, pcap_strerror(errno));
@@ -911,14 +955,28 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
* processed so far.
*/
if (p->break_loop) {
+ p->bp = bp;
+ p->cc = ep - bp;
+ /*
+ * ep is set based on the return value of read(),
+ * but read() from a BPF device doesn't necessarily
+ * return a value that's a multiple of the alignment
+ * value for BPF_WORDALIGN(). However, whenever we
+ * increment bp, we round up the increment value by
+ * a value rounded up by BPF_WORDALIGN(), so we
+ * could increment bp past ep after processing the
+ * last packet in the buffer.
+ *
+ * We treat ep < bp as an indication that this
+ * happened, and just set p->cc to 0.
+ */
+ if (p->cc < 0)
+ p->cc = 0;
if (n == 0) {
p->break_loop = 0;
return (PCAP_ERROR_BREAK);
- } else {
- p->bp = bp;
- p->cc = ep - bp;
+ } else
return (n);
- }
}
caplen = bhp->bh_caplen;
@@ -970,6 +1028,11 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if (++n >= cnt && cnt > 0) {
p->bp = bp;
p->cc = ep - bp;
+ /*
+ * See comment above about p->cc < 0.
+ */
+ if (p->cc < 0)
+ p->cc = 0;
return (n);
}
} else {
@@ -1270,15 +1333,19 @@ pcap_cleanup_bpf(pcap_t *p)
}
#ifdef HAVE_ZEROCOPY_BPF
- /*
- * In zero-copy mode, p->buffer is just a pointer into one of the two
- * memory-mapped buffers, so no need to free it.
- */
if (p->md.zerocopy) {
+ /*
+ * Delete the mappings. Note that p->buffer gets
+ * initialized to one of the mmapped regions in
+ * this case, so do not try and free it directly;
+ * null it out so that pcap_cleanup_live_common()
+ * doesn't try to free it.
+ */
if (p->md.zbuf1 != MAP_FAILED && p->md.zbuf1 != NULL)
- munmap(p->md.zbuf1, p->md.zbufsize);
+ (void) munmap(p->md.zbuf1, p->md.zbufsize);
if (p->md.zbuf2 != MAP_FAILED && p->md.zbuf2 != NULL)
- munmap(p->md.zbuf2, p->md.zbufsize);
+ (void) munmap(p->md.zbuf2, p->md.zbufsize);
+ p->buffer = NULL;
}
#endif
if (p->md.device != NULL) {
@@ -1392,7 +1459,15 @@ pcap_activate_bpf(pcap_t *p)
{
int status = 0;
int fd;
+#ifdef LIFNAMSIZ
+ struct lifreq ifr;
+ char *ifrname = ifr.lifr_name;
+ const size_t ifnamsiz = sizeof(ifr.lifr_name);
+#else
struct ifreq ifr;
+ char *ifrname = ifr.ifr_name;
+ const size_t ifnamsiz = sizeof(ifr.ifr_name);
+#endif
struct bpf_version bv;
#ifdef __APPLE__
int sockfd;
@@ -1484,9 +1559,8 @@ pcap_activate_bpf(pcap_t *p)
*/
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd != -1) {
- strlcpy(ifr.ifr_name,
- p->opt.source,
- sizeof(ifr.ifr_name));
+ strlcpy(ifrname,
+ p->opt.source, ifnamsiz);
if (ioctl(sockfd, SIOCGIFFLAGS,
(char *)&ifr) < 0) {
/*
@@ -1552,14 +1626,6 @@ pcap_activate_bpf(pcap_t *p)
p->md.zerocopy = 1;
/*
- * Set the cleanup and set/get nonblocking mode ops
- * as appropriate for zero-copy mode.
- */
- p->cleanup_op = pcap_cleanup_zbuf;
- p->setnonblock_op = pcap_setnonblock_zbuf;
- p->getnonblock_op = pcap_getnonblock_zbuf;
-
- /*
* How to pick a buffer size: first, query the maximum buffer
* size supported by zero-copy. This also lets us quickly
* determine whether the kernel generally supports zero-copy.
@@ -1608,7 +1674,7 @@ pcap_activate_bpf(pcap_t *p)
pcap_strerror(errno));
goto bad;
}
- (void)strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
+ (void)strncpy(ifrname, p->opt.source, ifnamsiz);
if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
p->opt.source, pcap_strerror(errno));
@@ -1638,9 +1704,13 @@ pcap_activate_bpf(pcap_t *p)
/*
* Now bind to the device.
*/
- (void)strncpy(ifr.ifr_name, p->opt.source,
- sizeof(ifr.ifr_name));
- if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
+ (void)strncpy(ifrname, p->opt.source, ifnamsiz);
+#ifdef BIOCSETLIF
+ if (ioctl(fd, BIOCSETLIF, (caddr_t)&ifr) < 0)
+#else
+ if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0)
+#endif
+ {
status = check_setif_failure(p, errno);
goto bad;
}
@@ -1667,9 +1737,12 @@ pcap_activate_bpf(pcap_t *p)
*/
(void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
- (void)strncpy(ifr.ifr_name, p->opt.source,
- sizeof(ifr.ifr_name));
+ (void)strncpy(ifrname, p->opt.source, ifnamsiz);
+#ifdef BIOCSETLIF
+ if (ioctl(fd, BIOCSETLIF, (caddr_t)&ifr) >= 0)
+#else
if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
+#endif
break; /* that size worked; we're done */
if (errno != ENOBUFS) {
@@ -2160,8 +2233,8 @@ pcap_activate_bpf(pcap_t *p)
p->setfilter_op = pcap_setfilter_bpf;
p->setdirection_op = pcap_setdirection_bpf;
p->set_datalink_op = pcap_set_datalink_bpf;
- p->getnonblock_op = pcap_getnonblock_fd;
- p->setnonblock_op = pcap_setnonblock_fd;
+ p->getnonblock_op = pcap_getnonblock_bpf;
+ p->setnonblock_op = pcap_setnonblock_bpf;
p->stats_op = pcap_stats_bpf;
p->cleanup_op = pcap_cleanup_bpf;
@@ -2214,17 +2287,28 @@ monitor_mode(pcap_t *p, int set)
/*
* Can't get the media types.
*/
- if (errno == EINVAL) {
+ switch (errno) {
+
+ case ENXIO:
+ /*
+ * There's no such device.
+ */
+ close(sock);
+ return (PCAP_ERROR_NO_SUCH_DEVICE);
+
+ case EINVAL:
/*
* Interface doesn't support SIOC{G,S}IFMEDIA.
*/
close(sock);
return (PCAP_ERROR_RFMON_NOTSUP);
+
+ default:
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCGIFMEDIA 1: %s", pcap_strerror(errno));
+ close(sock);
+ return (PCAP_ERROR);
}
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMEDIA 1: %s",
- pcap_strerror(errno));
- close(sock);
- return (PCAP_ERROR);
}
if (req.ifm_count == 0) {
/*
diff --git a/pcap-bt-linux.c b/pcap-bt-linux.c
index a36c144d8a9f..0c6c08d199eb 100644
--- a/pcap-bt-linux.c
+++ b/pcap-bt-linux.c
@@ -67,7 +67,6 @@ static const char rcsid[] _U_ =
static int bt_activate(pcap_t *);
static int bt_read_linux(pcap_t *, int , pcap_handler , u_char *);
static int bt_inject_linux(pcap_t *, const void *, size_t);
-static int bt_setfilter_linux(pcap_t *, struct bpf_program *);
static int bt_setdirection_linux(pcap_t *, pcap_direction_t);
static int bt_stats_linux(pcap_t *, struct pcap_stat *);
@@ -86,8 +85,8 @@ bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
/* if bluetooth is not supported this this is not fatal*/
if (errno == EAFNOSUPPORT)
return 0;
- snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't open raw Bluetooth socket %d:%s",
- errno, strerror(errno));
+ snprintf(err_str, PCAP_ERRBUF_SIZE,
+ "Can't open raw Bluetooth socket: %s", strerror(errno));
return -1;
}
@@ -104,8 +103,9 @@ bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
if (ioctl(sock, HCIGETDEVLIST, (void *) dev_list) < 0)
{
- snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't get Bluetooth device list via ioctl %d:%s",
- errno, strerror(errno));
+ snprintf(err_str, PCAP_ERRBUF_SIZE,
+ "Can't get Bluetooth device list via ioctl: %s",
+ strerror(errno));
ret = -1;
goto free;
}
@@ -172,7 +172,7 @@ bt_activate(pcap_t* handle)
handle->read_op = bt_read_linux;
handle->inject_op = bt_inject_linux;
- handle->setfilter_op = bt_setfilter_linux;
+ handle->setfilter_op = install_bpf_program; /* no kernel filtering */
handle->setdirection_op = bt_setdirection_linux;
handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd;
@@ -183,8 +183,8 @@ bt_activate(pcap_t* handle)
/* Create HCI socket */
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (handle->fd < 0) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s",
- errno, strerror(errno));
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Can't create raw socket: %s", strerror(errno));
return PCAP_ERROR;
}
@@ -197,15 +197,15 @@ bt_activate(pcap_t* handle)
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't enable data direction info %d:%s",
- errno, strerror(errno));
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Can't enable data direction info: %s", strerror(errno));
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't enable time stamp %d:%s",
- errno, strerror(errno));
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Can't enable time stamp: %s", strerror(errno));
goto close_fail;
}
@@ -215,8 +215,8 @@ bt_activate(pcap_t* handle)
memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask));
memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask));
if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't set filter %d:%s",
- errno, strerror(errno));
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Can't set filter: %s", strerror(errno));
goto close_fail;
}
@@ -225,8 +225,9 @@ bt_activate(pcap_t* handle)
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = handle->md.ifindex;
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s",
- handle->md.ifindex, errno, strerror(errno));
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Can't attach to device %d: %s", handle->md.ifindex,
+ strerror(errno));
goto close_fail;
}
@@ -238,7 +239,7 @@ bt_activate(pcap_t* handle)
goto close_fail;
}
- if (handle->opt.buffer_size == 0) {
+ if (handle->opt.buffer_size != 0) {
/*
* Set the socket buffer size to the specified value.
*/
@@ -265,6 +266,7 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
struct cmsghdr *cmsg;
struct msghdr msg;
struct iovec iv;
+ ssize_t ret;
struct pcap_pkthdr pkth;
pcap_bluetooth_h4_header* bthdr;
@@ -280,31 +282,33 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
/* ignore interrupt system call error */
do {
- pkth.caplen = recvmsg(handle->fd, &msg, 0);
+ ret = recvmsg(handle->fd, &msg, 0);
if (handle->break_loop)
{
handle->break_loop = 0;
return -2;
}
- } while ((pkth.caplen == -1) && (errno == EINTR));
+ } while ((ret == -1) && (errno == EINTR));
-
- if (pkth.caplen < 0) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s",
- errno, strerror(errno));
+ if (ret < 0) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Can't receive packet: %s", strerror(errno));
return -1;
}
+ pkth.caplen = ret;
+
/* get direction and timestamp*/
cmsg = CMSG_FIRSTHDR(&msg);
int in=0;
while (cmsg) {
switch (cmsg->cmsg_type) {
case HCI_CMSG_DIR:
- in = *((int *) CMSG_DATA(cmsg));
+ memcpy(&in, CMSG_DATA(cmsg), sizeof in);
break;
case HCI_CMSG_TSTAMP:
- pkth.ts = *((struct timeval *) CMSG_DATA(cmsg));
+ memcpy(&pkth.ts, CMSG_DATA(cmsg),
+ sizeof pkth.ts);
break;
}
cmsg = CMSG_NXTHDR(&msg, cmsg);
@@ -316,8 +320,13 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
bthdr->direction = htonl(in != 0);
pkth.caplen+=sizeof(pcap_bluetooth_h4_header);
pkth.len = pkth.caplen;
- callback(user, &pkth, &handle->buffer[handle->offset]);
- return 1;
+ if (handle->fcode.bf_insns == NULL ||
+ bpf_filter(handle->fcode.bf_insns, &handle->buffer[handle->offset],
+ pkth.len, pkth.caplen)) {
+ callback(user, &pkth, &handle->buffer[handle->offset]);
+ return 1;
+ }
+ return 0; /* didn't pass filter */
}
static int
@@ -337,14 +346,14 @@ bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
struct hci_dev_stats * s = &dev_info.stat;
dev_info.dev_id = handle->md.ifindex;
- /* ingnore eintr */
+ /* ignore eintr */
do {
ret = ioctl(handle->fd, HCIGETDEVINFO, (void *)&dev_info);
} while ((ret == -1) && (errno == EINTR));
if (ret < 0) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "can get stats"
- " via ioctl %d:%s", errno, strerror(errno));
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Can't get stats via ioctl: %s", strerror(errno));
return (-1);
}
@@ -358,13 +367,6 @@ bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
}
static int
-bt_setfilter_linux(pcap_t *p, struct bpf_program *fp)
-{
- return 0;
-}
-
-
-static int
bt_setdirection_linux(pcap_t *p, pcap_direction_t d)
{
p->direction = d;
diff --git a/pcap-common.c b/pcap-common.c
index 979b5e364dac..f188eeb750ec 100644
--- a/pcap-common.c
+++ b/pcap-common.c
@@ -18,21 +18,9 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * savefile.c - supports offline use of tcpdump
- * Extraction/creation by Jeffrey Mogul, DECWRL
- * Modified by Steve McCanne, LBL.
- *
- * Used to save the received packet headers, after filtering, to
- * a file, and then read them later.
- * The first record in the file contains saved values for the machine
- * dependent values so we can print the dump file on any architecture.
+ * pcap-common.c - common code for pcap and pcap-ng files
*/
-#ifndef lint
-static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.183 2008-12-23 20:13:29 guy Exp $ (LBL)";
-#endif
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -106,6 +94,23 @@ static const char rcsid[] _U_ =
* file, and new values after that one might have been assigned. Also,
* do *NOT* use any values below 100 - those might already have been
* taken by one (or more!) organizations.
+ *
+ * Any platform that defines additional DLT_* codes should:
+ *
+ * request a LINKTYPE_* code and value from tcpdump.org,
+ * as per the above;
+ *
+ * add, in their version of libpcap, an entry to map
+ * those DLT_* codes to the corresponding LINKTYPE_*
+ * code;
+ *
+ * redefine, in their "net/bpf.h", any DLT_* values
+ * that collide with the values used by their additional
+ * DLT_* codes, to remove those collisions (but without
+ * making them collide with any of the LINKTYPE_*
+ * values equal to 50 or above; they should also avoid
+ * defining DLT_* values that collide with those
+ * LINKTYPE_* values, either).
*/
#define LINKTYPE_NULL DLT_NULL
#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */
@@ -114,7 +119,7 @@ static const char rcsid[] _U_ =
#define LINKTYPE_PRONET DLT_PRONET
#define LINKTYPE_CHAOS DLT_CHAOS
#define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */
-#define LINKTYPE_ARCNET DLT_ARCNET /* BSD-style headers */
+#define LINKTYPE_ARCNET_BSD DLT_ARCNET /* BSD-style headers */
#define LINKTYPE_SLIP DLT_SLIP
#define LINKTYPE_PPP DLT_PPP
#define LINKTYPE_FDDI DLT_FDDI
@@ -140,10 +145,29 @@ static const char rcsid[] _U_ =
#define LINKTYPE_SYMANTEC_FIREWALL 99 /* Symantec Enterprise Firewall */
+/*
+ * These correspond to DLT_s that have different values on different
+ * platforms; we map between these values in capture files and
+ * the DLT_ values as returned by pcap_datalink() and passed to
+ * pcap_open_dead().
+ */
#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */
#define LINKTYPE_RAW 101 /* raw IP */
#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */
#define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */
+
+/*
+ * Values starting with 104 are used for newly-assigned link-layer
+ * header type values; for those link-layer header types, the DLT_
+ * value returned by pcap_datalink() and passed to pcap_open_dead(),
+ * and the LINKTYPE_ value that appears in capture files, are the
+ * same.
+ *
+ * LINKTYPE_MATCHING_MIN is the lowest such value; LINKTYPE_MATCHING_MAX
+ * is the highest such value.
+ */
+#define LINKTYPE_MATCHING_MIN 104 /* lowest value in the "matching" range */
+
#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */
#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */
#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */
@@ -544,39 +568,39 @@ static const char rcsid[] _U_ =
* IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman
* <avn@pigeonpoint.com>.
*/
-#define LINKTYPE_IPMB_LINUX 209
+#define LINKTYPE_IPMB_LINUX 209
/*
* FlexRay automotive bus - http://www.flexray.com/ - as requested
* by Hannes Kaelber <hannes.kaelber@x2e.de>.
*/
-#define LINKTYPE_FLEXRAY 210
+#define LINKTYPE_FLEXRAY 210
/*
* Media Oriented Systems Transport (MOST) bus for multimedia
* transport - http://www.mostcooperation.com/ - as requested
* by Hannes Kaelber <hannes.kaelber@x2e.de>.
*/
-#define LINKTYPE_MOST 211
+#define LINKTYPE_MOST 211
/*
* Local Interconnect Network (LIN) bus for vehicle networks -
* http://www.lin-subbus.org/ - as requested by Hannes Kaelber
* <hannes.kaelber@x2e.de>.
*/
-#define LINKTYPE_LIN 212
+#define LINKTYPE_LIN 212
/*
* X2E-private data link type used for serial line capture,
* as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
*/
-#define LINKTYPE_X2E_SERIAL 213
+#define LINKTYPE_X2E_SERIAL 213
/*
* X2E-private data link type used for the Xoraya data logger
* family, as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
*/
-#define LINKTYPE_X2E_XORAYA 214
+#define LINKTYPE_X2E_XORAYA 214
/*
* IEEE 802.15.4, exactly as it appears in the spec (no padding, no
@@ -595,22 +619,22 @@ static const char rcsid[] _U_ =
* is used to communicate keystrokes and mouse movements from the
* Linux kernel to display systems, such as Xorg.
*/
-#define LINKTYPE_LINUX_EVDEV 216
+#define LINKTYPE_LINUX_EVDEV 216
/*
* GSM Um and Abis interfaces, preceded by a "gsmtap" header.
*
* Requested by Harald Welte <laforge@gnumonks.org>.
*/
-#define LINKTYPE_GSMTAP_UM 217
-#define LINKTYPE_GSMTAP_ABIS 218
+#define LINKTYPE_GSMTAP_UM 217
+#define LINKTYPE_GSMTAP_ABIS 218
/*
* MPLS, with an MPLS label as the link-layer header.
* Requested by Michele Marchetto <michele@openbsd.org> on behalf
* of OpenBSD.
*/
-#define LINKTYPE_MPLS 219
+#define LINKTYPE_MPLS 219
/*
* USB packets, beginning with a Linux USB header, with the USB header
@@ -622,7 +646,7 @@ static const char rcsid[] _U_ =
* DECT packets, with a pseudo-header; requested by
* Matthias Wenzel <tcpdump@mazzoo.de>.
*/
-#define LINKTYPE_DECT 221
+#define LINKTYPE_DECT 221
/*
* From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" <eric.lidwa-1@nasa.gov>
@@ -633,7 +657,7 @@ static const char rcsid[] _U_ =
* legal before I can submit a patch.
*
*/
-#define LINKTYPE_AOS 222
+#define LINKTYPE_AOS 222
/*
* Wireless HART (Highway Addressable Remote Transducer)
@@ -642,13 +666,13 @@ static const char rcsid[] _U_ =
*
* Requested by Sam Roberts <vieuxtech@gmail.com>.
*/
-#define LINKTYPE_WIHART 223
+#define LINKTYPE_WIHART 223
/*
* Fibre Channel FC-2 frames, beginning with a Frame_Header.
* Requested by Kahou Lei <kahou82@gmail.com>.
*/
-#define LINKTYPE_FC_2 224
+#define LINKTYPE_FC_2 224
/*
* Fibre Channel FC-2 frames, beginning with an encoding of the
@@ -710,7 +734,7 @@ static const char rcsid[] _U_ =
* An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates
* which of those it is.
*/
-#define LINKTYPE_IPNET 226
+#define LINKTYPE_IPNET 226
/*
* CAN (Controller Area Network) frames, with a pseudo-header as supplied
@@ -719,15 +743,114 @@ static const char rcsid[] _U_ =
*
* Requested by Felix Obenhuber <felix@obenhuber.de>.
*/
-#define LINKTYPE_CAN_SOCKETCAN 227
+#define LINKTYPE_CAN_SOCKETCAN 227
/*
* Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies
* whether it's v4 or v6. Requested by Darren Reed <Darren.Reed@Sun.COM>.
*/
-#define LINKTYPE_IPV4 228
-#define LINKTYPE_IPV6 229
+#define LINKTYPE_IPV4 228
+#define LINKTYPE_IPV6 229
+
+/*
+ * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
+ * nothing), and with no FCS at the end of the frame; requested by
+ * Jon Smirl <jonsmirl@gmail.com>.
+ */
+#define LINKTYPE_IEEE802_15_4_NOFCS 230
+
+/*
+ * Raw D-Bus:
+ *
+ * http://www.freedesktop.org/wiki/Software/dbus
+ *
+ * messages:
+ *
+ * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
+ *
+ * starting with the endianness flag, followed by the message type, etc.,
+ * but without the authentication handshake before the message sequence:
+ *
+ * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
+ *
+ * Requested by Martin Vidner <martin@vidner.net>.
+ */
+#define LINKTYPE_DBUS 231
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ */
+#define LINKTYPE_JUNIPER_VS 232
+#define LINKTYPE_JUNIPER_SRX_E2E 233
+#define LINKTYPE_JUNIPER_FIBRECHANNEL 234
+
+/*
+ * DVB-CI (DVB Common Interface for communication between a PC Card
+ * module and a DVB receiver). See
+ *
+ * http://www.kaiser.cx/pcap-dvbci.html
+ *
+ * for the specification.
+ *
+ * Requested by Martin Kaiser <martin@kaiser.cx>.
+ */
+#define LINKTYPE_DVB_CI 235
+
+/*
+ * Variant of 3GPP TS 27.010 multiplexing protocol. Requested
+ * by Hans-Christoph Schemmel <hans-christoph.schemmel@cinterion.com>.
+ */
+#define LINKTYPE_MUX27010 236
+
+/*
+ * STANAG 5066 D_PDUs. Requested by M. Baris Demiray
+ * <barisdemiray@gmail.com>.
+ */
+#define LINKTYPE_STANAG_5066_D_PDU 237
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ */
+#define LINKTYPE_JUNIPER_ATM_CEMIC 238
+
+/*
+ * NetFilter LOG messages
+ * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets)
+ *
+ * Requested by Jakub Zawadzki <darkjames-ws@darkjames.pl>
+ */
+#define LINKTYPE_NFLOG 239
+/*
+ * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type
+ * for Ethernet packets with a 4-byte pseudo-header and always
+ * with the payload including the FCS, as supplied by their
+ * netANALYZER hardware and software.
+ *
+ * Requested by Holger P. Frommer <HPfrommer@hilscher.com>
+ */
+#define LINKTYPE_NETANALYZER 240
+
+/*
+ * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type
+ * for Ethernet packets with a 4-byte pseudo-header and FCS and
+ * 1 byte of SFD, as supplied by their netANALYZER hardware and
+ * software.
+ *
+ * Requested by Holger P. Frommer <HPfrommer@hilscher.com>
+ */
+#define LINKTYPE_NETANALYZER_TRANSPARENT 241
+
+/*
+ * IP-over-Infiniband, as specified by RFC 4391.
+ *
+ * Requested by Petr Sumbera <petr.sumbera@oracle.com>.
+ */
+#define LINKTYPE_IPOIB 242
+
+#define LINKTYPE_MATCHING_MAX 242 /* highest value in the "matching" range */
static struct linktype_map {
int dlt;
@@ -744,7 +867,7 @@ static struct linktype_map {
{ DLT_PRONET, LINKTYPE_PRONET },
{ DLT_CHAOS, LINKTYPE_CHAOS },
{ DLT_IEEE802, LINKTYPE_TOKEN_RING },
- { DLT_ARCNET, LINKTYPE_ARCNET },
+ { DLT_ARCNET, LINKTYPE_ARCNET_BSD },
{ DLT_SLIP, LINKTYPE_SLIP },
{ DLT_PPP, LINKTYPE_PPP },
{ DLT_FDDI, LINKTYPE_FDDI },
@@ -785,295 +908,12 @@ static struct linktype_map {
/* NetBSD PPP over Ethernet */
{ DLT_PPP_ETHER, LINKTYPE_PPP_ETHER },
- /* IEEE 802.11 wireless */
- { DLT_IEEE802_11, LINKTYPE_IEEE802_11 },
-
- /* Frame Relay */
- { DLT_FRELAY, LINKTYPE_FRELAY },
-
- /* OpenBSD loopback */
- { DLT_LOOP, LINKTYPE_LOOP },
-
- /* OpenBSD IPSEC enc */
- { DLT_ENC, LINKTYPE_ENC },
-
- /* Linux cooked socket capture */
- { DLT_LINUX_SLL, LINKTYPE_LINUX_SLL },
-
- /* Apple LocalTalk hardware */
- { DLT_LTALK, LINKTYPE_LTALK },
-
- /* Acorn Econet */
- { DLT_ECONET, LINKTYPE_ECONET },
-
- /* OpenBSD DLT_PFLOG */
- { DLT_PFLOG, LINKTYPE_PFLOG },
-
- /* For Cisco-internal use */
- { DLT_CISCO_IOS, LINKTYPE_CISCO_IOS },
-
- /* Prism II monitor-mode header plus 802.11 header */
- { DLT_PRISM_HEADER, LINKTYPE_PRISM_HEADER },
-
- /* FreeBSD Aironet driver stuff */
- { DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER },
-
- /* Siemens HiPath HDLC */
- { DLT_HHDLC, LINKTYPE_HHDLC },
-
- /* RFC 2625 IP-over-Fibre Channel */
- { DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC },
-
- /* Solaris+SunATM */
- { DLT_SUNATM, LINKTYPE_SUNATM },
-
- /* RapidIO */
- { DLT_RIO, LINKTYPE_RIO },
-
- /* PCI Express */
- { DLT_PCI_EXP, LINKTYPE_PCI_EXP },
-
- /* Xilinx Aurora link layer */
- { DLT_AURORA, LINKTYPE_AURORA },
-
- /* 802.11 plus BSD radio header */
- { DLT_IEEE802_11_RADIO, LINKTYPE_IEEE802_11_RADIO },
-
- /* Tazmen Sniffer Protocol */
- { DLT_TZSP, LINKTYPE_TZSP },
-
- /* Arcnet with Linux-style link-layer headers */
- { DLT_ARCNET_LINUX, LINKTYPE_ARCNET_LINUX },
-
- /* Juniper-internal chassis encapsulation */
- { DLT_JUNIPER_MLPPP, LINKTYPE_JUNIPER_MLPPP },
- { DLT_JUNIPER_MLFR, LINKTYPE_JUNIPER_MLFR },
- { DLT_JUNIPER_ES, LINKTYPE_JUNIPER_ES },
- { DLT_JUNIPER_GGSN, LINKTYPE_JUNIPER_GGSN },
- { DLT_JUNIPER_MFR, LINKTYPE_JUNIPER_MFR },
- { DLT_JUNIPER_ATM2, LINKTYPE_JUNIPER_ATM2 },
- { DLT_JUNIPER_SERVICES, LINKTYPE_JUNIPER_SERVICES },
- { DLT_JUNIPER_ATM1, LINKTYPE_JUNIPER_ATM1 },
-
- /* Apple IP-over-IEEE 1394 cooked header */
- { DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 },
-
- /* SS7 */
- { DLT_MTP2_WITH_PHDR, LINKTYPE_MTP2_WITH_PHDR },
- { DLT_MTP2, LINKTYPE_MTP2 },
- { DLT_MTP3, LINKTYPE_MTP3 },
- { DLT_SCCP, LINKTYPE_SCCP },
-
- /* DOCSIS MAC frames */
- { DLT_DOCSIS, LINKTYPE_DOCSIS },
-
- /* IrDA IrLAP packets + Linux-cooked header */
- { DLT_LINUX_IRDA, LINKTYPE_LINUX_IRDA },
-
- /* IBM SP and Next Federation switches */
- { DLT_IBM_SP, LINKTYPE_IBM_SP },
- { DLT_IBM_SN, LINKTYPE_IBM_SN },
-
- /* 802.11 plus AVS radio header */
- { DLT_IEEE802_11_RADIO_AVS, LINKTYPE_IEEE802_11_RADIO_AVS },
-
/*
- * Any platform that defines additional DLT_* codes should:
- *
- * request a LINKTYPE_* code and value from tcpdump.org,
- * as per the above;
- *
- * add, in their version of libpcap, an entry to map
- * those DLT_* codes to the corresponding LINKTYPE_*
- * code;
- *
- * redefine, in their "net/bpf.h", any DLT_* values
- * that collide with the values used by their additional
- * DLT_* codes, to remove those collisions (but without
- * making them collide with any of the LINKTYPE_*
- * values equal to 50 or above; they should also avoid
- * defining DLT_* values that collide with those
- * LINKTYPE_* values, either).
+ * All LINKTYPE_ values between LINKTYPE_MATCHING_MIN
+ * and LINKTYPE_MATCHING_MAX are mapped to identical
+ * DLT_ values.
*/
- /* Juniper-internal chassis encapsulation */
- { DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR },
-
- /* BACnet MS/TP */
- { DLT_BACNET_MS_TP, LINKTYPE_BACNET_MS_TP },
-
- /* PPP for pppd, with direction flag in the PPP header */
- { DLT_PPP_PPPD, LINKTYPE_PPP_PPPD},
-
- /* Juniper-internal chassis encapsulation */
- { DLT_JUNIPER_PPPOE, LINKTYPE_JUNIPER_PPPOE },
- { DLT_JUNIPER_PPPOE_ATM,LINKTYPE_JUNIPER_PPPOE_ATM },
-
- /* GPRS LLC */
- { DLT_GPRS_LLC, LINKTYPE_GPRS_LLC },
-
- /* Transparent Generic Framing Procedure (ITU-T G.7041/Y.1303) */
- { DLT_GPF_T, LINKTYPE_GPF_T },
-
- /* Framed Generic Framing Procedure (ITU-T G.7041/Y.1303) */
- { DLT_GPF_F, LINKTYPE_GPF_F },
-
- { DLT_GCOM_T1E1, LINKTYPE_GCOM_T1E1 },
- { DLT_GCOM_SERIAL, LINKTYPE_GCOM_SERIAL },
-
- /* Juniper-internal chassis encapsulation */
- { DLT_JUNIPER_PIC_PEER, LINKTYPE_JUNIPER_PIC_PEER },
-
- /* Endace types */
- { DLT_ERF_ETH, LINKTYPE_ERF_ETH },
- { DLT_ERF_POS, LINKTYPE_ERF_POS },
-
- /* viSDN LAPD */
- { DLT_LINUX_LAPD, LINKTYPE_LINUX_LAPD },
-
- /* Juniper meta-information before Ether, PPP, Frame Relay, C-HDLC Frames */
- { DLT_JUNIPER_ETHER, LINKTYPE_JUNIPER_ETHER },
- { DLT_JUNIPER_PPP, LINKTYPE_JUNIPER_PPP },
- { DLT_JUNIPER_FRELAY, LINKTYPE_JUNIPER_FRELAY },
- { DLT_JUNIPER_CHDLC, LINKTYPE_JUNIPER_CHDLC },
-
- /* Multi Link Frame Relay (FRF.16) */
- { DLT_MFR, LINKTYPE_MFR },
-
- /* Juniper Voice PIC */
- { DLT_JUNIPER_VP, LINKTYPE_JUNIPER_VP },
-
- /* Controller Area Network (CAN) v2.0B */
- { DLT_A429, LINKTYPE_A429 },
-
- /* Arinc 653 Interpartition Communication messages */
- { DLT_A653_ICM, LINKTYPE_A653_ICM },
-
- /* USB */
- { DLT_USB, LINKTYPE_USB },
-
- /* Bluetooth HCI UART transport layer */
- { DLT_BLUETOOTH_HCI_H4, LINKTYPE_BLUETOOTH_HCI_H4 },
-
- /* IEEE 802.16 MAC Common Part Sublayer */
- { DLT_IEEE802_16_MAC_CPS, LINKTYPE_IEEE802_16_MAC_CPS },
-
- /* USB with Linux header */
- { DLT_USB_LINUX, LINKTYPE_USB_LINUX },
-
- /* Controller Area Network (CAN) v2.0B */
- { DLT_CAN20B, LINKTYPE_CAN20B },
-
- /* IEEE 802.15.4 with address fields padded */
- { DLT_IEEE802_15_4_LINUX, LINKTYPE_IEEE802_15_4_LINUX },
-
- /* Per Packet Information encapsulated packets */
- { DLT_PPI, LINKTYPE_PPI },
-
- /* IEEE 802.16 MAC Common Part Sublayer plus radiotap header */
- { DLT_IEEE802_16_MAC_CPS_RADIO, LINKTYPE_IEEE802_16_MAC_CPS_RADIO },
-
- /* Juniper Voice ISM */
- { DLT_JUNIPER_ISM, LINKTYPE_JUNIPER_ISM },
-
- /* IEEE 802.15.4 exactly as it appears in the spec */
- { DLT_IEEE802_15_4, LINKTYPE_IEEE802_15_4 },
-
- /* Various link-layer types for SITA */
- { DLT_SITA, LINKTYPE_SITA },
-
- /* Various link-layer types for Endace */
- { DLT_ERF, LINKTYPE_ERF },
-
- /* Special header for u10 Networks boards */
- { DLT_RAIF1, LINKTYPE_RAIF1 },
-
- /* IPMB */
- { DLT_IPMB, LINKTYPE_IPMB },
-
- /* Juniper Secure Tunnel */
- { DLT_JUNIPER_ST, LINKTYPE_JUNIPER_ST },
-
- /* Bluetooth HCI UART transport layer, with pseudo-header */
- { DLT_BLUETOOTH_HCI_H4_WITH_PHDR, LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR },
-
- /* AX.25 with KISS header */
- { DLT_AX25_KISS, LINKTYPE_AX25_KISS },
-
- /* Raw LAPD, with no pseudo-header */
- { DLT_LAPD, LINKTYPE_LAPD },
-
- /* PPP with one-byte pseudo-header giving direction */
- { DLT_PPP_WITH_DIR, LINKTYPE_PPP_WITH_DIR },
-
- /* Cisco HDLC with one-byte pseudo-header giving direction */
- { DLT_C_HDLC_WITH_DIR, LINKTYPE_C_HDLC_WITH_DIR },
-
- /* Frame Relay with one-byte pseudo-header giving direction */
- { DLT_FRELAY_WITH_DIR, LINKTYPE_FRELAY_WITH_DIR },
-
- /* LAPB with one-byte pseudo-header giving direction */
- { DLT_LAPB_WITH_DIR, LINKTYPE_LAPB_WITH_DIR },
-
- /* IPMB with Linux pseudo-header */
- { DLT_IPMB_LINUX, LINKTYPE_IPMB_LINUX },
-
- /* FlexRay */
- { DLT_FLEXRAY, LINKTYPE_FLEXRAY },
-
- /* MOST */
- { DLT_MOST, LINKTYPE_MOST },
-
- /* LIN */
- { DLT_LIN, LINKTYPE_LIN },
-
- /* X2E-private serial line capture */
- { DLT_X2E_SERIAL, LINKTYPE_X2E_SERIAL },
-
- /* X2E-private for Xoraya data logger family */
- { DLT_X2E_XORAYA, LINKTYPE_X2E_XORAYA },
-
- /* IEEE 802.15.4 with PHY data for non-ASK PHYs */
- { DLT_IEEE802_15_4_NONASK_PHY, LINKTYPE_IEEE802_15_4_NONASK_PHY },
-
- /* Input device events from Linux /dev/input/eventN devices */
- { DLT_LINUX_EVDEV, LINKTYPE_LINUX_EVDEV },
-
- /* GSM types */
- { DLT_GSMTAP_UM, LINKTYPE_GSMTAP_UM },
- { DLT_GSMTAP_ABIS, LINKTYPE_GSMTAP_ABIS },
-
- /* MPLS, with an MPLS label as the link-layer header */
- { DLT_MPLS, LINKTYPE_MPLS },
-
- /* USB with padded Linux header */
- { DLT_USB_LINUX_MMAPPED, LINKTYPE_USB_LINUX_MMAPPED },
-
- /* DECT packets with a pseudo-header */
- { DLT_DECT, LINKTYPE_DECT },
-
- /* AOS Space Data Link Protocol */
- { DLT_AOS, LINKTYPE_AOS },
-
- /* Wireless HART */
- { DLT_WIHART, LINKTYPE_WIHART },
-
- /* Fibre Channel FC-2 frames without SOF or EOF */
- { DLT_FC_2, LINKTYPE_FC_2 },
-
- /* Fibre Channel FC-2 frames with SOF and EOF */
- { DLT_FC_2_WITH_FRAME_DELIMS, LINKTYPE_FC_2_WITH_FRAME_DELIMS },
-
- /* Solaris IPNET */
- { DLT_IPNET, LINKTYPE_IPNET },
-
- /* CAN frames with SocketCAN headers */
- { DLT_CAN_SOCKETCAN, LINKTYPE_CAN_SOCKETCAN },
-
- /* Raw IPv4/IPv6 */
- { DLT_IPV4, LINKTYPE_IPV4 },
- { DLT_IPV6, LINKTYPE_IPV6 },
-
{ -1, -1 }
};
@@ -1082,6 +922,15 @@ dlt_to_linktype(int dlt)
{
int i;
+ /*
+ * Map the values in the matching range.
+ */
+ if (dlt >= DLT_MATCHING_MIN && dlt <= DLT_MATCHING_MAX)
+ return (dlt);
+
+ /*
+ * Map the values outside that range.
+ */
for (i = 0; map[i].dlt != -1; i++) {
if (map[i].dlt == dlt)
return (map[i].linktype);
@@ -1089,8 +938,8 @@ dlt_to_linktype(int dlt)
/*
* If we don't have a mapping for this DLT_ code, return an
- * error; that means that the table above needs to have an
- * entry added.
+ * error; that means that this is a value with no corresponding
+ * LINKTYPE_ code, and we need to assign one.
*/
return (-1);
}
@@ -1100,6 +949,16 @@ linktype_to_dlt(int linktype)
{
int i;
+ /*
+ * Map the values in the matching range.
+ */
+ if (linktype >= LINKTYPE_MATCHING_MIN &&
+ linktype <= LINKTYPE_MATCHING_MAX)
+ return (linktype);
+
+ /*
+ * Map the values outside that range.
+ */
for (i = 0; map[i].linktype != -1; i++) {
if (map[i].linktype == linktype)
return (map[i].dlt);
@@ -1127,33 +986,72 @@ 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;
+ usb_isodesc *pisodesc;
+ int32_t numdesc, i;
+
+ /*
+ * "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???
*/
- if (hdr->caplen < 8)
+ offset += 8; /* skip past id */
+ if (hdr->caplen < offset)
return;
uhdr->id = SWAPLL(uhdr->id);
- if (hdr->caplen < 14)
+
+ 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);
- if (hdr->caplen < 24)
+
+ 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);
- if (hdr->caplen < 28)
+
+ offset += 4; /* skip past ts_usec */
+ if (hdr->caplen < offset)
return;
uhdr->ts_usec = SWAPLONG(uhdr->ts_usec);
- if (hdr->caplen < 32)
+
+ offset += 4; /* skip past status */
+ if (hdr->caplen < offset)
return;
uhdr->status = SWAPLONG(uhdr->status);
- if (hdr->caplen < 36)
+
+ offset += 4; /* skip past urb_len */
+ if (hdr->caplen < offset)
return;
uhdr->urb_len = SWAPLONG(uhdr->urb_len);
- if (hdr->caplen < 40)
+
+ 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 */
+
if (header_len_64_bytes) {
/*
* This is either the "version 1" header, with
@@ -1163,17 +1061,50 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
* at the end. Byte swap them as if this were
* a "version 1" header.
*/
- if (hdr->caplen < 52)
+ offset += 4; /* skip past interval */
+ if (hdr->caplen < offset)
return;
uhdr->interval = SWAPLONG(uhdr->interval);
- if (hdr->caplen < 56)
+
+ offset += 4; /* skip past start_frame */
+ if (hdr->caplen < offset)
return;
uhdr->start_frame = SWAPLONG(uhdr->start_frame);
- if (hdr->caplen < 60)
+
+ offset += 4; /* skip past xfer_flags */
+ if (hdr->caplen < offset)
return;
uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags);
- if (hdr->caplen < 64)
+
+ 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 */
+ pisodesc = (usb_isodesc *)(void *)(buf+offset);
+ numdesc = uhdr->s.iso.numdesc;
+ for (i = 0; i < numdesc; 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++;
+ }
+ }
}
diff --git a/pcap-config.in b/pcap-config.in
index 37526d7fed60..206be3b4a644 100644
--- a/pcap-config.in
+++ b/pcap-config.in
@@ -4,6 +4,13 @@
# Script to give the appropriate compiler flags and linker flags
# to use when building code that uses libpcap.
#
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+includedir="@includedir@"
+libdir="@libdir@"
+V_RPATH_OPT="@V_RPATH_OPT@"
+LIBS="@LIBS@"
+
static=0
show_cflags=0
show_libs=0
@@ -29,14 +36,14 @@ do
esac
shift
done
-if [ "@V_RPATH_OPT@" != "" ]
+if [ "$V_RPATH_OPT" != "" ]
then
#
# If libdir isn't /usr/lib, add it to the run-time linker path.
#
- if [ "@libdir@" != "/usr/lib" ]
+ if [ "$libdir" != "/usr/lib" ]
then
- RPATH=@V_RPATH_OPT@@libdir@
+ RPATH=$V_RPATH_OPT$libdir
fi
fi
if [ "$static" = 1 ]
@@ -47,19 +54,19 @@ then
#
if [ "$show_cflags" = 1 -a "$show_libs" = 1 ]
then
- echo "-I@includedir@ -L@libdir@ -lpcap @LIBS@"
+ echo "-I$includedir -L$libdir -lpcap $LIBS"
elif [ "$show_cflags" = 1 -a "$show_additional_libs" = 1 ]
then
- echo "-I@includedir@ -L@libdir@ @LIBS@"
+ echo "-I$includedir -L$libdir $LIBS"
elif [ "$show_cflags" = 1 ]
then
- echo "-I@includedir@"
+ echo "-I$includedir"
elif [ "$show_libs" = 1 ]
then
- echo "-L@libdir@ -lpcap @LIBS@"
+ echo "-L$libdir -lpcap $LIBS"
elif [ "$show_additional_libs" = 1 ]
then
- echo "@LIBS@"
+ echo "$LIBS"
fi
else
#
@@ -68,15 +75,15 @@ else
#
if [ "$show_cflags" = 1 -a "$show_libs" = 1 ]
then
- echo "-I@includedir@ -L@libdir@ $RPATH -lpcap"
+ echo "-I$includedir -L$libdir $RPATH -lpcap"
elif [ "$show_cflags" = 1 -a "$show_additional_libs" = 1 ]
then
- echo "-I@includedir@"
+ echo "-I$includedir"
elif [ "$show_cflags" = 1 ]
then
- echo "-I@includedir@"
+ echo "-I$includedir"
elif [ "$show_libs" = 1 ]
then
- echo "-L@libdir@ $RPATH -lpcap"
+ echo "-L$libdir $RPATH -lpcap"
fi
fi
diff --git a/pcap-dag.c b/pcap-dag.c
index 938ec26dce45..b5de0691b95a 100644
--- a/pcap-dag.c
+++ b/pcap-dag.c
@@ -879,8 +879,8 @@ dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
int dagstream;
int dagfd;
- /* Try all the DAGs 0-9 */
- for (c = 0; c < 9; c++) {
+ /* Try all the DAGs 0-31 */
+ for (c = 0; c < 32; c++) {
snprintf(name, 12, "dag%d", c);
if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
{
@@ -897,7 +897,7 @@ dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
{
int stream, rxstreams;
rxstreams = dag_rx_get_stream_count(dagfd);
- for(stream=0;stream<16;stream+=2) {
+ for(stream=0;stream<DAG_STREAM_MAX;stream+=2) {
if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
dag_detach_stream(dagfd, stream);
@@ -908,6 +908,11 @@ dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
*/
ret = -1;
}
+
+ rxstreams--;
+ if(rxstreams <= 0) {
+ break;
+ }
}
}
}
diff --git a/pcap-dlpi.c b/pcap-dlpi.c
index 8f938fe16874..78bb45118330 100644
--- a/pcap-dlpi.c
+++ b/pcap-dlpi.c
@@ -143,10 +143,9 @@ static int dl_doattach(int, int, char *);
#ifdef DL_HP_RAWDLS
static int dl_dohpuxbind(int, char *);
#endif
-static int dlattachreq(int, bpf_u_int32, char *);
+static int dlpromiscon(pcap_t *, bpf_u_int32);
static int dlbindreq(int, bpf_u_int32, char *);
static int dlbindack(int, char *, char *, int *);
-static int dlpromisconreq(int, bpf_u_int32, char *);
static int dlokack(int, const char *, char *, char *);
static int dlinforeq(int, char *);
static int dlinfoack(int, char *, char *);
@@ -450,7 +449,7 @@ pcap_activate_dlpi(pcap_t *p)
/* Try device without unit number */
if ((p->fd = open(dname, O_RDWR)) < 0) {
if (errno != ENOENT) {
- if (errno == EACCES)
+ if (errno == EPERM || errno == EACCES)
status = PCAP_ERROR_PERM_DENIED;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
pcap_strerror(errno));
@@ -486,7 +485,7 @@ pcap_activate_dlpi(pcap_t *p)
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: No DLPI device found", p->opt.source);
} else {
- if (errno == EACCES)
+ if (errno == EPERM || errno == EACCES)
status = PCAP_ERROR_PERM_DENIED;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
dname2, pcap_strerror(errno));
@@ -610,9 +609,12 @@ pcap_activate_dlpi(pcap_t *p)
/*
** Enable promiscuous (not necessary on send FD)
*/
- if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, p->errbuf) < 0 ||
- dlokack(p->fd, "promisc_phys", (char *)buf, p->errbuf) < 0)
+ status = dlpromiscon(p, DL_PROMISC_PHYS);
+ if (status < 0) {
+ if (status == PCAP_ERROR_PERM_DENIED)
+ status = PCAP_ERROR_PROMISC_PERM_DENIED;
goto bad;
+ }
/*
** Try to enable multicast (you would have thought
@@ -620,8 +622,8 @@ pcap_activate_dlpi(pcap_t *p)
** HP-UX or SINIX) (Not necessary on send FD)
*/
#if !defined(__hpux) && !defined(sinix)
- if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, p->errbuf) < 0 ||
- dlokack(p->fd, "promisc_multi", (char *)buf, p->errbuf) < 0)
+ status = dlpromiscon(p, DL_PROMISC_MULTI);
+ if (status < 0)
status = PCAP_WARNING;
#endif
}
@@ -631,20 +633,27 @@ pcap_activate_dlpi(pcap_t *p)
** under SINIX) (Not necessary on send FD)
*/
#ifndef sinix
- if (
-#ifdef __hpux
- !p->opt.promisc &&
-#endif
-#ifdef HAVE_SOLARIS
- !isatm &&
+#if defined(__hpux)
+ /* HP-UX - only do this when not in promiscuous mode */
+ if (!p->opt.promisc) {
+#elif defined(HAVE_SOLARIS)
+ /* Solaris - don't do this on SunATM devices */
+ if (!isatm) {
+#else
+ /* Everything else (except for SINIX) - always do this */
+ {
#endif
- (dlpromisconreq(p->fd, DL_PROMISC_SAP, p->errbuf) < 0 ||
- dlokack(p->fd, "promisc_sap", (char *)buf, p->errbuf) < 0)) {
- /* Not fatal if promisc since the DL_PROMISC_PHYS worked */
- if (p->opt.promisc)
- status = PCAP_WARNING;
- else
- goto bad;
+ status = dlpromiscon(p, DL_PROMISC_SAP);
+ if (status < 0) {
+ /*
+ * Not fatal, since the DL_PROMISC_PHYS mode worked.
+ * Report it as a warning, however.
+ */
+ if (p->opt.promisc)
+ status = PCAP_WARNING;
+ else
+ goto bad;
+ }
}
#endif /* sinix */
@@ -815,11 +824,15 @@ split_dname(char *device, int *unitp, char *ebuf)
static int
dl_doattach(int fd, int ppa, char *ebuf)
{
+ dl_attach_req_t req;
bpf_u_int32 buf[MAXDLBUF];
int err;
- if (dlattachreq(fd, ppa, ebuf) < 0)
+ req.dl_primitive = DL_ATTACH_REQ;
+ req.dl_ppa = ppa;
+ if (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf) < 0)
return (PCAP_ERROR);
+
err = dlokack(fd, "attach", (char *)buf, ebuf);
if (err < 0)
return (err);
@@ -877,6 +890,27 @@ dl_dohpuxbind(int fd, char *ebuf)
}
#endif
+#define STRINGIFY(n) #n
+
+static int
+dlpromiscon(pcap_t *p, bpf_u_int32 level)
+{
+ dl_promiscon_req_t req;
+ bpf_u_int32 buf[MAXDLBUF];
+ int err;
+
+ req.dl_primitive = DL_PROMISCON_REQ;
+ req.dl_level = level;
+ if (send_request(p->fd, (char *)&req, sizeof(req), "promiscon",
+ p->errbuf) < 0)
+ return (PCAP_ERROR);
+ err = dlokack(p->fd, "promiscon" STRINGIFY(level), (char *)buf,
+ p->errbuf);
+ if (err < 0)
+ return (err);
+ return (0);
+}
+
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
@@ -986,7 +1020,8 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: UNIX error - %s",
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
- if (dlp->error_ack.dl_unix_errno == EACCES)
+ if (dlp->error_ack.dl_unix_errno == EPERM ||
+ dlp->error_ack.dl_unix_errno == EACCES)
return (PCAP_ERROR_PERM_DENIED);
break;
@@ -1222,17 +1257,6 @@ dlprim(bpf_u_int32 prim)
}
static int
-dlattachreq(int fd, bpf_u_int32 ppa, char *ebuf)
-{
- dl_attach_req_t req;
-
- req.dl_primitive = DL_ATTACH_REQ;
- req.dl_ppa = ppa;
-
- return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf));
-}
-
-static int
dlbindreq(int fd, bpf_u_int32 sap, char *ebuf)
{
@@ -1260,17 +1284,6 @@ dlbindack(int fd, char *bufp, char *ebuf, int *uerror)
}
static int
-dlpromisconreq(int fd, bpf_u_int32 level, char *ebuf)
-{
- dl_promiscon_req_t req;
-
- req.dl_primitive = DL_PROMISCON_REQ;
- req.dl_level = level;
-
- return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf));
-}
-
-static int
dlokack(int fd, const char *what, char *bufp, char *ebuf)
{
diff --git a/pcap-filter.manmisc.in b/pcap-filter.manmisc.in
index 6b826e3cc495..d7b4b0a5f0f3 100644
--- a/pcap-filter.manmisc.in
+++ b/pcap-filter.manmisc.in
@@ -65,6 +65,8 @@ Possible directions are
.BR dst ,
.BR "src or dst" ,
.BR "src and dst" ,
+.BR ra ,
+.BR ta ,
.BR addr1 ,
.BR addr2 ,
.BR addr3 ,
@@ -76,6 +78,8 @@ there is no dir qualifier,
.B "src or dst"
is assumed.
The
+.BR ra ,
+.BR ta ,
.BR addr1 ,
.BR addr2 ,
.BR addr3 ,
@@ -472,6 +476,15 @@ and
.B scrub
(applies only to packets logged by OpenBSD's or FreeBSD's
.BR pf (4)).
+.IP "\fBwlan ra \fIehost\fR"
+True if the IEEE 802.11 RA is
+.IR ehost .
+The RA field is used in all frames except for management frames.
+.IP "\fBwlan ta \fIehost\fR"
+True if the IEEE 802.11 TA is
+.IR ehost .
+The TA field is used in all frames except for management frames and
+CTS (Clear To Send) and ACK (Acknowledgment) control frames.
.IP "\fBwlan addr1 \fIehost\fR"
True if the first IEEE 802.11 address is
.IR ehost .
@@ -490,7 +503,7 @@ True if the fourth IEEE 802.11 address, if present, is
.IR ehost .
The fourth address field is only used for
WDS (Wireless Distribution System) frames.
-.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fInetbeui\fP"
+.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP"
Abbreviations for:
.in +.5i
.nf
diff --git a/pcap-int.h b/pcap-int.h
index c3afbade52b3..8444e62cee84 100644
--- a/pcap-int.h
+++ b/pcap-int.h
@@ -209,6 +209,7 @@ struct pcap_opt {
char *source;
int promisc;
int rfmon;
+ int tstamp_type;
};
/*
@@ -331,6 +332,8 @@ struct pcap {
char errbuf[PCAP_ERRBUF_SIZE + 1];
int dlt_count;
u_int *dlt_list;
+ int tstamp_type_count;
+ u_int *tstamp_type_list;
struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
};
diff --git a/pcap-libdlpi.c b/pcap-libdlpi.c
index 87cd08b7d929..8d6a0386e012 100644
--- a/pcap-libdlpi.c
+++ b/pcap-libdlpi.c
@@ -49,6 +49,7 @@ static const char rcsid[] _U_ =
#include "dlpisubs.h"
/* Forwards. */
+static int dlpromiscon(pcap_t *, bpf_u_int32);
static int pcap_read_libdlpi(pcap_t *, int, pcap_handler, u_char *);
static int pcap_inject_libdlpi(pcap_t *, const void *, size_t);
static void pcap_close_libdlpi(pcap_t *);
@@ -114,7 +115,8 @@ pcap_activate_libdlpi(pcap_t *p)
if (retv != DLPI_SUCCESS) {
if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
err = PCAP_ERROR_NO_SUCH_DEVICE;
- else if (retv == DL_SYSERR && errno == EACCES)
+ else if (retv == DL_SYSERR &&
+ (errno == EPERM || errno == EACCES))
err = PCAP_ERROR_PERM_DENIED;
pcap_libdlpi_err(p->opt.source, "dlpi_open", retv,
p->errbuf);
@@ -139,34 +141,43 @@ pcap_activate_libdlpi(pcap_t *p)
/* Enable promiscuous mode. */
if (p->opt.promisc) {
- retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_PHYS);
- if (retv != DLPI_SUCCESS) {
- pcap_libdlpi_err(p->opt.source,
- "dlpi_promisc(PHYSICAL)", retv, p->errbuf);
+ err = dlpromiscon(p, DL_PROMISC_PHYS);
+ if (err < 0) {
+ /*
+ * "You don't have permission to capture on
+ * this device" and "you don't have permission
+ * to capture in promiscuous mode on this
+ * device" are different; let the user know,
+ * so if they can't get permission to
+ * capture in promiscuous mode, they can at
+ * least try to capture in non-promiscuous
+ * mode.
+ *
+ * XXX - you might have to capture in
+ * promiscuous mode to see outgoing packets.
+ */
+ if (err == PCAP_ERROR_PERM_DENIED)
+ err = PCAP_ERROR_PROMISC_PERM_DENIED;
goto bad;
}
} else {
/* Try to enable multicast. */
- retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_MULTI);
- if (retv != DLPI_SUCCESS) {
- pcap_libdlpi_err(p->opt.source, "dlpi_promisc(MULTI)",
- retv, p->errbuf);
+ err = dlpromiscon(p, DL_PROMISC_MULTI);
+ if (err < 0)
goto bad;
- }
}
/* Try to enable SAP promiscuity. */
- retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_SAP);
- if (retv != DLPI_SUCCESS) {
- if (p->opt.promisc) {
- pcap_libdlpi_err(p->opt.source, "dlpi_promisc(SAP)",
- retv, p->errbuf);
+ err = dlpromiscon(p, DL_PROMISC_SAP);
+ if (err < 0) {
+ /*
+ * Not fatal, since the DL_PROMISC_PHYS mode worked.
+ * Report it as a warning, however.
+ */
+ if (p->opt.promisc)
+ err = PCAP_WARNING;
+ else
goto bad;
- }
-
- /* Not fatal, since the DL_PROMISC_PHYS mode worked. */
- fprintf(stderr, "WARNING: dlpi_promisc(SAP) failed on"
- " %s:(%s)\n", p->opt.source, dlpi_strerror(retv));
}
/* Determine link type. */
@@ -219,6 +230,27 @@ bad:
return (err);
}
+#define STRINGIFY(n) #n
+
+static int
+dlpromiscon(pcap_t *p, bpf_u_int32 level)
+{
+ int err;
+
+ retv = dlpi_promiscon(p->hd, level);
+ if (retv != DLPI_SUCCESS) {
+ if (retv == DL_SYSERR &&
+ (errno == EPERM || errno == EACCES))
+ err = PCAP_ERROR_PERM_DENIED;
+ else
+ err = PCAP_ERROR;
+ pcap_libdlpi_err(p->opt.source, "dlpi_promiscon" STRINGIFY(level),
+ retv, p->errbuf);
+ return (err);
+ }
+ return (0);
+}
+
/*
* In Solaris, the "standard" mechanism" i.e SIOCGLIFCONF will only find
* network links that are plumbed and are up. dlpi_walk(3DLPI) will find
diff --git a/pcap-linktype.manmisc.in b/pcap-linktype.manmisc.in
index fa156120ff4d..890438728a39 100644
--- a/pcap-linktype.manmisc.in
+++ b/pcap-linktype.manmisc.in
@@ -44,241 +44,7 @@ by
The names for those values begin with
.BR LINKTYPE_ .
.PP
-The link-layer header types supported by libpcap are listed here. The
-value corresponding to
-.B LINKTYPE_
-names are given; the value corresponding to
-.B DLT_
-values are, in some cases, platform dependent, and are not given;
-applications should check for particular
-.B DLT_
-values by name.
-.RS 5
-.TP 5
-.BR DLT_NULL "; " LINKTYPE_NULL = 0
-BSD loopback encapsulation; the link-layer header is a 4-byte field, in
-.I host
-byte order, containing a PF_ value from
-.B socket.h
-for the network-layer protocol of the packet.
-.IP
-Note that ``host byte order'' is the byte order of the machine on which
-the packets are captured, and the PF_ values are for the OS of the
-machine on which the packets are captured; if a live capture is being
-done, ``host byte order'' is the byte order of the machine capturing the
-packets, and the PF_ values are those of the OS of the machine capturing
-the packets, but if a ``savefile'' is being read, the byte order and PF_
-values are
-.I not
-necessarily those of the machine reading the capture file.
-.TP 5
-.BR DLT_EN10MB "; " LINKTYPE_ETHERNET = 1
-Ethernet (10Mb, 100Mb, 1000Mb, and up); the
-.B 10MB
-in the
-.B DLT_
-name is historical.
-.TP 5
-.BR DLT_IEEE802 "; " LINKTYPE_TOKEN_RING = 6
-IEEE 802.5 Token Ring; the
-.B IEEE802
-in the
-.B DLT_
-name is historical.
-.TP 5
-.BR DLT_ARCNET "; " LINKTYPE_ARCNET = 7
-ARCNET
-.TP 5
-.BR DLT_SLIP "; " LINKTYPE_SLIP = 8
-SLIP; the link-layer header contains, in order:
-.RS 10
-.LP
-a 1-byte flag, which is 0 for packets received by the machine and 1 for
-packets sent by the machine;
-.LP
-a 1-byte field, the upper 4 bits of which indicate the type of packet,
-as per RFC 1144:
-.RS 5
-.TP 5
-0x40
-an unmodified IP datagram (TYPE_IP);
-.TP 5
-0x70
-an uncompressed-TCP IP datagram (UNCOMPRESSED_TCP), with that byte being
-the first byte of the raw IP header on the wire, containing the
-connection number in the protocol field;
-.TP 5
-0x80
-a compressed-TCP IP datagram (COMPRESSED_TCP), with that byte being the
-first byte of the compressed TCP/IP datagram header;
-.RE
-.LP
-for UNCOMPRESSED_TCP, the rest of the modified IP header, and for
-COMPRESSED_TCP, the compressed TCP/IP datagram header;
-.RE
-.RS 5
-.LP
-for a total of 16 bytes; the uncompressed IP datagram follows the header.
-.RE
-.TP 5
-.BR DLT_PPP "; " LINKTYPE_PPP = 9
-PPP; if the first 2 bytes are 0xff and 0x03, it's PPP in HDLC-like
-framing, with the PPP header following those two bytes, otherwise it's
-PPP without framing, and the packet begins with the PPP header.
-.TP 5
-.BR DLT_FDDI "; " LINKTYPE_FDDI = 10
-FDDI
-.TP 5
-.BR DLT_ATM_RFC1483 "; " LINKTYPE_ATM_RFC1483 = 100
-RFC 1483 LLC/SNAP-encapsulated ATM; the packet begins with an IEEE 802.2
-LLC header.
-.TP 5
-.BR DLT_RAW "; " LINKTYPE_RAW = 101
-raw IP; the packet begins with an IP header.
-.TP 5
-.BR DLT_PPP_SERIAL "; " LINKTYPE_PPP_HDLC = 50
-PPP in HDLC-like framing, as per RFC 1662, or Cisco PPP with HDLC
-framing, as per section 4.3.1 of RFC 1547; the first byte will be 0xFF
-for PPP in HDLC-like framing, and will be 0x0F or 0x8F for Cisco PPP
-with HDLC framing.
-.TP 5
-.BR DLT_PPP_ETHER "; " LINKTYPE_PPP_ETHER = 51
-PPPoE; the packet begins with a PPPoE header, as per RFC 2516.
-.TP 5
-.BR DLT_C_HDLC "; " LINKTYPE_C_HDLC = 104
-Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547.
-.TP 5
-.BR DLT_IEEE802_11 "; " LINKTYPE_IEEE802_11 = 105
-IEEE 802.11 wireless LAN
-.TP 5
-.BR DLT_FRELAY "; " LINKTYPE_FRELAY = 107
-Frame Relay
-.TP 5
-.BR DLT_LOOP "; " LINKTYPE_LOOP = 108
-OpenBSD loopback encapsulation; the link-layer header is a 4-byte field, in
-.I network
-byte order, containing a PF_ value from OpenBSD's
-.B socket.h
-for the network-layer protocol of the packet.
-.IP
-Note that, if a ``savefile'' is being read, those PF_ values are
-.I not
-necessarily those of the machine reading the capture file.
-.TP 5
-.BR DLT_LINUX_SLL "; " LINKTYPE_LINUX_SLL = 113
-Linux "cooked" capture encapsulation; the link-layer header contains, in
-order:
-.RS 10
-.LP
-a 2-byte "packet type", in network byte order, which is one of:
-.RS 5
-.TP 5
-0
-packet was sent to us by somebody else
-.TP 5
-1
-packet was broadcast by somebody else
-.TP 5
-2
-packet was multicast, but not broadcast, by somebody else
-.TP 5
-3
-packet was sent by somebody else to somebody else
-.TP 5
-4
-packet was sent by us
-.RE
-.LP
-a 2-byte field, in network byte order, containing a Linux ARPHRD_ value
-for the link-layer device type;
-.LP
-a 2-byte field, in network byte order, containing the length of the
-link-layer address of the sender of the packet (which could be 0);
-.LP
-an 8-byte field containing that number of bytes of the link-layer
-address of the sender (if there are more than 8 bytes, only the first
-8 are present, and if there are fewer than 8 bytes, there are padding
-bytes after the address to pad the field to 8 bytes);
-.LP
-a 2-byte field containing an Ethernet protocol type, in network byte
-order, or containing 1 for Novell 802.3 frames without an 802.2 LLC
-header or 4 for frames beginning with an 802.2 LLC header.
-.RE
-.TP 5
-.BR DLT_LTALK "; " LINKTYPE_LTALK = 104
-Apple LocalTalk; the packet begins with an AppleTalk LLAP header.
-.TP 5
-.BR DLT_PFLOG "; " LINKTYPE_PFLOG = 117
-OpenBSD pflog; the link-layer header contains a
-.B "struct pfloghdr"
-structure, as defined by the host on which the file was saved. (This
-differs from operating system to operating system and release to
-release; there is nothing in the file to indicate what the layout of
-that structure is.)
-.TP 5
-.BR DLT_PRISM_HEADER "; " LINKTYPE_PRISM_HEADER = 119
-Prism monitor mode information followed by an 802.11 header.
-.TP 5
-.BR DLT_IP_OVER_FC "; " LINKTYPE_IP_OVER_FC = 122
-RFC 2625 IP-over-Fibre Channel, with the link-layer header being the
-Network_Header as described in that RFC.
-.TP 5
-.BR DLT_SUNATM "; " LINKTYPE_SUNATM = 123
-SunATM devices; the link-layer header contains, in order:
-.RS 10
-.LP
-a 1-byte flag field, containing a direction flag in the uppermost bit,
-which is set for packets transmitted by the machine and clear for
-packets received by the machine, and a 4-byte traffic type in the
-low-order 4 bits, which is one of:
-.RS 5
-.TP 5
-0
-raw traffic
-.TP 5
-1
-LANE traffic
-.TP 5
-2
-LLC-encapsulated traffic
-.TP 5
-3
-MARS traffic
-.TP 5
-4
-IFMP traffic
-.TP 5
-5
-ILMI traffic
-.TP 5
-6
-Q.2931 traffic
-.RE
-.LP
-a 1-byte VPI value;
-.LP
-a 2-byte VCI field, in network byte order.
-.RE
-.TP 5
-.BR DLT_IEEE802_11_RADIO "; " LINKTYPE_IEEE802_11_RADIO = 127
-link-layer information followed by an 802.11 header - see
-http://www.shaftnet.org/~pizza/software/capturefrm.txt for a description
-of the link-layer information.
-.TP 5
-.BR DLT_ARCNET_LINUX "; " LINKTYPE_ARCNET_LINUX = 129
-ARCNET, with no exception frames, reassembled packets rather than raw
-frames, and an extra 16-bit offset field between the destination host
-and type bytes.
-.TP 5
-.BR DLT_LINUX_IRDA "; " LINKTYPE_LINUX_IRDA = 144
-Linux-IrDA packets, with a
-.B DLT_LINUX_SLL
-header followed by the IrLAP header.
-.TP 5
-.BR DLT_LINUX_LAPD "; " LINKTYPE_LINUX_LAPD = 177
-LAPD (Q.921) frames, with a
-.B DLT_LINUX_SLL
-header captured via vISDN.
-.RE
+The link-layer header types supported by libpcap are described at
+http://www.tcpdump.org/linktypes.html.
.SH SEE ALSO
pcap_datalink(3PCAP)
diff --git a/pcap-linux.c b/pcap-linux.c
index af125433f074..d4f50b7d16e3 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -138,26 +138,6 @@ static const char rcsid[] _U_ =
#include <poll.h>
#include <dirent.h>
-/*
- * Got Wireless Extensions?
- */
-#ifdef HAVE_LINUX_WIRELESS_H
-#include <linux/wireless.h>
-#endif /* HAVE_LINUX_WIRELESS_H */
-
-/*
- * Got libnl?
- */
-#ifdef HAVE_LIBNL
-#include <linux/nl80211.h>
-
-#include <netlink/genl/genl.h>
-#include <netlink/genl/family.h>
-#include <netlink/genl/ctrl.h>
-#include <netlink/msg.h>
-#include <netlink/attr.h>
-#endif /* HAVE_LIBNL */
-
#include "pcap-int.h"
#include "pcap/sll.h"
#include "pcap/vlan.h"
@@ -186,6 +166,10 @@ static const char rcsid[] _U_ =
#include "pcap-can-linux.h"
#endif
+#ifdef PCAP_SUPPORT_NETFILTER
+#include "pcap-netfilter-linux.h"
+#endif
+
/*
* If PF_PACKET is defined, we can use {SOCK_RAW,SOCK_DGRAM}/PF_PACKET
* sockets rather than SOCK_PACKET sockets.
@@ -250,6 +234,46 @@ static const char rcsid[] _U_ =
#include <linux/filter.h>
#endif
+/*
+ * We need linux/sockios.h if we have linux/net_tstamp.h (for time stamp
+ * specification) or linux/ethtool.h (for ethtool ioctls to get offloading
+ * information).
+ */
+#if defined(HAVE_LINUX_NET_TSTAMP_H) || defined(HAVE_LINUX_ETHTOOL_H)
+#include <linux/sockios.h>
+#endif
+
+#ifdef HAVE_LINUX_NET_TSTAMP_H
+#include <linux/net_tstamp.h>
+#endif
+
+/*
+ * Got Wireless Extensions?
+ */
+#ifdef HAVE_LINUX_WIRELESS_H
+#include <linux/wireless.h>
+#endif /* HAVE_LINUX_WIRELESS_H */
+
+/*
+ * Got libnl?
+ */
+#ifdef HAVE_LIBNL
+#include <linux/nl80211.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+#endif /* HAVE_LIBNL */
+
+/*
+ * Got ethtool support?
+ */
+#ifdef HAVE_LINUX_ETHTOOL_H
+#include <linux/ethtool.h>
+#endif
+
#ifndef HAVE_SOCKLEN_T
typedef int socklen_t;
#endif
@@ -295,7 +319,7 @@ static short int map_packet_type_to_sll_type(short int);
static int pcap_activate_linux(pcap_t *);
static int activate_old(pcap_t *);
static int activate_new(pcap_t *);
-static int activate_mmap(pcap_t *);
+static int activate_mmap(pcap_t *, int *);
static int pcap_can_set_rfmon_linux(pcap_t *);
static int pcap_read_linux(pcap_t *, int, pcap_handler, u_char *);
static int pcap_read_packet(pcap_t *, pcap_handler, u_char *);
@@ -315,7 +339,7 @@ union thdr {
#define RING_GET_FRAME(h) (((union thdr **)h->buffer)[h->offset])
static void destroy_ring(pcap_t *handle);
-static int create_ring(pcap_t *handle);
+static int create_ring(pcap_t *handle, int *status);
static int prepare_tpacket_socket(pcap_t *handle);
static void pcap_cleanup_linux_mmap(pcap_t *);
static int pcap_read_linux_mmap(pcap_t *, int, pcap_handler , u_char *);
@@ -331,7 +355,7 @@ static void pcap_oneshot_mmap(u_char *user, const struct pcap_pkthdr *h,
*/
#ifdef HAVE_PF_PACKET_SOCKETS
static int iface_get_id(int fd, const char *device, char *ebuf);
-#endif
+#endif /* HAVE_PF_PACKET_SOCKETS */
static int iface_get_mtu(int fd, const char *device, char *ebuf);
static int iface_get_arptype(int fd, const char *device, char *ebuf);
#ifdef HAVE_PF_PACKET_SOCKETS
@@ -342,6 +366,7 @@ static int has_wext(int sock_fd, const char *device, char *ebuf);
static int enter_rfmon_mode(pcap_t *handle, int sock_fd,
const char *device);
#endif /* HAVE_PF_PACKET_SOCKETS */
+static int iface_get_offload(pcap_t *handle);
static int iface_bind_old(int fd, const char *device, char *ebuf);
#ifdef SO_ATTACH_FILTER
@@ -355,7 +380,7 @@ static struct sock_filter total_insn
= BPF_STMT(BPF_RET | BPF_K, 0);
static struct sock_fprog total_fcode
= { 1, &total_insn };
-#endif
+#endif /* SO_ATTACH_FILTER */
pcap_t *
pcap_create(const char *device, char *ebuf)
@@ -405,58 +430,85 @@ pcap_create(const char *device, char *ebuf)
}
#endif
+#ifdef PCAP_SUPPORT_NETFILTER
+ if (strncmp(device, "nflog", strlen("nflog")) == 0) {
+ return nflog_create(device, ebuf);
+ }
+#endif
+
handle = pcap_create_common(device, ebuf);
if (handle == NULL)
return NULL;
handle->activate_op = pcap_activate_linux;
handle->can_set_rfmon_op = pcap_can_set_rfmon_linux;
+#if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP)
+ /*
+ * We claim that we support:
+ *
+ * software time stamps, with no details about their precision;
+ * hardware time stamps, synced to the host time;
+ * hardware time stamps, not synced to the host time.
+ *
+ * XXX - we can't ask a device whether it supports
+ * hardware time stamps, so we just claim all devices do.
+ */
+ handle->tstamp_type_count = 3;
+ handle->tstamp_type_list = malloc(3 * sizeof(u_int));
+ if (handle->tstamp_type_list == NULL) {
+ free(handle);
+ return NULL;
+ }
+ handle->tstamp_type_list[0] = PCAP_TSTAMP_HOST;
+ handle->tstamp_type_list[1] = PCAP_TSTAMP_ADAPTER;
+ handle->tstamp_type_list[2] = PCAP_TSTAMP_ADAPTER_UNSYNCED;
+#endif
+
return handle;
}
#ifdef HAVE_LIBNL
/*
- *
- * If interface {if} is a mac80211 driver, the file
- * /sys/class/net/{if}/phy80211 is a symlink to
- * /sys/class/ieee80211/{phydev}, for some {phydev}.
- *
- * On Fedora 9, with a 2.6.26.3-29 kernel, my Zydas stick, at
- * least, has a "wmaster0" device and a "wlan0" device; the
- * latter is the one with the IP address. Both show up in
- * "tcpdump -D" output. Capturing on the wmaster0 device
- * captures with 802.11 headers.
- *
- * airmon-ng searches through /sys/class/net for devices named
- * monN, starting with mon0; as soon as one *doesn't* exist,
- * it chooses that as the monitor device name. If the "iw"
- * command exists, it does "iw dev {if} interface add {monif}
- * type monitor", where {monif} is the monitor device. It
- * then (sigh) sleeps .1 second, and then configures the
- * device up. Otherwise, if /sys/class/ieee80211/{phydev}/add_iface
- * is a file, it writes {mondev}, without a newline, to that file,
- * and again (sigh) sleeps .1 second, and then iwconfig's that
- * device into monitor mode and configures it up. Otherwise,
- * you can't do monitor mode.
- *
- * All these devices are "glued" together by having the
- * /sys/class/net/{device}/phy80211 links pointing to the same
- * place, so, given a wmaster, wlan, or mon device, you can
- * find the other devices by looking for devices with
- * the same phy80211 link.
- *
- * To turn monitor mode off, delete the monitor interface,
- * either with "iw dev {monif} interface del" or by sending
- * {monif}, with no NL, down /sys/class/ieee80211/{phydev}/remove_iface
- *
- * Note: if you try to create a monitor device named "monN", and
- * there's already a "monN" device, it fails, as least with
- * the netlink interface (which is what iw uses), with a return
- * value of -ENFILE. (Return values are negative errnos.) We
- * could probably use that to find an unused device.
- *
- * Yes, you can have multiple monitor devices for a given
- * physical device.
+ * If interface {if} is a mac80211 driver, the file
+ * /sys/class/net/{if}/phy80211 is a symlink to
+ * /sys/class/ieee80211/{phydev}, for some {phydev}.
+ *
+ * On Fedora 9, with a 2.6.26.3-29 kernel, my Zydas stick, at
+ * least, has a "wmaster0" device and a "wlan0" device; the
+ * latter is the one with the IP address. Both show up in
+ * "tcpdump -D" output. Capturing on the wmaster0 device
+ * captures with 802.11 headers.
+ *
+ * airmon-ng searches through /sys/class/net for devices named
+ * monN, starting with mon0; as soon as one *doesn't* exist,
+ * it chooses that as the monitor device name. If the "iw"
+ * command exists, it does "iw dev {if} interface add {monif}
+ * type monitor", where {monif} is the monitor device. It
+ * then (sigh) sleeps .1 second, and then configures the
+ * device up. Otherwise, if /sys/class/ieee80211/{phydev}/add_iface
+ * is a file, it writes {mondev}, without a newline, to that file,
+ * and again (sigh) sleeps .1 second, and then iwconfig's that
+ * device into monitor mode and configures it up. Otherwise,
+ * you can't do monitor mode.
+ *
+ * All these devices are "glued" together by having the
+ * /sys/class/net/{device}/phy80211 links pointing to the same
+ * place, so, given a wmaster, wlan, or mon device, you can
+ * find the other devices by looking for devices with
+ * the same phy80211 link.
+ *
+ * To turn monitor mode off, delete the monitor interface,
+ * either with "iw dev {monif} interface del" or by sending
+ * {monif}, with no NL, down /sys/class/ieee80211/{phydev}/remove_iface
+ *
+ * Note: if you try to create a monitor device named "monN", and
+ * there's already a "monN" device, it fails, as least with
+ * the netlink interface (which is what iw uses), with a return
+ * value of -ENFILE. (Return values are negative errnos.) We
+ * could probably use that to find an unused device.
+ *
+ * Yes, you can have multiple monitor devices for a given
+ * physical device.
*/
/*
@@ -501,8 +553,41 @@ get_mac80211_phydev(pcap_t *handle, const char *device, char *phydev_path,
return 1;
}
+#ifdef HAVE_LIBNL_2_x
+#define get_nl_errmsg nl_geterror
+#else
+/* libnl 2.x compatibility code */
+
+#define nl_sock nl_handle
+
+static inline struct nl_handle *
+nl_socket_alloc(void)
+{
+ return nl_handle_alloc();
+}
+
+static inline void
+nl_socket_free(struct nl_handle *h)
+{
+ nl_handle_destroy(h);
+}
+
+#define get_nl_errmsg strerror
+
+static inline int
+__genl_ctrl_alloc_cache(struct nl_handle *h, struct nl_cache **cache)
+{
+ struct nl_cache *tmp = genl_ctrl_alloc_cache(h);
+ if (!tmp)
+ return -ENOMEM;
+ *cache = tmp;
+ return 0;
+}
+#define genl_ctrl_alloc_cache __genl_ctrl_alloc_cache
+#endif /* !HAVE_LIBNL_2_x */
+
struct nl80211_state {
- struct nl_handle *nl_handle;
+ struct nl_sock *nl_sock;
struct nl_cache *nl_cache;
struct genl_family *nl80211;
};
@@ -510,23 +595,26 @@ struct nl80211_state {
static int
nl80211_init(pcap_t *handle, struct nl80211_state *state, const char *device)
{
- state->nl_handle = nl_handle_alloc();
- if (!state->nl_handle) {
+ int err;
+
+ state->nl_sock = nl_socket_alloc();
+ if (!state->nl_sock) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"%s: failed to allocate netlink handle", device);
return PCAP_ERROR;
}
- if (genl_connect(state->nl_handle)) {
+ if (genl_connect(state->nl_sock)) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"%s: failed to connect to generic netlink", device);
goto out_handle_destroy;
}
- state->nl_cache = genl_ctrl_alloc_cache(state->nl_handle);
- if (!state->nl_cache) {
+ err = genl_ctrl_alloc_cache(state->nl_sock, &state->nl_cache);
+ if (err < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: failed to allocate generic netlink cache", device);
+ "%s: failed to allocate generic netlink cache: %s",
+ device, get_nl_errmsg(-err));
goto out_handle_destroy;
}
@@ -542,7 +630,7 @@ nl80211_init(pcap_t *handle, struct nl80211_state *state, const char *device)
out_cache_free:
nl_cache_free(state->nl_cache);
out_handle_destroy:
- nl_handle_destroy(state->nl_handle);
+ nl_socket_free(state->nl_sock);
return PCAP_ERROR;
}
@@ -551,7 +639,7 @@ nl80211_cleanup(struct nl80211_state *state)
{
genl_family_put(state->nl80211);
nl_cache_free(state->nl_cache);
- nl_handle_destroy(state->nl_handle);
+ nl_socket_free(state->nl_sock);
}
static int
@@ -579,12 +667,19 @@ add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, mondevice);
NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);
- err = nl_send_auto_complete(state->nl_handle, msg);
+ err = nl_send_auto_complete(state->nl_sock, msg);
if (err < 0) {
+#ifdef HAVE_LIBNL_2_x
+ if (err == -NLE_FAILURE) {
+#else
if (err == -ENFILE) {
+#endif
/*
* Device not available; our caller should just
- * keep trying.
+ * keep trying. (libnl 2.x maps ENFILE to
+ * NLE_FAILURE; it can also map other errors
+ * to that, but there's not much we can do
+ * about that.)
*/
nlmsg_free(msg);
return 0;
@@ -595,17 +690,24 @@ add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
*/
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"%s: nl_send_auto_complete failed adding %s interface: %s",
- device, mondevice, strerror(-err));
+ device, mondevice, get_nl_errmsg(-err));
nlmsg_free(msg);
return PCAP_ERROR;
}
}
- err = nl_wait_for_ack(state->nl_handle);
+ err = nl_wait_for_ack(state->nl_sock);
if (err < 0) {
+#ifdef HAVE_LIBNL_2_x
+ if (err == -NLE_FAILURE) {
+#else
if (err == -ENFILE) {
+#endif
/*
* Device not available; our caller should just
- * keep trying.
+ * keep trying. (libnl 2.x maps ENFILE to
+ * NLE_FAILURE; it can also map other errors
+ * to that, but there's not much we can do
+ * about that.)
*/
nlmsg_free(msg);
return 0;
@@ -616,7 +718,7 @@ add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
*/
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"%s: nl_wait_for_ack failed adding %s interface: %s",
- device, mondevice, strerror(-err));
+ device, mondevice, get_nl_errmsg(-err));
nlmsg_free(msg);
return PCAP_ERROR;
}
@@ -659,47 +761,21 @@ del_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
0, NL80211_CMD_DEL_INTERFACE, 0);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
- err = nl_send_auto_complete(state->nl_handle, msg);
+ err = nl_send_auto_complete(state->nl_sock, msg);
if (err < 0) {
- if (err == -ENFILE) {
- /*
- * Device not available; our caller should just
- * keep trying.
- */
- nlmsg_free(msg);
- return 0;
- } else {
- /*
- * Real failure, not just "that device is not
- * available.
- */
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: nl_send_auto_complete failed deleting %s interface: %s",
- device, mondevice, strerror(-err));
- nlmsg_free(msg);
- return PCAP_ERROR;
- }
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: nl_send_auto_complete failed deleting %s interface: %s",
+ device, mondevice, get_nl_errmsg(-err));
+ nlmsg_free(msg);
+ return PCAP_ERROR;
}
- err = nl_wait_for_ack(state->nl_handle);
+ err = nl_wait_for_ack(state->nl_sock);
if (err < 0) {
- if (err == -ENFILE) {
- /*
- * Device not available; our caller should just
- * keep trying.
- */
- nlmsg_free(msg);
- return 0;
- } else {
- /*
- * Real failure, not just "that device is not
- * available.
- */
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: nl_wait_for_ack failed adding %s interface: %s",
- device, mondevice, strerror(-err));
- nlmsg_free(msg);
- return PCAP_ERROR;
- }
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: nl_wait_for_ack failed adding %s interface: %s",
+ device, mondevice, get_nl_errmsg(-err));
+ nlmsg_free(msg);
+ return PCAP_ERROR;
}
/*
@@ -786,6 +862,18 @@ added:
#endif
/*
+ * If we haven't already done so, arrange to have
+ * "pcap_close_all()" called when we exit.
+ */
+ if (!pcap_do_addexit(handle)) {
+ /*
+ * "atexit()" failed; don't put the interface
+ * in rfmon mode, just give up.
+ */
+ return PCAP_ERROR_RFMON_NOTSUP;
+ }
+
+ /*
* Now configure the monitor interface up.
*/
memset(&ifr, 0, sizeof(ifr));
@@ -994,6 +1082,7 @@ static void pcap_cleanup_linux( pcap_t *handle )
int ret;
#endif /* HAVE_LIBNL */
#ifdef IW_MODE_MONITOR
+ int oldflags;
struct iwreq ireq;
#endif /* IW_MODE_MONITOR */
@@ -1017,10 +1106,10 @@ static void pcap_cleanup_linux( pcap_t *handle )
sizeof(ifr.ifr_name));
if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) {
fprintf(stderr,
- "Can't restore interface flags (SIOCGIFFLAGS failed: %s).\n"
+ "Can't restore interface %s flags (SIOCGIFFLAGS failed: %s).\n"
"Please adjust manually.\n"
"Hint: This can't happen with Linux >= 2.2.0.\n",
- strerror(errno));
+ handle->md.device, strerror(errno));
} else {
if (ifr.ifr_flags & IFF_PROMISC) {
/*
@@ -1031,9 +1120,10 @@ static void pcap_cleanup_linux( pcap_t *handle )
if (ioctl(handle->fd, SIOCSIFFLAGS,
&ifr) == -1) {
fprintf(stderr,
- "Can't restore interface flags (SIOCSIFFLAGS failed: %s).\n"
+ "Can't restore interface %s flags (SIOCSIFFLAGS failed: %s).\n"
"Please adjust manually.\n"
"Hint: This can't happen with Linux >= 2.2.0.\n",
+ handle->md.device,
strerror(errno));
}
}
@@ -1067,6 +1157,29 @@ static void pcap_cleanup_linux( pcap_t *handle )
* mode, this code cannot know that, so it'll take
* it out of rfmon mode.
*/
+
+ /*
+ * First, take the interface down if it's up;
+ * otherwise, we might get EBUSY.
+ * If we get errors, just drive on and print
+ * a warning if we can't restore the mode.
+ */
+ oldflags = 0;
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, handle->md.device,
+ sizeof(ifr.ifr_name));
+ if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) != -1) {
+ if (ifr.ifr_flags & IFF_UP) {
+ oldflags = ifr.ifr_flags;
+ ifr.ifr_flags &= ~IFF_UP;
+ if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1)
+ oldflags = 0; /* didn't set, don't restore */
+ }
+ }
+
+ /*
+ * Now restore the mode.
+ */
strncpy(ireq.ifr_ifrn.ifrn_name, handle->md.device,
sizeof ireq.ifr_ifrn.ifrn_name);
ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1]
@@ -1077,9 +1190,23 @@ static void pcap_cleanup_linux( pcap_t *handle )
* Scientist, you've failed.
*/
fprintf(stderr,
- "Can't restore interface wireless mode (SIOCSIWMODE failed: %s).\n"
+ "Can't restore interface %s wireless mode (SIOCSIWMODE failed: %s).\n"
"Please adjust manually.\n",
- strerror(errno));
+ handle->md.device, strerror(errno));
+ }
+
+ /*
+ * Now bring the interface back up if we brought
+ * it down.
+ */
+ if (oldflags != 0) {
+ ifr.ifr_flags = oldflags;
+ if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) {
+ fprintf(stderr,
+ "Can't bring interface %s back up (SIOCSIFFLAGS failed: %s).\n"
+ "Please adjust manually.\n",
+ handle->md.device, strerror(errno));
+ }
}
}
#endif /* IW_MODE_MONITOR */
@@ -1167,34 +1294,46 @@ pcap_activate_linux(pcap_t *handle)
* to be compatible with older kernels for a while so we are
* trying both methods with the newer method preferred.
*/
-
- if ((status = activate_new(handle)) == 1) {
+ status = activate_new(handle);
+ if (status < 0) {
+ /*
+ * Fatal error with the new way; just fail.
+ * status has the error return; if it's PCAP_ERROR,
+ * handle->errbuf has been set appropriately.
+ */
+ goto fail;
+ }
+ if (status == 1) {
/*
* Success.
* Try to use memory-mapped access.
*/
- switch (activate_mmap(handle)) {
+ switch (activate_mmap(handle, &status)) {
case 1:
- /* we succeeded; nothing more to do */
- return 0;
+ /*
+ * We succeeded. status has been
+ * set to the status to return,
+ * which might be 0, or might be
+ * a PCAP_WARNING_ value.
+ */
+ return status;
case 0:
/*
* Kernel doesn't support it - just continue
* with non-memory-mapped access.
*/
- status = 0;
break;
case -1:
/*
- * We failed to set up to use it, or kernel
- * supports it, but we failed to enable it;
- * return an error. handle->errbuf contains
- * an error message.
+ * We failed to set up to use it, or the kernel
+ * supports it, but we failed to enable it.
+ * status has been set to the error status to
+ * return and, if it's PCAP_ERROR, handle->errbuf
+ * contains the error message.
*/
- status = PCAP_ERROR;
goto fail;
}
}
@@ -1208,18 +1347,12 @@ pcap_activate_linux(pcap_t *handle)
*/
goto fail;
}
- } else {
- /*
- * Fatal error with the new way; just fail.
- * status has the error return; if it's PCAP_ERROR,
- * handle->errbuf has been set appropriately.
- */
- goto fail;
}
/*
* We set up the socket, but not with memory-mapped access.
*/
+ status = 0;
if (handle->opt.buffer_size != 0) {
/*
* Set the socket buffer size to the specified value.
@@ -1814,8 +1947,20 @@ scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
int ret = 1;
sys_class_net_d = opendir("/sys/class/net");
- if (sys_class_net_d == NULL && errno == ENOENT)
- return (0);
+ if (sys_class_net_d == NULL) {
+ /*
+ * Don't fail if it doesn't exist at all.
+ */
+ if (errno == ENOENT)
+ return (0);
+
+ /*
+ * Fail if we got some other error.
+ */
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Can't open /sys/class/net: %s", pcap_strerror(errno));
+ return (-1);
+ }
/*
* Create a socket from which to fetch interface information.
@@ -1824,6 +1969,7 @@ scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
if (fd < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
+ (void)closedir(sys_class_net_d);
return (-1);
}
@@ -1883,7 +2029,7 @@ scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
*/
strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
- if (errno == ENXIO)
+ if (errno == ENXIO || errno == ENODEV)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFFLAGS: %.*s: %s",
@@ -1947,8 +2093,20 @@ scan_proc_net_dev(pcap_if_t **devlistp, char *errbuf)
int ret = 0;
proc_net_f = fopen("/proc/net/dev", "r");
- if (proc_net_f == NULL && errno == ENOENT)
- return (0);
+ if (proc_net_f == NULL) {
+ /*
+ * Don't fail if it doesn't exist at all.
+ */
+ if (errno == ENOENT)
+ return (0);
+
+ /*
+ * Fail if we got some other error.
+ */
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Can't open /proc/net/dev: %s", pcap_strerror(errno));
+ return (-1);
+ }
/*
* Create a socket from which to fetch interface information.
@@ -1957,6 +2115,7 @@ scan_proc_net_dev(pcap_if_t **devlistp, char *errbuf)
if (fd < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
+ (void)fclose(proc_net_f);
return (-1);
}
@@ -2132,6 +2291,14 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
return (-1);
#endif
+#ifdef PCAP_SUPPORT_NETFILTER
+ /*
+ * Add netfilter devices.
+ */
+ if (netfilter_platform_finddevs(alldevsp, errbuf) < 0)
+ return (-1);
+#endif
+
return (0);
}
@@ -2227,6 +2394,30 @@ pcap_setfilter_linux_common(pcap_t *handle, struct bpf_program *filter,
}
}
+ /*
+ * NOTE: at this point, we've set both the "len" and "filter"
+ * fields of "fcode". As of the 2.6.32.4 kernel, at least,
+ * those are the only members of the "sock_fprog" structure,
+ * so we initialize every member of that structure.
+ *
+ * If there is anything in "fcode" that is not initialized,
+ * it is either a field added in a later kernel, or it's
+ * padding.
+ *
+ * If a new field is added, this code needs to be updated
+ * to set it correctly.
+ *
+ * If there are no other fields, then:
+ *
+ * if the Linux kernel looks at the padding, it's
+ * buggy;
+ *
+ * if the Linux kernel doesn't look at the padding,
+ * then if some tool complains that we're passing
+ * uninitialized data to the kernel, then the tool
+ * is buggy and needs to understand that it's just
+ * padding.
+ */
if (can_filter_in_kernel) {
if ((err = set_kernel_filter(handle, &fcode)) == 0)
{
@@ -2302,7 +2493,6 @@ pcap_setdirection_linux(pcap_t *handle, pcap_direction_t d)
return -1;
}
-
#ifdef HAVE_PF_PACKET_SOCKETS
/*
* Map the PACKET_ value to a LINUX_SLL_ value; we
@@ -2649,6 +2839,13 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok)
handle->linktype = DLT_RAW;
break;
+#ifndef ARPHRD_IEEE802154
+#define ARPHRD_IEEE802154 804
+#endif
+ case ARPHRD_IEEE802154:
+ handle->linktype = DLT_IEEE802_15_4_NOFCS;
+ break;
+
default:
handle->linktype = -1;
break;
@@ -2688,9 +2885,28 @@ activate_new(pcap_t *handle)
socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (sock_fd == -1) {
+ if (errno == EINVAL || errno == EAFNOSUPPORT) {
+ /*
+ * We don't support PF_PACKET/SOCK_whatever
+ * sockets; try the old mechanism.
+ */
+ return 0;
+ }
+
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
pcap_strerror(errno) );
- return 0; /* try old mechanism */
+ if (errno == EPERM || errno == EACCES) {
+ /*
+ * You don't have permission to open the
+ * socket.
+ */
+ return PCAP_ERROR_PERM_DENIED;
+ } else {
+ /*
+ * Other error.
+ */
+ return PCAP_ERROR;
+ }
}
/* It seems the kernel supports the new interface. */
@@ -2787,7 +3003,18 @@ activate_new(pcap_t *handle)
if (sock_fd == -1) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
- return PCAP_ERROR;
+ if (errno == EPERM || errno == EACCES) {
+ /*
+ * You don't have permission to
+ * open the socket.
+ */
+ return PCAP_ERROR_PERM_DENIED;
+ } else {
+ /*
+ * Other error.
+ */
+ return PCAP_ERROR;
+ }
}
handle->md.cooked = 1;
@@ -2950,10 +3177,22 @@ activate_new(pcap_t *handle)
#endif
}
+#ifdef HAVE_PACKET_RING
+/*
+ * Attempt to activate with memory-mapped access.
+ *
+ * On success, returns 1, and sets *status to 0 if there are no warnings
+ * or to a PCAP_WARNING_ code if there is a warning.
+ *
+ * On failure due to lack of support for memory-mapped capture, returns
+ * 0.
+ *
+ * On error, returns -1, and sets *status to the appropriate error code;
+ * if that is PCAP_ERROR, sets handle->errbuf to the appropriate message.
+ */
static int
-activate_mmap(pcap_t *handle)
+activate_mmap(pcap_t *handle, int *status)
{
-#ifdef HAVE_PACKET_RING
int ret;
/*
@@ -2965,7 +3204,8 @@ activate_mmap(pcap_t *handle)
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"can't allocate oneshot buffer: %s",
pcap_strerror(errno));
- return PCAP_ERROR;
+ *status = PCAP_ERROR;
+ return -1;
}
if (handle->opt.buffer_size == 0) {
@@ -2973,20 +3213,38 @@ activate_mmap(pcap_t *handle)
handle->opt.buffer_size = 2*1024*1024;
}
ret = prepare_tpacket_socket(handle);
- if (ret != 1) {
+ if (ret == -1) {
free(handle->md.oneshot_buffer);
+ *status = PCAP_ERROR;
return ret;
}
- ret = create_ring(handle);
- if (ret != 1) {
+ ret = create_ring(handle, status);
+ if (ret == 0) {
+ /*
+ * We don't support memory-mapped capture; our caller
+ * will fall back on reading from the socket.
+ */
free(handle->md.oneshot_buffer);
- return ret;
+ return 0;
+ }
+ if (ret == -1) {
+ /*
+ * Error attempting to enable memory-mapped capture;
+ * fail. create_ring() has set *status.
+ */
+ free(handle->md.oneshot_buffer);
+ return -1;
}
- /* override some defaults and inherit the other fields from
- * activate_new
- * handle->offset is used to get the current position into the rx ring
- * handle->cc is used to store the ring size */
+ /*
+ * Success. *status has been set either to 0 if there are no
+ * warnings or to a PCAP_WARNING_ value if there is a warning.
+ *
+ * Override some defaults and inherit the other fields from
+ * activate_new.
+ * handle->offset is used to get the current position into the rx ring.
+ * handle->cc is used to store the ring size.
+ */
handle->read_op = pcap_read_linux_mmap;
handle->cleanup_op = pcap_cleanup_linux_mmap;
handle->setfilter_op = pcap_setfilter_linux_mmap;
@@ -2995,12 +3253,21 @@ activate_mmap(pcap_t *handle)
handle->oneshot_callback = pcap_oneshot_mmap;
handle->selectable_fd = handle->fd;
return 1;
+}
#else /* HAVE_PACKET_RING */
+static int
+activate_mmap(pcap_t *handle _U_, int *status _U_)
+{
return 0;
-#endif /* HAVE_PACKET_RING */
}
+#endif /* HAVE_PACKET_RING */
#ifdef HAVE_PACKET_RING
+/*
+ * Attempt to set the socket to version 2 of the memory-mapped header.
+ * Return 1 if we succeed or if we fail because version 2 isn't
+ * supported; return -1 on any other error, and set handle->errbuf.
+ */
static int
prepare_tpacket_socket(pcap_t *handle)
{
@@ -3052,20 +3319,140 @@ prepare_tpacket_socket(pcap_t *handle)
return 1;
}
+/*
+ * Attempt to set up memory-mapped access.
+ *
+ * On success, returns 1, and sets *status to 0 if there are no warnings
+ * or to a PCAP_WARNING_ code if there is a warning.
+ *
+ * On failure due to lack of support for memory-mapped capture, returns
+ * 0.
+ *
+ * On error, returns -1, and sets *status to the appropriate error code;
+ * if that is PCAP_ERROR, sets handle->errbuf to the appropriate message.
+ */
static int
-create_ring(pcap_t *handle)
+create_ring(pcap_t *handle, int *status)
{
unsigned i, j, frames_per_block;
struct tpacket_req req;
+ socklen_t len;
+ unsigned int sk_type, tp_reserve, maclen, tp_hdrlen, netoff, macoff;
+ unsigned int frame_size;
- /* Note that with large snapshot (say 64K) only a few frames
- * will be available in the ring even with pretty large ring size
- * (and a lot of memory will be unused).
- * The snap len should be carefully chosen to achive best
- * performance */
- req.tp_frame_size = TPACKET_ALIGN(handle->snapshot +
- TPACKET_ALIGN(handle->md.tp_hdrlen) +
- sizeof(struct sockaddr_ll));
+ /*
+ * Start out assuming no warnings or errors.
+ */
+ *status = 0;
+
+ /* Note that with large snapshot length (say 64K, which is the default
+ * for recent versions of tcpdump, the value that "-s 0" has given
+ * for a long time with tcpdump, and the default in Wireshark/TShark),
+ * if we use the snapshot length to calculate the frame length,
+ * only a few frames will be available in the ring even with pretty
+ * large ring size (and a lot of memory will be unused).
+ *
+ * Ideally, we should choose a frame length based on the
+ * minimum of the specified snapshot length and the maximum
+ * packet size. That's not as easy as it sounds; consider, for
+ * example, an 802.11 interface in monitor mode, where the
+ * frame would include a radiotap header, where the maximum
+ * radiotap header length is device-dependent.
+ *
+ * So, for now, we just do this for Ethernet devices, where
+ * there's no metadata header, and the link-layer header is
+ * fixed length. We can get the maximum packet size by
+ * adding 18, the Ethernet header length plus the CRC length
+ * (just in case we happen to get the CRC in the packet), to
+ * the MTU of the interface; we fetch the MTU in the hopes
+ * that it reflects support for jumbo frames. (Even if the
+ * interface is just being used for passive snooping, the driver
+ * might set the size of buffers in the receive ring based on
+ * the MTU, so that the MTU limits the maximum size of packets
+ * that we can receive.)
+ *
+ * We don't do that if segmentation/fragmentation or receive
+ * offload are enabled, so we don't get rudely surprised by
+ * "packets" bigger than the MTU. */
+ frame_size = handle->snapshot;
+ if (handle->linktype == DLT_EN10MB) {
+ int mtu;
+ int offload;
+
+ offload = iface_get_offload(handle);
+ if (offload == -1) {
+ *status = PCAP_ERROR;
+ return -1;
+ }
+ if (!offload) {
+ mtu = iface_get_mtu(handle->fd, handle->opt.source,
+ handle->errbuf);
+ if (mtu == -1) {
+ *status = PCAP_ERROR;
+ return -1;
+ }
+ if (frame_size > mtu + 18)
+ frame_size = mtu + 18;
+ }
+ }
+
+ /* NOTE: calculus matching those in tpacket_rcv()
+ * in linux-2.6/net/packet/af_packet.c
+ */
+ len = sizeof(sk_type);
+ if (getsockopt(handle->fd, SOL_SOCKET, SO_TYPE, &sk_type, &len) < 0) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "getsockopt: %s", pcap_strerror(errno));
+ *status = PCAP_ERROR;
+ return -1;
+ }
+#ifdef PACKET_RESERVE
+ len = sizeof(tp_reserve);
+ if (getsockopt(handle->fd, SOL_PACKET, PACKET_RESERVE, &tp_reserve, &len) < 0) {
+ if (errno != ENOPROTOOPT) {
+ /*
+ * ENOPROTOOPT means "kernel doesn't support
+ * PACKET_RESERVE", in which case we fall back
+ * as best we can.
+ */
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "getsockopt: %s", pcap_strerror(errno));
+ *status = PCAP_ERROR;
+ return -1;
+ }
+ tp_reserve = 0; /* older kernel, reserve not supported */
+ }
+#else
+ tp_reserve = 0; /* older kernel, reserve not supported */
+#endif
+ maclen = (sk_type == SOCK_DGRAM) ? 0 : MAX_LINKHEADER_SIZE;
+ /* XXX: in the kernel maclen is calculated from
+ * LL_ALLOCATED_SPACE(dev) and vnet_hdr.hdr_len
+ * in: packet_snd() in linux-2.6/net/packet/af_packet.c
+ * then packet_alloc_skb() in linux-2.6/net/packet/af_packet.c
+ * then sock_alloc_send_pskb() in linux-2.6/net/core/sock.c
+ * but I see no way to get those sizes in userspace,
+ * like for instance with an ifreq ioctl();
+ * the best thing I've found so far is MAX_HEADER in the kernel
+ * part of linux-2.6/include/linux/netdevice.h
+ * which goes up to 128+48=176; since pcap-linux.c defines
+ * a MAX_LINKHEADER_SIZE of 256 which is greater than that,
+ * let's use it.. maybe is it even large enough to directly
+ * replace macoff..
+ */
+ tp_hdrlen = TPACKET_ALIGN(handle->md.tp_hdrlen) + sizeof(struct sockaddr_ll) ;
+ netoff = TPACKET_ALIGN(tp_hdrlen + (maclen < 16 ? 16 : maclen)) + tp_reserve;
+ /* NOTE: AFAICS tp_reserve may break the TPACKET_ALIGN of
+ * netoff, which contradicts
+ * linux-2.6/Documentation/networking/packet_mmap.txt
+ * documenting that:
+ * "- Gap, chosen so that packet data (Start+tp_net)
+ * aligns to TPACKET_ALIGNMENT=16"
+ */
+ /* NOTE: in linux-2.6/include/linux/skbuff.h:
+ * "CPUs often take a performance hit
+ * when accessing unaligned memory locations"
+ */
+ macoff = netoff - maclen;
+ req.tp_frame_size = TPACKET_ALIGN(macoff + frame_size);
req.tp_frame_nr = handle->opt.buffer_size/req.tp_frame_size;
/* compute the minumum block size that will handle this frame.
@@ -3078,6 +3465,109 @@ create_ring(pcap_t *handle)
frames_per_block = req.tp_block_size/req.tp_frame_size;
+ /*
+ * PACKET_TIMESTAMP was added after linux/net_tstamp.h was,
+ * so we check for PACKET_TIMESTAMP. We check for
+ * linux/net_tstamp.h just in case a system somehow has
+ * PACKET_TIMESTAMP but not linux/net_tstamp.h; that might
+ * be unnecessary.
+ *
+ * SIOCSHWTSTAMP was introduced in the patch that introduced
+ * linux/net_tstamp.h, so we don't bother checking whether
+ * SIOCSHWTSTAMP is defined (if your Linux system has
+ * linux/net_tstamp.h but doesn't define SIOCSHWTSTAMP, your
+ * Linux system is badly broken).
+ */
+#if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP)
+ /*
+ * If we were told to do so, ask the kernel and the driver
+ * to use hardware timestamps.
+ *
+ * Hardware timestamps are only supported with mmapped
+ * captures.
+ */
+ if (handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER ||
+ handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER_UNSYNCED) {
+ struct hwtstamp_config hwconfig;
+ struct ifreq ifr;
+ int timesource;
+
+ /*
+ * Ask for hardware time stamps on all packets,
+ * including transmitted packets.
+ */
+ memset(&hwconfig, 0, sizeof(hwconfig));
+ hwconfig.tx_type = HWTSTAMP_TX_ON;
+ hwconfig.rx_filter = HWTSTAMP_FILTER_ALL;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, handle->opt.source);
+ ifr.ifr_data = (void *)&hwconfig;
+
+ if (ioctl(handle->fd, SIOCSHWTSTAMP, &ifr) < 0) {
+ switch (errno) {
+
+ case EPERM:
+ /*
+ * Treat this as an error, as the
+ * user should try to run this
+ * with the appropriate privileges -
+ * and, if they can't, shouldn't
+ * try requesting hardware time stamps.
+ */
+ *status = PCAP_ERROR_PERM_DENIED;
+ return -1;
+
+ case EOPNOTSUPP:
+ /*
+ * Treat this as a warning, as the
+ * only way to fix the warning is to
+ * get an adapter that supports hardware
+ * time stamps. We'll just fall back
+ * on the standard host time stamps.
+ */
+ *status = PCAP_WARNING_TSTAMP_TYPE_NOTSUP;
+ break;
+
+ default:
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCSHWTSTAMP failed: %s",
+ pcap_strerror(errno));
+ *status = PCAP_ERROR;
+ return -1;
+ }
+ } else {
+ /*
+ * Well, that worked. Now specify the type of
+ * hardware time stamp we want for this
+ * socket.
+ */
+ if (handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER) {
+ /*
+ * Hardware timestamp, synchronized
+ * with the system clock.
+ */
+ timesource = SOF_TIMESTAMPING_SYS_HARDWARE;
+ } else {
+ /*
+ * PCAP_TSTAMP_ADAPTER_UNSYNCED - hardware
+ * timestamp, not synchronized with the
+ * system clock.
+ */
+ timesource = SOF_TIMESTAMPING_RAW_HARDWARE;
+ }
+ if (setsockopt(handle->fd, SOL_PACKET, PACKET_TIMESTAMP,
+ (void *)&timesource, sizeof(timesource))) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "can't set PACKET_TIMESTAMP: %s",
+ pcap_strerror(errno));
+ *status = PCAP_ERROR;
+ return -1;
+ }
+ }
+ }
+#endif /* HAVE_LINUX_NET_TSTAMP_H && PACKET_TIMESTAMP */
+
/* ask the kernel to create the ring */
retry:
req.tp_block_nr = req.tp_frame_nr / frames_per_block;
@@ -3112,6 +3602,7 @@ retry:
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"can't create rx ring on packet socket: %s",
pcap_strerror(errno));
+ *status = PCAP_ERROR;
return -1;
}
@@ -3125,6 +3616,7 @@ retry:
/* clear the allocated ring on error*/
destroy_ring(handle);
+ *status = PCAP_ERROR;
return -1;
}
@@ -3137,6 +3629,7 @@ retry:
pcap_strerror(errno));
destroy_ring(handle);
+ *status = PCAP_ERROR;
return -1;
}
@@ -3813,6 +4306,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
monitor_type montype;
int i;
__u32 cmd;
+ struct ifreq ifr;
+ int oldflags;
int args[2];
int channel;
@@ -3823,6 +4318,13 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
if (err <= 0)
return err; /* either it doesn't or the device doesn't even exist */
/*
+ * Start out assuming we have no private extensions to control
+ * radio metadata.
+ */
+ montype = MONITOR_WEXT;
+ cmd = 0;
+
+ /*
* Try to get all the Wireless Extensions private ioctls
* supported by this device.
*
@@ -3845,187 +4347,189 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
device);
return PCAP_ERROR;
}
- if (errno == EOPNOTSUPP) {
+ if (errno != EOPNOTSUPP) {
/*
- * No private ioctls, so we assume that there's only one
- * DLT_ for monitor mode.
+ * OK, it's not as if there are no private ioctls.
*/
- return 0;
- }
- if (errno != E2BIG) {
- /*
- * Failed.
- */
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: SIOCGIWPRIV: %s", device, pcap_strerror(errno));
- return PCAP_ERROR;
- }
- priv = malloc(ireq.u.data.length * sizeof (struct iw_priv_args));
- if (priv == NULL) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- return PCAP_ERROR;
- }
- ireq.u.data.pointer = (void *)priv;
- if (ioctl(sock_fd, SIOCGIWPRIV, &ireq) == -1) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: SIOCGIWPRIV: %s", device, pcap_strerror(errno));
- free(priv);
- return PCAP_ERROR;
- }
-
- /*
- * Look for private ioctls to turn monitor mode on or, if
- * monitor mode is on, to set the header type.
- */
- montype = MONITOR_WEXT;
- cmd = 0;
- for (i = 0; i < ireq.u.data.length; i++) {
- if (strcmp(priv[i].name, "monitor_type") == 0) {
- /*
- * Hostap driver, use this one.
- * Set monitor mode first.
- * You can set it to 0 to get DLT_IEEE80211,
- * 1 to get DLT_PRISM, 2 to get
- * DLT_IEEE80211_RADIO_AVS, and, with more
- * recent versions of the driver, 3 to get
- * DLT_IEEE80211_RADIO.
- */
- if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
- break;
- if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED))
- break;
- if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1)
- break;
- montype = MONITOR_HOSTAP;
- cmd = priv[i].cmd;
- break;
- }
- if (strcmp(priv[i].name, "set_prismhdr") == 0) {
+ if (errno != E2BIG) {
/*
- * Prism54 driver, use this one.
- * Set monitor mode first.
- * You can set it to 2 to get DLT_IEEE80211
- * or 3 or get DLT_PRISM.
+ * Failed.
*/
- if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
- break;
- if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED))
- break;
- if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1)
- break;
- montype = MONITOR_PRISM54;
- cmd = priv[i].cmd;
- break;
- }
- if (strcmp(priv[i].name, "forceprismheader") == 0) {
- /*
- * RT2570 driver, use this one.
- * Do this after turning monitor mode on.
- * You can set it to 1 to get DLT_PRISM or 2
- * to get DLT_IEEE80211.
- */
- if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
- break;
- if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED))
- break;
- if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1)
- break;
- montype = MONITOR_RT2570;
- cmd = priv[i].cmd;
- break;
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: SIOCGIWPRIV: %s", device,
+ pcap_strerror(errno));
+ return PCAP_ERROR;
}
- if (strcmp(priv[i].name, "forceprism") == 0) {
- /*
- * RT73 driver, use this one.
- * Do this after turning monitor mode on.
- * Its argument is a *string*; you can
- * set it to "1" to get DLT_PRISM or "2"
- * to get DLT_IEEE80211.
- */
- if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_CHAR)
- break;
- if (priv[i].set_args & IW_PRIV_SIZE_FIXED)
- break;
- montype = MONITOR_RT73;
- cmd = priv[i].cmd;
- break;
+
+ /*
+ * OK, try to get the list of private ioctls.
+ */
+ priv = malloc(ireq.u.data.length * sizeof (struct iw_priv_args));
+ if (priv == NULL) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ return PCAP_ERROR;
}
- if (strcmp(priv[i].name, "prismhdr") == 0) {
- /*
- * One of the RTL8xxx drivers, use this one.
- * It can only be done after monitor mode
- * has been turned on. You can set it to 1
- * to get DLT_PRISM or 0 to get DLT_IEEE80211.
- */
- if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
- break;
- if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED))
- break;
- if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1)
- break;
- montype = MONITOR_RTL8XXX;
- cmd = priv[i].cmd;
- break;
+ ireq.u.data.pointer = (void *)priv;
+ if (ioctl(sock_fd, SIOCGIWPRIV, &ireq) == -1) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: SIOCGIWPRIV: %s", device,
+ pcap_strerror(errno));
+ free(priv);
+ return PCAP_ERROR;
}
- if (strcmp(priv[i].name, "rfmontx") == 0) {
- /*
- * RT2500 or RT61 driver, use this one.
- * It has one one-byte parameter; set
- * u.data.length to 1 and u.data.pointer to
- * point to the parameter.
- * It doesn't itself turn monitor mode on.
- * You can set it to 1 to allow transmitting
- * in monitor mode(?) and get DLT_IEEE80211,
- * or set it to 0 to disallow transmitting in
- * monitor mode(?) and get DLT_PRISM.
- */
- if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
- break;
- if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 2)
+
+ /*
+ * Look for private ioctls to turn monitor mode on or, if
+ * monitor mode is on, to set the header type.
+ */
+ for (i = 0; i < ireq.u.data.length; i++) {
+ if (strcmp(priv[i].name, "monitor_type") == 0) {
+ /*
+ * Hostap driver, use this one.
+ * Set monitor mode first.
+ * You can set it to 0 to get DLT_IEEE80211,
+ * 1 to get DLT_PRISM, 2 to get
+ * DLT_IEEE80211_RADIO_AVS, and, with more
+ * recent versions of the driver, 3 to get
+ * DLT_IEEE80211_RADIO.
+ */
+ if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
+ break;
+ if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED))
+ break;
+ if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1)
+ break;
+ montype = MONITOR_HOSTAP;
+ cmd = priv[i].cmd;
break;
- montype = MONITOR_RT2500;
- cmd = priv[i].cmd;
- break;
- }
- if (strcmp(priv[i].name, "monitor") == 0) {
- /*
- * Either ACX100 or hostap, use this one.
- * It turns monitor mode on.
- * If it takes two arguments, it's ACX100;
- * the first argument is 1 for DLT_PRISM
- * or 2 for DLT_IEEE80211, and the second
- * argument is the channel on which to
- * run. If it takes one argument, it's
- * HostAP, and the argument is 2 for
- * DLT_IEEE80211 and 3 for DLT_PRISM.
- *
- * If we see this, we don't quit, as this
- * might be a version of the hostap driver
- * that also supports "monitor_type".
- */
- if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
+ }
+ if (strcmp(priv[i].name, "set_prismhdr") == 0) {
+ /*
+ * Prism54 driver, use this one.
+ * Set monitor mode first.
+ * You can set it to 2 to get DLT_IEEE80211
+ * or 3 or get DLT_PRISM.
+ */
+ if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
+ break;
+ if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED))
+ break;
+ if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1)
+ break;
+ montype = MONITOR_PRISM54;
+ cmd = priv[i].cmd;
break;
- if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED))
+ }
+ if (strcmp(priv[i].name, "forceprismheader") == 0) {
+ /*
+ * RT2570 driver, use this one.
+ * Do this after turning monitor mode on.
+ * You can set it to 1 to get DLT_PRISM or 2
+ * to get DLT_IEEE80211.
+ */
+ if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
+ break;
+ if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED))
+ break;
+ if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1)
+ break;
+ montype = MONITOR_RT2570;
+ cmd = priv[i].cmd;
break;
- switch (priv[i].set_args & IW_PRIV_SIZE_MASK) {
-
- case 1:
- montype = MONITOR_PRISM;
+ }
+ if (strcmp(priv[i].name, "forceprism") == 0) {
+ /*
+ * RT73 driver, use this one.
+ * Do this after turning monitor mode on.
+ * Its argument is a *string*; you can
+ * set it to "1" to get DLT_PRISM or "2"
+ * to get DLT_IEEE80211.
+ */
+ if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_CHAR)
+ break;
+ if (priv[i].set_args & IW_PRIV_SIZE_FIXED)
+ break;
+ montype = MONITOR_RT73;
cmd = priv[i].cmd;
break;
-
- case 2:
- montype = MONITOR_ACX100;
+ }
+ if (strcmp(priv[i].name, "prismhdr") == 0) {
+ /*
+ * One of the RTL8xxx drivers, use this one.
+ * It can only be done after monitor mode
+ * has been turned on. You can set it to 1
+ * to get DLT_PRISM or 0 to get DLT_IEEE80211.
+ */
+ if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
+ break;
+ if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED))
+ break;
+ if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 1)
+ break;
+ montype = MONITOR_RTL8XXX;
cmd = priv[i].cmd;
break;
-
- default:
+ }
+ if (strcmp(priv[i].name, "rfmontx") == 0) {
+ /*
+ * RT2500 or RT61 driver, use this one.
+ * It has one one-byte parameter; set
+ * u.data.length to 1 and u.data.pointer to
+ * point to the parameter.
+ * It doesn't itself turn monitor mode on.
+ * You can set it to 1 to allow transmitting
+ * in monitor mode(?) and get DLT_IEEE80211,
+ * or set it to 0 to disallow transmitting in
+ * monitor mode(?) and get DLT_PRISM.
+ */
+ if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
+ break;
+ if ((priv[i].set_args & IW_PRIV_SIZE_MASK) != 2)
+ break;
+ montype = MONITOR_RT2500;
+ cmd = priv[i].cmd;
break;
}
+ if (strcmp(priv[i].name, "monitor") == 0) {
+ /*
+ * Either ACX100 or hostap, use this one.
+ * It turns monitor mode on.
+ * If it takes two arguments, it's ACX100;
+ * the first argument is 1 for DLT_PRISM
+ * or 2 for DLT_IEEE80211, and the second
+ * argument is the channel on which to
+ * run. If it takes one argument, it's
+ * HostAP, and the argument is 2 for
+ * DLT_IEEE80211 and 3 for DLT_PRISM.
+ *
+ * If we see this, we don't quit, as this
+ * might be a version of the hostap driver
+ * that also supports "monitor_type".
+ */
+ if ((priv[i].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT)
+ break;
+ if (!(priv[i].set_args & IW_PRIV_SIZE_FIXED))
+ break;
+ switch (priv[i].set_args & IW_PRIV_SIZE_MASK) {
+
+ case 1:
+ montype = MONITOR_PRISM;
+ cmd = priv[i].cmd;
+ break;
+
+ case 2:
+ montype = MONITOR_ACX100;
+ cmd = priv[i].cmd;
+ break;
+
+ default:
+ break;
+ }
+ }
}
+ free(priv);
}
- free(priv);
/*
* XXX - ipw3945? islism?
@@ -4120,7 +4624,29 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
}
/*
- * First, turn monitor mode on.
+ * First, take the interface down if it's up; otherwise, we
+ * might get EBUSY.
+ */
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: Can't get flags: %s", device, strerror(errno));
+ return PCAP_ERROR;
+ }
+ oldflags = 0;
+ if (ifr.ifr_flags & IFF_UP) {
+ oldflags = ifr.ifr_flags;
+ ifr.ifr_flags &= ~IFF_UP;
+ if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: Can't set flags: %s", device, strerror(errno));
+ return PCAP_ERROR;
+ }
+ }
+
+ /*
+ * Then turn monitor mode on.
*/
strncpy(ireq.ifr_ifrn.ifrn_name, device,
sizeof ireq.ifr_ifrn.ifrn_name);
@@ -4129,7 +4655,14 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
if (ioctl(sock_fd, SIOCSIWMODE, &ireq) == -1) {
/*
* Scientist, you've failed.
+ * Bring the interface back up if we shut it down.
*/
+ ifr.ifr_flags = oldflags;
+ if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: Can't set flags: %s", device, strerror(errno));
+ return PCAP_ERROR;
+ }
return PCAP_ERROR_RFMON_NOTSUP;
}
@@ -4292,6 +4825,32 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
}
/*
+ * Now bring the interface back up if we brought it down.
+ */
+ if (oldflags != 0) {
+ ifr.ifr_flags = oldflags;
+ if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: Can't set flags: %s", device, strerror(errno));
+
+ /*
+ * At least try to restore the old mode on the
+ * interface.
+ */
+ if (ioctl(handle->fd, SIOCSIWMODE, &ireq) == -1) {
+ /*
+ * Scientist, you've failed.
+ */
+ fprintf(stderr,
+ "Can't restore interface wireless mode (SIOCSIWMODE failed: %s).\n"
+ "Please adjust manually.\n",
+ strerror(errno));
+ }
+ return PCAP_ERROR;
+ }
+ }
+
+ /*
* Note that we have to put the old mode back when we
* close the device.
*/
@@ -4340,6 +4899,112 @@ enter_rfmon_mode(pcap_t *handle, int sock_fd, const char *device)
return 0;
}
+/*
+ * Find out if we have any form of fragmentation/reassembly offloading.
+ *
+ * We do so using SIOCETHTOOL checking for various types of offloading;
+ * if SIOCETHTOOL isn't defined, or we don't have any #defines for any
+ * of the types of offloading, there's nothing we can do to check, so
+ * we just say "no, we don't".
+ */
+#if defined(SIOCETHTOOL) && (defined(ETHTOOL_GTSO) || defined(ETHTOOL_GUFO) || defined(ETHTOOL_GGSO) || defined(ETHTOOL_GFLAGS) || defined(ETHTOOL_GGRO))
+static int
+iface_ethtool_ioctl(pcap_t *handle, int cmd, const char *cmdname)
+{
+ struct ifreq ifr;
+ struct ethtool_value eval;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, handle->opt.source, sizeof(ifr.ifr_name));
+ eval.cmd = cmd;
+ ifr.ifr_data = (caddr_t)&eval;
+ if (ioctl(handle->fd, SIOCETHTOOL, &ifr) == -1) {
+ if (errno == EOPNOTSUPP) {
+ /*
+ * OK, let's just return 0, which, in our
+ * case, either means "no, what we're asking
+ * about is not enabled" or "all the flags
+ * are clear (i.e., nothing is enabled)".
+ */
+ return 0;
+ }
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: SIOETHTOOL(%s) ioctl failed: %s", handle->opt.source,
+ cmdname, strerror(errno));
+ return -1;
+ }
+ return eval.data;
+}
+
+static int
+iface_get_offload(pcap_t *handle)
+{
+ int ret;
+
+#ifdef ETHTOOL_GTSO
+ ret = iface_ethtool_ioctl(handle, ETHTOOL_GTSO, "ETHTOOL_GTSO");
+ if (ret == -1)
+ return -1;
+ if (ret)
+ return 1; /* TCP segmentation offloading on */
+#endif
+
+#ifdef ETHTOOL_GUFO
+ ret = iface_ethtool_ioctl(handle, ETHTOOL_GUFO, "ETHTOOL_GUFO");
+ if (ret == -1)
+ return -1;
+ if (ret)
+ return 1; /* UDP fragmentation offloading on */
+#endif
+
+#ifdef ETHTOOL_GGSO
+ /*
+ * XXX - will this cause large unsegmented packets to be
+ * handed to PF_PACKET sockets on transmission? If not,
+ * this need not be checked.
+ */
+ ret = iface_ethtool_ioctl(handle, ETHTOOL_GGSO, "ETHTOOL_GGSO");
+ if (ret == -1)
+ return -1;
+ if (ret)
+ return 1; /* generic segmentation offloading on */
+#endif
+
+#ifdef ETHTOOL_GFLAGS
+ ret = iface_ethtool_ioctl(handle, ETHTOOL_GFLAGS, "ETHTOOL_GFLAGS");
+ if (ret == -1)
+ return -1;
+ if (ret & ETH_FLAG_LRO)
+ return 1; /* large receive offloading on */
+#endif
+
+#ifdef ETHTOOL_GGRO
+ /*
+ * XXX - will this cause large reassembled packets to be
+ * handed to PF_PACKET sockets on receipt? If not,
+ * this need not be checked.
+ */
+ ret = iface_ethtool_ioctl(handle, ETHTOOL_GGRO, "ETHTOOL_GGRO");
+ if (ret == -1)
+ return -1;
+ if (ret)
+ return 1; /* generic (large) receive offloading on */
+#endif
+
+ return 0;
+}
+#else /* SIOCETHTOOL */
+static int
+iface_get_offload(pcap_t *handle _U_)
+{
+ /*
+ * XXX - do we need to get this information if we don't
+ * have the ethtool ioctls? If so, how do we do that?
+ */
+ return 0;
+}
+#endif /* SIOCETHTOOL */
+
#endif /* HAVE_PF_PACKET_SOCKETS */
/* ===== Functions to interface to the older kernels ================== */
@@ -4363,7 +5028,18 @@ activate_old(pcap_t *handle)
if (handle->fd == -1) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
- return PCAP_ERROR_PERM_DENIED;
+ if (errno == EPERM || errno == EACCES) {
+ /*
+ * You don't have permission to open the
+ * socket.
+ */
+ return PCAP_ERROR_PERM_DENIED;
+ } else {
+ /*
+ * Other error.
+ */
+ return PCAP_ERROR;
+ }
}
/* It worked - we are using the old interface */
diff --git a/pcap-stdinc.h b/pcap-stdinc.h
index f025013ce30b..f1c736e50ef3 100644
--- a/pcap-stdinc.h
+++ b/pcap-stdinc.h
@@ -33,13 +33,6 @@
#ifndef pcap_stdinc_h
#define pcap_stdinc_h
-#define SIZEOF_CHAR 1
-#define SIZEOF_SHORT 2
-#define SIZEOF_INT 4
-#ifndef _MSC_EXTENSIONS
-#define SIZEOF_LONG_LONG 8
-#endif
-
/*
* Avoids a compiler warning in case this was already defined
* (someone defined _WINSOCKAPI_ when including 'windows.h', in order
diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c
index fea527f4f9e1..f1b430c7bda9 100644
--- a/pcap-usb-linux.c
+++ b/pcap-usb-linux.c
@@ -61,8 +61,15 @@ static const char rcsid[] _U_ =
#include <sys/ioctl.h>
#include <sys/mman.h>
#ifdef HAVE_LINUX_USBDEVICE_FS_H
+/*
+ * We might need <linux/compiler.h> to define __user for
+ * <linux/usbdevice_fs.h>.
+ */
+#ifdef HAVE_LINUX_COMPILER_H
+#include <linux/compiler.h>
+#endif /* HAVE_LINUX_COMPILER_H */
#include <linux/usbdevice_fs.h>
-#endif
+#endif /* HAVE_LINUX_USBDEVICE_FS_H */
#define USB_IFACE "usbmon"
#define USB_TEXT_DIR_OLD "/sys/kernel/debug/usbmon"
@@ -122,7 +129,6 @@ static int usb_read_linux(pcap_t *, int , pcap_handler , u_char *);
static int usb_read_linux_bin(pcap_t *, int , pcap_handler , u_char *);
static int usb_read_linux_mmap(pcap_t *, int , pcap_handler , u_char *);
static int usb_inject_linux(pcap_t *, const void *, size_t);
-static int usb_setfilter_linux(pcap_t *, struct bpf_program *);
static int usb_setdirection_linux(pcap_t *, pcap_direction_t);
static void usb_cleanup_linux_mmap(pcap_t *);
@@ -301,7 +307,7 @@ usb_activate(pcap_t* handle)
handle->linktype = DLT_USB_LINUX;
handle->inject_op = usb_inject_linux;
- handle->setfilter_op = usb_setfilter_linux;
+ handle->setfilter_op = install_bpf_program; /* no kernel filtering */
handle->setdirection_op = usb_setdirection_linux;
handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd;
@@ -597,12 +603,17 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
got:
uhdr->data_len = data_len;
- handle->md.packets_read++;
if (pkth.caplen > handle->snapshot)
pkth.caplen = handle->snapshot;
- callback(user, &pkth, handle->buffer);
- return 1;
+ if (handle->fcode.bf_insns == NULL ||
+ bpf_filter(handle->fcode.bf_insns, handle->buffer,
+ pkth.len, pkth.caplen)) {
+ handle->md.packets_read++;
+ callback(user, &pkth, handle->buffer);
+ return 1;
+ }
+ return 0; /* didn't pass filter */
}
static int
@@ -689,12 +700,6 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
}
static int
-usb_setfilter_linux(pcap_t *p, struct bpf_program *fp)
-{
- return 0;
-}
-
-static int
usb_setdirection_linux(pcap_t *p, pcap_direction_t d)
{
p->direction = d;
@@ -767,9 +772,15 @@ usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_cha
pkth.ts.tv_sec = info.hdr->ts_sec;
pkth.ts.tv_usec = info.hdr->ts_usec;
- handle->md.packets_read++;
- callback(user, &pkth, handle->buffer);
- return 1;
+ if (handle->fcode.bf_insns == NULL ||
+ bpf_filter(handle->fcode.bf_insns, handle->buffer,
+ pkth.len, pkth.caplen)) {
+ handle->md.packets_read++;
+ callback(user, &pkth, handle->buffer);
+ return 1;
+ }
+
+ return 0; /* didn't pass filter */
}
/*
@@ -841,9 +852,13 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
pkth.ts.tv_sec = hdr->ts_sec;
pkth.ts.tv_usec = hdr->ts_usec;
- handle->md.packets_read++;
- callback(user, &pkth, (u_char*) hdr);
- packets++;
+ if (handle->fcode.bf_insns == NULL ||
+ bpf_filter(handle->fcode.bf_insns, (u_char*) hdr,
+ pkth.len, pkth.caplen)) {
+ handle->md.packets_read++;
+ callback(user, &pkth, (u_char*) hdr);
+ packets++;
+ }
}
/* with max_packets <= 0 we stop afer the first chunk*/
diff --git a/pcap-win32.c b/pcap-win32.c
index 0e2201e36f56..d8ed453510d9 100644
--- a/pcap-win32.c
+++ b/pcap-win32.c
@@ -39,7 +39,12 @@ static const char rcsid[] _U_ =
#include <pcap-int.h>
#include <Packet32.h>
#ifdef __MINGW32__
+#ifdef __MINGW64__
+#include <ntddndis.h>
+#else /*__MINGW64__*/
+#include <ddk/ntddndis.h>
#include <ddk/ndis.h>
+#endif /*__MINGW64__*/
#else /*__MINGW32__*/
#include <ntddndis.h>
#endif /*__MINGW32__*/
@@ -232,7 +237,7 @@ pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
* XXX A bpf_hdr matches a pcap_pkthdr.
*/
(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
- bp += BPF_WORDALIGN(caplen + hdrlen);
+ bp += Packet_WORDALIGN(caplen + hdrlen);
if (++n >= cnt && cnt > 0) {
p->bp = bp;
p->cc = ep - bp;
diff --git a/pcap.3pcap.in b/pcap.3pcap.in
index c2f912663b67..6f99cc519de4 100644
--- a/pcap.3pcap.in
+++ b/pcap.3pcap.in
@@ -37,22 +37,51 @@ on the network, even those destined for other hosts, are accessible
through this mechanism.
It also supports saving captured packets to a ``savefile'', and reading
packets from a ``savefile''.
-.PP
-To open a handle for a live capture, call
-.BR pcap_create() ,
+.SS Opening a capture handle for reading
+To open a handle for a live capture, given the name of the network or
+other interface on which the capture should be done, call
+.BR pcap_create (),
set the appropriate options on the handle, and then activate it with
-.BR pcap_activate() .
-To open a handle for a ``savefile'' with captured packets, call
-.BR pcap_open_offline() .
-Both
-.B pcap_create()
+.BR pcap_activate ().
+.PP
+To obtain a list of devices that can be opened for a live capture, call
+.BR pcap_findalldevs ();
+to free the list returned by
+.BR pcap_findalldevs (),
+call
+.BR pcap_freealldevs ().
+.BR pcap_lookupdev ()
+will return the first device on that list that is not a ``loopback``
+network interface.
+.PP
+To open a handle for a ``savefile'' from which to read packets, given the
+pathname of the ``savefile'', call
+.BR pcap_open_offline ();
+to set up a handle for a ``savefile'', given a
+.B "FILE\ *"
+referring to a file already opened for reading, call
+.BR pcap_fopen_offline ().
+.PP
+In order to get a ``fake''
+.B pcap_t
+for use in routines that require a
+.B pcap_t
+as an argument, such as routines to open a ``savefile'' for writing and
+to compile a filter expression, call
+.BR pcap_open_dead ().
+.PP
+.BR pcap_create (),
+.BR pcap_open_offline (),
+.BR pcap_fopen_offline (),
and
-.B pcap_open_offline()
+.BR pcap_open_dead ()
return a pointer to a
.BR pcap_t ,
which is the handle used for reading packets from the capture stream or
the ``savefile'', and for finding out information about the capture
stream or ``savefile''.
+To close a handle, use
+.BR pcap_close ().
.PP
The options that can be set on a capture handle include
.IP "snapshot length"
@@ -75,7 +104,7 @@ A snapshot length of 65535 should be sufficient, on most if not all
networks, to capture all the data available from the packet.
.IP
The snapshot length is set with
-.BR pcap_set_snaplen() .
+.BR pcap_set_snaplen ().
.IP "promiscuous mode"
On broadcast LANs such as Ethernet, if the network isn't switched, or if
the adapter is connected to a "mirror port" on a switch to which all
@@ -97,7 +126,7 @@ For now, this doesn't work on the "any" device; if an argument of "any"
or NULL is supplied, the setting of promiscuous mode is ignored.
.IP
Promiscuous mode is set with
-.BR pcap_set_promisc() .
+.BR pcap_set_promisc ().
.IP "monitor mode"
On IEEE 802.11 wireless LANs, even if an adapter is in promiscuous mode,
it will supply to the host only frames for the network with which it's
@@ -118,9 +147,9 @@ if you are capturing in monitor mode and are not connected to another
network with another adapter.
.IP
Monitor mode is set with
-.BR pcap_set_rfmon() ,
+.BR pcap_set_rfmon (),
and
-.B pcap_can_set_rfmon()
+.BR pcap_can_set_rfmon ()
can be used to determine whether an adapter can be put into monitor
mode.
.IP "read timeout"
@@ -162,7 +191,7 @@ guarantee that a call reading packets will return after the timeout
expires even if no packets have arrived.
.IP
The read timeout is set with
-.BR pcap_set_timeout() .
+.BR pcap_set_timeout ().
.IP "buffer size"
Packets that arrive for a capture are stored in a buffer, so that they
do not have to be read by the application as soon as they arrive. On
@@ -175,7 +204,17 @@ non-pageable operating system memory than is necessary to prevent
packets from being dropped.
.IP
The buffer size is set with
-.BR pcap_set_buffer_size() .
+.BR pcap_set_buffer_size ().
+.IP "timestamp type"
+On some platforms, the time stamp given to packets on live captures can
+come from different sources that can have different resolutions or that
+can have different relationships to the time values for the current time
+supplied by routines on the native operating system. See
+.BR pcap-tstamp (@MAN_MISC_INFO@)
+for a list of time stamp types.
+.IP
+The time stamp type is set with
+.BR pcap_set_tstamp_type ().
.PP
Reading packets from a network interface may require that you have
special privileges:
@@ -260,26 +299,193 @@ have to find some other way to make that happen at boot time.
.PP
Reading a saved packet file doesn't require special privileges.
.PP
-To open a ``savefile`` to which to write packets, call
-.BR pcap_dump_open() .
-It returns a pointer to a
-.BR pcap_dumper_t ,
-which is the handle used for writing packets to the ``savefile''.
+The packets read from the handle may include a ``pseudo-header''
+containing various forms of packet meta-data, and probably includes a
+link-layer header whose contents can differ for different network
+interfaces. To determine the format of the packets supplied by the
+handle, call
+.BR pcap_datalink ();
+.I http://www.tcpdump.org/linktypes.html
+lists the values it returns and describes the packet formats that
+correspond to those values.
.PP
+To obtain the
+.B "FILE\ *"
+corresponding to a
+.B pcap_t
+opened for a ``savefile'', call
+.BR pcap_file ().
+.TP
+.B Routines
+.RS
+.TP
+.BR pcap_create (3PCAP)
+get a
+.B pcap_t
+for live capture
+.TP
+.BR pcap_activate (3PCAP)
+activate a
+.B pcap_t
+for live capture
+.TP
+.BR pcap_findalldevs (3PCAP)
+get a list of devices that can be opened for a live capture
+.TP
+.BR pcap_freealldevs (3PCAP)
+free list of devices
+.TP
+.BR pcap_lookupdev (3PCAP)
+get first non-loopback device on that list
+.TP
+.BR pcap_open_offline (3PCAP)
+open a
+.B pcap_t
+for a ``savefile'', given a pathname
+.TP
+.BR pcap_fopen_offline (3PCAP)
+open a
+.B pcap_t
+for a ``savefile'', given a
+.B "FILE\ *"
+.TP
+.BR pcap_open_dead (3PCAP)
+create a ``fake''
+.B pcap_t
+.TP
+.BR pcap_close (3PCAP)
+close a
+.B pcap_t
+.TP
+.BR pcap_set_snaplen (3PCAP)
+set the snapshot length for a not-yet-activated
+.B pcap_t
+for live capture
+.TP
+.BR pcap_snapshot (3PCAP)
+get the snapshot length for a
+.B pcap_t
+.TP
+.BR pcap_set_promisc (3PCAP)
+set promiscuous mode for a not-yet-activated
+.B pcap_t
+for live capture
+.TP
+.BR pcap_set_rfmon (3PCAP)
+set monitor mode for a not-yet-activated
+.B pcap_t
+for live capture
+.TP
+.BR pcap_can_set_rfmon (3PCAP)
+determine whether monitor mode can be set for a
+.B pcap_t
+for live capture
+.TP
+.BR pcap_set_timeout (3PCAP)
+set read timeout for a not-yet-activated
+.B pcap_t
+for live capture
+.TP
+.BR pcap_set_buffer_size (3PCAP)
+set buffer size for a not-yet-activated
+.B pcap_t
+for live capture
+.TP
+.BR pcap_set_tstamp_type (3PCAP)
+set time stamp type for a not-yet-activated
+.B pcap_t
+for live capture
+.TP
+.BR pcap_list_tstamp_types (3PCAP)
+get list of available time stamp types for a not-yet-activated
+.B pcap_t
+for live capture
+.TP
+.BR pcap_free_tstamp_types (3PCAP)
+free list of available time stamp types
+.TP
+.BR pcap_tstamp_type_val_to_name (3PCAP)
+get name for a time stamp type
+.TP
+.BR pcap_tstamp_type_val_to_description (3PCAP)
+get description for a time stamp type
+.TP
+.BR pcap_tstamp_name_to_val (3PCAP)
+get time stamp type corresponding to a name
+.TP
+.BR pcap_datalink (3PCAP)
+get link-layer header type for a
+.B pcap_t
+.TP
+.BR pcap_file (3PCAP)
+get the
+.B "FILE\ *"
+for a
+.B pcap_t
+opened for a ``savefile''
+.TP
+.BR pcap_is_swapped (3PCAP)
+determine whether a ``savefile'' being read came from a machine with the
+opposite byte order
+.TP
+.BR pcap_major_version (3PCAP)
+.PD 0
+.TP
+.BR pcap_minor_version (3PCAP)
+get the major and minor version of the file format version for a
+``savefile''
+.PD
+.RE
+.SS Selecting a link-layer header type for a live capture
+Some devices may provide more than one link-layer header type. To
+obtain a list of all link-layer header types provided by a device, call
+.BR pcap_list_datalinks ()
+on an activated
+.B pcap_t
+for the device.
+To free a list of link-layer header types, call
+.BR pcap_free_datalinks ().
+To set the link-layer header type for a device, call
+.BR pcap_set_datalink ().
+This should be done after the device has been activated but before any
+packets are read and before any filters are compiled or installed.
+.TP
+.B Routines
+.RS
+.TP
+.BR pcap_list_datalinks (3PCAP)
+get a list of link-layer header types for a device
+.TP
+.BR pcap_free_datalinks (3PCAP)
+free list of link-layer header types
+.TP
+.BR pcap_set_datalink (3PCAP)
+set link-layer header type for a device
+.TP
+.BR pcap_datalink_val_to_name (3PCAP)
+get name for a link-layer header type
+.TP
+.BR pcap_datalink_val_to_description (3PCAP)
+get description for a link-layer header type
+.TP
+.BR pcap_datalink_name_to_val (3PCAP)
+get link-layer header type corresponding to a name
+.RE
+.SS Reading packets
Packets are read with
-.B pcap_dispatch()
+.BR pcap_dispatch ()
or
-.BR pcap_loop() ,
+.BR pcap_loop (),
which process one or more packets, calling a callback routine for each
packet, or with
-.B pcap_next()
+.BR pcap_next ()
or
-.BR pcap_next_ex() ,
+.BR pcap_next_ex (),
which return the next packet.
The callback for
-.B pcap_dispatch()
+.BR pcap_dispatch ()
and
-.BR pcap_loop()
+.BR pcap_loop ()
is supplied a pointer to a
.IR "struct pcap_pkthdr" ,
which includes the following members:
@@ -304,9 +510,9 @@ number of bytes available from the capture, if the length of the packet
is larger than the maximum number of bytes to capture).
.RE
.PP
-.B pcap_next_ex()
+.BR pcap_next_ex ()
supplies that pointer through a pointer argument.
-.B pcap_next()
+.BR pcap_next ()
is passed an argument that points to a
.I struct pcap_pkthdr
structure, and fills it in.
@@ -323,15 +529,306 @@ packet; to capture the entire packet, you will have to provide a value
for
.I snaplen
in your call to
-.B pcap_open_live()
+.BR pcap_set_snaplen ()
that is sufficiently large to get all of the packet's data - a value of
65535 should be sufficient on most if not all networks). When reading
from a ``savefile'', the snapshot length specified when the capture was
performed will limit the amount of packet data available.
-.B pcap_next()
+.BR pcap_next ()
returns that pointer;
-.B pcap_next_ex()
+.BR pcap_next_ex ()
supplies that pointer through a pointer argument.
+.PP
+To force the loop in
+.BR pcap_dispatch ()
+or
+.BR pcap_loop ()
+to terminate, call
+.BR pcap_breakloop ().
+.PP
+By default, when reading packets from an interface opened for a live
+capture,
+.BR pcap_dispatch (),
+.BR pcap_next (),
+and
+.BR pcap_next_ex ()
+will, if no packets are currently available to be read, block waiting
+for packets to become available. On some, but
+.I not
+all, platforms, if a read timeout was specified, the wait will terminate
+after the read timeout expires; applications should be prepared for
+this, as it happens on some platforms, but should not rely on it, as it
+does not happen on other platforms.
+.PP
+A handle can be put into ``non-blocking mode'', so that those routines
+will, rather than blocking, return an indication that no packets are
+available to read. Call
+.BR pcap_setnonblock ()
+to put a handle into non-blocking mode or to take it out of non-blocking
+mode; call
+.BR pcap_getnonblock ()
+to determine whether a handle is in non-blocking mode. Note that
+non-blocking mode does not work correctly in Mac OS X 10.6.
+.PP
+Non-blocking mode is often combined with routines such as
+.BR select (2)
+or
+.BR poll (2)
+or other routines a platform offers to wait for the availability of data
+on any of a set of descriptors. To obtain, for a handle, a descriptor
+that can be used in those routines, call
+.BR pcap_get_selectable_fd ().
+Not all handles have such a descriptor available;
+.BR pcap_get_selectable_fd ()
+will return \-1 if no such descriptor exists. In addition, for various
+reasons, one or more of those routines will not work properly with the
+descriptor; the documentation for
+.BR pcap_get_selectable_fd ()
+gives details.
+.TP
+.B Routines
+.RS
+.TP
+.BR pcap_dispatch (3PCAP)
+read a bufferful of packets from a
+.B pcap_t
+open for a live capture or the full set of packets from a
+.B pcap_t
+open for a ``savefile''
+.TP
+.BR pcap_loop (3PCAP)
+read packets from a
+.B pcap_t
+until an interrupt or error occurs
+.TP
+.BR pcap_next (3PCAP)
+read the next packet from a
+.B pcap_t
+without an indication whether an error occurred
+.TP
+.BR pcap_next_ex (3PCAP)
+read the next packet from a
+.B pcap_t
+with an error indication on an error
+.TP
+.BR pcap_breakloop (3PCAP)
+prematurely terminate the loop in
+.BR pcap_dispatch ()
+or
+.BR pcap_loop ()
+.TP
+.BR pcap_setnonblock (3PCAP)
+set or clear non-blocking mode on a
+.B pcap_t
+.TP
+.BR pcap_getnonblock (3PCAP)
+get the state of non-blocking mode for a
+.B pcap_t
+.TP
+.BR pcap_get_selectable_fd (3PCAP)
+attempt to get a descriptor for a
+.B pcap_t
+that can be used in calls such as
+.BR select (2)
+and
+.BR poll (2)
+.RE
+.SS Filters
+In order to cause only certain packets to be returned when reading
+packets, a filter can be set on a handle. For a live capture, the
+filtering will be performed in kernel mode, if possible, to avoid
+copying ``uninteresting'' packets from the kernel to user mode.
+.PP
+A filter can be specified as a text string; the syntax and semantics of
+the string are as described by
+.BR pcap-filter (@MAN_MISC_INFO@).
+A filter string is compiled into a program in a pseudo-machine-language
+by
+.BR pcap_compile ()
+and the resulting program can be made a filter for a handle with
+.BR pcap_setfilter ().
+The result of
+.BR pcap_compile ()
+can be freed with a call to
+.BR pcap_freecode ().
+.BR pcap_compile ()
+may require a network mask for certain expressions in the filter string;
+.BR pcap_lookupnet ()
+can be used to find the network address and network mask for a given
+capture device.
+.PP
+A compiled filter can also be applied directly to a packet that has been
+read using
+.BR pcap_offline_filter ().
+.TP
+.B Routines
+.RS
+.TP
+.BR pcap_compile (3PCAP)
+compile filter expression to a pseudo-machine-language code program
+.TP
+.BR pcap_freecode (3PCAP)
+free a filter program
+.TP
+.BR pcap_setfilter (3PCAP)
+set filter for a
+.B pcap_t
+.TP
+.BR pcap_lookupnet (3PCAP)
+get network address and network mask for a capture device
+.TP
+.BR pcap_offline_filter (3PCAP)
+apply a filter program to a packet
+.RE
+.SS Incoming and outgoing packets
+By default, libpcap will attempt to capture both packets sent by the
+machine and packets received by the machine. To limit it to capturing
+only packets received by the machine or, if possible, only packets sent
+by the machine, call
+.BR pcap_setdirection ().
+.TP
+.BR Routines
+.RS
+.TP
+.BR pcap_setdirection (3PCAP)
+specify whether to capture incoming packets, outgoing packets, or both
+.RE
+.SS Capture statistics
+To get statistics about packets received and dropped in a live capture,
+call
+.BR pcap_stats ().
+.TP
+.B Routines
+.RS
+.TP
+.BR pcap_stats (3PCAP)
+get capture statistics
+.RE
+.SS Opening a handle for writing captured packets
+To open a ``savefile`` to which to write packets, given the pathname the
+``savefile'' should have, call
+.BR pcap_dump_open ().
+To open a ``savefile`` to which to write packets, given the pathname the
+``savefile'' should have, call
+.BR pcap_dump_open ();
+to set up a handle for a ``savefile'', given a
+.B "FILE\ *"
+referring to a file already opened for writing, call
+.BR pcap_dump_fopen ().
+They each return pointers to a
+.BR pcap_dumper_t ,
+which is the handle used for writing packets to the ``savefile''. If it
+succeeds, it will have created the file if it doesn't exist and
+truncated the file if it does exist.
+To close a
+.BR pcap_dumper_t ,
+call
+.BR pcap_dump_close ().
+.TP
+.B Routines
+.RS
+.TP
+.BR pcap_dump_open (3PCAP)
+open a
+.B pcap_dumper_t
+for a ``savefile``, given a pathname
+.TP
+.BR pcap_dump_fopen (3PCAP)
+open a
+.B pcap_dumper_t
+for a ``savefile``, given a
+.B "FILE\ *"
+.TP
+.BR pcap_dump_close (3PCAP)
+close a
+.B pcap_dumper_t
+.TP
+.BR pcap_dump_file (3PCAP)
+get the
+.B "FILE\ *"
+for a
+.B pcap_dumper_t
+opened for a ``savefile''
+.RE
+.SS Writing packets
+To write a packet to a
+.BR pcap_dumper_t ,
+call
+.BR pcap_dump ().
+Packets written with
+.BR pcap_dump ()
+may be buffered, rather than being immediately written to the
+``savefile''. Closing the
+.B pcap_dumper_t
+will cause all buffered-but-not-yet-written packets to be written to the
+``savefile''.
+To force all packets written to the
+.BR pcap_dumper_t ,
+and not yet written to the ``savefile'' because they're buffered by the
+.BR pcap_dumper_t ,
+to be written to the ``savefile'', without closing the
+.BR pcap_dumper_t ,
+call
+.BR pcap_dump_flush ().
+.TP
+.B Routines
+.RS
+.TP
+.BR pcap_dump (3PCAP)
+write packet to a
+.B pcap_dumper_t
+.TP
+.BR pcap_dump_flush (3PCAP)
+flush buffered packets written to a
+.B pcap_dumper_t
+to the ``savefile''
+.TP
+.BR pcap_dump_ftell (3PCAP)
+get current file position for a
+.B pcap_dumper_t
+.RE
+.SS Injecting packets
+If you have the required privileges, you can inject packets onto a
+network with a
+.B pcap_t
+for a live capture, using
+.BR pcap_inject ()
+or
+.BR pcap_sendpacket ().
+(The two routines exist for compatibility with both OpenBSD and WinPcap;
+they perform the same function, but have different return values.)
+.TP
+.B Routines
+.RS
+.TP
+.BR pcap_inject (3PCAP)
+.PD 0
+.TP
+.BR pcap_sendpacket (3PCAP)
+transmit a packet
+.PD
+.RE
+.SS Reporting errors
+Some routines return error or warning status codes; to convert them to a
+string, use
+.BR pcap_statustostr ().
+.TP
+.B Routines
+.RS
+.TP
+.BR pcap_statustostr (3PCAP)
+get a string for an error or warning status code
+.RE
+.SS Getting library version information
+To get a string giving version information about libpcap, call
+.BR pcap_library_version ().
+.TP
+.B Routines
+.RS
+.TP
+.BR pcap_library_version (3PCAP)
+get library version string
+.RE
.SH BACKWARDS COMPATIBILITY
.PP
In versions of libpcap prior to 1.0, the
@@ -346,18 +843,18 @@ which will include
for you, rather than including
.BR <pcap/pcap.h> .
.PP
-.B pcap_create()
+.BR pcap_create ()
and
-.B pcap_activate()
+.BR pcap_activate ()
were not available in versions of libpcap prior to 1.0; if you are
writing an application that must work on versions of libpcap prior to
1.0, either use
-.B pcap_open_live()
+.BR pcap_open_live ()
to get a handle for a live capture or, if you want to be able to use the
additional capabilities offered by using
-.B pcap_create()
+.BR pcap_create ()
and
-.BR pcap_activate() ,
+.BR pcap_activate (),
use an
.BR autoconf (1)
script or some other configuration script to check whether the libpcap
diff --git a/pcap.c b/pcap.c
index 8c5959fee85e..b0146a7bd9b0 100644
--- a/pcap.c
+++ b/pcap.c
@@ -57,7 +57,7 @@ static const char rcsid[] _U_ =
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#if !defined(_MSC_VER) && !defined(__BORLANDC__)
+#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__MINGW32__)
#include <unistd.h>
#endif
#include <fcntl.h>
@@ -82,7 +82,7 @@ int
pcap_not_initialized(pcap_t *pcap)
{
/* this means 'not initialized' */
- return PCAP_ERROR_NOT_ACTIVATED;
+ return (PCAP_ERROR_NOT_ACTIVATED);
}
/*
@@ -105,6 +105,56 @@ pcap_cant_set_rfmon(pcap_t *p _U_)
}
/*
+ * Sets *tstamp_typesp to point to an array 1 or more supported time stamp
+ * types; the return value is the number of supported time stamp types.
+ * The list should be freed by a call to pcap_free_tstamp_types() when
+ * you're done with it.
+ *
+ * A return value of 0 means "you don't get a choice of time stamp type",
+ * in which case *tstamp_typesp is set to null.
+ *
+ * PCAP_ERROR is returned on error.
+ */
+int
+pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
+{
+ if (p->tstamp_type_count == 0) {
+ /*
+ * We don't support multiple time stamp types.
+ */
+ *tstamp_typesp = NULL;
+ } else {
+ *tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
+ p->tstamp_type_count);
+ if (*tstamp_typesp == NULL) {
+ (void)snprintf(p->errbuf, sizeof(p->errbuf),
+ "malloc: %s", pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ (void)memcpy(*tstamp_typesp, p->tstamp_type_list,
+ sizeof(**tstamp_typesp) * p->tstamp_type_count);
+ }
+ return (p->tstamp_type_count);
+}
+
+/*
+ * In Windows, you might have a library built with one version of the
+ * C runtime library and an application built with another version of
+ * the C runtime library, which means that the library might use one
+ * version of malloc() and free() and the application might use another
+ * version of malloc() and free(). If so, that means something
+ * allocated by the library cannot be freed by the application, so we
+ * need to have a pcap_free_tstamp_types() routine to free up the list
+ * allocated by pcap_list_tstamp_types(), even though it's just a wrapper
+ * around free().
+ */
+void
+pcap_free_tstamp_types(int *tstamp_type_list)
+{
+ free(tstamp_type_list);
+}
+
+/*
* Default one-shot callback; overridden for capture types where the
* packet data cannot be guaranteed to be available after the callback
* returns, so that a copy must be made.
@@ -149,7 +199,8 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
int status;
/* We are on an offline capture */
- status = pcap_offline_read(p, 1, pcap_oneshot, (u_char *)&s);
+ status = pcap_offline_read(p, 1, p->oneshot_callback,
+ (u_char *)&s);
/*
* Return codes for pcap_offline_read() are:
@@ -178,7 +229,7 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
* The first one ('0') conflicts with the return code of 0 from
* pcap_offline_read() meaning "end of file".
*/
- return (p->read_op(p, 1, pcap_oneshot, (u_char *)&s));
+ return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s));
}
static void
@@ -258,6 +309,7 @@ pcap_create_common(const char *source, char *ebuf)
pcap_set_snaplen(p, 65535); /* max packet size */
p->opt.promisc = 0;
p->opt.buffer_size = 0;
+ p->opt.tstamp_type = -1; /* default to not setting time stamp type */
return (p);
}
@@ -267,54 +319,89 @@ pcap_check_activated(pcap_t *p)
if (p->activated) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform "
" operation on activated capture");
- return -1;
+ return (-1);
}
- return 0;
+ return (0);
}
int
pcap_set_snaplen(pcap_t *p, int snaplen)
{
if (pcap_check_activated(p))
- return PCAP_ERROR_ACTIVATED;
+ return (PCAP_ERROR_ACTIVATED);
p->snapshot = snaplen;
- return 0;
+ return (0);
}
int
pcap_set_promisc(pcap_t *p, int promisc)
{
if (pcap_check_activated(p))
- return PCAP_ERROR_ACTIVATED;
+ return (PCAP_ERROR_ACTIVATED);
p->opt.promisc = promisc;
- return 0;
+ return (0);
}
int
pcap_set_rfmon(pcap_t *p, int rfmon)
{
if (pcap_check_activated(p))
- return PCAP_ERROR_ACTIVATED;
+ return (PCAP_ERROR_ACTIVATED);
p->opt.rfmon = rfmon;
- return 0;
+ return (0);
}
int
pcap_set_timeout(pcap_t *p, int timeout_ms)
{
if (pcap_check_activated(p))
- return PCAP_ERROR_ACTIVATED;
+ return (PCAP_ERROR_ACTIVATED);
p->md.timeout = timeout_ms;
- return 0;
+ return (0);
+}
+
+int
+pcap_set_tstamp_type(pcap_t *p, int tstamp_type)
+{
+ int i;
+
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+
+ /*
+ * If p->tstamp_type_count is 0, we don't support setting
+ * the time stamp type at all.
+ */
+ if (p->tstamp_type_count == 0)
+ return (PCAP_ERROR_CANTSET_TSTAMP_TYPE);
+
+ /*
+ * Check whether we claim to support this type of time stamp.
+ */
+ for (i = 0; i < p->tstamp_type_count; i++) {
+ if (p->tstamp_type_list[i] == tstamp_type) {
+ /*
+ * Yes.
+ */
+ p->opt.tstamp_type = tstamp_type;
+ return (0);
+ }
+ }
+
+ /*
+ * No. We support setting the time stamp type, but not to this
+ * particular value.
+ */
+ return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP);
}
int
pcap_set_buffer_size(pcap_t *p, int buffer_size)
{
if (pcap_check_activated(p))
- return PCAP_ERROR_ACTIVATED;
+ return (PCAP_ERROR_ACTIVATED);
p->opt.buffer_size = buffer_size;
- return 0;
+ return (0);
}
int
@@ -322,6 +409,15 @@ pcap_activate(pcap_t *p)
{
int status;
+ /*
+ * Catch attempts to re-activate an already-activated
+ * pcap_t; this should, for example, catch code that
+ * calls pcap_open_live() followed by pcap_activate(),
+ * as some code that showed up in a Stack Exchange
+ * question did.
+ */
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
status = p->activate_op(p);
if (status >= 0)
p->activated = 1;
@@ -384,7 +480,8 @@ fail:
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
p->errbuf);
else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
- status == PCAP_ERROR_PERM_DENIED)
+ status == PCAP_ERROR_PERM_DENIED ||
+ status == PCAP_ERROR_PROMISC_PERM_DENIED)
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source,
pcap_statustostr(status), p->errbuf);
else
@@ -397,7 +494,7 @@ fail:
int
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
- return p->read_op(p, cnt, callback, user);
+ return (p->read_op(p, cnt, callback, user));
}
/*
@@ -407,7 +504,7 @@ int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
- return p->read_op(p, cnt, callback, user);
+ return (p->read_op(p, cnt, callback, user));
}
int
@@ -571,6 +668,91 @@ unsupported:
return (-1);
}
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+static const u_char charmap[] = {
+ (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003',
+ (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007',
+ (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013',
+ (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017',
+ (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023',
+ (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027',
+ (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033',
+ (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037',
+ (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043',
+ (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047',
+ (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053',
+ (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057',
+ (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063',
+ (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067',
+ (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073',
+ (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077',
+ (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143',
+ (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
+ (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
+ (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
+ (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
+ (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
+ (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133',
+ (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137',
+ (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143',
+ (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
+ (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
+ (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
+ (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
+ (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
+ (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173',
+ (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177',
+ (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203',
+ (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207',
+ (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213',
+ (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217',
+ (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223',
+ (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227',
+ (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233',
+ (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237',
+ (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243',
+ (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247',
+ (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253',
+ (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257',
+ (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263',
+ (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267',
+ (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273',
+ (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277',
+ (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343',
+ (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
+ (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
+ (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
+ (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
+ (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
+ (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333',
+ (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337',
+ (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343',
+ (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
+ (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
+ (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
+ (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
+ (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
+ (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373',
+ (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377',
+};
+
+int
+pcap_strcasecmp(const char *s1, const char *s2)
+{
+ register const u_char *cm = charmap,
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ while (cm[*us1] == cm[*us2++])
+ if (*us1++ == '\0')
+ return(0);
+ return (cm[*us1] - cm[*--us2]);
+}
+
struct dlt_choice {
const char *name;
const char *description;
@@ -653,7 +835,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_PPI, "Per-Packet Information"),
DLT_CHOICE(DLT_IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"),
DLT_CHOICE(DLT_JUNIPER_ISM, "Juniper Integrated Service Module"),
- DLT_CHOICE(DLT_IEEE802_15_4, "IEEE 802.15.4"),
+ DLT_CHOICE(DLT_IEEE802_15_4, "IEEE 802.15.4 with FCS"),
DLT_CHOICE(DLT_SITA, "SITA pseudo-header"),
DLT_CHOICE(DLT_ERF, "Endace ERF header"),
DLT_CHOICE(DLT_RAIF1, "Ethernet with u10 Networks pseudo-header"),
@@ -673,94 +855,19 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"),
DLT_CHOICE(DLT_IPV4, "Raw IPv4"),
DLT_CHOICE(DLT_IPV6, "Raw IPv6"),
+ DLT_CHOICE(DLT_IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"),
+ DLT_CHOICE(DLT_JUNIPER_VS, "Juniper Virtual Server"),
+ DLT_CHOICE(DLT_JUNIPER_SRX_E2E, "Juniper SRX E2E"),
+ DLT_CHOICE(DLT_JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"),
+ DLT_CHOICE(DLT_DVB_CI, "DVB-CI"),
+ DLT_CHOICE(DLT_JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"),
+ DLT_CHOICE(DLT_NFLOG, "Linux netfilter log messages"),
+ DLT_CHOICE(DLT_NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"),
+ DLT_CHOICE(DLT_NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"),
+ DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"),
DLT_CHOICE_SENTINEL
};
-/*
- * This array is designed for mapping upper and lower case letter
- * together for a case independent comparison. The mappings are
- * based upon ascii character sequences.
- */
-static const u_char charmap[] = {
- (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003',
- (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007',
- (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013',
- (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017',
- (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023',
- (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027',
- (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033',
- (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037',
- (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043',
- (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047',
- (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053',
- (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057',
- (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063',
- (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067',
- (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073',
- (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077',
- (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143',
- (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
- (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
- (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
- (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
- (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
- (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133',
- (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137',
- (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143',
- (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
- (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
- (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
- (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
- (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
- (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173',
- (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177',
- (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203',
- (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207',
- (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213',
- (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217',
- (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223',
- (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227',
- (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233',
- (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237',
- (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243',
- (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247',
- (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253',
- (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257',
- (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263',
- (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267',
- (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273',
- (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277',
- (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343',
- (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
- (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
- (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
- (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
- (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
- (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333',
- (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337',
- (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343',
- (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
- (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
- (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
- (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
- (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
- (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373',
- (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377',
-};
-
-int
-pcap_strcasecmp(const char *s1, const char *s2)
-{
- register const u_char *cm = charmap,
- *us1 = (const u_char *)s1,
- *us2 = (const u_char *)s2;
-
- while (cm[*us1] == cm[*us2++])
- if (*us1++ == '\0')
- return(0);
- return (cm[*us1] - cm[*--us2]);
-}
-
int
pcap_datalink_name_to_val(const char *name)
{
@@ -798,6 +905,57 @@ pcap_datalink_val_to_description(int dlt)
return (NULL);
}
+struct tstamp_type_choice {
+ const char *name;
+ const char *description;
+ int type;
+};
+
+static struct tstamp_type_choice tstamp_type_choices[] = {
+ { "host", "Host", PCAP_TSTAMP_HOST },
+ { "host_lowprec", "Host, low precision", PCAP_TSTAMP_HOST_LOWPREC },
+ { "host_hiprec", "Host, high precision", PCAP_TSTAMP_HOST_HIPREC },
+ { "adapter", "Adapter", PCAP_TSTAMP_ADAPTER },
+ { "adapter_unsynced", "Adapter, not synced with system time", PCAP_TSTAMP_ADAPTER_UNSYNCED },
+ { NULL, NULL, 0 }
+};
+
+int
+pcap_tstamp_type_name_to_val(const char *name)
+{
+ int i;
+
+ for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
+ if (pcap_strcasecmp(tstamp_type_choices[i].name, name) == 0)
+ return (tstamp_type_choices[i].type);
+ }
+ return (PCAP_ERROR);
+}
+
+const char *
+pcap_tstamp_type_val_to_name(int tstamp_type)
+{
+ int i;
+
+ for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
+ if (tstamp_type_choices[i].type == tstamp_type)
+ return (tstamp_type_choices[i].name);
+ }
+ return (NULL);
+}
+
+const char *
+pcap_tstamp_type_val_to_description(int tstamp_type)
+{
+ int i;
+
+ for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
+ if (tstamp_type_choices[i].type == tstamp_type)
+ return (tstamp_type_choices[i].description);
+ }
+ return (NULL);
+}
+
int
pcap_snapshot(pcap_t *p)
{
@@ -864,7 +1022,7 @@ pcap_geterr(pcap_t *p)
int
pcap_getnonblock(pcap_t *p, char *errbuf)
{
- return p->getnonblock_op(p, errbuf);
+ return (p->getnonblock_op(p, errbuf));
}
/*
@@ -896,7 +1054,7 @@ pcap_getnonblock_fd(pcap_t *p, char *errbuf)
int
pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
{
- return p->setnonblock_op(p, nonblock, errbuf);
+ return (p->setnonblock_op(p, nonblock, errbuf));
}
#if !defined(WIN32) && !defined(MSDOS)
@@ -976,6 +1134,9 @@ pcap_statustostr(int errnum)
case PCAP_WARNING:
return("Generic warning");
+ case PCAP_WARNING_TSTAMP_TYPE_NOTSUP:
+ return ("That type of time stamp is not supported by that device");
+
case PCAP_WARNING_PROMISC_NOTSUP:
return ("That device doesn't support promiscuous mode");
@@ -1005,6 +1166,12 @@ pcap_statustostr(int errnum)
case PCAP_ERROR_IFACE_NOT_UP:
return ("That device is not up");
+
+ case PCAP_ERROR_CANTSET_TSTAMP_TYPE:
+ return ("That device doesn't support setting the time stamp type");
+
+ case PCAP_ERROR_PROMISC_PERM_DENIED:
+ return ("You don't have permission to capture in promiscuous mode on that device");
}
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
return(ebuf);
@@ -1033,7 +1200,7 @@ pcap_strerror(int errnum)
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
- return p->setfilter_op(p, fp);
+ return (p->setfilter_op(p, fp));
}
/*
@@ -1048,15 +1215,15 @@ pcap_setdirection(pcap_t *p, pcap_direction_t d)
if (p->setdirection_op == NULL) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Setting direction is not implemented on this platform");
- return -1;
+ return (-1);
} else
- return p->setdirection_op(p, d);
+ return (p->setdirection_op(p, d));
}
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
- return p->stats_op(p, ps);
+ return (p->stats_op(p, ps));
}
static int
@@ -1071,7 +1238,7 @@ pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_)
int
pcap_setbuff(pcap_t *p, int dim)
{
- return p->setbuff_op(p, dim);
+ return (p->setbuff_op(p, dim));
}
static int
@@ -1085,7 +1252,7 @@ pcap_setbuff_dead(pcap_t *p, int dim)
int
pcap_setmode(pcap_t *p, int mode)
{
- return p->setmode_op(p, mode);
+ return (p->setmode_op(p, mode));
}
static int
@@ -1099,7 +1266,7 @@ pcap_setmode_dead(pcap_t *p, int mode)
int
pcap_setmintocopy(pcap_t *p, int size)
{
- return p->setmintocopy_op(p, size);
+ return (p->setmintocopy_op(p, size));
}
static int
@@ -1212,6 +1379,11 @@ pcap_cleanup_live_common(pcap_t *p)
p->dlt_list = NULL;
p->dlt_count = 0;
}
+ if (p->tstamp_type_list != NULL) {
+ free(p->tstamp_type_list);
+ p->tstamp_type_list = NULL;
+ p->tstamp_type_count = 0;
+ }
pcap_freecode(&p->fcode);
#if !defined(WIN32) && !defined(MSDOS)
if (p->fd >= 0) {
@@ -1248,7 +1420,7 @@ pcap_open_dead(int linktype, int snaplen)
#endif
p->cleanup_op = pcap_cleanup_dead;
p->activated = 1;
- return p;
+ return (p);
}
/*
diff --git a/pcap/bpf.h b/pcap/bpf.h
index eff892c42ccf..17d533cb477b 100644
--- a/pcap/bpf.h
+++ b/pcap/bpf.h
@@ -48,10 +48,30 @@
* "pcap-bpf.c" will include the native OS version, as it deals with
* the OS's BPF implementation.
*
- * XXX - should this all just be moved to "pcap.h"?
+ * At least two programs found by Google Code Search explicitly includes
+ * <pcap/bpf.h> (even though <pcap.h>/<pcap/pcap.h> includes it for you),
+ * so moving that stuff to <pcap/pcap.h> would break the build for some
+ * programs.
*/
-#ifndef BPF_MAJOR_VERSION
+/*
+ * If we've already included <net/bpf.h>, don't re-define this stuff.
+ * We assume BSD-style multiple-include protection in <net/bpf.h>,
+ * which is true of all but the oldest versions of FreeBSD and NetBSD,
+ * or Tru64 UNIX-style multiple-include protection (or, at least,
+ * Tru64 UNIX 5.x-style; I don't have earlier versions available to check),
+ * or AIX-style multiple-include protection (or, at least, AIX 5.x-style;
+ * I don't have earlier versions available to check).
+ *
+ * We do not check for BPF_MAJOR_VERSION, as that's defined by
+ * <linux/filter.h>, which is directly or indirectly included in some
+ * programs that also include pcap.h, and <linux/filter.h> doesn't
+ * define stuff we need.
+ *
+ * This also provides our own multiple-include protection.
+ */
+#if !defined(_NET_BPF_H_) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h)
+#define lib_pcap_bpf_h
#ifdef __cplusplus
extern "C" {
@@ -70,7 +90,9 @@ typedef u_int bpf_u_int32;
/*
* Alignment macros. BPF_WORDALIGN rounds up to the next
- * even multiple of BPF_ALIGNMENT.
+ * even multiple of BPF_ALIGNMENT.
+ *
+ * Tcpdump's print-pflog.c uses this, so we define it here.
*/
#ifndef __NetBSD__
#define BPF_ALIGNMENT sizeof(bpf_int32)
@@ -79,9 +101,6 @@ typedef u_int bpf_u_int32;
#endif
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
-#define BPF_MAXBUFSIZE 0x8000
-#define BPF_MINBUFSIZE 32
-
/*
* Structure for "pcap_compile()", "pcap_setfilter()", etc..
*/
@@ -91,26 +110,7 @@ struct bpf_program {
};
/*
- * Struct return by BIOCVERSION. This represents the version number of
- * the filter language described by the instruction encodings below.
- * bpf understands a program iff kernel_major == filter_major &&
- * kernel_minor >= filter_minor, that is, if the value returned by the
- * running kernel has the same major number and a minor number equal
- * equal to or less than the filter being downloaded. Otherwise, the
- * results are undefined, meaning an error may be returned or packets
- * may be accepted haphazardly.
- * It has nothing to do with the source code version.
- */
-struct bpf_version {
- u_short bv_major;
- u_short bv_minor;
-};
-/* Current version number of filter architecture. */
-#define BPF_MAJOR_VERSION 1
-#define BPF_MINOR_VERSION 1
-
-/*
- * Data-link level type codes.
+ * Link-layer header type codes.
*
* Do *NOT* add new values to this list without asking
* "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run
@@ -119,6 +119,12 @@ struct bpf_version {
* being able to handle captures with your new DLT_ value, with no hope
* that they will ever be changed to do so (as that would destroy their
* ability to read captures using that value for that other purpose).
+ *
+ * See
+ *
+ * http://www.tcpdump.org/linktypes.html
+ *
+ * for detailed descriptions of some of these link-layer header types.
*/
/*
@@ -203,9 +209,22 @@ struct bpf_version {
/*
* Values between 100 and 103 are used in capture file headers as
- * link-layer types corresponding to DLT_ types that differ
- * between platforms; don't use those values for new DLT_ new types.
+ * link-layer header type LINKTYPE_ values corresponding to DLT_ types
+ * that differ between platforms; don't use those values for new DLT_
+ * new types.
+ */
+
+/*
+ * Values starting with 104 are used for newly-assigned link-layer
+ * header type values; for those link-layer header types, the DLT_
+ * value returned by pcap_datalink() and passed to pcap_open_dead(),
+ * and the LINKTYPE_ value that appears in capture files, are the
+ * same.
+ *
+ * DLT_MATCHING_MIN is the lowest such value; DLT_MATCHING_MAX is
+ * the highest such value.
*/
+#define DLT_MATCHING_MIN 104
/*
* This value was defined by libpcap 0.5; platforms that have defined
@@ -697,6 +716,8 @@ struct bpf_version {
/*
* IEEE 802.15.4, exactly as it appears in the spec (no padding, no
* nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
+ * For this one, we expect the FCS to be present at the end of the frame;
+ * if the frame has no FCS, DLT_IEEE802_15_4_NOFCS should be used.
*/
#define DLT_IEEE802_15_4 195
@@ -942,7 +963,7 @@ struct bpf_version {
* An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates
* which of those it is.
*/
-#define DLT_IPNET 226
+#define DLT_IPNET 226
/*
* CAN (Controller Area Network) frames, with a pseudo-header as supplied
@@ -951,14 +972,116 @@ struct bpf_version {
*
* Requested by Felix Obenhuber <felix@obenhuber.de>.
*/
-#define DLT_CAN_SOCKETCAN 227
+#define DLT_CAN_SOCKETCAN 227
/*
* Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies
* whether it's v4 or v6. Requested by Darren Reed <Darren.Reed@Sun.COM>.
*/
-#define DLT_IPV4 228
-#define DLT_IPV6 229
+#define DLT_IPV4 228
+#define DLT_IPV6 229
+
+/*
+ * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
+ * nothing), and with no FCS at the end of the frame; requested by
+ * Jon Smirl <jonsmirl@gmail.com>.
+ */
+#define DLT_IEEE802_15_4_NOFCS 230
+
+/*
+ * Raw D-Bus:
+ *
+ * http://www.freedesktop.org/wiki/Software/dbus
+ *
+ * messages:
+ *
+ * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
+ *
+ * starting with the endianness flag, followed by the message type, etc.,
+ * but without the authentication handshake before the message sequence:
+ *
+ * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
+ *
+ * Requested by Martin Vidner <martin@vidner.net>.
+ */
+#define DLT_DBUS 231
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ */
+#define DLT_JUNIPER_VS 232
+#define DLT_JUNIPER_SRX_E2E 233
+#define DLT_JUNIPER_FIBRECHANNEL 234
+
+/*
+ * DVB-CI (DVB Common Interface for communication between a PC Card
+ * module and a DVB receiver). See
+ *
+ * http://www.kaiser.cx/pcap-dvbci.html
+ *
+ * for the specification.
+ *
+ * Requested by Martin Kaiser <martin@kaiser.cx>.
+ */
+#define DLT_DVB_CI 235
+
+/*
+ * Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but
+ * *not* the same as, 27.010). Requested by Hans-Christoph Schemmel
+ * <hans-christoph.schemmel@cinterion.com>.
+ */
+#define DLT_MUX27010 236
+
+/*
+ * STANAG 5066 D_PDUs. Requested by M. Baris Demiray
+ * <barisdemiray@gmail.com>.
+ */
+#define DLT_STANAG_5066_D_PDU 237
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ */
+#define DLT_JUNIPER_ATM_CEMIC 238
+
+/*
+ * NetFilter LOG messages
+ * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets)
+ *
+ * Requested by Jakub Zawadzki <darkjames-ws@darkjames.pl>
+ */
+#define DLT_NFLOG 239
+
+/*
+ * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type
+ * for Ethernet packets with a 4-byte pseudo-header and always
+ * with the payload including the FCS, as supplied by their
+ * netANALYZER hardware and software.
+ *
+ * Requested by Holger P. Frommer <HPfrommer@hilscher.com>
+ */
+#define DLT_NETANALYZER 240
+
+/*
+ * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type
+ * for Ethernet packets with a 4-byte pseudo-header and FCS and
+ * with the Ethernet header preceded by 7 bytes of preamble and
+ * 1 byte of SFD, as supplied by their netANALYZER hardware and
+ * software.
+ *
+ * Requested by Holger P. Frommer <HPfrommer@hilscher.com>
+ */
+#define DLT_NETANALYZER_TRANSPARENT 241
+
+/*
+ * IP-over-Infiniband, as specified by RFC 4391.
+ *
+ * Requested by Petr Sumbera <petr.sumbera@oracle.com>.
+ */
+#define DLT_IPOIB 242
+
+#define DLT_MATCHING_MAX 242 /* highest value in the "matching" range */
/*
* DLT and savefile link type values are split into a class and
@@ -1069,4 +1192,4 @@ extern u_int bpf_filter();
}
#endif
-#endif
+#endif /* !defined(_NET_BPF_H_) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h) */
diff --git a/pcap/pcap.h b/pcap/pcap.h
index 05ba31f35be9..a02b359961de 100644
--- a/pcap/pcap.h
+++ b/pcap/pcap.h
@@ -251,6 +251,8 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
+#define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */
+#define PCAP_ERROR_PROMISC_PERM_DENIED -11 /* you don't have permission to capture in promiscuous mode */
/*
* Warning codes for the pcap API.
@@ -259,6 +261,7 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
*/
#define PCAP_WARNING 1 /* generic warning code */
#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */
+#define PCAP_WARNING_TSTAMP_TYPE_NOTSUP 3 /* the requested time stamp type is not supported */
/*
* Value to pass to pcap_compile() as the netmask if you don't know what
@@ -275,9 +278,60 @@ int pcap_set_promisc(pcap_t *, int);
int pcap_can_set_rfmon(pcap_t *);
int pcap_set_rfmon(pcap_t *, int);
int pcap_set_timeout(pcap_t *, int);
+int pcap_set_tstamp_type(pcap_t *, int);
int pcap_set_buffer_size(pcap_t *, int);
int pcap_activate(pcap_t *);
+int pcap_list_tstamp_types(pcap_t *, int **);
+void pcap_free_tstamp_types(int *);
+int pcap_tstamp_type_name_to_val(const char *);
+const char *pcap_tstamp_type_val_to_name(int);
+const char *pcap_tstamp_type_val_to_description(int);
+
+/*
+ * Time stamp types.
+ * Not all systems and interfaces will necessarily support all of these.
+ *
+ * A system that supports PCAP_TSTAMP_HOST is offering time stamps
+ * provided by the host machine, rather than by the capture device,
+ * but not committing to any characteristics of the time stamp;
+ * it will not offer any of the PCAP_TSTAMP_HOST_ subtypes.
+ *
+ * PCAP_TSTAMP_HOST_LOWPREC is a time stamp, provided by the host machine,
+ * that's low-precision but relatively cheap to fetch; it's normally done
+ * using the system clock, so it's normally synchronized with times you'd
+ * fetch from system calls.
+ *
+ * PCAP_TSTAMP_HOST_HIPREC is a time stamp, provided by the host machine,
+ * that's high-precision; it might be more expensive to fetch. It might
+ * or might not be synchronized with the system clock, and might have
+ * problems with time stamps for packets received on different CPUs,
+ * depending on the platform.
+ *
+ * PCAP_TSTAMP_ADAPTER is a high-precision time stamp supplied by the
+ * capture device; it's synchronized with the system clock.
+ *
+ * PCAP_TSTAMP_ADAPTER_UNSYNCED is a high-precision time stamp supplied by
+ * the capture device; it's not synchronized with the system clock.
+ *
+ * Note that time stamps synchronized with the system clock can go
+ * backwards, as the system clock can go backwards. If a clock is
+ * not in sync with the system clock, that could be because the
+ * system clock isn't keeping accurate time, because the other
+ * clock isn't keeping accurate time, or both.
+ *
+ * Note that host-provided time stamps generally correspond to the
+ * time when the time-stamping code sees the packet; this could
+ * be some unknown amount of time after the first or last bit of
+ * the packet is received by the network adapter, due to batching
+ * of interrupts for packet arrival, queueing delays, etc..
+ */
+#define PCAP_TSTAMP_HOST 0 /* host-provided, unknown characteristics */
+#define PCAP_TSTAMP_HOST_LOWPREC 1 /* host-provided, low precision */
+#define PCAP_TSTAMP_HOST_HIPREC 2 /* host-provided, high precision */
+#define PCAP_TSTAMP_ADAPTER 3 /* device-provided, synced with the system clock */
+#define PCAP_TSTAMP_ADAPTER_UNSYNCED 4 /* device-provided, not synced with the system clock */
+
pcap_t *pcap_open_live(const char *, int, int, int, char *);
pcap_t *pcap_open_dead(int, int);
pcap_t *pcap_open_offline(const char *, char *);
@@ -348,8 +402,16 @@ void pcap_freealldevs(pcap_if_t *);
const char *pcap_lib_version(void);
-/* XXX this guy lives in the bpf tree */
+/*
+ * On at least some versions of NetBSD, we don't want to declare
+ * bpf_filter() here, as it's also be declared in <net/bpf.h>, with a
+ * different signature, but, on other BSD-flavored UN*Xes, it's not
+ * declared in <net/bpf.h>, so we *do* want to declare it here, so it's
+ * declared when we build pcap-bpf.c.
+ */
+#ifndef __NetBSD__
u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
+#endif
int bpf_validate(const struct bpf_insn *f, int len);
char *bpf_image(const struct bpf_insn *, int);
void bpf_dump(const struct bpf_program *, int);
@@ -397,4 +459,4 @@ int pcap_get_selectable_fd(pcap_t *);
}
#endif
-#endif
+#endif /* lib_pcap_pcap_h */
diff --git a/pcap_activate.3pcap b/pcap_activate.3pcap
index b33fa530fd28..f963d35e5193 100644
--- a/pcap_activate.3pcap
+++ b/pcap_activate.3pcap
@@ -43,6 +43,11 @@ returns 0 on success without warnings,
.B PCAP_WARNING_PROMISC_NOTSUP
on success on a device that doesn't support promiscuous mode if
promiscuous mode was requested,
+.B PCAP_WARNING_TSTAMP_TYPE_NOTSUP
+on success if the time stamp type specified in a previous
+.B pcap_set_tstamp_type()
+call isn't supported by the capture source (the time stamp type is
+left as the default),
.B PCAP_WARNING
on success with any other warning,
.B PCAP_ERROR_ACTIVATED
@@ -52,6 +57,9 @@ if the capture source specified when the handle was created doesn't
exist,
.B PCAP_ERROR_PERM_DENIED
if the process doesn't have permission to open the capture source,
+.B PCAP_ERROR_PROMISC_PERM_DENIED
+if the process has permission to open the capture source but doesn't
+have permission to put it into promiscuous mode,
.B PCAP_ERROR_RFMON_NOTSUP
if monitor mode was specified but the capture source doesn't support
monitor mode,
diff --git a/pcap_can_set_rfmon.3pcap b/pcap_can_set_rfmon.3pcap
index 4c85e238ba0a..00b92a403439 100644
--- a/pcap_can_set_rfmon.3pcap
+++ b/pcap_can_set_rfmon.3pcap
@@ -19,7 +19,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_CAN_SET_RFMON 3PCAP "5 April 2008"
+.TH PCAP_CAN_SET_RFMON 3PCAP "18 May 2010"
.SH NAME
pcap_can_set_rfmon \- check whether monitor mode can be set for a
not-yet-activated capture handle
@@ -37,11 +37,15 @@ int pcap_can_set_rfmon(pcap_t *p);
checks whether monitor mode could be set on a capture handle when
the handle is activated.
.SH RETURN VALUE
-.B pcap_set_rfmon()
+.B pcap_can_set_rfmon()
returns 0 if monitor mode could not be set,
1 if monitor mode could be set,
.B PCAP_ERROR_NO_SUCH_DEVICE
-if the device specified when the handle was created doesn't exist,
+if the capture source specified when the handle was created doesn't
+exist,
+.B PCAP_ERROR_PERM_DENIED
+if the process doesn't have permission to check whether monitor mode
+could be supported,
.B PCAP_ERROR_ACTIVATED
if called on a capture handle that has been activated, or
.B PCAP_ERROR
diff --git a/pcap_compile.3pcap.in b/pcap_compile.3pcap.in
index e557fdb43ec8..7dbdad5a1ca4 100644
--- a/pcap_compile.3pcap.in
+++ b/pcap_compile.3pcap.in
@@ -55,7 +55,7 @@ the filter program. If the netmask of the network on which packets are
being captured isn't known to the program, or if packets are being
captured on the Linux "any" pseudo-interface that can capture on more
than one network, a value of PCAP_NETMASK_UNKNOWN can be supplied; tests
-for IPv4 broadcast addreses will fail to compile, but all other tests in
+for IPv4 broadcast addresses will fail to compile, but all other tests in
the filter program will be OK.
.SH RETURN VALUE
.B pcap_compile()
diff --git a/pcap_datalink.3pcap.in b/pcap_datalink.3pcap.in
index cdc7c245630c..3d4ace1d794c 100644
--- a/pcap_datalink.3pcap.in
+++ b/pcap_datalink.3pcap.in
@@ -19,7 +19,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_DATALINK 3PCAP "5 April 2008"
+.TH PCAP_DATALINK 3PCAP "22 August 2010"
.SH NAME
pcap_datalink \- get the link-layer header type
.SH SYNOPSIS
@@ -34,7 +34,7 @@ int pcap_datalink(pcap_t *p);
.fi
.SH DESCRIPTION
.B pcap_datalink()
-returns the link layer type for the live capture or ``savefile''
+returns the link-layer header type for the live capture or ``savefile''
specified by
.IR p .
.SH SEE ALSO
diff --git a/pcap_datalink_name_to_val.3pcap b/pcap_datalink_name_to_val.3pcap
index 93daafdfb13e..9c8e18a3c48e 100644
--- a/pcap_datalink_name_to_val.3pcap
+++ b/pcap_datalink_name_to_val.3pcap
@@ -19,7 +19,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_DATALINK_NAME_TO_VAL 3PCAP "5 April 2008"
+.TH PCAP_DATALINK_NAME_TO_VAL 3PCAP "22 August 2010"
.SH NAME
pcap_datalink_name_to_val \- get the link-layer header type value
corresponding to a header type name
@@ -35,12 +35,12 @@ int pcap_datalink_name_to_val(const char *name);
.fi
.SH DESCRIPTION
.B pcap_datalink_name_to_val()
-translates a data link type name, which is a
+translates a link-layer header type name, which is a
.B DLT_
name with the
.B DLT_
-removed, to the corresponding data link type value. The translation
-is case-insensitive.
+removed, to the corresponding link-layer header type value. The
+translation is case-insensitive.
.SH RETURN VALUE
.B pcap_datalink_name_to_val()
returns 0 on success and \-1 on failure.
diff --git a/pcap_datalink_val_to_name.3pcap b/pcap_datalink_val_to_name.3pcap
index 5e4f6bceda2e..26397faf91d5 100644
--- a/pcap_datalink_val_to_name.3pcap
+++ b/pcap_datalink_val_to_name.3pcap
@@ -19,7 +19,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_DATALINK_VAL_TO_NAME 3PCAP "24 December 2008"
+.TH PCAP_DATALINK_VAL_TO_NAME 3PCAP "22 August 2010"
.SH NAME
pcap_datalink_val_to_name, pcap_datalink_val_to_description \- get a
name or description for a link-layer header type value
@@ -36,9 +36,9 @@ const char *pcap_datalink_val_to_description(int dlt);
.fi
.SH DESCRIPTION
.B pcap_datalink_val_to_name()
-translates a data link type value to the corresponding data link type
-name. NULL is returned on failure.
+translates a link-layer header type value to the corresponding
+link-layer header type name. NULL is returned on failure.
.PP
.B pcap_datalink_val_to_description()
-translates a data link type value to a short description of that data
-link type. NULL is returned on failure.
+translates a link-layer header type value to a short description of that
+link-layer header type. NULL is returned on failure.
diff --git a/pcap_fileno.3pcap b/pcap_fileno.3pcap
index 02d24b532fb7..723733e73de9 100644
--- a/pcap_fileno.3pcap
+++ b/pcap_fileno.3pcap
@@ -47,7 +47,7 @@ returns the file descriptor from which captured packets are read.
.LP
If
.I p
-refers to a ``savefile'' that was opened using fuctions such as
+refers to a ``savefile'' that was opened using functions such as
.BR pcap_open_offline()
or
.BR pcap_fopen_offline() ,
diff --git a/pcap_findalldevs.3pcap b/pcap_findalldevs.3pcap
index 3bf152059e8b..2e56d0916585 100644
--- a/pcap_findalldevs.3pcap
+++ b/pcap_findalldevs.3pcap
@@ -19,9 +19,10 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_FINDALLDEVS 3PCAP "5 April 2008"
+.TH PCAP_FINDALLDEVS 3PCAP "22 August 2010"
.SH NAME
-pcap_findalldevs \- get a list of capture devices
+pcap_findalldevs, pcap_freealldevs \- get a list of capture devices, and
+free that list
.SH SYNOPSIS
.nf
.ft B
@@ -35,6 +36,7 @@ char errbuf[PCAP_ERRBUF_SIZE];
.LP
.ft B
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf);
+void pcap_freealldevs(pcap_if_t *alldevs);
.ft
.fi
.SH DESCRIPTION
@@ -48,12 +50,17 @@ or with
(Note that there may be network devices that cannot be opened by the
process calling
.BR pcap_findalldevs() ,
-because, for example, that process might not have sufficient privileges
+because, for example, that process does not have sufficient privileges
to open them for capturing; if so, those devices will not appear on the
list.)
+If
+.B pcap_findalldevs()
+succeeds, the pointer pointed to by
.I alldevsp
-is set to point to the first element of the list; each element of the
-list is of type
+is set to point to the first element of the list, or to
+.B NULL
+if no devices were found (this is considered success).
+Each element of the list is of type
.BR pcap_if_t ,
and has the following members:
.RS
@@ -75,14 +82,18 @@ if not
a pointer to a string giving a human-readable description of the device
.TP
.B addresses
-a pointer to the first element of a list of addresses for the interface
+a pointer to the first element of a list of network addresses for the
+device,
+or
+.B NULL
+if the device has no addresses
.TP
.B flags
-interface flags:
+device flags:
.RS
.TP
.B PCAP_IF_LOOPBACK
-set if the interface is a loopback interface
+set if the device is a loopback interface
.RE
.RE
.PP
@@ -119,7 +130,7 @@ a pointer to a
that contains the broadcast address corresponding to the address pointed
to by
.BR addr ;
-may be null if the interface doesn't support broadcasts
+may be null if the device doesn't support broadcasts
.TP
.B dstaddr
if not
@@ -129,21 +140,40 @@ a pointer to a
that contains the destination address corresponding to the address pointed
to by
.BR addr ;
-may be null if the interface isn't a point-to-point interface
+may be null if the device isn't a point-to-point interface
.RE
.PP
-Note that not all the addresses in the list of addresses are
-necessarily IPv4 or IPv6 addresses - you must check the
+Note that the addresses in the list of addresses might be IPv4
+addresses, IPv6 addresses, or some other type of addresses, so you must
+check the
.B sa_family
member of the
.B "struct sockaddr"
-before interpreting the contents of the address.
+before interpreting the contents of the address; do not assume that the
+addresses are all IPv4 addresses, or even all IPv4 or IPv6 addresses.
+IPv4 addresses have the value
+.BR AF_INET ,
+IPv6 addresses have the value
+.B AF_INET6
+(which older operating systems that don't support IPv6 might not
+define), and other addresses have other values. Whether other addresses
+are returned, and what types they might have is platform-dependent.
+For IPv4 addresses, the
+.B "struct sockaddr"
+pointer can be interpreted as if it pointed to a
+.BR "struct sockaddr_in" ;
+for IPv6 addresses, it can be interpreted as if it pointed to a
+.BR "struct sockaddr_in6".
.PP
The list of devices must be freed with
-.BR pcap_freealldevs() .
+.BR pcap_freealldevs() ,
+whch frees the list pointed to by
+.IR alldevs .
.SH RETURN VALUE
.B pcap_findalldevs()
-returns 0 on success and \-1 on failure.
+returns 0 on success and \-1 on failure; as indicated, finding no
+devices is considered success, rather than failure, so 0 will be
+returned in that case.
If \-1 is returned,
.I errbuf
is filled in with an appropriate error message.
@@ -153,4 +183,4 @@ is assumed to be able to hold at least
chars.
.SH SEE ALSO
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP),
-pcap_open_live(3PCAP), pcap_freealldevs(3PCAP)
+pcap_open_live(3PCAP)
diff --git a/pcap_free_datalinks.3pcap b/pcap_free_datalinks.3pcap
index b7355bdf8199..e69de29bb2d1 100644
--- a/pcap_free_datalinks.3pcap
+++ b/pcap_free_datalinks.3pcap
@@ -1,41 +0,0 @@
-.\" @(#) $Header: /tcpdump/master/libpcap/pcap_free_datalinks.3pcap,v 1.1 2008-05-26 19:58:06 guy Exp $
-.\"
-.\" Copyright (c) 1994, 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.
-.\"
-.TH PCAP_FREE_DATALINKS 3PCAP "26 May 2008"
-.SH NAME
-pcap_free_datalinks \- free a list of link-layer header types from
-pcap_get_datalinks()
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.LP
-.ft B
-void pcap_free_datalinks(int *dlt_list);
-.ft
-.fi
-.SH DESCRIPTION
-.B pcap_free_datalinks()
-is used to free a list of supported data link types returned by
-.BR pcap_list_datalinks() .
-.SH SEE ALSO
-pcap(3PCAP), pcap_list_datalinks(3PCAP)
diff --git a/pcap_freealldevs.3pcap b/pcap_freealldevs.3pcap
index d3f234fc6fd4..e69de29bb2d1 100644
--- a/pcap_freealldevs.3pcap
+++ b/pcap_freealldevs.3pcap
@@ -1,40 +0,0 @@
-.\" @(#) $Header: /tcpdump/master/libpcap/pcap_freealldevs.3pcap,v 1.3 2008-04-06 02:53:22 guy Exp $
-.\"
-.\" Copyright (c) 1994, 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.
-.\"
-.TH PCAP_FREEALLDEVS 3PCAP "5 April 2008"
-.SH NAME
-pcap_freealldevs \- free a list of capture devices
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.LP
-.ft B
-void pcap_freealldevs(pcap_if_t *alldevs);
-.ft
-.fi
-.SH DESCRIPTION
-.B pcap_freealldevs()
-is used to free a list allocated by
-.BR pcap_findalldevs() .
-.SH SEE ALSO
-pcap(3PCAP), pcap_findalldevs(3PCAP)
diff --git a/pcap_get_selectable_fd.3pcap b/pcap_get_selectable_fd.3pcap
index 61be3d32e8ab..ae33dbb2e4bc 100644
--- a/pcap_get_selectable_fd.3pcap
+++ b/pcap_get_selectable_fd.3pcap
@@ -56,19 +56,29 @@ or
(for example, regular network devices on FreeBSD 4.3 and 4.4, and Endace
DAG devices), so \-1 is returned for those devices.
.PP
-Note that on most versions of most BSDs (including Mac OS X)
+Note that in:
+.IP
+FreeBSD prior to FreeBSD 4.6;
+.IP
+NetBSD prior to NetBSD 3.0;
+.IP
+OpenBSD prior to OpenBSD 2.4;
+.IP
+Mac OS X prior to Mac OS X 10.7;
+.PP
.B select()
and
.B poll()
do not work correctly on BPF devices;
.B pcap_get_selectable_fd()
will return a file descriptor on most of those versions (the exceptions
-being FreeBSD 4.3 and 4.4), a simple
+being FreeBSD 4.3 and 4.4), but a simple
.B select()
or
.B poll()
-will not return even after the read timeout expires. To work around
-this, an application that uses
+will not indicate that the descriptor is readable until a full buffer's
+worth of packets is received, even if the read timeout expires before
+then. To work around this, an application that uses
.B select()
or
.B poll()
diff --git a/pcap_list_datalinks.3pcap.in b/pcap_list_datalinks.3pcap.in
index 490e8dde7992..632757642b55 100644
--- a/pcap_list_datalinks.3pcap.in
+++ b/pcap_list_datalinks.3pcap.in
@@ -19,10 +19,10 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_LIST_DATALINKS 3PCAP "5 April 2008"
+.TH PCAP_LIST_DATALINKS 3PCAP "22 August 2010"
.SH NAME
-pcap_list_datalinks \- get a list of link-layer header types supported
-by a capture device
+pcap_list_datalinks, pcap_free_datalinks \- get a list of link-layer header
+types supported by a capture device, and free that list
.SH SYNOPSIS
.nf
.ft B
@@ -31,21 +31,26 @@ by a capture device
.LP
.ft B
int pcap_list_datalinks(pcap_t *p, int **dlt_buf);
+void pcap_free_datalinks(int *dlt_list);
.ft
.fi
.SH DESCRIPTION
.B pcap_list_datalinks()
-is used to get a list of the supported data link types of the interface
-associated with the pcap descriptor.
+is used to get a list of the supported link-layer header types of the
+interface associated with the pcap descriptor.
.B pcap_list_datalinks()
allocates an array to hold the list and sets
-.IR *dlt_buf .
+.IR *dlt_buf
+to point to that array.
+.LP
The caller is responsible for freeing the array with
-.BR pcap_free_datalinks (3PCAP).
+.BR pcap_free_datalinks() ,
+which frees the list of link-layer header types pointed to by
+.IR dlt_list .
.SH RETURN VALUE
.B pcap_list_datalinks()
-returns the number of data link types in the array on success and \-1
-on failure.
+returns the number of link-layer header types in the array on success
+and \-1 on failure.
If \-1 is returned,
.B pcap_geterr()
or
@@ -54,5 +59,6 @@ may be called with
.I p
as an argument to fetch or display the error text.
.SH SEE ALSO
-pcap(3PCAP), pcap_geterr(3PCAP), pcap_free_datalinks(3PCAP),
+pcap(3PCAP), pcap_geterr(3PCAP),
+pcap_datalink_val_to_name(3PCAP),
pcap-linktype(@MAN_MISC_INFO@)
diff --git a/pcap_loop.3pcap b/pcap_loop.3pcap
index 70cfaa0293c3..da3069310a2b 100644
--- a/pcap_loop.3pcap
+++ b/pcap_loop.3pcap
@@ -109,7 +109,12 @@ pointer to the first
(as given in the
.I struct pcap_pkthdr
a pointer to which is passed to the callback routine)
-bytes of data from the packet.
+bytes of data from the packet. The
+.I struct pcap_pkthdr
+and the packet data are not to be freed by the callback routine, and are
+not guaranteed to be valid after the callback routine returns; if the
+code needs them to be valid after the callback, it must make a copy of
+them.
.SH RETURN VALUE
.B pcap_loop()
returns 0 if
diff --git a/pcap_major_version.3pcap b/pcap_major_version.3pcap
index 6f9c8ae705d7..31903dcfd030 100644
--- a/pcap_major_version.3pcap
+++ b/pcap_major_version.3pcap
@@ -36,12 +36,14 @@ int pcap_minor_version(pcap_t *p);
.SH DESCRIPTION
If
.I p
-refers to a savefile,
+refers to a ``savefile'',
.B pcap_major_version()
-returns the major number of the file format of the savefile and
+returns the major number of the file format of the ``savefile'' and
.B pcap_minor_version()
-returns the minor number of the file format of the savefile. The
-version number is stored in the header of the savefile.
+returns the minor number of the file format of the ``savefile''. The
+version number is stored in the ``savefile''; note that the meaning of
+its values depends on the type of ``savefile'' (for example, pcap or
+pcap-NG).
.PP
If
.I p
diff --git a/pcap_next_ex.3pcap b/pcap_next_ex.3pcap
index 50ad198aa436..737383604b13 100644
--- a/pcap_next_ex.3pcap
+++ b/pcap_next_ex.3pcap
@@ -45,7 +45,16 @@ argument is set to point to the
struct for the packet, and the
pointer pointed to by the
.I pkt_data
-argument is set to point to the data in the packet.
+argument is set to point to the data in the packet. The
+.I struct pcap_pkthdr
+and the packet data are not to be freed by the caller, and are not
+guaranteed to be valid after the next call to
+.BR pcap_next_ex() ,
+.BR pcap_next() ,
+.BR pcap_loop() ,
+or
+.BR pcap_dispatch() ;
+if the code needs them to remain valid, it must make a copy of them.
.PP
.B pcap_next()
reads the next packet (by calling
@@ -54,7 +63,15 @@ with a
.I cnt
of 1) and returns a
.I u_char
-pointer to the data in that packet.
+pointer to the data in that packet. The
+packet data is not to be freed by the caller, and is not
+guaranteed to be valid after the next call to
+.BR pcap_next_ex() ,
+.BR pcap_next() ,
+.BR pcap_loop() ,
+or
+.BR pcap_dispatch() ;
+if the code needs it to remain valid, it must make a copy of it.
The
.I pcap_pkthdr
structure pointed to by
@@ -78,13 +95,13 @@ as an argument to fetch or display the error text.
.B pcap_next()
returns a pointer to the packet data on success, and returns
.B NULL
-if an error occured, or if no packets were read from a live
+if an error occurred, or if no packets were read from a live
capture (if, for example, they were discarded because they didn't pass
the packet filter, or if, on platforms that support a read timeout that
starts before any packets arrive, the timeout expires before any packets
arrive, or if the file descriptor for the capture device is in
non-blocking mode and no packets were available to be read), or if no
more packets are available in a ``savefile.'' Unfortunately, there is
-no way to determine whether an error occured or not.
+no way to determine whether an error occurred or not.
.SH SEE ALSO
pcap(3PCAP), pcap_geterr(3PCAP), pcap_dispatch(3PCAP)
diff --git a/pcap_open_live.3pcap b/pcap_open_live.3pcap
index 623f0986ed00..0889a2a25868 100644
--- a/pcap_open_live.3pcap
+++ b/pcap_open_live.3pcap
@@ -74,7 +74,7 @@ is filled in with an appropriate error message.
.I errbuf
may also be set to warning text when
.B pcap_open_live()
-succeds; to detect this case the caller should store a zero-length string in
+succeeds; to detect this case the caller should store a zero-length string in
.I errbuf
before calling
.B pcap_open_live()
diff --git a/pcap_set_datalink.3pcap b/pcap_set_datalink.3pcap
index bad39e4c836a..9af32d0696a9 100644
--- a/pcap_set_datalink.3pcap
+++ b/pcap_set_datalink.3pcap
@@ -19,7 +19,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_SET_DATALINK 3PCAP "5 April 2008"
+.TH PCAP_SET_DATALINK 3PCAP "22 August 2010"
.SH NAME
pcap_set_datalink \- set the link-layer header type to be used by a
capture device
@@ -35,7 +35,7 @@ int pcap_set_datalink(pcap_t *p, int dlt);
.fi
.SH DESCRIPTION
.B pcap_set_datalink()
-is used to set the current data link type of the pcap descriptor
+is used to set the current link-layer header type of the pcap descriptor
to the type specified by
.IR dlt .
.SH RETURN VALUE
@@ -49,4 +49,5 @@ may be called with
.I p
as an argument to fetch or display the error text.
.SH SEE ALSO
-pcap(3PCAP), pcap_geterr(3PCAP)
+pcap(3PCAP), pcap_geterr(3PCAP),
+pcap_datalink_name_to_val(3PCAP)
diff --git a/savefile.c b/savefile.c
index 56e571937d2a..8115749b1343 100644
--- a/savefile.c
+++ b/savefile.c
@@ -94,10 +94,16 @@ static int
sf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
{
/*
- * This is a savefile, not a live capture file, so ignore
- * requests to put it in non-blocking mode.
+ * This is a savefile, not a live capture file, so reject
+ * requests to put it in non-blocking mode. (If it's a
+ * pipe, it could be put in non-blocking mode, but that
+ * would significantly complicate the code to read packets,
+ * as it would have to handle reading partial packets and
+ * keeping the state of the read.)
*/
- return (0);
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Savefiles cannot be put into non-blocking mode");
+ return (-1);
}
static int
@@ -161,6 +167,7 @@ sf_cleanup(pcap_t *p)
(void)fclose(p->sf.rfile);
if (p->buffer != NULL)
free(p->buffer);
+ pcap_freecode(&p->fcode);
}
pcap_t *
@@ -376,7 +383,7 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
}
if ((fcode = p->fcode.bf_insns) == NULL ||
- bpf_filter(fcode, p->buffer, h.len, h.caplen)) {
+ bpf_filter(fcode, data, h.len, h.caplen)) {
(*callback)(user, &h, data);
if (++n >= cnt && cnt > 0)
break;
diff --git a/scanner.l b/scanner.l
index 9b3e139f628d..064e9c885fbc 100644
--- a/scanner.l
+++ b/scanner.l
@@ -54,7 +54,7 @@ static const char rcsid[] _U_ =
#include <pcap-stdinc.h>
#ifdef __MINGW32__
-#include "IP6_misc.h"
+#include "ip6_misc.h"
#endif
#else /* WIN32 */
#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */
@@ -77,6 +77,7 @@ static int stoi(char *);
static inline int xdtoi(int);
#ifdef FLEX_SCANNER
+#define YY_NO_INPUT
#define YY_NO_UNPUT
static YY_BUFFER_STATE in_buffer;
#else
@@ -202,6 +203,7 @@ igmp return IGMP;
igrp return IGRP;
pim return PIM;
vrrp return VRRP;
+carp return CARP;
radio return RADIO;
ip6 {
@@ -273,6 +275,8 @@ address1|addr1 return ADDR1;
address2|addr2 return ADDR2;
address3|addr3 return ADDR3;
address4|addr4 return ADDR4;
+ra return RA;
+ta return TA;
less return LESS;
greater return GREATER;
diff --git a/sf-pcap-ng.c b/sf-pcap-ng.c
index 3535777ceb39..7eb6db76493b 100644
--- a/sf-pcap-ng.c
+++ b/sf-pcap-ng.c
@@ -746,7 +746,7 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
done:
p->tzoff = 0; /* XXX - not used in pcap */
p->snapshot = idbp->snaplen;
- p->linktype = idbp->linktype;
+ p->linktype = linktype_to_dlt(idbp->linktype);
p->linktype_ext = 0;
p->sf.next_packet_op = pcap_ng_next_packet;
@@ -772,7 +772,6 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
struct simple_packet_block *spbp;
struct packet_block *pbp;
bpf_u_int32 interface_id = 0xFFFFFFFF;
- size_t pblock_len;
struct interface_description_block *idbp;
struct section_header_block *shbp;
FILE *fp = p->sf.rfile;
@@ -823,7 +822,6 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
t = ((u_int64_t)epbp->timestamp_high) << 32 |
epbp->timestamp_low;
}
- pblock_len = sizeof(*epbp);
goto found;
case BT_SPB:
@@ -860,7 +858,6 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
if (hdr->caplen > p->snapshot)
hdr->caplen = p->snapshot;
t = 0; /* no time stamps */
- pblock_len = sizeof(*spbp);
goto found;
case BT_PB:
@@ -890,7 +887,6 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
t = ((u_int64_t)pbp->timestamp_high) << 32 |
pbp->timestamp_low;
}
- pblock_len = sizeof(*pbp);
goto found;
case BT_IDB:
@@ -1053,7 +1049,7 @@ found:
/*
* Is the interface ID an interface we know?
*/
- if (interface_id > p->sf.ifcount) {
+ if (interface_id >= p->sf.ifcount) {
/*
* Yes. Fail.
*/
diff --git a/sf-pcap.c b/sf-pcap.c
index 9d55dae5fbe9..2b31a2b7a0f1 100644
--- a/sf-pcap.c
+++ b/sf-pcap.c
@@ -271,8 +271,12 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
* Allocate a buffer for the packet data.
*/
p->bufsize = p->snapshot;
- if (p->bufsize <= 0)
- p->bufsize = BPF_MAXBUFSIZE;
+ if (p->bufsize <= 0) {
+ /*
+ * Bogus snapshot length; use 64KiB as a fallback.
+ */
+ p->bufsize = 65536;
+ }
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");