Ethereal-dev: Re: [Ethereal-dev] Patch 2 for writing Novell LanAlyzer files

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

From: Markus Steinmann <ms@xxxxxx>
Date: Wed, 26 Jun 2002 08:12:30 +0200
Hi,

Guy Harris wrote:

On Tue, Jun 25, 2002 at 01:34:46PM +0200, Markus Steinmann wrote:
Could you re-do the patch as a "diff -c" or "diff -u" patch?  Without
the context information provided by 'diff -c" or "diff -u", the version
of "patch" we have installed here:

sorry, I thought my .cvsrc with "diff -u" should be enough.
Okay, I've now made a "cvs update -Pd" and a
"cvs diff -u wiretap". Hope this will work.

Nice regards,

		Markus
__________________________________________________________________

Markus Steinmann                                         ms@xxxxxx
Software Development
SEH Computertechnik GmbH Bielefeld               http://www.seh.de
__________________________________________________________________
? wiretap/.file.c,
? wiretap/.kped
? wiretap/.lanalyzer.c,
? wiretap/.lanalyzer.h,
? wiretap/.snoop.c,
? wiretap/.visual.c,
? wiretap/mops.xd
Index: wiretap/file.c
===================================================================
RCS file: /cvsroot/ethereal/wiretap/file.c,v
retrieving revision 1.92
diff -u -r1.92 file.c
--- file.c	2002/06/07 07:47:57	1.92
+++ file.c	2002/06/26 06:01:05
@@ -4,17 +4,17 @@
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xxxxxxxxxxxxxxx>
- * 
+ *
  * 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.
@@ -343,8 +343,8 @@
 	  NULL, NULL },
 
 	/* WTAP_FILE_LANALYZER */
-	{ "Novell LANalyzer", NULL,
-	  NULL, NULL },
+	{ "Novell LanAlyzer","lanalyzer",
+	  lanalyzer_dump_can_write_encap, lanalyzer_dump_open },
 
 	/* WTAP_FILE_NGSNIFFER_UNCOMPRESSED */
 	{ "Network Associates Sniffer (DOS-based)", "ngsniffer",
Index: wiretap/lanalyzer.c
===================================================================
RCS file: /cvsroot/ethereal/wiretap/lanalyzer.c,v
retrieving revision 1.33
diff -u -r1.33 lanalyzer.c
--- lanalyzer.c	2002/06/07 07:27:35	1.33
+++ lanalyzer.c	2002/06/26 06:01:05
@@ -4,17 +4,17 @@
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xxxxxxxxxxxxxxx>
- * 
+ *
  * 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.
@@ -47,8 +47,84 @@
 #define BOARD_325		226	/* LANalyzer 325 (Ethernet) */
 #define BOARD_325TR		227	/* LANalyzer 325TR (Token-ring) */
 
+static const gint8 LA_HeaderRegularFake[] = {
+0x01,0x10,0x4c,0x00,0x01,0x05,0x54,0x72,0x61,0x63,0x65,0x20,0x44,0x69,0x73,0x70,
+0x6c,0x61,0x79,0x20,0x54,0x72,0x61,0x63,0x65,0x20,0x46,0x69,0x6c,0x65,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+      };
+
+static const gint8 LA_RxChannelNameFake[] = {
+0x06,0x10,0x80,0x00,0x43,0x68,0x61,0x6e ,0x6e,0x65,0x6c,0x31,0x00,0x43,0x68,0x61,
+0x6e,0x6e,0x65,0x6c,0x32,0x00,0x43,0x68 ,0x61,0x6e,0x6e,0x65,0x6c,0x33,0x00,0x43,
+0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x00 ,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x35,
+0x00,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c ,0x36,0x00,0x43,0x68,0x61,0x6e,0x6e,0x65,
+0x6c,0x37,0x00,0x43,0x68,0x61,0x6e,0x6e ,0x65,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00
+      };
+
+static const gint8 LA_TxChannelNameFake[] = {
+                    0x0b,0x10,0x36,0x00 ,0x54,0x72,0x61,0x6e,0x73,0x31,0x00,0x00,
+0x00,0x54,0x72,0x61,0x6e,0x73,0x32,0x00 ,0x00,0x00,0x54,0x72,0x61,0x6e,0x73,0x33,
+0x00,0x00,0x00,0x54,0x72,0x61,0x6e,0x73 ,0x34,0x00,0x00,0x00,0x54,0x72,0x61,0x6e,
+0x73,0x35,0x00,0x00,0x00,0x54,0x72,0x61 ,0x6e,0x73,0x36,0x00,0x00,0x00
+      };
+
+static const gint8 LA_RxTemplateNameFake[] = {
+                                                                       0x35,0x10,
+0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00
+      };
+
+static const gint8 LA_TxTemplateNameFake[] = {
+          0x36,0x10,0x36,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00
+      };
+
+static const gint8 LA_DisplayOptionsFake[] = {
+                                                             0x0a,0x10,0x0a,0x01,
+0x00,0x00,0x01,0x00,0x01,0x02,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00
+      };
+
+static const gint8 LA_CyclicInformationFake[] = {
+                                                   0x09,0x10,0x1a,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+      };
+
 static gboolean lanalyzer_read(wtap *wth, int *err, long *data_offset);
-static void lanalyzer_close(wtap *wth);
+static void     lanalyzer_close(wtap *wth);
+static gboolean lanalyzer_dump_close(wtap_dumper *wdh, int *err);
 
 int lanalyzer_open(wtap *wth, int *err)
 {
@@ -74,7 +150,7 @@
 	record_type = pletohs(LE_record_type);
 	record_length = pletohs(LE_record_length); /* make sure to do this for while() loop */
 
-	if (record_type != REC_TRACE_HEADER && record_type != REC_CYCLIC_TRACE_HEADER) {  
+	if (record_type != REC_TRACE_HEADER && record_type != REC_CYCLIC_TRACE_HEADER) {
 		return 0;
 	}
 
@@ -193,7 +269,7 @@
 			default:
 				; /* no action */
 		}
-	} 
+	}
 }
 
 #define DESCRIPTOR_LEN	32
