dect
/
libpcap
Archived
13
0
Fork 0

Initial revision

This commit is contained in:
mcr 1999-10-07 23:46:40 +00:00
commit b11ddf8a9b
53 changed files with 17241 additions and 0 deletions

267
CHANGES Normal file
View File

@ -0,0 +1,267 @@
@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.47 1999-10-07 23:46:40 mcr Exp $ (LBL)
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)
- Fix alignment problem with FDDI under DLPI. This was causing core
dumps under Solaris.
- Added configure options to disable flex and bison. Resulted from a
bug report by barnett@grymoire.crd.ge.com (Bruce Barnett). Also added
options to disable gcc and to force a particular packet capture type.
- Added support for Fore ATM interfaces (qaa and fa) under IRIX. Thanks
to John Hawkinson (jhawk@mit.edu)
- Change Linux PPP and SLIP to use DLT_RAW since the kernel does not
supply any "link layer" data.
- Change Linux to use SIOCGIFHWADDR ioctl to determine link layer type.
Thanks to Thomas Sailer (sailer@ife.ee.ethz.ch)
- Change IRIX PPP to use DLT_RAW since the kernel does not supply any
"link layer" data.
- Modified to support the new BSD/OS 2.1 PPP and SLIP link layer header
formats.
- Added some new SGI snoop interface types. Thanks to Steve Alexander
(sca@refugee.engr.sgi.com)
- Fixes for HP-UX 10.20 (which is similar to HP-UX 9). Thanks to
Richard Allen (ra@hp.is) and Steinar Haug (sthaug@nethelp.no)
- Fddi supports broadcast as reported by Jeff Macdonald
(jeff@iacnet.com). Also correct ieee802 and arcnet.
- Determine Linux pcap buffer size at run time or else it might not be
big enough for some interface types (e.g. FDDI). Thanks to Jes
Sorensen (Jes.Sorensen@cern.ch)
- Fix some linux alignment problems.
- Document promisc argument to pcap_open_live(). Reported by Ian Marsh
(ianm@sics.se)
- Support Metricom radio packets under Linux. Thanks to Kevin Lai
(laik@gunpowder.stanford.edu)
- Bind to interface name under Linux to avoid packets from multiple
interfaces on multi-homed hosts. Thanks to Kevin Lai
(laik@gunpowder.stanford.edu)
- Change L_SET to SEEK_SET for HP-UX. Thanks to Roland Roberts
(rroberts@muller.com)
- Fixed an uninitialized memory reference found by Kent Vander Velden
(graphix@iastate.edu)
- Fixed lex pattern for IDs to allow leading digits. As reported by
Theo de Raadt (deraadt@cvs.openbsd.org)
- Fixed Linux include file problems when using GNU libc.
- 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.
- Fixed savefile bugs.
- Solaris x86 fix from Tim Rylance (t.rylance@elsevier.nl)
- Add support for bpf kernel port filters.
- Remove duplicate atalk protocol table entry. Thanks to Christian
Hopps (chopps@water.emich.edu)
- Fixed pcap_lookupdev() to ignore nonexistent devices. This was
reported to happen under BSD/OS by David Vincenzetti
(vince@cryptonet.it)
- Avoid solaris compiler warnings. Thanks to Bruce Barnett
(barnett@grymoire.crd.ge.com)
v0.2.1 Sun Jul 14 03:02:26 PDT 1996
- Fixes for HP-UX 10. Thanks in part to to Thomas Wolfram
(wolf@prz.tu-berlin.de) and Rick Jones (raj@hpisrdq.cup.hp.com)
- Added support for SINIX. Thanks to Andrej Borsenkow
(borsenkow.msk@sni.de)
- Fixes for AIX (although this system is not yet supported). Thanks to
John Hawkinson (jhawk@mit.edu)
- Use autoconf's idea of the top level directory in install targets.
Thanks to John Hawkinson.
- Add missing autoconf packet capture result message. Thanks to Bill
Fenner (fenner@parc.xerox.com)
- Fixed padding problems in the pf module.
- Fixed some more alignment problems on the alpha.
- Added explicit netmask support. Thanks to Steve Nuchia
(steve@research.oknet.com)
- Fixed to handle raw ip addresses such as 0.0.0.1 without "left
justifing"
- Add "sca" keyword (for DEC cluster services) as suggested by Terry
Kennedy (terry@spcvxa.spc.edu)
- Add "atalk" keyword as suggested by John Hawkinson.
- Add "igrp" keyword.
- Fixed HID definition in grammar.y to be a string, not a value.
- Use $CC when checking gcc version. Thanks to Carl Lindberg
(carl_lindberg@blacksmith.com)
- Removed obsolete reference to pcap_immediate() from the man page.
Michael Stolarchuk (mts@terminator.rs.itd.umich.edu)
- DLT_NULL has a 4 byte family header. Thanks to Jeffrey Honig
(jch@bsdi.com)
v0.2 Sun Jun 23 02:28:42 PDT 1996
- Add support for HP-UX. Resulted from code contributed by Tom Murray
(tmurray@hpindck.cup.hp.com) and Philippe-Andri Prindeville
(philipp@res.enst.fr)
- Update INSTALL with a reminder to install include files. Thanks to
Mark Andrews (mandrews@aw.sgi.com)
- Fix bpf compiler alignment bug on the alpha.
- Use autoconf to detect architectures that can't handle misaligned
accesses.
- Added loopback support for snoop. Resulted from report Steve
Alexander (sca@engr.sgi.com)
v0.1 Fri Apr 28 18:11:03 PDT 1995
- Fixed compiler and optimizer bugs. The BPF filter engine uses unsigned
comparison operators, while the code generator and optimizer assumed
signed semantics in several places. Thanks to Charlie Slater
(cslater@imatek.com) for pointing this out.
- Removed FDDI ifdef's, they aren't really needed. Resulted from report
by Gary Veum (veum@boa.gsfc.nasa.gov).
- Add pcap-null.c which allows offline use of libpcap on systems that
don't support live package capture. This feature resulting from a
request from Jan van Oorschot (j.p.m.voorschot@et.tudelft.nl).
- Make bpf_compile() reentrant. Fix thanks to Pascal Hennequin
(Pascal.Hennequin@hugo.int-evry.fr).
- Port to GNU autoconf.
- Fix pcap-dlpi.c to work with isdn. Resulted from report by Flemming
Johansen (fsj@csd.cri.dk).
- Handle multi-digit interface unit numbers (aka ppa's) under dlpi.
Resulted from report by Daniel Ehrlich (ehrlich@cse.psu.edu).
- Fix pcap-dlpi.c to work in non-promiscuous mode. Resulted from report
by Jeff Murphy (jcmurphy@acsu.buffalo.edu).
- Add support for "long jumps". Thanks to Jeffrey Mogul
(mogul@pa.dec.com).
- Fix minor problems when compiling with BDEBUG as noticed by Scott
Bertilson (scott@unet.umn.edu).
- Declare sys_errlist "const char *const" to avoid problems under
FreeBSD. Resulted from report by jher@eden.com.
v0.0.6 Fri Apr 28 04:07:13 PDT 1995
- Add missing variable declaration missing from 0.0.6
v0.0.5 Fri Apr 28 00:22:21 PDT 1995
- Workaround for problems when pcap_read() returns 0 due to the timeout
expiring.
v0.0.4 Thu Apr 20 20:41:48 PDT 1995
- Change configuration to not use gcc v2 flags with gcc v1.
- Fixed a bug in pcap_next(); if pcap_dispatch() returns 0, pcap_next()
should also return 0. Thanks to Richard Stevens (rstevens@noao.edu).
- Fixed configure to test for snoop before dlpi to avoid problems under
IRIX 5. Thanks to J. Eric Townsend (jet@abulafia.genmagic.com).
- Hack around deficiency in Ultrix's make.
- Fix two bugs related to the Solaris pre-5.3.2 bufmod bug; handle
savefiles that have more than snapshot bytes of data in them (so we
can read old savefiles) and avoid writing such files.
- Added checkioctl which is used with gcc to check that the
"fixincludes" script has been run.
v0.0.3 Tue Oct 18 18:13:46 PDT 1994
- Fixed configure to test for snoop before dlpi to avoid problems under
IRIX 5. Thanks to J. Eric Townsend (jet@abulafia.genmagic.com).
v0.0.2 Wed Oct 12 20:56:37 PDT 1994
- Implement timeout in the dlpi pcap_open_live(). Thanks to Richard
Stevens.
- Determine pcap link type from dlpi media type. Resulted from report
by Mahesh Jethanandani (mahesh@npix.com).
v0.0.1 Fri Jun 24 14:50:57 PDT 1994
- Fixed bug in nit_setflags() in pcap-snit.c. The streams ioctl timeout
wasn't being initialized sometimes resulting in an "NIOCSFLAGS:
Invalid argument" error under OSF/1. Reported by Matt Day
(mday@artisoft.com) and Danny Mitzel (dmitzel@whitney.hitc.com).
- Turn on FDDI support by default.
v0.0 Mon Jun 20 19:20:16 PDT 1994
- Initial release.
- Fixed bug with greater/less keywords, reported by Mark Andrews
(mandrews@alias.com).
- Fix bug where '|' was defined as BPF_AND instead of BPF_OR, reported
by Elan Amir (elan@leeb.cs.berkeley.edu).
- Machines with little-endian byte ordering are supported thanks to
Jeff Mogul.
- Add hack for version 2.3 savefiles which don't have caplen and len
swapped thanks to Vern Paxson.
- Added "&&" and "||" aliases for "and" and "or" thanks to Vern Paxson.
- Added length, inbound and outbound keywords.

50
FILES Normal file
View File

@ -0,0 +1,50 @@
CHANGES
FILES
INSTALL
Makefile.in
README
SUNOS4
VERSION
aclocal.m4
bpf/net/bpf.h
bpf/net/bpf_filter.c
bpf_image.c
config.guess
config.sub
configure
configure.in
etherent.c
ethertype.h
gencode.c
gencode.h
grammar.y
inet.c
install-sh
lbl/gnuc.h
lbl/os-solaris2.h
lbl/os-sunos4.h
lbl/os-ultrix4.h
linux-include/netinet/if_ether.h
linux-include/netinet/ip_var.h
mkdep
nametoaddr.c
optimize.c
pcap-bpf.c
pcap-dlpi.c
pcap-enet.c
pcap-int.h
pcap-linux.c
pcap-namedb.h
pcap-nit.c
pcap-nit.h
pcap-null.c
pcap-pf.c
pcap-pf.h
pcap-snit.c
pcap-snoop.c
pcap.3
pcap.c
pcap.h
ppp.h
savefile.c
scanner.l

328
INSTALL Normal file
View File

@ -0,0 +1,328 @@
@(#) $Header: /tcpdump/master/libpcap/Attic/INSTALL,v 1.42 1999-10-07 23:46:40 mcr Exp $ (LBL)
To build libpcap, first customize any paths in Makefile.in, then run
"./configure" (a shell script). The configure script will determine
your system attributes and generate an appropriate Makefile from
Makefile.in. Next run "make". If everything goes well you can su to
root and run "make install", "make install-incl" and "make
install-man". However, you need not install libpcap if you just want to
build tcpdump; just make sure the tcpdump and libpcap directory trees
have the same parent directory.
If configure says:
configure: warning: cannot determine packet capture interface
configure: warning: (see INSTALL for more info)
then your system either does not support packet capture or your system
does support packet capture but libpcap does not support that
particular type. (If you have HP-UX, see below.) If your system uses a
packet capture not supported by libpcap, please send us patches; don't
forget to include an autoconf fragment suitable for use in
configure.in.
It is possible to override the default packet capture type, although
the circumstance where this works are limited. For example if you have
installed bpf under SunOS 4 and wish to build a snit libpcap:
./configure --with-pcap=snit
Another example is to force a supported packet capture type in the case
where the configure scripts fails to detect it.
You will need an ANSI C compiler to build libpcap. The configure script
will abort if your compiler is not ANSI compliant. If this happens, use
the GNU C compiler, available via anonymous ftp:
ftp://prep.ai.mit.edu/pub/gnu/gcc-*.tar.gz
Note well: If you use gcc, you may need to run its "fixincludes"
script. Running fixincludes is not required with later versions of gcc
and in some cases (e.g. Solaris 2.5) causes problems when run. The
configure script will abort with:
checking for ANSI ioctl definitions... yes
configure: error: see the INSTALL for more info
if it detects if the fixincludes needs to be run. If the fixincludes
test in configure passes, you're probably ok.
If you use flex, you must use version 2.4.6 or higher. The configure
script automatically detects the version of flex and will not use it
unless it is new enough. You can use "flex -V" to see what version you
have (unless it's really old). The current version of flex is available
via anonymous ftp:
ftp://ftp.ee.lbl.gov/flex-*.tar.Z
As of this writing, the current version is 2.5.4.
If you use bison, you must use flex (and visa versa). The configure
script automatically falls back to lex and yacc if both flex and bison
are not found.
Sometimes the stock C compiler does not interact well with flex and
bison. The list of problems includes undefined references for alloca.
You can get around this by installing gcc or manually disabling flex
and bison with:
./configure --without-flex --without-bison
If your system only has AT&T lex, this is okay unless your libpcap
program uses other lex/yacc generated code. (Although it's possible to
map the yy* identifiers with a script, we use flex and bison so we
don't feel this is necessary.)
Some systems support the Berkeley Packet Filter natively; for example
out of the box OSF and BSD/OS have bpf. If your system does not support
bpf, you will need to pick up:
ftp://ftp.ee.lbl.gov/bpf-*.tar.Z
Note well: you MUST have kernel source for your operating system in
order to install bpf. An exception is SunOS 4; the bpf distribution
includes replacement kernel objects for some of the standard SunOS 4
network device drivers. See the bpf INSTALL document for more
information.
If you use Solaris, there is a bug with bufmod(7) that is fixed in
Solaris 2.3.2 (aka SunOS 5.3.2). Setting a snapshot length with the
broken bufmod(7) results in data be truncated from the FRONT of the
packet instead of the end. The work around is to not set a snapshot
length but this results in performance problems since the entire packet
is copied to user space. If you must run an older version of Solaris,
there is a patch available from Sun; ask for bugid 1149065. After
installing the patch, use "setenv BUFMOD_FIXED" to enable use of
bufmod(7). However, we recommend you run a more current release of
Solaris.
If you use the SPARCompiler, you must be careful to not use the
/usr/ucb/cc interface. If you do, you will get bogus warnings and
perhaps errors. Either make sure your path has /opt/SUNWspro/bin
before /usr/ucb or else:
setenv CC /opt/SUNWspro/bin/cc
before running configure. (You might have to do a "make distclean"
if you already ran configure once).
Also note that "make depend" won't work; while all of the known
universe uses -M, the SPARCompiler uses -xM to generate makefile
dependencies.
If you are trying to do packet capture with a FORE ATM card, you may or
may not be able to. They usually only release their driver in object
code so unless their driver supports packet capture, there's not much
libpcap can do.
If you get an error like:
tcpdump: recv_ack: bind error 0x???
when using DLPI, look for the DL_ERROR_ACK error return values, usually
in /usr/include/sys/dlpi.h, and find the corresponding value.
Under OSF, packet capture must be enabled before it can be used. For
instructions on how to enable packet filter support, see:
ftp://ftp.digital.com/pub/Digital/dec-faq/Digital-UNIX
Once you enable packet filter support, your OSF system will support bpf
natively.
Under Ultrix, packet capture must be enabled before it can be used. For
instructions on how to enable packet filter support, see:
ftp://ftp.digital.com/pub/Digital/dec-faq/ultrix
If you use HP-UX, you must have at least version 9 and either the
version of cc that supports ANSI C (cc -Aa) or else use the GNU C
compiler. You must also buy the optional streams package. If you don't
have:
/usr/include/sys/dlpi.h
/usr/include/sys/dlpi_ext.h
then you don't have the streams package. In addition, we believe you
need to install the "9.X LAN and DLPI drivers cumulative" patch
(PHNE_6855) to make the version 9 DLPI work with libpcap.
It's been reported that the DLPI streams package is standard starting
with HP-UX 10.
The HP implementation of DLPI is a little bit eccentric. Unlike
Solaris, you must attach /dev/dlpi instead of the specific /dev/*
network pseudo device entry in order to capture packets. The ppa is
based on the ifnet "index" number. Under HP-UX 9, it is necessary to
read /dev/kmem and the kernel symbol file (/hp-ux). Under HP-UX 10,
dlpi can provide information for determining the ppa. It does not seem
to be possible to trace the loopback interface. Unlike other DLPI
implementations, PHYS implies MULTI and SAP and you get an error if you
try to enable more than one promiscous more than one promiscuous mode
at a time. Finally, testing shows that there can't be more than one
simultaneous dlpi user per network interface and you cannot capture
outbound packets.
If you use Linux, this version of libpcap is known to compile and run
under Red Hat 4.0 with the 2.0.25 kernel. It may work with earlier 2.X
versions but is guaranteed not to work with 1.X kernels. Running more
than one libpcap program at a time can cause problems since promiscuous
mode is implemented by twiddlin the interface flags from the libpcap
application. Also, packet timestamps aren't very good. This appears to
be due to haphazard handling of the timestamp in the kernel.
Note well: there is rumoured to be a version of tcpdump floating around
called 3.0.3 that includes libpcap and is supposed to support Linux.
You should be advised that the Network Research Group at LBNL never
generated a release with this version number. We note with interest
that a standard cracker trick to get people to install trojans is to
distribute bogus packages that have a version number higher than the
current release. We also note with annoyance that 90% of the Linux
related bug reports we get are due to changes made to unofficial
versions of our page. If you are having trouble but aren't using a
version that came from ftp.ee.lbl.gov, please try that before
submitting a bug report!
If you use AIX, you may not be able to build libpcap from this release.
Although AIX 4 ships with tcpdump, it is an old version that predates
libpcap. We do not have an AIX system in house so it's impossible for
us to test AIX patches submitted to us. We are told that you must link
against /lib/pse.exp, that you must use AIX cc or a GNU C compiler
newer than 2.7.2 and that you may need to run strload before running a
libpcap application. Also, it may be necessary to run the configure
script as root in order for it to detect that bpf is available. Another
workaround is to use:
./configure --with-pcap=bpf
If you use NeXTSTEP, you will not be able to build libpcap from this
release. We hope to support this operating system in some future
release of libpcap.
If you use SINIX, you should be able to build libpcap from this
release. It is known to compile and run on SINIX-Y/N 5.42 with the C-DS
V1.0 or V1.1 compiler. But note that in some releases of SINIX, yacc
emits incorrect code; if grammar.y fails to compile, change every
occurence of:
#ifdef YYDEBUG
to:
#if YYDEBUG
Another workaround is to use flex and bison.
If you use SCO, you might have trouble building libpcap from this
release. We do not have a machine running SCO and have not had reports
of anyone successfully building on it. Since SCO apparently supports
dlpi, it's possible the current version works. Meanwhile, sco provides
a tcpdump binary as part of their "Network/Security Tools" package:
http://www.sco.com/technology/internet/goodies/#SECURITY
There is also a README that explains how to enable packet capture.
If you use UnixWare, you will not be able to build libpcap from this
release. We hope to support this operating system in some future
release of libpcap. Meanwhile, there appears to be an UnixWare port of
libpcap 0.0 (and tcpdump 3.0) in:
ftp://ftp1.freebird.org/pub/mirror/freebird/internet/systools/
UnixWare appears to use a hacked version of DLPI.
If linking tcpdump fails with "Undefined: _alloca" when using bison on
a Sun4, your version of bison is broken. In any case version 1.16 or
higher is recommended (1.14 is known to cause problems 1.16 is known to
work). Either pick up a current version from:
ftp://prep.ai.mit.edu/pub/gnu/bison.tar.gz
or hack around it by inserting the lines:
#ifdef __GNUC__
#define alloca __builtin_alloca
#else
#ifdef sparc
#include <alloca.h>
#else
char *alloca ();
#endif
#endif
right after the (100 line!) GNU license comment in bison.simple, remove
grammar.[co] and fire up make again.
If you use SunOS 4, your kernel must support streams NIT. If you run a
libpcap program and it dies with:
/dev/nit: No such device
You must add streams NIT support to your kernel configuration, run
config and boot the new kernel.
If you are running a version of SunOS earlier than 4.1, you will need
to replace the Sun supplied /sys/sun{3,4,4c}/OBJ/nit_if.o with the
appropriate version from this distribution's SUNOS4 subdirectory and
build a new kernel:
nit_if.o.sun3-sunos4 (any flavor of sun3)
nit_if.o.sun4c-sunos4.0.3c (SS1, SS1+, IPC, SLC, etc.)
nit_if.o.sun4-sunos4 (Sun4's not covered by
nit_if.o.sun4c-sunos4.0.3c)
These nit replacements fix a bug that makes nit essentially unusable in
pre-SunOS 4.1. In addition, our sun4c-sunos4.0.3c nit gives you
timestamps to the resolution of the SS-1 clock (1 us) rather than the
lousy 20ms timestamps Sun gives you (tcpdump will print out the full
timestamp resolution if it finds it's running on a SS-1).
FILES
-----
CHANGES - description of differences between releases
FILES - list of files exported as part of the distribution
INSTALL - this file
Makefile.in - compilation rules (input to the configure script)
README - description of distribution
SUNOS4 - pre-SunOS 4.1 replacement kernel nit modules
VERSION - version of this release
aclocal.m4 - autoconf macros
bpf/net - copies of bpf_filter.c and bpf.h
bpf_filter.c - symlink to bpf/net/bpf_filter.c
bpf_image.c - bpf disassembly routine
config.guess - autoconf support
config.sub - autoconf support
configure - configure script (run this first)
configure.in - configure script source
etherent.c - /etc/ethers support routines
ethertype.h - ethernet protocol types and names definitions
gencode.c - bpf code generation routines
gencode.h - bpf code generation definitions
grammar.y - filter string grammar
inet.c - network routines
install-sh - BSD style install script
lbl/gnuc.h - gcc macros and defines
lbl/os-*.h - os dependent defines and prototypes
linux-include/* - network include files missing on Linux
mkdep - construct Makefile dependency list
nametoaddr.c - hostname to address routines
net - symlink to bpf/net
optimize.c - bpf optimization routines
pcap-bpf.c - BSD Packet Filter support
pcap-dlpi.c - Data Link Provider Interface support
pcap-enet.c - enet support
pcap-int.h - internal libpcap definitions
pcap-namedb.h - public libpcap name database definitions
pcap-nit.c - Network Interface Tap support
pcap-nit.h - Network Interface Tap definitions
pcap-null.c - dummy monitor support (allows offline use of libpcap)
pcap-pf.c - Packet Filter support
pcap-pf.h - Packet Filter definitions
pcap-snit.c - Streams based Network Interface Tap support
pcap-snoop.c - Snoop network monitoring support
pcap.3 - manual entry
pcap.c - pcap utility routines
pcap.h - public libpcap definitions
ppp.h - Point to Point Protocol definitions
savefile.c - offline support
scanner.l - filter string scanner

163
Makefile.in Normal file
View File

@ -0,0 +1,163 @@
# Copyright (c) 1993, 1994, 1995, 1996
# The Regents of the University of California. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that: (1) source code distributions
# retain the above copyright notice and this paragraph in its entirety, (2)
# distributions including binary code include the above copyright notice and
# this paragraph in its entirety in the documentation or other materials
# provided with the distribution, and (3) all advertising materials mentioning
# features or use of this software display the following acknowledgement:
# ``This product includes software developed by the University of California,
# Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
# the University nor the names of its contributors may be used to endorse
# or promote products derived from this software without specific prior
# written permission.
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.72 1999-10-07 23:46:40 mcr Exp $ (LBL)
#
# Various configurable paths (remember to edit Makefile.in, not Makefile)
#
# Top level hierarchy
prefix = @prefix@
exec_prefix = @exec_prefix@
# Pathname of directory to install the include files
INCLDEST = @includedir@
# Pathname of directory to install the library
LIBDEST = @libdir@
# Pathname of directory to install the man page
MANDEST = @mandir@
# VPATH
srcdir = @srcdir@
VPATH = @srcdir@
#
# You shouldn't need to edit anything below.
#
CC = @CC@
CCOPT = @V_CCOPT@
INCLS = -I. @V_INCLS@
DEFS = @DEFS@
# Standard CFLAGS
CFLAGS = $(CCOPT) $(INCLS) $(DEFS)
INSTALL = @INSTALL@
RANLIB = @V_RANLIB@
#
# Flex and bison allow you to specify the prefixes of the global symbols
# used by the generated parser. This allows programs to use lex/yacc
# and link against libpcap. If you don't have flex or bison, get them.
#
LEX = @V_LEX@
YACC = @V_YACC@
# Explicitly define compilation rule since SunOS 4's make doesn't like gcc.
# Also, gcc does not remove the .o before forking 'as', which can be a
# problem if you don't own the file but can write to the directory.
.c.o:
@rm -f $@
$(CC) $(CFLAGS) -c $(srcdir)/$*.c
PSRC = pcap-@V_PCAP@.c
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \
etherent.c savefile.c bpf_filter.c bpf_image.c
GENSRC = scanner.c grammar.c version.c
SRC = $(PSRC) $(CSRC) $(GENSRC)
# We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot
# hack the extra indirection
OBJ = $(PSRC:.c=.o) $(CSRC:.c=.o) $(GENSRC:.c=.o)
HDR = pcap.h pcap-int.h pcap-namedb.h pcap-nit.h pcap-pf.h \
ethertype.h gencode.h gnuc.h
GENHDR = \
tokdefs.h
TAGHDR = \
bpf/net/bpf.h
TAGFILES = \
$(SRC) $(HDR) $(TAGHDR)
CLEANFILES = $(OBJ) libpcap.a $(GENSRC) $(GENHDR) lex.yy.c
all: libpcap.a
libpcap.a: $(OBJ)
@rm -f $@
ar rc $@ $(OBJ)
$(RANLIB) $@
scanner.c: $(srcdir)/scanner.l
@rm -f $@
$(LEX) -t $< > $$$$.$@; mv $$$$.$@ $@
scanner.o: scanner.c tokdefs.h
tokdefs.h: grammar.c
grammar.c: $(srcdir)/grammar.y
@rm -f grammar.c tokdefs.h
$(YACC) -d $<
mv y.tab.c grammar.c
mv y.tab.h tokdefs.h
grammar.o: grammar.c
@rm -f $@
$(CC) $(CFLAGS) -Dyylval=pcap_lval -c grammar.c
version.o: version.c
version.c: $(srcdir)/VERSION
@rm -f $@
sed -e 's/.*/char pcap_version[] = "&";/' $(srcdir)/VERSION > $@
install: force
$(INSTALL) -m 444 -o bin -g bin libpcap.a $(DESTDIR)$(LIBDEST)/libpcap.a
$(RANLIB) $(DESTDIR)$(LIBDEST)/libpcap.a
install-incl: force
$(INSTALL) -m 444 -o bin -g bin $(srcdir)/pcap.h \
$(DESTDIR)$(INCLDEST)/pcap.h
$(INSTALL) -m 444 -o bin -g bin $(srcdir)/pcap-namedb.h \
$(DESTDIR)$(INCLDEST)/pcap-namedb.h
$(INSTALL) -m 444 -o bin -g bin $(srcdir)/net/bpf.h \
$(DESTDIR)$(INCLDEST)/net/bpf.h
install-man: force
$(INSTALL) -m 444 -o bin -g bin $(srcdir)/pcap.3 \
$(DESTDIR)$(MANDEST)/man3/pcap.3
clean:
rm -f $(CLEANFILES)
distclean:
rm -f $(CLEANFILES) Makefile config.cache config.log config.status \
gnuc.h os-proto.h bpf_filter.c net
tags: $(TAGFILES)
ctags -wtd $(TAGFILES)
tar: force
@cwd=`pwd` ; dir=`basename $$cwd` ; name=libpcap-`cat VERSION` ; \
list="" ; tar="tar chFFf" ; \
for i in `cat FILES` ; do list="$$list $$name/$$i" ; done; \
echo \
"rm -f ../$$name; ln -s $$dir ../$$name" ; \
rm -f ../$$name; ln -s $$dir ../$$name ; \
echo \
"(cd .. ; $$tar - [lots of files]) | compress > /tmp/$$name.tar.Z" ; \
(cd .. ; $$tar - $$list) | compress > /tmp/$$name.tar.Z ; \
echo \
"rm -f ../$$name" ; \
rm -f ../$$name
force: /tmp
depend: $(GENSRC) force
./mkdep -c $(CC) $(DEFS) $(INCLS) $(SRC)

49
README Normal file
View File

@ -0,0 +1,49 @@
@(#) $Header: /tcpdump/master/libpcap/README,v 1.18 1999-10-07 23:46:40 mcr Exp $ (LBL)
LIBPCAP 0.4
Lawrence Berkeley National Laboratory
Network Research Group
libpcap@ee.lbl.gov
ftp://ftp.ee.lbl.gov/libpcap.tar.Z
This directory contains source code for libpcap, a system-independent
interface for user-level packet capture. libpcap provides a portable
framework for low-level network monitoring. Applications include
network statistics collection, security monitoring, network debugging,
etc. Since almost every system vendor provides a different interface
for packet capture, and since we've developed several tools that
require this functionality, we've created this system-independent API
to ease in porting and to alleviate the need for several
system-dependent packet capture modules in each application.
Note well: this interface is new and is likely to change.
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:
ftp://ftp.ee.lbl.gov/papers/bpf-usenix93.ps.Z.
Although most packet capture interfaces support in-kernel filtering,
libpcap utilizes in-kernel filtering only for the BPF interface.
On systems that don't have BPF, all packets are read into user-space
and the BPF filters are evaluated in the libpcap library, incurring
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 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".
- Steve McCanne
Craig Leres
Van Jacobson

BIN
SUNOS4/nit_if.o.sparc Normal file

Binary file not shown.

BIN
SUNOS4/nit_if.o.sun3 Normal file

Binary file not shown.

Binary file not shown.

1
VERSION Normal file
View File

@ -0,0 +1 @@
0.4

706
aclocal.m4 vendored Normal file
View File

@ -0,0 +1,706 @@
dnl @(#) $Header: /tcpdump/master/libpcap/aclocal.m4,v 1.63 1999-10-07 23:46:40 mcr Exp $ (LBL)
dnl
dnl Copyright (c) 1995, 1996, 1997, 1998
dnl The Regents of the University of California. All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that: (1) source code distributions
dnl retain the above copyright notice and this paragraph in its entirety, (2)
dnl distributions including binary code include the above copyright notice and
dnl this paragraph in its entirety in the documentation or other materials
dnl provided with the distribution, and (3) all advertising materials mentioning
dnl features or use of this software display the following acknowledgement:
dnl ``This product includes software developed by the University of California,
dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
dnl the University nor the names of its contributors may be used to endorse
dnl or promote products derived from this software without specific prior
dnl written permission.
dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
dnl
dnl LBL autoconf macros
dnl
dnl
dnl Determine which compiler we're using (cc or gcc)
dnl If using gcc, determine the version number
dnl If using cc, require that it support ansi prototypes
dnl If using gcc, use -O2 (otherwise use -O)
dnl If using cc, explicitly specify /usr/local/include
dnl
dnl usage:
dnl
dnl AC_LBL_C_INIT(copt, incls)
dnl
dnl results:
dnl
dnl $1 (copt set)
dnl $2 (incls set)
dnl CC
dnl LDFLAGS
dnl ac_cv_lbl_gcc_vers
dnl LBL_CFLAGS
dnl
AC_DEFUN(AC_LBL_C_INIT,
[AC_PREREQ(2.12)
AC_BEFORE([$0], [AC_PROG_CC])
AC_BEFORE([$0], [AC_LBL_FIXINCLUDES])
AC_BEFORE([$0], [AC_LBL_DEVEL])
AC_ARG_WITH(gcc, [ --without-gcc don't use gcc])
$1="-O"
$2=""
if test "${srcdir}" != "." ; then
$2="-I\$\(srcdir\)"
fi
if test "${CFLAGS+set}" = set; then
LBL_CFLAGS="$CFLAGS"
fi
if test -z "$CC" ; then
case "$target_os" in
bsdi*)
AC_CHECK_PROG(SHLICC2, shlicc2, yes, no)
if test $SHLICC2 = yes ; then
CC=shlicc2
export CC
fi
;;
esac
fi
if test -z "$CC" -a "$with_gcc" = no ; then
CC=cc
export CC
fi
AC_PROG_CC
if test "$GCC" = yes ; then
if test "$SHLICC2" = yes ; then
ac_cv_lbl_gcc_vers=2
$1="-O2"
else
AC_MSG_CHECKING(gcc version)
AC_CACHE_VAL(ac_cv_lbl_gcc_vers,
ac_cv_lbl_gcc_vers=`$CC -v 2>&1 | \
sed -e '/^gcc version /!d' \
-e 's/^gcc version //' \
-e 's/ .*//' -e 's/^[[[^0-9]]]*//' \
-e 's/\..*//'`)
AC_MSG_RESULT($ac_cv_lbl_gcc_vers)
if test $ac_cv_lbl_gcc_vers -gt 1 ; then
$1="-O2"
fi
fi
else
AC_MSG_CHECKING(that $CC handles ansi prototypes)
AC_CACHE_VAL(ac_cv_lbl_cc_ansi_prototypes,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[int frob(int, char *)],
ac_cv_lbl_cc_ansi_prototypes=yes,
ac_cv_lbl_cc_ansi_prototypes=no))
AC_MSG_RESULT($ac_cv_lbl_cc_ansi_prototypes)
if test $ac_cv_lbl_cc_ansi_prototypes = no ; then
case "$target_os" in
hpux*)
AC_MSG_CHECKING(for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE))
savedcflags="$CFLAGS"
CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS"
AC_CACHE_VAL(ac_cv_lbl_cc_hpux_cc_aa,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[int frob(int, char *)],
ac_cv_lbl_cc_hpux_cc_aa=yes,
ac_cv_lbl_cc_hpux_cc_aa=no))
AC_MSG_RESULT($ac_cv_lbl_cc_hpux_cc_aa)
if test $ac_cv_lbl_cc_hpux_cc_aa = no ; then
AC_MSG_ERROR(see the INSTALL doc for more info)
fi
CFLAGS="$savedcflags"
V_CCOPT="-Aa $V_CCOPT"
AC_DEFINE(_HPUX_SOURCE)
;;
*)
AC_MSG_ERROR(see the INSTALL doc for more info)
;;
esac
fi
$2="$$2 -I/usr/local/include"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
case "$target_os" in
irix*)
V_CCOPT="$V_CCOPT -xansi -signed -g3"
;;
osf*)
V_CCOPT="$V_CCOPT -std1 -g3"
;;
ultrix*)
AC_MSG_CHECKING(that Ultrix $CC hacks const in prototypes)
AC_CACHE_VAL(ac_cv_lbl_cc_const_proto,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[struct a { int b; };
void c(const struct a *)],
ac_cv_lbl_cc_const_proto=yes,
ac_cv_lbl_cc_const_proto=no))
AC_MSG_RESULT($ac_cv_lbl_cc_const_proto)
if test $ac_cv_lbl_cc_const_proto = no ; then
AC_DEFINE(const,)
fi
;;
esac
fi
])
dnl
dnl Use pfopen.c if available and pfopen() not in standard libraries
dnl Require libpcap
dnl Look for libpcap in ..
dnl Use the installed libpcap if there is no local version
dnl
dnl usage:
dnl
dnl AC_LBL_LIBPCAP(pcapdep, incls)
dnl
dnl results:
dnl
dnl $1 (pcapdep set)
dnl $2 (incls appended)
dnl LIBS
dnl LBL_LIBS
dnl
AC_DEFUN(AC_LBL_LIBPCAP,
[AC_REQUIRE([AC_LBL_LIBRARY_NET])
dnl
dnl save a copy before locating libpcap.a
dnl
LBL_LIBS="$LIBS"
pfopen=/usr/examples/packetfilter/pfopen.c
if test -f $pfopen ; then
AC_CHECK_FUNCS(pfopen)
if test $ac_cv_func_pfopen = "no" ; then
AC_MSG_RESULT(Using $pfopen)
LIBS="$LIBS $pfopen"
fi
fi
AC_MSG_CHECKING(for local pcap library)
libpcap=FAIL
lastdir=FAIL
places=`ls .. | sed -e 's,/$,,' -e 's,^,../,' | \
egrep '/libpcap-[[0-9]]*\.[[0-9]]*(\.[[0-9]]*)?([[ab]][[0-9]]*)?$'`
for dir in $places ../libpcap libpcap ; do
basedir=`echo $dir | sed -e 's/[[ab]][[0-9]]*$//'`
if test $lastdir = $basedir ; then
dnl skip alphas when an actual release is present
continue;
fi
lastdir=$dir
if test -r $dir/pcap.c ; then
libpcap=$dir/libpcap.a
d=$dir
dnl continue and select the last one that exists
fi
done
if test $libpcap = FAIL ; then
AC_MSG_RESULT(not found)
AC_CHECK_LIB(pcap, main, libpcap="-lpcap")
if test $libpcap = FAIL ; then
AC_MSG_ERROR(see the INSTALL doc for more info)
fi
else
$1=$libpcap
$2="-I$d $$2"
AC_MSG_RESULT($libpcap)
fi
LIBS="$libpcap $LIBS"
case "$target_os" in
aix*)
pseexe="/lib/pse.exp"
AC_MSG_CHECKING(for $pseexe)
if test -f $pseexe ; then
AC_MSG_RESULT(yes)
LIBS="$LIBS -I:$pseexe"
fi
;;
esac])
dnl
dnl Define RETSIGTYPE and RETSIGVAL
dnl
dnl usage:
dnl
dnl AC_LBL_TYPE_SIGNAL
dnl
dnl results:
dnl
dnl RETSIGTYPE (defined)
dnl RETSIGVAL (defined)
dnl
AC_DEFUN(AC_LBL_TYPE_SIGNAL,
[AC_BEFORE([$0], [AC_LBL_LIBPCAP])
AC_TYPE_SIGNAL
if test "$ac_cv_type_signal" = void ; then
AC_DEFINE(RETSIGVAL,)
else
AC_DEFINE(RETSIGVAL,(0))
fi
case "$target_os" in
irix*)
AC_DEFINE(_BSD_SIGNALS)
;;
*)
dnl prefer sigset() to sigaction()
AC_CHECK_FUNCS(sigset)
if test $ac_cv_func_sigset = no ; then
AC_CHECK_FUNCS(sigaction)
fi
;;
esac])
dnl
dnl If using gcc, make sure we have ANSI ioctl definitions
dnl
dnl usage:
dnl
dnl AC_LBL_FIXINCLUDES
dnl
AC_DEFUN(AC_LBL_FIXINCLUDES,
[if test "$GCC" = yes ; then
AC_MSG_CHECKING(for ANSI ioctl definitions)
AC_CACHE_VAL(ac_cv_lbl_gcc_fixincludes,
AC_TRY_COMPILE(
[/*
* This generates a "duplicate case value" when fixincludes
* has not be run.
*/
# include <sys/types.h>
# include <sys/time.h>
# include <sys/ioctl.h>
# ifdef HAVE_SYS_IOCCOM_H
# include <sys/ioccom.h>
# endif],
[switch (0) {
case _IO('A', 1):;
case _IO('B', 1):;
}],
ac_cv_lbl_gcc_fixincludes=yes,
ac_cv_lbl_gcc_fixincludes=no))
AC_MSG_RESULT($ac_cv_lbl_gcc_fixincludes)
if test $ac_cv_lbl_gcc_fixincludes = no ; then
# Don't cache failure
unset ac_cv_lbl_gcc_fixincludes
AC_MSG_ERROR(see the INSTALL for more info)
fi
fi])
dnl
dnl Check for flex, default to lex
dnl Require flex 2.4 or higher
dnl Check for bison, default to yacc
dnl Default to lex/yacc if both flex and bison are not available
dnl Define the yy prefix string if using flex and bison
dnl
dnl usage:
dnl
dnl AC_LBL_LEX_AND_YACC(lex, yacc, yyprefix)
dnl
dnl results:
dnl
dnl $1 (lex set)
dnl $2 (yacc appended)
dnl $3 (optional flex and bison -P prefix)
dnl
AC_DEFUN(AC_LBL_LEX_AND_YACC,
[AC_ARG_WITH(flex, [ --without-flex don't use flex])
AC_ARG_WITH(bison, [ --without-bison don't use bison])
if test "$with_flex" = no ; then
$1=lex
else
AC_CHECK_PROGS($1, flex, lex)
fi
if test "$$1" = flex ; then
# The -V flag was added in 2.4
AC_MSG_CHECKING(for flex 2.4 or higher)
AC_CACHE_VAL(ac_cv_lbl_flex_v24,
if flex -V >/dev/null 2>&1; then
ac_cv_lbl_flex_v24=yes
else
ac_cv_lbl_flex_v24=no
fi)
AC_MSG_RESULT($ac_cv_lbl_flex_v24)
if test $ac_cv_lbl_flex_v24 = no ; then
s="2.4 or higher required"
AC_MSG_WARN(ignoring obsolete flex executable ($s))
$1=lex
fi
fi
if test "$with_bison" = no ; then
$2=yacc
else
AC_CHECK_PROGS($2, bison, yacc)
fi
if test "$$2" = bison ; then
$2="$$2 -y"
fi
if test "$$1" != lex -a "$$2" = yacc -o "$$1" = lex -a "$$2" != yacc ; then
AC_MSG_WARN(don't have both flex and bison; reverting to lex/yacc)
$1=lex
$2=yacc
fi
if test "$$1" = flex -a -n "$3" ; then
$1="$$1 -P$3"
$2="$$2 -p $3"
fi])
dnl
dnl Checks to see if union wait is used with WEXITSTATUS()
dnl
dnl usage:
dnl
dnl AC_LBL_UNION_WAIT
dnl
dnl results:
dnl
dnl DECLWAITSTATUS (defined)
dnl
AC_DEFUN(AC_LBL_UNION_WAIT,
[AC_MSG_CHECKING(if union wait is used)
AC_CACHE_VAL(ac_cv_lbl_union_wait,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/wait.h>],
[int status;
u_int i = WEXITSTATUS(status);
u_int j = waitpid(0, &status, 0);],
ac_cv_lbl_union_wait=no,
ac_cv_lbl_union_wait=yes))
AC_MSG_RESULT($ac_cv_lbl_union_wait)
if test $ac_cv_lbl_union_wait = yes ; then
AC_DEFINE(DECLWAITSTATUS,union wait)
else
AC_DEFINE(DECLWAITSTATUS,int)
fi])
dnl
dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member
dnl
dnl usage:
dnl
dnl AC_LBL_SOCKADDR_SA_LEN
dnl
dnl results:
dnl
dnl HAVE_SOCKADDR_SA_LEN (defined)
dnl
AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN,
[AC_MSG_CHECKING(if sockaddr struct has sa_len member)
AC_CACHE_VAL(ac_cv_lbl_sockaddr_has_sa_len,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/socket.h>],
[u_int i = sizeof(((struct sockaddr *)0)->sa_len)],
ac_cv_lbl_sockaddr_has_sa_len=yes,
ac_cv_lbl_sockaddr_has_sa_len=no))
AC_MSG_RESULT($ac_cv_lbl_sockaddr_has_sa_len)
if test $ac_cv_lbl_sockaddr_has_sa_len = yes ; then
AC_DEFINE(HAVE_SOCKADDR_SA_LEN)
fi])
dnl
dnl Checks to see if -R is used
dnl
dnl usage:
dnl
dnl AC_LBL_HAVE_RUN_PATH
dnl
dnl results:
dnl
dnl ac_cv_lbl_have_run_path (yes or no)
dnl
AC_DEFUN(AC_LBL_HAVE_RUN_PATH,
[AC_MSG_CHECKING(for ${CC-cc} -R)
AC_CACHE_VAL(ac_cv_lbl_have_run_path,
[echo 'main(){}' > conftest.c
${CC-cc} -o conftest conftest.c -R/a1/b2/c3 >conftest.out 2>&1
if test ! -s conftest.out ; then
ac_cv_lbl_have_run_path=yes
else
ac_cv_lbl_have_run_path=no
fi
rm -f conftest*])
AC_MSG_RESULT($ac_cv_lbl_have_run_path)
])
dnl
dnl Due to the stupid way it's implemented, AC_CHECK_TYPE is nearly useless.
dnl
dnl usage:
dnl
dnl AC_LBL_CHECK_TYPE
dnl
dnl results:
dnl
dnl int32_t (defined)
dnl u_int32_t (defined)
dnl
AC_DEFUN(AC_LBL_CHECK_TYPE,
[AC_MSG_CHECKING(for $1 using $CC)
AC_CACHE_VAL(ac_cv_lbl_have_$1,
AC_TRY_COMPILE([
# include "confdefs.h"
# include <sys/types.h>
# if STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
# endif],
[$1 i],
ac_cv_lbl_have_$1=yes,
ac_cv_lbl_have_$1=no))
AC_MSG_RESULT($ac_cv_lbl_have_$1)
if test $ac_cv_lbl_have_$1 = no ; then
AC_DEFINE($1, $2)
fi])
dnl
dnl Checks to see if unaligned memory accesses fail
dnl
dnl usage:
dnl
dnl AC_LBL_UNALIGNED_ACCESS
dnl
dnl results:
dnl
dnl LBL_ALIGN (DEFINED)
dnl
AC_DEFUN(AC_LBL_UNALIGNED_ACCESS,
[AC_MSG_CHECKING(if unaligned accesses fail)
AC_CACHE_VAL(ac_cv_lbl_unaligned_fail,
[case "$target_cpu" in
alpha|hp*|mips|sparc)
ac_cv_lbl_unaligned_fail=yes
;;
*)
cat >conftest.c <<EOF
# include <sys/types.h>
# include <sys/wait.h>
# include <stdio.h>
unsigned char a[[5]] = { 1, 2, 3, 4, 5 };
main() {
unsigned int i;
pid_t pid;
int status;
/* avoid "core dumped" message */
pid = fork();
if (pid < 0)
exit(2);
if (pid > 0) {
/* parent */
pid = waitpid(pid, &status, 0);
if (pid < 0)
exit(3);
exit(!WIFEXITED(status));
}
/* child */
i = *(unsigned int *)&a[[1]];
printf("%d\n", i);
exit(0);
}
EOF
${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \
conftest.c $LIBS >/dev/null 2>&1
if test ! -x conftest ; then
dnl failed to compile for some reason
ac_cv_lbl_unaligned_fail=yes
else
./conftest >conftest.out
if test ! -s conftest.out ; then
ac_cv_lbl_unaligned_fail=yes
else
ac_cv_lbl_unaligned_fail=no
fi
fi
rm -f conftest* core core.conftest
;;
esac])
AC_MSG_RESULT($ac_cv_lbl_unaligned_fail)
if test $ac_cv_lbl_unaligned_fail = yes ; then
AC_DEFINE(LBL_ALIGN)
fi])
dnl
dnl If using gcc and the file .devel exists:
dnl Compile with -g (if supported) and -Wall
dnl If using gcc 2, do extra prototype checking
dnl If an os prototype include exists, symlink os-proto.h to it
dnl
dnl usage:
dnl
dnl AC_LBL_DEVEL(copt)
dnl
dnl results:
dnl
dnl $1 (copt appended)
dnl HAVE_OS_PROTO_H (defined)
dnl os-proto.h (symlinked)
dnl
AC_DEFUN(AC_LBL_DEVEL,
[rm -f os-proto.h
if test "${LBL_CFLAGS+set}" = set; then
$1="$$1 ${LBL_CFLAGS}"
fi
if test -f .devel ; then
if test "$GCC" = yes ; then
if test "${LBL_CFLAGS+set}" != set; then
if test "$ac_cv_prog_cc_g" = yes ; then
$1="-g $$1"
fi
$1="$$1 -Wall"
if test $ac_cv_lbl_gcc_vers -gt 1 ; then
$1="$$1 -Wmissing-prototypes -Wstrict-prototypes"
fi
fi
else
case "$target_os" in
irix6*)
V_CCOPT="$V_CCOPT -n32"
;;
*)
;;
esac
fi
os=`echo $target_os | sed -e 's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'`
name="lbl/os-$os.h"
if test -f $name ; then
ln -s $name os-proto.h
AC_DEFINE(HAVE_OS_PROTO_H)
else
AC_MSG_WARN(can't find $name)
fi
fi])
dnl
dnl Improved version of AC_CHECK_LIB
dnl
dnl Thanks to John Hawkinson (jhawk@mit.edu)
dnl
dnl usage:
dnl
dnl AC_LBL_CHECK_LIB(LIBRARY, FUNCTION [, ACTION-IF-FOUND [,
dnl ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
dnl
dnl results:
dnl
dnl LIBS
dnl
define(AC_LBL_CHECK_LIB,
[AC_MSG_CHECKING([for $2 in -l$1])
dnl Use a cache variable name containing both the library and function name,
dnl because the test really is for library $1 defining function $2, not
dnl just for library $1. Separate tests with the same $1 and different $2's
dnl may have different results.
ac_lib_var=`echo $1['_']$2['_']$5 | sed 'y%./+- %__p__%'`
AC_CACHE_VAL(ac_cv_lbl_lib_$ac_lib_var,
[ac_save_LIBS="$LIBS"
LIBS="-l$1 $5 $LIBS"
AC_TRY_LINK(dnl
ifelse([$2], [main], , dnl Avoid conflicting decl of main.
[/* Override any gcc2 internal prototype to avoid an error. */
]ifelse(AC_LANG, CPLUSPLUS, [#ifdef __cplusplus
extern "C"
#endif
])dnl
[/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char $2();
]),
[$2()],
eval "ac_cv_lbl_lib_$ac_lib_var=yes",
eval "ac_cv_lbl_lib_$ac_lib_var=no")
LIBS="$ac_save_LIBS"
])dnl
if eval "test \"`echo '$ac_cv_lbl_lib_'$ac_lib_var`\" = yes"; then
AC_MSG_RESULT(yes)
ifelse([$3], ,
[changequote(, )dnl
ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
changequote([, ])dnl
AC_DEFINE_UNQUOTED($ac_tr_lib)
LIBS="-l$1 $LIBS"
], [$3])
else
AC_MSG_RESULT(no)
ifelse([$4], , , [$4
])dnl
fi
])
dnl
dnl AC_LBL_LIBRARY_NET
dnl
dnl This test is for network applications that need socket() and
dnl gethostbyname() -ish functions. Under Solaris, those applications
dnl need to link with "-lsocket -lnsl". Under IRIX, they need to link
dnl with "-lnsl" but should *not* link with "-lsocket" because
dnl libsocket.a breaks a number of things (for instance:
dnl gethostbyname() under IRIX 5.2, and snoop sockets under most
dnl versions of IRIX).
dnl
dnl Unfortunately, many application developers are not aware of this,
dnl and mistakenly write tests that cause -lsocket to be used under
dnl IRIX. It is also easy to write tests that cause -lnsl to be used
dnl under operating systems where neither are necessary (or useful),
dnl such as SunOS 4.1.4, which uses -lnsl for TLI.
dnl
dnl This test exists so that every application developer does not test
dnl this in a different, and subtly broken fashion.
dnl It has been argued that this test should be broken up into two
dnl seperate tests, one for the resolver libraries, and one for the
dnl libraries necessary for using Sockets API. Unfortunately, the two
dnl are carefully intertwined and allowing the autoconf user to use
dnl them independantly potentially results in unfortunate ordering
dnl dependancies -- as such, such component macros would have to
dnl carefully use indirection and be aware if the other components were
dnl executed. Since other autoconf macros do not go to this trouble,
dnl and almost no applications use sockets without the resolver, this
dnl complexity has not been implemented.
dnl
dnl The check for libresolv is in case you are attempting to link
dnl statically and happen to have a libresolv.a lying around (and no
dnl libnsl.a).
dnl
AC_DEFUN(AC_LBL_LIBRARY_NET, [
# Most operating systems have gethostbyname() in the default searched
# libraries (i.e. libc):
AC_CHECK_FUNC(gethostbyname, ,
# Some OSes (eg. Solaris) place it in libnsl:
AC_LBL_CHECK_LIB(nsl, gethostbyname, ,
# Some strange OSes (SINIX) have it in libsocket:
AC_LBL_CHECK_LIB(socket, gethostbyname, ,
# Unfortunately libsocket sometimes depends on libnsl.
# AC_CHECK_LIB's API is essentially broken so the
# following ugliness is necessary:
AC_LBL_CHECK_LIB(socket, gethostbyname,
LIBS="-lsocket -lnsl $LIBS",
AC_CHECK_LIB(resolv, gethostbyname),
-lnsl))))
AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket, ,
AC_LBL_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", ,
-lnsl)))
# DLPI needs putmsg under HPUX so test for -lstr while we're at it
AC_CHECK_LIB(str, putmsg)
])

