Implement epan_dissect_new() and epan_dissect_free(). These are the

"top-level" dissectors that libepan-users call, instead of dissect_packet().
The epan_dissect_t holds the tvbuff after dissection so that the tvbuff's
memory is not cleared until after the proto_tree is freed. (I might stuff
the proto_tree into the epan_dissect_t, too).

What remains of dissect_packet() in packet.c handles the tvbuff initialiation.
The real meat of dissect_packet() is now in dissect_frame(), in packet-frame.c
This means that "packet.c" is no longer a dissector, os it is no longer
passed to make-reg-dotc.

Once dissect_fddi() gets two wrapper functions (dissect_fddi_swapped()
and dissect_fddi_nonswapped()), the a dissector handoff routine could
be used instead of the switch statement in dissect_frame(). I'd register
a field like "wtap.encap"

svn path=/trunk/; revision=2478
This commit is contained in:
Gilbert Ramirez 2000-10-06 10:11:40 +00:00
parent e735d485ae
commit e69b5278aa
11 changed files with 390 additions and 216 deletions

View File

@ -1,7 +1,7 @@
# Makefile.am # Makefile.am
# Automake file for Ethereal # Automake file for Ethereal
# #
# $Id: Makefile.am,v 1.231 2000/09/28 03:52:03 gram Exp $ # $Id: Makefile.am,v 1.232 2000/10/06 10:10:44 gram Exp $
# #
# Ethereal - Network traffic analyzer # Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org> # By Gerald Combs <gerald@zing.org>
@ -58,6 +58,7 @@ DISSECTOR_SOURCES = \
packet-eth.c \ packet-eth.c \
packet-ethertype.c \ packet-ethertype.c \
packet-fddi.c \ packet-fddi.c \
packet-frame.c \
packet-ftp.c \ packet-ftp.c \
packet-giop.c \ packet-giop.c \
packet-gre.c \ packet-gre.c \
@ -188,6 +189,7 @@ noinst_HEADERS = \
packet-esis.h \ packet-esis.h \
packet-eth.h \ packet-eth.h \
packet-fddi.h \ packet-fddi.h \
packet-frame.h \
packet-http.h \ packet-http.h \
packet-ip.h \ packet-ip.h \
packet-ipp.h \ packet-ipp.h \
@ -413,8 +415,7 @@ editcap_LDADD = wiretap/libwiretap.a @GLIB_LIBS@
# start in column zero, or must be preceded only by "void " starting in # start in column zero, or must be preceded only by "void " starting in
# column zero, and must not be inside #if. # column zero, and must not be inside #if.
# #
# We assume that all dissector routines are in "packet-XXX.c" files, # We assume that all dissector routines are in "packet-XXX.c" files.
# or in "packet.c".
# #
# For some unknown reason, having a big "for" loop in the Makefile # For some unknown reason, having a big "for" loop in the Makefile
# to scan all the "packet-XXX.c" files doesn't work with some "make"s; # to scan all the "packet-XXX.c" files doesn't work with some "make"s;
@ -426,9 +427,9 @@ editcap_LDADD = wiretap/libwiretap.a @GLIB_LIBS@
# The first argument is the directory in which the source files live. # The first argument is the directory in which the source files live.
# All subsequent arguments are the files to scan. # All subsequent arguments are the files to scan.
# #
register.c: $(srcdir)/epan/packet.c $(DISSECTOR_SOURCES) $(srcdir)/make-reg-dotc register.c: $(DISSECTOR_SOURCES) $(srcdir)/make-reg-dotc
@echo Making register.c @echo Making register.c
@$(srcdir)/make-reg-dotc $(srcdir) $(srcdir)/epan/packet.c $(DISSECTOR_SOURCES) @$(srcdir)/make-reg-dotc $(srcdir) $(DISSECTOR_SOURCES)
ps.c: print.ps rdps ps.c: print.ps rdps
./rdps $(srcdir)/print.ps ps.c ./rdps $(srcdir)/print.ps ps.c

View File