@@ -205,10 +281,10 @@
 	int		bytes_read;
 	char		LE_record_type[2];
 	char		LE_record_length[2];
-	guint16		record_type, record_length;
+	guint16	record_type, record_length;
 	gchar		descriptor[DESCRIPTOR_LEN];
-	guint16		time_low, time_med, time_high, true_size;
-	double		t;
+	guint16	time_low, time_med, time_high, true_size;
+	double	t;
 
 	/* read the record type and length. */
 	errno = WTAP_ERR_CANT_READ;
@@ -293,8 +369,294 @@
 	return TRUE;
 }
 
-static void
-lanalyzer_close(wtap *wth)
+/*---------------------------------------------------
+ *
+ *---------------------------------------------------*/
+static void lanalyzer_close(wtap *wth)
 {
 	g_free(wth->capture.lanalyzer);
 }
+
+/*---------------------------------------------------
+ * Returns 0 or error
+ * Write one block with error control
+ *---------------------------------------------------*/
+static int swrite(const void* what, guint size, FILE *hd)
+{
+	size_t nwritten;
+	
+      nwritten = fwrite(what, 1, size, hd);
+	if (nwritten != size) {
+		if (nwritten == 0 && ferror(hd))
+			return errno;
+		else
+			return WTAP_ERR_SHORT_WRITE;
+            }
+      return 0; /* ok */
+}
+
+/*---------------------------------------------------
+ *
+ * calculates C.c = A.a - B.b
+ *---------------------------------------------------*/
+static void my_timersub(const struct timeval *a,
+                        const struct timeval *b,
+                              struct timeval *c)
+{
+      gint32 usec = a->tv_usec;
+
+      c->tv_sec = a->tv_sec - b->tv_sec;
+      if (b->tv_usec > usec) {
+           c->tv_sec--;
+           usec += 1000000;
+           }
+      c->tv_usec = usec - b->tv_usec;
+}
+
+/*---------------------------------------------------
+ * Write a record for a packet to a dump file.
+ * Returns TRUE on success, FALSE on failure.
+ *---------------------------------------------------*/
+static gboolean lanalyzer_dump(wtap_dumper *wdh,
+	const struct wtap_pkthdr *phdr,
+	const union wtap_pseudo_header *pseudo_header _U_,
+	const u_char *pd, int *err)
+{
+      guint64 x;
+      int     i;
+      static LA_RecordHeader hr;
+      static LA_PacketRecord pr;
+             LA_TmpInfo *itmp = (LA_TmpInfo*)(wdh->dump.opaque);
+      struct timeval td;
+      int    thisSize = phdr->caplen + sizeof(pr) + sizeof(hr); 
+
+      if (wdh->bytes_dumped + thisSize > LA_ProFileLimit) {
+             /* printf(" LA_ProFileLimit reached\n");    */
+            *err = WTAP_ERR_SHORT_WRITE;
+            return FALSE; /* and don't forget the header */
+            }
+
+      hr.rid         = 0x1005;
+      pr.rx_channels = 0x0001;
+      pr.rx_errors   = 0x0008;
+
+      if (!itmp->init) {
+            /* collect some information for the
+             * finally written header
+             */
+            itmp->start = phdr->ts;
+            itmp->pkts  = 0;
+            itmp->init  = TRUE;
+            itmp->encap = wdh->encap;
+            }
+
+      my_timersub(&(phdr->ts),&(itmp->start),&td);
+
+      x   = td.tv_usec;
+      x  += td.tv_sec * 1000000;
+      x <<= 1;
+
+      for (i = 0; i < 3; i++, x >>= 16) {
+            pr.rx_time[i] = (x & 0xffff);
+            }
+
+      pr.pktno      = ++itmp->pkts;
+      pr.prvlen     = hr.rlen;
+      pr.rx_frm_len = phdr->len + 4;
+      pr.rx_frm_sln = phdr->caplen;
+
+      hr.rlen       = pr.rx_frm_sln +  (pr.rx_frm_sln ? sizeof(LA_PacketRecord) : 0);
+
+      *err = swrite(&hr, sizeof hr, wdh->fh);
+      if (*err)
+		return FALSE;
+      
+      *err = swrite(&pr , sizeof pr , wdh->fh);
+      if (*err)
+		return FALSE;
+
+      *err = swrite(pd , phdr->caplen , wdh->fh);
+      if (*err)
+		return FALSE;
+
+      wdh->bytes_dumped += thisSize;
+
+      return TRUE;
+}
+
+/*---------------------------------------------------
+ * Returns 0 if we could write the specified encapsulation type,
+ * an error indication otherwise.
+ *---------------------------------------------------*/
+int lanalyzer_dump_can_write_encap(int encap)
+{
+      /* Per-packet encapsulations aren't supported. */
+      if (encap == WTAP_ENCAP_PER_PACKET)
+                  return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
+
+      if ( encap != WTAP_ENCAP_ETHERNET
+        && encap != WTAP_ENCAP_TOKEN_RING )
+                  return WTAP_ERR_UNSUPPORTED_ENCAP;
+      /*
+       * printf("lanalyzer_dump_can_write_encap(%d)\n",encap);
+       */
+	return 0;
+}
+
+/*---------------------------------------------------
+ * Returns TRUE on success, FALSE on failure; sets "*err" to an
+ * error code on failure
+ *---------------------------------------------------*/
+gboolean lanalyzer_dump_open(wtap_dumper *wdh, int *err)
+{
+      int   jump;
+      void  *tmp;
+
+      /* This is a LanAlyzer file */
+
+      tmp = g_malloc(sizeof(LA_TmpInfo));
+      if (!tmp) {
+	      *err = errno;
+	      return FALSE;
+            }
+
+      ((LA_TmpInfo*)tmp)->init = FALSE;
+      wdh->dump.opaque         = tmp;
+	wdh->subtype_write       = lanalyzer_dump;
+	wdh->subtype_close       = lanalyzer_dump_close;
+
+      /* Some of the fields in the file header aren't known yet so
+       just skip over it for now.  It will be created after all
+       of the packets have been written. */
+
+      jump = sizeof (LA_HeaderRegularFake)
+           + sizeof (LA_RxChannelNameFake)
+           + sizeof (LA_TxChannelNameFake)
+           + sizeof (LA_RxTemplateNameFake)
+           + sizeof (LA_TxTemplateNameFake)
+           + sizeof (LA_DisplayOptionsFake)
+           + sizeof (LA_SummaryRecord)
+           + sizeof (LA_SubfileSummaryRecord)
+           + sizeof (LA_IndexRecord)
+           + sizeof (LA_CyclicInformationFake);
+
+      if (fseek(wdh->fh, jump, SEEK_SET) == -1) {
+	      *err = errno;
+	      return FALSE;
+            }
+      wdh->bytes_dumped = jump;
+      return TRUE;
+}
+
+/*---------------------------------------------------
+ *
+ *---------------------------------------------------*/
+static gboolean lanalyzer_dump_header(wtap_dumper *wdh, int *err)
+{
+      static LA_SummaryRecord sr;
+      static LA_SubfileSummaryRecord ssr;
+      static LA_IndexRecord sir;
+             LA_TmpInfo *itmp = (LA_TmpInfo*)(wdh->dump.opaque);
+      struct tm         *fT   = localtime(&(itmp->start.tv_sec));
+
+      /* printf("lanalyzer_dump_header pkts:%d\n",itmp->pkts); */
+      fseek(wdh->fh, 0, SEEK_SET);
+
+      *err = swrite(&LA_HeaderRegularFake,  sizeof LA_HeaderRegularFake, wdh->fh);
+      if (*err)
+		return FALSE;
+      *err = swrite(&LA_RxChannelNameFake , sizeof LA_RxChannelNameFake , wdh->fh);
+      if (*err)
+		return FALSE;
+      *err = swrite(&LA_TxChannelNameFake , sizeof LA_TxChannelNameFake , wdh->fh);
+      if (*err)
+		return FALSE;
+      *err = swrite(&LA_RxTemplateNameFake, sizeof LA_RxTemplateNameFake, wdh->fh);
+      if (*err)
+		return FALSE;
+      *err = swrite(&LA_TxTemplateNameFake, sizeof LA_TxTemplateNameFake, wdh->fh);
+      if (*err)
+		return FALSE;
+      *err = swrite(&LA_DisplayOptionsFake, sizeof LA_DisplayOptionsFake, wdh->fh);
+      if (*err)
+		return FALSE;
+
+      /*-----------------------------------------------------------------*/
+      /*fprintf(stderr,"%02d.%02d.%d %02d:%02d:%02d",
+       *    fT->tm_mday,1+fT->tm_mon,1900 + fT->tm_year,
+       *    fT->tm_hour,fT->tm_min,fT->tm_sec);
+       */
+      sr.rid              = RT_Summary;
+      sr.rlen             = sizeof (Summary);
+      sr.s.datcre.day     = fT->tm_mday;
+      sr.s.datcre.mon     = fT->tm_mon  + 1;
+      sr.s.datcre.year    = fT->tm_year + 1900;
+      sr.s.datclo.day     = fT->tm_mday;
+      sr.s.datclo.mon     = fT->tm_mon  + 1;
+      sr.s.datclo.year    = fT->tm_year + 1900;
+      sr.s.timeopn.second = fT->tm_sec;
+      sr.s.timeopn.minute = fT->tm_min;
+      sr.s.timeopn.hour   = fT->tm_hour;
+      sr.s.timeopn.day    = fT->tm_mday;
+      sr.s.timeclo.second = fT->tm_sec;
+      sr.s.timeclo.minute = fT->tm_min;
+      sr.s.timeclo.hour   = fT->tm_hour;
+      sr.s.timeclo.day    = fT->tm_mday;
+      /* EAddr  == 0      */
+      sr.s.mxseqno        = 1;
+      /* slcoff == 0      */
+      sr.s.mxslc          = 1514;
+      sr.s.totpktt        = itmp->pkts;
+      /* statrg == 0; ? -1*/
+      /* stptrg == 0; ? -1*/
+      sr.s.mxpkta[1]      = itmp->pkts;        /* *.tr1                */
+      sr.s.board_type     =  itmp->encap == WTAP_ENCAP_TOKEN_RING
+                             ? BOARD_325TR     /* Lanalyzer Board Type */
+                             : BOARD_325;      /* Lanalyzer Board Type */
+
+      /* board_version == 0 */
+
+      *err = swrite(&sr, sizeof sr, wdh->fh);
+      if (*err)
+		return FALSE;
+
+      /*-----------------------------------------------------------------*/
+      ssr.rid              = RT_SubfileSummary;
+      ssr.rlen             = sizeof(LA_SubfileSummaryRecord) - 4;
+      ssr.seqno            = 1;
+      ssr.totpktf          = itmp->pkts;
+      *err = swrite(&ssr, sizeof ssr, wdh->fh);
+      if (*err)
+		return FALSE;
+      /*-----------------------------------------------------------------*/
+      *err = swrite(&LA_CyclicInformationFake, sizeof LA_CyclicInformationFake, wdh->fh);
+      if (*err)
+		return FALSE;
+      /*-----------------------------------------------------------------*/
+      sir.rid              = RT_Index;
+      sir.rlen             = sizeof(sir) - 4;
+      sir.idxsp            = LA_IndexSize;
+
+      *err = swrite(&sir, sizeof sir, wdh->fh);
+      if (*err)
+		return FALSE;
+
+	return TRUE;
+}
+
+/*---------------------------------------------------
+ * Finish writing to a dump file.
+ * Returns TRUE on success, FALSE on failure.
+ *---------------------------------------------------*/
+static gboolean lanalyzer_dump_close(wtap_dumper *wdh, int *err)
+{
+      if (wdh->dump.opaque) {
+            lanalyzer_dump_header(wdh,err);
+            g_free(wdh->dump.opaque);
+            wdh->dump.opaque = 0;
+            }
+      return *err ? FALSE : TRUE;
+}
+
+
+
Index: wiretap/lanalyzer.h
===================================================================
RCS file: /cvsroot/ethereal/wiretap/lanalyzer.h,v
retrieving revision 1.5
diff -u -r1.5 lanalyzer.h
--- lanalyzer.h	2001/11/13 23:55:43	1.5
+++ lanalyzer.h	2002/06/26 06:01:05
@@ -4,17 +4,17 @@
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xxxxxxxxxxxxxxx>
- * 
+ *
  * 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.
