/* packet-sll.c
* Routines for disassembly of packets from Linux "cooked mode" captures
*
- * $Id: packet-sll.c,v 1.2 2001/01/03 06:55:32 guy Exp $
+ * $Id: packet-sll.c,v 1.18 2002/08/02 23:36:01 jmayer Exp $
*
* Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
- *
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
# include "config.h"
#endif
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
#include <stdio.h>
#include <string.h>
#include <glib.h>
-#include "packet.h"
+#include <epan/packet.h>
+#include "packet-sll.h"
#include "packet-ipx.h"
#include "packet-llc.h"
-#include "resolv.h"
+#include <epan/resolv.h>
+#include "etypes.h"
static int proto_sll = -1;
static int hf_sll_pkttype = -1;
{ 0, NULL }
};
+static dissector_handle_t ipx_handle;
+static dissector_handle_t llc_handle;
+static dissector_handle_t data_handle;
+
void
-capture_sll(const u_char *pd, packet_counts *ld)
+capture_sll(const guchar *pd, int len, packet_counts *ld)
{
guint16 protocol;
- if (!BYTES_ARE_IN_FRAME(0, SLL_HEADER_SIZE)) {
+ if (!BYTES_ARE_IN_FRAME(0, len, SLL_HEADER_SIZE)) {
ld->other++;
return;
}
/*
* 802.2 LLC.
*/
- capture_llc(pd, SLL_HEADER_SIZE, ld);
+ capture_llc(pd, len, SLL_HEADER_SIZE, ld);
break;
case LINUX_SLL_P_802_3:
* Novell IPX inside 802.3 with no 802.2 LLC
* header.
*/
- capture_ipx(pd, SLL_HEADER_SIZE, ld);
+ capture_ipx(ld);
break;
default:
break;
}
} else
- capture_ethertype(protocol, SLL_HEADER_SIZE, pd, ld);
+ capture_ethertype(protocol, pd, SLL_HEADER_SIZE, len, ld);
}
static void
guint16 pkttype;
guint16 protocol;
guint16 hatype, halen;
- guint8 *src;
+ const guint8 *src;
proto_item *ti;
- volatile guint16 length;
- tvbuff_t *volatile next_tvb;
- tvbuff_t *volatile trailer_tvb;
- proto_tree *volatile fh_tree = NULL;
- guint length_before;
-
- CHECK_DISPLAY_AS_DATA(proto_sll, tvb, pinfo, tree);
+ tvbuff_t *next_tvb;
+ proto_tree *fh_tree = NULL;
- pinfo->current_proto = "SLL";
- if (check_col(pinfo->fd, COL_PROTOCOL))
- col_set_str(pinfo->fd, COL_PROTOCOL, "SLL");
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "SLL");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
pkttype = tvb_get_ntohs(tvb, 0);
- if (check_col(pinfo->fd, COL_INFO))
- col_add_str(pinfo->fd, COL_INFO,
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_str(pinfo->cinfo, COL_INFO,
val_to_str(pkttype, packet_type_vals, "Unknown (%u)"));
if (tree) {
}
} else {
if (tree) {
- proto_tree_add_bytes(fh_tree, hf_sll_src_other, tvb,
- 6, halen, tvb_get_ptr(tvb, 6, halen));
+ proto_tree_add_item(fh_tree, hf_sll_src_other, tvb,
+ 6, halen, FALSE);
}
}
protocol);
next_tvb = tvb_new_subset(tvb, SLL_HEADER_SIZE, -1, -1);
- trailer_tvb = NULL;
switch (protocol) {
case LINUX_SLL_P_802_2:
/*
* 802.2 LLC.
*/
- dissect_llc(next_tvb, pinfo, tree);
+ call_dissector(llc_handle, next_tvb, pinfo, tree);
break;
case LINUX_SLL_P_802_3:
* Novell IPX inside 802.3 with no 802.2 LLC
* header.
*/
- dissect_ipx(next_tvb, pinfo, tree);
+ call_dissector(ipx_handle, next_tvb, pinfo, tree);
break;
default:
- dissect_data(next_tvb, 0, pinfo, tree);
+ call_dissector(data_handle,next_tvb, pinfo, tree);
break;
}
} else {
- length_before = tvb_reported_length(tvb);
- length = ethertype(protocol, tvb, SLL_HEADER_SIZE, pinfo, tree,
- fh_tree, hf_sll_etype) + SLL_HEADER_SIZE;
- if (length < length_before) {
- /*
- * Create a tvbuff for the padding.
- */
- TRY {
- trailer_tvb = tvb_new_subset(tvb, length, -1,
- -1);
- }
- CATCH2(BoundsError, ReportedBoundsError) {
- /* The packet doesn't have "length" bytes
- worth of captured data left in it. No
- trailer to display. */
- trailer_tvb = NULL;
- }
- ENDTRY;
- } else {
- /*
- * There is no padding.
- */
- trailer_tvb = NULL;
- }
- }
-
- /* If there's some bytes left over, mark them. */
- if (trailer_tvb && tree) {
- guint trailer_length;
-
- trailer_length = tvb_length(trailer_tvb);
- if (trailer_length != 0) {
- proto_tree_add_item(fh_tree, hf_sll_trailer,
- trailer_tvb, 0, trailer_length, FALSE);
- }
+ ethertype(protocol, tvb, SLL_HEADER_SIZE, pinfo, tree,
+ fh_tree, hf_sll_etype, hf_sll_trailer);
}
}
static hf_register_info hf[] = {
{ &hf_sll_pkttype,
{ "Packet type", "sll.pkttype", FT_UINT16, BASE_DEC,
- VALS(packet_type_vals), 0x0, "Packet type" }},
+ VALS(packet_type_vals), 0x0, "Packet type", HFILL }},
/* ARP hardware type? With Linux extensions? */
{ &hf_sll_hatype,
{ "Link-layer address type", "sll.hatype", FT_UINT16, BASE_DEC,
- NULL, 0x0, "Link-layer address type" }},
+ NULL, 0x0, "Link-layer address type", HFILL }},
{ &hf_sll_halen,
{ "Link-layer address length", "sll.halen", FT_UINT16, BASE_DEC,
- NULL, 0x0, "Link-layer address length" }},
+ NULL, 0x0, "Link-layer address length", HFILL }},
/* Source address if it's an Ethernet-type address */
{ &hf_sll_src_eth,
{ "Source", "sll.src.eth", FT_ETHER, BASE_NONE, NULL, 0x0,
- "Source link-layer address" }},
+ "Source link-layer address", HFILL }},
/* Source address if it's not an Ethernet-type address */
{ &hf_sll_src_other,
{ "Source", "sll.src.other", FT_BYTES, BASE_HEX, NULL, 0x0,
- "Source link-layer address" }},
+ "Source link-layer address", HFILL }},
/* if the protocol field is an internal Linux protocol type */
{ &hf_sll_ltype,
{ "Protocol", "sll.ltype", FT_UINT16, BASE_HEX,
- VALS(ltype_vals), 0x0, "Linux protocol type" }},
+ VALS(ltype_vals), 0x0, "Linux protocol type", HFILL }},
/* registered here but handled in ethertype.c */
{ &hf_sll_etype,
{ "Protocol", "sll.etype", FT_UINT16, BASE_HEX,
- VALS(etype_vals), 0x0, "Ethernet protocol type" }},
+ VALS(etype_vals), 0x0, "Ethernet protocol type", HFILL }},
{ &hf_sll_trailer,
{ "Trailer", "sll.trailer", FT_BYTES, BASE_NONE, NULL, 0x0,
- "Trailer" }},
+ "Trailer", HFILL }},
};
static gint *ett[] = {
&ett_sll,
void
proto_reg_handoff_sll(void)
{
- dissector_add("wtap_encap", WTAP_ENCAP_SLL, dissect_sll);
+ dissector_handle_t sll_handle;
+
+ /*
+ * Get handles for the IPX and LLC dissectors.
+ */
+ llc_handle = find_dissector("llc");
+ ipx_handle = find_dissector("ipx");
+ data_handle = find_dissector("data");
+
+ sll_handle = create_dissector_handle(dissect_sll, proto_sll);
+ dissector_add("wtap_encap", WTAP_ENCAP_SLL, sll_handle);
}