Ethereal-dev: [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: Tue, 25 Jun 2002 13:34:46 +0200
Hi,

I've (hopefully) done the suggestions from Guy Harris (thanks),
tested successfully sliced packets and added TokenRing support
and DumpFile size limitation to LA limit of 32Mb per file.

If there should anybody in this universe, who is really interested
in bigger traces for the Novell Lanalyzer, he must divide the
Traces per hand (save marked) or I have to add the LA multifile
support ( .tr1, .tr2,..., .trZ).

Looking forward to your comments
regards

		Markus
__________________________________________________________________

Markus Steinmann                                         ms@xxxxxx
Software Development
SEH Computertechnik GmbH Bielefeld               http://www.seh.de
__________________________________________________________________
Index: wiretap/file.c
===================================================================
RCS file: /cvsroot/ethereal/wiretap/file.c,v
retrieving revision 1.92
diff -r1.92 file.c
7c7
<  *
---
>  *
12c12
<  *
---
>  *
17c17
<  *
---
>  *
346,347c346,347
< 	{ "Novell LANalyzer", NULL,
< 	  NULL, NULL },
---
> 	{ "Novell LanAlyzer","lanalyzer",
> 	  lanalyzer_dump_can_write_encap, lanalyzer_dump_open },
Index: wiretap/lanalyzer.c
===================================================================
RCS file: /cvsroot/ethereal/wiretap/lanalyzer.c,v
retrieving revision 1.33
diff -r1.33 lanalyzer.c
7c7
<  *
---
>  *
12c12
<  *
---
>  *
17c17
<  *
---
>  *
49a50,124
> 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
>       };
>
51c126,127
< static void lanalyzer_close(wtap *wth);
---
> static void     lanalyzer_close(wtap *wth);
> static gboolean lanalyzer_dump_close(wtap_dumper *wdh, int *err);
77c153
< 	if (record_type != REC_TRACE_HEADER && record_type != REC_CYCLIC_TRACE_HEADER) {
---
> 	if (record_type != REC_TRACE_HEADER && record_type != REC_CYCLIC_TRACE_HEADER) {
196c272
< 	}
---
> 	}
208c284
< 	guint16		record_type, record_length;
---
> 	guint16	record_type, record_length;
210,211c286,287
< 	guint16		time_low, time_med, time_high, true_size;
< 	double		t;
---
> 	guint16	time_low, time_med, time_high, true_size;
> 	double	t;
296,297c372,375
< static void
< lanalyzer_close(wtap *wth)
---
> /*---------------------------------------------------
>  *
>  *---------------------------------------------------*/
> static void lanalyzer_close(wtap *wth)
300a379,662
>
> /*---------------------------------------------------
>  * 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 -r1.5 lanalyzer.h
7c7
<  *
---
>  *
12c12
<  *
---
>  *
17c17
<  *
---
>  *
27c27,138
< int lanalyzer_open(wtap *wth, int *err);
---
> /*    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);
> gboolean    lanalyzer_dump_open(wtap_dumper *wdh, int *err);
> int         lanalyzer_dump_can_write_encap(int encap);

Attachment: lanalyzer2.zip
Description: Binary data