Ethereal-users: [Ethereal-users] ethereal 0.10.12 + synclink / lapd / isis

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: clay wispell <clay.wispell@xxxxxxxxxxxxxx>
Date: Tue, 13 Sep 2005 10:55:28 -0500
hello,

i am capturing and decoding data from an agilent omniber captured from a microgate synclink card. packet-lapd.c has been modified so that the incoming data is decoded as lapd (native cisco-hdlc on layer 2) and so that any information packets are decoded based on the nlpid of the packet. clnp and esis work well (nlpid 0x81 and 0x82), however, isis (nlpid 0x83) causes a segmentation fault. it appears that the culprit is a null value returned here in packet-lapd.c

   isis_handle = find_dissector("isis");

i'm not sure where to look next. any help/pointer/rtfm are appreciated.


here is some system information and the results of a capture. the modified packet-lapd.c is attached.



10:49:43 impaler /msc/ethereal-0.10.12/epan/dissectors# ifconfig hdlc0
hdlc0     Link encap:(Cisco)-HDLC
         UP POINTOPOINT NOARP  MTU:1500  Metric:1
         RX packets:97496 errors:97496 dropped:0 overruns:0 frame:0
         TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:50
         RX bytes:2034406 (1.9 MiB)  TX bytes:0 (0.0 b)
         Interrupt:5 Base address:0xcc00



10:39:39 impaler /msc/ethereal-0.10.12/epan/dissectors# tethereal -i hdlc0

lapd_handle = 0x80f5fa0
osi_handle = (nil)
clnp_handle = 0x8098928
isis_handle = (nil)
esis_handle = 0x82410d8Warning: Couldn't obtain netmask info (hdlc0: no IPv4 address assigned).
Capturing on hdlc0

call dissector 0x80c0470. before call_dissector_work
call dissector handle 0x80c0470
call dissector after handle->protocol
call dissector inside else handle->is_new
call dissector handle 0x80f5fa0
call dissector after handle->protocol
call dissector inside else handle->is_new
esis tvb 82
esis_handle = 0x82410d8
call dissector 0x82410d8. before call_dissector_work
call dissector handle 0x82410d8
call dissector after handle->protocol
call dissector inside else handle->is_new
call dissector after not new ret =
call dissector after call_dissector_work
after 82
call dissector after not new ret =
call dissector 0x8238608. before call_dissector_work
call dissector handle 0x8238608
call dissector after handle->protocol
call dissector inside else handle->is_new
call dissector after not new ret =
call dissector after call_dissector_work
call dissector after not new ret =
call dissector after call_dissector_work 0.000000 Network -> User ESIS IS HELLO

call dissector 0x80c0470. before call_dissector_work
call dissector handle 0x80c0470
call dissector after handle->protocol
call dissector inside else handle->is_new
call dissector handle 0x80f5fa0
call dissector after handle->protocol
call dissector inside else handle->is_new
isis tvb 83

isis_handle = (nil)
call dissector (nil). before call_dissector_workSegmentation fault









/* packet-lapd.c
 * Routines for LAPD frame disassembly
 * Gilbert Ramirez <gram@xxxxxxxxxxxxxxx>
 *
 * $Id: packet-lapd.c 12127 2004-09-28 23:48:02Z guy $
 *
 * Ethereal - Network traffic analyzer
 * By Gerald Combs <gerald@xxxxxxxxxxxx>
 * Copyright 1998
 *
 * 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 <stdio.h>
#include <glib.h>
#include <string.h>
#include <epan/packet.h>
#include <epan/xdlc.h>
//hcw
#include "packet-osi.h"
#include "packet-osi-options.h"
#include "packet-isis.h"
#include "packet-esis.h"
#include "nlpid.h"
//hcwmake 
#include "lapd_sapi.h"

/* ISDN/LAPD references:
 *
 * http://www.cisco.com/univercd/cc/td/doc/cisintwk/ito_doc/isdn.htm
 * http://www.ece.wpi.edu/courses/ee535/hwk11cd95/agrebe/agrebe.html
 * http://www.acacia-net.com/Clarinet/Protocol/q9213o84.htm
 */

static int proto_lapd = -1;
static int hf_lapd_address = -1;
static int hf_lapd_sapi = -1;
static int hf_lapd_cr = -1;
static int hf_lapd_ea1 = -1;
static int hf_lapd_tei = -1;
static int hf_lapd_ea2 = -1;
static int hf_lapd_control = -1;
static int hf_lapd_n_r = -1;
static int hf_lapd_n_s = -1;
static int hf_lapd_p = -1;
static int hf_lapd_p_ext = -1;
static int hf_lapd_f = -1;
static int hf_lapd_f_ext = -1;
static int hf_lapd_s_ftype = -1;
static int hf_lapd_u_modifier_cmd = -1;
static int hf_lapd_u_modifier_resp = -1;
static int hf_lapd_ftype_i = -1;
static int hf_lapd_ftype_s_u = -1;
static int hf_lapd_ftype_s_u_ext = -1;