264
bpf/net/bpf.h Normal file
View File

@ -0,0 +1,264 @@
/*-
* 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/bpf/net/Attic/bpf.h,v 1.36 1999-10-07 23:46:41 mcr Exp $ (LBL)
*/
#ifndef BPF_MAJOR_VERSION
/* 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.
*/
#define BPF_ALIGNMENT sizeof(bpf_int32)
#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 BIOCSETF.
*/
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;
};
/*
* Struct returned by BIOCGSTATS.
*/
struct bpf_stat {
u_int bs_recv; /* number of packets received */
u_int bs_drop; /* number of packets dropped */
};
/*
* 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
/*
* BPF ioctls
*
* The first set is for compatibility with Sun's pcc style
* header files. If your using gcc, we assume that you
* have run fixincludes so the latter set should work.
*/
#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
#define BIOCGBLEN _IOR(B,102, u_int)
#define BIOCSBLEN _IOWR(B,102, u_int)
#define BIOCSETF _IOW(B,103, struct bpf_program)
#define BIOCFLUSH _IO(B,104)
#define BIOCPROMISC _IO(B,105)
#define BIOCGDLT _IOR(B,106, u_int)
#define BIOCGETIF _IOR(B,107, struct ifreq)
#define BIOCSETIF _IOW(B,108, struct ifreq)
#define BIOCSRTIMEOUT _IOW(B,109, struct timeval)
#define BIOCGRTIMEOUT _IOR(B,110, struct timeval)
#define BIOCGSTATS _IOR(B,111, struct bpf_stat)
#define BIOCIMMEDIATE _IOW(B,112, u_int)
#define BIOCVERSION _IOR(B,113, struct bpf_version)
#define BIOCSTCPF _IOW(B,114, struct bpf_program)
#define BIOCSUDPF _IOW(B,115, struct bpf_program)
#else
#define BIOCGBLEN _IOR('B',102, u_int)
#define BIOCSBLEN _IOWR('B',102, u_int)
#define BIOCSETF _IOW('B',103, struct bpf_program)
#define BIOCFLUSH _IO('B',104)
#define BIOCPROMISC _IO('B',105)
#define BIOCGDLT _IOR('B',106, u_int)
#define BIOCGETIF _IOR('B',107, struct ifreq)
#define BIOCSETIF _IOW('B',108, struct ifreq)
#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
#define BIOCGRTIMEOUT _IOR('B',110, struct timeval)
#define BIOCGSTATS _IOR('B',111, struct bpf_stat)
#define BIOCIMMEDIATE _IOW('B',112, u_int)
#define BIOCVERSION _IOR('B',113, struct bpf_version)
#define BIOCSTCPF _IOW('B',114, struct bpf_program)
#define BIOCSUDPF _IOW('B',115, struct bpf_program)
#endif
/*
* Structure prepended to each packet.
*/
struct bpf_hdr {
struct timeval bh_tstamp; /* time stamp */
bpf_u_int32 bh_caplen; /* length of captured portion */
bpf_u_int32 bh_datalen; /* original length of packet */
u_short bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
};
/*
* Because the structure above is not a multiple of 4 bytes, some compilers
* will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
* Only the kernel needs to know about it; applications use bh_hdrlen.
*/
#ifdef KERNEL
#define SIZEOF_BPF_HDR 18
#endif
/*
* Data-link level type codes.
*/
#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 */
#define DLT_SLIP 8 /* Serial Line IP */
#define DLT_PPP 9 /* Point-to-point Protocol */
#define DLT_FDDI 10 /* FDDI */
#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
#define DLT_RAW 12 /* raw IP */
#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
/*
* The instruction encondings.
*/
/* 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 }
#ifdef KERNEL
extern u_int bpf_filter();
extern void bpfattach();
extern void bpf_tap();
extern void bpf_mtap();
#else
#if __STDC__
extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
#endif
#endif
/*
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
*/
#define BPF_MEMWORDS 16
#endif