@@ -23,7 +23,118 @@
 
 #ifndef __LANALYZER_H__
 #define __LANALYZER_H__
+
+/*    Record type codes:                */
+
+#define     RT_HeaderRegular       0x1001
+#define     RT_HeaderCyclic        0x1007
+#define     RT_RxChannelName       0x1006
+#define     RT_TxChannelName       0x100b
+#define     RT_FilterName          0x1032
+#define     RT_RxTemplateName      0x1035
+#define     RT_TxTemplateName      0x1036
+#define     RT_DisplayOptions      0x100a
+#define     RT_Summary             0x1002
+#define     RT_SubfileSummary      0x1003
+#define     RT_CyclicInformation   0x1009
+#define     RT_Index               0x1004
+#define     RT_PacketData          0x1005
+
+#define     LA_ProFileLimit       (1024 * 1024 * 32)
+
+typedef guint8  Eadr[6];
+typedef guint16 TimeStamp[3];  /* 0.5 microseconds since start of trace */
+
+#pragma pack(2)
+
+typedef struct {
+      guint8      day;
+      guint8      mon;
+      gint16      year;
+      } Date;
+
+typedef struct {
+      guint8      second;
+      guint8      minute;
+      guint8      hour;
+      guint8      day;
+      gint16      reserved;
+      } Time;
+
+typedef struct {
+      guint16     rx_channels;
+      guint16     rx_errors;
+      gint16      rx_frm_len;
+      gint16      rx_frm_sln;
+      TimeStamp   rx_time;
+      guint32     pktno;
+      gint16      prvlen;
+      gint16      offset;
+      gint16      tx_errs;
+      gint16      rx_filters;
+      gint8       unused[2];
+      gint16      hwcolls;
+      gint16      hwcollschans;
+      /*          Packetdata ....; */
+      } LA_PacketRecord;
+
+typedef struct {
+      Date        datcre;
+      Date        datclo;
+      Time        timeopn;
+      Time        timeclo;
+      Eadr        statadr;
+      gint16      mxseqno;
+      gint16      slcoff;
+      gint16      mxslc;
+      gint32      totpktt;
+      gint32      statrg;
+      gint32      stptrg;
+      gint32      mxpkta[36];
+      gint16      board_type;
+      gint16      board_version;
+      gint8       reserved[18];
+      } Summary;
+
+typedef struct {
+      gint16      rid;
+      gint16      rlen;
+      Summary     s;
+      } LA_SummaryRecord;
+
+typedef struct {
+      gint16      rid;
+      gint16      rlen;
+      gint16      seqno;
+      gint32      totpktf;
+      } LA_SubfileSummaryRecord;
+
+#define LA_IndexSize 500
+
+typedef struct {
+      gint16      rid;
+      gint16      rlen;
+      gint16      idxsp;                    /* = LA_IndexSize */
+      gint16      idxct;
+      gint8       idxgranu;
+      gint8       idxvd;
+      gint32      trcidx[LA_IndexSize + 2]; /* +2 undocumented but used by La 2.2 */
+      } LA_IndexRecord;
+
+typedef struct {
+      gint16      rid;
+      gint16      rlen;
+      } LA_RecordHeader;
+
+typedef struct {
+      gboolean        init;
+      struct timeval  start;
+      guint32         pkts;
+      int             encap;
+      } LA_TmpInfo;
 