static gint ett_lapd = -1;
static gint ett_lapd_address = -1;
static gint ett_lapd_control = -1;

static dissector_table_t lapd_sapi_dissector_table;

static dissector_handle_t data_handle;
static dissector_handle_t tei_handle;
static dissector_handle_t lapd_handle;

/*
 * Bits in the address field.
 */
#define	LAPD_SAPI	0xfc00	/* Service Access Point Identifier */
#define	LAPD_SAPI_SHIFT	10
#define	LAPD_CR		0x0200	/* Command/Response bit */
#define	LAPD_EA1	0x0100	/* First Address Extension bit */
#define	LAPD_TEI	0x00fe	/* Terminal Endpoint Identifier */
#define	LAPD_EA2	0x0001	/* Second Address Extension bit */


static dissector_handle_t osi_handle;
static dissector_handle_t clnp_handle;
static dissector_handle_t isis_handle;
static dissector_handle_t esis_handle;


static const value_string lapd_sapi_vals[] = {
	{ LAPD_SAPI_Q931,	"Q.931 Call control procedure" },
	{ LAPD_SAPI_PM_Q931,	"Packet mode Q.931 Call control procedure" },
	{ LAPD_SAPI_X25,	"X.25 Level 3 procedures" },
	{ LAPD_SAPI_L2,		"Layer 2 management procedures" },
	{ 0,			NULL }
};

/* Used only for U frames */
static const xdlc_cf_items lapd_cf_items = {
	NULL,
	NULL,
	&hf_lapd_p,
	&hf_lapd_f,
	NULL,
	&hf_lapd_u_modifier_cmd,
	&hf_lapd_u_modifier_resp,
	NULL,
	&hf_lapd_ftype_s_u
};

/* Used only for I and S frames */
static const xdlc_cf_items lapd_cf_items_ext = {
	&hf_lapd_n_r,
	&hf_lapd_n_s,
	&hf_lapd_p_ext,
	&hf_lapd_f_ext,
	&hf_lapd_s_ftype,
	NULL,
	NULL,
	&hf_lapd_ftype_i,
	&hf_lapd_ftype_s_u_ext
};

static void
dissect_lapd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*lapd_tree, *addr_tree;
	proto_item	*lapd_ti, *addr_ti;
	guint16		control;
	int		lapd_header_len;
	guint16		address, cr, sapi;
	gboolean	is_response;
	tvbuff_t	*next_tvb;

	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;
	sapi = (address & LAPD_SAPI) >> LAPD_SAPI_SHIFT;
	lapd_header_len = 2;	/* address */

	if (pinfo->p2p_dir == P2P_DIR_SENT) {
		is_response = cr ? TRUE : FALSE;
		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 {
		/* XXX - what if the direction is unknown? */
		is_response = cr ? FALSE : TRUE;
		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) {
		lapd_ti = proto_tree_add_item(tree, proto_lapd, tvb, 0, -1,
		    FALSE);
		lapd_tree = proto_item_add_subtree(lapd_ti, ett_lapd);

		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_ea1, tvb, 0, 1, address);
		proto_tree_add_uint(addr_tree, hf_lapd_tei, tvb, 1, 1, address);
		proto_tree_add_uint(addr_tree, hf_lapd_ea2, tvb, 1, 1, address);
	}
	else {
		lapd_ti = NULL;
		lapd_tree = NULL;
	}

	control = dissect_xdlc_control(tvb, 2, pinfo, lapd_tree, hf_lapd_control,
	    ett_lapd_control, &lapd_cf_items, &lapd_cf_items_ext, NULL, NULL,
	    is_response, TRUE, FALSE);
	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 */
		if (!dissector_try_port(lapd_sapi_dissector_table, sapi,next_tvb, pinfo, tree))
{
		switch (tvb_get_guint8(next_tvb, 0)) {
		case 0x81:
printf("\nclnp tvb %x",tvb_get_guint8(next_tvb, 0)); fflush(stdout);
printf("\nclnp_handle = %p",clnp_handle); fflush(stdout);
		call_dissector(clnp_handle,next_tvb, pinfo, tree);
printf("\nafter %x",tvb_get_guint8(next_tvb, 0)); fflush(stdout);
		break;
		case 0x82:
printf("\nesis tvb %x",tvb_get_guint8(next_tvb, 0)); fflush(stdout);
printf("\nesis_handle = %p",esis_handle); fflush(stdout);
		call_dissector(esis_handle,next_tvb, pinfo, tree);
printf("\nafter %x",tvb_get_guint8(next_tvb, 0)); fflush(stdout);
		break;
		case 0x83:
printf("\nisis tvb %x\n",tvb_get_guint8(next_tvb, 0)); fflush(stdout);
printf("\nisis_handle = %p",isis_handle); fflush(stdout);
		call_dissector(isis_handle,next_tvb, pinfo, tree);
printf("\nafter %x",tvb_get_guint8(next_tvb, 0)); fflush(stdout);
		break;
		default:
printf("\ndefault nlpid"); fflush(stdout);
		break;
		}
}
	} else
		call_dissector(data_handle,next_tvb, pinfo, tree);
}