532
bpf/net/bpf_filter.c Normal file
View File

@ -0,0 +1,532 @@
/*-
* 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.c 7.5 (Berkeley) 7/15/91
*/
#if !(defined(lint) || defined(KERNEL))
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.33 1999-10-07 23:46:41 mcr Exp $ (LBL)";
#endif
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>
#include <net/bpf.h>
#ifndef KERNEL
#include <stdlib.h>
#endif
#define int32 bpf_int32
#define u_int32 bpf_u_int32
#ifndef LBL_ALIGN
#if defined(sparc) || defined(mips) || defined(ibm032) || \
defined(__alpha) || defined(__hpux)
#define LBL_ALIGN
#endif
#endif
#ifndef LBL_ALIGN
#include <netinet/in.h>
#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p))
#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p))
#else
#define EXTRACT_SHORT(p)\
((u_short)\
((u_short)*((u_char *)p+0)<<8|\
(u_short)*((u_char *)p+1)<<0))
#define EXTRACT_LONG(p)\
((u_int32)*((u_char *)p+0)<<24|\
(u_int32)*((u_char *)p+1)<<16|\
(u_int32)*((u_char *)p+2)<<8|\
(u_int32)*((u_char *)p+3)<<0)
#endif
#ifdef KERNEL
#include <sys/mbuf.h>
#define MINDEX(len, m, k) \
{ \
len = m->m_len; \
while (k >= len) { \
k -= len; \
m = m->m_next; \
if (m == 0) \
return 0; \
len = m->m_len; \
} \
}
static int
m_xword(m, k, err)
register struct mbuf *m;
register int k, *err;
{
register int len;
register u_char *cp, *np;
register struct mbuf *m0;
MINDEX(len, m, k);
cp = mtod(m, u_char *) + k;
if (len - k >= 4) {
*err = 0;
return EXTRACT_LONG(cp);
}
m0 = m->m_next;
if (m0 == 0 || m0->m_len + len - k < 4)
goto bad;
*err = 0;
np = mtod(m0, u_char *);
switch (len - k) {
case 1:
return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2];
case 2:
return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1];
default:
return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0];
}
bad:
*err = 1;
return 0;
}
static int
m_xhalf(m, k, err)
register struct mbuf *m;
register int k, *err;
{
register int len;
register u_char *cp;
register struct mbuf *m0;
MINDEX(len, m, k);
cp = mtod(m, u_char *) + k;
if (len - k >= 2) {
*err = 0;
return EXTRACT_SHORT(cp);
}
m0 = m->m_next;
if (m0 == 0)
goto bad;
*err = 0;
return (cp[0] << 8) | mtod(m0, u_char *)[0];
bad:
*err = 1;
return 0;
}
#endif
/*
* Execute the filter program starting at pc on the packet p
* wirelen is the length of the original packet
* buflen is the amount of data present
*/
u_int
bpf_filter(pc, p, wirelen, buflen)
register struct bpf_insn *pc;
register u_char *p;
u_int wirelen;
register u_int buflen;
{
register u_int32 A, X;
register int k;
int32 mem[BPF_MEMWORDS];
if (pc == 0)
/*
* No filter means accept all.
*/
return (u_int)-1;
A = 0;
X = 0;
--pc;
while (1) {
++pc;
switch (pc->code) {
default:
#ifdef KERNEL
return 0;
#else
abort();
#endif
case BPF_RET|BPF_K:
return (u_int)pc->k;
case BPF_RET|BPF_A:
return (u_int)A;
case BPF_LD|BPF_W|BPF_ABS:
k = pc->k;
if (k + sizeof(int32) > buflen) {
#ifdef KERNEL
int merr;
if (buflen != 0)
return 0;
A = m_xword((struct mbuf *)p, k, &merr);
if (merr != 0)
return 0;
continue;
#else
return 0;
#endif
}
A = EXTRACT_LONG(&p[k]);
continue;
case BPF_LD|BPF_H|BPF_ABS:
k = pc->k;
if (k + sizeof(short) > buflen) {
#ifdef KERNEL
int merr;
if (buflen != 0)
return 0;
A = m_xhalf((struct mbuf *)p, k, &merr);
continue;
#else
return 0;
#endif
}
A = EXTRACT_SHORT(&p[k]);
continue;
case BPF_LD|BPF_B|BPF_ABS:
k = pc->k;
if (k >= buflen) {
#ifdef KERNEL
register struct mbuf *m;
register int len;
if (buflen != 0)
return 0;
m = (struct mbuf *)p;
MINDEX(len, m, k);
A = mtod(m, u_char *)[k];
continue;
#else
return 0;
#endif
}
A = p[k];
continue;
case BPF_LD|BPF_W|BPF_LEN:
A = wirelen;
continue;
case BPF_LDX|BPF_W|BPF_LEN:
X = wirelen;
continue;
case BPF_LD|BPF_W|BPF_IND:
k = X + pc->k;
if (k + sizeof(int32) > buflen) {
#ifdef KERNEL
int merr;
if (buflen != 0)
return 0;
A = m_xword((struct mbuf *)p, k, &merr);
if (merr != 0)
return 0;
continue;
#else
return 0;
#endif
}
A = EXTRACT_LONG(&p[k]);
continue;
case BPF_LD|BPF_H|BPF_IND:
k = X + pc->k;
if (k + sizeof(short) > buflen) {
#ifdef KERNEL
int merr;
if (buflen != 0)
return 0;
A = m_xhalf((struct mbuf *)p, k, &merr);
if (merr != 0)
return 0;
continue;
#else
return 0;
#endif
}
A = EXTRACT_SHORT(&p[k]);
continue;
case BPF_LD|BPF_B|BPF_IND:
k = X + pc->k;
if (k >= buflen) {
#ifdef KERNEL
register struct mbuf *m;
register int len;
if (buflen != 0)
return 0;
m = (struct mbuf *)p;
MINDEX(len, m, k);
A = mtod(m, u_char *)[k];
continue;
#else
return 0;
#endif
}
A = p[k];
continue;
case BPF_LDX|BPF_MSH|BPF_B:
k = pc->k;
if (k >= buflen) {
#ifdef KERNEL
register struct mbuf *m;
register int len;
if (buflen != 0)
return 0;
m = (struct mbuf *)p;
MINDEX(len, m, k);
X = (mtod(m, char *)[k] & 0xf) << 2;
continue;
#else
return 0;
#endif
}
X = (p[pc->k] & 0xf) << 2;
continue;
case BPF_LD|BPF_IMM:
A = pc->k;
continue;
case BPF_LDX|BPF_IMM:
X = pc->k;
continue;
case BPF_LD|BPF_MEM:
A = mem[pc->k];
continue;
case BPF_LDX|BPF_MEM:
X = mem[pc->k];
continue;
case BPF_ST:
mem[pc->k] = A;
continue;
case BPF_STX:
mem[pc->k] = X;
continue;
case BPF_JMP|BPF_JA:
pc += pc->k;
continue;
case BPF_JMP|BPF_JGT|BPF_K:
pc += (A > pc->k) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JGE|BPF_K:
pc += (A >= pc->k) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JEQ|BPF_K:
pc += (A == pc->k) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JSET|BPF_K:
pc += (A & pc->k) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JGT|BPF_X:
pc += (A > X) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JGE|BPF_X:
pc += (A >= X) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JEQ|BPF_X:
pc += (A == X) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JSET|BPF_X:
pc += (A & X) ? pc->jt : pc->jf;
continue;
case BPF_ALU|BPF_ADD|BPF_X:
A += X;
continue;
case BPF_ALU|BPF_SUB|BPF_X:
A -= X;
continue;
case BPF_ALU|BPF_MUL|BPF_X:
A *= X;
continue;
case BPF_ALU|BPF_DIV|BPF_X:
if (X == 0)
return 0;
A /= X;
continue;
case BPF_ALU|BPF_AND|BPF_X:
A &= X;
continue;
case BPF_ALU|BPF_OR|BPF_X:
A |= X;
continue;
case BPF_ALU|BPF_LSH|BPF_X:
A <<= X;
continue;
case BPF_ALU|BPF_RSH|BPF_X:
A >>= X;
continue;
case BPF_ALU|BPF_ADD|BPF_K:
A += pc->k;
continue;
case BPF_ALU|BPF_SUB|BPF_K:
A -= pc->k;
continue;
case BPF_ALU|BPF_MUL|BPF_K:
A *= pc->k;
continue;
case BPF_ALU|BPF_DIV|BPF_K:
A /= pc->k;
continue;
case BPF_ALU|BPF_AND|BPF_K:
A &= pc->k;
continue;
case BPF_ALU|BPF_OR|BPF_K:
A |= pc->k;
continue;
case BPF_ALU|BPF_LSH|BPF_K:
A <<= pc->k;
continue;
case BPF_ALU|BPF_RSH|BPF_K:
A >>= pc->k;
continue;
case BPF_ALU|BPF_NEG:
A = -A;
continue;
case BPF_MISC|BPF_TAX:
X = A;
continue;
case BPF_MISC|BPF_TXA:
A = X;
continue;
}
}
}
#ifdef KERNEL
/*
* Return true if the 'fcode' is a valid filter program.
* The constraints are that each jump be forward and to a valid
* code. The code must terminate with either an accept or reject.
* 'valid' is an array for use by the routine (it must be at least
* 'len' bytes long).
*
* The kernel needs to be able to verify an application's filter code.
* Otherwise, a bogus program could easily crash the system.
*/
int
bpf_validate(f, len)
struct bpf_insn *f;
int len;
{
register int i;
register struct bpf_insn *p;
for (i = 0; i < len; ++i) {
/*
* Check that that jumps are forward, and within
* the code block.
*/
p = &f[i];
if (BPF_CLASS(p->code) == BPF_JMP) {
register int from = i + 1;
if (BPF_OP(p->code) == BPF_JA) {
if (from + p->k >= (unsigned)len)
return 0;
}
else if (from + p->jt >= len || from + p->jf >= len)
return 0;
}
/*
* Check that memory operations use valid addresses.
*/
if ((BPF_CLASS(p->code) == BPF_ST ||
(BPF_CLASS(p->code) == BPF_LD &&
(p->code & 0xe0) == BPF_MEM)) &&
(p->k >= BPF_MEMWORDS || p->k < 0))
return 0;
/*
* Check for constant division by 0.
*/
if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
return 0;
}
return BPF_CLASS(f[len - 1].code) == BPF_RET;
}
#endif

65
bpf_dump.c Normal file
View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 1992, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.9 1999-10-07 23:47:09 mcr Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <pcap.h>
#include <stdio.h>
#include "interface.h"
extern void bpf_dump(struct bpf_program *, int);
void
bpf_dump(struct bpf_program *p, int option)
{
struct bpf_insn *insn;
int i;
int n = p->bf_len;
insn = p->bf_insns;
if (option > 2) {
printf("%d\n", n);
for (i = 0; i < n; ++insn, ++i) {
printf("%u %u %u %u\n", insn->code,
insn->jt, insn->jf, insn->k);
}
return ;
}
if (option > 1) {
for (i = 0; i < n; ++insn, ++i)
printf("{ 0x%x, %d, %d, 0x%08x },\n",
insn->code, insn->jt, insn->jf, insn->k);
return;
}
for (i = 0; i < n; ++insn, ++i) {
#ifdef BDEBUG
extern int bids[];
printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1);
#endif
puts(bpf_image(insn, i));
}
}

288
bpf_image.c Normal file
View File

@ -0,0 +1,288 @@
/*
* Copyright (c) 1990, 1991, 1992, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.22 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
char *
bpf_image(p, n)
struct bpf_insn *p;
int n;
{
int v;
char *fmt, *op;
static char image[256];
char operand[64];
v = p->k;
switch (p->code) {
default:
op = "unimp";
fmt = "0x%x";
v = p->code;
break;
case BPF_RET|BPF_K:
op = "ret";
fmt = "#%d";
break;
case BPF_RET|BPF_A:
op = "ret";
fmt = "";
break;
case BPF_LD|BPF_W|BPF_ABS:
op = "ld";
fmt = "[%d]";
break;
case BPF_LD|BPF_H|BPF_ABS:
op = "ldh";
fmt = "[%d]";
break;
case BPF_LD|BPF_B|BPF_ABS:
op = "ldb";
fmt = "[%d]";
break;
case BPF_LD|BPF_W|BPF_LEN:
op = "ld";
fmt = "#pktlen";
break;
case BPF_LD|BPF_W|BPF_IND:
op = "ld";
fmt = "[x + %d]";
break;
case BPF_LD|BPF_H|BPF_IND:
op = "ldh";
fmt = "[x + %d]";
break;
case BPF_LD|BPF_B|BPF_IND:
op = "ldb";
fmt = "[x + %d]";
break;
case BPF_LD|BPF_IMM:
op = "ld";
fmt = "#0x%x";
break;
case BPF_LDX|BPF_IMM:
op = "ldx";
fmt = "#0x%x";
break;
case BPF_LDX|BPF_MSH|BPF_B:
op = "ldxb";
fmt = "4*([%d]&0xf)";
break;
case BPF_LD|BPF_MEM:
op = "ld";
fmt = "M[%d]";
break;
case BPF_LDX|BPF_MEM:
op = "ldx";
fmt = "M[%d]";
break;
case BPF_ST:
op = "st";
fmt = "M[%d]";
break;
case BPF_STX:
op = "stx";
fmt = "M[%d]";
break;
case BPF_JMP|BPF_JA:
op = "ja";
fmt = "%d";
v = n + 1 + p->k;
break;
case BPF_JMP|BPF_JGT|BPF_K:
op = "jgt";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JGE|BPF_K:
op = "jge";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JEQ|BPF_K:
op = "jeq";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JSET|BPF_K:
op = "jset";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JGT|BPF_X:
op = "jgt";
fmt = "x";
break;
case BPF_JMP|BPF_JGE|BPF_X:
op = "jge";
fmt = "x";
break;
case BPF_JMP|BPF_JEQ|BPF_X:
op = "jeq";
fmt = "x";
break;
case BPF_JMP|BPF_JSET|BPF_X:
op = "jset";
fmt = "x";
break;
case BPF_ALU|BPF_ADD|BPF_X:
op = "add";
fmt = "x";
break;
case BPF_ALU|BPF_SUB|BPF_X:
op = "sub";
fmt = "x";
break;
case BPF_ALU|BPF_MUL|BPF_X:
op = "mul";
fmt = "x";
break;
case BPF_ALU|BPF_DIV|BPF_X:
op = "div";
fmt = "x";
break;
case BPF_ALU|BPF_AND|BPF_X:
op = "and";
fmt = "x";
break;
case BPF_ALU|BPF_OR|BPF_X:
op = "or";
fmt = "x";
break;
case BPF_ALU|BPF_LSH|BPF_X:
op = "lsh";
fmt = "x";
break;
case BPF_ALU|BPF_RSH|BPF_X:
op = "rsh";
fmt = "x";
break;
case BPF_ALU|BPF_ADD|BPF_K:
op = "add";
fmt = "#%d";
break;
case BPF_ALU|BPF_SUB|BPF_K:
op = "sub";
fmt = "#%d";
break;
case BPF_ALU|BPF_MUL|BPF_K:
op = "mul";
fmt = "#%d";
break;
case BPF_ALU|BPF_DIV|BPF_K:
op = "div";
fmt = "#%d";
break;
case BPF_ALU|BPF_AND|BPF_K:
op = "and";
fmt = "#0x%x";
break;
case BPF_ALU|BPF_OR|BPF_K:
op = "or";
fmt = "#0x%x";
break;
case BPF_ALU|BPF_LSH|BPF_K:
op = "lsh";
fmt = "#%d";
break;
case BPF_ALU|BPF_RSH|BPF_K:
op = "rsh";
fmt = "#%d";
break;
case BPF_ALU|BPF_NEG:
op = "neg";
fmt = "";
break;
case BPF_MISC|BPF_TAX:
op = "tax";
fmt = "";
break;
case BPF_MISC|BPF_TXA:
op = "txa";
fmt = "";
break;
}
(void)sprintf(operand, fmt, v);
(void)sprintf(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;
}

693
config.guess vendored Executable file
View File

@ -0,0 +1,693 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Written by Per Bothner <bothner@cygnus.com>.
# The master version of this file is at the FSF in /home/gd/gnu/lib.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
#
# The plan is that this can be called by configure scripts if you
# don't specify an explicit system type (host/target name).
#
# Only a few systems have been added to this list; please add others
# (but try to keep the structure clean).
#
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 8/24/94.)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
alpha:OSF1:*:*)
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'`
exit 0 ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit 0 ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-cbm-sysv4
exit 0;;
amiga:NetBSD:*:*)
echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;;
amiga:OpenBSD:*:*)
echo m68k-cbm-openbsd${UNAME_RELEASE}
exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit 0 ;;
NILE:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
i86pc:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
exit 0 ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
atari*:NetBSD:*:*)
echo m68k-atari-netbsd${UNAME_RELEASE}
exit 0 ;;
atari*:OpenBSD:*:*)
echo m68k-atari-openbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:OpenBSD:*:*)
echo m68k-sun-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:NetBSD:*:*)
echo m68k-apple-netbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-apple-openbsd${UNAME_RELEASE}
exit 0 ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit 0 ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
sed 's/^ //' << EOF >dummy.c
int main (argc, argv) int argc; char **argv; {
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
${CC-cc} dummy.c -o dummy \
&& ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit 0 ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit 0 ;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
exit 0 ;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
exit 0 ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else echo i586-dg-dgux${UNAME_RELEASE}
fi
exit 0 ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit 0 ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
exit 0 ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
exit 0 ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
exit 0 ;;
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit 0 ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i?86:AIX:*:*)
echo i386-ibm-aix
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
sed 's/^ //' << EOF >dummy.c
#include <sys/systemcfg.h>
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
exit 0 ;;
*:AIX:*:4)
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=4.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit 0 ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit 0 ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit 0 ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit 0 ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
exit 0 ;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
exit 0 ;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
exit 0 ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit 0 ;;
9000/[3478]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
9000/8?? ) HP_ARCH=hppa1.0 ;;
esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
sed 's/^ //' << EOF >dummy.c
#include <unistd.h>
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
exit 0 ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit 0 ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit 0 ;;
i?86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
exit 0 ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit 0 ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit 0 ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit 0 ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
CRAY*X-MP:*:*:*)
echo xmp-cray-unicos
exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
exit 0 ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
F300:UNIX_System_V:*:*)
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
F301:UNIX_System_V:*:*)
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
exit 0 ;;
hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0 ;;
hp3[0-9][05]:OpenBSD:*:*)
echo m68k-hp-openbsd${UNAME_RELEASE}
exit 0 ;;
i?86:BSD/386:*:* | *:BSD/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
*:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
i*:CYGWIN*:*)
echo i386-pc-cygwin32
exit 0 ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin32
exit 0 ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
*:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
*:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us.
ld_help_string=`ld --help 2>&1`
if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i.86"; then
echo "${UNAME_MACHINE}-pc-linux-gnu" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86linux"; then
echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86coff"; then
echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then
echo "${UNAME_MACHINE}-unknown-linux-gnu" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then
echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf32ppc"; then
echo "powerpc-unknown-linux-gnu" ; exit 0
elif test "${UNAME_MACHINE}" = "alpha" ; then
echo alpha-unknown-linux-gnu ; exit 0
elif test "${UNAME_MACHINE}" = "sparc" ; then
echo sparc-unknown-linux-gnu ; exit 0
else
# Either a pre-BFD a.out linker (linux-gnuoldld) or one that does not give us
# useful --help. Gcc wants to distinguish between linux-gnuoldld and linux-gnuaout.
test ! -d /usr/lib/ldscripts/. \
&& echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
# Determine whether the default compiler is a.out or elf
cat >dummy.c <<EOF
main(argc, argv)
int argc;
char *argv[];
{
#ifdef __ELF__
printf ("%s-pc-linux-gnu\n", argv[1]);
#else
printf ("%s-pc-linux-gnuaout\n", argv[1]);
#endif
return 0;
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
fi ;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
# are messed up and put the nodename in both sysname and nodename.
i?86:DYNIX/ptx:4*:*)
echo i386-sequent-sysv4
exit 0 ;;
i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
fi
exit 0 ;;
i?86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit 0 ;;
paragon:*:*:*)
echo i860-intel-osf1
exit 0 ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
exit 0 ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4.3${OS_REL} && exit 0
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4 && exit 0 ;;
m68*:LynxOS:2.*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
i?86:LynxOS:2.*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit 0 ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
echo ${UNAME_MACHINE}-sni-sysv4
else
echo ns32k-sni-sysv
fi
exit 0 ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
exit 0 ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit 0 ;;
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
cat >dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
#if !defined (ultrix)
printf ("vax-dec-bsd\n"); exit (0);
#else
printf ("vax-dec-ultrix\n"); exit (0);
#endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
exit 0 ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit 0 ;;
c34*)
echo c34-convex-bsd
exit 0 ;;
c38*)
echo c38-convex-bsd
exit 0 ;;
c4*)
echo c4-convex-bsd
exit 0 ;;
esac
fi
#echo '(Unable to guess system type)' 1>&2
exit 1

927
config.sub vendored Executable file
View File

@ -0,0 +1,927 @@
#! /bin/sh
# Configuration validation subroutine script, version 1.1.
# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support. The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
if [ x$1 = x ]
then
echo Configuration name missing. 1>&2
echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
echo "or $0 ALIAS" 1>&2
echo where ALIAS is a recognized configuration type. 1>&2
exit 1
fi
# First pass through any local machine types.
case $1 in
*local*)
echo $1
exit 0
;;
*)
;;
esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
linux-gnu*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
;;
esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
### recognize some manufacturers as not being operating systems, so we
### can provide default operating systems below.
case $os in
-sun*os*)
# Prevent following clause from handling this invalid input.
;;
-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple)
os=
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco5)
os=sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*)
os=-lynxos
;;
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
-psos*)
os=-psos
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \
| arme[lb] | pyramid \
| tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
| alpha | we32k | ns16k | clipper | i370 | sh \
| powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \
| pdp11 | mips64el | mips64orion | mips64orionel \
| sparc | sparclet | sparclite | sparc64)
basic_machine=$basic_machine-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i[3456]86)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
| sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
| none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
| hppa-* | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
| pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
| pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* | f301-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
alliant | fx80)
basic_machine=fx80-alliant
;;
altos | altos3068)
basic_machine=m68k-altos
;;
am29k)
basic_machine=a29k-none
os=-bsd
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-cbm
;;
amigados)
basic_machine=m68k-cbm
os=-amigados
;;
amigaunix | amix)
basic_machine=m68k-cbm
os=-sysv4
;;
apollo68)
basic_machine=m68k-apollo
os=-sysv
;;
aux)
basic_machine=m68k-apple
os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
;;
convex-c2)
basic_machine=c2-convex
os=-bsd
;;
convex-c32)
basic_machine=c32-convex
os=-bsd
;;
convex-c34)
basic_machine=c34-convex
os=-bsd
;;
convex-c38)
basic_machine=c38-convex
os=-bsd
;;
cray | ymp)
basic_machine=ymp-cray
os=-unicos
;;
cray2)
basic_machine=cray2-cray
os=-unicos
;;
[ctj]90-cray)
basic_machine=c90-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
;;
delta88)
basic_machine=m88k-motorola
os=-sysv3
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
;;
dpx2* | dpx2*-bull)
basic_machine=m68k-bull
os=-sysv3
;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
;;
elxsi)
basic_machine=elxsi-elxsi
os=-bsd
;;
encore | umax | mmax)
basic_machine=ns32k-encore
;;
fx2800)
basic_machine=i860-alliant
;;
genix)
basic_machine=ns32k-ns
;;
gmicro)
basic_machine=tron-gmicro
os=-sysv
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
h8300hms)
basic_machine=h8300-hitachi
os=-hms
;;
harris)
basic_machine=m88k-harris
os=-sysv3
;;
hp300-*)
basic_machine=m68k-hp
;;
hp300bsd)
basic_machine=m68k-hp
os=-bsd
;;
hp300hpux)
basic_machine=m68k-hp
os=-hpux
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hppa-next)
os=-nextstep3
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
os=-mvs
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i[3456]86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i[3456]86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i[3456]86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i[3456]86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
-irix*)
;;
*)
os=-irix4
;;
esac
;;
isi68 | isi)
basic_machine=m68k-isi
os=-sysv
;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
;;
merlin)
basic_machine=ns32k-utek
os=-sysv
;;
miniframe)
basic_machine=m68000-convergent
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
;;
news1000)
basic_machine=m68030-sony
os=-newsos
;;
news-3600 | risc-news)
basic_machine=mips-sony
os=-newsos
;;
next | m*-next )
basic_machine=m68k-next
case $os in
-nextstep* )
;;
-ns2*)
os=-nextstep2
;;
*)
os=-nextstep3
;;
esac
;;
nh3000)
basic_machine=m68k-harris
os=-cxux
;;
nh[45]000)
basic_machine=m88k-harris
os=-cxux
;;
nindy960)
basic_machine=i960-intel
os=-nindy
;;
np1)
basic_machine=np1-gould
;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
paragon)
basic_machine=i860-intel
os=-osf
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5)
basic_machine=i586-intel
;;
pentiumpro | p6)
basic_machine=i686-intel
;;
pentium-* | p5-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
k5)
# We don't have specific support for AMD's K5 yet, so just call it a Pentium
basic_machine=i586-amd
;;
nexen)
# We don't have specific support for Nexgen yet, so just call it a Pentium
basic_machine=i586-nexgen
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=rs6000-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
rm[46]00)
basic_machine=mips-siemens
;;
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
sequent)
basic_machine=i386-sequent
;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sps7)
basic_machine=m68k-bull
os=-sysv2
;;
spur)
basic_machine=spur-unknown
;;
sun2)
basic_machine=m68000-sun
;;
sun2os3)
basic_machine=m68000-sun
os=-sunos3
;;
sun2os4)
basic_machine=m68000-sun
os=-sunos4
;;
sun3os3)
basic_machine=m68k-sun
os=-sunos3
;;
sun3os4)
basic_machine=m68k-sun
os=-sunos4
;;
sun4os3)
basic_machine=sparc-sun
os=-sunos3
;;
sun4os4)
basic_machine=sparc-sun
os=-sunos4
;;
sun4sol2)
basic_machine=sparc-sun
os=-solaris2
;;
sun3 | sun3-*)
basic_machine=m68k-sun
;;
sun4)
basic_machine=sparc-sun
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
udi29k)
basic_machine=a29k-amd
os=-udi
;;
ultra3)
basic_machine=a29k-nyu
os=-sym1
;;
vaxv)
basic_machine=vax-dec
os=-sysv
;;
vms)
basic_machine=vax-dec
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
;;
vxworks68)
basic_machine=m68k-wrs
os=-vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
os=-vxworks
;;
xmp)
basic_machine=xmp-cray
os=-unicos
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
none)
basic_machine=none-none
os=-none
;;
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
mips)
basic_machine=mips-mips
;;
romp)
basic_machine=romp-ibm
;;
rs6000)
basic_machine=rs6000-ibm
;;
vax)
basic_machine=vax-dec
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sparc)
basic_machine=sparc-sun
;;
cydra)
basic_machine=cydra-cydrome
;;
orion)
basic_machine=orion-highlevel
;;
orion105)
basic_machine=clipper-highlevel
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
;;
*-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
;;
*)
;;
esac
# Decode manufacturer-specific aliases for certain operating systems.
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
-solaris)
os=-solaris2
;;
-unixware* | svr4*)
os=-sysv4
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -linux-gnu* | -uxpv*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*)
os=-bsd
;;
-dynix*)
os=-bsd
;;
-acis*)
os=-aos
;;
-ctix* | -uts*)
os=-sysv
;;
-ns2 )
os=-nextstep2
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
-sinix*)
os=-sysv4
;;
-triton*)
os=-sysv3
;;
-oss*)
os=-sysv3
;;
-svr4)
os=-sysv4
;;
-svr3)
os=-sysv3
;;
-sysvr4)
os=-sysv4
;;
# This must come after -sysvr4.
-sysv*)
;;
-xenix)
os=-xenix
;;
-none)
;;
*)
# Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
exit 1
;;
esac
else
# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.
# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system. Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
case $basic_machine in
*-acorn)
os=-riscix1.2
;;
arm*-semi)
os=-aout
;;
pdp11-*)
os=-none
;;
*-dec | vax-*)
os=-ultrix4.2
;;
m68*-apollo)
os=-domain
;;
i386-sun)
os=-sunos4.0.2
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-ibm)
os=-aix
;;
*-hp)
os=-hpux
;;
*-hitachi)
os=-hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
os=-sysv
;;
*-cbm)
os=-amigados
;;
*-dg)
os=-dgux
;;
*-dolphin)
os=-sysv3
;;
m68k-ccur)
os=-rtu
;;
m88k-omron*)
os=-luna
;;
*-next )
os=-nextstep
;;
*-sequent)
os=-ptx
;;
*-crds)
os=-unos
;;
*-ns)
os=-genix
;;
i370-*)
os=-mvs
;;
*-next)
os=-nextstep3
;;
*-gould)
os=-sysv
;;
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
os=-irix
;;
*-siemens)
os=-sysv4
;;
*-masscomp)
os=-rtu
;;
f301-fujitsu)
os=-uxpv
;;
*)
os=-none
;;
esac
fi
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
vendor=unknown
case $basic_machine in
*-unknown)
case $os in
-riscix*)
vendor=acorn
;;
-sunos*)
vendor=sun
;;
-aix*)
vendor=ibm
;;
-hpux*)
vendor=hp
;;
-hiux*)
vendor=hitachi
;;
-unos*)
vendor=crds
;;
-dgux*)
vendor=dg
;;
-luna*)
vendor=omron
;;
-genix*)
vendor=ns
;;
-mvs*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-vxsim* | -vxworks*)
vendor=wrs
;;
-aux*)
vendor=apple
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os

2137
configure vendored Executable file

File diff suppressed because it is too large Load Diff

189
configure.in Normal file
View File

@ -0,0 +1,189 @@
dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.67 1999-10-07 23:46:40 mcr Exp $ (LBL)
dnl
dnl Copyright (c) 1994, 1995, 1996, 1997
dnl The Regents of the University of California. All rights reserved.
dnl
dnl Process this file with autoconf to produce a configure script.
dnl
AC_INIT(pcap.c)
AC_CANONICAL_SYSTEM
umask 002
if test -z "$PWD" ; then
PWD=`pwd`
fi
AC_LBL_C_INIT(V_CCOPT, V_INCLS)
AC_CHECK_HEADERS(malloc.h sys/ioccom.h sys/sockio.h)
AC_LBL_FIXINCLUDES
AC_CHECK_FUNCS(ether_hostton strerror)
dnl
dnl Not all versions of test support -c (character special) but it's a
dnl better way of testing since the device might be protected. So we
dnl check in our normal order using -r and then check the for the /dev
dnl guys again using -c.
dnl
AC_ARG_WITH(pcap, [ --with-pcap=TYPE use packet capture TYPE])
AC_MSG_CHECKING(packet capture type)
if test ! -z "$with_pcap" ; then
V_PCAP="$withval"
elif test -r /dev/bpf0 ; then
V_PCAP=bpf
elif test -r /usr/include/net/pfilt.h ; then
V_PCAP=pf
elif test -r /dev/enet ; then
V_PCAP=enet
elif test -r /dev/nit ; then
V_PCAP=snit
elif test -r /usr/include/sys/net/nit.h ; then
V_PCAP=nit
elif test -r /usr/include/net/raw.h ; then
V_PCAP=snoop
elif test -r /usr/include/sys/dlpi.h ; then
V_PCAP=dlpi
elif test -r /usr/include/linux/socket.h ; then
V_PCAP=linux
elif test -c /dev/bpf0 ; then # check again in case not readable
V_PCAP=bpf
elif test -c /dev/enet ; then # check again in case not readable
V_PCAP=enet
elif test -c /dev/nit ; then # check again in case not readable
V_PCAP=snit
else
V_PCAP=null
fi
AC_MSG_RESULT($V_PCAP)
case "$V_PCAP" in
dlpi)
AC_CHECK_HEADERS(sys/bufmod.h sys/dlpi_ext.h)
AC_MSG_CHECKING(for /dev/dlpi device)
if test -c /dev/dlpi ; then
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_DEV_DLPI)
else
AC_MSG_RESULT(no)
dir="/dev/dlpi"
AC_MSG_CHECKING(for $dir directory)
if test -d $dir ; then
AC_MSG_RESULT(yes)
AC_DEFINE_UNQUOTED(PCAP_DEV_PREFIX, "$dir")
else
AC_MSG_RESULT(no)
fi
fi
;;
linux)
AC_CHECK_HEADERS(net/if_arp.h)
AC_MSG_CHECKING(Linux kernel version)
AC_CACHE_VAL(ac_cv_linux_vers,
ac_cv_linux_vers=`uname -r 2>&1 | \
sed -n -e '$s/.* //' -e '$s/\..*//p'`)
AC_MSG_RESULT($ac_cv_linux_vers)
if test $ac_cv_linux_vers -lt 2 ; then
AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info)
fi
;;
null)
AC_MSG_WARN(cannot determine packet capture interface)
AC_MSG_WARN((see the INSTALL doc for more info))
;;
esac
AC_LBL_LEX_AND_YACC(V_LEX, V_YACC, pcap_)
case "$target_os" in
aix*)
dnl Workaround to enable certain features
AC_DEFINE(_SUN)
;;
hpux9*)
AC_DEFINE(HAVE_HPUX9)
;;
hpux10.0*)
;;
hpux10.1*)
;;
hpux*)
dnl HPUX 10.20 and above is similar to HPUX 9...
AC_DEFINE(HAVE_HPUX10_20)
;;
sinix*)
AC_MSG_CHECKING(if SINIX compiler defines sinix)
AC_CACHE_VAL(ac_cv_cc_sinix_defined,
AC_TRY_COMPILE(
[],
[int i = sinix;],
ac_cv_cc_sinix_defined=yes,
ac_cv_cc_sinix_defined=no))
AC_MSG_RESULT($ac_cv_cc_sinix_defined)
if test $ac_cv_cc_sinix_defined = no ; then
AC_DEFINE(sinix)
fi
;;
solaris*)
AC_DEFINE(HAVE_SOLARIS)
;;
linux*)
V_INCLS="$V_INCLS -Ilinux-include"
;;
esac
AC_CHECK_PROGS(V_RANLIB, ranlib, @true)
AC_LBL_DEVEL(V_CCOPT)
AC_LBL_SOCKADDR_SA_LEN
AC_LBL_UNALIGNED_ACCESS
if test "${srcdir}" = "." ; then
srcdirprefix=""
else
srcdirprefix="./"
fi
if test -r ${srcdirprefix}lbl/gnuc.h ; then
rm -f gnuc.h
ln -s ${srcdirprefix}lbl/gnuc.h gnuc.h
fi
rm -f bpf_filter.c
ln -s ${srcdirprefix}bpf/net/bpf_filter.c bpf_filter.c
rm -f net
ln -s ${srcdirprefix}bpf/net net
AC_SUBST(V_CCOPT)
AC_SUBST(V_INCLS)
AC_SUBST(V_LEX)
AC_SUBST(V_PCAP)
AC_SUBST(V_RANLIB)
AC_SUBST(V_YACC)
AC_PROG_INSTALL
AC_OUTPUT(Makefile)
if test -f .devel ; then
make depend
fi
exit 0