-int lanalyzer_open(wtap *wth, int *err);
+int         lanalyzer_open(wtap *wth, int *err);
+gboolean    lanalyzer_dump_open(wtap_dumper *wdh, int *err);
+int         lanalyzer_dump_can_write_encap(int encap);
 
 #endif
Index: wiretap/snoop.c
===================================================================
RCS file: /cvsroot/ethereal/wiretap/snoop.c,v
retrieving revision 1.52
diff -u -r1.52 snoop.c
--- snoop.c	2002/06/07 07:27:35	1.52
+++ snoop.c	2002/06/26 06:01:06
@@ -4,17 +4,17 @@
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xxxxxxxxxxxxxxx>
- * 
+ *
  * 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.
@@ -78,7 +78,7 @@
 
 /*
  * See
- * 
+ *
  *	http://www.opengroup.org/onlinepubs/9638599/apdxf.htm
  *
  * for the "dlpi.h" header file specified by The Open Group, which lists
Index: wiretap/visual.c
===================================================================
RCS file: /cvsroot/ethereal/wiretap/visual.c,v
retrieving revision 1.8
diff -u -r1.8 visual.c
--- visual.c	2002/06/07 07:27:35	1.8
+++ visual.c	2002/06/26 06:01:06
@@ -6,17 +6,17 @@
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xxxxxxxxxxxxxxx>
- * 
+ *
  * 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.
@@ -228,7 +228,7 @@
     /* Check for the end of the packet data.  Note that a check for file EOF
        will not work because there are index values stored after the last
        packet's data. */
