/* packet-lapd.c
* Routines for LAPD frame disassembly
- * Gilbert Ramirez <gram@xiexie.org>
+ * Gilbert Ramirez <gram@alumni.rice.edu>
*
- * $Id: packet-lapd.c,v 1.14 2000/09/21 04:41:07 gram Exp $
+ * $Id: packet-lapd.c,v 1.29 2002/02/22 08:54:54 guy Exp $
*
* Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
* Copyright 1998
- *
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
#include <stdio.h>
#include <glib.h>
#include <string.h>
-#include "packet.h"
-#include "packet-lapd.h"
-#include "packet-q931.h"
+#include <epan/packet.h>
#include "xdlc.h"
/* ISDN/LAPD references:
static gint ett_lapd_address = -1;
static gint ett_lapd_control = -1;
+static dissector_handle_t q931_handle;
+static dissector_handle_t data_handle;
+
/*
* Bits in the address field.
*/
{ 0, NULL }
};
-void
+static void
dissect_lapd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *lapd_tree, *addr_tree;
- proto_item *ti;
+ proto_item *lapd_ti, *addr_ti;
guint16 control;
int lapd_header_len;
guint16 address, cr, sapi;
gboolean is_response;
tvbuff_t *next_tvb;
- CHECK_DISPLAY_AS_DATA(proto_lapd, tvb, pinfo, tree);
-
- pinfo->current_proto = "LAPD";
-
- if (check_col(pinfo->fd, COL_PROTOCOL))
- col_add_str(pinfo->fd, COL_PROTOCOL, "LAPD");
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LAPD");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
address = tvb_get_ntohs(tvb, 0);
cr = address & LAPD_CR;
if (pinfo->pseudo_header->p2p.sent) {
is_response = cr ? TRUE : FALSE;
- if(check_col(pinfo->fd, COL_RES_DL_DST))
- col_add_str(pinfo->fd, COL_RES_DL_DST, "Network");
- if(check_col(pinfo->fd, COL_RES_DL_SRC))
- col_add_str(pinfo->fd, COL_RES_DL_SRC, "User");
+ if(check_col(pinfo->cinfo, COL_RES_DL_DST))
+ col_set_str(pinfo->cinfo, COL_RES_DL_DST, "Network");
+ if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
+ col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "User");
}
else {
is_response = cr ? FALSE : TRUE;
- if(check_col(pinfo->fd, COL_RES_DL_DST))
- col_add_str(pinfo->fd, COL_RES_DL_DST, "User");
- if(check_col(pinfo->fd, COL_RES_DL_SRC))
- col_add_str(pinfo->fd, COL_RES_DL_SRC, "Network");
+ if(check_col(pinfo->cinfo, COL_RES_DL_DST))
+ col_set_str(pinfo->cinfo, COL_RES_DL_DST, "User");
+ if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
+ col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "Network");
}
-
if (tree) {
- ti = proto_tree_add_item(tree, proto_lapd, tvb, 0, 3, FALSE);
- lapd_tree = proto_item_add_subtree(ti, ett_lapd);
+ lapd_ti = proto_tree_add_item(tree, proto_lapd, tvb, 0, -1,
+ FALSE);
+ lapd_tree = proto_item_add_subtree(lapd_ti, ett_lapd);
- ti = proto_tree_add_uint(lapd_tree, hf_lapd_address, tvb, 0, 2, address);
- addr_tree = proto_item_add_subtree(ti, ett_lapd_address);
+ addr_ti = proto_tree_add_uint(lapd_tree, hf_lapd_address, tvb,
+ 0, 2, address);
+ addr_tree = proto_item_add_subtree(addr_ti, ett_lapd_address);
proto_tree_add_uint(addr_tree, hf_lapd_sapi,tvb, 0, 1, address);
proto_tree_add_uint(addr_tree, hf_lapd_cr, tvb, 0, 1, address);
proto_tree_add_uint(addr_tree, hf_lapd_ea2, tvb, 1, 1, address);
}
else {
+ lapd_ti = NULL;
lapd_tree = NULL;
}
ett_lapd_control, is_response, TRUE);
lapd_header_len += XDLC_CONTROL_LEN(control, TRUE);
+ if (tree)
+ proto_item_set_len(lapd_ti, lapd_header_len);
+
next_tvb = tvb_new_subset(tvb, lapd_header_len, -1, -1);
if (XDLC_IS_INFORMATION(control)) {
/* call next protocol */
switch (sapi) {
case LAPD_SAPI_Q931:
- dissect_q931(next_tvb, pinfo, tree);
+ call_dissector(q931_handle, next_tvb, pinfo, tree);
break;
default:
- dissect_data(next_tvb, pinfo, tree);
+ call_dissector(data_handle,next_tvb, pinfo, tree);
break;
}
} else
- dissect_data(next_tvb, pinfo, tree);
+ call_dissector(data_handle,next_tvb, pinfo, tree);
}
void
static hf_register_info hf[] = {
{ &hf_lapd_address,
{ "Address Field", "lapd.address", FT_UINT16, BASE_HEX, NULL, 0x0,
- "" }},
+ "Address", HFILL }},
{ &hf_lapd_sapi,
{ "SAPI", "lapd.sapi", FT_UINT16, BASE_DEC, VALS(lapd_sapi_vals), LAPD_SAPI,
- "Service Access Point Identifier" }},
+ "Service Access Point Identifier", HFILL }},
{ &hf_lapd_cr,
{ "C/R", "lapd.cr", FT_UINT16, BASE_DEC, NULL, LAPD_CR,
- "Command/Response bit" }},
+ "Command/Response bit", HFILL }},
{ &hf_lapd_ea1,
{ "EA1", "lapd.ea1", FT_UINT16, BASE_DEC, NULL, LAPD_EA1,
- "First Address Extension bit" }},
+ "First Address Extension bit", HFILL }},
{ &hf_lapd_tei,
{ "TEI", "lapd.tei", FT_UINT16, BASE_DEC, NULL, LAPD_TEI,
- "Terminal Endpoint Identifier" }},
+ "Terminal Endpoint Identifier", HFILL }},
{ &hf_lapd_ea2,
{ "EA2", "lapd.ea2", FT_UINT16, BASE_DEC, NULL, LAPD_EA2,
- "Second Address Extension bit" }},
+ "Second Address Extension bit", HFILL }},
{ &hf_lapd_control,
{ "Control Field", "lapd.control", FT_UINT16, BASE_HEX, NULL, 0x0,
- "" }},
+ "Control field", HFILL }},
};
static gint *ett[] = {
&ett_lapd,
&ett_lapd_control,
};
- proto_lapd = proto_register_protocol ("Link Access Procedure, Channel D (LAPD)", "lapd");
+ proto_lapd = proto_register_protocol("Link Access Procedure, Channel D (LAPD)",
+ "LAPD", "lapd");
proto_register_field_array (proto_lapd, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
+
+void
+proto_reg_handoff_lapd(void)
+{
+ dissector_handle_t lapd_handle;
+
+ /*
+ * Get handle for the Q.931 dissector.
+ */
+ q931_handle = find_dissector("q931");
+ data_handle = find_dissector("data");
+
+ lapd_handle = create_dissector_handle(dissect_lapd, proto_lapd);
+ dissector_add("wtap_encap", WTAP_ENCAP_LAPD, lapd_handle);
+}