@ -10,6 +10,7 @@
#include "conversation.h" #include "conversation.h"
#include "dfilter.h" #include "dfilter.h"
#include "except.h" #include "except.h"
#include "packet.h"
#include "proto.h" #include "proto.h"
#include "tvbuff.h" #include "tvbuff.h"
@ -18,6 +19,7 @@ epan_init(void)
{ {
except_init(); except_init();
tvbuff_init(); tvbuff_init();
packet_init();
proto_init(); proto_init();
dfilter_init(); dfilter_init();
#ifdef HAVE_PLUGINS #ifdef HAVE_PLUGINS
@ -30,6 +32,7 @@ epan_cleanup(void)
{ {
dfilter_cleanup(); dfilter_cleanup();
proto_cleanup(); proto_cleanup();
packet_cleanup();
tvbuff_cleanup(); tvbuff_cleanup();
except_deinit(); except_deinit();
} }
@ -40,3 +43,35 @@ epan_conversation_init(void)
{ {
conversation_init(); conversation_init();
} }
struct epan_dissect {
tvbuff_t *tvb;
proto_tree *tree;
};
epan_dissect_t*
epan_dissect_new(void* pseudo_header, const guint8* data, frame_data *fd, proto_tree *tree)
{
epan_dissect_t *edt;
edt = g_new(epan_dissect_t, 1);
/* XXX - init tree */
dissect_packet(&edt->tvb, pseudo_header, data, fd, tree);
return edt;
}
void
epan_dissect_free(epan_dissect_t* edt)
{
/* Free all tvb's created from this tvb, unless dissector
* wanted to store the pointer (in which case, the dissector
* would have incremented the usage count on that tvbuff_t*) */
tvb_free_chain(edt->tvb);
g_free(edt);
}

View File

@ -5,13 +5,19 @@
*/ */
#ifndef EPAN_H #ifndef EPAN_H
#define EPAN_H
#include <glib.h> #include <glib.h>
/* XXX - for now */
#include "packet.h"
void epan_init(void); void epan_init(void);
void epan_cleanup(void); void epan_cleanup(void);
void epan_conversation_init(void); void epan_conversation_init(void);
/* A client will create one epan_t for an entire dissection session. /* A client will create one epan_t for an entire dissection session.
* A single epan_t will be used to analyze the entire sequence of packets, * A single epan_t will be used to analyze the entire sequence of packets,
* sequentially, in a single session. A session corresponds to a single * sequentially, in a single session. A session corresponds to a single
@ -21,7 +27,6 @@ void epan_conversation_init(void);
*/ */
typedef struct epan_session epan_t; typedef struct epan_session epan_t;
epan_t* epan_t*
epan_new(void); epan_new(void);
@ -39,17 +44,21 @@ epan_free(epan_t*);
*/ */
typedef struct epan_dissect epan_dissect_t; typedef struct epan_dissect epan_dissect_t;
epan_dissect_t* epan_dissect_t*
epan_dissect_new(epan_t*, guint8* data, guint len, guint32 wtap_encap, epan_dissect_new(void* pseudo_header, const guint8* data, frame_data *fd, proto_tree *tree);
void* pseudo_header);
void void
epan_dissect_free(epan_t*, epan_dissect_t*); epan_dissect_free(epan_dissect_t* edt);
/* Should this be ".libepan"? For backwards-compatibility, I'll keep /* Should this be ".libepan"? For backwards-compatibility, I'll keep
* it ".ethereal" for now. * it ".ethereal" for now.
*/ */
#define PF_DIR ".ethereal" #define PF_DIR ".ethereal"
#endif /* EPAN_H */ #endif /* EPAN_H */

View File

@ -1,7 +1,7 @@
/* packet.c /* packet.c
* Routines for packet disassembly * Routines for packet disassembly
* *
* $Id: packet.c,v 1.1 2000/09/27 05:18:05 gram Exp $ * $Id: packet.c,v 1.2 2000/10/06 10:11:15 gram Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org> * By Gerald Combs <gerald@zing.org>
@ -73,22 +73,10 @@
#include "timestamp.h" #include "timestamp.h"
#include "file.h" #include "file.h"
#include "packet-ascend.h"
#include "packet-atalk.h" #include "packet-atalk.h"
#include "packet-atm.h" #include "packet-frame.h"
#include "packet-clip.h"
#include "packet-eth.h"
#include "packet-fddi.h"
#include "packet-ipv6.h" #include "packet-ipv6.h"
#include "packet-lapb.h"
#include "packet-lapd.h"
#include "packet-llc.h"
#include "packet-null.h"
#include "packet-ppp.h"
#include "packet-raw.h"
#include "packet-sna.h" #include "packet-sna.h"
#include "packet-tr.h"
#include "packet-v120.h"
#include "packet-vines.h" #include "packet-vines.h"
#include "resolv.h" #include "resolv.h"
@ -97,29 +85,15 @@
extern capture_file cfile; extern capture_file cfile;
static int proto_frame = -1;
static int hf_frame_arrival_time = -1;
static int hf_frame_time_delta = -1;
static int hf_frame_number = -1;
static int hf_frame_packet_len = -1;
static int hf_frame_capture_len = -1;
static int hf_frame_p2p_dir = -1;
static int proto_short = -1;
static int proto_malformed = -1;
static gint ett_frame = -1; extern int proto_malformed;
static void display_signed_time(gchar *, int, gint32, gint32); static void display_signed_time(gchar *, int, gint32, gint32);
static const value_string p2p_dirs[] = {
{ P2P_DIR_SENT, "Sent" },
{ P2P_DIR_RECV, "Received" },
{ 0, NULL }
};
/* Protocol-specific data attched to a frame_data structure - protocol /* Protocol-specific data attached to a frame_data structure - protocol
index and opaque pointer. */ index and opaque pointer. */
typedef struct _frame_proto_data { typedef struct _frame_proto_data {
int proto; int proto;
@ -128,6 +102,7 @@ typedef struct _frame_proto_data {
GMemChunk *frame_proto_data_area = NULL; GMemChunk *frame_proto_data_area = NULL;
/* /*
* Free up any space allocated for frame proto data areas and then * Free up any space allocated for frame proto data areas and then
* allocate a new area. * allocate a new area.
@ -149,6 +124,19 @@ packet_init_protocol(void)
} }
void
packet_init(void)
{
register_init_routine(&packet_init_protocol);
}
void
packet_cleanup(void)
{
/* nothing */
}
/* Wrapper for the most common case of asking /* Wrapper for the most common case of asking
* for a string using a colon as the hex-digit separator. * for a string using a colon as the hex-digit separator.
*/ */
@ -980,63 +968,13 @@ init_all_protocols(void)
g_slist_foreach(init_routines, &call_init_routine, NULL); g_slist_foreach(init_routines, &call_init_routine, NULL);
} }
/* this routine checks the frame type from the cf structure */ /* Creates the top-most tvbuff and calls dissect_frame() */
void void
dissect_packet(union wtap_pseudo_header *pseudo_header, const u_char *pd, dissect_packet(tvbuff_t **p_tvb, union wtap_pseudo_header *pseudo_header,
frame_data *fd, proto_tree *tree) const u_char *pd, frame_data *fd, proto_tree *tree)
{ {
proto_tree *fh_tree;
proto_item *ti;
struct timeval tv;
static tvbuff_t *tvb;
blank_packetinfo(); blank_packetinfo();
if (fd->lnk_t == WTAP_ENCAP_LAPD ||
fd->lnk_t == WTAP_ENCAP_PPP_WITH_PHDR) {
pi.p2p_dir = pseudo_header->p2p.sent ? P2P_DIR_SENT : P2P_DIR_RECV;
}
/* Put in frame header information. */
if (tree) {
ti = proto_tree_add_protocol_format(tree, proto_frame, NullTVB, 0, fd->cap_len,
"Frame %u (%u on wire, %u captured)", fd->num,
fd->pkt_len, fd->cap_len);
fh_tree = proto_item_add_subtree(ti, ett_frame);
tv.tv_sec = fd->abs_secs;
tv.tv_usec = fd->abs_usecs;
proto_tree_add_time(fh_tree, hf_frame_arrival_time, NullTVB,
0, 0, &tv);
tv.tv_sec = fd->del_secs;
tv.tv_usec = fd->del_usecs;
proto_tree_add_time(fh_tree, hf_frame_time_delta, NullTVB,
0, 0, &tv);
proto_tree_add_uint(fh_tree, hf_frame_number, NullTVB,
0, 0, fd->num);
proto_tree_add_uint_format(fh_tree, hf_frame_packet_len, NullTVB,
0, 0, fd->pkt_len, "Packet Length: %d byte%s", fd->pkt_len,
plurality(fd->pkt_len, "", "s"));
proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, NullTVB,
0, 0, fd->cap_len, "Capture Length: %d byte%s", fd->cap_len,
plurality(fd->cap_len, "", "s"));
/* Check for existences of P2P pseudo header */
if (fd->lnk_t == WTAP_ENCAP_LAPD || fd->lnk_t == WTAP_ENCAP_PPP_WITH_PHDR) {
proto_tree_add_uint(fh_tree, hf_frame_p2p_dir, NullTVB,
0, 0, pi.p2p_dir);
}
}
/* Set the initial payload to the packet length, and the initial /* Set the initial payload to the packet length, and the initial
captured payload to the capture length (other protocols may captured payload to the capture length (other protocols may
reduce them if their headers say they're less). */ reduce them if their headers say they're less). */
@ -1045,81 +983,29 @@ dissect_packet(union wtap_pseudo_header *pseudo_header, const u_char *pd,
pi.fd = fd; pi.fd = fd;
pi.pseudo_header = pseudo_header; pi.pseudo_header = pseudo_header;
pi.current_proto = "Frame";
col_set_writable(fd, TRUE); col_set_writable(fd, TRUE);
TRY { TRY {
tvb = tvb_new_real_data(pd, fd->cap_len, fd->pkt_len); *p_tvb = tvb_new_real_data(pd, fd->cap_len, fd->pkt_len);
pi.compat_top_tvb = tvb; pi.compat_top_tvb = *p_tvb;
switch (fd->lnk_t) {
case WTAP_ENCAP_ETHERNET :
dissect_eth(tvb, &pi, tree);
break;
case WTAP_ENCAP_FDDI :
dissect_fddi(tvb, &pi, tree, FALSE);
break;
case WTAP_ENCAP_FDDI_BITSWAPPED :
dissect_fddi(tvb, &pi, tree, TRUE);
break;
case WTAP_ENCAP_TOKEN_RING :
dissect_tr(tvb, &pi, tree);
break;
case WTAP_ENCAP_NULL :
dissect_null(tvb, &pi, tree);
break;
case WTAP_ENCAP_PPP :
case WTAP_ENCAP_PPP_WITH_PHDR :
dissect_ppp(tvb, &pi, tree);
break;
case WTAP_ENCAP_LAPB :
dissect_lapb(tvb, &pi, tree);
break;
case WTAP_ENCAP_RAW_IP :
dissect_raw(tvb, &pi, tree);
break;
case WTAP_ENCAP_LINUX_ATM_CLIP :
dissect_clip(tvb, &pi, tree);
break;
case WTAP_ENCAP_ATM_SNIFFER :
dissect_atm(tvb, &pi, tree);
break;
case WTAP_ENCAP_ASCEND :
dissect_ascend(tvb, &pi, tree);
break;
case WTAP_ENCAP_LAPD :
dissect_lapd(tvb, &pi, tree);
break;
case WTAP_ENCAP_V120 :
dissect_v120(tvb, &pi, tree);
break;
case WTAP_ENCAP_ATM_RFC1483:
dissect_llc(tvb, &pi, tree);
break;
default:
g_assert_not_reached();
break;
}
} }
CATCH(BoundsError) { CATCH(BoundsError) {
proto_tree_add_protocol_format(tree, proto_short, NullTVB, 0, 0, g_assert_not_reached();
"[Short Frame: %s]", pi.current_proto );
} }
CATCH(ReportedBoundsError) { CATCH(ReportedBoundsError) {
proto_tree_add_protocol_format(tree, proto_malformed, NullTVB, 0, 0, proto_tree_add_protocol_format(tree, proto_malformed, *p_tvb, 0, 0,
"[Malformed Frame: %s]", pi.current_proto ); "[Malformed Frame: Packet Length]" );
} }
ENDTRY; ENDTRY;
/* Free all tvb's created from this tvb, unless dissector dissect_frame(*p_tvb, &pi, tree);
* wanted to store the pointer (in which case, the dissector
* would have incremented the usage count on that tvbuff_t*) */
tvb_free_chain(tvb);
fd->flags.visited = 1; fd->flags.visited = 1;
} }
gint p_compare(gconstpointer a, gconstpointer b) gint p_compare(gconstpointer a, gconstpointer b)
{ {
@ -1189,48 +1075,6 @@ p_rem_proto_data(frame_data *fd, int proto)
} }
void
proto_register_frame(void)
{
static hf_register_info hf[] = {
{ &hf_frame_arrival_time,
{ "Arrival Time", "frame.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
""}},
{ &hf_frame_time_delta,
{ "Time delta from previous packet", "frame.time_delta", FT_RELATIVE_TIME, BASE_NONE, NULL,
0x0,
"" }},
{ &hf_frame_number,
{ "Frame Number", "frame.number", FT_UINT32, BASE_DEC, NULL, 0x0,
"" }},
{ &hf_frame_packet_len,
{ "Total Frame Length", "frame.pkt_len", FT_UINT32, BASE_DEC, NULL, 0x0,
"" }},
{ &hf_frame_capture_len,
{ "Capture Frame Length", "frame.cap_len", FT_UINT32, BASE_DEC, NULL, 0x0,
"" }},
{ &hf_frame_p2p_dir,
{ "Point-to-Point Direction", "frame.p2p_dir", FT_UINT8, BASE_DEC, VALS(p2p_dirs), 0x0,
"" }},
};
static gint *ett[] = {
&ett_frame,
};
proto_frame = proto_register_protocol("Frame", "frame");
proto_register_field_array(proto_frame, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
proto_short = proto_register_protocol("Short Frame", "short");
proto_malformed = proto_register_protocol("Malformed Frame", "malformed");
register_init_routine(&packet_init_protocol);
}
/*********************** code added for sub-dissector lookup *********************/ /*********************** code added for sub-dissector lookup *********************/

View File

@ -1,7 +1,7 @@
/* packet.h /* packet.h
* Definitions for packet disassembly structures and routines * Definitions for packet disassembly structures and routines
* *
* $Id: packet.h,v 1.1 2000/09/27 05:18:06 gram Exp $ * $Id: packet.h,v 1.2 2000/10/06 10:11:17 gram Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org> * By Gerald Combs <gerald@zing.org>
@ -190,6 +190,9 @@ typedef struct true_false_string {
char *false_string; char *false_string;
} true_false_string; } true_false_string;
void packet_init(void);
void packet_cleanup(void);
/* Hash table for matching port numbers and dissectors */ /* Hash table for matching port numbers and dissectors */
typedef GHashTable* dissector_table_t; typedef GHashTable* dissector_table_t;
@ -305,12 +308,10 @@ void init_all_protocols(void);
void init_dissect_rpc(void); void init_dissect_rpc(void);
/* /*
* Routines should take four args: packet data *, offset, frame_data *, * Dissectors should never modify the packet data.
* tree *
* They should never modify the packet data.
*/ */
void dissect_packet(union wtap_pseudo_header *, const u_char *, frame_data *, void dissect_packet(tvbuff_t **p_tvb, union wtap_pseudo_header *pseudo_header,
proto_tree *); const u_char *pd, frame_data *fd, proto_tree *tree);
void old_dissect_data(const u_char *, int, frame_data *, proto_tree *); void old_dissect_data(const u_char *, int, frame_data *, proto_tree *);
void dissect_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); void dissect_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);

24
file.c
View File

@ -1,7 +1,7 @@
/* file.c /* file.c
* File I/O routines * File I/O routines
* *
* $Id: file.c,v 1.223 2000/09/27 04:54:28 gram Exp $ * $Id: file.c,v 1.224 2000/10/06 10:10:46 gram Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org> * By Gerald Combs <gerald@zing.org>
@ -604,6 +604,7 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
apply_color_filter_args args; apply_color_filter_args args;
gint i, row; gint i, row;
proto_tree *protocol_tree = NULL; proto_tree *protocol_tree = NULL;
epan_dissect_t *edt;
/* We don't yet have a color filter to apply. */ /* We don't yet have a color filter to apply. */
args.colorf = NULL; args.colorf = NULL;
@ -640,7 +641,7 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
protocol_tree = proto_tree_create_root(); protocol_tree = proto_tree_create_root();
/* Dissect the frame. */ /* Dissect the frame. */
dissect_packet(pseudo_header, buf, fdata, protocol_tree); edt = epan_dissect_new(pseudo_header, buf, fdata, protocol_tree);
/* If we have a display filter, apply it if we're refiltering, otherwise /* If we have a display filter, apply it if we're refiltering, otherwise
leave the "passed_dfilter" flag alone. leave the "passed_dfilter" flag alone.
@ -672,6 +673,8 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
if (protocol_tree != NULL) if (protocol_tree != NULL)
proto_tree_free(protocol_tree); proto_tree_free(protocol_tree);
epan_dissect_free(edt);
if (fdata->flags.passed_dfilter) { if (fdata->flags.passed_dfilter) {
/* This frame passed the display filter, so add it to the clist. */ /* This frame passed the display filter, so add it to the clist. */
@ -759,6 +762,7 @@ read_packet(capture_file *cf, int offset)
int passed; int passed;
proto_tree *protocol_tree; proto_tree *protocol_tree;
frame_data *plist_end; frame_data *plist_end;
epan_dissect_t *edt;
/* Allocate the next list entry, and add it to the list. */ /* Allocate the next list entry, and add it to the list. */
fdata = g_mem_chunk_alloc(cf->plist_chunk); fdata = g_mem_chunk_alloc(cf->plist_chunk);
@ -780,9 +784,10 @@ read_packet(capture_file *cf, int offset)
passed = TRUE; passed = TRUE;
if (cf->rfcode) { if (cf->rfcode) {
protocol_tree = proto_tree_create_root(); protocol_tree = proto_tree_create_root();
dissect_packet(pseudo_header, buf, fdata, protocol_tree); edt = epan_dissect_new(pseudo_header, buf, fdata, protocol_tree);
passed = dfilter_apply(cf->rfcode, protocol_tree, buf, fdata->cap_len); passed = dfilter_apply(cf->rfcode, protocol_tree, buf, fdata->cap_len);
proto_tree_free(protocol_tree); proto_tree_free(protocol_tree);
epan_dissect_free(edt);
} }
if (passed) { if (passed) {
plist_end = cf->plist_end; plist_end = cf->plist_end;
@ -1052,6 +1057,7 @@ print_packets(capture_file *cf, print_args_t *print_args)
char *cp; char *cp;
int column_len; int column_len;
int line_len; int line_len;
epan_dissect_t *edt = NULL;
cf->print_fh = open_print_dest(print_args->to_file, print_args->dest); cf->print_fh = open_print_dest(print_args->to_file, print_args->dest);
if (cf->print_fh == NULL) if (cf->print_fh == NULL)
@ -1167,7 +1173,7 @@ print_packets(capture_file *cf, print_args_t *print_args)
for (i = 0; i < fdata->cinfo->num_cols; i++) { for (i = 0; i < fdata->cinfo->num_cols; i++) {
fdata->cinfo->col_data[i][0] = '\0'; fdata->cinfo->col_data[i][0] = '\0';
} }
dissect_packet(&cf->pseudo_header, cf->pd, fdata, NULL); edt = epan_dissect_new(&cf->pseudo_header, cf->pd, fdata, NULL);
fill_in_columns(fdata); fill_in_columns(fdata);
cp = &line_buf[0]; cp = &line_buf[0];
line_len = 0; line_len = 0;
@ -1204,7 +1210,7 @@ print_packets(capture_file *cf, print_args_t *print_args)
/* Create the logical protocol tree. */ /* Create the logical protocol tree. */
protocol_tree = proto_tree_create_root(); protocol_tree = proto_tree_create_root();
dissect_packet(&cf->pseudo_header, cf->pd, fdata, protocol_tree); edt = epan_dissect_new(&cf->pseudo_header, cf->pd, fdata, protocol_tree);
/* Print the information in that tree. */ /* Print the information in that tree. */
proto_tree_print(FALSE, print_args, (GNode *)protocol_tree, proto_tree_print(FALSE, print_args, (GNode *)protocol_tree,
@ -1221,6 +1227,7 @@ print_packets(capture_file *cf, print_args_t *print_args)
/* Print a blank line if we print anything after this. */ /* Print a blank line if we print anything after this. */
print_separator = TRUE; print_separator = TRUE;
} }
epan_dissect_free(edt);
} }
} }
@ -1380,6 +1387,7 @@ find_packet(capture_file *cf, dfilter *sfcode)
proto_tree *protocol_tree; proto_tree *protocol_tree;
gboolean frame_matched; gboolean frame_matched;
int row; int row;
epan_dissect_t *edt;
start_fd = cf->current_frame; start_fd = cf->current_frame;
if (start_fd != NULL) { if (start_fd != NULL) {
@ -1444,9 +1452,10 @@ find_packet(capture_file *cf, dfilter *sfcode)
protocol_tree = proto_tree_create_root(); protocol_tree = proto_tree_create_root();
wtap_seek_read(cf->wth, fdata->file_off, &cf->pseudo_header, wtap_seek_read(cf->wth, fdata->file_off, &cf->pseudo_header,
cf->pd, fdata->cap_len); cf->pd, fdata->cap_len);
dissect_packet(&cf->pseudo_header, cf->pd, fdata, protocol_tree); edt = epan_dissect_new(&cf->pseudo_header, cf->pd, fdata, protocol_tree);
frame_matched = dfilter_apply(sfcode, protocol_tree, cf->pd, fdata->cap_len); frame_matched = dfilter_apply(sfcode, protocol_tree, cf->pd, fdata->cap_len);
proto_tree_free(protocol_tree); proto_tree_free(protocol_tree);
epan_dissect_free(edt);
if (frame_matched) { if (frame_matched) {
new_fd = fdata; new_fd = fdata;
break; /* found it! */ break; /* found it! */
@ -1552,7 +1561,7 @@ select_packet(capture_file *cf, int row)
proto_tree_free(cf->protocol_tree); proto_tree_free(cf->protocol_tree);
cf->protocol_tree = proto_tree_create_root(); cf->protocol_tree = proto_tree_create_root();
proto_tree_is_visible = TRUE; proto_tree_is_visible = TRUE;
dissect_packet(&cf->pseudo_header, cf->pd, cf->current_frame, cf->edt = epan_dissect_new(&cf->pseudo_header, cf->pd, cf->current_frame,
cf->protocol_tree); cf->protocol_tree);
proto_tree_is_visible = FALSE; proto_tree_is_visible = FALSE;
@ -1573,6 +1582,7 @@ unselect_packet(capture_file *cf)
if (cf->protocol_tree != NULL) { if (cf->protocol_tree != NULL) {
proto_tree_free(cf->protocol_tree); proto_tree_free(cf->protocol_tree);
cf->protocol_tree = NULL; cf->protocol_tree = NULL;
epan_dissect_free(cf->edt);
} }
finfo_selected = NULL; finfo_selected = NULL;

5
file.h
View File

@ -1,7 +1,7 @@
/* file.h /* file.h
* Definitions for file structures and routines * Definitions for file structures and routines
* *
* $Id: file.h,v 1.76 2000/08/21 15:45:21 deniel Exp $ * $Id: file.h,v 1.77 2000/10/06 10:10:48 gram Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org> * By Gerald Combs <gerald@zing.org>
@ -42,6 +42,8 @@
#include <errno.h> #include <errno.h>
#include <epan.h>
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
#include "zlib.h" #include "zlib.h"
#define FILE_T gzFile #define FILE_T gzFile
@ -106,6 +108,7 @@ typedef struct _capture_file {
column_info cinfo; /* Column formatting information */ column_info cinfo; /* Column formatting information */
frame_data *current_frame; /* Frame data for current frame */ frame_data *current_frame; /* Frame data for current frame */
proto_tree *protocol_tree; /* Protocol tree for currently selected packet */ proto_tree *protocol_tree; /* Protocol tree for currently selected packet */
epan_dissect_t *edt; /* Protocol dissection fo rcurrently selected packet */
FILE *print_fh; /* File we're printing to */ FILE *print_fh; /* File we're printing to */
} capture_file; } capture_file;

View File

@ -3,7 +3,7 @@
* *
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com> * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
* *
* $Id: packet_win.c,v 1.15 2000/09/09 10:26:56 guy Exp $ * $Id: packet_win.c,v 1.16 2000/10/06 10:11:40 gram Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org> * By Gerald Combs <gerald@zing.org>
@ -46,6 +46,7 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <epan.h>
#include "main.h" #include "main.h"
#include "timestamp.h" #include "timestamp.h"
#include "packet.h" #include "packet.h"
@ -80,6 +81,7 @@ struct PacketWinData {
GtkWidget *bv_scrollw; GtkWidget *bv_scrollw;
GtkWidget *byte_view; GtkWidget *byte_view;
field_info *finfo_selected; field_info *finfo_selected;
epan_dissect_t *edt;
}; };
/* List of all the packet-detail windows popped up. */ /* List of all the packet-detail windows popped up. */
@ -171,7 +173,7 @@ create_new_window ( char *Title, gint tv_size, gint bv_size){
memcpy(DataPtr->pd, cfile.pd, DataPtr->frame->cap_len); memcpy(DataPtr->pd, cfile.pd, DataPtr->frame->cap_len);
DataPtr->protocol_tree = proto_tree_create_root(); DataPtr->protocol_tree = proto_tree_create_root();
proto_tree_is_visible = TRUE; proto_tree_is_visible = TRUE;
dissect_packet(&DataPtr->pseudo_header, DataPtr->pd, DataPtr->frame, DataPtr->edt = epan_dissect_new(&DataPtr->pseudo_header, DataPtr->pd, DataPtr->frame,
DataPtr->protocol_tree); DataPtr->protocol_tree);
proto_tree_is_visible = FALSE; proto_tree_is_visible = FALSE;
DataPtr->main = main_w; DataPtr->main = main_w;
@ -206,6 +208,7 @@ destroy_new_window(GtkObject *object, gpointer user_data)
detail_windows = g_list_remove(detail_windows, DataPtr); detail_windows = g_list_remove(detail_windows, DataPtr);
proto_tree_free(DataPtr->protocol_tree); proto_tree_free(DataPtr->protocol_tree);
epan_dissect_free(DataPtr->edt);
g_free(DataPtr->pd); g_free(DataPtr->pd);
g_free(DataPtr); g_free(DataPtr);
} }