-    if (visual->current_pkt > visual->num_pkts) 
+    if (visual->current_pkt > visual->num_pkts)
     {
         *err = 0;   /* it's just an EOF, not an error */
         return FALSE;
@@ -238,10 +238,10 @@
     /* Read the packet header. */
     errno = WTAP_ERR_CANT_READ;
     bytes_read = file_read(&vpkt_hdr, 1, phdr_size, wth->fh);
-    if (bytes_read != phdr_size) 
+    if (bytes_read != phdr_size)
     {
         *err = file_error(wth->fh);
-        if (*err == 0 && bytes_read != 0) 
+        if (*err == 0 && bytes_read != 0)
         {
             *err = WTAP_ERR_SHORT_READ;
         }
@@ -251,7 +251,7 @@
 
     /* Read the packet data. */
     packet_size = pletohs(&vpkt_hdr.incl_len);
-    if (packet_size > WTAP_MAX_PACKET_SIZE) 
+    if (packet_size > WTAP_MAX_PACKET_SIZE)
     {
         /* Probably a corrupt capture file; don't blow up trying
           to allocate space for an immensely-large packet. */
@@ -266,7 +266,7 @@
     bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1,
             packet_size, wth->fh);
 
-    if (bytes_read != (int) packet_size) 
+    if (bytes_read != (int) packet_size)
     {
         *err = file_error(wth->fh);
         if (*err == 0)
@@ -329,7 +329,7 @@
 /* Read packet data for random access.
    This gets the packet data and rebuilds the pseudo header so that
    the direction flag works. */
-static gboolean visual_seek_read (wtap *wth, long seek_off, 
+static gboolean visual_seek_read (wtap *wth, long seek_off,
     union wtap_pseudo_header *pseudo_header, guint8 *pd, int len, int *err)
 {
     struct visual_pkt_hdr vpkt_hdr;
@@ -383,7 +383,7 @@
 }
 
 
-/* Check for media types that may be written in Visual file format. 
+/* Check for media types that may be written in Visual file format.
    Returns 0 if the specified encapsulation type is supported,
    an error indication otherwise. */
 int visual_dump_can_write_encap(int encap)
@@ -465,7 +465,7 @@
        file header.  Each packet has a capture time (in msec) relative
        to the file start time.  Use the time of the first packet as the
        file start time. */
-    if (visual->index_table_index == 0) 
+    if (visual->index_table_index == 0)
     {
         /* This is the first packet.  Save its start time as the file time. */
         visual->start_time = phdr->ts.tv_sec;
@@ -474,7 +474,7 @@
         visual->index_table = g_malloc(1024 * sizeof *visual->index_table);
         visual->index_table_size = 1024;
     }
-    
+
     /* Calculate milliseconds since capture start. */
     delta_msec = phdr->ts.tv_usec / 1000;
     delta_msec += (phdr->ts.tv_sec - visual->start_time) * 1000;
@@ -488,20 +488,20 @@
     switch (wdh->encap)
     {
     case WTAP_ENCAP_ETHERNET:   /* Ethernet */
-        vpkt_hdr.encap_hint = 2;    
+        vpkt_hdr.encap_hint = 2;
         break;
     case WTAP_ENCAP_TOKEN_RING: /* Token Ring */
-        vpkt_hdr.encap_hint = 3;    
+        vpkt_hdr.encap_hint = 3;
         break;
     case WTAP_ENCAP_PPP:        /* PPP */
     case WTAP_ENCAP_PPP_WITH_PHDR:
-        vpkt_hdr.encap_hint = 14;   
+        vpkt_hdr.encap_hint = 14;
         break;
     case WTAP_ENCAP_CHDLC:      /* HDLC Router */
-        vpkt_hdr.encap_hint = 13;   
+        vpkt_hdr.encap_hint = 13;
         break;
     case WTAP_ENCAP_FRELAY:     /* Frame Relay Auto-detect */
-        vpkt_hdr.encap_hint = 12;   
+        vpkt_hdr.encap_hint = 12;
         break;
     case WTAP_ENCAP_LAPB:       /* Unknown */
     default:
@@ -530,7 +530,7 @@
 
     /* Write the packet header. */
     nwritten = fwrite(&vpkt_hdr, 1, hdr_size, wdh->fh);
-    if (nwritten != hdr_size) 
+    if (nwritten != hdr_size)
     {
         if (nwritten == 0 && ferror(wdh->fh))
             *err = errno;
@@ -541,7 +541,7 @@
 
     /* Write the packet data */
     nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
-    if (nwritten != phdr->caplen) 
+    if (nwritten != phdr->caplen)
     {
         if (nwritten == 0 && ferror(wdh->fh))
             *err = errno;
@@ -551,7 +551,7 @@
     }
 
     /* Store the frame offset in the index table. */
-    if (visual->index_table_index >= visual->index_table_size) 
+    if (visual->index_table_index >= visual->index_table_size)
     {
         /* End of table reached.  Reallocate with a larger size */
         visual->index_table_size *= 2;
@@ -590,7 +590,7 @@
         /* Write the index table to the file. */
         n_to_write = visual->index_table_index * sizeof *visual->index_table;
         nwritten = fwrite(visual->index_table, 1, n_to_write, wdh->fh);
-        if (nwritten != n_to_write) 
+        if (nwritten != n_to_write)
         {
             if (err != NULL)
             {
@@ -645,7 +645,7 @@
 
     /* Write the file header following the magic bytes. */
     nwritten = fwrite(&vfile_hdr, 1, sizeof vfile_hdr, wdh->fh);
-    if (nwritten != sizeof vfile_hdr) 
+    if (nwritten != sizeof vfile_hdr)
     {
         if (err != NULL)
         {

Attachment: lanalyzer2b.patch.zip
Description: Binary data