Resolve conflicts in libpcap-0.8.3 import.
Remove some extraneous files.
This commit is contained in:
parent
64657f857f
commit
c14b894413
@ -1,7 +1,126 @@
|
||||
$NetBSD: CHANGES,v 1.4 1997/10/03 15:53:00 christos Exp $
|
||||
@(#) Header: CHANGES,v 1.43 97/09/24 19:48:58 leres Exp (LBL)
|
||||
$NetBSD: CHANGES,v 1.5 2004/09/27 23:02:53 dyoung Exp $
|
||||
@(#) Header: /tcpdump/master/libpcap/CHANGES,v 1.56.4.3 2004/03/30 14:29:16 mcr Exp (LBL)
|
||||
|
||||
v0.4 Wed Sep 24 19:48:54 PDT 1997
|
||||
Tue. March 30, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.3 release
|
||||
|
||||
Fixed minor problem in gencode.c that would appear on 64-bit
|
||||
platforms.
|
||||
Version number is now sane.
|
||||
|
||||
Mon. March 29, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.2 release
|
||||
|
||||
updates for autoconf 2.5
|
||||
fixes for ppp interfaces for freebsd 4.1
|
||||
pcap gencode can generate code for 802.11, IEEE1394, and pflog.
|
||||
|
||||
Wed. November 12, 2003. mcr@sandelman.ottawa.on.ca. Summary for 0.8 release
|
||||
|
||||
added pcap_findalldevs()
|
||||
Win32 patches from NetGroup, Politecnico di Torino (Italy)
|
||||
OpenBSD pf, DLT_PFLOG added
|
||||
Many changes to ATM support.
|
||||
lookup pcap_lookupnet()
|
||||
Added DLT_ARCNET_LINUX, DLT_ENC, DLT_IEEE802_11_RADIO, DLT_SUNATM,
|
||||
DLT_IP_OVER_FC, DLT_FRELAY, others.
|
||||
Sigh. More AIX wonderfulness.
|
||||
Document updates.
|
||||
Changes to API: pcap_next_ex(), pcap_breakloop(), pcap_dump_flush(),
|
||||
pcap_list_datalinks(), pcap_set_datalink(),
|
||||
pcap_lib_version(), pcap_datalink_val_to_name(),
|
||||
pcap_datalink_name_to_val(), new error returns.
|
||||
|
||||
Tuesday, February 25, 2003. fenner@research.att.com. 0.7.2 release
|
||||
|
||||
Support link types that use 802.2 always, never, and sometimes.
|
||||
Don't decrease the size of the BPF buffer from the default.
|
||||
Support frame relay.
|
||||
Handle 32-bit timestamps in DLPI, and pass the right buffer size.
|
||||
Handle Linux systems with modern kernel but without
|
||||
SOL_PACKET in the userland headers.
|
||||
Linux support for ARPHRD_RAWHDLC.
|
||||
Handle 32-bit timestamps in snoop.
|
||||
Support eg (Octane/O2xxx/O3xxx Gigabit) devices.
|
||||
Add new reserved DLT types.
|
||||
|
||||
Monday October 23, 2001. mcr@sandelman.ottawa.on.ca. Summary for 0.7 release
|
||||
|
||||
Added pcap_findalldevs() call to get list of interfaces in a MI way.
|
||||
|
||||
pcap_stats() has been documented as to what its counters mean on
|
||||
each platform.
|
||||
|
||||
Tuesday January 9, 2001. guy@alum.mit.edu. Summary for 0.6 release
|
||||
|
||||
New Linux libpcap implementation, which, in 2.2 and later
|
||||
kernels, uses PF_PACKET sockets and supports kernel packet
|
||||
filtering (if compiled into the kernel), and supports the "any"
|
||||
device for capturing on all interfaces. Cleans up promiscuous
|
||||
mode better on pre-2.2 kernels, and has various other fixes
|
||||
(handles 2.4 ARPHRD_IEEE802_TR, handles ISDN devices better,
|
||||
doesn't show duplicate packets on loopback interface, etc.).
|
||||
|
||||
Fixed HP-UX libpcap implementation to correctly get the PPA for
|
||||
an interface, to allow interfaces to be opened by interface name.
|
||||
|
||||
libpcap savefiles have system-independent link-layer type values
|
||||
in the header, rather than sometimes platform-dependent DLT_
|
||||
values, to make it easier to exchange capture files between
|
||||
different OSes.
|
||||
|
||||
Non-standard capture files produced by some Linux tcpdumps, e.g.
|
||||
the one from Red Hat Linux 6.2 and later, can now be read.
|
||||
|
||||
Updated autoconf stock files.
|
||||
|
||||
Filter expressions can filter on VLAN IDs and various OSI
|
||||
protocols, and work on Token Ring (with non-source-routed
|
||||
packets).
|
||||
|
||||
"pcap_open_dead()" added to allow compiling filter expressions
|
||||
to pcap code without opening a capture device or capture file.
|
||||
|
||||
Header files fixed to allow use in C++ programs.
|
||||
|
||||
Removed dependancy on native headers for packet layout.
|
||||
Removed Linux specific headers that were shipped.
|
||||
|
||||
Security fixes: Strcpy replaced with strlcpy, sprintf replaced
|
||||
with snprintf.
|
||||
|
||||
Fixed bug that could cause subsequent "pcap_compile()"s to fail
|
||||
erroneously after one compile failed.
|
||||
|
||||
Assorted other bug fixes.
|
||||
|
||||
README.aix and README.linux files added to describe
|
||||
platform-specific issues.
|
||||
|
||||
"getifaddrs()" rather than SIOCGIFCONF used, if available.
|
||||
|
||||
v0.5 Sat Jun 10 11:09:15 PDT 2000
|
||||
|
||||
itojun@iijlab.net
|
||||
- Brought in KAME IPv6/IPsec bpf compiler.
|
||||
- Fixes for NetBSD.
|
||||
- Support added for OpenBSD DLT_LOOP and BSD/OS DLT_C_HDLC (Cisco HDLC),
|
||||
and changes to work around different BSDs having different DLT_ types
|
||||
with the same numeric value.
|
||||
|
||||
Assar Westerlund <assar@sics.se>
|
||||
- Building outside the source code tree fixed.
|
||||
- Changed to write out time stamps with 32-bit seconds and microseconds
|
||||
fields, regardless of whether those fields are 32 bits or 64 bits in
|
||||
the OS's native "struct timeval".
|
||||
- Changed "pcap_lookupdev()" to dynamically grow the buffer into which
|
||||
the list of interfaces is read as necessary in order to hold the
|
||||
entire list.
|
||||
|
||||
Greg Troxel <gdt@ir.bbn.com>
|
||||
- Added a new "pcap_compile_nopcap()", which lets you compile a filter
|
||||
expression into a BPF program without having an open live capture or
|
||||
capture file.
|
||||
|
||||
v0.4 Sat Jul 25 12:40:09 PDT 1998
|
||||
|
||||
- Fix endian problem with DLT_NULL devices. From FreeBSD via Bill
|
||||
Fenner (fenner@parc.xerox.com)
|
||||
@ -67,6 +186,17 @@ v0.4 Wed Sep 24 19:48:54 PDT 1997
|
||||
- Ifdef ARPHRD_FDDI since not all versions of the Linux kernel have it.
|
||||
Reported reported by Eric Jacksch (jacksch@tenebris.ca)
|
||||
|
||||
- Fixed bug in pcap_dispatch() that kept it from returning on packet
|
||||
timeouts.
|
||||
|
||||
- Changed ISLOOPBACK() macro when IFF_LOOPBACK isn't available to check
|
||||
for "lo" followed by an eos or digit (newer versions of Linux
|
||||
apparently call the loopback "lo" instead of "lo0").
|
||||
|
||||
- Fixed Linux networking include files to use ints instead of longs to
|
||||
avoid problems with 64 bit longs on the alpha. Thanks to Cristian
|
||||
Gafton (gafton@redhat.com)
|
||||
|
||||
v0.3 Sat Nov 30 20:56:27 PST 1996
|
||||
|
||||
- Added Linux support.
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.25 2004/06/25 12:22:23 itojun Exp $
|
||||
# $NetBSD: Makefile,v 1.26 2004/09/27 23:02:53 dyoung Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
@ -10,8 +10,10 @@ WARNS?= 1
|
||||
CPPFLAGS+=-I. -I${.CURDIR} -I${NETBSDSRCDIR}/sys/dist/pf -DYYBISON
|
||||
CPPFLAGS+=-DINET6
|
||||
CPPFLAGS+=-DHAVE_MALLOC_H=1 -DHAVE_SYS_IOCCOM_H=1 -DHAVE_SYS_SOCKIO_H=1
|
||||
CPPFLAGS+=-DHAVE_NETINET_IF_ETHER_H
|
||||
CPPFLAGS+=-DHAVE_ETHER_HOSTTON=1 -DHAVE_STRERROR=1 -DHAVE_SOCKADDR_SA_LEN=1
|
||||
CPPFLAGS+=-DHAVE_IFADDRS_H=1
|
||||
CPPFLAGS+=-DHAVE_IFADDRS_H=1 -DHAVE_LIMITS_H=1
|
||||
CPPFLAGS+=-DHAVE_SNPRINTF=1 -DHAVE_STRLCPY=1 -DHAVE_VSNPRINTF=1
|
||||
# used in no place
|
||||
#CPPFLAGS+=-DLBL_ALIGN=1
|
||||
LPREFIX=pcap_
|
||||
@ -19,7 +21,8 @@ YPREFIX=pcap_
|
||||
YHEADER=1
|
||||
|
||||
SRCS= scanner.l savefile.c pcap.c pcap-bpf.c optimize.c nametoaddr.c \
|
||||
inet.c grammar.y gencode.c etherent.c bpf_image.c
|
||||
inet.c grammar.y gencode.c fad-getad.c etherent.c bpf_image.c \
|
||||
bpf_dump.c
|
||||
SRCS+= bpf_filter.c version.c
|
||||
|
||||
.PATH: ${NETBSDSRCDIR}/sys/net
|
||||
@ -27,4 +30,7 @@ SRCS+= bpf_filter.c version.c
|
||||
INCS= pcap-namedb.h pcap.h
|
||||
INCSDIR=/usr/include
|
||||
|
||||
# XXX -dcy
|
||||
scanner.c: grammar.h
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
@ -1,11 +1,25 @@
|
||||
$NetBSD: README,v 1.5 2003/02/05 00:02:25 perry Exp $
|
||||
@(#) Header: README,v 1.18 97/06/12 14:23:56 leres Exp (LBL)
|
||||
$NetBSD: README,v 1.6 2004/09/27 23:02:53 dyoung Exp $
|
||||
@(#) Header: /tcpdump/master/libpcap/README,v 1.27.2.1 2003/11/15 23:29:19 guy Exp (LBL)
|
||||
|
||||
LIBPCAP 0.4
|
||||
Lawrence Berkeley National Laboratory
|
||||
Network Research Group
|
||||
libpcap@ee.lbl.gov
|
||||
ftp://ftp.ee.lbl.gov/libpcap.tar.Z
|
||||
LIBPCAP 0.8
|
||||
Now maintained by "The Tcpdump Group"
|
||||
See www.tcpdump.org
|
||||
|
||||
Please send inquiries/comments/reports to tcpdump-workers@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.8 of LIBPCAP can be retrieved with the CVS tag "libpcap_0_8rel1":
|
||||
cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_0_8rel1 libpcap
|
||||
|
||||
Please send patches against the master copy to patches@tcpdump.org.
|
||||
|
||||
formerly from Lawrence Berkeley National Laboratory
|
||||
Network Research Group <libpcap@ee.lbl.gov>
|
||||
ftp://ftp.ee.lbl.gov/libpcap.tar.Z (0.4)
|
||||
|
||||
This directory contains source code for libpcap, a system-independent
|
||||
interface for user-level packet capture. libpcap provides a portable
|
||||
@ -19,12 +33,30 @@ 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
|
||||
by default.
|
||||
|
||||
The libpcap interface supports a filtering mechanism based on the
|
||||
architecture in the BSD packet filter. BPF is described in the 1993
|
||||
Winter Usenix paper ``The BSD Packet Filter: A New Architecture for
|
||||
User-level Packet Capture''. A compressed postscript version is in:
|
||||
User-level Packet Capture''. A compressed PostScript version can be
|
||||
found at
|
||||
|
||||
ftp://ftp.ee.lbl.gov/papers/bpf-usenix93.ps.Z.
|
||||
ftp://ftp.ee.lbl.gov/papers/bpf-usenix93.ps.Z
|
||||
|
||||
or
|
||||
|
||||
http://www.tcpdump.org/papers/bpf-usenix93.ps.Z
|
||||
|
||||
and a gzipped version can be found at
|
||||
|
||||
http://www.tcpdump.org/papers/bpf-usenix93.ps.gz
|
||||
|
||||
A PDF version can be found at
|
||||
|
||||
http://www.tcpdump.org/papers/bpf-usenix93.pdf
|
||||
|
||||
Although most packet capture interfaces support in-kernel filtering,
|
||||
libpcap uses in-kernel filtering only for the BPF interface.
|
||||
@ -34,17 +66,30 @@ added overhead (especially, for selective filters). Ideally, libpcap
|
||||
would translate BPF filters into a filter program that is compatible
|
||||
with the underlying kernel subsystem, but this is not yet implemented.
|
||||
|
||||
BPF is standard in 4.4BSD, BSD/386, NetBSD, and FreeBSD. DEC OSF/1
|
||||
uses the packetfilter interface but has been extended to accept BPF
|
||||
filters (which libpcap uses). Also, you can add BPF filter support
|
||||
to Ultrix using the kernel source and/or object patches available in:
|
||||
BPF is standard in 4.4BSD, BSD/OS, NetBSD, FreeBSD, and OpenBSD. DEC
|
||||
OSF/1/Digital UNIX/Tru64 UNIX uses the packetfilter interface but has
|
||||
been extended to accept BPF filters (which libpcap utilizes). Also, you
|
||||
can add BPF filter support to Ultrix using the kernel source and/or
|
||||
object patches available in:
|
||||
|
||||
ftp://gatekeeper.dec.com/pub/DEC/net/bpfext42.tar.Z.
|
||||
|
||||
Problems, bugs, questions, desirable enhancements, source code
|
||||
contributions, etc., should be sent to the email address
|
||||
"libpcap@ee.lbl.gov".
|
||||
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.
|
||||
|
||||
- Steve McCanne
|
||||
Craig Leres
|
||||
Van Jacobson
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
Current versions can be found at www.tcpdump.org, or the SourceForge
|
||||
site for libpcap.
|
||||
|
||||
- The TCPdump team
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: bpf_dump.c,v 1.1.1.2 2004/09/19 21:57:48 dyoung Exp $ */
|
||||
/* $NetBSD: bpf_dump.c,v 1.2 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993, 1994, 1995, 1996
|
||||
@ -23,10 +23,10 @@
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] _U_ =
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.13.2.1 2003/11/15 23:26:37 guy Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: bpf_dump.c,v 1.1.1.2 2004/09/19 21:57:48 dyoung Exp $");
|
||||
__RCSID("$NetBSD: bpf_dump.c,v 1.2 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: bpf_image.c,v 1.6 2000/10/10 19:12:48 is Exp $ */
|
||||
/* $NetBSD: bpf_image.c,v 1.7 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990, 1991, 1992, 1994, 1995, 1996
|
||||
@ -25,21 +25,21 @@
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: bpf_image.c,v 1.22 96/09/26 23:27:56 leres Exp (LBL)";
|
||||
"@(#) Header: /tcpdump/master/libpcap/bpf_image.c,v 1.25.2.1 2003/11/15 23:26:38 guy Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: bpf_image.c,v 1.6 2000/10/10 19:12:48 is Exp $");
|
||||
__RCSID("$NetBSD: bpf_image.c,v 1.7 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include "gnuc.h"
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
@ -256,15 +256,11 @@ bpf_image(p, n)
|
||||
op = "txa";
|
||||
break;
|
||||
}
|
||||
|
||||
if (BPF_CLASS(p->code) == BPF_JMP &&
|
||||
BPF_OP(p->code) != BPF_JA)
|
||||
(void)snprintf(image, sizeof image,
|
||||
"(%03d) %-8s %-16s jt %d\tjf %d",
|
||||
n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
|
||||
else
|
||||
(void)snprintf(image, sizeof image,
|
||||
"(%03d) %-8s %s",
|
||||
n, op, operand);
|
||||
(void)snprintf(image, sizeof image,
|
||||
(BPF_CLASS(p->code) == BPF_JMP &&
|
||||
BPF_OP(p->code) != BPF_JA) ?
|
||||
"(%03d) %-8s %-16s jt %d\tjf %d"
|
||||
: "(%03d) %-8s %s",
|
||||
n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
|
||||
return image;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: etherent.c,v 1.4 1997/10/03 15:53:03 christos Exp $ */
|
||||
/* $NetBSD: etherent.c,v 1.5 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990, 1993, 1994, 1995, 1996
|
||||
@ -25,12 +25,16 @@
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: etherent.c,v 1.20 96/09/26 23:28:00 leres Exp (LBL)";
|
||||
"@(#) Header: /tcpdump/master/libpcap/etherent.c,v 1.21.6.1 2003/11/15 23:26:38 guy Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: etherent.c,v 1.4 1997/10/03 15:53:03 christos Exp $");
|
||||
__RCSID("$NetBSD: etherent.c,v 1.5 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
@ -42,17 +46,16 @@ __RCSID("$NetBSD: etherent.c,v 1.4 1997/10/03 15:53:03 christos Exp $");
|
||||
|
||||
#include <pcap-namedb.h>
|
||||
|
||||
#include "gnuc.h"
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
|
||||
static inline int xdtoi(int);
|
||||
static inline int skip_space(FILE *);
|
||||
static inline int skip_line(FILE *);
|
||||
static __inline int xdtoi(int);
|
||||
static __inline int skip_space(FILE *);
|
||||
static __inline int skip_line(FILE *);
|
||||
|
||||
/* Hex digit to integer. */
|
||||
static inline int
|
||||
static __inline int
|
||||
xdtoi(c)
|
||||
register int c;
|
||||
{
|
||||
@ -64,7 +67,7 @@ xdtoi(c)
|
||||
return c - 'A' + 10;
|
||||
}
|
||||
|
||||
static inline int
|
||||
static __inline int
|
||||
skip_space(f)
|
||||
FILE *f;
|
||||
{
|
||||
@ -77,7 +80,7 @@ skip_space(f)
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline int
|
||||
static __inline int
|
||||
skip_line(f)
|
||||
FILE *f;
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ethertype.h,v 1.6 2002/12/19 16:33:47 hannken Exp $ */
|
||||
/* $NetBSD: ethertype.h,v 1.7 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1996
|
||||
@ -20,11 +20,33 @@
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* @(#) Header: ethertype.h,v 1.6 96/07/14 18:21:49 leres Exp (LBL)
|
||||
* @(#) Header: /tcpdump/master/libpcap/ethertype.h,v 1.12 2001/01/14 21:26:52 guy Exp (LBL)
|
||||
*/
|
||||
|
||||
/* Types missing from some systems */
|
||||
/*
|
||||
* Ethernet types.
|
||||
*
|
||||
* We wrap the declarations with #ifdef, so that if a file includes
|
||||
* <netinet/if_ether.h>, which may declare some of these, we don't
|
||||
* get a bunch of complaints from the C compiler about redefinitions
|
||||
* of these values.
|
||||
*
|
||||
* We declare all of them here so that no file has to include
|
||||
* <netinet/if_ether.h> if all it needs are ETHERTYPE_ values.
|
||||
*/
|
||||
|
||||
#ifndef ETHERTYPE_PUP
|
||||
#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
|
||||
#endif
|
||||
#ifndef ETHERTYPE_IP
|
||||
#define ETHERTYPE_IP 0x0800 /* IP protocol */
|
||||
#endif
|
||||
#ifndef ETHERTYPE_ARP
|
||||
#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
|
||||
#endif
|
||||
#ifndef ETHERTYPE_REVARP
|
||||
#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
|
||||
#endif
|
||||
#ifndef ETHERTYPE_NS
|
||||
#define ETHERTYPE_NS 0x0600
|
||||
#endif
|
||||
@ -76,8 +98,11 @@
|
||||
#ifndef ETHERTYPE_8021Q
|
||||
#define ETHERTYPE_8021Q 0x8100
|
||||
#endif
|
||||
#ifndef ETHERTYPE_IPX
|
||||
#define ETHERTYPE_IPX 0x8137
|
||||
#endif
|
||||
#ifndef ETHERTYPE_IPV6
|
||||
#define ETHERTYPE_IPV6 0x80f3
|
||||
#define ETHERTYPE_IPV6 0x86dd
|
||||
#endif
|
||||
#ifndef ETHERTYPE_LOOPBACK
|
||||
#define ETHERTYPE_LOOPBACK 0x9000
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: fad-getad.c,v 1.1.1.2 2004/09/19 21:57:48 dyoung Exp $ */
|
||||
/* $NetBSD: fad-getad.c,v 1.2 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||
/*
|
||||
@ -37,10 +37,10 @@
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] _U_ =
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: /tcpdump/master/libpcap/fad-getad.c,v 1.7.2.2 2004/03/11 23:04:52 guy Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: fad-getad.c,v 1.1.1.2 2004/09/19 21:57:48 dyoung Exp $");
|
||||
__RCSID("$NetBSD: fad-getad.c,v 1.2 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: gencode.h,v 1.13 2004/06/25 12:22:23 itojun Exp $ */
|
||||
/* $NetBSD: gencode.h,v 1.14 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
|
||||
@ -20,11 +20,42 @@
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* @(#) Header: gencode.h,v 1.36 96/07/17 00:11:34 leres Exp (LBL)
|
||||
* @(#) Header: /tcpdump/master/libpcap/gencode.h,v 1.58.2.1 2004/03/28 21:45:31 fenner Exp (LBL)
|
||||
*/
|
||||
|
||||
/*XXX*/
|
||||
#include "gnuc.h"
|
||||
/*
|
||||
* ATM support:
|
||||
*
|
||||
* Copyright (c) 1997 Yen Yen Lim and North Dakota State University
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Yen Yen Lim and
|
||||
* North Dakota State University
|
||||
* 4. 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 AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
/* Address qualifiers. */
|
||||
|
||||
@ -41,28 +72,54 @@
|
||||
#define Q_IP 2
|
||||
#define Q_ARP 3
|
||||
#define Q_RARP 4
|
||||
#define Q_TCP 5
|
||||
#define Q_UDP 6
|
||||
#define Q_ICMP 7
|
||||
#define Q_IGMP 8
|
||||
#define Q_IGRP 9
|
||||
#define Q_SCTP 5
|
||||
#define Q_TCP 6
|
||||
#define Q_UDP 7
|
||||
#define Q_ICMP 8
|
||||
#define Q_IGMP 9
|
||||
#define Q_IGRP 10
|
||||
|
||||
|
||||
#define Q_ATALK 10
|
||||
#define Q_DECNET 11
|
||||
#define Q_LAT 12
|
||||
#define Q_SCA 13
|
||||
#define Q_MOPRC 14
|
||||
#define Q_MOPDL 15
|
||||
#define Q_ATALK 11
|
||||
#define Q_DECNET 12
|
||||
#define Q_LAT 13
|
||||
#define Q_SCA 14
|
||||
#define Q_MOPRC 15
|
||||
#define Q_MOPDL 16
|
||||
|
||||
|
||||
#define Q_IPV6 16
|
||||
#define Q_ICMPV6 17
|
||||
#define Q_AH 18
|
||||
#define Q_ESP 19
|
||||
#define Q_IPV6 17
|
||||
#define Q_ICMPV6 18
|
||||
#define Q_AH 19
|
||||
#define Q_ESP 20
|
||||
|
||||
#define Q_PIM 20
|
||||
#define Q_VRRP 21
|
||||
#define Q_PIM 21
|
||||
#define Q_VRRP 22
|
||||
|
||||
#define Q_AARP 23
|
||||
|
||||
#define Q_ISO 24
|
||||
#define Q_ESIS 25
|
||||
#define Q_ISIS 26
|
||||
#define Q_CLNP 27
|
||||
|
||||
#define Q_STP 28
|
||||
|
||||
#define Q_IPX 29
|
||||
|
||||
#define Q_NETBEUI 30
|
||||
|
||||
/* IS-IS Levels */
|
||||
#define Q_ISIS_L1 31
|
||||
#define Q_ISIS_L2 32
|
||||
/* PDU types */
|
||||
#define Q_ISIS_IIH 33
|
||||
#define Q_ISIS_LAN_IIH 34
|
||||
#define Q_ISIS_PTP_IIH 35
|
||||
#define Q_ISIS_SNP 36
|
||||
#define Q_ISIS_CSNP 37
|
||||
#define Q_ISIS_PSNP 38
|
||||
#define Q_ISIS_LSP 39
|
||||
|
||||
/* Directional qualifiers. */
|
||||
|
||||
@ -74,6 +131,43 @@
|
||||
#define Q_DEFAULT 0
|
||||
#define Q_UNDEF 255
|
||||
|
||||
/* ATM types */
|
||||
#define A_METAC 22 /* Meta signalling Circuit */
|
||||
#define A_BCC 23 /* Broadcast Circuit */
|
||||
#define A_OAMF4SC 24 /* Segment OAM F4 Circuit */
|
||||
#define A_OAMF4EC 25 /* End-to-End OAM F4 Circuit */
|
||||
#define A_SC 26 /* Signalling Circuit*/
|
||||
#define A_ILMIC 27 /* ILMI Circuit */
|
||||
#define A_OAM 28 /* OAM cells : F4 only */
|
||||
#define A_OAMF4 29 /* OAM F4 cells: Segment + End-to-end */
|
||||
#define A_LANE 30 /* LANE traffic */
|
||||
#define A_LLC 31 /* LLC-encapsulated traffic */
|
||||
|
||||
/* Based on Q.2931 signalling protocol */
|
||||
#define A_SETUP 41 /* Setup message */
|
||||
#define A_CALLPROCEED 42 /* Call proceeding message */
|
||||
#define A_CONNECT 43 /* Connect message */
|
||||
#define A_CONNECTACK 44 /* Connect Ack message */
|
||||
#define A_RELEASE 45 /* Release message */
|
||||
#define A_RELEASE_DONE 46 /* Release message */
|
||||
|
||||
/* ATM field types */
|
||||
#define A_VPI 51
|
||||
#define A_VCI 52
|
||||
#define A_PROTOTYPE 53
|
||||
#define A_MSGTYPE 54
|
||||
#define A_CALLREFTYPE 55
|
||||
|
||||
#define A_CONNECTMSG 70 /* returns Q.2931 signalling messages for
|
||||
establishing and destroying switched
|
||||
virtual connection */
|
||||
#define A_METACONNECT 71 /* returns Q.2931 signalling messages for
|
||||
establishing and destroying predefined
|
||||
virtual circuits, such as broadcast
|
||||
circuit, oamf4 segment circuit, oamf4
|
||||
end-to-end circuits, ILMI circuits or
|
||||
connection signalling circuit. */
|
||||
|
||||
struct slist;
|
||||
|
||||
struct stmt {
|
||||
@ -168,7 +262,7 @@ struct block *gen_ecode(const u_char *, struct qual);
|
||||
struct block *gen_acode(const u_char *, struct qual);
|
||||
struct block *gen_mcode(const char *, const char *, int, struct qual);
|
||||
#ifdef INET6
|
||||
struct block *gen_mcode6(const char *, const char *, int, struct qual);
|
||||
struct block *gen_mcode6(const char *, const char *, u_int, struct qual);
|
||||
#endif
|
||||
struct block *gen_ncode(const char *, bpf_u_int32, struct qual);
|
||||
struct block *gen_proto_abbrev(int);
|
||||
@ -181,7 +275,13 @@ struct block *gen_multicast(int);
|
||||
struct block *gen_inbound(int);
|
||||
struct block *gen_vlan(int);
|
||||
|
||||
struct block *gen_pf_ifname(char *);
|
||||
struct block *gen_vlan(int);
|
||||
|
||||
struct block *gen_atmfield_code(int atmfield, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);
|
||||
struct block *gen_atmtype_abbrev(int type);
|
||||
struct block *gen_atmmulti_abbrev(int type);
|
||||
|
||||
struct block *gen_pf_ifname(const char *);
|
||||
struct block *gen_pf_rnr(int);
|
||||
struct block *gen_pf_srnr(int);
|
||||
struct block *gen_pf_ruleset(char *);
|
||||
@ -190,10 +290,9 @@ struct block *gen_pf_action(int);
|
||||
struct block *gen_pf_dir(int);
|
||||
|
||||
void bpf_optimize(struct block **);
|
||||
#if __STDC__
|
||||
__dead void bpf_error(const char *, ...)
|
||||
__attribute__((volatile, format (printf, 1, 2)));
|
||||
#endif
|
||||
void bpf_error(const char *, ...)
|
||||
__attribute__((noreturn, format (printf, 1, 2)))
|
||||
;
|
||||
|
||||
void finish_parse(struct block *);
|
||||
char *sdup(const char *);
|
||||
@ -203,6 +302,7 @@ struct bpf_insn *icode_to_fcode(struct block *, int *);
|
||||
int pcap_parse(void);
|
||||
#endif
|
||||
void lex_init(char *);
|
||||
void lex_cleanup(void);
|
||||
void sappend(struct slist *, struct slist *);
|
||||
|
||||
/* XXX */
|
||||
|
@ -1,45 +0,0 @@
|
||||
/* $NetBSD: gnuc.h,v 1.4 1997/10/03 15:53:07 christos Exp $ */
|
||||
|
||||
/* @(#) Header: gnuc.h,v 1.3 95/10/09 02:47:01 leres Exp (LBL) */
|
||||
|
||||
/* Define __P() macro, if necessary */
|
||||
#ifndef __P
|
||||
#if __STDC__
|
||||
#define __P(protos) protos
|
||||
#else
|
||||
#define __P(protos) ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* inline foo */
|
||||
#ifdef __GNUC__
|
||||
#define inline __inline
|
||||
#else
|
||||
#define inline
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Handle new and old "dead" routine prototypes
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* __dead void foo(void) __attribute__((volatile));
|
||||
*
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#ifndef __dead
|
||||
#define __dead volatile
|
||||
#endif
|
||||
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
|
||||
#ifndef __attribute__
|
||||
#define __attribute__(args)
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#ifndef __dead
|
||||
#define __dead
|
||||
#endif
|
||||
#ifndef __attribute__
|
||||
#define __attribute__(args)
|
||||
#endif
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
%{
|
||||
/* $NetBSD: grammar.y,v 1.10 2004/06/25 12:22:23 itojun Exp $ */
|
||||
/* $NetBSD: grammar.y,v 1.11 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
|
||||
@ -26,31 +26,42 @@
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: grammar.y,v 1.56 96/11/02 21:54:55 leres Exp (LBL)";
|
||||
"@(#) Header: /tcpdump/master/libpcap/grammar.y,v 1.79.2.3 2004/03/28 21:45:32 fenner Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: grammar.y,v 1.10 2004/06/25 12:22:23 itojun Exp $");
|
||||
__RCSID("$NetBSD: grammar.y,v 1.11 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* WIN32 */
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef WIN32
|
||||
#if __STDC__
|
||||
struct mbuf;
|
||||
struct rtentry;
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#ifdef __NetBSD__
|
||||
#include <net/if.h>
|
||||
#include <net/if_ether.h>
|
||||
#else
|
||||
#include <netinet/if_ether.h>
|
||||
#endif
|
||||
|
||||
#include <net/pfvar.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
@ -60,7 +71,6 @@ struct rtentry;
|
||||
#include "gencode.h"
|
||||
#include <pcap-namedb.h>
|
||||
|
||||
#include "gnuc.h"
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
@ -102,6 +112,7 @@ pcap_parse()
|
||||
struct arth *a;
|
||||
struct {
|
||||
struct qual q;
|
||||
int atmfieldtype;
|
||||
struct block *b;
|
||||
} blk;
|
||||
struct block *rblk;
|
||||
@ -114,11 +125,14 @@ pcap_parse()
|
||||
%type <i> byteop pname pnum relop irelop
|
||||
%type <blk> and or paren not null prog
|
||||
%type <rblk> other pfvar
|
||||
%type <i> atmtype atmmultitype
|
||||
%type <blk> atmfield
|
||||
%type <blk> atmfieldvalue atmvalue atmlistvalue
|
||||
|
||||
%token DST SRC HOST GATEWAY
|
||||
%token NET MASK PORT LESS GREATER PROTO PROTOCHAIN BYTE
|
||||
%token ARP RARP IP TCP UDP ICMP IGMP IGRP PIM VRRP
|
||||
%token ATALK DECNET LAT SCA MOPRC MOPDL
|
||||
%token NET NETMASK PORT LESS GREATER PROTO PROTOCHAIN CBYTE
|
||||
%token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP
|
||||
%token ATALK AARP DECNET LAT SCA MOPRC MOPDL
|
||||
%token TK_BROADCAST TK_MULTICAST
|
||||
%token NUM INBOUND OUTBOUND
|
||||
%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
|
||||
@ -129,6 +143,13 @@ pcap_parse()
|
||||
%token LEN
|
||||
%token IPV6 ICMPV6 AH ESP
|
||||
%token VLAN
|
||||
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
|
||||
%token STP
|
||||
%token IPX
|
||||
%token NETBEUI
|
||||
%token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
|
||||
%token OAM OAMF4 CONNECTMSG METACONNECT
|
||||
%token VPI VCI
|
||||
|
||||
%type <s> ID
|
||||
%type <e> EID
|
||||
@ -171,23 +192,17 @@ id: nid
|
||||
nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
|
||||
| HID '/' NUM { $$.b = gen_mcode($1, NULL, $3,
|
||||
$$.q = $<blk>0.q); }
|
||||
| HID MASK HID { $$.b = gen_mcode($1, $3, 0,
|
||||
| HID NETMASK HID { $$.b = gen_mcode($1, $3, 0,
|
||||
$$.q = $<blk>0.q); }
|
||||
| HID {
|
||||
/* Decide how to parse HID based on proto */
|
||||
$$.q = $<blk>0.q;
|
||||
switch ($$.q.proto) {
|
||||
case Q_DECNET:
|
||||
$$.b = gen_ncode($1, 0, $$.q);
|
||||
break;
|
||||
default:
|
||||
$$.b = gen_ncode($1, 0, $$.q);
|
||||
break;
|
||||
}
|
||||
$$.b = gen_ncode($1, 0, $$.q);
|
||||
}
|
||||
| HID6 '/' NUM {
|
||||
#ifdef INET6
|
||||
$$.b = gen_mcode6($1, NULL, $3,
|
||||
$$.b = gen_mcode6($1, NULL,
|
||||
(u_int)$3, /* XXX */
|
||||
$$.q = $<blk>0.q);
|
||||
#else
|
||||
bpf_error("'ip6addr/prefixlen' not supported "
|
||||
@ -203,8 +218,24 @@ nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
|
||||
"in this configuration");
|
||||
#endif /*INET6*/
|
||||
}
|
||||
| EID { $$.b = gen_ecode($1, $$.q = $<blk>0.q); }
|
||||
| AID { $$.b = gen_acode($1, $$.q = $<blk>0.q); }
|
||||
| EID {
|
||||
$$.b = gen_ecode($1, $$.q = $<blk>0.q);
|
||||
/*
|
||||
* $1 was allocated by "pcap_ether_aton()",
|
||||
* so we must free it now that we're done
|
||||
* with it.
|
||||
*/
|
||||
free($1);
|
||||
}
|
||||
| AID {
|
||||
$$.b = gen_acode($1, $$.q = $<blk>0.q);
|
||||
/*
|
||||
* $1 was allocated by "pcap_ether_aton()",
|
||||
* so we must free it now that we're done
|
||||
* with it.
|
||||
*/
|
||||
free($1);
|
||||
}
|
||||
| not id { gen_not($2.b); $$ = $2; }
|
||||
;
|
||||
not: '!' { $$ = $<blk>0; }
|
||||
@ -237,6 +268,9 @@ rterm: head id { $$ = $2; }
|
||||
| arth irelop arth { $$.b = gen_relation($2, $1, $3, 1);
|
||||
$$.q = qerr; }
|
||||
| other { $$.b = $1; $$.q = qerr; }
|
||||
| atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
|
||||
| atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
|
||||
| atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
/* protocol level qualifiers */
|
||||
pqual: pname
|
||||
@ -262,6 +296,7 @@ pname: LINK { $$ = Q_LINK; }
|
||||
| IP { $$ = Q_IP; }
|
||||
| ARP { $$ = Q_ARP; }
|
||||
| RARP { $$ = Q_RARP; }
|
||||
| SCTP { $$ = Q_SCTP; }
|
||||
| TCP { $$ = Q_TCP; }
|
||||
| UDP { $$ = Q_UDP; }
|
||||
| ICMP { $$ = Q_ICMP; }
|
||||
@ -270,6 +305,7 @@ pname: LINK { $$ = Q_LINK; }
|
||||
| PIM { $$ = Q_PIM; }
|
||||
| VRRP { $$ = Q_VRRP; }
|
||||
| ATALK { $$ = Q_ATALK; }
|
||||
| AARP { $$ = Q_AARP; }
|
||||
| DECNET { $$ = Q_DECNET; }
|
||||
| LAT { $$ = Q_LAT; }
|
||||
| SCA { $$ = Q_SCA; }
|
||||
@ -279,12 +315,26 @@ pname: LINK { $$ = Q_LINK; }
|
||||
| ICMPV6 { $$ = Q_ICMPV6; }
|
||||
| AH { $$ = Q_AH; }
|
||||
| ESP { $$ = Q_ESP; }
|
||||
| ISO { $$ = Q_ISO; }
|
||||
| ESIS { $$ = Q_ESIS; }
|
||||
| ISIS { $$ = Q_ISIS; }
|
||||
| L1 { $$ = Q_ISIS_L1; }
|
||||
| L2 { $$ = Q_ISIS_L2; }
|
||||
| IIH { $$ = Q_ISIS_IIH; }
|
||||
| LSP { $$ = Q_ISIS_LSP; }
|
||||
| SNP { $$ = Q_ISIS_SNP; }
|
||||
| PSNP { $$ = Q_ISIS_PSNP; }
|
||||
| CSNP { $$ = Q_ISIS_CSNP; }
|
||||
| CLNP { $$ = Q_CLNP; }
|
||||
| STP { $$ = Q_STP; }
|
||||
| IPX { $$ = Q_IPX; }
|
||||
| NETBEUI { $$ = Q_NETBEUI; }
|
||||
;
|
||||
other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
|
||||
| pqual TK_MULTICAST { $$ = gen_multicast($1); }
|
||||
| LESS NUM { $$ = gen_less($2); }
|
||||
| GREATER NUM { $$ = gen_greater($2); }
|
||||
| BYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
|
||||
| CBYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
|
||||
| INBOUND { $$ = gen_inbound(0); }
|
||||
| OUTBOUND { $$ = gen_inbound(1); }
|
||||
| VLAN pnum { $$ = gen_vlan($2); }
|
||||
@ -304,7 +354,7 @@ reason: NUM { $$ = $1; }
|
||||
| ID { const char *reasons[] = PFRES_NAMES;
|
||||
int i;
|
||||
for (i = 0; reasons[i]; i++) {
|
||||
if (strcasecmp($1, reasons[i]) == 0) {
|
||||
if (pcap_strcasecmp($1, reasons[i]) == 0) {
|
||||
$$ = i;
|
||||
break;
|
||||
}
|
||||
@ -314,11 +364,11 @@ reason: NUM { $$ = $1; }
|
||||
}
|
||||
;
|
||||
|
||||
action: ID { if (strcasecmp($1, "pass") == 0 ||
|
||||
strcasecmp($1, "accept") == 0)
|
||||
action: ID { if (pcap_strcasecmp($1, "pass") == 0 ||
|
||||
pcap_strcasecmp($1, "accept") == 0)
|
||||
$$ = PF_PASS;
|
||||
else if (strcasecmp($1, "drop") == 0 ||
|
||||
strcasecmp($1, "block") == 0)
|
||||
else if (pcap_strcasecmp($1, "drop") == 0 ||
|
||||
pcap_strcasecmp($1, "block") == 0)
|
||||
$$ = PF_DROP;
|
||||
else
|
||||
bpf_error("unknown PF action");
|
||||
@ -359,4 +409,37 @@ byteop: '&' { $$ = '&'; }
|
||||
pnum: NUM
|
||||
| paren pnum ')' { $$ = $2; }
|
||||
;
|
||||
atmtype: LANE { $$ = A_LANE; }
|
||||
| LLC { $$ = A_LLC; }
|
||||
| METAC { $$ = A_METAC; }
|
||||
| BCC { $$ = A_BCC; }
|
||||
| OAMF4EC { $$ = A_OAMF4EC; }
|
||||
| OAMF4SC { $$ = A_OAMF4SC; }
|
||||
| SC { $$ = A_SC; }
|
||||
| ILMIC { $$ = A_ILMIC; }
|
||||
;
|
||||
atmmultitype: OAM { $$ = A_OAM; }
|
||||
| OAMF4 { $$ = A_OAMF4; }
|
||||
| CONNECTMSG { $$ = A_CONNECTMSG; }
|
||||
| METACONNECT { $$ = A_METACONNECT; }
|
||||
;
|
||||
/* ATM field types quantifier */
|
||||
atmfield: VPI { $$.atmfieldtype = A_VPI; }
|
||||
| VCI { $$.atmfieldtype = A_VCI; }
|
||||
;
|
||||
atmvalue: atmfieldvalue
|
||||
| relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 1); }
|
||||
| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
atmfieldvalue: NUM {
|
||||
$$.atmfieldtype = $<blk>0.atmfieldtype;
|
||||
if ($$.atmfieldtype == A_VPI ||
|
||||
$$.atmfieldtype == A_VCI)
|
||||
$$.b = gen_atmfield_code($$.atmfieldtype, (u_int) $1, BPF_JEQ, 0);
|
||||
}
|
||||
;
|
||||
atmlistvalue: atmfieldvalue
|
||||
| atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
|
||||
;
|
||||
%%
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* $NetBSD: inet.c,v 1.9 2004/09/07 13:20:40 jrf Exp $ */
|
||||
/* $NetBSD: inet.c,v 1.10 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||
/*
|
||||
* Copyright (c) 1994, 1995, 1996, 1997
|
||||
* Copyright (c) 1994, 1995, 1996, 1997, 1998
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -37,12 +38,20 @@
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: inet.c,v 1.21 97/07/17 14:24:58 leres Exp (LBL)";
|
||||
"@(#) Header: /tcpdump/master/libpcap/inet.c,v 1.58.2.1 2003/11/15 23:26:41 guy Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet.c,v 1.9 2004/09/07 13:20:40 jrf Exp $");
|
||||
__RCSID("$NetBSD: inet.c,v 1.10 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* WIN32 */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -52,13 +61,11 @@ __RCSID("$NetBSD: inet.c,v 1.9 2004/09/07 13:20:40 jrf Exp $");
|
||||
#endif
|
||||
#include <sys/time.h> /* concession to AIX */
|
||||
|
||||
#if __STDC__
|
||||
struct mbuf;
|
||||
struct rtentry;
|
||||
#endif
|
||||
|
||||
struct mbuf; /* Squelch compiler warnings on some platforms for */
|
||||
struct rtentry; /* declarations in <net/if.h> */
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@ -66,26 +73,392 @@ struct rtentry;
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#endif /* WIN32 */
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#else
|
||||
#define INT_MAX 2147483647
|
||||
#endif
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include "gnuc.h"
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
|
||||
/* Not all systems have IFF_LOOPBACK */
|
||||
#ifdef IFF_LOOPBACK
|
||||
#define ISLOOPBACK(p) ((p)->ifr_flags & IFF_LOOPBACK)
|
||||
#define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)
|
||||
#else
|
||||
#define ISLOOPBACK(p) ((p)->ifr_name[0] == 'l' && (p)->ifr_name[1] == 'o' && \
|
||||
(isdigit((p)->ifr_name[2]) || (p)->ifr_name[2] == '\0'))
|
||||
#define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \
|
||||
(isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
|
||||
#endif
|
||||
|
||||
struct sockaddr *
|
||||
dup_sockaddr(struct sockaddr *sa, size_t sa_length)
|
||||
{
|
||||
struct sockaddr *newsa;
|
||||
|
||||
if ((newsa = malloc(sa_length)) == NULL)
|
||||
return (NULL);
|
||||
return (memcpy(newsa, sa, sa_length));
|
||||
}
|
||||
|
||||
static int
|
||||
get_instance(const char *name)
|
||||
{
|
||||
const char *cp, *endcp;
|
||||
int n;
|
||||
|
||||
if (strcmp(name, "any") == 0) {
|
||||
/*
|
||||
* Give the "any" device an artificially high instance
|
||||
* number, so it shows up after all other non-loopback
|
||||
* interfaces.
|
||||
*/
|
||||
return INT_MAX;
|
||||
}
|
||||
|
||||
endcp = name + strlen(name);
|
||||
for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp)
|
||||
continue;
|
||||
|
||||
if (isdigit((unsigned char)*cp))
|
||||
n = atoi(cp);
|
||||
else
|
||||
n = 0;
|
||||
return (n);
|
||||
}
|
||||
|
||||
int
|
||||
add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
|
||||
u_int flags, const char *description, char *errbuf)
|
||||
{
|
||||
pcap_if_t *curdev, *prevdev, *nextdev;
|
||||
int this_instance;
|
||||
|
||||
/*
|
||||
* Is there already an entry in the list for this interface?
|
||||
*/
|
||||
for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
|
||||
if (strcmp(name, curdev->name) == 0)
|
||||
break; /* yes, we found it */
|
||||
}
|
||||
if (curdev == NULL) {
|
||||
/*
|
||||
* No, we didn't find it.
|
||||
* Allocate a new entry.
|
||||
*/
|
||||
curdev = malloc(sizeof(pcap_if_t));
|
||||
if (curdev == NULL) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the entry.
|
||||
*/
|
||||
curdev->next = NULL;
|
||||
curdev->name = malloc(strlen(name) + 1);
|
||||
strcpy(curdev->name, name);
|
||||
if (description != NULL) {
|
||||
/*
|
||||
* We have a description for this interface.
|
||||
*/
|
||||
curdev->description = malloc(strlen(description) + 1);
|
||||
strcpy(curdev->description, description);
|
||||
} else {
|
||||
/*
|
||||
* We don't.
|
||||
*/
|
||||
curdev->description = NULL;
|
||||
}
|
||||
curdev->addresses = NULL; /* list starts out as empty */
|
||||
curdev->flags = 0;
|
||||
if (ISLOOPBACK(name, flags))
|
||||
curdev->flags |= PCAP_IF_LOOPBACK;
|
||||
|
||||
/*
|
||||
* Add it to the list, in the appropriate location.
|
||||
* First, get the instance number of this interface.
|
||||
*/
|
||||
this_instance = get_instance(name);
|
||||
|
||||
/*
|
||||
* Now look for the last interface with an instance number
|
||||
* less than or equal to the new interface's instance
|
||||
* number - except that non-loopback interfaces are
|
||||
* arbitrarily treated as having interface numbers less
|
||||
* than those of loopback interfaces, so the loopback
|
||||
* interfaces are put at the end of the list.
|
||||
*
|
||||
* We start with "prevdev" being NULL, meaning we're before
|
||||
* the first element in the list.
|
||||
*/
|
||||
prevdev = NULL;
|
||||
for (;;) {
|
||||
/*
|
||||
* Get the interface after this one.
|
||||
*/
|
||||
if (prevdev == NULL) {
|
||||
/*
|
||||
* The next element is the first element.
|
||||
*/
|
||||
nextdev = *alldevs;
|
||||
} else
|
||||
nextdev = prevdev->next;
|
||||
|
||||
/*
|
||||
* Are we at the end of the list?
|
||||
*/
|
||||
if (nextdev == NULL) {
|
||||
/*
|
||||
* Yes - we have to put the new entry
|
||||
* after "prevdev".
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the new interface a non-loopback interface
|
||||
* and the next interface a loopback interface?
|
||||
*/
|
||||
if (!(curdev->flags & PCAP_IF_LOOPBACK) &&
|
||||
(nextdev->flags & PCAP_IF_LOOPBACK)) {
|
||||
/*
|
||||
* Yes, we should put the new entry
|
||||
* before "nextdev", i.e. after "prevdev".
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the new interface's instance number less
|
||||
* than the next interface's instance number,
|
||||
* and is it the case that the new interface is a
|
||||
* non-loopback interface or the next interface is
|
||||
* a loopback interface?
|
||||
*
|
||||
* (The goal of both loopback tests is to make
|
||||
* sure that we never put a loopback interface
|
||||
* before any non-loopback interface and that we
|
||||
* always put a non-loopback interface before all
|
||||
* loopback interfaces.)
|
||||
*/
|
||||
if (this_instance < get_instance(nextdev->name) &&
|
||||
(!(curdev->flags & PCAP_IF_LOOPBACK) ||
|
||||
(nextdev->flags & PCAP_IF_LOOPBACK))) {
|
||||
/*
|
||||
* Yes - we should put the new entry
|
||||
* before "nextdev", i.e. after "prevdev".
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
prevdev = nextdev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert before "nextdev".
|
||||
*/
|
||||
curdev->next = nextdev;
|
||||
|
||||
/*
|
||||
* Insert after "prevdev" - unless "prevdev" is null,
|
||||
* in which case this is the first interface.
|
||||
*/
|
||||
if (prevdev == NULL) {
|
||||
/*
|
||||
* This is the first interface. Pass back a
|
||||
* pointer to it, and put "curdev" before
|
||||
* "nextdev".
|
||||
*/
|
||||
*alldevs = curdev;
|
||||
} else
|
||||
prevdev->next = curdev;
|
||||
}
|
||||
|
||||
*curdev_ret = curdev;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
|
||||
struct sockaddr *addr, size_t addr_size,
|
||||
struct sockaddr *netmask, size_t netmask_size,
|
||||
struct sockaddr *broadaddr, size_t broadaddr_size,
|
||||
struct sockaddr *dstaddr, size_t dstaddr_size,
|
||||
char *errbuf)
|
||||
{
|
||||
pcap_if_t *curdev;
|
||||
pcap_addr_t *curaddr, *prevaddr, *nextaddr;
|
||||
|
||||
if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
|
||||
/*
|
||||
* Error - give up.
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
if (curdev == NULL) {
|
||||
/*
|
||||
* Device wasn't added because it can't be opened.
|
||||
* Not a fatal error.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* "curdev" is an entry for this interface; add an entry for this
|
||||
* address to its list of addresses.
|
||||
*
|
||||
* Allocate the new entry and fill it in.
|
||||
*/
|
||||
curaddr = malloc(sizeof(pcap_addr_t));
|
||||
if (curaddr == NULL) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
curaddr->next = NULL;
|
||||
if (addr != NULL) {
|
||||
curaddr->addr = dup_sockaddr(addr, addr_size);
|
||||
if (curaddr->addr == NULL) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
free(curaddr);
|
||||
return (-1);
|
||||
}
|
||||
} else
|
||||
curaddr->addr = NULL;
|
||||
|
||||
if (netmask != NULL) {
|
||||
curaddr->netmask = dup_sockaddr(netmask, netmask_size);
|
||||
if (curaddr->netmask == NULL) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
free(curaddr);
|
||||
return (-1);
|
||||
}
|
||||
} else
|
||||
curaddr->netmask = NULL;
|
||||
|
||||
if (broadaddr != NULL) {
|
||||
curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
|
||||
if (curaddr->broadaddr == NULL) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
free(curaddr);
|
||||
return (-1);
|
||||
}
|
||||
} else
|
||||
curaddr->broadaddr = NULL;
|
||||
|
||||
if (dstaddr != NULL) {
|
||||
curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
|
||||
if (curaddr->dstaddr == NULL) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
free(curaddr);
|
||||
return (-1);
|
||||
}
|
||||
} else
|
||||
curaddr->dstaddr = NULL;
|
||||
|
||||
/*
|
||||
* Find the end of the list of addresses.
|
||||
*/
|
||||
for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
|
||||
nextaddr = prevaddr->next;
|
||||
if (nextaddr == NULL) {
|
||||
/*
|
||||
* This is the end of the list.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (prevaddr == NULL) {
|
||||
/*
|
||||
* The list was empty; this is the first member.
|
||||
*/
|
||||
curdev->addresses = curaddr;
|
||||
} else {
|
||||
/*
|
||||
* "prevaddr" is the last member of the list; append
|
||||
* this member to it.
|
||||
*/
|
||||
prevaddr->next = curaddr;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_add_if(pcap_if_t **devlist, char *name, u_int flags,
|
||||
const char *description, char *errbuf)
|
||||
{
|
||||
pcap_if_t *curdev;
|
||||
|
||||
return (add_or_find_if(&curdev, devlist, name, flags, description,
|
||||
errbuf));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free a list of interfaces.
|
||||
*/
|
||||
void
|
||||
pcap_freealldevs(pcap_if_t *alldevs)
|
||||
{
|
||||
pcap_if_t *curdev, *nextdev;
|
||||
pcap_addr_t *curaddr, *nextaddr;
|
||||
|
||||
for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
|
||||
nextdev = curdev->next;
|
||||
|
||||
/*
|
||||
* Free all addresses.
|
||||
*/
|
||||
for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
|
||||
nextaddr = curaddr->next;
|
||||
if (curaddr->addr)
|
||||
free(curaddr->addr);
|
||||
if (curaddr->netmask)
|
||||
free(curaddr->netmask);
|
||||
if (curaddr->broadaddr)
|
||||
free(curaddr->broadaddr);
|
||||
if (curaddr->dstaddr)
|
||||
free(curaddr->dstaddr);
|
||||
free(curaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the name string.
|
||||
*/
|
||||
free(curdev->name);
|
||||
|
||||
/*
|
||||
* Free the description string, if any.
|
||||
*/
|
||||
if (curdev->description != NULL)
|
||||
free(curdev->description);
|
||||
|
||||
/*
|
||||
* Free the interface.
|
||||
*/
|
||||
free(curdev);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
/*
|
||||
* Return the name of a network interface attached to the system, or NULL
|
||||
* if none can be found. The interface must be configured up; the
|
||||
@ -95,138 +468,47 @@ char *
|
||||
pcap_lookupdev(errbuf)
|
||||
register char *errbuf;
|
||||
{
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
struct ifaddrs *ifap, *ifa, *mp;
|
||||
int n, minunit;
|
||||
char *cp;
|
||||
pcap_if_t *alldevs;
|
||||
/* for old BSD systems, including bsdi3 */
|
||||
#ifndef IF_NAMESIZE
|
||||
#define IF_NAMESIZE IFNAMSIZ
|
||||
#endif
|
||||
static char device[IF_NAMESIZE + 1];
|
||||
char *ret;
|
||||
|
||||
if (getifaddrs(&ifap) != 0) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"getifaddrs: %s", pcap_strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp = NULL;
|
||||
minunit = 666;
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||
if ((ifa->ifa_flags & IFF_UP) == 0)
|
||||
continue;
|
||||
#ifdef IFF_LOOPBACK
|
||||
if ((ifa->ifa_flags & IFF_LOOPBACK) != 0)
|
||||
continue;
|
||||
#else
|
||||
if (strncmp(ifa->ifa_name, "lo", 2) == 0 &&
|
||||
(ifa->ifa_name[2] == '\0' || isdigit(ifa->ifa_name[2]))) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (cp = ifa->ifa_name; !isdigit(*cp); ++cp)
|
||||
continue;
|
||||
n = atoi(cp);
|
||||
if (n < minunit) {
|
||||
minunit = n;
|
||||
mp = ifa;
|
||||
}
|
||||
}
|
||||
if (mp == NULL) {
|
||||
(void)strncpy(errbuf, "no suitable device found",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
freeifaddrs(ifap);
|
||||
if (pcap_findalldevs(&alldevs, errbuf) == -1)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
(void)strlcpy(device, mp->ifa_name, sizeof(device));
|
||||
freeifaddrs(ifap);
|
||||
return (device);
|
||||
#else
|
||||
register int fd, minunit, n;
|
||||
register char *cp;
|
||||
register struct ifreq *ifrp, *ifend, *ifnext, *mp;
|
||||
struct ifconf ifc;
|
||||
struct ifreq ibuf[16], ifr;
|
||||
static char device[sizeof(ifrp->ifr_name) + 1];
|
||||
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
|
||||
pcap_strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
ifc.ifc_len = sizeof ibuf;
|
||||
ifc.ifc_buf = (caddr_t)ibuf;
|
||||
|
||||
memset((char *)ibuf, 0, sizeof(ibuf));
|
||||
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 ||
|
||||
ifc.ifc_len < sizeof(struct ifreq)) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFCONF: %s",
|
||||
pcap_strerror(errno));
|
||||
(void)close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
ifrp = ibuf;
|
||||
ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);
|
||||
|
||||
mp = NULL;
|
||||
minunit = 666;
|
||||
for (; ifrp < ifend; ifrp = ifnext) {
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
|
||||
if (n < sizeof(*ifrp))
|
||||
ifnext = ifrp + 1;
|
||||
else
|
||||
ifnext = (struct ifreq *)((char *)ifrp + n);
|
||||
if (ifrp->ifr_addr.sa_family != AF_INET)
|
||||
continue;
|
||||
#else
|
||||
ifnext = ifrp + 1;
|
||||
#endif
|
||||
if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
|
||||
/*
|
||||
* Need a template to preserve address info that is
|
||||
* used below to locate the next entry. (Otherwise,
|
||||
* SIOCGIFFLAGS stomps over it because the requests
|
||||
* are returned in a union.)
|
||||
* There are no devices on the list, or the first device
|
||||
* on the list is a loopback device, which means there
|
||||
* are no non-loopback devices on the list. This means
|
||||
* we can't return any device.
|
||||
*
|
||||
* XXX - why not return a loopback device? If we can't
|
||||
* capture on it, it won't be on the list, and if it's
|
||||
* on the list, there aren't any non-loopback devices,
|
||||
* so why not just supply it as the default device?
|
||||
*/
|
||||
strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
|
||||
if (errno == ENXIO)
|
||||
continue;
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGIFFLAGS: %.*s: %s",
|
||||
(int)sizeof(ifr.ifr_name), ifr.ifr_name,
|
||||
pcap_strerror(errno));
|
||||
(void)close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Must be up and not the loopback */
|
||||
if ((ifr.ifr_flags & IFF_UP) == 0 || ISLOOPBACK(&ifr))
|
||||
continue;
|
||||
|
||||
for (cp = ifrp->ifr_name; !isdigit(*cp); ++cp)
|
||||
continue;
|
||||
n = atoi(cp);
|
||||
if (n < minunit) {
|
||||
minunit = n;
|
||||
mp = ifrp;
|
||||
}
|
||||
}
|
||||
(void)close(fd);
|
||||
if (mp == NULL) {
|
||||
(void)strncpy(errbuf, "no suitable device found",
|
||||
PCAP_ERRBUF_SIZE - 1);
|
||||
return (NULL);
|
||||
(void)strlcpy(errbuf, "no suitable device found",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
ret = NULL;
|
||||
} else {
|
||||
/*
|
||||
* Return the name of the first device on the list.
|
||||
*/
|
||||
(void)strlcpy(device, alldevs->name, sizeof(device));
|
||||
ret = device;
|
||||
}
|
||||
|
||||
(void)strlcpy(device, mp->ifr_name, sizeof(device));
|
||||
return (device);
|
||||
#endif
|
||||
pcap_freealldevs(alldevs);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_lookupnet(device, netp, maskp, errbuf)
|
||||
register char *device;
|
||||
register const char *device;
|
||||
register bpf_u_int32 *netp, *maskp;
|
||||
register char *errbuf;
|
||||
{
|
||||
@ -234,6 +516,20 @@ pcap_lookupnet(device, netp, maskp, errbuf)
|
||||
register struct sockaddr_in *sin;
|
||||
struct ifreq ifr;
|
||||
|
||||
/*
|
||||
* The pseudo-device "any" listens on all interfaces and therefore
|
||||
* has the network address and -mask "0.0.0.0" therefore catching
|
||||
* all traffic. Using NULL for the interface is the same as "any".
|
||||
*/
|
||||
if (!device || strcmp(device, "any") == 0
|
||||
#ifdef HAVE_DAG_API
|
||||
|| strstr(device, "dag") != NULL
|
||||
#endif
|
||||
) {
|
||||
*netp = *maskp = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
|
||||
@ -284,3 +580,121 @@ pcap_lookupnet(device, netp, maskp, errbuf)
|
||||
*netp &= *maskp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#else /* WIN32 */
|
||||
|
||||
/*
|
||||
* Return the name of a network interface attached to the system, or NULL
|
||||
* if none can be found. The interface must be configured up; the
|
||||
* lowest unit number is preferred; loopback is ignored.
|
||||
*/
|
||||
char *
|
||||
pcap_lookupdev(errbuf)
|
||||
register char *errbuf;
|
||||
{
|
||||
DWORD dwVersion;
|
||||
DWORD dwWindowsMajorVersion;
|
||||
dwVersion = GetVersion(); /* get the OS version */
|
||||
dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
||||
|
||||
if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
|
||||
/*
|
||||
* Windows 95, 98, ME.
|
||||
*/
|
||||
ULONG NameLength = 8192;
|
||||
static char AdaptersName[8192];
|
||||
|
||||
PacketGetAdapterNames(AdaptersName,&NameLength);
|
||||
|
||||
return (AdaptersName);
|
||||
} else {
|
||||
/*
|
||||
* Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility
|
||||
*/
|
||||
ULONG NameLength = 8192;
|
||||
static WCHAR AdaptersName[8192];
|
||||
char *tAstr;
|
||||
WCHAR *tUstr;
|
||||
WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR));
|
||||
int NAdapts = 0;
|
||||
|
||||
if(TAdaptersName == NULL)
|
||||
{
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength);
|
||||
|
||||
tAstr = (char*)TAdaptersName;
|
||||
tUstr = (WCHAR*)AdaptersName;
|
||||
|
||||
/*
|
||||
* Convert and copy the device names
|
||||
*/
|
||||
while(sscanf(tAstr, "%S", tUstr) > 0)
|
||||
{
|
||||
tAstr += strlen(tAstr) + 1;
|
||||
tUstr += wcslen(tUstr) + 1;
|
||||
NAdapts ++;
|
||||
}
|
||||
|
||||
tAstr++;
|
||||
*tUstr = 0;
|
||||
tUstr++;
|
||||
|
||||
/*
|
||||
* Copy the descriptions
|
||||
*/
|
||||
while(NAdapts--)
|
||||
{
|
||||
strcpy((char*)tUstr, tAstr);
|
||||
(char*)tUstr += strlen(tAstr) + 1;;
|
||||
tAstr += strlen(tAstr) + 1;
|
||||
}
|
||||
|
||||
return (char *)(AdaptersName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pcap_lookupnet(device, netp, maskp, errbuf)
|
||||
const register char *device;
|
||||
register bpf_u_int32 *netp, *maskp;
|
||||
register char *errbuf;
|
||||
{
|
||||
/*
|
||||
* We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
|
||||
* in order to skip non IPv4 (i.e. IPv6 addresses)
|
||||
*/
|
||||
npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
|
||||
LONG if_addr_size = 1;
|
||||
struct sockaddr_in *t_addr;
|
||||
unsigned int i;
|
||||
|
||||
if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
|
||||
*netp = *maskp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
|
||||
{
|
||||
if(if_addrs[i].IPAddress.ss_family == AF_INET)
|
||||
{
|
||||
t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
|
||||
*netp = t_addr->sin_addr.S_un.S_addr;
|
||||
t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
|
||||
*maskp = t_addr->sin_addr.S_un.S_addr;
|
||||
|
||||
*netp &= *maskp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*netp = *maskp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: nametoaddr.c,v 1.13 2000/04/14 14:18:40 itojun Exp $ */
|
||||
/* $NetBSD: nametoaddr.c,v 1.14 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
|
||||
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -28,26 +28,48 @@
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: nametoaddr.c,v 1.47 97/06/13 13:16:19 leres Exp (LBL)";
|
||||
"@(#) Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.68.2.3 2003/11/19 18:13:48 guy Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: nametoaddr.c,v 1.13 2000/04/14 14:18:40 itojun Exp $");
|
||||
__RCSID("$NetBSD: nametoaddr.c,v 1.14 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
|
||||
#else /* WIN32 */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h> /* concession to AIX */
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#if __STDC__
|
||||
struct mbuf;
|
||||
struct rtentry;
|
||||
#include <netinet/in.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
/*
|
||||
* XXX - why was this included even on UNIX?
|
||||
*/
|
||||
#ifdef __MINGW32__
|
||||
#include "IP6_misc.h"
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#ifndef WIN32
|
||||
#ifdef HAVE_ETHER_HOSTTON
|
||||
#ifdef HAVE_NETINET_IF_ETHER_H
|
||||
struct mbuf; /* Squelch compiler warnings on some platforms for */
|
||||
struct rtentry; /* declarations in <net/if.h> */
|
||||
#include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */
|
||||
#include <netinet/if_ether.h>
|
||||
#endif /* HAVE_NETINET_IF_ETHER_H */
|
||||
#endif /* HAVE_ETHER_HOSTTON */
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif /* WIN32 */
|
||||
#ifdef INET6
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
@ -57,7 +79,6 @@ struct rtentry;
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pcap-int.h"
|
||||
@ -65,7 +86,6 @@ struct rtentry;
|
||||
#include "gencode.h"
|
||||
#include <pcap-namedb.h>
|
||||
|
||||
#include "gnuc.h"
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
@ -75,7 +95,7 @@ struct rtentry;
|
||||
#define NTOHS(x) (x) = ntohs(x)
|
||||
#endif
|
||||
|
||||
static inline int xdtoi(int);
|
||||
static __inline int xdtoi(int);
|
||||
|
||||
/*
|
||||
* Convert host name to internet address.
|
||||
@ -130,12 +150,19 @@ pcap_nametoaddrinfo(const char *name)
|
||||
bpf_u_int32
|
||||
pcap_nametonetaddr(const char *name)
|
||||
{
|
||||
#ifndef WIN32
|
||||
struct netent *np;
|
||||
|
||||
if ((np = getnetbyname(name)) != NULL)
|
||||
return np->n_net;
|
||||
else
|
||||
return 0;
|
||||
#else
|
||||
/*
|
||||
* There's no "getnetbyname()" on Windows.
|
||||
*/
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -147,38 +174,40 @@ int
|
||||
pcap_nametoport(const char *name, int *port, int *proto)
|
||||
{
|
||||
struct servent *sp;
|
||||
char *other;
|
||||
int tcp_port = -1;
|
||||
int udp_port = -1;
|
||||
|
||||
sp = getservbyname(name, (char *)0);
|
||||
if (sp != NULL) {
|
||||
NTOHS(sp->s_port);
|
||||
*port = sp->s_port;
|
||||
*proto = pcap_nametoproto(sp->s_proto);
|
||||
/*
|
||||
* We need to check /etc/services for ambiguous entries.
|
||||
* If we find the ambiguous entry, and it has the
|
||||
* same port number, change the proto to PROTO_UNDEF
|
||||
* so both TCP and UDP will be checked.
|
||||
*/
|
||||
if (*proto == IPPROTO_TCP)
|
||||
other = "udp";
|
||||
else
|
||||
other = "tcp";
|
||||
|
||||
sp = getservbyname(name, other);
|
||||
if (sp != 0) {
|
||||
NTOHS(sp->s_port);
|
||||
/*
|
||||
* We need to check /etc/services for ambiguous entries.
|
||||
* If we find the ambiguous entry, and it has the
|
||||
* same port number, change the proto to PROTO_UNDEF
|
||||
* so both TCP and UDP will be checked.
|
||||
*/
|
||||
sp = getservbyname(name, "tcp");
|
||||
if (sp != NULL) tcp_port = ntohs(sp->s_port);
|
||||
sp = getservbyname(name, "udp");
|
||||
if (sp != NULL) udp_port = ntohs(sp->s_port);
|
||||
if (tcp_port >= 0) {
|
||||
*port = tcp_port;
|
||||
*proto = IPPROTO_TCP;
|
||||
if (udp_port >= 0) {
|
||||
if (udp_port == tcp_port)
|
||||
*proto = PROTO_UNDEF;
|
||||
#ifdef notdef
|
||||
if (*port != sp->s_port)
|
||||
else
|
||||
/* Can't handle ambiguous names that refer
|
||||
to different port numbers. */
|
||||
warning("ambiguous port %s in /etc/services",
|
||||
name);
|
||||
#endif
|
||||
*proto = PROTO_UNDEF;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (udp_port >= 0) {
|
||||
*port = udp_port;
|
||||
*proto = IPPROTO_UDP;
|
||||
return 1;
|
||||
}
|
||||
#if defined(ultrix) || defined(__osf__)
|
||||
/* Special hack in case NFS isn't in /etc/services */
|
||||
if (strcmp(name, "nfs") == 0) {
|
||||
@ -250,7 +279,7 @@ pcap_nametoeproto(const char *s)
|
||||
}
|
||||
|
||||
/* Hex digit to integer. */
|
||||
static inline int
|
||||
static __inline int
|
||||
xdtoi(c)
|
||||
register int c;
|
||||
{
|
||||
@ -318,7 +347,7 @@ pcap_ether_aton(const char *s)
|
||||
if (*s == ':')
|
||||
s += 1;
|
||||
d = xdtoi(*s++);
|
||||
if (isxdigit(*s)) {
|
||||
if (isxdigit((unsigned char)*s)) {
|
||||
d <<= 4;
|
||||
d |= xdtoi(*s++);
|
||||
}
|
||||
@ -336,7 +365,7 @@ pcap_ether_hostton(const char *name)
|
||||
register struct pcap_etherent *ep;
|
||||
register u_char *ap;
|
||||
static FILE *fp = NULL;
|
||||
static init = 0;
|
||||
static int init = 0;
|
||||
|
||||
if (!init) {
|
||||
fp = fopen(PCAP_ETHERS_FILE, "r");
|
||||
@ -362,7 +391,17 @@ pcap_ether_hostton(const char *name)
|
||||
}
|
||||
#else
|
||||
|
||||
#if !defined(sgi) && !defined(__NetBSD__)
|
||||
/*
|
||||
* XXX - perhaps this should, instead, be declared in "lbl/os-XXX.h" files,
|
||||
* for those OS versions that don't declare it, rather than being declared
|
||||
* here? That way, for example, we could declare it on FreeBSD 2.x (which
|
||||
* doesn't declare it), but not on FreeBSD 3.x (which declares it like
|
||||
* this) or FreeBSD 4.x (which declares it with its first argument as
|
||||
* "const char *", so no matter how we declare it here, it'll fail to
|
||||
* compile on one of 3.x or 4.x).
|
||||
*/
|
||||
#if !defined(sgi) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \
|
||||
!defined(_UNICOSMP)
|
||||
extern int ether_hostton(char *, struct ether_addr *);
|
||||
#endif
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: optimize.c,v 1.15 2002/08/26 11:21:19 yamt Exp $ */
|
||||
/* $NetBSD: optimize.c,v 1.16 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
|
||||
@ -26,24 +26,26 @@
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: optimize.c,v 1.60 96/09/26 23:28:14 leres Exp (LBL)";
|
||||
"@(#) Header: /tcpdump/master/libpcap/optimize.c,v 1.76.2.3 2003/12/22 00:26:36 guy Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: optimize.c,v 1.15 2002/08/26 11:21:19 yamt Exp $");
|
||||
__RCSID("$NetBSD: optimize.c,v 1.16 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include "gencode.h"
|
||||
|
||||
#include "gnuc.h"
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
@ -104,26 +106,26 @@ static void compute_local_ud(struct block *);
|
||||
static void find_ud(struct block *);
|
||||
static void init_val(void);
|
||||
static int F(int, int, int);
|
||||
static inline void vstore(struct stmt *, int *, int, int);
|
||||
static __inline void vstore(struct stmt *, int *, int, int);
|
||||
static void opt_blk(struct block *, int);
|
||||
static int use_conflict(struct block *, struct block *);
|
||||
static void opt_j(struct edge *);
|
||||
static void or_pullup(struct block *);
|
||||
static void and_pullup(struct block *);
|
||||
static void opt_blks(struct block *, int);
|
||||
static inline void link_inedge(struct edge *, struct block *);
|
||||
static __inline void link_inedge(struct edge *, struct block *);
|
||||
static void find_inedges(struct block *);
|
||||
static void opt_root(struct block **);
|
||||
static void opt_loop(struct block *, int);
|
||||
static void fold_op(struct stmt *, int, int);
|
||||
static inline struct slist *this_op(struct slist *);
|
||||
static __inline struct slist *this_op(struct slist *);
|
||||
static void opt_not(struct block *);
|
||||
static void opt_peep(struct block *);
|
||||
static void opt_stmt(struct stmt *, int[], int);
|
||||
static void deadstmt(struct stmt *, struct stmt *[]);
|
||||
static void opt_deadstores(struct block *);
|
||||
static struct block *fold_edge(struct block *, struct edge *);
|
||||
static inline int eq_blk(struct block *, struct block *);
|
||||
static __inline int eq_blk(struct block *, struct block *);
|
||||
static int slength(struct slist *);
|
||||
static int count_blocks(struct block *);
|
||||
static void number_blks_r(struct block *);
|
||||
@ -567,7 +569,7 @@ F(code, v0, v1)
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void
|
||||
static __inline void
|
||||
vstore(s, valp, newval, alter)
|
||||
struct stmt *s;
|
||||
int *valp;
|
||||
@ -637,7 +639,7 @@ fold_op(s, v0, v1)
|
||||
done = 0;
|
||||
}
|
||||
|
||||
static inline struct slist *
|
||||
static __inline struct slist *
|
||||
this_op(s)
|
||||
struct slist *s;
|
||||
{
|
||||
@ -810,6 +812,16 @@ opt_peep(b)
|
||||
done = 0;
|
||||
opt_not(b);
|
||||
}
|
||||
/*
|
||||
* jset #0 -> never
|
||||
* jset #ffffffff -> always
|
||||
*/
|
||||
if (b->s.code == (BPF_JMP|BPF_K|BPF_JSET)) {
|
||||
if (b->s.k == 0)
|
||||
JT(b) = JF(b);
|
||||
if (b->s.k == 0xffffffff)
|
||||
JF(b) = JT(b);
|
||||
}
|
||||
/*
|
||||
* If the accumulator is a known constant, we can compute the
|
||||
* comparison result.
|
||||
@ -927,7 +939,10 @@ opt_stmt(s, val, alter)
|
||||
op = BPF_OP(s->code);
|
||||
if (alter) {
|
||||
if (s->k == 0) {
|
||||
if (op == BPF_ADD || op == BPF_SUB ||
|
||||
/* don't optimize away "sub #0"
|
||||
* as it may be needed later to
|
||||
* fixup the generated math code */
|
||||
if (op == BPF_ADD ||
|
||||
op == BPF_LSH || op == BPF_RSH ||
|
||||
op == BPF_OR) {
|
||||
s->code = NOP;
|
||||
@ -1501,7 +1516,7 @@ opt_blks(root, do_stmts)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
static __inline void
|
||||
link_inedge(parent, child)
|
||||
struct edge *parent;
|
||||
struct block *child;
|
||||
@ -1564,8 +1579,10 @@ opt_loop(root, do_stmts)
|
||||
{
|
||||
|
||||
#ifdef BDEBUG
|
||||
if (dflag > 1)
|
||||
if (dflag > 1) {
|
||||
printf("opt_loop(root, %d) begin\n", do_stmts);
|
||||
opt_dump(root);
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
done = 1;
|
||||
@ -1576,8 +1593,10 @@ opt_loop(root, do_stmts)
|
||||
find_edom(root);
|
||||
opt_blks(root, do_stmts);
|
||||
#ifdef BDEBUG
|
||||
if (dflag > 1)
|
||||
if (dflag > 1) {
|
||||
printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, done);
|
||||
opt_dump(root);
|
||||
}
|
||||
#endif
|
||||
} while (!done);
|
||||
}
|
||||
@ -1597,7 +1616,19 @@ bpf_optimize(rootp)
|
||||
opt_loop(root, 0);
|
||||
opt_loop(root, 1);
|
||||
intern_blocks(root);
|
||||
#ifdef BDEBUG
|
||||
if (dflag > 1) {
|
||||
printf("after intern_blocks()\n");
|
||||
opt_dump(root);
|
||||
}
|
||||
#endif
|
||||
opt_root(rootp);
|
||||
#ifdef BDEBUG
|
||||
if (dflag > 1) {
|
||||
printf("after opt_root()\n");
|
||||
opt_dump(root);
|
||||
}
|
||||
#endif
|
||||
opt_cleanup();
|
||||
}
|
||||
|
||||
@ -1650,7 +1681,7 @@ eq_slist(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
static __inline int
|
||||
eq_blk(b0, b1)
|
||||
struct block *b0, *b1;
|
||||
{
|
||||
@ -1771,6 +1802,20 @@ number_blks_r(p)
|
||||
/*
|
||||
* Return the number of stmts in the flowgraph reachable by 'p'.
|
||||
* The nodes should be unmarked before calling.
|
||||
*
|
||||
* Note that "stmts" means "instructions", and that this includes
|
||||
*
|
||||
* side-effect statements in 'p' (slength(p->stmts));
|
||||
*
|
||||
* statements in the true branch from 'p' (count_stmts(JT(p)));
|
||||
*
|
||||
* statements in the false branch from 'p' (count_stmts(JF(p)));
|
||||
*
|
||||
* the conditional jump itself (1);
|
||||
*
|
||||
* an extra long jump if the true branch requires it (p->longjt);
|
||||
*
|
||||
* an extra long jump if the false branch requires it (p->longjf).
|
||||
*/
|
||||
static int
|
||||
count_stmts(p)
|
||||
@ -1782,7 +1827,7 @@ count_stmts(p)
|
||||
return 0;
|
||||
Mark(p);
|
||||
n = count_stmts(JT(p)) + count_stmts(JF(p));
|
||||
return slength(p->stmts) + n + 1;
|
||||
return slength(p->stmts) + n + 1 + p->longjt + p->longjf;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1804,17 +1849,23 @@ opt_init(root)
|
||||
unMarkAll();
|
||||
n = count_blocks(root);
|
||||
blocks = (struct block **)malloc(n * sizeof(*blocks));
|
||||
if (blocks == NULL)
|
||||
bpf_error("malloc");
|
||||
unMarkAll();
|
||||
n_blocks = 0;
|
||||
number_blks_r(root);
|
||||
|
||||
n_edges = 2 * n_blocks;
|
||||
edges = (struct edge **)malloc(n_edges * sizeof(*edges));
|
||||
if (edges == NULL)
|
||||
bpf_error("malloc");
|
||||
|
||||
/*
|
||||
* The number of levels is bounded by the number of nodes.
|
||||
*/
|
||||
levels = (struct block **)malloc(n_blocks * sizeof(*levels));
|
||||
if (levels == NULL)
|
||||
bpf_error("malloc");
|
||||
|
||||
edgewords = n_edges / (8 * sizeof(bpf_u_int32)) + 1;
|
||||
nodewords = n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
|
||||
@ -1822,6 +1873,8 @@ opt_init(root)
|
||||
/* XXX */
|
||||
space = (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space)
|
||||
+ n_edges * edgewords * sizeof(*space));
|
||||
if (space == NULL)
|
||||
bpf_error("malloc");
|
||||
p = space;
|
||||
all_dom_sets = p;
|
||||
for (i = 0; i < n; ++i) {
|
||||
@ -1858,7 +1911,9 @@ opt_init(root)
|
||||
*/
|
||||
maxval = 3 * max_stmts;
|
||||
vmap = (struct vmapinfo *)malloc(maxval * sizeof(*vmap));
|
||||
vnode_base = (struct valnode *)malloc(maxval * sizeof(*vmap));
|
||||
vnode_base = (struct valnode *)malloc(maxval * sizeof(*vnode_base));
|
||||
if (vmap == NULL || vnode_base == NULL)
|
||||
bpf_error("malloc");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2048,7 +2103,7 @@ icode_to_fcode(root, lenp)
|
||||
struct bpf_insn *fp;
|
||||
|
||||
/*
|
||||
* Loop doing convert_codr_r() until no branches remain
|
||||
* Loop doing convert_code_r() until no branches remain
|
||||
* with too-large offsets.
|
||||
*/
|
||||
while (1) {
|
||||
@ -2056,6 +2111,8 @@ icode_to_fcode(root, lenp)
|
||||
n = *lenp = count_stmts(root);
|
||||
|
||||
fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
|
||||
if (fp == NULL)
|
||||
bpf_error("malloc");
|
||||
memset((char *)fp, 0, sizeof(*fp) * n);
|
||||
fstart = fp;
|
||||
ftail = fp + n;
|
||||
@ -2069,6 +2126,36 @@ icode_to_fcode(root, lenp)
|
||||
return fp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a copy of a BPF program and put it in the "fcode" member of
|
||||
* a "pcap_t".
|
||||
*
|
||||
* If we fail to allocate memory for the copy, fill in the "errbuf"
|
||||
* member of the "pcap_t" with an error message, and return -1;
|
||||
* otherwise, return 0.
|
||||
*/
|
||||
int
|
||||
install_bpf_program(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
size_t prog_size;
|
||||
|
||||
/*
|
||||
* Free up any already installed program.
|
||||
*/
|
||||
pcap_freecode(&p->fcode);
|
||||
|
||||
prog_size = sizeof(*fp->bf_insns) * fp->bf_len;
|
||||
p->fcode.bf_len = fp->bf_len;
|
||||
p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size);
|
||||
if (p->fcode.bf_insns == NULL) {
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef BDEBUG
|
||||
static void
|
||||
opt_dump(root)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: pcap-bpf.c,v 1.11 2004/01/20 23:31:20 jonathan Exp $ */
|
||||
/* $NetBSD: pcap-bpf.c,v 1.12 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1998
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -24,21 +24,73 @@
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: pcap-bpf.c,v 1.29 96/12/31 20:53:40 leres Exp (LBL)";
|
||||
"@(#) Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.67.2.4 2003/11/22 00:06:28 guy Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: pcap-bpf.c,v 1.11 2004/01/20 23:31:20 jonathan Exp $");
|
||||
__RCSID("$NetBSD: pcap-bpf.c,v 1.12 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h> /* optionally get BSD define */
|
||||
#include <sys/time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#ifdef _AIX
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* Prevent bpf.h from redefining the DLT_ values to their
|
||||
* IFT_ values, as we're going to return the standard libpcap
|
||||
* values, not IBM's non-standard IFT_ values.
|
||||
*/
|
||||
#undef _AIX
|
||||
#include <net/bpf.h>
|
||||
#define _AIX
|
||||
|
||||
#include <net/if_types.h> /* for IFT_ values */
|
||||
#include <sys/sysconfig.h>
|
||||
#include <sys/device.h>
|
||||
#include <odmi.h>
|
||||
#include <cf.h>
|
||||
|
||||
#ifdef __64BIT__
|
||||
#define domakedev makedev64
|
||||
#define getmajor major64
|
||||
#define bpf_hdr bpf_hdr32
|
||||
#else /* __64BIT__ */
|
||||
#define domakedev makedev
|
||||
#define getmajor major
|
||||
#endif /* __64BIT__ */
|
||||
|
||||
#define BPF_NAME "bpf"
|
||||
#define BPF_MINORS 4
|
||||
#define DRIVER_PATH "/usr/lib/drivers"
|
||||
#define BPF_NODE "/dev/bpf"
|
||||
static int bpfloadedflag = 0;
|
||||
static int odmlockid = 0;
|
||||
|
||||
#else /* _AIX */
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#endif /* _AIX */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
@ -49,20 +101,39 @@ __RCSID("$NetBSD: pcap-bpf.c,v 1.11 2004/01/20 23:31:20 jonathan Exp $");
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include "gnuc.h"
|
||||
#ifdef HAVE_DAG_API
|
||||
#include "pcap-dag.h"
|
||||
#endif /* HAVE_DAG_API */
|
||||
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
|
||||
#include "gencode.h"
|
||||
#include "gencode.h" /* for "no_optimize" */
|
||||
|
||||
int __PCAP_MAX_BUFSIZE = (4*1024*1024);
|
||||
|
||||
int
|
||||
pcap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
static int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp);
|
||||
static int pcap_set_datalink_bpf(pcap_t *p, int dlt);
|
||||
|
||||
static int
|
||||
pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
struct bpf_stat s;
|
||||
|
||||
/*
|
||||
* "ps_recv" counts packets handed to the filter, not packets
|
||||
* that passed the filter. This includes packets later dropped
|
||||
* because we ran out of buffer space.
|
||||
*
|
||||
* "ps_drop" counts packets dropped inside the BPF device
|
||||
* because we ran out of buffer space. It doesn't count
|
||||
* packets dropped by the interface driver. It counts
|
||||
* only packets that passed the filter.
|
||||
*
|
||||
* Both statistics include packets not yet read from the kernel
|
||||
* by libpcap, and thus not yet seen by the application.
|
||||
*/
|
||||
if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) {
|
||||
(void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s",
|
||||
pcap_strerror(errno));
|
||||
@ -74,14 +145,28 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
static int
|
||||
pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
{
|
||||
int cc;
|
||||
int n = 0;
|
||||
register u_char *bp, *ep;
|
||||
struct bpf_insn *fcode;
|
||||
|
||||
fcode = p->md.use_bpf ? NULL : p->fcode.bf_insns;
|
||||
again:
|
||||
/*
|
||||
* Has "pcap_breakloop()" been called?
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
p->break_loop = 0;
|
||||
return (-2);
|
||||
}
|
||||
cc = p->cc;
|
||||
if (p->cc == 0) {
|
||||
cc = read(p->fd, (char *)p->buffer, p->bufsize);
|
||||
@ -92,6 +177,32 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
case EINTR:
|
||||
goto again;
|
||||
|
||||
#ifdef _AIX
|
||||
case EFAULT:
|
||||
/*
|
||||
* Sigh. More AIX wonderfulness.
|
||||
*
|
||||
* For some unknown reason the uiomove()
|
||||
* operation in the bpf kernel extension
|
||||
* 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.
|
||||
* Very strange.... Shaun Clowes
|
||||
*
|
||||
* 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
|
||||
* the last packet you saw" indication,
|
||||
* we just ignore EFAULT and keep reading.
|
||||
*/
|
||||
goto again;
|
||||
#endif
|
||||
|
||||
case EWOULDBLOCK:
|
||||
return (0);
|
||||
#if defined(sun) && !defined(BSD)
|
||||
@ -124,17 +235,65 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
ep = bp + cc;
|
||||
while (bp < ep) {
|
||||
register int caplen, hdrlen;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (p->break_loop) {
|
||||
if (n == 0) {
|
||||
p->break_loop = 0;
|
||||
return (-2);
|
||||
} else {
|
||||
p->bp = bp;
|
||||
p->cc = ep - bp;
|
||||
return (n);
|
||||
}
|
||||
}
|
||||
|
||||
caplen = bhp->bh_caplen;
|
||||
hdrlen = bhp->bh_hdrlen;
|
||||
/*
|
||||
* XXX A bpf_hdr matches a pcap_pkthdr.
|
||||
* Short-circuit evaluation: if using BPF filter
|
||||
* in kernel, no need to do it now.
|
||||
*/
|
||||
(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
|
||||
bp += BPF_WORDALIGN(caplen + hdrlen);
|
||||
if (++n >= cnt && cnt > 0) {
|
||||
p->bp = bp;
|
||||
p->cc = ep - bp;
|
||||
return (n);
|
||||
if (fcode == NULL ||
|
||||
bpf_filter(fcode, bp + hdrlen, bhp->bh_datalen, caplen)) {
|
||||
#ifdef _AIX
|
||||
/*
|
||||
* AIX's BPF returns seconds/nanoseconds time
|
||||
* stamps, not seconds/microseconds time stamps.
|
||||
*
|
||||
* XXX - I'm guessing here that it's a "struct
|
||||
* timestamp"; if not, this code won't compile,
|
||||
* but, if not, you want to send us a bug report
|
||||
* and fall back on using DLPI. It's not as if
|
||||
* BPF used to work right on AIX before this
|
||||
* change; this change attempts to fix the fact
|
||||
* that it didn't....
|
||||
*/
|
||||
bhp->bh_tstamp.tv_usec = bhp->bh_tstamp.tv_usec/1000;
|
||||
#endif
|
||||
/*
|
||||
* XXX A bpf_hdr matches a pcap_pkthdr.
|
||||
*/
|
||||
(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
|
||||
bp += BPF_WORDALIGN(caplen + hdrlen);
|
||||
if (++n >= cnt && cnt > 0) {
|
||||
p->bp = bp;
|
||||
p->cc = ep - bp;
|
||||
return (n);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Skip this packet.
|
||||
*/
|
||||
bp += BPF_WORDALIGN(caplen + hdrlen);
|
||||
}
|
||||
}
|
||||
#undef bhp
|
||||
@ -142,18 +301,181 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
return (n);
|
||||
}
|
||||
|
||||
static inline int
|
||||
#ifdef _AIX
|
||||
static int
|
||||
bpf_odminit(char *errbuf)
|
||||
{
|
||||
char *errstr;
|
||||
|
||||
if (odm_initialize() == -1) {
|
||||
if (odm_err_msg(odmerrno, &errstr) == -1)
|
||||
errstr = "Unknown error";
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bpf_load: odm_initialize failed: %s",
|
||||
errstr);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) {
|
||||
if (odm_err_msg(odmerrno, &errstr) == -1)
|
||||
errstr = "Unknown error";
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s",
|
||||
errstr);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
bpf_odmcleanup(char *errbuf)
|
||||
{
|
||||
char *errstr;
|
||||
|
||||
if (odm_unlock(odmlockid) == -1) {
|
||||
if (odm_err_msg(odmerrno, &errstr) == -1)
|
||||
errstr = "Unknown error";
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bpf_load: odm_unlock failed: %s",
|
||||
errstr);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (odm_terminate() == -1) {
|
||||
if (odm_err_msg(odmerrno, &errstr) == -1)
|
||||
errstr = "Unknown error";
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bpf_load: odm_terminate failed: %s",
|
||||
errstr);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
bpf_load(char *errbuf)
|
||||
{
|
||||
long major;
|
||||
int *minors;
|
||||
int numminors, i, rc;
|
||||
char buf[1024];
|
||||
struct stat sbuf;
|
||||
struct bpf_config cfg_bpf;
|
||||
struct cfg_load cfg_ld;
|
||||
struct cfg_kmod cfg_km;
|
||||
|
||||
/*
|
||||
* This is very very close to what happens in the real implementation
|
||||
* but I've fixed some (unlikely) bug situations.
|
||||
*/
|
||||
if (bpfloadedflag)
|
||||
return (0);
|
||||
|
||||
if (bpf_odminit(errbuf) != 0)
|
||||
return (-1);
|
||||
|
||||
major = genmajor(BPF_NAME);
|
||||
if (major == -1) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bpf_load: genmajor failed: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
minors = getminor(major, &numminors, BPF_NAME);
|
||||
if (!minors) {
|
||||
minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1);
|
||||
if (!minors) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bpf_load: genminor failed: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (bpf_odmcleanup(errbuf))
|
||||
return (-1);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (rc == -1 || getmajor(sbuf.st_rdev) != major) {
|
||||
for (i = 0; i < BPF_MINORS; i++) {
|
||||
sprintf(buf, "%s%d", BPF_NODE, i);
|
||||
unlink(buf);
|
||||
if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bpf_load: can't mknod %s: %s",
|
||||
buf, pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the driver is loaded */
|
||||
memset(&cfg_ld, 0x0, sizeof(cfg_ld));
|
||||
cfg_ld.path = buf;
|
||||
sprintf(cfg_ld.path, "%s/%s", DRIVER_PATH, BPF_NAME);
|
||||
if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
|
||||
(cfg_ld.kmid == 0)) {
|
||||
/* Driver isn't loaded, load it now */
|
||||
if (sysconfig(SYS_SINGLELOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bpf_load: could not load driver: %s",
|
||||
strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure the driver */
|
||||
cfg_km.cmd = CFG_INIT;
|
||||
cfg_km.kmid = cfg_ld.kmid;
|
||||
cfg_km.mdilen = sizeof(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);
|
||||
}
|
||||
}
|
||||
|
||||
bpfloadedflag = 1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline int
|
||||
bpf_open(pcap_t *p, char *errbuf)
|
||||
{
|
||||
int fd;
|
||||
int n = 0;
|
||||
char device[sizeof "/dev/bpf000"];
|
||||
char device[sizeof "/dev/bpf0000000000"];
|
||||
|
||||
#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
|
||||
|
||||
/*
|
||||
* Go through all the minors and find one that isn't in use.
|
||||
*/
|
||||
do {
|
||||
(void)snprintf(device, sizeof device, "/dev/bpf%d", n++);
|
||||
(void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
|
||||
fd = open(device, O_RDWR);
|
||||
} while (fd < 0 && errno == EBUSY);
|
||||
|
||||
@ -161,21 +483,54 @@ bpf_open(pcap_t *p, char *errbuf)
|
||||
* XXX better message for all minors used
|
||||
*/
|
||||
if (fd < 0)
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
|
||||
pcap_strerror(errno));
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"(no devices found) %s: %s", device, pcap_strerror(errno));
|
||||
|
||||
return (fd);
|
||||
}
|
||||
|
||||
static void
|
||||
pcap_close_bpf(pcap_t *p)
|
||||
{
|
||||
if (p->buffer != NULL)
|
||||
free(p->buffer);
|
||||
if (p->fd >= 0)
|
||||
close(p->fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - on AIX, IBM's tcpdump (and perhaps the incompatible-with-everybody-
|
||||
* else's libpcap in AIX 5.1) appears to forcibly load the BPF driver
|
||||
* if it's not already loaded, and to create the BPF devices if they
|
||||
* don't exist.
|
||||
*
|
||||
* It'd be nice if we could do the same, although the code to do so
|
||||
* might be version-dependent, alas (the way to do it isn't necessarily
|
||||
* documented).
|
||||
*/
|
||||
pcap_t *
|
||||
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
|
||||
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
char *ebuf)
|
||||
{
|
||||
int fd;
|
||||
struct ifreq ifr;
|
||||
struct bpf_version bv;
|
||||
#ifdef BIOCGDLTLIST
|
||||
struct bpf_dltlist bdl;
|
||||
#endif
|
||||
u_int v;
|
||||
pcap_t *p;
|
||||
struct utsname osinfo;
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
if (strstr(device, "dag")) {
|
||||
return dag_open_live(device, snaplen, promisc, to_ms, ebuf);
|
||||
}
|
||||
#endif /* HAVE_DAG_API */
|
||||
|
||||
#ifdef BIOCGDLTLIST
|
||||
memset(&bdl, 0, sizeof(bdl));
|
||||
#endif
|
||||
|
||||
bzero(&bdl, sizeof(bdl));
|
||||
|
||||
@ -185,7 +540,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
|
||||
pcap_strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
bzero(p, sizeof(*p));
|
||||
memset(p, 0, sizeof(*p));
|
||||
fd = bpf_open(p, ebuf);
|
||||
if (fd < 0)
|
||||
goto bad;
|
||||
@ -243,6 +598,38 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
#ifdef _AIX
|
||||
/*
|
||||
* AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT.
|
||||
*/
|
||||
switch (v) {
|
||||
|
||||
case IFT_ETHER:
|
||||
case IFT_ISO88023:
|
||||
v = DLT_EN10MB;
|
||||
break;
|
||||
|
||||
case IFT_FDDI:
|
||||
v = DLT_FDDI;
|
||||
break;
|
||||
|
||||
case IFT_ISO88025:
|
||||
v = DLT_IEEE802;
|
||||
break;
|
||||
|
||||
case IFT_LOOP:
|
||||
v = DLT_NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* We don't know what to map this to yet.
|
||||
*/
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown interface type %u",
|
||||
v);
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
#if _BSDI_VERSION - 0 >= 199510
|
||||
/* The SLIP and PPP link layer header changed in BSD/OS 2.1 */
|
||||
switch (v) {
|
||||
@ -254,16 +641,25 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
|
||||
case DLT_PPP:
|
||||
v = DLT_PPP_BSDOS;
|
||||
break;
|
||||
|
||||
case 11: /*DLT_FR*/
|
||||
v = DLT_FRELAY;
|
||||
break;
|
||||
|
||||
case 12: /*DLT_C_HDLC*/
|
||||
v = DLT_CHDLC;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
p->linktype = v;
|
||||
|
||||
#ifdef BIOCGDLTLIST
|
||||
/*
|
||||
* We know the default link type -- now determine any additional
|
||||
* DLTs this interface supports. If this fails, it's not fatal;
|
||||
* we just don't get to use the feature later.
|
||||
* 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.
|
||||
*/
|
||||
if (ioctl(fd, BIOCGDLTLIST, (caddr_t) &bdl) == 0) {
|
||||
if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) == 0) {
|
||||
bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * bdl.bfl_len);
|
||||
if (bdl.bfl_list == NULL) {
|
||||
(void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||
@ -271,7 +667,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (ioctl(fd, BIOCGDLTLIST, (caddr_t) &bdl) < 0) {
|
||||
if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) < 0) {
|
||||
(void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"BIOCGDLTLIST: %s", pcap_strerror(errno));
|
||||
goto bad;
|
||||
@ -279,10 +675,22 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
|
||||
|
||||
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
|
||||
|
||||
/* set timeout */
|
||||
if (to_ms != 0) {
|
||||
/*
|
||||
* 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;
|
||||
@ -292,9 +700,71 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
if (promisc)
|
||||
|
||||
#ifdef _AIX
|
||||
#ifdef BIOCIMMEDIATE
|
||||
/*
|
||||
* Darren Reed notes that
|
||||
*
|
||||
* On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the
|
||||
* timeout appears to be ignored and it waits until the buffer
|
||||
* is filled before returning. The result of not having it
|
||||
* set is almost worse than useless if your BPF filter
|
||||
* is reducing things to only a few packets (i.e. one every
|
||||
* second or so).
|
||||
*
|
||||
* so we turn BIOCIMMEDIATE mode on if this is AIX.
|
||||
*
|
||||
* We don't turn it on for other platforms, as that means we
|
||||
* get woken up for every packet, which may not be what we want;
|
||||
* in the Winter 1993 USENIX paper on BPF, they say:
|
||||
*
|
||||
* Since a process might want to look at every packet on a
|
||||
* network and the time between packets can be only a few
|
||||
* microseconds, it is not possible to do a read system call
|
||||
* per packet and BPF must collect the data from several
|
||||
* packets and return it as a unit when the monitoring
|
||||
* application does a read.
|
||||
*
|
||||
* which I infer is the reason for the timeout - it means we
|
||||
* wait that amount of time, in the hopes that more packets
|
||||
* will arrive and we'll get them all with one read.
|
||||
*
|
||||
* Setting BIOCIMMEDIATE mode on FreeBSD (and probably other
|
||||
* BSDs) causes the timeout to be ignored.
|
||||
*
|
||||
* On the other hand, some platforms (e.g., Linux) don't support
|
||||
* timeouts, they just hand stuff to you as soon as it arrives;
|
||||
* if that doesn't cause a problem on those platforms, it may
|
||||
* be OK to have BIOCIMMEDIATE mode on BSD as well.
|
||||
*
|
||||
* (Note, though, that applications may depend on the read
|
||||
* completing, even if no packets have arrived, when the timeout
|
||||
* expires, e.g. GUI applications that have to check for input
|
||||
* while waiting for packets to arrive; a non-zero timeout
|
||||
* prevents "select()" from working right on FreeBSD and
|
||||
* possibly other BSDs, as the timer doesn't start until a
|
||||
* "read()" is done, so the timer isn't in effect if the
|
||||
* application is blocked on a "select()", and the "select()"
|
||||
* doesn't get woken up for a BPF device until the buffer
|
||||
* fills up.)
|
||||
*/
|
||||
v = 1;
|
||||
if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
#endif /* BIOCIMMEDIATE */
|
||||
#endif /* _AIX */
|
||||
|
||||
if (promisc) {
|
||||
/* set promiscuous mode, okay if it fails */
|
||||
(void)ioctl(p->fd, BIOCPROMISC, NULL);
|
||||
if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
|
||||
pcap_strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
|
||||
(void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
|
||||
@ -308,54 +778,140 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
#ifdef _AIX
|
||||
/* For some strange reason this seems to prevent the EFAULT
|
||||
* problems we have experienced from AIX BPF. */
|
||||
memset(p->buffer, 0x0, p->bufsize);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On most BPF platforms, either you can do a "select()" or
|
||||
* "poll()" on a BPF file descriptor and it works correctly,
|
||||
* or you can do it and it will return "readable" if the
|
||||
* hold buffer is full but not if the timeout expires *and*
|
||||
* a non-blocking read will, if the hold buffer is empty
|
||||
* but the store buffer isn't empty, rotate the buffers
|
||||
* and return what packets are available.
|
||||
*
|
||||
* In the latter case, the fact that a non-blocking read
|
||||
* will give you the available packets means you can work
|
||||
* around the failure of "select()" and "poll()" to wake up
|
||||
* and return "readable" when the timeout expires by using
|
||||
* the timeout as the "select()" or "poll()" timeout, putting
|
||||
* the BPF descriptor into non-blocking mode, and read from
|
||||
* it regardless of whether "select()" reports it as readable
|
||||
* or not.
|
||||
*
|
||||
* However, in FreeBSD 4.3 and 4.4, "select()" and "poll()"
|
||||
* won't wake up and return "readable" if the timer expires
|
||||
* and non-blocking reads return EWOULDBLOCK if the hold
|
||||
* buffer is empty, even if the store buffer is non-empty.
|
||||
*
|
||||
* This means the workaround in question won't work.
|
||||
*
|
||||
* Therefore, on FreeBSD 4.3 and 4.4, we set "p->selectable_fd"
|
||||
* to -1, which means "sorry, you can't use 'select()' or 'poll()'
|
||||
* here". On all other BPF platforms, we set it to the FD for
|
||||
* the BPF device; in NetBSD, OpenBSD, and Darwin, a non-blocking
|
||||
* read will, if the hold buffer is empty and the store buffer
|
||||
* isn't empty, rotate the buffers and return what packets are
|
||||
* there (and in sufficiently recent versions of OpenBSD
|
||||
* "select()" and "poll()" should work correctly).
|
||||
*
|
||||
* XXX - what about AIX?
|
||||
*/
|
||||
if (uname(&osinfo) == 0) {
|
||||
/*
|
||||
* We can check what OS this is.
|
||||
*/
|
||||
if (strcmp(osinfo.sysname, "FreeBSD") == 0 &&
|
||||
(strcmp(osinfo.release, "4.3") == 0 ||
|
||||
strcmp(osinfo.release, "4.4") == 0))
|
||||
p->selectable_fd = -1;
|
||||
else
|
||||
p->selectable_fd = p->fd;
|
||||
} else {
|
||||
/*
|
||||
* We can't find out what OS this is, so assume we can
|
||||
* do a "select()" or "poll()".
|
||||
*/
|
||||
p->selectable_fd = p->fd;
|
||||
}
|
||||
|
||||
p->read_op = pcap_read_bpf;
|
||||
p->setfilter_op = pcap_setfilter_bpf;
|
||||
p->set_datalink_op = pcap_set_datalink_bpf;
|
||||
p->getnonblock_op = pcap_getnonblock_fd;
|
||||
p->setnonblock_op = pcap_setnonblock_fd;
|
||||
p->stats_op = pcap_stats_bpf;
|
||||
p->close_op = pcap_close_bpf;
|
||||
|
||||
return (p);
|
||||
bad:
|
||||
(void)close(fd);
|
||||
#ifdef BIOCGDLTLIST
|
||||
if (bdl.bfl_list != NULL)
|
||||
free(bdl.bfl_list);
|
||||
#endif
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
#ifdef HAVE_DAG_API
|
||||
if (dag_platform_finddevs(alldevsp, errbuf) < 0)
|
||||
return (-1);
|
||||
#endif /* HAVE_DAG_API */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (no_optimize)
|
||||
p->fcode = *fp;
|
||||
if (p->sf.rfile != NULL)
|
||||
p->fcode = *fp;
|
||||
else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
|
||||
(void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
|
||||
if (no_optimize) {
|
||||
/*
|
||||
* XXX - what if we already have a filter in the kernel?
|
||||
*/
|
||||
if (install_bpf_program(p, fp) < 0)
|
||||
return (-1);
|
||||
p->md.use_bpf = 0; /* filtering in userland */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free any user-mode filter we might happen to have installed.
|
||||
*/
|
||||
pcap_freecode(&p->fcode);
|
||||
|
||||
/*
|
||||
* Try to install the kernel filter.
|
||||
*/
|
||||
if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
p->md.use_bpf = 1; /* filtering in the kernel */
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_set_datalink(pcap_t *p, int dlt)
|
||||
static int
|
||||
pcap_set_datalink_bpf(pcap_t *p, int dlt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < p->dlt_count; i++)
|
||||
if (p->dlt_list[i] == dlt)
|
||||
break;
|
||||
if (i >= p->dlt_count) {
|
||||
(void) snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"No such DLT as %d", dlt);
|
||||
return -1;
|
||||
}
|
||||
#ifdef BIOCSDLT
|
||||
if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
|
||||
(void) snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"Cannot set DLT %d: %s", dlt, strerror(errno));
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
p->linktype = dlt;
|
||||
return 0;
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
@ -1,598 +0,0 @@
|
||||
/* $NetBSD: pcap-bpf.h,v 1.1.1.2 2004/09/19 21:57:55 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* 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.9.2.9 2004/03/28 21:45:32 fenner 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
|
||||
|
||||
typedef int bpf_int32;
|
||||
typedef u_int bpf_u_int32;
|
||||
|
||||
/*
|
||||
* 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 <net/bpf.h> for ages.
|
||||
*/
|
||||
#define DLT_NULL 0 /* no link-layer 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 /* IEEE 802 Networks */
|
||||
#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 <net/bpf.h> for ages. We use #ifdefs to
|
||||
* detect the BSDs that define them differently from the traditional
|
||||
* libpcap <net/bpf.h>
|
||||
*
|
||||
* 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/SNAP 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 */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* OpenBSD defines it as 12, but that collides with DLT_RAW, so we
|
||||
* define it as 108 here. If OpenBSD picks up this file, it should
|
||||
* define DLT_LOOP as 12 in its version, as per the comment above -
|
||||
* and should not use 108 as a DLT_ value.
|
||||
*/
|
||||
#define DLT_LOOP 108
|
||||
|
||||
/*
|
||||
* 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 <kent@praesum.com>
|
||||
* for private use.
|
||||
*/
|
||||
#define DLT_RIO 124 /* RapidIO */
|
||||
#define DLT_PCI_EXP 125 /* PCI Express */
|
||||
#define DLT_AURORA 126 /* Xilinx Aurora link layer */
|
||||
|
||||
/*
|
||||
* BSD header for 802.11 plus a number of bits of link-layer information
|
||||
* including radio information.
|
||||
*/
|
||||
#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */
|
||||
|
||||
/*
|
||||
* Reserved for the TZSP encapsulation, as per request from
|
||||
* Chris Waters <chris.waters@networkchemistry.com>
|
||||
* 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 <hannes@juniper.net>. 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
|
||||
* <dieter@apple.com>. 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
|
||||
|
||||
/*
|
||||
* 139 through 142 are reserved for SS7.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Reserved for 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 could and arguably should also be used by non-AVS Linux
|
||||
* 802.11 drivers; that may happen 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 <hannes@juniper.net>. The DLT_s are used
|
||||
* for passing on chassis-internal metainformation such as
|
||||
* QOS profiles, etc..
|
||||
*/
|
||||
#define DLT_JUNIPER_MONITOR 164
|
||||
|
||||
/*
|
||||
* 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
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pcap-int.h,v 1.9 2002/09/22 16:13:01 thorpej Exp $ */
|
||||
/* $NetBSD: pcap-int.h,v 1.10 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995, 1996
|
||||
@ -32,21 +32,36 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) Header: pcap-int.h,v 1.18 96/11/27 18:43:09 leres Exp (LBL)
|
||||
* @(#) Header: /tcpdump/master/libpcap/pcap-int.h,v 1.55.2.4 2003/12/15 01:42:24 guy Exp (LBL)
|
||||
*/
|
||||
|
||||
#ifndef pcap_int_h
|
||||
#define pcap_int_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <packet32.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
/*
|
||||
* Savefile
|
||||
*/
|
||||
typedef enum {
|
||||
NOT_SWAPPED,
|
||||
SWAPPED,
|
||||
MAYBE_SWAPPED
|
||||
} swapped_type_t;
|
||||
|
||||
struct pcap_sf {
|
||||
FILE *rfile;
|
||||
int swapped;
|
||||
int hdrsize;
|
||||
swapped_type_t lengths_swapped;
|
||||
int version_major;
|
||||
int version_minor;
|
||||
u_char *base;
|
||||
@ -55,26 +70,48 @@ struct pcap_sf {
|
||||
struct pcap_md {
|
||||
struct pcap_stat stat;
|
||||
/*XXX*/
|
||||
int use_bpf;
|
||||
int use_bpf; /* using kernel filter */
|
||||
u_long TotPkts; /* can't oflow for 79 hrs on ether */
|
||||
u_long TotAccepted; /* count accepted by filter */
|
||||
u_long TotDrops; /* count of dropped packets */
|
||||
long TotMissed; /* missed by i/f during this run */
|
||||
long OrigMissed; /* missed by i/f before this run */
|
||||
#ifdef linux
|
||||
int pad;
|
||||
int skip;
|
||||
char *device;
|
||||
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 lo_ifindex; /* interface index of the loopback device */
|
||||
char *device; /* device name */
|
||||
struct pcap *next; /* list of open promiscuous sock_packet pcaps */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
void *dag_mem_base; /* DAG card memory base address */
|
||||
u_int dag_mem_bottom; /* DAG card current memory bottom pointer */
|
||||
u_int dag_mem_top; /* DAG card current memory top pointer */
|
||||
int dag_fcs_bits; /* Number of checksum bits from link layer */
|
||||
int dag_offset_flags; /* Flags to pass to dag_offset(). */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct pcap {
|
||||
#ifdef WIN32
|
||||
ADAPTER *adapter;
|
||||
LPPACKET Packet;
|
||||
int timeout;
|
||||
int nonblock;
|
||||
#else
|
||||
int fd;
|
||||
int selectable_fd;
|
||||
#endif /* WIN32 */
|
||||
int snapshot;
|
||||
int linktype;
|
||||
int tzoff; /* timezone offset */
|
||||
int offset; /* offset for proper alignment */
|
||||
|
||||
int break_loop; /* flag set to force break from packet-reading loop */
|
||||
|
||||
struct pcap_sf sf;
|
||||
struct pcap_md md;
|
||||
|
||||
@ -91,15 +128,27 @@ struct pcap {
|
||||
*/
|
||||
u_char *pkt;
|
||||
|
||||
/*
|
||||
* Methods.
|
||||
*/
|
||||
int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);
|
||||
int (*setfilter_op)(pcap_t *, struct bpf_program *);
|
||||
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 *);
|
||||
|
||||
/*
|
||||
* Placeholder for filter code if bpf not in kernel.
|
||||
*/
|
||||
struct bpf_program fcode;
|
||||
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
char errbuf[PCAP_ERRBUF_SIZE + 1];
|
||||
int dlt_count;
|
||||
int *dlt_list;
|
||||
|
||||
struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -145,6 +194,25 @@ struct pcap_sf_pkthdr {
|
||||
bpf_u_int32 len; /* length this packet (off wire) */
|
||||
};
|
||||
|
||||
/*
|
||||
* How a `pcap_pkthdr' is actually stored in dumpfiles written
|
||||
* by some patched versions of libpcap (e.g. the ones in Red
|
||||
* Hat Linux 6.1 and 6.2).
|
||||
*
|
||||
* Do not change the format of this structure, in any way (this includes
|
||||
* changes that only affect the length of fields in this structure).
|
||||
* Instead, introduce a new structure, as per the above.
|
||||
*/
|
||||
|
||||
struct pcap_sf_patched_pkthdr {
|
||||
struct pcap_timeval ts; /* time stamp */
|
||||
bpf_u_int32 caplen; /* length of portion present */
|
||||
bpf_u_int32 len; /* length this packet (off wire) */
|
||||
int index;
|
||||
unsigned short protocol;
|
||||
unsigned char pkt_type;
|
||||
};
|
||||
|
||||
int yylex(void);
|
||||
|
||||
#ifndef min
|
||||
@ -155,12 +223,73 @@ int yylex(void);
|
||||
int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
|
||||
int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
|
||||
|
||||
/* ULTRIX, Digital UNIX & NetBSD pad to make everything line
|
||||
up on a nice boundary */
|
||||
#if defined(ultrix) || defined(__alpha) || defined(__NetBSD__)
|
||||
|
||||
/*
|
||||
* Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
|
||||
* Tru64 UNIX, and NetBSD pad to make everything line up on a nice boundary.
|
||||
*/
|
||||
#if defined(ultrix) || defined(__osf__) || defined(__NetBSD__)
|
||||
#define PCAP_FDDIPAD 3
|
||||
#endif
|
||||
|
||||
/* XXX */
|
||||
extern int pcap_fddipad;
|
||||
#ifndef HAVE_STRLCPY
|
||||
#define strlcpy(x, y, z) \
|
||||
(strncpy((x), (y), (z)), \
|
||||
((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \
|
||||
strlen((y)))
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !defined(HAVE_SNPRINTF)
|
||||
#define snprintf pcap_snprintf
|
||||
extern int snprintf (char *, size_t, const char *, ...);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_VSNPRINTF)
|
||||
#define vsnprintf pcap_vsnprintf
|
||||
extern int vsnprintf (char *, size_t, const char *, va_list ap);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Routines that most pcap implementations can use for non-blocking mode.
|
||||
*/
|
||||
#ifndef WIN32
|
||||
int pcap_getnonblock_fd(pcap_t *, char *);
|
||||
int pcap_setnonblock_fd(pcap_t *p, int, char *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Internal interfaces for "pcap_findalldevs()".
|
||||
*
|
||||
* "pcap_platform_finddevs()" is a platform-dependent routine to
|
||||
* add devices not found by the "standard" mechanisms (SIOCGIFCONF,
|
||||
* "getifaddrs()", etc..
|
||||
*
|
||||
* "pcap_add_if()" adds an interface to the list of interfaces.
|
||||
*/
|
||||
int pcap_platform_finddevs(pcap_if_t **, char *);
|
||||
int add_addr_to_iflist(pcap_if_t **, char *, u_int, struct sockaddr *,
|
||||
size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
|
||||
struct sockaddr *, size_t, char *);
|
||||
int pcap_add_if(pcap_if_t **, char *, u_int, const char *, char *);
|
||||
struct sockaddr *dup_sockaddr(struct sockaddr *, size_t);
|
||||
int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
|
||||
const char *, char *);
|
||||
|
||||
#ifdef WIN32
|
||||
char *pcap_win32strerror(void);
|
||||
#endif
|
||||
|
||||
/* XXX */
|
||||
extern u_int pcap_fddipad;
|
||||
|
||||
int install_bpf_program(pcap_t *, struct bpf_program *);
|
||||
|
||||
int pcap_strcasecmp(const char *, const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pcap-namedb.h,v 1.6 1999/07/02 10:05:22 itojun Exp $ */
|
||||
/* $NetBSD: pcap-namedb.h,v 1.7 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1996
|
||||
@ -32,12 +32,16 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) Header: pcap-namedb.h,v 1.5 96/07/14 03:00:14 leres Exp (LBL)
|
||||
* @(#) Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.8 2000/07/29 07:36:43 guy Exp (LBL)
|
||||
*/
|
||||
|
||||
#ifndef lib_pcap_ethers_h
|
||||
#define lib_pcap_ethers_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* As returned by the pcap_next_etherent()
|
||||
* XXX this stuff doesn't belong in this interface, but this
|
||||
@ -78,4 +82,8 @@ 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
|
||||
|
@ -1,63 +0,0 @@
|
||||
/* $NetBSD: pcap-stdinc.h,v 1.1.1.2 2004/09/19 21:57:55 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 - 2003
|
||||
* NetGroup, Politecnico di Torino (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. Neither the name of the Politecnico di Torino 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 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#define SIZEOF_CHAR 1
|
||||
#define SIZEOF_SHORT 2
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/*
|
||||
* Avoids a compiler warning in case this was already defined
|
||||
* (someone defined _WINSOCKAPI_ when including 'windows.h', in order
|
||||
* to prevent it from including 'winsock.h')
|
||||
*/
|
||||
#ifdef _WINSOCKAPI_
|
||||
#undef _WINSOCKAPI_
|
||||
#endif
|
||||
#include <winsock2.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "bittypes.h"
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#include "IP6_misc.h"
|
||||
#endif
|
||||
|
||||
#define caddr_t char*
|
||||
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#define inline __inline
|
1008
lib/libpcap/pcap.3
1008
lib/libpcap/pcap.3
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: pcap.c,v 1.9 2002/09/22 16:13:01 thorpej Exp $ */
|
||||
/* $NetBSD: pcap.c,v 1.10 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -37,51 +37,77 @@
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: pcap.c,v 1.27 96/11/27 18:43:25 leres Exp (LBL)";
|
||||
"@(#) Header: /tcpdump/master/libpcap/pcap.c,v 1.63.2.9 2004/03/25 22:40:52 guy Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: pcap.c,v 1.9 2002/09/22 16:13:01 thorpej Exp $");
|
||||
__RCSID("$NetBSD: pcap.c,v 1.10 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* WIN32 */
|
||||
#include <sys/types.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "gnuc.h"
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
#include <dagnew.h>
|
||||
#include <dagapi.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
{
|
||||
|
||||
if (p->sf.rfile != NULL)
|
||||
return (pcap_offline_read(p, cnt, callback, user));
|
||||
return (pcap_read(p, cnt, callback, user));
|
||||
return p->read_op(p, cnt, callback, user);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - is this necessary?
|
||||
*/
|
||||
int
|
||||
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
{
|
||||
|
||||
return p->read_op(p, cnt, callback, user);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
{
|
||||
int n;
|
||||
register int n;
|
||||
|
||||
for (;;) {
|
||||
if (p->sf.rfile != NULL)
|
||||
if (p->sf.rfile != NULL) {
|
||||
/*
|
||||
* 0 means EOF, so don't loop if we get 0.
|
||||
*/
|
||||
n = pcap_offline_read(p, cnt, callback, user);
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* XXX keep reading until we get something
|
||||
* (or an error occurs)
|
||||
*/
|
||||
do {
|
||||
n = pcap_read(p, cnt, callback, user);
|
||||
n = p->read_op(p, cnt, callback, user);
|
||||
} while (n == 0);
|
||||
}
|
||||
if (n <= 0)
|
||||
@ -119,6 +145,79 @@ pcap_next(pcap_t *p, struct pcap_pkthdr *h)
|
||||
return (s.pkt);
|
||||
}
|
||||
|
||||
struct pkt_for_fakecallback {
|
||||
struct pcap_pkthdr *hdr;
|
||||
const u_char **pkt;
|
||||
};
|
||||
|
||||
static void
|
||||
pcap_fakecallback(u_char *userData, const struct pcap_pkthdr *h,
|
||||
const u_char *pkt)
|
||||
{
|
||||
struct pkt_for_fakecallback *sp = (struct pkt_for_fakecallback *)userData;
|
||||
|
||||
*sp->hdr = *h;
|
||||
*sp->pkt = pkt;
|
||||
}
|
||||
|
||||
int
|
||||
pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
|
||||
const u_char **pkt_data)
|
||||
{
|
||||
struct pkt_for_fakecallback s;
|
||||
|
||||
s.hdr = &p->pcap_header;
|
||||
s.pkt = pkt_data;
|
||||
|
||||
/* Saves a pointer to the packet headers */
|
||||
*pkt_header= &p->pcap_header;
|
||||
|
||||
if (p->sf.rfile != NULL) {
|
||||
int status;
|
||||
|
||||
/* We are on an offline capture */
|
||||
status = pcap_offline_read(p, 1, pcap_fakecallback,
|
||||
(u_char *)&s);
|
||||
|
||||
/*
|
||||
* Return codes for pcap_offline_read() are:
|
||||
* - 0: EOF
|
||||
* - -1: error
|
||||
* - >1: OK
|
||||
* The first one ('0') conflicts with the return code of
|
||||
* 0 from pcap_read() meaning "no packets arrived before
|
||||
* the timeout expired", so we map it to -2 so you can
|
||||
* distinguish between an EOF from a savefile and a
|
||||
* "no packets arrived before the timeout expired, try
|
||||
* again" from a live capture.
|
||||
*/
|
||||
if (status == 0)
|
||||
return (-2);
|
||||
else
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return codes for pcap_read() are:
|
||||
* - 0: timeout
|
||||
* - -1: error
|
||||
* - -2: loop was broken out of with pcap_breakloop()
|
||||
* - >1: OK
|
||||
* The first one ('0') conflicts with the return code of 0 from
|
||||
* pcap_offline_read() meaning "end of file".
|
||||
*/
|
||||
return (p->read_op(p, 1, pcap_fakecallback, (u_char *)&s));
|
||||
}
|
||||
|
||||
/*
|
||||
* Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate.
|
||||
*/
|
||||
void
|
||||
pcap_breakloop(pcap_t *p)
|
||||
{
|
||||
p->break_loop = 1;
|
||||
}
|
||||
|
||||
int
|
||||
pcap_datalink(pcap_t *p)
|
||||
{
|
||||
@ -128,19 +227,243 @@ pcap_datalink(pcap_t *p)
|
||||
int
|
||||
pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
|
||||
{
|
||||
if (p->dlt_count <= 0) {
|
||||
*dlt_buffer = NULL;
|
||||
return -1;
|
||||
if (p->dlt_count == 0) {
|
||||
/*
|
||||
* We couldn't fetch the list of DLTs, which means
|
||||
* this platform doesn't support changing the
|
||||
* DLT for an interface. Return a list of DLTs
|
||||
* containing only the DLT this device supports.
|
||||
*/
|
||||
*dlt_buffer = (int*)malloc(sizeof(**dlt_buffer));
|
||||
if (*dlt_buffer == NULL) {
|
||||
(void)snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
**dlt_buffer = p->linktype;
|
||||
return (1);
|
||||
} else {
|
||||
*dlt_buffer = (int*)malloc(sizeof(**dlt_buffer) * p->dlt_count);
|
||||
if (*dlt_buffer == NULL) {
|
||||
(void)snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
(void)memcpy(*dlt_buffer, p->dlt_list,
|
||||
sizeof(**dlt_buffer) * p->dlt_count);
|
||||
return (p->dlt_count);
|
||||
}
|
||||
*dlt_buffer = (int*)malloc(sizeof(**dlt_buffer) * p->dlt_count);
|
||||
if (*dlt_buffer == NULL) {
|
||||
(void)snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s",
|
||||
pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
pcap_set_datalink(pcap_t *p, int dlt)
|
||||
{
|
||||
int i;
|
||||
const char *dlt_name;
|
||||
|
||||
if (p->dlt_count == 0 || p->set_datalink_op == NULL) {
|
||||
/*
|
||||
* We couldn't fetch the list of DLTs, or we don't
|
||||
* have a "set datalink" operation, which means
|
||||
* this platform doesn't support changing the
|
||||
* DLT for an interface. Check whether the new
|
||||
* DLT is the one this interface supports.
|
||||
*/
|
||||
if (p->linktype != dlt)
|
||||
goto unsupported;
|
||||
|
||||
/*
|
||||
* It is, so there's nothing we need to do here.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
(void)memcpy(*dlt_buffer, p->dlt_list,
|
||||
sizeof(**dlt_buffer) * p->dlt_count);
|
||||
return (p->dlt_count);
|
||||
for (i = 0; i < p->dlt_count; i++)
|
||||
if (p->dlt_list[i] == dlt)
|
||||
break;
|
||||
if (i >= p->dlt_count)
|
||||
goto unsupported;
|
||||
if (p->set_datalink_op(p, dlt) == -1)
|
||||
return (-1);
|
||||
p->linktype = dlt;
|
||||
return (0);
|
||||
|
||||
unsupported:
|
||||
dlt_name = pcap_datalink_val_to_name(dlt);
|
||||
if (dlt_name != NULL) {
|
||||
(void) snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"%s is not one of the DLTs supported by this device",
|
||||
dlt_name);
|
||||
} else {
|
||||
(void) snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"DLT %d is not one of the DLTs supported by this device",
|
||||
dlt);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
struct dlt_choice {
|
||||
const char *name;
|
||||
const char *description;
|
||||
int dlt;
|
||||
};
|
||||
|
||||
#define DLT_CHOICE(code, description) { #code, description, code }
|
||||
#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 }
|
||||
|
||||
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_SLIP, "SLIP"),
|
||||
DLT_CHOICE(DLT_PPP, "PPP"),
|
||||
DLT_CHOICE(DLT_FDDI, "FDDI"),
|
||||
DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 IP-over-ATM"),
|
||||
DLT_CHOICE(DLT_RAW, "Raw IP"),
|
||||
DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"),
|
||||
DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"),
|
||||
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_C_HDLC, "Cisco HDLC"),
|
||||
DLT_CHOICE(DLT_IEEE802_11, "802.11"),
|
||||
DLT_CHOICE(DLT_FRELAY, "Frame Relay"),
|
||||
DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"),
|
||||
DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"),
|
||||
DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"),
|
||||
DLT_CHOICE(DLT_LTALK, "Localtalk"),
|
||||
DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"),
|
||||
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_ARCNET_LINUX, "Linux ARCNET"),
|
||||
DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
|
||||
DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
|
||||
DLT_CHOICE_SENTINEL
|
||||
};
|
||||
|
||||
/*
|
||||
* This array is designed for mapping upper and lower case letter
|
||||
* together for a case independent comparison. The mappings are
|
||||
* based upon ascii character sequences.
|
||||
*/
|
||||
static const u_char charmap[] = {
|
||||
(u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003',
|
||||
(u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007',
|
||||
(u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013',
|
||||
(u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017',
|
||||
(u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023',
|
||||
(u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027',
|
||||
(u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033',
|
||||
(u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037',
|
||||
(u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043',
|
||||
(u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047',
|
||||
(u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053',
|
||||
(u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057',
|
||||
(u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063',
|
||||
(u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067',
|
||||
(u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073',
|
||||
(u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077',
|
||||
(u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143',
|
||||
(u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
|
||||
(u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
|
||||
(u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
|
||||
(u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
|
||||
(u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
|
||||
(u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133',
|
||||
(u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137',
|
||||
(u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143',
|
||||
(u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
|
||||
(u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
|
||||
(u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
|
||||
(u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
|
||||
(u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
|
||||
(u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173',
|
||||
(u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177',
|
||||
(u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203',
|
||||
(u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207',
|
||||
(u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213',
|
||||
(u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217',
|
||||
(u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223',
|
||||
(u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227',
|
||||
(u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233',
|
||||
(u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237',
|
||||
(u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243',
|
||||
(u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247',
|
||||
(u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253',
|
||||
(u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257',
|
||||
(u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263',
|
||||
(u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267',
|
||||
(u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273',
|
||||
(u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277',
|
||||
(u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343',
|
||||
(u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
|
||||
(u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
|
||||
(u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
|
||||
(u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
|
||||
(u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
|
||||
(u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333',
|
||||
(u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337',
|
||||
(u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343',
|
||||
(u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
|
||||
(u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
|
||||
(u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
|
||||
(u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
|
||||
(u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
|
||||
(u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373',
|
||||
(u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377',
|
||||
};
|
||||
|
||||
int
|
||||
pcap_strcasecmp(const char *s1, const char *s2)
|
||||
{
|
||||
register const u_char *cm = charmap,
|
||||
*us1 = (u_char *)s1,
|
||||
*us2 = (u_char *)s2;
|
||||
|
||||
while (cm[*us1] == cm[*us2++])
|
||||
if (*us1++ == '\0')
|
||||
return(0);
|
||||
return (cm[*us1] - cm[*--us2]);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_datalink_name_to_val(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; dlt_choices[i].name != NULL; i++) {
|
||||
if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1,
|
||||
name) == 0)
|
||||
return (dlt_choices[i].dlt);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
const char *
|
||||
pcap_datalink_val_to_name(int dlt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; dlt_choices[i].name != NULL; i++) {
|
||||
if (dlt_choices[i].dlt == dlt)
|
||||
return (dlt_choices[i].name + sizeof("DLT_") - 1);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
pcap_datalink_val_to_description(int dlt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; dlt_choices[i].name != NULL; i++) {
|
||||
if (dlt_choices[i].dlt == dlt)
|
||||
return (dlt_choices[i].description);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
@ -176,9 +499,24 @@ pcap_file(pcap_t *p)
|
||||
int
|
||||
pcap_fileno(pcap_t *p)
|
||||
{
|
||||
#ifndef WIN32
|
||||
return (p->fd);
|
||||
#else
|
||||
if (p->adapter != NULL)
|
||||
return ((int)(DWORD)p->adapter->hFile);
|
||||
else
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
int
|
||||
pcap_get_selectable_fd(pcap_t *p)
|
||||
{
|
||||
return (p->selectable_fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
pcap_perror(pcap_t *p, char *prefix)
|
||||
{
|
||||
@ -191,6 +529,105 @@ pcap_geterr(pcap_t *p)
|
||||
return (p->errbuf);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_getnonblock(pcap_t *p, char *errbuf)
|
||||
{
|
||||
return p->getnonblock_op(p, errbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current non-blocking mode setting, under the assumption that
|
||||
* it's just the standard POSIX non-blocking flag.
|
||||
*
|
||||
* We don't look at "p->nonblock", in case somebody tweaked the FD
|
||||
* directly.
|
||||
*/
|
||||
#ifndef WIN32
|
||||
int
|
||||
pcap_getnonblock_fd(pcap_t *p, char *errbuf)
|
||||
{
|
||||
int fdflags;
|
||||
|
||||
fdflags = fcntl(p->fd, F_GETFL, 0);
|
||||
if (fdflags == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
if (fdflags & O_NONBLOCK)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
{
|
||||
return p->setnonblock_op(p, nonblock, errbuf);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
/*
|
||||
* Set non-blocking mode, under the assumption that it's just the
|
||||
* standard POSIX non-blocking flag. (This can be called by the
|
||||
* per-platform non-blocking-mode routine if that routine also
|
||||
* needs to do some additional work.)
|
||||
*/
|
||||
int
|
||||
pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
|
||||
{
|
||||
int fdflags;
|
||||
|
||||
fdflags = fcntl(p->fd, F_GETFL, 0);
|
||||
if (fdflags == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
if (nonblock)
|
||||
fdflags |= O_NONBLOCK;
|
||||
else
|
||||
fdflags &= ~O_NONBLOCK;
|
||||
if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* Generate a string for the last Win32-specific error (i.e. an error generated when
|
||||
* calling a Win32 API).
|
||||
* For errors occurred during standard C calls, we still use pcap_strerror()
|
||||
*/
|
||||
char *
|
||||
pcap_win32strerror(void)
|
||||
{
|
||||
DWORD error;
|
||||
static char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
int errlen;
|
||||
|
||||
error = GetLastError();
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
|
||||
PCAP_ERRBUF_SIZE, NULL);
|
||||
|
||||
/*
|
||||
* "FormatMessage()" "helpfully" sticks CR/LF at the end of the
|
||||
* message. Get rid of it.
|
||||
*/
|
||||
errlen = strlen(errbuf);
|
||||
if (errlen >= 2) {
|
||||
errbuf[errlen - 1] = '\0';
|
||||
errbuf[errlen - 2] = '\0';
|
||||
}
|
||||
return (errbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Not all systems have strerror().
|
||||
*/
|
||||
@ -211,24 +648,132 @@ pcap_strerror(int errnum)
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
return p->setfilter_op(p, fp);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
return p->stats_op(p, ps);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_stats_dead(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Statistics aren't available from a pcap_open_dead pcap_t");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
pcap_close_dead(pcap_t *p)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_open_dead(int linktype, int snaplen)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
p = malloc(sizeof(*p));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
memset (p, 0, sizeof(*p));
|
||||
p->snapshot = snaplen;
|
||||
p->linktype = linktype;
|
||||
p->stats_op = pcap_stats_dead;
|
||||
p->close_op = pcap_close_dead;
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
pcap_close(pcap_t *p)
|
||||
{
|
||||
/*XXX*/
|
||||
if (p->fd >= 0)
|
||||
close(p->fd);
|
||||
if (p->sf.rfile != NULL) {
|
||||
(void)fclose(p->sf.rfile);
|
||||
if (p->sf.base != NULL)
|
||||
free(p->sf.base);
|
||||
} else if (p->buffer != NULL)
|
||||
free(p->buffer);
|
||||
#ifdef linux
|
||||
if (p->md.device != NULL)
|
||||
free(p->md.device);
|
||||
#endif
|
||||
p->close_op(p);
|
||||
if (p->dlt_list != NULL)
|
||||
free(p->dlt_list);
|
||||
|
||||
pcap_freecode(&p->fcode);
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* We make the version string static, and return a pointer to it, rather
|
||||
* than exporting the version string directly. On at least some UNIXes,
|
||||
* if you import data from a shared library into an program, the data is
|
||||
* bound into the program binary, so if the string in the version of the
|
||||
* library with which the program was linked isn't the same as the
|
||||
* string in the version of the library with which the program is being
|
||||
* run, various undesirable things may happen (warnings, the string
|
||||
* being the one from the version of the library with which the program
|
||||
* was linked, or even weirder things, such as the string being the one
|
||||
* from the library but being truncated).
|
||||
*/
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* XXX - it'd be nice if we could somehow generate the WinPcap and libpcap
|
||||
* version numbers when building WinPcap. (It'd be nice to do so for
|
||||
* the packet.dll version number as well.)
|
||||
*/
|
||||
static const char wpcap_version_string[] = "3.0";
|
||||
static const char pcap_version_string_fmt[] =
|
||||
"WinPcap version %s, based on libpcap version 0.8";
|
||||
static const char pcap_version_string_packet_dll_fmt[] =
|
||||
"WinPcap version %s (packet.dll version %s), based on libpcap version 0.8";
|
||||
static char *pcap_version_string;
|
||||
|
||||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
char *packet_version_string;
|
||||
size_t pcap_version_string_len;
|
||||
|
||||
if (pcap_version_string == NULL) {
|
||||
/*
|
||||
* Generate the version string.
|
||||
*/
|
||||
packet_version_string = PacketGetVersion();
|
||||
if (strcmp(wpcap_version_string, packet_version_string) == 0) {
|
||||
/*
|
||||
* WinPcap version string and packet.dll version
|
||||
* string are the same; just report the WinPcap
|
||||
* version.
|
||||
*/
|
||||
pcap_version_string_len =
|
||||
(sizeof pcap_version_string_fmt - 2) +
|
||||
strlen(wpcap_version_string);
|
||||
pcap_version_string = malloc(pcap_version_string_len);
|
||||
sprintf(pcap_version_string, pcap_version_string_fmt,
|
||||
wpcap_version_string);
|
||||
} else {
|
||||
/*
|
||||
* WinPcap version string and packet.dll version
|
||||
* string are different; that shouldn't be the
|
||||
* case (the two libraries should come from the
|
||||
* same version of WinPcap), so we report both
|
||||
* versions.
|
||||
*/
|
||||
pcap_version_string_len =
|
||||
(sizeof pcap_version_string_packet_dll_fmt - 4) +
|
||||
strlen(wpcap_version_string) +
|
||||
strlen(packet_version_string);
|
||||
pcap_version_string = malloc(pcap_version_string_len);
|
||||
sprintf(pcap_version_string,
|
||||
pcap_version_string_packet_dll_fmt,
|
||||
wpcap_version_string, packet_version_string);
|
||||
}
|
||||
}
|
||||
return (pcap_version_string);
|
||||
}
|
||||
#else
|
||||
#include "version.h"
|
||||
|
||||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
return (pcap_version_string);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* $NetBSD: pcap.h,v 1.10 2002/09/22 16:13:01 thorpej Exp $ */
|
||||
/* $NetBSD: pcap.h,v 1.11 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -32,19 +33,27 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) Header: pcap.h,v 1.20 96/07/12 19:24:15 leres Exp (LBL)
|
||||
* @(#) Header: /tcpdump/master/libpcap/pcap.h,v 1.45.2.4 2004/01/27 22:56:20 guy Exp (LBL)
|
||||
*/
|
||||
|
||||
#ifndef lib_pcap_h
|
||||
#define lib_pcap_h
|
||||
|
||||
#ifdef WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* WIN32 */
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PCAP_VERSION_MAJOR 2
|
||||
#define PCAP_VERSION_MINOR 4
|
||||
|
||||
@ -61,12 +70,42 @@ typedef u_int32_t bpf_u_int32;
|
||||
|
||||
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;
|
||||
*
|
||||
* 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;
|
||||
@ -75,7 +114,7 @@ struct pcap_file_header {
|
||||
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 (DLT_*) */
|
||||
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -96,35 +135,69 @@ 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 */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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(char *, bpf_u_int32 *, bpf_u_int32 *, char *);
|
||||
pcap_t *pcap_open_live(char *, int, int, int, char *);
|
||||
pcap_t *pcap_open_offline(char *, 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 *);
|
||||
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_getnonblock(pcap_t *, char *);
|
||||
int pcap_setnonblock(pcap_t *, int, char *);
|
||||
void pcap_perror(pcap_t *, char *);
|
||||
const char*
|
||||
pcap_strerror(int);
|
||||
char *pcap_geterr(pcap_t *);
|
||||
int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
|
||||
bpf_u_int32);
|
||||
int pcap_compile_nopcap(int, int, struct bpf_program *, char *,
|
||||
int, bpf_u_int32, char *);
|
||||
/* XXX */
|
||||
int pcap_freecode(pcap_t *, struct bpf_program *);
|
||||
int pcap_compile_nopcap(int, int, struct bpf_program *,
|
||||
char *, int, bpf_u_int32, char *errbuf);
|
||||
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 *);
|
||||
@ -134,13 +207,55 @@ int pcap_minor_version(pcap_t *);
|
||||
FILE *pcap_file(pcap_t *);
|
||||
int pcap_fileno(pcap_t *);
|
||||
|
||||
pcap_dumper_t *pcap_dump_open(pcap_t *, char *);
|
||||
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
|
||||
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 *);
|
||||
FILE *pcap_dump_file(pcap_dumper_t *);
|
||||
|
||||
int pcap_findalldevs(pcap_if_t **, char *);
|
||||
void pcap_freealldevs(pcap_if_t *);
|
||||
|
||||
const char *pcap_lib_version(void);
|
||||
|
||||
#ifdef notdef
|
||||
/* XXX this guy lives in the bpf tree */
|
||||
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
|
||||
#endif
|
||||
int bpf_validate(struct bpf_insn *f, int len);
|
||||
char *bpf_image(struct bpf_insn *, int);
|
||||
void bpf_dump(struct bpf_program *, int);
|
||||
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* Win32 definitions
|
||||
*/
|
||||
|
||||
int pcap_setbuff(pcap_t *p, int dim);
|
||||
int pcap_setmode(pcap_t *p, int mode);
|
||||
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
|
||||
int pcap_setmintocopy(pcap_t *p, int size);
|
||||
|
||||
#ifdef WPCAP
|
||||
/* Include file with the wpcap-specific extensions */
|
||||
#include <Win32-Extensions.h>
|
||||
#endif
|
||||
|
||||
#define MODE_CAPT 0
|
||||
#define MODE_STAT 1
|
||||
#define MODE_MON 2
|
||||
|
||||
#else
|
||||
/*
|
||||
* UN*X definitions
|
||||
*/
|
||||
|
||||
int pcap_get_selectable_fd(pcap_t *);
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* $NetBSD: ppp.h,v 1.2 1999/07/25 00:15:22 itojun Exp $ */
|
||||
/* $NetBSD: ppp.h,v 1.3 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/* @(#) Header: ppp.h,v 1.7 95/05/04 17:52:46 mccanne Exp (LBL) */
|
||||
/* @(#) Header: /tcpdump/master/libpcap/ppp.h,v 1.8 1999/10/19 15:18:31 itojun Exp (LBL) */
|
||||
/*
|
||||
* Point to Point Protocol (PPP) RFC1331
|
||||
*
|
||||
@ -32,7 +32,7 @@
|
||||
#define PPP_BRPDU 0x0031 /* Bridging PDU */
|
||||
#define PPP_STII 0x0033 /* Stream Protocol (ST-II) */
|
||||
#define PPP_VINES 0x0035 /* Banyan Vines */
|
||||
#define PPP_IPV6 0x0057 /* Internet Protocol Version 6 */
|
||||
#define PPP_IPV6 0x0057 /* Internet Protocol version 6 */
|
||||
|
||||
#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */
|
||||
#define PPP_LUXCOM 0x0231 /* Luxcom */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: savefile.c,v 1.7 2001/02/07 17:35:56 itojun Exp $ */
|
||||
/* $NetBSD: savefile.c,v 1.8 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -34,36 +34,40 @@
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: savefile.c,v 1.36 96/12/10 23:15:02 leres Exp (LBL)";
|
||||
"@(#) Header: /tcpdump/master/libpcap/savefile.c,v 1.92.2.11 2004/03/11 23:46:14 guy Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: savefile.c,v 1.7 2001/02/07 17:35:56 itojun Exp $");
|
||||
__RCSID("$NetBSD: savefile.c,v 1.8 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include "gnuc.h"
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
|
||||
#define TCPDUMP_MAGIC 0xa1b2c3d4
|
||||
#define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34
|
||||
|
||||
/*
|
||||
* We use the "receiver-makes-right" approach to byte order,
|
||||
* because time is at a premium when we are writing the file.
|
||||
* In other words, the pcap_file_header and pcap_pkthdr,
|
||||
* records are written in host byte order.
|
||||
* Note that the packets are always written in network byte order.
|
||||
* Note that the bytes of packet data are written out in the order in
|
||||
* which they were received, so multi-byte fields in packets are not
|
||||
* written in host byte order, they're written in whatever order the
|
||||
* sending machine put them in.
|
||||
*
|
||||
* ntoh[ls] aren't sufficient because we might need to swap on a big-endian
|
||||
* machine (if the file was written in little-end order).
|
||||
@ -78,6 +82,456 @@ __RCSID("$NetBSD: savefile.c,v 1.7 2001/02/07 17:35:56 itojun Exp $");
|
||||
#define SFERR_BADF 3
|
||||
#define SFERR_EOF 4 /* not really an error, just a status */
|
||||
|
||||
/*
|
||||
* We don't write DLT_* values to the capture file header, because
|
||||
* they're not the same on all platforms.
|
||||
*
|
||||
* Unfortunately, the various flavors of BSD have not always used the same
|
||||
* numerical values for the same data types, and various patches to
|
||||
* libpcap for non-BSD OSes have added their own DLT_* codes for link
|
||||
* layer encapsulation types seen on those OSes, and those codes have had,
|
||||
* in some cases, values that were also used, on other platforms, for other
|
||||
* link layer encapsulation types.
|
||||
*
|
||||
* This means that capture files of a type whose numerical DLT_* code
|
||||
* means different things on different BSDs, or with different versions
|
||||
* of libpcap, can't always be read on systems other than those like
|
||||
* the one running on the machine on which the capture was made.
|
||||
*
|
||||
* Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes
|
||||
* to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_*
|
||||
* codes to DLT_* codes when reading a savefile header.
|
||||
*
|
||||
* For those DLT_* codes that have, as far as we know, the same values on
|
||||
* all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as
|
||||
* DLT_xxx; that way, captures of those types can still be read by
|
||||
* versions of libpcap that map LINKTYPE_* values to DLT_* values, and
|
||||
* captures of those types written by versions of libpcap that map DLT_
|
||||
* values to LINKTYPE_ values can still be read by older versions
|
||||
* of libpcap.
|
||||
*
|
||||
* The other LINKTYPE_* codes are given values starting at 100, in the
|
||||
* hopes that no DLT_* code will be given one of those values.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should, if possible, also contribute patches to libpcap and tcpdump
|
||||
* to handle the new encapsulation type, so that they can also be checked
|
||||
* into the tcpdump.org CVS repository and so that they will appear in
|
||||
* future libpcap and tcpdump releases.
|
||||
*
|
||||
* Do *NOT* assume that any values after the largest value in this file
|
||||
* are available; you might not have the most up-to-date version of this
|
||||
* file, and new values after that one might have been assigned. Also,
|
||||
* do *NOT* use any values below 100 - those might already have been
|
||||
* taken by one (or more!) organizations.
|
||||
*/
|
||||
#define LINKTYPE_NULL DLT_NULL
|
||||
#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */
|
||||
#define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */
|
||||
#define LINKTYPE_AX25 DLT_AX25
|
||||
#define LINKTYPE_PRONET DLT_PRONET
|
||||
#define LINKTYPE_CHAOS DLT_CHAOS
|
||||
#define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */
|
||||
#define LINKTYPE_ARCNET DLT_ARCNET /* BSD-style headers */
|
||||
#define LINKTYPE_SLIP DLT_SLIP
|
||||
#define LINKTYPE_PPP DLT_PPP
|
||||
#define LINKTYPE_FDDI DLT_FDDI
|
||||
|
||||
/*
|
||||
* LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662
|
||||
* PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol
|
||||
* field) at the beginning of the packet.
|
||||
*
|
||||
* This is for use when there is always such a header; the address field
|
||||
* might be 0xff, for regular PPP, or it might be an address field for Cisco
|
||||
* point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco
|
||||
* HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL.
|
||||
*
|
||||
* We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that
|
||||
* nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL
|
||||
* captures will be written out with a link type that NetBSD's tcpdump
|
||||
* can read.
|
||||
*/
|
||||
#define LINKTYPE_PPP_HDLC 50 /* PPP in HDLC-like framing */
|
||||
|
||||
#define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */
|
||||
|
||||
/*
|
||||
* This isn't supported in libpcap 0.8[.x], but is supported in the
|
||||
* current CVS version; we include it here to note that it's not available
|
||||
* for anybody else to use.
|
||||
*/
|
||||
#define LINKTYPE_SYMANTEC_FIREWALL 99 /* Symantec Enterprise Firewall */
|
||||
|
||||
#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */
|
||||
#define LINKTYPE_RAW 101 /* raw IP */
|
||||
#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */
|
||||
#define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */
|
||||
#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */
|
||||
#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */
|
||||
#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */
|
||||
#define LINKTYPE_FRELAY 107 /* Frame Relay */
|
||||
#define LINKTYPE_LOOP 108 /* OpenBSD loopback */
|
||||
#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */
|
||||
|
||||
/*
|
||||
* These three types are reserved for future use.
|
||||
*/
|
||||
#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */
|
||||
#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */
|
||||
#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */
|
||||
|
||||
#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */
|
||||
#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */
|
||||
#define LINKTYPE_ECONET 115 /* Acorn Econet */
|
||||
|
||||
/*
|
||||
* Reserved for use with OpenBSD ipfilter.
|
||||
*/
|
||||
#define LINKTYPE_IPFILTER 116
|
||||
|
||||
#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */
|
||||
#define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */
|
||||
#define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */
|
||||
#define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */
|
||||
|
||||
/*
|
||||
* Reserved for Siemens HiPath HDLC.
|
||||
*/
|
||||
#define LINKTYPE_HHDLC 121
|
||||
|
||||
#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */
|
||||
#define LINKTYPE_SUNATM 123 /* Solaris+SunATM */
|
||||
|
||||
/*
|
||||
* Reserved as per request from Kent Dahlgren <kent@praesum.com>
|
||||
* for private use.
|
||||
*/
|
||||
#define LINKTYPE_RIO 124 /* RapidIO */
|
||||
#define LINKTYPE_PCI_EXP 125 /* PCI Express */
|
||||
#define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */
|
||||
|
||||
#define LINKTYPE_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */
|
||||
|
||||
/*
|
||||
* Reserved for the TZSP encapsulation, as per request from
|
||||
* Chris Waters <chris.waters@networkchemistry.com>
|
||||
* 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 LINKTYPE_TZSP 128 /* Tazmen Sniffer Protocol */
|
||||
|
||||
#define LINKTYPE_ARCNET_LINUX 129 /* Linux-style headers */
|
||||
|
||||
/*
|
||||
* Juniper-private data link types, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>. The corresponding
|
||||
* DLT_s are used for passing on chassis-internal
|
||||
* metainformation such as QOS profiles, etc..
|
||||
*/
|
||||
#define LINKTYPE_JUNIPER_MLPPP 130
|
||||
#define LINKTYPE_JUNIPER_MLFR 131
|
||||
#define LINKTYPE_JUNIPER_ES 132
|
||||
#define LINKTYPE_JUNIPER_GGSN 133
|
||||
#define LINKTYPE_JUNIPER_MFR 134
|
||||
#define LINKTYPE_JUNIPER_ATM2 135
|
||||
#define LINKTYPE_JUNIPER_SERVICES 136
|
||||
#define LINKTYPE_JUNIPER_ATM1 137
|
||||
|
||||
#define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */
|
||||
|
||||
#define LINKTYPE_RAWSS7 139 /* see rawss7.h for */
|
||||
#define LINKTYPE_RAWSS7_MTP2 140 /* information on these */
|
||||
#define LINKTYPE_RAWSS7_MTP3 141 /* definitions */
|
||||
#define LINKTYPE_RAWSS7_SCCP 142
|
||||
|
||||
/*
|
||||
* This isn't supported in libpcap 0.8[.x], but is supported in the
|
||||
* current CVS version; we include it here to note that it's not available
|
||||
* for anybody else to use.
|
||||
*/
|
||||
#define LINKTYPE_DOCSIS 143 /* DOCSIS MAC frames */
|
||||
|
||||
#define LINKTYPE_LINUX_IRDA 144 /* Linux-IrDA */
|
||||
|
||||
/*
|
||||
* Reserved for IBM SP switch and IBM Next Federation switch.
|
||||
*/
|
||||
#define LINKTYPE_IBM_SP 145
|
||||
#define LINKTYPE_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 LINKTYPE_ 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, 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.
|
||||
*/
|
||||
#define LINKTYPE_USER0 147
|
||||
#define LINKTYPE_USER1 148
|
||||
#define LINKTYPE_USER2 149
|
||||
#define LINKTYPE_USER3 150
|
||||
#define LINKTYPE_USER4 151
|
||||
#define LINKTYPE_USER5 152
|
||||
#define LINKTYPE_USER6 153
|
||||
#define LINKTYPE_USER7 154
|
||||
#define LINKTYPE_USER8 155
|
||||
#define LINKTYPE_USER9 156
|
||||
#define LINKTYPE_USER10 157
|
||||
#define LINKTYPE_USER11 158
|
||||
#define LINKTYPE_USER12 159
|
||||
#define LINKTYPE_USER13 160
|
||||
#define LINKTYPE_USER14 161
|
||||
#define LINKTYPE_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 could and arguably should also be used by non-AVS Linux
|
||||
* 802.11 drivers; that may happen in the future.
|
||||
*/
|
||||
#define LINKTYPE_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>. The corresponding
|
||||
* DLT_s are used for passing on chassis-internal
|
||||
* metainformation such as QOS profiles, etc..
|
||||
*/
|
||||
#define LINKTYPE_JUNIPER_MONITOR 164
|
||||
|
||||
static struct linktype_map {
|
||||
int dlt;
|
||||
int linktype;
|
||||
} map[] = {
|
||||
/*
|
||||
* These DLT_* codes have LINKTYPE_* codes with values identical
|
||||
* to the values of the corresponding DLT_* code.
|
||||
*/
|
||||
{ DLT_NULL, LINKTYPE_NULL },
|
||||
{ DLT_EN10MB, LINKTYPE_ETHERNET },
|
||||
{ DLT_EN3MB, LINKTYPE_EXP_ETHERNET },
|
||||
{ DLT_AX25, LINKTYPE_AX25 },
|
||||
{ DLT_PRONET, LINKTYPE_PRONET },
|
||||
{ DLT_CHAOS, LINKTYPE_CHAOS },
|
||||
{ DLT_IEEE802, LINKTYPE_TOKEN_RING },
|
||||
{ DLT_ARCNET, LINKTYPE_ARCNET },
|
||||
{ DLT_SLIP, LINKTYPE_SLIP },
|
||||
{ DLT_PPP, LINKTYPE_PPP },
|
||||
{ DLT_FDDI, LINKTYPE_FDDI },
|
||||
|
||||
/*
|
||||
* These DLT_* codes have different values on different
|
||||
* platforms; we map them to LINKTYPE_* codes that
|
||||
* have values that should never be equal to any DLT_*
|
||||
* code.
|
||||
*/
|
||||
#ifdef DLT_FR
|
||||
/* BSD/OS Frame Relay */
|
||||
{ DLT_FR, LINKTYPE_FRELAY },
|
||||
#endif
|
||||
|
||||
{ DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL },
|
||||
{ DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
|
||||
{ DLT_RAW, LINKTYPE_RAW },
|
||||
{ DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS },
|
||||
{ DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS },
|
||||
|
||||
/* BSD/OS Cisco HDLC */
|
||||
{ DLT_C_HDLC, LINKTYPE_C_HDLC },
|
||||
|
||||
/*
|
||||
* These DLT_* codes are not on all platforms, but, so far,
|
||||
* there don't appear to be any platforms that define
|
||||
* other codes with those values; we map them to
|
||||
* different LINKTYPE_* values anyway, just in case.
|
||||
*/
|
||||
|
||||
/* Linux ATM Classical IP */
|
||||
{ DLT_ATM_CLIP, LINKTYPE_ATM_CLIP },
|
||||
|
||||
/* NetBSD sync/async serial PPP (or Cisco HDLC) */
|
||||
{ DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC },
|
||||
|
||||
/* NetBSD PPP over Ethernet */
|
||||
{ DLT_PPP_ETHER, LINKTYPE_PPP_ETHER },
|
||||
|
||||
/* IEEE 802.11 wireless */
|
||||
{ DLT_IEEE802_11, LINKTYPE_IEEE802_11 },
|
||||
|
||||
/* Frame Relay */
|
||||
{ DLT_FRELAY, LINKTYPE_FRELAY },
|
||||
|
||||
/* OpenBSD loopback */
|
||||
{ DLT_LOOP, LINKTYPE_LOOP },
|
||||
|
||||
/* Linux cooked socket capture */
|
||||
{ DLT_LINUX_SLL, LINKTYPE_LINUX_SLL },
|
||||
|
||||
/* Apple LocalTalk hardware */
|
||||
{ DLT_LTALK, LINKTYPE_LTALK },
|
||||
|
||||
/* Acorn Econet */
|
||||
{ DLT_ECONET, LINKTYPE_ECONET },
|
||||
|
||||
/* OpenBSD DLT_PFLOG */
|
||||
{ DLT_PFLOG, LINKTYPE_PFLOG },
|
||||
|
||||
/* For Cisco-internal use */
|
||||
{ DLT_CISCO_IOS, LINKTYPE_CISCO_IOS },
|
||||
|
||||
/* Prism II monitor-mode header plus 802.11 header */
|
||||
{ DLT_PRISM_HEADER, LINKTYPE_PRISM_HEADER },
|
||||
|
||||
/* FreeBSD Aironet driver stuff */
|
||||
{ DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER },
|
||||
|
||||
/* Siemens HiPath HDLC */
|
||||
{ DLT_HHDLC, LINKTYPE_HHDLC },
|
||||
|
||||
/* RFC 2625 IP-over-Fibre Channel */
|
||||
{ DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC },
|
||||
|
||||
/* Solaris+SunATM */
|
||||
{ DLT_SUNATM, LINKTYPE_SUNATM },
|
||||
|
||||
/* RapidIO */
|
||||
{ DLT_RIO, LINKTYPE_RIO },
|
||||
|
||||
/* PCI Express */
|
||||
{ DLT_PCI_EXP, LINKTYPE_PCI_EXP },
|
||||
|
||||
/* Xilinx Aurora link layer */
|
||||
{ DLT_AURORA, LINKTYPE_AURORA },
|
||||
|
||||
/* 802.11 plus BSD radio header */
|
||||
{ DLT_IEEE802_11_RADIO, LINKTYPE_IEEE802_11_RADIO },
|
||||
|
||||
/* Tazmen Sniffer Protocol */
|
||||
{ DLT_TZSP, LINKTYPE_TZSP },
|
||||
|
||||
/* Arcnet with Linux-style link-layer headers */
|
||||
{ DLT_ARCNET_LINUX, LINKTYPE_ARCNET_LINUX },
|
||||
|
||||
/* Juniper-internal chassis encapsulation */
|
||||
{ DLT_JUNIPER_MLPPP, LINKTYPE_JUNIPER_MLPPP },
|
||||
{ DLT_JUNIPER_MLFR, LINKTYPE_JUNIPER_MLFR },
|
||||
{ DLT_JUNIPER_ES, LINKTYPE_JUNIPER_ES },
|
||||
{ DLT_JUNIPER_GGSN, LINKTYPE_JUNIPER_GGSN },
|
||||
{ DLT_JUNIPER_MFR, LINKTYPE_JUNIPER_MFR },
|
||||
{ DLT_JUNIPER_ATM2, LINKTYPE_JUNIPER_ATM2 },
|
||||
{ DLT_JUNIPER_SERVICES, LINKTYPE_JUNIPER_SERVICES },
|
||||
{ DLT_JUNIPER_ATM1, LINKTYPE_JUNIPER_ATM1 },
|
||||
|
||||
/* Apple IP-over-IEEE 1394 cooked header */
|
||||
{ DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 },
|
||||
|
||||
/* DOCSIS MAC frames */
|
||||
{ DLT_DOCSIS, LINKTYPE_DOCSIS },
|
||||
|
||||
/* IrDA IrLAP packets + Linux-cooked header */
|
||||
{ DLT_LINUX_IRDA, LINKTYPE_LINUX_IRDA },
|
||||
|
||||
/* IBM SP and Next Federation switches */
|
||||
{ DLT_IBM_SP, LINKTYPE_IBM_SP },
|
||||
{ DLT_IBM_SN, LINKTYPE_IBM_SN },
|
||||
|
||||
/* 802.11 plus AVS radio header */
|
||||
{ DLT_IEEE802_11_RADIO_AVS, LINKTYPE_IEEE802_11_RADIO_AVS },
|
||||
|
||||
/*
|
||||
* Any platform that defines additional DLT_* codes should:
|
||||
*
|
||||
* request a LINKTYPE_* code and value from tcpdump.org,
|
||||
* as per the above;
|
||||
*
|
||||
* add, in their version of libpcap, an entry to map
|
||||
* those DLT_* codes to the corresponding LINKTYPE_*
|
||||
* code;
|
||||
*
|
||||
* redefine, in their "net/bpf.h", any DLT_* values
|
||||
* that collide with the values used by their additional
|
||||
* DLT_* codes, to remove those collisions (but without
|
||||
* making them collide with any of the LINKTYPE_*
|
||||
* values equal to 50 or above; they should also avoid
|
||||
* defining DLT_* values that collide with those
|
||||
* LINKTYPE_* values, either).
|
||||
*/
|
||||
|
||||
/* Juniper-internal chassis encapsulation */
|
||||
{ DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR },
|
||||
|
||||
{ -1, -1 }
|
||||
};
|
||||
|
||||
static int
|
||||
dlt_to_linktype(int dlt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; map[i].dlt != -1; i++) {
|
||||
if (map[i].dlt == dlt)
|
||||
return (map[i].linktype);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we don't have a mapping for this DLT_ code, return an
|
||||
* error; that means that the table above needs to have an
|
||||
* entry added.
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
linktype_to_dlt(int linktype)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; map[i].linktype != -1; i++) {
|
||||
if (map[i].linktype == linktype)
|
||||
return (map[i].dlt);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we don't have an entry for this link type, return
|
||||
* the link type value; it may be a DLT_ value from an
|
||||
* older version of libpcap.
|
||||
*/
|
||||
return linktype;
|
||||
}
|
||||
|
||||
static int
|
||||
sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen)
|
||||
{
|
||||
@ -109,30 +563,68 @@ swap_hdr(struct pcap_file_header *hp)
|
||||
hp->linktype = SWAPLONG(hp->linktype);
|
||||
}
|
||||
|
||||
static int
|
||||
sf_getnonblock(pcap_t *p, char *errbuf)
|
||||
{
|
||||
/*
|
||||
* This is a savefile, not a live capture file, so never say
|
||||
* it's in non-blocking mode.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
sf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
{
|
||||
/*
|
||||
* This is a savefile, not a live capture file, so ignore
|
||||
* requests to put it in non-blocking mode.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
sf_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Statistics aren't available from savefiles");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
sf_close(pcap_t *p)
|
||||
{
|
||||
if (p->sf.rfile != stdin)
|
||||
(void)fclose(p->sf.rfile);
|
||||
if (p->sf.base != NULL)
|
||||
free(p->sf.base);
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_open_offline(char *fname, char *errbuf)
|
||||
pcap_open_offline(const char *fname, char *errbuf)
|
||||
{
|
||||
register pcap_t *p;
|
||||
register FILE *fp;
|
||||
struct pcap_file_header hdr;
|
||||
bpf_u_int32 magic;
|
||||
int linklen;
|
||||
|
||||
p = (pcap_t *)malloc(sizeof(*p));
|
||||
if (p == NULL) {
|
||||
(void)strncpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE - 1);
|
||||
strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
memset((char *)p, 0, sizeof(*p));
|
||||
/*
|
||||
* Set this field so we don't close stdin in pcap_close!
|
||||
*/
|
||||
p->fd = -1;
|
||||
|
||||
if (fname[0] == '-' && fname[1] == '\0')
|
||||
fp = stdin;
|
||||
else {
|
||||
#ifndef WIN32
|
||||
fp = fopen(fname, "r");
|
||||
#else
|
||||
fp = fopen(fname, "rb");
|
||||
#endif
|
||||
if (fp == NULL) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
|
||||
fname, pcap_strerror(errno));
|
||||
@ -144,8 +636,10 @@ pcap_open_offline(char *fname, char *errbuf)
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
if (hdr.magic != TCPDUMP_MAGIC) {
|
||||
if (SWAPLONG(hdr.magic) != TCPDUMP_MAGIC) {
|
||||
magic = hdr.magic;
|
||||
if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
|
||||
magic = SWAPLONG(magic);
|
||||
if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bad dump file format");
|
||||
goto bad;
|
||||
@ -153,16 +647,30 @@ pcap_open_offline(char *fname, char *errbuf)
|
||||
p->sf.swapped = 1;
|
||||
swap_hdr(&hdr);
|
||||
}
|
||||
p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr);
|
||||
if (magic == PATCHED_TCPDUMP_MAGIC) {
|
||||
/*
|
||||
* XXX - the patch that's in some versions of libpcap
|
||||
* changes the packet header but not the magic number;
|
||||
* we'd have to use some hacks^H^H^H^H^Hheuristics to
|
||||
* detect that.
|
||||
*/
|
||||
p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
|
||||
} else
|
||||
p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr);
|
||||
if (hdr.version_major < PCAP_VERSION_MAJOR) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format");
|
||||
goto bad;
|
||||
}
|
||||
p->tzoff = hdr.thiszone;
|
||||
p->snapshot = hdr.snaplen;
|
||||
p->linktype = hdr.linktype;
|
||||
p->linktype = linktype_to_dlt(hdr.linktype);
|
||||
p->sf.rfile = fp;
|
||||
#ifndef WIN32
|
||||
p->bufsize = hdr.snaplen;
|
||||
#else
|
||||
/* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */
|
||||
p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr);
|
||||
#endif
|
||||
|
||||
/* Align link header as required for proper data alignment */
|
||||
/* XXX should handle all types */
|
||||
@ -197,8 +705,59 @@ pcap_open_offline(char *fname, char *errbuf)
|
||||
pcap_fddipad = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We interchanged the caplen and len fields at version 2.3,
|
||||
* in order to match the bpf header layout. But unfortunately
|
||||
* some files were written with version 2.3 in their headers
|
||||
* but without the interchanged fields.
|
||||
*
|
||||
* In addition, DG/UX tcpdump writes out files with a version
|
||||
* number of 543.0, and with the caplen and len fields in the
|
||||
* pre-2.3 order.
|
||||
*/
|
||||
switch (hdr.version_major) {
|
||||
|
||||
case 2:
|
||||
if (hdr.version_minor < 3)
|
||||
p->sf.lengths_swapped = SWAPPED;
|
||||
else if (hdr.version_minor == 3)
|
||||
p->sf.lengths_swapped = MAYBE_SWAPPED;
|
||||
else
|
||||
p->sf.lengths_swapped = NOT_SWAPPED;
|
||||
break;
|
||||
|
||||
case 543:
|
||||
p->sf.lengths_swapped = SWAPPED;
|
||||
break;
|
||||
|
||||
default:
|
||||
p->sf.lengths_swapped = NOT_SWAPPED;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
/*
|
||||
* You can do "select()" and "poll()" on plain files on most
|
||||
* platforms, and should be able to do so on pipes.
|
||||
*
|
||||
* You can't do "select()" on anything other than sockets in
|
||||
* Windows, so, on Win32 systems, we don't have "selectable_fd".
|
||||
*/
|
||||
p->selectable_fd = fileno(fp);
|
||||
#endif
|
||||
|
||||
p->read_op = pcap_offline_read;
|
||||
p->setfilter_op = install_bpf_program;
|
||||
p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
|
||||
p->getnonblock_op = sf_getnonblock;
|
||||
p->setnonblock_op = sf_setnonblock;
|
||||
p->stats_op = sf_stats;
|
||||
p->close_op = sf_close;
|
||||
|
||||
return (p);
|
||||
bad:
|
||||
if(fp)
|
||||
fclose(fp);
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
@ -209,10 +768,12 @@ pcap_open_offline(char *fname, char *errbuf)
|
||||
* no more packets, and SFERR_TRUNC if a partial packet was encountered.
|
||||
*/
|
||||
static int
|
||||
sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
|
||||
sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen)
|
||||
{
|
||||
struct pcap_sf_pkthdr sf_hdr;
|
||||
struct pcap_sf_patched_pkthdr sf_hdr;
|
||||
FILE *fp = p->sf.rfile;
|
||||
size_t amt_read;
|
||||
bpf_u_int32 t;
|
||||
|
||||
/*
|
||||
* Read the packet header; the structure we use as a buffer
|
||||
@ -221,9 +782,23 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
|
||||
* unpatched libpcap we only read as many bytes as the regular
|
||||
* header has.
|
||||
*/
|
||||
if (fread(&sf_hdr, p->sf.hdrsize, 1, fp) != 1) {
|
||||
/* probably an EOF, though could be a truncated packet */
|
||||
return (1);
|
||||
amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp);
|
||||
if (amt_read != p->sf.hdrsize) {
|
||||
if (ferror(fp)) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"error reading dump file: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
} 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);
|
||||
return (-1);
|
||||
}
|
||||
/* EOF */
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (p->sf.swapped) {
|
||||
@ -238,17 +813,27 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
|
||||
hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
|
||||
hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
|
||||
}
|
||||
/*
|
||||
* We interchanged the caplen and len fields at version 2.3,
|
||||
* in order to match the bpf header layout. But unfortunately
|
||||
* some files were written with version 2.3 in their headers
|
||||
* but without the interchanged fields.
|
||||
*/
|
||||
if (p->sf.version_minor < 3 ||
|
||||
(p->sf.version_minor == 3 && hdr->caplen > hdr->len)) {
|
||||
int t = hdr->caplen;
|
||||
/* Swap the caplen and len fields, if necessary. */
|
||||
switch (p->sf.lengths_swapped) {
|
||||
|
||||
case NOT_SWAPPED:
|
||||
break;
|
||||
|
||||
case MAYBE_SWAPPED:
|
||||
if (hdr->caplen <= hdr->len) {
|
||||
/*
|
||||
* The captured length is <= the actual length,
|
||||
* so presumably they weren't swapped.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case SWAPPED:
|
||||
t = hdr->caplen;
|
||||
hdr->caplen = hdr->len;
|
||||
hdr->len = t;
|
||||
break;
|
||||
}
|
||||
|
||||
if (hdr->caplen > buflen) {
|
||||
@ -259,13 +844,14 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
|
||||
* grossly wrong, try to salvage.
|
||||
*/
|
||||
static u_char *tp = NULL;
|
||||
static int tsize = 0;
|
||||
static size_t tsize = 0;
|
||||
|
||||
if (hdr->caplen > 65535) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bogus savefile header");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (tsize < hdr->caplen) {
|
||||
tsize = ((hdr->caplen + 1023) / 1024) * 1024;
|
||||
if (tp != NULL)
|
||||
@ -278,9 +864,17 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
if (fread((char *)tp, hdr->caplen, 1, fp) != 1) {
|
||||
(void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file");
|
||||
amt_read = fread((char *)tp, 1, hdr->caplen, fp);
|
||||
if (amt_read != hdr->caplen) {
|
||||
if (ferror(fp)) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"error reading dump file: %s",
|
||||
pcap_strerror(errno));
|
||||
} else {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file; tried to read %u captured bytes, only got %lu",
|
||||
hdr->caplen, (unsigned long)amt_read);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
/*
|
||||
@ -295,9 +889,18 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
|
||||
|
||||
} else {
|
||||
/* read the packet itself */
|
||||
if (fread((char *)buf, hdr->caplen, 1, fp) != 1) {
|
||||
(void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file");
|
||||
amt_read = fread((char *)buf, 1, hdr->caplen, fp);
|
||||
if (amt_read != hdr->caplen) {
|
||||
if (ferror(fp)) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"error reading dump file: %s",
|
||||
pcap_strerror(errno));
|
||||
} else {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file; tried to read %u captured bytes, only got %lu",
|
||||
hdr->caplen, (unsigned long)amt_read);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
@ -317,6 +920,23 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
while (status == 0) {
|
||||
struct pcap_pkthdr h;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (p->break_loop) {
|
||||
if (n == 0) {
|
||||
p->break_loop = 0;
|
||||
return (-2);
|
||||
} else
|
||||
return (n);
|
||||
}
|
||||
|
||||
status = sf_next_packet(p, &h, p->buffer, p->bufsize);
|
||||
if (status) {
|
||||
if (status == 1)
|
||||
@ -358,23 +978,57 @@ pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
|
||||
* Initialize so that sf_write() will output to the file named 'fname'.
|
||||
*/
|
||||
pcap_dumper_t *
|
||||
pcap_dump_open(pcap_t *p, char *fname)
|
||||
pcap_dump_open(pcap_t *p, const char *fname)
|
||||
{
|
||||
FILE *f;
|
||||
if (fname[0] == '-' && fname[1] == '\0')
|
||||
int linktype;
|
||||
|
||||
linktype = dlt_to_linktype(p->linktype);
|
||||
if (linktype == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: link-layer type %d isn't supported in savefiles",
|
||||
fname, linktype);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (fname[0] == '-' && fname[1] == '\0') {
|
||||
f = stdout;
|
||||
else {
|
||||
#ifdef WIN32
|
||||
_setmode(_fileno(f), _O_BINARY);
|
||||
#endif
|
||||
} else {
|
||||
#ifndef WIN32
|
||||
f = fopen(fname, "w");
|
||||
#else
|
||||
f = fopen(fname, "wb");
|
||||
setbuf(f, NULL); /* XXX - why? */
|
||||
#endif
|
||||
if (f == NULL) {
|
||||
(void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
|
||||
fname, pcap_strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
(void)sf_write_header(f, p->linktype, p->tzoff, p->snapshot);
|
||||
(void)sf_write_header(f, linktype, p->tzoff, p->snapshot);
|
||||
return ((pcap_dumper_t *)f);
|
||||
}
|
||||
|
||||
FILE *
|
||||
pcap_dump_file(pcap_dumper_t *p)
|
||||
{
|
||||
return ((FILE *)p);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_dump_flush(pcap_dumper_t *p)
|
||||
{
|
||||
|
||||
if (fflush((FILE *)p) == EOF)
|
||||
return (-1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
pcap_dump_close(pcap_dumper_t *p)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
%{
|
||||
/* $NetBSD: scanner.l,v 1.16 2004/06/25 12:22:23 itojun Exp $ */
|
||||
/* $NetBSD: scanner.l,v 1.17 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
|
||||
@ -26,21 +26,39 @@
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static const char rcsid[] =
|
||||
"@(#) Header: scanner.l,v 1.56 97/07/21 13:31:50 leres Exp (LBL)";
|
||||
"@(#) Header: /tcpdump/master/libpcap/scanner.l,v 1.95.2.3 2004/03/28 21:45:33 fenner Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: scanner.l,v 1.16 2004/06/25 12:22:23 itojun Exp $");
|
||||
__RCSID("$NetBSD: scanner.l,v 1.17 2004/09/27 23:02:53 dyoung Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include "gencode.h"
|
||||
#ifdef INET6
|
||||
#ifdef WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include "IP6_misc.h"
|
||||
#endif
|
||||
#else /* WIN32 */
|
||||
#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */
|
||||
#include <netdb.h> /* for "struct addrinfo" */
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* Workaround for AIX 4.3 */
|
||||
#if !defined(AI_NUMERICHOST)
|
||||
#define AI_NUMERICHOST 0x04
|
||||
#endif
|
||||
#endif /*INET6*/
|
||||
#include <pcap-namedb.h>
|
||||
#ifdef INET6
|
||||
#include <netdb.h>
|
||||
@ -49,7 +67,6 @@ __RCSID("$NetBSD: scanner.l,v 1.16 2004/06/25 12:22:23 itojun Exp $");
|
||||
#endif /*INET6*/
|
||||
#include "grammar.h"
|
||||
|
||||
#include "gnuc.h"
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
@ -59,22 +76,10 @@ static inline int xdtoi(int);
|
||||
|
||||
#ifdef FLEX_SCANNER
|
||||
#define YY_NO_UNPUT
|
||||
#undef YY_INPUT
|
||||
#define YY_INPUT(buf, result, max)\
|
||||
{\
|
||||
char *src = in_buffer;\
|
||||
int i;\
|
||||
\
|
||||
if (*src == 0)\
|
||||
result = YY_NULL;\
|
||||
else {\
|
||||
for (i = 0; *src && i < max; ++i)\
|
||||
buf[i] = *src++;\
|
||||
in_buffer += i;\
|
||||
result = i;\
|
||||
}\
|
||||
}
|
||||
static YY_BUFFER_STATE in_buffer;
|
||||
#else
|
||||
static char *in_buffer;
|
||||
|
||||
#undef getc
|
||||
#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++)
|
||||
#endif
|
||||
@ -84,15 +89,18 @@ static inline int xdtoi(int);
|
||||
extern YYSTYPE yylval;
|
||||
#endif
|
||||
|
||||
static char *in_buffer;
|
||||
|
||||
%}
|
||||
|
||||
N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
|
||||
B ([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 3000
|
||||
%a 16000
|
||||
%o 19000
|
||||
%e 6000
|
||||
%k 4000
|
||||
%p 25000
|
||||
%n 2000
|
||||
|
||||
V680 {W}:{W}:{W}:{W}:{W}:{W}:{W}:{W}
|
||||
|
||||
@ -177,10 +185,11 @@ dst return DST;
|
||||
src return SRC;
|
||||
|
||||
link|ether|ppp|slip return LINK;
|
||||
fddi return LINK;
|
||||
fddi|tr|wlan return LINK;
|
||||
arp return ARP;
|
||||
rarp return RARP;
|
||||
ip return IP;
|
||||
sctp return SCTP;
|
||||
tcp return TCP;
|
||||
udp return UDP;
|
||||
icmp return ICMP;
|
||||
@ -189,21 +198,55 @@ igrp return IGRP;
|
||||
pim return PIM;
|
||||
vrrp return VRRP;
|
||||
|
||||
ip6 return IPV6;
|
||||
icmp6 return ICMPV6;
|
||||
ip6 {
|
||||
#ifdef INET6
|
||||
return IPV6;
|
||||
#else
|
||||
bpf_error("%s not supported", yytext);
|
||||
#endif
|
||||
}
|
||||
icmp6 {
|
||||
#ifdef INET6
|
||||
return ICMPV6;
|
||||
#else
|
||||
bpf_error("%s not supported", yytext);
|
||||
#endif
|
||||
}
|
||||
ah return AH;
|
||||
esp return ESP;
|
||||
|
||||
atalk return ATALK;
|
||||
aarp return AARP;
|
||||
decnet return DECNET;
|
||||
lat return LAT;
|
||||
sca return SCA;
|
||||
moprc return MOPRC;
|
||||
mopdl return MOPDL;
|
||||
|
||||
iso return ISO;
|
||||
esis return ESIS;
|
||||
es-is return ESIS;
|
||||
isis return ISIS;
|
||||
is-is return ISIS;
|
||||
l1 return L1;
|
||||
l2 return L2;
|
||||
iih return IIH;
|
||||
lsp return LSP;
|
||||
snp return SNP;
|
||||
csnp return CSNP;
|
||||
psnp return PSNP;
|
||||
|
||||
clnp return CLNP;
|
||||
|
||||
stp return STP;
|
||||
|
||||
ipx return IPX;
|
||||
|
||||
netbeui return NETBEUI;
|
||||
|
||||
host return HOST;
|
||||
net return NET;
|
||||
mask return MASK;
|
||||
mask return NETMASK;
|
||||
port return PORT;
|
||||
proto return PROTO;
|
||||
protochain {
|
||||
@ -218,7 +261,7 @@ gateway return GATEWAY;
|
||||
|
||||
less return LESS;
|
||||
greater return GREATER;
|
||||
byte return BYTE;
|
||||
byte return CBYTE;
|
||||
broadcast return TK_BROADCAST;
|
||||
multicast return TK_MULTICAST;
|
||||
|
||||
@ -229,8 +272,24 @@ not return '!';
|
||||
len|length return LEN;
|
||||
inbound return INBOUND;
|
||||
outbound return OUTBOUND;
|
||||
|
||||
vlan return VLAN;
|
||||
|
||||
lane return LANE;
|
||||
llc return LLC;
|
||||
metac return METAC;
|
||||
bcc return BCC;
|
||||
oam return OAM;
|
||||
oamf4 return OAMF4;
|
||||
oamf4ec return OAMF4EC;
|
||||
oamf4sc return OAMF4SC;
|
||||
sc return SC;
|
||||
ilmic return ILMIC;
|
||||
vpi return VPI;
|
||||
vci return VCI;
|
||||
connectmsg return CONNECTMSG;
|
||||
metaconnect return METACONNECT;
|
||||
|
||||
on|ifname return PF_IFNAME;
|
||||
rset|ruleset return PF_RSET;
|
||||
rnr|rulenum return PF_RNR;
|
||||
@ -238,7 +297,7 @@ srnr|subrulenum return PF_SRNR;
|
||||
reason return PF_REASON;
|
||||
action return PF_ACTION;
|
||||
|
||||
[ \n\t] ;
|
||||
[ \r\n\t] ;
|
||||
[+\-*/:\[\]!<>()&|=] return yytext[0];
|
||||
">=" return GEQ;
|
||||
"<=" return LEQ;
|
||||
@ -262,7 +321,7 @@ ${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1);
|
||||
if (getaddrinfo(yytext, NULL, &hints, &res))
|
||||
bpf_error("bogus IPv6 address %s", yytext);
|
||||
else {
|
||||
yylval.e = sdup((char *)yytext); return HID6;
|
||||
yylval.s = sdup((char *)yytext); return HID6;
|
||||
}
|
||||
#else
|
||||
bpf_error("IPv6 address %s not supported", yytext);
|
||||
@ -293,18 +352,35 @@ tcp-rst { yylval.i = 0x04; return NUM; }
|
||||
tcp-push { yylval.i = 0x08; return NUM; }
|
||||
tcp-ack { yylval.i = 0x10; return NUM; }
|
||||
tcp-urg { yylval.i = 0x20; return NUM; }
|
||||
[A-Za-z0-9][-_.A-Za-z0-9]*[.A-Za-z0-9] {
|
||||
[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? {
|
||||
yylval.s = sdup((char *)yytext); return ID; }
|
||||
"\\"[^ !()\n\t]+ { yylval.s = sdup((char *)yytext + 1); return ID; }
|
||||
[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+i {
|
||||
bpf_error("illegal token: %s\n", yytext); }
|
||||
[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+ {
|
||||
bpf_error("illegal token: %s", yytext); }
|
||||
. { bpf_error("illegal char '%c'", *yytext); }
|
||||
%%
|
||||
void
|
||||
lex_init(buf)
|
||||
char *buf;
|
||||
{
|
||||
#ifdef FLEX_SCANNER
|
||||
in_buffer = yy_scan_string(buf);
|
||||
#else
|
||||
in_buffer = buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Do any cleanup necessary after parsing.
|
||||
*/
|
||||
void
|
||||
lex_cleanup()
|
||||
{
|
||||
#ifdef FLEX_SCANNER
|
||||
if (in_buffer != NULL)
|
||||
yy_delete_buffer(in_buffer);
|
||||
in_buffer = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -356,4 +432,3 @@ stoi(s)
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
/* $NetBSD: version.c,v 1.3 2000/10/08 14:28:05 itojun Exp $ */
|
||||
char pcap_version[] = "0.4";
|
||||
/* $NetBSD: version.c,v 1.4 2004/09/27 23:02:53 dyoung Exp $ */
|
||||
char pcap_version[] = "0.8.3";
|
||||
|
Loading…
Reference in New Issue
Block a user