159
etherent.c Normal file
View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 1990, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.20 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <ctype.h>
#include <memory.h>
#include <stdio.h>
#include <string.h>
#include "pcap-int.h"
#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 *);
/* Hex digit to integer. */
static inline int
xdtoi(c)
register int c;
{
if (isdigit(c))
return c - '0';
else if (islower(c))
return c - 'a' + 10;
else
return c - 'A' + 10;
}
static inline int
skip_space(f)
FILE *f;
{
int c;
do {
c = getc(f);
} while (isspace(c) && c != '\n');
return c;
}
static inline int
skip_line(f)
FILE *f;
{
int c;
do
c = getc(f);
while (c != '\n' && c != EOF);
return c;
}
struct pcap_etherent *
pcap_next_etherent(FILE *fp)
{
register int c, d, i;
char *bp;
static struct pcap_etherent e;
memset((char *)&e, 0, sizeof(e));
do {
/* Find addr */
c = skip_space(fp);
if (c == '\n')
continue;
/* If this is a comment, or first thing on line
cannot be etehrnet address, skip the line. */
if (!isxdigit(c)) {
c = skip_line(fp);
continue;
}
/* must be the start of an address */
for (i = 0; i < 6; i += 1) {
d = xdtoi(c);
c = getc(fp);
if (isxdigit(c)) {
d <<= 4;
d |= xdtoi(c);
c = getc(fp);
}
e.addr[i] = d;
if (c != ':')
break;
c = getc(fp);
}
if (c == EOF)
break;
/* Must be whitespace */
if (!isspace(c)) {
c = skip_line(fp);
continue;
}
c = skip_space(fp);
/* hit end of line... */
if (c == '\n')
continue;
if (c == '#') {
c = skip_line(fp);
continue;
}
/* pick up name */
bp = e.name;
/* Use 'd' to prevent buffer overflow. */
d = sizeof(e.name) - 1;
do {
*bp++ = c;
c = getc(fp);
} while (!isspace(c) && c != EOF && --d > 0);
*bp = '\0';
/* Eat trailing junk */
if (c != '\n')
(void)skip_line(fp);
return &e;
} while (c != EOF);
return (NULL);
}

76
ethertype.h Normal file
View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 1993, 1994, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.6 1999-10-07 23:46:40 mcr Exp $ (LBL)
*/
/* Types missing from some systems */
#ifndef ETHERTYPE_NS
#define ETHERTYPE_NS 0x0600
#endif
#ifndef ETHERTYPE_SPRITE
#define ETHERTYPE_SPRITE 0x0500
#endif
#ifndef ETHERTYPE_TRAIL
#define ETHERTYPE_TRAIL 0x1000
#endif
#ifndef ETHERTYPE_MOPDL
#define ETHERTYPE_MOPDL 0x6001
#endif
#ifndef ETHERTYPE_MOPRC
#define ETHERTYPE_MOPRC 0x6002
#endif
#ifndef ETHERTYPE_DN
#define ETHERTYPE_DN 0x6003
#endif
#ifndef ETHERTYPE_LAT
#define ETHERTYPE_LAT 0x6004
#endif
#ifndef ETHERTYPE_SCA
#define ETHERTYPE_SCA 0x6007
#endif
#ifndef ETHERTYPE_REVARP
#define ETHERTYPE_REVARP 0x8035
#endif
#ifndef ETHERTYPE_LANBRIDGE
#define ETHERTYPE_LANBRIDGE 0x8038
#endif
#ifndef ETHERTYPE_DECDNS
#define ETHERTYPE_DECDNS 0x803c
#endif
#ifndef ETHERTYPE_DECDTS
#define ETHERTYPE_DECDTS 0x803e
#endif
#ifndef ETHERTYPE_VEXP
#define ETHERTYPE_VEXP 0x805b
#endif
#ifndef ETHERTYPE_VPROD
#define ETHERTYPE_VPROD 0x805c
#endif
#ifndef ETHERTYPE_ATALK
#define ETHERTYPE_ATALK 0x809b
#endif
#ifndef ETHERTYPE_AARP
#define ETHERTYPE_AARP 0x80f3
#endif
#ifndef ETHERTYPE_LOOPBACK
#define ETHERTYPE_LOOPBACK 0x9000
#endif

1944
gencode.c Normal file

File diff suppressed because it is too large Load Diff

179
gencode.h Normal file
View File

@ -0,0 +1,179 @@
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.36 1999-10-07 23:46:40 mcr Exp $ (LBL)
*/
/*XXX*/
#include "gnuc.h"
/* Address qualifiers. */
#define Q_HOST 1
#define Q_NET 2
#define Q_PORT 3
#define Q_GATEWAY 4
#define Q_PROTO 5
/* Protocol qualifiers. */
#define Q_LINK 1
#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_ATALK 10
#define Q_DECNET 11
#define Q_LAT 12
#define Q_SCA 13
#define Q_MOPRC 14
#define Q_MOPDL 15
/* Directional qualifiers. */
#define Q_SRC 1
#define Q_DST 2
#define Q_OR 3
#define Q_AND 4
#define Q_DEFAULT 0
#define Q_UNDEF 255
struct stmt {
int code;
bpf_int32 k;
};
struct slist {
struct stmt s;
struct slist *next;
};
/*
* A bit vector to represent definition sets. We assume TOT_REGISTERS
* is smaller than 8*sizeof(atomset).
*/
typedef bpf_u_int32 atomset;
#define ATOMMASK(n) (1 << (n))
#define ATOMELEM(d, n) (d & ATOMMASK(n))
/*
* An unbounded set.
*/
typedef bpf_u_int32 *uset;
/*
* Total number of atomic entities, including accumulator (A) and index (X).
* We treat all these guys similarly during flow analysis.
*/
#define N_ATOMS (BPF_MEMWORDS+2)
struct edge {
int id;
int code;
uset edom;
struct block *succ;
struct block *pred;
struct edge *next; /* link list of incoming edges for a node */
};
struct block {
int id;
struct slist *stmts; /* side effect stmts */
struct stmt s; /* branch stmt */
int mark;
int longjt; /* jt branch requires long jump */
int longjf; /* jf branch requires long jump */
int level;
int offset;
int sense;
struct edge et;
struct edge ef;
struct block *head;
struct block *link; /* link field used by optimizer */
uset dom;
uset closure;
struct edge *in_edges;
atomset def, kill;
atomset in_use;
atomset out_use;
int oval;
int val[N_ATOMS];
};
struct arth {
struct block *b; /* protocol checks */
struct slist *s; /* stmt list */
int regno; /* virtual register number of result */
};
struct qual {
unsigned char addr;
unsigned char proto;
unsigned char dir;
unsigned char pad;
};
struct arth *gen_loadi(int);
struct arth *gen_load(int, struct arth *, int);
struct arth *gen_loadlen(void);
struct arth *gen_neg(struct arth *);
struct arth *gen_arth(int, struct arth *, struct arth *);
void gen_and(struct block *, struct block *);
void gen_or(struct block *, struct block *);
void gen_not(struct block *);
struct block *gen_scode(const char *, struct qual);
struct block *gen_ecode(const u_char *, struct qual);
struct block *gen_mcode(const char *, const char *, int, struct qual);
struct block *gen_ncode(const char *, bpf_u_int32, struct qual);
struct block *gen_proto_abbrev(int);
struct block *gen_relation(int, struct arth *, struct arth *, int);
struct block *gen_less(int);
struct block *gen_greater(int);
struct block *gen_byteop(int, int, int);
struct block *gen_broadcast(int);
struct block *gen_multicast(int);
struct block *gen_inbound(int);
void bpf_optimize(struct block **);
#if __STDC__
__dead void bpf_error(const char *, ...)
__attribute__((volatile, format (printf, 1, 2)));
#endif
void finish_parse(struct block *);
char *sdup(const char *);
struct bpf_insn *icode_to_fcode(struct block *, int *);
int pcap_parse(void);
void lex_init(char *);
void sappend(struct slist *, struct slist *);
/* XXX */
#define JT(b) ((b)->et.succ)
#define JF(b) ((b)->ef.succ)

281
grammar.y Normal file
View File

@ -0,0 +1,281 @@
%{
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.56 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#if __STDC__
struct mbuf;
struct rtentry;
#endif
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <stdio.h>
#include "pcap-int.h"
#include "gencode.h"
#include <pcap-namedb.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#define QSET(q, p, d, a) (q).proto = (p),\
(q).dir = (d),\
(q).addr = (a)
int n_errors = 0;
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
static void
yyerror(char *msg)
{
++n_errors;
bpf_error("%s", msg);
/* NOTREACHED */
}
#ifndef YYBISON
int yyparse(void);
int
pcap_parse()
{
return (yyparse());
}
#endif
%}
%union {
int i;
bpf_u_int32 h;
u_char *e;
char *s;
struct stmt *stmt;
struct arth *a;
struct {
struct qual q;
struct block *b;
} blk;
struct block *rblk;
}
%type <blk> expr id nid pid term rterm qid
%type <blk> head
%type <i> pqual dqual aqual ndaqual
%type <a> arth narth
%type <i> byteop pname pnum relop irelop
%type <blk> and or paren not null prog
%type <rblk> other
%token DST SRC HOST GATEWAY
%token NET MASK PORT LESS GREATER PROTO BYTE
%token ARP RARP IP TCP UDP ICMP IGMP IGRP
%token ATALK DECNET LAT SCA MOPRC MOPDL
%token TK_BROADCAST TK_MULTICAST
%token NUM INBOUND OUTBOUND
%token LINK
%token GEQ LEQ NEQ
%token ID EID HID
%token LSH RSH
%token LEN
%type <s> ID
%type <e> EID
%type <s> HID
%type <i> NUM
%left OR AND
%nonassoc '!'
%left '|'
%left '&'
%left LSH RSH
%left '+' '-'
%left '*' '/'
%nonassoc UMINUS
%%
prog: null expr
{
finish_parse($2.b);
}
| null
;
null: /* null */ { $$.q = qerr; }
;
expr: term
| expr and term { gen_and($1.b, $3.b); $$ = $3; }
| expr and id { gen_and($1.b, $3.b); $$ = $3; }
| expr or term { gen_or($1.b, $3.b); $$ = $3; }
| expr or id { gen_or($1.b, $3.b); $$ = $3; }
;
and: AND { $$ = $<blk>0; }
;
or: OR { $$ = $<blk>0; }
;
id: nid
| pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
$$.q = $<blk>0.q); }
| paren pid ')' { $$ = $2; }
;
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,
$$.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;
}
}
| EID { $$.b = gen_ecode($1, $$.q = $<blk>0.q); }
| not id { gen_not($2.b); $$ = $2; }
;
not: '!' { $$ = $<blk>0; }
;
paren: '(' { $$ = $<blk>0; }
;
pid: nid
| qid and id { gen_and($1.b, $3.b); $$ = $3; }
| qid or id { gen_or($1.b, $3.b); $$ = $3; }
;
qid: pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
$$.q = $<blk>0.q); }
| pid
;
term: rterm
| not term { gen_not($2.b); $$ = $2; }
;
head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
| pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); }
| pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); }
| pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
| pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); }
;
rterm: head id { $$ = $2; }
| paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
| pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; }
| arth relop arth { $$.b = gen_relation($2, $1, $3, 0);
$$.q = qerr; }
| arth irelop arth { $$.b = gen_relation($2, $1, $3, 1);
$$.q = qerr; }
| other { $$.b = $1; $$.q = qerr; }
;
/* protocol level qualifiers */
pqual: pname
| { $$ = Q_DEFAULT; }
;
/* 'direction' qualifiers */
dqual: SRC { $$ = Q_SRC; }
| DST { $$ = Q_DST; }
| SRC OR DST { $$ = Q_OR; }
| DST OR SRC { $$ = Q_OR; }
| SRC AND DST { $$ = Q_AND; }
| DST AND SRC { $$ = Q_AND; }
;
/* address type qualifiers */
aqual: HOST { $$ = Q_HOST; }
| NET { $$ = Q_NET; }
| PORT { $$ = Q_PORT; }
;
/* non-directional address type qualifiers */
ndaqual: GATEWAY { $$ = Q_GATEWAY; }
;
pname: LINK { $$ = Q_LINK; }
| IP { $$ = Q_IP; }
| ARP { $$ = Q_ARP; }
| RARP { $$ = Q_RARP; }
| TCP { $$ = Q_TCP; }
| UDP { $$ = Q_UDP; }
| ICMP { $$ = Q_ICMP; }
| IGMP { $$ = Q_IGMP; }
| IGRP { $$ = Q_IGRP; }
| ATALK { $$ = Q_ATALK; }
| DECNET { $$ = Q_DECNET; }
| LAT { $$ = Q_LAT; }
| SCA { $$ = Q_SCA; }
| MOPDL { $$ = Q_MOPDL; }
| MOPRC { $$ = Q_MOPRC; }
;
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); }
| INBOUND { $$ = gen_inbound(0); }
| OUTBOUND { $$ = gen_inbound(1); }
;
relop: '>' { $$ = BPF_JGT; }
| GEQ { $$ = BPF_JGE; }
| '=' { $$ = BPF_JEQ; }
;
irelop: LEQ { $$ = BPF_JGT; }
| '<' { $$ = BPF_JGE; }
| NEQ { $$ = BPF_JEQ; }
;
arth: pnum { $$ = gen_loadi($1); }
| narth
;
narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); }
| pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); }
| arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); }
| arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); }
| arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); }
| arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); }
| arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); }
| arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); }
| arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); }
| arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); }
| '-' arth %prec UMINUS { $$ = gen_neg($2); }
| paren narth ')' { $$ = $2; }
| LEN { $$ = gen_loadlen(); }
;
byteop: '&' { $$ = '&'; }
| '|' { $$ = '|'; }
| '<' { $$ = '<'; }
| '>' { $$ = '>'; }
| '=' { $$ = '='; }
;
pnum: NUM
| paren pnum ')' { $$ = $2; }
;
%%

219
inet.c Normal file
View File

@ -0,0 +1,219 @@
/*
* 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
* 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 Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory 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.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.22 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#include <sys/time.h> /* concession to AIX */
#if __STDC__
struct mbuf;
struct rtentry;
#endif
#include <net/if.h>
#include <netinet/in.h>
#include <ctype.h>
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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)
#else
#define ISLOOPBACK(p) ((p)->ifr_name[0] == 'l' && (p)->ifr_name[1] == 'o' && \
(isdigit((p)->ifr_name[2]) || (p)->ifr_name[2] == '\0'))
#endif
/*
* 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;
{
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)sprintf(errbuf, "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)sprintf(errbuf, "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
/*
* 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.)
*/
strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
if (errno == ENXIO)
continue;
(void)sprintf(errbuf, "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)strcpy(errbuf, "no suitable device found");
return (NULL);
}
(void)strncpy(device, mp->ifr_name, sizeof(device) - 1);
device[sizeof(device) - 1] = '\0';
return (device);
}
int
pcap_lookupnet(device, netp, maskp, errbuf)
register char *device;
register bpf_u_int32 *netp, *maskp;
register char *errbuf;
{
register int fd;
register struct sockaddr_in *sin;
struct ifreq ifr;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
(void)sprintf(errbuf, "socket: %s", pcap_strerror(errno));
return (-1);
}
memset(&ifr, 0, sizeof(ifr));
#ifdef linux
/* XXX Work around Linux kernel bug */
ifr.ifr_addr.sa_family = AF_INET;
#endif
(void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
(void)sprintf(errbuf, "SIOCGIFADDR: %s: %s",
device, pcap_strerror(errno));
(void)close(fd);
return (-1);
}
sin = (struct sockaddr_in *)&ifr.ifr_addr;
*netp = sin->sin_addr.s_addr;
if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
(void)sprintf(errbuf, "SIOCGIFNETMASK: %s: %s",
device, pcap_strerror(errno));
(void)close(fd);
return (-1);
}
(void)close(fd);
*maskp = sin->sin_addr.s_addr;
if (*maskp == 0) {
if (IN_CLASSA(*netp))
*maskp = IN_CLASSA_NET;
else if (IN_CLASSB(*netp))
*maskp = IN_CLASSB_NET;
else if (IN_CLASSC(*netp))
*maskp = IN_CLASSC_NET;
else {
(void)sprintf(errbuf, "inet class for 0x%x unknown",
*netp);
return (-1);
}
}
*netp &= *maskp;
return (0);
}

250
install-sh Executable file
View File

@ -0,0 +1,250 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

43
lbl/gnuc.h Normal file
View File

@ -0,0 +1,43 @@
/* @(#) $Header: /tcpdump/master/libpcap/lbl/Attic/gnuc.h,v 1.3 1999-10-07 23:46:41 mcr 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

54
lbl/os-solaris2.h Normal file
View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/lbl/os-solaris2.h,v 1.18 1999-10-07 23:46:41 mcr Exp $ (LBL)
*/
/* Prototypes missing in SunOS 5 */
int daemon(int, int);
int dn_expand(const u_char *, const u_char *, const u_char *, char *, int);
int dn_skipname(const u_char *, const u_char *);
int flock(int, int);
int getdtablesize(void);
int gethostname(char *, int);
int getpagesize(void);
char *getusershell(void);
char *getwd(char *);
int iruserok(u_int, int, char *, char *);
#ifdef __STDC__
struct utmp;
void login(struct utmp *);
#endif
int logout(const char *);
int res_query(const char *, int, int, u_char *, int);
int setenv(const char *, const char *, int);
#if defined(_STDIO_H) && defined(HAVE_SETLINEBUF)
int setlinebuf(FILE *);
#endif
int sigblock(int);
int sigsetmask(int);
char *strerror(int);
int snprintf(char *, size_t, const char *, ...);
int strcasecmp(const char *, const char *);
void unsetenv(const char *);
#ifdef __STDC__
struct timeval;
#endif
int utimes(const char *, struct timeval *);

215
lbl/os-sunos4.h Normal file
View File

