Added display filters to wiretap.

svn path=/trunk/; revision=198
This commit is contained in:
Gilbert Ramirez 1999-03-01 18:57:07 +00:00
parent 2744866326
commit 2dbd008ea5
41 changed files with 3583 additions and 172 deletions

View File

@ -1,6 +1,6 @@
/* ethereal.c
*
* $Id: ethereal.c,v 1.23 1999/02/19 05:28:38 guy Exp $
* $Id: ethereal.c,v 1.24 1999/03/01 18:57:00 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -289,6 +289,8 @@ void
file_reload_cmd_cb(GtkWidget *w, gpointer data) {
GtkWidget *filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
if (cf.dfilter) g_free(cf.dfilter);
cf.dfilter = g_strdup(gtk_entry_get_text(GTK_ENTRY(filter_te)));
load_cap_file(cf.filename, &cf);
@ -705,24 +707,23 @@ main(int argc, char *argv[])
GTK_SIGNAL_FUNC(prefs_cb), (gpointer) E_PR_PG_FILTER);
gtk_box_pack_start(GTK_BOX(stat_hbox), filter_bt, FALSE, TRUE, 0);
gtk_widget_show(filter_bt);
#ifdef WITH_WIRETAP
gtk_widget_set_sensitive(filter_bt, FALSE);
#endif
filter_te = gtk_entry_new();
gtk_object_set_data(GTK_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te);
gtk_box_pack_start(GTK_BOX(stat_hbox), filter_te, TRUE, TRUE, 3);
gtk_widget_show(filter_te);
#ifdef WITH_WIRETAP
gtk_widget_set_sensitive(filter_te, FALSE);
gtk_entry_set_text(GTK_ENTRY(filter_te), "<unavailable>");
#endif
#ifdef USE_ITEM
set_menu_object_data("/File/Open", E_DFILTER_TE_KEY, filter_te);
set_menu_object_data("/File/Reload", E_DFILTER_TE_KEY, filter_te);
set_menu_object_data("/Tools/Follow TCP Stream", E_DFILTER_TE_KEY,
filter_te);
#else
set_menu_object_data("<Main>/File/Open", E_DFILTER_TE_KEY, filter_te);
set_menu_object_data("<Main>/File/Reload", E_DFILTER_TE_KEY, filter_te);
set_menu_object_data("<Main>/Tools/Follow TCP Stream", E_DFILTER_TE_KEY,
filter_te);
#endif
info_bar = gtk_statusbar_new();
main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main");
file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file");

8
file.c
View File

@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
* $Id: file.c,v 1.19 1999/01/21 05:03:55 gram Exp $
* $Id: file.c,v 1.20 1999/03/01 18:57:01 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -181,6 +181,12 @@ open_cap_file(char *fname, capture_file *cf) {
return 1;
}
#else
if (cf->dfilter) {
if (wtap_offline_filter(cf->wth, cf->dfilter) < 0) {
simple_dialog(ESD_TYPE_WARN, NULL, "Unable to parse filter string "
"\"%s\".", cf->dfilter);
}
}
cf->fh = wtap_file(cf->wth);
cf->cd_t = wtap_file_type(cf->wth);
cf->snap = wtap_snapshot_length(cf->wth);

6
menu.c
View File

@ -1,7 +1,7 @@
/* menu.c
* Menu routines
*
* $Id: menu.c,v 1.13 1999/02/09 00:35:36 guy Exp $
* $Id: menu.c,v 1.14 1999/03/01 18:57:01 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -167,7 +167,9 @@ menus_init(void) {
#ifdef USE_ITEM
factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", grp);
gtk_item_factory_create_items(factory, nmenu_items, menu_items, NULL);
/*gtk_item_factory_create_items(factory, nmenu_items, menu_items,
*NULL);grj*/
gtk_item_factory_create_items_ac(factory, nmenu_items, menu_items, NULL,2);
set_menu_sensitivity("/File/Close", FALSE);
set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save as", FALSE);

View File

@ -1,7 +1,7 @@
/* prefs.c
* Routines for handling preferences
*
* $Id: prefs.c,v 1.15 1998/12/29 04:05:36 gerald Exp $
* $Id: prefs.c,v 1.16 1999/03/01 18:57:01 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -115,9 +115,6 @@ prefs_cb(GtkWidget *w, gpointer sp) {
if (w)
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_FILT_TE_PTR_KEY);
filter_pg = filter_prefs_show(filter_te);
#ifdef WITH_WIRETAP
gtk_widget_set_sensitive(filter_pg, FALSE);
#endif
/* Pass along the entry widget pointer from the calling widget */
gtk_object_set_data(GTK_OBJECT(filter_pg), E_FILT_TE_PTR_KEY, filter_te);

View File

@ -1,3 +1,9 @@
March 1, 1999
Added first code for display filters.
February 20, 1999
Guy added the netxray file format.
January 27, 1999
Added token-ring support in netmon.c
@ -5,7 +11,7 @@ January 19, 1999
Changed number of arguments of wtap_open_offline().
January 14, 1999
Guy added support for reading MicroSoft Network Monitor files.
Guy added support for reading Microsoft Network Monitor files.
January 7, 1999
Made all filetypes provide a per-packet encapsulation type, and

View File

@ -1,14 +1,27 @@
bin_PROGRAMS = wiretap filterc
noinst_LIBRARIES = @LIBWIRETAP_A@
EXTRA_LIBRARIES = libwiretap.a
CLEANFILES = libwiretap.a
CLEANFILES = \
libwiretap.a \
filterc \
*~ \
ct-grammar.c \
ct-scanner.c \
ct-tokdefs.h \
rt-grammar.c \
rt-grammar.y \
rt-scanner.c \
rt-scanner.l \
rt-tokdefs.h
libwiretap_a_SOURCES = \
bpf.c \
bpf-engine.c \
buffer.c \
buffer.h \
config.h \
debug.h \
file.c \
iptrace.c \
iptrace.h \
@ -22,7 +35,58 @@ libwiretap_a_SOURCES = \
netxray.h \
ngsniffer.c \
ngsniffer.h \
rt-compile.c \
rt-grammar.c \
rt-scanner.c \
snoop.c \
snoop.h \
wtap.c \
wtap.h
filterc_SOURCES = \
ct-compile.c \
ct-grammar.c \
ct-main.c \
ct-scanner.c \
glib-new.c
FILTERS = \
filter-eth \
filter-tr
CT_YACC=bison -y
CT_LEX=flex -i
RT_YACC=bison -y -p wtap_
RT_LEX=flex -i -Pwtap_
ct-grammar.c : ct-grammar.y
@rm -f $@ ct-tokdefs.h
$(CT_YACC) -d $<
mv y.tab.c ct-grammar.c
mv y.tab.h ct-tokdefs.h
ct-scanner.c : ct-scanner.l
@rm -f $@
$(CT_LEX) -t $< > $@
rt-scanner.l : rt-scanner-skel.l filterc
cat $(FILTERS) | ./filterc > /dev/null
rt-scanner.c : rt-scanner.l rt-grammar.c
@rm -f $@
$(RT_LEX) -t $< > $@
rt-grammar.y : rt-grammar-skel.y filterc
cat $(FILTERS) | ./filterc > /dev/null
rt-grammar.c : rt-grammar.y
@rm -f $@ rt-tokdefs.h
$(RT_YACC) -d $<
mv y.tab.c rt-grammar.c
mv y.tab.h rt-tokdefs.h
wiretap_SOURCES = \
wiretap.c \
glib-new.c
wiretap_LDADD = libwiretap.a

View File

@ -58,6 +58,9 @@ NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
CC = @CC@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_CONFIG = @GLIB_CONFIG@
GLIB_LIBS = @GLIB_LIBS@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_CONFIG = @GTK_CONFIG@
GTK_LIBS = @GTK_LIBS@
@ -67,17 +70,30 @@ PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
VERSION = @VERSION@
bin_PROGRAMS = wiretap filterc
noinst_LIBRARIES = @LIBWIRETAP_A@
EXTRA_LIBRARIES = libwiretap.a
CLEANFILES = libwiretap.a
CLEANFILES = \
libwiretap.a \
filterc \
*~ \
ct-grammar.c \
ct-scanner.c \
ct-tokdefs.h \
rt-grammar.c \
rt-grammar.y \
rt-scanner.c \
rt-scanner.l \
rt-tokdefs.h
libwiretap_a_SOURCES = \
bpf.c \
bpf-engine.c \
buffer.c \
buffer.h \
config.h \
debug.h \
file.c \
iptrace.c \
iptrace.h \
@ -91,10 +107,35 @@ libwiretap_a_SOURCES = \
netxray.h \
ngsniffer.c \
ngsniffer.h \
rt-compile.c \
rt-grammar.c \
rt-scanner.c \
snoop.c \
snoop.h \
wtap.c \
wtap.h
filterc_SOURCES = \
ct-compile.c \
ct-grammar.c \
ct-main.c \
ct-scanner.c \
glib-new.c
FILTERS = \
filter-eth \
filter-tr
CT_YACC=bison -y
CT_LEX=flex -i
RT_YACC=bison -y -p wtap_
RT_LEX=flex -i -Pwtap_
wiretap_SOURCES = \
wiretap.c \
glib-new.c
wiretap_LDADD = libwiretap.a
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = config.h
@ -107,9 +148,20 @@ CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libwiretap_a_LIBADD =
libwiretap_a_OBJECTS = buffer.o file.o iptrace.o lanalyzer.o libpcap.o \
netmon.o netxray.o ngsniffer.o snoop.o wtap.o
libwiretap_a_OBJECTS = bpf.o bpf-engine.o buffer.o file.o iptrace.o \
lanalyzer.o libpcap.o netmon.o netxray.o ngsniffer.o rt-compile.o \
rt-grammar.o rt-scanner.o snoop.o wtap.o
AR = ar
PROGRAMS = $(bin_PROGRAMS)
wiretap_OBJECTS = wiretap.o glib-new.o
wiretap_DEPENDENCIES = libwiretap.a
wiretap_LDFLAGS =
filterc_OBJECTS = ct-compile.o ct-grammar.o ct-main.o ct-scanner.o \
glib-new.o
filterc_LDADD = $(LDADD)
filterc_DEPENDENCIES =
filterc_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
@ -122,13 +174,16 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP = --best
DEP_FILES = .deps/buffer.P .deps/file.P .deps/iptrace.P \
DEP_FILES = .deps/bpf-engine.P .deps/bpf.P .deps/buffer.P \
.deps/ct-compile.P .deps/ct-grammar.P .deps/ct-main.P \
.deps/ct-scanner.P .deps/file.P .deps/glib-new.P .deps/iptrace.P \
.deps/lanalyzer.P .deps/libpcap.P .deps/netmon.P .deps/netxray.P \
.deps/ngsniffer.P .deps/snoop.P .deps/wtap.P
SOURCES = $(libwiretap_a_SOURCES)
OBJECTS = $(libwiretap_a_OBJECTS)
.deps/ngsniffer.P .deps/rt-compile.P .deps/rt-grammar.P \
.deps/rt-scanner.P .deps/snoop.P .deps/wiretap.P .deps/wtap.P
SOURCES = $(libwiretap_a_SOURCES) $(wiretap_SOURCES) $(filterc_SOURCES)
OBJECTS = $(libwiretap_a_OBJECTS) $(wiretap_OBJECTS) $(filterc_OBJECTS)
all: Makefile $(LIBRARIES) config.h
all: Makefile $(LIBRARIES) $(PROGRAMS) config.h
.SUFFIXES:
.SUFFIXES: .S .c .o .s
@ -198,6 +253,39 @@ libwiretap.a: $(libwiretap_a_OBJECTS) $(libwiretap_a_DEPENDENCIES)
$(AR) cru libwiretap.a $(libwiretap_a_OBJECTS) $(libwiretap_a_LIBADD)
$(RANLIB) libwiretap.a
mostlyclean-binPROGRAMS:
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
distclean-binPROGRAMS:
maintainer-clean-binPROGRAMS:
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
if test -f $$p; then \
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
list='$(bin_PROGRAMS)'; for p in $$list; do \
rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
done
wiretap: $(wiretap_OBJECTS) $(wiretap_DEPENDENCIES)
@rm -f wiretap
$(LINK) $(wiretap_LDFLAGS) $(wiretap_OBJECTS) $(wiretap_LDADD) $(LIBS)
filterc: $(filterc_OBJECTS) $(filterc_DEPENDENCIES)
@rm -f filterc
$(LINK) $(filterc_LDFLAGS) $(filterc_OBJECTS) $(filterc_LDADD) $(LIBS)
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
@ -299,7 +387,7 @@ dvi:
check: all
$(MAKE)
installcheck:
install-exec:
install-exec: install-binPROGRAMS
@$(NORMAL_INSTALL)
install-data:
@ -308,11 +396,12 @@ install-data:
install: install-exec install-data all
@:
uninstall:
uninstall: uninstall-binPROGRAMS
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
installdirs:
$(mkinstalldirs) $(DATADIR)$(bindir)
mostlyclean-generic:
@ -330,20 +419,21 @@ maintainer-clean-generic:
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean: mostlyclean-hdr mostlyclean-noinstLIBRARIES \
mostlyclean-compile mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean-compile mostlyclean-binPROGRAMS \
mostlyclean-tags mostlyclean-depend mostlyclean-generic
clean: clean-hdr clean-noinstLIBRARIES clean-compile clean-tags \
clean-depend clean-generic mostlyclean
clean: clean-hdr clean-noinstLIBRARIES clean-compile clean-binPROGRAMS \
clean-tags clean-depend clean-generic mostlyclean
distclean: distclean-hdr distclean-noinstLIBRARIES distclean-compile \
distclean-tags distclean-depend distclean-generic clean
distclean-binPROGRAMS distclean-tags distclean-depend \
distclean-generic clean
-rm -f config.status
maintainer-clean: maintainer-clean-hdr maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-tags \
maintainer-clean-depend maintainer-clean-generic \
distclean
maintainer-clean-compile maintainer-clean-binPROGRAMS \
maintainer-clean-tags maintainer-clean-depend \
maintainer-clean-generic distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
-rm -f config.status
@ -352,14 +442,42 @@ maintainer-clean: maintainer-clean-hdr maintainer-clean-noinstLIBRARIES \
mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile tags mostlyclean-tags distclean-tags \
clean-tags maintainer-clean-tags distdir mostlyclean-depend \
distclean-depend clean-depend maintainer-clean-depend info dvi \
installcheck install-exec install-data install uninstall all \
installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
maintainer-clean-compile mostlyclean-binPROGRAMS distclean-binPROGRAMS \
clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \
install-binPROGRAMS tags mostlyclean-tags distclean-tags clean-tags \
maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
clean-depend maintainer-clean-depend info dvi installcheck install-exec \
install-data install uninstall all installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
mostlyclean distclean maintainer-clean
ct-grammar.c : ct-grammar.y
@rm -f $@ ct-tokdefs.h
$(CT_YACC) -d $<
mv y.tab.c ct-grammar.c
mv y.tab.h ct-tokdefs.h
ct-scanner.c : ct-scanner.l
@rm -f $@
$(CT_LEX) -t $< > $@
rt-scanner.l : rt-scanner-skel.l filterc
cat $(FILTERS) | ./filterc > /dev/null
rt-scanner.c : rt-scanner.l rt-grammar.c
@rm -f $@
$(RT_LEX) -t $< > $@
rt-grammar.y : rt-grammar-skel.y filterc
cat $(FILTERS) | ./filterc > /dev/null
rt-grammar.c : rt-grammar.y
@rm -f $@ rt-tokdefs.h
$(RT_YACC) -d $<
mv y.tab.c rt-grammar.c
mv y.tab.h rt-tokdefs.h
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,4 +1,4 @@
$Id: README,v 1.10 1999/02/20 08:12:20 guy Exp $
$Id: README,v 1.11 1999/03/01 18:57:02 gram 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
@ -32,8 +32,16 @@ SunOS has NIT and Solaris has DLPI, which both use the CMU/Stanford
packet-filter psuedomachine. RMON has another type of packet-filter syntax
which we could support.
Currently, only #2 is available. Wiretap doesn't even do any filtering yet. It
can only be used to read packet capture files.
Wiretap is very good at reading may file formats, as per #2
above. Display filters are now appearing in wiretap, but they are
still basic. Development is continuing on the BPF compiler, so display
filters will continue to be enhanced. Wiretap can't capture packets yet,
but once it can, it will have the ability to do capture-filtering via
BPF, either through BPF kernel facilities or through a user-space BPF
implementation. BPF is my first target, but the filter compiler will
be generic enough so that as per #6, other packet-filtering engines can
be used.
File Formats
============
@ -77,7 +85,7 @@ Network Monitor
---------------
Microsoft's Network Monitor file format is supported, at least under Ethernet
and token-ring. If you have capture files of other datalink types, please send
them to Guy Harris <guy@netapp.com>.
them to Guy Harris.
"snoop"
-------
@ -103,5 +111,5 @@ read, and the packet time stamp isn't correctly computed. Network
Associates' Windows Sniffer Pro appears to use a variant of that format;
it's supported to the same extent.
Gilbert Ramirez
<gram@verdict.uthscsa.edu>
Gilbert Ramirez <gram@verdict.uthscsa.edu>
Guy Harris <guy@netapp.com>

