diff options
-rw-r--r-- | Makefile.in | 8 | ||||
-rw-r--r-- | acconfig.h | 2 | ||||
-rw-r--r-- | aclocal.m4 | 70 | ||||
-rw-r--r-- | capture.c | 4 | ||||
-rw-r--r-- | config.h.in | 2 | ||||
-rwxr-xr-x | configure | 70 | ||||
-rw-r--r-- | configure.in | 7 | ||||
-rw-r--r-- | file.c | 26 | ||||
-rw-r--r-- | file.h | 40 | ||||
-rw-r--r-- | wiretap/Makefile | 29 | ||||
-rw-r--r-- | wiretap/Makefile.am | 2 | ||||
-rw-r--r-- | wiretap/Makefile.in | 7 | ||||
-rw-r--r-- | wiretap/README | 22 | ||||
-rwxr-xr-x | wiretap/configure | 66 | ||||
-rw-r--r-- | wiretap/configure.in | 5 | ||||
-rw-r--r-- | wiretap/file.c | 82 | ||||
-rw-r--r-- | wiretap/lanalyzer.c | 21 | ||||
-rw-r--r-- | wiretap/libpcap.c | 212 | ||||
-rw-r--r-- | wiretap/libpcap.h | 25 | ||||
-rw-r--r-- | wiretap/ngsniffer.c | 19 | ||||
-rw-r--r-- | wiretap/snoop.c | 154 | ||||
-rw-r--r-- | wiretap/snoop.h | 25 | ||||
-rw-r--r-- | wiretap/wtap.c | 52 | ||||
-rw-r--r-- | wiretap/wtap.h | 16 |
24 files changed, 703 insertions, 263 deletions
diff --git a/Makefile.in b/Makefile.in index e509090d9f..1678de55ef 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 diff --git a/acconfig.h b/acconfig.h index e24f8eb258..49aaba9156 100644 --- a/acconfig.h +++ b/acconfig.h @@ -2,7 +2,7 @@ #undef VERSION -#undef HAVE_SOCKADDR_SA_LEN +#undef HAVE_SA_LEN #undef DATAFILE_DIR diff --git a/aclocal.m4 b/aclocal.m4 index 2052094092..aa8e872e78 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -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. @@ -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)); diff --git a/config.h.in b/config.h.in index 66a8c35379..ad8d4c00ab 100644 --- a/config.h.in +++ b/config.h.in @@ -11,6 +11,8 @@ #undef VERSION +#undef HAVE_SA_LEN + #undef DATAFILE_DIR #undef NEED_SNPRINTF_H @@ -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 diff --git a/configure.in b/configure.in index 08aa2e7402..0286fd2bdf 100644 --- a/configure.in +++ b/configure.in @@ -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 @@ -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; @@ -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,28 +31,29 @@ #ifdef WITH_WIRETAP #include <wtap.h> + #include <pcap.h> #else #include <pcap.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 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 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 + /* 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 */ + /* Link types (removed in favor of the DLT_* defines from bpf.h */ +#endif typedef struct bpf_program bpf_prog; @@ -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 */ diff --git a/wiretap/Makefile b/wiretap/Makefile index 2b53870591..ecd6b67d8f 100644 --- a/wiretap/Makefile +++ b/wiretap/Makefile @@ -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) diff --git a/wiretap/Makefile.am b/wiretap/Makefile.am index cb753935b4..8913ef3d1d 100644 --- a/wiretap/Makefile.am +++ b/wiretap/Makefile.am @@ -4,6 +4,8 @@ libwiretap_a_SOURCES = \ buffer.c \ file.c \ lanalyzer.c \ + libpcap.c \ ngsniffer.c \ + snoop.c \ wtap.c diff --git a/wiretap/Makefile.in b/wiretap/Makefile.in index 8faf818bb2..a26da4054b 100644 --- a/wiretap/Makefile.in +++ b/wiretap/Makefile.in @@ -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) diff --git a/wiretap/README b/wiretap/README index f4c7f2f2a0..980c809330 100644 --- a/wiretap/README +++ b/wiretap/README @@ -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> diff --git a/wiretap/configure b/wiretap/configure index 272767a439..3c58fd137b 100755 --- a/wiretap/configure +++ b/wiretap/configure @@ -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* diff --git a/wiretap/configure.in b/wiretap/configure.in index cb2f94757f..5dc1287119 100644 --- a/wiretap/configure.in +++ b/wiretap/configure.in @@ -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) diff --git a/wiretap/file.c b/wiretap/file.c index 0a2390b3e8..5aee94034f 100644 --- a/wiretap/file.c +++ b/wiretap/file.c @@ -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]; -} - diff --git a/wiretap/lanalyzer.c b/wiretap/lanalyzer.c index 91bdf86ea4..811fa1b901 100644 --- a/wiretap/lanalyzer.c +++ b/wiretap/lanalyzer.c @@ -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; } - diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c new file mode 100644 index 0000000000..fc901c6b19 --- /dev/null +++ b/wiretap/libpcap.c @@ -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; +} diff --git a/wiretap/libpcap.h b/wiretap/libpcap.h new file mode 100644 index 0000000000..5de0a34e71 --- /dev/null +++ b/wiretap/libpcap.h @@ -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); diff --git a/wiretap/ngsniffer.c b/wiretap/ngsniffer.c index e78793010f..3b085638d1 100644 --- a/wiretap/ngsniffer.c +++ b/wiretap/ngsniffer.c @@ -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; } diff --git a/wiretap/snoop.c b/wiretap/snoop.c new file mode 100644 index 0000000000..c43f9f5f38 --- /dev/null +++ b/wiretap/snoop.c @@ -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; +} diff --git a/wiretap/snoop.h b/wiretap/snoop.h new file mode 100644 index 0000000000..d1d5461de2 --- /dev/null +++ b/wiretap/snoop.h @@ -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); diff --git a/wiretap/wtap.c b/wiretap/wtap.c index 1da8f4ed23..f8e02cd8e8 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -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); -} diff --git a/wiretap/wtap.h b/wiretap/wtap.h index a16491f407..2256cddc59 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -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; |