@ -0,0 +1,215 @@
/*
* Copyright (c) 1989, 1990, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/lbl/os-sunos4.h,v 1.32 1999-10-07 23:46:41 mcr Exp $ (LBL)
*/
/* Prototypes missing in SunOS 4 */
#ifdef FILE
int _filbuf(FILE *);
int _flsbuf(u_char, FILE *);
int fclose(FILE *);
int fflush(FILE *);
int fgetc(FILE *);
int fprintf(FILE *, const char *, ...);
int fputc(int, FILE *);
int fputs(const char *, FILE *);
u_int fread(void *, u_int, u_int, FILE *);
int fseek(FILE *, long, int);
u_int fwrite(const void *, u_int, u_int, FILE *);
int pclose(FILE *);
void rewind(FILE *);
void setbuf(FILE *, char *);
int setlinebuf(FILE *);
int ungetc(int, FILE *);
int vfprintf(FILE *, const char *, ...);
int vprintf(const char *, ...);
#endif
#if __GNUC__ <= 1
int read(int, char *, u_int);
int write(int, char *, u_int);
#endif
long a64l(const char *);
#ifdef __STDC__
struct sockaddr;
#endif
int accept(int, struct sockaddr *, int *);
int bind(int, struct sockaddr *, int);
int bcmp(const void *, const void *, u_int);
void bcopy(const void *, void *, u_int);
void bzero(void *, int);
int chroot(const char *);
int close(int);
void closelog(void);
int connect(int, struct sockaddr *, int);
char *crypt(const char *, const char *);
int daemon(int, int);
int fchmod(int, int);
int fchown(int, int, int);
void endgrent(void);
void endpwent(void);
void endservent(void);
#ifdef __STDC__
struct ether_addr;
#endif
struct ether_addr *ether_aton(const char *);
int flock(int, int);
#ifdef __STDC__
struct stat;
#endif
int fstat(int, struct stat *);
#ifdef __STDC__
struct statfs;
#endif
int fstatfs(int, struct statfs *);
int fsync(int);
#ifdef __STDC__
struct timeb;
#endif
int ftime(struct timeb *);
int ftruncate(int, off_t);
int getdtablesize(void);
long gethostid(void);
int gethostname(char *, int);
int getopt(int, char * const *, const char *);
int getpagesize(void);
char *getpass(char *);
int getpeername(int, struct sockaddr *, int *);
int getpriority(int, int);
#ifdef __STDC__
struct rlimit;
#endif
int getrlimit(int, struct rlimit *);
int getsockname(int, struct sockaddr *, int *);
int getsockopt(int, int, int, char *, int *);
#ifdef __STDC__
struct timeval;
struct timezone;
#endif
int gettimeofday(struct timeval *, struct timezone *);
char *getusershell(void);
char *getwd(char *);
int initgroups(const char *, int);
int ioctl(int, int, caddr_t);
int iruserok(u_long, int, char *, char *);
int isatty(int);
int killpg(int, int);
int listen(int, int);
#ifdef __STDC__
struct utmp;
#endif
void login(struct utmp *);
int logout(const char *);
off_t lseek(int, off_t, int);
int lstat(const char *, struct stat *);
int mkstemp(char *);
char *mktemp(char *);
int munmap(caddr_t, int);
void openlog(const char *, int, int);
void perror(const char *);
int printf(const char *, ...);
int puts(const char *);
long random(void);
int readlink(const char *, char *, int);
#ifdef __STDC__
struct iovec;
#endif
int readv(int, struct iovec *, int);
int recv(int, char *, u_int, int);
int recvfrom(int, char *, u_int, int, struct sockaddr *, int *);
int rename(const char *, const char *);
int rcmd(char **, u_short, char *, char *, char *, int *);
int rresvport(int *);
int send(int, char *, u_int, int);
int sendto(int, char *, u_int, int, struct sockaddr *, int);
int setenv(const char *, const char *, int);
int seteuid(int);
int setpriority(int, int, int);
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
int setpgrp(int, int);
void setpwent(void);
int setrlimit(int, struct rlimit *);
void setservent(int);
int setsockopt(int, int, int, char *, int);
int shutdown(int, int);
int sigblock(int);
void (*signal (int, void (*) (int))) (int);
int sigpause(int);
int sigsetmask(int);
#ifdef __STDC__
struct sigvec;
#endif
int sigvec(int, struct sigvec *, struct sigvec*);
int snprintf(char *, size_t, const char *, ...);
int socket(int, int, int);
int socketpair(int, int, int, int *);
int symlink(const char *, const char *);
void srandom(int);
int sscanf(char *, const char *, ...);
int stat(const char *, struct stat *);
int statfs(char *, struct statfs *);
char *strerror(int);
int strcasecmp(const char *, const char *);
#ifdef __STDC__
struct tm;
#endif
int strftime(char *, int, char *, struct tm *);
int strncasecmp(const char *, const char *, int);
long strtol(const char *, char **, int);
void sync(void);
void syslog(int, const char *, ...);
int system(const char *);
long tell(int);
time_t time(time_t *);
char *timezone(int, int);
int tolower(int);
int toupper(int);
int truncate(char *, off_t);
void unsetenv(const char *);
int vfork(void);
int vsprintf(char *, const char *, ...);
int writev(int, struct iovec *, int);
#ifdef __STDC__
struct rusage;
#endif
int utimes(const char *, struct timeval *);
#if __GNUC__ <= 1
int wait(int *);
pid_t wait3(int *, int, struct rusage *);
#endif
/* Ugly signal hacking */
#ifdef SIG_ERR
#undef SIG_ERR
#define SIG_ERR (void (*)(int))-1
#undef SIG_DFL
#define SIG_DFL (void (*)(int))0
#undef SIG_IGN
#define SIG_IGN (void (*)(int))1
#ifdef KERNEL
#undef SIG_CATCH
#define SIG_CATCH (void (*)(int))2
#endif
#undef SIG_HOLD
#define SIG_HOLD (void (*)(int))3
#endif

39
lbl/os-ultrix4.h Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 1990, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/lbl/os-ultrix4.h,v 1.19 1999-10-07 23:46:41 mcr Exp $ (LBL)
*/
/* Prototypes missing in Ultrix 4 */
int bcmp(const char *, const char *, u_int);
void bcopy(const void *, void *, u_int);
void bzero(void *, u_int);
void endservent(void);
int getopt(int, char * const *, const char *);
#ifdef __STDC__
struct timeval;
struct timezone;
#endif
int gettimeofday(struct timeval *, struct timezone *);
int ioctl(int, int, caddr_t);
int pfopen(char *, int);
int setlinebuf(FILE *);
int socket(int, int, int);
int strcasecmp(const char *, const char *);

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)if_ether.h 8.3 (Berkeley) 5/2/95
*/
#include <net/if_arp.h>
/*
* Ethernet address - 6 octets
*/
struct ether_addr {
u_char ether_addr_octet[6];
};
/*
* Structure of a 10Mb/s Ethernet header.
*/
struct ether_header {
u_char ether_dhost[6];
u_char ether_shost[6];
u_short ether_type;
};
#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
#define ETHERTYPE_IP 0x0800 /* IP protocol */
#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
/*
* The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
* (type-ETHERTYPE_TRAIL)*512 bytes of data followed
* by an ETHER type (as given above) and then the (variable-length) header.
*/
#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
#define ETHERTYPE_NTRAILER 16
#define ETHERMTU 1500
#define ETHERMIN (60-14)
/*
* Ethernet Address Resolution Protocol.
*
* See RFC 826 for protocol description. Structure below is adapted
* to resolving internet addresses. Field names used correspond to
* RFC 826.
*/
struct ether_arp {
struct arphdr ea_hdr; /* fixed-size header */
u_char arp_sha[6]; /* sender hardware address */
u_char arp_spa[4]; /* sender protocol address */
u_char arp_tha[6]; /* target hardware address */
u_char arp_tpa[4]; /* target protocol address */
};
#define arp_hrd ea_hdr.ar_hrd
#define arp_pro ea_hdr.ar_pro
#define arp_hln ea_hdr.ar_hln
#define arp_pln ea_hdr.ar_pln
#define arp_op ea_hdr.ar_op

View File

@ -0,0 +1,178 @@
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ip_var.h 8.2 (Berkeley) 1/9/95
*/
#include <endian.h>
/*
* Overlay for ip header used by other protocols (tcp, udp).
*/
struct ipovly {
caddr_t ih_next, ih_prev; /* for protocol sequence q's */
u_char ih_x1; /* (unused) */
u_char ih_pr; /* protocol */
short ih_len; /* protocol length */
struct in_addr ih_src; /* source internet address */
struct in_addr ih_dst; /* destination internet address */
};
/*
* Ip reassembly queue structure. Each fragment
* being reassembled is attached to one of these structures.
* They are timed out after ipq_ttl drops to 0, and may also
* be reclaimed if memory becomes tight.
*/
struct ipq {
struct ipq *next,*prev; /* to other reass headers */
u_char ipq_ttl; /* time for reass q to live */
u_char ipq_p; /* protocol of this fragment */
u_short ipq_id; /* sequence id for reassembly */
struct ipasfrag *ipq_next,*ipq_prev;
/* to ip headers of fragments */
struct in_addr ipq_src,ipq_dst;
};
/*
* Ip header, when holding a fragment.
*
* Note: ipf_next must be at same offset as ipq_next above
*/
struct ipasfrag {
#if BYTE_ORDER == LITTLE_ENDIAN
u_char ip_hl:4,
ip_v:4;
#endif
#if BYTE_ORDER == BIG_ENDIAN
u_char ip_v:4,
ip_hl:4;
#endif
u_char ipf_mff; /* XXX overlays ip_tos: use low bit
* to avoid destroying tos;
* copied from (ip_off&IP_MF) */
short ip_len;
u_short ip_id;
short ip_off;
u_char ip_ttl;
u_char ip_p;
u_short ip_sum;
struct ipasfrag *ipf_next; /* next fragment */
struct ipasfrag *ipf_prev; /* previous fragment */
};
/*
* Structure stored in mbuf in inpcb.ip_options
* and passed to ip_output when ip options are in use.
* The actual length of the options (including ipopt_dst)
* is in m_len.
*/
#define MAX_IPOPTLEN 40
struct ipoption {
struct in_addr ipopt_dst; /* first-hop dst if source routed */
char ipopt_list[MAX_IPOPTLEN]; /* options proper */
};
struct ipstat {
n_long ips_total; /* total packets received */
n_long ips_badsum; /* checksum bad */
n_long ips_tooshort; /* packet too short */
n_long ips_toosmall; /* not enough data */
n_long ips_badhlen; /* ip header length < data size */
n_long ips_badlen; /* ip length < ip header length */
n_long ips_fragments; /* fragments received */
n_long ips_fragdropped; /* frags dropped (dups, out of space) */
n_long ips_fragtimeout; /* fragments timed out */
n_long ips_forward; /* packets forwarded */
n_long ips_cantforward; /* packets rcvd for unreachable dest */
n_long ips_redirectsent; /* packets forwarded on same net */
n_long ips_noproto; /* unknown or unsupported protocol */
n_long ips_delivered; /* datagrams delivered to upper level*/
n_long ips_localout; /* total ip packets generated here */
n_long ips_odropped; /* lost packets due to nobufs, etc. */
n_long ips_reassembled; /* total packets reassembled ok */
n_long ips_fragmented; /* datagrams sucessfully fragmented */
n_long ips_ofragments; /* output fragments created */
n_long ips_cantfrag; /* don't fragment flag was set, etc. */
n_long ips_badoptions; /* error in option processing */
n_long ips_noroute; /* packets discarded due to no route */
n_long ips_badvers; /* ip version != 4 */
n_long ips_rawout; /* total raw ip packets generated */
};
#ifdef KERNEL
/* flags passed to ip_output as last parameter */
#define IP_FORWARDING 0x1 /* most of ip header exists */
#define IP_RAWOUTPUT 0x2 /* raw ip header exists */
#define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */
#define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */
struct ipstat ipstat;
struct ipq ipq; /* ip reass. queue */
u_short ip_id; /* ip packet ctr, for ids */
int ip_defttl; /* default IP ttl */
int in_control __P((struct socket *, n_long, caddr_t, struct ifnet *));
int ip_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
void ip_deq __P((struct ipasfrag *));
int ip_dooptions __P((struct mbuf *));
void ip_drain __P((void));
void ip_enq __P((struct ipasfrag *, struct ipasfrag *));
void ip_forward __P((struct mbuf *, int));
void ip_freef __P((struct ipq *));
void ip_freemoptions __P((struct ip_moptions *));
int ip_getmoptions __P((int, struct ip_moptions *, struct mbuf **));
void ip_init __P((void));
int ip_mforward __P((struct mbuf *, struct ifnet *));
int ip_optcopy __P((struct ip *, struct ip *));
int ip_output __P((struct mbuf *,
struct mbuf *, struct route *, int, struct ip_moptions *));
int ip_pcbopts __P((struct mbuf **, struct mbuf *));
struct ip *
ip_reass __P((struct ipasfrag *, struct ipq *));
struct in_ifaddr *
ip_rtaddr __P((struct in_addr));
int ip_setmoptions __P((int, struct ip_moptions **, struct mbuf *));
void ip_slowtimo __P((void));
struct mbuf *
ip_srcroute __P((void));
void ip_stripoptions __P((struct mbuf *, struct mbuf *));
int ip_sysctl __P((int *, n_long, void *, size_t *, void *, size_t));
void ipintr __P((void));
int rip_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
void rip_init __P((void));
void rip_input __P((struct mbuf *));
int rip_output __P((struct mbuf *, struct socket *, n_long));
int rip_usrreq __P((struct socket *,
int, struct mbuf *, struct mbuf *, struct mbuf *));
#endif

109
mkdep Executable file
View File

@ -0,0 +1,109 @@
#!/bin/sh -
#
# Copyright (c) 1994, 1996
# The Regents of the University of California. All rights reserved.
#
# Redistribution and use in source and binary forms are permitted
# provided that this notice is preserved and that due credit is given
# to the University of California at Berkeley. The name of the University
# may not be used to endorse or promote products derived from this
# software without specific prior written permission. This software
# is provided ``as is'' without express or implied warranty.
#
# @(#)mkdep.sh 5.11 (Berkeley) 5/5/88
#
PATH=/bin:/usr/bin:/usr/ucb:/usr/local:/usr/local/bin
export PATH
MAKE=Makefile # default makefile name is "Makefile"
CC=cc # default C compiler is "cc"
while :
do case "$1" in
# -c allows you to specify the C compiler
-c)
CC=$2
shift; shift ;;
# -f allows you to select a makefile name
-f)
MAKE=$2
shift; shift ;;
# the -p flag produces "program: program.c" style dependencies
# so .o's don't get produced
-p)
SED='s;\.o;;'
shift ;;
*)
break ;;
esac
done
if [ $# = 0 ] ; then
echo 'usage: mkdep [-p] [-c cc] [-f makefile] [flags] file ...'
exit 1
fi
if [ ! -w $MAKE ]; then
echo "mkdep: no writeable file \"$MAKE\""
exit 1
fi
TMP=/tmp/mkdep$$
trap 'rm -f $TMP ; exit 1' 1 2 3 13 15
cp $MAKE ${MAKE}.bak
sed -e '/DO NOT DELETE THIS LINE/,$d' < $MAKE > $TMP
cat << _EOF_ >> $TMP
# DO NOT DELETE THIS LINE -- mkdep uses it.
# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
_EOF_
# If your compiler doesn't have -M, add it. If you can't, the next two
# lines will try and replace the "cc -M". The real problem is that this
# hack can't deal with anything that requires a search path, and doesn't
# even try for anything using bracket (<>) syntax.
#
# egrep '^#include[ ]*".*"' /dev/null $* |
# sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' |
# XXX this doesn't work with things like "-DDECLWAITSTATUS=union\ wait"
$CC -M $* |
sed "
s; \./; ;g
$SED" |
awk '{
if ($1 != prev) {
if (rec != "")
print rec;
rec = $0;
prev = $1;
}
else {
if (length(rec $2) > 78) {
print rec;
rec = $0;
}
else
rec = rec " " $2
}
}
END {
print rec
}' >> $TMP
cat << _EOF_ >> $TMP
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
_EOF_
# copy to preserve permissions
cp $TMP $MAKE
rm -f ${MAKE}.bak $TMP
exit 0

372
nametoaddr.c Normal file
View File

@ -0,0 +1,372 @@
/*
* 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
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Name to id translation routines used by the scanner.
* These functions are not time critical.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.48 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#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;
#endif
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <memory.h>
#include <netdb.h>
#include <stdio.h>
#include "pcap-int.h"
#include "gencode.h"
#include <pcap-namedb.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#ifndef NTOHL
#define NTOHL(x) (x) = ntohl(x)
#define NTOHS(x) (x) = ntohs(x)
#endif
static inline int xdtoi(int);
/*
* Convert host name to internet address.
* Return 0 upon failure.
*/
bpf_u_int32 **
pcap_nametoaddr(const char *name)
{
#ifndef h_addr
static bpf_u_int32 *hlist[2];
#endif
bpf_u_int32 **p;
struct hostent *hp;
if ((hp = gethostbyname(name)) != NULL) {
#ifndef h_addr
hlist[0] = (bpf_u_int32 *)hp->h_addr;
NTOHL(hp->h_addr);
return hlist;
#else
for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
NTOHL(**p);
return (bpf_u_int32 **)hp->h_addr_list;
#endif
}
else
return 0;
}
/*
* Convert net name to internet address.
* Return 0 upon failure.
*/
bpf_u_int32
pcap_nametonetaddr(const char *name)
{
struct netent *np;
if ((np = getnetbyname(name)) != NULL)
return np->n_net;
else
return 0;
}
/*
* Convert a port name to its port and protocol numbers.
* We assume only TCP or UDP.
* Return 0 upon failure.
*/
int
pcap_nametoport(const char *name, int *port, int *proto)
{
struct servent *sp;
char *other;
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);
#ifdef notdef
if (*port != sp->s_port)
/* 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 defined(ultrix) || defined(__osf__)
/* Special hack in case NFS isn't in /etc/services */
if (strcmp(name, "nfs") == 0) {
*port = 2049;
*proto = PROTO_UNDEF;
return 1;
}
#endif
return 0;
}
int
pcap_nametoproto(const char *str)
{
struct protoent *p;
p = getprotobyname(str);
if (p != 0)
return p->p_proto;
else
return PROTO_UNDEF;
}
#include "ethertype.h"
struct eproto {
char *s;
u_short p;
};
/* Static data base of ether protocol types. */
struct eproto eproto_db[] = {
{ "pup", ETHERTYPE_PUP },
{ "xns", ETHERTYPE_NS },
{ "ip", ETHERTYPE_IP },
{ "arp", ETHERTYPE_ARP },
{ "rarp", ETHERTYPE_REVARP },
{ "sprite", ETHERTYPE_SPRITE },
{ "mopdl", ETHERTYPE_MOPDL },
{ "moprc", ETHERTYPE_MOPRC },
{ "decnet", ETHERTYPE_DN },
{ "lat", ETHERTYPE_LAT },
{ "sca", ETHERTYPE_SCA },
{ "lanbridge", ETHERTYPE_LANBRIDGE },
{ "vexp", ETHERTYPE_VEXP },
{ "vprod", ETHERTYPE_VPROD },
{ "atalk", ETHERTYPE_ATALK },
{ "atalkarp", ETHERTYPE_AARP },
{ "loopback", ETHERTYPE_LOOPBACK },
{ "decdts", ETHERTYPE_DECDTS },
{ "decdns", ETHERTYPE_DECDNS },
{ (char *)0, 0 }
};
int
pcap_nametoeproto(const char *s)
{
struct eproto *p = eproto_db;
while (p->s != 0) {
if (strcmp(p->s, s) == 0)
return p->p;
p += 1;
}
return PROTO_UNDEF;
}
/* Hex digit to integer. */
static inline int
xdtoi(c)
register int c;
{
if (isdigit(c))
return c - '0';
else if (islower(c))
return c - 'a' + 10;
else
return c - 'A' + 10;
}
int
__pcap_atoin(const char *s, bpf_u_int32 *addr)
{
u_int n;
int len;
*addr = 0;
len = 0;
while (1) {
n = 0;
while (*s && *s != '.')
n = n * 10 + *s++ - '0';
*addr <<= 8;
*addr |= n & 0xff;
len += 8;
if (*s == '\0')
return len;
++s;
}
/* NOTREACHED */
}
int
__pcap_atodn(const char *s, bpf_u_int32 *addr)
{
#define AREASHIFT 10
#define AREAMASK 0176000
#define NODEMASK 01777
u_int node, area;
if (sscanf((char *)s, "%d.%d", &area, &node) != 2)
bpf_error("malformed decnet address '%s'", s);
*addr = (area << AREASHIFT) & AREAMASK;
*addr |= (node & NODEMASK);
return(32);
}
/*
* Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
* ethernet address. Assumes 's' is well formed.
*/
u_char *
pcap_ether_aton(const char *s)
{
register u_char *ep, *e;
register u_int d;
e = ep = (u_char *)malloc(6);
while (*s) {
if (*s == ':')
s += 1;
d = xdtoi(*s++);
if (isxdigit(*s)) {
d <<= 4;
d |= xdtoi(*s++);
}
*ep++ = d;
}
return (e);
}
#ifndef HAVE_ETHER_HOSTTON
/* Roll our own */
u_char *
pcap_ether_hostton(const char *name)
{
register struct pcap_etherent *ep;
register u_char *ap;
static FILE *fp = NULL;
static init = 0;
if (!init) {
fp = fopen(PCAP_ETHERS_FILE, "r");
++init;
if (fp == NULL)
return (NULL);
} else if (fp == NULL)
return (NULL);
else
rewind(fp);
while ((ep = pcap_next_etherent(fp)) != NULL) {
if (strcmp(ep->name, name) == 0) {
ap = (u_char *)malloc(6);
if (ap != NULL) {
memcpy(ap, ep->addr, 6);
return (ap);
}
break;
}
}
return (NULL);
}
#else
#ifndef sgi
extern int ether_hostton(char *, struct ether_addr *);
#endif
/* Use the os supplied routines */
u_char *
pcap_ether_hostton(const char *name)
{
register u_char *ap;
u_char a[6];
ap = NULL;
if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) {
ap = (u_char *)malloc(6);
if (ap != NULL)
memcpy((char *)ap, (char *)a, 6);
}
return (ap);
}
#endif
u_short
__pcap_nametodnaddr(const char *name)
{
#ifdef DECNETLIB
struct nodeent *getnodebyname();
struct nodeent *nep;
unsigned short res;
nep = getnodebyname(name);
if (nep == ((struct nodeent *)0))
bpf_error("unknown decnet host name '%s'\n", name);
memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
return(res);
#else
bpf_error("decnet name support not included, '%s' cannot be translated\n",
name);
#endif
}

2004
optimize.c Normal file

File diff suppressed because it is too large Load Diff

263
pcap-bpf.c Normal file
View File

@ -0,0 +1,263 @@
/*
* 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
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.31 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#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 <net/if.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
struct bpf_stat s;
if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) {
sprintf(p->errbuf, "BIOCGSTATS: %s", pcap_strerror(errno));
return (-1);
}
ps->ps_recv = s.bs_recv;
ps->ps_drop = s.bs_drop;
return (0);
}
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
int cc;
int n = 0;
register u_char *bp, *ep;
again:
cc = p->cc;
if (p->cc == 0) {
cc = read(p->fd, (char *)p->buffer, p->bufsize);
if (cc < 0) {
/* Don't choke when we get ptraced */
switch (errno) {
case EINTR:
goto again;
case EWOULDBLOCK:
return (0);
#if defined(sun) && !defined(BSD)
/*
* Due to a SunOS bug, after 2^31 bytes, the kernel
* file offset overflows and read fails with EINVAL.
* The lseek() to 0 will fix things.
*/
case EINVAL:
if (lseek(p->fd, 0L, SEEK_CUR) +
p->bufsize < 0) {
(void)lseek(p->fd, 0L, SEEK_SET);
goto again;
}
/* fall through */
#endif
}
sprintf(p->errbuf, "read: %s", pcap_strerror(errno));
return (-1);
}
bp = p->buffer;
} else
bp = p->bp;
/*
* Loop through each packet.
*/
#define bhp ((struct bpf_hdr *)bp)
ep = bp + cc;
while (bp < ep) {
register int caplen, hdrlen;
caplen = bhp->bh_caplen;
hdrlen = bhp->bh_hdrlen;
/*
* 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);
}
}
#undef bhp
p->cc = 0;
return (n);
}
static inline int
bpf_open(pcap_t *p, char *errbuf)
{
int fd;
int n = 0;
char device[sizeof "/dev/bpf000"];
/*
* Go through all the minors and find one that isn't in use.
*/
do {
(void)sprintf(device, "/dev/bpf%d", n++);
fd = open(device, O_RDONLY);
} while (fd < 0 && errno == EBUSY);
/*
* XXX better message for all minors used
*/
if (fd < 0)
sprintf(errbuf, "%s: %s", device, pcap_strerror(errno));
return (fd);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
int fd;
struct ifreq ifr;
struct bpf_version bv;
u_int v;
pcap_t *p;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
return (NULL);
}
bzero(p, sizeof(*p));
fd = bpf_open(p, ebuf);
if (fd < 0)
goto bad;
p->fd = fd;
p->snapshot = snaplen;
if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
sprintf(ebuf, "BIOCVERSION: %s", pcap_strerror(errno));
goto bad;
}
if (bv.bv_major != BPF_MAJOR_VERSION ||
bv.bv_minor < BPF_MINOR_VERSION) {
sprintf(ebuf, "kernel bpf filter out of date");
goto bad;
}
v = 32768; /* XXX this should be a user-accessible hook */
/* Ignore the return value - this is because the call fails on
* BPF systems that don't have kernel malloc. And if the call
* fails, it's no big deal, we just continue to use the standard
* buffer size.
*/
(void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
(void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
sprintf(ebuf, "%s: %s", device, pcap_strerror(errno));
goto bad;
}
/* Get the data link layer type. */
if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
sprintf(ebuf, "BIOCGDLT: %s", pcap_strerror(errno));
goto bad;
}
#if _BSDI_VERSION - 0 >= 199510
/* The SLIP and PPP link layer header changed in BSD/OS 2.1 */
switch (v) {
case DLT_SLIP:
v = DLT_SLIP_BSDOS;
break;
case DLT_PPP:
v = DLT_PPP_BSDOS;
break;
}
#endif
p->linktype = v;
/* set timeout */
if (to_ms != 0) {
struct timeval to;
to.tv_sec = to_ms / 1000;
to.tv_usec = (to_ms * 1000) % 1000000;
if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
sprintf(ebuf, "BIOCSRTIMEOUT: %s",
pcap_strerror(errno));
goto bad;
}
}
if (promisc)
/* set promiscuous mode, okay if it fails */
(void)ioctl(p->fd, BIOCPROMISC, NULL);
if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
sprintf(ebuf, "BIOCGBLEN: %s", pcap_strerror(errno));
goto bad;
}
p->bufsize = v;
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
goto bad;
}
return (p);
bad:
(void)close(fd);
free(p);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
if (p->sf.rfile != NULL)
p->fcode = *fp;
else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
sprintf(p->errbuf, "BIOCSETF: %s", pcap_strerror(errno));
return (-1);
}
return (0);
}

848
pcap-dlpi.c Normal file
View File