void
proto_register_lapd(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", HFILL }},

	{ &hf_lapd_cr,
	  { "C/R", "lapd.cr", FT_UINT16, BASE_DEC, NULL, LAPD_CR,
	  	"Command/Response bit", HFILL }},

	{ &hf_lapd_ea1,
	  { "EA1", "lapd.ea1", FT_UINT16, BASE_DEC, NULL, LAPD_EA1,
	  	"First Address Extension bit", HFILL }},

	{ &hf_lapd_tei,
	  { "TEI", "lapd.tei", FT_UINT16, BASE_DEC, NULL, LAPD_TEI,
	  	"Terminal Endpoint Identifier", HFILL }},

	{ &hf_lapd_ea2,
	  { "EA2", "lapd.ea2", FT_UINT16, BASE_DEC, NULL, LAPD_EA2,
	  	"Second Address Extension bit", HFILL }},

	{ &hf_lapd_control,
	  { "Control Field", "lapd.control", FT_UINT16, BASE_HEX, NULL, 0x0,
	  	"Control field", HFILL }},

	{ &hf_lapd_n_r,
	    { "N(R)", "lapd.control.n_r", FT_UINT16, BASE_DEC,
		NULL, XDLC_N_R_EXT_MASK, "", HFILL }},

	{ &hf_lapd_n_s,
	    { "N(S)", "lapd.control.n_s", FT_UINT16, BASE_DEC,
		NULL, XDLC_N_S_EXT_MASK, "", HFILL }},

	{ &hf_lapd_p,
	    { "Poll", "lapd.control.p", FT_BOOLEAN, 8,
		TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},

	{ &hf_lapd_p_ext,
	    { "Poll", "lapd.control.p", FT_BOOLEAN, 16,
		TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},

	{ &hf_lapd_f,
	    { "Final", "lapd.control.f", FT_BOOLEAN, 8,
		TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},

	{ &hf_lapd_f_ext,
	    { "Final", "lapd.control.f", FT_BOOLEAN, 16,
		TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},

	{ &hf_lapd_s_ftype,
	    { "Supervisory frame type", "lapd.control.s_ftype", FT_UINT16, BASE_HEX,
		VALS(stype_vals), XDLC_S_FTYPE_MASK, "", HFILL }},

	{ &hf_lapd_u_modifier_cmd,
	    { "Command", "lapd.control.u_modifier_cmd", FT_UINT8, BASE_HEX,
		VALS(modifier_vals_cmd), XDLC_U_MODIFIER_MASK, "", HFILL }},

	{ &hf_lapd_u_modifier_resp,
	    { "Response", "lapd.control.u_modifier_resp", FT_UINT8, BASE_HEX,
		VALS(modifier_vals_resp), XDLC_U_MODIFIER_MASK, "", HFILL }},

	{ &hf_lapd_ftype_i,
	    { "Frame type", "lapd.control.ftype", FT_UINT16, BASE_HEX,
		VALS(ftype_vals), XDLC_I_MASK, "", HFILL }},

	{ &hf_lapd_ftype_s_u,
	    { "Frame type", "lapd.control.ftype", FT_UINT8, BASE_HEX,
		VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},

	{ &hf_lapd_ftype_s_u_ext,
	    { "Frame type", "lapd.control.ftype", FT_UINT16, BASE_HEX,
		VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
    };
    static gint *ett[] = {
        &ett_lapd,
        &ett_lapd_address,
        &ett_lapd_control,
    };

    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));

    register_dissector("lapd", dissect_lapd, proto_lapd);

    lapd_sapi_dissector_table = register_dissector_table("lapd.sapi",
	    "LAPD SAPI", FT_UINT16, BASE_DEC);
}

void
proto_reg_handoff_lapd(void)
{
// dissector_handle_t lapd_handle;

	data_handle = find_dissector("data");
	tei_handle  = find_dissector("tei");
	lapd_handle = find_dissector("lapd");
printf("\nlapd_handle = %p", lapd_handle); fflush(stdout);
	osi_handle  = find_dissector("osi");
printf("\nosi_handle = %p", osi_handle); fflush(stdout);
	clnp_handle = find_dissector("clnp");
printf("\nclnp_handle = %p", clnp_handle); fflush(stdout);
	isis_handle = find_dissector("isis");
printf("\nisis_handle = %p", isis_handle); fflush(stdout);
	esis_handle = find_dissector("esis");
printf("\nesis_handle = %p", esis_handle); fflush(stdout);

 dissector_add("wtap_encap", WTAP_ENCAP_CHDLC, lapd_handle);
}