Add support to wiretap for reading Sun "snoop" capture files.

That requires that, in the packet-reading loop, we pass to the callback
routine the offset in the file of a packet's data, because we can no
longer compute that offset by subtracting the size of the captured
packet data from the offset in the file after the data was read -
"snoop" may stick padding in after the packet data to align packet
headers on 4-byte boundaries.

Doing that required that we arrange that we do that for "libpcap"
capture files as well; the cleanest way to do that was to write our own
code for reading "libpcap" capture files, rather than using the
"libpcap" code to do it.

Make "wtap_dispatch_cb()" and "pcap_dispatch_cb()" static to "file.c",
as they're not used elsewhere.

If we're using wiretap, don't define in "file.h" stuff used only when
we're not using wiretap.

Update the wiretap README to reflect Gilbert's and my recent changes.

Clean up some memory leaks in "wiretap/lanalyzer.c" and
"wiretap/ngsniffer.c", where the capture-file-format-specific data
wasn't freed if the open failed.

svn path=/trunk/; revision=91
This commit is contained in:
Guy Harris 1998-11-15 05:29:17 +00:00
parent 8efdf8a74c
commit 86bf1fc851
24 changed files with 706 additions and 266 deletions

View File

@ -194,9 +194,9 @@ NROFF = nroff
DATA = $(sysconf_DATA)
DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
Makefile.in NEWS acconfig.h aclocal.m4 config.guess config.h.in \
config.sub configure configure.in install-sh missing mkinstalldirs \
stamp-h.in
Makefile.in NEWS acconfig.h acinclude.m4 aclocal.m4 config.guess \
config.h.in config.sub configure configure.in install-sh missing \
mkinstalldirs stamp-h.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
@ -230,7 +230,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(ACLOCAL_M4): configure.in
$(ACLOCAL_M4): configure.in acinclude.m4
cd $(srcdir) && $(ACLOCAL)
config.status: $(srcdir)/configure

View File

@ -2,7 +2,7 @@
#undef VERSION
#undef HAVE_SOCKADDR_SA_LEN
#undef HAVE_SA_LEN
#undef DATAFILE_DIR

70
aclocal.m4 vendored
View File

@ -10,6 +10,76 @@ dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
dnl PARTICULAR PURPOSE.
dnl Macros that test for specific features.
dnl This file is part of Autoconf.
dnl Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2, or (at your option)
dnl any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
dnl 02111-1307, USA.
dnl
dnl As a special exception, the Free Software Foundation gives unlimited
dnl permission to copy, distribute and modify the configure scripts that
dnl are the output of Autoconf. You need not follow the terms of the GNU
dnl General Public License when using or distributing such scripts, even
dnl though portions of the text of Autoconf appear in them. The GNU
dnl General Public License (GPL) does govern all other use of the material
dnl that constitutes the Autoconf program.
dnl
dnl Certain portions of the Autoconf source text are designed to be copied
dnl (in certain cases, depending on the input) into the output of
dnl Autoconf. We call these the "data" portions. The rest of the Autoconf
dnl source text consists of comments plus executable code that decides which
dnl of the data portions to output in any given case. We call these
dnl comments and executable code the "non-data" portions. Autoconf never
dnl copies any of the non-data portions into its output.
dnl
dnl This special exception to the GPL applies to versions of Autoconf
dnl released by the Free Software Foundation. When you make and
dnl distribute a modified version of Autoconf, you may extend this special
dnl exception to the GPL to apply to your modified version as well, *unless*
dnl your modified version has the potential to copy into its output some
dnl of the text that was the non-data portion of the version that you started
dnl with. (In other words, unless your change moves or copies text from
dnl the non-data portions to the data portions.) If your modification has
dnl such potential, you must delete any notice of this special exception
dnl to the GPL from your modified version.
dnl
dnl Written by David MacKenzie, with help from
dnl Franc,ois Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor,
dnl Roland McGrath, Noah Friedman, david d zuhn, and many others.
dnl AC_STRUCT_ST_BLKSIZE extracted from the file in qustion,
dnl "acspecific.m4" in GNU Autoconf 2.12, and turned into
dnl AC_ETHEREAL_STRUCT_SA_LEN, which checks if "struct sockaddr"
dnl has the 4.4BSD "sa_len" member, and defines HAVE_SA_LEN; that's
dnl what's in this file.
dnl Done by Guy Harris <guy@netapp.com> on 1998-11-14.
dnl ### Checks for structure members
AC_DEFUN(AC_ETHEREAL_STRUCT_SA_LEN,
[AC_CACHE_CHECK([for sa_len in struct sockaddr], ac_cv_ethereal_struct_sa_len,
[AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/socket.h>], [struct sockaddr s; s.sa_len;],
ac_cv_ethereal_struct_sa_len=yes, ac_cv_ethereal_struct_sa_len=no)])
if test $ac_cv_ethereal_struct_sa_len = yes; then
AC_DEFINE(HAVE_SA_LEN)
fi
])
# Do all the work for Automake. This macro actually does too much --
# some checks are only needed if your package does certain things.
# But this isn't really a big deal.

View File

