From de0d3203d3edcf5278fe35179d7735cf52901cf3 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 5 Jul 2009 14:17:07 -1000 Subject: [PATCH] Update to libpcap-1.0.0. --- contrib/libpcap/CHANGES | 63 +- contrib/libpcap/README | 42 +- contrib/libpcap/README.DELETED | 43 +- contrib/libpcap/VERSION | 2 +- contrib/libpcap/atmuni31.h | 14 +- contrib/libpcap/bpf/net/bpf_filter.c | 167 +- contrib/libpcap/bpf_dump.c | 6 +- contrib/libpcap/bpf_image.c | 4 +- contrib/libpcap/etherent.c | 4 +- contrib/libpcap/ethertype.h | 2 +- contrib/libpcap/fad-getad.c | 2 +- contrib/libpcap/gencode.c | 2411 ++++++++++++----- contrib/libpcap/gencode.h | 9 +- contrib/libpcap/grammar.y | 198 +- contrib/libpcap/inet.c | 67 +- contrib/libpcap/nametoaddr.c | 16 +- contrib/libpcap/optimize.c | 26 +- contrib/libpcap/pcap-bpf.c | 1864 +++++++++++-- contrib/libpcap/pcap-bpf.h | 834 ------ contrib/libpcap/pcap-filter.manmisc.in | 949 +++++++ contrib/libpcap/pcap-int.h | 165 +- contrib/libpcap/pcap-linktype.manmisc.in | 282 ++ contrib/libpcap/pcap-namedb.h | 59 +- contrib/libpcap/pcap-savefile.manfile.in | 127 + contrib/libpcap/pcap.3 | 1312 --------- contrib/libpcap/pcap.3pcap.in | 386 +++ contrib/libpcap/pcap.c | 506 +++- contrib/libpcap/pcap.h | 295 +- .../libpcap/{pcap-namedb.h => pcap/namedb.h} | 2 +- contrib/libpcap/{ => pcap}/pcap.h | 91 +- contrib/libpcap/{ => pcap}/sll.h | 11 +- contrib/libpcap/pcap/usb.h | 90 + contrib/libpcap/pcap_activate.3pcap | 89 + contrib/libpcap/pcap_breakloop.3pcap | 105 + contrib/libpcap/pcap_can_set_rfmon.3pcap | 60 + contrib/libpcap/pcap_close.3pcap | 41 + contrib/libpcap/pcap_compile.3pcap.in | 72 + contrib/libpcap/pcap_create.3pcap | 74 + contrib/libpcap/pcap_datalink.3pcap.in | 41 + .../libpcap/pcap_datalink_name_to_val.3pcap | 48 + .../libpcap/pcap_datalink_val_to_name.3pcap | 44 + contrib/libpcap/pcap_dump.3pcap | 53 + contrib/libpcap/pcap_dump_close.3pcap | 39 + contrib/libpcap/pcap_dump_file.3pcap | 40 + contrib/libpcap/pcap_dump_flush.3pcap | 45 + contrib/libpcap/pcap_dump_ftell.3pcap | 44 + contrib/libpcap/pcap_dump_open.3pcap.in | 87 + contrib/libpcap/pcap_file.3pcap | 59 + contrib/libpcap/pcap_fileno.3pcap | 47 + contrib/libpcap/pcap_findalldevs.3pcap | 156 ++ contrib/libpcap/pcap_free_datalinks.3pcap | 41 + contrib/libpcap/pcap_freealldevs.3pcap | 40 + contrib/libpcap/pcap_freecode.3pcap | 45 + contrib/libpcap/pcap_get_selectable_fd.3pcap | 114 + contrib/libpcap/pcap_geterr.3pcap | 53 + contrib/libpcap/pcap_inject.3pcap | 90 + contrib/libpcap/pcap_is_swapped.3pcap | 42 + contrib/libpcap/pcap_lib_version.3pcap | 41 + contrib/libpcap/pcap_list_datalinks.3pcap.in | 58 + contrib/libpcap/pcap_lookupdev.3pcap | 62 + contrib/libpcap/pcap_lookupnet.3pcap | 65 + contrib/libpcap/pcap_loop.3pcap | 150 + contrib/libpcap/pcap_major_version.3pcap | 54 + contrib/libpcap/pcap_next_ex.3pcap | 90 + contrib/libpcap/pcap_offline_filter.3pcap | 57 + contrib/libpcap/pcap_open_dead.3pcap.in | 52 + contrib/libpcap/pcap_open_live.3pcap | 89 + contrib/libpcap/pcap_open_offline.3pcap.in | 78 + contrib/libpcap/pcap_set_buffer_size.3pcap | 47 + contrib/libpcap/pcap_set_datalink.3pcap | 52 + contrib/libpcap/pcap_set_promisc.3pcap | 48 + contrib/libpcap/pcap_set_rfmon.3pcap | 49 + contrib/libpcap/pcap_set_snaplen.3pcap | 46 + contrib/libpcap/pcap_set_timeout.3pcap | 47 + contrib/libpcap/pcap_setdirection.3pcap | 71 + contrib/libpcap/pcap_setfilter.3pcap | 54 + contrib/libpcap/pcap_setnonblock.3pcap | 75 + contrib/libpcap/pcap_snapshot.3pcap | 44 + contrib/libpcap/pcap_stats.3pcap | 59 + contrib/libpcap/pcap_statustostr.3pcap | 43 + contrib/libpcap/pcap_strerror.3pcap | 42 + contrib/libpcap/pf.h | 77 - contrib/libpcap/savefile.c | 282 +- contrib/libpcap/scanner.l | 21 +- 84 files changed, 9706 insertions(+), 3765 deletions(-) delete mode 100644 contrib/libpcap/pcap-bpf.h create mode 100644 contrib/libpcap/pcap-filter.manmisc.in create mode 100644 contrib/libpcap/pcap-linktype.manmisc.in create mode 100644 contrib/libpcap/pcap-savefile.manfile.in delete mode 100644 contrib/libpcap/pcap.3 create mode 100644 contrib/libpcap/pcap.3pcap.in copy contrib/libpcap/{pcap-namedb.h => pcap/namedb.h} (97%) copy contrib/libpcap/{ => pcap}/pcap.h (77%) rename contrib/libpcap/{ => pcap}/sll.h (94%) create mode 100644 contrib/libpcap/pcap/usb.h create mode 100644 contrib/libpcap/pcap_activate.3pcap create mode 100644 contrib/libpcap/pcap_breakloop.3pcap create mode 100644 contrib/libpcap/pcap_can_set_rfmon.3pcap create mode 100644 contrib/libpcap/pcap_close.3pcap create mode 100644 contrib/libpcap/pcap_compile.3pcap.in create mode 100644 contrib/libpcap/pcap_create.3pcap create mode 100644 contrib/libpcap/pcap_datalink.3pcap.in create mode 100644 contrib/libpcap/pcap_datalink_name_to_val.3pcap create mode 100644 contrib/libpcap/pcap_datalink_val_to_name.3pcap create mode 100644 contrib/libpcap/pcap_dump.3pcap create mode 100644 contrib/libpcap/pcap_dump_close.3pcap create mode 100644 contrib/libpcap/pcap_dump_file.3pcap create mode 100644 contrib/libpcap/pcap_dump_flush.3pcap create mode 100644 contrib/libpcap/pcap_dump_ftell.3pcap create mode 100644 contrib/libpcap/pcap_dump_open.3pcap.in create mode 100644 contrib/libpcap/pcap_file.3pcap create mode 100644 contrib/libpcap/pcap_fileno.3pcap create mode 100644 contrib/libpcap/pcap_findalldevs.3pcap create mode 100644 contrib/libpcap/pcap_free_datalinks.3pcap create mode 100644 contrib/libpcap/pcap_freealldevs.3pcap create mode 100644 contrib/libpcap/pcap_freecode.3pcap create mode 100644 contrib/libpcap/pcap_get_selectable_fd.3pcap create mode 100644 contrib/libpcap/pcap_geterr.3pcap create mode 100644 contrib/libpcap/pcap_inject.3pcap create mode 100644 contrib/libpcap/pcap_is_swapped.3pcap create mode 100644 contrib/libpcap/pcap_lib_version.3pcap create mode 100644 contrib/libpcap/pcap_list_datalinks.3pcap.in create mode 100644 contrib/libpcap/pcap_lookupdev.3pcap create mode 100644 contrib/libpcap/pcap_lookupnet.3pcap create mode 100644 contrib/libpcap/pcap_loop.3pcap create mode 100644 contrib/libpcap/pcap_major_version.3pcap create mode 100644 contrib/libpcap/pcap_next_ex.3pcap create mode 100644 contrib/libpcap/pcap_offline_filter.3pcap create mode 100644 contrib/libpcap/pcap_open_dead.3pcap.in create mode 100644 contrib/libpcap/pcap_open_live.3pcap create mode 100644 contrib/libpcap/pcap_open_offline.3pcap.in create mode 100644 contrib/libpcap/pcap_set_buffer_size.3pcap create mode 100644 contrib/libpcap/pcap_set_datalink.3pcap create mode 100644 contrib/libpcap/pcap_set_promisc.3pcap create mode 100644 contrib/libpcap/pcap_set_rfmon.3pcap create mode 100644 contrib/libpcap/pcap_set_snaplen.3pcap create mode 100644 contrib/libpcap/pcap_set_timeout.3pcap create mode 100644 contrib/libpcap/pcap_setdirection.3pcap create mode 100644 contrib/libpcap/pcap_setfilter.3pcap create mode 100644 contrib/libpcap/pcap_setnonblock.3pcap create mode 100644 contrib/libpcap/pcap_snapshot.3pcap create mode 100644 contrib/libpcap/pcap_stats.3pcap create mode 100644 contrib/libpcap/pcap_statustostr.3pcap create mode 100644 contrib/libpcap/pcap_strerror.3pcap delete mode 100644 contrib/libpcap/pf.h diff --git a/contrib/libpcap/CHANGES b/contrib/libpcap/CHANGES index 536e1a2c18..dc4e006991 100644 --- a/contrib/libpcap/CHANGES +++ b/contrib/libpcap/CHANGES @@ -1,28 +1,41 @@ -@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.59.2.13 2007/09/12 22:40:04 ken Exp $ (LBL) - -Mon. September 10, 2007. ken@xelerance.com. Summary for 0.9.8 libpcap release - Change build process to put public libpcap headers into pcap subir - DLT: Add value for IPMI IPMB packets - DLT: Add value for u10 Networks boards - Require for pf definitions - allows reading of pflog formatted - libpcap files on an OS other than where the file was generated - -Wed. July 23, 2007. mcr@xelerance.com. Summary for 0.9.7 libpcap release - - FIXED version file to be 0.9.7 instead of 0.9.5. - added flags/configuration for cloning bpf device. - added DLT_MTP2_WITH_PHDR support (PPI) - "fix" the "memory leak" in icode_to_fcode() -- documentation bug - Various link-layer types, with a pseudo-header, for SITA http://www.sita.aero/ - introduces support for the DAG ERF type TYPE_COLOR_MC_HDLC_POS. - Basic BPF filtering support for DLT_MTP2_WITH_PHDR is also added. - check for IPv4 and IPv6, even for DLT_RAW - add support for DLT_JUNIPER_ISM - Pick up changes from NetBSD: many from tron, christos, drochner - Allocate DLT_ for 802.15.4 without any header munging, for Mikko Saarnivala. - Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header - -Wed. April 25, 2007. ken@xelerance.com. Summary for 0.9.6 libpcap release +@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.67.2.4 2008-10-28 00:27:42 ken Exp $ (LBL) + +Mon. October 27, 2008. ken@netfunctional.ca. Summary for 1.0.0 libpcap release + Compile with IPv6 support by default + Compile with large file support on by default + Add pcap-config script, which deals with -I/-L flags for compiling + DLT: Add IPMB + DLT: Add LAPD + DLT: Add AX25 (AX.25 w/KISS header) + DLT: Add JUNIPER_ST + 802.15.4 support + Variable length 802.11 header support + X2E data type support + SITA ACN Interface support - see README.sita + Support for zerocopy BPF on platforms that support it + Better support for dealing with VLAN tagging/stripping on Linux + Fix dynamic library support on OSX + Return PCAP_ERROR_IFACE_NOT_UP if the interface isn't 'UP', so applications + can print better diagnostic information + Return PCAP_ERROR_PERM_DENIED if we don't have permission to open a device, so + applications can tell the user they need to go play with permissions + On Linux, ignore ENETDOWN so we can continue to capture packets if the + interface goes down and comes back up again. + On Linux, support new tpacket frame headers (2.6.27+) + On Mac OS X, add scripts for changing permissions on /dev/pbf* and launchd plist + On Solaris, support 'passive mode' on systems that support it + Fixes to autoconf and general build environment + Man page reorganization + cleanup + Autogenerate VERSION numbers better + +Mon. September 10, 2007. ken@xelerance.com. Summary for 0.9.8 libpcap release + Change build process to put public libpcap headers into pcap subir + DLT: Add value for IPMI IPMB packets + DLT: Add value for u10 Networks boards + Require for pf definitions - allows reading of pflog formatted + libpcap files on an OS other than where the file was generated + +Wed. April 25, 2007. ken@xelerance.com. Summary for 0.9.6 libpcap release Put the public libpcap headers into a pcap subdirectory in both the source directory and the target include directory, and have include diff --git a/contrib/libpcap/README b/contrib/libpcap/README index 90571a1505..ee1a14186f 100644 --- a/contrib/libpcap/README +++ b/contrib/libpcap/README @@ -1,20 +1,22 @@ -@(#) $Header: /tcpdump/master/libpcap/README,v 1.30 2004/10/12 02:02:28 guy Exp $ (LBL) +@(#) $Header: /tcpdump/master/libpcap/README,v 1.30.4.3 2008-10-17 10:39:20 ken Exp $ (LBL) -LIBPCAP 0.9 -Now maintained by "The Tcpdump Group" -See www.tcpdump.org +LIBPCAP 1.0.0 -Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org +www.tcpdump.org + +Please send inquiries/comments/reports to: + tcpdump-workers@lists.tcpdump.org Anonymous CVS is available via: cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master login (password "anoncvs") cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout libpcap -Version 0.9 of LIBPCAP can be retrieved with the CVS tag "libpcap_0_9rel1": - cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_0_9rel1 libpcap +Version 1.0.0 of LIBPCAP can be retrieved with the CVS tag "libpcap_1_0": + cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_1_0 libpcap -Please send patches against the master copy to patches@tcpdump.org. +Please submit patches against the master copy to the libpcap project on +sourceforge.net. formerly from Lawrence Berkeley National Laboratory Network Research Group @@ -30,8 +32,6 @@ require this functionality, we've created this system-independent API to ease in porting and to alleviate the need for several system-dependent packet capture modules in each application. -Note well: this interface is new and is likely to change. - For some platforms there are README.{system} files that discuss issues with the OS's interface for packet capture on those platforms, such as how to enable support for that interface in the OS, if it's not built in @@ -77,16 +77,28 @@ Linux, in the 2.2 kernel and later kernels, has a "Socket Filter" mechanism that accepts BPF filters; see the README.linux file for information on configuring that option. +Note to Linux distributions and *BSD systems that include libpcap: + +There's now a rule to make a shared library, which should work on Linux +and *BSD (and OS X). + +It sets the soname of the library to "libpcap.so.1"; this is what it +should be, *NOT* libpcap.so.1.0 or libpcap.so.1.0.0 or something such as +that. + +We've been maintaining binary compatibility between libpcap releases for +quite a while; there's no reason to tie a binary linked with libpcap to +a particular release of libpcap. + Problems, bugs, questions, desirable enhancements, etc. should be sent -to the address "tcpdump-workers@tcpdump.org". Bugs, support requests, -and feature requests may also be submitted on the SourceForge site for -libpcap at +to the address "tcpdump-workers@lists.tcpdump.org". Bugs, support +requests, and feature requests may also be submitted on the SourceForge +site for libpcap at http://sourceforge.net/projects/libpcap/ Source code contributions, etc. should be sent to the email address -"patches@tcpdump.org", or submitted as patches on the SourceForge site -for libpcap. +submitted as patches on the SourceForge site for libpcap. Current versions can be found at www.tcpdump.org, or the SourceForge site for libpcap. diff --git a/contrib/libpcap/README.DELETED b/contrib/libpcap/README.DELETED index 2bb3acd0a0..f6a678a4c5 100644 --- a/contrib/libpcap/README.DELETED +++ b/contrib/libpcap/README.DELETED @@ -1,11 +1,5 @@ -.#CHANGES.1.59 -.#Makefile.in.1.99.2.1 -.cvsignore -CHANGES~ CREDITS -CVS/ ChmodBPF/ -FILES INSTALL.txt Makefile.in README.Win32 @@ -15,51 +9,66 @@ README.hpux README.linux README.macosx README.septel +README.sita README.tru64 SUNOS4/ TODO Win32/ acconfig.h aclocal.m4 -bpf/CVS/ -bpf/net/CVS/ +bpf_filter.c +chmod_bpf config.guess config.h.in config.sub configure configure.in -doc/ +dlpisubs.c +dlpisubs.h fad-gifc.c fad-glifc.c fad-null.c +fad-sita.c fad-win32.c -gencode.c.orig -gencode.c.rej +filtertest.c +findalldevstest.c +ieee80211.h install-sh lbl/ -libpcap-0.9 missing/ mkdep msdos/ -net +net/ +org.tcpdump.chmod_bpf.plist packaging/ +pcap/bluetooth.h +pcap/bpf.h +pcap/vlan.h +pcap-bpf.h +pcap-bt-linux.c +pcap-bt-linux.h +pcap-config.1 +pcap-config.in pcap-dag.c pcap-dag.h pcap-dlpi.c pcap-dos.c pcap-dos.h pcap-enet.c +pcap-libdlpi.c pcap-linux.c pcap-nit.c -pcap-nit.h pcap-null.c pcap-pf.c -pcap-pf.h pcap-septel.c pcap-septel.h +pcap-sita.c +pcap-sita.h +pcap-sita.html pcap-snit.c pcap-snoop.c pcap-stdinc.h +pcap-usb-linux.c +pcap-usb-linux.h pcap-win32.c -pcap1.h -wlan_filtering.patch +runlex.sh diff --git a/contrib/libpcap/VERSION b/contrib/libpcap/VERSION index e3e180701e..3eefcb9dd5 100644 --- a/contrib/libpcap/VERSION +++ b/contrib/libpcap/VERSION @@ -1 +1 @@ -0.9.8 +1.0.0 diff --git a/contrib/libpcap/atmuni31.h b/contrib/libpcap/atmuni31.h index 877ed6879c..11242b8bfc 100644 --- a/contrib/libpcap/atmuni31.h +++ b/contrib/libpcap/atmuni31.h @@ -29,18 +29,18 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/libpcap/atmuni31.h,v 1.1 2002/07/11 09:06:32 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/atmuni31.h,v 1.1.6.2 2007/10/22 19:30:14 guy Exp $ (LBL) */ /* Based on UNI3.1 standard by ATM Forum */ /* ATM traffic types based on VPI=0 and (the following VCI */ -#define PPC 0x05 /* Point-to-point signal msg */ -#define BCC 0x02 /* Broadcast signal msg */ -#define OAMF4SC 0x03 /* Segment OAM F4 flow cell */ -#define OAMF4EC 0x04 /* End-to-end OAM F4 flow cell */ -#define METAC 0x01 /* Meta signal msg */ -#define ILMIC 0x10 /* ILMI msg */ +#define VCI_PPC 0x05 /* Point-to-point signal msg */ +#define VCI_BCC 0x02 /* Broadcast signal msg */ +#define VCI_OAMF4SC 0x03 /* Segment OAM F4 flow cell */ +#define VCI_OAMF4EC 0x04 /* End-to-end OAM F4 flow cell */ +#define VCI_METAC 0x01 /* Meta signal msg */ +#define VCI_ILMIC 0x10 /* ILMI msg */ /* Q.2931 signalling messages */ #define CALL_PROCEED 0x02 /* call proceeding */ diff --git a/contrib/libpcap/bpf/net/bpf_filter.c b/contrib/libpcap/bpf/net/bpf_filter.c index 40df32a8b3..a2733d1b1b 100644 --- a/contrib/libpcap/bpf/net/bpf_filter.c +++ b/contrib/libpcap/bpf/net/bpf_filter.c @@ -40,7 +40,7 @@ #if !(defined(lint) || defined(KERNEL) || defined(_KERNEL)) static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.44 2003/11/15 23:24:07 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.45.2.1 2008/01/02 04:22:16 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -71,7 +71,7 @@ static const char rcsid[] _U_ = #endif /* WIN32 */ -#include +#include #if !defined(KERNEL) && !defined(_KERNEL) #include @@ -200,8 +200,8 @@ m_xhalf(m, k, err) */ u_int bpf_filter(pc, p, wirelen, buflen) - register struct bpf_insn *pc; - register u_char *p; + register const struct bpf_insn *pc; + register const u_char *p; u_int wirelen; register u_int buflen; { @@ -512,54 +512,155 @@ bpf_filter(pc, p, wirelen, buflen) } } - /* * Return true if the 'fcode' is a valid filter program. * The constraints are that each jump be forward and to a valid - * code. The code must terminate with either an accept or reject. - * 'valid' is an array for use by the routine (it must be at least - * 'len' bytes long). + * code, that memory accesses are within valid ranges (to the + * extent that this can be checked statically; loads of packet + * data have to be, and are, also checked at run time), and that + * the code terminates with either an accept or reject. * * The kernel needs to be able to verify an application's filter code. * Otherwise, a bogus program could easily crash the system. */ int bpf_validate(f, len) - struct bpf_insn *f; + const struct bpf_insn *f; int len; { - register int i; - register struct bpf_insn *p; + u_int i, from; + const struct bpf_insn *p; + + if (len < 1) + return 0; + /* + * There's no maximum program length in userland. + */ +#if defined(KERNEL) || defined(_KERNEL) + if (len > BPF_MAXINSNS) + return 0; +#endif for (i = 0; i < len; ++i) { + p = &f[i]; + switch (BPF_CLASS(p->code)) { /* - * Check that that jumps are forward, and within - * the code block. + * Check that memory operations use valid addresses. */ - p = &f[i]; - if (BPF_CLASS(p->code) == BPF_JMP) { - register int from = i + 1; - - if (BPF_OP(p->code) == BPF_JA) { - if (from + p->k >= (unsigned)len) + case BPF_LD: + case BPF_LDX: + switch (BPF_MODE(p->code)) { + case BPF_IMM: + break; + case BPF_ABS: + case BPF_IND: + case BPF_MSH: + /* + * There's no maximum packet data size + * in userland. The runtime packet length + * check suffices. + */ +#if defined(KERNEL) || defined(_KERNEL) + /* + * More strict check with actual packet length + * is done runtime. + */ + if (p->k >= bpf_maxbufsize) return 0; +#endif + break; + case BPF_MEM: + if (p->k >= BPF_MEMWORDS) + return 0; + break; + case BPF_LEN: + break; + default: + return 0; } - else if (from + p->jt >= len || from + p->jf >= len) + break; + case BPF_ST: + case BPF_STX: + if (p->k >= BPF_MEMWORDS) return 0; - } - /* - * Check that memory operations use valid addresses. - */ - if ((BPF_CLASS(p->code) == BPF_ST || - (BPF_CLASS(p->code) == BPF_LD && - (p->code & 0xe0) == BPF_MEM)) && - (p->k >= BPF_MEMWORDS || p->k < 0)) - return 0; - /* - * Check for constant division by 0. - */ - if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0) + break; + case BPF_ALU: + switch (BPF_OP(p->code)) { + case BPF_ADD: + case BPF_SUB: + case BPF_MUL: + case BPF_OR: + case BPF_AND: + case BPF_LSH: + case BPF_RSH: + case BPF_NEG: + break; + case BPF_DIV: + /* + * Check for constant division by 0. + */ + if (BPF_RVAL(p->code) == BPF_K && p->k == 0) + return 0; + break; + default: + return 0; + } + break; + case BPF_JMP: + /* + * Check that jumps are within the code block, + * and that unconditional branches don't go + * backwards as a result of an overflow. + * Unconditional branches have a 32-bit offset, + * so they could overflow; we check to make + * sure they don't. Conditional branches have + * an 8-bit offset, and the from address is <= + * BPF_MAXINSNS, and we assume that BPF_MAXINSNS + * is sufficiently small that adding 255 to it + * won't overflow. + * + * We know that len is <= BPF_MAXINSNS, and we + * assume that BPF_MAXINSNS is < the maximum size + * of a u_int, so that i + 1 doesn't overflow. + * + * For userland, we don't know that the from + * or len are <= BPF_MAXINSNS, but we know that + * from <= len, and, except on a 64-bit system, + * it's unlikely that len, if it truly reflects + * the size of the program we've been handed, + * will be anywhere near the maximum size of + * a u_int. We also don't check for backward + * branches, as we currently support them in + * userland for the protochain operation. + */ + from = i + 1; + switch (BPF_OP(p->code)) { + case BPF_JA: +#if defined(KERNEL) || defined(_KERNEL) + if (from + p->k < from || from + p->k >= len) +#else + if (from + p->k >= len) +#endif + return 0; + break; + case BPF_JEQ: + case BPF_JGT: + case BPF_JGE: + case BPF_JSET: + if (from + p->jt >= len || from + p->jf >= len) + return 0; + break; + default: + return 0; + } + break; + case BPF_RET: + break; + case BPF_MISC: + break; + default: return 0; + } } return BPF_CLASS(f[len - 1].code) == BPF_RET; } diff --git a/contrib/libpcap/bpf_dump.c b/contrib/libpcap/bpf_dump.c index 303602e207..5c0033dc5d 100644 --- a/contrib/libpcap/bpf_dump.c +++ b/contrib/libpcap/bpf_dump.c @@ -20,7 +20,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.14 2003/11/15 23:23:57 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.14.4.1 2008/01/02 04:22:16 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -31,9 +31,9 @@ static const char rcsid[] _U_ = #include void -bpf_dump(struct bpf_program *p, int option) +bpf_dump(const struct bpf_program *p, int option) { - struct bpf_insn *insn; + const struct bpf_insn *insn; int i; int n = p->bf_len; diff --git a/contrib/libpcap/bpf_image.c b/contrib/libpcap/bpf_image.c index 2e761289f7..91f7cef43b 100644 --- a/contrib/libpcap/bpf_image.c +++ b/contrib/libpcap/bpf_image.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.26.2.1 2007/06/11 09:52:04 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.27.2.1 2008/01/02 04:22:16 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -39,7 +39,7 @@ static const char rcsid[] _U_ = char * bpf_image(p, n) - struct bpf_insn *p; + const struct bpf_insn *p; int n; { int v; diff --git a/contrib/libpcap/etherent.c b/contrib/libpcap/etherent.c index 9d299557f0..27e55024e3 100644 --- a/contrib/libpcap/etherent.c +++ b/contrib/libpcap/etherent.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.22 2003/11/15 23:23:57 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.23 2006/10/04 18:09:22 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -37,7 +37,7 @@ static const char rcsid[] _U_ = #include "pcap-int.h" -#include +#include #ifdef HAVE_OS_PROTO_H #include "os-proto.h" diff --git a/contrib/libpcap/ethertype.h b/contrib/libpcap/ethertype.h index 2d21c6d9cc..867d33eaed 100644 --- a/contrib/libpcap/ethertype.h +++ b/contrib/libpcap/ethertype.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.13.2.1 2005/09/05 09:08:03 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.14 2005/09/05 09:06:58 guy Exp $ (LBL) */ /* diff --git a/contrib/libpcap/fad-getad.c b/contrib/libpcap/fad-getad.c index 8101165796..2ce6d7009b 100644 --- a/contrib/libpcap/fad-getad.c +++ b/contrib/libpcap/fad-getad.c @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.10.2.2 2007/09/14 00:45:17 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.12 2007/09/14 00:44:55 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H diff --git a/contrib/libpcap/gencode.c b/contrib/libpcap/gencode.c index d2cae2101c..41057ba8cb 100644 --- a/contrib/libpcap/gencode.c +++ b/contrib/libpcap/gencode.c @@ -21,7 +21,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.221.2.53 2007/09/12 19:17:24 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.290.2.16 2008-09-22 20:16:01 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -68,10 +68,11 @@ static const char rcsid[] _U_ = #include "nlpid.h" #include "llc.h" #include "gencode.h" +#include "ieee80211.h" #include "atmuni31.h" #include "sunatmpos.h" #include "ppp.h" -#include "sll.h" +#include "pcap/sll.h" #include "arcnet.h" #ifdef HAVE_NET_PFVAR_H #include @@ -87,7 +88,7 @@ static const char rcsid[] _U_ = #include /* for "struct addrinfo" */ #endif /* WIN32 */ #endif /*INET6*/ -#include +#include #define ETHERMTU 1500 @@ -105,8 +106,8 @@ static const char rcsid[] _U_ = static jmp_buf top_ctx; static pcap_t *bpf_pcap; -#ifdef WIN32 /* Hack for updating VLAN, MPLS, and PPPoE offsets. */ +#ifdef WIN32 static u_int orig_linktype = (u_int)-1, orig_nl = (u_int)-1, label_stack_depth = (u_int)-1; #else static u_int orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U; @@ -134,6 +135,7 @@ bpf_error(const char *fmt, ...) static void init_linktype(pcap_t *); +static void init_regs(void); static int alloc_reg(void); static void free_reg(int); @@ -145,7 +147,8 @@ static struct block *root; */ enum e_offrel { OR_PACKET, /* relative to the beginning of the packet */ - OR_LINK, /* relative to the link-layer header */ + OR_LINK, /* relative to the beginning of the link-layer header */ + OR_MACPL, /* relative to the end of the MAC-layer header */ OR_NET, /* relative to the network-layer header */ OR_NET_NOSNAP, /* relative to the network-layer header, with no SNAP header at the link layer */ OR_TRAN_IPV4, /* relative to the transport-layer header, with IPv4 network layer */ @@ -190,6 +193,7 @@ static struct block *gen_bcmp(enum e_offrel, u_int, u_int, const u_char *); static struct block *gen_ncmp(enum e_offrel, bpf_u_int32, bpf_u_int32, bpf_u_int32, bpf_u_int32, int, bpf_int32); static struct slist *gen_load_llrel(u_int, u_int); +static struct slist *gen_load_macplrel(u_int, u_int); static struct slist *gen_load_a(enum e_offrel, u_int, u_int); static struct slist *gen_loadx_iphdrlen(void); static struct block *gen_uncond(int); @@ -197,12 +201,16 @@ static inline struct block *gen_true(void); static inline struct block *gen_false(void); static struct block *gen_ether_linktype(int); static struct block *gen_linux_sll_linktype(int); -static void insert_radiotap_load_llprefixlen(struct block *); -static void insert_ppi_load_llprefixlen(struct block *); -static void insert_load_llprefixlen(struct block *); +static struct slist *gen_load_prism_llprefixlen(void); +static struct slist *gen_load_avs_llprefixlen(void); +static struct slist *gen_load_radiotap_llprefixlen(void); +static struct slist *gen_load_ppi_llprefixlen(void); +static void insert_compute_vloffsets(struct block *); static struct slist *gen_llprefixlen(void); +static struct slist *gen_off_macpl(void); +static int ethertype_to_ppptype(int); static struct block *gen_linktype(int); -static struct block *gen_snap(bpf_u_int32, bpf_u_int32, u_int); +static struct block *gen_snap(bpf_u_int32, bpf_u_int32); static struct block *gen_llc_linktype(int); static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int); #ifdef INET6 @@ -247,6 +255,7 @@ static struct slist *xfer_to_x(struct arth *); static struct slist *xfer_to_a(struct arth *); static struct block *gen_mac_multicast(int); static struct block *gen_len(int, int); +static struct block *gen_check_802_11_data_frame(void); static struct block *gen_ppi_dlt_check(void); static struct block *gen_msg_abbrev(int type); @@ -369,6 +378,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, n_errors = 0; root = NULL; bpf_pcap = p; + init_regs(); if (setjmp(top_ctx)) { lex_cleanup(); freechunks(); @@ -484,24 +494,11 @@ merge(b0, b1) *p = b1; } - void finish_parse(p) struct block *p; { struct block *ppi_dlt_check; - - ppi_dlt_check = gen_ppi_dlt_check(); - - if (ppi_dlt_check != NULL) - { - gen_and(ppi_dlt_check, p); - } - - backpatch(p, gen_retblk(snaplen)); - p->sense = !p->sense; - backpatch(p, gen_retblk(0)); - root = p->head; /* * Insert before the statements of the first (root) block any @@ -512,14 +509,30 @@ finish_parse(p) * statements of all blocks that use those lengths and that * have no predecessors that use them, so that we only compute * the lengths if we need them. There might be even better - * approaches than that. However, as we're currently only - * handling variable-length radiotap headers, and as all - * filtering expressions other than raw link[M:N] tests - * require the length of that header, doing more for that - * header length isn't really worth the effort. + * approaches than that. + * + * However, those strategies would be more complicated, and + * as we don't generate code to compute a length if the + * program has no tests that use the length, and as most + * tests will probably use those lengths, we would just + * postpone computing the lengths so that it's not done + * for tests that fail early, and it's not clear that's + * worth the effort. */ + insert_compute_vloffsets(p->head); + + /* + * For DLT_PPI captures, generate a check of the per-packet + * DLT value to make sure it's DLT_IEEE802_11. + */ + ppi_dlt_check = gen_ppi_dlt_check(); + if (ppi_dlt_check != NULL) + gen_and(ppi_dlt_check, p); - insert_load_llprefixlen(root); + backpatch(p, gen_retblk(snaplen)); + p->sense = !p->sense; + backpatch(p, gen_retblk(0)); + root = p->head; } void @@ -682,13 +695,7 @@ gen_ncmp(offrel, offset, size, mask, jtype, reverse, v) * Various code constructs need to know the layout of the data link * layer. These variables give the necessary offsets from the beginning * of the packet data. - * - * If the link layer has variable_length headers, the offsets are offsets - * from the end of the link-link-layer header, and "reg_ll_size" is - * the register number for a register containing the length of the - * link-layer header. Otherwise, "reg_ll_size" is -1. */ -static int reg_ll_size; /* * This is the offset of the beginning of the link-layer header from @@ -701,12 +708,48 @@ static int reg_ll_size; static u_int off_ll; /* - * This is the offset of the beginning of the MAC-layer header. + * If there's a variable-length header preceding the link-layer header, + * "reg_off_ll" is the register number for a register containing the + * length of that header, and therefore the offset of the link-layer + * header from the beginning of the raw packet data. Otherwise, + * "reg_off_ll" is -1. + */ +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. */ static u_int off_mac; +/* + * This is the offset of the beginning of the MAC-layer payload, + * from the beginning of the raw packet data. + * + * I.e., it's the sum of the length of the link-layer header (without, + * for example, any 802.2 LLC header, so it's the MAC-layer + * portion of that header), plus any prefix preceding the + * link-layer header. + */ +static u_int off_macpl; + +/* + * This is 1 if the offset of the beginning of the MAC-layer payload + * from the beginning of the link-layer header is variable-length. + */ +static int off_macpl_is_variable; + +/* + * If the link layer has variable_length headers, "reg_off_macpl" + * is the register number for a register containing the length of the + * link-layer header plus the length of any variable-length header + * preceding the link-layer header. Otherwise, "reg_off_macpl" + * is -1. + */ +static int reg_off_macpl; + /* * "off_linktype" is the offset to information in the link-layer header * giving the packet type. This offset is relative to the beginning @@ -729,6 +772,13 @@ static u_int off_mac; */ static u_int off_linktype; +/* + * TRUE if "pppoes" appeared in the filter; it causes link-layer type + * checks to check the PPP header, assumed to follow a LAN-style link- + * layer header and a PPPoE session header. + */ +static int is_pppoes = 0; + /* * TRUE if the link layer includes an ATM pseudo-header. */ @@ -768,8 +818,8 @@ static u_int off_payload; /* * These are offsets to the beginning of the network-layer header. - * They are relative to the beginning of the link-layer header (i.e., - * they don't include off_ll). + * They are relative to the beginning of the MAC-layer payload (i.e., + * they don't include off_ll or off_macpl). * * If the link layer never uses 802.2 LLC: * @@ -815,6 +865,11 @@ init_linktype(p) off_proto = -1; off_payload = -1; + /* + * And that we're not doing PPPoE. + */ + is_pppoes = 0; + /* * And assume we're not doing SS7. */ @@ -825,34 +880,40 @@ init_linktype(p) off_sls = -1; /* - * Also assume it's not 802.11 with a fixed-length radio header. + * Also assume it's not 802.11. */ off_ll = 0; + off_macpl = 0; + off_macpl_is_variable = 0; orig_linktype = -1; orig_nl = -1; label_stack_depth = 0; - reg_ll_size = -1; + reg_off_ll = -1; + reg_off_macpl = -1; switch (linktype) { case DLT_ARCNET: off_linktype = 2; - off_nl = 6; /* XXX in reality, variable! */ - off_nl_nosnap = 6; /* no 802.2 LLC */ + off_macpl = 6; + off_nl = 0; /* XXX in reality, variable! */ + off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_ARCNET_LINUX: off_linktype = 4; - off_nl = 8; /* XXX in reality, variable! */ - off_nl_nosnap = 8; /* no 802.2 LLC */ + off_macpl = 8; + off_nl = 0; /* XXX in reality, variable! */ + off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_EN10MB: off_linktype = 12; - off_nl = 14; /* Ethernet II */ - off_nl_nosnap = 17; /* 802.3+802.2 */ + off_macpl = 14; /* Ethernet header length */ + off_nl = 0; /* Ethernet II */ + off_nl_nosnap = 3; /* 802.3+802.2 */ return; case DLT_SLIP: @@ -861,29 +922,33 @@ init_linktype(p) * header is hacked into our SLIP driver. */ off_linktype = -1; - off_nl = 16; - off_nl_nosnap = 16; /* no 802.2 LLC */ + off_macpl = 16; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_SLIP_BSDOS: /* XXX this may be the same as the DLT_PPP_BSDOS case */ off_linktype = -1; /* XXX end */ - off_nl = 24; - off_nl_nosnap = 24; /* no 802.2 LLC */ + off_macpl = 24; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_NULL: case DLT_LOOP: off_linktype = 0; - off_nl = 4; - off_nl_nosnap = 4; /* no 802.2 LLC */ + off_macpl = 4; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_ENC: off_linktype = 0; - off_nl = 12; - off_nl_nosnap = 12; /* no 802.2 LLC */ + off_macpl = 12; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_PPP: @@ -891,8 +956,9 @@ init_linktype(p) case DLT_C_HDLC: /* BSD/OS Cisco HDLC */ case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */ off_linktype = 2; - off_nl = 4; - off_nl_nosnap = 4; /* no 802.2 LLC */ + off_macpl = 4; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_PPP_ETHER: @@ -901,14 +967,16 @@ init_linktype(p) * only covers session state. */ off_linktype = 6; - off_nl = 8; - off_nl_nosnap = 8; /* no 802.2 LLC */ + off_macpl = 8; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_PPP_BSDOS: off_linktype = 5; - off_nl = 24; - off_nl_nosnap = 24; /* no 802.2 LLC */ + off_macpl = 24; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_FDDI: @@ -924,12 +992,12 @@ init_linktype(p) #ifdef PCAP_FDDIPAD off_linktype += pcap_fddipad; #endif - off_nl = 21; /* FDDI+802.2+SNAP */ - off_nl_nosnap = 16; /* FDDI+802.2 */ + off_macpl = 13; /* FDDI MAC header length */ #ifdef PCAP_FDDIPAD - off_nl += pcap_fddipad; - off_nl_nosnap += pcap_fddipad; + off_macpl += pcap_fddipad; #endif + off_nl = 8; /* 802.2+SNAP */ + off_nl_nosnap = 3; /* 802.2 */ return; case DLT_IEEE802: @@ -957,11 +1025,15 @@ init_linktype(p) * 8 - figure out which byte that is). */ off_linktype = 14; - off_nl = 22; /* Token Ring+802.2+SNAP */ - off_nl_nosnap = 17; /* Token Ring+802.2 */ + off_macpl = 14; /* Token Ring MAC header length */ + off_nl = 8; /* 802.2+SNAP */ + off_nl_nosnap = 3; /* 802.2 */ return; case DLT_IEEE802_11: + case DLT_PRISM_HEADER: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: /* * 802.11 doesn't really have a link-level type field. * We set "off_linktype" to the offset of the LLC header. @@ -970,90 +1042,37 @@ init_linktype(p) * is being used and pick out the encapsulated Ethernet type. * XXX - should we generate code to check for SNAP? * - * XXX - the header is actually variable-length. We - * assume a 24-byte link-layer header, as appears in - * data frames in networks with no bridges. If the - * fromds and tods 802.11 header bits are both set, - * it's actually supposed to be 30 bytes. - */ - off_linktype = 24; - off_nl = 32; /* 802.11+802.2+SNAP */ - off_nl_nosnap = 27; /* 802.11+802.2 */ - return; - - case DLT_PRISM_HEADER: - /* - * Same as 802.11, but with an additional header before - * the 802.11 header, containing a bunch of additional - * information including radio-level information. - * - * The header is 144 bytes long. - * - * XXX - same variable-length header problem; at least - * the Prism header is fixed-length. + * We also handle variable-length radio headers here. + * The Prism header is in theory variable-length, but in + * practice it's always 144 bytes long. However, some + * drivers on Linux use ARPHRD_IEEE80211_PRISM, but + * sometimes or always supply an AVS header, so we + * have to check whether the radio header is a Prism + * header or an AVS header, so, in practice, it's + * variable-length. */ - off_ll = 144; off_linktype = 24; - off_nl = 32; /* Prism+802.11+802.2+SNAP */ - off_nl_nosnap = 27; /* Prism+802.11+802.2 */ - return; - - case DLT_IEEE802_11_RADIO_AVS: - /* - * Same as 802.11, but with an additional header before - * the 802.11 header, containing a bunch of additional - * information including radio-level information. - * - * The header is 64 bytes long, at least in its - * current incarnation. - * - * XXX - same variable-length header problem, only - * more so; this header is also variable-length, - * with the length being the 32-bit big-endian - * number at an offset of 4 from the beginning - * of the radio header. We should handle that the - * same way we handle the length at the beginning - * of the radiotap header. - * - * XXX - in Linux, do any drivers that supply an AVS - * header supply a link-layer type other than - * ARPHRD_IEEE80211_PRISM? If so, we should map that - * to DLT_IEEE802_11_RADIO_AVS; if not, or if there are - * any drivers that supply an AVS header but supply - * an ARPHRD value of ARPHRD_IEEE80211_PRISM, we'll - * have to check the header in the generated code to - * determine whether it's Prism or AVS. - */ - off_ll = 64; - off_linktype = 24; - off_nl = 32; /* Radio+802.11+802.2+SNAP */ - off_nl_nosnap = 27; /* Radio+802.11+802.2 */ + off_macpl = 0; /* link-layer header is variable-length */ + off_macpl_is_variable = 1; + off_nl = 8; /* 802.2+SNAP */ + off_nl_nosnap = 3; /* 802.2 */ return; - - /* - * At the moment we treat PPI as normal Radiotap encoded - * packets. The difference is in the function that generates - * the code at the beginning to compute the header length. - * Since this code generator of PPI supports bare 802.11 - * encapsulation only (i.e. the encapsulated DLT should be - * DLT_IEEE802_11) we generate code to check for this too. - */ case DLT_PPI: - case DLT_IEEE802_11_RADIO: - /* - * Same as 802.11, but with an additional header before - * the 802.11 header, containing a bunch of additional - * information including radio-level information. - * - * The radiotap header is variable length, and we - * generate code to compute its length and store it - * in a register. These offsets are relative to the - * beginning of the 802.11 header. + /* + * At the moment we treat PPI the same way that we treat + * normal Radiotap encoded packets. The difference is in + * the function that generates the code at the beginning + * to compute the header length. Since this code generator + * of PPI supports bare 802.11 encapsulation only (i.e. + * the encapsulated DLT should be DLT_IEEE802_11) we + * generate code to check for this too. */ off_linktype = 24; - off_nl = 32; /* 802.11+802.2+SNAP */ - off_nl_nosnap = 27; /* 802.11+802.2 */ + off_macpl = 0; /* link-layer header is variable-length */ + off_macpl_is_variable = 1; + off_nl = 8; /* 802.2+SNAP */ + off_nl_nosnap = 3; /* 802.2 */ return; case DLT_ATM_RFC1483: @@ -1070,6 +1089,7 @@ init_linktype(p) * PPPo{A,E} and a PPP protocol of IP and.... */ off_linktype = 0; + off_macpl = 0; /* packet begins with LLC header */ off_nl = 8; /* 802.2+SNAP */ off_nl_nosnap = 3; /* 802.2 */ return; @@ -1083,23 +1103,26 @@ init_linktype(p) off_vpi = SUNATM_VPI_POS; off_vci = SUNATM_VCI_POS; off_proto = PROTO_POS; - off_mac = -1; /* LLC-encapsulated, so no MAC-layer header */ + off_mac = -1; /* assume LLC-encapsulated, so no MAC-layer header */ off_payload = SUNATM_PKT_BEGIN_POS; off_linktype = off_payload; - off_nl = off_payload+8; /* 802.2+SNAP */ - off_nl_nosnap = off_payload+3; /* 802.2 */ + off_macpl = off_payload; /* if LLC-encapsulated */ + off_nl = 8; /* 802.2+SNAP */ + off_nl_nosnap = 3; /* 802.2 */ return; case DLT_RAW: off_linktype = -1; + off_macpl = 0; off_nl = 0; off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_LINUX_SLL: /* fake header for Linux cooked socket */ off_linktype = 14; - off_nl = 16; - off_nl_nosnap = 16; /* no 802.2 LLC */ + off_macpl = 16; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_LTALK: @@ -1109,6 +1132,7 @@ init_linktype(p) * "long" DDP packet following. */ off_linktype = -1; + off_macpl = 0; off_nl = 0; off_nl_nosnap = 0; /* no 802.2 LLC */ return; @@ -1125,8 +1149,9 @@ init_linktype(p) * 2625 says SNAP should be used. */ off_linktype = 16; - off_nl = 24; /* IPFC+802.2+SNAP */ - off_nl_nosnap = 19; /* IPFC+802.2 */ + off_macpl = 16; + off_nl = 8; /* 802.2+SNAP */ + off_nl_nosnap = 3; /* 802.2 */ return; case DLT_FRELAY: @@ -1135,6 +1160,7 @@ init_linktype(p) * frames (NLPID of 0x80). */ off_linktype = -1; + off_macpl = 0; off_nl = 0; off_nl_nosnap = 0; /* no 802.2 LLC */ return; @@ -1146,14 +1172,16 @@ init_linktype(p) */ case DLT_MFR: off_linktype = -1; + off_macpl = 0; off_nl = 4; off_nl_nosnap = 0; /* XXX - for now -> no 802.2 LLC */ return; case DLT_APPLE_IP_OVER_IEEE1394: off_linktype = 16; - off_nl = 18; - off_nl_nosnap = 18; /* no 802.2 LLC */ + off_macpl = 18; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ return; case DLT_LINUX_IRDA: @@ -1161,6 +1189,7 @@ init_linktype(p) * Currently, only raw "link[N:M]" filtering is supported. */ off_linktype = -1; + off_macpl = -1; off_nl = -1; off_nl_nosnap = -1; return; @@ -1170,21 +1199,24 @@ init_linktype(p) * 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_nl = 44; /* Ethernet II */ - off_nl_nosnap = 44; /* XXX - what does it do with 802.3 packets? */ + off_macpl = 44; + off_nl = 0; /* Ethernet II */ + off_nl_nosnap = 0; /* XXX - what does it do with 802.3 packets? */ return; #ifdef HAVE_NET_PFVAR_H case DLT_PFLOG: off_linktype = 0; - off_nl = PFLOG_HDRLEN; - off_nl_nosnap = PFLOG_HDRLEN; /* no 802.2 LLC */ + off_macpl = PFLOG_HDRLEN; + off_nl = 0; + off_nl_nosnap = 0; /* no 802.2 LLC */ return; #endif @@ -1195,26 +1227,30 @@ init_linktype(p) case DLT_JUNIPER_CHDLC: case DLT_JUNIPER_FRELAY: off_linktype = 4; - off_nl = 4; + off_macpl = 4; + off_nl = 0; off_nl_nosnap = -1; /* no 802.2 LLC */ return; case DLT_JUNIPER_ATM1: - off_linktype = 4; /* in reality variable between 4-8 */ - off_nl = 4; - off_nl_nosnap = 14; + off_linktype = 4; /* in reality variable between 4-8 */ + off_macpl = 4; /* in reality variable between 4-8 */ + off_nl = 0; + off_nl_nosnap = 10; return; case DLT_JUNIPER_ATM2: - off_linktype = 8; /* in reality variable between 8-12 */ - off_nl = 8; - off_nl_nosnap = 18; + off_linktype = 8; /* in reality variable between 8-12 */ + off_macpl = 8; /* in reality variable between 8-12 */ + off_nl = 0; + off_nl_nosnap = 10; return; /* frames captured on a Juniper PPPoE service PIC * contain raw ethernet frames */ case DLT_JUNIPER_PPPOE: case DLT_JUNIPER_ETHER: + off_macpl = 14; off_linktype = 16; off_nl = 18; /* Ethernet II */ off_nl_nosnap = 21; /* 802.3+802.2 */ @@ -1222,36 +1258,56 @@ init_linktype(p) case DLT_JUNIPER_PPPOE_ATM: off_linktype = 4; - off_nl = 6; - off_nl_nosnap = -1; /* no 802.2 LLC */ + off_macpl = 6; + off_nl = 0; + off_nl_nosnap = -1; /* no 802.2 LLC */ return; case DLT_JUNIPER_GGSN: off_linktype = 6; - off_nl = 12; - off_nl_nosnap = -1; /* no 802.2 LLC */ + off_macpl = 12; + off_nl = 0; + off_nl_nosnap = -1; /* no 802.2 LLC */ return; case DLT_JUNIPER_ES: off_linktype = 6; - off_nl = -1; /* not really a network layer but raw IP adresses */ + off_macpl = -1; /* not really a network layer but raw IP addresses */ + off_nl = -1; /* not really a network layer but raw IP addresses */ off_nl_nosnap = -1; /* no 802.2 LLC */ return; case DLT_JUNIPER_MONITOR: off_linktype = 12; - off_nl = 12; /* raw IP/IP6 header */ + off_macpl = 12; + off_nl = 0; /* raw IP/IP6 header */ off_nl_nosnap = -1; /* no 802.2 LLC */ return; case DLT_JUNIPER_SERVICES: off_linktype = 12; + off_macpl = -1; /* L3 proto location dep. on cookie type */ off_nl = -1; /* L3 proto location dep. on cookie type */ off_nl_nosnap = -1; /* no 802.2 LLC */ return; case DLT_JUNIPER_VP: off_linktype = 18; + off_macpl = -1; + off_nl = -1; + off_nl_nosnap = -1; + return; + + case DLT_JUNIPER_ST: + off_linktype = 18; + off_macpl = -1; + off_nl = -1; + off_nl_nosnap = -1; + return; + + case DLT_JUNIPER_ISM: + off_linktype = 8; + off_macpl = -1; off_nl = -1; off_nl_nosnap = -1; return; @@ -1263,6 +1319,7 @@ init_linktype(p) off_dpc = 4; off_sls = 7; off_linktype = -1; + off_macpl = -1; off_nl = -1; off_nl_nosnap = -1; return; @@ -1274,6 +1331,19 @@ init_linktype(p) off_dpc = 8; off_sls = 11; off_linktype = -1; + off_macpl = -1; + off_nl = -1; + off_nl_nosnap = -1; + return; + + case DLT_ERF: + off_li = 22; + off_sio = 23; + off_opc = 24; + off_dpc = 24; + off_sls = 27; + off_linktype = -1; + off_macpl = -1; off_nl = -1; off_nl_nosnap = -1; return; @@ -1281,8 +1351,9 @@ init_linktype(p) #ifdef DLT_PFSYNC case DLT_PFSYNC: off_linktype = -1; - off_nl = 4; - off_nl_nosnap = 4; + off_macpl = 4; + off_nl = 0; + off_nl_nosnap = 0; return; #endif @@ -1291,6 +1362,7 @@ init_linktype(p) * Currently, only raw "link[N:M]" filtering is supported. */ off_linktype = -1; + off_macpl = -1; off_nl = -1; off_nl_nosnap = -1; return; @@ -1300,6 +1372,7 @@ init_linktype(p) * Currently, only raw "link[N:M]" filtering is supported. */ off_linktype = -1; + off_macpl = -1; off_nl = -1; off_nl_nosnap = -1; return; @@ -1309,6 +1382,118 @@ init_linktype(p) * 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. + */ + off_linktype = -1; /* variable, min 15, max 71 steps of 7 */ + off_macpl = -1; + off_nl = -1; /* variable, min 16, max 71 steps of 7 */ + off_nl_nosnap = -1; /* no 802.2 LLC */ + 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; off_nl_nosnap = -1; return; @@ -1362,6 +1547,45 @@ gen_load_llrel(offset, size) return s; } +/* + * Load a value relative to the beginning of the MAC-layer payload. + */ +static struct slist * +gen_load_macplrel(offset, size) + u_int offset, size; +{ + struct slist *s, *s2; + + s = gen_off_macpl(); + + /* + * If s is non-null, the offset of the MAC-layer payload is + * variable, and s points to a list of instructions that + * arrange that the X register contains that offset. + * + * Otherwise, the offset of the MAC-layer payload is constant, + * and is in off_macpl. + */ + if (s != NULL) { + /* + * The offset of the MAC-layer payload is in the X + * register. Do an indirect load, to use the X register + * as an offset. + */ + s2 = new_stmt(BPF_LD|BPF_IND|size); + s2->s.k = offset; + sappend(s, s2); + } else { + /* + * The offset of the MAC-layer payload is constant, + * and is in off_macpl; load the value at that offset + * plus the specified offset. + */ + s = new_stmt(BPF_LD|BPF_ABS|size); + s->s.k = off_macpl + offset; + } + return s; +} /* * Load a value relative to the beginning of the specified header. @@ -1384,12 +1608,16 @@ gen_load_a(offrel, offset, size) s = gen_load_llrel(offset, size); break; + case OR_MACPL: + s = gen_load_macplrel(offset, size); + break; + case OR_NET: - s = gen_load_llrel(off_nl + offset, size); + s = gen_load_macplrel(off_nl + offset, size); break; case OR_NET_NOSNAP: - s = gen_load_llrel(off_nl_nosnap + offset, size); + s = gen_load_macplrel(off_nl_nosnap + offset, size); break; case OR_TRAN_IPV4: @@ -1402,21 +1630,22 @@ gen_load_a(offrel, offset, size) s = gen_loadx_iphdrlen(); /* - * Load the item at {offset of the link-layer header} + - * {offset, relative to the start of the link-layer - * header, of the IPv4 header} + {length of the IPv4 header} + + * Load the item at {offset of the MAC-layer payload} + + * {offset, relative to the start of the MAC-layer + * paylod, of the IPv4 header} + {length of the IPv4 header} + * {specified offset}. * - * (If the link-layer is variable-length, it's included - * in the value in the X register, and off_ll is 0.) + * (If the offset of the MAC-layer payload is variable, + * it's included in the value in the X register, and + * off_macpl is 0.) */ s2 = new_stmt(BPF_LD|BPF_IND|size); - s2->s.k = off_ll + off_nl + offset; + s2->s.k = off_macpl + off_nl + offset; sappend(s, s2); break; case OR_TRAN_IPV6: - s = gen_load_llrel(off_nl + 40 + offset, size); + s = gen_load_macplrel(off_nl + 40 + offset, size); break; default: @@ -1436,12 +1665,15 @@ gen_loadx_iphdrlen() { struct slist *s, *s2; - s = gen_llprefixlen(); + s = gen_off_macpl(); if (s != NULL) { /* * There's a variable-length prefix preceding the - * link-layer header. "s" points to a list of statements - * that put the length of that prefix into the X register. + * link-layer header, or the link-layer header is itself + * variable-length. "s" points to a list of statements + * that put the offset of the MAC-layer payload into + * the X register. + * * The 4*([k]&0xf) addressing mode can't be used, as we * don't have a constant offset, so we have to load the * value in question into the A register and add to it @@ -1459,22 +1691,24 @@ gen_loadx_iphdrlen() /* * The A register now contains the length of the - * IP header. We need to add to it the length - * of the prefix preceding the link-layer - * header, which is still in the X register, and - * move the result into the X register. + * IP header. We need to add to it the offset of + * the MAC-layer payload, which is still in the X + * register, and move the result into the X register. */ sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); sappend(s, new_stmt(BPF_MISC|BPF_TAX)); } else { /* * There is no variable-length header preceding the - * link-layer header; add in off_ll, which, if there's - * a fixed-length header preceding the link-layer header, - * is the length of that header. + * link-layer header, and the link-layer header is + * fixed-length; load the length of the IPv4 header, + * which is at an offset of off_nl from the beginning + * of the MAC-layer payload, and thus at an offset + * of off_mac_pl + off_nl from the beginning of the + * raw packet data. */ s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); - s->s.k = off_ll + off_nl; + s->s.k = off_macpl + off_nl; } return s; } @@ -1548,7 +1782,7 @@ gen_ether_linktype(proto) */ b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU); gen_not(b0); - b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_H, (bpf_int32) + b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32) ((proto << 8) | proto)); gen_and(b0, b1); return b1; @@ -1586,17 +1820,15 @@ gen_ether_linktype(proto) * This generates code to check both for the * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3. */ - b0 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B, - (bpf_int32)LLCSAP_IPX); - b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_H, - (bpf_int32)0xFFFF); + b0 = gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)LLCSAP_IPX); + b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)0xFFFF); gen_or(b0, b1); /* * Now we add code to check for SNAP frames with * ETHERTYPE_IPX, i.e. Ethernet_SNAP. */ - b0 = gen_snap(0x000000, ETHERTYPE_IPX, 14); + b0 = gen_snap(0x000000, ETHERTYPE_IPX); gen_or(b0, b1); /* @@ -1651,9 +1883,9 @@ gen_ether_linktype(proto) * type of ETHERTYPE_AARP (Appletalk ARP). */ if (proto == ETHERTYPE_ATALK) - b1 = gen_snap(0x080007, ETHERTYPE_ATALK, 14); + b1 = gen_snap(0x080007, ETHERTYPE_ATALK); else /* proto == ETHERTYPE_AARP */ - b1 = gen_snap(0x000000, ETHERTYPE_AARP, 14); + b1 = gen_snap(0x000000, ETHERTYPE_AARP); gen_and(b0, b1); /* @@ -1730,7 +1962,7 @@ gen_linux_sll_linktype(proto) * (i.e., other SAP values)? */ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2); - b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_H, (bpf_int32) + b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32) ((proto << 8) | proto)); gen_and(b0, b1); return b1; @@ -1761,10 +1993,8 @@ gen_linux_sll_linktype(proto) * then put a check for LINUX_SLL_P_802_2 frames * before it. */ - b0 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B, - (bpf_int32)LLCSAP_IPX); - b1 = gen_snap(0x000000, ETHERTYPE_IPX, - off_linktype + 2); + b0 = gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)LLCSAP_IPX); + b1 = gen_snap(0x000000, ETHERTYPE_IPX); gen_or(b0, b1); b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2); gen_and(b0, b1); @@ -1812,11 +2042,9 @@ gen_linux_sll_linktype(proto) * type of ETHERTYPE_AARP (Appletalk ARP). */ if (proto == ETHERTYPE_ATALK) - b1 = gen_snap(0x080007, ETHERTYPE_ATALK, - off_linktype + 2); + b1 = gen_snap(0x080007, ETHERTYPE_ATALK); else /* proto == ETHERTYPE_AARP */ - b1 = gen_snap(0x000000, ETHERTYPE_AARP, - off_linktype + 2); + b1 = gen_snap(0x000000, ETHERTYPE_AARP); gen_and(b0, b1); /* @@ -1840,7 +2068,7 @@ gen_linux_sll_linktype(proto) */ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2); - b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B, + b1 = gen_cmp(OR_LINK, off_macpl, BPF_B, (bpf_int32)proto); gen_and(b0, b1); return b1; @@ -1860,18 +2088,169 @@ gen_linux_sll_linktype(proto) } } -static void -insert_radiotap_load_llprefixlen(b) - struct block *b; +static struct slist * +gen_load_prism_llprefixlen() { struct slist *s1, *s2; + struct slist *sjeq_avs_cookie; + struct slist *sjcommon; + + /* + * This code is not compatible with the optimizer, as + * we are generating jmp instructions within a normal + * slist of instructions + */ + no_optimize = 1; /* - * Prepend to the statements in this block code to load the - * length of the radiotap header into the register assigned - * to hold that length, if one has been assigned. + * Generate code to load the length of the radio header into + * the register assigned to hold that length, if one has been + * assigned. (If one hasn't been assigned, no code we've + * generated uses that prefix, so we don't need to generate any + * code to load it.) + * + * Some Linux drivers use ARPHRD_IEEE80211_PRISM but sometimes + * or always use the AVS header rather than the Prism header. + * We load a 4-byte big-endian value at the beginning of the + * raw packet data, and see whether, when masked with 0xFFFFF000, + * it's equal to 0x80211000. If so, that indicates that it's + * an AVS header (the masked-out bits are the version number). + * Otherwise, it's a Prism header. + * + * XXX - the Prism header is also, in theory, variable-length, + * but no known software generates headers that aren't 144 + * bytes long. */ - if (reg_ll_size != -1) { + if (reg_off_ll != -1) { + /* + * Load the cookie. + */ + s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS); + s1->s.k = 0; + + /* + * AND it with 0xFFFFF000. + */ + s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K); + s2->s.k = 0xFFFFF000; + sappend(s1, s2); + + /* + * Compare with 0x80211000. + */ + sjeq_avs_cookie = new_stmt(JMP(BPF_JEQ)); + sjeq_avs_cookie->s.k = 0x80211000; + sappend(s1, sjeq_avs_cookie); + + /* + * If it's AVS: + * + * The 4 bytes at an offset of 4 from the beginning of + * the AVS header are the length of the AVS header. + * That field is big-endian. + */ + s2 = new_stmt(BPF_LD|BPF_W|BPF_ABS); + s2->s.k = 4; + sappend(s1, s2); + sjeq_avs_cookie->s.jt = s2; + + /* + * Now jump to the code to allocate a register + * into which to save the header length and + * store the length there. (The "jump always" + * instruction needs to have the k field set; + * it's added to the PC, so, as we're jumping + * over a single instruction, it should be 1.) + */ + sjcommon = new_stmt(JMP(BPF_JA)); + sjcommon->s.k = 1; + sappend(s1, sjcommon); + + /* + * Now for the code that handles the Prism header. + * Just load the length of the Prism header (144) + * into the A register. Have the test for an AVS + * header branch here if we don't have an AVS header. + */ + s2 = new_stmt(BPF_LD|BPF_W|BPF_IMM); + s2->s.k = 144; + sappend(s1, s2); + sjeq_avs_cookie->s.jf = s2; + + /* + * Now allocate a register to hold that value and store + * it. The code for the AVS header will jump here after + * loading the length of the AVS header. + */ + s2 = new_stmt(BPF_ST); + s2->s.k = reg_off_ll; + sappend(s1, s2); + sjcommon->s.jf = s2; + + /* + * Now move it into the X register. + */ + s2 = new_stmt(BPF_MISC|BPF_TAX); + sappend(s1, s2); + + return (s1); + } else + return (NULL); +} + +static struct slist * +gen_load_avs_llprefixlen() +{ + struct slist *s1, *s2; + + /* + * Generate code to load the length of the AVS header into + * the register assigned to hold that length, if one has been + * assigned. (If one hasn't been assigned, no code we've + * generated uses that prefix, so we don't need to generate any + * code to load it.) + */ + if (reg_off_ll != -1) { + /* + * The 4 bytes at an offset of 4 from the beginning of + * the AVS header are the length of the AVS header. + * That field is big-endian. + */ + s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS); + s1->s.k = 4; + + /* + * Now allocate a register to hold that value and store + * it. + */ + s2 = new_stmt(BPF_ST); + s2->s.k = reg_off_ll; + sappend(s1, s2); + + /* + * Now move it into the X register. + */ + s2 = new_stmt(BPF_MISC|BPF_TAX); + sappend(s1, s2); + + return (s1); + } else + return (NULL); +} + +static struct slist * +gen_load_radiotap_llprefixlen() +{ + struct slist *s1, *s2; + + /* + * Generate code to load the length of the radiotap header into + * the register assigned to hold that length, if one has been + * assigned. (If one hasn't been assigned, no code we've + * generated uses that prefix, so we don't need to generate any + * code to load it.) + */ + if (reg_off_ll != -1) { /* * The 2 bytes at offsets of 2 and 3 from the beginning * of the radiotap header are the length of the radiotap @@ -1906,7 +2285,7 @@ insert_radiotap_load_llprefixlen(b) * it. */ s2 = new_stmt(BPF_ST); - s2->s.k = reg_ll_size; + s2->s.k = reg_off_ll; sappend(s1, s2); /* @@ -1915,13 +2294,9 @@ insert_radiotap_load_llprefixlen(b) s2 = new_stmt(BPF_MISC|BPF_TAX); sappend(s1, s2); - /* - * Now append all the existing statements in this - * block to these statements. - */ - sappend(s1, b->stmts); - b->stmts = s1; - } + return (s1); + } else + return (NULL); } /* @@ -1930,21 +2305,21 @@ insert_radiotap_load_llprefixlen(b) * the code at the beginning to compute the header length. * Since this code generator of PPI supports bare 802.11 * encapsulation only (i.e. the encapsulated DLT should be - * DLT_IEEE802_11) we generate code to check for this too. + * DLT_IEEE802_11) we generate code to check for this too; + * that's done in finish_parse(). */ -static void -insert_ppi_load_llprefixlen(b) - struct block *b; +static struct slist * +gen_load_ppi_llprefixlen() { struct slist *s1, *s2; /* - * Prepend to the statements in this block code to load the - * length of the radiotap header into the register assigned - * to hold that length, if one has been assigned. + * Generate code to load the length of the radiotap header + * into the register assigned to hold that length, if one has + * been assigned. */ - if (reg_ll_size != -1) { - /* + if (reg_off_ll != -1) { + /* * The 2 bytes at offsets of 2 and 3 from the beginning * of the radiotap header are the length of the radiotap * header; unfortunately, it's little-endian, so we have @@ -1978,7 +2353,7 @@ insert_ppi_load_llprefixlen(b) * it. */ s2 = new_stmt(BPF_ST); - s2->s.k = reg_ll_size; + s2->s.k = reg_off_ll; sappend(s1, s2); /* @@ -1987,16 +2362,295 @@ insert_ppi_load_llprefixlen(b) s2 = new_stmt(BPF_MISC|BPF_TAX); sappend(s1, s2); + return (s1); + } else + return (NULL); +} + +/* + * Load a value relative to the beginning of the link-layer header after the 802.11 + * header, i.e. LLC_SNAP. + * The link-layer header doesn't necessarily begin at the beginning + * of the packet data; there might be a variable-length prefix containing + * radio information. + */ +static struct slist * +gen_load_802_11_header_len(struct slist *s, struct slist *snext) +{ + struct slist *s2; + struct slist *sjset_data_frame_1; + struct slist *sjset_data_frame_2; + struct slist *sjset_qos; + struct slist *sjset_radiotap_flags; + struct slist *sjset_radiotap_tsft; + struct slist *sjset_tsft_datapad, *sjset_notsft_datapad; + struct slist *s_roundup; + + if (reg_off_macpl == -1) { + /* + * No register has been assigned to the offset of + * the MAC-layer payload, which means nobody needs + * it; don't bother computing it - just return + * what we already have. + */ + return (s); + } + + /* + * This code is not compatible with the optimizer, as + * we are generating jmp instructions within a normal + * slist of instructions + */ + no_optimize = 1; + + /* + * If "s" is non-null, it has code to arrange that the X register + * contains the length of the prefix preceding the link-layer + * header. + * + * Otherwise, the length of the prefix preceding the link-layer + * header is "off_ll". + */ + if (s == NULL) { + /* + * There is no variable-length header preceding the + * link-layer header. + * + * Load the length of the fixed-length prefix preceding + * the link-layer header (if any) into the X register, + * and store it in the reg_off_macpl register. + * That length is off_ll. + */ + s = new_stmt(BPF_LDX|BPF_IMM); + s->s.k = off_ll; + } + + /* + * The X register contains the offset of the beginning of the + * link-layer header; add 24, which is the minimum length + * of the MAC header for a data frame, to that, and store it + * in reg_off_macpl, and then load the Frame Control field, + * which is at the offset in the X register, with an indexed load. + */ + s2 = new_stmt(BPF_MISC|BPF_TXA); + sappend(s, s2); + s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_K); + s2->s.k = 24; + sappend(s, s2); + s2 = new_stmt(BPF_ST); + s2->s.k = reg_off_macpl; + sappend(s, s2); + + s2 = new_stmt(BPF_LD|BPF_IND|BPF_B); + s2->s.k = 0; + sappend(s, s2); + + /* + * Check the Frame Control field to see if this is a data frame; + * a data frame has the 0x08 bit (b3) in that field set and the + * 0x04 bit (b2) clear. + */ + sjset_data_frame_1 = new_stmt(JMP(BPF_JSET)); + sjset_data_frame_1->s.k = 0x08; + sappend(s, sjset_data_frame_1); + + /* + * If b3 is set, test b2, otherwise go to the first statement of + * the rest of the program. + */ + sjset_data_frame_1->s.jt = sjset_data_frame_2 = new_stmt(JMP(BPF_JSET)); + sjset_data_frame_2->s.k = 0x04; + sappend(s, sjset_data_frame_2); + sjset_data_frame_1->s.jf = snext; + + /* + * If b2 is not set, this is a data frame; test the QoS bit. + * Otherwise, go to the first statement of the rest of the + * program. + */ + sjset_data_frame_2->s.jt = snext; + sjset_data_frame_2->s.jf = sjset_qos = new_stmt(JMP(BPF_JSET)); + sjset_qos->s.k = 0x80; /* QoS bit */ + sappend(s, sjset_qos); + + /* + * If it's set, add 2 to reg_off_macpl, to skip the QoS + * field. + * Otherwise, go to the first statement of the rest of the + * program. + */ + sjset_qos->s.jt = s2 = new_stmt(BPF_LD|BPF_MEM); + s2->s.k = reg_off_macpl; + sappend(s, s2); + s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM); + s2->s.k = 2; + sappend(s, s2); + s2 = new_stmt(BPF_ST); + s2->s.k = reg_off_macpl; + sappend(s, s2); + + /* + * If we have a radiotap header, look at it to see whether + * there's Atheros padding between the MAC-layer header + * and the payload. + * + * Note: all of the fields in the radiotap header are + * little-endian, so we byte-swap all of the values + * we test against, as they will be loaded as big-endian + * values. + */ + if (linktype == DLT_IEEE802_11_RADIO) { /* - * Now append all the existing statements in this - * block to these statements. + * Is the IEEE80211_RADIOTAP_FLAGS bit (0x0000002) set + * in the presence flag? */ - sappend(s1, b->stmts); - b->stmts = s1; + sjset_qos->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_W); + s2->s.k = 4; + sappend(s, s2); + + sjset_radiotap_flags = new_stmt(JMP(BPF_JSET)); + sjset_radiotap_flags->s.k = SWAPLONG(0x00000002); + sappend(s, sjset_radiotap_flags); + /* + * If not, skip all of this. + */ + sjset_radiotap_flags->s.jf = snext; + + /* + * Otherwise, is the IEEE80211_RADIOTAP_TSFT bit set? + */ + sjset_radiotap_tsft = sjset_radiotap_flags->s.jt = + new_stmt(JMP(BPF_JSET)); + sjset_radiotap_tsft->s.k = SWAPLONG(0x00000001); + sappend(s, sjset_radiotap_tsft); + + /* + * If IEEE80211_RADIOTAP_TSFT is set, the flags field is + * at an offset of 16 from the beginning of the raw packet + * data (8 bytes for the radiotap header and 8 bytes for + * the TSFT field). + * + * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20) + * is set. + */ + sjset_radiotap_tsft->s.jt = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B); + s2->s.k = 16; + sappend(s, s2); + + sjset_tsft_datapad = new_stmt(JMP(BPF_JSET)); + sjset_tsft_datapad->s.k = 0x20; + sappend(s, sjset_tsft_datapad); + + /* + * If IEEE80211_RADIOTAP_TSFT is not set, the flags field is + * at an offset of 8 from the beginning of the raw packet + * data (8 bytes for the radiotap header). + * + * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20) + * is set. + */ + sjset_radiotap_tsft->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B); + s2->s.k = 8; + sappend(s, s2); + + sjset_notsft_datapad = new_stmt(JMP(BPF_JSET)); + sjset_notsft_datapad->s.k = 0x20; + sappend(s, sjset_notsft_datapad); + + /* + * In either case, if IEEE80211_RADIOTAP_F_DATAPAD is + * set, round the length of the 802.11 header to + * a multiple of 4. Do that by adding 3 and then + * dividing by and multiplying by 4, which we do by + * ANDing with ~3. + */ + s_roundup = new_stmt(BPF_LD|BPF_MEM); + s_roundup->s.k = reg_off_macpl; + sappend(s, s_roundup); + s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM); + s2->s.k = 3; + sappend(s, s2); + s2 = new_stmt(BPF_ALU|BPF_AND|BPF_IMM); + s2->s.k = ~3; + sappend(s, s2); + s2 = new_stmt(BPF_ST); + s2->s.k = reg_off_macpl; + sappend(s, s2); + + sjset_tsft_datapad->s.jt = s_roundup; + sjset_tsft_datapad->s.jf = snext; + sjset_notsft_datapad->s.jt = s_roundup; + sjset_notsft_datapad->s.jf = snext; + } else + sjset_qos->s.jf = snext; + + return s; +} + +static void +insert_compute_vloffsets(b) + struct block *b; +{ + struct slist *s; + + /* + * For link-layer types that have a variable-length header + * preceding the link-layer header, generate code to load + * the offset of the link-layer header into the register + * assigned to that offset, if any. + */ + switch (linktype) { + + case DLT_PRISM_HEADER: + s = gen_load_prism_llprefixlen(); + break; + + case DLT_IEEE802_11_RADIO_AVS: + s = gen_load_avs_llprefixlen(); + break; + + case DLT_IEEE802_11_RADIO: + s = gen_load_radiotap_llprefixlen(); + break; + + case DLT_PPI: + s = gen_load_ppi_llprefixlen(); + break; + + default: + s = NULL; + break; + } + + /* + * For link-layer types that have a variable-length link-layer + * header, generate code to load the offset of the MAC-layer + * payload into the register assigned to that offset, if any. + */ + switch (linktype) { + + case DLT_IEEE802_11: + case DLT_PRISM_HEADER: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PPI: + s = gen_load_802_11_header_len(s, b->stmts); + break; + } + + /* + * If we have any offset-loading code, append all the + * existing statements in the block to those statements, + * and make the resulting list the list of statements + * for the block. + */ + if (s != NULL) { + sappend(s, b->stmts); + b->stmts = s; } } - + static struct block * gen_ppi_dlt_check(void) { @@ -2023,42 +2677,61 @@ gen_ppi_dlt_check(void) return b; } -static void -insert_load_llprefixlen(b) - struct block *b; +static struct slist * +gen_prism_llprefixlen(void) { - switch (linktype) { + struct slist *s; + + if (reg_off_ll == -1) { + /* + * We haven't yet assigned a register for the length + * of the radio header; allocate one. + */ + reg_off_ll = alloc_reg(); + } - /* - * At the moment we treat PPI as normal Radiotap encoded - * packets. The difference is in the function that generates - * the code at the beginning to compute the header length. - * Since this code generator of PPI supports bare 802.11 - * encapsulation only (i.e. the encapsulated DLT should be - * DLT_IEEE802_11) we generate code to check for this too. + /* + * Load the register containing the radio length + * into the X register. */ - case DLT_PPI: - insert_ppi_load_llprefixlen(b); - break; + s = new_stmt(BPF_LDX|BPF_MEM); + s->s.k = reg_off_ll; + return s; +} - case DLT_IEEE802_11_RADIO: - insert_radiotap_load_llprefixlen(b); - break; +static struct slist * +gen_avs_llprefixlen(void) +{ + struct slist *s; + + if (reg_off_ll == -1) { + /* + * We haven't yet assigned a register for the length + * of the AVS header; allocate one. + */ + reg_off_ll = alloc_reg(); } -} + /* + * Load the register containing the AVS length + * into the X register. + */ + s = new_stmt(BPF_LDX|BPF_MEM); + s->s.k = reg_off_ll; + return s; +} static struct slist * gen_radiotap_llprefixlen(void) { struct slist *s; - if (reg_ll_size == -1) { + if (reg_off_ll == -1) { /* * We haven't yet assigned a register for the length * of the radiotap header; allocate one. */ - reg_ll_size = alloc_reg(); + reg_off_ll = alloc_reg(); } /* @@ -2066,7 +2739,7 @@ gen_radiotap_llprefixlen(void) * into the X register. */ s = new_stmt(BPF_LDX|BPF_MEM); - s->s.k = reg_ll_size; + s->s.k = reg_off_ll; return s; } @@ -2083,25 +2756,23 @@ gen_ppi_llprefixlen(void) { struct slist *s; - if (reg_ll_size == -1) { + if (reg_off_ll == -1) { /* * We haven't yet assigned a register for the length * of the radiotap header; allocate one. */ - reg_ll_size = alloc_reg(); + reg_off_ll = alloc_reg(); } /* - * Load the register containing the radiotap length + * Load the register containing the PPI length * into the X register. */ s = new_stmt(BPF_LDX|BPF_MEM); - s->s.k = reg_ll_size; + s->s.k = reg_off_ll; return s; } - - /* * Generate code to compute the link-layer header length, if necessary, * putting it into the X register, and to return either a pointer to a @@ -2113,18 +2784,109 @@ gen_llprefixlen(void) { switch (linktype) { - case DLT_PPI: - return gen_ppi_llprefixlen(); + case DLT_PRISM_HEADER: + return gen_prism_llprefixlen(); + + case DLT_IEEE802_11_RADIO_AVS: + return gen_avs_llprefixlen(); - case DLT_IEEE802_11_RADIO: return gen_radiotap_llprefixlen(); + case DLT_PPI: + return gen_ppi_llprefixlen(); + default: return NULL; } } +/* + * Generate code to load the register containing the offset of the + * MAC-layer payload into the X register; if no register for that offset + * has been allocated, allocate it first. + */ +static struct slist * +gen_off_macpl(void) +{ + struct slist *s; + + if (off_macpl_is_variable) { + if (reg_off_macpl == -1) { + /* + * We haven't yet assigned a register for the offset + * of the MAC-layer payload; allocate one. + */ + reg_off_macpl = alloc_reg(); + } + + /* + * Load the register containing the offset of the MAC-layer + * payload into the X register. + */ + s = new_stmt(BPF_LDX|BPF_MEM); + s->s.k = reg_off_macpl; + return s; + } else { + /* + * That offset isn't variable, so we don't need to + * generate any code. + */ + return NULL; + } +} + +/* + * Map an Ethernet type to the equivalent PPP type. + */ +static int +ethertype_to_ppptype(proto) + int proto; +{ + switch (proto) { + + case ETHERTYPE_IP: + proto = PPP_IP; + break; + +#ifdef INET6 + case ETHERTYPE_IPV6: + proto = PPP_IPV6; + break; +#endif + + case ETHERTYPE_DN: + proto = PPP_DECNET; + break; + + case ETHERTYPE_ATALK: + proto = PPP_APPLE; + break; + + case ETHERTYPE_NS: + proto = PPP_NS; + break; + + case LLCSAP_ISONS: + proto = PPP_OSI; + break; + + case LLCSAP_8021D: + /* + * I'm assuming the "Bridging PDU"s that go + * over PPP are Spanning Tree Protocol + * Bridging PDUs. + */ + proto = PPP_BRPDU; + break; + + case LLCSAP_IPX: + proto = PPP_IPX; + break; + } + return (proto); +} + /* * Generate code to match a particular packet type by matching the * link-layer type field or fields in the 802.2 LLC header. @@ -2143,12 +2905,12 @@ gen_linktype(proto) switch (proto) { case ETHERTYPE_IP: case PPP_IP: - /* FIXME add other L3 proto IDs */ + /* FIXME add other L3 proto IDs */ return gen_mpls_linktype(Q_IP); case ETHERTYPE_IPV6: case PPP_IPV6: - /* FIXME add other L3 proto IDs */ + /* FIXME add other L3 proto IDs */ return gen_mpls_linktype(Q_IPV6); default: @@ -2157,6 +2919,25 @@ gen_linktype(proto) } } + /* + * Are we testing PPPoE packets? + */ + if (is_pppoes) { + /* + * The PPPoE session header is part of the + * MAC-layer payload, so all references + * should be relative to the beginning of + * that payload. + */ + + /* + * We use Ethernet protocol types inside libpcap; + * map them to the corresponding PPP protocol types. + */ + proto = ethertype_to_ppptype(proto); + return gen_cmp(OR_MACPL, off_linktype, BPF_H, (bpf_int32)proto); + } + switch (linktype) { case DLT_EN10MB: @@ -2179,13 +2960,41 @@ gen_linktype(proto) } break; - case DLT_PPI: - case DLT_FDDI: - case DLT_IEEE802: case DLT_IEEE802_11: + case DLT_PRISM_HEADER: case DLT_IEEE802_11_RADIO_AVS: case DLT_IEEE802_11_RADIO: - case DLT_PRISM_HEADER: + case DLT_PPI: + /* + * Check that we have a data frame. + */ + b0 = gen_check_802_11_data_frame(); + + /* + * Now check for the specified link-layer type. + */ + b1 = gen_llc_linktype(proto); + gen_and(b0, b1); + return b1; + /*NOTREACHED*/ + break; + + case DLT_FDDI: + /* + * XXX - check for asynchronous frames, as per RFC 1103. + */ + return gen_llc_linktype(proto); + /*NOTREACHED*/ + break; + + case DLT_IEEE802: + /* + * XXX - check for LLC PDUs, as per IEEE 802.5. + */ + return gen_llc_linktype(proto); + /*NOTREACHED*/ + break; + case DLT_ATM_RFC1483: case DLT_ATM_CLIP: case DLT_IP_OVER_FC: @@ -2270,47 +3079,9 @@ gen_linktype(proto) * We use Ethernet protocol types inside libpcap; * map them to the corresponding PPP protocol types. */ - switch (proto) { - - case ETHERTYPE_IP: - proto = PPP_IP; - break; - -#ifdef INET6 - case ETHERTYPE_IPV6: - proto = PPP_IPV6; - break; -#endif - - case ETHERTYPE_DN: - proto = PPP_DECNET; - break; - - case ETHERTYPE_ATALK: - proto = PPP_APPLE; - break; - - case ETHERTYPE_NS: - proto = PPP_NS; - break; - - case LLCSAP_ISONS: - proto = PPP_OSI; - break; - - case LLCSAP_8021D: - /* - * I'm assuming the "Bridging PDU"s that go - * over PPP are Spanning Tree Protocol - * Bridging PDUs. - */ - proto = PPP_BRPDU; - break; - - case LLCSAP_IPX: - proto = PPP_IPX; - break; - } + proto = ethertype_to_ppptype(proto); + return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto); + /*NOTREACHED*/ break; case DLT_PPP_BSDOS: @@ -2321,6 +3092,10 @@ gen_linktype(proto) switch (proto) { case ETHERTYPE_IP: + /* + * Also check for Van Jacobson-compressed IP. + * XXX - do this for other forms of PPP? + */ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_IP); b1 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJC); gen_or(b0, b1); @@ -2328,42 +3103,12 @@ gen_linktype(proto) gen_or(b1, b0); return b0; -#ifdef INET6 - case ETHERTYPE_IPV6: - proto = PPP_IPV6; - /* more to go? */ - break; -#endif - - case ETHERTYPE_DN: - proto = PPP_DECNET; - break; - - case ETHERTYPE_ATALK: - proto = PPP_APPLE; - break; - - case ETHERTYPE_NS: - proto = PPP_NS; - break; - - case LLCSAP_ISONS: - proto = PPP_OSI; - break; - - case LLCSAP_8021D: - /* - * I'm assuming the "Bridging PDU"s that go - * over PPP are Spanning Tree Protocol - * Bridging PDUs. - */ - proto = PPP_BRPDU; - break; - - case LLCSAP_IPX: - proto = PPP_IPX; - break; + default: + proto = ethertype_to_ppptype(proto); + return gen_cmp(OR_LINK, off_linktype, BPF_H, + (bpf_int32)proto); } + /*NOTREACHED*/ break; case DLT_NULL: @@ -2552,6 +3297,9 @@ gen_linktype(proto) /*NOTREACHED*/ break; + case DLT_MFR: + bpf_error("Multi-link Frame Relay link-layer type filtering not implemented"); + case DLT_JUNIPER_MFR: case DLT_JUNIPER_MLFR: case DLT_JUNIPER_MLPPP: @@ -2568,6 +3316,8 @@ gen_linktype(proto) case DLT_JUNIPER_FRELAY: case DLT_JUNIPER_CHDLC: case DLT_JUNIPER_VP: + case DLT_JUNIPER_ST: + case DLT_JUNIPER_ISM: /* 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 @@ -2583,8 +3333,51 @@ gen_linktype(proto) case DLT_DOCSIS: bpf_error("DOCSIS link-layer type filtering not implemented"); + case DLT_MTP2: + case DLT_MTP2_WITH_PHDR: + bpf_error("MTP2 link-layer type filtering not implemented"); + + case DLT_ERF: + bpf_error("ERF link-layer type filtering not implemented"); + +#ifdef DLT_PFSYNC + case DLT_PFSYNC: + bpf_error("PFSYNC link-layer type filtering not implemented"); +#endif + case DLT_LINUX_LAPD: bpf_error("LAPD link-layer type filtering not implemented"); + + case DLT_USB: + case DLT_USB_LINUX: + bpf_error("USB link-layer type filtering not implemented"); + + case DLT_BLUETOOTH_HCI_H4: + case DLT_BLUETOOTH_HCI_H4_WITH_PHDR: + bpf_error("Bluetooth link-layer type filtering not implemented"); + + case DLT_CAN20B: + bpf_error("CAN20B link-layer type filtering not implemented"); + + case DLT_IEEE802_15_4: + case DLT_IEEE802_15_4_LINUX: + case DLT_IEEE802_15_4_NONASK_PHY: + bpf_error("IEEE 802.15.4 link-layer type filtering not implemented"); + + case DLT_IEEE802_16_MAC_CPS_RADIO: + bpf_error("IEEE 802.16 link-layer type filtering not implemented"); + + case DLT_SITA: + bpf_error("SITA link-layer type filtering not implemented"); + + case DLT_RAIF1: + bpf_error("RAIF1 link-layer type filtering not implemented"); + + case DLT_IPMB: + bpf_error("IPMB link-layer type filtering not implemented"); + + case DLT_AX25_KISS: + bpf_error("AX.25 link-layer type filtering not implemented"); } /* @@ -2602,12 +3395,7 @@ gen_linktype(proto) /* * Any type not handled above should always have an Ethernet - * type at an offset of "off_linktype". (PPP is partially - * handled above - the protocol type is mapped from the - * Ethernet and LLC types we use internally to the corresponding - * PPP type - but the PPP type is always specified by a value - * at "off_linktype", so we don't have to do the code generation - * above.) + * type at an offset of "off_linktype". */ return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto); } @@ -2620,10 +3408,9 @@ gen_linktype(proto) * code and protocol type in the SNAP header. */ static struct block * -gen_snap(orgcode, ptype, offset) +gen_snap(orgcode, ptype) bpf_u_int32 orgcode; bpf_u_int32 ptype; - u_int offset; { u_char snapblock[8]; @@ -2635,7 +3422,7 @@ gen_snap(orgcode, ptype, offset) snapblock[5] = (orgcode >> 0); /* lower 8 bits of organization code */ snapblock[6] = (ptype >> 8); /* upper 8 bits of protocol type */ snapblock[7] = (ptype >> 0); /* lower 8 bits of protocol type */ - return gen_bcmp(OR_LINK, offset, 8, snapblock); + return gen_bcmp(OR_MACPL, 0, 8, snapblock); } /* @@ -2668,7 +3455,7 @@ gen_llc_linktype(proto) * DSAP, as we do for other types <= ETHERMTU * (i.e., other SAP values)? */ - return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_u_int32) + return gen_cmp(OR_MACPL, 0, BPF_H, (bpf_u_int32) ((proto << 8) | proto)); case LLCSAP_IPX: @@ -2676,7 +3463,7 @@ gen_llc_linktype(proto) * XXX - are there ever SNAP frames for IPX on * non-Ethernet 802.x networks? */ - return gen_cmp(OR_LINK, off_linktype, BPF_B, + return gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)LLCSAP_IPX); case ETHERTYPE_ATALK: @@ -2689,7 +3476,7 @@ gen_llc_linktype(proto) * XXX - check for an organization code of * encapsulated Ethernet as well? */ - return gen_snap(0x080007, ETHERTYPE_ATALK, off_linktype); + return gen_snap(0x080007, ETHERTYPE_ATALK); default: /* @@ -2701,8 +3488,7 @@ gen_llc_linktype(proto) * This is an LLC SAP value, so check * the DSAP. */ - return gen_cmp(OR_LINK, off_linktype, BPF_B, - (bpf_int32)proto); + return gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)proto); } else { /* * This is an Ethernet type; we assume that it's @@ -2717,15 +3503,13 @@ gen_llc_linktype(proto) * organization code of 0x000000 (encapsulated * Ethernet), we'd do * - * return gen_snap(0x000000, proto, - * off_linktype); + * return gen_snap(0x000000, proto); * * here; for now, we don't, as per the above. * I don't know whether it's worth the extra CPU * time to do the right check or not. */ - return gen_cmp(OR_LINK, off_linktype+6, BPF_H, - (bpf_int32)proto); + return gen_cmp(OR_MACPL, 6, BPF_H, (bpf_int32)proto); } } } @@ -2934,7 +3718,8 @@ gen_thostop(eaddr, dir) } /* - * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN) + * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN) and + * various 802.11 + radio headers. */ static struct block * gen_wlanhostop(eaddr, dir) @@ -2944,6 +3729,16 @@ gen_wlanhostop(eaddr, dir) register struct block *b0, *b1, *b2; register struct slist *s; +#ifdef ENABLE_WLAN_FILTERING_PATCH + /* + * TODO GV 20070613 + * We need to disable the optimizer because the optimizer is buggy + * and wipes out some LD instructions generated by the below + * code to validate the Frame Control bits + */ + no_optimize = 1; +#endif /* ENABLE_WLAN_FILTERING_PATCH */ + switch (dir) { case Q_SRC: /* @@ -3041,7 +3836,7 @@ gen_wlanhostop(eaddr, dir) * Now check for a data frame. * I.e, check "link[0] & 0x08". */ - gen_load_a(OR_LINK, 0, BPF_B); + s = gen_load_a(OR_LINK, 0, BPF_B); b1 = new_block(JMP(BPF_JSET)); b1->s.k = 0x08; b1->stmts = s; @@ -3210,6 +4005,55 @@ gen_wlanhostop(eaddr, dir) gen_and(b1, b0); return b0; + /* + * XXX - add RA, TA, and BSSID keywords? + */ + case Q_ADDR1: + return (gen_bcmp(OR_LINK, 4, 6, eaddr)); + + case Q_ADDR2: + /* + * 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); + b1 = gen_bcmp(OR_LINK, 10, 6, eaddr); + gen_and(b2, b1); + return b1; + + case Q_ADDR3: + /* + * Not present in control frames. + */ + b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL, + IEEE80211_FC0_TYPE_MASK); + gen_not(b0); + b1 = gen_bcmp(OR_LINK, 16, 6, eaddr); + gen_and(b0, b1); + return b1; + + case Q_ADDR4: + /* + * Present only if the direction mask has both "From DS" + * and "To DS" set. Neither control frames nor management + * frames should have both of those set, so we don't + * check the frame type. + */ + b0 = gen_mcmp(OR_LINK, 1, BPF_B, + IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK); + b1 = gen_bcmp(OR_LINK, 24, 6, eaddr); + gen_and(b0, b1); + return b1; + case Q_AND: b0 = gen_wlanhostop(eaddr, Q_SRC); b1 = gen_wlanhostop(eaddr, Q_DST); @@ -3652,48 +4496,48 @@ gen_gateway(eaddr, alist, proto, dir) case Q_IP: case Q_ARP: case Q_RARP: - switch (linktype) { - case DLT_EN10MB: - b0 = gen_ehostop(eaddr, Q_OR); - break; - case DLT_FDDI: - b0 = gen_fhostop(eaddr, Q_OR); - break; + switch (linktype) { + case DLT_EN10MB: + b0 = gen_ehostop(eaddr, Q_OR); + break; + case DLT_FDDI: + b0 = gen_fhostop(eaddr, Q_OR); + break; case DLT_IEEE802: - b0 = gen_thostop(eaddr, Q_OR); - break; + b0 = gen_thostop(eaddr, Q_OR); + break; case DLT_IEEE802_11: + case DLT_PRISM_HEADER: case DLT_IEEE802_11_RADIO_AVS: - case DLT_PPI: case DLT_IEEE802_11_RADIO: - case DLT_PRISM_HEADER: - b0 = gen_wlanhostop(eaddr, Q_OR); - break; - case DLT_SUNATM: - if (is_lane) { - /* - * Check that the packet doesn't begin with an - * LE Control marker. (We've already generated - * a test for LANE.) - */ - b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H, - 0xFF00); - gen_not(b1); + case DLT_PPI: + b0 = gen_wlanhostop(eaddr, Q_OR); + break; + case DLT_SUNATM: + if (is_lane) { + /* + * Check that the packet doesn't begin with an + * LE Control marker. (We've already generated + * a test for LANE.) + */ + b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, + BPF_H, 0xFF00); + gen_not(b1); - /* - * Now check the MAC address. - */ - b0 = gen_ehostop(eaddr, Q_OR); - gen_and(b1, b0); - } - break; + /* + * Now check the MAC address. + */ + b0 = gen_ehostop(eaddr, Q_OR); + gen_and(b1, b0); + } + break; case DLT_IP_OVER_FC: - b0 = gen_ipfchostop(eaddr, Q_OR); - break; - default: - bpf_error( + b0 = gen_ipfchostop(eaddr, Q_OR); + break; + default: + bpf_error( "'gateway' supported only on ethernet/FDDI/token ring/802.11/Fibre Channel"); - } + } b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR, Q_HOST); while (*alist) { tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR, @@ -4458,7 +5302,8 @@ gen_protochain(v, proto, dir) } /* - * We don't handle variable-length radiotap here headers yet. + * We don't handle variable-length prefixes before the link-layer + * header, or variable-length link-layer headers, here yet. * We might want to add BPF instructions to do the protochain * work, to simplify that and, on platforms that have a BPF * interpreter with the new instructions, let the filtering @@ -4467,11 +5312,15 @@ gen_protochain(v, proto, dir) * branches, and backward branch support is unlikely to appear * in kernel BPF engines.) */ - if (linktype == DLT_IEEE802_11_RADIO) - bpf_error("'protochain' not supported with radiotap headers"); + switch (linktype) { - if (linktype == DLT_PPI) - bpf_error("'protochain' not supported with PPI headers"); + case DLT_IEEE802_11: + case DLT_PRISM_HEADER: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PPI: + bpf_error("'protochain' not supported with 802.11"); + } no_optimize = 1; /*this code is not compatible with optimzer yet */ @@ -4490,11 +5339,11 @@ gen_protochain(v, proto, dir) /* A = ip->ip_p */ s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); - s[i]->s.k = off_ll + off_nl + 9; + s[i]->s.k = off_macpl + off_nl + 9; i++; /* X = ip->ip_hl << 2 */ s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B); - s[i]->s.k = off_ll + off_nl; + s[i]->s.k = off_macpl + off_nl; i++; break; #ifdef INET6 @@ -4503,7 +5352,7 @@ gen_protochain(v, proto, dir) /* A = ip6->ip_nxt */ s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); - s[i]->s.k = off_ll + off_nl + 6; + s[i]->s.k = off_macpl + off_nl + 6; i++; /* X = sizeof(struct ip6_hdr) */ s[i] = new_stmt(BPF_LDX|BPF_IMM); @@ -4583,7 +5432,7 @@ gen_protochain(v, proto, dir) i++; /* A = P[X + packet head] */ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_ll + off_nl; + s[i]->s.k = off_macpl + off_nl; i++; /* MEM[reg2] = A */ s[i] = new_stmt(BPF_ST); @@ -4601,7 +5450,7 @@ gen_protochain(v, proto, dir) i++; /* A = P[X + packet head]; */ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_ll + off_nl; + s[i]->s.k = off_macpl + off_nl; i++; /* A += 1 */ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); @@ -4660,7 +5509,7 @@ gen_protochain(v, proto, dir) i++; /* A = P[X + packet head]; */ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_ll + off_nl; + s[i]->s.k = off_macpl + off_nl; i++; /* MEM[reg2] = A */ s[i] = new_stmt(BPF_ST); @@ -4678,7 +5527,7 @@ gen_protochain(v, proto, dir) i++; /* A = P[X + packet head] */ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_ll + off_nl; + s[i]->s.k = off_macpl + off_nl; i++; /* A += 2 */ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); @@ -4732,6 +5581,31 @@ gen_protochain(v, proto, dir) #endif } +static struct block * +gen_check_802_11_data_frame() +{ + struct slist *s; + struct block *b0, *b1; + + /* + * A data frame has the 0x08 bit (b3) in the frame control field set + * and the 0x04 bit (b2) clear. + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b0 = new_block(JMP(BPF_JSET)); + b0->s.k = 0x08; + b0->stmts = s; + + s = gen_load_a(OR_LINK, 0, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x04; + b1->stmts = s; + gen_not(b1); + + gen_and(b1, b0); + + return b0; +} /* * Generate code that checks whether the packet is a packet for protocol @@ -5019,9 +5893,9 @@ gen_scode(name, q) return b; case DLT_IEEE802_11: + case DLT_PRISM_HEADER: case DLT_IEEE802_11_RADIO_AVS: case DLT_IEEE802_11_RADIO: - case DLT_PRISM_HEADER: case DLT_PPI: eaddr = pcap_ether_hostton(name); if (eaddr == NULL) @@ -5250,7 +6124,6 @@ gen_scode(name, q) else bpf_error("unknown protocol: %s", name); - case Q_UNDEF: syntax(); /* NOTREACHED */ @@ -5487,44 +6360,44 @@ gen_ecode(eaddr, q) struct block *b, *tmp; if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { - switch (linktype) { - case DLT_EN10MB: - return gen_ehostop(eaddr, (int)q.dir); - case DLT_FDDI: - return gen_fhostop(eaddr, (int)q.dir); - case DLT_IEEE802: - return gen_thostop(eaddr, (int)q.dir); - case DLT_IEEE802_11: - case DLT_IEEE802_11_RADIO_AVS: - case DLT_IEEE802_11_RADIO: - case DLT_PRISM_HEADER: - case DLT_PPI: - return gen_wlanhostop(eaddr, (int)q.dir); - case DLT_SUNATM: - if (is_lane) { - /* - * Check that the packet doesn't begin with an - * LE Control marker. (We've already generated - * a test for LANE.) - */ - tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H, - 0xFF00); - gen_not(tmp); - - /* - * Now check the MAC address. - */ - b = gen_ehostop(eaddr, (int)q.dir); - gen_and(tmp, b); - return b; - } - break; - case DLT_IP_OVER_FC: - return gen_ipfchostop(eaddr, (int)q.dir); - default: - bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); - break; - } + switch (linktype) { + case DLT_EN10MB: + return gen_ehostop(eaddr, (int)q.dir); + case DLT_FDDI: + return gen_fhostop(eaddr, (int)q.dir); + case DLT_IEEE802: + return gen_thostop(eaddr, (int)q.dir); + case DLT_IEEE802_11: + case DLT_PRISM_HEADER: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PPI: + return gen_wlanhostop(eaddr, (int)q.dir); + case DLT_SUNATM: + if (is_lane) { + /* + * Check that the packet doesn't begin with an + * LE Control marker. (We've already generated + * a test for LANE.) + */ + tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H, + 0xFF00); + gen_not(tmp); + + /* + * Now check the MAC address. + */ + b = gen_ehostop(eaddr, (int)q.dir); + gen_and(tmp, b); + return b; + } + break; + case DLT_IP_OVER_FC: + return gen_ipfchostop(eaddr, (int)q.dir); + default: + bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); + break; + } } bpf_error("ethernet address used in non-ether expression"); /* NOTREACHED */ @@ -5691,14 +6564,14 @@ gen_load(proto, inst, size) * XXX - are there any cases where we want * off_nl_nosnap? */ - s = gen_llprefixlen(); + s = gen_off_macpl(); /* * If "s" is non-null, it has code to arrange that the - * X register contains the length of the prefix preceding - * 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 + * X register contains the offset of the MAC-layer + * 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 * by "index". */ @@ -5712,13 +6585,17 @@ gen_load(proto, inst, size) /* * Load the item at the sum of the offset we've put in the * X register, the offset of the start of the network - * layer header, and the offset of the start of the link - * layer header (which is 0 if the radio header is - * variable-length; that header length is what we put - * into the X register and then added to the index). + * layer header from the beginning of the MAC-layer + * payload, and the purported offset of the start of the + * MAC-layer payload (which might be 0 if there's a + * variable-length prefix before the link-layer header + * or the link-layer header itself is variable-length; + * the variable-length offset of the start of the + * MAC-layer payload is what we put into the X register + * and then added to the index). */ tmp = new_stmt(BPF_LD|BPF_IND|size); - tmp->s.k = off_ll + off_nl; + tmp->s.k = off_macpl + off_nl; sappend(s, tmp); sappend(inst->s, s); @@ -5759,22 +6636,24 @@ gen_load(proto, inst, size) /* * The X register now contains the sum of the length * of any variable-length header preceding the link-layer - * header and the length of the network-layer header. + * header, any variable-length link-layer header, and the + * length of the network-layer header. + * * Load into the A register the offset relative to * the beginning of the transport layer header, * add the X register to that, move that to the * X register, and load with an offset from the * X register equal to the offset of the network * layer header relative to the beginning of - * the link-layer header plus the length of any - * fixed-length header preceding the link-layer - * header. + * the MAC-layer payload plus the fixed-length + * portion of the offset of the MAC-layer payload + * from the beginning of the raw packet data. */ sappend(s, xfer_to_a(inst)); sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); sappend(s, new_stmt(BPF_MISC|BPF_TAX)); sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size)); - tmp->s.k = off_ll + off_nl; + tmp->s.k = off_macpl + off_nl; sappend(inst->s, s); /* @@ -5940,6 +6819,16 @@ gen_arth(code, a0, a1) static int regused[BPF_MEMWORDS]; static int curreg; +/* + * Initialize the table of used registers and the current register. + */ +static void +init_regs() +{ + curreg = 0; + memset(regused, 0, sizeof regused); +} + /* * Return the next free register. */ @@ -6071,46 +6960,46 @@ gen_broadcast(proto) case Q_DEFAULT: case Q_LINK: - switch (linktype) { - case DLT_ARCNET: - case DLT_ARCNET_LINUX: - return gen_ahostop(abroadcast, Q_DST); - case DLT_EN10MB: - return gen_ehostop(ebroadcast, Q_DST); - case DLT_FDDI: - return gen_fhostop(ebroadcast, Q_DST); - case DLT_IEEE802: - return gen_thostop(ebroadcast, Q_DST); - case DLT_IEEE802_11: - case DLT_IEEE802_11_RADIO_AVS: - case DLT_IEEE802_11_RADIO: - case DLT_PPI: - case DLT_PRISM_HEADER: - return gen_wlanhostop(ebroadcast, Q_DST); - case DLT_IP_OVER_FC: - return gen_ipfchostop(ebroadcast, Q_DST); - case DLT_SUNATM: - if (is_lane) { - /* - * Check that the packet doesn't begin with an - * LE Control marker. (We've already generated - * a test for LANE.) - */ - b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H, - 0xFF00); - gen_not(b1); + switch (linktype) { + case DLT_ARCNET: + case DLT_ARCNET_LINUX: + return gen_ahostop(abroadcast, Q_DST); + case DLT_EN10MB: + return gen_ehostop(ebroadcast, Q_DST); + case DLT_FDDI: + return gen_fhostop(ebroadcast, Q_DST); + case DLT_IEEE802: + return gen_thostop(ebroadcast, Q_DST); + case DLT_IEEE802_11: + case DLT_PRISM_HEADER: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PPI: + return gen_wlanhostop(ebroadcast, Q_DST); + case DLT_IP_OVER_FC: + return gen_ipfchostop(ebroadcast, Q_DST); + case DLT_SUNATM: + if (is_lane) { + /* + * Check that the packet doesn't begin with an + * LE Control marker. (We've already generated + * a test for LANE.) + */ + b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, + BPF_H, 0xFF00); + gen_not(b1); - /* - * Now check the MAC address. - */ - b0 = gen_ehostop(ebroadcast, Q_DST); - gen_and(b1, b0); - return b0; - } - break; - default: - bpf_error("not a broadcast link"); - } + /* + * Now check the MAC address. + */ + b0 = gen_ehostop(ebroadcast, Q_DST); + gen_and(b1, b0); + return b0; + } + break; + default: + bpf_error("not a broadcast link"); + } break; case Q_IP: @@ -6158,167 +7047,167 @@ gen_multicast(proto) case Q_DEFAULT: case Q_LINK: - switch (linktype) { - case DLT_ARCNET: - case DLT_ARCNET_LINUX: - /* all ARCnet multicasts use the same address */ - return gen_ahostop(abroadcast, Q_DST); - case DLT_EN10MB: - /* ether[0] & 1 != 0 */ - return gen_mac_multicast(0); - case DLT_FDDI: - /* - * XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX - * - * XXX - was that referring to bit-order issues? - */ - /* fddi[1] & 1 != 0 */ - return gen_mac_multicast(1); - case DLT_IEEE802: - /* tr[2] & 1 != 0 */ - return gen_mac_multicast(2); - case DLT_IEEE802_11: - case DLT_IEEE802_11_RADIO_AVS: - case DLT_PPI: - case DLT_IEEE802_11_RADIO: - case DLT_PRISM_HEADER: - /* - * Oh, yuk. - * - * For control frames, there is no DA. - * - * For management frames, DA is at an - * offset of 4 from the beginning of - * the packet. - * - * For data frames, DA is at an offset - * of 4 from the beginning of the packet - * if To DS is clear and at an offset of - * 16 from the beginning of the packet - * if To DS is set. - */ - - /* - * Generate the tests to be done for data frames. - * - * First, check for To DS set, i.e. "link[1] & 0x01". - */ - s = gen_load_a(OR_LINK, 1, BPF_B); - b1 = new_block(JMP(BPF_JSET)); - b1->s.k = 0x01; /* To DS */ - b1->stmts = s; - - /* - * If To DS is set, the DA is at 16. - */ - b0 = gen_mac_multicast(16); - gen_and(b1, b0); - - /* - * Now, check for To DS not set, i.e. check - * "!(link[1] & 0x01)". - */ - s = gen_load_a(OR_LINK, 1, BPF_B); - b2 = new_block(JMP(BPF_JSET)); - b2->s.k = 0x01; /* To DS */ - b2->stmts = s; - gen_not(b2); - - /* - * If To DS is not set, the DA is at 4. - */ - b1 = gen_mac_multicast(4); - gen_and(b2, b1); - - /* - * Now OR together the last two checks. That gives - * the complete set of checks for data frames. - */ - gen_or(b1, b0); - - /* - * Now check for a data 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 checks done for data frames. - */ - gen_and(b1, b0); - - /* - * 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); - b2 = new_block(JMP(BPF_JSET)); - b2->s.k = 0x08; - b2->stmts = s; - gen_not(b2); - - /* - * For management frames, the DA is at 4. - */ - b1 = gen_mac_multicast(4); - gen_and(b2, b1); - - /* - * OR that with the checks done for data frames. - * That gives the checks done for management and - * data frames. - */ - gen_or(b1, b0); - - /* - * If the low-order bit of the type value is 1, - * this is either a control frame or a frame - * with a reserved type, and thus not a - * frame with an SA. - * - * I.e., check "!(link[0] & 0x04)". - */ - s = gen_load_a(OR_LINK, 0, BPF_B); - b1 = new_block(JMP(BPF_JSET)); - b1->s.k = 0x04; - b1->stmts = s; - gen_not(b1); - - /* - * AND that with the checks for data and management - * frames. - */ - gen_and(b1, b0); - return b0; - case DLT_IP_OVER_FC: - b0 = gen_mac_multicast(2); - return b0; - case DLT_SUNATM: - if (is_lane) { + switch (linktype) { + case DLT_ARCNET: + case DLT_ARCNET_LINUX: + /* all ARCnet multicasts use the same address */ + return gen_ahostop(abroadcast, Q_DST); + case DLT_EN10MB: + /* ether[0] & 1 != 0 */ + return gen_mac_multicast(0); + case DLT_FDDI: /* - * Check that the packet doesn't begin with an - * LE Control marker. (We've already generated - * a test for LANE.) + * XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX + * + * XXX - was that referring to bit-order issues? */ - b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H, - 0xFF00); + /* fddi[1] & 1 != 0 */ + return gen_mac_multicast(1); + case DLT_IEEE802: + /* tr[2] & 1 != 0 */ + return gen_mac_multicast(2); + case DLT_IEEE802_11: + case DLT_PRISM_HEADER: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PPI: + /* + * Oh, yuk. + * + * For control frames, there is no DA. + * + * For management frames, DA is at an + * offset of 4 from the beginning of + * the packet. + * + * For data frames, DA is at an offset + * of 4 from the beginning of the packet + * if To DS is clear and at an offset of + * 16 from the beginning of the packet + * if To DS is set. + */ + + /* + * Generate the tests to be done for data frames. + * + * First, check for To DS set, i.e. "link[1] & 0x01". + */ + s = gen_load_a(OR_LINK, 1, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x01; /* To DS */ + b1->stmts = s; + + /* + * If To DS is set, the DA is at 16. + */ + b0 = gen_mac_multicast(16); + gen_and(b1, b0); + + /* + * Now, check for To DS not set, i.e. check + * "!(link[1] & 0x01)". + */ + s = gen_load_a(OR_LINK, 1, BPF_B); + b2 = new_block(JMP(BPF_JSET)); + b2->s.k = 0x01; /* To DS */ + b2->stmts = s; + gen_not(b2); + + /* + * If To DS is not set, the DA is at 4. + */ + b1 = gen_mac_multicast(4); + gen_and(b2, b1); + + /* + * Now OR together the last two checks. That gives + * the complete set of checks for data frames. + */ + gen_or(b1, b0); + + /* + * Now check for a data 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 checks done for data frames. + */ + gen_and(b1, b0); + + /* + * 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); + b2 = new_block(JMP(BPF_JSET)); + b2->s.k = 0x08; + b2->stmts = s; + gen_not(b2); + + /* + * For management frames, the DA is at 4. + */ + b1 = gen_mac_multicast(4); + gen_and(b2, b1); + + /* + * OR that with the checks done for data frames. + * That gives the checks done for management and + * data frames. + */ + gen_or(b1, b0); + + /* + * If the low-order bit of the type value is 1, + * this is either a control frame or a frame + * with a reserved type, and thus not a + * frame with an SA. + * + * I.e., check "!(link[0] & 0x04)". + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x04; + b1->stmts = s; gen_not(b1); - /* ether[off_mac] & 1 != 0 */ - b0 = gen_mac_multicast(off_mac); + /* + * AND that with the checks for data and management + * frames. + */ gen_and(b1, b0); return b0; - } - break; - default: - break; - } - /* Link not known to support multicasts */ - break; + case DLT_IP_OVER_FC: + b0 = gen_mac_multicast(2); + return b0; + case DLT_SUNATM: + if (is_lane) { + /* + * Check that the packet doesn't begin with an + * LE Control marker. (We've already generated + * a test for LANE.) + */ + b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, + BPF_H, 0xFF00); + gen_not(b1); + + /* ether[off_mac] & 1 != 0 */ + b0 = gen_mac_multicast(off_mac); + gen_and(b1, b0); + return b0; + } + break; + default: + break; + } + /* Link not known to support multicasts */ + break; case Q_IP: b0 = gen_linktype(ETHERTYPE_IP); @@ -6415,6 +7304,8 @@ gen_inbound(dir) case DLT_JUNIPER_FRELAY: case DLT_JUNIPER_CHDLC: case DLT_JUNIPER_VP: + case DLT_JUNIPER_ST: + case DLT_JUNIPER_ISM: /* juniper flags (including direction) are stored * the byte after the 3-byte magic number */ if (dir) { @@ -6424,7 +7315,7 @@ gen_inbound(dir) /* match incoming packets */ b0 = gen_mcmp(OR_LINK, 3, BPF_B, 1, 0x01); } - break; + break; default: bpf_error("inbound/outbound not supported on linktype %d", @@ -6443,13 +7334,12 @@ gen_pf_ifname(const char *ifname) struct block *b0; u_int len, off; - if (linktype == DLT_PFLOG) { - len = sizeof(((struct pfloghdr *)0)->ifname); - off = offsetof(struct pfloghdr, ifname); - } else { - bpf_error("ifname not supported on linktype 0x%x", linktype); + if (linktype != DLT_PFLOG) { + bpf_error("ifname supported only on PF linktype"); /* NOTREACHED */ } + len = sizeof(((struct pfloghdr *)0)->ifname); + off = offsetof(struct pfloghdr, ifname); if (strlen(ifname) >= len) { bpf_error("ifname interface names can only be %d characters", len-1); @@ -6466,14 +7356,16 @@ gen_pf_ruleset(char *ruleset) struct block *b0; if (linktype != DLT_PFLOG) { - bpf_error("ruleset not supported on linktype 0x%x", linktype); + bpf_error("ruleset supported only on PF linktype"); /* NOTREACHED */ } + if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) { bpf_error("ruleset names can only be %ld characters", (long)(sizeof(((struct pfloghdr *)0)->ruleset) - 1)); /* NOTREACHED */ } + b0 = gen_bcmp(OR_LINK, offsetof(struct pfloghdr, ruleset), strlen(ruleset), (const u_char *)ruleset); return (b0); @@ -6485,14 +7377,13 @@ gen_pf_rnr(int rnr) { struct block *b0; - if (linktype == DLT_PFLOG) { - b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, rulenr), BPF_W, - (bpf_int32)rnr); - } else { - bpf_error("rnr not supported on linktype 0x%x", linktype); + if (linktype != DLT_PFLOG) { + bpf_error("rnr supported only on PF linktype"); /* NOTREACHED */ } + b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, rulenr), BPF_W, + (bpf_int32)rnr); return (b0); } @@ -6503,7 +7394,7 @@ gen_pf_srnr(int srnr) struct block *b0; if (linktype != DLT_PFLOG) { - bpf_error("srnr not supported on linktype 0x%x", linktype); + bpf_error("srnr supported only on PF linktype"); /* NOTREACHED */ } @@ -6518,14 +7409,13 @@ gen_pf_reason(int reason) { struct block *b0; - if (linktype == DLT_PFLOG) { - b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, reason), BPF_B, - (bpf_int32)reason); - } else { - bpf_error("reason not supported on linktype 0x%x", linktype); + if (linktype != DLT_PFLOG) { + bpf_error("reason supported only on PF linktype"); /* NOTREACHED */ } + b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, reason), BPF_B, + (bpf_int32)reason); return (b0); } @@ -6535,14 +7425,13 @@ gen_pf_action(int action) { struct block *b0; - if (linktype == DLT_PFLOG) { - b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, action), BPF_B, - (bpf_int32)action); - } else { - bpf_error("action not supported on linktype 0x%x", linktype); + if (linktype != DLT_PFLOG) { + bpf_error("action supported only on PF linktype"); /* NOTREACHED */ } + b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, action), BPF_B, + (bpf_int32)action); return (b0); } #else /* !HAVE_NET_PFVAR_H */ @@ -6595,14 +7484,75 @@ gen_pf_action(int action) } #endif /* HAVE_NET_PFVAR_H */ +/* IEEE 802.11 wireless header */ +struct block * +gen_p80211_type(int type, int mask) +{ + struct block *b0; + + switch (linktype) { + + case DLT_IEEE802_11: + case DLT_PRISM_HEADER: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + b0 = gen_mcmp(OR_LINK, 0, BPF_B, (bpf_int32)type, + (bpf_int32)mask); + break; + + default: + bpf_error("802.11 link-layer types supported only on 802.11"); + /* NOTREACHED */ + } + + return (b0); +} + +struct block * +gen_p80211_fcdir(int fcdir) +{ + struct block *b0; + + switch (linktype) { + + case DLT_IEEE802_11: + case DLT_PRISM_HEADER: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + break; + + default: + bpf_error("frame direction supported only with 802.11 headers"); + /* NOTREACHED */ + } + + b0 = gen_mcmp(OR_LINK, 1, BPF_B, (bpf_int32)fcdir, + (bpf_u_int32)IEEE80211_FC1_DIR_MASK); + + return (b0); +} + struct block * gen_acode(eaddr, q) register const u_char *eaddr; struct qual q; { - if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { - if (linktype == DLT_ARCNET || linktype == DLT_ARCNET_LINUX) - return gen_ahostop(eaddr, (int)q.dir); + switch (linktype) { + + case DLT_ARCNET: + case DLT_ARCNET_LINUX: + if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && + q.proto == Q_LINK) + return (gen_ahostop(eaddr, (int)q.dir)); + else { + bpf_error("ARCnet address used in non-arc expression"); + /* NOTREACHED */ + } + break; + + default: + bpf_error("aid supported only on ARCnet"); + /* NOTREACHED */ } bpf_error("ARCnet address used in non-arc expression"); /* NOTREACHED */ @@ -6655,10 +7605,11 @@ gen_vlan(vlan_num) bpf_error("no VLAN match after MPLS"); /* - * Change the offsets to point to the type and data fields within - * the VLAN packet. Just increment the offsets, so that we - * can support a hierarchy, e.g. "vlan 300 && vlan 200" to - * capture VLAN 200 encapsulated within VLAN 100. + * Check for a VLAN packet, and then change the offsets to point + * to the type and data fields within the VLAN packet. Just + * increment the offsets, so that we can support a hierarchy, e.g. + * "vlan 300 && vlan 200" to capture VLAN 200 encapsulated within + * VLAN 100. * * XXX - this is a bit of a kludge. If we were to split the * compiler into a parser that parses an expression and @@ -6684,15 +7635,29 @@ gen_vlan(vlan_num) * be done assuming a VLAN, even though the "or" could be viewed * as meaning "or, if this isn't a VLAN packet...". */ - orig_linktype = off_linktype; /* save original values */ orig_nl = off_nl; switch (linktype) { case DLT_EN10MB: + /* check for VLAN */ + b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, + (bpf_int32)ETHERTYPE_8021Q); + + /* If a specific VLAN is requested, check VLAN id */ + if (vlan_num >= 0) { + b1 = gen_mcmp(OR_MACPL, 0, BPF_H, + (bpf_int32)vlan_num, 0x0fff); + gen_and(b0, b1); + b0 = b1; + } + + off_macpl += 4; off_linktype += 4; +#if 0 off_nl_nosnap += 4; off_nl += 4; +#endif break; default: @@ -6701,17 +7666,6 @@ gen_vlan(vlan_num) /*NOTREACHED*/ } - /* check for VLAN */ - b0 = gen_cmp(OR_LINK, orig_linktype, BPF_H, (bpf_int32)ETHERTYPE_8021Q); - - /* If a specific VLAN is requested, check VLAN id */ - if (vlan_num >= 0) { - b1 = gen_mcmp(OR_LINK, orig_nl, BPF_H, (bpf_int32)vlan_num, - 0x0fff); - gen_and(b0, b1); - b0 = b1; - } - return (b0); } @@ -6737,7 +7691,7 @@ gen_mpls(label_num) if (label_stack_depth > 0) { /* just match the bottom-of-stack bit clear */ - b0 = gen_mcmp(OR_LINK, orig_nl-2, BPF_B, 0, 0x01); + b0 = gen_mcmp(OR_MACPL, orig_nl-2, BPF_B, 0, 0x01); } else { /* * Indicate that we're checking MPLS-encapsulated headers, @@ -6772,7 +7726,7 @@ gen_mpls(label_num) /* If a specific MPLS label is requested, check it */ if (label_num >= 0) { label_num = label_num << 12; /* label is shifted 12 bits on the wire */ - b1 = gen_mcmp(OR_LINK, orig_nl, BPF_W, (bpf_int32)label_num, + b1 = gen_mcmp(OR_MACPL, orig_nl, BPF_W, (bpf_int32)label_num, 0xfffff000); /* only compare the first 20 bits */ gen_and(b0, b1); b0 = b1; @@ -6806,7 +7760,8 @@ gen_pppoes() /* * Change the offsets to point to the type and data fields within - * the PPP packet. + * the PPP packet, and note that this is PPPoE rather than + * raw PPP. * * XXX - this is a bit of a kludge. If we were to split the * compiler into a parser that parses an expression and @@ -6834,24 +7789,28 @@ gen_pppoes() */ orig_linktype = off_linktype; /* save original values */ orig_nl = off_nl; + is_pppoes = 1; /* * The "network-layer" protocol is PPPoE, which has a 6-byte - * PPPoE header, followed by PPP payload, so we set the - * offsets to the network layer offset plus 6 bytes for - * the PPPoE header plus the values appropriate for PPP when - * encapsulated in Ethernet (which means there's no HDLC - * encapsulation). + * PPPoE header, followed by a PPP packet. + * + * There is no HDLC encapsulation for the PPP packet (it's + * encapsulated in PPPoES instead), so the link-layer type + * starts at the first byte of the PPP packet. For PPPoE, + * that offset is relative to the beginning of the total + * link-layer payload, including any 802.2 LLC header, so + * it's 6 bytes past off_nl. */ - off_linktype = orig_nl + 6; - off_nl = orig_nl + 6 + 2; - off_nl_nosnap = orig_nl + 6 + 2; + off_linktype = off_nl + 6; /* - * Set the link-layer type to PPP, as all subsequent tests will - * be on the encapsulated PPP header. + * The network-layer offsets are relative to the beginning + * of the MAC-layer payload; that's past the 6-byte + * PPPoE header and the 2-byte PPP header. */ - linktype = DLT_PPP; + off_nl = 6+2; + off_nl_nosnap = 6+2; return b0; } @@ -6997,8 +7956,9 @@ gen_atmtype_abbrev(type) is_lane = 1; off_mac = off_payload + 2; /* MAC header */ off_linktype = off_mac + 12; - off_nl = off_mac + 14; /* Ethernet II */ - off_nl_nosnap = off_mac + 17; /* 802.3+802.2 */ + off_macpl = off_mac + 14; /* Ethernet */ + off_nl = 0; /* Ethernet II */ + off_nl_nosnap = 3; /* 802.3+802.2 */ break; case A_LLC: @@ -7031,6 +7991,7 @@ gen_mtp2type_abbrev(type) case M_FISU: if ( (linktype != DLT_MTP2) && + (linktype != DLT_ERF) && (linktype != DLT_MTP2_WITH_PHDR) ) bpf_error("'fisu' supported only on MTP2"); /* gen_ncmp(offrel, offset, size, mask, jtype, reverse, value) */ @@ -7039,6 +8000,7 @@ gen_mtp2type_abbrev(type) case M_LSSU: if ( (linktype != DLT_MTP2) && + (linktype != DLT_ERF) && (linktype != DLT_MTP2_WITH_PHDR) ) bpf_error("'lssu' supported only on MTP2"); b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 1, 2); @@ -7048,6 +8010,7 @@ gen_mtp2type_abbrev(type) case M_MSU: if ( (linktype != DLT_MTP2) && + (linktype != DLT_ERF) && (linktype != DLT_MTP2_WITH_PHDR) ) bpf_error("'msu' supported only on MTP2"); b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 2); diff --git a/contrib/libpcap/gencode.h b/contrib/libpcap/gencode.h index f4c5cf7503..39b1eea547 100644 --- a/contrib/libpcap/gencode.h +++ b/contrib/libpcap/gencode.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.60.2.11 2007/06/11 09:52:04 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.70.2.1 2007/11/18 02:04:55 guy Exp $ (LBL) */ /* @@ -132,6 +132,10 @@ #define Q_DST 2 #define Q_OR 3 #define Q_AND 4 +#define Q_ADDR1 5 +#define Q_ADDR2 6 +#define Q_ADDR3 7 +#define Q_ADDR4 8 #define Q_DEFAULT 0 #define Q_UNDEF 255 @@ -312,6 +316,9 @@ struct block *gen_pf_reason(int); struct block *gen_pf_action(int); struct block *gen_pf_dir(int); +struct block *gen_p80211_type(int, int); +struct block *gen_p80211_fcdir(int); + void bpf_optimize(struct block **); void bpf_error(const char *, ...) __attribute__((noreturn, format (printf, 1, 2))); diff --git a/contrib/libpcap/grammar.y b/contrib/libpcap/grammar.y index f9b7cb1b6c..7076c87bc0 100644 --- a/contrib/libpcap/grammar.y +++ b/contrib/libpcap/grammar.y @@ -22,7 +22,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.86.2.9 2007/09/12 19:17:25 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.99.2.2 2007/11/18 02:04:55 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -57,7 +57,8 @@ struct rtentry; #include #include #endif -#include +#include "ieee80211.h" +#include #ifdef HAVE_OS_PROTO_H #include "os-proto.h" @@ -67,6 +68,92 @@ struct rtentry; (q).dir = (d),\ (q).addr = (a) +struct tok { + int v; /* value */ + const char *s; /* string */ +}; + +static const struct tok ieee80211_types[] = { + { IEEE80211_FC0_TYPE_DATA, "data" }, + { IEEE80211_FC0_TYPE_MGT, "mgt" }, + { IEEE80211_FC0_TYPE_MGT, "management" }, + { IEEE80211_FC0_TYPE_CTL, "ctl" }, + { IEEE80211_FC0_TYPE_CTL, "control" }, + { 0, NULL } +}; +static const struct tok ieee80211_mgt_subtypes[] = { + { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" }, + { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" }, + { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" }, + { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" }, + { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" }, + { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" }, + { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" }, + { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" }, + { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" }, + { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" }, + { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" }, + { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" }, + { IEEE80211_FC0_SUBTYPE_BEACON, "beacon" }, + { IEEE80211_FC0_SUBTYPE_ATIM, "atim" }, + { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" }, + { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" }, + { IEEE80211_FC0_SUBTYPE_AUTH, "auth" }, + { IEEE80211_FC0_SUBTYPE_AUTH, "authentication" }, + { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" }, + { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" }, + { 0, NULL } +}; +static const struct tok ieee80211_ctl_subtypes[] = { + { IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" }, + { IEEE80211_FC0_SUBTYPE_RTS, "rts" }, + { IEEE80211_FC0_SUBTYPE_CTS, "cts" }, + { IEEE80211_FC0_SUBTYPE_ACK, "ack" }, + { IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" }, + { IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" }, + { 0, NULL } +}; +static const struct tok ieee80211_data_subtypes[] = { + { IEEE80211_FC0_SUBTYPE_DATA, "data" }, + { IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" }, + { IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" }, + { IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" }, + { IEEE80211_FC0_SUBTYPE_NODATA, "null" }, + { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" }, + { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll" }, + { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" }, + { 0, NULL } +}; +struct type2tok { + int type; + const struct tok *tok; +}; +static const struct type2tok ieee80211_type_subtypes[] = { + { IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes }, + { IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes }, + { IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes }, + { 0, NULL } +}; + +static int +str2tok(const char *str, const struct tok *toks) +{ + int i; + + for (i = 0; toks[i].s != NULL; i++) { + if (pcap_strcasecmp(toks[i].s, str) == 0) + return (toks[i].v); + } + return (-1); +} + int n_errors = 0; static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; @@ -113,6 +200,16 @@ pfaction_to_num(const char *action) else if (pcap_strcasecmp(action, "drop") == 0 || pcap_strcasecmp(action, "block") == 0) return (PF_DROP); +#if HAVE_PF_NAT_THROUGH_PF_NORDR + else if (pcap_strcasecmp(action, "rdr") == 0) + return (PF_RDR); + else if (pcap_strcasecmp(action, "nat") == 0) + return (PF_NAT); + else if (pcap_strcasecmp(action, "binat") == 0) + return (PF_BINAT); + else if (pcap_strcasecmp(action, "nordr") == 0) + return (PF_NORDR); +#endif else { bpf_error("unknown PF action"); /*NOTREACHED*/ @@ -124,6 +221,9 @@ pfreason_to_num(const char *reason) { bpf_error("libpcap was compiled on a machine without pf support"); /*NOTREACHED*/ + + /* this is to make the VC compiler happy */ + return -1; } static int @@ -131,6 +231,9 @@ pfaction_to_num(const char *action) { bpf_error("libpcap was compiled on a machine without pf support"); /*NOTREACHED*/ + + /* this is to make the VC compiler happy */ + return -1; } #endif /* HAVE_NET_PFVAR_H */ %} @@ -157,7 +260,7 @@ pfaction_to_num(const char *action) %type arth narth %type byteop pname pnum relop irelop %type and or paren not null prog -%type other pfvar +%type other pfvar p80211 %type atmtype atmmultitype %type atmfield %type atmfieldvalue atmvalue atmlistvalue @@ -173,6 +276,7 @@ pfaction_to_num(const char *action) %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 LINK %token GEQ LEQ NEQ %token ID EID HID HID6 AID @@ -196,7 +300,7 @@ pfaction_to_num(const char *action) %type EID %type AID %type HID HID6 -%type NUM action reason +%type NUM action reason type subtype type_subtype dir %left OR AND %nonassoc '!' @@ -238,6 +342,14 @@ nid: ID { $$.b = gen_scode($1, $$.q = $0.q); } | HID { /* Decide how to parse HID based on proto */ $$.q = $0.q; + if ($$.q.addr == Q_PORT) + bpf_error("'port' modifier applied to ip host"); + else if ($$.q.addr == Q_PORTRANGE) + bpf_error("'portrange' modifier applied to ip host"); + else if ($$.q.addr == Q_PROTO) + bpf_error("'proto' modifier applied to ip host"); + else if ($$.q.addr == Q_PROTOCHAIN) + bpf_error("'protochain' modifier applied to ip host"); $$.b = gen_ncode($1, 0, $$.q); } | HID6 '/' NUM { @@ -325,6 +437,10 @@ dqual: SRC { $$ = Q_SRC; } | DST OR SRC { $$ = Q_OR; } | SRC AND DST { $$ = Q_AND; } | DST AND SRC { $$ = Q_AND; } + | ADDR1 { $$ = Q_ADDR1; } + | ADDR2 { $$ = Q_ADDR2; } + | ADDR3 { $$ = Q_ADDR3; } + | ADDR4 { $$ = Q_ADDR4; } ; /* address type qualifiers */ aqual: HOST { $$ = Q_HOST; } @@ -388,6 +504,7 @@ other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } | PPPOED { $$ = gen_pppoed(); } | PPPOES { $$ = gen_pppoes(); } | pfvar { $$ = $1; } + | pqual p80211 { $$ = $2; } ; pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); } @@ -398,6 +515,79 @@ pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); } | PF_ACTION action { $$ = gen_pf_action($2); } ; +p80211: TYPE type SUBTYPE subtype + { $$ = gen_p80211_type($2 | $4, + IEEE80211_FC0_TYPE_MASK | + IEEE80211_FC0_SUBTYPE_MASK); + } + | TYPE type { $$ = gen_p80211_type($2, + IEEE80211_FC0_TYPE_MASK); + } + | SUBTYPE type_subtype { $$ = gen_p80211_type($2, + IEEE80211_FC0_TYPE_MASK | + IEEE80211_FC0_SUBTYPE_MASK); + } + | DIR dir { $$ = gen_p80211_fcdir($2); } + ; + +type: NUM + | ID { $$ = str2tok($1, ieee80211_types); + if ($$ == -1) + bpf_error("unknown 802.11 type name"); + } + ; + +subtype: NUM + | ID { const struct tok *types = NULL; + int i; + for (i = 0;; i++) { + if (ieee80211_type_subtypes[i].tok == NULL) { + /* Ran out of types */ + bpf_error("unknown 802.11 type"); + break; + } + if ($-1 == ieee80211_type_subtypes[i].type) { + types = ieee80211_type_subtypes[i].tok; + break; + } + } + + $$ = str2tok($1, types); + if ($$ == -1) + bpf_error("unknown 802.11 subtype name"); + } + ; + +type_subtype: ID { int i; + for (i = 0;; i++) { + if (ieee80211_type_subtypes[i].tok == NULL) { + /* Ran out of types */ + bpf_error("unknown 802.11 type name"); + break; + } + $$ = str2tok($1, ieee80211_type_subtypes[i].tok); + if ($$ != -1) { + $$ |= ieee80211_type_subtypes[i].type; + break; + } + } + } + ; + +dir: NUM + | ID { if (pcap_strcasecmp($1, "nods") == 0) + $$ = IEEE80211_FC1_DIR_NODS; + else if (pcap_strcasecmp($1, "tods") == 0) + $$ = IEEE80211_FC1_DIR_TODS; + else if (pcap_strcasecmp($1, "fromds") == 0) + $$ = IEEE80211_FC1_DIR_FROMDS; + else if (pcap_strcasecmp($1, "dstods") == 0) + $$ = IEEE80211_FC1_DIR_DSTODS; + else + bpf_error("unknown 802.11 direction"); + } + ; + reason: NUM { $$ = $1; } | ID { $$ = pfreason_to_num($1); } ; diff --git a/contrib/libpcap/inet.c b/contrib/libpcap/inet.c index 8a44728b31..aad87963e7 100644 --- a/contrib/libpcap/inet.c +++ b/contrib/libpcap/inet.c @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.66.2.6 2007/06/11 09:52:04 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.75.2.4 2008-04-20 18:19:24 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -356,6 +356,40 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name, return (0); } +/* + * XXX - on FreeBSDs that support it, should it get the sysctl named + * "dev.{adapter family name}.{adapter unit}.%desc" to get a description + * of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800" + * with my Cisco 350 card, so the name isn't entirely descriptive. The + * "dev.an.0.%pnpinfo" has a better description, although one might argue + * that the problem is really a driver bug - if it can find out that it's + * a Cisco 340 or 350, rather than an old Aironet card, it should use + * that in the description. + * + * Do NetBSD, DragonflyBSD, or OpenBSD support this as well? OpenBSD + * lets you get a description, but it's not generated by the OS, it's + * set with another ioctl that ifconfig supports; we use that to get + * the description in OpenBSD. + * + * In OS X, the System Configuration framework can apparently return + * names in 10.4 and later; it also appears that freedesktop.org's HAL + * offers an "info.product" string, but the HAL specification says + * it "should not be used in any UI" and "subsystem/capability + * specific properties" should be used instead. Using that would + * require that libpcap applications be linked with the frameworks/ + * libraries in question, which would be a bit of a pain unless we + * offer, for example, a pkg-config: + * + * http://pkg-config.freedesktop.org/wiki/ + * + * script, so applications can just use that script to find out what + * libraries you need to link with when linking with libpcap. + * pkg-config is GPLed; I don't know whether that would prevent its + * use with a BSD-licensed library such as libpcap. + * + * Do any other UN*Xes, or desktop environments support getting a + * description? + */ int add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags, struct sockaddr *addr, size_t addr_size, @@ -365,9 +399,32 @@ add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags, char *errbuf) { pcap_if_t *curdev; + char *description = NULL; pcap_addr_t *curaddr, *prevaddr, *nextaddr; +#ifdef SIOCGIFDESCR + struct ifreq ifrdesc; + char ifdescr[IFDESCRSIZE]; + int s; +#endif - if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) { +#ifdef SIOCGIFDESCR + /* + * Get the description for the interface. + */ + memset(&ifrdesc, 0, sizeof ifrdesc); + strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name); + ifrdesc.ifr_data = (caddr_t)&ifdescr; + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s >= 0) { + if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0 && + strlen(ifrdesc.ifr_data) != 0) + description = ifrdesc.ifr_data; + close(s); + } +#endif + + if (add_or_find_if(&curdev, alldevs, name, flags, description, + errbuf) == -1) { /* * Error - give up. */ @@ -607,6 +664,12 @@ pcap_lookupnet(device, netp, maskp, errbuf) #endif #ifdef HAVE_SEPTEL_API || strstr(device, "septel") != NULL +#endif +#ifdef PCAP_SUPPORT_BT + || strstr(device, "bluetooth") != NULL +#endif +#ifdef PCAP_SUPPORT_USB + || strstr(device, "usb") != NULL #endif ) { *netp = *maskp = 0; diff --git a/contrib/libpcap/nametoaddr.c b/contrib/libpcap/nametoaddr.c index d60e93d5c3..c21e7849cf 100644 --- a/contrib/libpcap/nametoaddr.c +++ b/contrib/libpcap/nametoaddr.c @@ -24,7 +24,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.77.2.4 2007/06/11 09:52:05 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.82.2.1 2008/02/06 10:21:47 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -80,7 +80,7 @@ struct rtentry; /* declarations in */ #include "pcap-int.h" #include "gencode.h" -#include +#include #ifdef HAVE_OS_PROTO_H #include "os-proto.h" @@ -398,7 +398,15 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr) } /* - * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new + * Convert 's', which can have the one of the forms: + * + * "xx:xx:xx:xx:xx:xx" + * "xx.xx.xx.xx.xx.xx" + * "xx-xx-xx-xx-xx-xx" + * "xxxx.xxxx.xxxx" + * "xxxxxxxxxxxx" + * + * (or various mixes of ':', '.', and '-') into a new * ethernet address. Assumes 's' is well formed. */ u_char * @@ -410,7 +418,7 @@ pcap_ether_aton(const char *s) e = ep = (u_char *)malloc(6); while (*s) { - if (*s == ':') + if (*s == ':' || *s == '.' || *s == '-') s += 1; d = xdtoi(*s++); if (isxdigit((unsigned char)*s)) { diff --git a/contrib/libpcap/optimize.c b/contrib/libpcap/optimize.c index d39273b2aa..475313f269 100644 --- a/contrib/libpcap/optimize.c +++ b/contrib/libpcap/optimize.c @@ -22,7 +22,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.85.2.3 2007/09/12 21:29:45 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.90.2.1 2008/01/02 04:22:16 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -53,6 +53,10 @@ extern int _w32_ffs (int mask); #define ffs _w32_ffs #endif +#if defined(WIN32) && defined (_MSC_VER) +int ffs(int mask); +#endif + /* * Represents a deleted instruction. */ @@ -905,6 +909,17 @@ opt_peep(b) if (b->s.k == 0xffffffff) JF(b) = JT(b); } + /* + * If we're comparing against the index register, and the index + * register is a known constant, we can just compare against that + * constant. + */ + val = b->val[X_ATOM]; + if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_X) { + bpf_int32 v = vmap[val].const_val; + b->s.code &= ~BPF_X; + b->s.k = v; + } /* * If the accumulator is a known constant, we can compute the * comparison result. @@ -2276,6 +2291,15 @@ install_bpf_program(pcap_t *p, struct bpf_program *fp) { size_t prog_size; + /* + * Validate the program. + */ + if (!bpf_validate(fp->bf_insns, fp->bf_len)) { + snprintf(p->errbuf, sizeof(p->errbuf), + "BPF program is not valid"); + return (-1); + } + /* * Free up any already installed program. */ diff --git a/contrib/libpcap/pcap-bpf.c b/contrib/libpcap/pcap-bpf.c index 027913e7f4..6ec6515fb7 100644 --- a/contrib/libpcap/pcap-bpf.c +++ b/contrib/libpcap/pcap-bpf.c @@ -20,7 +20,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.86.2.12 2007/06/15 17:57:27 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.99.2.17 2008-09-16 18:43:02 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -28,6 +28,9 @@ static const char rcsid[] _U_ = #endif #include /* optionally get BSD define */ +#ifdef HAVE_ZEROCOPY_BPF +#include +#endif #include #include #include @@ -35,12 +38,16 @@ static const char rcsid[] _U_ = #include #include +#ifdef HAVE_ZEROCOPY_BPF +#include +#endif + #include #ifdef _AIX /* - * Make "pcap.h" not include "pcap-bpf.h"; we are going to include the + * Make "pcap.h" not include "pcap/bpf.h"; we are going to include the * native OS version, as we need "struct bpf_config" from it. */ #define PCAP_DONT_INCLUDE_PCAP_BPF_H @@ -92,6 +99,10 @@ static int odmlockid = 0; #include #include +#ifdef HAVE_NET_IF_MEDIA_H +# include +#endif + #include "pcap-int.h" #ifdef HAVE_DAG_API @@ -102,12 +113,579 @@ static int odmlockid = 0; #include "os-proto.h" #endif -#include "gencode.h" /* for "no_optimize" */ +#ifdef BIOCGDLTLIST +# if (defined(HAVE_NET_IF_MEDIA_H) && defined(IFM_IEEE80211)) && !defined(__APPLE__) +#define HAVE_BSD_IEEE80211 +# endif + +# if defined(__APPLE__) || defined(HAVE_BSD_IEEE80211) +static int find_802_11(struct bpf_dltlist *); + +# ifdef HAVE_BSD_IEEE80211 +static int monitor_mode(pcap_t *, int); +# endif + +# if defined(__APPLE__) +static void remove_en(pcap_t *); +static void remove_802_11(pcap_t *); +# endif + +# endif /* defined(__APPLE__) || defined(HAVE_BSD_IEEE80211) */ + +#endif /* BIOCGDLTLIST */ + +/* + * We include the OS's , not our "pcap/bpf.h", so we probably + * don't get DLT_DOCSIS defined. + */ +#ifndef DLT_DOCSIS +#define DLT_DOCSIS 143 +#endif + +/* + * On OS X, we don't even get any of the 802.11-plus-radio-header DLT_'s + * defined, even though some of them are used by various Airport drivers. + */ +#ifndef DLT_PRISM_HEADER +#define DLT_PRISM_HEADER 119 +#endif +#ifndef DLT_AIRONET_HEADER +#define DLT_AIRONET_HEADER 120 +#endif +#ifndef DLT_IEEE802_11_RADIO +#define DLT_IEEE802_11_RADIO 127 +#endif +#ifndef DLT_IEEE802_11_RADIO_AVS +#define DLT_IEEE802_11_RADIO_AVS 163 +#endif +static int pcap_can_set_rfmon_bpf(pcap_t *p); +static int pcap_activate_bpf(pcap_t *p); 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. + */ +static int +pcap_getnonblock_zbuf(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); +} + +static int +pcap_setnonblock_zbuf(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) + p->md.timeout = p->md.timeout * -1 - 1; + } else + if (p->md.timeout < 0) + p->md.timeout = (p->md.timeout + 1) * -1; + 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); +} + +/* + * Zero-copy BPF buffer routines to check for and acknowledge BPF data in + * shared memory buffers. + * + * pcap_next_zbuf_shm(): Check for a newly available shared memory buffer, + * and set up p->buffer and cc to reflect one if available. Notice that if + * there was no prior buffer, we select zbuf1 as this will be the first + * buffer filled for a fresh BPF session. + */ +static int +pcap_next_zbuf_shm(pcap_t *p, int *cc) +{ + struct bpf_zbuf_header *bzh; + + if (p->md.zbuffer == p->md.zbuf2 || p->md.zbuffer == NULL) { + bzh = (struct bpf_zbuf_header *)p->md.zbuf1; + if (bzh->bzh_user_gen != + atomic_load_acq_int(&bzh->bzh_kernel_gen)) { + p->md.bzh = bzh; + p->md.zbuffer = (u_char *)p->md.zbuf1; + p->buffer = p->md.zbuffer + sizeof(*bzh); + *cc = bzh->bzh_kernel_len; + return (1); + } + } else if (p->md.zbuffer == p->md.zbuf1) { + bzh = (struct bpf_zbuf_header *)p->md.zbuf2; + if (bzh->bzh_user_gen != + atomic_load_acq_int(&bzh->bzh_kernel_gen)) { + p->md.bzh = bzh; + p->md.zbuffer = (u_char *)p->md.zbuf2; + p->buffer = p->md.zbuffer + sizeof(*bzh); + *cc = bzh->bzh_kernel_len; + return (1); + } + } + *cc = 0; + return (0); +} + +/* + * pcap_next_zbuf() -- Similar to pcap_next_zbuf_shm(), except wait using + * select() for data or a timeout, and possibly force rotation of the buffer + * in the event we time out or are in immediate mode. Invoke the shared + * memory check before doing system calls in order to avoid doing avoidable + * work. + */ +static int +pcap_next_zbuf(pcap_t *p, int *cc) +{ + struct bpf_zbuf bz; + struct timeval tv; + struct timespec cur; + fd_set r_set; + int data, r; + int expire, tmout; + +#define TSTOMILLI(ts) (((ts)->tv_sec * 1000) + ((ts)->tv_nsec / 1000000)) + /* + * Start out by seeing whether anything is waiting by checking the + * next shared memory buffer for data. + */ + data = pcap_next_zbuf_shm(p, cc); + if (data) + return (data); + /* + * If a previous sleep was interrupted due to signal delivery, make + * sure that the timeout gets adjusted accordingly. This requires + * that we analyze when the timeout should be been expired, and + * subtract the current time from that. If after this operation, + * our timeout is less then or equal to zero, handle it like a + * regular timeout. + */ + tmout = p->md.timeout; + if (tmout) + (void) clock_gettime(CLOCK_MONOTONIC, &cur); + if (p->md.interrupted && p->md.timeout) { + expire = TSTOMILLI(&p->md.firstsel) + p->md.timeout; + tmout = expire - TSTOMILLI(&cur); +#undef TSTOMILLI + if (tmout <= 0) { + p->md.interrupted = 0; + data = pcap_next_zbuf_shm(p, cc); + if (data) + return (data); + if (ioctl(p->fd, BIOCROTZBUF, &bz) < 0) { + (void) snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "BIOCROTZBUF: %s", strerror(errno)); + return (PCAP_ERROR); + } + return (pcap_next_zbuf_shm(p, cc)); + } + } + /* + * No data in the buffer, so must use select() to wait for data or + * the next timeout. Note that we only call select if the handle + * is in blocking mode. + */ + if (p->md.timeout >= 0) { + FD_ZERO(&r_set); + FD_SET(p->fd, &r_set); + if (tmout != 0) { + tv.tv_sec = tmout / 1000; + tv.tv_usec = (tmout * 1000) % 1000000; + } + r = select(p->fd + 1, &r_set, NULL, NULL, + p->md.timeout != 0 ? &tv : NULL); + if (r < 0 && errno == EINTR) { + if (!p->md.interrupted && p->md.timeout) { + p->md.interrupted = 1; + p->md.firstsel = cur; + } + return (0); + } else if (r < 0) { + (void) snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "select: %s", strerror(errno)); + return (PCAP_ERROR); + } + } + p->md.interrupted = 0; + /* + * Check again for data, which may exist now that we've either been + * woken up as a result of data or timed out. Try the "there's data" + * case first since it doesn't require a system call. + */ + data = pcap_next_zbuf_shm(p, cc); + if (data) + return (data); + /* + * Try forcing a buffer rotation to dislodge timed out or immediate + * data. + */ + if (ioctl(p->fd, BIOCROTZBUF, &bz) < 0) { + (void) snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "BIOCROTZBUF: %s", strerror(errno)); + return (PCAP_ERROR); + } + return (pcap_next_zbuf_shm(p, cc)); +} + +/* + * Notify kernel that we are done with the buffer. We don't reset zbuffer so + * that we know which buffer to use next time around. + */ +static int +pcap_ack_zbuf(pcap_t *p) +{ + + atomic_store_rel_int(&p->md.bzh->bzh_user_gen, + p->md.bzh->bzh_kernel_gen); + p->md.bzh = NULL; + p->buffer = NULL; + return (0); +} +#endif + +pcap_t * +pcap_create(const char *device, char *ebuf) +{ + pcap_t *p; + +#ifdef HAVE_DAG_API + if (strstr(device, "dag")) + return (dag_create(device, ebuf)); +#endif /* HAVE_DAG_API */ + + p = pcap_create_common(device, ebuf); + if (p == NULL) + return (NULL); + + p->activate_op = pcap_activate_bpf; + p->can_set_rfmon_op = pcap_can_set_rfmon_bpf; + return (p); +} + +static int +bpf_open(pcap_t *p) +{ + int fd; +#ifdef HAVE_CLONING_BPF + static const char device[] = "/dev/bpf"; +#else + int n = 0; + char device[sizeof "/dev/bpf0000000000"]; +#endif + +#ifdef _AIX + /* + * Load the bpf driver, if it isn't already loaded, + * and create the BPF device entries, if they don't + * already exist. + */ + if (bpf_load(p->errbuf) == PCAP_ERROR) + return (PCAP_ERROR); +#endif + +#ifdef HAVE_CLONING_BPF + if ((fd = open(device, O_RDWR)) == -1 && + (errno != EACCES || (fd = open(device, O_RDONLY)) == -1)) { + if (errno == EACCES) + fd = PCAP_ERROR_PERM_DENIED; + else + fd = PCAP_ERROR; + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "(cannot open device) %s: %s", device, pcap_strerror(errno)); + } +#else + /* + * Go through all the minors and find one that isn't in use. + */ + do { + (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++); + /* + * Initially try a read/write open (to allow the inject + * method to work). If that fails due to permission + * issues, fall back to read-only. This allows a + * non-root user to be granted specific access to pcap + * capabilities via file permissions. + * + * XXX - we should have an API that has a flag that + * controls whether to open read-only or read-write, + * so that denial of permission to send (or inability + * to send, if sending packets isn't supported on + * the device in question) can be indicated at open + * time. + */ + fd = open(device, O_RDWR); + if (fd == -1 && errno == EACCES) + fd = open(device, O_RDONLY); + } while (fd < 0 && errno == EBUSY); + + /* + * XXX better message for all minors used + */ + if (fd < 0) { + if (errno == EACCES) + fd = PCAP_ERROR_PERM_DENIED; + else + fd = PCAP_ERROR; + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s", + device, pcap_strerror(errno)); + } +#endif + + return (fd); +} + +#ifdef BIOCGDLTLIST +static int +get_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf) +{ + memset(bdlp, 0, sizeof(*bdlp)); + if (ioctl(fd, BIOCGDLTLIST, (caddr_t)bdlp) == 0) { + u_int i; + int is_ethernet; + + bdlp->bfl_list = (u_int *) malloc(sizeof(u_int) * (bdlp->bfl_len + 1)); + if (bdlp->bfl_list == NULL) { + (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + return (PCAP_ERROR); + } + + if (ioctl(fd, BIOCGDLTLIST, (caddr_t)bdlp) < 0) { + (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, + "BIOCGDLTLIST: %s", pcap_strerror(errno)); + free(bdlp->bfl_list); + return (PCAP_ERROR); + } + + /* + * OK, for real Ethernet devices, add DLT_DOCSIS to the + * list, so that an application can let you choose it, + * in case you're capturing DOCSIS traffic that a Cisco + * Cable Modem Termination System is putting out onto + * an Ethernet (it doesn't put an Ethernet header onto + * the wire, it puts raw DOCSIS frames out on the wire + * inside the low-level Ethernet framing). + * + * A "real Ethernet device" is defined here as a device + * that has a link-layer type of DLT_EN10MB and that has + * no alternate link-layer types; that's done to exclude + * 802.11 interfaces (which might or might not be the + * right thing to do, but I suspect it is - Ethernet <-> + * 802.11 bridges would probably badly mishandle frames + * that don't have Ethernet headers). + */ + if (v == DLT_EN10MB) { + is_ethernet = 1; + for (i = 0; i < bdlp->bfl_len; i++) { + if (bdlp->bfl_list[i] != DLT_EN10MB) { + is_ethernet = 0; + break; + } + } + if (is_ethernet) { + /* + * We reserved one more slot at the end of + * the list. + */ + bdlp->bfl_list[bdlp->bfl_len] = DLT_DOCSIS; + bdlp->bfl_len++; + } + } + } else { + /* + * EINVAL just means "we don't support this ioctl on + * this device"; don't treat it as an error. + */ + if (errno != EINVAL) { + (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, + "BIOCGDLTLIST: %s", pcap_strerror(errno)); + return (PCAP_ERROR); + } + } + return (0); +} +#endif + +static int +pcap_can_set_rfmon_bpf(pcap_t *p) +{ +#if defined(__APPLE__) + struct utsname osinfo; + struct ifreq ifr; + int fd; +#ifdef BIOCGDLTLIST + struct bpf_dltlist bdl; +#endif + + /* + * The joys of monitor mode on OS X. + * + * Prior to 10.4, it's not supported at all. + * + * In 10.4, if adapter enN supports monitor mode, there's a + * wltN adapter corresponding to it; you open it, instead of + * enN, to get monitor mode. You get whatever link-layer + * headers it supplies. + * + * In 10.5, and, we assume, later releases, if adapter enN + * supports monitor mode, it offers, among its selectable + * DLT_ values, values that let you get the 802.11 header; + * selecting one of those values puts the adapter into monitor + * mode (i.e., you can't get 802.11 headers except in monitor + * mode, and you can't get Ethernet headers in monitor mode). + */ + if (uname(&osinfo) == -1) { + /* + * Can't get the OS version; just say "no". + */ + return (0); + } + /* + * We assume osinfo.sysname is "Darwin", because + * __APPLE__ is defined. We just check the version. + */ + if (osinfo.release[0] < '8' && osinfo.release[1] == '.') { + /* + * 10.3 (Darwin 7.x) or earlier. + * Monitor mode not supported. + */ + return (0); + } + if (osinfo.release[0] == '8' && osinfo.release[1] == '.') { + /* + * 10.4 (Darwin 8.x). s/en/wlt/, and check + * whether the device exists. + */ + if (strncmp(p->opt.source, "en", 2) != 0) { + /* + * Not an enN device; no monitor mode. + */ + return (0); + } + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd == -1) { + (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "socket: %s", pcap_strerror(errno)); + return (PCAP_ERROR); + } + strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name)); + strlcat(ifr.ifr_name, p->opt.source + 2, sizeof(ifr.ifr_name)); + if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { + /* + * No such device? + */ + close(fd); + return (0); + } + close(fd); + return (1); + } + +#ifdef BIOCGDLTLIST + /* + * Everything else is 10.5 or later; for those, + * we just open the enN device, and check whether + * we have any 802.11 devices. + * + * First, open a BPF device. + */ + fd = bpf_open(p); + if (fd < 0) + return (fd); + + /* + * 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) { + /* + * Return a "network down" indication, so that + * the application can report that rather than + * saying we had a mysterious failure and + * suggest that they report a problem to the + * libpcap developers. + */ + close(fd); + return (PCAP_ERROR_IFACE_NOT_UP); + } else { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "BIOCSETIF: %s: %s", + p->opt.source, pcap_strerror(errno)); + close(fd); + return (PCAP_ERROR); + } + } + + /* + * We know the default link type -- now determine all the DLTs + * this interface supports. If this fails with EINVAL, it's + * not fatal; we just don't get to use the feature later. + * (We don't care about DLT_DOCSIS, so we pass DLT_NULL + * as the default DLT for this adapter.) + */ + if (get_dlt_list(fd, DLT_NULL, &bdl, p->errbuf) == PCAP_ERROR) { + close(fd); + return (PCAP_ERROR); + } + if (find_802_11(&bdl) != -1) { + /* + * We have an 802.11 DLT, so we can set monitor mode. + */ + free(bdl.bfl_list); + close(fd); + return (1); + } + free(bdl.bfl_list); +#endif /* BIOCGDLTLIST */ + return (0); +#elif defined(HAVE_BSD_IEEE80211) + int ret; + + ret = monitor_mode(p, 0); + if (ret == PCAP_ERROR_RFMON_NOTSUP) + return (0); /* not an error, just a "can't do" */ + if (ret == 0) + return (1); /* success */ + return (ret); +#else + return (0); +#endif +} + static int pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps) { @@ -129,7 +707,7 @@ pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps) if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s", pcap_strerror(errno)); - return (-1); + return (PCAP_ERROR); } ps->ps_recv = s.bs_recv; @@ -144,12 +722,13 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) int n = 0; register u_char *bp, *ep; u_char *datap; - struct bpf_insn *fcode; #ifdef PCAP_FDDIPAD register int pad; #endif +#ifdef HAVE_ZEROCOPY_BPF + int i; +#endif - fcode = p->md.use_bpf ? NULL : p->fcode.bf_insns; again: /* * Has "pcap_breakloop()" been called? @@ -157,15 +736,36 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) if (p->break_loop) { /* * Yes - clear the flag that indicates that it - * has, and return -2 to indicate that we were - * told to break out of the loop. + * has, and return PCAP_ERROR_BREAK to indicate + * that we were told to break out of the loop. */ p->break_loop = 0; - return (-2); + return (PCAP_ERROR_BREAK); } cc = p->cc; if (p->cc == 0) { - cc = read(p->fd, (char *)p->buffer, p->bufsize); + /* + * When reading without zero-copy from a file descriptor, we + * use a single buffer and return a length of data in the + * buffer. With zero-copy, we update the p->buffer pointer + * to point at whatever underlying buffer contains the next + * data and update cc to reflect the data found in the + * buffer. + */ +#ifdef HAVE_ZEROCOPY_BPF + if (p->md.zerocopy) { + if (p->buffer != NULL) + pcap_ack_zbuf(p); + i = pcap_next_zbuf(p, &cc); + if (i == 0) + goto again; + if (i < 0) + return (PCAP_ERROR); + } else +#endif + { + cc = read(p->fd, (char *)p->buffer, p->bufsize); + } if (cc < 0) { /* Don't choke when we get ptraced */ switch (errno) { @@ -180,16 +780,16 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) * * For some unknown reason the uiomove() * operation in the bpf kernel extension - * used to copy the buffer into user + * used to copy the buffer into user * space sometimes returns EFAULT. I have * no idea why this is the case given that - * a kernel debugger shows the user buffer - * is correct. This problem appears to - * be mostly mitigated by the memset of - * the buffer before it is first used. + * a kernel debugger shows the user buffer + * is correct. This problem appears to + * be mostly mitigated by the memset of + * the buffer before it is first used. * Very strange.... Shaun Clowes * - * In any case this means that we shouldn't + * In any case this means that we shouldn't * treat EFAULT as a fatal error; as we * don't have an API for returning * a "some packets were dropped since @@ -197,8 +797,8 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) * we just ignore EFAULT and keep reading. */ goto again; -#endif - +#endif + case EWOULDBLOCK: return (0); #if defined(sun) && !defined(BSD) @@ -218,7 +818,7 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) } snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s", pcap_strerror(errno)); - return (-1); + return (PCAP_ERROR); } bp = p->buffer; } else @@ -238,16 +838,17 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) /* * Has "pcap_breakloop()" been called? * If so, return immediately - if we haven't read any - * packets, clear the flag and return -2 to indicate - * that we were told to break out of the loop, otherwise - * leave the flag set, so that the *next* call will break - * out of the loop without having read any packets, and - * return the number of packets we've processed so far. + * packets, clear the flag and return PCAP_ERROR_BREAK + * to indicate that we were told to break out of the loop, + * otherwise leave the flag set, so that the *next* call + * will break out of the loop without having read any + * packets, and return the number of packets we've + * processed so far. */ if (p->break_loop) { if (n == 0) { p->break_loop = 0; - return (-2); + return (PCAP_ERROR_BREAK); } else { p->bp = bp; p->cc = ep - bp; @@ -260,7 +861,8 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) datap = bp + hdrlen; /* * Short-circuit evaluation: if using BPF filter - * in kernel, no need to do it now. + * in kernel, no need to do it now - we already know + * the packet passed the filter. * #ifdef PCAP_FDDIPAD * Note: the filter code was generated assuming @@ -270,8 +872,8 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) * skipping that padding. #endif */ - if (fcode == NULL || - bpf_filter(fcode, datap, bhp->bh_datalen, caplen)) { + if (p->md.use_bpf || + bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { struct pcap_pkthdr pkthdr; pkthdr.ts.tv_sec = bhp->bh_tstamp.tv_sec; @@ -349,7 +951,7 @@ pcap_inject_bpf(pcap_t *p, const void *buf, size_t size) (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: can't turn off BIOCSHDRCMPLT: %s", pcap_strerror(errno)); - return (-1); + return (PCAP_ERROR); } /* @@ -361,13 +963,13 @@ pcap_inject_bpf(pcap_t *p, const void *buf, size_t size) if (ret == -1) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", pcap_strerror(errno)); - return (-1); + return (PCAP_ERROR); } return (ret); } #ifdef _AIX -static int +static int bpf_odminit(char *errbuf) { char *errstr; @@ -378,7 +980,7 @@ bpf_odminit(char *errbuf) snprintf(errbuf, PCAP_ERRBUF_SIZE, "bpf_load: odm_initialize failed: %s", errstr); - return (-1); + return (PCAP_ERROR); } if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) { @@ -387,13 +989,13 @@ bpf_odminit(char *errbuf) snprintf(errbuf, PCAP_ERRBUF_SIZE, "bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s", errstr); - return (-1); + return (PCAP_ERROR); } return (0); } -static int +static int bpf_odmcleanup(char *errbuf) { char *errstr; @@ -404,7 +1006,7 @@ bpf_odmcleanup(char *errbuf) snprintf(errbuf, PCAP_ERRBUF_SIZE, "bpf_load: odm_unlock failed: %s", errstr); - return (-1); + return (PCAP_ERROR); } if (odm_terminate() == -1) { @@ -413,7 +1015,7 @@ bpf_odmcleanup(char *errbuf) snprintf(errbuf, PCAP_ERRBUF_SIZE, "bpf_load: odm_terminate failed: %s", errstr); - return (-1); + return (PCAP_ERROR); } return (0); @@ -438,14 +1040,14 @@ bpf_load(char *errbuf) if (bpfloadedflag) return (0); - if (bpf_odminit(errbuf) != 0) - return (-1); + if (bpf_odminit(errbuf) == PCAP_ERROR) + return (PCAP_ERROR); major = genmajor(BPF_NAME); if (major == -1) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "bpf_load: genmajor failed: %s", pcap_strerror(errno)); - return (-1); + return (PCAP_ERROR); } minors = getminor(major, &numminors, BPF_NAME); @@ -455,19 +1057,19 @@ bpf_load(char *errbuf) snprintf(errbuf, PCAP_ERRBUF_SIZE, "bpf_load: genminor failed: %s", pcap_strerror(errno)); - return (-1); + return (PCAP_ERROR); } } - if (bpf_odmcleanup(errbuf)) - return (-1); + if (bpf_odmcleanup(errbuf) == PCAP_ERROR) + return (PCAP_ERROR); rc = stat(BPF_NODE "0", &sbuf); if (rc == -1 && errno != ENOENT) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "bpf_load: can't stat %s: %s", BPF_NODE "0", pcap_strerror(errno)); - return (-1); + return (PCAP_ERROR); } if (rc == -1 || getmajor(sbuf.st_rdev) != major) { @@ -478,7 +1080,7 @@ bpf_load(char *errbuf) snprintf(errbuf, PCAP_ERRBUF_SIZE, "bpf_load: can't mknod %s: %s", buf, pcap_strerror(errno)); - return (-1); + return (PCAP_ERROR); } } } @@ -494,7 +1096,7 @@ bpf_load(char *errbuf) snprintf(errbuf, PCAP_ERRBUF_SIZE, "bpf_load: could not load driver: %s", strerror(errno)); - return (-1); + return (PCAP_ERROR); } } @@ -502,190 +1104,507 @@ bpf_load(char *errbuf) cfg_km.cmd = CFG_INIT; cfg_km.kmid = cfg_ld.kmid; cfg_km.mdilen = sizeof(cfg_bpf); - cfg_km.mdiptr = (void *)&cfg_bpf; + cfg_km.mdiptr = (void *)&cfg_bpf; for (i = 0; i < BPF_MINORS; i++) { cfg_bpf.devno = domakedev(major, i); if (sysconfig(SYS_CFGKMOD, (void *)&cfg_km, sizeof(cfg_km)) == -1) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "bpf_load: could not configure driver: %s", strerror(errno)); - return (-1); + return (PCAP_ERROR); } } - + bpfloadedflag = 1; return (0); } #endif -static inline int -bpf_open(pcap_t *p, char *errbuf) +/* + * Turn off rfmon mode if necessary. + */ +static void +pcap_cleanup_bpf(pcap_t *p) { - int fd; -#ifdef HAVE_CLONING_BPF - static const char device[] = "/dev/bpf"; -#else - int n = 0; - char device[sizeof "/dev/bpf0000000000"]; +#ifdef HAVE_BSD_IEEE80211 + int sock; + struct ifmediareq req; + struct ifreq ifr; #endif -#ifdef _AIX - /* - * Load the bpf driver, if it isn't already loaded, - * and create the BPF device entries, if they don't - * already exist. - */ - if (bpf_load(errbuf) == -1) - return (-1); -#endif + if (p->md.must_clear != 0) { + /* + * There's something we have to do when closing this + * pcap_t. + */ +#ifdef HAVE_BSD_IEEE80211 + if (p->md.must_clear & MUST_CLEAR_RFMON) { + /* + * We put the interface into rfmon mode; + * take it out of rfmon mode. + * + * XXX - if somebody else wants it in rfmon + * mode, this code cannot know that, so it'll take + * it out of rfmon mode. + */ + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) { + fprintf(stderr, + "Can't restore interface flags (socket() failed: %s).\n" + "Please adjust manually.\n", + strerror(errno)); + } else { + memset(&req, 0, sizeof(req)); + strncpy(req.ifm_name, p->md.device, + sizeof(req.ifm_name)); + if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) { + fprintf(stderr, + "Can't restore interface flags (SIOCGIFMEDIA failed: %s).\n" + "Please adjust manually.\n", + strerror(errno)); + } else { + if (req.ifm_current & IFM_IEEE80211_MONITOR) { + /* + * Rfmon mode is currently on; + * turn it off. + */ + memset(&ifr, 0, sizeof(ifr)); + (void)strncpy(ifr.ifr_name, + p->md.device, + sizeof(ifr.ifr_name)); + ifr.ifr_media = + req.ifm_current & ~IFM_IEEE80211_MONITOR; + if (ioctl(sock, SIOCSIFMEDIA, + &ifr) == -1) { + fprintf(stderr, + "Can't restore interface flags (SIOCSIFMEDIA failed: %s).\n" + "Please adjust manually.\n", + strerror(errno)); + } + } + } + close(sock); + } + } +#endif /* HAVE_BSD_IEEE80211 */ -#ifdef HAVE_CLONING_BPF - if ((fd = open(device, O_RDWR)) == -1 && - (errno != EACCES || (fd = open(device, O_RDONLY)) == -1)) - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "(cannot open device) %s: %s", device, pcap_strerror(errno)); -#else - /* - * Go through all the minors and find one that isn't in use. - */ - do { - (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++); /* - * Initially try a read/write open (to allow the inject - * method to work). If that fails due to permission - * issues, fall back to read-only. This allows a - * non-root user to be granted specific access to pcap - * capabilities via file permissions. - * - * XXX - we should have an API that has a flag that - * controls whether to open read-only or read-write, - * so that denial of permission to send (or inability - * to send, if sending packets isn't supported on - * the device in question) can be indicated at open - * time. + * Take this pcap out of the list of pcaps for which we + * have to take the interface out of some mode. */ - fd = open(device, O_RDWR); - if (fd == -1 && errno == EACCES) - fd = open(device, O_RDONLY); - } while (fd < 0 && errno == EBUSY); + pcap_remove_from_pcaps_to_close(p); + p->md.must_clear = 0; + } +#ifdef HAVE_ZEROCOPY_BPF /* - * XXX better message for all minors used + * 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 (fd < 0) - snprintf(errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s", - device, pcap_strerror(errno)); + if (p->md.zerocopy) { + if (p->md.zbuf1 != MAP_FAILED && p->md.zbuf1 != NULL) + munmap(p->md.zbuf1, p->md.zbufsize); + if (p->md.zbuf2 != MAP_FAILED && p->md.zbuf2 != NULL) + munmap(p->md.zbuf2, p->md.zbufsize); + } #endif - - return (fd); + if (p->md.device != NULL) { + free(p->md.device); + p->md.device = NULL; + } + pcap_cleanup_live_common(p); } -/* - * We include the OS's , not our "pcap-bpf.h", so we probably - * don't get DLT_DOCSIS defined. - */ -#ifndef DLT_DOCSIS -#define DLT_DOCSIS 143 +static int +check_setif_failure(pcap_t *p, int error) +{ +#ifdef __APPLE__ + int fd; + struct ifreq ifr; + int err; #endif -pcap_t * -pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, - char *ebuf) + if (error == ENXIO) { + /* + * No such device exists. + */ +#ifdef __APPLE__ + if (p->opt.rfmon && strncmp(p->opt.source, "wlt", 3) == 0) { + /* + * Monitor mode was requested, and we're trying + * to open a "wltN" device. Assume that this + * is 10.4 and that we were asked to open an + * "enN" device; if that device exists, return + * "monitor mode not supported on the device". + */ + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd != -1) { + strlcpy(ifr.ifr_name, "en", + sizeof(ifr.ifr_name)); + strlcat(ifr.ifr_name, p->opt.source + 3, + sizeof(ifr.ifr_name)); + if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { + /* + * We assume this failed because + * the underlying device doesn't + * exist. + */ + err = PCAP_ERROR_NO_SUCH_DEVICE; + strcpy(p->errbuf, ""); + } else { + /* + * The underlying "enN" device + * exists, but there's no + * corresponding "wltN" device; + * that means that the "enN" + * device doesn't support + * monitor mode, probably because + * it's an Ethernet device rather + * than a wireless device. + */ + err = PCAP_ERROR_RFMON_NOTSUP; + } + close(fd); + } else { + /* + * We can't find out whether there's + * an underlying "enN" device, so + * just report "no such device". + */ + err = PCAP_ERROR_NO_SUCH_DEVICE; + strcpy(p->errbuf, ""); + } + return (err); + } +#endif + /* + * No such device. + */ + strcpy(p->errbuf, ""); + return (PCAP_ERROR_NO_SUCH_DEVICE); + } else if (errno == ENETDOWN) { + /* + * Return a "network down" indication, so that + * the application can report that rather than + * saying we had a mysterious failure and + * suggest that they report a problem to the + * libpcap developers. + */ + return (PCAP_ERROR_IFACE_NOT_UP); + } else { + /* + * Some other error; fill in the error string, and + * return PCAP_ERROR. + */ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s", + p->opt.source, pcap_strerror(errno)); + return (PCAP_ERROR); + } +} + +static int +pcap_activate_bpf(pcap_t *p) { + int status = 0; int fd; struct ifreq ifr; struct bpf_version bv; +#ifdef __APPLE__ + int sockfd; + char *wltdev = NULL; +#endif #ifdef BIOCGDLTLIST struct bpf_dltlist bdl; +#if defined(__APPLE__) || defined(HAVE_BSD_IEEE80211) + int new_dlt; #endif +#endif /* BIOCGDLTLIST */ #if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) u_int spoof_eth_src = 1; #endif u_int v; - pcap_t *p; struct bpf_insn total_insn; struct bpf_program total_prog; struct utsname osinfo; + int have_osinfo = 0; +#ifdef HAVE_ZEROCOPY_BPF + struct bpf_zbuf bz; + u_int bufmode, zbufmax; +#endif -#ifdef HAVE_DAG_API - if (strstr(device, "dag")) { - return dag_open_live(device, snaplen, promisc, to_ms, ebuf); + fd = bpf_open(p); + if (fd < 0) { + status = fd; + goto bad; } -#endif /* HAVE_DAG_API */ -#ifdef BIOCGDLTLIST - memset(&bdl, 0, sizeof(bdl)); -#endif + p->fd = fd; - p = (pcap_t *)malloc(sizeof(*p)); - if (p == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s", pcap_strerror(errno)); - return (NULL); + status = PCAP_ERROR; + goto bad; } - memset(p, 0, sizeof(*p)); - fd = bpf_open(p, ebuf); - if (fd < 0) + if (bv.bv_major != BPF_MAJOR_VERSION || + bv.bv_minor < BPF_MINOR_VERSION) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "kernel bpf filter out of date"); + status = PCAP_ERROR; + goto bad; + } + + p->md.device = strdup(p->opt.source); + if (p->md.device == NULL) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s", + pcap_strerror(errno)); + status = PCAP_ERROR; goto bad; + } - p->fd = fd; - p->snapshot = snaplen; + /* + * Attempt to find out the version of the OS on which we're running. + */ + if (uname(&osinfo) == 0) + have_osinfo = 1; + +#ifdef __APPLE__ + /* + * See comment in pcap_can_set_rfmon_bpf() for an explanation + * of why we check the version number. + */ + if (p->opt.rfmon) { + if (have_osinfo) { + /* + * We assume osinfo.sysname is "Darwin", because + * __APPLE__ is defined. We just check the version. + */ + if (osinfo.release[0] < '8' && + osinfo.release[1] == '.') { + /* + * 10.3 (Darwin 7.x) or earlier. + */ + status = PCAP_ERROR_RFMON_NOTSUP; + goto bad; + } + if (osinfo.release[0] == '8' && + osinfo.release[1] == '.') { + /* + * 10.4 (Darwin 8.x). s/en/wlt/ + */ + if (strncmp(p->opt.source, "en", 2) != 0) { + /* + * Not an enN device; check + * whether the device even exists. + */ + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd != -1) { + strlcpy(ifr.ifr_name, + p->opt.source, + sizeof(ifr.ifr_name)); + if (ioctl(sockfd, SIOCGIFFLAGS, + (char *)&ifr) < 0) { + /* + * We assume this + * failed because + * the underlying + * device doesn't + * exist. + */ + status = PCAP_ERROR_NO_SUCH_DEVICE; + strcpy(p->errbuf, ""); + } else + status = PCAP_ERROR_RFMON_NOTSUP; + close(sockfd); + } else { + /* + * We can't find out whether + * the device exists, so just + * report "no such device". + */ + status = PCAP_ERROR_NO_SUCH_DEVICE; + strcpy(p->errbuf, ""); + } + goto bad; + } + wltdev = malloc(strlen(p->opt.source) + 2); + if (wltdev == NULL) { + (void)snprintf(p->errbuf, + PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + status = PCAP_ERROR; + goto bad; + } + strcpy(wltdev, "wlt"); + strcat(wltdev, p->opt.source + 2); + free(p->opt.source); + p->opt.source = wltdev; + } + /* + * Everything else is 10.5 or later; for those, + * we just open the enN device, and set the DLT. + */ + } + } +#endif /* __APPLE__ */ +#ifdef HAVE_ZEROCOPY_BPF + /* + * If the BPF extension to set buffer mode is present, try setting + * the mode to zero-copy. If that fails, use regular buffering. If + * it succeeds but other setup fails, return an error to the user. + */ + bufmode = BPF_BUFMODE_ZBUF; + if (ioctl(fd, BIOCSETBUFMODE, (caddr_t)&bufmode) == 0) { + /* + * We have zerocopy BPF; use it. + */ + 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. + * Then, if a buffer size was specified, use that, otherwise + * query the default buffer size, which reflects kernel + * policy for a desired default. Round to the nearest page + * size. + */ + if (ioctl(fd, BIOCGETZMAX, (caddr_t)&zbufmax) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGETZMAX: %s", + pcap_strerror(errno)); + goto bad; + } + + if (p->opt.buffer_size != 0) { + /* + * A buffer size was explicitly specified; use it. + */ + v = p->opt.buffer_size; + } else { + if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || + v < 32768) + v = 32768; + } +#ifndef roundup +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ +#endif + p->md.zbufsize = roundup(v, getpagesize()); + if (p->md.zbufsize > zbufmax) + p->md.zbufsize = zbufmax; + p->md.zbuf1 = mmap(NULL, p->md.zbufsize, PROT_READ | PROT_WRITE, + MAP_ANON, -1, 0); + p->md.zbuf2 = mmap(NULL, p->md.zbufsize, PROT_READ | PROT_WRITE, + MAP_ANON, -1, 0); + if (p->md.zbuf1 == MAP_FAILED || p->md.zbuf2 == MAP_FAILED) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "mmap: %s", + pcap_strerror(errno)); + goto bad; + } + bzero(&bz, sizeof(bz)); + bz.bz_bufa = p->md.zbuf1; + bz.bz_bufb = p->md.zbuf2; + bz.bz_buflen = p->md.zbufsize; + if (ioctl(fd, BIOCSETZBUF, (caddr_t)&bz) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETZBUF: %s", + pcap_strerror(errno)); + goto bad; + } + (void)strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name)); + if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s", + p->opt.source, pcap_strerror(errno)); + goto bad; + } + v = p->md.zbufsize - sizeof(struct bpf_zbuf_header); + } else +#endif + { + /* + * We don't have zerocopy BPF. + * Set the buffer size. + */ + if (p->opt.buffer_size != 0) { + /* + * A buffer size was explicitly specified; use it. + */ + if (ioctl(fd, BIOCSBLEN, + (caddr_t)&p->opt.buffer_size) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "BIOCSBLEN: %s: %s", p->opt.source, + pcap_strerror(errno)); + status = PCAP_ERROR; + goto bad; + } - if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s", - pcap_strerror(errno)); - goto bad; - } - if (bv.bv_major != BPF_MAJOR_VERSION || - bv.bv_minor < BPF_MINOR_VERSION) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "kernel bpf filter out of date"); - goto bad; - } + /* + * 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) { + status = check_setif_failure(p, errno); + goto bad; + } + } else { + /* + * No buffer size was explicitly specified. + * + * Try finding a good size for the buffer; 32768 may + * be too big, so keep cutting it in half until we + * find a size that works, or run out of sizes to try. + * If the default is larger, don't make it smaller. + */ + if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || + v < 32768) + v = 32768; + for ( ; v != 0; v >>= 1) { + /* + * Ignore the return value - this is because the + * call fails on BPF systems that don't have + * kernel malloc. And if the call fails, it's + * no big deal, we just continue to use the + * standard buffer size. + */ + (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v); - /* - * Try finding a good size for the buffer; 32768 may be too - * big, so keep cutting it in half until we find a size - * that works, or run out of sizes to try. If the default - * is larger, don't make it smaller. - * - * XXX - there should be a user-accessible hook to set the - * initial buffer size. - */ - if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || v < 32768) - v = 32768; - for ( ; v != 0; v >>= 1) { - /* Ignore the return value - this is because the call fails - * on BPF systems that don't have kernel malloc. And if - * the call fails, it's no big deal, we just continue to - * use the standard buffer size. - */ - (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v); + (void)strncpy(ifr.ifr_name, p->opt.source, + sizeof(ifr.ifr_name)); + if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) + break; /* that size worked; we're done */ - (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) - break; /* that size worked; we're done */ + if (errno != ENOBUFS) { + status = check_setif_failure(p, errno); + goto bad; + } + } - if (errno != ENOBUFS) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s", - device, pcap_strerror(errno)); - goto bad; + if (v == 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "BIOCSBLEN: %s: No buffer size worked", + p->opt.source); + status = PCAP_ERROR; + goto bad; + } } } - if (v == 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "BIOCSBLEN: %s: No buffer size worked", device); - goto bad; - } - /* Get the data link layer type. */ if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s", + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s", pcap_strerror(errno)); + status = PCAP_ERROR; goto bad; } + #ifdef _AIX /* * AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT. @@ -713,8 +1632,9 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, /* * We don't know what to map this to yet. */ - snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown interface type %u", + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown interface type %u", v); + status = PCAP_ERROR; goto bad; } #endif @@ -739,13 +1659,6 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, break; } #endif -#ifdef PCAP_FDDIPAD - if (v == DLT_FDDI) - p->fddipad = PCAP_FDDIPAD; - else - p->fddipad = 0; -#endif - p->linktype = v; #ifdef BIOCGDLTLIST /* @@ -753,68 +1666,144 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, * this interface supports. If this fails with EINVAL, it's * not fatal; we just don't get to use the feature later. */ - if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) == 0) { - u_int i; - int is_ethernet; + if (get_dlt_list(fd, v, &bdl, p->errbuf) == -1) { + status = PCAP_ERROR; + goto bad; + } + p->dlt_count = bdl.bfl_len; + p->dlt_list = bdl.bfl_list; - bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * (bdl.bfl_len + 1)); - if (bdl.bfl_list == NULL) { - (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", - pcap_strerror(errno)); - goto bad; +#ifdef __APPLE__ + /* + * Monitor mode fun, continued. + * + * For 10.5 and, we're assuming, later releases, as noted above, + * 802.1 adapters that support monitor mode offer both DLT_EN10MB, + * DLT_IEEE802_11, and possibly some 802.11-plus-radio-information + * DLT_ value. Choosing one of the 802.11 DLT_ values will turn + * monitor mode on. + * + * Therefore, if the user asked for monitor mode, we filter out + * the DLT_EN10MB value, as you can't get that in monitor mode, + * and, if the user didn't ask for monitor mode, we filter out + * the 802.11 DLT_ values, because selecting those will turn + * monitor mode on. Then, for monitor mode, if an 802.11-plus- + * radio DLT_ value is offered, we try to select that, otherwise + * we try to select DLT_IEEE802_11. + */ + if (have_osinfo) { + if (isdigit((unsigned)osinfo.release[0]) && + (osinfo.release[0] == '9' || + isdigit((unsigned)osinfo.release[1]))) { + /* + * 10.5 (Darwin 9.x), or later. + */ + new_dlt = find_802_11(&bdl); + if (new_dlt != -1) { + /* + * We have at least one 802.11 DLT_ value, + * so this is an 802.11 interface. + * new_dlt is the best of the 802.11 + * DLT_ values in the list. + */ + if (p->opt.rfmon) { + /* + * Our caller wants monitor mode. + * Purge DLT_EN10MB from the list + * of link-layer types, as selecting + * it will keep monitor mode off. + */ + remove_en(p); + + /* + * If the new mode we want isn't + * the default mode, attempt to + * select the new mode. + */ + if (new_dlt != v) { + if (ioctl(p->fd, BIOCSDLT, + &new_dlt) != -1) { + /* + * We succeeded; + * make this the + * new DLT_ value. + */ + v = new_dlt; + } + } + } else { + /* + * Our caller doesn't want + * monitor mode. Unless this + * is being done by pcap_open_live(), + * purge the 802.11 link-layer types + * from the list, as selecting + * one of them will turn monitor + * mode on. + */ + if (!p->oldstyle) + remove_802_11(p); + } + } else { + if (p->opt.rfmon) { + /* + * The caller requested monitor + * mode, but we have no 802.11 + * link-layer types, so they + * can't have it. + */ + status = PCAP_ERROR_RFMON_NOTSUP; + goto bad; + } + } } - - if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) < 0) { - (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, - "BIOCGDLTLIST: %s", pcap_strerror(errno)); - free(bdl.bfl_list); + } +#elif defined(HAVE_BSD_IEEE80211) + /* + * *BSD with the new 802.11 ioctls. + * Do we want monitor mode? + */ + if (p->opt.rfmon) { + /* + * Try to put the interface into monitor mode. + */ + status = monitor_mode(p, 1); + if (status != 0) { + /* + * We failed. + */ goto bad; } /* - * OK, for real Ethernet devices, add DLT_DOCSIS to the - * list, so that an application can let you choose it, - * in case you're capturing DOCSIS traffic that a Cisco - * Cable Modem Termination System is putting out onto - * an Ethernet (it doesn't put an Ethernet header onto - * the wire, it puts raw DOCSIS frames out on the wire - * inside the low-level Ethernet framing). - * - * A "real Ethernet device" is defined here as a device - * that has a link-layer type of DLT_EN10MB and that has - * no alternate link-layer types; that's done to exclude - * 802.11 interfaces (which might or might not be the - * right thing to do, but I suspect it is - Ethernet <-> - * 802.11 bridges would probably badly mishandle frames - * that don't have Ethernet headers). + * We're in monitor mode. + * Try to find the best 802.11 DLT_ value and, if we + * succeed, try to switch to that mode if we're not + * already in that mode. */ - if (p->linktype == DLT_EN10MB) { - is_ethernet = 1; - for (i = 0; i < bdl.bfl_len; i++) { - if (bdl.bfl_list[i] != DLT_EN10MB) { - is_ethernet = 0; - break; + new_dlt = find_802_11(&bdl); + if (new_dlt != -1) { + /* + * We have at least one 802.11 DLT_ value. + * new_dlt is the best of the 802.11 + * DLT_ values in the list. + * + * If the new mode we want isn't the default mode, + * attempt to select the new mode. + */ + if (new_dlt != v) { + if (ioctl(p->fd, BIOCSDLT, &new_dlt) != -1) { + /* + * We succeeded; make this the + * new DLT_ value. + */ + v = new_dlt; } } - if (is_ethernet) { - /* - * We reserved one more slot at the end of - * the list. - */ - bdl.bfl_list[bdl.bfl_len] = DLT_DOCSIS; - bdl.bfl_len++; - } - } - p->dlt_count = bdl.bfl_len; - p->dlt_list = bdl.bfl_list; - } else { - if (errno != EINVAL) { - (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, - "BIOCGDLTLIST: %s", pcap_strerror(errno)); - goto bad; } } -#endif +#endif /* various platforms */ +#endif /* BIOCGDLTLIST */ /* * If this is an Ethernet device, and we don't have a DLT_ list, @@ -824,7 +1813,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, * some other way of determining whether it's an Ethernet or 802.11 * device.) */ - if (p->linktype == DLT_EN10MB && p->dlt_count == 0) { + if (v == DLT_EN10MB && p->dlt_count == 0) { p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); /* * If that fails, just leave the list empty. @@ -835,7 +1824,14 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, p->dlt_count = 2; } } - +#ifdef PCAP_FDDIPAD + if (v == DLT_FDDI) + p->fddipad = PCAP_FDDIPAD; + else + p->fddipad = 0; +#endif + p->linktype = v; + #if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) /* * Do a BIOCSHDRCMPLT, if defined, to turn that flag on, so @@ -847,24 +1843,30 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, * BSDs - check CVS log for "bpf.c"? */ if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) { - (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, + (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSHDRCMPLT: %s", pcap_strerror(errno)); + status = PCAP_ERROR; goto bad; } #endif /* set timeout */ - if (to_ms != 0) { +#ifdef HAVE_ZEROCOPY_BPF + if (p->md.timeout != 0 && !p->md.zerocopy) { +#else + if (p->md.timeout) { +#endif /* * XXX - is this seconds/nanoseconds in AIX? * (Treating it as such doesn't fix the timeout * problem described below.) */ struct timeval to; - to.tv_sec = to_ms / 1000; - to.tv_usec = (to_ms * 1000) % 1000000; + to.tv_sec = p->md.timeout / 1000; + to.tv_usec = (p->md.timeout * 1000) % 1000000; if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s", + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s", pcap_strerror(errno)); + status = PCAP_ERROR; goto bad; } } @@ -919,38 +1921,48 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, */ v = 1; if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s", + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s", pcap_strerror(errno)); + status = PCAP_ERROR; goto bad; } #endif /* BIOCIMMEDIATE */ #endif /* _AIX */ - if (promisc) { - /* set promiscuous mode, okay if it fails */ + if (p->opt.promisc) { + /* set promiscuous mode, just warn if it fails */ if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s", + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s", pcap_strerror(errno)); + status = PCAP_WARNING_PROMISC_NOTSUP; } } if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s", + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s", pcap_strerror(errno)); + status = PCAP_ERROR; goto bad; } p->bufsize = v; +#ifdef HAVE_ZEROCOPY_BPF + if (!p->md.zerocopy) { +#endif p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); + status = PCAP_ERROR; goto bad; } #ifdef _AIX - /* For some strange reason this seems to prevent the EFAULT + /* For some strange reason this seems to prevent the EFAULT * problems we have experienced from AIX BPF. */ memset(p->buffer, 0x0, p->bufsize); #endif +#ifdef HAVE_ZEROCOPY_BPF + } +#endif /* * If there's no filter program installed, there's @@ -964,13 +1976,14 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, total_insn.code = (u_short)(BPF_RET | BPF_K); total_insn.jt = 0; total_insn.jf = 0; - total_insn.k = snaplen; + total_insn.k = p->snapshot; total_prog.bf_len = 1; total_prog.bf_insns = &total_insn; if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s", + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s", pcap_strerror(errno)); + status = PCAP_ERROR; goto bad; } @@ -1011,7 +2024,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, * XXX - what about AIX? */ p->selectable_fd = p->fd; /* assume select() works until we know otherwise */ - if (uname(&osinfo) == 0) { + if (have_osinfo) { /* * We can check what OS this is. */ @@ -1030,15 +2043,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, p->getnonblock_op = pcap_getnonblock_fd; p->setnonblock_op = pcap_setnonblock_fd; p->stats_op = pcap_stats_bpf; - p->close_op = pcap_close_common; + p->cleanup_op = pcap_cleanup_bpf; - return (p); + return (status); bad: - (void)close(fd); - if (p->dlt_list != NULL) - free(p->dlt_list); - free(p); - return (NULL); + pcap_cleanup_bpf(p); + return (status); } int @@ -1052,24 +2062,313 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) return (0); } +#ifdef HAVE_BSD_IEEE80211 static int -pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp) +monitor_mode(pcap_t *p, int set) { + int sock; + struct ifmediareq req; + int *media_list; + int i; + int can_do; + struct ifreq ifr; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't open socket: %s", + pcap_strerror(errno)); + return (PCAP_ERROR); + } + + memset(&req, 0, sizeof req); + strncpy(req.ifm_name, p->opt.source, sizeof req.ifm_name); + /* - * It looks that BPF code generated by gen_protochain() is not - * compatible with some of kernel BPF code (for example BSD/OS 3.1). - * Take a safer side for now. + * Find out how many media types we have. */ - if (no_optimize) { + if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) { /* - * XXX - what if we already have a filter in the kernel? + * Can't get the media types. */ - if (install_bpf_program(p, fp) < 0) - return (-1); - p->md.use_bpf = 0; /* filtering in userland */ - return (0); + if (errno == EINVAL) { + /* + * Interface doesn't support SIOC{G,S}IFMEDIA. + */ + close(sock); + return (PCAP_ERROR_RFMON_NOTSUP); + } + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMEDIA 1: %s", + pcap_strerror(errno)); + close(sock); + return (PCAP_ERROR); + } + if (req.ifm_count == 0) { + /* + * No media types. + */ + close(sock); + return (PCAP_ERROR_RFMON_NOTSUP); + } + + /* + * Allocate a buffer to hold all the media types, and + * get the media types. + */ + media_list = malloc(req.ifm_count * sizeof(int)); + if (media_list == NULL) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + close(sock); + return (PCAP_ERROR); + } + req.ifm_ulist = media_list; + if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMEDIA: %s", + pcap_strerror(errno)); + free(media_list); + close(sock); + return (PCAP_ERROR); + } + + /* + * Look for an 802.11 "automatic" media type. + * We assume that all 802.11 adapters have that media type, + * and that it will carry the monitor mode supported flag. + */ + can_do = 0; + for (i = 0; i < req.ifm_count; i++) { + if (IFM_TYPE(media_list[i]) == IFM_IEEE80211 + && IFM_SUBTYPE(media_list[i]) == IFM_AUTO) { + /* OK, does it do monitor mode? */ + if (media_list[i] & IFM_IEEE80211_MONITOR) { + can_do = 1; + break; + } + } + } + free(media_list); + if (!can_do) { + /* + * This adapter doesn't support monitor mode. + */ + close(sock); + return (PCAP_ERROR_RFMON_NOTSUP); + } + + if (set) { + /* + * Don't just check whether we can enable monitor mode, + * do so, if it's not already enabled. + */ + if ((req.ifm_current & IFM_IEEE80211_MONITOR) == 0) { + /* + * Monitor mode isn't currently on, so turn it on, + * and remember that we should turn it off when the + * pcap_t is closed. + */ + + /* + * If we haven't already done so, arrange to have + * "pcap_close_all()" called when we exit. + */ + if (!pcap_do_addexit(p)) { + /* + * "atexit()" failed; don't put the interface + * in monitor mode, just give up. + */ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "atexit failed"); + close(sock); + return (PCAP_ERROR); + } + memset(&ifr, 0, sizeof(ifr)); + (void)strncpy(ifr.ifr_name, p->opt.source, + sizeof(ifr.ifr_name)); + ifr.ifr_media = req.ifm_current | IFM_IEEE80211_MONITOR; + if (ioctl(sock, SIOCSIFMEDIA, &ifr) == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "SIOCSIFMEDIA: %s", pcap_strerror(errno)); + close(sock); + return (PCAP_ERROR); + } + + p->md.must_clear |= MUST_CLEAR_RFMON; + + /* + * Add this to the list of pcaps to close when we exit. + */ + pcap_add_to_pcaps_to_close(p); + } + } + return (0); +} +#endif /* HAVE_BSD_IEEE80211 */ + +#if defined(BIOCGDLTLIST) && (defined(__APPLE__) || defined(HAVE_BSD_IEEE80211)) +/* + * Check whether we have any 802.11 link-layer types; return the best + * of the 802.11 link-layer types if we find one, and return -1 + * otherwise. + * + * DLT_IEEE802_11_RADIO, with the radiotap header, is considered the + * best 802.11 link-layer type; any of the other 802.11-plus-radio + * headers are second-best; 802.11 with no radio information is + * the least good. + */ +static int +find_802_11(struct bpf_dltlist *bdlp) +{ + int new_dlt; + int i; + + /* + * Scan the list of DLT_ values, looking for 802.11 values, + * and, if we find any, choose the best of them. + */ + new_dlt = -1; + for (i = 0; i < bdlp->bfl_len; i++) { + switch (bdlp->bfl_list[i]) { + + case DLT_IEEE802_11: + /* + * 802.11, but no radio. + * + * Offer this, and select it as the new mode + * unless we've already found an 802.11 + * header with radio information. + */ + if (new_dlt == -1) + new_dlt = bdlp->bfl_list[i]; + break; + + case DLT_PRISM_HEADER: + case DLT_AIRONET_HEADER: + case DLT_IEEE802_11_RADIO_AVS: + /* + * 802.11 with radio, but not radiotap. + * + * Offer this, and select it as the new mode + * unless we've already found the radiotap DLT_. + */ + if (new_dlt != DLT_IEEE802_11_RADIO) + new_dlt = bdlp->bfl_list[i]; + break; + + case DLT_IEEE802_11_RADIO: + /* + * 802.11 with radiotap. + * + * Offer this, and select it as the new mode. + */ + new_dlt = bdlp->bfl_list[i]; + break; + + default: + /* + * Not 802.11. + */ + break; + } + } + + return (new_dlt); +} +#endif /* defined(BIOCGDLTLIST) && (defined(__APPLE__) || defined(HAVE_BSD_IEEE80211)) */ + +#if defined(__APPLE__) && defined(BIOCGDLTLIST) +/* + * Remove DLT_EN10MB from the list of DLT_ values. + */ +static void +remove_en(pcap_t *p) +{ + int i, j; + + /* + * Scan the list of DLT_ values and discard DLT_EN10MB. + */ + j = 0; + for (i = 0; i < p->dlt_count; i++) { + switch (p->dlt_list[i]) { + + case DLT_EN10MB: + /* + * Don't offer this one. + */ + continue; + + default: + /* + * Just copy this mode over. + */ + break; + } + + /* + * Copy this DLT_ value to its new position. + */ + p->dlt_list[j] = p->dlt_list[i]; + j++; + } + + /* + * Set the DLT_ count to the number of entries we copied. + */ + p->dlt_count = j; +} + +/* + * Remove DLT_EN10MB from the list of DLT_ values, and look for the + * best 802.11 link-layer type in that list and return it. + * Radiotap is better than anything else; 802.11 with any other radio + * header is better than 802.11 with no radio header. + */ +static void +remove_802_11(pcap_t *p) +{ + int i, j; + + /* + * Scan the list of DLT_ values and discard 802.11 values. + */ + j = 0; + for (i = 0; i < p->dlt_count; i++) { + switch (p->dlt_list[i]) { + + case DLT_IEEE802_11: + case DLT_PRISM_HEADER: + case DLT_AIRONET_HEADER: + case DLT_IEEE802_11_RADIO: + case DLT_IEEE802_11_RADIO_AVS: + /* + * 802.11. Don't offer this one. + */ + continue; + + default: + /* + * Just copy this mode over. + */ + break; + } + + /* + * Copy this DLT_ value to its new position. + */ + p->dlt_list[j] = p->dlt_list[i]; + j++; } + /* + * Set the DLT_ count to the number of entries we copied. + */ + p->dlt_count = j; +} +#endif /* defined(__APPLE__) && defined(BIOCGDLTLIST) */ + +static int +pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp) +{ /* * Free any user-mode filter we might happen to have installed. */ @@ -1078,20 +2377,51 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp) /* * Try to install the kernel filter. */ - if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { + if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) == 0) { + /* + * It worked. + */ + p->md.use_bpf = 1; /* filtering in the kernel */ + + /* + * Discard any previously-received packets, as they might + * have passed whatever filter was formerly in effect, but + * might not pass this filter (BIOCSETF discards packets + * buffered in the kernel, so you can lose packets in any + * case). + */ + p->cc = 0; + return (0); + } + + /* + * We failed. + * + * If it failed with EINVAL, that's probably because the program + * is invalid or too big. Validate it ourselves; if we like it + * (we currently allow backward branches, to support protochain), + * run it in userland. (There's no notion of "too big" for + * userland.) + * + * Otherwise, just give up. + * XXX - if the copy of the program into the kernel failed, + * we will get EINVAL rather than, say, EFAULT on at least + * some kernels. + */ + if (errno != EINVAL) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s", pcap_strerror(errno)); return (-1); } - p->md.use_bpf = 1; /* filtering in the kernel */ /* - * Discard any previously-received packets, as they might have - * passed whatever filter was formerly in effect, but might - * not pass this filter (BIOCSETF discards packets buffered - * in the kernel, so you can lose packets in any case). + * install_bpf_program() validates the program. + * + * XXX - what if we already have a filter in the kernel? */ - p->cc = 0; + if (install_bpf_program(p, fp) < 0) + return (-1); + p->md.use_bpf = 0; /* filtering in userland */ return (0); } diff --git a/contrib/libpcap/pcap-bpf.h b/contrib/libpcap/pcap-bpf.h deleted file mode 100644 index 62c493b276..0000000000 --- a/contrib/libpcap/pcap-bpf.h +++ /dev/null @@ -1,834 +0,0 @@ -/*- - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from the Stanford/CMU enet packet filter, - * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence - * Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)bpf.h 7.1 (Berkeley) 5/7/91 - * - * @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.34.2.24 2007/09/19 02:52:12 guy Exp $ (LBL) - */ - -/* - * This is libpcap's cut-down version of bpf.h; it includes only - * the stuff needed for the code generator and the userland BPF - * interpreter, and the libpcap APIs for setting filters, etc.. - * - * "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"? - */ - -#ifndef BPF_MAJOR_VERSION - -#ifdef __cplusplus -extern "C" { -#endif - -/* BSD style release date */ -#define BPF_RELEASE 199606 - -#ifdef MSDOS /* must be 32-bit */ -typedef long bpf_int32; -typedef unsigned long bpf_u_int32; -#else -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif - -/* - * Alignment macros. BPF_WORDALIGN rounds up to the next - * even multiple of BPF_ALIGNMENT. - */ -#ifndef __NetBSD__ -#define BPF_ALIGNMENT sizeof(bpf_int32) -#else -#define BPF_ALIGNMENT sizeof(long) -#endif -#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) - -#define BPF_MAXINSNS 512 -#define BPF_MAXBUFSIZE 0x8000 -#define BPF_MINBUFSIZE 32 - -/* - * Structure for "pcap_compile()", "pcap_setfilter()", etc.. - */ -struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; -}; - -/* - * 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. - * - * Do *NOT* add new values to this list without asking - * "tcpdump-workers@tcpdump.org" for a value. Otherwise, you run the - * risk of using a value that's already being used for some other purpose, - * and of having tools that read libpcap-format captures not 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). - */ - -/* - * These are the types that are the same on all platforms, and that - * have been defined by for ages. - */ -#define DLT_NULL 0 /* BSD loopback encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* 802.5 Token Ring */ -#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ - -/* - * These are types that are different on some platforms, and that - * have been defined by for ages. We use #ifdefs to - * detect the BSDs that define them differently from the traditional - * libpcap - * - * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, - * but I don't know what the right #define is for BSD/OS. - */ -#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ - -#ifdef __OpenBSD__ -#define DLT_RAW 14 /* raw IP */ -#else -#define DLT_RAW 12 /* raw IP */ -#endif - -/* - * Given that the only OS that currently generates BSD/OS SLIP or PPP - * is, well, BSD/OS, arguably everybody should have chosen its values - * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they - * didn't. So it goes. - */ -#if defined(__NetBSD__) || defined(__FreeBSD__) -#ifndef DLT_SLIP_BSDOS -#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ -#endif -#else -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#endif - -/* - * 17 is used for DLT_OLD_PFLOG in OpenBSD; - * OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below. - * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else. - */ - -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ - -/* - * Apparently Redback uses this for its SmartEdge 400/800. I hope - * nobody else decided to use it, too. - */ -#define DLT_REDBACK_SMARTEDGE 32 - -/* - * These values are defined by NetBSD; other platforms should refrain from - * using them for other purposes, so that NetBSD savefiles with link - * types of 50 or 51 can be read as this type on all platforms. - */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ - -/* - * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses - * a link-layer type of 99 for the tcpdump it supplies. The link-layer - * header has 6 bytes of unknown data, something that appears to be an - * Ethernet type, and 36 bytes that appear to be 0 in at least one capture - * I've seen. - */ -#define DLT_SYMANTEC_FIREWALL 99 - -/* - * 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. - */ - -/* - * This value was defined by libpcap 0.5; platforms that have defined - * it with a different value should define it here with that value - - * a link type of 104 in a save file will be mapped to DLT_C_HDLC, - * whatever value that happens to be, so programs will correctly - * handle files with that link type regardless of the value of - * DLT_C_HDLC. - * - * The name DLT_C_HDLC was used by BSD/OS; we use that name for source - * compatibility with programs written for BSD/OS. - * - * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, - * for source compatibility with programs written for libpcap 0.5. - */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC - -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ - -/* - * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, - * except when it isn't. (I.e., sometimes it's just raw IP, and - * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, - * so that we don't have to worry about the link-layer header.) - */ - -/* - * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides - * with other values. - * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header - * (DLCI, etc.). - */ -#define DLT_FRELAY 107 - -/* - * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except - * that the AF_ type in the link-layer header is in network byte order. - * - * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so - * we don't use 12 for it in OSes other than OpenBSD. - */ -#ifdef __OpenBSD__ -#define DLT_LOOP 12 -#else -#define DLT_LOOP 108 -#endif - -/* - * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's - * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other - * than OpenBSD. - */ -#ifdef __OpenBSD__ -#define DLT_ENC 13 -#else -#define DLT_ENC 109 -#endif - -/* - * Values between 110 and 112 are reserved for use in capture file headers - * as link-layer types corresponding to DLT_ types that might differ - * between platforms; don't use those values for new DLT_ types - * other than the corresponding DLT_ types. - */ - -/* - * This is for Linux cooked sockets. - */ -#define DLT_LINUX_SLL 113 - -/* - * Apple LocalTalk hardware. - */ -#define DLT_LTALK 114 - -/* - * Acorn Econet. - */ -#define DLT_ECONET 115 - -/* - * Reserved for use with OpenBSD ipfilter. - */ -#define DLT_IPFILTER 116 - -/* - * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023 - * in SuSE 6.3, so we can't use 17 for it in capture-file headers. - * - * XXX: is there a conflict with DLT_PFSYNC 18 as well? - */ -#ifdef __OpenBSD__ -#define DLT_OLD_PFLOG 17 -#define DLT_PFSYNC 18 -#endif -#define DLT_PFLOG 117 - -/* - * Registered for Cisco-internal use. - */ -#define DLT_CISCO_IOS 118 - -/* - * For 802.11 cards using the Prism II chips, with a link-layer - * header including Prism monitor mode information plus an 802.11 - * header. - */ -#define DLT_PRISM_HEADER 119 - -/* - * Reserved for Aironet 802.11 cards, with an Aironet link-layer header - * (see Doug Ambrisko's FreeBSD patches). - */ -#define DLT_AIRONET_HEADER 120 - -/* - * Reserved for Siemens HiPath HDLC. - */ -#define DLT_HHDLC 121 - -/* - * This is for RFC 2625 IP-over-Fibre Channel. - * - * This is not for use with raw Fibre Channel, where the link-layer - * header starts with a Fibre Channel frame header; it's for IP-over-FC, - * where the link-layer header starts with an RFC 2625 Network_Header - * field. - */ -#define DLT_IP_OVER_FC 122 - -/* - * This is for Full Frontal ATM on Solaris with SunATM, with a - * pseudo-header followed by an AALn PDU. - * - * There may be other forms of Full Frontal ATM on other OSes, - * with different pseudo-headers. - * - * If ATM software returns a pseudo-header with VPI/VCI information - * (and, ideally, packet type information, e.g. signalling, ILMI, - * LANE, LLC-multiplexed traffic, etc.), it should not use - * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump - * and the like don't have to infer the presence or absence of a - * pseudo-header and the form of the pseudo-header. - */ -#define DLT_SUNATM 123 /* Solaris+SunATM */ - -/* - * Reserved as per request from Kent Dahlgren - * for private use. - */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ - -/* - * Header for 802.11 plus a number of bits of link-layer information - * including radio information, used by some recent BSD drivers as - * well as the madwifi Atheros driver for Linux. - */ -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ - -/* - * Reserved for the TZSP encapsulation, as per request from - * Chris Waters - * TZSP is a generic encapsulation for any other link type, - * which includes a means to include meta-information - * with the packet, e.g. signal strength and channel - * for 802.11 packets. - */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ - -/* - * BSD's ARCNET headers have the source host, destination host, - * and type at the beginning of the packet; that's what's handed - * up to userland via BPF. - * - * Linux's ARCNET headers, however, have a 2-byte offset field - * between the host IDs and the type; that's what's handed up - * to userland via PF_PACKET sockets. - * - * We therefore have to have separate DLT_ values for them. - */ -#define DLT_ARCNET_LINUX 129 /* ARCNET */ - -/* - * Juniper-private data link types, as per request from - * Hannes Gredler . The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, etc.. - */ -#define DLT_JUNIPER_MLPPP 130 -#define DLT_JUNIPER_MLFR 131 -#define DLT_JUNIPER_ES 132 -#define DLT_JUNIPER_GGSN 133 -#define DLT_JUNIPER_MFR 134 -#define DLT_JUNIPER_ATM2 135 -#define DLT_JUNIPER_SERVICES 136 -#define DLT_JUNIPER_ATM1 137 - -/* - * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund - * . The header that's presented is an Ethernet-like - * header: - * - * #define FIREWIRE_EUI64_LEN 8 - * struct firewire_header { - * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; - * u_char firewire_shost[FIREWIRE_EUI64_LEN]; - * u_short firewire_type; - * }; - * - * with "firewire_type" being an Ethernet type value, rather than, - * for example, raw GASP frames being handed up. - */ -#define DLT_APPLE_IP_OVER_IEEE1394 138 - -/* - * Various SS7 encapsulations, as per a request from Jeff Morriss - * and subsequent discussions. - */ -#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ -#define DLT_MTP2 140 /* MTP2, without pseudo-header */ -#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ -#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ - -/* - * DOCSIS MAC frames. - */ -#define DLT_DOCSIS 143 - -/* - * Linux-IrDA packets. Protocol defined at http://www.irda.org. - * Those packets include IrLAP headers and above (IrLMP...), but - * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy - * framing can be handled by the hardware and depend on the bitrate. - * This is exactly the format you would get capturing on a Linux-IrDA - * interface (irdaX), but not on a raw serial port. - * Note the capture is done in "Linux-cooked" mode, so each packet include - * a fake packet header (struct sll_header). This is because IrDA packet - * decoding is dependant on the direction of the packet (incomming or - * outgoing). - * When/if other platform implement IrDA capture, we may revisit the - * issue and define a real DLT_IRDA... - * Jean II - */ -#define DLT_LINUX_IRDA 144 - -/* - * Reserved for IBM SP switch and IBM Next Federation switch. - */ -#define DLT_IBM_SP 145 -#define DLT_IBM_SN 146 - -/* - * Reserved for private use. If you have some link-layer header type - * that you want to use within your organization, with the capture files - * using that link-layer header type not ever be sent outside your - * organization, you can use these values. - * - * No libpcap release will use these for any purpose, nor will any - * tcpdump release use them, either. - * - * Do *NOT* use these in capture files that you expect anybody not using - * your private versions of capture-file-reading tools to read; in - * particular, do *NOT* use them in products, otherwise you may find that - * people won't be able to use tcpdump, or snort, or Ethereal, or... to - * read capture files from your firewall/intrusion detection/traffic - * monitoring/etc. appliance, or whatever product uses that DLT_ value, - * and you may also find that the developers of those applications will - * not accept patches to let them read those files. - * - * Also, do not use them if somebody might send you a capture using them - * for *their* private type and tools using them for *your* private type - * would have to read them. - * - * Instead, ask "tcpdump-workers@tcpdump.org" for a new DLT_ value, - * as per the comment above, and use the type you're given. - */ -#define DLT_USER0 147 -#define DLT_USER1 148 -#define DLT_USER2 149 -#define DLT_USER3 150 -#define DLT_USER4 151 -#define DLT_USER5 152 -#define DLT_USER6 153 -#define DLT_USER7 154 -#define DLT_USER8 155 -#define DLT_USER9 156 -#define DLT_USER10 157 -#define DLT_USER11 158 -#define DLT_USER12 159 -#define DLT_USER13 160 -#define DLT_USER14 161 -#define DLT_USER15 162 - -/* - * For future use with 802.11 captures - defined by AbsoluteValue - * Systems to store a number of bits of link-layer information - * including radio information: - * - * http://www.shaftnet.org/~pizza/software/capturefrm.txt - * - * but it might be used by some non-AVS drivers now or in the - * future. - */ -#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, etc.. - */ -#define DLT_JUNIPER_MONITOR 164 - -/* - * Reserved for BACnet MS/TP. - */ -#define DLT_BACNET_MS_TP 165 - -/* - * Another PPP variant as per request from Karsten Keil . - * - * This is used in some OSes to allow a kernel socket filter to distinguish - * between incoming and outgoing packets, on a socket intended to - * supply pppd with outgoing packets so it can do dial-on-demand and - * hangup-on-lack-of-demand; incoming packets are filtered out so they - * don't cause pppd to hold the connection up (you don't want random - * input packets such as port scans, packets from old lost connections, - * etc. to force the connection to stay up). - * - * The first byte of the PPP header (0xff03) is modified to accomodate - * the direction - 0x00 = IN, 0x01 = OUT. - */ -#define DLT_PPP_PPPD 166 - -/* - * Names for backwards compatibility with older versions of some PPP - * software; new software should use DLT_PPP_PPPD. - */ -#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD -#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, cookies, etc.. - */ -#define DLT_JUNIPER_PPPOE 167 -#define DLT_JUNIPER_PPPOE_ATM 168 - -#define DLT_GPRS_LLC 169 /* GPRS LLC */ -#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ -#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ - -/* - * Requested by Oolan Zimmer for use in Gcom's T1/E1 line - * monitoring equipment. - */ -#define DLT_GCOM_T1E1 172 -#define DLT_GCOM_SERIAL 173 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . The DLT_ is used - * for internal communication to Physical Interface Cards (PIC) - */ -#define DLT_JUNIPER_PIC_PEER 174 - -/* - * Link types requested by Gregor Maier of Endace - * Measurement Systems. They add an ERF header (see - * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of - * the link-layer header. - */ -#define DLT_ERF_ETH 175 /* Ethernet */ -#define DLT_ERF_POS 176 /* Packet-over-SONET */ - -/* - * Requested by Daniele Orlandi for raw LAPD - * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header - * includes additional information before the LAPD header, so it's - * not necessarily a generic LAPD header. - */ -#define DLT_LINUX_LAPD 177 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ are used for prepending meta-information - * like interface index, interface name - * before standard Ethernet, PPP, Frelay & C-HDLC Frames - */ -#define DLT_JUNIPER_ETHER 178 -#define DLT_JUNIPER_PPP 179 -#define DLT_JUNIPER_FRELAY 180 -#define DLT_JUNIPER_CHDLC 181 - -/* - * Multi Link Frame Relay (FRF.16) - */ -#define DLT_MFR 182 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ is used for internal communication with a - * voice Adapter Card (PIC) - */ -#define DLT_JUNIPER_VP 183 - -/* - * Arinc 429 frames. - * DLT_ requested by Gianluca Varenni . - * Every frame contains a 32bit A429 label. - * More documentation on Arinc 429 can be found at - * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf - */ -#define DLT_A429 184 - -/* - * Arinc 653 Interpartition Communication messages. - * DLT_ requested by Gianluca Varenni . - * Please refer to the A653-1 standard for more information. - */ -#define DLT_A653_ICM 185 - -/* - * USB packets, beginning with a USB setup header; requested by - * Paolo Abeni . - */ -#define DLT_USB 186 - -/* - * Bluetooth HCI UART transport layer (part H:4); requested by - * Paolo Abeni. - */ -#define DLT_BLUETOOTH_HCI_H4 187 - -/* - * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz - * . - */ -#define DLT_IEEE802_16_MAC_CPS 188 - -/* - * USB packets, beginning with a Linux USB header; requested by - * Paolo Abeni . - */ -#define DLT_USB_LINUX 189 - -/* - * Controller Area Network (CAN) v. 2.0B packets. - * DLT_ requested by Gianluca Varenni . - * Used to dump CAN packets coming from a CAN Vector board. - * More documentation on the CAN v2.0B frames can be found at - * http://www.can-cia.org/downloads/?269 - */ -#define DLT_CAN20B 190 - -/* - * IEEE 802.15.4, with address fields padded, as is done by Linux - * drivers; requested by Juergen Schimmer. - */ -#define DLT_IEEE802_15_4_LINUX 191 - -/* - * Per Packet Information encapsulated packets. - * DLT_ requested by Gianluca Varenni . - */ -#define DLT_PPI 192 - -/* - * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; - * requested by Charles Clancy. - */ -#define DLT_IEEE802_16_MAC_CPS_RADIO 193 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ is used for internal communication with a - * integrated service module (ISM). - */ -#define DLT_JUNIPER_ISM 194 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing); requested by Mikko Saarnivala . - */ -#define DLT_IEEE802_15_4 195 - -/* - * Various link-layer types, with a pseudo-header, for SITA - * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). - */ -#define DLT_SITA 196 - -/* - * Various link-layer types, with a pseudo-header, for Endace DAG cards; - * encapsulates Endace ERF records. Requested by Stephen Donnelly - * . - */ -#define DLT_ERF 197 - -/* - * Special header prepended to Ethernet packets when capturing from a - * u10 Networks board. Requested by Phil Mulholland - * . - */ -#define DLT_RAIF1 198 - -/* - * IPMB packet for IPMI, beginning with the I2C slave address, followed - * by the netFn and LUN, etc.. Requested by Chanthy Toeung - * . - */ -#define DLT_IPMB 199 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ is used for capturing data on a secure tunnel interface. - */ -#define DLT_JUNIPER_ST 200 - -/* - * Bluetooth HCI UART transport layer (part H:4), with pseudo-header - * that includes direction information; requested by Paolo Abeni. - */ -#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 - - -/* - * The instruction encodings. - */ -/* instruction classes */ -#define BPF_CLASS(code) ((code) & 0x07) -#define BPF_LD 0x00 -#define BPF_LDX 0x01 -#define BPF_ST 0x02 -#define BPF_STX 0x03 -#define BPF_ALU 0x04 -#define BPF_JMP 0x05 -#define BPF_RET 0x06 -#define BPF_MISC 0x07 - -/* ld/ldx fields */ -#define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 -#define BPF_MODE(code) ((code) & 0xe0) -#define BPF_IMM 0x00 -#define BPF_ABS 0x20 -#define BPF_IND 0x40 -#define BPF_MEM 0x60 -#define BPF_LEN 0x80 -#define BPF_MSH 0xa0 - -/* alu/jmp fields */ -#define BPF_OP(code) ((code) & 0xf0) -#define BPF_ADD 0x00 -#define BPF_SUB 0x10 -#define BPF_MUL 0x20 -#define BPF_DIV 0x30 -#define BPF_OR 0x40 -#define BPF_AND 0x50 -#define BPF_LSH 0x60 -#define BPF_RSH 0x70 -#define BPF_NEG 0x80 -#define BPF_JA 0x00 -#define BPF_JEQ 0x10 -#define BPF_JGT 0x20 -#define BPF_JGE 0x30 -#define BPF_JSET 0x40 -#define BPF_SRC(code) ((code) & 0x08) -#define BPF_K 0x00 -#define BPF_X 0x08 - -/* ret - BPF_K and BPF_X also apply */ -#define BPF_RVAL(code) ((code) & 0x18) -#define BPF_A 0x10 - -/* misc */ -#define BPF_MISCOP(code) ((code) & 0xf8) -#define BPF_TAX 0x00 -#define BPF_TXA 0x80 - -/* - * The instruction data structure. - */ -struct bpf_insn { - u_short code; - u_char jt; - u_char jf; - bpf_int32 k; -}; - -/* - * Macros for insn array initializers. - */ -#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } -#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } - -#if __STDC__ || defined(__cplusplus) -extern int bpf_validate(struct bpf_insn *, int); -extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); -#else -extern int bpf_validate(); -extern u_int bpf_filter(); -#endif - -/* - * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). - */ -#define BPF_MEMWORDS 16 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/contrib/libpcap/pcap-filter.manmisc.in b/contrib/libpcap/pcap-filter.manmisc.in new file mode 100644 index 0000000000..3beec58029 --- /dev/null +++ b/contrib/libpcap/pcap-filter.manmisc.in @@ -0,0 +1,949 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap-filter.manmisc.in,v 1.1.2.2 2008-10-21 07:44:56 guy Exp $ (LBL) +.\" +.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997 +.\" The Regents of the University of California. All rights reserved. +.\" 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-FILTER @MAN_MISC_INFO@ "6 January 2008" +.SH NAME +pcap-filter \- packet filter syntax +.br +.ad +.SH DESCRIPTION +.LP +.B pcap_compile() +is used to compile a string into a filter program. +The resulting filter program can then be applied to +some stream of packets to determine which packets will be supplied to +.BR pcap_loop() , +.BR pcap_dispatch() , +.BR pcap_next() , +or +.BR pcap_next_ex() . +.LP +The \fIfilter expression\fP consists of one or more +.IR primitives . +Primitives usually consist of an +.I id +(name or number) preceded by one or more qualifiers. +There are three +different kinds of qualifier: +.IP \fItype\fP +qualifiers say what kind of thing the id name or number refers to. +Possible types are +.BR host , +.B net , +.B port +and +.BR portrange . +E.g., `host foo', `net 128.3', `port 20', `portrange 6000-6008'. +If there is no type +qualifier, +.B host +is assumed. +.IP \fIdir\fP +qualifiers specify a particular transfer direction to and/or from +.IR id . +Possible directions are +.BR src , +.BR dst , +.BR "src or dst" , +.BR "src and dst" , +.BR addr1 , +.BR addr2 , +.BR addr3 , +and +.BR addr4 . +E.g., `src foo', `dst net 128.3', `src or dst port ftp-data'. +If +there is no dir qualifier, +.B "src or dst" +is assumed. +The +.BR addr1 , +.BR addr2 , +.BR addr3 , +and +.B addr4 +qualifiers are only valid for IEEE 802.11 Wireless LAN link layers. +For some link layers, such as SLIP and the ``cooked'' Linux capture mode +used for the ``any'' device and for some other device types, the +.B inbound +and +.B outbound +qualifiers can be used to specify a desired direction. +.IP \fIproto\fP +qualifiers restrict the match to a particular protocol. +Possible +protos are: +.BR ether , +.BR fddi , +.BR tr , +.BR wlan , +.BR ip , +.BR ip6 , +.BR arp , +.BR rarp , +.BR decnet , +.B tcp +and +.BR udp . +E.g., `ether src foo', `arp net 128.3', `tcp port 21', `udp portrange +7000-7009', `wlan addr2 0:2:3:4:5:6'. +If there is +no proto qualifier, all protocols consistent with the type are +assumed. +E.g., `src foo' means `(ip or arp or rarp) src foo' +(except the latter is not legal syntax), `net bar' means `(ip or +arp or rarp) net bar' and `port 53' means `(tcp or udp) port 53'. +.LP +[`fddi' is actually an alias for `ether'; the parser treats them +identically as meaning ``the data link level used on the specified +network interface.'' FDDI headers contain Ethernet-like source +and destination addresses, and often contain Ethernet-like packet +types, so you can filter on these FDDI fields just as with the +analogous Ethernet fields. +FDDI headers also contain other fields, +but you cannot name them explicitly in a filter expression. +.LP +Similarly, `tr' and `wlan' are aliases for `ether'; the previous +paragraph's statements about FDDI headers also apply to Token Ring +and 802.11 wireless LAN headers. For 802.11 headers, the destination +address is the DA field and the source address is the SA field; the +BSSID, RA, and TA fields aren't tested.] +.LP +In addition to the above, there are some special `primitive' keywords +that don't follow the pattern: +.BR gateway , +.BR broadcast , +.BR less , +.B greater +and arithmetic expressions. +All of these are described below. +.LP +More complex filter expressions are built up by using the words +.BR and , +.B or +and +.B not +to combine primitives. +E.g., `host foo and not port ftp and not port ftp-data'. +To save typing, identical qualifier lists can be omitted. +E.g., +`tcp dst port ftp or ftp-data or domain' is exactly the same as +`tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'. +.LP +Allowable primitives are: +.IP "\fBdst host \fIhost\fR" +True if the IPv4/v6 destination field of the packet is \fIhost\fP, +which may be either an address or a name. +.IP "\fBsrc host \fIhost\fR" +True if the IPv4/v6 source field of the packet is \fIhost\fP. +.IP "\fBhost \fIhost\fP +True if either the IPv4/v6 source or destination of the packet is \fIhost\fP. +.IP +Any of the above host expressions can be prepended with the keywords, +\fBip\fP, \fBarp\fP, \fBrarp\fP, or \fBip6\fP as in: +.in +.5i +.nf +\fBip host \fIhost\fR +.fi +.in -.5i +which is equivalent to: +.in +.5i +.nf +\fBether proto \fI\\ip\fB and host \fIhost\fR +.fi +.in -.5i +If \fIhost\fR is a name with multiple IP addresses, each address will +be checked for a match. +.IP "\fBether dst \fIehost\fP +True if the Ethernet destination address is \fIehost\fP. +\fIEhost\fP +may be either a name from /etc/ethers or a number (see +.IR ethers (3N) +for numeric format). +.IP "\fBether src \fIehost\fP +True if the Ethernet source address is \fIehost\fP. +.IP "\fBether host \fIehost\fP +True if either the Ethernet source or destination address is \fIehost\fP. +.IP "\fBgateway\fP \fIhost\fP +True if the packet used \fIhost\fP as a gateway. +I.e., the Ethernet +source or destination address was \fIhost\fP but neither the IP source +nor the IP destination was \fIhost\fP. +\fIHost\fP must be a name and +must be found both by the machine's host-name-to-IP-address resolution +mechanisms (host name file, DNS, NIS, etc.) and by the machine's +host-name-to-Ethernet-address resolution mechanism (/etc/ethers, etc.). +(An equivalent expression is +.in +.5i +.nf +\fBether host \fIehost \fBand not host \fIhost\fR +.fi +.in -.5i +which can be used with either names or numbers for \fIhost / ehost\fP.) +This syntax does not work in IPv6-enabled configuration at this moment. +.IP "\fBdst net \fInet\fR" +True if the IPv4/v6 destination address of the packet has a network +number of \fInet\fP. +\fINet\fP may be either a name from the networks database +(/etc/networks, etc.) or a network number. +An IPv4 network number can be written as a dotted quad (e.g., 192.168.1.0), +dotted triple (e.g., 192.168.1), dotted pair (e.g, 172.16), or single +number (e.g., 10); the netmask is 255.255.255.255 for a dotted quad +(which means that it's really a host match), 255.255.255.0 for a dotted +triple, 255.255.0.0 for a dotted pair, or 255.0.0.0 for a single number. +An IPv6 network number must be written out fully; the netmask is +ff:ff:ff:ff:ff:ff:ff:ff, so IPv6 "network" matches are really always +host matches, and a network match requires a netmask length. +.IP "\fBsrc net \fInet\fR" +True if the IPv4/v6 source address of the packet has a network +number of \fInet\fP. +.IP "\fBnet \fInet\fR" +True if either the IPv4/v6 source or destination address of the packet has a network +number of \fInet\fP. +.IP "\fBnet \fInet\fR \fBmask \fInetmask\fR" +True if the IPv4 address matches \fInet\fR with the specific \fInetmask\fR. +May be qualified with \fBsrc\fR or \fBdst\fR. +Note that this syntax is not valid for IPv6 \fInet\fR. +.IP "\fBnet \fInet\fR/\fIlen\fR" +True if the IPv4/v6 address matches \fInet\fR with a netmask \fIlen\fR +bits wide. +May be qualified with \fBsrc\fR or \fBdst\fR. +.IP "\fBdst port \fIport\fR" +True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a +destination port value of \fIport\fP. +The \fIport\fP can be a number or a name used in /etc/services (see +.IR tcp (4P) +and +.IR udp (4P)). +If a name is used, both the port +number and protocol are checked. +If a number or ambiguous name is used, +only the port number is checked (e.g., \fBdst port 513\fR will print both +tcp/login traffic and udp/who traffic, and \fBport domain\fR will print +both tcp/domain and udp/domain traffic). +.IP "\fBsrc port \fIport\fR" +True if the packet has a source port value of \fIport\fP. +.IP "\fBport \fIport\fR" +True if either the source or destination port of the packet is \fIport\fP. +.IP "\fBdst portrange \fIport1\fB-\fIport2\fR" +True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a +destination port value between \fIport1\fP and \fIport2\fP. +.I port1 +and +.I port2 +are interpreted in the same fashion as the +.I port +parameter for +.BR port . +.IP "\fBsrc portrange \fIport1\fB-\fIport2\fR" +True if the packet has a source port value between \fIport1\fP and +\fIport2\fP. +.IP "\fBportrange \fIport1\fB-\fIport2\fR" +True if either the source or destination port of the packet is between +\fIport1\fP and \fIport2\fP. +.IP +Any of the above port or port range expressions can be prepended with +the keywords, \fBtcp\fP or \fBudp\fP, as in: +.in +.5i +.nf +\fBtcp src port \fIport\fR +.fi +.in -.5i +which matches only tcp packets whose source port is \fIport\fP. +.IP "\fBless \fIlength\fR" +True if the packet has a length less than or equal to \fIlength\fP. +This is equivalent to: +.in +.5i +.nf +\fBlen <= \fIlength\fP. +.fi +.in -.5i +.IP "\fBgreater \fIlength\fR" +True if the packet has a length greater than or equal to \fIlength\fP. +This is equivalent to: +.in +.5i +.nf +\fBlen >= \fIlength\fP. +.fi +.in -.5i +.IP "\fBip proto \fIprotocol\fR" +True if the packet is an IPv4 packet (see +.IR ip (4P)) +of protocol type \fIprotocol\fP. +\fIProtocol\fP can be a number or one of the names +\fBicmp\fP, \fBicmp6\fP, \fBigmp\fP, \fBigrp\fP, \fBpim\fP, \fBah\fP, +\fBesp\fP, \fBvrrp\fP, \fBudp\fP, or \fBtcp\fP. +Note that the identifiers \fBtcp\fP, \fBudp\fP, and \fBicmp\fP are also +keywords and must be escaped via backslash (\\), which is \\\\ in the C-shell. +Note that this primitive does not chase the protocol header chain. +.IP "\fBip6 proto \fIprotocol\fR" +True if the packet is an IPv6 packet of protocol type \fIprotocol\fP. +Note that this primitive does not chase the protocol header chain. +.IP "\fBip6 protochain \fIprotocol\fR" +True if the packet is IPv6 packet, +and contains protocol header with type \fIprotocol\fR +in its protocol header chain. +For example, +.in +.5i +.nf +\fBip6 protochain 6\fR +.fi +.in -.5i +matches any IPv6 packet with TCP protocol header in the protocol header chain. +The packet may contain, for example, +authentication header, routing header, or hop-by-hop option header, +between IPv6 header and TCP header. +The BPF code emitted by this primitive is complex and +cannot be optimized by the BPF optimizer code, so this can be somewhat +slow. +.IP "\fBip protochain \fIprotocol\fR" +Equivalent to \fBip6 protochain \fIprotocol\fR, but this is for IPv4. +.IP "\fBether broadcast\fR" +True if the packet is an Ethernet broadcast packet. +The \fIether\fP +keyword is optional. +.IP "\fBip broadcast\fR" +True if the packet is an IPv4 broadcast packet. +It checks for both the all-zeroes and all-ones broadcast conventions, +and looks up the subnet mask on the interface on which the capture is +being done. +.IP +If the subnet mask of the interface on which the capture is being done +is not available, either because the interface on which capture is being +done has no netmask or because the capture is being done on the Linux +"any" interface, which can capture on more than one interface, this +check will not work correctly. +.IP "\fBether multicast\fR" +True if the packet is an Ethernet multicast packet. +The \fBether\fP +keyword is optional. +This is shorthand for `\fBether[0] & 1 != 0\fP'. +.IP "\fBip multicast\fR" +True if the packet is an IPv4 multicast packet. +.IP "\fBip6 multicast\fR" +True if the packet is an IPv6 multicast packet. +.IP "\fBether proto \fIprotocol\fR" +True if the packet is of ether type \fIprotocol\fR. +\fIProtocol\fP can be a number or one of the names +\fBip\fP, \fBip6\fP, \fBarp\fP, \fBrarp\fP, \fBatalk\fP, \fBaarp\fP, +\fBdecnet\fP, \fBsca\fP, \fBlat\fP, \fBmopdl\fP, \fBmoprc\fP, +\fBiso\fP, \fBstp\fP, \fBipx\fP, or \fBnetbeui\fP. +Note these identifiers are also keywords +and must be escaped via backslash (\\). +.IP +[In the case of FDDI (e.g., `\fBfddi protocol arp\fR'), Token Ring +(e.g., `\fBtr protocol arp\fR'), and IEEE 802.11 wireless LANS (e.g., +`\fBwlan protocol arp\fR'), for most of those protocols, the +protocol identification comes from the 802.2 Logical Link Control (LLC) +header, which is usually layered on top of the FDDI, Token Ring, or +802.11 header. +.IP +When filtering for most protocol identifiers on FDDI, Token Ring, or +802.11, the filter checks only the protocol ID field of an LLC header +in so-called SNAP format with an Organizational Unit Identifier (OUI) of +0x000000, for encapsulated Ethernet; it doesn't check whether the packet +is in SNAP format with an OUI of 0x000000. +The exceptions are: +.RS +.TP +\fBiso\fP +the filter checks the DSAP (Destination Service Access Point) and +SSAP (Source Service Access Point) fields of the LLC header; +.TP +\fBstp\fP and \fBnetbeui\fP +the filter checks the DSAP of the LLC header; +.TP +\fBatalk\fP +the filter checks for a SNAP-format packet with an OUI of 0x080007 +and the AppleTalk etype. +.RE +.IP +In the case of Ethernet, the filter checks the Ethernet type field +for most of those protocols. The exceptions are: +.RS +.TP +\fBiso\fP, \fBstp\fP, and \fBnetbeui\fP +the filter checks for an 802.3 frame and then checks the LLC header as +it does for FDDI, Token Ring, and 802.11; +.TP +\fBatalk\fP +the filter checks both for the AppleTalk etype in an Ethernet frame and +for a SNAP-format packet as it does for FDDI, Token Ring, and 802.11; +.TP +\fBaarp\fP +the filter checks for the AppleTalk ARP etype in either an Ethernet +frame or an 802.2 SNAP frame with an OUI of 0x000000; +.TP +\fBipx\fP +the filter checks for the IPX etype in an Ethernet frame, the IPX +DSAP in the LLC header, the 802.3-with-no-LLC-header encapsulation of +IPX, and the IPX etype in a SNAP frame. +.RE +.IP "\fBdecnet src \fIhost\fR" +True if the DECNET source address is +.IR host , +which may be an address of the form ``10.123'', or a DECNET host +name. +[DECNET host name support is only available on ULTRIX systems +that are configured to run DECNET.] +.IP "\fBdecnet dst \fIhost\fR" +True if the DECNET destination address is +.IR host . +.IP "\fBdecnet host \fIhost\fR" +True if either the DECNET source or destination address is +.IR host . +.IP "\fBifname \fIinterface\fR" +True if the packet was logged as coming from the specified interface (applies +only to packets logged by OpenBSD's or FreeBSD's +.BR pf (4)). +.IP "\fBon \fIinterface\fR" +Synonymous with the +.B ifname +modifier. +.IP "\fBrnr \fInum\fR" +True if the packet was logged as matching the specified PF rule number +(applies only to packets logged by OpenBSD's or FreeBSD's +.BR pf (4)). +.IP "\fBrulenum \fInum\fR" +Synonymous with the +.B rnr +modifier. +.IP "\fBreason \fIcode\fR" +True if the packet was logged with the specified PF reason code. The known +codes are: +.BR match , +.BR bad-offset , +.BR fragment , +.BR short , +.BR normalize , +and +.B memory +(applies only to packets logged by OpenBSD's or FreeBSD's +.BR pf (4)). +.IP "\fBrset \fIname\fR" +True if the packet was logged as matching the specified PF ruleset +name of an anchored ruleset (applies only to packets logged by OpenBSD's +or FreeBSD's +.BR pf (4)). +.IP "\fBruleset \fIname\fR" +Synonomous with the +.B rset +modifier. +.IP "\fBsrnr \fInum\fR" +True if the packet was logged as matching the specified PF rule number +of an anchored ruleset (applies only to packets logged by OpenBSD's or +FreeBSD's +.BR pf (4)). +.IP "\fBsubrulenum \fInum\fR" +Synonomous with the +.B srnr +modifier. +.IP "\fBaction \fIact\fR" +True if PF took the specified action when the packet was logged. Known actions +are: +.B pass +and +.B block +and, with later versions of +.BR pf (4)), +.BR nat , +.BR rdr , +.B binat +and +.B scrub +(applies only to packets logged by OpenBSD's or FreeBSD's +.BR pf (4)). +.IP "\fBwlan addr1 \fIehost\fR" +True if the first IEEE 802.11 address is +.IR ehost . +.IP "\fBwlan addr2 \fIehost\fR" +True if the second IEEE 802.11 address, if present, is +.IR ehost . +The second address field is used in all frames except for CTS (Clear To +Send) and ACK (Acknowledgment) control frames. +.IP "\fBwlan addr3 \fIehost\fR" +True if the third IEEE 802.11 address, if present, is +.IR ehost . +The third address field is used in management and data frames, but not +in control frames. +.IP "\fBwlan addr4 \fIehost\fR" +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" +Abbreviations for: +.in +.5i +.nf +\fBether proto \fIp\fR +.fi +.in -.5i +where \fIp\fR is one of the above protocols. +.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR" +Abbreviations for: +.in +.5i +.nf +\fBether proto \fIp\fR +.fi +.in -.5i +where \fIp\fR is one of the above protocols. +Note that not all applications using +.BR pcap (3) +currently know how to parse these protocols. +.IP "\fBtype \fIwlan_type\fR" +True if the IEEE 802.11 frame type matches the specified \fIwlan_type\fR. +Valid \fIwlan_type\fRs are: +\fBmgt\fP, +\fBctl\fP +and \fBdata\fP. +.IP "\fBtype \fIwlan_type \fBsubtype \fIwlan_subtype\fR" +True if the IEEE 802.11 frame type matches the specified \fIwlan_type\fR +and frame subtype matches the specified \fIwlan_subtype\fR. +.IP +If the specified \fIwlan_type\fR is \fBmgt\fP, +then valid \fIwlan_subtype\fRs are: +\fBassoc-req\fP, +\fBassoc-resp\fP, +\fBreassoc-req\fP, +\fBreassoc-resp\fP, +\fBprobe-req\fP, +\fBprobe-resp\fP, +\fBbeacon\fP, +\fBatim\fP, +\fBdisassoc\fP, +\fBauth\fP and +\fBdeauth\fP. +.IP +If the specified \fIwlan_type\fR is \fBctl\fP, +then valid \fIwlan_subtype\fRs are: +\fBps-poll\fP, +\fBrts\fP, +\fBcts\fP, +\fBack\fP, +\fBcf-end\fP and +\fBcf-end-ack\fP. +.IP +If the specified \fIwlan_type\fR is \fBdata\fP, +then valid \fIwlan_subtype\fRs are: +\fBdata\fP, +\fBdata-cf-ack\fP, +\fBdata-cf-poll\fP, +\fBdata-cf-ack-poll\fP, +\fBnull\fP, +\fBcf-ack\fP, +\fBcf-poll\fP, +\fBcf-ack-poll\fP, +\fBqos-data\fP, +\fBqos-data-cf-ack\fP, +\fBqos-data-cf-poll\fP, +\fBqos-data-cf-ack-poll\fP, +\fBqos\fP, +\fBqos-cf-poll\fP and +\fBqos-cf-ack-poll\fP. +.IP "\fBsubtype \fIwlan_subtype\fR" +True if the IEEE 802.11 frame subtype matches the specified \fIwlan_subtype\fR +and frame has the type to which the specified \fIwlan_subtype\fR belongs. +.IP "\fBdir \fIdir\fR" +True if the IEEE 802.11 frame direction matches the specified +.IR dir . +Valid directions are: +.BR nods , +.BR tods , +.BR fromds , +.BR dstods , +or a numeric value. +.IP "\fBvlan \fI[vlan_id]\fR" +True if the packet is an IEEE 802.1Q VLAN packet. +If \fI[vlan_id]\fR is specified, only true if the packet has the specified +\fIvlan_id\fR. +Note that the first \fBvlan\fR keyword encountered in \fIexpression\fR +changes the decoding offsets for the remainder of \fIexpression\fR on +the assumption that the packet is a VLAN packet. The \fBvlan +\fI[vlan_id]\fR expression may be used more than once, to filter on VLAN +hierarchies. Each use of that expression increments the filter offsets +by 4. +.IP +For example: +.in +.5i +.nf +\fBvlan 100 && vlan 200\fR +.fi +.in -.5i +filters on VLAN 200 encapsulated within VLAN 100, and +.in +.5i +.nf +\fBvlan && vlan 300 && ip\fR +.fi +.in -.5i +filters IPv4 protocols encapsulated in VLAN 300 encapsulated within any +higher order VLAN. +.IP "\fBmpls \fI[label_num]\fR" +True if the packet is an MPLS packet. +If \fI[label_num]\fR is specified, only true is the packet has the specified +\fIlabel_num\fR. +Note that the first \fBmpls\fR keyword encountered in \fIexpression\fR +changes the decoding offsets for the remainder of \fIexpression\fR on +the assumption that the packet is a MPLS-encapsulated IP packet. The +\fBmpls \fI[label_num]\fR expression may be used more than once, to +filter on MPLS hierarchies. Each use of that expression increments the +filter offsets by 4. +.IP +For example: +.in +.5i +.nf +\fBmpls 100000 && mpls 1024\fR +.fi +.in -.5i +filters packets with an outer label of 100000 and an inner label of +1024, and +.in +.5i +.nf +\fBmpls && mpls 1024 && host 192.9.200.1\fR +.fi +.in -.5i +filters packets to or from 192.9.200.1 with an inner label of 1024 and +any outer label. +.IP \fBpppoed\fP +True if the packet is a PPP-over-Ethernet Discovery packet (Ethernet +type 0x8863). +.IP \fBpppoes\fP +True if the packet is a PPP-over-Ethernet Session packet (Ethernet +type 0x8864). +Note that the first \fBpppoes\fR keyword encountered in \fIexpression\fR +changes the decoding offsets for the remainder of \fIexpression\fR on +the assumption that the packet is a PPPoE session packet. +.IP +For example: +.in +.5i +.nf +\fBpppoes && ip\fR +.fi +.in -.5i +filters IPv4 protocols encapsulated in PPPoE. +.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR" +Abbreviations for: +.in +.5i +.nf +\fBip proto \fIp\fR\fB or ip6 proto \fIp\fR +.fi +.in -.5i +where \fIp\fR is one of the above protocols. +.IP "\fBiso proto \fIprotocol\fR" +True if the packet is an OSI packet of protocol type \fIprotocol\fP. +\fIProtocol\fP can be a number or one of the names +\fBclnp\fP, \fBesis\fP, or \fBisis\fP. +.IP "\fBclnp\fR, \fBesis\fR, \fBisis\fR" +Abbreviations for: +.in +.5i +.nf +\fBiso proto \fIp\fR +.fi +.in -.5i +where \fIp\fR is one of the above protocols. +.IP "\fBl1\fR, \fBl2\fR, \fBiih\fR, \fBlsp\fR, \fBsnp\fR, \fBcsnp\fR, \fBpsnp\fR" +Abbreviations for IS-IS PDU types. +.IP "\fBvpi\fP \fIn\fR +True if the packet is an ATM packet, for SunATM on Solaris, with a +virtual path identifier of +.IR n . +.IP "\fBvci\fP \fIn\fR +True if the packet is an ATM packet, for SunATM on Solaris, with a +virtual channel identifier of +.IR n . +.IP \fBlane\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +an ATM LANE packet. +Note that the first \fBlane\fR keyword encountered in \fIexpression\fR +changes the tests done in the remainder of \fIexpression\fR +on the assumption that the packet is either a LANE emulated Ethernet +packet or a LANE LE Control packet. If \fBlane\fR isn't specified, the +tests are done under the assumption that the packet is an +LLC-encapsulated packet. +.IP \fBllc\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +an LLC-encapsulated packet. +.IP \fBoamf4s\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +a segment OAM F4 flow cell (VPI=0 & VCI=3). +.IP \fBoamf4e\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +an end-to-end OAM F4 flow cell (VPI=0 & VCI=4). +.IP \fBoamf4\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +a segment or end-to-end OAM F4 flow cell (VPI=0 & (VCI=3 | VCI=4)). +.IP \fBoam\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +a segment or end-to-end OAM F4 flow cell (VPI=0 & (VCI=3 | VCI=4)). +.IP \fBmetac\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on a meta signaling circuit (VPI=0 & VCI=1). +.IP \fBbcc\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on a broadcast signaling circuit (VPI=0 & VCI=2). +.IP \fBsc\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on a signaling circuit (VPI=0 & VCI=5). +.IP \fBilmic\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on an ILMI circuit (VPI=0 & VCI=16). +.IP \fBconnectmsg\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on a signaling circuit and is a Q.2931 Setup, Call Proceeding, Connect, +Connect Ack, Release, or Release Done message. +.IP \fBmetaconnect\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on a meta signaling circuit and is a Q.2931 Setup, Call Proceeding, Connect, +Release, or Release Done message. +.IP "\fIexpr relop expr\fR" +True if the relation holds, where \fIrelop\fR is one of >, <, >=, <=, =, +!=, and \fIexpr\fR is an arithmetic expression composed of integer +constants (expressed in standard C syntax), the normal binary operators +[+, -, *, /, &, |, <<, >>], a length operator, and special packet data +accessors. Note that all comparisons are unsigned, so that, for example, +0x80000000 and 0xffffffff are > 0. +To access +data inside the packet, use the following syntax: +.in +.5i +.nf +\fIproto\fB [ \fIexpr\fB : \fIsize\fB ]\fR +.fi +.in -.5i +\fIProto\fR is one of \fBether, fddi, tr, wlan, ppp, slip, link, +ip, arp, rarp, tcp, udp, icmp, ip6\fR or \fBradio\fR, and +indicates the protocol layer for the index operation. +(\fBether, fddi, wlan, tr, ppp, slip\fR and \fBlink\fR all refer to the +link layer. \fBradio\fR refers to the "radio header" added to some +802.11 captures.) +Note that \fItcp, udp\fR and other upper-layer protocol types only +apply to IPv4, not IPv6 (this will be fixed in the future). +The byte offset, relative to the indicated protocol layer, is +given by \fIexpr\fR. +\fISize\fR is optional and indicates the number of bytes in the +field of interest; it can be either one, two, or four, and defaults to one. +The length operator, indicated by the keyword \fBlen\fP, gives the +length of the packet. + +For example, `\fBether[0] & 1 != 0\fP' catches all multicast traffic. +The expression `\fBip[0] & 0xf != 5\fP' +catches all IPv4 packets with options. +The expression +`\fBip[6:2] & 0x1fff = 0\fP' +catches only unfragmented IPv4 datagrams and frag zero of fragmented +IPv4 datagrams. +This check is implicitly applied to the \fBtcp\fP and \fBudp\fP +index operations. +For instance, \fBtcp[0]\fP always means the first +byte of the TCP \fIheader\fP, and never means the first byte of an +intervening fragment. + +Some offsets and field values may be expressed as names rather than +as numeric values. +The following protocol header field offsets are +available: \fBicmptype\fP (ICMP type field), \fBicmpcode\fP (ICMP +code field), and \fBtcpflags\fP (TCP flags field). + +The following ICMP type field values are available: \fBicmp-echoreply\fP, +\fBicmp-unreach\fP, \fBicmp-sourcequench\fP, \fBicmp-redirect\fP, +\fBicmp-echo\fP, \fBicmp-routeradvert\fP, \fBicmp-routersolicit\fP, +\fBicmp-timxceed\fP, \fBicmp-paramprob\fP, \fBicmp-tstamp\fP, +\fBicmp-tstampreply\fP, \fBicmp-ireq\fP, \fBicmp-ireqreply\fP, +\fBicmp-maskreq\fP, \fBicmp-maskreply\fP. + +The following TCP flags field values are available: \fBtcp-fin\fP, +\fBtcp-syn\fP, \fBtcp-rst\fP, \fBtcp-push\fP, +\fBtcp-ack\fP, \fBtcp-urg\fP. +.LP +Primitives may be combined using: +.IP +A parenthesized group of primitives and operators +(parentheses are special to the Shell and must be escaped). +.IP +Negation (`\fB!\fP' or `\fBnot\fP'). +.IP +Concatenation (`\fB&&\fP' or `\fBand\fP'). +.IP +Alternation (`\fB||\fP' or `\fBor\fP'). +.LP +Negation has highest precedence. +Alternation and concatenation have equal precedence and associate +left to right. +Note that explicit \fBand\fR tokens, not juxtaposition, +are now required for concatenation. +.LP +If an identifier is given without a keyword, the most recent keyword +is assumed. +For example, +.in +.5i +.nf +\fBnot host vs and ace\fR +.fi +.in -.5i +is short for +.in +.5i +.nf +\fBnot host vs and host ace\fR +.fi +.in -.5i +which should not be confused with +.in +.5i +.nf +\fBnot ( host vs or ace )\fR +.fi +.in -.5i +.SH EXAMPLES +.LP +To select all packets arriving at or departing from \fIsundown\fP: +.RS +.nf +\fBhost sundown\fP +.fi +.RE +.LP +To select traffic between \fIhelios\fR and either \fIhot\fR or \fIace\fR: +.RS +.nf +\fBhost helios and \\( hot or ace \\)\fP +.fi +.RE +.LP +To select all IP packets between \fIace\fR and any host except \fIhelios\fR: +.RS +.nf +\fBip host ace and not helios\fP +.fi +.RE +.LP +To select all traffic between local hosts and hosts at Berkeley: +.RS +.nf +.B +net ucb-ether +.fi +.RE +.LP +To select all ftp traffic through internet gateway \fIsnup\fP: +.RS +.nf +.B +gateway snup and (port ftp or ftp-data) +.fi +.RE +.LP +To select traffic neither sourced from nor destined for local hosts +(if you gateway to one other net, this stuff should never make it +onto your local net). +.RS +.nf +.B +ip and not net \fIlocalnet\fP +.fi +.RE +.LP +To select the start and end packets (the SYN and FIN packets) of each +TCP conversation that involves a non-local host. +.RS +.nf +.B +tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net \fIlocalnet\fP +.fi +.RE +.LP +To select all IPv4 HTTP packets to and from port 80, i.e. print only +packets that contain data, not, for example, SYN and FIN packets and +ACK-only packets. (IPv6 is left as an exercise for the reader.) +.RS +.nf +.B +tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0) +.fi +.RE +.LP +To select IP packets longer than 576 bytes sent through gateway \fIsnup\fP: +.RS +.nf +.B +gateway snup and ip[2:2] > 576 +.fi +.RE +.LP +To select IP broadcast or multicast packets that were +.I not +sent via Ethernet broadcast or multicast: +.RS +.nf +.B +ether[0] & 1 = 0 and ip[16] >= 224 +.fi +.RE +.LP +To select all ICMP packets that are not echo requests/replies (i.e., not +ping packets): +.RS +.nf +.B +icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply +.fi +.RE +.SH "SEE ALSO" +pcap(3PCAP) +.SH AUTHORS +The original authors are: +.LP +Van Jacobson, +Craig Leres and +Steven McCanne, all of the +Lawrence Berkeley National Laboratory, University of California, Berkeley, CA. +.LP +It is currently being maintained by tcpdump.org. +.LP +The current version of libpcap is available via http: +.LP +.RS +.I http://www.tcpdump.org/ +.RE +.LP +The original distribution is available via anonymous ftp: +.LP +.RS +.I ftp://ftp.ee.lbl.gov/tcpdump.tar.Z +.RE +.SH BUGS +Please send problems, bugs, questions, desirable enhancements, etc. to: +.LP +.RS +tcpdump-workers@lists.tcpdump.org +.RE +.LP +Filter expressions on fields other than those in Token Ring headers will +not correctly handle source-routed Token Ring packets. +.LP +Filter expressions on fields other than those in 802.11 headers will not +correctly handle 802.11 data packets with both To DS and From DS set. +.LP +.BR "ip6 proto" +should chase header chain, but at this moment it does not. +.BR "ip6 protochain" +is supplied for this behavior. +.LP +Arithmetic expression against transport layer headers, like \fBtcp[0]\fP, +does not work against IPv6 packets. +It only looks at IPv4 packets. diff --git a/contrib/libpcap/pcap-int.h b/contrib/libpcap/pcap-int.h index 3071c77f5b..080470e937 100644 --- a/contrib/libpcap/pcap-int.h +++ b/contrib/libpcap/pcap-int.h @@ -30,17 +30,21 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.68.2.11 2007/06/22 06:43:58 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.85.2.9 2008-09-16 00:21:08 guy Exp $ (LBL) */ #ifndef pcap_int_h -#define pcap_int_h +#define pcap_int_h + +#include #ifdef __cplusplus extern "C" { #endif -#include +#ifdef HAVE_LIBDLPI +#include +#endif #ifdef WIN32 #include @@ -51,6 +55,23 @@ extern "C" { #include #endif +#if (defined(_MSC_VER) && (_MSC_VER <= 1200)) /* we are compiling with Visual Studio 6, that doesn't support the LL suffix*/ + +/* + * Swap byte ordering of unsigned long long timestamp on a big endian + * machine. + */ +#define SWAPLL(ull) ((ull & 0xff00000000000000) >> 56) | \ + ((ull & 0x00ff000000000000) >> 40) | \ + ((ull & 0x0000ff0000000000) >> 24) | \ + ((ull & 0x000000ff00000000) >> 8) | \ + ((ull & 0x00000000ff000000) << 8) | \ + ((ull & 0x0000000000ff0000) << 24) | \ + ((ull & 0x000000000000ff00) << 40) | \ + ((ull & 0x00000000000000ff) << 56) + +#else /* A recent Visual studio compiler or not VC */ + /* * Swap byte ordering of unsigned long long timestamp on a big endian * machine. @@ -64,6 +85,8 @@ extern "C" { ((ull & 0x000000000000ff00LL) << 40) | \ ((ull & 0x00000000000000ffLL) << 56) +#endif /* _MSC_VER */ + /* * Savefile */ @@ -73,16 +96,22 @@ typedef enum { MAYBE_SWAPPED } swapped_type_t; +/* + * Used when reading a savefile. + */ struct pcap_sf { FILE *rfile; int swapped; - int hdrsize; + size_t hdrsize; swapped_type_t lengths_swapped; int version_major; int version_minor; u_char *base; }; +/* + * Used when doing a live capture. + */ struct pcap_md { struct pcap_stat stat; /*XXX*/ @@ -93,22 +122,25 @@ struct pcap_md { long TotMissed; /* missed by i/f during this run */ long OrigMissed; /* missed by i/f before this run */ char *device; /* device name */ + int timeout; /* timeout for buffering */ + int must_clear; /* stuff we must clear when we close */ + struct pcap *next; /* list of open pcaps that need stuff cleared on close */ #ifdef linux int sock_packet; /* using Linux 2.0 compatible interface */ - int timeout; /* timeout specified to pcap_open_live */ - int clear_promisc; /* must clear promiscuous mode when we close */ int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */ int ifindex; /* interface index of device we're bound to */ int lo_ifindex; /* interface index of the loopback device */ - struct pcap *next; /* list of open promiscuous sock_packet pcaps */ u_int packets_read; /* count of packets read with recvfrom() */ -#endif + bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */ + u_int tp_version; /* version of tpacket_hdr for mmaped ring */ + u_int tp_hdrlen; /* hdrlen of tpacket_hdr for mmaped ring */ +#endif /* linux */ #ifdef HAVE_DAG_API #ifdef HAVE_DAG_STREAMS_API u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */ u_char *dag_mem_top; /* DAG card current memory top pointer */ -#else +#else /* HAVE_DAG_STREAMS_API */ void *dag_mem_base; /* DAG card memory base address */ u_int dag_mem_bottom; /* DAG card current memory bottom offset */ u_int dag_mem_top; /* DAG card current memory top offset */ @@ -120,6 +152,41 @@ struct pcap_md { * Same as in linux above, introduce * generally? */ #endif /* HAVE_DAG_API */ +#ifdef HAVE_ZEROCOPY_BPF + /* + * Zero-copy read buffer -- for zero-copy BPF. 'buffer' above will + * alternative between these two actual mmap'd buffers as required. + * As there is a header on the front size of the mmap'd buffer, only + * some of the buffer is exposed to libpcap as a whole via bufsize; + * zbufsize is the true size. zbuffer tracks the current zbuf + * assocated with buffer so that it can be used to decide which the + * next buffer to read will be. + */ + u_char *zbuf1, *zbuf2, *zbuffer; + u_int zbufsize; + u_int zerocopy; + u_int interrupted; + struct timespec firstsel; + /* + * If there's currently a buffer being actively processed, then it is + * referenced here; 'buffer' is also pointed at it, but offset by the + * size of the header. + */ + struct bpf_zbuf_header *bzh; +#endif /* HAVE_ZEROCOPY_BPF */ +}; + +/* + * Stuff to clear when we close. + */ +#define MUST_CLEAR_PROMISC 0x00000001 /* promiscuous mode */ +#define MUST_CLEAR_RFMON 0x00000002 /* rfmon (monitor) mode */ + +struct pcap_opt { + int buffer_size; + char *source; + int promisc; + int rfmon; }; /* @@ -135,21 +202,44 @@ struct pcap_md { #define PCAP_FDDIPAD 3 #endif +typedef int (*activate_op_t)(pcap_t *); +typedef int (*can_set_rfmon_op_t)(pcap_t *); +typedef int (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *); +typedef int (*inject_op_t)(pcap_t *, const void *, size_t); +typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *); +typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t); +typedef int (*set_datalink_op_t)(pcap_t *, int); +typedef int (*getnonblock_op_t)(pcap_t *, char *); +typedef int (*setnonblock_op_t)(pcap_t *, int, char *); +typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *); +#ifdef WIN32 +typedef int (*setbuff_op_t)(pcap_t *, int); +typedef int (*setmode_op_t)(pcap_t *, int); +typedef int (*setmintocopy_op_t)(pcap_t *, int); +#endif +typedef void (*cleanup_op_t)(pcap_t *); + struct pcap { #ifdef WIN32 ADAPTER *adapter; LPPACKET Packet; - int timeout; int nonblock; #else int fd; int selectable_fd; int send_fd; #endif /* WIN32 */ + +#ifdef HAVE_LIBDLPI + dlpi_handle_t dlpi_hd; +#endif int snapshot; - int linktype; + int linktype; /* Network linktype */ + int linktype_ext; /* Extended information stored in the linktype field of a file */ int tzoff; /* timezone offset */ int offset; /* offset for proper alignment */ + int activated; /* true if the capture is really started */ + int oldstyle; /* if we're opening with pcap_open_live() */ int break_loop; /* flag set to force break from packet-reading loop */ @@ -158,12 +248,12 @@ struct pcap { #endif #ifdef MSDOS - int inter_packet_wait; /* offline: wait between packets */ void (*wait_proc)(void); /* call proc while waiting */ #endif struct pcap_sf sf; struct pcap_md md; + struct pcap_opt opt; /* * Read buffer. @@ -184,15 +274,27 @@ struct pcap { /* * Methods. */ - int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *); - int (*inject_op)(pcap_t *, const void *, size_t); - int (*setfilter_op)(pcap_t *, struct bpf_program *); - int (*setdirection_op)(pcap_t *, pcap_direction_t); - int (*set_datalink_op)(pcap_t *, int); - int (*getnonblock_op)(pcap_t *, char *); - int (*setnonblock_op)(pcap_t *, int, char *); - int (*stats_op)(pcap_t *, struct pcap_stat *); - void (*close_op)(pcap_t *); + activate_op_t activate_op; + can_set_rfmon_op_t can_set_rfmon_op; + read_op_t read_op; + inject_op_t inject_op; + setfilter_op_t setfilter_op; + setdirection_op_t setdirection_op; + set_datalink_op_t set_datalink_op; + getnonblock_op_t getnonblock_op; + setnonblock_op_t setnonblock_op; + stats_op_t stats_op; + +#ifdef WIN32 + /* + * These are, at least currently, specific to the Win32 NPF + * driver. + */ + setbuff_op_t setbuff_op; + setmode_op_t setmode_op; + setmintocopy_op_t setmintocopy_op; +#endif + cleanup_op_t cleanup_op; /* * Placeholder for filter code if bpf not in kernel. @@ -231,8 +333,8 @@ struct pcap_timeval { * * introduce a new structure for the new format; * - * send mail to "tcpdump-workers@tcpdump.org", requesting a new - * magic number for your new capture file format, and, when + * send mail to "tcpdump-workers@lists.tcpdump.org", requesting + * a new magic number for your new capture file format, and, when * you get the new magic number, put it in "savefile.c"; * * use that magic number for save files with the changed record @@ -242,9 +344,12 @@ struct pcap_timeval { * the old record header as well as files with the new record header * (using the magic number to determine the header format). * - * Then supply the changes to "patches@tcpdump.org", so that future - * versions of libpcap and programs that use it (such as tcpdump) will - * be able to read your new capture file format. + * Then supply the changes as a patch at + * + * http://sourceforge.net/projects/libpcap/ + * + * so that future versions of libpcap and programs that use it (such as + * tcpdump) will be able to read your new capture file format. */ struct pcap_sf_pkthdr { @@ -309,7 +414,13 @@ int pcap_getnonblock_fd(pcap_t *, char *); int pcap_setnonblock_fd(pcap_t *p, int, char *); #endif -void pcap_close_common(pcap_t *); +pcap_t *pcap_create_common(const char *, char *); +int pcap_do_addexit(pcap_t *); +void pcap_add_to_pcaps_to_close(pcap_t *); +void pcap_remove_from_pcaps_to_close(pcap_t *); +void pcap_cleanup_live_common(pcap_t *); +int pcap_not_initialized(pcap_t *); +int pcap_check_activated(pcap_t *); /* * Internal interfaces for "pcap_findalldevs()". diff --git a/contrib/libpcap/pcap-linktype.manmisc.in b/contrib/libpcap/pcap-linktype.manmisc.in new file mode 100644 index 0000000000..7d33b7f883 --- /dev/null +++ b/contrib/libpcap/pcap-linktype.manmisc.in @@ -0,0 +1,282 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap-linktype.manmisc.in,v 1.1.2.4 2008-10-27 22:52:05 guy Exp $ +.\" +.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997 +.\" The Regents of the University of California. All rights reserved. +.\" 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-LINKTYPE @MAN_MISC_INFO@ "23 October 2008" +.SH NAME +pcap-linktype \- link-layer header types supported by libpcap +.SH DESCRIPTION +For a live capture or ``savefile'', libpcap supplies, as the return +value of the +.BR pcap_datalink (3PCAP) +routine, a value that indicates the type of link-layer header at the +beginning of the packets it provides. This is not necessarily the type +of link-layer header that the packets being captured have on the network +from which they're being captured; for example, packets from an IEEE +802.11 network might be provided by libpcap with Ethernet headers that +the network adapter or the network adapter driver generates from the +802.11 headers. The names for those values begin with +.BR DLT_ , +so they are sometimes called "DLT_ values". +.PP +The values stored in the link-layer header type field in the savefile +header are, in most but not all cases, the same as the values returned +by +.BR pcap_datalink() . +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 header +(if there are more than 8 bytes, only the first 8 are present); +.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 +.SH SEE ALSO +pcap_datalink(3PCAP) diff --git a/contrib/libpcap/pcap-namedb.h b/contrib/libpcap/pcap-namedb.h index acaabd9636..80a2f00401 100644 --- a/contrib/libpcap/pcap-namedb.h +++ b/contrib/libpcap/pcap-namedb.h @@ -30,60 +30,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.10.2.1 2005/04/19 04:26:08 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.13 2006/10/04 18:13:32 guy Exp $ (LBL) */ -#ifndef lib_pcap_namedb_h -#define lib_pcap_namedb_h - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * As returned by the pcap_next_etherent() - * XXX this stuff doesn't belong in this interface, but this - * library already must do name to address translation, so - * on systems that don't have support for /etc/ethers, we - * export these hooks since they'll - */ -struct pcap_etherent { - u_char addr[6]; - char name[122]; -}; -#ifndef PCAP_ETHERS_FILE -#define PCAP_ETHERS_FILE "/etc/ethers" -#endif -struct pcap_etherent *pcap_next_etherent(FILE *); -u_char *pcap_ether_hostton(const char*); -u_char *pcap_ether_aton(const char *); - -bpf_u_int32 **pcap_nametoaddr(const char *); -#ifdef INET6 -struct addrinfo *pcap_nametoaddrinfo(const char *); -#endif -bpf_u_int32 pcap_nametonetaddr(const char *); - -int pcap_nametoport(const char *, int *, int *); -int pcap_nametoportrange(const char *, int *, int *, int *); -int pcap_nametoproto(const char *); -int pcap_nametoeproto(const char *); -int pcap_nametollc(const char *); /* - * If a protocol is unknown, PROTO_UNDEF is returned. - * Also, pcap_nametoport() returns the protocol along with the port number. - * If there are ambiguous entried in /etc/services (i.e. domain - * can be either tcp or udp) PROTO_UNDEF is returned. + * For backwards compatibility. + * + * Note to OS vendors: do NOT get rid of this file! Some applications + * might expect to be able to include . */ -#define PROTO_UNDEF -1 - -/* XXX move these to pcap-int.h? */ -int __pcap_atodn(const char *, bpf_u_int32 *); -int __pcap_atoin(const char *, bpf_u_int32 *); -u_short __pcap_nametodnaddr(const char *); - -#ifdef __cplusplus -} -#endif - -#endif +#include diff --git a/contrib/libpcap/pcap-savefile.manfile.in b/contrib/libpcap/pcap-savefile.manfile.in new file mode 100644 index 0000000000..3b9503fd27 --- /dev/null +++ b/contrib/libpcap/pcap-savefile.manfile.in @@ -0,0 +1,127 @@ +'\" t +.\" @(#) $Header: /tcpdump/master/libpcap/pcap-savefile.manfile.in,v 1.1.2.3 2008-10-24 07:34: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-SAVEFILE @MAN_FILE_FORMATS@ "21 October 2008" +.SH NAME +pcap-savefile \- libpcap savefile format +.SH DESCRIPTION +NOTE: applications and libraries should, if possible, use libpcap to +read savefiles, rather than having their own code to read savefiles. +If, in the future, a new file format is supported by libpcap, +applications and libraries using libpcap to read savefiles will be able +to read the new format of savefiles, but applications and libraries +using their own code to read savefiles will have to be changed to +support the new file format. +.PP +``Savefiles'' read and written by libpcap and applications using libpcap +start with a per-file header. The format of the per-file header is: +.RS +.TS +box; +c s +c | c +c s. +Magic number +_ +Major version Minor version +_ +Time zone offset +_ +Time stamp accuracy +_ +Snapshot length +_ +Link-layer header type +.TE +.RE +.PP +All fields in the per-file header are in the byte order of the host +writing the file. The first field in the per-file header is a 4-byte +magic number, with the value 0xa1b2c3d4. The magic number, when read by +a host with the same byte order as the host that wrote the file, will +have the value 0xa1b2c3d4, and, when read by a host with the opposite +byte order as the host that wrote the file, will have the value +0xd4c3b2a1. That allows software reading the file to determine whether +the byte order of the host that wrote the file is the same as the byte +order of the host on which the file is being read, and thus whether the +values in the per-file and per-packet headers need to be byte-swapped. +.PP +Following this are: +.IP +A 2-byte file format major version number; the current version number is +2. +.IP +A 2-byte file format minor version number; the current version number is +4. +.IP +A 4-byte time zone offset; this is always 0. +.IP +A 4-byte number giving the accuracy of time stamps in the file; this is +always 0. +.IP +A 4-byte number giving the "snapshot length" of the capture; packets +longer than the snapshot length are truncated to the snapshot length, so +that, if the snapshot length is +.IR N , +only the first +.I N +bytes of a packet longer than +.I N +bytes will be saved in the capture. +.IP +a 4-byte number giving the link-layer header type for packets in the +capture; see +.BR pcap-linktype (@MAN_MISC_INFO@) +for the +.B LINKTYPE_ +values that can appear in this field. +.PP +Following the per-file header are zero or more packets; each packet +begins with a per-packet header, which is immediately followed by the +raw packet data. The format of the per-packet header is: +.RS +.TS +box; +c. +Time stamp, seconds value +_ +Time stamp, microseconds value +_ +Length of captured packet data +_ +Un-truncated length of the packet data +.TE +.RE +.PP +All fields in the per-packet header are in the byte order of the host +writing the file. The per-packet header begins with a time stamp giving +the approximate time the packet was captured; the time stamp consists of +a 4-byte value, giving the time in seconds since January 1, 1970, +00:00:00 UTC, followed by a 4-byte value, giving the time in +microseconds since that second. Following that are a 4-byte value +giving the number of bytes of captured data that follow the per-packet +header and a 4-byte value giving the number of bytes that would have +been present had the packet not been truncated by the snapshot length. +The two lengths will be equal if the number of bytes of packet data are +less than or equal to the snapshot length. +.SH SEE ALSO +pcap(3PCAP), pcap-linktype(@MAN_MISC_INFO@) diff --git a/contrib/libpcap/pcap.3 b/contrib/libpcap/pcap.3 deleted file mode 100644 index 94b1f6a552..0000000000 --- a/contrib/libpcap/pcap.3 +++ /dev/null @@ -1,1312 +0,0 @@ -.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.64.2.11 2007/06/11 09:52:05 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 3 "27 February 2004" -.SH NAME -pcap \- Packet Capture library -.SH SYNOPSIS -.nf -.ft B -#include -.ft -.LP -.nf -.ft B -char errbuf[PCAP_ERRBUF_SIZE]; -.ft -.LP -.ft B -pcap_t *pcap_open_live(const char *device, int snaplen, -.ti +8 -int promisc, int to_ms, char *errbuf) -pcap_t *pcap_open_dead(int linktype, int snaplen) -pcap_t *pcap_open_offline(const char *fname, char *errbuf) -pcap_t *pcap_fopen_offline(FILE *fp, char *errbuf) -pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname) -pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *fp) -.ft -.LP -.ft B -int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf); -int pcap_getnonblock(pcap_t *p, char *errbuf); -.ft -.LP -.ft B -int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) -void pcap_freealldevs(pcap_if_t *alldevs) -char *pcap_lookupdev(char *errbuf) -int pcap_lookupnet(const char *device, bpf_u_int32 *netp, -.ti +8 -bpf_u_int32 *maskp, char *errbuf) -.ft -.LP -.ft B -typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h, -.ti +8 - const u_char *bytes); -.ft B -int pcap_dispatch(pcap_t *p, int cnt, -.ti +8 -pcap_handler callback, u_char *user) -int pcap_loop(pcap_t *p, int cnt, -.ti +8 -pcap_handler callback, u_char *user) -void pcap_dump(u_char *user, struct pcap_pkthdr *h, -.ti +8 -u_char *sp) -.ft -.LP -.ft B -int pcap_compile(pcap_t *p, struct bpf_program *fp, -.ti +8 -const char *str, int optimize, bpf_u_int32 netmask) -int pcap_setfilter(pcap_t *p, struct bpf_program *fp) -void pcap_freecode(struct bpf_program *) -int pcap_setdirection(pcap_t *p, pcap_direction_t d) -.ft -.LP -.ft B -const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h) -int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, -.ti +8 -const u_char **pkt_data) -.ft -.LP -.ft B -void pcap_breakloop(pcap_t *) -.ft -.LP -.ft B -int pcap_inject(pcap_t *p, const void *buf, size_t size) -int pcap_sendpacket(pcap_t *p, const u_char *buf, int size) -.ft -.LP -.ft B -int pcap_datalink(pcap_t *p) -int pcap_list_datalinks(pcap_t *p, int **dlt_buf); -int pcap_set_datalink(pcap_t *p, int dlt); -int pcap_datalink_name_to_val(const char *name); -const char *pcap_datalink_val_to_name(int dlt); -const char *pcap_datalink_val_to_description(int dlt); -int pcap_snapshot(pcap_t *p) -int pcap_is_swapped(pcap_t *p) -int pcap_major_version(pcap_t *p) -int pcap_minor_version(pcap_t *p) -int pcap_stats(pcap_t *p, struct pcap_stat *ps) -FILE *pcap_file(pcap_t *p) -int pcap_fileno(pcap_t *p) -int pcap_get_selectable_fd(pcap_t *p); -void pcap_perror(pcap_t *p, char *prefix) -char *pcap_geterr(pcap_t *p) -const char *pcap_strerror(int error) -const char *pcap_lib_version(void) -.ft -.LP -.ft B -void pcap_close(pcap_t *p) -int pcap_dump_flush(pcap_dumper_t *p) -long pcap_dump_ftell(pcap_dumper_t *p) -FILE *pcap_dump_file(pcap_dumper_t *p) -void pcap_dump_close(pcap_dumper_t *p) -.ft -.fi -.SH DESCRIPTION -The Packet Capture library -provides a high level interface to packet capture systems. All packets -on the network, even those destined for other hosts, are accessible -through this mechanism. -.PP -.SH ROUTINES -NOTE: -.I errbuf -in -.BR pcap_open_live() , -.BR pcap_open_dead() , -.BR pcap_open_offline() , -.BR pcap_fopen_offline() , -.BR pcap_setnonblock() , -.BR pcap_getnonblock() , -.BR pcap_findalldevs() , -.BR pcap_lookupdev() , -and -.B pcap_lookupnet() -is assumed to be able to hold at least -.B PCAP_ERRBUF_SIZE -chars. -.PP -.B pcap_open_live() -is used to obtain a packet capture descriptor to look -at packets on the network. -.I device -is a string that specifies the network device to open; on Linux systems -with 2.2 or later kernels, a -.I device -argument of "any" or -.B NULL -can be used to capture packets from all interfaces. -.I snaplen -specifies the maximum number of bytes to capture. If this value is less -than the size of a packet that is captured, only the first -.I snaplen -bytes of that packet will be captured and provided as packet data. A -value of 65535 should be sufficient, on most if not all networks, to -capture all the data available from the packet. -.I promisc -specifies if the interface is to be put into promiscuous mode. -(Note that even if this parameter is false, the interface -could well be in promiscuous mode for some other reason.) For now, this -doesn't work on the "any" device; if an argument of "any" or NULL is -supplied, the -.I promisc -flag is ignored. -.I to_ms -specifies the read timeout in milliseconds. The read timeout is used to -arrange that the read not necessarily return immediately when a packet -is seen, but that it wait for some amount of time to allow more packets -to arrive and to read multiple packets from the OS kernel in one -operation. Not all platforms support a read timeout; on platforms that -don't, the read timeout is ignored. A zero value for -.IR to_ms , -on platforms that support a read timeout, -will cause a read to wait forever to allow enough packets to -arrive, with no timeout. -.I errbuf -is used to return error or warning text. It will be set to error text when -.B pcap_open_live() -fails and returns -.BR NULL . -.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 -.I errbuf -before calling -.B pcap_open_live() -and display the warning to the user if -.I errbuf -is no longer a zero-length string. -.PP -.B pcap_open_dead() -is used for creating a -.B pcap_t -structure to use when calling the other functions in libpcap. It is -typically used when just using libpcap for compiling BPF code. -.PP -.B pcap_open_offline() -is called to open a ``savefile'' for reading. -.I fname -specifies the name of the file to open. The file has -the same format as those used by -.B tcpdump(1) -and -.BR tcpslice(1) . -The name "-" in a synonym for -.BR stdin . -Alternatively, you may call -.B pcap_fopen_offline() -to read dumped data from an existing open stream -.IR fp . -Note that on Windows, that stream should be opened in binary mode. -.I errbuf -is used to return error text and is only set when -.B pcap_open_offline() -or -.B pcap_fopen_offline() -fails and returns -.BR NULL . -.PP -.B pcap_dump_open() -is called to open a ``savefile'' for writing. The name "-" in a synonym -for -.BR stdout . -.B NULL -is returned on failure. -.I p -is a -.I pcap -struct as returned by -.B pcap_open_offline() -or -.BR pcap_open_live() . -.I fname -specifies the name of the file to open. Alternatively, you may call -.B pcap_dump_fopen() -to write data to an existing open stream -.IR fp . -Note that on Windows, that stream should be opened in binary mode. -If -.B NULL -is returned, -.B pcap_geterr() -can be used to get the error text. -.PP -.PP -.B pcap_setnonblock() -puts a capture descriptor, opened with -.BR pcap_open_live() , -into ``non-blocking'' mode, or takes it out of ``non-blocking'' mode, -depending on whether the -.I nonblock -argument is non-zero or zero. It has no effect on ``savefiles''. -If there is an error, \-1 is returned and -.I errbuf -is filled in with an appropriate error message; otherwise, 0 is -returned. -In -``non-blocking'' mode, an attempt to read from the capture descriptor -with -.B pcap_dispatch() -will, if no packets are currently available to be read, return 0 -immediately rather than blocking waiting for packets to arrive. -.B pcap_loop() -and -.B pcap_next() -will not work in ``non-blocking'' mode. -.PP -.B pcap_getnonblock() -returns the current ``non-blocking'' state of the capture descriptor; it -always returns 0 on ``savefiles''. -If there is an error, \-1 is returned and -.I errbuf -is filled in with an appropriate error message. -.PP -.B pcap_findalldevs() -constructs a list of network devices that can be opened with -.BR pcap_open_live() . -(Note that there may be network devices that cannot be opened with -.BR pcap_open_live() -by the -process calling -.BR pcap_findalldevs() , -because, for example, that process might not have sufficient privileges -to open them for capturing; if so, those devices will not appear on the -list.) -.I alldevsp -is set to point to the first element of the list; each element of the -list is of type -.BR pcap_if_t , -and has the following members: -.RS -.TP -.B next -if not -.BR NULL , -a pointer to the next element in the list; -.B NULL -for the last element of the list -.TP -.B name -a pointer to a string giving a name for the device to pass to -.B pcap_open_live() -.TP -.B description -if not -.BR NULL , -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 -.TP -.B flags -interface flags: -.RS -.TP -.B PCAP_IF_LOOPBACK -set if the interface is a loopback interface -.RE -.RE -.PP -Each element of the list of addresses is of type -.BR pcap_addr_t , -and has the following members: -.RS -.TP -.B next -if not -.BR NULL , -a pointer to the next element in the list; -.B NULL -for the last element of the list -.TP -.B addr -a pointer to a -.B "struct sockaddr" -containing an address -.TP -.B netmask -if not -.BR NULL , -a pointer to a -.B "struct sockaddr" -that contains the netmask corresponding to the address pointed to by -.B addr -.TP -.B broadaddr -if not -.BR NULL , -a pointer to a -.B "struct sockaddr" -that contains the broadcast address corresponding to the address pointed -to by -.BR addr ; -may be null if the interface doesn't support broadcasts -.TP -.B dstaddr -if not -.BR NULL , -a pointer to a -.B "struct sockaddr" -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 -.RE -.PP -Note that not all the addresses in the list of addresses are -necessarily IPv4 or IPv6 addresses - you must check the -.B sa_family -member of the -.B "struct sockaddr" -before interpreting the contents of the address. -.PP -.B \-1 -is returned on failure, in which case -.B errbuf -is filled in with an appropriate error message; -.B 0 -is returned on success. -.PP -.B pcap_freealldevs() -is used to free a list allocated by -.BR pcap_findalldevs() . -.PP -.B pcap_lookupdev() -returns a pointer to a network device suitable for use with -.B pcap_open_live() -and -.BR pcap_lookupnet() . -If there is an error, -.B NULL -is returned and -.I errbuf -is filled in with an appropriate error message. -.PP -.B pcap_lookupnet() -is used to determine the network number and mask -associated with the network device -.BR device . -Both -.I netp -and -.I maskp -are -.I bpf_u_int32 -pointers. -A return of \-1 indicates an error in which case -.I errbuf -is filled in with an appropriate error message. -.PP -.B pcap_dispatch() -is used to collect and process packets. -.I cnt -specifies the maximum number of packets to process before returning. -This is not a minimum number; when reading a live capture, only one -bufferful of packets is read at a time, so fewer than -.I cnt -packets may be processed. A -.I cnt -of \-1 processes all the packets received in one buffer when reading a -live capture, or all the packets in the file when reading a -``savefile''. -.I callback -specifies a routine to be called with three arguments: -a -.I u_char -pointer which is passed in from -.BR pcap_dispatch() , -a -.I const struct pcap_pkthdr -pointer to a structure with the following members: -.RS -.TP -.B ts -a -.I struct timeval -containing the time when the packet was captured -.TP -.B caplen -a -.I bpf_u_int32 -giving the number of bytes of the packet that are available from the -capture -.TP -.B len -a -.I bpf_u_int32 -giving the length of the packet, in bytes (which might be more than the -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 -and a -.I const u_char -pointer to the first -.B caplen -(as given in the -.I struct pcap_pkthdr -a pointer to which is passed to the callback routine) -bytes of data from the packet (which won't necessarily be the entire -packet; to capture the entire packet, you will have to provide a value -for -.I snaplen -in your call to -.B pcap_open_live() -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). -.PP -The number of packets read is returned. -0 is returned 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.'' A return of \-1 indicates -an error in which case -.B pcap_perror() -or -.B pcap_geterr() -may be used to display the error text. -A return of \-2 indicates that the loop terminated due to a call to -.B pcap_breakloop() -before any packets were processed. -.ft B -If your application uses pcap_breakloop(), -make sure that you explicitly check for \-1 and \-2, rather than just -checking for a return value < 0. -.ft R -.PP -.BR NOTE : -when reading a live capture, -.B pcap_dispatch() -will not necessarily return when the read times out; on some platforms, -the read timeout isn't supported, and, on other platforms, the timer -doesn't start until at least one packet arrives. This means that the -read timeout should -.B NOT -be used in, for example, an interactive application, to allow the packet -capture loop to ``poll'' for user input periodically, as there's no -guarantee that -.B pcap_dispatch() -will return after the timeout expires. -.PP -.B pcap_loop() -is similar to -.B pcap_dispatch() -except it keeps reading packets until -.I cnt -packets are processed or an error occurs. -It does -.B not -return when live read timeouts occur. -Rather, specifying a non-zero read timeout to -.B pcap_open_live() -and then calling -.B pcap_dispatch() -allows the reception and processing of any packets that arrive when the -timeout occurs. -A negative -.I cnt -causes -.B pcap_loop() -to loop forever (or at least until an error occurs). \-1 is returned on -an error; 0 is returned if -.I cnt -is exhausted; \-2 is returned if the loop terminated due to a call to -.B pcap_breakloop() -before any packets were processed. -.ft B -If your application uses pcap_breakloop(), -make sure that you explicitly check for \-1 and \-2, rather than just -checking for a return value < 0. -.ft R -.PP -.B pcap_next() -reads the next packet (by calling -.B pcap_dispatch() -with a -.I cnt -of 1) and returns a -.I u_char -pointer to the data in that packet. (The -.I pcap_pkthdr -struct for that packet is not supplied.) -.B NULL -is returned if an error occured, 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. -.PP -.B pcap_next_ex() -reads the next packet and returns a success/failure indication: -.RS -.TP -1 -the packet was read without problems -.TP -0 -packets are being read from a live capture, and the timeout expired -.TP -\-1 -an error occurred while reading the packet -.TP -\-2 -packets are being read from a ``savefile'', and there are no more -packets to read from the savefile. -.RE -.PP -If the packet was read without problems, the pointer pointed to by the -.I pkt_header -argument is set to point to the -.I pcap_pkthdr -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. -.PP -.B pcap_breakloop() -sets a flag that will force -.B pcap_dispatch() -or -.B pcap_loop() -to return rather than looping; they will return the number of packets -that have been processed so far, or \-2 if no packets have been -processed so far. -.PP -This routine is safe to use inside a signal handler on UNIX or a console -control handler on Windows, as it merely sets a flag that is checked -within the loop. -.PP -The flag is checked in loops reading packets from the OS - a signal by -itself will not necessarily terminate those loops - as well as in loops -processing a set of packets returned by the OS. -.ft B -Note that if you are catching signals on UNIX systems that support -restarting system calls after a signal, and calling pcap_breakloop() -in the signal handler, you must specify, when catching those signals, -that system calls should NOT be restarted by that signal. Otherwise, -if the signal interrupted a call reading packets in a live capture, -when your signal handler returns after calling pcap_breakloop(), the -call will be restarted, and the loop will not terminate until more -packets arrive and the call completes. -.PP -Note also that, in a multi-threaded application, if one thread is -blocked in -.BR pcap_dispatch() , -.BR pcap_loop() , -.BR pcap_next() , -or -.BR pcap_next_ex() , -a call to -.B pcap_breakloop() -in a different thread will not unblock that thread; you will need to use -whatever mechanism the OS provides for breaking a thread out of blocking -calls in order to unblock the thread, such as thread cancellation in -systems that support POSIX threads. -.ft R -.PP -Note that -.B pcap_next() -will, on some platforms, loop reading packets from the OS; that loop -will not necessarily be terminated by a signal, so -.B pcap_breakloop() -should be used to terminate packet processing even if -.B pcap_next() -is being used. -.PP -.B pcap_breakloop() -does not guarantee that no further packets will be processed by -.B pcap_dispatch() -or -.B pcap_loop() -after it is called; at most one more packet might be processed. -.PP -If \-2 is returned from -.B pcap_dispatch() -or -.BR pcap_loop() , -the flag is cleared, so a subsequent call will resume reading packets. -If a positive number is returned, the flag is not cleared, so a -subsequent call will return \-2 and clear the flag. -.PP -.B pcap_inject() -sends a raw packet through the network interface; -.I buf -points to the data of the packet, including the link-layer header, and -.I size -is the number of bytes in the packet. -It returns the number of bytes written on success. A return of \-1 -indicates an error in which case -.B pcap_perror() -or -.B pcap_geterr() -may be used to display the error text. -Note that, even if you successfully open the network interface, you -might not have permission to send packets on it, or it might not support -sending packets; as -.I pcap_open_live() -doesn't have a flag to indicate whether to open for capturing, sending, -or capturing and sending, you cannot request an open that supports -sending and be notified at open time whether sending will be possible. -Note also that some devices might not support sending packets. -.PP -Note that, on some platforms, the link-layer header of the packet that's -sent might not be the same as the link-layer header of the packet -supplied to -.BR pcap_inject() , -as the source link-layer address, if the header contains such an -address, might be changed to be the address assigned to the interface on -which the packet it sent, if the platform doesn't support sending -completely raw and unchanged packets. Even worse, some drivers on some -platforms might change the link-layer type field to whatever value -libpcap used when attaching to the device, even on platforms that -.I do -nominally support sending completely raw and unchanged packets. -.PP -.B pcap_sendpacket() -is like -.BR pcap_inject() , -but it returns 0 on success and \-1 on failure. -.RB ( pcap_inject() -comes from OpenBSD; -.B pcap_sendpacket() -comes from WinPcap. Both are provided for compatibility.) -.PP -.B pcap_dump() -outputs a packet to the ``savefile'' opened with -.BR pcap_dump_open() . -Note that its calling arguments are suitable for use with -.B pcap_dispatch() -or -.BR pcap_loop() . -If called directly, the -.I user -parameter is of type -.I pcap_dumper_t -as returned by -.BR pcap_dump_open() . -.PP -.B pcap_compile() -is used to compile the string -.I str -into a filter program. -.I program -is a pointer to a -.I bpf_program -struct and is filled in by -.BR pcap_compile() . -.I optimize -controls whether optimization on the resulting code is performed. -.I netmask -specifies the IPv4 netmask of the network on which packets are being -captured; it is used only when checking for IPv4 broadcast addresses in -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 0 can be supplied; tests for IPv4 broadcast -addreses won't be done correctly, but all other tests in the filter -program will be OK. A return of \-1 indicates an error in which case -.BR pcap_geterr() -may be used to display the error text. -.PP -.B pcap_compile_nopcap() -is similar to -.B pcap_compile() -except that instead of passing a pcap structure, one passes the -snaplen and linktype explicitly. It is intended to be used for -compiling filters for direct BPF usage, without necessarily having -called -.BR pcap_open() . -A return of \-1 indicates an error; the error text is unavailable. -.RB ( pcap_compile_nopcap() -is a wrapper around -.BR pcap_open_dead() , -.BR pcap_compile() , -and -.BR pcap_close() ; -the latter three routines can be used directly in order to get the error -text for a compilation error.) -.B -.PP -.B pcap_setfilter() -is used to specify a filter program. -.I fp -is a pointer to a -.I bpf_program -struct, usually the result of a call to -.BR pcap_compile() . -.B \-1 -is returned on failure, in which case -.BR pcap_geterr() -may be used to display the error text; -.B 0 -is returned on success. -.PP -.B pcap_freecode() -is used to free up allocated memory pointed to by a -.I bpf_program -struct generated by -.B pcap_compile() -when that BPF program is no longer needed, for example after it -has been made the filter program for a pcap structure by a call to -.BR pcap_setfilter() . -.PP -.B pcap_setdirection() -is used to specify a direction that packets will be captured. -.I pcap_direction_t -is one of the constants -.BR PCAP_D_IN , -.B PCAP_D_OUT -or -.BR PCAP_D_INOUT . -.B PCAP_D_IN -will only capture packets received by the device, -.B PCAP_D_OUT -will only capture packets sent by the device and -.B PCAP_D_INOUT -will capture packets received by or sent by the device. -.B PCAP_D_INOUT -is the default setting if this function is not called. This isn't -necessarily supported on all platforms; some platforms might return an -error, and some other platforms might not support -.BR PCAP_D_OUT . -This operation is not supported if a ``savefile'' is being read. -.B \-1 -is returned on failure, -.B 0 -is returned on success. -.PP -.B pcap_datalink() -returns the link layer type; link layer types it can return include: -.PP -.RS 5 -.TP 5 -.B DLT_NULL -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 -.B DLT_EN10MB -Ethernet (10Mb, 100Mb, 1000Mb, and up) -.TP 5 -.B DLT_IEEE802 -IEEE 802.5 Token Ring -.TP 5 -.B DLT_ARCNET -ARCNET -.TP 5 -.B DLT_SLIP -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 -.B DLT_PPP -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 -.B DLT_FDDI -FDDI -.TP 5 -.B DLT_ATM_RFC1483 -RFC 1483 LLC/SNAP-encapsulated ATM; the packet begins with an IEEE 802.2 -LLC header. -.TP 5 -.B DLT_RAW -raw IP; the packet begins with an IP header. -.TP 5 -.B DLT_PPP_SERIAL -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 -.B DLT_PPP_ETHER -PPPoE; the packet begins with a PPPoE header, as per RFC 2516. -.TP 5 -.B DLT_C_HDLC -Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547. -.TP 5 -.B DLT_IEEE802_11 -IEEE 802.11 wireless LAN -.TP 5 -.B DLT_FRELAY -Frame Relay -.TP 5 -.B DLT_LOOP -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 -.B DLT_LINUX_SLL -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 header -(if there are more than 8 bytes, only the first 8 are present); -.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 -.B DLT_LTALK -Apple LocalTalk; the packet begins with an AppleTalk LLAP header. -.TP 5 -.B DLT_PFLOG -OpenBSD pflog; the link layer header contains, in order: -.RS 10 -.LP -a 1-byte header length, in host byte order; -.LP -a 4-byte PF_ value, in host byte order; -.LP -a 2-byte action code, in network byte order, which is one of: -.RS 5 -.TP 5 -0 -passed -.TP 5 -1 -dropped -.TP 5 -2 -scrubbed -.RE -.LP -a 2-byte reason code, in network byte order, which is one of: -.RS 5 -.TP 5 -0 -match -.TP 5 -1 -bad offset -.TP 5 -2 -fragment -.TP 5 -3 -short -.TP 5 -4 -normalize -.TP 5 -5 -memory -.RE -.LP -a 16-character interface name; -.LP -a 16-character ruleset name (only meaningful if subrule is set); -.LP -a 4-byte rule number, in network byte order; -.LP -a 4-byte subrule number, in network byte order; -.LP -a 1-byte direction, in network byte order, which is one of: -.RS 5 -.TP 5 -0 -incoming or outgoing -.TP 5 -1 -incoming -.TP 5 -2 -outgoing -.RE -.RE -.TP 5 -.B DLT_PRISM_HEADER -Prism monitor mode information followed by an 802.11 header. -.TP 5 -.B DLT_IP_OVER_FC -RFC 2625 IP-over-Fibre Channel, with the link-layer header being the -Network_Header as described in that RFC. -.TP 5 -.B DLT_SUNATM -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 -.B DLT_IEEE802_11_RADIO -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 -.B DLT_ARCNET_LINUX -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 -.B DLT_LINUX_IRDA -Linux-IrDA packets, with a -.B DLT_LINUX_SLL -header followed by the IrLAP header. -.TP 5 -.B DLT_LINUX_LAPD -LAPD (Q.921) frames, with a -.B DLT_LINUX_SLL -header captured via vISDN. -.RE -.PP -.B pcap_list_datalinks() -is used to get a list of the supported data link 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 . -The caller is responsible for freeing the array. -.B \-1 -is returned on failure; -otherwise, the number of data link types in the array is returned. -.PP -.B pcap_set_datalink() -is used to set the current data link type of the pcap descriptor -to the type specified by -.IR dlt . -.B \-1 -is returned on failure. -.PP -.B pcap_datalink_name_to_val() -translates a data link 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. -.B \-1 -is returned on failure. -.PP -.B pcap_datalink_val_to_name() -translates a data link type value to the corresponding data link 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. -.PP -.B pcap_snapshot() -returns the snapshot length specified when -.B pcap_open_live() -was called. -.PP -.B pcap_is_swapped() -returns true if the current ``savefile'' uses a different byte order -than the current system. -.PP -.B pcap_major_version() -returns the major number of the file format of the savefile; -.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. -.PP -.B pcap_file() -returns the standard I/O stream of the ``savefile,'' if a ``savefile'' -was opened with -.BR pcap_open_offline() , -or NULL, if a network device was opened with -.BR pcap_open_live() . -.PP -.B pcap_stats() -returns 0 and fills in the -.B pcap_stat -structure pointed to by its second argument. The values represent -packet statistics from the start of the run to the time of the call. If -there is an error or the underlying packet capture doesn't support -packet statistics, \-1 is returned and the error text can be obtained -with -.B pcap_perror() -or -.BR pcap_geterr() . -.B pcap_stats() -is supported only on live captures, not on ``savefiles''; no statistics -are stored in ``savefiles'', so no statistics are available when reading -from a ``savefile''. -.PP -.B pcap_fileno() -returns the file descriptor number from which captured packets are read, -if a network device was opened with -.BR pcap_open_live() , -or \-1, if a ``savefile'' was opened with -.BR pcap_open_offline() . -.PP -.B pcap_get_selectable_fd() -returns, on UNIX, a file descriptor number for a file descriptor on -which one can -do a -.B select() -or -.B poll() -to wait for it to be possible to read packets without blocking, if such -a descriptor exists, or \-1, if no such descriptor exists. Some network -devices opened with -.B pcap_open_live() -do not support -.B select() -or -.B poll() -(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) -.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 -.B select() -or -.B poll() -will not return even after a timeout specified in -.B pcap_open_live() -expires. To work around this, an application that uses -.B select() -or -.B poll() -to wait for packets to arrive must put the -.B pcap_t -in non-blocking mode, and must arrange that the -.B select() -or -.B poll() -have a timeout less than or equal to the timeout specified in -.BR pcap_open_live() , -and must try to read packets after that timeout expires, regardless of -whether -.B select() -or -.B poll() -indicated that the file descriptor for the -.B pcap_t -is ready to be read or not. (That workaround will not work in FreeBSD -4.3 and later; however, in FreeBSD 4.6 and later, -.B select() -and -.B poll() -work correctly on BPF devices, so the workaround isn't necessary, -although it does no harm.) -.PP -.B pcap_get_selectable_fd() -is not available on Windows. -.PP -.B pcap_perror() -prints the text of the last pcap library error on -.BR stderr , -prefixed by -.IR prefix . -.PP -.B pcap_geterr() -returns the error text pertaining to the last pcap library error. -.BR NOTE : -the pointer it returns will no longer point to a valid error message -string after the -.B pcap_t -passed to it is closed; you must use or copy the string before closing -the -.BR pcap_t . -.PP -.B pcap_strerror() -is provided in case -.BR strerror (1) -isn't available. -.PP -.B pcap_lib_version() -returns a pointer to a string giving information about the version of -the libpcap library being used; note that it contains more information -than just a version number. -.PP -.B pcap_close() -closes the files associated with -.I p -and deallocates resources. -.PP -.B pcap_dump_file() -returns the standard I/O stream of the ``savefile'' opened by -.BR pcap_dump_open(). -.PP -.B pcap_dump_flush() -flushes the output buffer to the ``savefile,'' so that any packets -written with -.B pcap_dump() -but not yet written to the ``savefile'' will be written. -.B \-1 -is returned on error, 0 on success. -.PP -.B pcap_dump_ftell() -returns the current file position for the ``savefile'', representing the -number of bytes written by -.B pcap_dump_open() -and -.BR pcap_dump() . -.B \-1 -is returned on error. -.PP -.B pcap_dump_close() -closes the ``savefile.'' -.PP -.SH SEE ALSO -tcpdump(1), tcpslice(1) -.SH AUTHORS -The original authors are: -.LP -Van Jacobson, -Craig Leres and -Steven McCanne, all of the -Lawrence Berkeley National Laboratory, University of California, Berkeley, CA. -.LP -The current version is available from "The Tcpdump Group"'s Web site at -.LP -.RS -.I http://www.tcpdump.org/ -.RE -.SH BUGS -Please send problems, bugs, questions, desirable enhancements, etc. to: -.LP -.RS -tcpdump-workers@tcpdump.org -.RE -.LP -Please send source code contributions, etc. to: -.LP -.RS -patches@tcpdump.org -.RE diff --git a/contrib/libpcap/pcap.3pcap.in b/contrib/libpcap/pcap.3pcap.in new file mode 100644 index 0000000000..1c66508371 --- /dev/null +++ b/contrib/libpcap/pcap.3pcap.in @@ -0,0 +1,386 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3pcap.in,v 1.1.2.2 2008-10-21 07:44:57 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 3PCAP "4 April 2008" +.SH NAME +pcap \- Packet Capture library +.SH SYNOPSIS +.nf +.ft B +#include +.LP +.ft B +.ft +.fi +.SH DESCRIPTION +The Packet Capture library +provides a high level interface to packet capture systems. All packets +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() , +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() +and +.B pcap_open_offline() +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''. +.PP +The options that can be set on a capture handle include +.IP "snapshot length" +If, when capturing, you capture the entire contents of the packet, that +requires more CPU time to copy the packet to your application, more disk +and possibly network bandwidth to write the packet data to a file, and +more disk space to save the packet. If you don't need the entire +contents of the packet - for example, if you are only interested in the +TCP headers of packets - you can set the "snapshot length" for the +capture to an appropriate value. If the snapshot length is set to +.IR snaplen , +and +.I snaplen +is less +than the size of a packet that is captured, only the first +.I snaplen +bytes of that packet will be captured and provided as packet data. +.IP +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() . +.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 +packets passing through the switch are sent, a network adapter receives +all packets on the LAN, including unicast or multicast packets not sent +to a network address that the network adapter isn't configured to +recognize. +.IP +Normally, the adapter will discard those packets; however, many network +adapters support "promiscuous mode", which is a mode in which all +packets, even if they are not sent to an address that the adapter +recognizes, are provided to the host. This is useful for passively +capturing traffic between two or more other hosts for analysis. +.IP +Note that even if an application does not set promiscuous mode, the +adapter could well be in promiscuous mode for some other reason. +.IP +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() . +.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 +associated. It might also supply only data frames, not management or +control frames, and might not provide the 802.11 header or radio +information pseudo-header for those frames. +.IP +In "monitor mode", sometimes also called "rfmon mode" (for "Radio +Frequency MONitor"), the adapter will supply all frames that it +receives, with 802.11 headers, and might supply a pseudo-header with +radio information about the frame as well. +.IP +Note that in monitor mode the adapter might disassociate from the +network with which it's associated, so that you will not be able to use +any wireless networks with that adapter. This could prevent accessing +files on a network server, or resolving host names or network addresses, +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() , +and +.B pcap_can_set_rfmon() +can be used to determine whether an adapter can be put into monitor +mode. +.IP "read timeout" +If, when capturing, packets are delivered as soon as they arrive, the +application capturing the packets will be woken up for each packet as it +arrives, and might have to make one or more calls to the operating +system to fetch each packet. +.IP +If, instead, packets are not delivered as soon as they arrive, but are +delivered after a short delay (called a "read timeout"), more than one +packet can be accumulated before the packets are delivered, so that a +single wakeup would be done for multiple packets, and each set of calls +made to the operating system would supply multiple packets, rather than +a single packet. This reduces the per-packet CPU overhead if packets +are arriving at a high rate, increasing the number of packets per second +that can be captured. +.IP +The read timeout is required so that an application won't wait for the +operating system's capture buffer to fill up before packets are +delivered; if packets are arriving slowly, that wait could take an +arbitrarily long period of time. +.IP +Not all platforms support a read timeout; on platforms that +don't, the read timeout is ignored. A zero value for the timeout, +on platforms that support a read timeout, +will cause a read to wait forever to allow enough packets to +arrive, with no timeout. +.IP +.BR NOTE : +the read timeout cannot be used to cause calls that read +packets to return within a limited period of time, because, on some +platforms, the read timeout isn't supported, and, on other platforms, +the timer doesn't start until at least one packet arrives. This means +that the read timeout should +.B NOT +be used, for example, in an interactive application to allow the packet +capture loop to ``poll'' for user input periodically, as there's no +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() . +.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 +some platforms, the buffer's size can be set; a size that's too small +could mean that, if too many packets are being captured and the snapshot +length doesn't limit the amount of data that's buffered, packets could +be dropped if the buffer fills up before the application can read +packets from it, while a size that's too large could use more +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() . +.PP +Reading packets from a network interface may require that you have +special privileges: +.TP +.B Under SunOS 3.x or 4.x with NIT or BPF: +You must have read access to +.I /dev/nit +or +.IR /dev/bpf* . +.TP +.B Under Solaris with DLPI: +You must have read/write access to the network pseudo device, e.g. +.IR /dev/le . +On at least some versions of Solaris, however, this is not sufficient to +allow +.I tcpdump +to capture in promiscuous mode; on those versions of Solaris, you must +be root, or the application capturing packets +must be installed setuid to root, in order to capture in promiscuous +mode. Note that, on many (perhaps all) interfaces, if you don't capture +in promiscuous mode, you will not see any outgoing packets, so a capture +not done in promiscuous mode may not be very useful. +.IP +In newer versions of Solaris, you must have been given the +.B net_rawaccess +privilege; this is both necessary and sufficient to give you access to the +network pseudo-device - there is no need to change the privileges on +that device. A user can be given that privilege by, for example, adding +that privilege to the user's +.B defaultpriv +key with the +.B usermod (1M) +command. +.TP +.B Under HP-UX with DLPI: +You must be root or the application capturing packets must be installed +setuid to root. +.TP +.B Under IRIX with snoop: +You must be root or the application capturing packets must be installed +setuid to root. +.TP +.B Under Linux: +You must be root or the application capturing packets must be installed +setuid to root (unless your distribution has a kernel +that supports capability bits such as CAP_NET_RAW and code to allow +those capability bits to be given to particular accounts and to cause +those bits to be set on a user's initial processes when they log in, in +which case you must have CAP_NET_RAW in order to capture and +CAP_NET_ADMIN to enumerate network devices with, for example, the +.B \-D +flag). +.TP +.B Under ULTRIX and Digital UNIX/Tru64 UNIX: +Any user may capture network traffic. +However, no user (not even the super-user) can capture in promiscuous +mode on an interface unless the super-user has enabled promiscuous-mode +operation on that interface using +.IR pfconfig (8), +and no user (not even the super-user) can capture unicast traffic +received by or sent by the machine on an interface unless the super-user +has enabled copy-all-mode operation on that interface using +.IR pfconfig , +so +.I useful +packet capture on an interface probably requires that either +promiscuous-mode or copy-all-mode operation, or both modes of +operation, be enabled on that interface. +.TP +.B Under BSD (this includes Mac OS X): +You must have read access to +.I /dev/bpf* +on systems that don't have a cloning BPF device, or to +.I /dev/bpf +on systems that do. +On BSDs with a devfs (this includes Mac OS X), this might involve more +than just having somebody with super-user access setting the ownership +or permissions on the BPF devices - it might involve configuring devfs +to set the ownership or permissions every time the system is booted, +if the system even supports that; if it doesn't support that, you might +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''. +.PP +Packets are read with +.B pcap_dispatch() +or +.BR pcap_loop() , +which process one or more packets, calling a callback routine for each +packet, or with +.B pcap_next() +or +.BR pcap_next_ex() , +which return the next packet. +The callback for +.B pcap_dispatch() +and +.BR pcap_loop() +is supplied a pointer to a +.IR "struct pcap_pkthdr" , +which includes the following members: +.RS +.TP +.B ts +a +.I struct timeval +containing the time when the packet was captured +.TP +.B caplen +a +.I bpf_u_int32 +giving the number of bytes of the packet that are available from the +capture +.TP +.B len +a +.I bpf_u_int32 +giving the length of the packet, in bytes (which might be more than the +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() +supplies that pointer through a pointer argument. +.B pcap_next() +is passed an argument that points to a +.I struct pcap_pkthdr +structure, and fills it in. +.PP +The callback is also supplied a +.I const u_char +pointer to the first +.B caplen +(as given in the +.I struct pcap_pkthdr +a pointer to which is passed to the callback routine) +bytes of data from the packet. This won't necessarily be the entire +packet; to capture the entire packet, you will have to provide a value +for +.I snaplen +in your call to +.B pcap_open_live() +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() +returns that pointer; +.B pcap_next_ex() +supplies that pointer through a pointer argument. +.SH BACKWARDS COMPATIBILITY +.PP +In versions of libpcap prior to 1.0, the +.B pcap.h +header file was not in a +.B pcap +directory on most platforms; if you are writing an application that must +work on versions of libpcap prior to 1.0, include +.BR , +which will include +.B +for you, rather than including +.BR . +.PP +.B pcap_create() +and +.B 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() +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() +and +.BR pcap_activate() , +use an +.BR autoconf (1) +script or some other configuration script to check whether the libpcap +1.0 APIs are available and use them only if they are. +.SH SEE ALSO +autoconf(1), tcpdump(1), tcpslice(1), pcap-filter(@MAN_MISC_INFO@), pfconfig(8), +usermod(1M) +.SH AUTHORS +The original authors of libpcap are: +.LP +Van Jacobson, +Craig Leres and +Steven McCanne, all of the +Lawrence Berkeley National Laboratory, University of California, Berkeley, CA. +.LP +The current version is available from "The Tcpdump Group"'s Web site at +.LP +.RS +.I http://www.tcpdump.org/ +.RE +.SH BUGS +Please send problems, bugs, questions, desirable enhancements, etc. to: +.LP +.RS +tcpdump-workers@lists.tcpdump.org +.RE diff --git a/contrib/libpcap/pcap.c b/contrib/libpcap/pcap.c index 0822e1adf0..010ef74cd0 100644 --- a/contrib/libpcap/pcap.c +++ b/contrib/libpcap/pcap.c @@ -33,7 +33,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.88.2.19 2007/09/19 02:50:52 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.112.2.12 2008-09-22 20:16:01 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -70,10 +70,205 @@ static const char rcsid[] _U_ = #include #endif +int +pcap_not_initialized(pcap_t *pcap) +{ + /* this means 'not initialized' */ + return PCAP_ERROR_NOT_ACTIVATED; +} + +/* + * Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't, + * a PCAP_ERROR value on an error. + */ int -pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +pcap_can_set_rfmon(pcap_t *p) +{ + return (p->can_set_rfmon_op(p)); +} + +/* + * For systems where rfmon mode is never supported. + */ +static int +pcap_cant_set_rfmon(pcap_t *p _U_) +{ + return (0); +} + +pcap_t * +pcap_create_common(const char *source, char *ebuf) +{ + pcap_t *p; + + p = malloc(sizeof(*p)); + if (p == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + return (NULL); + } + memset(p, 0, sizeof(*p)); +#ifndef WIN32 + p->fd = -1; /* not opened yet */ +#endif + + p->opt.source = strdup(source); + if (p->opt.source == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + free(p); + return (NULL); + } + + /* + * Default to "can't set rfmon mode"; if it's supported by + * a platform, it can set the op to its routine to check + * whether a particular device supports it. + */ + p->can_set_rfmon_op = pcap_cant_set_rfmon; + + /* + * Some operations can be performed only on activated pcap_t's; + * have those operations handled by a "not supported" handler + * until the pcap_t is activated. + */ + p->read_op = (read_op_t)pcap_not_initialized; + p->inject_op = (inject_op_t)pcap_not_initialized; + p->setfilter_op = (setfilter_op_t)pcap_not_initialized; + p->setdirection_op = (setdirection_op_t)pcap_not_initialized; + p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized; + p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized; + p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized; + p->stats_op = (stats_op_t)pcap_not_initialized; +#ifdef WIN32 + p->setbuff_op = (setbuff_op_t)pcap_not_initialized; + p->setmode_op = (setmode_op_t)pcap_not_initialized; + p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized; +#endif + p->cleanup_op = pcap_cleanup_live_common; + + /* put in some defaults*/ + pcap_set_timeout(p, 0); + pcap_set_snaplen(p, 65535); /* max packet size */ + p->opt.promisc = 0; + p->opt.buffer_size = 0; + return (p); +} + +int +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 0; +} + +int +pcap_set_snaplen(pcap_t *p, int snaplen) +{ + if (pcap_check_activated(p)) + return PCAP_ERROR_ACTIVATED; + p->snapshot = snaplen; + return 0; +} + +int +pcap_set_promisc(pcap_t *p, int promisc) +{ + if (pcap_check_activated(p)) + return PCAP_ERROR_ACTIVATED; + p->opt.promisc = promisc; + return 0; +} + +int +pcap_set_rfmon(pcap_t *p, int rfmon) +{ + if (pcap_check_activated(p)) + return PCAP_ERROR_ACTIVATED; + p->opt.rfmon = rfmon; + return 0; +} + +int +pcap_set_timeout(pcap_t *p, int timeout_ms) { + if (pcap_check_activated(p)) + return PCAP_ERROR_ACTIVATED; + p->md.timeout = timeout_ms; + return 0; +} + +int +pcap_set_buffer_size(pcap_t *p, int buffer_size) +{ + if (pcap_check_activated(p)) + return PCAP_ERROR_ACTIVATED; + p->opt.buffer_size = buffer_size; + return 0; +} + +int +pcap_activate(pcap_t *p) +{ + int status; + status = p->activate_op(p); + if (status >= 0) + p->activated = 1; + return (status); +} + +pcap_t * +pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf) +{ + pcap_t *p; + int status; + + p = pcap_create(source, errbuf); + if (p == NULL) + return (NULL); + status = pcap_set_snaplen(p, snaplen); + if (status < 0) + goto fail; + status = pcap_set_promisc(p, promisc); + if (status < 0) + goto fail; + status = pcap_set_timeout(p, to_ms); + if (status < 0) + goto fail; + /* + * Mark this as opened with pcap_open_live(), so that, for + * example, we show the full list of DLT_ values, rather + * than just the ones that are compatible with capturing + * when not in monitor mode. That allows existing applications + * to work the way they used to work, but allows new applications + * that know about the new open API to, for example, find out the + * DLT_ values that they can select without changing whether + * the adapter is in monitor mode or not. + */ + p->oldstyle = 1; + status = pcap_activate(p); + if (status < 0) + goto fail; + return (p); +fail: + if (status == PCAP_ERROR || status == PCAP_ERROR_NO_SUCH_DEVICE || + status == PCAP_ERROR_PERM_DENIED) + strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE); + else + snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, + pcap_statustostr(status)); + pcap_close(p); + return (NULL); +} + +int +pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ return p->read_op(p, cnt, callback, user); } @@ -221,6 +416,12 @@ pcap_datalink(pcap_t *p) return (p->linktype); } +int +pcap_datalink_ext(pcap_t *p) +{ + return (p->linktype_ext); +} + int pcap_list_datalinks(pcap_t *p, int **dlt_buffer) { @@ -252,6 +453,23 @@ pcap_list_datalinks(pcap_t *p, int **dlt_buffer) } } +/* + * 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_datalinks() routine to free up the list + * allocated by pcap_list_datalinks(), even though it's just a wrapper + * around free(). + */ +void +pcap_free_datalinks(int *dlt_list) +{ + free(dlt_list); +} + int pcap_set_datalink(pcap_t *p, int dlt) { @@ -327,7 +545,7 @@ static struct dlt_choice dlt_choices[] = { DLT_CHOICE(DLT_NULL, "BSD loopback"), DLT_CHOICE(DLT_EN10MB, "Ethernet"), DLT_CHOICE(DLT_IEEE802, "Token ring"), - DLT_CHOICE(DLT_ARCNET, "ARCNET"), + DLT_CHOICE(DLT_ARCNET, "BSD ARCNET"), DLT_CHOICE(DLT_SLIP, "SLIP"), DLT_CHOICE(DLT_PPP, "PPP"), DLT_CHOICE(DLT_FDDI, "FDDI"), @@ -338,6 +556,7 @@ static struct dlt_choice dlt_choices[] = { DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"), DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"), DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"), + DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"), DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"), DLT_CHOICE(DLT_IEEE802_11, "802.11"), DLT_CHOICE(DLT_FRELAY, "Frame Relay"), @@ -349,17 +568,25 @@ static struct dlt_choice dlt_choices[] = { DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"), DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"), DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"), - DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus BSD radio information header"), - DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"), + DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus radiotap header"), DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"), + DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"), + DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"), + DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"), + DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"), + DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"), + DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"), + DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"), + DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"), + DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"), + DLT_CHOICE(DLT_MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"), + DLT_CHOICE(DLT_MTP2, "SS7 MTP2"), + DLT_CHOICE(DLT_MTP3, "SS7 MTP3"), + DLT_CHOICE(DLT_SCCP, "SS7 SCCP"), DLT_CHOICE(DLT_DOCSIS, "DOCSIS"), DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"), - DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"), DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"), - DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"), - DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"), - DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"), - DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"), + DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"), DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"), DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"), DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"), @@ -367,27 +594,35 @@ static struct dlt_choice dlt_choices[] = { DLT_CHOICE(DLT_GPF_T, "GPF-T"), DLT_CHOICE(DLT_GPF_F, "GPF-F"), DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"), - DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"), DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"), DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"), - DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"), - DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"), - DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"), - DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"), - DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"), + DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"), DLT_CHOICE(DLT_JUNIPER_ETHER, "Juniper Ethernet"), DLT_CHOICE(DLT_JUNIPER_PPP, "Juniper PPP"), DLT_CHOICE(DLT_JUNIPER_FRELAY, "Juniper Frame Relay"), DLT_CHOICE(DLT_JUNIPER_CHDLC, "Juniper C-HDLC"), DLT_CHOICE(DLT_MFR, "FRF.16 Frame Relay"), DLT_CHOICE(DLT_JUNIPER_VP, "Juniper Voice PIC"), - DLT_CHOICE(DLT_MTP2, "SS7 MTP2"), DLT_CHOICE(DLT_A429, "Arinc 429"), DLT_CHOICE(DLT_A653_ICM, "Arinc 653 Interpartition Communication"), DLT_CHOICE(DLT_USB, "USB"), DLT_CHOICE(DLT_BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"), + DLT_CHOICE(DLT_IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"), + DLT_CHOICE(DLT_USB_LINUX, "USB with Linux header"), DLT_CHOICE(DLT_CAN20B, "Controller Area Network (CAN) v. 2.0B"), - DLT_CHOICE(DLT_MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"), + DLT_CHOICE(DLT_IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"), + 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_SITA, "SITA pseudo-header"), + DLT_CHOICE(DLT_ERF, "Endace ERF header"), + DLT_CHOICE(DLT_RAIF1, "Ethernet with u10 Networks pseudo-header"), + DLT_CHOICE(DLT_IPMB, "IPMB"), + DLT_CHOICE(DLT_JUNIPER_ST, "Juniper Secure Tunnel"), + DLT_CHOICE(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"), + DLT_CHOICE(DLT_AX25_KISS, "AX.25 with KISS header"), + DLT_CHOICE(DLT_IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"), DLT_CHOICE_SENTINEL }; @@ -678,6 +913,53 @@ pcap_win32strerror(void) } #endif +/* + * Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values. + */ +const char * +pcap_statustostr(int errnum) +{ + static char ebuf[15+10+1]; + + switch (errnum) { + + case PCAP_WARNING: + return("Generic warning"); + + case PCAP_WARNING_PROMISC_NOTSUP: + return ("That device doesn't support promiscuous mode"); + + case PCAP_ERROR: + return("Generic error"); + + case PCAP_ERROR_BREAK: + return("Loop terminated by pcap_breakloop"); + + case PCAP_ERROR_NOT_ACTIVATED: + return("The pcap_t has not been activated"); + + case PCAP_ERROR_ACTIVATED: + return ("The setting can't be changed after the pcap_t is activated"); + + case PCAP_ERROR_NO_SUCH_DEVICE: + return ("No such device exists"); + + case PCAP_ERROR_RFMON_NOTSUP: + return ("That device doesn't support monitor mode"); + + case PCAP_ERROR_NOT_RFMON: + return ("That operation is supported only in monitor mode"); + + case PCAP_ERROR_PERM_DENIED: + return ("You don't have permission to capture on that device"); + + case PCAP_ERROR_IFACE_NOT_UP: + return ("That device is not up"); + } + (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); + return(ebuf); +} + /* * Not all systems have strerror(). */ @@ -689,7 +971,7 @@ pcap_strerror(int errnum) #else extern int sys_nerr; extern const char *const sys_errlist[]; - static char ebuf[20]; + static char ebuf[15+10+1]; if ((unsigned int)errnum < sys_nerr) return ((char *)sys_errlist[errnum]); @@ -735,19 +1017,162 @@ pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_) return (-1); } +#ifdef WIN32 +int +pcap_setbuff(pcap_t *p, int dim) +{ + return p->setbuff_op(p, dim); +} + +static int +pcap_setbuff_dead(pcap_t *p, int dim) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "The kernel buffer size cannot be set on a pcap_open_dead pcap_t"); + return (-1); +} + +int +pcap_setmode(pcap_t *p, int mode) +{ + return p->setmode_op(p, mode); +} + +static int +pcap_setmode_dead(pcap_t *p, int mode) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "impossible to set mode on a pcap_open_dead pcap_t"); + return (-1); +} + +int +pcap_setmintocopy(pcap_t *p, int size) +{ + return p->setmintocopy_op(p, size); +} + +static int +pcap_setmintocopy_dead(pcap_t *p, int size) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "The mintocopy parameter cannot be set on a pcap_open_dead pcap_t"); + return (-1); +} +#endif + +/* + * On some platforms, we need to clean up promiscuous or monitor mode + * when we close a device - and we want that to happen even if the + * application just exits without explicitl closing devices. + * On those platforms, we need to register a "close all the pcaps" + * routine to be called when we exit, and need to maintain a list of + * pcaps that need to be closed to clean up modes. + * + * XXX - not thread-safe. + */ + +/* + * List of pcaps on which we've done something that needs to be + * cleaned up. + * If there are any such pcaps, we arrange to call "pcap_close_all()" + * when we exit, and have it close all of them. + */ +static struct pcap *pcaps_to_close; + +/* + * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to + * be called on exit. + */ +static int did_atexit; + +static void +pcap_close_all(void) +{ + struct pcap *handle; + + while ((handle = pcaps_to_close) != NULL) + pcap_close(handle); +} + +int +pcap_do_addexit(pcap_t *p) +{ + /* + * If we haven't already done so, arrange to have + * "pcap_close_all()" called when we exit. + */ + if (!did_atexit) { + if (atexit(pcap_close_all) == -1) { + /* + * "atexit()" failed; let our caller know. + */ + strncpy(p->errbuf, "atexit failed", + PCAP_ERRBUF_SIZE); + return (0); + } + did_atexit = 1; + } + return (1); +} + void -pcap_close_common(pcap_t *p) +pcap_add_to_pcaps_to_close(pcap_t *p) { - if (p->buffer != NULL) + p->md.next = pcaps_to_close; + pcaps_to_close = p; +} + +void +pcap_remove_from_pcaps_to_close(pcap_t *p) +{ + pcap_t *pc, *prevpc; + + for (pc = pcaps_to_close, prevpc = NULL; pc != NULL; + prevpc = pc, pc = pc->md.next) { + if (pc == p) { + /* + * Found it. Remove it from the list. + */ + if (prevpc == NULL) { + /* + * It was at the head of the list. + */ + pcaps_to_close = pc->md.next; + } else { + /* + * It was in the middle of the list. + */ + prevpc->md.next = pc->md.next; + } + break; + } + } +} + +void +pcap_cleanup_live_common(pcap_t *p) +{ + if (p->buffer != NULL) { free(p->buffer); + p->buffer = NULL; + } + if (p->dlt_list != NULL) { + free(p->dlt_list); + p->dlt_list = NULL; + p->dlt_count = 0; + } + pcap_freecode(&p->fcode); #if !defined(WIN32) && !defined(MSDOS) - if (p->fd >= 0) + if (p->fd >= 0) { close(p->fd); + p->fd = -1; + } #endif } static void -pcap_close_dead(pcap_t *p _U_) +pcap_cleanup_dead(pcap_t *p _U_) { /* Nothing to do. */ } @@ -764,7 +1189,13 @@ pcap_open_dead(int linktype, int snaplen) p->snapshot = snaplen; p->linktype = linktype; p->stats_op = pcap_stats_dead; - p->close_op = pcap_close_dead; +#ifdef WIN32 + p->setbuff_op = pcap_setbuff_dead; + p->setmode_op = pcap_setmode_dead; + p->setmintocopy_op = pcap_setmintocopy_dead; +#endif + p->cleanup_op = pcap_cleanup_dead; + p->activated = 1; return p; } @@ -795,13 +1226,30 @@ pcap_inject(pcap_t *p, const void *buf, size_t size) void pcap_close(pcap_t *p) { - p->close_op(p); - if (p->dlt_list != NULL) - free(p->dlt_list); - pcap_freecode(&p->fcode); + if (p->opt.source != NULL) + free(p->opt.source); + p->cleanup_op(p); free(p); } +/* + * Given a BPF program, a pcap_pkthdr structure for a packet, and the raw + * data for the packet, check whether the packet passes the filter. + * Returns the return value of the filter program, which will be zero if + * the packet doesn't pass and non-zero if the packet does pass. + */ +int +pcap_offline_filter(struct bpf_program *fp, const struct pcap_pkthdr *h, + const u_char *pkt) +{ + struct bpf_insn *fcode = fp->bf_insns; + + if (fcode != NULL) + return (bpf_filter(fcode, pkt, h->len, h->caplen)); + else + return (0); +} + /* * We make the version string static, and return a pointer to it, rather * than exporting the version string directly. On at least some UNIXes, @@ -817,7 +1265,7 @@ pcap_close(pcap_t *p) #ifdef HAVE_VERSION_H #include "version.h" #else -static const char pcap_version_string[] = "libpcap version 0.9.8"; +static const char pcap_version_string[] = "libpcap version 0.9[.x]"; #endif #ifdef WIN32 diff --git a/contrib/libpcap/pcap.h b/contrib/libpcap/pcap.h index 9c8767e25a..935f9494c1 100644 --- a/contrib/libpcap/pcap.h +++ b/contrib/libpcap/pcap.h @@ -1,4 +1,3 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ /* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. @@ -31,294 +30,16 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.52.2.7 2007/06/11 09:52:05 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.59 2006/10/04 18:09:22 guy Exp $ (LBL) */ -#ifndef lib_pcap_h -#define lib_pcap_h - -#if defined(WIN32) - #include -#elif defined(MSDOS) - #include - #include /* u_int, u_char etc. */ -#else /* UN*X */ - #include - #include -#endif /* WIN32/MSDOS/UN*X */ - -#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H -#include -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define PCAP_VERSION_MAJOR 2 -#define PCAP_VERSION_MINOR 4 - -#define PCAP_ERRBUF_SIZE 256 - /* - * Compatibility for systems that have a bpf.h that - * predates the bpf typedefs for 64-bit support. - */ -#if BPF_RELEASE - 0 < 199406 -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif - -typedef struct pcap pcap_t; -typedef struct pcap_dumper pcap_dumper_t; -typedef struct pcap_if pcap_if_t; -typedef struct pcap_addr pcap_addr_t; - -/* - * The first record in the file contains saved values for some - * of the flags used in the printout phases of tcpdump. - * Many fields here are 32 bit ints so compilers won't insert unwanted - * padding; these files need to be interchangeable across architectures. - * - * Do not change the layout of this structure, in any way (this includes - * changes that only affect the length of fields in this structure). - * - * Also, do not change the interpretation of any of the members of this - * structure, in any way (this includes using values other than - * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" - * field). - * - * Instead: - * - * introduce a new structure for the new format, if the layout - * of the structure changed; - * - * send mail to "tcpdump-workers@tcpdump.org", requesting a new - * magic number for your new capture file format, and, when - * you get the new magic number, put it in "savefile.c"; - * - * use that magic number for save files with the changed file - * header; + * For backwards compatibility. * - * make the code in "savefile.c" capable of reading files with - * the old file header as well as files with the new file header - * (using the magic number to determine the header format). - * - * Then supply the changes to "patches@tcpdump.org", so that future - * versions of libpcap and programs that use it (such as tcpdump) will - * be able to read your new capture file format. - */ -struct pcap_file_header { - bpf_u_int32 magic; - u_short version_major; - u_short version_minor; - bpf_int32 thiszone; /* gmt to local correction */ - bpf_u_int32 sigfigs; /* accuracy of timestamps */ - bpf_u_int32 snaplen; /* max length saved portion of each pkt */ - bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ -}; - -typedef enum { - PCAP_D_INOUT = 0, - PCAP_D_IN, - PCAP_D_OUT -} pcap_direction_t; - -/* - * Generic per-packet information, as supplied by libpcap. - * - * The time stamp can and should be a "struct timeval", regardless of - * whether your system supports 32-bit tv_sec in "struct timeval", - * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit - * and 64-bit applications. The on-disk format of savefiles uses 32-bit - * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit - * and 64-bit versions of libpcap, even if they're on the same platform, - * should supply the appropriate version of "struct timeval", even if - * that's not what the underlying packet capture mechanism supplies. - */ -struct pcap_pkthdr { - struct timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ -}; - -/* - * As returned by the pcap_stats() - */ -struct pcap_stat { - u_int ps_recv; /* number of packets received */ - u_int ps_drop; /* number of packets dropped */ - u_int ps_ifdrop; /* drops by interface XXX not yet supported */ -#ifdef WIN32 - u_int bs_capt; /* number of packets that reach the application */ -#endif /* WIN32 */ -}; - -#ifdef MSDOS -/* - * As returned by the pcap_stats_ex() + * Note to OS vendors: do NOT get rid of this file! Many applications + * expect to be able to include , and at least some of them + * go through contortions in their configure scripts to try to detect + * OSes that have "helpfully" moved pcap.h to without + * leaving behind a file. */ -struct pcap_stat_ex { - u_long rx_packets; /* total packets received */ - u_long tx_packets; /* total packets transmitted */ - u_long rx_bytes; /* total bytes received */ - u_long tx_bytes; /* total bytes transmitted */ - u_long rx_errors; /* bad packets received */ - u_long tx_errors; /* packet transmit problems */ - u_long rx_dropped; /* no space in Rx buffers */ - u_long tx_dropped; /* no space available for Tx */ - u_long multicast; /* multicast packets received */ - u_long collisions; - - /* detailed rx_errors: */ - u_long rx_length_errors; - u_long rx_over_errors; /* receiver ring buff overflow */ - u_long rx_crc_errors; /* recv'd pkt with crc error */ - u_long rx_frame_errors; /* recv'd frame alignment error */ - u_long rx_fifo_errors; /* recv'r fifo overrun */ - u_long rx_missed_errors; /* recv'r missed packet */ - - /* detailed tx_errors */ - u_long tx_aborted_errors; - u_long tx_carrier_errors; - u_long tx_fifo_errors; - u_long tx_heartbeat_errors; - u_long tx_window_errors; - }; -#endif - -/* - * Item in a list of interfaces. - */ -struct pcap_if { - struct pcap_if *next; - char *name; /* name to hand to "pcap_open_live()" */ - char *description; /* textual description of interface, or NULL */ - struct pcap_addr *addresses; - bpf_u_int32 flags; /* PCAP_IF_ interface flags */ -}; - -#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ - -/* - * Representation of an interface address. - */ -struct pcap_addr { - struct pcap_addr *next; - struct sockaddr *addr; /* address */ - struct sockaddr *netmask; /* netmask for that address */ - struct sockaddr *broadaddr; /* broadcast address for that address */ - struct sockaddr *dstaddr; /* P2P destination address for that address */ -}; - -typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, - const u_char *); - -char *pcap_lookupdev(char *); -int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); -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 *); -pcap_t *pcap_fopen_offline(FILE *, char *); -void pcap_close(pcap_t *); -int pcap_loop(pcap_t *, int, pcap_handler, u_char *); -int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); -const u_char* - pcap_next(pcap_t *, struct pcap_pkthdr *); -int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); -void pcap_breakloop(pcap_t *); -int pcap_stats(pcap_t *, struct pcap_stat *); -int pcap_setfilter(pcap_t *, struct bpf_program *); -int pcap_setdirection(pcap_t *, pcap_direction_t); -int pcap_getnonblock(pcap_t *, char *); -int pcap_setnonblock(pcap_t *, int, char *); -void pcap_perror(pcap_t *, char *); -int pcap_inject(pcap_t *, const void *, size_t); -int pcap_sendpacket(pcap_t *, const u_char *, int); -const char *pcap_strerror(int); -char *pcap_geterr(pcap_t *); -int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, - bpf_u_int32); -int pcap_compile_nopcap(int, int, struct bpf_program *, - const char *, int, bpf_u_int32); -void pcap_freecode(struct bpf_program *); -int pcap_datalink(pcap_t *); -int pcap_list_datalinks(pcap_t *, int **); -int pcap_set_datalink(pcap_t *, int); -int pcap_datalink_name_to_val(const char *); -const char *pcap_datalink_val_to_name(int); -const char *pcap_datalink_val_to_description(int); -int pcap_snapshot(pcap_t *); -int pcap_is_swapped(pcap_t *); -int pcap_major_version(pcap_t *); -int pcap_minor_version(pcap_t *); - -/* XXX */ -FILE *pcap_file(pcap_t *); -int pcap_fileno(pcap_t *); - -pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); -pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); -FILE *pcap_dump_file(pcap_dumper_t *); -long pcap_dump_ftell(pcap_dumper_t *); -int pcap_dump_flush(pcap_dumper_t *); -void pcap_dump_close(pcap_dumper_t *); -void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); - -int pcap_findalldevs(pcap_if_t **, char *); -void pcap_freealldevs(pcap_if_t *); - -const char *pcap_lib_version(void); - -/* XXX this guy lives in the bpf tree */ -u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); -int bpf_validate(struct bpf_insn *f, int len); -char *bpf_image(struct bpf_insn *, int); -void bpf_dump(struct bpf_program *, int); - -#if defined(WIN32) - -/* - * Win32 definitions - */ - -int pcap_setbuff(pcap_t *p, int dim); -int pcap_setmode(pcap_t *p, int mode); -int pcap_setmintocopy(pcap_t *p, int size); - -#ifdef WPCAP -/* Include file with the wpcap-specific extensions */ -#include -#endif /* WPCAP */ - -#define MODE_CAPT 0 -#define MODE_STAT 1 -#define MODE_MON 2 - -#elif defined(MSDOS) - -/* - * MS-DOS definitions - */ - -int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); -void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); -u_long pcap_mac_packets (void); - -#else /* UN*X */ - -/* - * UN*X definitions - */ - -int pcap_get_selectable_fd(pcap_t *); - -#endif /* WIN32/MSDOS/UN*X */ - -#ifdef __cplusplus -} -#endif - -#endif +#include diff --git a/contrib/libpcap/pcap-namedb.h b/contrib/libpcap/pcap/namedb.h similarity index 97% copy from contrib/libpcap/pcap-namedb.h copy to contrib/libpcap/pcap/namedb.h index acaabd9636..9002c75093 100644 --- a/contrib/libpcap/pcap-namedb.h +++ b/contrib/libpcap/pcap/namedb.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.10.2.1 2005/04/19 04:26:08 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap/namedb.h,v 1.1 2006/10/04 18:09:22 guy Exp $ (LBL) */ #ifndef lib_pcap_namedb_h diff --git a/contrib/libpcap/pcap.h b/contrib/libpcap/pcap/pcap.h similarity index 77% copy from contrib/libpcap/pcap.h copy to contrib/libpcap/pcap/pcap.h index 9c8767e25a..ea18edcff5 100644 --- a/contrib/libpcap/pcap.h +++ b/contrib/libpcap/pcap/pcap.h @@ -31,11 +31,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.52.2.7 2007/06/11 09:52:05 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.4.2.11 2008-10-06 15:38:39 gianluca Exp $ (LBL) */ -#ifndef lib_pcap_h -#define lib_pcap_h +#ifndef lib_pcap_pcap_h +#define lib_pcap_pcap_h #if defined(WIN32) #include @@ -48,7 +48,7 @@ #endif /* WIN32/MSDOS/UN*X */ #ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H -#include +#include #endif #include @@ -95,8 +95,8 @@ typedef struct pcap_addr pcap_addr_t; * introduce a new structure for the new format, if the layout * of the structure changed; * - * send mail to "tcpdump-workers@tcpdump.org", requesting a new - * magic number for your new capture file format, and, when + * send mail to "tcpdump-workers@lists.tcpdump.org", requesting + * a new magic number for your new capture file format, and, when * you get the new magic number, put it in "savefile.c"; * * use that magic number for save files with the changed file @@ -106,9 +106,12 @@ typedef struct pcap_addr pcap_addr_t; * the old file header as well as files with the new file header * (using the magic number to determine the header format). * - * Then supply the changes to "patches@tcpdump.org", so that future - * versions of libpcap and programs that use it (such as tcpdump) will - * be able to read your new capture file format. + * Then supply the changes as a patch at + * + * http://sourceforge.net/projects/libpcap/ + * + * so that future versions of libpcap and programs that use it (such as + * tcpdump) will be able to read your new capture file format. */ struct pcap_file_header { bpf_u_int32 magic; @@ -120,6 +123,16 @@ struct pcap_file_header { bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ }; +/* + * Macros for the value returned by pcap_datalink_ext(). + * + * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro + * gives the FCS length of packets in the capture. + */ +#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000) +#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28) +#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000) + typedef enum { PCAP_D_INOUT = 0, PCAP_D_IN, @@ -216,12 +229,57 @@ struct pcap_addr { typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char *); +/* + * Error codes for the pcap API. + * These will all be negative, so you can check for the success or + * failure of a call that returns these codes by checking for a + * negative value. + */ +#define PCAP_ERROR -1 /* generic error code */ +#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ +#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ +#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ +#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ +#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ +#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 */ + +/* + * Warning codes for the pcap API. + * These will all be positive and non-zero, so they won't look like + * errors. + */ +#define PCAP_WARNING 1 /* generic warning code */ +#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ + char *pcap_lookupdev(char *); int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); + +pcap_t *pcap_create(const char *, char *); +int pcap_set_snaplen(pcap_t *, int); +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_buffer_size(pcap_t *, int); +int pcap_activate(pcap_t *); + 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 *); +#if defined(WIN32) +pcap_t *pcap_hopen_offline(intptr_t, char *); +#if !defined(LIBPCAP_EXPORTS) +#define pcap_fopen_offline(f,b) \ + pcap_hopen_offline(_get_osfhandle(_fileno(f)), b) +#else /*LIBPCAP_EXPORTS*/ +static pcap_t *pcap_fopen_offline(FILE *, char *); +#endif +#else /*WIN32*/ pcap_t *pcap_fopen_offline(FILE *, char *); +#endif /*WIN32*/ + void pcap_close(pcap_t *); int pcap_loop(pcap_t *, int, pcap_handler, u_char *); int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); @@ -234,19 +292,24 @@ int pcap_setfilter(pcap_t *, struct bpf_program *); int pcap_setdirection(pcap_t *, pcap_direction_t); int pcap_getnonblock(pcap_t *, char *); int pcap_setnonblock(pcap_t *, int, char *); -void pcap_perror(pcap_t *, char *); int pcap_inject(pcap_t *, const void *, size_t); int pcap_sendpacket(pcap_t *, const u_char *, int); +const char *pcap_statustostr(int); const char *pcap_strerror(int); char *pcap_geterr(pcap_t *); +void pcap_perror(pcap_t *, char *); int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32); int pcap_compile_nopcap(int, int, struct bpf_program *, const char *, int, bpf_u_int32); void pcap_freecode(struct bpf_program *); +int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *, + const u_char *); int pcap_datalink(pcap_t *); +int pcap_datalink_ext(pcap_t *); int pcap_list_datalinks(pcap_t *, int **); int pcap_set_datalink(pcap_t *, int); +void pcap_free_datalinks(int *); int pcap_datalink_name_to_val(const char *); const char *pcap_datalink_val_to_name(int); const char *pcap_datalink_val_to_description(int); @@ -273,10 +336,10 @@ void pcap_freealldevs(pcap_if_t *); const char *pcap_lib_version(void); /* XXX this guy lives in the bpf tree */ -u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); -int bpf_validate(struct bpf_insn *f, int len); -char *bpf_image(struct bpf_insn *, int); -void bpf_dump(struct bpf_program *, int); +u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); +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); #if defined(WIN32) diff --git a/contrib/libpcap/sll.h b/contrib/libpcap/pcap/sll.h similarity index 94% rename from contrib/libpcap/sll.h rename to contrib/libpcap/pcap/sll.h index 85a3a9d97d..e9d5452af7 100644 --- a/contrib/libpcap/sll.h +++ b/contrib/libpcap/pcap/sll.h @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/libpcap/sll.h,v 1.7 2002/06/11 17:04:48 itojun Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap/sll.h,v 1.2.2.1 2008-05-30 01:36:06 guy Exp $ (LBL) */ /* @@ -64,8 +64,8 @@ * DO NOT change the layout of this structure, or change any of the * LINUX_SLL_ values below. If you must change the link-layer header * for a "cooked" Linux capture, introduce a new DLT_ type (ask - * "tcpdump-workers@tcpdump.org" for one, so that you don't give it a - * value that collides with a value already being used), and use the + * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it + * a value that collides with a value already being used), and use the * new header in captures of that type, so that programs that can * handle DLT_LINUX_SLL captures will continue to handle them correctly * without any change, and so that capture files with different headers @@ -73,6 +73,9 @@ * packets in them. */ +#ifndef lib_pcap_sll_h +#define lib_pcap_sll_h + /* * A DLT_LINUX_SLL fake link-layer header. */ @@ -122,3 +125,5 @@ struct sll_header { */ #define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ #define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ + +#endif diff --git a/contrib/libpcap/pcap/usb.h b/contrib/libpcap/pcap/usb.h new file mode 100644 index 0000000000..adcd19c058 --- /dev/null +++ b/contrib/libpcap/pcap/usb.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2006 Paolo Abeni (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Basic USB data struct + * By Paolo Abeni + * + * @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.6 2007/09/22 02:06:08 guy Exp $ + */ + +#ifndef _PCAP_USB_STRUCTS_H__ +#define _PCAP_USB_STRUCTS_H__ + +/* + * possible transfer mode + */ +#define URB_TRANSFER_IN 0x80 +#define URB_ISOCHRONOUS 0x0 +#define URB_INTERRUPT 0x1 +#define URB_CONTROL 0x2 +#define URB_BULK 0x3 + +/* + * possible event type + */ +#define URB_SUBMIT 'S' +#define URB_COMPLETE 'C' +#define URB_ERROR 'E' + +/* + * USB setup header as defined in USB specification. + * Appears at the front of each packet in DLT_USB captures. + */ +typedef struct _usb_setup { + u_int8_t bmRequestType; + u_int8_t bRequest; + u_int16_t wValue; + u_int16_t wIndex; + u_int16_t wLength; +} pcap_usb_setup; + + +/* + * Header prepended by linux kernel to each event. + * Appears at the front of each packet in DLT_USB_LINUX captures. + */ +typedef struct _usb_header { + u_int64_t id; + u_int8_t event_type; + u_int8_t transfer_type; + u_int8_t endpoint_number; + u_int8_t device_address; + u_int16_t bus_id; + char setup_flag;/*if !=0 the urb setup header is not present*/ + char data_flag; /*if !=0 no urb data is present*/ + int64_t ts_sec; + int32_t ts_usec; + int32_t status; + u_int32_t urb_len; + u_int32_t data_len; /* amount of urb data really present in this event*/ + pcap_usb_setup setup; +} pcap_usb_header; + + +#endif diff --git a/contrib/libpcap/pcap_activate.3pcap b/contrib/libpcap/pcap_activate.3pcap new file mode 100644 index 0000000000..5b19136047 --- /dev/null +++ b/contrib/libpcap/pcap_activate.3pcap @@ -0,0 +1,89 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_activate.3pcap,v 1.1.2.5 2008-07-01 08:04:03 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_ACTIVATE 3PCAP "5 April 2008" +.SH NAME +pcap_activate \- activate a capture handle +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_activate(pcap_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_activate() +is used to activate a packet capture handle to look +at packets on the network, with the options that were set on the handle +being in effect. +.SH RETURN VALUE +.B pcap_activate() +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 +on success with any other warning, +.B PCAP_ERROR_ACTIVATED +if the handle has already been activated, +.B PCAP_ERROR_NO_SUCH_DEVICE +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_RFMON_NOTSUP +if monitor mode was specified but the capture source doesn't support +monitor mode, +.B PCAP_ERROR_IFACE_NOT_UP +if the capture source is not up, and +.B PCAP_ERROR +if another error occurred. +If +.B PCAP_WARNING +or +.B PCAP_ERROR +is returned, +.B pcap_geterr() +or +.B pcap_perror() +may be called with +.I p +as an argument to fetch or display a message describing the warning or +error. +If +.BR PCAP_WARNING_PROMISC_NOTSUP , +.BR PCAP_ERROR_NO_SUCH_DEVICE , +or +.B PCAP_ERROR_PERM_DENIED +is returned, +.B pcap_geterr() +or +.B pcap_perror() +may be called with +.I p +as an argument to fetch or display an message giving additional details +about the problem that might be useful for debugging the problem if it's +unexpected. +.SH SEE ALSO +pcap(3PCAP) diff --git a/contrib/libpcap/pcap_breakloop.3pcap b/contrib/libpcap/pcap_breakloop.3pcap new file mode 100644 index 0000000000..cf78860321 --- /dev/null +++ b/contrib/libpcap/pcap_breakloop.3pcap @@ -0,0 +1,105 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_breakloop.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_BREAKLOOP 3PCAP "5 April 2008" +.SH NAME +pcap_breakloop \- force a pcap_dispatch() or pcap_loop() call to return +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +void pcap_breakloop(pcap_t *); +.ft +.fi +.SH DESCRIPTION +.B pcap_breakloop() +sets a flag that will force +.B pcap_dispatch() +or +.B pcap_loop() +to return rather than looping; they will return the number of packets +that have been processed so far, or \-2 if no packets have been +processed so far. +.PP +This routine is safe to use inside a signal handler on UNIX or a console +control handler on Windows, as it merely sets a flag that is checked +within the loop. +.PP +The flag is checked in loops reading packets from the OS - a signal by +itself will not necessarily terminate those loops - as well as in loops +processing a set of packets returned by the OS. +.ft B +Note that if you are catching signals on UNIX systems that support +restarting system calls after a signal, and calling pcap_breakloop() +in the signal handler, you must specify, when catching those signals, +that system calls should NOT be restarted by that signal. Otherwise, +if the signal interrupted a call reading packets in a live capture, +when your signal handler returns after calling pcap_breakloop(), the +call will be restarted, and the loop will not terminate until more +packets arrive and the call completes. +.PP +Note also that, in a multi-threaded application, if one thread is +blocked in +.BR pcap_dispatch() , +.BR pcap_loop() , +.BR pcap_next() , +or +.BR pcap_next_ex() , +a call to +.B pcap_breakloop() +in a different thread will not unblock that thread; you will need to use +whatever mechanism the OS provides for breaking a thread out of blocking +calls in order to unblock the thread, such as thread cancellation in +systems that support POSIX threads. +.ft R +.PP +Note that +.B pcap_next() +and +.B pcap_next_ex() +will, on some platforms, loop reading packets from the OS; that loop +will not necessarily be terminated by a signal, so +.B pcap_breakloop() +should be used to terminate packet processing even if +.B pcap_next() +or +.B pcap_next_ex() +is being used. +.PP +.B pcap_breakloop() +does not guarantee that no further packets will be processed by +.B pcap_dispatch() +or +.B pcap_loop() +after it is called; at most one more packet might be processed. +.PP +If \-2 is returned from +.B pcap_dispatch() +or +.BR pcap_loop() , +the flag is cleared, so a subsequent call will resume reading packets. +If a positive number is returned, the flag is not cleared, so a +subsequent call will return \-2 and clear the flag. +.SH SEE ALSO +pcap(3PCAP), pcap_loop(3PCAP), pcap_next_ex(3PCAP) diff --git a/contrib/libpcap/pcap_can_set_rfmon.3pcap b/contrib/libpcap/pcap_can_set_rfmon.3pcap new file mode 100644 index 0000000000..992d2c8c48 --- /dev/null +++ b/contrib/libpcap/pcap_can_set_rfmon.3pcap @@ -0,0 +1,60 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_can_set_rfmon.3pcap,v 1.1.2.1 2008-04-06 03:21:55 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_CAN_SET_RFMON 3PCAP "5 April 2008" +.SH NAME +pcap_can_set_rfmon \- check whether monitor mode can be set for a +not-yet-activated capture handle +.SH SYNOPSIS +.nf +.ft B +#include +.LP +.ft B +int pcap_can_set_rfmon(pcap_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_can_set_rfmon() +checks whether monitor mode could be set on a capture handle when +the handle is activated. +.SH RETURN VALUE +.B pcap_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, +.B PCAP_ERROR_ACTIVATED +if called on a capture handle that has been activated, or +.B PCAP_ERROR +if an error occurred. +If +.B PCAP_ERROR +is returned, +.B pcap_geterr() +or +.B pcap_perror() +may be called with +.I p +as an argument to fetch or display the error text. +.SH SEE ALSO +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP), +pcap_set_rfmon(3PCAP) diff --git a/contrib/libpcap/pcap_close.3pcap b/contrib/libpcap/pcap_close.3pcap new file mode 100644 index 0000000000..3d92f03067 --- /dev/null +++ b/contrib/libpcap/pcap_close.3pcap @@ -0,0 +1,41 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_close.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_CLOSE 3PCAP "5 April 2008" +.SH NAME +pcap_close \- close a capture device or savefile +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +void pcap_close(pcap_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_close() +closes the files associated with +.I p +and deallocates resources. +.SH SEE ALSO +pcap(3PCAP) diff --git a/contrib/libpcap/pcap_compile.3pcap.in b/contrib/libpcap/pcap_compile.3pcap.in new file mode 100644 index 0000000000..87e2778696 --- /dev/null +++ b/contrib/libpcap/pcap_compile.3pcap.in @@ -0,0 +1,72 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_compile.3pcap.in,v 1.1.2.2 2008-10-21 07:44:57 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_COMPILE 3PCAP "5 April 2008" +.SH NAME +pcap_compile \- compile a filter expression +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_compile(pcap_t *p, struct bpf_program *fp, +.ti +8 +const char *str, int optimize, bpf_u_int32 netmask); +.ft +.fi +.SH DESCRIPTION +.B pcap_compile() +is used to compile the string +.I str +into a filter program. See +.BR pcap-filter (@MAN_MISC_INFO@) +for the syntax of that string. +.I program +is a pointer to a +.I bpf_program +struct and is filled in by +.BR pcap_compile() . +.I optimize +controls whether optimization on the resulting code is performed. +.I netmask +specifies the IPv4 netmask of the network on which packets are being +captured; it is used only when checking for IPv4 broadcast addresses in +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 0 can be supplied; tests for IPv4 broadcast +addreses won't be done correctly, but all other tests in the filter +program will be OK. +.SH RETURN VALUE +.B pcap_compile() +returns 0 on success and \-1 on failure. +If \-1 is returned, +.B pcap_geterr() +or +.B pcap_perror() +may be called with +.I p +as an argument to fetch or display the error text. +.SH SEE ALSO +pcap(3PCAP), pcap_setfilter(3PCAP), pcap_freecode(3PCAP), +pcap_geterr(3PCAP), pcap-filter(@MAN_MISC_INFO@) diff --git a/contrib/libpcap/pcap_create.3pcap b/contrib/libpcap/pcap_create.3pcap new file mode 100644 index 0000000000..32071b3358 --- /dev/null +++ b/contrib/libpcap/pcap_create.3pcap @@ -0,0 +1,74 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_create.3pcap,v 1.1.2.1 2008-04-06 03:21:55 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_CREATE 3PCAP "5 April 2008" +.SH NAME +pcap_create \- create a live capture handle +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.nf +.ft B +char errbuf[PCAP_ERRBUF_SIZE]; +.ft +.LP +.ft B +pcap_t *pcap_create(const char *source, char *errbuf); +.ft +.fi +.SH DESCRIPTION +.B pcap_create() +is used to create a packet capture handle to look +at packets on the network. +.I source +is a string that specifies the network device to open; on Linux systems +with 2.2 or later kernels, a +.I source +argument of "any" or +.B NULL +can be used to capture packets from all interfaces. +.PP +The returned handle must be activated with +.B pcap_activate() +before packets can be captured +with it; options for the capture, such as promiscuous mode, can be set +on the handle before activating it. +.SH RETURN VALUE +.B pcap_create() +returns a +.I pcap_t * +on success and +.B NULL +on failure. +If +.B NULL +is returned, +.I errbuf +is filled in with an appropriate error message. +.I errbuf +is assumed to be able to hold at least +.B PCAP_ERRBUF_SIZE +chars. +.SH SEE ALSO +pcap(3PCAP), pcap_activate(3PCAP) diff --git a/contrib/libpcap/pcap_datalink.3pcap.in b/contrib/libpcap/pcap_datalink.3pcap.in new file mode 100644 index 0000000000..83426f05ca --- /dev/null +++ b/contrib/libpcap/pcap_datalink.3pcap.in @@ -0,0 +1,41 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_datalink.3pcap.in,v 1.1.2.2 2008-10-21 07:44:57 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_DATALINK 3PCAP "5 April 2008" +.SH NAME +pcap_datalink \- get the link-layer header type +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_datalink(pcap_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_datalink() +returns the link layer type for the live capture or ``savefile'' +specified by +.IR p . +.SH SEE ALSO +pcap(3PCAP), pcap-linktype(@MAN_MISC_INFO@) diff --git a/contrib/libpcap/pcap_datalink_name_to_val.3pcap b/contrib/libpcap/pcap_datalink_name_to_val.3pcap new file mode 100644 index 0000000000..f51b933e3f --- /dev/null +++ b/contrib/libpcap/pcap_datalink_name_to_val.3pcap @@ -0,0 +1,48 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_datalink_name_to_val.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_DATALINK_NAME_TO_VAL 3PCAP "5 April 2008" +.SH NAME +pcap_datalink_name_to_val \- get the link-layer header type value +corresponding to a header type name +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_datalink_name_to_val(const char *name); +.ft +.fi +.SH DESCRIPTION +.B pcap_datalink_name_to_val() +translates a data link 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. +.SH RETURN VALUE +.B pcap_datalink_name_to_val() +returns 0 on success and \-1 on failure. +.SH SEE ALSO +pcap(3PCAP) diff --git a/contrib/libpcap/pcap_datalink_val_to_name.3pcap b/contrib/libpcap/pcap_datalink_val_to_name.3pcap new file mode 100644 index 0000000000..476bf10364 --- /dev/null +++ b/contrib/libpcap/pcap_datalink_val_to_name.3pcap @@ -0,0 +1,44 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_datalink_val_to_name.3pcap,v 1.1.2.2 2008-05-30 01:32:55 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_DATALINK_VAL_TO_NAME 3 "4 April 2008" +.SH NAME +pcap_datalink_val_to_name, pcap_datalink_val_to_description \- get a +name or description for a link-layer header type value +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +const char *pcap_datalink_val_to_name(int dlt); +const char *pcap_datalink_val_to_description(int dlt); +.ft +.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. +.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. diff --git a/contrib/libpcap/pcap_dump.3pcap b/contrib/libpcap/pcap_dump.3pcap new file mode 100644 index 0000000000..1808869b74 --- /dev/null +++ b/contrib/libpcap/pcap_dump.3pcap @@ -0,0 +1,53 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_dump.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_DUMP 3PCAP "5 April 2008" +.SH NAME +pcap_dump \- write a packet to a capture file +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +void pcap_dump(u_char *user, struct pcap_pkthdr *h, +.ti +8 +u_char *sp); +.ft +.fi +.SH DESCRIPTION +.B pcap_dump() +outputs a packet to the ``savefile'' opened with +.BR pcap_dump_open() . +Note that its calling arguments are suitable for use with +.B pcap_dispatch() +or +.BR pcap_loop() . +If called directly, the +.I user +parameter is of type +.B pcap_dumper_t +as returned by +.BR pcap_dump_open() . +.SH SEE ALSO +pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dispatch(3PCAP), +pcap_loop(3PCAP) diff --git a/contrib/libpcap/pcap_dump_close.3pcap b/contrib/libpcap/pcap_dump_close.3pcap new file mode 100644 index 0000000000..07b690a86f --- /dev/null +++ b/contrib/libpcap/pcap_dump_close.3pcap @@ -0,0 +1,39 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_dump_close.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_DUMP_CLOSE 3PCAP "5 April 2008" +.SH NAME +pcap_dump_close \- close a savefile being written to +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +void pcap_dump_close(pcap_dumper_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_dump_close() +closes the ``savefile.'' +.SH SEE ALSO +pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dump(3PCAP) diff --git a/contrib/libpcap/pcap_dump_file.3pcap b/contrib/libpcap/pcap_dump_file.3pcap new file mode 100644 index 0000000000..5cf0de65a1 --- /dev/null +++ b/contrib/libpcap/pcap_dump_file.3pcap @@ -0,0 +1,40 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_dump_file.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_DUMP_FILE 3PCAP "5 April 2008" +.SH NAME +pcap_dump_file \- get the standard I/O stream for a savefile being written +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +FILE *pcap_dump_file(pcap_dumper_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_dump_file() +returns the standard I/O stream of the ``savefile'' opened by +.BR pcap_dump_open() . +.SH SEE ALSO +pcap(3PCAP) diff --git a/contrib/libpcap/pcap_dump_flush.3pcap b/contrib/libpcap/pcap_dump_flush.3pcap new file mode 100644 index 0000000000..e83e2a0740 --- /dev/null +++ b/contrib/libpcap/pcap_dump_flush.3pcap @@ -0,0 +1,45 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_dump_flush.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_DUMP_FLUSH 3PCAP "5 April 2008" +.SH NAME +pcap_dump_flush \- flush to a savefile packets dumped +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_dump_flush(pcap_dumper_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_dump_flush() +flushes the output buffer to the ``savefile,'' so that any packets +written with +.B pcap_dump() +but not yet written to the ``savefile'' will be written. +.SH RETURN VALUE +.B pcap_dump_flush() +returns 0 on success and \-1 on failure. +.SH SEE ALSO +pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dump(3PCAP) diff --git a/contrib/libpcap/pcap_dump_ftell.3pcap b/contrib/libpcap/pcap_dump_ftell.3pcap new file mode 100644 index 0000000000..d9c3600cec --- /dev/null +++ b/contrib/libpcap/pcap_dump_ftell.3pcap @@ -0,0 +1,44 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_dump_ftell.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_DUMP_FTELL 3PCAP "5 April 2008" +.SH NAME +pcap_dump_ftell \- get the current file offset for a savefile being written +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +long pcap_dump_ftell(pcap_dumper_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_dump_ftell() +returns the current file position for the ``savefile'', representing the +number of bytes written by +.B pcap_dump_open() +and +.BR pcap_dump() . +\-1 is returned on error. +.SH SEE ALSO +pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dump(3PCAP) diff --git a/contrib/libpcap/pcap_dump_open.3pcap.in b/contrib/libpcap/pcap_dump_open.3pcap.in new file mode 100644 index 0000000000..9fe116bb7a --- /dev/null +++ b/contrib/libpcap/pcap_dump_open.3pcap.in @@ -0,0 +1,87 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_dump_open.3pcap.in,v 1.1.2.2 2008-10-23 05:59:43 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_DUMP_OPEN 3PCAP "5 April 2008" +.SH NAME +pcap_dump_open, pcap_dump_fopen \- open a file to which to write packets +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.nf +.LP +.ft B +pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname); +pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *fp); +.ft +.fi +.SH DESCRIPTION +.B pcap_dump_open() +is called to open a ``savefile'' for writing. +.I fname +specifies the name of the file to open. The file will have +the same format as those used by +.BR tcpdump (1) +and +.BR tcpslice (1). +The name "-" in a synonym +for +.BR stdout . +.PP +.B pcap_dump_fopen() +is called to write data to an existing open stream +.IR fp . +Note that on Windows, that stream should be opened in binary mode. +.PP +.I p +is a capture or ``savefile'' handle returned by an earlier call to +.B pcap_create() +and activated by an earlier call to +.BR pcap_activate() , +or returned by an earlier call to +.BR pcap_open_offline() , +.BR pcap_open_live() , +or +.BR pcap_open_dead() . +The link-layer type and snapshot length from +.I p +are used as the link-layer type and snapshot length of the output file. +.SH RETURN VALUES +A pointer to a +.B pcap_dumper_t +structure to use in subsequent +.B pcap_dump() +and +.B pcap_dump_close() +calls is returned on success. +.B NULL +is returned on failure. +If +.B NULL +is returned, +.B pcap_geterr(\fIp\fB) +can be used to get the error text. +.SH SEE ALSO +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP), +pcap_open_offline(3PCAP), pcap_open_live(3PCAP), pcap_open_dead(3PCAP), +pcap_dump(3PCAP), pcap_dump_close(3PCAP), pcap_geterr(3PCAP), +pcap-savefile(@MAN_FILE_FORMATS@) diff --git a/contrib/libpcap/pcap_file.3pcap b/contrib/libpcap/pcap_file.3pcap new file mode 100644 index 0000000000..b74e502164 --- /dev/null +++ b/contrib/libpcap/pcap_file.3pcap @@ -0,0 +1,59 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_file.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_FILE 3PCAP "5 April 2008" +.SH NAME +pcap_file \- get the standard I/O stream for a savefile being read +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +FILE *pcap_file(pcap_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_file() +returns the standard I/O stream of the ``savefile,'' if a ``savefile'' +was opened with +.BR pcap_open_offline() , +or NULL, if a network device was opened with +.B pcap_create() +and +.BR pcap_activate() , +or with +.BR pcap_open_live() . +.PP +Note that the Packet Capture library is usually built with large file +support, so the standard I/O stream of the ``savefile'' might refer to +a file larger than 2 gigabytes; applications that use +.B pcap_file() +should, if possible, use calls that support large files on the return +value of +.B pcap_file() +or the value returned by +.B fileno() +when passed the return value of +.BR pcap_file() . +.SH SEE ALSO +pcap(3PCAP), pcap_open_offline(3PCAP) diff --git a/contrib/libpcap/pcap_fileno.3pcap b/contrib/libpcap/pcap_fileno.3pcap new file mode 100644 index 0000000000..9c05be0d08 --- /dev/null +++ b/contrib/libpcap/pcap_fileno.3pcap @@ -0,0 +1,47 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_fileno.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_FILENO 3PCAP "5 April 2008" +.SH NAME +pcap_fileno \- get the file descriptor for a live capture +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_fileno(pcap_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_fileno() +returns the file descriptor number from which captured packets are read, +if a network device was opened with +.B pcap_create() +and +.B pcap_activate() +or with +.BR pcap_open_live() , +or \-1, if a ``savefile'' was opened with +.BR pcap_open_offline() . +.SH SEE ALSO +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP) diff --git a/contrib/libpcap/pcap_findalldevs.3pcap b/contrib/libpcap/pcap_findalldevs.3pcap new file mode 100644 index 0000000000..93c0455f82 --- /dev/null +++ b/contrib/libpcap/pcap_findalldevs.3pcap @@ -0,0 +1,156 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_findalldevs.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_FINDALLDEVS 3PCAP "5 April 2008" +.SH NAME +pcap_findalldevs \- get a list of capture devices +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.nf +.ft B +char errbuf[PCAP_ERRBUF_SIZE]; +.ft +.LP +.ft B +int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf); +.ft +.fi +.SH DESCRIPTION +.B pcap_findalldevs() +constructs a list of network devices that can be opened with +.B pcap_create() +and +.B pcap_activate() +or with +.BR pcap_open_live() . +(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 +to open them for capturing; if so, those devices will not appear on the +list.) +.I alldevsp +is set to point to the first element of the list; each element of the +list is of type +.BR pcap_if_t , +and has the following members: +.RS +.TP +.B next +if not +.BR NULL , +a pointer to the next element in the list; +.B NULL +for the last element of the list +.TP +.B name +a pointer to a string giving a name for the device to pass to +.B pcap_open_live() +.TP +.B description +if not +.BR NULL , +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 +.TP +.B flags +interface flags: +.RS +.TP +.B PCAP_IF_LOOPBACK +set if the interface is a loopback interface +.RE +.RE +.PP +Each element of the list of addresses is of type +.BR pcap_addr_t , +and has the following members: +.RS +.TP +.B next +if not +.BR NULL , +a pointer to the next element in the list; +.B NULL +for the last element of the list +.TP +.B addr +a pointer to a +.B "struct sockaddr" +containing an address +.TP +.B netmask +if not +.BR NULL , +a pointer to a +.B "struct sockaddr" +that contains the netmask corresponding to the address pointed to by +.B addr +.TP +.B broadaddr +if not +.BR NULL , +a pointer to a +.B "struct sockaddr" +that contains the broadcast address corresponding to the address pointed +to by +.BR addr ; +may be null if the interface doesn't support broadcasts +.TP +.B dstaddr +if not +.BR NULL , +a pointer to a +.B "struct sockaddr" +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 +.RE +.PP +Note that not all the addresses in the list of addresses are +necessarily IPv4 or IPv6 addresses - you must check the +.B sa_family +member of the +.B "struct sockaddr" +before interpreting the contents of the address. +.PP +The list of devices must be freed with +.BR pcap_freealldevs() . +.SH RETURN VALUE +.B pcap_findalldevs() +returns 0 on success and \-1 on failure. +If \-1 is returned, +.I errbuf +is filled in with an appropriate error message. +.I errbuf +is assumed to be able to hold at least +.B PCAP_ERRBUF_SIZE +chars. +.SH SEE ALSO +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP), +pcap_open_live(3PCAP), pcap_freealldevs(3PCAP) diff --git a/contrib/libpcap/pcap_free_datalinks.3pcap b/contrib/libpcap/pcap_free_datalinks.3pcap new file mode 100644 index 0000000000..8bb7899c70 --- /dev/null +++ b/contrib/libpcap/pcap_free_datalinks.3pcap @@ -0,0 +1,41 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_free_datalinks.3pcap,v 1.1.2.1 2008-05-26 19:58:59 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 +.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/contrib/libpcap/pcap_freealldevs.3pcap b/contrib/libpcap/pcap_freealldevs.3pcap new file mode 100644 index 0000000000..09d4706df9 --- /dev/null +++ b/contrib/libpcap/pcap_freealldevs.3pcap @@ -0,0 +1,40 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_freealldevs.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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 +.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/contrib/libpcap/pcap_freecode.3pcap b/contrib/libpcap/pcap_freecode.3pcap new file mode 100644 index 0000000000..061b50641b --- /dev/null +++ b/contrib/libpcap/pcap_freecode.3pcap @@ -0,0 +1,45 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_freecode.3pcap,v 1.1.2.3 2008-04-06 03:21:55 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_FREECODE 3PCAP "5 April 2008" +.SH NAME +pcap_freecode \- free a BPF program +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +void pcap_freecode(struct bpf_program *); +.ft +.fi +.SH DESCRIPTION +.B pcap_freecode() +is used to free up allocated memory pointed to by a +.I bpf_program +struct generated by +.B pcap_compile() +when that BPF program is no longer needed, for example after it +has been made the filter program for a pcap structure by a call to +.BR pcap_setfilter() . +.SH SEE ALSO +pcap(3PCAP), pcap_compile(3PCAP), pcap_setfilter(3PCAP) diff --git a/contrib/libpcap/pcap_get_selectable_fd.3pcap b/contrib/libpcap/pcap_get_selectable_fd.3pcap new file mode 100644 index 0000000000..9026f451b8 --- /dev/null +++ b/contrib/libpcap/pcap_get_selectable_fd.3pcap @@ -0,0 +1,114 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_get_selectable_fd.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_GET_SELECTABLE_FD 3PCAP "5 April 2008" +.SH NAME +pcap_get_selectable_fd \- get a file descriptor on which a select() can +be done for a live capture +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_get_selectable_fd(pcap_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_get_selectable_fd() +returns, on UNIX, a file descriptor number for a file descriptor on +which one can +do a +.B select() +or +.B poll() +to wait for it to be possible to read packets without blocking, if such +a descriptor exists, or \-1, if no such descriptor exists. Some network +devices opened with +.B pcap_create() +and +.BR pcap_activate() , +or with +.BR pcap_open_live() , +do not support +.B select() +or +.B poll() +(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) +.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 +.B select() +or +.B poll() +will not return even after the read timeout expires. To work around +this, an application that uses +.B select() +or +.B poll() +to wait for packets to arrive must put the +.B pcap_t +in non-blocking mode, and must arrange that the +.B select() +or +.B poll() +have a timeout less than or equal to the read timeout, +and must try to read packets after that timeout expires, regardless of +whether +.B select() +or +.B poll() +indicated that the file descriptor for the +.B pcap_t +is ready to be read or not. (That workaround will not work in FreeBSD +4.3 and later; however, in FreeBSD 4.6 and later, +.B select() +and +.B poll() +work correctly on BPF devices, so the workaround isn't necessary, +although it does no harm.) +.PP +Note also that +.B poll() +doesn't work on character special files, including BPF devices, in Mac +OS X 10.4 and 10.5, so, while +.B select() +can be used on the descriptor returned by +.BR pcap_get_selectable_fd() , +.B poll() +cannot be used on it those versions of Mac OS X. Kqueues also don't +work on that descriptor. +.PP +.B pcap_get_selectable_fd() +is not available on Windows. +.SH RETURN VALUE +A selectable file descriptor is returned if one exists; otherwise, \-1 +is returned. +.SH SEE ALSO +pcap(3PCAP), select(2), poll(2) diff --git a/contrib/libpcap/pcap_geterr.3pcap b/contrib/libpcap/pcap_geterr.3pcap new file mode 100644 index 0000000000..9a46a830c5 --- /dev/null +++ b/contrib/libpcap/pcap_geterr.3pcap @@ -0,0 +1,53 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_geterr.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_GETERR 3PCAP "5 April 2008" +.SH NAME +pcap_geterr, pcap_perror \- get or print libpcap error message text +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +char *pcap_geterr(pcap_t *p); +void pcap_perror(pcap_t *p, char *prefix); +.ft +.fi +.SH DESCRIPTION +.B pcap_geterr() +returns the error text pertaining to the last pcap library error. +.BR NOTE : +the pointer it returns will no longer point to a valid error message +string after the +.B pcap_t +passed to it is closed; you must use or copy the string before closing +the +.BR pcap_t . +.PP +.B pcap_perror() +prints the text of the last pcap library error on +.BR stderr , +prefixed by +.IR prefix . +.SH SEE ALSO +pcap(3PCAP) diff --git a/contrib/libpcap/pcap_inject.3pcap b/contrib/libpcap/pcap_inject.3pcap new file mode 100644 index 0000000000..954984c7f2 --- /dev/null +++ b/contrib/libpcap/pcap_inject.3pcap @@ -0,0 +1,90 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_inject.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_INJECT 3PCAP "5 April 2008" +.SH NAME +pcap_inject, pcap_sendpacket \- transmit a packet +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_inject(pcap_t *p, const void *buf, size_t size); +int pcap_sendpacket(pcap_t *p, const u_char *buf, int size); +.ft +.fi +.SH DESCRIPTION +.B pcap_inject() +sends a raw packet through the network interface; +.I buf +points to the data of the packet, including the link-layer header, and +.I size +is the number of bytes in the packet. +.PP +Note that, even if you successfully open the network interface, you +might not have permission to send packets on it, or it might not support +sending packets; as +.I pcap_open_live() +doesn't have a flag to indicate whether to open for capturing, sending, +or capturing and sending, you cannot request an open that supports +sending and be notified at open time whether sending will be possible. +Note also that some devices might not support sending packets. +.PP +Note that, on some platforms, the link-layer header of the packet that's +sent might not be the same as the link-layer header of the packet +supplied to +.BR pcap_inject() , +as the source link-layer address, if the header contains such an +address, might be changed to be the address assigned to the interface on +which the packet it sent, if the platform doesn't support sending +completely raw and unchanged packets. Even worse, some drivers on some +platforms might change the link-layer type field to whatever value +libpcap used when attaching to the device, even on platforms that +.I do +nominally support sending completely raw and unchanged packets. +.PP +.B pcap_sendpacket() +is like +.BR pcap_inject() , +but it returns 0 on success, rather than returning the number of bytes +written. +.RB ( pcap_inject() +comes from OpenBSD; +.B pcap_sendpacket() +comes from WinPcap. Both are provided for compatibility.) +.SH RETURN VALUE +.B pcap_inject() +returns the number of bytes written on success and \-1 on failure. +.PP +.B pcap_sendpacket() +returns 0 on success and \-1 on failure. +.PP +If \-1 is returned, +.B pcap_geterr() +or +.B pcap_perror() +may be called with +.I p +as an argument to fetch or display the error text. +.SH SEE ALSO +pcap(3PCAP), pcap_geterr(3PCAP) diff --git a/contrib/libpcap/pcap_is_swapped.3pcap b/contrib/libpcap/pcap_is_swapped.3pcap new file mode 100644 index 0000000000..6cc70896f2 --- /dev/null +++ b/contrib/libpcap/pcap_is_swapped.3pcap @@ -0,0 +1,42 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_is_swapped.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_IS_SWAPPED 3PCAP "5 April 2008" +.SH NAME +pcap_is_swapped \- find out whether a savefile has the native byte order +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_is_swapped(pcap_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_is_swapped() +returns true if +.I p +refers to a ``savefile'' that uses a different byte order +than the current system. For a live capture, it always returns false. +.SH SEE ALSO +pcap(3PCAP) diff --git a/contrib/libpcap/pcap_lib_version.3pcap b/contrib/libpcap/pcap_lib_version.3pcap new file mode 100644 index 0000000000..fff9149713 --- /dev/null +++ b/contrib/libpcap/pcap_lib_version.3pcap @@ -0,0 +1,41 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_lib_version.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_LIB_VERSION 3PCAP "5 April 2008" +.SH NAME +pcap_lib_version \- get the version information for libpcap +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +const char *pcap_lib_version(void); +.ft +.fi +.SH DESCRIPTION +.B pcap_lib_version() +returns a pointer to a string giving information about the version of +the libpcap library being used; note that it contains more information +than just a version number. +.SH SEE ALSO +pcap(3PCAP) diff --git a/contrib/libpcap/pcap_list_datalinks.3pcap.in b/contrib/libpcap/pcap_list_datalinks.3pcap.in new file mode 100644 index 0000000000..822c70c519 --- /dev/null +++ b/contrib/libpcap/pcap_list_datalinks.3pcap.in @@ -0,0 +1,58 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_list_datalinks.3pcap.in,v 1.1.2.2 2008-10-21 07:44:57 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_LIST_DATALINKS 3PCAP "5 April 2008" +.SH NAME +pcap_list_datalinks \- get a list of link-layer header types supported +by a capture device +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_list_datalinks(pcap_t *p, int **dlt_buf); +.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. +.B pcap_list_datalinks() +allocates an array to hold the list and sets +.IR *dlt_buf . +The caller is responsible for freeing the array with +.BR pcap_free_datalinks (3PCAP). +.SH RETURN VALUE +.B pcap_list_datalinks() +returns the number of data link types in the array on success and \-1 +on failure. +If \-1 is returned, +.B pcap_geterr() +or +.B pcap_perror() +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-linktype(@MAN_MISC_INFO@) diff --git a/contrib/libpcap/pcap_lookupdev.3pcap b/contrib/libpcap/pcap_lookupdev.3pcap new file mode 100644 index 0000000000..2d80bf5b6a --- /dev/null +++ b/contrib/libpcap/pcap_lookupdev.3pcap @@ -0,0 +1,62 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_lookupdev.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_LOOKUPDEV 3PCAP "5 April 2008" +.SH NAME +pcap_lookupdev \- find the default device on which to capture +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.nf +.ft B +char errbuf[PCAP_ERRBUF_SIZE]; +.ft +.LP +.ft B +char *pcap_lookupdev(char *errbuf); +.ft +.fi +.SH DESCRIPTION +.B pcap_lookupdev() +returns a pointer to a string giving the name of a network device +suitable for use with +.B pcap_create() +and +.BR pcap_activate() , +or with +.BR pcap_open_live() , +and with +.BR pcap_lookupnet() . +If there is an error, +.B NULL +is returned and +.I errbuf +is filled in with an appropriate error message. +.I errbuf +is assumed to be able to hold at least +.B PCAP_ERRBUF_SIZE +chars. +.SH SEE ALSO +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP), +pcap_open_live(3PCAP), pcap_lookupnet(3PCAP) diff --git a/contrib/libpcap/pcap_lookupnet.3pcap b/contrib/libpcap/pcap_lookupnet.3pcap new file mode 100644 index 0000000000..031acb7812 --- /dev/null +++ b/contrib/libpcap/pcap_lookupnet.3pcap @@ -0,0 +1,65 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_lookupnet.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_LOOKUPNET 3PCAP "5 April 2008" +.SH NAME +pcap_lookupnet \- find the IPv4 network number and netmask for a device +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.nf +.ft B +char errbuf[PCAP_ERRBUF_SIZE]; +.ft +.LP +.ft B +int pcap_lookupnet(const char *device, bpf_u_int32 *netp, +.ti +8 +bpf_u_int32 *maskp, char *errbuf); +.ft +.fi +.SH DESCRIPTION +.B pcap_lookupnet() +is used to determine the IPv4 network number and mask +associated with the network device +.IR device . +Both +.I netp +and +.I maskp +are +.I bpf_u_int32 +pointers. +.SH RETURN VALUE +.B pcap_lookupnet() +returns 0 on success and \-1 on failure. +If \-1 is returned, +.I errbuf +is filled in with an appropriate error message. +.I errbuf +is assumed to be able to hold at least +.B PCAP_ERRBUF_SIZE +chars. +.SH SEE ALSO +pcap(3PCAP) diff --git a/contrib/libpcap/pcap_loop.3pcap b/contrib/libpcap/pcap_loop.3pcap new file mode 100644 index 0000000000..8e491d4c11 --- /dev/null +++ b/contrib/libpcap/pcap_loop.3pcap @@ -0,0 +1,150 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_loop.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_LOOP 3PCAP "5 April 2008" +.SH NAME +pcap_loop, pcap_dispatch \- process packets from a live capture or savefile +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h, +.ti +8 + const u_char *bytes); +.ft +.LP +.ft B +int pcap_loop(pcap_t *p, int cnt, +.ti +8 +pcap_handler callback, u_char *user); +int pcap_dispatch(pcap_t *p, int cnt, +.ti +8 +pcap_handler callback, u_char *user); +.ft +.fi +.SH DESCRIPTION +.B pcap_loop() +processes packets from a live capture or ``savefile'' until +.I cnt +packets are processed, the end of the ``savefile'' is +reached when reading from a ``savefile'', +.B pcap_breakloop() +is called, or an error occurs. +It does +.B not +return when live read timeouts occur. +A value of \-1 or 0 for +.I cnt +is equivalent to infinity, so that packets are processed until another +ending condition occurs. +.PP +.B pcap_dispatch() +processes packets from a live capture or ``savefile'' until +.I cnt +packets are processed, the end of the current bufferful of packets is +reached when doing a live capture, the end of the ``savefile'' is +reached when reading from a ``savefile'', +.B pcap_breakloop() +is called, or an error occurs. +Thus, when doing a live capture, +.I cnt +is the maximum number of packets to process before returning, but is not +a minimum number; when reading a live capture, only one +bufferful of packets is read at a time, so fewer than +.I cnt +packets may be processed. A value of \-1 or 0 for +.I cnt +causes all the packets received in one buffer to be processed when +reading a live capture, and causes all the packets in the file to be +processed when reading a ``savefile''. +.PP +.ft B +(In older versions of libpcap, the behavior when +\fIcnt\fP +was 0 was undefined; different platforms and devices behaved +differently, so code that must work with older versions of libpcap +should use \-1, nor 0, as the value of +\fIcnt\fP.) +.ft R +.PP +.I callback +specifies a routine to be called with three arguments: +a +.I u_char +pointer which is passed in the +.I user +argument to +.B pcap_loop() +or +.BR pcap_dispatch() , +a +.I const struct pcap_pkthdr +pointer pointing to the packet time stamp and lengths, and a +.I const u_char +pointer to the first +.B caplen +(as given in the +.I struct pcap_pkthdr +a pointer to which is passed to the callback routine) +bytes of data from the packet. +.SH RETURN VALUE +.B pcap_loop() +returns 0 if +.I cnt +is exhausted, \-1 if an error occurs, or \-2 if the loop terminated due +to a call to +.B pcap_breakloop() +before any packets were processed. +It does +.B not +return when live read timeouts occur; instead, it attempts to read more +packets. +.PP +.B pcap_dispatch() +returns the number of packets processed on success; this can be 0 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.'' It returns \-1 if an error occurs or \-2 if the loop +terminated due to a call to +.B pcap_breakloop() +before any packets were processed. +.ft B +If your application uses pcap_breakloop(), +make sure that you explicitly check for \-1 and \-2, rather than just +checking for a return value < 0. +.ft R +.PP +If \-1 is returned, +.B pcap_geterr() +or +.B pcap_perror() +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_breakloop(3PCAP) diff --git a/contrib/libpcap/pcap_major_version.3pcap b/contrib/libpcap/pcap_major_version.3pcap new file mode 100644 index 0000000000..1eabcf00f2 --- /dev/null +++ b/contrib/libpcap/pcap_major_version.3pcap @@ -0,0 +1,54 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_major_version.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_MAJOR_VERSION 3PCAP "5 April 2008" +.SH NAME +pcap_major_version, pcap_minor_version \- get the version number of a savefile +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_major_version(pcap_t *p); +int pcap_minor_version(pcap_t *p); +.ft +.fi +.SH DESCRIPTION +If +.I p +refers to a savefile, +.B pcap_major_version() +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. +.PP +If +.I p +refers to a live capture, the values returned by +.B pcap_major_version() +and +.B pcap_minor_version() +are not meaningful. +.SH SEE ALSO +pcap(3PCAP) diff --git a/contrib/libpcap/pcap_next_ex.3pcap b/contrib/libpcap/pcap_next_ex.3pcap new file mode 100644 index 0000000000..d472a2b6e1 --- /dev/null +++ b/contrib/libpcap/pcap_next_ex.3pcap @@ -0,0 +1,90 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_next_ex.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_NEXT_EX 3PCAP "5 April 2008" +.SH NAME +pcap_next_ex, pcap_next \- read the next packet from a pcap_t +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, +.ti +8 +const u_char **pkt_data); +const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h); +.ft +.fi +.SH DESCRIPTION +.B pcap_next_ex() +reads the next packet and returns a success/failure indication. +If the packet was read without problems, the pointer pointed to by the +.I pkt_header +argument is set to point to the +.I pcap_pkthdr +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. +.PP +.B pcap_next() +reads the next packet (by calling +.B pcap_dispatch() +with a +.I cnt +of 1) and returns a +.I u_char +pointer to the data in that packet. +The +.I pcap_pkthdr +structure pointed to by +.I h +is filled in with the appropriate values for the packet. +.SH RETURN VALUE +.B pcap_next_ex() +returns 1 if the packet was read without problems, 0 +if packets are being read from a live capture, and the timeout expired, +\-1 if an error occurred while reading the packet, and \-2 if +packets are being read from a ``savefile'', and there are no more +packets to read from the savefile. +If \-1 is returned, +.B pcap_geterr() +or +.B pcap_perror() +may be called with +.I p +as an argument to fetch or display the error text. +.PP +.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 +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. +.SH SEE ALSO +pcap(3PCAP), pcap_geterr(3PCAP), pcap_dispatch(3PCAP) diff --git a/contrib/libpcap/pcap_offline_filter.3pcap b/contrib/libpcap/pcap_offline_filter.3pcap new file mode 100644 index 0000000000..0ec6977884 --- /dev/null +++ b/contrib/libpcap/pcap_offline_filter.3pcap @@ -0,0 +1,57 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_offline_filter.3pcap,v 1.1.2.1 2008-05-13 15:20:44 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_OFFLINE_FILTER 3PCAP "13 May 2008" +.SH NAME +pcap_offline_filter \- check whether a filter matches a packet +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_offline_filter(struct bpf_program *fp, +.ti +8 +const struct pcap_pkthdr *h, const u_char *pkt) +.ft +.fi +.SH DESCRIPTION +.B pcap_offline_filter() +checks whether a filter matches a packet. +.I fp +is a pointer to a +.I bpf_program +struct, usually the result of a call to +.BR pcap_compile() . +.I h +points to the +.I pcap_pkthdr +structure for the packet, and +.I pkt +points to the data in the packet. +.SH RETURN VALUE +.B pcap_offline_filter() +returns the return value of the filter program. This will be zero if +the packet doesn't match the filter and non-zero if the packet matches +the filter. +.SH SEE ALSO +pcap(3PCAP), pcap_compile(3PCAP) diff --git a/contrib/libpcap/pcap_open_dead.3pcap.in b/contrib/libpcap/pcap_open_dead.3pcap.in new file mode 100644 index 0000000000..18c98ffcab --- /dev/null +++ b/contrib/libpcap/pcap_open_dead.3pcap.in @@ -0,0 +1,52 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_open_dead.3pcap.in,v 1.1.2.2 2008-10-21 07:44:57 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_OPEN_DEAD 3PCAP "5 April 2008" +.SH NAME +pcap_open_dead \- open a fake pcap_t for compiling filters or opening a +capture for output +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +pcap_t *pcap_open_dead(int linktype, int snaplen); +.ft +.fi +.SH DESCRIPTION +.PP +.B pcap_open_dead() +is used for creating a +.B pcap_t +structure to use when calling the other functions in libpcap. It is +typically used when just using libpcap for compiling BPF code. +.PP +.I linktype +specifies the link-layer type for the +.BR pcap_t . +.PP +.I snaplen +specifies the snapshot length for the +.BR pcap_t . +.SH SEE ALSO +pcap(3PCAP), pcap-linktype(@MAN_MISC_INFO@) diff --git a/contrib/libpcap/pcap_open_live.3pcap b/contrib/libpcap/pcap_open_live.3pcap new file mode 100644 index 0000000000..6ef1d5fbd1 --- /dev/null +++ b/contrib/libpcap/pcap_open_live.3pcap @@ -0,0 +1,89 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_open_live.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_OPEN_LIVE 3PCAP "5 April 2008" +.SH NAME +pcap_open_live \- open a device for capturing +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.nf +.ft B +char errbuf[PCAP_ERRBUF_SIZE]; +.ft +.LP +.ft B +pcap_t *pcap_open_live(const char *device, int snaplen, +.ti +8 +int promisc, int to_ms, char *errbuf); +.ft +.fi +.SH DESCRIPTION +.B pcap_open_live() +is used to obtain a packet capture handle to look +at packets on the network. +.I device +is a string that specifies the network device to open; on Linux systems +with 2.2 or later kernels, a +.I device +argument of "any" or +.B NULL +can be used to capture packets from all interfaces. +.PP +.I snaplen +specifies the snapshot length to be set on the handle. +.PP +.I promisc +specifies if the interface is to be put into promiscuous mode. +.PP +.I to_ms +specifies the read timeout in milliseconds. +.SH RETURN VALUE +.B pcap_open_live() +returns a +.I pcap_t * +on success and +.B NULL +on failure. +If +.B NULL +is returned, +.I errbuf +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 +.I errbuf +before calling +.B pcap_open_live() +and display the warning to the user if +.I errbuf +is no longer a zero-length string. +.I errbuf +is assumed to be able to hold at least +.B PCAP_ERRBUF_SIZE +chars. +.SH SEE ALSO +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP) diff --git a/contrib/libpcap/pcap_open_offline.3pcap.in b/contrib/libpcap/pcap_open_offline.3pcap.in new file mode 100644 index 0000000000..ce350ddf7b --- /dev/null +++ b/contrib/libpcap/pcap_open_offline.3pcap.in @@ -0,0 +1,78 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_open_offline.3pcap.in,v 1.1.2.2 2008-10-23 05:59:43 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_OPEN_OFFLINE 3PCAP "5 April 2008" +.SH NAME +pcap_open_offline, pcap_fopen_offline \- open a saved capture file for reading +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.nf +.ft B +char errbuf[PCAP_ERRBUF_SIZE]; +.ft +.LP +.ft B +pcap_t *pcap_open_offline(const char *fname, char *errbuf); +pcap_t *pcap_fopen_offline(FILE *fp, char *errbuf); +.ft +.fi +.SH DESCRIPTION +.B pcap_open_offline() +is called to open a ``savefile'' for reading. +.PP +.I fname +specifies the name of the file to open. The file has +the same format as those used by +.BR tcpdump (1) +and +.BR tcpslice (1). +The name "-" in a synonym for +.BR stdin . +.PP +Alternatively, you may call +.B pcap_fopen_offline() +to read dumped data from an existing open stream +.IR fp . +Note that on Windows, that stream should be opened in binary mode. +.SH RETURN VALUE +.B pcap_open_offline() +and +.B pcap_fopen_offline() +return a +.I pcap_t * +on success and +.B NULL +on failure. +If +.B NULL +is returned, +.I errbuf +is filled in with an appropriate error message. +.I errbuf +is assumed to be able to hold at least +.B PCAP_ERRBUF_SIZE +chars. +.SH SEE ALSO +pcap(3PCAP), pcap-savefile(@MAN_FILE_FORMATS@) diff --git a/contrib/libpcap/pcap_set_buffer_size.3pcap b/contrib/libpcap/pcap_set_buffer_size.3pcap new file mode 100644 index 0000000000..d26a7a5d0b --- /dev/null +++ b/contrib/libpcap/pcap_set_buffer_size.3pcap @@ -0,0 +1,47 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_set_buffer_size.3pcap,v 1.1.2.1 2008-04-06 03:21:56 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_SET_BUFFER_SIZE 3PCAP "5 April 2008" +.SH NAME +pcap_set_buffer_size \- set the buffer size for a not-yet-activated +capture handle +.SH SYNOPSIS +.nf +.ft B +#include +.LP +.ft B +int pcap_set_buffer_size(pcap_t *p, int buffer_size); +.ft +.fi +.SH DESCRIPTION +.B pcap_set_buffer_size() +sets the buffer size that will be used on a capture handle when +the handle is activated to +.IR buffer_size , +which is in units of bytes. +.SH RETURN VALUE +.B pcap_set_buffer_size() +returns 0 on success or +.B PCAP_ERROR_ACTIVATED +if called on a capture handle that has been activated. +.SH SEE ALSO +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP) diff --git a/contrib/libpcap/pcap_set_datalink.3pcap b/contrib/libpcap/pcap_set_datalink.3pcap new file mode 100644 index 0000000000..5754d764d1 --- /dev/null +++ b/contrib/libpcap/pcap_set_datalink.3pcap @@ -0,0 +1,52 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_set_datalink.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_SET_DATALINK 3PCAP "5 April 2008" +.SH NAME +pcap_set_datalink \- set the link-layer header type to be used by a +capture device +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_set_datalink(pcap_t *p, int dlt); +.ft +.fi +.SH DESCRIPTION +.B pcap_set_datalink() +is used to set the current data link type of the pcap descriptor +to the type specified by +.IR dlt . +.SH RETURN VALUE +.B pcap_set_datalink() +returns 0 on success and \-1 on failure. +If \-1 is returned, +.B pcap_geterr() +or +.B pcap_perror() +may be called with +.I p +as an argument to fetch or display the error text. +.SH SEE ALSO +pcap(3PCAP), pcap_geterr(3PCAP) diff --git a/contrib/libpcap/pcap_set_promisc.3pcap b/contrib/libpcap/pcap_set_promisc.3pcap new file mode 100644 index 0000000000..27c071455c --- /dev/null +++ b/contrib/libpcap/pcap_set_promisc.3pcap @@ -0,0 +1,48 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_set_promisc.3pcap,v 1.1.2.1 2008-04-06 03:21:56 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_SET_PROMISC 3PCAP "5 April 2008" +.SH NAME +pcap_set_promisc \- set promiscuous mode for a not-yet-activated +capture handle +.SH SYNOPSIS +.nf +.ft B +#include +.LP +.ft B +int pcap_set_promisc(pcap_t *p, int promisc); +.ft +.fi +.SH DESCRIPTION +.B pcap_set_promisc() +sets whether promiscuous mode should be set on a capture handle when +the handle is activated. +If +.I promisc +is non-zero, promiscuous mode will be set, otherwise it will not be set. +.SH RETURN VALUE +.B pcap_set_promisc() +returns 0 on success or +.B PCAP_ERROR_ACTIVATED +if called on a capture handle that has been activated. +.SH SEE ALSO +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP) diff --git a/contrib/libpcap/pcap_set_rfmon.3pcap b/contrib/libpcap/pcap_set_rfmon.3pcap new file mode 100644 index 0000000000..ceb62a676a --- /dev/null +++ b/contrib/libpcap/pcap_set_rfmon.3pcap @@ -0,0 +1,49 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_set_rfmon.3pcap,v 1.1.2.1 2008-04-06 03:21:56 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_SET_RFMON 3PCAP "5 April 2008" +.SH NAME +pcap_set_rfmon \- set monitor mode for a not-yet-activated capture +handle +.SH SYNOPSIS +.nf +.ft B +#include +.LP +.ft B +int pcap_set_rfmon(pcap_t *p, int rfmon); +.ft +.fi +.SH DESCRIPTION +.B pcap_set_rfmon() +sets whether monitor mode should be set on a capture handle when +the handle is activated. +If +.I rfmon +is non-zero, monitor mode will be set, otherwise it will not be set. +.SH RETURN VALUE +.B pcap_set_rfmon() +returns 0 on success or +.B PCAP_ERROR_ACTIVATED +if called on a capture handle that has been activated. +.SH SEE ALSO +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP), +pcap_can_set_rfmon(3PCAP) diff --git a/contrib/libpcap/pcap_set_snaplen.3pcap b/contrib/libpcap/pcap_set_snaplen.3pcap new file mode 100644 index 0000000000..10093e482b --- /dev/null +++ b/contrib/libpcap/pcap_set_snaplen.3pcap @@ -0,0 +1,46 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_set_snaplen.3pcap,v 1.1.2.1 2008-04-06 03:21:56 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_SET_SNAPLEN 3PCAP "5 April 2008" +.SH NAME +pcap_set_snaplen \- set the snapshot length for a not-yet-activated +capture handle +.SH SYNOPSIS +.nf +.ft B +#include +.LP +.ft B +int pcap_set_snaplen(pcap_t *p, int snaplen); +.ft +.fi +.SH DESCRIPTION +.B pcap_set_snaplen() +sets the snapshot length to be used on a capture handle when the handle +is activated to +.IR snaplen . +.SH RETURN VALUE +.B pcap_set_snaplen() +returns 0 on success or +.B PCAP_ERROR_ACTIVATED +if called on a capture handle that has been activated. +.SH SEE ALSO +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP) diff --git a/contrib/libpcap/pcap_set_timeout.3pcap b/contrib/libpcap/pcap_set_timeout.3pcap new file mode 100644 index 0000000000..17f2c31e40 --- /dev/null +++ b/contrib/libpcap/pcap_set_timeout.3pcap @@ -0,0 +1,47 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_set_timeout.3pcap,v 1.1.2.1 2008-04-06 03:21:56 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_SET_TIMEOUT 3PCAP "5 April 2008" +.SH NAME +pcap_set_timeout \- set the read timeout for a not-yet-activated +capture handle +.SH SYNOPSIS +.nf +.ft B +#include +.LP +.ft B +int pcap_set_timeout(pcap_t *p, int to_ms); +.ft +.fi +.SH DESCRIPTION +.B pcap_set_timeout() +sets the read timeout that will be used on a capture handle when +the handle is activated to +.IR to_ms , +which is in units of milliseconds. +.SH RETURN VALUE +.B pcap_set_timeout() +returns 0 on success or +.B PCAP_ERROR_ACTIVATED +if called on a capture handle that has been activated. +.SH SEE ALSO +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP) diff --git a/contrib/libpcap/pcap_setdirection.3pcap b/contrib/libpcap/pcap_setdirection.3pcap new file mode 100644 index 0000000000..70891a2583 --- /dev/null +++ b/contrib/libpcap/pcap_setdirection.3pcap @@ -0,0 +1,71 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_setdirection.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_SETDIRECTION 3PCAP "5 April 2008" +.SH NAME +pcap_setdirection \- set the direction for which packets will be captured +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_setdirection(pcap_t *p, pcap_direction_t d); +.ft +.fi +.SH DESCRIPTION +.B pcap_setdirection() +is used to specify a direction that packets will be captured. +.I d +is one of the constants +.BR PCAP_D_IN , +.B PCAP_D_OUT +or +.BR PCAP_D_INOUT . +.B PCAP_D_IN +will only capture packets received by the device, +.B PCAP_D_OUT +will only capture packets sent by the device and +.B PCAP_D_INOUT +will capture packets received by or sent by the device. +.B PCAP_D_INOUT +is the default setting if this function is not called. +.PP +.B pcap_setdirection() +isn't necessarily fully supported on all platforms; some platforms might +return an error for all values, and some other platforms might not +support +.BR PCAP_D_OUT . +.PP +This operation is not supported if a ``savefile'' is being read. +.SH RETURN VALUE +.B pcap_setdirection() +returns 0 on success and \-1 on failure. +If \-1 is returned, +.B pcap_geterr() +or +.B pcap_perror() +may be called with +.I p +as an argument to fetch or display the error text. +.SH SEE ALSO +pcap(3PCAP), pcap_geterr(3PCAP) diff --git a/contrib/libpcap/pcap_setfilter.3pcap b/contrib/libpcap/pcap_setfilter.3pcap new file mode 100644 index 0000000000..67c1214fa3 --- /dev/null +++ b/contrib/libpcap/pcap_setfilter.3pcap @@ -0,0 +1,54 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_setfilter.3pcap,v 1.1.2.4 2008-05-13 15:20:44 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_SETFILTER 3PCAP "5 April 2008" +.SH NAME +pcap_setfilter \- set the filter +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_setfilter(pcap_t *p, struct bpf_program *fp); +.ft +.fi +.SH DESCRIPTION +.B pcap_setfilter() +is used to specify a filter program. +.I fp +is a pointer to a +.I bpf_program +struct, usually the result of a call to +.BR pcap_compile() . +.SH RETURN VALUE +.B pcap_setfilter() +returns 0 on success and \-1 on failure. +If \-1 is returned, +.B pcap_geterr() +or +.B pcap_perror() +may be called with +.I p +as an argument to fetch or display the error text. +.SH SEE ALSO +pcap(3PCAP), pcap_compile(3PCAP), pcap_geterr(3PCAP) diff --git a/contrib/libpcap/pcap_setnonblock.3pcap b/contrib/libpcap/pcap_setnonblock.3pcap new file mode 100644 index 0000000000..07d962938c --- /dev/null +++ b/contrib/libpcap/pcap_setnonblock.3pcap @@ -0,0 +1,75 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_setnonblock.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_SETNONBLOCK 3PCAP "5 April 2008" +.SH NAME +pcap_setnonblock, pcap_getnonblock \- set or get the state of +non-blocking mode on a capture device +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.nf +.ft B +char errbuf[PCAP_ERRBUF_SIZE]; +.ft +.LP +.ft B +int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf); +int pcap_getnonblock(pcap_t *p, char *errbuf); +.ft +.fi +.SH DESCRIPTION +.B pcap_setnonblock() +puts a capture handle into ``non-blocking'' mode, or takes it out +of ``non-blocking'' mode, depending on whether the +.I nonblock +argument is non-zero or zero. It has no effect on ``savefiles''. +If there is an error, \-1 is returned and +.I errbuf +is filled in with an appropriate error message; otherwise, 0 is +returned. +In +``non-blocking'' mode, an attempt to read from the capture descriptor +with +.B pcap_dispatch() +will, if no packets are currently available to be read, return 0 +immediately rather than blocking waiting for packets to arrive. +.B pcap_loop() +and +.B pcap_next() +will not work in ``non-blocking'' mode. +.SH RETURN VALUE +.B pcap_getnonblock() +returns the current ``non-blocking'' state of the capture descriptor; it +always returns 0 on ``savefiles''. +If there is an error, \-1 is returned and +.I errbuf +is filled in with an appropriate error message. +.PP +.I errbuf +is assumed to be able to hold at least +.B PCAP_ERRBUF_SIZE +chars. +.SH SEE ALSO +pcap(3PCAP), pcap_loop(3PCAP), pcap_next_ex(3PCAP), pcap_geterr(3PCAP) diff --git a/contrib/libpcap/pcap_snapshot.3pcap b/contrib/libpcap/pcap_snapshot.3pcap new file mode 100644 index 0000000000..19bb9dec61 --- /dev/null +++ b/contrib/libpcap/pcap_snapshot.3pcap @@ -0,0 +1,44 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_snapshot.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_SNAPSHOT 3PCAP "5 April 2008" +.SH NAME +pcap_snapshot \- get the snapshot length +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_snapshot(pcap_t *p); +.ft +.fi +.SH DESCRIPTION +.B pcap_snapshot() +returns the snapshot length specified when +.B pcap_set_snapshot() +or +.B pcap_open_live() +was called, for a live capture, or the snapshot length from the capture +file, for a ``savefile''. +.SH SEE ALSO +pcap(3PCAP) diff --git a/contrib/libpcap/pcap_stats.3pcap b/contrib/libpcap/pcap_stats.3pcap new file mode 100644 index 0000000000..0a68c1ec21 --- /dev/null +++ b/contrib/libpcap/pcap_stats.3pcap @@ -0,0 +1,59 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_stats.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_SNAPSHOT 3PCAP "5 April 2008" +.SH NAME +pcap_stats \- get capture statistics +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +int pcap_stats(pcap_t *p, struct pcap_stat *ps); +.ft +.fi +.SH DESCRIPTION +.B pcap_stats() +fills in the +.I pcap_stat +structure pointed to by its second argument. The values represent +packet statistics from the start of the run to the time of the call. +.PP +.B pcap_stats() +is supported only on live captures, not on ``savefiles''; no statistics +are stored in ``savefiles'', so no statistics are available when reading +from a ``savefile''. +.SH RETURN VALUE +.B pcap_stats() +returns 0 on success and returns \-1 if there is an error or the +.I p +doesn't support packet statistics. +If \-1 is returned, +.B pcap_geterr() +or +.B pcap_perror() +may be called with +.I p +as an argument to fetch or display the error text. +.SH SEE ALSO +pcap(3PCAP), pcap_geterr(3PCAP) diff --git a/contrib/libpcap/pcap_statustostr.3pcap b/contrib/libpcap/pcap_statustostr.3pcap new file mode 100644 index 0000000000..5e8942c158 --- /dev/null +++ b/contrib/libpcap/pcap_statustostr.3pcap @@ -0,0 +1,43 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_statustostr.3pcap,v 1.1.2.1 2008-04-09 21:41:53 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_STATUSTOSTR 3PCAP "9 April 2008" +.SH NAME +pcap_statustostr \- convert a PCAP_ERROR_ or PCAP_WARNING_ value to a string +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +const char *pcap_statustostr(int error); +.ft +.fi +.SH DESCRIPTION +.B pcap_statustostr() +converts a +.B PCAP_ERROR_ +or +.B PCAP_WARNING_ +value returned by a libpcap routine to an error string. +.SH SEE ALSO +pcap(3PCAP) diff --git a/contrib/libpcap/pcap_strerror.3pcap b/contrib/libpcap/pcap_strerror.3pcap new file mode 100644 index 0000000000..eacdce492e --- /dev/null +++ b/contrib/libpcap/pcap_strerror.3pcap @@ -0,0 +1,42 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap_strerror.3pcap,v 1.1.2.3 2008-04-06 03:21:56 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_STRERROR 3PCAP "4 April 2008" +.SH NAME +pcap_strerror \- convert an errno value to a string +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.ft B +const char *pcap_strerror(int error); +.ft +.fi +.SH DESCRIPTION +.B pcap_strerror() +is provided in case +.BR strerror (3) +isn't available. It returns an error message string corresponding to +.IR error . +.SH SEE ALSO +strerror(3) diff --git a/contrib/libpcap/pf.h b/contrib/libpcap/pf.h deleted file mode 100644 index a9b127ac29..0000000000 --- a/contrib/libpcap/pf.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2001 Daniel Hartmeier - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @(#) $Header: /tcpdump/master/libpcap/pf.h,v 1.3 2004/04/02 06:33:30 guy Exp $ (LBL) - */ - -/* from $OpenBSD: pfvar.h,v 1.170 2003/08/22 21:50:34 david Exp $ */ - -enum { PF_INOUT=0, PF_IN=1, PF_OUT=2 }; -enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2, PF_NAT=3, PF_NONAT=4, - PF_BINAT=5, PF_NOBINAT=6, PF_RDR=7, PF_NORDR=8, PF_SYNPROXY_DROP=9 }; - -/* Reasons code for passing/dropping a packet */ -#define PFRES_MATCH 0 /* Explicit match of a rule */ -#define PFRES_BADOFF 1 /* Bad offset for pull_hdr */ -#define PFRES_FRAG 2 /* Dropping following fragment */ -#define PFRES_SHORT 3 /* Dropping short packet */ -#define PFRES_NORM 4 /* Dropping by normalizer */ -#define PFRES_MEMORY 5 /* Dropped due to lacking mem */ -#define PFRES_MAX 6 /* total+1 */ - -#define PFRES_NAMES { \ - "match", \ - "bad-offset", \ - "fragment", \ - "short", \ - "normalize", \ - "memory", \ - NULL \ -} - -#define PF_RULESET_NAME_SIZE 16 - -/* from $OpenBSD: if_pflog.h,v 1.9 2003/07/15 20:27:27 dhartmei Exp $ */ - -#ifndef IFNAMSIZ -#define IFNAMSIZ 16 -#endif - -struct pfloghdr { - u_int8_t length; - u_int8_t af; - u_int8_t action; - u_int8_t reason; - char ifname[IFNAMSIZ]; - char ruleset[PF_RULESET_NAME_SIZE]; - u_int32_t rulenr; - u_int32_t subrulenr; - u_int8_t dir; - u_int8_t pad[3]; -}; -#define PFLOG_HDRLEN sizeof(struct pfloghdr) diff --git a/contrib/libpcap/savefile.c b/contrib/libpcap/savefile.c index e5a540315f..65416f64db 100644 --- a/contrib/libpcap/savefile.c +++ b/contrib/libpcap/savefile.c @@ -30,7 +30,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.126.2.30 2007/08/14 20:57:49 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.168.2.10 2008-10-06 15:38:39 gianluca Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -44,6 +44,7 @@ static const char rcsid[] _U_ = #include #include "pcap-int.h" +#include "pcap/usb.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" @@ -146,11 +147,12 @@ static const char rcsid[] _U_ = * * In order to ensure that a given LINKTYPE_* code's value will refer to * the same encapsulation type on all platforms, you should not allocate - * a new LINKTYPE_* value without consulting "tcpdump-workers@tcpdump.org". - * The tcpdump developers will allocate a value for you, and will not - * subsequently allocate it to anybody else; that value will be added to - * the "pcap.h" in the tcpdump.org CVS repository, so that a future - * libpcap release will include it. + * a new LINKTYPE_* value without consulting + * "tcpdump-workers@lists.tcpdump.org". The tcpdump developers will + * allocate a value for you, and will not subsequently allocate it to + * anybody else; that value will be added to the "pcap.h" in the + * tcpdump.org CVS repository, so that a future libpcap release will + * include it. * * You should, if possible, also contribute patches to libpcap and tcpdump * to handle the new encapsulation type, so that they can also be checked @@ -312,9 +314,9 @@ static const char rcsid[] _U_ = * for *their* private type and tools using them for *your* private type * would have to read them. * - * Instead, in those cases, ask "tcpdump-workers@tcpdump.org" for a new DLT_ - * and LINKTYPE_ value, as per the comment in pcap-bpf.h, and use the type - * you're given. + * Instead, in those cases, ask "tcpdump-workers@lists.tcpdump.org" for a + * new DLT_ and LINKTYPE_ value, as per the comment in pcap/bpf.h, and use + * the type you're given. */ #define LINKTYPE_USER0 147 #define LINKTYPE_USER1 148 @@ -551,6 +553,100 @@ static const char rcsid[] _U_ = */ #define LINKTYPE_IPMB 199 +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for capturing data on a secure tunnel interface. + */ +#define LINKTYPE_JUNIPER_ST 200 + +/* + * Bluetooth HCI UART transport layer (part H:4), with pseudo-header + * that includes direction information; requested by Paolo Abeni. + */ +#define LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR 201 + +/* + * AX.25 packet with a 1-byte KISS header; see + * + * http://www.ax25.net/kiss.htm + * + * as per Richard Stearn . + */ +#define LINKTYPE_AX25_KISS 202 + +/* + * LAPD packets from an ISDN channel, starting with the address field, + * with no pseudo-header. + * Requested by Varuna De Silva . + */ +#define LINKTYPE_LAPD 203 + +/* + * Variants of various link-layer headers, with a one-byte direction + * pseudo-header prepended - zero means "received by this host", + * non-zero (any non-zero value) means "sent by this host" - as per + * Will Barker . + */ +#define LINKTYPE_PPP_WITH_DIR 204 /* PPP */ +#define LINKTYPE_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ +#define LINKTYPE_FRELAY_WITH_DIR 206 /* Frame Relay */ +#define LINKTYPE_LAPB_WITH_DIR 207 /* LAPB */ + +/* + * 208 is reserved for an as-yet-unspecified proprietary link-layer + * type, as requested by Will Barker. + */ + +/* + * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman + * . + */ +#define LINKTYPE_IPMB_LINUX 209 + +/* + * FlexRay automotive bus - http://www.flexray.com/ - as requested + * by Hannes Kaelber . + */ +#define LINKTYPE_FLEXRAY 210 + +/* + * Media Oriented Systems Transport (MOST) bus for multimedia + * transport - http://www.mostcooperation.com/ - as requested + * by Hannes Kaelber . + */ +#define LINKTYPE_MOST 211 + +/* + * Local Interconnect Network (LIN) bus for vehicle networks - + * http://www.lin-subbus.org/ - as requested by Hannes Kaelber + * . + */ +#define LINKTYPE_LIN 212 + +/* + * X2E-private data link type used for serial line capture, + * as requested by Hannes Kaelber . + */ +#define LINKTYPE_X2E_SERIAL 213 + +/* + * X2E-private data link type used for the Xoraya data logger + * family, as requested by Hannes Kaelber . + */ +#define LINKTYPE_X2E_XORAYA 214 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing), but with the PHY-level data for non-ASK PHYs (4 octets + * of 0 as preamble, one octet of SFD, one octet of frame length+ + * reserved bit, and then the MAC-layer data, starting with the + * frame control field). + * + * Requested by Max Filippov . + */ +#define LINKTYPE_IEEE802_15_4_NONASK_PHY 215 + static struct linktype_map { int dlt; @@ -811,9 +907,66 @@ static struct linktype_map { /* 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 }, + { -1, -1 } }; +/* + * Mechanism for storing information about a capture in the upper + * 6 bits of a linktype value in a capture file. + * + * LT_LINKTYPE_EXT(x) extracts the additional information. + * + * The rest of the bits are for a value describing the link-layer + * value. LT_LINKTYPE(x) extracts that value. + */ +#define LT_LINKTYPE(x) ((x) & 0x03FFFFFF) +#define LT_LINKTYPE_EXT(x) ((x) & 0xFC000000) + static int dlt_to_linktype(int dlt) { @@ -909,6 +1062,32 @@ sf_stats(pcap_t *p, struct pcap_stat *ps) return (-1); } +#ifdef WIN32 +static int +sf_setbuff(pcap_t *p, int dim) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "The kernel buffer size cannot be set while reading from a file"); + return (-1); +} + +static int +sf_setmode(pcap_t *p, int mode) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "impossible to set mode while reading from a file"); + return (-1); +} + +static int +sf_setmintocopy(pcap_t *p, int size) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "The mintocopy parameter cannot be set while reading from a file"); + return (-1); +} +#endif + static int sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_) { @@ -930,7 +1109,7 @@ sf_setdirection(pcap_t *p, pcap_direction_t d) } static void -sf_close(pcap_t *p) +sf_cleanup(pcap_t *p) { if (p->sf.rfile != stdin) (void)fclose(p->sf.rfile); @@ -975,6 +1154,33 @@ pcap_open_offline(const char *fname, char *errbuf) return (p); } +#ifdef WIN32 +pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf) +{ + int fd; + FILE *file; + + fd = _open_osfhandle(osfd, _O_RDONLY); + if ( fd < 0 ) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, pcap_strerror(errno)); + return NULL; + } + + file = _fdopen(fd, "rb"); + if ( file == NULL ) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, pcap_strerror(errno)); + return NULL; + } + + return pcap_fopen_offline(file, errbuf); +} +#endif + +#ifdef WIN32 +static +#endif pcap_t * pcap_fopen_offline(FILE *fp, char *errbuf) { @@ -1044,7 +1250,8 @@ pcap_fopen_offline(FILE *fp, char *errbuf) } p->tzoff = hdr.thiszone; p->snapshot = hdr.snaplen; - p->linktype = linktype_to_dlt(hdr.linktype); + p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype)); + p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype); if (magic == KUZNETZOV_TCPDUMP_MAGIC && p->linktype == DLT_EN10MB) { /* * This capture might have been done in raw mode or cooked @@ -1157,7 +1364,13 @@ pcap_fopen_offline(FILE *fp, char *errbuf) p->getnonblock_op = sf_getnonblock; p->setnonblock_op = sf_setnonblock; p->stats_op = sf_stats; - p->close_op = sf_close; +#ifdef WIN32 + p->setbuff_op = sf_setbuff; + p->setmode_op = sf_setmode; + p->setmintocopy_op = sf_setmintocopy; +#endif + p->cleanup_op = sf_cleanup; + p->activated = 1; return (p); bad: @@ -1195,8 +1408,9 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen) } else { if (amt_read != 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "truncated dump file; tried to read %d header bytes, only got %lu", - p->sf.hdrsize, (unsigned long)amt_read); + "truncated dump file; tried to read %lu header bytes, only got %lu", + (unsigned long)p->sf.hdrsize, + (unsigned long)amt_read); return (-1); } /* EOF */ @@ -1306,6 +1520,44 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen) return (-1); } } + + /* + * The DLT_USB_LINUX header is in host byte order when capturing + * (it's supplied directly from a memory-mapped buffer shared + * by the kernel). + * + * When reading a DLT_USB_LINUX capture file, we need to convert + * it from the capturing host's byte order to the reading host's + * byte order. + */ + if (p->sf.swapped && p->linktype == DLT_USB_LINUX) { + pcap_usb_header* uhdr = (pcap_usb_header*) buf; + /* + * The URB id is a totally opaque value; do we really need to + * converte it to the reading host's byte order??? + */ + if (hdr->caplen < 8) + return 0; + uhdr->id = SWAPLL(uhdr->id); + if (hdr->caplen < 14) + return 0; + uhdr->bus_id = SWAPSHORT(uhdr->bus_id); + if (hdr->caplen < 24) + return 0; + uhdr->ts_sec = SWAPLL(uhdr->ts_sec); + if (hdr->caplen < 28) + return 0; + uhdr->ts_usec = SWAPLONG(uhdr->ts_usec); + if (hdr->caplen < 32) + return 0; + uhdr->status = SWAPLONG(uhdr->status); + if (hdr->caplen < 36) + return 0; + uhdr->urb_len = SWAPLONG(uhdr->urb_len); + if (hdr->caplen < 40) + return 0; + uhdr->data_len = SWAPLONG(uhdr->data_len); + } return (0); } @@ -1420,6 +1672,7 @@ pcap_dump_open(pcap_t *p, const char *fname) fname, linktype); return (NULL); } + linktype |= p->linktype_ext; if (fname[0] == '-' && fname[1] == '\0') { f = stdout; @@ -1454,6 +1707,7 @@ pcap_dump_fopen(pcap_t *p, FILE *f) linktype); return (NULL); } + linktype |= p->linktype_ext; return (pcap_setup_dump(p, linktype, f, "stream")); } diff --git a/contrib/libpcap/scanner.l b/contrib/libpcap/scanner.l index 01face17dc..c477684e14 100644 --- a/contrib/libpcap/scanner.l +++ b/contrib/libpcap/scanner.l @@ -22,7 +22,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.99.2.9 2007/06/11 09:52:05 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.110.2.2 2008/02/06 10:21:47 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -52,7 +52,7 @@ static const char rcsid[] _U_ = #define AI_NUMERICHOST 0x04 #endif #endif /*INET6*/ -#include +#include #include "tokdefs.h" #ifdef HAVE_OS_PROTO_H @@ -79,6 +79,7 @@ extern YYSTYPE yylval; N ([0-9]+|(0X|0x)[0-9A-Fa-f]+) B ([0-9A-Fa-f][0-9A-Fa-f]?) +B2 ([0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]) W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?) %a 18400 @@ -166,6 +167,10 @@ V6004 ::{N}\.{N}\.{N}\.{N} V6 ({V680}|{V670}|{V671}|{V672}|{V673}|{V674}|{V675}|{V676}|{V677}|{V660}|{V661}|{V662}|{V663}|{V664}|{V665}|{V666}|{V650}|{V651}|{V652}|{V653}|{V654}|{V655}|{V640}|{V641}|{V642}|{V643}|{V644}|{V630}|{V631}|{V632}|{V633}|{V620}|{V621}|{V622}|{V610}|{V611}|{V600}|{V6604}|{V6504}|{V6514}|{V6524}|{V6534}|{V6544}|{V6554}|{V6404}|{V6414}|{V6424}|{V6434}|{V6444}|{V6304}|{V6314}|{V6324}|{V6334}|{V6204}|{V6214}|{V6224}|{V6104}|{V6114}|{V6004}) +MAC ({B}:{B}:{B}:{B}:{B}:{B}|{B}\-{B}\-{B}\-{B}\-{B}\-{B}|{B}\.{B}\.{B}\.{B}\.{B}\.{B}|{B2}\.{B2}\.{B2}|{B2}{3}) + + + %% dst return DST; src return SRC; @@ -247,6 +252,14 @@ protochain { gateway return GATEWAY; +type return TYPE; +subtype return SUBTYPE; +direction|dir return DIR; +address1|addr1 return ADDR1; +address2|addr2 return ADDR2; +address3|addr3 return ADDR3; +address4|addr4 return ADDR4; + less return LESS; greater return GREATER; byte return CBYTE; @@ -307,11 +320,11 @@ sls return SLS; ">>" return RSH; ${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1); return AID; } +{MAC} { yylval.e = pcap_ether_aton((char *)yytext); + return EID; } {N} { yylval.i = stoi((char *)yytext); return NUM; } ({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) { yylval.s = sdup((char *)yytext); return HID; } -{B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext); - return EID; } {V6} { #ifdef INET6 struct addrinfo hints, *res; -- 2.41.0