@ -0,0 +1,848 @@
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk),
* University College London.
*/
/*
* Packet capture routine for dlpi under SunOS 5
*
* Notes:
*
* - Apparently the DLIOCRAW ioctl() is specific to SunOS.
*
* - There is a bug in bufmod(7) such that setting the snapshot
* length results in data being left of the front of the packet.
*
* - It might be desirable to use pfmod(7) to filter packets in the
* kernel.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.52 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#ifdef HAVE_SYS_BUFMOD_H
#include <sys/bufmod.h>
#endif
#include <sys/dlpi.h>
#ifdef HAVE_SYS_DLPI_EXT_H
#include <sys/dlpi_ext.h>
#endif
#ifdef HAVE_HPUX9
#include <sys/socket.h>
#endif
#ifdef DL_HP_PPA_ACK_OBS
#include <sys/stat.h>
#endif
#include <sys/stream.h>
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
#include <sys/systeminfo.h>
#endif
#ifdef HAVE_HPUX9
#include <net/if.h>
#endif
#include <ctype.h>
#ifdef HAVE_HPUX9
#include <nlist.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stropts.h>
#include <unistd.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#ifndef PCAP_DEV_PREFIX
#define PCAP_DEV_PREFIX "/dev"
#endif
#define MAXDLBUF 8192
/* Forwards */
static int dlattachreq(int, bpf_u_int32, char *);
static int dlbindack(int, char *, char *);
static int dlbindreq(int, bpf_u_int32, char *);
static int dlinfoack(int, char *, char *);
static int dlinforeq(int, char *);
static int dlokack(int, const char *, char *, char *);
static int recv_ack(int, int, const char *, char *, char *);
static int dlpromisconreq(int, bpf_u_int32, char *);
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
static char *get_release(bpf_u_int32 *, bpf_u_int32 *, bpf_u_int32 *);
#endif
static int send_request(int, char *, int, char *, char *);
#ifdef HAVE_SYS_BUFMOD_H
static int strioctl(int, int, int, char *);
#endif
#ifdef HAVE_HPUX9
static int dlpi_kread(int, off_t, void *, u_int, char *);
#endif
#ifdef HAVE_DEV_DLPI
static int get_dlpi_ppa(int, const char *, int, char *);
#endif
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
*ps = p->md.stat;
return (0);
}
/* XXX Needed by HP-UX (at least) */
static bpf_u_int32 ctlbuf[MAXDLBUF];
static struct strbuf ctl = {
MAXDLBUF,
0,
(char *)ctlbuf
};
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
register int cc, n, caplen, origlen;
register u_char *bp, *ep, *pk;
register struct bpf_insn *fcode;
#ifdef HAVE_SYS_BUFMOD_H
register struct sb_hdr *sbp;
#ifdef LBL_ALIGN
struct sb_hdr sbhdr;
#endif
#endif
int flags;
struct strbuf data;
struct pcap_pkthdr pkthdr;
flags = 0;
cc = p->cc;
if (cc == 0) {
data.buf = (char *)p->buffer + p->offset;
data.maxlen = MAXDLBUF;
data.len = 0;
do {
if (getmsg(p->fd, &ctl, &data, &flags) < 0) {
/* Don't choke when we get ptraced */
if (errno == EINTR) {
cc = 0;
continue;
}
strcpy(p->errbuf, pcap_strerror(errno));
return (-1);
}
cc = data.len;
} while (cc == 0);
bp = p->buffer + p->offset;
} else
bp = p->bp;
/* Loop through packets */
fcode = p->fcode.bf_insns;
ep = bp + cc;
n = 0;
#ifdef HAVE_SYS_BUFMOD_H
while (bp < ep) {
#ifdef LBL_ALIGN
if ((long)bp & 3) {
sbp = &sbhdr;
memcpy(sbp, bp, sizeof(*sbp));
} else
#endif
sbp = (struct sb_hdr *)bp;
p->md.stat.ps_drop += sbp->sbh_drops;
pk = bp + sizeof(*sbp);
bp += sbp->sbh_totlen;
origlen = sbp->sbh_origlen;
caplen = sbp->sbh_msglen;
#else
origlen = cc;
caplen = min(p->snapshot, cc);
pk = bp;
bp += caplen;
#endif
++p->md.stat.ps_recv;
if (bpf_filter(fcode, pk, origlen, caplen)) {
#ifdef HAVE_SYS_BUFMOD_H
pkthdr.ts = sbp->sbh_timestamp;
#else
(void)gettimeofday(&pkthdr.ts, NULL);
#endif
pkthdr.len = origlen;
pkthdr.caplen = caplen;
/* Insure caplen does not exceed snapshot */
if (pkthdr.caplen > p->snapshot)
pkthdr.caplen = p->snapshot;
(*callback)(user, &pkthdr, pk);
if (++n >= cnt && cnt >= 0) {
p->cc = ep - bp;
p->bp = bp;
return (n);
}
}
#ifdef HAVE_SYS_BUFMOD_H
}
#endif
p->cc = 0;
return (n);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
register char *cp;
char *eos;
register pcap_t *p;
register int ppa;
register dl_info_ack_t *infop;
#ifdef HAVE_SYS_BUFMOD_H
bpf_u_int32 ss, flag;
#ifdef HAVE_SOLARIS
register char *release;
bpf_u_int32 osmajor, osminor, osmicro;
#endif
#endif
bpf_u_int32 buf[MAXDLBUF];
char dname[100];
#ifndef HAVE_DEV_DLPI
char dname2[100];
#endif
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strcpy(ebuf, pcap_strerror(errno));
return (NULL);
}
memset(p, 0, sizeof(*p));
/*
** Determine device and ppa
*/
cp = strpbrk(device, "0123456789");
if (cp == NULL) {
sprintf(ebuf, "%s missing unit number", device);
goto bad;
}
ppa = strtol(cp, &eos, 10);
if (*eos != '\0') {
sprintf(ebuf, "%s bad unit number", device);
goto bad;
}
if (*device == '/')
strcpy(dname, device);
else
sprintf(dname, "%s/%s", PCAP_DEV_PREFIX, device);
#ifdef HAVE_DEV_DLPI
/* Map network device to /dev/dlpi unit */
cp = "/dev/dlpi";
if ((p->fd = open(cp, O_RDWR)) < 0) {
sprintf(ebuf, "%s: %s", cp, pcap_strerror(errno));
goto bad;
}
/* Map network interface to /dev/dlpi unit */
ppa = get_dlpi_ppa(p->fd, dname, ppa, ebuf);
if (ppa < 0)
goto bad;
#else
/* Try device without unit number */
strcpy(dname2, dname);
cp = strchr(dname, *cp);
*cp = '\0';
if ((p->fd = open(dname, O_RDWR)) < 0) {
if (errno != ENOENT) {
sprintf(ebuf, "%s: %s", dname, pcap_strerror(errno));
goto bad;
}
/* Try again with unit number */
if ((p->fd = open(dname2, O_RDWR)) < 0) {
sprintf(ebuf, "%s: %s", dname2, pcap_strerror(errno));
goto bad;
}
/* XXX Assume unit zero */
ppa = 0;
}
#endif
p->snapshot = snaplen;
/*
** Attach if "style 2" provider
*/
if (dlinforeq(p->fd, ebuf) < 0 ||
dlinfoack(p->fd, (char *)buf, ebuf) < 0)
goto bad;
infop = &((union DL_primitives *)buf)->info_ack;
if (infop->dl_provider_style == DL_STYLE2 &&
(dlattachreq(p->fd, ppa, ebuf) < 0 ||
dlokack(p->fd, "attach", (char *)buf, ebuf) < 0))
goto bad;
/*
** Bind (defer if using HP-UX 9 or HP-UX 10.20, totally skip if
** using SINIX)
*/
#if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20) && !defined(sinix)
if (dlbindreq(p->fd, 0, ebuf) < 0 ||
dlbindack(p->fd, (char *)buf, ebuf) < 0)
goto bad;
#endif
if (promisc) {
/*
** Enable promiscuous
*/
if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 ||
dlokack(p->fd, "promisc_phys", (char *)buf, ebuf) < 0)
goto bad;
/*
** Try to enable multicast (you would have thought
** promiscuous would be sufficient). (Skip if using
** HP-UX or SINIX)
*/
#if !defined(__hpux) && !defined(sinix)
if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 ||
dlokack(p->fd, "promisc_multi", (char *)buf, ebuf) < 0)
fprintf(stderr,
"WARNING: DL_PROMISC_MULTI failed (%s)\n", ebuf);
#endif
}
/*
** Try to enable sap (when not in promiscuous mode when using
** using HP-UX and never under SINIX)
*/
#ifndef sinix
if (
#ifdef __hpux
!promisc &&
#endif
(dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 ||
dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0)) {
/* Not fatal if promisc since the DL_PROMISC_PHYS worked */
if (promisc)
fprintf(stderr,
"WARNING: DL_PROMISC_SAP failed (%s)\n", ebuf);
else
goto bad;
}
#endif
/*
** HP-UX 9 and HP-UX 10.20 must bind after setting promiscuous
** options)
*/
#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20)
if (dlbindreq(p->fd, 0, ebuf) < 0 ||
dlbindack(p->fd, (char *)buf, ebuf) < 0)
goto bad;
#endif
/*
** Determine link type
*/
if (dlinforeq(p->fd, ebuf) < 0 ||
dlinfoack(p->fd, (char *)buf, ebuf) < 0)
goto bad;
infop = &((union DL_primitives *)buf)->info_ack;
switch (infop->dl_mac_type) {
case DL_CSMACD:
case DL_ETHER:
p->linktype = DLT_EN10MB;
p->offset = 2;
break;
case DL_FDDI:
p->linktype = DLT_FDDI;
p->offset = 3;
break;
default:
sprintf(ebuf, "unknown mac type 0x%lu", infop->dl_mac_type);
goto bad;
}
#ifdef DLIOCRAW
/*
** This is a non standard SunOS hack to get the ethernet header.
*/
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
sprintf(ebuf, "DLIOCRAW: %s", pcap_strerror(errno));
goto bad;
}
#endif
#ifdef HAVE_SYS_BUFMOD_H
/*
** Another non standard call to get the data nicely buffered
*/
if (ioctl(p->fd, I_PUSH, "bufmod") != 0) {
sprintf(ebuf, "I_PUSH bufmod: %s", pcap_strerror(errno));
goto bad;
}
/*
** Now that the bufmod is pushed lets configure it.
**
** There is a bug in bufmod(7). When dealing with messages of
** less than snaplen size it strips data from the beginning not
** the end.
**
** This bug is supposed to be fixed in 5.3.2. Also, there is a
** patch available. Ask for bugid 1149065.
*/
ss = snaplen;
#ifdef HAVE_SOLARIS
release = get_release(&osmajor, &osminor, &osmicro);
if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) &&
getenv("BUFMOD_FIXED") == NULL) {
fprintf(stderr,
"WARNING: bufmod is broken in SunOS %s; ignoring snaplen.\n",
release);
ss = 0;
}
#endif
if (ss > 0 &&
strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) {
sprintf(ebuf, "SBIOCSSNAP: %s", pcap_strerror(errno));
goto bad;
}
/*
** Set up the bufmod flags
*/
if (strioctl(p->fd, SBIOCGFLAGS, sizeof(flag), (char *)&flag) < 0) {
sprintf(ebuf, "SBIOCGFLAGS: %s", pcap_strerror(errno));
goto bad;
}
flag |= SB_NO_DROPS;
if (strioctl(p->fd, SBIOCSFLAGS, sizeof(flag), (char *)&flag) != 0) {
sprintf(ebuf, "SBIOCSFLAGS: %s", pcap_strerror(errno));
goto bad;
}
/*
** Set up the bufmod timeout
*/
if (to_ms != 0) {
struct timeval to;
to.tv_sec = to_ms / 1000;
to.tv_usec = (to_ms * 1000) % 1000000;
if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) {
sprintf(ebuf, "SBIOCSTIME: %s", pcap_strerror(errno));
goto bad;
}
}
#endif
/*
** As the last operation flush the read side.
*/
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
sprintf(ebuf, "FLUSHR: %s", pcap_strerror(errno));
goto bad;
}
/* Allocate data buffer */
p->bufsize = MAXDLBUF * sizeof(bpf_u_int32);
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
return (p);
bad:
free(p);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
p->fcode = *fp;
return (0);
}
static int
send_request(int fd, char *ptr, int len, char *what, char *ebuf)
{
struct strbuf ctl;
int flags;
ctl.maxlen = 0;
ctl.len = len;
ctl.buf = ptr;
flags = 0;
if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) {
sprintf(ebuf, "send_request: putmsg \"%s\": %s",
what, pcap_strerror(errno));
return (-1);
}
return (0);
}
static int
recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf)
{
union DL_primitives *dlp;
struct strbuf ctl;
int flags;
ctl.maxlen = MAXDLBUF;
ctl.len = 0;
ctl.buf = bufp;
flags = 0;
if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) {
sprintf(ebuf, "recv_ack: %s getmsg: %s",
what, pcap_strerror(errno));
return (-1);
}
dlp = (union DL_primitives *) ctl.buf;
switch (dlp->dl_primitive) {
case DL_INFO_ACK:
case DL_BIND_ACK:
case DL_OK_ACK:
#ifdef DL_HP_PPA_ACK
case DL_HP_PPA_ACK:
#endif
/* These are OK */
break;
case DL_ERROR_ACK:
switch (dlp->error_ack.dl_errno) {
case DL_BADPPA:
sprintf(ebuf, "recv_ack: %s bad ppa (device unit)",
what);
break;
case DL_SYSERR:
sprintf(ebuf, "recv_ack: %s: %s",
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
break;
case DL_UNSUPPORTED:
sprintf(ebuf,
"recv_ack: %s: Service not supplied by provider",
what);
break;
default:
sprintf(ebuf, "recv_ack: %s error 0x%x",
what, (bpf_u_int32)dlp->error_ack.dl_errno);
break;
}
return (-1);
default:
sprintf(ebuf, "recv_ack: %s unexpected primitive ack 0x%x ",
what, (bpf_u_int32)dlp->dl_primitive);
return (-1);
}
if (ctl.len < size) {
sprintf(ebuf, "recv_ack: %s ack too small (%d < %d)",
what, ctl.len, size);
return (-1);
}
return (ctl.len);
}
static int
dlattachreq(int fd, bpf_u_int32 ppa, char *ebuf)
{
dl_attach_req_t req;
req.dl_primitive = DL_ATTACH_REQ;
req.dl_ppa = ppa;
return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf));
}
static int
dlbindreq(int fd, bpf_u_int32 sap, char *ebuf)
{
dl_bind_req_t req;
memset((char *)&req, 0, sizeof(req));
req.dl_primitive = DL_BIND_REQ;
#ifdef DL_HP_RAWDLS
req.dl_max_conind = 1; /* XXX magic number */
/* 22 is INSAP as per the HP-UX DLPI Programmer's Guide */
req.dl_sap = 22;
req.dl_service_mode = DL_HP_RAWDLS;
#else
req.dl_sap = sap;
#ifdef DL_CLDLS
req.dl_service_mode = DL_CLDLS;
#endif
#endif
return (send_request(fd, (char *)&req, sizeof(req), "bind", ebuf));
}
static int
dlbindack(int fd, char *bufp, char *ebuf)
{
return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf));
}
static int
dlpromisconreq(int fd, bpf_u_int32 level, char *ebuf)
{
dl_promiscon_req_t req;
req.dl_primitive = DL_PROMISCON_REQ;
req.dl_level = level;
return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf));
}
static int
dlokack(int fd, const char *what, char *bufp, char *ebuf)
{
return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf));
}
static int
dlinforeq(int fd, char *ebuf)
{
dl_info_req_t req;
req.dl_primitive = DL_INFO_REQ;
return (send_request(fd, (char *)&req, sizeof(req), "info", ebuf));
}
static int
dlinfoack(int fd, char *bufp, char *ebuf)
{
return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf));
}
#ifdef HAVE_SYS_BUFMOD_H
static int
strioctl(int fd, int cmd, int len, char *dp)
{
struct strioctl str;
int rc;
str.ic_cmd = cmd;
str.ic_timout = -1;
str.ic_len = len;
str.ic_dp = dp;
rc = ioctl(fd, I_STR, &str);
if (rc < 0)
return (rc);
else
return (str.ic_len);
}
#endif
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
static char *
get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp)
{
char *cp;
static char buf[32];
*majorp = 0;
*minorp = 0;
*microp = 0;
if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0)
return ("?");
cp = buf;
if (!isdigit(*cp))
return (buf);
*majorp = strtol(cp, &cp, 10);
if (*cp++ != '.')
return (buf);
*minorp = strtol(cp, &cp, 10);
if (*cp++ != '.')
return (buf);
*microp = strtol(cp, &cp, 10);
return (buf);
}
#endif
#ifdef DL_HP_PPA_ACK_OBS
/*
* Under HP-UX 10, we can ask for the ppa
*/
/* Determine ppa number that specifies ifname */
static int
get_dlpi_ppa(register int fd, register const char *device, register int unit,
register char *ebuf)
{
register dl_hp_ppa_ack_t *ap;
register dl_hp_ppa_info_t *ip;
register int i;
register u_long majdev;
dl_hp_ppa_req_t req;
struct stat statbuf;
bpf_u_int32 buf[MAXDLBUF];
if (stat(device, &statbuf) < 0) {
sprintf(ebuf, "stat: %s: %s", device, pcap_strerror(errno));
return (-1);
}
majdev = major(statbuf.st_rdev);
memset((char *)&req, 0, sizeof(req));
req.dl_primitive = DL_HP_PPA_REQ;
memset((char *)buf, 0, sizeof(buf));
if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0 ||
recv_ack(fd, DL_HP_PPA_ACK_SIZE, "hpppa", (char *)buf, ebuf) < 0)
return (-1);
ap = (dl_hp_ppa_ack_t *)buf;
ip = (dl_hp_ppa_info_t *)((u_char *)ap + ap->dl_offset);
for(i = 0; i < ap->dl_count; i++) {
if (ip->dl_mjr_num == majdev && ip->dl_instance_num == unit)
break;
ip = (dl_hp_ppa_info_t *)((u_char *)ip + ip->dl_next_offset);
}
if (i == ap->dl_count) {
sprintf(ebuf, "can't find PPA for %s", device);
return (-1);
}
if (ip->dl_hdw_state == HDW_DEAD) {
sprintf(ebuf, "%s: hardware state: DOWN\n", device);
return (-1);
}
return ((int)ip->dl_ppa);
}
#endif
#ifdef HAVE_HPUX9
/*
* Under HP-UX 9, there is no good way to determine the ppa.
* So punt and read it from /dev/kmem.
*/
static struct nlist nl[] = {
#define NL_IFNET 0
{ "ifnet" },
{ "" }
};
static char path_vmunix[] = "/hp-ux";
/* Determine ppa number that specifies ifname */
static int
get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
register char *ebuf)
{
register const char *cp;
register int kd;
void *addr;
struct ifnet ifnet;
char if_name[sizeof(ifnet.if_name)], tifname[32];
cp = strrchr(ifname, '/');
if (cp != NULL)
ifname = cp + 1;
if (nlist(path_vmunix, &nl) < 0) {
sprintf(ebuf, "nlist %s failed", path_vmunix);
return (-1);
}
if (nl[NL_IFNET].n_value == 0) {
sprintf(ebuf, "could't find %s kernel symbol",
nl[NL_IFNET].n_name);
return (-1);
}
kd = open("/dev/kmem", O_RDONLY);
if (kd < 0) {
sprintf(ebuf, "kmem open: %s", pcap_strerror(errno));
return (-1);
}
if (dlpi_kread(kd, nl[NL_IFNET].n_value,
&addr, sizeof(addr), ebuf) < 0) {
close(kd);
return (-1);
}
for (; addr != NULL; addr = ifnet.if_next) {
if (dlpi_kread(kd, (off_t)addr,
&ifnet, sizeof(ifnet), ebuf) < 0 ||
dlpi_kread(kd, (off_t)ifnet.if_name,
if_name, sizeof(if_name), ebuf) < 0) {
(void)close(kd);
return (-1);
}
sprintf(tifname, "%.*s%d",
(int)sizeof(if_name), if_name, ifnet.if_unit);
if (strcmp(tifname, ifname) == 0)
return (ifnet.if_index);
}
sprintf(ebuf, "Can't find %s", ifname);
return (-1);
}
static int
dlpi_kread(register int fd, register off_t addr,
register void *buf, register u_int len, register char *ebuf)
{
register int cc;
if (lseek(fd, addr, SEEK_SET) < 0) {
sprintf(ebuf, "lseek: %s", pcap_strerror(errno));
return (-1);
}
cc = read(fd, buf, len);
if (cc < 0) {
sprintf(ebuf, "read: %s", pcap_strerror(errno));
return (-1);
} else if (cc != len) {
sprintf(ebuf, "short read (%d != %d)", cc, len);
return (-1);
}
return (cc);
}
#endif

227
pcap-enet.c Normal file
View File

@ -0,0 +1,227 @@
/*
* Stanford Enetfilter subroutines for tcpdump
*
* Based on the MERIT NNstat etherifrt.c and the Ultrix pcap-pf.c
* subroutines.
*
* Rayan Zachariassen, CA*Net
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/bpf.h>
#include <net/enet.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <stdio.h>
#include <errno.h>
#include "interface.h"
struct packet_header {
#ifdef IBMRTPC
struct LengthWords length;
struct tap_header tap;
#endif /* IBMRTPC */
u_char packet[8]
};
extern int errno;
#define BUFSPACE (4*1024)
/* Forwards */
static void efReadError(int, char *);
void
readloop(int cnt, int if_fd, struct bpf_program *fp, printfunc printit)
{
#ifdef IBMRTPC
register struct packet_header *ph;
register u_char *bp;
register int inc;
#else /* !IBMRTPC */
static struct timeval tv = { 0 };
#endif /* IBMRTPC */
register int cc, caplen;
register struct bpf_insn *fcode = fp->bf_insns;
union {
struct packet_header hdr;
u_char p[BUFSPACE];
u_short s;
} buf;
while (1) {
if ((cc = read(if_fd, (char *)buf.p, sizeof(buf))) < 0)
efReadError(if_fd, "reader");
#ifdef IBMRTPC
/*
* Loop through each packet.
*/
bp = buf.p;
while (cc > 0) {
ph = (struct packet_header *)bp;
caplen = ph->tap.th_wirelen > snaplen ? snaplen : ph->tap
.th_wirelen ;
if (bpf_filter(fcode, (char *)ph->packet,
ph->tap.th_wirelen, caplen)) {
if (cnt >= 0 && --cnt < 0)
goto out;
(*printit)((char *)ph->packet,
(struct timeval *)ph->tap.th_timestamp,
ph->tap.th_wirelen, caplen);
}
inc = ph->length.PacketOffset;
cc -= inc;
bp += inc;
}
#else /* !IBMRTPC */
caplen = cc > snaplen ? snaplen : cc ;
if (bpf_filter(fcode, buf.hdr.packet, cc, caplen)) {
if (cnt >= 0 && --cnt < 0)
goto out;
(*printit)(buf.hdr.packet, &tv, cc, caplen);
}
#endif /* IBMRTPC */
}
out:
wrapup(if_fd);
}
/* Call ONLY if read() has returned an error on packet filter */
static void
efReadError(int fid, char *msg)
{
if (errno == EINVAL) { /* read MAXINT bytes already! */
if (lseek(fid, 0, 0) < 0) {
perror("tcpdump: efReadError/lseek");
exit(-1);
}
else
return;
}
else {
(void) fprintf(stderr, "tcpdump: ");
perror(msg);
exit(-1);
}
}
void
wrapup(int fd)
{
#ifdef IBMRTPC
struct enstats es;
if (ioctl(fd, EIOSTATS, &es) == -1) {
perror("tcpdump: enet ioctl EIOSTATS error");
exit(-1);
}
fprintf(stderr, "%d packets queued", es.enStat_Rcnt);
if (es.enStat_Rdrops > 0)
fprintf(stderr, ", %d dropped", es.enStat_Rdrops);
if (es.enStat_Reads > 0)
fprintf(stderr, ", %d tcpdump %s", es.enStat_Reads,
es.enStat_Reads > 1 ? "reads" : "read");
if (es.enStat_MaxRead > 1)
fprintf(stderr, ", %d packets in largest read",
es.enStat_MaxRead);
putc('\n', stderr);
#endif /* IBMRTPC */
close(fd);
}
int
initdevice(char *device, int pflag, int *linktype)
{
struct eniocb ctl;
struct enfilter filter;
u_int maxwaiting;
int if_fd;
#ifdef IBMRTPC
GETENETDEVICE(0, O_RDONLY, &if_fd);
#else /* !IBMRTPC */
if_fd = open("/dev/enet", O_RDONLY, 0);
#endif /* IBMRTPC */
if (if_fd == -1) {
perror("tcpdump: enet open error");
error(
"your system may not be properly configured; see \"man enet(4)\"");
exit(-1);
}
/* Get operating parameters. */
if (ioctl(if_fd, EIOCGETP, (char *)&ctl) == -1) {
perror("tcpdump: enet ioctl EIOCGETP error");
exit(-1);
}
/* Set operating parameters. */
#ifdef IBMRTPC
ctl.en_rtout = 1 * ctl.en_hz;
ctl.en_tr_etherhead = 1;
ctl.en_tap_network = 1;
ctl.en_multi_packet = 1;
ctl.en_maxlen = BUFSPACE;
#else /* !IBMRTPC */
ctl.en_rtout = 64; /* randomly picked value for HZ */
#endif /* IBMRTPC */
if (ioctl(if_fd, EIOCSETP, &ctl) == -1) {
perror("tcpdump: enet ioctl EIOCSETP error");
exit(-1);
}
/* Flush the receive queue, since we've changed
the operating parameters and we otherwise might
receive data without headers. */
if (ioctl(if_fd, EIOCFLUSH) == -1) {
perror("tcpdump: enet ioctl EIOCFLUSH error");
exit(-1);
}
/* Set the receive queue depth to its maximum. */
maxwaiting = ctl.en_maxwaiting;
if (ioctl(if_fd, EIOCSETW, &maxwaiting) == -1) {
perror("tcpdump: enet ioctl EIOCSETW error");
exit(-1);
}
#ifdef IBMRTPC
/* Clear statistics. */
if (ioctl(if_fd, EIOCLRSTAT, 0) == -1) {
perror("tcpdump: enet ioctl EIOCLRSTAT error");
exit(-1);
}
#endif /* IBMRTPC */
/* Set the filter (accept all packets). */
filter.enf_Priority = 3;
filter.enf_FilterLen = 0;
if (ioctl(if_fd, EIOCSETF, &filter) == -1) {
perror("tcpdump: enet ioctl EIOCSETF error");
exit(-1);
}
/*
* "enetfilter" supports only ethernets.
*/
*linktype = DLT_EN10MB;
return(if_fd);
}

117
pcap-int.h Normal file
View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory 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.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.18 1999-10-07 23:46:40 mcr Exp $ (LBL)
*/
#ifndef pcap_int_h
#define pcap_int_h
#include <pcap.h>
/*
* Savefile
*/
struct pcap_sf {
FILE *rfile;
int swapped;
int version_major;
int version_minor;
u_char *base;
};
struct pcap_md {
struct pcap_stat stat;
/*XXX*/
int use_bpf;
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;
#endif
};
struct pcap {
int fd;
int snapshot;
int linktype;
int tzoff; /* timezone offset */
int offset; /* offset for proper alignment */
struct pcap_sf sf;
struct pcap_md md;
/*
* Read buffer.
*/
int bufsize;
u_char *buffer;
u_char *bp;
int cc;
/*
* Place holder for pcap_next().
*/
u_char *pkt;
/*
* Placeholder for filter code if bpf not in kernel.
*/
struct bpf_program fcode;
char errbuf[PCAP_ERRBUF_SIZE];
};
int yylex(void);
#ifndef min
#define min(a, b) ((a) > (b) ? (b) : (a))
#endif
/* XXX should these be in pcap.h? */
int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
/* Ultrix pads to make everything line up on a nice boundary */
#if defined(ultrix) || defined(__alpha)
#define PCAP_FDDIPAD 3
#endif
/* XXX */
extern int pcap_fddipad;
#endif

331
pcap-linux.c Normal file
View File

