ANNOUNCEMENT: Live Wireshark University & Allegro Packets online APAC Wireshark Training Session
July 17th, 2024 | 10:00am-11:55am SGT (UTC+8) | Online

Ethereal-dev: [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 17:29:12 +0100
Folks,

here's my attempt at decoding V.120 from an I4B (ISDN for BSD) trace
file.

The code has some rough edges, but it allowed me to finally work on
implementing V.120, so... it works for me<tm>.

Because the i4btrace format doesn't include a magic header to
authoritative brand it as an I4B trace file, I've used a heuristic to
determine whether or not it actually is one. Again, it works for me...
The same holds for detecting V.120 versus other B-channel apps. The
V.120 spec sucks.

By the way, I noticed the Q.931 code needs some work for Euro ISDN,
which Q.931 implementation was it written for?

The diff is relative to Ethereal 0.7.9 and might require some tweaking,
as I'm not an automake wizard. I hope I touched the right files...

Let me know what is required to make this go into Ethereal...

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.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/Makefile.in ./wiretap/Makefile.in
*** ethereal-0.7.9/wiretap/Makefile.in	Mon Nov 29 06:59:32 1999
--- ./wiretap/Makefile.in	Mon Dec  6 23:32:11 1999
***************
*** 107,111 ****
  
  
! libwiretap_a_SOURCES =  	ascend-grammar.y		ascend-scanner.l		ascend.c			ascend.h			ascend-int.h			buffer.c			buffer.h			file.c				file.h				iptrace.c			iptrace.h			lanalyzer.c			lanalyzer.h			libpcap.c			libpcap.h			netmon.c			netmon.h			nettl.c				nettl.h				netxray.c			netxray.h			ngsniffer.c			ngsniffer.h			radcom.c			radcom.h			snoop.c				snoop.h				toshiba.c			toshiba.h			wtap.c				wtap.h
  
  
--- 107,111 ----
  
  
! libwiretap_a_SOURCES =  	ascend-grammar.y		ascend-scanner.l		ascend.c			ascend.h			ascend-int.h			buffer.c			buffer.h			file.c				file.h				i4btrace.c			iptrace.c			iptrace.h			lanalyzer.c			lanalyzer.h			libpcap.c			libpcap.h			netmon.c			netmon.h			nettl.c				nettl.h				netxray.c			netxray.h			ngsniffer.c			ngsniffer.h			radcom.c			radcom.h			snoop.c				snoop.h				toshiba.c			toshiba.h			wtap.c				wtap.h
  
  
***************
*** 128,133 ****
  libwiretap_a_LIBADD = 
  libwiretap_a_OBJECTS =  ascend-grammar.o ascend-scanner.o ascend.o \
! buffer.o file.o iptrace.o lanalyzer.o libpcap.o netmon.o nettl.o \
! netxray.o ngsniffer.o radcom.o snoop.o toshiba.o wtap.o
  AR = ar
  LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
--- 128,133 ----
  libwiretap_a_LIBADD = 
  libwiretap_a_OBJECTS =  ascend-grammar.o ascend-scanner.o ascend.o \
! buffer.o file.o i4btrace.o iptrace.o lanalyzer.o libpcap.o netmon.o \
! nettl.o netxray.o ngsniffer.o radcom.o snoop.o toshiba.o wtap.o
  AR = ar
  LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
***************
*** 146,149 ****
--- 146,154 ----
  TAR = tar
  GZIP_ENV = --best
+ DEP_FILES =  .deps/ascend-grammar.P .deps/ascend-scanner.P \
+ .deps/ascend.P .deps/buffer.P .deps/file.P .deps/i4btrace.P \
+ .deps/iptrace.P .deps/lanalyzer.P .deps/libpcap.P .deps/netmon.P \
+ .deps/nettl.P .deps/netxray.P .deps/ngsniffer.P .deps/radcom.P \
+ .deps/snoop.P .deps/toshiba.P .deps/wtap.P
  SOURCES = $(libwiretap_a_SOURCES)
  OBJECTS = $(libwiretap_a_OBJECTS)
***************
*** 153,159 ****
  .SUFFIXES: .S .c .l .o .s .y
  $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
! 	cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile
  
! Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
  	cd $(top_builddir) \
  	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
--- 158,164 ----
  .SUFFIXES: .S .c .l .o .s .y
  $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
! 	cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile
  
! Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
  	cd $(top_builddir) \
  	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
***************
*** 204,210 ****
  maintainer-clean-noinstLIBRARIES:
  
- .c.o:
- 	$(COMPILE) -c $<
- 
  .s.o:
  	$(COMPILE) -c $<
--- 209,212 ----
***************
*** 304,311 ****
  	mkdir $(distdir)
  	-chmod 777 $(distdir)
  	@for file in $(DISTFILES); do \
  	  d=$(srcdir); \
  	  if test -d $$d/$$file; then \
! 	    cp -pr $$d/$$file $(distdir)/$$file; \
  	  else \
  	    test -f $(distdir)/$$file \
--- 306,318 ----
  	mkdir $(distdir)
  	-chmod 777 $(distdir)
+ 	here=`cd $(top_builddir) && pwd`; \
+ 	top_distdir=`cd $(distdir) && pwd`; \
+ 	distdir=`cd $(distdir) && pwd`; \
+ 	cd $(top_srcdir) \
+ 	  && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile
  	@for file in $(DISTFILES); do \
  	  d=$(srcdir); \
  	  if test -d $$d/$$file; then \
! 	    cp -pr $$/$$file $(distdir)/$$file; \
  	  else \
  	    test -f $(distdir)/$$file \
***************
*** 314,338 ****
  	  fi; \
  	done
- ascend-grammar.o: ascend-grammar.c config.h wtap.h buffer.h ascend.h \
- 	ascend-int.h
- ascend-scanner.o: ascend-scanner.c config.h wtap.h ascend.h \
- 	ascend-grammar.h ascend-int.h file.h
- ascend.o: ascend.c config.h wtap.h buffer.h ascend.h ascend-int.h file.h
- buffer.o: buffer.c buffer.h
- file.o: file.c config.h wtap.h file.h buffer.h lanalyzer.h ngsniffer.h \
- 	radcom.h ascend.h nettl.h libpcap.h snoop.h iptrace.h netmon.h \
- 	netxray.h toshiba.h
- iptrace.o: iptrace.c config.h wtap.h file.h buffer.h iptrace.h
- lanalyzer.o: lanalyzer.c config.h wtap.h file.h buffer.h lanalyzer.h
- libpcap.o: libpcap.c config.h wtap.h file.h buffer.h libpcap.h
- netmon.o: netmon.c config.h wtap.h file.h buffer.h netmon.h
- nettl.o: nettl.c config.h wtap.h file.h buffer.h nettl.h
- netxray.o: netxray.c config.h wtap.h file.h netxray.h buffer.h
- ngsniffer.o: ngsniffer.c config.h wtap.h file.h buffer.h ngsniffer.h
- radcom.o: radcom.c config.h wtap.h file.h buffer.h radcom.h
- snoop.o: snoop.c config.h wtap.h file.h buffer.h snoop.h
- toshiba.o: toshiba.c config.h wtap.h buffer.h toshiba.h file.h
- wtap.o: wtap.c config.h wtap.h file.h buffer.h ascend.h toshiba.h
  
  info-am:
  info: info-am
--- 321,356 ----
  	  fi; \
  	done
  
+ DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+ 
+ -include $(DEP_FILES)
+ 
+ mostlyclean-depend:
+ 
+ clean-depend:
+ 
+ distclean-depend:
+ 	-rm -rf .deps
+ 
+ maintainer-clean-depend:
+ 
+ %.o: %.c
+ 	@echo '$(COMPILE) -c $<'; \
+ 	$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ 	@-cp .deps/$(*F).pp .deps/$(*F).P; \
+ 	tr ' ' '\012' < .deps/$(*F).pp \
+ 	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ 	    >> .deps/$(*F).P; \
+ 	rm .deps/$(*F).pp
+ 
+ %.lo: %.c
+ 	@echo '$(LTCOMPILE) -c $<'; \
+ 	$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ 	@-sed -e 's/^\([^:]*\)\.o[ 	]*:/\1.lo \1.o :/' \
+ 	  < .deps/$(*F).pp > .deps/$(*F).P; \
+ 	tr ' ' '\012' < .deps/$(*F).pp \
+ 	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ 	    >> .deps/$(*F).P; \
+ 	rm -f .deps/$(*F).pp
  info-am:
  info: info-am
***************
*** 376,380 ****
  	-test -z "ascend-scannerlascend-grammarhascend-grammarc" || rm -f ascend-scannerl ascend-grammarh ascend-grammarc
  mostlyclean-am:  mostlyclean-hdr mostlyclean-noinstLIBRARIES \
! 		mostlyclean-compile mostlyclean-tags \
  		mostlyclean-generic
  
--- 394,398 ----
  	-test -z "ascend-scannerlascend-grammarhascend-grammarc" || rm -f ascend-scannerl ascend-grammarh ascend-grammarc
  mostlyclean-am:  mostlyclean-hdr mostlyclean-noinstLIBRARIES \
! 		mostlyclean-compile mostlyclean-tags mostlyclean-depend \
  		mostlyclean-generic
  
***************
*** 382,391 ****
  
  clean-am:  clean-hdr clean-noinstLIBRARIES clean-compile clean-tags \
! 		clean-generic mostlyclean-am
  
  clean: clean-am
  
  distclean-am:  distclean-hdr distclean-noinstLIBRARIES distclean-compile \
! 		distclean-tags distclean-generic clean-am
  
  distclean: distclean-am
--- 400,410 ----
  
  clean-am:  clean-hdr clean-noinstLIBRARIES clean-compile clean-tags \
! 		clean-depend clean-generic mostlyclean-am
  
  clean: clean-am
  
  distclean-am:  distclean-hdr distclean-noinstLIBRARIES distclean-compile \
! 		distclean-tags distclean-depend distclean-generic \
! 		clean-am
  
  distclean: distclean-am
***************
*** 395,399 ****
  		maintainer-clean-noinstLIBRARIES \
  		maintainer-clean-compile maintainer-clean-tags \
! 		maintainer-clean-generic distclean-am
  	@echo "This command is intended for maintainers to use;"
  	@echo "it deletes files that may require special tools to rebuild."
--- 414,419 ----
  		maintainer-clean-noinstLIBRARIES \
  		maintainer-clean-compile maintainer-clean-tags \
! 		maintainer-clean-depend maintainer-clean-generic \
! 		distclean-am
  	@echo "This command is intended for maintainers to use;"
  	@echo "it deletes files that may require special tools to rebuild."
***************
*** 407,414 ****
  mostlyclean-compile distclean-compile clean-compile \
  maintainer-clean-compile tags mostlyclean-tags distclean-tags \
! clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
! check-am installcheck-am installcheck all-recursive-am install-exec-am \
! install-exec install-data-am install-data install-am install \
! uninstall-am uninstall all-redirect all-am all installdirs \
  mostlyclean-generic distclean-generic clean-generic \
  maintainer-clean-generic clean mostlyclean distclean maintainer-clean
--- 427,435 ----
  mostlyclean-compile distclean-compile clean-compile \
  maintainer-clean-compile tags mostlyclean-tags distclean-tags \
! clean-tags maintainer-clean-tags distdir mostlyclean-depend \
! distclean-depend clean-depend maintainer-clean-depend info-am info \
! dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
! install-exec-am install-exec install-data-am install-data install-am \
! install uninstall-am uninstall all-redirect all-am all installdirs \
  mostlyclean-generic distclean-generic clean-generic \
  maintainer-clean-generic clean mostlyclean distclean maintainer-clean
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;