233
packet-frame.c Normal file
View File

@ -0,0 +1,233 @@
/* packet-frame.c
*
* Top-most dissector. Decides dissector based on Wiretap Encapsulation Type.
*
* $Id: packet-frame.c,v 1.1 2000/10/06 10:10:49 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 2000 Gerald Combs
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <glib.h>
#include "packet.h"
#include "timestamp.h"
#include "tvbuff.h"
#include "packet-frame.h"
#include "packet-ascend.h"
#include "packet-atalk.h"
#include "packet-atm.h"
#include "packet-clip.h"
#include "packet-eth.h"
#include "packet-fddi.h"
#include "packet-ipv6.h"
#include "packet-lapb.h"
#include "packet-lapd.h"
#include "packet-llc.h"
#include "packet-null.h"
#include "packet-ppp.h"
#include "packet-raw.h"
#include "packet-sna.h"
#include "packet-tr.h"
#include "packet-v120.h"
#include "packet-vines.h"
static int proto_frame = -1;
static int hf_frame_arrival_time = -1;
static int hf_frame_time_delta = -1;
static int hf_frame_number = -1;
static int hf_frame_packet_len = -1;
static int hf_frame_capture_len = -1;
static int hf_frame_p2p_dir = -1;
static int proto_short = -1;
int proto_malformed = -1;
static gint ett_frame = -1;
static const value_string p2p_dirs[] = {
{ P2P_DIR_SENT, "Sent" },
{ P2P_DIR_RECV, "Received" },
{ 0, NULL }
};
void
dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *fh_tree;
proto_item *ti;
struct timeval tv;
int cap_len, pkt_len;
pinfo->current_proto = "Frame";
if (pinfo->fd->lnk_t == WTAP_ENCAP_LAPD ||
pinfo->fd->lnk_t == WTAP_ENCAP_PPP_WITH_PHDR) {
pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ? P2P_DIR_SENT : P2P_DIR_RECV;
}
/* Put in frame header information. */
if (tree) {
cap_len = tvb_length(tvb);
pkt_len = tvb_reported_length(tvb);
ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, tvb_length(tvb),
"Frame %u (%u on wire, %u captured)", pinfo->fd->num, pkt_len, cap_len);
fh_tree = proto_item_add_subtree(ti, ett_frame);
tv.tv_sec = pinfo->fd->abs_secs;
tv.tv_usec = pinfo->fd->abs_usecs;
proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb,
0, 0, &tv);
tv.tv_sec = pinfo->fd->del_secs;
tv.tv_usec = pinfo->fd->del_usecs;
proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb,
0, 0, &tv);
proto_tree_add_uint(fh_tree, hf_frame_number, tvb,
0, 0, pinfo->fd->num);
proto_tree_add_uint_format(fh_tree, hf_frame_packet_len, tvb,
0, 0, pkt_len, "Packet Length: %d byte%s", pkt_len,
plurality(pkt_len, "", "s"));
proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb,
0, 0, cap_len, "Capture Length: %d byte%s", cap_len,
plurality(cap_len, "", "s"));
/* Check for existences of P2P pseudo header */
if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) {
proto_tree_add_uint(fh_tree, hf_frame_p2p_dir, tvb,
0, 0, pinfo->p2p_dir);
}
}
TRY {
switch (pinfo->fd->lnk_t) {
case WTAP_ENCAP_ETHERNET :
dissect_eth(tvb, pinfo, tree);
break;
case WTAP_ENCAP_FDDI :
dissect_fddi(tvb, pinfo, tree, FALSE);
break;
case WTAP_ENCAP_FDDI_BITSWAPPED :
dissect_fddi(tvb, pinfo, tree, TRUE);
break;
case WTAP_ENCAP_TOKEN_RING :
dissect_tr(tvb, pinfo, tree);
break;
case WTAP_ENCAP_NULL :
dissect_null(tvb, pinfo, tree);
break;
case WTAP_ENCAP_PPP :
case WTAP_ENCAP_PPP_WITH_PHDR :
dissect_ppp(tvb, pinfo, tree);
break;
case WTAP_ENCAP_LAPB :
dissect_lapb(tvb, pinfo, tree);
break;
case WTAP_ENCAP_RAW_IP :
dissect_raw(tvb, pinfo, tree);
break;
case WTAP_ENCAP_LINUX_ATM_CLIP :
dissect_clip(tvb, pinfo, tree);
break;
case WTAP_ENCAP_ATM_SNIFFER :
dissect_atm(tvb, pinfo, tree);
break;
case WTAP_ENCAP_ASCEND :
dissect_ascend(tvb, pinfo, tree);
break;
case WTAP_ENCAP_LAPD :
dissect_lapd(tvb, pinfo, tree);
break;
case WTAP_ENCAP_V120 :
dissect_v120(tvb, pinfo, tree);
break;
case WTAP_ENCAP_ATM_RFC1483:
dissect_llc(tvb, pinfo, tree);
break;
default:
g_assert_not_reached();
break;
}
}
CATCH(BoundsError) {
proto_tree_add_protocol_format(tree, proto_short, tvb, 0, 0,
"[Short Frame: %s]", pinfo->current_proto );
}
CATCH(ReportedBoundsError) {
proto_tree_add_protocol_format(tree, proto_malformed, tvb, 0, 0,
"[Malformed Frame: %s]", pinfo->current_proto );
}
ENDTRY;
}
void
proto_register_frame(void)
{
static hf_register_info hf[] = {
{ &hf_frame_arrival_time,
{ "Arrival Time", "frame.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
""}},
{ &hf_frame_time_delta,
{ "Time delta from previous packet", "frame.time_delta", FT_RELATIVE_TIME, BASE_NONE, NULL,
0x0,
"" }},
{ &hf_frame_number,
{ "Frame Number", "frame.number", FT_UINT32, BASE_DEC, NULL, 0x0,
"" }},
{ &hf_frame_packet_len,
{ "Total Frame Length", "frame.pkt_len", FT_UINT32, BASE_DEC, NULL, 0x0,
"" }},
{ &hf_frame_capture_len,
{ "Capture Frame Length", "frame.cap_len", FT_UINT32, BASE_DEC, NULL, 0x0,
"" }},
{ &hf_frame_p2p_dir,
{ "Point-to-Point Direction", "frame.p2p_dir", FT_UINT8, BASE_DEC, VALS(p2p_dirs), 0x0,
"" }},
};
static gint *ett[] = {
&ett_frame,
};
proto_frame = proto_register_protocol("Frame", "frame");
proto_register_field_array(proto_frame, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
proto_short = proto_register_protocol("Short Frame", "short");
proto_malformed = proto_register_protocol("Malformed Frame", "malformed");
}

28
packet-frame.h Normal file
View File

@ -0,0 +1,28 @@
/* packet-frame.h
*
* Top-most dissector. Decides dissector based on Wiretap Encapsulation Type.
*
* $Id: packet-frame.h,v 1.1 2000/10/06 10:10:49 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 2000 Gerald Combs
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
void
dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);

View File

@ -1,6 +1,6 @@
/* tethereal.c /* tethereal.c
* *
* $Id: tethereal.c,v 1.48 2000/09/27 04:54:33 gram Exp $ * $Id: tethereal.c,v 1.49 2000/10/06 10:10:50 gram Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org> * By Gerald Combs <gerald@zing.org>
@ -883,16 +883,18 @@ wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr, int offset,
proto_tree *protocol_tree; proto_tree *protocol_tree;
int err; int err;
gboolean passed; gboolean passed;
epan_dissect_t *edt;
cf->count++; cf->count++;
if (cf->rfcode) { if (cf->rfcode) {
fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset); fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
protocol_tree = proto_tree_create_root(); protocol_tree = proto_tree_create_root();
dissect_packet(pseudo_header, buf, &fdata, protocol_tree); edt = epan_dissect_new(pseudo_header, buf, &fdata, protocol_tree);
passed = dfilter_apply(cf->rfcode, protocol_tree, buf, fdata.cap_len); passed = dfilter_apply(cf->rfcode, protocol_tree, buf, fdata.cap_len);
} else { } else {
protocol_tree = NULL; protocol_tree = NULL;
passed = TRUE; passed = TRUE;
edt = NULL;
} }
if (passed) { if (passed) {
/* XXX - do something if this fails */ /* XXX - do something if this fails */
@ -900,6 +902,8 @@ wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr, int offset,
} }
if (protocol_tree != NULL) if (protocol_tree != NULL)
proto_tree_free(protocol_tree); proto_tree_free(protocol_tree);
if (edt != NULL)
epan_dissect_free(edt);
} }
static void static void
@ -912,6 +916,7 @@ wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr, int offset,
proto_tree *protocol_tree; proto_tree *protocol_tree;
gboolean passed; gboolean passed;
print_args_t print_args; print_args_t print_args;
epan_dissect_t *edt;
cf->count++; cf->count++;
@ -926,7 +931,7 @@ wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr, int offset,
protocol_tree = proto_tree_create_root(); protocol_tree = proto_tree_create_root();
else else
protocol_tree = NULL; protocol_tree = NULL;
dissect_packet(pseudo_header, buf, &fdata, protocol_tree); edt = epan_dissect_new(pseudo_header, buf, &fdata, protocol_tree);
if (cf->rfcode) if (cf->rfcode)
passed = dfilter_apply(cf->rfcode, protocol_tree, buf, fdata.cap_len); passed = dfilter_apply(cf->rfcode, protocol_tree, buf, fdata.cap_len);
if (passed) { if (passed) {
@ -975,6 +980,8 @@ wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr, int offset,
if (protocol_tree != NULL) if (protocol_tree != NULL)
proto_tree_free(protocol_tree); proto_tree_free(protocol_tree);
epan_dissect_free(edt);
proto_tree_is_visible = FALSE; proto_tree_is_visible = FALSE;
} }