Ethereal-dev: Re: [ethereal-dev] I4B trace & V.120 decoder

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

From: Bert Driehuis <driehuis@xxxxxxxxxxxxx>
Date: Sun, 12 Dec 1999 20:42:43 +0100
Sigh... I always forget to include the small details, like the actual
code...

Here's a fresh patch without the Makefile.in junk, but including the
packet-v120.c file.

Cheers,

				-- Bert

-- 
Bert Driehuis -- driehuis@xxxxxxxxxxxxx -- +31-20-3116119
The grand leap of the whale up the Fall of Niagara is esteemed, by all
who have seen it, as one of the finest spectacles in nature.
                -- Benjamin Franklin.
diff -rc2 ethereal-0.7.9/packet-v120.c ./packet-v120.c
*** ethereal-0.7.9/packet-v120.c	Sun Dec 12 20:38:16 1999
--- ./packet-v120.c	Sun Dec 12 20:40:20 1999
***************
*** 0 ****
--- 1,153 ----
+ /* packet-v120.c
+  * Routines for v120 frame disassembly
+  * Bert Driehuis <driehuis@xxxxxxxxxxxxx>
+  *
+  * $Id: $
+  *
+  * Ethereal - Network traffic analyzer
+  * By Gerald Combs <gerald@xxxxxxxx>
+  * 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
+ 
+ #ifdef HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <glib.h>
+ #include <string.h>
+ #include "packet.h"
+ #include "xdlc.h"
+ 
+ #define FROM_DCE	0x80
+ 
+ static int proto_v120 = -1;
+ static int hf_v120_address = -1;
+ static int hf_v120_control = -1;
+ 
+ static gint ett_v120 = -1;
+ static gint ett_v120_address = -1;
+ static gint ett_v120_control = -1;
+ 
+ void
+ dissect_v120(const u_char *pd, frame_data *fd, proto_tree *tree)
+ {
+     proto_tree *v120_tree, *ti, *tc, *address_tree;
+     int is_response;
+     int addr;
+     char info[80];
+     int v120len;
+ 
+     if (check_col(fd, COL_PROTOCOL))
+ 	col_add_str(fd, COL_PROTOCOL, "V.120");
+ 
+     if(check_col(fd, COL_RES_DL_SRC))
+ 	col_add_fstr(fd, COL_RES_DL_SRC, "0x%02X", pd[0]);
+     if ((pd[0] & 0x01) != 0x00 && (pd[1] && 0x01) != 0x01)
+     {
+ 	if (check_col(fd, COL_INFO))
+ 	    col_add_str(fd, COL_INFO, "Invalid V.120 frame");
+ 	if (tree)
+ 	    ti = proto_tree_add_item_format(tree, proto_v120, 0, fd->cap_len,
+ 			                    NULL, "Invalid V.120 frame");
+ 	return;
+     }
+ 
+     if (fd->pseudo_header.x25.flags & FROM_DCE) {
+ 	if(check_col(fd, COL_RES_DL_DST))
+ 	    col_add_str(fd, COL_RES_DL_DST, "DTE");
+ 	if(check_col(fd, COL_RES_DL_SRC))
+ 	    col_add_str(fd, COL_RES_DL_SRC, "DCE");
+     }
+     else {
+ 	if(check_col(fd, COL_RES_DL_DST))
+ 	    col_add_str(fd, COL_RES_DL_DST, "DCE");
+ 	if(check_col(fd, COL_RES_DL_SRC))
+ 	    col_add_str(fd, COL_RES_DL_SRC, "DTE");
+     }
+ 
+     if (((fd->pseudo_header.x25.flags & FROM_DCE) && pd[0] & 0x02) ||
+        (!(fd->pseudo_header.x25.flags & FROM_DCE) && !(pd[0] & 0x02)))
+ 	is_response = TRUE;
+     else
+ 	is_response = FALSE;
+ 
+     if (tree) {
+ 	if (fd->pkt_len <= 5)
+ 		v120len = fd->pkt_len;
+ 	else
+ 		v120len = 5;
+ 	ti = proto_tree_add_item_format(tree, proto_v120, 0, v120len, NULL,
+ 					    "V.120");
+ 	v120_tree = proto_item_add_subtree(ti, ett_v120);
+ 	addr = pd[0] << 8 | pd[1];
+ 	sprintf(info, "LLI: %d C/R: %s",
+ 			((pd[0] & 0xfc) << 5) | ((pd[1] & 0xfe) >> 1),
+ 			pd[0] & 0x02 ? "R" : "C");
+ 	tc = proto_tree_add_item_format(v120_tree, ett_v120_address,
+ 			0, 2,
+ 			"Address field: %s (0x%02X)", info, addr);
+ 	address_tree = proto_item_add_subtree(tc, ett_v120_address);
+ 	proto_tree_add_text(address_tree, 0, 2,
+ 		    decode_boolean_bitfield(addr, 0x0200, 2*8,
+ 			"Response", "Command"), NULL);
+ 	sprintf(info, "LLI: %d", ((pd[0] & 0xfc) << 5) | ((pd[1] & 0xfe) >> 1));
+ 	proto_tree_add_text(address_tree, 0, 2,
+ 		    decode_numeric_bitfield(addr, 0xfcfe, 2*8, info));
+ 	proto_tree_add_text(address_tree, 0, 2,
+ 		    decode_boolean_bitfield(addr, 0x0100, 2*8,
+ 			"EA0 = 1 (Error)", "EA0 = 0"), NULL);
+ 	proto_tree_add_text(address_tree, 0, 2,
+ 		    decode_boolean_bitfield(addr, 0x01, 2*8,
+ 			"EA1 = 1", "EA1 = 0 (Error)"), NULL);
+ 	/* TODO: parse octets 4 & 5. Not that they're used in
+ 	   practice, but it looks so professional. */
+     }
+     else
+         v120_tree = NULL;
+     dissect_xdlc_control(pd, 2, fd, v120_tree, hf_v120_control,
+ 	    ett_v120_control, is_response, v120len == 3 ? FALSE : TRUE);
+ 
+     /* not end of frame ==> X.25 */
+ }
+ 
+ void
+ proto_register_v120(void)
+ {
+     static hf_register_info hf[] = {
+ 	{ &hf_v120_address,
+ 	  { "Link Address", "v120.address", FT_UINT16, BASE_HEX, NULL,
+ 		  0x0, "" }},
+ 	{ &hf_v120_control,
+ 	  { "Control Field", "v120.control", FT_STRING, BASE_NONE, NULL, 0x0,
+ 	  	"" }},
+     };
+     static gint *ett[] = {
+         &ett_v120,
+         &ett_v120_address,
+         &ett_v120_control,
+     };
+ 
+     proto_v120 = proto_register_protocol ("Async data over ISDN (V.120)", "v120");
+     proto_register_field_array (proto_v120, hf, array_length(hf));
+     proto_register_subtree_array(ett, array_length(ett));
+ }
diff -rc2 ethereal-0.7.9/packet.c ./packet.c
*** ethereal-0.7.9/packet.c	Sat Nov 27 09:51:53 1999
--- ./packet.c	Tue Dec  7 10:36:59 1999
***************
*** 847,850 ****
--- 847,853 ----
  			dissect_lapd(pd, fd, tree);
  			break;