@ -0,0 +1,331 @@
/*
* Copyright (c) 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.15 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <net/if.h>
#ifdef HAVE_NET_IF_ARP_H
#include <net/if_arp.h>
#else
#include <linux/if_arp.h>
#endif
#include <linux/if_ether.h>
#include <netinet/in.h>
#include <errno.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static struct ifreq saved_ifr;
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
void linux_restore_ifr(void);
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
*ps = p->md.stat;
return (0);
}
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
register int cc;
register int bufsize;
register int caplen;
register u_char *bp;
struct sockaddr from;
int fromlen;
bp = p->buffer + p->offset;
bufsize = p->bufsize;
if (p->md.pad > 0) {
memset(bp, 0, p->md.pad);
bp += p->md.pad;
bufsize -= p->md.pad;
}
again:
do {
fromlen = sizeof(from);
cc = recvfrom(p->fd, bp, bufsize, 0, &from, &fromlen);
if (cc < 0) {
/* Don't choke when we get ptraced */
switch (errno) {
case EINTR:
goto again;
case EWOULDBLOCK:
return (0); /* XXX */
}
sprintf(p->errbuf, "read: %s", pcap_strerror(errno));
return (-1);
}
} while (strcmp(p->md.device, from.sa_data));
/* If we need have leading zero bytes, adjust count */
cc += p->md.pad;
bp = p->buffer + p->offset;
/* If we need to step over leading junk, adjust count and pointer */
cc -= p->md.skip;
bp += p->md.skip;
/* Captured length can't exceed our read buffer size */
caplen = cc;
if (caplen > bufsize)
caplen = bufsize;
/* Captured length can't exceed the snapshot length */
if (caplen > p->snapshot)
caplen = p->snapshot;
if (p->fcode.bf_insns == NULL ||
bpf_filter(p->fcode.bf_insns, bp, cc, caplen)) {
struct pcap_pkthdr h;
++p->md.stat.ps_recv;
/* Get timestamp */
if (ioctl(p->fd, SIOCGSTAMP, &h.ts) < 0) {
sprintf(p->errbuf, "SIOCGSTAMP: %s",
pcap_strerror(errno));
return (-1);
}
h.len = cc;
h.caplen = caplen;
(*callback)(user, &h, bp);
return (1);
}
return (0);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
register int fd, broadcast;
register pcap_t *p;
struct ifreq ifr;
struct sockaddr sa;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
return (NULL);
}
memset(p, 0, sizeof(*p));
fd = -1;
fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
if (fd < 0) {
sprintf(ebuf, "socket: %s", pcap_strerror(errno));
goto bad;
}
p->fd = fd;
/* Bind to the interface name */
memset(&sa, 0, sizeof(sa));
sa.sa_family = AF_INET;
(void)strncpy(sa.sa_data, device, sizeof(sa.sa_data));
if (bind(p->fd, &sa, sizeof(sa))) {
sprintf(ebuf, "bind: %s: %s", device, pcap_strerror(errno));
goto bad;
}
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(p->fd, SIOCGIFHWADDR, &ifr) < 0 ) {
sprintf(ebuf, "SIOCGIFHWADDR: %s", pcap_strerror(errno));
goto bad;
}
broadcast = 0;
switch (ifr.ifr_hwaddr.sa_family) {
case ARPHRD_ETHER:
case ARPHRD_METRICOM:
p->linktype = DLT_EN10MB;
p->offset = 2;
++broadcast;
break;
case ARPHRD_EETHER:
p->linktype = DLT_EN3MB;
++broadcast;
break;
case ARPHRD_AX25:
p->linktype = DLT_AX25;
++broadcast;
break;
case ARPHRD_PRONET:
p->linktype = DLT_PRONET;
break;
case ARPHRD_CHAOS:
p->linktype = DLT_CHAOS;
break;
case ARPHRD_IEEE802:
p->linktype = DLT_IEEE802;
++broadcast;
break;
case ARPHRD_ARCNET:
p->linktype = DLT_ARCNET;
++broadcast;
break;
case ARPHRD_SLIP:
case ARPHRD_CSLIP:
case ARPHRD_SLIP6:
case ARPHRD_CSLIP6:
case ARPHRD_PPP:
p->linktype = DLT_RAW;
break;
case ARPHRD_LOOPBACK:
p->linktype = DLT_NULL;
p->md.pad = 2;
p->md.skip = 12;
break;
#ifdef ARPHRD_FDDI
/* Not all versions of the kernel has this define */
case ARPHRD_FDDI:
p->linktype = DLT_FDDI;
++broadcast;
break;
#endif
#ifdef notdef
case ARPHRD_LOCALTLK:
case ARPHRD_NETROM:
case ARPHRD_APPLETLK:
case ARPHRD_DLCI:
case ARPHRD_RSRVD:
case ARPHRD_ADAPT:
case ARPHRD_TUNNEL:
case ARPHRD_TUNNEL6:
case ARPHRD_FRAD:
case ARPHRD_SKIP:
/* XXX currently do not know what to do with these... */
abort();
#endif
default:
sprintf(ebuf, "unknown physical layer type 0x%x",
ifr.ifr_hwaddr.sa_family);
goto bad;
}
/* Base the buffer size on the interface MTU */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(p->fd, SIOCGIFMTU, &ifr) < 0 ) {
sprintf(ebuf, "SIOCGIFMTU: %s", pcap_strerror(errno));
goto bad;
}
/* Leave room for link header (which is never large under linux...) */
p->bufsize = ifr.ifr_mtu + 64;
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
goto bad;
}
/* XXX */
if (promisc && broadcast) {
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, device);
if (ioctl(p->fd, SIOCGIFFLAGS, &ifr) < 0 ) {
sprintf(ebuf, "SIOCGIFFLAGS: %s", pcap_strerror(errno));
goto bad;
}
saved_ifr = ifr;
ifr.ifr_flags |= IFF_PROMISC;
if (ioctl(p->fd, SIOCSIFFLAGS, &ifr) < 0 ) {
sprintf(ebuf, "SIOCSIFFLAGS: %s", pcap_strerror(errno));
goto bad;
}
ifr.ifr_flags &= ~IFF_PROMISC;
atexit(linux_restore_ifr);
}
p->md.device = strdup(device);
if (p->md.device == NULL) {
sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
return (p);
bad:
if (fd >= 0)
(void)close(fd);
if (p->buffer != NULL)
free(p->buffer);
if (p->md.device != NULL)
free(p->md.device);
free(p);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
p->fcode = *fp;
return (0);
}
void
linux_restore_ifr(void)
{
register int fd;
fd = socket(PF_INET, SOCK_PACKET, htons(0x0003));
if (fd < 0)
fprintf(stderr, "linux socket: %s", pcap_strerror(errno));
else if (ioctl(fd, SIOCSIFFLAGS, &saved_ifr) < 0)
fprintf(stderr, "linux SIOCSIFFLAGS: %s", pcap_strerror(errno));
}

76
pcap-namedb.h Normal file
View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 1994, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory 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.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.5 1999-10-07 23:46:40 mcr Exp $ (LBL)
*/
#ifndef lib_pcap_ethers_h
#define lib_pcap_ethers_h
/*
* As returned by the pcap_next_etherent()
* XXX this stuff doesn't belong in this interface, but this
* library already must do name to address translation, so
* on systems that don't have support for /etc/ethers, we
* export these hooks since they'll
*/
struct pcap_etherent {
u_char addr[6];
char name[122];
};
#ifndef PCAP_ETHERS_FILE
#define PCAP_ETHERS_FILE "/etc/ethers"
#endif
struct pcap_etherent *pcap_next_etherent(FILE *);
u_char *pcap_ether_hostton(const char*);
u_char *pcap_ether_aton(const char *);
bpf_u_int32 **pcap_nametoaddr(const char *);
bpf_u_int32 pcap_nametonetaddr(const char *);
int pcap_nametoport(const char *, int *, int *);
int pcap_nametoproto(const char *);
int pcap_nametoeproto(const char *);
/*
* If a protocol is unknown, PROTO_UNDEF is returned.
* Also, pcap_nametoport() returns the protocol along with the port number.
* If there are ambiguous entried in /etc/services (i.e. domain
* can be either tcp or udp) PROTO_UNDEF is returned.
*/
#define PROTO_UNDEF -1
/* XXX move these to pcap-int.h? */
int __pcap_atodn(const char *, bpf_u_int32 *);
int __pcap_atoin(const char *, bpf_u_int32 *);
u_short __pcap_nametodnaddr(const char *);
#endif

244
pcap-nit.c Normal file
View File

@ -0,0 +1,244 @@
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.31 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/nit.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/*
* The chunk size for NIT. This is the amount of buffering
* done for read calls.
*/
#define CHUNKSIZE (2*1024)
/*
* The total buffer space used by NIT.
*/
#define BUFSPACE (4*CHUNKSIZE)
/* Forwards */
static int nit_setflags(int, int, int, char *);
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
*ps = p->md.stat;
return (0);
}
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
register int cc, n;
register struct bpf_insn *fcode = p->fcode.bf_insns;
register u_char *bp, *cp, *ep;
register struct nit_hdr *nh;
register int caplen;
cc = p->cc;
if (cc == 0) {
cc = read(p->fd, (char *)p->buffer, p->bufsize);
if (cc < 0) {
if (errno == EWOULDBLOCK)
return (0);
sprintf(p->errbuf, "pcap_read: %s",
pcap_strerror(errno));
return (-1);
}
bp = p->buffer;
} else
bp = p->bp;
/*
* Loop through each packet. The increment expression
* rounds up to the next int boundary past the end of
* the previous packet.
*/
n = 0;
ep = bp + cc;
while (bp < ep) {
nh = (struct nit_hdr *)bp;
cp = bp + sizeof(*nh);
switch (nh->nh_state) {
case NIT_CATCH:
break;
case NIT_NOMBUF:
case NIT_NOCLUSTER:
case NIT_NOSPACE:
p->md.stat.ps_drop = nh->nh_dropped;
continue;
case NIT_SEQNO:
continue;
default:
sprintf(p->errbuf, "bad nit state %d", nh->nh_state);
return (-1);
}
++p->md.stat.ps_recv;
bp += ((sizeof(struct nit_hdr) + nh->nh_datalen +
sizeof(int) - 1) & ~(sizeof(int) - 1));
caplen = nh->nh_wirelen;
if (caplen > p->snapshot)
caplen = p->snapshot;
if (bpf_filter(fcode, cp, nh->nh_wirelen, caplen)) {
struct pcap_pkthdr h;
h.ts = nh->nh_timestamp;
h.len = nh->nh_wirelen;
h.caplen = caplen;
(*callback)(user, &h, cp);
if (++n >= cnt && cnt >= 0) {
p->cc = ep - bp;
p->bp = bp;
return (n);
}
}
}
p->cc = 0;
return (n);
}
static int
nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
{
struct nit_ioc nioc;
bzero((char *)&nioc, sizeof(nioc));
nioc.nioc_bufspace = BUFSPACE;
nioc.nioc_chunksize = CHUNKSIZE;
nioc.nioc_typetomatch = NT_ALLTYPES;
nioc.nioc_snaplen = p->snapshot;
nioc.nioc_bufalign = sizeof(int);
nioc.nioc_bufoffset = 0;
if (to_ms != 0) {
nioc.nioc_flags |= NF_TIMEOUT;
nioc.nioc_timeout.tv_sec = to_ms / 1000;
nioc.nioc_timeout.tv_usec = (to_ms * 1000) % 1000000;
}
if (promisc)
nioc.nioc_flags |= NF_PROMISC;
if (ioctl(fd, SIOCSNIT, &nioc) < 0) {
sprintf(ebuf, "SIOCSNIT: %s", pcap_strerror(errno));
return (-1);
}
return (0);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
int fd;
struct sockaddr_nit snit;
register pcap_t *p;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strcpy(ebuf, pcap_strerror(errno));
return (NULL);
}
if (snaplen < 96)
/*
* NIT requires a snapshot length of at least 96.
*/
snaplen = 96;
bzero(p, sizeof(*p));
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
if (fd < 0) {
sprintf(ebuf, "socket: %s", pcap_strerror(errno));
goto bad;
}
snit.snit_family = AF_NIT;
(void)strncpy(snit.snit_ifname, device, NITIFSIZ);
if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) {
sprintf(ebuf, "bind: %s: %s", snit.snit_ifname,
pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
nit_setflags(p->fd, promisc, to_ms, ebuf);
/*
* NIT supports only ethernets.
*/
p->linktype = DLT_EN10MB;
p->bufsize = BUFSPACE;
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
strcpy(ebuf, pcap_strerror(errno));
goto bad;
}
return (p);
bad:
if (fd >= 0)
close(fd);
free(p);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
p->fcode = *fp;
return (0);
}

19
pcap-nit.h Normal file
View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 1990, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Lawrence Berkeley Laboratory,
* Berkeley, CA. The name of the University may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/Attic/pcap-nit.h,v 1.2 1999-10-07 23:46:40 mcr Exp $ (LBL)
*/

73
pcap-null.c Normal file
View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.7 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/param.h> /* optionally get BSD define */
#include <string.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include "pcap-int.h"
static char nosup[] = "live packet capture not supported on this system";
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
(void)sprintf(p->errbuf, "pcap_stats: %s", nosup);
return (-1);
}
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
(void)sprintf(p->errbuf, "pcap_read: %s", nosup);
return (-1);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
(void)strcpy(ebuf, nosup);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
if (p->sf.rfile == NULL) {
(void)sprintf(p->errbuf, "pcap_setfilter: %s", nosup);
return (-1);
}
p->fcode = *fp;
return (0);
}

351
pcap-pf.c Normal file
View File

@ -0,0 +1,351 @@
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* packet filter subroutines for tcpdump
* Extraction/creation by Jeffrey Mogul, DECWRL
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.54 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <net/pfilt.h>
#if __STDC__
struct mbuf;
struct rtentry;
#endif
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/*
* BUFSPACE is the size in bytes of the packet read buffer. Most tcpdump
* applications aren't going to need more than 200 bytes of packet header
* and the read shouldn't return more packets than packetfilter's internal
* queue limit (bounded at 256).
*/
#define BUFSPACE (200 * 256)
int
pcap_read(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
{
register u_char *p, *bp;
struct bpf_insn *fcode;
register int cc, n, buflen, inc;
register struct enstamp *sp;
#ifdef LBL_ALIGN
struct enstamp stamp;
#endif
#ifdef PCAP_FDDIPAD
register int pad;
#endif
fcode = pc->md.use_bpf ? NULL : pc->fcode.bf_insns;
again:
cc = pc->cc;
if (cc == 0) {
cc = read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize);
if (cc < 0) {
if (errno == EWOULDBLOCK)
return (0);
if (errno == EINVAL &&
lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) {
/*
* Due to a kernel bug, after 2^31 bytes,
* the kernel file offset overflows and
* read fails with EINVAL. The lseek()
* to 0 will fix things.
*/
(void)lseek(pc->fd, 0L, SEEK_SET);
goto again;
}
sprintf(pc->errbuf, "pf read: %s",
pcap_strerror(errno));
return (-1);
}
bp = pc->buffer + pc->offset;
} else
bp = pc->bp;
/*
* Loop through each packet.
*/
n = 0;
#ifdef PCAP_FDDIPAD
if (pc->linktype == DLT_FDDI)
pad = pcap_fddipad;
else
pad = 0;
#endif
while (cc > 0) {
if (cc < sizeof(*sp)) {
sprintf(pc->errbuf, "pf short read (%d)", cc);
return (-1);
}
#ifdef LBL_ALIGN
if ((long)bp & 3) {
sp = &stamp;
memcpy((char *)sp, (char *)bp, sizeof(*sp));
} else
#endif
sp = (struct enstamp *)bp;
if (sp->ens_stamplen != sizeof(*sp)) {
sprintf(pc->errbuf, "pf short stamplen (%d)",
sp->ens_stamplen);
return (-1);
}
p = bp + sp->ens_stamplen;
buflen = sp->ens_count;
if (buflen > pc->snapshot)
buflen = pc->snapshot;
/* Calculate inc before possible pad update */
inc = ENALIGN(buflen + sp->ens_stamplen);
cc -= inc;
bp += inc;
#ifdef PCAP_FDDIPAD
p += pad;
buflen -= pad;
#endif
pc->md.TotPkts++;
pc->md.TotDrops += sp->ens_dropped;
pc->md.TotMissed = sp->ens_ifoverflows;
if (pc->md.OrigMissed < 0)
pc->md.OrigMissed = pc->md.TotMissed;
/*
* Short-circuit evaluation: if using BPF filter
* in kernel, no need to do it now.
*/
if (fcode == NULL ||
bpf_filter(fcode, p, sp->ens_count, buflen)) {
struct pcap_pkthdr h;
pc->md.TotAccepted++;
h.ts = sp->ens_tstamp;
#ifdef PCAP_FDDIPAD
h.len = sp->ens_count - pad;
#else
h.len = sp->ens_count;
#endif
h.caplen = buflen;
(*callback)(user, &h, p);
if (++n >= cnt && cnt > 0) {
pc->cc = cc;
pc->bp = bp;
return (n);
}
}
}
pc->cc = 0;
return (n);
}
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
ps->ps_recv = p->md.TotAccepted;
ps->ps_drop = p->md.TotDrops;
ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed;
return (0);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
pcap_t *p;
short enmode;
int backlog = -1; /* request the most */
struct enfilter Filter;
struct endevp devparams;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
sprintf(ebuf, "pcap_open_live: %s", pcap_strerror(errno));
return (0);
}
bzero((char *)p, sizeof(*p));
p->fd = pfopen(device, O_RDONLY);
if (p->fd < 0) {
sprintf(ebuf, "pf open: %s: %s\n\
your system may not be properly configured; see \"man packetfilter(4)\"\n",
device, pcap_strerror(errno));
goto bad;
}
p->md.OrigMissed = -1;
enmode = ENTSTAMP|ENBATCH|ENNONEXCL;
if (promisc)
enmode |= ENPROMISC;
if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
sprintf(ebuf, "EIOCMBIS: %s", pcap_strerror(errno));
goto bad;
}
#ifdef ENCOPYALL
/* Try to set COPYALL mode so that we see packets to ourself */
enmode = ENCOPYALL;
(void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */
#endif
/* set the backlog */
if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
sprintf(ebuf, "EIOCSETW: %s", pcap_strerror(errno));
goto bad;
}
/* discover interface type */
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
sprintf(ebuf, "EIOCDEVP: %s", pcap_strerror(errno));
goto bad;
}
/* HACK: to compile prior to Ultrix 4.2 */
#ifndef ENDT_FDDI
#define ENDT_FDDI 4
#endif
switch (devparams.end_dev_type) {
case ENDT_10MB:
p->linktype = DLT_EN10MB;
p->offset = 2;
break;
case ENDT_FDDI:
p->linktype = DLT_FDDI;
break;
default:
/*
* XXX
* Currently, the Ultrix packet filter supports only
* Ethernet and FDDI. Eventually, support for SLIP and PPP
* (and possibly others: T1?) should be added.
*/
#ifdef notdef
warning(
"Packet filter data-link type %d unknown, assuming Ethernet",
devparams.end_dev_type);
#endif
p->linktype = DLT_EN10MB;
p->offset = 2;
break;
}
/* set truncation */
#ifdef PCAP_FDDIPAD
if (p->linktype == DLT_FDDI)
/* packetfilter includes the padding in the snapshot */
snaplen += pcap_fddipad;
#endif
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) {
sprintf(ebuf, "EIOCTRUNCATE: %s", pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
/* accept all packets */
bzero((char *)&Filter, sizeof(Filter));
Filter.enf_Priority = 37; /* anything > 2 */
Filter.enf_FilterLen = 0; /* means "always true" */
if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
sprintf(ebuf, "EIOCSETF: %s", pcap_strerror(errno));
goto bad;
}
if (to_ms != 0) {
struct timeval timeout;
timeout.tv_sec = to_ms / 1000;
timeout.tv_usec = (to_ms * 1000) % 1000000;
if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
sprintf(ebuf, "EIOCSRTIMEOUT: %s",
pcap_strerror(errno));
goto bad;
}
}
p->bufsize = BUFSPACE;
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
return (p);
bad:
free(p);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
/*
* See if BIOCSETF works. If it does, the kernel supports
* BPF-style filters, and we do not need to do post-filtering.
*/
p->md.use_bpf = (ioctl(p->fd, BIOCSETF, (caddr_t)fp) >= 0);
if (p->md.use_bpf) {
struct bpf_version bv;
if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) < 0) {
sprintf(p->errbuf, "BIOCVERSION: %s",
pcap_strerror(errno));
return (-1);
}
else if (bv.bv_major != BPF_MAJOR_VERSION ||
bv.bv_minor < BPF_MINOR_VERSION) {
fprintf(stderr,
"requires bpf language %d.%d or higher; kernel is %d.%d",
BPF_MAJOR_VERSION, BPF_MINOR_VERSION,
bv.bv_major, bv.bv_minor);
/* don't give up, just be inefficient */
p->md.use_bpf = 0;
}
} else
p->fcode = *fp;
/*XXX this goes in tcpdump*/
if (p->md.use_bpf)
fprintf(stderr, "tcpdump: Using kernel BPF filter\n");
else
fprintf(stderr, "tcpdump: Filtering in user process\n");
return (0);
}

19
pcap-pf.h Normal file
View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 1990, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Lawrence Berkeley Laboratory,
* Berkeley, CA. The name of the University may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/Attic/pcap-pf.h,v 1.2 1999-10-07 23:46:40 mcr Exp $ (LBL)
*/

300
pcap-snit.c Normal file
View File

@ -0,0 +1,300 @@
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Modifications made to accommodate the new SunOS4.0 NIT facility by
* Micky Liu, micky@cunixc.cc.columbia.edu, Columbia University in May, 1989.
* This module now handles the STREAMS based NIT.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.45 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <sys/dir.h>
#include <sys/fcntlcom.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stropts.h>
#include <net/if.h>
#include <net/nit.h>
#include <net/nit_if.h>
#include <net/nit_pf.h>
#include <net/nit_buf.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <ctype.h>
#include <errno.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/*
* The chunk size for NIT. This is the amount of buffering
* done for read calls.
*/
#define CHUNKSIZE (2*1024)
/*
* The total buffer space used by NIT.
*/
#define BUFSPACE (4*CHUNKSIZE)
/* Forwards */
static int nit_setflags(int, int, int, char *);
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
*ps = p->md.stat;
return (0);
}
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
register int cc, n;
register struct bpf_insn *fcode = p->fcode.bf_insns;
register u_char *bp, *cp, *ep;
register struct nit_bufhdr *hdrp;
register struct nit_iftime *ntp;
register struct nit_iflen *nlp;
register struct nit_ifdrops *ndp;
register int caplen;
cc = p->cc;
if (cc == 0) {
cc = read(p->fd, (char *)p->buffer, p->bufsize);
if (cc < 0) {
if (errno == EWOULDBLOCK)
return (0);
sprintf(p->errbuf, "pcap_read: %s",
pcap_strerror(errno));
return (-1);
}
bp = p->buffer;
} else
bp = p->bp;
/*
* loop through each snapshot in the chunk
*/
n = 0;
ep = bp + cc;
while (bp < ep) {
++p->md.stat.ps_recv;
cp = bp;
/* get past NIT buffer */
hdrp = (struct nit_bufhdr *)cp;
cp += sizeof(*hdrp);
/* get past NIT timer */
ntp = (struct nit_iftime *)cp;
cp += sizeof(*ntp);
ndp = (struct nit_ifdrops *)cp;
p->md.stat.ps_drop = ndp->nh_drops;
cp += sizeof *ndp;
/* get past packet len */
nlp = (struct nit_iflen *)cp;
cp += sizeof(*nlp);
/* next snapshot */
bp += hdrp->nhb_totlen;
caplen = nlp->nh_pktlen;
if (caplen > p->snapshot)
caplen = p->snapshot;
if (bpf_filter(fcode, cp, nlp->nh_pktlen, caplen)) {
struct pcap_pkthdr h;
h.ts = ntp->nh_timestamp;
h.len = nlp->nh_pktlen;
h.caplen = caplen;
(*callback)(user, &h, cp);
if (++n >= cnt && cnt >= 0) {
p->cc = ep - bp;
p->bp = bp;
return (n);
}
}
}
p->cc = 0;
return (n);
}
static int
nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
{
bpf_u_int32 flags;
struct strioctl si;
struct timeval timeout;
si.ic_timout = INFTIM;
if (to_ms != 0) {
timeout.tv_sec = to_ms / 1000;
timeout.tv_usec = (to_ms * 1000) % 1000000;
si.ic_cmd = NIOCSTIME;
si.ic_len = sizeof(timeout);
si.ic_dp = (char *)&timeout;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
sprintf(ebuf, "NIOCSTIME: %s", pcap_strerror(errno));
return (-1);
}
}
flags = NI_TIMESTAMP | NI_LEN | NI_DROPS;
if (promisc)
flags |= NI_PROMISC;
si.ic_cmd = NIOCSFLAGS;
si.ic_len = sizeof(flags);
si.ic_dp = (char *)&flags;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
sprintf(ebuf, "NIOCSFLAGS: %s", pcap_strerror(errno));
return (-1);
}
return (0);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
struct strioctl si; /* struct for ioctl() */
struct ifreq ifr; /* interface request struct */
int chunksize = CHUNKSIZE;
int fd;
static char dev[] = "/dev/nit";
register pcap_t *p;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strcpy(ebuf, pcap_strerror(errno));
return (NULL);
}
if (snaplen < 96)
/*
* NIT requires a snapshot length of at least 96.
*/
snaplen = 96;
bzero(p, sizeof(*p));
p->fd = fd = open(dev, O_RDONLY);
if (fd < 0) {
sprintf(ebuf, "%s: %s", dev, pcap_strerror(errno));
goto bad;
}
/* arrange to get discrete messages from the STREAM and use NIT_BUF */
if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
sprintf(ebuf, "I_SRDOPT: %s", pcap_strerror(errno));
goto bad;
}
if (ioctl(fd, I_PUSH, "nbuf") < 0) {
sprintf(ebuf, "push nbuf: %s", pcap_strerror(errno));
goto bad;
}
/* set the chunksize */
si.ic_cmd = NIOCSCHUNK;
si.ic_timout = INFTIM;
si.ic_len = sizeof(chunksize);
si.ic_dp = (char *)&chunksize;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
sprintf(ebuf, "NIOCSCHUNK: %s", pcap_strerror(errno));
goto bad;
}
/* request the interface */
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' ';
si.ic_cmd = NIOCBIND;
si.ic_len = sizeof(ifr);
si.ic_dp = (char *)&ifr;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
sprintf(ebuf, "NIOCBIND: %s: %s",
ifr.ifr_name, pcap_strerror(errno));
goto bad;
}
/* set the snapshot length */
si.ic_cmd = NIOCSSNAP;
si.ic_len = sizeof(snaplen);
si.ic_dp = (char *)&snaplen;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
sprintf(ebuf, "NIOCSSNAP: %s", pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0)
goto bad;
(void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
/*
* NIT supports only ethernets.
*/
p->linktype = DLT_EN10MB;
p->bufsize = BUFSPACE;
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
strcpy(ebuf, pcap_strerror(errno));
goto bad;
}
return (p);
bad:
if (fd >= 0)
close(fd);
free(p);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
p->fcode = *fp;
return (0);
}

216
pcap-snoop.c Normal file
View File

