Resolve conflicts in libpcap-0.8.3 import.

Remove some extraneous files.
This commit is contained in:
dyoung 2004-09-27 23:02:53 +00:00
parent 64657f857f
commit c14b894413
27 changed files with 7207 additions and 1674 deletions

View File

@ -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.

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
{

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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; }
;
%%

View File

@ -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 */

View File

@ -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

View File

@ -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)

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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";