+ 		case WTAP_ENCAP_V120 :
+ 			dissect_v120(pd, fd, tree);
+ 			break;
  	}
  }
diff -rc2 ethereal-0.7.9/wiretap/Makefile.am ./wiretap/Makefile.am
*** ethereal-0.7.9/wiretap/Makefile.am	Sun Oct 31 18:46:04 1999
--- ./wiretap/Makefile.am	Mon Dec  6 23:32:06 1999
***************
*** 41,44 ****
--- 41,45 ----
  	file.c			\
  	file.h			\
+ 	i4btrace.c		\
  	iptrace.c		\
  	iptrace.h		\
diff -rc2 ethereal-0.7.9/wiretap/file.c ./wiretap/file.c
*** ethereal-0.7.9/wiretap/file.c	Thu Nov 11 04:05:06 1999
--- ./wiretap/file.c	Mon Dec  6 23:52:06 1999
***************
*** 44,47 ****
--- 44,48 ----
  #include "netxray.h"
  #include "toshiba.h"
+ #include "i4btrace.h"
  
  /* The open_file_* routines should return:
***************
*** 87,90 ****
--- 88,92 ----
  	ascend_open,
  	toshiba_open,
+ 	i4btrace_open,
  };
  
diff -rc2 ethereal-0.7.9/wiretap/i4b_trace.h ./wiretap/i4b_trace.h
*** ethereal-0.7.9/wiretap/i4b_trace.h	Sun Dec 12 14:49:02 1999
--- ./wiretap/i4b_trace.h	Mon Dec  6 23:33:36 1999
***************
*** 0 ****
--- 1,91 ----
+ /*
+  * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  *
+  *---------------------------------------------------------------------------
+  *
+  *	i4b_trace.h - header file for trace data read device
+  *	----------------------------------------------------
+  *
+  *	$Id: i4b_trace.h,v 1.6 1999/02/14 09:45:02 hm Exp $ 
+  *
+  *      last edit-date: [Sun Feb 14 10:39:26 1999]
+  *
+  *---------------------------------------------------------------------------*/
+ 
+ #ifndef _I4B_TRACE_H_
+ #define _I4B_TRACE_H_
+ 
+ /*---------------------------------------------------------------------------*
+  *	structure of the header at the beginning of every trace mbuf
+  *---------------------------------------------------------------------------*/
+ typedef struct {
+ 	int length;		/* length of the following mbuf		*/
+ 	int unit;		/* controller unit number		*/
+ 	int type;		/* type of channel			*/
+ #define TRC_CH_I	0		/* Layer 1 INFO's		*/
+ #define TRC_CH_D 	1		/* D channel 			*/
+ #define TRC_CH_B1	2		/* B1 channel			*/
+ #define TRC_CH_B2	3		/* B2 channel			*/
+ 	int dir;		/* direction 				*/
+ #define FROM_TE	0			/* user -> network		*/
+ #define FROM_NT 1			/* network -> user		*/
+ 	int trunc;		/* # of truncated bytes (frame > MCLBYTES) */
+ 	unsigned int count;	/* frame count for this unit/type	*/
+ 	struct timeval time;	/* timestamp for this frame		*/
+ } i4b_trace_hdr_t;
+ 
+ #define INFO0		0	/* layer 1 */
+ #define INFO1_8		1
+ #define INFO1_10	2
+ #define INFO2		3
+ #define INFO3		4
+ #define INFO4_8		5
+ #define INFO4_10	6
+ 
+ /*---------------------------------------------------------------------------*
+  * 	ioctl via /dev/i4btrc device(s):
+  *	get/set current trace flag settings
+  *---------------------------------------------------------------------------*/
+ 	
+ #define	I4B_TRC_GET	_IOR('T', 0, int)	/* get trace settings	*/
+ #define	I4B_TRC_SET	_IOW('T', 1, int)	/* set trace settings	*/
+ 
+ #define TRACE_OFF       0x00		/* tracing off 		*/
+ #define TRACE_I		0x01		/* trace L1 INFO's on	*/
+ #define TRACE_D_TX	0x02		/* trace D channel on	*/
+ #define TRACE_D_RX	0x04		/* trace D channel on	*/
+ #define TRACE_B_TX	0x08		/* trace B channel on	*/
+ #define TRACE_B_RX	0x10		/* trace B channel on	*/
+ 
+ typedef struct {
+ 	int rxunit;		/* unit # for rx frames	*/
+ 	int rxflags;		/* d and/or b channel	*/
+ 	int txunit;		/* unit # for tx frames */
+ 	int txflags;		/* d and/or b channel	*/
+ } i4b_trace_setupa_t;
+ 
+ #define	I4B_TRC_SETA	_IOW('T', 2, i4b_trace_setupa_t) /* set analyze mode */
+ #define	I4B_TRC_RESETA	_IOW('T', 3, int)	/* reset analyze mode	*/
+ 
+ #endif /* _I4B_TRACE_H_ */
diff -rc2 ethereal-0.7.9/wiretap/i4btrace.c ./wiretap/i4btrace.c
*** ethereal-0.7.9/wiretap/i4btrace.c	Sun Dec 12 14:48:55 1999
--- ./wiretap/i4btrace.c	Sun Dec 12 14:45:51 1999
***************
*** 0 ****
--- 1,163 ----
+ /* i4btrace.c
+  *
+  * $Id: $
+  *
+  * Wiretap Library
+  * Copyright (c) 1999 by Bert Driehuis <driehuis@xxxxxxxxxxxxx>
+  *
+  * 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 <stdlib.h>
+ #include <errno.h>
+ #include <time.h>
+ #include "wtap.h"
+ #include "file.h"
+ #include "buffer.h"
+ #include "i4b_trace.h"
+ 
+ static int i4btrace_read(wtap *wth, int *err);
+ 
+ int i4btrace_open(wtap *wth, int *err)
+ {
+ 	int bytes_read;
+ 	i4b_trace_hdr_t hdr;
+ 
+ 	/* I4B trace files have no magic in the header... Sigh */
+ 	file_seek(wth->fh, 0, SEEK_SET);
+ 	errno = WTAP_ERR_CANT_READ;
+ 	bytes_read = file_read(&hdr, 1, sizeof(hdr), wth->fh);
+ 	if (bytes_read != sizeof(hdr)) {
+ 		*err = file_error(wth->fh);
+ 		if (*err != 0)
+ 			return -1;
+ 		return 0;
+ 	}
+ 
+ 	/* Silly heuristic... */
+ 	if ((unsigned)hdr.length < 3 || (unsigned)hdr.unit > 4 ||
+ 			(unsigned)hdr.type > 4 || (unsigned)hdr.dir > 2 ||
+ 			(unsigned)hdr.trunc > 2048)
+ 		return 0;
+ 
+ 	file_seek(wth->fh, 0, SEEK_SET);
+ 	wth->data_offset = 0;
+ 
+ 	/* Get capture start time */
+ 
+ 	wth->file_type = WTAP_FILE_I4BTRACE;
+ 	wth->capture.i4btrace = g_malloc(sizeof(i4btrace_t));
+ 	wth->subtype_read = i4btrace_read;
+ 	wth->snapshot_length = 2048;	/* actual length set per packet */
+ 
+ 	wth->capture.i4btrace->start = hdr.time.tv_sec;
+ 	wth->capture.i4btrace->bchannel_prot[0] = -1;
+ 	wth->capture.i4btrace->bchannel_prot[1] = -1;
+ 
+ 	wth->file_encap = WTAP_ENCAP_PER_PACKET;
+ 
+ 	return 1;
+ }
+ 
+ #define V120SABME	"\010\001\177"
+ 
+ /* Read the next packet */
+ static int i4btrace_read(wtap *wth, int *err)
+ {
+ 	int	bytes_read;
+ 	i4b_trace_hdr_t hdr;
+ 	guint16 length;
+ 	int	data_offset;
+ 	void *bufp;
+ 
+ 	/* Read record header. */
+ 	errno = WTAP_ERR_CANT_READ;
+ 	bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
+ 	if (bytes_read != sizeof hdr) {
+ 		*err = file_error(wth->fh);
+ 		if (*err != 0)
+ 			return -1;
+ 		if (bytes_read != 0) {
+ 			*err = WTAP_ERR_SHORT_READ;
+ 			return -1;
+ 		}
+ 		return 0;
+ 	}
+ 	wth->data_offset += sizeof hdr;
+ 	length = pletohs(&hdr.length) - sizeof(hdr);
+ 	if (length == 0) return 0;
+ 
+ 	wth->phdr.len = length;
+ 	wth->phdr.caplen = length;
+ 
+ 	wth->phdr.ts.tv_sec = hdr.time.tv_sec;
+ 	wth->phdr.ts.tv_usec = hdr.time.tv_usec;
+ 
+ 	wth->phdr.pseudo_header.x25.flags = (hdr.dir == FROM_TE) ? 0x00 : 0x80;
+ 
+ 	/*
+ 	 * Read the packet data.
+ 	 */
+ 	buffer_assure_space(wth->frame_buffer, length);
+ 	data_offset = wth->data_offset;
+ 	errno = WTAP_ERR_CANT_READ;
+ 	bufp = buffer_start_ptr(wth->frame_buffer);
+ 	bytes_read = file_read(bufp, 1, length, wth->fh);
+ 
+ 	if (bytes_read != length) {
+ 		*err = file_error(wth->fh);
+ 		if (*err == 0)
+ 			*err = WTAP_ERR_SHORT_READ;
+ 		return -1;
+ 	}
+ 	wth->data_offset += length;
+ 
+ 	/*
+ 	 * This heuristic tries to figure out whether the datastream is
+ 	 * V.120 or not. We cannot glean this from the Q.931 SETUP message,
+ 	 * because no commercial V.120 implementation I've seen actually
+ 	 * sets the V.120 protocol discriminator (that, or I'm misreading
+ 	 * the spec badly).
+ 	 * TODO: reset the flag to -1 (unknown) after a close on the B
+ 	 * channel is detected.
+ 	 */
+ 	if (hdr.type == TRC_CH_B1 || hdr.type == TRC_CH_B2) {
+ 		int channel = hdr.type - TRC_CH_B1;
+ 		if (wth->capture.i4btrace->bchannel_prot[channel] == -1) {
+ 			if (memcmp(bufp, V120SABME, 3) == 0)
+ 			    wth->capture.i4btrace->bchannel_prot[channel] = 1;
+ 			else
+ 			    wth->capture.i4btrace->bchannel_prot[channel] = 0;
+ 		}
+ 	}
+ 
+ 	if (hdr.type == TRC_CH_I) {
+ 		wth->phdr.pkt_encap = WTAP_ENCAP_NULL;
+ 	} else if (hdr.type == TRC_CH_D) {
+ 		wth->phdr.pkt_encap = WTAP_ENCAP_LAPD;
+ 	} else {
+ 		int channel = hdr.type - TRC_CH_B1;
+ 		if (wth->capture.i4btrace->bchannel_prot[channel] == 1)
+ 			wth->phdr.pkt_encap = WTAP_ENCAP_V120;
+ 		else
+ 			wth->phdr.pkt_encap = WTAP_ENCAP_NULL;
+ 	}
+ 
+ 	return data_offset;
+ }
diff -rc2 ethereal-0.7.9/wiretap/i4btrace.h ./wiretap/i4btrace.h
*** ethereal-0.7.9/wiretap/i4btrace.h	Sun Dec 12 14:48:58 1999
--- ./wiretap/i4btrace.h	Mon Dec  6 23:51:02 1999
***************
*** 0 ****
--- 1,24 ----
+ /* i4btrace.h
+  *
+  * $Id: i4btrace.h,v $
+  *
+  * Wiretap Library
+  * Copyright (c) 1999 by Bert Driehuis <driehuis@xxxxxxxxxxxxx>
+  * 
+  * 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.
+  *
+  */
+ 
+ int i4btrace_open(wtap *wth, int *err);
diff -rc2 ethereal-0.7.9/wiretap/wtap.c ./wiretap/wtap.c
*** ethereal-0.7.9/wiretap/wtap.c	Fri Nov 26 18:57:14 1999
--- ./wiretap/wtap.c	Mon Dec  6 23:56:16 1999
***************
*** 112,115 ****
--- 112,118 ----
  			return "Toshiba Compact ISDN Router snoop trace";
  