@ -0,0 +1,216 @@
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.20 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <net/raw.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
int cc;
register struct snoopheader *sh;
register int datalen;
register int caplen;
register u_char *cp;
again:
cc = read(p->fd, (char *)p->buffer, p->bufsize);
if (cc < 0) {
/* Don't choke when we get ptraced */
switch (errno) {
case EINTR:
goto again;
case EWOULDBLOCK:
return (0); /* XXX */
}
sprintf(p->errbuf, "read: %s", pcap_strerror(errno));
return (-1);
}
sh = (struct snoopheader *)p->buffer;
datalen = sh->snoop_packetlen;
caplen = (datalen < p->snapshot) ? datalen : p->snapshot;
cp = (u_char *)(sh + 1) + p->offset; /* XXX */
if (p->fcode.bf_insns == NULL ||
bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) {
struct pcap_pkthdr h;
++p->md.stat.ps_recv;
h.ts = sh->snoop_timestamp;
h.len = datalen;
h.caplen = caplen;
(*callback)(user, &h, cp);
return (1);
}
return (0);
}
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
register struct rawstats *rs;
struct rawstats rawstats;
rs = &rawstats;
bzero((char *)rs, sizeof(*rs));
if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) {
sprintf(p->errbuf, "SIOCRAWSTATS: %s", pcap_strerror(errno));
return (-1);
}
p->md.stat.ps_drop =
rs->rs_snoop.ss_ifdrops + rs->rs_snoop.ss_sbdrops +
rs->rs_drain.ds_ifdrops + rs->rs_drain.ds_sbdrops;
*ps = p->md.stat;
return (0);
}
/* XXX can't disable promiscuous */
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
int fd;
struct sockaddr_raw sr;
struct snoopfilter sf;
u_int v;
pcap_t *p;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
return (NULL);
}
bzero((char *)p, sizeof(*p));
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
if (fd < 0) {
sprintf(ebuf, "snoop socket: %s", pcap_strerror(errno));
goto bad;
}
p->fd = fd;
bzero((char *)&sr, sizeof(sr));
sr.sr_family = AF_RAW;
(void)strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname));
if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) {
sprintf(ebuf, "snoop bind: %s", pcap_strerror(errno));
goto bad;
}
bzero((char *)&sf, sizeof(sf));
if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
sprintf(ebuf, "SIOCADDSNOOP: %s", pcap_strerror(errno));
goto bad;
}
v = 64 * 1024;
(void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v));
if (ioctl(fd, SIOCSNOOPLEN, &snaplen) < 0) {
sprintf(ebuf, "SIOCSNOOPLEN: %s", pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
v = 1;
if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
sprintf(ebuf, "SIOCSNOOPING: %s", pcap_strerror(errno));
goto bad;
}
/*
* XXX hack - map device name to link layer type
*/
if (strncmp("et", device, 2) == 0 || /* Challenge 10 Mbit */
strncmp("ec", device, 2) == 0 || /* Indigo/Indy 10 Mbit,
O2 10/100 */
strncmp("ef", device, 2) == 0 || /* O200/2000 10/100 Mbit */
strncmp("gfe", device, 3) == 0 || /* GIO 100 Mbit */
strncmp("fxp", device, 3) == 0 || /* Challenge VME Enet */
strncmp("ep", device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
strncmp("vfe", device, 3) == 0 || /* Challenge VME 100Mbit */
strncmp("fa", device, 2) == 0 ||
strncmp("qaa", device, 3) == 0) {
p->linktype = DLT_EN10MB;
p->offset = RAW_HDRPAD(sizeof(struct ether_header));
} else if (strncmp("ipg", device, 3) == 0 ||
strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */
strncmp("xpi", device, 3) == 0) {
p->linktype = DLT_FDDI;
p->offset = 3; /* XXX yeah? */
} else if (strncmp("ppp", device, 3) == 0) {
p->linktype = DLT_RAW;
} else if (strncmp("lo", device, 2) == 0) {
p->linktype = DLT_NULL;
} else {
sprintf(ebuf, "snoop: unknown physical layer type");
goto bad;
}
p->bufsize = 4096; /* XXX */
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
goto bad;
}
return (p);
bad:
(void)close(fd);
free(p);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
p->fcode = *fp;
return (0);
}

340
pcap.3 Normal file
View File

@ -0,0 +1,340 @@
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that: (1) source code distributions
.\" retain the above copyright notice and this paragraph in its entirety, (2)
.\" distributions including binary code include the above copyright notice and
.\" this paragraph in its entirety in the documentation or other materials
.\" provided with the distribution, and (3) all advertising materials mentioning
.\" features or use of this software display the following acknowledgement:
.\" ``This product includes software developed by the University of California,
.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
.\" the University nor the names of its contributors may be used to endorse
.\" or promote products derived from this software without specific prior
.\" written permission.
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP 3 "24 June 1998"
.SH NAME
pcap \- Packet Capture library
.SH SYNOPSIS
.nf
.ft B
#include <pcap.h>
.ft
.LP
.ft B
pcap_t *pcap_open_live(char *device, int snaplen,
.ti +8
int promisc, int to_ms, char *ebuf)
pcap_t *pcap_open_offline(char *fname, char *ebuf)
pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname)
.ft
.LP
.ft B
char errbuf[PCAP_ERRBUF_SIZE];
char *pcap_lookupdev(char *errbuf)
int pcap_lookupnet(char *device, bpf_u_int32 *netp,
.ti +8
bpf_u_int32 *maskp, char *errbuf)
.ft
.LP
.ft B
int pcap_dispatch(pcap_t *p, int cnt,
.ti +8
pcap_handler callback, u_char *user)
int pcap_loop(pcap_t *p, int cnt,
.ti +8
pcap_handler callback, u_char *user)
void pcap_dump(u_char *user, struct pcap_pkthdr *h,
.ti +8
u_char *sp)
.ft
.LP
.ft B
int pcap_compile(pcap_t *p, struct bpf_program *fp,
.ti +8
char *str, int optimize, bpf_u_int32 netmask)
int pcap_setfilter(pcap_t *p, struct bpf_program *fp)
.ft
.LP
.ft B
u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
.ft
.LP
.ft B
int pcap_datalink(pcap_t *p)
int pcap_snapshot(pcap_t *p)
int pcap_is_swapped(pcap_t *p)
int pcap_major_version(pcap_t *p)
int pcap_minor_version(pcap_t *p)
int pcap_stats(pcap_t *p, struct pcap_stat *ps)
FILE *pcap_file(pcap_t *p)
int pcap_fileno(pcap_t *p)
void pcap_perror(pcap_t *p, char *prefix)
char *pcap_geterr(pcap_t *p)
char *pcap_strerror(int error)
.ft
.LP
.ft B
void pcap_close(pcap_t *p)
void pcap_dump_close(pcap_dumper_t *p)
.ft
.fi
.SH DESCRIPTION
The Packet Capture library
provides a high level interface to packet capture systems. All packets
on the network, even those destined for other hosts, are accessible
through this mechanism.
.PP
.SH ROUTINES
.B pcap_open_live()
is used to obtain a packet capture descriptor to look
at packets on the network.
.I device
is a string that specifies the network device to open.
.I snaplen
specifies the maximum number of bytes to capture.
.I promisc
specifies if the interface is to be put into promiscuous mode.
(Note that even if this parameter is false, the interface
could well be in promiscuous mode for some other reason.)
.I to_ms
specifies the read timeout in milliseconds.
.I ebuf
is used to return error text and is only set when
.B pcap_open_live()
fails and returns
.BR NULL .
.PP
.B pcap_open_offline()
is called to open a ``savefile'' for reading.
.I fname
specifies the name of the file to open. The file has
the same format as those used by
.B tcpdump(1)
and
.BR tcpslice(1) .
The name "-" in a synonym for
.BR stdin .
.I ebuf
is used to return error text and is only set when
.B pcap_open_offline()
fails and returns
.BR NULL .
.PP
.B pcap_dump_open()
is called to open a ``savefile'' for writing. The name "-" in a synonym
for
.BR stdout .
.B NULL
is returned on failure.
.I p
is a
.I pcap
struct as returned by
.B pcap_open_offline()
or
.BR pcap_open_live() .
.I fname
specifies the name of the file to open.
If
.B NULL
is returned,
.B pcap_geterr()
can be used to get the error text.
.PP
.B pcap_lookupdev()
returns a pointer to a network device suitable for use with
.B pcap_open_live()
and
.BR pcap_lookupnet() .
If there is an error,
.B NULL
is returned and
.I errbuf
is filled in with with an appropriate error message.
.PP
.B pcap_lookupnet()
is used to determine the network number and mask
associated with the network device
.BR device .
Both
.I netp
and
.I maskp
are
.I bpf_u_int32
pointers.
A return of -1 indicates an error in which case
.I errbuf
is filled in with with an appropriate error message.
.PP
.B pcap_dispatch()
is used to collect and process packets.
.I cnt
specifies the maximum number of packets to process before returning. A
.I cnt
of -1 processes all the packets received in one buffer. A
.I cnt
of 0 processes all packets until an error occurs,
.B EOF
is reached, or the read times out (when doing live reads and a non-zero
read timeout is specified).
.I callback
specifies a routine to be called with three arguments:
a
.I u_char
pointer which is passed in from
.BR pcap_dispatch() ,
a pointer to the
.I pcap_pkthdr
struct (which precede the actual network headers and data),
and a
.I u_char
pointer to the packet data. The number of packets read is returned.
Zero is returned when
.B EOF
is reached in a ``savefile.'' A return of -1 indicates
an error in which case
.B pcap_perror()
or
.BR pcap_geterr()
may be used to display the error text.
.PP
.B pcap_dump()
outputs a packet to the ``savefile'' opened with
.BR pcap_dump_open() .
Note that its calling arguments are suitable for use with
.BR pcap_dispatch() .
.PP
.B pcap_compile()
is used to compile the string
.I str
into a filter program.
.I program
is a pointer to a
.I bpf_program
struct and is filled in by
.BR pcap_compile() .
.I optimize
controls whether optimization on the resulting code is performed.
.I netmask
specifies the netmask of the local net.
.PP
.B pcap_setfilter()
is used to specify a filter program.
.I fp
is a pointer to an array of
.I bpf_program
struct, usually the result of a call to
.BR pcap_compile() .
.B \-1
is returned on failure;
.B 0
is returned on success.
.PP
.B pcap_loop()
is similar to
.B pcap_dispatch()
except it keeps reading packets until
.I cnt
packets are processed or an error occurs.
It does
.B not
return when live read timeouts occur.
Rather, specifying a non-zero read timeout to
.B pcap_open_live()
and then calling
.B pcap_dispatch()
allows the reception and processing of any packets that arrive when the
timeout occurs.
A negative
.I cnt
causes
.B pcap_loop()
to loop forever (or at least until an error occurs).
.PP
.B pcap_next()
returns a
.I u_char
pointer to the next packet.
.PP
.B pcap_datalink()
returns the link layer type, e.g.
.BR DLT_EN10MB .
.PP
.B pcap_snapshot()
returns the snapshot length specified when
.B pcap_open_live
was called.
.PP
.B pcap_is_swapped()
returns true if the current ``savefile'' uses a different byte order
than the current system.
.PP
.B pcap_major_version()
returns the major number of the version of the pcap used to write the
savefile.
.PP
.B pcap_minor_version()
returns the minor number of the version of the pcap used to write the
savefile.
.PP
.B pcap_file()
returns the name of the ``savefile.''
.PP
.B int pcap_stats()
returns 0 and fills in a
.B pcap_stat
struct. The values represent packet statistics from the start of the
run to the time of the call. If there is an error or the under lying
packet capture doesn't support packet statistics, -1 is returned and
the error text can be obtained with
.B pcap_perror()
or
.BR pcap_geterr() .
.PP
.B pcap_fileno()
returns the file descriptor number of the ``savefile.''
.PP
.B pcap_perror()
prints the text of the last pcap library error on
.BR stderr ,
prefixed by
.IR prefix .
.PP
.B pcap_geterr()
returns the error text pertaining to the last pcap library error.
.PP
.B pcap_strerror()
is provided in case
.BR strerror (1)
isn't available.
.PP
.B pcap_close()
closes the files associated with
.I p
and deallocates resources.
.PP
.B pcap_dump_close()
closes the ``savefile.''
.PP
.SH SEE ALSO
tcpdump(1), tcpslice(1)
.SH AUTHORS
Van Jacobson,
Craig Leres and
Steven McCanne, all of the
Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
.LP
The current version is available via anonymous ftp:
.LP
.RS
.I ftp://ftp.ee.lbl.gov/libpcap.tar.Z
.RE
.SH BUGS
Please send bug reports to libpcap@ee.lbl.gov.

206
pcap.c Normal file
View File

@ -0,0 +1,206 @@
/*
* 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
* 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 Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory 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.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.29 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include "pcap-int.h"
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));
}
int
pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
register int n;
for (;;) {
if (p->sf.rfile != NULL)
n = pcap_offline_read(p, cnt, callback, user);
else {
/*
* XXX keep reading until we get something
* (or an error occurs)
*/
do {
n = pcap_read(p, cnt, callback, user);
} while (n == 0);
}
if (n <= 0)
return (n);
if (cnt > 0) {
cnt -= n;
if (cnt <= 0)
return (0);
}
}
}
struct singleton {
struct pcap_pkthdr *hdr;
const u_char *pkt;
};
static void
pcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt)
{
struct singleton *sp = (struct singleton *)userData;
*sp->hdr = *h;
sp->pkt = pkt;
}
const u_char *
pcap_next(pcap_t *p, struct pcap_pkthdr *h)
{
struct singleton s;
s.hdr = h;
if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0)
return (0);
return (s.pkt);
}
int
pcap_datalink(pcap_t *p)
{
return (p->linktype);
}
int
pcap_snapshot(pcap_t *p)
{
return (p->snapshot);
}
int
pcap_is_swapped(pcap_t *p)
{
return (p->sf.swapped);
}
int
pcap_major_version(pcap_t *p)
{
return (p->sf.version_major);
}
int
pcap_minor_version(pcap_t *p)
{
return (p->sf.version_minor);
}
FILE *
pcap_file(pcap_t *p)
{
return (p->sf.rfile);
}
int
pcap_fileno(pcap_t *p)
{
return (p->fd);
}
void
pcap_perror(pcap_t *p, char *prefix)
{
fprintf(stderr, "%s: %s\n", prefix, p->errbuf);
}
char *
pcap_geterr(pcap_t *p)
{
return (p->errbuf);
}
/*
* Not all systems have strerror().
*/
char *
pcap_strerror(int errnum)
{
#ifdef HAVE_STRERROR
return (strerror(errnum));
#else
extern int sys_nerr;
extern const char *const sys_errlist[];
static char ebuf[20];
if ((unsigned int)errnum < sys_nerr)
return ((char *)sys_errlist[errnum]);
(void)sprintf(ebuf, "Unknown error: %d", errnum);
return(ebuf);
#endif
}
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
free(p);
}

137
pcap.h Normal file
View File

@ -0,0 +1,137 @@
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that 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 Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory 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.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.21 1999-10-07 23:46:40 mcr Exp $ (LBL)
*/
#ifndef lib_pcap_h
#define lib_pcap_h
#include <sys/types.h>
#include <sys/time.h>
#include <net/bpf.h>
#include <stdio.h>
#define PCAP_VERSION_MAJOR 2
#define PCAP_VERSION_MINOR 4
#define PCAP_ERRBUF_SIZE 256
/*
* Compatibility for systems that have a bpf.h that
* predates the bpf typedefs for 64-bit support.
*/
#if BPF_RELEASE - 0 < 199406
typedef int bpf_int32;
typedef u_int bpf_u_int32;
#endif
typedef struct pcap pcap_t;
typedef struct pcap_dumper pcap_dumper_t;
/*
* 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.
*/
struct pcap_file_header {
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone; /* gmt to local correction */
bpf_u_int32 sigfigs; /* accuracy of timestamps */
bpf_u_int32 snaplen; /* max length saved portion of each pkt */
bpf_u_int32 linktype; /* data link type (DLT_*) */
};
/*
* Each packet in the dump file is prepended with this generic header.
* This gets around the problem of different headers for different
* packet interfaces.
*/
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};
/*
* As returned by the pcap_stats()
*/
struct pcap_stat {
u_int ps_recv; /* number of packets received */
u_int ps_drop; /* number of packets dropped */
u_int ps_ifdrop; /* drops by interface XXX not yet supported */
};
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(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_stats(pcap_t *, struct pcap_stat *);
int pcap_setfilter(pcap_t *, struct bpf_program *);
void pcap_perror(pcap_t *, char *);
char *pcap_strerror(int);
char *pcap_geterr(pcap_t *);
int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
bpf_u_int32);
/* XXX */
int pcap_freecode(pcap_t *, struct bpf_program *);
int pcap_datalink(pcap_t *);
int pcap_snapshot(pcap_t *);
int pcap_is_swapped(pcap_t *);
int pcap_major_version(pcap_t *);
int pcap_minor_version(pcap_t *);
/* XXX */
FILE *pcap_file(pcap_t *);
int pcap_fileno(pcap_t *);
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
void pcap_dump_close(pcap_dumper_t *);
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
/* XXX this guy lives in the bpf tree */
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
char *bpf_image(struct bpf_insn *, int);
#endif

50
ppp.h Normal file
View File

@ -0,0 +1,50 @@
/* @(#) $Header: /tcpdump/master/libpcap/ppp.h,v 1.7 1999-10-07 23:46:40 mcr Exp $ (LBL) */
/*
* Point to Point Protocol (PPP) RFC1331
*
* Copyright 1989 by Carnegie Mellon.
*
* Permission to use, copy, modify, and distribute this program for any
* purpose and without fee is hereby granted, provided that this copyright
* and permission notice appear on all copies and supporting documentation,
* the name of Carnegie Mellon not be used in advertising or publicity
* pertaining to distribution of the program without specific prior
* permission, and notice be given in supporting documentation that copying
* and distribution is by permission of Carnegie Mellon and Stanford
* University. Carnegie Mellon makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
#define PPP_ADDRESS 0xff /* The address byte value */
#define PPP_CONTROL 0x03 /* The control byte value */
/* Protocol numbers */
#define PPP_IP 0x0021 /* Raw IP */
#define PPP_OSI 0x0023 /* OSI Network Layer */
#define PPP_NS 0x0025 /* Xerox NS IDP */
#define PPP_DECNET 0x0027 /* DECnet Phase IV */
#define PPP_APPLE 0x0029 /* Appletalk */
#define PPP_IPX 0x002b /* Novell IPX */
#define PPP_VJC 0x002d /* Van Jacobson Compressed TCP/IP */
#define PPP_VJNC 0x002f /* Van Jacobson Uncompressed TCP/IP */
#define PPP_BRPDU 0x0031 /* Bridging PDU */
#define PPP_STII 0x0033 /* Stream Protocol (ST-II) */
#define PPP_VINES 0x0035 /* Banyan Vines */
#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */
#define PPP_LUXCOM 0x0231 /* Luxcom */
#define PPP_SNS 0x0233 /* Sigma Network Systems */
#define PPP_IPCP 0x8021 /* IP Control Protocol */
#define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */
#define PPP_NSCP 0x8025 /* Xerox NS IDP Control Protocol */
#define PPP_DECNETCP 0x8027 /* DECnet Control Protocol */
#define PPP_APPLECP 0x8029 /* Appletalk Control Protocol */
#define PPP_IPXCP 0x802b /* Novell IPX Control Protocol */
#define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */
#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */
#define PPP_LCP 0xc021 /* Link Control Protocol */
#define PPP_PAP 0xc023 /* Password Authentication Protocol */
#define PPP_LQM 0xc025 /* Link Quality Monitoring */
#define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */

352
savefile.c Normal file
View File

@ -0,0 +1,352 @@
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* savefile.c - supports offline use of tcpdump
* Extraction/creation by Jeffrey Mogul, DECWRL
* Modified by Steve McCanne, LBL.
*
* Used to save the received packet headers, after filtering, to
* a file, and then read them later.
* The first record in the file contains saved values for the machine
* dependent values so we can print the dump file on any architecture.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.37 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#define TCPDUMP_MAGIC 0xa1b2c3d4
/*
* 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.
*
* ntoh[ls] aren't sufficient because we might need to swap on a big-endian
* machine (if the file was written in little-end order).
*/
#define SWAPLONG(y) \
((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
#define SWAPSHORT(y) \
( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
#define SFERR_TRUNC 1
#define SFERR_BADVERSION 2
#define SFERR_BADF 3
#define SFERR_EOF 4 /* not really an error, just a status */
static int
sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen)
{
struct pcap_file_header hdr;
hdr.magic = TCPDUMP_MAGIC;
hdr.version_major = PCAP_VERSION_MAJOR;
hdr.version_minor = PCAP_VERSION_MINOR;
hdr.thiszone = thiszone;
hdr.snaplen = snaplen;
hdr.sigfigs = 0;
hdr.linktype = linktype;
if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
return (-1);
return (0);
}
static void
swap_hdr(struct pcap_file_header *hp)
{
hp->version_major = SWAPSHORT(hp->version_major);
hp->version_minor = SWAPSHORT(hp->version_minor);
hp->thiszone = SWAPLONG(hp->thiszone);
hp->sigfigs = SWAPLONG(hp->sigfigs);
hp->snaplen = SWAPLONG(hp->snaplen);
hp->linktype = SWAPLONG(hp->linktype);
}
pcap_t *
pcap_open_offline(const char *fname, char *errbuf)
{
register pcap_t *p;
register FILE *fp;
struct pcap_file_header hdr;
int linklen;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strcpy(errbuf, "out of swap");
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 {
fp = fopen(fname, "r");
if (fp == NULL) {
sprintf(errbuf, "%s: %s", fname, pcap_strerror(errno));
goto bad;
}
}
if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
sprintf(errbuf, "fread: %s", pcap_strerror(errno));
goto bad;
}
if (hdr.magic != TCPDUMP_MAGIC) {
if (SWAPLONG(hdr.magic) != TCPDUMP_MAGIC) {
sprintf(errbuf, "bad dump file format");
goto bad;
}
p->sf.swapped = 1;
swap_hdr(&hdr);
}
if (hdr.version_major < PCAP_VERSION_MAJOR) {
sprintf(errbuf, "archaic file format");
goto bad;
}
p->tzoff = hdr.thiszone;
p->snapshot = hdr.snaplen;
p->linktype = hdr.linktype;
p->sf.rfile = fp;
p->bufsize = hdr.snaplen;
/* Align link header as required for proper data alignment */
/* XXX should handle all types */
switch (p->linktype) {
case DLT_EN10MB:
linklen = 14;
break;
case DLT_FDDI:
linklen = 13 + 8; /* fddi_header + llc */
break;
case DLT_NULL:
default:
linklen = 0;
break;
}
p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT);
p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT);
p->sf.version_major = hdr.version_major;
p->sf.version_minor = hdr.version_minor;
#ifdef PCAP_FDDIPAD
/* XXX padding only needed for kernel fcode */
pcap_fddipad = 0;
#endif
return (p);
bad:
free(p);
return (NULL);
}
/*
* Read sf_readfile and return the next packet. Return the header in hdr
* and the contents in buf. Return 0 on success, SFERR_EOF if there were
* 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)
{
FILE *fp = p->sf.rfile;
/* read the stamp */
if (fread((char *)hdr, sizeof(struct pcap_pkthdr), 1, fp) != 1) {
/* probably an EOF, though could be a truncated packet */
return (1);
}
if (p->sf.swapped) {
/* these were written in opposite byte order */
hdr->caplen = SWAPLONG(hdr->caplen);
hdr->len = SWAPLONG(hdr->len);
hdr->ts.tv_sec = SWAPLONG(hdr->ts.tv_sec);
hdr->ts.tv_usec = SWAPLONG(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;
hdr->caplen = hdr->len;
hdr->len = t;
}
if (hdr->caplen > buflen) {
/*
* This can happen due to Solaris 2.3 systems tripping
* over the BUFMOD problem and not setting the snapshot
* correctly in the savefile header. If the caplen isn't
* grossly wrong, try to salvage.
*/
static u_char *tp = NULL;
static int tsize = 0;
if (hdr->caplen > 65535) {
sprintf(p->errbuf, "bogus savefile header");
return (-1);
}
if (tsize < hdr->caplen) {
tsize = ((hdr->caplen + 1023) / 1024) * 1024;
if (tp != NULL)
free((u_char *)tp);
tp = (u_char *)malloc(tsize);
if (tp == NULL) {
tsize = 0;
sprintf(p->errbuf, "BUFMOD hack malloc");
return (-1);
}
}
if (fread((char *)tp, hdr->caplen, 1, fp) != 1) {
sprintf(p->errbuf, "truncated dump file");
return (-1);
}
/*
* We can only keep up to buflen bytes. Since caplen > buflen
* is exactly how we got here, we know we can only keep the
* first buflen bytes and must drop the remainder. Adjust
* caplen accordingly, so we don't get confused later as
* to how many bytes we have to play with.
*/
hdr->caplen = buflen;
memcpy((char *)buf, (char *)tp, buflen);
} else {
/* read the packet itself */
if (fread((char *)buf, hdr->caplen, 1, fp) != 1) {
sprintf(p->errbuf, "truncated dump file");
return (-1);
}
}
return (0);
}
/*
* Print out packets stored in the file initialized by sf_read_init().
* If cnt > 0, return after 'cnt' packets, otherwise continue until eof.
*/
int
pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
struct bpf_insn *fcode = p->fcode.bf_insns;
int status = 0;
int n = 0;
while (status == 0) {
struct pcap_pkthdr h;
status = sf_next_packet(p, &h, p->buffer, p->bufsize);
if (status) {
if (status == 1)
return (0);
return (status);
}
if (fcode == NULL ||
bpf_filter(fcode, p->buffer, h.len, h.caplen)) {
(*callback)(user, &h, p->buffer);
if (++n >= cnt && cnt > 0)
break;
}
}
/*XXX this breaks semantics tcpslice expects */
return (n);
}
/*
* Output a packet to the initialized dump file.
*/
void
pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
{
register FILE *f;
f = (FILE *)user;
/* XXX we should check the return status */
(void)fwrite((char *)h, sizeof(*h), 1, f);
(void)fwrite((char *)sp, h->caplen, 1, f);
}
/*
* Initialize so that sf_write() will output to the file named 'fname'.
*/
pcap_dumper_t *
pcap_dump_open(pcap_t *p, const char *fname)
{
FILE *f;
if (fname[0] == '-' && fname[1] == '\0')
f = stdout;
else {
f = fopen(fname, "w");
if (f == NULL) {
sprintf(p->errbuf, "%s: %s",
fname, pcap_strerror(errno));
return (NULL);
}
}
(void)sf_write_header(f, p->linktype, p->tzoff, p->snapshot);
return ((pcap_dumper_t *)f);
}
void
pcap_dump_close(pcap_dumper_t *p)
{
#ifdef notyet
if (ferror((FILE *)p))
return-an-error;
/* XXX should check return from fclose() too */
#endif
(void)fclose((FILE *)p);
}

203
scanner.l Normal file
View File

@ -0,0 +1,203 @@
%{
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.56 1999-10-07 23:46:40 mcr Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <ctype.h>
#include <unistd.h>
#include "pcap-int.h"
#include "gencode.h"
#include <pcap-namedb.h>
#include "tokdefs.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
static int stoi(char *);
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;\
}\
}
#else
#undef getc
#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++)
#endif
#define yylval pcap_lval
extern YYSTYPE yylval;
static char *in_buffer;
%}
N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
B ([0-9A-Fa-f][0-9A-Fa-f]?)
%a 3000
%%
dst return DST;
src return SRC;
link|ether|ppp|slip return LINK;
fddi return LINK;
arp return ARP;
rarp return RARP;
ip return IP;
tcp return TCP;
udp return UDP;
icmp return ICMP;
igmp return IGMP;
igrp return IGRP;
atalk return ATALK;
decnet return DECNET;
lat return LAT;
sca return SCA;
moprc return MOPRC;
mopdl return MOPDL;
host return HOST;
net return NET;
mask return MASK;
port return PORT;
proto return PROTO;
gateway return GATEWAY;
less return LESS;
greater return GREATER;
byte return BYTE;
broadcast return TK_BROADCAST;
multicast return TK_MULTICAST;
and|"&&" return AND;
or|"||" return OR;
not return '!';
len|length return LEN;
inbound return INBOUND;
outbound return OUTBOUND;
[ \n\t] ;
[+\-*/:\[\]!<>()&|=] return yytext[0];
">=" return GEQ;
"<=" return LEQ;
"!=" return NEQ;
"==" return '=';
"<<" return LSH;
">>" return RSH;
{N} { yylval.i = stoi((char *)yytext); return NUM; }
({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) {
yylval.s = sdup((char *)yytext); return HID; }
{B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext);
return EID; }
{B}:+({B}:+)+ { bpf_error("bogus ethernet address %s", yytext); }
[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); }
. { bpf_error("illegal char '%c'", *yytext); }
%%
void
lex_init(buf)
char *buf;
{
in_buffer = buf;
}
/*
* Also define a yywrap. Note that if we're using flex, it will
* define a macro to map this identifier to pcap_wrap.
*/
int
yywrap()
{
return 1;
}
/* Hex digit to integer. */
static inline int
xdtoi(c)
register int c;
{
if (isdigit(c))
return c - '0';
else if (islower(c))
return c - 'a' + 10;
else
return c - 'A' + 10;
}
/*
* Convert string to integer. Just like atoi(), but checks for
* preceding 0x or 0 and uses hex or octal instead of decimal.
*/
static int
stoi(s)
char *s;
{
int base = 10;
int n = 0;
if (*s == '0') {
if (s[1] == 'x' || s[1] == 'X') {
s += 2;
base = 16;
}
else {
base = 8;
s += 1;
}
}
while (*s)
n = n * base + xdtoi(*s++);
return n;
}