diff options
author | Gilbert Ramirez <gram@alumni.rice.edu> | 2000-10-06 10:11:40 +0000 |
---|---|---|
committer | Gilbert Ramirez <gram@alumni.rice.edu> | 2000-10-06 10:11:40 +0000 |
commit | e69b5278aaddce2af02174afe0515adceb841973 (patch) | |
tree | 8cb476c958c815d3d73d4ac79ffeb15df28484d8 /packet-frame.c | |
parent | e735d485aee9d56723dea97fae3064cf4bdd7e9a (diff) | |
download | wireshark-e69b5278aaddce2af02174afe0515adceb841973.tar.gz |
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
Diffstat (limited to 'packet-frame.c')
-rw-r--r-- | packet-frame.c | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/packet-frame.c b/packet-frame.c new file mode 100644 index 0000000000..01456f429c --- /dev/null +++ b/packet-frame.c @@ -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"); + +} |