+ 		case WTAP_FILE_I4BTRACE:
+ 			return "I4B ISDN trace";
+ 
  		default:
  			g_error("Unknown capture file type %d", wth->file_type);
diff -rc2 ethereal-0.7.9/wiretap/wtap.h ./wiretap/wtap.h
*** ethereal-0.7.9/wiretap/wtap.h	Fri Nov 26 18:57:14 1999
--- ./wiretap/wtap.h	Sun Dec 12 13:55:34 1999
***************
*** 93,99 ****
  #define WTAP_ENCAP_ASCEND			14
  #define WTAP_ENCAP_LAPD				15
  
  /* last WTAP_ENCAP_ value + 1 */
! #define WTAP_NUM_ENCAP_TYPES			16
  
  /* File types that can be read by wiretap.
--- 93,100 ----
  #define WTAP_ENCAP_ASCEND			14
  #define WTAP_ENCAP_LAPD				15
+ #define WTAP_ENCAP_V120				16
  
  /* last WTAP_ENCAP_ value + 1 */
! #define WTAP_NUM_ENCAP_TYPES			17
  
  /* File types that can be read by wiretap.
***************
*** 118,121 ****
--- 119,123 ----
  #define WTAP_FILE_NETTL				16
  #define WTAP_FILE_TOSHIBA			17
+ #define WTAP_FILE_I4BTRACE			18
  
  /*
***************
*** 156,159 ****
--- 158,166 ----
  typedef struct {
  	time_t	start;
+ 	int bchannel_prot[2];	/* For the V.120 heuristic */
+ } i4btrace_t;
+ 
+ typedef struct {
+ 	time_t	start;
  } nettl_t;
  
***************
*** 321,324 ****
--- 328,332 ----
  		ngsniffer_t		*ngsniffer;
  		radcom_t		*radcom;
+ 		i4btrace_t		*i4btrace;
  		nettl_t			*nettl;
  		netmon_t		*netmon;