@ -1,7 +1,7 @@
/* capture.c
* Routines for packet capture windows
*
* $Id: capture.c,v 1.8 1998/10/28 21:38:06 gerald Exp $
* $Id: capture.c,v 1.9 1998/11/15 05:28:54 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -126,7 +126,7 @@ get_interface_list() {
! strchr(ifr->ifr_name, ':')) {
il = g_list_append(il, g_strdup(ifr->ifr_name));
}
#ifdef HAVE_SOCKADDR_SA_LEN
#ifdef HAVE_SA_LEN
ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
#else
ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq));

View File

@ -11,6 +11,8 @@
#undef VERSION
#undef HAVE_SA_LEN
#undef DATAFILE_DIR
#undef NEED_SNPRINTF_H

70
configure vendored
View File

@ -1694,20 +1694,54 @@ done
# AC_C_CONST
# We need libpcap's AC_LBL_SOCKADDR_SA_LEN test for get_interface_list().
# We need to know whether "struct sockaddr" has an "sa_len" member
# for get_interface_list().
echo $ac_n "checking for sa_len in struct sockaddr""... $ac_c" 1>&6
echo "configure:1702: checking for sa_len in struct sockaddr" >&5
if eval "test \"`echo '$''{'ac_cv_ethereal_struct_sa_len'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1707 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/socket.h>
int main() {
struct sockaddr s; s.sa_len;
; return 0; }
EOF
if { (eval echo configure:1715: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_ethereal_struct_sa_len=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_ethereal_struct_sa_len=no
fi
rm -f conftest*
fi
echo "$ac_t""$ac_cv_ethereal_struct_sa_len" 1>&6
if test $ac_cv_ethereal_struct_sa_len = yes; then
cat >> confdefs.h <<\EOF
#define HAVE_SA_LEN 1
EOF
fi
AC_LBL_SOCKADDR_SA_LEN
# We must know our byte order
echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
echo "configure:1704: checking whether byte ordering is bigendian" >&5
echo "configure:1738: checking whether byte ordering is bigendian" >&5
if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_bigendian=unknown
# See if sys/param.h defines the BYTE_ORDER macro.
cat > conftest.$ac_ext <<EOF
#line 1711 "configure"
#line 1745 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
@ -1718,11 +1752,11 @@ int main() {
#endif
; return 0; }
EOF
if { (eval echo configure:1722: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:1756: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
# It does; now see whether it defined to BIG_ENDIAN or not.
cat > conftest.$ac_ext <<EOF
#line 1726 "configure"
#line 1760 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
@ -1733,7 +1767,7 @@ int main() {
#endif
; return 0; }
EOF
if { (eval echo configure:1737: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:1771: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_bigendian=yes
else
@ -1753,7 +1787,7 @@ if test "$cross_compiling" = yes; then
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
#line 1757 "configure"
#line 1791 "configure"
#include "confdefs.h"
main () {
/* Are we little or big endian? From Harbison&Steele. */
@ -1766,7 +1800,7 @@ main () {
exit (u.c[sizeof (long) - 1] == 1);
}
EOF
if { (eval echo configure:1770: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
if { (eval echo configure:1804: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
then
ac_cv_c_bigendian=no
else
@ -1792,13 +1826,13 @@ fi
if test $ac_cv_prog_gcc = yes; then
echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
echo "configure:1796: checking whether ${CC-cc} needs -traditional" >&5
echo "configure:1830: checking whether ${CC-cc} needs -traditional" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_pattern="Autoconf.*'x'"
cat > conftest.$ac_ext <<EOF
#line 1802 "configure"
#line 1836 "configure"
#include "confdefs.h"
#include <sgtty.h>
Autoconf TIOCGETP
@ -1816,7 +1850,7 @@ rm -f conftest*
if test $ac_cv_prog_gcc_traditional = no; then
cat > conftest.$ac_ext <<EOF
#line 1820 "configure"
#line 1854 "configure"
#include "confdefs.h"
#include <termio.h>
Autoconf TCGETA
@ -1838,12 +1872,12 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
fi
echo $ac_n "checking for socket""... $ac_c" 1>&6
echo "configure:1842: checking for socket" >&5
echo "configure:1876: checking for socket" >&5
if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1847 "configure"
#line 1881 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char socket(); below. */
@ -1866,7 +1900,7 @@ socket();
; return 0; }
EOF
if { (eval echo configure:1870: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
if { (eval echo configure:1904: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_func_socket=yes"
else
@ -1892,12 +1926,12 @@ fi
SNPRINTF_C=""
SNPRINTF_O=""
echo $ac_n "checking for snprintf""... $ac_c" 1>&6
echo "configure:1896: checking for snprintf" >&5
echo "configure:1930: checking for snprintf" >&5
if eval "test \"`echo '$''{'ac_cv_func_snprintf'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1901 "configure"
#line 1935 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char snprintf(); below. */
@ -1920,7 +1954,7 @@ snprintf();
; return 0; }
EOF
if { (eval echo configure:1924: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
if { (eval echo configure:1958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_func_snprintf=yes"
else

View File

@ -1,4 +1,4 @@
# $Id: configure.in,v 1.10 1998/11/12 00:06:18 gram Exp $
# $Id: configure.in,v 1.11 1998/11/15 05:28:58 guy Exp $
dnl Process this file with autoconf to produce a configure script.
AC_INIT(etypes.h)
@ -91,9 +91,10 @@ AC_CHECK_HEADERS(sys/sockio.h sys/types.h netinet/in.h)
dnl Checks for typedefs, structures, and compiler characteristics.
# AC_C_CONST
# We need libpcap's AC_LBL_SOCKADDR_SA_LEN test for get_interface_list().
# We need to know whether "struct sockaddr" has an "sa_len" member
# for get_interface_list().
AC_LBL_SOCKADDR_SA_LEN
AC_ETHEREAL_STRUCT_SA_LEN
# We must know our byte order
AC_C_BIGENDIAN

26
file.c
View File

@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
* $Id: file.c,v 1.11 1998/11/12 00:06:20 gram Exp $
* $Id: file.c,v 1.12 1998/11/15 05:28:59 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -68,12 +68,20 @@ extern guint file_ctx;
static guint32 ssec, susec;
static guint32 lastsec, lastusec;
#ifdef WITH_WIRETAP
static void wtap_dispatch_cb(u_char *, const struct wtap_pkthdr *, int,
const u_char *);
#else
static void pcap_dispatch_cb(u_char *, const struct pcap_pkthdr *,
const u_char *);
#endif
int
open_cap_file(char *fname, capture_file *cf) {
#ifndef WITH_WIRETAP
guint32 magic[2];
#endif
char err_str[PCAP_ERRBUF_SIZE];
#endif
struct stat cf_stat;
/* First, make sure the file is valid */
@ -260,9 +268,9 @@ load_cap_file(char *fname, capture_file *cf) {
#endif
gtk_clist_freeze(GTK_CLIST(packet_list));
#ifdef WITH_WIRETAP
wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf);
wtap_close(cf->wth);
cf->wth = NULL;
wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf);
wtap_close(cf->wth);
cf->wth = NULL;
#else
pcap_loop(cf->pfh, 0, pcap_dispatch_cb, (u_char *) cf);
pcap_close(cf->pfh);
@ -301,9 +309,9 @@ load_cap_file(char *fname, capture_file *cf) {
return err;
}
void
static void
#ifdef WITH_WIRETAP
wtap_dispatch_cb(u_char *user, const struct wtap_pkthdr *phdr,
wtap_dispatch_cb(u_char *user, const struct wtap_pkthdr *phdr, int offset,
#else
pcap_dispatch_cb(u_char *user, const struct pcap_pkthdr *phdr,
#endif
@ -324,7 +332,11 @@ pcap_dispatch_cb(u_char *user, const struct pcap_pkthdr *phdr,
fdata->pkt_len = phdr->len;
fdata->cap_len = phdr->caplen;
#ifdef WITH_WIRETAP
fdata->file_off = offset;
#else
fdata->file_off = ftell(cf->fh) - phdr->caplen;
#endif
fdata->secs = phdr->ts.tv_sec;
fdata->usecs = phdr->ts.tv_usec;

46
file.h
View File

@ -1,7 +1,7 @@
/* file.h
* Definitions for file structures and routines
*
* $Id: file.h,v 1.5 1998/11/12 00:06:21 gram Exp $
* $Id: file.h,v 1.6 1998/11/15 05:29:01 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -31,29 +31,30 @@
#ifdef WITH_WIRETAP
#include <wtap.h>
#include <pcap.h>
#else
#include <pcap.h>
/* Data file formats */
#define CD_UNKNOWN 0
#define CD_WIRE 1
#define CD_SNOOP 2
#define CD_PCAP_BE 3
#define CD_PCAP_LE 4
#define CD_NA_UNCOMPR 5
/* Data file magic info */
#define SNOOP_MAGIC_1 0x736e6f6f /* 'snoop' in ASCII */
#define SNOOP_MAGIC_2 0x70000000
#define PCAP_MAGIC 0xa1b2c3d4
/* Data file format versions we can handle */
#define SNOOP_MIN_VERSION 2
#define SNOOP_MAX_VERSION 2
/* Link types (removed in favor of the DLT_* defines from bpf.h */
#endif
/* Data file formats */
#define CD_UNKNOWN 0
#define CD_WIRE 1
#define CD_SNOOP 2
#define CD_PCAP_BE 3
#define CD_PCAP_LE 4
#define CD_NA_UNCOMPR 5
/* Data file magic info */
#define SNOOP_MAGIC_1 0x736e6f6f /* 'snoop' in ASCII */
#define SNOOP_MAGIC_2 0x70000000
#define PCAP_MAGIC 0xa1b2c3d4
/* Data file format versions we can handle */
#define SNOOP_MIN_VERSION 2
#define SNOOP_MAX_VERSION 2
/* Link types (removed in favor of the DLT_* defines from bpf.h */
typedef struct bpf_program bpf_prog;
typedef struct _capture_file {
@ -105,11 +106,6 @@ typedef struct _snoop_frame_hdr {
int open_cap_file(char *, capture_file *);
void close_cap_file(capture_file *, GtkWidget *, guint);
int load_cap_file(char *, capture_file *);
#ifdef WITH_WIRETAP
void wtap_dispatch_cb(u_char *, const struct wtap_pkthdr *, const u_char *);
#else
void pcap_dispatch_cb(u_char *, const struct pcap_pkthdr *, const u_char *);
#endif
/* size_t read_frame_header(capture_file *); */
#endif /* file.h */

View File

@ -15,7 +15,7 @@
SHELL = /bin/sh
srcdir = .
top_srcdir = ..
top_srcdir = .
prefix = /usr/local
exec_prefix = ${prefix}
@ -34,9 +34,9 @@ oldincludedir = /usr/include
DISTDIR =
pkgdatadir = $(datadir)/ethereal
pkglibdir = $(libdir)/ethereal
pkgincludedir = $(includedir)/ethereal
pkgdatadir = $(datadir)/libwtap.a
pkglibdir = $(libdir)/libwtap.a
pkgincludedir = $(includedir)/libwtap.a
top_builddir = .
@ -45,7 +45,7 @@ AUTOCONF = autoconf
AUTOMAKE = automake
AUTOHEADER = autoheader
INSTALL = /usr/bin/install -c
INSTALL = ./../install-sh -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL_PROGRAM}
@ -58,13 +58,13 @@ NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
CC = gcc
GTK_CFLAGS = -I/usr/local/lib/glib/include -I/usr/local/include
GTK_CFLAGS = -I/usr/local/lib/glib/include -I/usr/local/include -I/usr/openwin/include
GTK_CONFIG = /usr/local/bin/gtk-config
GTK_LIBS = -L/usr/local/lib -L/usr/X11R6/lib -lgtk -lgdk -lglib -lXext -lX11 -lm
GTK_LIBS = -L/usr/local/lib -R/usr/local/lib -L/usr/openwin/lib -R/usr/openwin/lib -lgtk -lgdk -lglib -lXext -lX11 -lsocket -lnsl -lm
MAKEINFO = makeinfo
PACKAGE = ethereal
PACKAGE = libwtap.a
RANLIB = ranlib
VERSION = 0.4.1
VERSION = 0.0.0
noinst_LIBRARIES = libwiretap.a
@ -72,7 +72,9 @@ libwiretap_a_SOURCES = \
buffer.c \
file.c \
lanalyzer.c \
libpcap.c \
ngsniffer.c \
snoop.c \
wtap.c
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
@ -84,11 +86,12 @@ LIBRARIES = $(noinst_LIBRARIES)
DEFS = -DHAVE_CONFIG_H -I. -I$(srcdir) -I.
CPPFLAGS =
LDFLAGS =
LIBS = -lpcap -L/usr/local/lib -L/usr/X11R6/lib -lgtk -lgdk -lglib -lXext -lX11 -lm
LIBS = -L/usr/local/lib -R/usr/local/lib -L/usr/openwin/lib -R/usr/openwin/lib -lgtk -lgdk -lglib -lXext -lX11 -lsocket -lnsl -lm
libwiretap_a_LIBADD =
libwiretap_a_OBJECTS = buffer.o file.o lanalyzer.o ngsniffer.o wtap.o
libwiretap_a_OBJECTS = buffer.o file.o lanalyzer.o libpcap.o \
ngsniffer.o snoop.o wtap.o
AR = ar
CFLAGS = -g -O2 -I/usr/local/lib/glib/include -I/usr/local/include -Iwiretap
CFLAGS = -g -O2 -I/usr/local/lib/glib/include -I/usr/local/include -I/usr/openwin/include
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
@ -101,7 +104,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP = --best
DEP_FILES = .deps/buffer.P .deps/file.P .deps/lanalyzer.P \
.deps/ngsniffer.P .deps/wtap.P
.deps/libpcap.P .deps/ngsniffer.P .deps/snoop.P .deps/wtap.P
SOURCES = $(libwiretap_a_SOURCES)
OBJECTS = $(libwiretap_a_OBJECTS)

View File

@ -4,6 +4,8 @@ libwiretap_a_SOURCES = \
buffer.c \
file.c \
lanalyzer.c \
libpcap.c \
ngsniffer.c \
snoop.c \
wtap.c

View File

@ -72,7 +72,9 @@ libwiretap_a_SOURCES = \
buffer.c \
file.c \
lanalyzer.c \
libpcap.c \
ngsniffer.c \
snoop.c \
wtap.c
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
@ -86,7 +88,8 @@ CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libwiretap_a_LIBADD =
libwiretap_a_OBJECTS = buffer.o file.o lanalyzer.o ngsniffer.o wtap.o
libwiretap_a_OBJECTS = buffer.o file.o lanalyzer.o libpcap.o \
ngsniffer.o snoop.o wtap.o
AR = ar
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
@ -101,7 +104,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP = --best
DEP_FILES = .deps/buffer.P .deps/file.P .deps/lanalyzer.P \
.deps/ngsniffer.P .deps/wtap.P
.deps/libpcap.P .deps/ngsniffer.P .deps/snoop.P .deps/wtap.P
SOURCES = $(libwiretap_a_SOURCES)
OBJECTS = $(libwiretap_a_OBJECTS)

View File

@ -1,4 +1,4 @@
$Id: README,v 1.2 1998/11/12 06:01:17 gram Exp $
$Id: README,v 1.3 1998/11/15 05:29:05 guy Exp $
Wiretap is a library that is being developed as a future replacement for
libpcap, the current standard Unix library for packet capturing. Libpcap is
@ -36,19 +36,15 @@ File Formats
Libpcap
-------
Currently the libpcap file format is handled by linking in the pcap library.
Eventualy libpcap will not be linked in with wiretap as to avoid the overhead
of bringing in the libpcap packet capturing and BPF optimizing code.
The "libpcap" file format was determined by reading the "libpcap" code;
wiretap reads the "libpcap" file format with its own code, rather than
using the "libpcap" library's code to read it.
Sniffer
-------
The Sniffer format has been deduced by looking at hex dumps of Sniffer trace
files. I have access to many Token-Ring Sniffer trace files, but very few
ethernet Sniffer trace files. I am guessing as to which field in the header
denotes link type. Perhaps I am wrong; perhaps only the file extension (*.enc
vs. *.trc) denotes the link type. If you have a Sniffer trace file which
doesn't work with wiretap, please send it to me. BTW, I have not yet figured
out how packet timestamps are stored in the Sniffer format.
The Sniffer format, at least for Token-Ring, is documented in the
Sniffer manual. Unfortunately, Sniffer manuals tend to document only
the format for the Sniffer model they document.
LANalyzer
---------
@ -57,5 +53,9 @@ knowledge base for "Trace File Format". The code in wiretap so far only dumps
the packet data; I have yet to decode the timestamp for each packet. At least
I have the format for this, so it will be supported soon.
"snoop"
-------
The Solaris 2.x "snoop" program's format is documented in RFC 1761.
Gilbert Ramirez
<gram@verdict.uthscsa.edu>

66
wiretap/configure vendored
View File

@ -1224,9 +1224,8 @@ rm -f conftest*
rm -f conf.gtktest
# Pcap checks (copied from ethereal)
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:1230: checking how to run the C preprocessor" >&5
echo "configure:1229: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@ -1241,13 +1240,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
#line 1245 "configure"
#line 1244 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1251: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1250: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
@ -1258,13 +1257,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
#line 1262 "configure"
#line 1261 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1268: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1267: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
@ -1286,48 +1285,13 @@ else
fi
echo "$ac_t""$CPP" 1>&6
ac_safe=`echo "pcap.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for pcap.h""... $ac_c" 1>&6
echo "configure:1292: checking for pcap.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1297 "configure"
#include "confdefs.h"
#include <pcap.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1302: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_header_$ac_safe=no"
fi
rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
:
else
echo "$ac_t""no" 1>&6
{ echo "configure: error: Header file pcap.h not found." 1>&2; exit 1; }
fi
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
echo "configure:1326: checking for ANSI C header files" >&5
echo "configure:1290: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1331 "configure"
#line 1295 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@ -1335,7 +1299,7 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1339: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1303: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
@ -1352,7 +1316,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
#line 1356 "configure"
#line 1320 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@ -1370,7 +1334,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
#line 1374 "configure"
#line 1338 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@ -1391,7 +1355,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
#line 1395 "configure"
#line 1359 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@ -1402,7 +1366,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
if { (eval echo configure:1406: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
if { (eval echo configure:1370: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
then
:
else
@ -1429,17 +1393,17 @@ for ac_hdr in unistd.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:1433: checking for $ac_hdr" >&5
echo "configure:1397: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1438 "configure"
#line 1402 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1443: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1407: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*

View File

@ -1,4 +1,4 @@
# $Id: configure.in,v 1.3 1998/11/13 03:21:20 gram Exp $
# $Id: configure.in,v 1.4 1998/11/15 05:29:08 guy Exp $
dnl Process this file with autoconf to produce a configure script.
AC_INIT(wtap.c)
AM_INIT_AUTOMAKE(libwtap.a, 0.0.0)
@ -12,9 +12,6 @@ AC_PROG_RANLIB
AM_PATH_GTK(1.0.0, CFLAGS="$CFLAGS $GTK_CFLAGS" LIBS="$LIBS $GTK_LIBS",
AC_MSG_ERROR(GTK+ distribution not found.))
# Pcap checks (copied from ethereal)
AC_CHECK_HEADER(pcap.h,, AC_MSG_ERROR(Header file pcap.h not found.))
dnl Checks for header files
AC_HEADER_STDC
AC_CHECK_HEADERS(unistd.h)

View File

@ -1,6 +1,6 @@
/* file.c
*
* $Id: file.c,v 1.3 1998/11/12 23:29:34 gram Exp $
* $Id: file.c,v 1.4 1998/11/15 05:29:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -27,13 +27,13 @@
#include "wtap.h"
#include "lanalyzer.h"
#include "ngsniffer.h"
#include "libpcap.h"
#include "snoop.h"
/* The open_file_* routines should return the WTAP_FILE_* type
* that they are checking for if the file is successfully recognized
* as such. If the file is not of that type, the routine should return
* WTAP_FILE_UNKNOWN */
static int open_file_pcap(wtap *wth, char *filename);
static int convert_dlt_to_wtap_encap(int dlt);
/* Opens a file and prepares a wtap struct */
wtap* wtap_open_offline(char *filename, int filetype)
@ -50,7 +50,7 @@ wtap* wtap_open_offline(char *filename, int filetype)
/* If the filetype is unknown, try all my file types */
if (filetype == WTAP_FILE_UNKNOWN) {
/* WTAP_FILE_PCAP */
if ((wth->file_type = open_file_pcap(wth, filename)) != WTAP_FILE_UNKNOWN) {
if ((wth->file_type = libpcap_open(wth)) != WTAP_FILE_UNKNOWN) {
goto success;
}
/* WTAP_FILE_NGSNIFFER */
@ -61,6 +61,10 @@ wtap* wtap_open_offline(char *filename, int filetype)
if ((wth->file_type = lanalyzer_open(wth)) != WTAP_FILE_UNKNOWN) {
goto success;
}
/* WTAP_FILE_SNOOP */
if ((wth->file_type = snoop_open(wth)) != WTAP_FILE_UNKNOWN) {
goto success;
}
printf("failed\n");
/* WTAP_FILE_UNKNOWN */
@ -70,7 +74,7 @@ wtap* wtap_open_offline(char *filename, int filetype)
/* If the user tells us what the file is supposed to be, check it */
switch (filetype) {
case WTAP_FILE_PCAP:
if ((wth->file_type = open_file_pcap(wth, filename)) != WTAP_FILE_UNKNOWN) {
if ((wth->file_type = libpcap_open(wth)) != WTAP_FILE_UNKNOWN) {
goto success;
}
break;
@ -84,6 +88,11 @@ wtap* wtap_open_offline(char *filename, int filetype)
goto success;
}
break;
case WTAP_FILE_SNOOP:
if ((wth->file_type = snoop_open(wth)) != WTAP_FILE_UNKNOWN) {
goto success;
}
break;
default:
goto failure;
}
@ -104,66 +113,3 @@ success:
wth->file_byte_offset = 0;
return wth;
}
/* libpcap/tcpdump files */
static
int open_file_pcap(wtap *wth, char *filename)
{
int bytes_read, dlt;
struct pcap_file_header file_hdr;
fseek(wth->fh, 0, SEEK_SET);
bytes_read = fread((char*)&file_hdr, 1,
sizeof(struct pcap_file_header), wth->fh);
if (bytes_read != sizeof(struct pcap_file_header)) {
return WTAP_FILE_UNKNOWN;
}
if (file_hdr.magic != 0xa1b2c3d4) {
return WTAP_FILE_UNKNOWN;
}
/* This is a pcap file */
wth->capture.pcap = pcap_open_offline(filename, wth->err_str);
dlt = pcap_datalink(wth->capture.pcap);
wth->encapsulation = convert_dlt_to_wtap_encap(dlt);
wth->subtype_read = NULL;
/* For most file types I don't fclose my handle, but for pcap I'm
* letting libpcap handle the file, so I don't need an open file
* handle. Libpcap already has the file open with the above
* pcap_open_offline() */
fclose(wth->fh);
return WTAP_FILE_PCAP;
}
static
int convert_dlt_to_wtap_encap(int dlt)
{
int encap[] = {
WTAP_ENCAP_NONE,
WTAP_ENCAP_ETHERNET,
WTAP_ENCAP_NONE,
WTAP_ENCAP_NONE,
WTAP_ENCAP_NONE,
WTAP_ENCAP_NONE,
WTAP_ENCAP_TR,
WTAP_ENCAP_NONE,
WTAP_ENCAP_SLIP,
WTAP_ENCAP_PPP,
WTAP_ENCAP_FDDI,
WTAP_ENCAP_NONE,
WTAP_ENCAP_RAW_IP,
WTAP_ENCAP_NONE,
WTAP_ENCAP_NONE,
WTAP_ENCAP_NONE,
WTAP_ENCAP_NONE
};
return encap[dlt];
}

View File

@ -1,6 +1,6 @@
/* lanalyzer.c
*
* $Id: lanalyzer.c,v 1.1 1998/11/12 06:01:22 gram Exp $
* $Id: lanalyzer.c,v 1.2 1998/11/15 05:29:10 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -20,6 +20,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include <stdlib.h>
#include "wtap.h"
#include "lanalyzer.h"
@ -50,6 +51,7 @@ int lanalyzer_open(wtap *wth)
* Let's get some info from it */
wth->capture.lanalyzer = g_malloc(sizeof(lanalyzer_t));
wth->subtype_read = lanalyzer_read;
wth->snapshot_length = 16384; /* XXX - available in header? */
/* Read records until we find the start of packets */
@ -58,6 +60,7 @@ int lanalyzer_open(wtap *wth)
bytes_read = fread(record_type, 1, 2, wth->fh);
bytes_read += fread(record_length, 1, 2, wth->fh);
if (bytes_read != 4) {
free(wth->capture.lanalyzer);
return WTAP_FILE_UNKNOWN;
}
@ -106,6 +109,7 @@ int lanalyzer_read(wtap *wth)
char record_length[2];
guint16 type, length;
gchar descriptor[32];
int data_offset;
/* If this is the very first packet, then the fh cursor will already
* be at the start of the packet data instead of at the start of the Trace
@ -142,13 +146,18 @@ int lanalyzer_read(wtap *wth)
}
buffer_assure_space(&wth->frame_buffer, packet_size);
data_offset = ftell(wth->fh);
bytes_read = fread(buffer_start_ptr(&wth->frame_buffer), 1,
packet_size, wth->fh);
if (bytes_read != packet_size) {
g_error("lanalyzer_read: fread for data: %d bytes out of %d read",
bytes_read, packet_size);
return 0;
if (ferror(wth->fh)) {
g_error("lanalyzer_read: fread for data: read error\n");
} else {
g_error("lanalyzer_read: fread for data: %d bytes out of %d read",
bytes_read, packet_size);
}
return -1;
}
wth->phdr.ts.tv_sec = 0;
@ -156,7 +165,5 @@ int lanalyzer_read(wtap *wth)
wth->phdr.caplen = packet_size;
wth->phdr.len = packet_size;
return 1;
return data_offset;
}

212
wiretap/libpcap.c Normal file
View File

@ -0,0 +1,212 @@
/* libpcap.c
*
* $Id: libpcap.c,v 1.1 1998/11/15 05:29:11 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
* This program 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.
*
*/
#include "wtap.h"
#include "libpcap.h"
/* See source to the "libpcap" library for information on the "libpcap"
file format. */
/* Magic numbers in "libpcap" files.
"libpcap" file records are written in the byte order of the host that
writes them, and the reader is expected to fix this up.
PCAP_MAGIC is the magic number, in host byte order; PCAP_SWAPPED_MAGIC
is a byte-swapped version of that. */
#define PCAP_MAGIC 0xa1b2c3d4
#define PCAP_SWAPPED_MAGIC 0xd4c3b2a1
/* Macros to byte-swap 32-bit and 16-bit quantities. */
#define BSWAP32(x) \
((((x)&0xFF000000)>>24) | \
(((x)&0x00FF0000)>>8) | \
(((x)&0x0000FF00)<<8) | \
(((x)&0x000000FF)<<24))
#define BSWAP16(x) \
((((x)&0xFF00)>>8) | \
(((x)&0x00FF)<<8))
/* "libpcap" file header (minus magic number). */
struct pcap_hdr {
guint16 version_major; /* major version number */
guint16 version_minor; /* minor version number */
gint32 thiszone; /* GMT to local correction */
guint32 sigfigs; /* accuracy of timestamps */
guint32 snaplen; /* max length of captured packets, in octets */
guint32 network; /* data link type */
};
/* "libpcap" record header. */
struct pcaprec_hdr {
guint32 ts_sec; /* timestamp seconds */
guint32 ts_usec; /* timestamp microseconds */
guint32 incl_len; /* number of octets captured in file */
guint32 orig_len; /* actual length of packet */
};
/* Returns WTAP_FILE_PCAP on success, WTAP_FILE_UNKNOWN on failure */
int libpcap_open(wtap *wth)
{
int bytes_read;
guint32 magic;
struct pcap_hdr hdr;
static const int pcap_encap[] = {
WTAP_ENCAP_NONE, /* no encapsulation */
WTAP_ENCAP_ETHERNET,
WTAP_ENCAP_NONE, /* 3Mb experimental Ethernet */
WTAP_ENCAP_NONE, /* Amateur Radio AX.25 */
WTAP_ENCAP_NONE, /* Proteon ProNET Token Ring */
WTAP_ENCAP_NONE, /* Chaos */
WTAP_ENCAP_TR, /* IEEE 802 Networks - assume token ring */
WTAP_ENCAP_ARCNET,
WTAP_ENCAP_SLIP,
WTAP_ENCAP_PPP,
WTAP_ENCAP_FDDI,
WTAP_ENCAP_NONE, /* LLC/SNAP-encapsulated ATM (RFC 1483) */
WTAP_ENCAP_RAW_IP
};
#define NUM_PCAP_ENCAPS (sizeof pcap_encap / sizeof pcap_encap[0])
int byte_swapped = 0;
/* Read in the number that should be at the start of a "libpcap" file */
fseek(wth->fh, 0, SEEK_SET);
bytes_read = fread(&magic, 1, sizeof magic, wth->fh);
if (bytes_read != sizeof magic) {
return WTAP_FILE_UNKNOWN;
}
if (magic == PCAP_SWAPPED_MAGIC) {
/* Host that wrote it has a byte order opposite to ours. */
magic = PCAP_MAGIC;
byte_swapped = 1;
}
if (magic != PCAP_MAGIC) {
return WTAP_FILE_UNKNOWN;
}
/* Read the rest of the header. */
bytes_read = fread(&hdr, 1, sizeof hdr, wth->fh);
if (bytes_read != sizeof hdr) {
return WTAP_FILE_UNKNOWN;
}
if (byte_swapped) {
/* Byte-swap the header fields about which we care. */
hdr.version_major = BSWAP16(hdr.version_major);
hdr.version_minor = BSWAP16(hdr.version_minor);
hdr.snaplen = BSWAP32(hdr.snaplen);
hdr.network = BSWAP32(hdr.network);
}
if (hdr.version_major < 2) {
/* We only support version 2.0 and later. */
return WTAP_FILE_UNKNOWN;
}
if (hdr.network >= NUM_PCAP_ENCAPS) {
g_error("pcap: network type %d unknown", hdr.network);
return WTAP_FILE_UNKNOWN;
}
/* This is a libpcap file */
wth->capture.pcap = g_malloc(sizeof(libpcap_t));
wth->capture.pcap->byte_swapped = byte_swapped;
wth->capture.pcap->version_major = hdr.version_major;
wth->capture.pcap->version_minor = hdr.version_minor;
wth->subtype_read = libpcap_read;
wth->encapsulation = pcap_encap[hdr.network];
wth->snapshot_length = hdr.snaplen;
/*wth->frame_number = 0;*/
/*wth->file_byte_offset = 0x10b;*/
return WTAP_FILE_PCAP;
}
/* Read the next packet */
int libpcap_read(wtap *wth)
{
int packet_size;
int bytes_read;
struct pcaprec_hdr hdr;
int data_offset;
/* Read record header. */
bytes_read = fread(&hdr, 1, sizeof hdr, wth->fh);
if (bytes_read != sizeof hdr) {
if (bytes_read != 0) {
g_error("pcap_read: not enough packet header data (%d bytes)",
bytes_read);
return -1;
}
return 0;
}
if (wth->capture.pcap->byte_swapped) {
/* Byte-swap the record header fields. */
hdr.ts_sec = BSWAP32(hdr.ts_sec);
hdr.ts_usec = BSWAP32(hdr.ts_usec);
hdr.incl_len = BSWAP32(hdr.incl_len);
hdr.orig_len = BSWAP32(hdr.orig_len);
}
/* In file format version 2.3, the "incl_len" and "orig_len" fields
were swapped, in order to match the BPF header layout.
Unfortunately, some files were, according to a comment in the
"libpcap" source, written with version 2.3 in their headers
but without the interchanged fields, so if "incl_len" is
greater than "orig_len" - which would make no sense - we
assume that we need to swap them. */
if (wth->capture.pcap->version_major == 2 &&
(wth->capture.pcap->version_minor < 3 ||
(wth->capture.pcap->version_minor == 3 &&
hdr.incl_len > hdr.orig_len))) {
guint32 temp;
temp = hdr.orig_len;
hdr.orig_len = hdr.incl_len;
hdr.incl_len = temp;
}
packet_size = hdr.incl_len;
buffer_assure_space(&wth->frame_buffer, packet_size);
data_offset = ftell(wth->fh);
bytes_read = fread(buffer_start_ptr(&wth->frame_buffer), 1,
packet_size, wth->fh);
if (bytes_read != packet_size) {
if (ferror(wth->fh)) {
g_error("pcap_read: fread for data: read error\n");
} else {
g_error("pcap_read: fread for data: %d bytes out of %d",
bytes_read, packet_size);
}
return -1;
}
wth->phdr.ts.tv_sec = hdr.ts_sec;
wth->phdr.ts.tv_usec = hdr.ts_usec;
wth->phdr.caplen = packet_size;
wth->phdr.len = hdr.orig_len;
return data_offset;
}

25
wiretap/libpcap.h Normal file
View File

@ -0,0 +1,25 @@
/* libpcap.h
*
* $Id: libpcap.h,v 1.1 1998/11/15 05:29:12 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
* This program 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.
*
*/
int libpcap_open(wtap *wth);
int libpcap_read(wtap *wth);

View File

@ -1,6 +1,6 @@
/* ngsniffer.c
*
* $Id: ngsniffer.c,v 1.4 1998/11/13 06:47:36 gram Exp $
* $Id: ngsniffer.c,v 1.5 1998/11/15 05:29:13 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -56,6 +56,7 @@
*
*/
#include <stdlib.h>
#include "wtap.h"
#include "ngsniffer.h"
@ -107,6 +108,7 @@ int ngsniffer_open(wtap *wth)
/* This is a ngsniffer file */
wth->capture.ngsniffer = g_malloc(sizeof(ngsniffer_t));
wth->subtype_read = ngsniffer_read;
wth->snapshot_length = 16384; /* XXX - available in header? */
/*wth->frame_number = 0;*/
/*wth->file_byte_offset = 0x10b;*/
@ -116,6 +118,7 @@ int ngsniffer_open(wtap *wth)
bytes_read = fread(record_type, 1, 2, wth->fh);
bytes_read += fread(record_length, 1, 4, wth->fh);
if (bytes_read != 6) {
free(wth->capture.ngsniffer);
return WTAP_FILE_UNKNOWN;
}
@ -132,6 +135,7 @@ int ngsniffer_open(wtap *wth)
network = version[9];
if (network >= NUM_NGSNIFF_ENCAPS) {
g_error("ngsniffer: network type %d unknown", network);
free(wth->capture.ngsniffer);
return WTAP_FILE_UNKNOWN;
}
else {
@ -142,6 +146,7 @@ int ngsniffer_open(wtap *wth)
timeunit = version[11];
if (timeunit >= NUM_NGSNIFF_TIMEUNITS) {
g_error("ngsniffer: Unknown timeunit %d", timeunit);
free(wth->capture.ngsniffer);
return WTAP_FILE_UNKNOWN;
}
else {
@ -173,6 +178,7 @@ int ngsniffer_read(wtap *wth)
char frame2[14];
double t, x;
guint16 time_low, time_med, time_high, true_size, size;
int data_offset;
/* if this is the very first packet, then the fh cursor will be at the
* start of a f_frame2_struct instead of at the start of the record.
@ -216,13 +222,18 @@ int ngsniffer_read(wtap *wth)
time_high = frame2[4];
buffer_assure_space(&wth->frame_buffer, packet_size);
data_offset = ftell(wth->fh);
bytes_read = fread(buffer_start_ptr(&wth->frame_buffer), 1,
packet_size, wth->fh);
if (bytes_read != packet_size) {
g_error("ngsniffer_read: fread for data: %d bytes out of %d",
if (ferror(wth->fh)) {
g_error("ngsniffer_read: fread for data: read error\n");
} else {
g_error("ngsniffer_read: fread for data: %d bytes out of %d",
bytes_read, packet_size);
return 0;
}
return -1;
}
x = 4.0 * (double)(1<<30);
@ -236,5 +247,5 @@ int ngsniffer_read(wtap *wth)
wth->phdr.len = true_size ? true_size : size;
wth->phdr.caplen = size;
return 1;
return data_offset;
}

154
wiretap/snoop.c Normal file
View File

@ -0,0 +1,154 @@
/* snoop.c
*
* $Id: snoop.c,v 1.1 1998/11/15 05:29:14 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
* This program 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.
*
*/
#include "wtap.h"
#include "snoop.h"
#include <netinet/in.h>
/* See RFC 1761 for a description of the "snoop" file format. */
/* Magic number in "snoop" files. */
static char snoop_magic[] = {
's', 'n', 'o', 'o', 'p', '\0', '\0', '\0'
};
/* "snoop" file header (minus magic number). */
struct snoop_hdr {
guint32 version; /* version number (should be 2) */
guint32 network; /* network type */
};
/* "snoop" record header. */
struct snooprec_hdr {
guint32 orig_len; /* actual length of packet */
guint32 incl_len; /* number of octets captured in file */
guint32 rec_len; /* length of record */
guint32 cum_drops; /* cumulative number of dropped packets */
guint32 ts_sec; /* timestamp seconds */
guint32 ts_usec; /* timestamp microseconds */
};
/* Returns WTAP_FILE_SNOOP on success, WTAP_FILE_UNKNOWN on failure */
int snoop_open(wtap *wth)
{
int bytes_read;
char magic[sizeof snoop_magic];
struct snoop_hdr hdr;
static const int snoop_encap[] = {
WTAP_ENCAP_NONE, /* IEEE 802.3 */
WTAP_ENCAP_NONE, /* IEEE 802.4 Token Bus */
WTAP_ENCAP_TR,
WTAP_ENCAP_NONE, /* IEEE 802.6 Metro Net */
WTAP_ENCAP_ETHERNET,
WTAP_ENCAP_NONE, /* HDLC */
WTAP_ENCAP_NONE, /* Character Synchronous */
WTAP_ENCAP_NONE, /* IBM Channel-to-Channel */
WTAP_ENCAP_FDDI,
WTAP_ENCAP_NONE /* Other */
};
#define NUM_SNOOP_ENCAPS (sizeof snoop_encap / sizeof snoop_encap[0])
/* Read in the string that should be at the start of a "snoop" file */
fseek(wth->fh, 0, SEEK_SET);
bytes_read = fread(magic, 1, sizeof magic, wth->fh);
if (bytes_read != sizeof magic) {
return WTAP_FILE_UNKNOWN;
}
if (memcmp(magic, snoop_magic, sizeof snoop_magic) != 0) {
return WTAP_FILE_UNKNOWN;
}
/* Read the rest of the header. */
bytes_read = fread(&hdr, 1, sizeof hdr, wth->fh);
if (bytes_read != sizeof hdr) {
return WTAP_FILE_UNKNOWN;
}
hdr.version = ntohl(hdr.version);
if (hdr.version != 2) {
/* We only support version 2. */
return WTAP_FILE_UNKNOWN;
}
hdr.network = ntohl(hdr.network);
if (hdr.network >= NUM_SNOOP_ENCAPS) {
g_error("snoop: network type %d unknown", hdr.network);
return WTAP_FILE_UNKNOWN;
}
/* This is a snoop file */
wth->subtype_read = snoop_read;
wth->encapsulation = snoop_encap[hdr.network];
wth->snapshot_length = 16384; /* XXX - not available in header */
/*wth->frame_number = 0;*/
/*wth->file_byte_offset = 0x10b;*/
return WTAP_FILE_SNOOP;
}
/* Read the next packet */
int snoop_read(wtap *wth)
{
int packet_size;
int bytes_read;
struct snooprec_hdr hdr;
int data_offset;
/* Read record header. */
bytes_read = fread(&hdr, 1, sizeof hdr, wth->fh);
if (bytes_read != sizeof hdr) {
if (bytes_read != 0) {
g_error("snoop_read: not enough packet header data (%d bytes)",
bytes_read);
return -1;
}
return 0;
}
packet_size = ntohl(hdr.incl_len);
buffer_assure_space(&wth->frame_buffer, packet_size);
data_offset = ftell(wth->fh);
bytes_read = fread(buffer_start_ptr(&wth->frame_buffer), 1,
packet_size, wth->fh);
if (bytes_read != packet_size) {
if (ferror(wth->fh)) {
g_error("snoop_read: fread for data: read error\n");
} else {
g_error("snoop_read: fread for data: %d bytes out of %d",
bytes_read, packet_size);
}
return -1;
}
wth->phdr.ts.tv_sec = ntohl(hdr.ts_sec);
wth->phdr.ts.tv_usec = ntohl(hdr.ts_usec);
wth->phdr.caplen = packet_size;
wth->phdr.len = ntohl(hdr.orig_len);
/* Skip over the padding. */
fseek(wth->fh, ntohl(hdr.rec_len) - (sizeof hdr + packet_size),
SEEK_CUR);
return data_offset;
}

25
wiretap/snoop.h Normal file
View File

@ -0,0 +1,25 @@
/* snoop.h
*
* $Id: snoop.h,v 1.1 1998/11/15 05:29:15 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
* This program 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.
*
*/
int snoop_open(wtap *wth);
int snoop_read(wtap *wth);

View File

@ -1,6 +1,6 @@
/* wtap.c
*
* $Id: wtap.c,v 1.2 1998/11/12 06:01:26 gram Exp $
* $Id: wtap.c,v 1.3 1998/11/15 05:29:16 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -23,19 +23,9 @@
#include "wtap.h"
static
void pcap_callback_wrapper(u_char *user, const struct pcap_pkthdr *phdr,
const u_char *buf);
wtap_handler wtap_callback = NULL;
FILE* wtap_file(wtap *wth)
{
if (wth->file_type == WTAP_FILE_PCAP) {
return pcap_file(wth->capture.pcap);
}
else
return wth->fh;
return wth->fh;
}
int wtap_file_type(wtap *wth)
@ -51,44 +41,24 @@ int wtap_encapsulation(wtap *wth)
int wtap_snapshot_length(wtap *wth)
{
if (wth->file_type == WTAP_FILE_PCAP)
return pcap_snapshot(wth->capture.pcap);
else
/* this is obviously *very* temporary :-) */
return 5000;
return wth->snapshot_length;
}
void wtap_close(wtap *wth)
{
if (wth->file_type == WTAP_FILE_PCAP)
pcap_close(wth->capture.pcap);
else
fclose(wth->fh);
/* XXX - free up memory? */
fclose(wth->fh);
}
void wtap_loop(wtap *wth, int count, wtap_handler callback, u_char* user)
{
int i = 0;
int data_offset;
if (wth->file_type == WTAP_FILE_PCAP) {
wtap_callback = callback;
pcap_loop(wth->capture.pcap, count, pcap_callback_wrapper, user);
}
else {
/*while (ngsniffer_read(wth)) {*/
while (wth->subtype_read(wth)) {
i++;
/*g_message("Parsing packet %d", i);*/
callback(user, &wth->phdr, buffer_start_ptr(&wth->frame_buffer));
}
while ((data_offset = wth->subtype_read(wth)) > 0) {
i++;
/*g_message("Parsing packet %d", i);*/
callback(user, &wth->phdr, data_offset,
buffer_start_ptr(&wth->frame_buffer));
}
}
static
void pcap_callback_wrapper(u_char *user, const struct pcap_pkthdr *phdr,
const u_char *buf)
{
/* struct wtap_pkthdr whdr;
memcpy(&whdr, phdr, sizeof(struct wtap_pkthdr));*/
wtap_callback(user, (struct wtap_pkthdr*) phdr, buf);
}

View File

@ -1,6 +1,6 @@
/* wtap.h
*
* $Id: wtap.h,v 1.4 1998/11/13 06:47:37 gram Exp $
* $Id: wtap.h,v 1.5 1998/11/15 05:29:17 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -43,7 +43,7 @@
#include <sys/types.h>
#include <sys/time.h>
#include <glib.h>
#include <pcap.h>
#include <stdio.h>
#include <buffer.h>
typedef struct {
@ -56,6 +56,12 @@ typedef struct {
guint32 totpktt;
} lanalyzer_t;
typedef struct {
int byte_swapped;
guint16 version_major;
guint16 version_minor;
} libpcap_t;
struct wtap_pkthdr {
struct timeval ts;
guint32 caplen;
@ -63,26 +69,26 @@ struct wtap_pkthdr {
};
typedef void (*wtap_handler)(u_char*, const struct wtap_pkthdr*,
const u_char *);
int, const u_char *);
struct wtap;
typedef int (*subtype_func)(struct wtap*);
typedef struct wtap {
FILE* fh;
int file_type;
int snapshot_length;
unsigned long frame_number;
unsigned long file_byte_offset;
Buffer frame_buffer;
struct wtap_pkthdr phdr;
union {
pcap_t *pcap;
libpcap_t *pcap;
lanalyzer_t *lanalyzer;
ngsniffer_t *ngsniffer;
} capture;
subtype_func subtype_read;
char err_str[PCAP_ERRBUF_SIZE];
int encapsulation;
} wtap;