196
wiretap/aclocal.m4 vendored
View File

@ -308,3 +308,199 @@ main ()
rm -f conf.gtktest
])
# Configure paths for GLIB
# Owen Taylor 97-11-3
dnl AM_PATH_GLIB([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]])
dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if "gmodule" or
dnl gthread is specified in MODULES, pass to glib-config
dnl
AC_DEFUN(AM_PATH_GLIB,
[dnl
dnl Get the cflags and libraries from the glib-config script
dnl
AC_ARG_WITH(glib-prefix,[ --with-glib-prefix=PFX Prefix where GLIB is installed (optional)],
glib_config_prefix="$withval", glib_config_prefix="")
AC_ARG_WITH(glib-exec-prefix,[ --with-glib-exec-prefix=PFX Exec prefix where GLIB is installed (optional)],
glib_config_exec_prefix="$withval", glib_config_exec_prefix="")
AC_ARG_ENABLE(glibtest, [ --disable-glibtest Do not try to compile and run a test GLIB program],
, enable_glibtest=yes)
if test x$glib_config_exec_prefix != x ; then
glib_config_args="$glib_config_args --exec-prefix=$glib_config_exec_prefix"
if test x${GLIB_CONFIG+set} != xset ; then
GLIB_CONFIG=$glib_config_exec_prefix/bin/glib-config
fi
fi
if test x$glib_config_prefix != x ; then
glib_config_args="$glib_config_args --prefix=$glib_config_prefix"
if test x${GLIB_CONFIG+set} != xset ; then
GLIB_CONFIG=$glib_config_prefix/bin/glib-config
fi
fi
for module in . $4
do
case "$module" in
gmodule)
glib_config_args="$glib_config_args gmodule"
;;
gthread)
glib_config_args="$glib_config_args gthread"
;;
esac
done
AC_PATH_PROG(GLIB_CONFIG, glib-config, no)
min_glib_version=ifelse([$1], ,0.99.7,$1)
AC_MSG_CHECKING(for GLIB - version >= $min_glib_version)
no_glib=""
if test "$GLIB_CONFIG" = "no" ; then
no_glib=yes
else
GLIB_CFLAGS=`$GLIB_CONFIG $glib_config_args --cflags`
GLIB_LIBS=`$GLIB_CONFIG $glib_config_args --libs`
glib_config_major_version=`$GLIB_CONFIG $glib_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
glib_config_minor_version=`$GLIB_CONFIG $glib_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
glib_config_micro_version=`$GLIB_CONFIG $glib_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
if test "x$enable_glibtest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $GLIB_CFLAGS"
LIBS="$GLIB_LIBS $LIBS"
dnl
dnl Now check if the installed GLIB is sufficiently new. (Also sanity
dnl checks the results of glib-config to some extent
dnl
rm -f conf.glibtest
AC_TRY_RUN([
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
int
main ()
{
int major, minor, micro;
char *tmp_version;
system ("touch conf.glibtest");
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = g_strdup("$min_glib_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string\n", "$min_glib_version");
exit(1);
}
if ((glib_major_version != $glib_config_major_version) ||
(glib_minor_version != $glib_config_minor_version) ||
(glib_micro_version != $glib_config_micro_version))
{
printf("\n*** 'glib-config --version' returned %d.%d.%d, but GLIB (%d.%d.%d)\n",
$glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version,
glib_major_version, glib_minor_version, glib_micro_version);
printf ("*** was found! If glib-config was correct, then it is best\n");
printf ("*** to remove the old version of GLIB. You may also be able to fix the error\n");
printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
printf("*** required on your system.\n");
printf("*** If glib-config was wrong, set the environment variable GLIB_CONFIG\n");
printf("*** to point to the correct copy of glib-config, and remove the file config.cache\n");
printf("*** before re-running configure\n");
}
else if ((glib_major_version != GLIB_MAJOR_VERSION) ||
(glib_minor_version != GLIB_MINOR_VERSION) ||
(glib_micro_version != GLIB_MICRO_VERSION))
{
printf("*** GLIB header files (version %d.%d.%d) do not match\n",
GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
printf("*** library (version %d.%d.%d)\n",
glib_major_version, glib_minor_version, glib_micro_version);
}
else
{
if ((glib_major_version > major) ||
((glib_major_version == major) && (glib_minor_version > minor)) ||
((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** An old version of GLIB (%d.%d.%d) was found.\n",
glib_major_version, glib_minor_version, glib_micro_version);
printf("*** You need a version of GLIB newer than %d.%d.%d. The latest version of\n",
major, minor, micro);
printf("*** GLIB is always available from ftp://ftp.gtk.org.\n");
printf("***\n");
printf("*** If you have already installed a sufficiently new version, this error\n");
printf("*** probably means that the wrong copy of the glib-config shell script is\n");
printf("*** being found. The easiest way to fix this is to remove the old version\n");
printf("*** of GLIB, but you can also set the GLIB_CONFIG environment to point to the\n");
printf("*** correct copy of glib-config. (In this case, you will have to\n");
printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
printf("*** so that the correct libraries are found at run-time))\n");
}
}
return 1;
}
],, no_glib=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_glib" = x ; then
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
AC_MSG_RESULT(no)
if test "$GLIB_CONFIG" = "no" ; then
echo "*** The glib-config script installed by GLIB could not be found"
echo "*** If GLIB was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the GLIB_CONFIG environment variable to the"
echo "*** full path to glib-config."
else
if test -f conf.glibtest ; then
:
else
echo "*** Could not run GLIB test program, checking why..."
CFLAGS="$CFLAGS $GLIB_CFLAGS"
LIBS="$LIBS $GLIB_LIBS"
AC_TRY_LINK([
#include <glib.h>
#include <stdio.h>
], [ return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ],
[ echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding GLIB or finding the wrong"
echo "*** version of GLIB. If it is not finding GLIB, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
echo "***"
echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that"
echo "*** came with the system with the command"
echo "***"
echo "*** rpm --erase --nodeps gtk gtk-devel" ],
[ echo "*** The test program failed to compile or link. See the file config.log for the"
echo "*** exact error that occured. This usually means GLIB was incorrectly installed"
echo "*** or that you have moved GLIB since it was installed. In the latter case, you"
echo "*** may want to edit the glib-config script: $GLIB_CONFIG" ])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
GLIB_CFLAGS=""
GLIB_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
rm -f conf.glibtest
])

319
wiretap/bpf-engine.c Normal file
View File

@ -0,0 +1,319 @@
/* bpf-engine.c
* ------------
* The BPF engine used for offline ("display") filters in wiretap.
* The code is taken from the Linux Socket Filter, and only slightly
* modified for use in wiretap.
*
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*/
/*
* Linux Socket Filter - Kernel level socket filtering
*
* Author:
* Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
*
* Based on the design of:
* - The Berkeley Packet Filter
*
* 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.
*/
#include <netinet/in.h>
#include <glib.h>
#include "wtap.h"
#include "bpf-engine.h"
/*
* Decode and apply filter instructions to the skb->data.
* Return length to keep, 0 for none. skb is the data we are
* filtering, filter is the array of filter instructions, and
* len is the number of filter blocks in the array.
*/
int bpf_run_filter(unsigned char *data, int len, struct bpf_instruction *filter, int flen)
{
struct bpf_instruction *fentry; /* We walk down these */
guint32 A = 0; /* Accumulator */
guint32 X = 0; /* Index Register */
guint32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */
int k;
int pc;
int *t;
/*
* Process array of filter instructions.
*/
for(pc = 0; pc < flen; pc++)
{
fentry = &filter[pc];
if(fentry->code & BPF_X)
t=&X;
else
t=&fentry->k;
switch(fentry->code)
{
case BPF_ALU|BPF_ADD|BPF_X:
case BPF_ALU|BPF_ADD|BPF_K:
A += *t;
continue;
case BPF_ALU|BPF_SUB|BPF_X:
case BPF_ALU|BPF_SUB|BPF_K:
A -= *t;
continue;
case BPF_ALU|BPF_MUL|BPF_X:
case BPF_ALU|BPF_MUL|BPF_K:
A *= *t;
continue;
case BPF_ALU|BPF_DIV|BPF_X:
case BPF_ALU|BPF_DIV|BPF_K:
if(*t == 0)
return (0);
A /= *t;
continue;
case BPF_ALU|BPF_AND|BPF_X:
case BPF_ALU|BPF_AND|BPF_K:
A &= *t;
continue;
case BPF_ALU|BPF_OR|BPF_X:
case BPF_ALU|BPF_OR|BPF_K:
A |= *t;
continue;
case BPF_ALU|BPF_LSH|BPF_X:
case BPF_ALU|BPF_LSH|BPF_K:
A <<= *t;
continue;
case BPF_ALU|BPF_RSH|BPF_X:
case BPF_ALU|BPF_RSH|BPF_K:
A >>= *t;
continue;
case BPF_ALU|BPF_NEG:
A = -A;
continue;
case BPF_JMP|BPF_JA:
pc += fentry->k;
continue;
case BPF_JMP|BPF_JGT|BPF_K:
pc += (A > fentry->k) ? fentry->jt : fentry->jf;
continue;
case BPF_JMP|BPF_JGE|BPF_K:
pc += (A >= fentry->k) ? fentry->jt : fentry->jf;
continue;
case BPF_JMP|BPF_JEQ|BPF_K:
pc += (A == fentry->k) ? fentry->jt : fentry->jf;
continue;
case BPF_JMP|BPF_JSET|BPF_K:
pc += (A & fentry->k) ? fentry->jt : fentry->jf;
continue;
case BPF_JMP|BPF_JGT|BPF_X:
pc += (A > X) ? fentry->jt : fentry->jf;
continue;
case BPF_JMP|BPF_JGE|BPF_X:
pc += (A >= X) ? fentry->jt : fentry->jf;
continue;
case BPF_JMP|BPF_JEQ|BPF_X:
pc += (A == X) ? fentry->jt : fentry->jf;
continue;
case BPF_JMP|BPF_JSET|BPF_X:
pc += (A & X) ? fentry->jt : fentry->jf;
continue;
case BPF_LD|BPF_W|BPF_ABS:
k = fentry->k;
if(k + sizeof(long) > len)
return (0);
A = pntohl(&data[k]);
continue;
case BPF_LD|BPF_H|BPF_ABS:
k = fentry->k;
if(k + sizeof(short) > len)
return (0);
A = pntohs(&data[k]);
continue;
case BPF_LD|BPF_B|BPF_ABS:
k = fentry->k;
if(k >= len)
return (0);
A = data[k];
continue;
case BPF_LD|BPF_W|BPF_LEN:
A = len;
continue;
case BPF_LDX|BPF_W|BPF_LEN:
X = len;
continue;
case BPF_LD|BPF_W|BPF_IND:
k = X + fentry->k;
if(k + sizeof(guint32) > len)
return (0);
A = pntohl(&data[k]);
continue;
case BPF_LD|BPF_H|BPF_IND:
k = X + fentry->k;
if(k + sizeof(guint16) > len)
return (0);
A = pntohs(&data[k]);
continue;
case BPF_LD|BPF_B|BPF_IND:
k = X + fentry->k;
if(k >= len)
return (0);
A = data[k];
continue;
case BPF_LDX|BPF_B|BPF_MSH:
/*
* Hack for BPF to handle TOS etc
*/
k = fentry->k;
if(k >= len)
return (0);
X = (data[fentry->k] & 0xf) << 2;
continue;
case BPF_LD|BPF_IMM:
A = fentry->k;
continue;
case BPF_LDX|BPF_IMM:
X = fentry->k;
continue;
case BPF_LD|BPF_MEM:
A = mem[fentry->k];
continue;
case BPF_LDX|BPF_MEM:
X = mem[fentry->k];
continue;
case BPF_MISC|BPF_TAX:
X = A;
continue;
case BPF_MISC|BPF_TXA:
A = X;
continue;
case BPF_RET|BPF_K:
return ((unsigned int)fentry->k);
case BPF_RET|BPF_A:
return ((unsigned int)A);
case BPF_ST:
mem[fentry->k] = A;
continue;
case BPF_STX:
mem[fentry->k] = X;
continue;
default:
/* Invalid instruction counts as RET */
return (0);
}
}
g_error("Filter ruleset ran off the end.\n");
return (0);
}
/*
* Check the user's filter code. If we let some ugly
* filter code slip through kaboom!
*/
int bpf_chk_filter(struct bpf_instruction *filter, int flen)
{
struct bpf_instruction *ftest;
int pc;
/*
* Check the filter code now.
*/
for(pc = 0; pc < flen; pc++)
{
/*
* All jumps are forward as they are not signed
*/
ftest = &filter[pc];
if(BPF_CLASS(ftest->code) == BPF_JMP)
{
/*
* But they mustn't jump off the end.
*/
if(BPF_OP(ftest->code) == BPF_JA)
{
if(pc + ftest->k + 1>= (unsigned)flen)
return (-1);
}
else
{
/*
* For conditionals both must be safe
*/
if(pc + ftest->jt +1 >= flen || pc + ftest->jf +1 >= flen)
return (-1);
}
}
/*
* Check that memory operations use valid addresses.
*/
if(ftest->k <0 || ftest->k >= BPF_MEMWORDS)
{
/*
* But it might not be a memory operation...
*/
if (BPF_CLASS(ftest->code) == BPF_ST)
return -1;
if((BPF_CLASS(ftest->code) == BPF_LD) &&
(BPF_MODE(ftest->code) == BPF_MEM))
return (-1);
}
}
/*
* The program must end with a return. We don't care where they
* jumped within the script (its always forwards) but in the
* end they _will_ hit this.
*/
return (BPF_CLASS(filter[flen - 1].code) == BPF_RET)?0:-1;
}

120
wiretap/bpf-engine.h Normal file
View File

@ -0,0 +1,120 @@
/* bpf-engine.h
* ------------
* The BPF engine used for offline ("display") filters in wiretap.
* The code is taken from the Linux Socket Filter, and only slightly
* modified for use in wiretap.
*
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*/
/*
* Linux Socket Filter - Kernel level socket filtering
*
* Author:
* Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
*
* Based on the design of:
* - The Berkeley Packet Filter
*
* 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.
*/
/*
* Linux Socket Filter Data Structures
*/
/*
* Current version of the filter code architecture.
*/
#define BPF_MAJOR_VERSION 1
#define BPF_MINOR_VERSION 1
/* each BPF instruction is a block of 8 bytes */
struct bpf_instruction {
guint16 code; /* Actual filter code */
guint8 jt; /* Jump true */
guint8 jf; /* Jump false */
guint32 k; /* Generic multiuse field */
};
struct bpf_code_unit {
int line_label;
struct bpf_instruction bpf;
};
int bpf_run_filter(unsigned char *data, int len, struct bpf_instruction *filter, int flen);
int bpf_chk_filter(struct bpf_instruction *filter, int flen);
/*
* Instruction classes
*/
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
/* misc */
#define BPF_MISCOP(code) ((code) & 0xf8)
#define BPF_TAX 0x00
#define BPF_TXA 0x80
#define BPF_MAXINSNS 512
/*
* Macros for filter block array initializers.
*/
#define BPF_STMT(code, k) { (unsigned short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k }
/*
* Number of scratch memory words for: BPF_ST and BPF_STX
*/
#define BPF_MEMWORDS 16

372
wiretap/bpf.c Normal file
View File

@ -0,0 +1,372 @@
/*
* bpf.c
* -----
* Creates and handles the BPF code produced by wiretap.
*
* Gilbert Ramirez
*/
#ifndef __G_LIB_H__
#include <glib.h>
#endif
#include <netinet/in.h>
#include "wtap.h"
#include "rt-compile.h"
#include "rt-global.h"
#include "bpf-engine.h"
#include "bpf.h"
static GList *bpf_code_just_parsed = NULL;
static struct bpf_instruction *bpf_record = NULL;
static int
bpf_clean_jump(GList *L, int i_this, int jmp, int num_bpf_instructions,
int i_ret_success, int i_ret_failure);
static void
bpf_pass1(GList *L);
static GList*
bpf_mk_bytecmp(int ftype, int rel_opcode, guint8 *bytes);
static void
bpf_optimize(GList *L);
static int
bpf_attach(wtap *wth);
static void
bpf_attach_record(gpointer bpf_code, gpointer junk);
static int
offline_attach(wtap *wth);
/* sets function pointers in rt-grammar.y to point to the BPF-related
* functions */
void
wtap_filter_bpf_init(void)
{
mk_bytecmp = bpf_mk_bytecmp;
mk_optimize = bpf_optimize;
mk_attach = bpf_attach;
}
/* almost the same as bpf_init... */
void
wtap_filter_offline_init(wtap *wth)
{
int fi; /* filter index */
mk_bytecmp = bpf_mk_bytecmp;
mk_optimize = bpf_optimize;
mk_attach = offline_attach;
wtap_filter_offline_clear(wth);
/* make the offline filter array */
wth->filter.offline = g_malloc(sizeof(int*) * WTAP_NUM_ENCAP_TYPES);
wth->filter_type = WTAP_FILTER_OFFLINE;
wth->offline_filter_lengths = g_malloc(sizeof(int) * WTAP_NUM_ENCAP_TYPES);
for (fi = 0; fi < WTAP_NUM_ENCAP_TYPES; fi++) {
wth->filter.offline[fi] = NULL;
}
}
/* Removes an offline filter from a wtap struct, and frees memory used
* by that filter */
void
wtap_filter_offline_clear(wtap *wth)
{
int fi; /* filter index */
if (wth->filter.offline) {
for (fi = 0; fi < WTAP_NUM_ENCAP_TYPES; fi++) {
if (wth->filter.offline[fi])
g_free(wth->filter.offline[fi]);
}
g_free(wth->filter.offline);
g_free(wth->offline_filter_lengths);
}
wth->filter_type = WTAP_FILTER_NONE;
}
/* Allocate a new bpf_code_unit structure and initialize the BPF instruction
* codes to the values passed by the caller. */
static struct bpf_code_unit *
bpf_code_unit_alloc(guint8 label, guint16 code, guint8 jt, guint8 jf, guint32 k)
{
struct bpf_code_unit *bpf;
bpf = g_malloc(sizeof(struct bpf_code_unit));
bpf->line_label = label;
bpf->bpf.code = code;
bpf->bpf.jt = jt;
bpf->bpf.jf = jf;
bpf->bpf.k = k;
/*g_print("{ %d { 0x%02x, %d, %d, 0x%08x }},\n",
label, code, jt, jf, k);*/
return bpf;
}
/* Finds ftype in the bytecmp_table, the relation, and the n-string
byte array, and creates BPF that will check those bytes */
static GList*
bpf_mk_bytecmp(int ftype, int rel_opcode, guint8 *bytes)
{
GList *L;
struct bpf_code_unit *bpf;
int len_to_cmp, offset, endpoint, label;
bytecmp_info *b;
L = g_list_alloc();
/* find the field in the table */
b = lookup_bytecmp(ftype);
/* How many bytes do we have to compare, and where? */
len_to_cmp = b->length;
offset = b->offset;
endpoint = len_to_cmp + offset;
/*g_print("len_to_cmp=%d, offset=%d, endpoint=%d\n",
len_to_cmp, offset, endpoint);
g_print("bytes: (%d) %02X:%02X:%02X\n",
bytes[0], bytes[1], bytes[2], bytes[3]);*/
label = NEXT_BLOCK;
/* loop until we have written instructions to compare
all bytes */
while (len_to_cmp) {
if (len_to_cmp >= 4) {
bpf = bpf_code_unit_alloc(label,
BPF_LD|BPF_W|BPF_ABS,
0, 0, endpoint - 4);
g_list_append(L, bpf);
label = NO_LABEL;
endpoint -= 4;
bpf = bpf_code_unit_alloc(NO_LABEL,
BPF_JMP|BPF_JEQ,
(len_to_cmp == 4 ? END_OF_PROGRAM_SUCCESS : 0),
NEXT_BLOCK,
htonl(*(guint32*)&bytes[len_to_cmp-3]));
g_list_append(L, bpf);
len_to_cmp -= 4;
}
else if (len_to_cmp == 3) {
bpf = bpf_code_unit_alloc(label,
BPF_LD|BPF_W|BPF_ABS,
0, 0, endpoint - 3);
g_list_append(L, bpf);
label = NO_LABEL;
endpoint -= 3;
bpf = bpf_code_unit_alloc(NO_LABEL,
BPF_ALU|BPF_AND,
0, 0,
htonl(0xffffff));
g_list_append(L, bpf);
bpf = bpf_code_unit_alloc(NO_LABEL,
BPF_JMP|BPF_JEQ,
(len_to_cmp == 3 ? END_OF_PROGRAM_SUCCESS : 0),
NEXT_BLOCK,
htonl(*(guint32*)&bytes[len_to_cmp-2]) & 0xffffff00);
g_list_append(L, bpf);
len_to_cmp -= 3;
}
else if (len_to_cmp == 2) {
bpf = bpf_code_unit_alloc(label,
BPF_LD|BPF_H|BPF_ABS,
0, 0, endpoint - 2);
g_list_append(L, bpf);
label = NO_LABEL;
endpoint -= 2;
bpf = bpf_code_unit_alloc(NO_LABEL,
BPF_JMP|BPF_JEQ,
(len_to_cmp == 2 ? END_OF_PROGRAM_SUCCESS : 0),
NEXT_BLOCK,
(guint32)htons(*(guint16*)&bytes[len_to_cmp-1]));
g_list_append(L, bpf);
len_to_cmp -= 2;
}
else if (len_to_cmp == 1) {
bpf = bpf_code_unit_alloc(label,
BPF_LD|BPF_B|BPF_ABS,
0, 0, endpoint - 1);
g_list_append(L, bpf);
label = NO_LABEL;
endpoint--;
bpf = bpf_code_unit_alloc(NO_LABEL,
BPF_JMP|BPF_JEQ,
END_OF_PROGRAM_SUCCESS, NEXT_BLOCK,
bytes[len_to_cmp]);
g_list_append(L, bpf);
len_to_cmp--;
}
}
L = g_list_remove(L, 0);
return L;
}
static void
bpf_optimize(GList *L)
{
bpf_pass1(L);
bpf_code_just_parsed = L;
}
/* after the BPF code is constructed from the parser, this step is run. During
* pass1 we:
*
* 1. Clean up the jump variables
*/
static void
bpf_pass1(GList *L)
{
struct bpf_code_unit *bpf;
int num_bpf_instructions;
int i_ret_success;
int i_ret_failure;
int i;
/* Attach a SUCCESS return to the end of the BPF code */
bpf = bpf_code_unit_alloc(END_OF_PROGRAM_SUCCESS, BPF_RET, 0, 0, 0xffff);
g_list_append(L, bpf);
/* Attach a FAILURE return to the end of the BPF code */
bpf = bpf_code_unit_alloc(END_OF_PROGRAM_FAILURE, BPF_RET, 0, 0, 0);
g_list_append(L, bpf);
num_bpf_instructions = g_list_length(L);
i_ret_success = num_bpf_instructions - 2;
i_ret_failure = num_bpf_instructions - 1;
for(i = 0; i < num_bpf_instructions; i++) {
bpf = (struct bpf_code_unit*) g_list_nth_data(L, i);
if (!bpf)
continue;
/* Check for Jump to end failure/success */
if (bpf->bpf.code & BPF_JMP) {
bpf->bpf.jt = bpf_clean_jump(L, i, bpf->bpf.jt, num_bpf_instructions,
i_ret_success, i_ret_failure);
bpf->bpf.jf = bpf_clean_jump(L, i, bpf->bpf.jf, num_bpf_instructions,
i_ret_success, i_ret_failure);
}
}
}
static int
bpf_clean_jump(GList *L, int i_this, int jmp, int num_bpf_instructions,
int i_ret_success, int i_ret_failure)
{
int i;
struct bpf_code_unit *bpf;
switch(jmp) {
case END_OF_PROGRAM_SUCCESS:
return i_ret_success - i_this - 1;
case END_OF_PROGRAM_FAILURE:
return i_ret_failure - i_this - 1;
case NEXT_BLOCK:
for (i = i_this + 1; i < num_bpf_instructions; i++) {
bpf = (struct bpf_code_unit*) g_list_nth_data(L, i);
if (!bpf)
continue;
if (bpf->line_label == NEXT_BLOCK) {
return i - i_this - 1;
}
}
/* failed to find NEXT_BLOCK.... chose FAILURE */
return i_ret_failure - i_this - 1;
/* default: nothing */
}
return jmp;
}
/* Takes code from bpf_code_just_parsed and attaches it to wth
* returns 1 if sucessfull, 0 if not */
static int bpf_attach(wtap *wth)
{
if (wth->filter.bpf)
g_free(wth->filter.bpf);
/* filter_length will be number of bpf_block records */
wth->filter_length = g_list_length(bpf_code_just_parsed) - 1;
wth->filter.bpf = g_malloc(wth->filter_length *
sizeof(struct bpf_instruction));
wth->filter_type = WTAP_FILTER_BPF;
bpf_record = wth->filter.bpf;
g_list_foreach(bpf_code_just_parsed, bpf_attach_record, NULL);
if (bpf_chk_filter(wth->filter.bpf, wth->filter_length) == 0)
return 1;
else
return 0;
}
void bpf_attach_record(gpointer bpf_code, gpointer junk)
{
struct bpf_code_unit *bpf_c = (struct bpf_code_unit*) bpf_code;
struct bpf_instruction *bpf_i;
if (!bpf_c)
return;
bpf_i = &(bpf_c->bpf);
memcpy(bpf_record, bpf_i, sizeof(struct bpf_instruction));
bpf_record++;
}
/* Takes code from bpf_code_just_parsed and attachs it to wth.
* returns 1 if sucessfull, 0 if not */
static int offline_attach(wtap *wth)
{
/* filter_length will be number of bpf_instruction records */
wth->offline_filter_lengths[comp_encap_type] =
g_list_length(bpf_code_just_parsed);
/* Make space for this filter */
wth->filter.offline[comp_encap_type] =
g_malloc(wth->offline_filter_lengths[comp_encap_type]
* sizeof(struct bpf_instruction));
bpf_record = wth->filter.offline[comp_encap_type];
g_list_foreach(bpf_code_just_parsed, bpf_attach_record, NULL);
if (bpf_chk_filter(wth->filter.offline[comp_encap_type],
wth->offline_filter_lengths[comp_encap_type]) == 0)
return 1;
else
return 0;
}

22
wiretap/bpf.h Normal file
View File

@ -0,0 +1,22 @@
/* we limit the number of BPF records a jmp can take by using a few of the
* jmp values as special identifiers during the compilation process. Many
* pieces of code need to jump to the end of the entire BPF block, returing
* either a successful value or a failure value (either the number of bytes
* to read, or 0). The code creator uses these 4 variables to represent
* the retval of failure or success, then the code cleaner fills in the
* true value for these variables.
*/
#define NO_LABEL 255
#define END_OF_PROGRAM_FAILURE 254
#define END_OF_PROGRAM_SUCCESS 253
#define NEXT_BLOCK 252
void
wtap_filter_bpf_init(void);
void
wtap_filter_offline_init(wtap *wth);
void
wtap_filter_offline_clear(wtap *wth);

View File

@ -9,3 +9,6 @@
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you are using glib 1.0 (or below) */
#undef HAVE_GLIB10

369
wiretap/configure vendored
View File

@ -11,6 +11,12 @@
ac_help=
ac_default_prefix=/usr/local
# Any additions from configure.in:
ac_help="$ac_help
--with-glib-prefix=PFX Prefix where GLIB is installed (optional)"
ac_help="$ac_help
--with-glib-exec-prefix=PFX Exec prefix where GLIB is installed (optional)"
ac_help="$ac_help
--disable-glibtest Do not try to compile and run a test GLIB program"
ac_help="$ac_help
--with-gtk-prefix=PFX Prefix where GTK is installed (optional)"
ac_help="$ac_help
@ -557,7 +563,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:561: checking for a BSD compatible install" >&5
echo "configure:567: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -610,7 +616,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
echo "configure:614: checking whether build environment is sane" >&5
echo "configure:620: checking whether build environment is sane" >&5
# Just in case
sleep 1
echo timestamp > conftestfile
@ -667,7 +673,7 @@ test "$program_suffix" != NONE &&
test "$program_transform_name" = "" && program_transform_name="s,x,x,"
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
echo "configure:671: checking whether ${MAKE-make} sets \${MAKE}" >&5
echo "configure:677: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -713,7 +719,7 @@ EOF
missing_dir=`cd $ac_aux_dir && pwd`
echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
echo "configure:717: checking for working aclocal" >&5
echo "configure:723: checking for working aclocal" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
@ -726,7 +732,7 @@ else
fi
echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
echo "configure:730: checking for working autoconf" >&5
echo "configure:736: checking for working autoconf" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
@ -739,7 +745,7 @@ else
fi
echo $ac_n "checking for working automake""... $ac_c" 1>&6
echo "configure:743: checking for working automake" >&5
echo "configure:749: checking for working automake" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
@ -752,7 +758,7 @@ else
fi
echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
echo "configure:756: checking for working autoheader" >&5
echo "configure:762: checking for working autoheader" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
@ -765,7 +771,7 @@ else
fi
echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
echo "configure:769: checking for working makeinfo" >&5
echo "configure:775: checking for working makeinfo" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
@ -785,7 +791,7 @@ fi
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:789: checking for $ac_word" >&5
echo "configure:795: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -814,7 +820,7 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:818: checking for $ac_word" >&5
echo "configure:824: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -862,7 +868,7 @@ fi
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
echo "configure:866: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
echo "configure:872: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@ -872,11 +878,11 @@ ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS
cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext <<EOF
#line 876 "configure"
#line 882 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
if { (eval echo configure:880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
if { (eval echo configure:886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
@ -896,12 +902,12 @@ if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
echo "configure:900: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "configure:906: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
echo "configure:905: checking whether we are using GNU C" >&5
echo "configure:911: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -910,7 +916,7 @@ else
yes;
#endif
EOF
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:920: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@ -925,7 +931,7 @@ if test $ac_cv_prog_gcc = yes; then
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:929: checking whether ${CC-cc} accepts -g" >&5
echo "configure:935: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -955,7 +961,7 @@ fi
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:959: checking for $ac_word" >&5
echo "configure:965: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -984,7 +990,7 @@ fi
# If we're running gcc, add '-Wall' to CFLAGS.
echo $ac_n "checking to see if we can add '-Wall' to CFLAGS""... $ac_c" 1>&6
echo "configure:988: checking to see if we can add '-Wall' to CFLAGS" >&5
echo "configure:994: checking to see if we can add '-Wall' to CFLAGS" >&5
if test x$GCC != x ; then
CFLAGS="-Wall $CFLAGS"
echo "$ac_t""yes" 1>&6
@ -992,8 +998,275 @@ else
echo "$ac_t""no" 1>&6
fi
# GTK checks (copied from ethereal)
# Check whether --with-gtk-prefix or --without-gtk-prefix was given.
# Checks for glib first, or gtk+ if not present
# Check whether --with-glib-prefix or --without-glib-prefix was given.
if test "${with_glib_prefix+set}" = set; then
withval="$with_glib_prefix"
glib_config_prefix="$withval"
else
glib_config_prefix=""
fi
# Check whether --with-glib-exec-prefix or --without-glib-exec-prefix was given.
if test "${with_glib_exec_prefix+set}" = set; then
withval="$with_glib_exec_prefix"
glib_config_exec_prefix="$withval"
else
glib_config_exec_prefix=""
fi
# Check whether --enable-glibtest or --disable-glibtest was given.
if test "${enable_glibtest+set}" = set; then
enableval="$enable_glibtest"
:
else
enable_glibtest=yes
fi
if test x$glib_config_exec_prefix != x ; then
glib_config_args="$glib_config_args --exec-prefix=$glib_config_exec_prefix"
if test x${GLIB_CONFIG+set} != xset ; then
GLIB_CONFIG=$glib_config_exec_prefix/bin/glib-config
fi
fi
if test x$glib_config_prefix != x ; then
glib_config_args="$glib_config_args --prefix=$glib_config_prefix"
if test x${GLIB_CONFIG+set} != xset ; then
GLIB_CONFIG=$glib_config_prefix/bin/glib-config
fi
fi
for module in .
do
case "$module" in
gmodule)
glib_config_args="$glib_config_args gmodule"
;;
gthread)
glib_config_args="$glib_config_args gthread"
;;
esac
done
# Extract the first word of "glib-config", so it can be a program name with args.
set dummy glib-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1056: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GLIB_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
case "$GLIB_CONFIG" in
/*)
ac_cv_path_GLIB_CONFIG="$GLIB_CONFIG" # Let the user override the test with a path.
;;
*)
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_path_GLIB_CONFIG="$ac_dir/$ac_word"
break
fi
done
IFS="$ac_save_ifs"
test -z "$ac_cv_path_GLIB_CONFIG" && ac_cv_path_GLIB_CONFIG="no"
;;
esac
fi
GLIB_CONFIG="$ac_cv_path_GLIB_CONFIG"
if test -n "$GLIB_CONFIG"; then
echo "$ac_t""$GLIB_CONFIG" 1>&6
else
echo "$ac_t""no" 1>&6
fi
min_glib_version=1.1.0
echo $ac_n "checking for GLIB - version >= $min_glib_version""... $ac_c" 1>&6
echo "configure:1087: checking for GLIB - version >= $min_glib_version" >&5
no_glib=""
if test "$GLIB_CONFIG" = "no" ; then
no_glib=yes
else
GLIB_CFLAGS=`$GLIB_CONFIG $glib_config_args --cflags`
GLIB_LIBS=`$GLIB_CONFIG $glib_config_args --libs`
glib_config_major_version=`$GLIB_CONFIG $glib_config_args --version | \
sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'`
glib_config_minor_version=`$GLIB_CONFIG $glib_config_args --version | \
sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'`
glib_config_micro_version=`$GLIB_CONFIG $glib_config_args --version | \
sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
if test "x$enable_glibtest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $GLIB_CFLAGS"
LIBS="$GLIB_LIBS $LIBS"
rm -f conf.glibtest
if test "$cross_compiling" = yes; then
echo $ac_n "cross compiling; assumed OK... $ac_c"
else
cat > conftest.$ac_ext <<EOF
#line 1110 "configure"
#include "confdefs.h"
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
int
main ()
{
int major, minor, micro;
char *tmp_version;
system ("touch conf.glibtest");
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = g_strdup("$min_glib_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string\n", "$min_glib_version");
exit(1);
}
if ((glib_major_version != $glib_config_major_version) ||
(glib_minor_version != $glib_config_minor_version) ||
(glib_micro_version != $glib_config_micro_version))
{
printf("\n*** 'glib-config --version' returned %d.%d.%d, but GLIB (%d.%d.%d)\n",
$glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version,
glib_major_version, glib_minor_version, glib_micro_version);
printf ("*** was found! If glib-config was correct, then it is best\n");
printf ("*** to remove the old version of GLIB. You may also be able to fix the error\n");
printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
printf("*** required on your system.\n");
printf("*** If glib-config was wrong, set the environment variable GLIB_CONFIG\n");
printf("*** to point to the correct copy of glib-config, and remove the file config.cache\n");
printf("*** before re-running configure\n");
}
else if ((glib_major_version != GLIB_MAJOR_VERSION) ||
(glib_minor_version != GLIB_MINOR_VERSION) ||
(glib_micro_version != GLIB_MICRO_VERSION))
{
printf("*** GLIB header files (version %d.%d.%d) do not match\n",
GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
printf("*** library (version %d.%d.%d)\n",
glib_major_version, glib_minor_version, glib_micro_version);
}
else
{
if ((glib_major_version > major) ||
((glib_major_version == major) && (glib_minor_version > minor)) ||
((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** An old version of GLIB (%d.%d.%d) was found.\n",
glib_major_version, glib_minor_version, glib_micro_version);
printf("*** You need a version of GLIB newer than %d.%d.%d. The latest version of\n",
major, minor, micro);
printf("*** GLIB is always available from ftp://ftp.gtk.org.\n");
printf("***\n");
printf("*** If you have already installed a sufficiently new version, this error\n");
printf("*** probably means that the wrong copy of the glib-config shell script is\n");
printf("*** being found. The easiest way to fix this is to remove the old version\n");
printf("*** of GLIB, but you can also set the GLIB_CONFIG environment to point to the\n");
printf("*** correct copy of glib-config. (In this case, you will have to\n");
printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
printf("*** so that the correct libraries are found at run-time))\n");
}
}
return 1;
}
EOF
if { (eval echo configure:1186: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
then
:
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
no_glib=yes
fi
rm -fr conftest*
fi
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_glib" = x ; then
echo "$ac_t""yes" 1>&6
CFLAGS="$CFLAGS $GLIB_CFLAGS" LIBS="$LIBS $GLIB_LIBS"
else
echo "$ac_t""no" 1>&6
if test "$GLIB_CONFIG" = "no" ; then
echo "*** The glib-config script installed by GLIB could not be found"
echo "*** If GLIB was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the GLIB_CONFIG environment variable to the"
echo "*** full path to glib-config."
else
if test -f conf.glibtest ; then
:
else
echo "*** Could not run GLIB test program, checking why..."
CFLAGS="$CFLAGS $GLIB_CFLAGS"
LIBS="$LIBS $GLIB_LIBS"
cat > conftest.$ac_ext <<EOF
#line 1220 "configure"
#include "confdefs.h"
#include <glib.h>
#include <stdio.h>
int main() {
return ((glib_major_version) || (glib_minor_version) || (glib_micro_version));
; return 0; }
EOF
if { (eval echo configure:1230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding GLIB or finding the wrong"
echo "*** version of GLIB. If it is not finding GLIB, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
echo "***"
echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that"
echo "*** came with the system with the command"
echo "***"
echo "*** rpm --erase --nodeps gtk gtk-devel"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
echo "*** The test program failed to compile or link. See the file config.log for the"
echo "*** exact error that occured. This usually means GLIB was incorrectly installed"
echo "*** or that you have moved GLIB since it was installed. In the latter case, you"
echo "*** may want to edit the glib-config script: $GLIB_CONFIG"
fi
rm -f conftest*
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
GLIB_CFLAGS=""
GLIB_LIBS=""
echo "configure: warning: GLIB 1.1.x or above not found." 1>&2
fi
rm -f conf.glibtest
if test "x$GLIB_CFLAGS" = x ; then
# Check whether --with-gtk-prefix or --without-gtk-prefix was given.
if test "${with_gtk_prefix+set}" = set; then
withval="$with_gtk_prefix"
gtk_config_prefix="$withval"
@ -1034,7 +1307,7 @@ fi
# Extract the first word of "gtk-config", so it can be a program name with args.
set dummy gtk-config; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1038: checking for $ac_word" >&5
echo "configure:1311: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GTK_CONFIG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1065,7 +1338,7 @@ fi
min_gtk_version=1.0.0
echo $ac_n "checking for GTK - version >= $min_gtk_version""... $ac_c" 1>&6
echo "configure:1069: checking for GTK - version >= $min_gtk_version" >&5
echo "configure:1342: checking for GTK - version >= $min_gtk_version" >&5
no_gtk=""
if test "$GTK_CONFIG" = "no" ; then
no_gtk=yes
@ -1088,7 +1361,7 @@ echo "configure:1069: checking for GTK - version >= $min_gtk_version" >&5
echo $ac_n "cross compiling; assumed OK... $ac_c"
else
cat > conftest.$ac_ext <<EOF
#line 1092 "configure"
#line 1365 "configure"
#include "confdefs.h"
#include <gtk/gtk.h>
@ -1154,7 +1427,7 @@ main ()
}
EOF
if { (eval echo configure:1158: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
if { (eval echo configure:1431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
then
:
else
@ -1188,7 +1461,7 @@ fi
CFLAGS="$CFLAGS $GTK_CFLAGS"
LIBS="$LIBS $GTK_LIBS"
cat > conftest.$ac_ext <<EOF
#line 1192 "configure"
#line 1465 "configure"
#include "confdefs.h"
#include <gtk/gtk.h>
@ -1198,7 +1471,7 @@ int main() {
return ((gtk_major_version) || (gtk_minor_version) || (gtk_micro_version));
; return 0; }
EOF
if { (eval echo configure:1202: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
if { (eval echo configure:1475: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding GTK or finding the wrong"
@ -1230,16 +1503,21 @@ rm -f conftest*
fi
GTK_CFLAGS=""
GTK_LIBS=""
{ echo "configure: error: GTK+ distribution not found." 1>&2; exit 1; }
{ echo "configure: error: GTK+ library not found." 1>&2; exit 1; }
fi
rm -f conf.gtktest
cat >> confdefs.h <<\EOF
#define HAVE_GLIB10 1
EOF
fi
# Wiretap check (copied and modified from ethereal)
echo $ac_n "checking whether to include wiretap library""... $ac_c" 1>&6
echo "configure:1243: checking whether to include wiretap library" >&5
echo "configure:1521: checking whether to include wiretap library" >&5
# Check whether --with-wiretap or --without-wiretap was given.
if test "${with_wiretap+set}" = set; then
withval="$with_wiretap"
@ -1261,7 +1539,7 @@ fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:1265: checking how to run the C preprocessor" >&5
echo "configure:1543: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@ -1276,13 +1554,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 1280 "configure"
#line 1558 "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:1286: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1564: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
@ -1293,13 +1571,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
#line 1297 "configure"
#line 1575 "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:1303: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1581: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
@ -1322,12 +1600,12 @@ fi
echo "$ac_t""$CPP" 1>&6
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:1604: 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 1609 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@ -1335,7 +1613,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:1617: \"$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 +1630,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 1634 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@ -1370,7 +1648,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 1652 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@ -1391,7 +1669,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
#line 1395 "configure"
#line 1673 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@ -1402,7 +1680,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:1684: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
then
:
else
@ -1429,17 +1707,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:1711: 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 1716 "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:1721: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
@ -1610,6 +1888,9 @@ s%@MAKEINFO@%$MAKEINFO%g
s%@SET_MAKE@%$SET_MAKE%g
s%@CC@%$CC%g
s%@RANLIB@%$RANLIB%g
s%@GLIB_CONFIG@%$GLIB_CONFIG%g
s%@GLIB_CFLAGS@%$GLIB_CFLAGS%g
s%@GLIB_LIBS@%$GLIB_LIBS%g
s%@GTK_CONFIG@%$GTK_CONFIG%g
s%@GTK_CFLAGS@%$GTK_CFLAGS%g
s%@GTK_LIBS@%$GTK_LIBS%g

View File

@ -1,4 +1,4 @@
# $Id: configure.in,v 1.6 1999/01/13 04:14:29 gerald Exp $
# $Id: configure.in,v 1.7 1999/03/01 18:57:03 gram Exp $
dnl Process this file with autoconf to produce a configure script.
AC_INIT(wtap.c)
AM_INIT_AUTOMAKE(libwtap.a, 0.0.0)
@ -17,9 +17,15 @@ else
AC_MSG_RESULT(no)
fi
# GTK checks (copied from ethereal)
AM_PATH_GTK(1.0.0, CFLAGS="$CFLAGS $GTK_CFLAGS" LIBS="$LIBS $GTK_LIBS",
AC_MSG_ERROR(GTK+ distribution not found.))
# Checks for glib first, or gtk+ if not present
AM_PATH_GLIB(1.1.0, CFLAGS="$CFLAGS $GLIB_CFLAGS" LIBS="$LIBS $GLIB_LIBS",
AC_MSG_WARN(GLIB 1.1.x or above not found.))
if test "x$GLIB_CFLAGS" = x ; then
AM_PATH_GTK(1.0.0, CFLAGS="$CFLAGS $GTK_CFLAGS" LIBS="$LIBS $GTK_LIBS",
AC_MSG_ERROR(GTK+ library not found.))
AC_DEFINE(HAVE_GLIB10)
fi
# Wiretap check (copied and modified from ethereal)
AC_MSG_CHECKING(whether to include wiretap library)

487
wiretap/ct-compile.c Normal file
View File

@ -0,0 +1,487 @@
/* ct-compile.c
------------
Compile-time filter-compiler for Wiretap
*/
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "ct-compile.h"
#ifdef HAVE_GLIB10
#include "glib-new.h"
#endif
#define LINE_SIZE 1024
GHashTable *field_hash;
GHashTable *protocol_hash;
char *protocol_name = NULL;
int rt_iteration;
extern struct field_info working_field; /* in ct-grammar.y */
char *ftype_text[] = {
"NONE",
"BOOLEAN",
"ETHER",
"IPv4ADDR",
"UINT8",
"UINT16",
"UINT32",
"BYTE"
};
char *ctype_text[] = {
"NONE",
"ANDMASK",
"BYTECMP",
"EITHEROF"
};
static
int many_list_subtype(struct field_info *val);
/* Called by main() to initialize the global variables that ct-compile.c
* worries about. */
void compiler_init(void)
{
field_hash = g_hash_table_new(g_str_hash, g_str_equal);
protocol_hash = g_hash_table_new(g_str_hash, g_str_equal);
field_info_init(&working_field);
}
/* takes a pointer to a field_info struct that the parser built,
* makes a copy of the struct, and adds it to our list of fields */
void field_info_add(struct field_info *fi, char *protocol)
{
struct field_info *new_fi;
/* Make a duplicate of the field_info struct, destroying
* the pointers of the old struct in the process. */
new_fi = g_memdup(fi, sizeof(struct field_info));
new_fi->name = fi->name;
new_fi->short_name = fi->short_name;
new_fi->description = fi->description;
new_fi->many_list = fi->many_list;
new_fi->aliases = fi->aliases;
fi->name = NULL;
fi->short_name = NULL;
fi->description = NULL;
fi->many_list = NULL;
fi->aliases = NULL;
/* Find the parent */
new_fi->parent = g_hash_table_lookup(protocol_hash, protocol);
if (!new_fi)
g_print("Cannot find parent protocol %s for field %s\n",
protocol, new_fi->name);
g_hash_table_insert(field_hash, new_fi->name, new_fi);
g_print("field_info_add added %s (%s) \n\t"
"ftype=%s, off=%d, len=%d, val=%d, ctype=%s\n",
new_fi->name,
new_fi->description,
ftype_text[new_fi->field_type], new_fi->offset,
new_fi->length, new_fi->value,
ctype_text[new_fi->computation_type]);
}
/* initialize a field_info struct */
void field_info_init(struct field_info *fi)
{
/* put NULLs in the fields that field_info_zero assumes
* that a non-NULL value corresponds to allocated memory. */
fi->name = NULL;
fi->description = NULL;
fi->aliases = NULL;
fi->many_list = NULL;
field_info_zero(fi);
}
/* zero out the values of an existing field_info struct */
void field_info_zero(struct field_info *fi)
{
if (fi->name)
free(fi->name);
if (fi->short_name)
free(fi->short_name);
if (fi->description)
free(fi->description);
fi->field_type = 0;
fi->computation_type = CTYPE_NONE;
fi->offset = 0;
fi->length = 0;
fi->value = 0;
fi->parent = NULL;
if (fi->aliases)
g_slist_free(fi->aliases);
if (fi->many_list)
g_slist_free(fi->many_list);
fi->aliases = g_slist_alloc();
fi->many_list = g_slist_alloc();
}
void show_aliases(gpointer alias, gpointer field)
{
if (alias)
g_print("%s ", ((GString*)alias)->str);
}
/* add alias(es) to this field */
void field_info_add_alias(char *field_name, GSList *aliases)
{
struct field_info *fi;
fi = g_hash_table_lookup(field_hash, field_name);
if (!fi) {
g_print("Could not find field %s to alias.\n", field_name);
return;
}
g_slist_concat(fi->aliases, aliases);
g_print("(%s) added aliases: ", fi->name);
g_slist_foreach(fi->aliases, show_aliases, NULL);
g_print("\n");
}
/* Given a list of GStrings of field_names, return a list of field_info
* pointers */
GSList* field_info_list(GSList *field_names, char *protocol)
{
GSList *new_list;
char *protocol_dot;
protocol_dot = g_strjoin("", protocol, ".", NULL);
g_slist_foreach(field_names, field_info_list_func1, protocol_dot);
new_list = g_slist_alloc();
g_slist_foreach(field_names, field_info_list_func2, new_list);
return new_list;
}
void field_info_list_func1(gpointer node, gpointer protocol)
{
if(node)
g_string_prepend((GString*)node, (char*)protocol);
}
void field_info_list_func2(gpointer node, gpointer new_list)
{
if (node)
g_slist_append(new_list,
g_hash_table_lookup(field_hash,
((GString*)node)->str));
/* if (node)
g_print("info_list added %s\n", ((GString*)node)->str);*/
}
/* add a protocol to the hash */
void protocol_layer_add(char *name, char *description)
{
struct protocol_layer *new_pr;
new_pr = g_malloc(sizeof(struct protocol_layer));
new_pr->name = g_strdup(name);
new_pr->description = g_strdup(description);
g_hash_table_insert(protocol_hash, new_pr->name, new_pr);
g_print("protocol_layer_add added %s (%s)\n",
new_pr->name,
new_pr->description);
}
/* Creates rt-scanner.l from rt-scanner-skel.l */
void write_rt_lex(void)
{
char buf[LINE_SIZE];
FILE *in, *out;
if (!(in = fopen("rt-scanner-skel.l", "r"))) {
g_error("Could not open rt-scanner-skel.l for reading.");
exit(1);
}
if (!(out = fopen("rt-scanner.l", "w"))) {
g_error("Could not open rt-scanner.l for writing.");
exit(1);
}
while(fgets(buf, LINE_SIZE, in)) {
if (strcmp(buf, "/* ct-compile: lex tokens */\n") == 0) {
write_rt_lex_tokens(out);
continue;
}
else {
fprintf(out, "%s", buf);
}
}
fclose(in);
fclose(out);
}
void write_rt_lex_tokens(FILE *out)
{
g_hash_table_foreach(field_hash, rt_lex_tokens, out);
}
void rt_lex_tokens(gpointer key, gpointer value, gpointer out)
{
char *upcase;
if (!value) {
g_print("key %s has no value.\n", (char*)key);
return;
}
protocol_name = ((struct field_info*) value)->parent->name;
if (((struct field_info*) value)->aliases) {
g_slist_foreach(((struct field_info*) value)->aliases,
rt_lex_tokens_aliases, out);
}
upcase = rt_lex_token_upcase(((struct field_info*)value)->name);
fprintf((FILE*)out, "%s\\.%s\t return %s;\n", protocol_name,
((struct field_info*) value)->short_name,
upcase);
free(upcase);
}
char* rt_lex_token_upcase(char *text)
{
char *new_text;
char *p;
new_text = g_strdup(text);
g_strup(new_text);
/* s/\./_/g */
for (p = new_text; *p; p++) {
if (*p == '.') {
*p = '_';
}
}
return new_text;
}
void rt_lex_tokens_aliases(gpointer node, gpointer out)
{
if (node) {
fprintf((FILE*)out, "%s\\.%s\t|\n",
protocol_name,
((GString*) node)->str);
}
}
/* Creates rt-grammar.y from rt-grammar-skel.y */
void write_rt_yacc(void)
{
char buf[LINE_SIZE];
FILE *in, *out;
if (!(in = fopen("rt-grammar-skel.y", "r"))) {
g_error("Could not open rt-grammar-skel.y for reading.");
exit(1);
}
if (!(out = fopen("rt-grammar.y", "w"))) {
g_error("Could not open rt-scanner.l for writing.");
exit(1);
}
while(fgets(buf, LINE_SIZE, in)) {
if (strcmp(buf, "/* ct-compile: bytecmp_table */\n") == 0) {
write_rt_bytecmp_table(out);
continue;
}
else if (strcmp(buf, "/* ct-compile: eitherof_table */\n") == 0) {
write_rt_eitherof_table(out);
continue;
}
else if (strcmp(buf, "/* ct-compile: yacc tokens */\n") == 0) {
write_rt_yacc_tokens(out);
continue;
}
else if (strcmp(buf, "/* ct-compile: bytecmp_lval */\n") == 0) {
write_rt_bytecmp_lval(out);
continue;
}
else {
fprintf(out, "%s", buf);
}
}
fclose(in);
fclose(out);
}
/* ------------------------- BYTECMP_TABLE -------------------- */
void write_rt_bytecmp_table(FILE *out)
{
fprintf(out, "bytecmp_info bytecmp_table[] = {\n");
g_hash_table_foreach(field_hash, rt_bytecmp_table, out);
fprintf(out, "\t{ 0, 0, 0, 0 }\n};\n");
}
void rt_bytecmp_table(gpointer key, gpointer value, gpointer out)
{
char *upcase;
struct field_info *val = (struct field_info*) value;
if (!val) {
g_print("key %s has no value.\n", (char*)key);
return;
}
/* return now if we're not dealing with a bytecmp field */
if (val->computation_type == CTYPE_EITHEROF) {
if (many_list_subtype(val) != CTYPE_BYTECMP)
return;
}
else if (val->computation_type != CTYPE_BYTECMP) {
return;
}
upcase = rt_lex_token_upcase(((struct field_info*)value)->name);
fprintf((FILE*)out, "\t{ %s, %d, %d, %d },\n",
upcase, val->computation_type, val->offset, val->length);
free(upcase);
}
static
int many_list_subtype(struct field_info *val)
{
struct field_info *fi;
gchar *field1;
if (!val->many_list)
return 0;
field1 = ((GString*)g_slist_nth_data(val->many_list, 1))->str;
fi = g_hash_table_lookup(field_hash, field1);
if (!fi)
return 0;
return fi->computation_type;;
}
/* ------------------- EITHEROF_TABLE ------------------------ */
void write_rt_eitherof_table(FILE *out)
{
fprintf(out, "eitherof_info eitherof_table[] = {\n");
g_hash_table_foreach(field_hash, rt_eitherof_table, out);
fprintf(out, "\t{ 0, 0, 0, 0 }\n};\n");
}
void rt_eitherof_table(gpointer key, gpointer value, gpointer out)
{
char *upcase_field, *upcase_field1, *upcase_field2;
struct field_info *val = (struct field_info*) value;
if (!val) {
g_print("key %s has no value.\n", (char*)key);
return;
}
if (val->computation_type != CTYPE_EITHEROF) {
return;
}
upcase_field = rt_lex_token_upcase(((struct field_info*)value)->name);
g_print("EITHEROF checking %s\n", upcase_field);
if (val->many_list) {
g_print("getting fields\n");
upcase_field1 = ((GString*)g_slist_nth_data(val->many_list, 1))->str;
g_print("got field1 %s\n", upcase_field1);
upcase_field2 = ((GString*)g_slist_nth_data(val->many_list, 2))->str;
g_print("got field2 %s\n", upcase_field2);
upcase_field1 = rt_lex_token_upcase(upcase_field1);
g_print("got field1 %s\n", upcase_field1);
upcase_field2 = rt_lex_token_upcase(upcase_field2);
g_print("got field2 %s\n", upcase_field2);
}
else
return;
fprintf((FILE*)out, "\t{ %s, %d, %s, %s },\n",
upcase_field, val->computation_type,
upcase_field1, upcase_field2);
free(upcase_field);
free(upcase_field1);
free(upcase_field2);
}
/* ---------------------- YACC_TOKENS ---------------------------- */
void write_rt_yacc_tokens(FILE *out)
{
g_hash_table_foreach(field_hash, rt_yacc_tokens, out);
}
void rt_yacc_tokens(gpointer key, gpointer value, gpointer out)
{
char *upcase;
struct field_info *val = (struct field_info*) value;
if (!val) {
g_print("key %s has no value.\n", (char*)key);
return;
}
upcase = rt_lex_token_upcase(((struct field_info*)value)->name);
fprintf((FILE*)out, "%%token <d>\t%s\n", upcase);
free(upcase);
}
/* ------------------------ BYTECMP_LVAL -------------------------- */
void write_rt_bytecmp_lval(FILE *out)
{
rt_iteration = 0;
g_hash_table_foreach(field_hash, rt_bytecmp_lval, out);
fprintf(out, "\t;\n");
}
void rt_bytecmp_lval(gpointer key, gpointer value, gpointer out)
{
char *upcase;
struct field_info *val = (struct field_info*) value;
if (!val) {
g_print("key %s has no value.\n", (char*)key);
return;
}
if (val->computation_type == CTYPE_EITHEROF) {
if (many_list_subtype(val) != CTYPE_BYTECMP)
return;
}
else if (val->computation_type != CTYPE_BYTECMP) {
return;
}
if (rt_iteration == 0) {
fprintf(out, "bytecmp_lval:\t");
}
else {
fprintf(out,"\t|\t");
}
upcase = rt_lex_token_upcase(((struct field_info*)value)->name);
fprintf((FILE*)out, "\t%s { $$ = %s; }\n",
upcase, upcase);
free(upcase);
rt_iteration++;
}

104
wiretap/ct-compile.h Normal file
View File

@ -0,0 +1,104 @@
/* ct-compile.h
------------
Compile-time filter-compiler for Wiretap
*/
#ifndef __G_LIB_H__
#include <glib.h>
#endif
/* field type IDs */
#define FTYPE_BOOLEAN 1
#define FTYPE_ETHER 2
#define FTYPE_IPv4ADDR 3
#define FTYPE_UINT8 4
#define FTYPE_UINT16 5
#define FTYPE_UINT32 6
#define FTYPE_BYTE 7
/* field lengths */
#define FLEN_BOOLEAN 1
#define FLEN_ETHER 6
#define FLEN_IPv4ADDR 4
#define FLEN_UINT8 1
#define FLEN_UINT16 2
#define FLEN_UINT32 4
/* FLEN_BYTE doesn't get a fixed length, of course */
/* computation types */
#define CTYPE_NONE 0
#define CTYPE_ANDMASK 1
#define CTYPE_BYTECMP 2
#define CTYPE_EITHEROF 3
/* Protocol-layer information */
struct protocol_layer {
char *name;
char *description;
GSList *parents;
};
/* Fields */
struct field_info {
char *name;
char *short_name;
char *description;
int field_type;
int computation_type;
int offset;
int value;
int length;
GSList *aliases;
GSList *many_list;
struct protocol_layer *parent;
};
/* Add a field-info struct to the compiler's list of fields */
void field_info_add(struct field_info *fi, char *protocol);
/* Initialize values in a field_info struct. This can only be run once per
* structure, as it would cause a memory leak if used multiple times. */
void field_info_init(struct field_info *fi);
/* Zero-out the values in a field_info struct. This can be used more than once
* per structure, as it avoids a memory leak. But call field_info_init the
* first time, and field_info_zero for all other times */
void field_info_zero(struct field_info *fi);
/* add alias(es) to this field */
void field_info_add_alias(char *field_name, GSList *aliases);
/* add a protocol to the hash */
void protocol_layer_add(char *name, char *description);
/* Given a list of GStrings of field names, returns a list of pointers
* to field_info structs */
GSList* field_info_list(GSList *field_names, char *protocol);
/* used by field_info_list() */
void field_info_list_func1(gpointer node, gpointer protocol);
void field_info_list_func2(gpointer node, gpointer new_list);
void compiler_init(void);
void write_rt_lex(void);
void write_rt_lex_tokens(FILE *out);
void rt_lex_tokens(gpointer key, gpointer value, gpointer out);
void rt_lex_tokens_aliases(gpointer node, gpointer out);
char* rt_lex_token_upcase(char *text);
void write_rt_yacc(void);
void write_rt_bytecmp_table(FILE *out);
void rt_bytecmp_table(gpointer key, gpointer value, gpointer out);
void write_rt_eitherof_table(FILE *out);
void rt_eitherof_table(gpointer key, gpointer value, gpointer out);
void write_rt_yacc_tokens(FILE *out);
void rt_yacc_tokens(gpointer key, gpointer value, gpointer out);
void write_rt_bytecmp_lval(FILE *out);
void rt_bytecmp_lval(gpointer key, gpointer value, gpointer out);
int yylex(void);
int yyparse(void);
void yyerror(char *string);

149
wiretap/ct-grammar.y Normal file
View File

@ -0,0 +1,149 @@
%{
#include <stdlib.h>
#include <stdio.h>
#include "ct-compile.h"
#include "config.h"
#ifdef HAVE_GLIB10
#include "glib-new.h"
#endif
struct field_info working_field;
gchar *current_protocol = NULL;
char *full_field_name = NULL;
%}
%union {
gint d;
GString *s;
GSList *a;
}
%type <s> sentence protocol
%type <a> parents text_list
%token <s> TEXT PROTOCOL PARENTS QUOTED
%token <d> NUMBER BOOLEAN ETHER UINT8 UINT16 UINT32 BYTE
%token FIELD ALIAS
%token AND_MASK BYTE_OFFSET EITHER_OF
%%
paragraph: /* EMPTY */
| paragraph sentence
;
sentence: protocol
{
if (current_protocol)
free(current_protocol);
current_protocol = g_strdup($1->str);
}
| parents
{
g_print("sentence Got parents %d\n", g_slist_length($1));
}
| alias { }
| field { }
;
protocol: PROTOCOL TEXT QUOTED ';'
{
protocol_layer_add($2->str, $3->str);
$$ = $2;
}
;
parents: PARENTS text_list ';'
{
$$ = $2;
g_slist_free($2);
}
;
alias: ALIAS TEXT text_list ';'
{
full_field_name = g_strjoin(".", current_protocol, $2->str, NULL);
field_info_add_alias(full_field_name, $3);
g_free(full_field_name);
}
field: FIELD TEXT QUOTED ',' field_type ',' field_location ';'
{
working_field.name = g_strjoin(".", current_protocol, $2->str, NULL);
working_field.short_name = g_strdup($2->str);
working_field.description = g_strdup($3->str);
field_info_add(&working_field, current_protocol);
field_info_zero(&working_field);
}
field_type: BOOLEAN
{
working_field.field_type = FTYPE_BOOLEAN;
working_field.length = FLEN_BOOLEAN;
}
| ETHER
{
working_field.field_type = FTYPE_ETHER;
working_field.length = FLEN_ETHER;
}
| UINT8
{
working_field.field_type = FTYPE_UINT8;
working_field.length = FLEN_UINT8;
}
| UINT16
{
working_field.field_type = FTYPE_UINT16;
working_field.length = FLEN_UINT16;
}
| UINT32
{
working_field.field_type = FTYPE_UINT32;
working_field.length = FLEN_UINT32;
}
| BYTE '[' NUMBER ']'
{
working_field.field_type = FTYPE_BYTE;
working_field.length = $3;
}
;
field_location: AND_MASK '(' NUMBER '@' NUMBER ')'
{
working_field.computation_type = CTYPE_ANDMASK;
working_field.value = $3;
working_field.offset = $5;
}
| BYTE_OFFSET '(' NUMBER ')'
{
working_field.computation_type = CTYPE_BYTECMP;
working_field.offset = $3;
}
| EITHER_OF '(' text_list ')'
{
working_field.computation_type = CTYPE_EITHEROF;
working_field.many_list = field_info_list($3, current_protocol);
g_slist_free($3);
}
;
text_list: TEXT
{
$$ = g_slist_alloc();
g_slist_append($$, $1);
}
| text_list ',' TEXT
{
$$ = $1;
g_slist_append($$, $3);
}
;

24
wiretap/ct-main.c Normal file
View File

@ -0,0 +1,24 @@
/* ct-main.c
* ---------
* Wiretap filter compilter
*/
#include <stdio.h>
#include "ct-compile.h"
int main(void)
{
FILE *yyin;
yyin = stdin;
compiler_init();
yyparse();
write_rt_lex();
write_rt_yacc();
return 0;
}

74
wiretap/ct-scanner.l Normal file
View File

@ -0,0 +1,74 @@
%{
#include <glib.h>
#include <stdio.h>
#include "ct-tokdefs.h"
int lex_line_number = 1;
%}
N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
B [0-9A-Fa-f][0-9A-Fa-f]?
W [A-Za-z_]
quoted \"[^"\n]*["\n]
%%
\n lex_line_number++;
[\t ]+ /* eat whitespace */
#.* /* one-line shell-style comments */
{quoted} {
yylval.s = g_string_new(yytext + 1);
g_string_truncate(yylval.s, strlen(yytext) - 2);
/* g_print("lex made QUOTED (%s)\n", yylval.s->str);*/
return QUOTED;
}
";" return ';';
"," return ',';
"(" return '(';
")" return ')';
"@" return '@';
"[" return '[';
"]" return ']';
protocol return PROTOCOL;
parents return PARENTS;
field return FIELD;
alias return ALIAS;
boolean return BOOLEAN;
ether return ETHER;
uint8 return UINT8;
uint16 return UINT16;
uint32 return UINT32;
byte return BYTE;
and_mask return AND_MASK;
byte_offset return BYTE_OFFSET;
either_of return EITHER_OF;
{N} {
yylval.d = atoi(yytext);
return NUMBER;
}
{W}+ {
yylval.s = g_string_new(yytext);
/* g_print("lex made TEXT (%s)\n", yylval.s->str);*/
return TEXT;
}
%%
int
yywrap()
{
return 1;
}
void yyerror(char *string)
{
fprintf(stderr,"%s on line %d\n",string, lex_line_number);
exit(0);
}

View File

@ -1,6 +1,6 @@
/* file.c
*
* $Id: file.c,v 1.8 1999/02/20 06:49:26 guy Exp $
* $Id: file.c,v 1.9 1999/03/01 18:57:04 gram Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -25,6 +25,7 @@
#include <string.h>
#include <stdlib.h>
#include "wtap.h"
#include "buffer.h"
#include "lanalyzer.h"
#include "ngsniffer.h"
#include "libpcap.h"
@ -50,7 +51,14 @@ wtap* wtap_open_offline(char *filename)
return NULL;
}
/* Try all my file types */
/* initialization */
wth->file_encap = WTAP_ENCAP_NONE;
wth->filter.offline = NULL;
wth->filter_type = WTAP_FILTER_NONE;
wth->filter_length = 0;
wth->offline_filter_lengths = NULL;
/* Try all file types */
/* WTAP_FILE_PCAP */
if ((wth->file_type = libpcap_open(wth)) != WTAP_FILE_UNKNOWN) {
@ -89,8 +97,7 @@ wtap* wtap_open_offline(char *filename)
return wth;
success:
buffer_init(&wth->frame_buffer, 1500);
wth->frame_number = 0;
wth->file_byte_offset = 0;
wth->frame_buffer = g_malloc(sizeof(struct Buffer));
buffer_init(wth->frame_buffer, 1500);
return wth;
}

38
wiretap/filter-eth Normal file
View File

@ -0,0 +1,38 @@
# filter-eth
#
# Ethernet Filter
#
protocol eth "Ethernet";
#length variable;
parents none;
field src "Source Hardware Address",
ether,
byte_offset(6);
field dst "Destination Hardware Address",
ether,
byte_offset(0);
field srcvendor "Vendor of Source Hardware Address",
byte[3],
byte_offset(6);
field dstvendor "Vendor of Destination Hardware Address",
byte[3],
byte_offset(0);
alias src srcaddr;
alias dst dest, dstaddr, destaddr;
field addr "Hardware Address",
ether,
either_of(src, dst);
alias addr hwaddr;
field vendor "Hardware Vendor",
byte[3],
either_of(srcvendor, dstvendor);

57
wiretap/filter-tr Normal file
View File

@ -0,0 +1,57 @@
# filter-tr
#
# Token-Ring Filter
#
protocol tr "Token-Ring";
#length variable;
parents none;
field sr "Source-Routed Flag",
boolean,
and_mask(127 @ 8);
field src "Source Hardware Address",
ether,
byte_offset(8);
field dst "Destination Hardware Address",
ether,
byte_offset(2);
field srcvendor "Vendor of Source Hardware Address",
byte[3],
byte_offset(8);
field dstvendor "Vendor of Destination Hardware Address",
byte[3],
byte_offset(2);
field _next "Next protocol layer",
uint8,
and_mask(192 @ 1);
alias src srcaddr;
alias dst dest, dstaddr, destaddr;
alias dstvendor destvendor;
field addr "Hardware Address",
ether,
either_of(src, dst);
alias addr hwaddr;
field vendor "Hardware Vendor",
byte[3],
either_of(srcvendor, dstvendor);
#next_protocol {
# 64 : trmac
# 128 : llc
#}
#next_offset {
# ldx
# df
#}

92
wiretap/glib-new.c Normal file
View File

@ -0,0 +1,92 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#ifdef HAVE_GLIB10
#include <glib.h>
#include <stdarg.h>
#include <string.h>
gpointer
g_memdup (const gpointer mem,
guint byte_size)
{
gpointer new_mem;
if (mem)
{
new_mem = g_malloc (byte_size);
memcpy (new_mem, mem, byte_size);
}
else
new_mem = NULL;
return new_mem;
}
gchar*
g_strjoin (const gchar *separator,
...)
{
gchar *string, *s;
va_list args;
guint len;
guint separator_len;
if(separator == NULL)
separator = "";
separator_len = strlen (separator);
va_start(args, separator);
s = va_arg(args, gchar *);
if(s) {
len = strlen(s) + 1;
while((s = va_arg(args, gchar*)))
{
len += separator_len + strlen(s);
}
va_end(args);
string = g_new (gchar, len);
va_start(args, separator);
*string = 0;
s = va_arg(args, gchar*);
strcat (string, s);
while((s = va_arg(args, gchar*)))
{
strcat(string, separator);
strcat(string, s);
}
} else
string = g_strdup("");
va_end(args);
return string;
}
#endif

26
wiretap/glib-new.h Normal file
View File

@ -0,0 +1,26 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
gpointer
g_memdup (const gpointer mem,
guint byte_size);
gchar*
g_strjoin (const gchar *separator,
...);

View File

@ -1,6 +1,6 @@
/* iptrace.c
*
* $Id: iptrace.c,v 1.2 1999/01/07 16:15:35 gram Exp $
* $Id: iptrace.c,v 1.3 1999/03/01 18:57:04 gram Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -24,6 +24,7 @@
#include <time.h>
#include <string.h>
#include "wtap.h"
#include "buffer.h"
#include "iptrace.h"
int iptrace_open(wtap *wth)
@ -70,9 +71,9 @@ int iptrace_read(wtap *wth)
packet_size = pntohs(&header[2]) - 32;
/* Read the packet data */
buffer_assure_space(&wth->frame_buffer, packet_size);
buffer_assure_space(wth->frame_buffer, packet_size);
data_offset = ftell(wth->fh);
bytes_read = fread(buffer_start_ptr(&wth->frame_buffer), 1,
bytes_read = fread(buffer_start_ptr(wth->frame_buffer), 1,
packet_size, wth->fh);
if (bytes_read != packet_size) {

View File

@ -1,6 +1,6 @@
/* lanalyzer.c
*
* $Id: lanalyzer.c,v 1.8 1999/01/29 17:06:56 gram Exp $
* $Id: lanalyzer.c,v 1.9 1999/03/01 18:57:05 gram Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -23,6 +23,7 @@
#include <stdlib.h>
#include <time.h>
#include "wtap.h"
#include "buffer.h"
#include "lanalyzer.h"
int lanalyzer_open(wtap *wth)
@ -111,13 +112,13 @@ int lanalyzer_open(wtap *wth)
board_type = pletohs(&summary[188]);
switch (board_type) {
case 226:
wth->encapsulation = WTAP_ENCAP_ETHERNET;
wth->file_encap = WTAP_ENCAP_ETHERNET;
break;
case 227:
wth->encapsulation = WTAP_ENCAP_TR;
wth->file_encap = WTAP_ENCAP_TR;
break;
default:
wth->encapsulation = WTAP_ENCAP_NONE;
wth->file_encap = WTAP_ENCAP_NONE;
}
break;
@ -183,9 +184,9 @@ int lanalyzer_read(wtap *wth)
}
/* Read the packet data */
buffer_assure_space(&wth->frame_buffer, packet_size);
buffer_assure_space(wth->frame_buffer, packet_size);
data_offset = ftell(wth->fh);
bytes_read = fread(buffer_start_ptr(&wth->frame_buffer), 1,
bytes_read = fread(buffer_start_ptr(wth->frame_buffer), 1,
packet_size, wth->fh);
if (bytes_read != packet_size) {
@ -214,7 +215,7 @@ int lanalyzer_read(wtap *wth)
wth->phdr.len = true_size - 4;
wth->phdr.caplen = packet_size;
wth->phdr.pkt_encap = wth->encapsulation;
wth->phdr.pkt_encap = wth->file_encap;
return data_offset;
}

View File

@ -1,6 +1,6 @@
/* libpcap.c
*
* $Id: libpcap.c,v 1.3 1999/01/07 16:15:36 gram Exp $
* $Id: libpcap.c,v 1.4 1999/03/01 18:57:05 gram Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -21,6 +21,7 @@
*
*/
#include "wtap.h"
#include "buffer.h"
#include "libpcap.h"
/* See source to the "libpcap" library for information on the "libpcap"
@ -133,10 +134,8 @@ int libpcap_open(wtap *wth)
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->file_encap = pcap_encap[hdr.network];
wth->snapshot_length = hdr.snaplen;
/*wth->frame_number = 0;*/
/*wth->file_byte_offset = 0x10b;*/
return WTAP_FILE_PCAP;
}
@ -188,9 +187,9 @@ int libpcap_read(wtap *wth)
}
packet_size = hdr.incl_len;
buffer_assure_space(&wth->frame_buffer, packet_size);
buffer_assure_space(wth->frame_buffer, packet_size);
data_offset = ftell(wth->fh);
bytes_read = fread(buffer_start_ptr(&wth->frame_buffer), 1,
bytes_read = fread(buffer_start_ptr(wth->frame_buffer), 1,
packet_size, wth->fh);
if (bytes_read != packet_size) {
@ -207,7 +206,7 @@ int libpcap_read(wtap *wth)
wth->phdr.ts.tv_usec = hdr.ts_usec;
wth->phdr.caplen = packet_size;
wth->phdr.len = hdr.orig_len;
wth->phdr.pkt_encap = wth->encapsulation;
wth->phdr.pkt_encap = wth->file_encap;
return data_offset;
}

View File

@ -1,6 +1,6 @@
/* netmon.c
*
* $Id: netmon.c,v 1.4 1999/02/20 06:46:33 guy Exp $
* $Id: netmon.c,v 1.5 1999/03/01 18:57:05 gram Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -23,6 +23,7 @@
#include <netinet/in.h>
#include <time.h>
#include "wtap.h"
#include "buffer.h"
#include "netmon.h"
/* The file at
@ -117,7 +118,7 @@ int netmon_open(wtap *wth)
/* This is a netmon file */
wth->capture.netmon = g_malloc(sizeof(netmon_t));
wth->subtype_read = netmon_read;
wth->encapsulation = netmon_encap[hdr.network];
wth->file_encap = netmon_encap[hdr.network];
wth->snapshot_length = 16384; /* XXX - not available in header */
/*
* Convert the time stamp to a "time_t" and a number of
@ -153,8 +154,6 @@ int netmon_open(wtap *wth)
* more packets to read.
*/
wth->capture.netmon->end_offset = pletohl(&hdr.frametableoffset);
/*wth->frame_number = 0;*/
/*wth->file_byte_offset = 0x10b;*/
/* Seek to the beginning of the data records. */
fseek(wth->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET);
@ -191,8 +190,8 @@ int netmon_read(wtap *wth)
data_offset += sizeof hdr;
packet_size = pletohs(&hdr.incl_len);
buffer_assure_space(&wth->frame_buffer, packet_size);
bytes_read = fread(buffer_start_ptr(&wth->frame_buffer), 1,
buffer_assure_space(wth->frame_buffer, packet_size);
bytes_read = fread(buffer_start_ptr(wth->frame_buffer), 1,
packet_size, wth->fh);
if (bytes_read != packet_size) {
@ -212,7 +211,7 @@ int netmon_read(wtap *wth)
wth->phdr.ts.tv_usec = msecs*1000;
wth->phdr.caplen = packet_size;
wth->phdr.len = pletohs(&hdr.orig_len);
wth->phdr.pkt_encap = wth->encapsulation;
wth->phdr.pkt_encap = wth->file_encap;
return data_offset;
}

View File

@ -1,6 +1,6 @@
/* netxray.c
*
* $Id: netxray.c,v 1.1 1999/02/20 06:49:26 guy Exp $
* $Id: netxray.c,v 1.2 1999/03/01 18:57:06 gram Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -25,6 +25,7 @@
#include <time.h>
#include "wtap.h"
#include "netxray.h"
#include "buffer.h"
/* Capture file header, *including* magic number, is padded to 128 bytes. */
#define CAPTUREFILE_HEADER_SIZE 128
@ -37,7 +38,12 @@ static const char netxray_magic[] = { /* magic header */
/* NetXRay file header (minus magic number). */
struct netxray_hdr {
char version[8]; /* version number */
guint32 xxx[10]; /* unknown */
guint32 xxx[3]; /* unknown */
guint32 start_offset; /* offset of first packet in capture */
guint32 end_offset; /* offset after last packet in capture */
guint32 xxy[3]; /* unknown */
guint16 network; /* datalink type */
guint8 xxz[6];
guint32 timelo; /* lower 32 bits of time stamp */
guint32 timehi; /* upper 32 bits of time stamp */
/*
@ -69,8 +75,13 @@ int netxray_open(wtap *wth)
int bytes_read;
char magic[sizeof netxray_magic];
struct netxray_hdr hdr;
double timeunit;
double t;
double timeunit;
double t;
static const int netxray_encap[] = {
WTAP_ENCAP_ETHERNET,
WTAP_ENCAP_TR
};
#define NUM_NETXRAY_ENCAPS (sizeof netxray_encap / sizeof netxray_encap[0])
/* Read in the string that should be at the start of a NetXRay
* file */
@ -102,10 +113,16 @@ int netxray_open(wtap *wth)
return WTAP_FILE_UNKNOWN;
}
hdr.network = pletohs(&hdr.network);
if (hdr.network >= NUM_NETXRAY_ENCAPS) {
g_error("netxray: network type %d unknown", hdr.network);
return WTAP_FILE_UNKNOWN;
}
/* This is a netxray file */
wth->capture.netxray = g_malloc(sizeof(netxray_t));
wth->subtype_read = netxray_read;
wth->encapsulation = WTAP_ENCAP_ETHERNET; /* XXX - where is it? */
wth->file_encap = netxray_encap[hdr.network];
wth->snapshot_length = 16384; /* XXX - not available in header */
wth->capture.netxray->timeunit = timeunit;
t = (double)pletohl(&hdr.timelo)
@ -115,8 +132,14 @@ int netxray_open(wtap *wth)
/*wth->frame_number = 0;*/
/*wth->file_byte_offset = 0x10b;*/
/* Remember the offset after the last packet in the capture (which
* isn't necessarily the last packet in the file), as it appears
* there's sometimes crud after it. */
wth->capture.netxray->wrapped = 0;
wth->capture.netxray->end_offset = pletohl(&hdr.end_offset);
/* Seek to the beginning of the data records. */
fseek(wth->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET);
fseek(wth->fh, pletohl(&hdr.start_offset), SEEK_SET);
return WTAP_FILE_NETXRAY;
}
@ -130,6 +153,13 @@ int netxray_read(wtap *wth)
int data_offset;
double t;
reread:
/* Have we reached the end of the packet data? */
data_offset = ftell(wth->fh);
if (data_offset == wth->capture.netxray->end_offset) {
/* Yes. */
return 0;
}
/* Read record header. */
bytes_read = fread(&hdr, 1, sizeof hdr, wth->fh);
if (bytes_read != sizeof hdr) {
@ -138,14 +168,23 @@ int netxray_read(wtap *wth)
bytes_read);
return -1;
}
/* We're at EOF. Wrap? */
if (!wth->capture.netxray->wrapped) {
/* Yes. Remember that we did. */
wth->capture.netxray->wrapped = 1;
fseek(wth->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET);
goto reread;
}
/* We've already wrapped - don't wrap again. */
return 0;
}
data_offset += sizeof hdr;
packet_size = pletohs(&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,
buffer_assure_space(wth->frame_buffer, packet_size);
bytes_read = fread(buffer_start_ptr(wth->frame_buffer), 1,
packet_size, wth->fh);
if (bytes_read != packet_size) {
@ -169,7 +208,7 @@ int netxray_read(wtap *wth)
*1.0e6);
wth->phdr.caplen = packet_size;
wth->phdr.len = pletohs(&hdr.orig_len);
wth->phdr.pkt_encap = wth->encapsulation;
wth->phdr.pkt_encap = wth->file_encap;
return data_offset;
}

View File

@ -1,6 +1,6 @@
/* ngsniffer.c
*
* $Id: ngsniffer.c,v 1.11 1999/01/07 16:15:36 gram Exp $
* $Id: ngsniffer.c,v 1.12 1999/03/01 18:57:06 gram Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -59,6 +59,7 @@
#include <stdlib.h>
#include <time.h>
#include "wtap.h"
#include "buffer.h"
#include "ngsniffer.h"
/*
@ -290,8 +291,6 @@ int ngsniffer_open(wtap *wth)
wth->capture.ngsniffer = g_malloc(sizeof(ngsniffer_t));
wth->subtype_read = ngsniffer_read;
wth->snapshot_length = 16384; /* not available in header, only in frame */
/*wth->frame_number = 0;*/
/*wth->file_byte_offset = 0x10b;*/
/*
* Read the first record, which the manual says is a version
@ -317,7 +316,7 @@ int ngsniffer_open(wtap *wth)
/* Make sure this is an uncompressed Sniffer file */
if (version.format != 1) {
g_message("ngsniffer: This Sniffer file type is not supported");
g_message("ngsniffer: Compressed Sniffer files are not supported");
free(wth->capture.ngsniffer);
return WTAP_FILE_UNKNOWN;
}
@ -329,7 +328,7 @@ int ngsniffer_open(wtap *wth)
return WTAP_FILE_UNKNOWN;
}
else {
wth->encapsulation = sniffer_encap[version.network];
wth->file_encap = sniffer_encap[version.network];
}
/* Get time unit */
@ -404,8 +403,8 @@ int ngsniffer_open(wtap *wth)
* anyway; the only place you lose is with FORE
* SPANS.
*/
wth->encapsulation = get_atm_linktype(wth);
if (wth->encapsulation == -1) {
wth->file_encap = get_atm_linktype(wth);
if (wth->file_encap == -1) {
/*
* Oops, we couldn't find a link type we can
* handle.
@ -675,7 +674,7 @@ int ngsniffer_read(wtap *wth)
linktype = linktype_for_packet(
frame4.atm_info.AppTrafType,
frame4.atm_info.AppHLType);
if (wth->encapsulation != linktype)
if (wth->file_encap != linktype)
break;
/*
@ -714,7 +713,7 @@ found:
* leaves an Ethernet/802.3 header for Ethernet/802.3, and
* leaves a pad byte and an 802.5 frame control byte for 802.5.
*/
if (wth->capture.ngsniffer->is_atm && wth->encapsulation != WTAP_ENCAP_ATM_RFC1483) {
if (wth->capture.ngsniffer->is_atm && wth->file_encap != WTAP_ENCAP_ATM_RFC1483) {
if (length <= ATM_LANE_HEADER_LEN)
return -1;
fseek(wth->fh, ATM_LANE_HEADER_LEN, SEEK_CUR);
@ -726,9 +725,9 @@ found:
/*
* Read the packet data.
*/
buffer_assure_space(&wth->frame_buffer, length);
buffer_assure_space(wth->frame_buffer, length);
data_offset = ftell(wth->fh);
bytes_read = fread(buffer_start_ptr(&wth->frame_buffer), 1,
bytes_read = fread(buffer_start_ptr(wth->frame_buffer), 1,
length, wth->fh);
if (bytes_read != length) {
@ -746,6 +745,6 @@ found:
wth->phdr.ts.tv_sec = (long)t;
wth->phdr.ts.tv_usec = (unsigned long)((t-(double)(wth->phdr.ts.tv_sec))
*1.0e6);
wth->phdr.pkt_encap = wth->encapsulation;
wth->phdr.pkt_encap = wth->file_encap;
return data_offset;
}

82
wiretap/rt-compile.c Normal file
View File

@ -0,0 +1,82 @@
/*
* rt-compile.c
* ------------
*
*/
#include <glib.h>
#include "wtap.h"
#include "bpf.h"
#include "rt-compile.h"
#include "rt-global.h"
int (*mk_attach)
(wtap *wth);
/* Takes a string representing a display filter, compiles it, and
if the filter compiles successfully, attaches the filter to the wtap handle.
The tricky part comes from the fact that some display filters are
datalink-type-independent (they refer to layers 3 and above of the OSI
protocol stack), whereas others are datalink-type-dependent. Furthermore, some
trace files supported by wiretap can handle more than one datalink type.
We rely on the user to use the proper logic for multiple datalink types. For
example, if the user has a trace file with ethernet and token-ring packets,
and wants to filter on the MAC-layer broadcast address, he should write:
(eth.dst eq ff:ff:ff:ff:ff:ff or tr.dst eq ff:ff:ff:ff:ff:ff)
That is, "eth.dst eq ...." fails for a token-ring interface, and
"tr.dst eq ...." fails for an ethernet device. A logical "or" is needed
to find MAC-level broadcast addresses in both datalink types. */
int wtap_offline_filter(wtap *wth, char *filter)
{
int encap_type;
if (!filter)
return 0;
/* temporary hack */
if (filter[0] == 0) {
wtap_filter_offline_clear(wth);
return 0;
}
/* we use the BPF engine for offline filters */
wtap_filter_offline_init(wth);
wth->filter_text = g_strdup(filter);
/* if the file format we are using has a per-file encapsulation
* type, then we can go ahead and compile the display filter for
* that datalink type. Otherwise, we'll guess ethernet.
*/
if (wth->file_encap != WTAP_ENCAP_NONE)
encap_type = wth->file_encap;
else
encap_type = WTAP_ENCAP_ETHERNET;
if (!wtap_offline_filter_compile(wth, encap_type)) {
wtap_filter_offline_clear(wth);
return -1;
}
return 0;
}
/* this function is called from within wiretap to recompile the same display
* filter for a different datalink type. This is needed for trace files that
* have more than one encapsulation type in the same file
*/
int wtap_offline_filter_compile(wtap *wth, int encap_type)
{
comp_encap_type = encap_type;
filter_parsed = 0;
lex_init(wth->filter_text);
wtap_parse();
if (!filter_parsed)
return 0;
return mk_attach(wth);
}

29
wiretap/rt-compile.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef __WTAP_H_
#include "wtap.h"
#endif
/* Holds info for fields defined as bytecmp. */
typedef struct {
int ftype;
int ctype;
int offset;
int length;
} bytecmp_info;
/* Holds info for fields defined as either_of */
typedef struct {
int ftype;
int ctype;
int field1;
int field2;
} eitherof_info;
int wtap_lex(void);
int wtap_parse(void);
void wtap_error(char *string);
void lex_init(char *);
int wtap_offline_filter_compile(wtap *wth, int encap_type);

23
wiretap/rt-global.h Normal file
View File

@ -0,0 +1,23 @@
extern GList* (*mk_bytecmp)
(int ftype, int rel_opcode, guint8 *bytes);
extern void (*mk_optimize)
(GList *L);
/* for those modules that are interested in mk_attach,
* wtap.h will have already been included.
*/
#ifdef __WTAP_H__
extern int (*mk_attach)
(wtap *wth);
#endif
extern bytecmp_info bytecmp_table[];
extern int comp_encap_type;
extern int filter_parsed;
bytecmp_info* lookup_bytecmp(int ftype);
eitherof_info* lookup_eitherof(int ftype);

134
wiretap/rt-grammar-skel.y Normal file
View File

@ -0,0 +1,134 @@
%{
#ifndef __G_LIB_H__
#include <glib.h>
#endif
#include "rt-compile.h"
#include "rt-global.h"
#include "ct-compile.h"
GList* (*mk_bytecmp) (int ftype, int rel_opcode, guint8 *bytes);
void (*mk_optimize) (GList *L);
/* The encapsulation type for which we are compiling the filter */
int comp_encap_type;
int filter_parsed = 0;
bytecmp_info *bytecmp;
eitherof_info *either;
GList *L1, *L2;
/* ct-compile: bytecmp_table */
/*bytecmp_info bytecmp_table[] = {
{ ETH_TYPE, 12, 2 },
{ TR_DST, 2, 6 },
{ TR_SRC, 8, 6 },
{ ETH_DSTVENDOR, 0, 3 },
{ 0, 0, 0 }
};*/
/* ct-compile: eitherof_table */
/*eitherof_table[] = {
{ TR_VENDOR, CTYPE_BYTECMP, TR_SRCVENDOR, TR_DSTVENDOR },
{ TR_ADDR, CTYPE_BYTECMP, TR_SRCADDR, TR_DSTADDR }
};
*/
%}
%union {
gint d;
guint8 *b;
GString *s;
GList *L;
}
%type <d> bytecmp_lval
%type <L> sentence bytecmp_relation
%type <d> bytecmp_test;
%token <b> BYTES
%token <s> QUOTED TEXT
%token <d> NUMBER
%token <d> EQ NE
/* ct-compile: yacc tokens */
%%
paragraph: /* EMPTY */
| paragraph sentence { mk_optimize($2); filter_parsed = 1; }
;
sentence: bytecmp_relation { $$ = $1 }
;
bytecmp_relation: bytecmp_lval bytecmp_test BYTES
{
bytecmp = lookup_bytecmp($1);
if (bytecmp->ctype == CTYPE_EITHEROF) {
either = lookup_eitherof($1);
L1 = mk_bytecmp(either->field1, $2, $3);
L2 = mk_bytecmp(either->field2, $2, $3);
$$ = g_list_concat(L1, L2);
}
else {
$$ = mk_bytecmp($1, $2, $3);
}
}
;
/* ct-compile: bytecmp_lval */
/*bytecmp_lval: TR_DST { $$ = TR_DST; }
| TR_SRC { $$ = TR_SRC; }
| TR_SRCVENDOR { $$ = TR_SRCVENDOR; }
| TR_DSTVENDOR { $$ = TR_DSTVENDOR; }
;*/
bytecmp_test: EQ { $$ = EQ; }
| NE { $$ = NE; }
;
%%
bytecmp_info*
lookup_bytecmp(int ftype)
{
bytecmp_info *b = &bytecmp_table[0];
bytecmp_info *ret_val = NULL;
/* find the field in the table */
while (b->ftype != 0) {
if (b->ftype == ftype) {
ret_val = b;
break;
}
else {
b++;
}
}
return ret_val;
}
eitherof_info*
lookup_eitherof(int ftype)
{
eitherof_info *e = &eitherof_table[0];
eitherof_info *ret_val = NULL;
/* find the field in the table */
while (e->ftype != 0) {
if (e->ftype == ftype) {
ret_val = e;
break;
}
else {
e++;
}
}
return ret_val;
}

161
wiretap/rt-scanner-skel.l Normal file
View File

@ -0,0 +1,161 @@
%{
#include <glib.h>
#include "rt-tokdefs.h"
guint8* parse_bytes(char *text);
enum nibble_t { high, low };
static char *in_buffer;
/* from libpcap */
#ifdef FLEX_SCANNER
#define YY_NO_UNPUT
#undef YY_INPUT
#define YY_INPUT(buf, result, max)\
{\
char *src = in_buffer;\
int i;\
\
if (*src == 0)\
result = YY_NULL;\
else {\
for (i = 0; *src && i < max; ++i)\
buf[i] = *src++;\
in_buffer += i;\
result = i;\
}\
}
#else
#undef getc
#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++)
#endif
%}
N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
B [0-9A-Fa-f][0-9A-Fa-f]?([-:.]?[0-9A-Fa-f][0-9A-Fa-f]?)*
W [A-Za-z_]
quoted \"[^"\n]*["\n]
%%
[\n\t ]+ /* eat whitespace */
{quoted} {
wtap_lval.s = g_string_new(wtap_text + 1);
g_string_truncate(wtap_lval.s, strlen(wtap_text) - 2);
return QUOTED;
}
";" return ';';
"," return ',';
"(" return '(';
")" return ')';
"@" return '@';
/* ct-compile: lex tokens */
eq return EQ;
ne return NE;
{B} {
wtap_lval.b = parse_bytes(wtap_text);
return BYTES;
}
{N} {
wtap_lval.d = atoi(wtap_text);
return NUMBER;
}
{W}+ {
wtap_lval.s = g_string_new(wtap_text);
return TEXT;
}
%%
guint8*
parse_bytes(char *text)
{
guint8 buffer[256];
guint8 index = 0;
char *cp;
char character;
guint8 byte_val=0;
gchar *dup_ptr;
enum nibble_t nibble = high;
for (cp = text; (*cp != '\x0') && index < 256; cp++) {
character = *cp;
if (nibble == high) {
/* assumes ASCII, not EBCDIC */
if (character >= '0' && character <= '9') {
byte_val = (character - '0') << 4;
}
else if (character >= 'A' && character <= 'F') {
byte_val = (character - 'A' + 10) << 4;
}
else if (character >= 'a' && character <= 'f') {
byte_val = (character - 'a' + 10) << 4;
}
else {
continue;
}
nibble = low;
continue;
}
else {
/* assumes ASCII, not EBCDIC */
if (character >= '0' && character <= '9') {
byte_val += (character - '0');
}
else if (character >= 'A' && character <= 'F') {
byte_val += (character - 'A' + 10);
}
else if (character >= 'a' && character <= 'f') {
byte_val += (character - 'a' + 10);
}
else {
byte_val >>= 4;
}
nibble = high;
buffer[index] = byte_val;
index++;
}
}
/* did we finish mid-nibble? */
if (nibble == low) {
buffer[index] = byte_val >> 4;
index++;
}
dup_ptr = g_malloc(index + 1);
dup_ptr[0] = index;
memcpy(dup_ptr + 1, buffer, index);
return dup_ptr;
}
void wtap_error(char *string)
{
g_error("%s\n",string);
exit(0);
}
/* from libpcap */
void
lex_init(char *buf)
{
in_buffer = buf;
}
int
yywrap()
{
return 1;
}

View File

@ -1,6 +1,6 @@
/* snoop.c
*
* $Id: snoop.c,v 1.3 1999/02/20 06:46:57 guy Exp $
* $Id: snoop.c,v 1.4 1999/03/01 18:57:07 gram Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -21,6 +21,7 @@
*
*/
#include "wtap.h"
#include "buffer.h"
#include "snoop.h"
#include <netinet/in.h>
@ -98,10 +99,8 @@ int snoop_open(wtap *wth)
/* This is a snoop file */
wth->subtype_read = snoop_read;
wth->encapsulation = snoop_encap[hdr.network];
wth->file_encap = 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;
}
@ -126,9 +125,9 @@ int snoop_read(wtap *wth)
}
packet_size = ntohl(hdr.incl_len);
buffer_assure_space(&wth->frame_buffer, packet_size);
buffer_assure_space(wth->frame_buffer, packet_size);
data_offset = ftell(wth->fh);
bytes_read = fread(buffer_start_ptr(&wth->frame_buffer), 1,
bytes_read = fread(buffer_start_ptr(wth->frame_buffer), 1,
packet_size, wth->fh);
if (bytes_read != packet_size) {
@ -145,7 +144,7 @@ int snoop_read(wtap *wth)
wth->phdr.ts.tv_usec = ntohl(hdr.ts_usec);
wth->phdr.caplen = packet_size;
wth->phdr.len = ntohl(hdr.orig_len);
wth->phdr.pkt_encap = wth->encapsulation;
wth->phdr.pkt_encap = wth->file_encap;
/* Skip over the padding. */
fseek(wth->fh, ntohl(hdr.rec_len) - (sizeof hdr + packet_size),

297
wiretap/wiretap.c Normal file
View File

@ -0,0 +1,297 @@
#include <stdio.h>
#include <glib.h>
#include "wtap.h"
#include "bpf-engine.h"
#include "glib-new.h"
void bpf_dump(wtap *wth);
char *bpf_image(struct bpf_instruction *p, int n);
int main(int argc, char **argv)
{
wtap *wth;
char *fsyntax = "";
int i;
if (argc <= 1) {
fprintf(stderr, "usage: wiretap filter\n");
exit(-1);
}
for (i = 1; i < argc; i++) {
fsyntax = g_strjoin(" ", fsyntax, argv[i], NULL);
}
wth = wtap_open_offline("/home/gram/prj/sniff/test.trace");
wtap_offline_filter(wth, fsyntax);
/* wtap_offline_filter_compile(wth, WTAP_ENCAP_ETHERNET);*/
bpf_dump(wth);
return 0;
}
void
bpf_dump(wtap *wth)
{
struct bpf_instruction *fentry;
int flen;
int i;
fentry = wth->filter.offline[WTAP_ENCAP_ETHERNET];
flen = wth->offline_filter_lengths[WTAP_ENCAP_ETHERNET];
/* this loop is from tcpdump's bpf_dump.c */
for (i = 0; i < flen; ++fentry, ++i) {
puts(bpf_image(fentry, i));
}
}
/* this entire function is from libpcap's bpf_image.c */
char *
bpf_image(struct bpf_instruction *p, int n)
{
int v;
char *fmt, *op;
static char image[256];
char operand[64];
v = p->k;
switch (p->code) {
default:
op = "unimp";
fmt = "0x%x";
v = p->code;
break;
case BPF_RET|BPF_K:
op = "ret";
fmt = "#%d";
break;
case BPF_RET|BPF_A:
op = "ret";
fmt = "";
break;
case BPF_LD|BPF_W|BPF_ABS:
op = "ld";
fmt = "[%d]";
break;
case BPF_LD|BPF_H|BPF_ABS:
op = "ldh";
fmt = "[%d]";
break;
case BPF_LD|BPF_B|BPF_ABS:
op = "ldb";
fmt = "[%d]";
break;
case BPF_LD|BPF_W|BPF_LEN:
op = "ld";
fmt = "#pktlen";
break;
case BPF_LD|BPF_W|BPF_IND:
op = "ld";
fmt = "[x + %d]";
break;
case BPF_LD|BPF_H|BPF_IND:
op = "ldh";
fmt = "[x + %d]";
break;
case BPF_LD|BPF_B|BPF_IND:
op = "ldb";
fmt = "[x + %d]";
break;
case BPF_LD|BPF_IMM:
op = "ld";
fmt = "#0x%x";
break;
case BPF_LDX|BPF_IMM:
op = "ldx";
fmt = "#0x%x";
break;
case BPF_LDX|BPF_MSH|BPF_B:
op = "ldxb";
fmt = "4*([%d]&0xf)";
break;
case BPF_LD|BPF_MEM:
op = "ld";
fmt = "M[%d]";
break;
case BPF_LDX|BPF_MEM:
op = "ldx";
fmt = "M[%d]";
break;
case BPF_ST:
op = "st";
fmt = "M[%d]";
break;
case BPF_STX:
op = "stx";
fmt = "M[%d]";
break;
case BPF_JMP|BPF_JA:
op = "ja";
fmt = "%d";
v = n + 1 + p->k;
break;
case BPF_JMP|BPF_JGT|BPF_K:
op = "jgt";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JGE|BPF_K:
op = "jge";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JEQ|BPF_K:
op = "jeq";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JSET|BPF_K:
op = "jset";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JGT|BPF_X:
op = "jgt";
fmt = "x";
break;
case BPF_JMP|BPF_JGE|BPF_X:
op = "jge";
fmt = "x";
break;
case BPF_JMP|BPF_JEQ|BPF_X:
op = "jeq";
fmt = "x";
break;
case BPF_JMP|BPF_JSET|BPF_X:
op = "jset";
fmt = "x";
break;
case BPF_ALU|BPF_ADD|BPF_X:
op = "add";
fmt = "x";
break;
case BPF_ALU|BPF_SUB|BPF_X:
op = "sub";
fmt = "x";
break;
case BPF_ALU|BPF_MUL|BPF_X:
op = "mul";
fmt = "x";
break;
case BPF_ALU|BPF_DIV|BPF_X:
op = "div";
fmt = "x";
break;
case BPF_ALU|BPF_AND|BPF_X:
op = "and";
fmt = "x";
break;
case BPF_ALU|BPF_OR|BPF_X:
op = "or";
fmt = "x";
break;
case BPF_ALU|BPF_LSH|BPF_X:
op = "lsh";
fmt = "x";
break;
case BPF_ALU|BPF_RSH|BPF_X:
op = "rsh";
fmt = "x";
break;
case BPF_ALU|BPF_ADD|BPF_K:
op = "add";
fmt = "#%d";
break;
case BPF_ALU|BPF_SUB|BPF_K:
op = "sub";
fmt = "#%d";
break;
case BPF_ALU|BPF_MUL|BPF_K:
op = "mul";
fmt = "#%d";
break;
case BPF_ALU|BPF_DIV|BPF_K:
op = "div";
fmt = "#%d";
break;
case BPF_ALU|BPF_AND|BPF_K:
op = "and";
fmt = "#0x%x";
break;
case BPF_ALU|BPF_OR|BPF_K:
op = "or";
fmt = "#0x%x";
break;
case BPF_ALU|BPF_LSH|BPF_K:
op = "lsh";
fmt = "#%d";
break;
case BPF_ALU|BPF_RSH|BPF_K:
op = "rsh";
fmt = "#%d";
break;
case BPF_ALU|BPF_NEG:
op = "neg";
fmt = "";
break;
case BPF_MISC|BPF_TAX:
op = "tax";
fmt = "";
break;
case BPF_MISC|BPF_TXA:
op = "txa";
fmt = "";
break;
}
(void)sprintf(operand, fmt, v);
(void)sprintf(image,
(BPF_CLASS(p->code) == BPF_JMP &&
BPF_OP(p->code) != BPF_JA) ?
"(%03d) %-8s %-16s jt %d\tjf %d"
: "(%03d) %-8s %s",
n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
return image;
}

View File

@ -1,6 +1,6 @@
/* wtap.c
*
* $Id: wtap.c,v 1.6 1999/02/12 16:26:09 gram Exp $
* $Id: wtap.c,v 1.7 1999/03/01 18:57:07 gram Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -22,6 +22,9 @@
*/
#include "wtap.h"
#include "buffer.h"
#include "bpf-engine.h"
#include "rt-compile.h"
FILE* wtap_file(wtap *wth)
{
@ -58,6 +61,10 @@ void wtap_close(wtap *wth)
g_free(wth->capture.ngsniffer);
break;
case WTAP_FILE_NETMON:
g_free(wth->capture.netmon);
break;
/* default:
nothing */
}
@ -67,13 +74,36 @@ void wtap_close(wtap *wth)
void wtap_loop(wtap *wth, int count, wtap_handler callback, u_char* user)
{
int i = 0;
int data_offset;
int ret;
int pkt_encap;
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));
/* offline filter? */
if (wth->filter_type == WTAP_FILTER_OFFLINE) {
pkt_encap = wth->phdr.pkt_encap;
/* do we have a compiled filter for this
* encapsulation type? */
if (!wth->filter.offline[pkt_encap])
wtap_offline_filter_compile(wth, pkt_encap);
/* run the filter */
ret = bpf_run_filter(
buffer_start_ptr(wth->frame_buffer),
wth->phdr.caplen,
wth->filter.offline[pkt_encap],
wth->offline_filter_lengths[pkt_encap]
);
/* if the packet made it through the filter,
* send the data to the user */
if (ret > 0)
callback(user, &wth->phdr, data_offset,
buffer_start_ptr(wth->frame_buffer));
}
else
callback(user, &wth->phdr, data_offset,
buffer_start_ptr(wth->frame_buffer));
}
}

View File

@ -1,6 +1,6 @@
/* wtap.h
*
* $Id: wtap.h,v 1.13 1999/02/20 06:49:26 guy Exp $
* $Id: wtap.h,v 1.14 1999/03/01 18:57:07 gram Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -21,6 +21,9 @@
*
*/
#ifndef __WTAP_H__
#define __WTAP_H__
/* Encapsulation types. Choose names that truly reflect
* what is contained in the packet trace file. */
#define WTAP_ENCAP_NONE 0
@ -33,6 +36,9 @@
#define WTAP_ENCAP_ARCNET 7
#define WTAP_ENCAP_ATM_RFC1483 8
/* last WTAP_ENCAP_ value + 1 */
#define WTAP_NUM_ENCAP_TYPES 9
/* File types that can be read by wiretap */
#define WTAP_FILE_UNKNOWN 0
#define WTAP_FILE_WTAP 1
@ -44,11 +50,18 @@
#define WTAP_FILE_NETMON 8
#define WTAP_FILE_NETXRAY 9
/* Filter types that wiretap can create. An 'offline' filter is really
* a BPF filter, but it is treated specially because wiretap might not know
* in advance the datalink type(s) needed.
*/
#define WTAP_FILTER_NONE 0
#define WTAP_FILTER_OFFLINE 1
#define WTAP_FILTER_BPF 2
#include <sys/types.h>
#include <sys/time.h>
#include <glib.h>
#include <stdio.h>
#include <buffer.h>
typedef struct {
double timeunit;
@ -81,6 +94,8 @@ typedef struct {
typedef struct {
double timeunit;
double starttime;
int wrapped;
int end_offset;
} netxray_t;
struct wtap_pkthdr {
@ -94,14 +109,15 @@ typedef void (*wtap_handler)(u_char*, const struct wtap_pkthdr*,
int, const u_char *);
struct wtap;
struct bpf_instruction;
struct Buffer;
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;
int file_type;
int snapshot_length;
struct Buffer *frame_buffer;
struct wtap_pkthdr phdr;
union {
@ -112,13 +128,28 @@ typedef struct wtap {
netxray_t *netxray;
} capture;
subtype_func subtype_read;
int encapsulation;
subtype_func subtype_read;
int file_encap; /* per-file, for those
file formats that have
per-file encapsulation
types */
union {
struct bpf_instruction *bpf;
struct bpf_instruction **offline;
} filter;
gchar *filter_text;
int filter_type;
int filter_length; /* length in bytes or records,
depending upon filter_type */
int *offline_filter_lengths;
} wtap;
wtap* wtap_open_offline(char *filename);
void wtap_loop(wtap *wth, int, wtap_handler, u_char*);
int wtap_offline_filter(wtap *wth, char *filter);
FILE* wtap_file(wtap *wth);
int wtap_snapshot_length(wtap *wth); /* per file */
@ -131,22 +162,30 @@ void wtap_close(wtap *wth);
* The pletoh[sl] versions return the little-endian representation.
*/
#ifndef pntohs
#define pntohs(p) ((guint16) \
((guint16)*((guint8 *)p+0)<<8| \
(guint16)*((guint8 *)p+1)<<0))
#endif
#ifndef pntohl
#define pntohl(p) ((guint32)*((guint8 *)p+0)<<24| \
(guint32)*((guint8 *)p+1)<<16| \
(guint32)*((guint8 *)p+2)<<8| \
(guint32)*((guint8 *)p+3)<<0)
#endif
#ifndef pletohs
#define pletohs(p) ((guint16) \
((guint16)*((guint8 *)p+1)<<8| \
(guint16)*((guint8 *)p+0)<<0))
#endif
#ifndef plethol
#define pletohl(p) ((guint32)*((guint8 *)p+3)<<24| \
(guint32)*((guint8 *)p+2)<<16| \
(guint32)*((guint8 *)p+1)<<8| \
(guint32)*((guint8 *)p+0)<<0)
#endif
#endif /* __WTAP_H__ */