Ethereal-dev: Re: [ethereal-dev] wiretap request - if it's not too much trouble

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

From: Olivier Abad <abad@xxxxxxxxxxxxx>
Date: Thu, 9 Dec 1999 11:39:58 +0100
On Wed, Dec 08, 1999 at 04:46:57PM -0700, Eichert, Diana wrote:
> I've got SnifferPro here, so i'd be interested in looking at it.
> 
> BTW, I am one of the people that requested this ability, thanks for the
> work.
> 
> diana eichert

Here is the patch. It doesn't include ATM support, and was tested only
with X.25 captures.
I used 4.40 as the version in the REC_VERS record. It is the version of
my DOS based sniffer, but it doesn't seem to work.
I noticed two records between the REC_VERS and the first REC_FRAME2 in
the files written by my sniffer. However, these record types (07 and 06)
are not documented.

Olivier

diff -Nru ethereal/wiretap/file.c ethereal.sniff/wiretap/file.c
--- ethereal/wiretap/file.c	Mon Dec  6 10:05:16 1999
+++ ethereal.sniff/wiretap/file.c	Thu Dec  9 11:03:25 1999
@@ -199,8 +199,8 @@
 	  NULL, NULL },
 
 	/* WTAP_FILE_NGSNIFFER */
-	{ "Network Associates Sniffer (DOS-based)", NULL,
-	  NULL, NULL },
+	{ "Network Associates Sniffer (DOS-based)", "ngsniffer",
+	  ngsniffer_dump_can_write_encap, ngsniffer_dump_open },
 
 	/* WTAP_FILE_SNOOP */
 	{ "Sun snoop", "snoop",
diff -Nru ethereal/wiretap/ngsniffer.c ethereal.sniff/wiretap/ngsniffer.c
--- ethereal/wiretap/ngsniffer.c	Mon Nov 29 09:00:58 1999
+++ ethereal.sniff/wiretap/ngsniffer.c	Thu Dec  9 11:03:18 1999
@@ -62,6 +62,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <time.h>
+#include <string.h>
 #include "wtap.h"
 #include "file.h"
 #include "buffer.h"
@@ -240,6 +241,9 @@
 static double Usec[] = { 15.0, 0.838096, 15.0, 0.5, 2.0, 1.0, 0.1 };
 
 static int ngsniffer_read(wtap *wth, int *err);
+static gboolean ngsniffer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
+	const u_char *pd, int *err);
+static gboolean ngsniffer_dump_close(wtap_dumper *wdh, int *err);
 
 int ngsniffer_open(wtap *wth, int *err)
 {
@@ -627,4 +631,173 @@
 			*1.0e6);
 	wth->phdr.pkt_encap = wth->file_encap;
 	return data_offset;
+}
+
+static const int wtap_encap[] = {
+    -1,		/* WTAP_ENCAP_UNKNOWN -> unsupported */
+    1,		/* WTAP_ENCAP_ETHERNET */
+    0,		/* WTAP_ENCAP_TR */
+    -1,		/* WTAP_ENCAP_SLIP -> unsupported */
+    7,		/* WTAP_ENCAP_PPP -> Internetwork analyzer (synchronous) FIXME ! */
+    -1,		/* WTAP_ENCAP_FDDI -> unsupported */
+    9,		/* WTAP_ENCAP_FDDI_BITSWAPPED */
+    -1,		/* WTAP_ENCAP_RAW_IP -> unsupported */
+    2,		/* WTAP_ENCAP_ARCNET */
+    -1,		/* WTAP_ENCAP_ATM_RFC1483 */
+    -1,		/* WTAP_ENCAP_LINUX_ATM_CLIP */
+    7,		/* WTAP_ENCAP_LAPB -> Internetwork analyzer (synchronous) */
+    -1,		/* WTAP_ENCAP_ATM_SNIFFER */
+    -1		/* WTAP_ENCAP_NULL -> unsupported */
+};
+#define NUM_WTAP_ENCAPS (sizeof wtap_encap / sizeof wtap_encap[0])
+
+/* Returns 0 if we could write the specified encapsulation type,
+   an error indication otherwise. */
+int ngsniffer_dump_can_write_encap(int filetype, int encap)
+{
+    /* Per-packet encapsulations aren't supported. */
+    if (encap == WTAP_ENCAP_PER_PACKET)
+	return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
+
+    if (encap < 0 || encap >= NUM_WTAP_ENCAPS || wtap_encap[encap] == -1)
+	return WTAP_ERR_UNSUPPORTED_ENCAP;
+
+    return 0;
+}
+
+/* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
+   failure */
+gboolean ngsniffer_dump_open(wtap_dumper *wdh, int *err)
+{
+    struct vers_rec version;
+    int nwritten;
+    char buf[6] = {0x01, 0x00, 0x12, 0x00, 0x00, 0x00}; /* version record */
+    gint16 maj_vers, min_vers;
+
+    /* This is a sniffer file */
+    wdh->subtype_write = ngsniffer_dump;
+    wdh->subtype_close = ngsniffer_dump_close;
+
+    /* Write the file header. */
+    nwritten = fwrite("TRSNIFF data    \x1a", 1, 17, wdh->fh);
+    if (nwritten != 17) {
+	if (nwritten < 0)
+	    *err = errno;
+	else
+	    *err = WTAP_ERR_SHORT_WRITE;
+	return FALSE;
+    }
+    nwritten = fwrite(buf, 1, 6, wdh->fh);
+    if (nwritten != 6) {
+	if (nwritten < 0)
+	    *err = errno;
+	else
+	    *err = WTAP_ERR_SHORT_WRITE;
+	return FALSE;
+    }
+
+    /* "sniffer" version ? */
+    maj_vers = 4;
+    min_vers = 40;
+    version.maj_vers = pletohs(&maj_vers);
+    version.min_vers = pletohs(&min_vers);
+    version.time = 0;
+    version.date = 0;
+    version.type = 4;
+    version.network = wtap_encap[wdh->encap];
+    version.format = 1;
+    version.timeunit = 1; /* 0.838096 */
+    version.cmprs_vers = 0;
+    version.cmprs_level = 0;
+    version.rsvd[0] = 0;
+    version.rsvd[1] = 0;
+    nwritten = fwrite(&version, 1, sizeof version, wdh->fh);
+    if (nwritten != sizeof version) {
+	if (nwritten < 0)
+	    *err = errno;
+	else
+	    *err = WTAP_ERR_SHORT_WRITE;
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+/* Write a record for a packet to a dump file.
+   Returns TRUE on success, FALSE on failure. */
+static gboolean ngsniffer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
+    const u_char *pd, int *err)
+{
+    struct frame2_rec rec_hdr;
+    int nwritten;
+    char buf[6];
+    double t;
+    guint16 t_low, t_med, t_high;
+
+    buf[0] = 0x04;
+    buf[1] = 0x00;
+    buf[2] = (char)((phdr->caplen + sizeof(struct frame2_rec))%256);
+    buf[3] = (char)((phdr->caplen + sizeof(struct frame2_rec))/256);
+    buf[4] = 0x00;
+    buf[5] = 0x00;
+    nwritten = fwrite(buf, 1, 6, wdh->fh);
+    if (nwritten != 6) {
+	if (nwritten < 0)
+	    *err = errno;
+	else
+	    *err = WTAP_ERR_SHORT_WRITE;
+	return FALSE;
+    }
+    t = (double)phdr->ts.tv_sec + (double)phdr->ts.tv_usec/1.0e6;
+    t = t * (1.0e6 / Usec[1]); /* timeunit = 1 */
+    t_low = (guint16)(t-(double)((guint32)(t/65536.0))*65536.0);
+    t_med = (guint16)((guint32)(t/65536.0) % 65536);
+    t_high = (guint16)((guint32)(t/4294967296.0));
+    rec_hdr.time_low = pletohs(&t_low);
+    rec_hdr.time_med = pletohs(&t_med);
+    rec_hdr.time_high = pletohs(&t_high);
+    rec_hdr.size = pletohs(&phdr->caplen);
+    if (wdh->encap == WTAP_ENCAP_LAPB || wdh->encap == WTAP_ENCAP_PPP)
+	rec_hdr.fs = phdr->pseudo_header.x25.flags & 0x80;
+    else
+	rec_hdr.fs = 0;
+    rec_hdr.flags = 0;
+    rec_hdr.true_size = phdr->len != phdr->caplen ? pletohs(&phdr->len) : 0;
+    rec_hdr.rsvd = 0;
+    nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, wdh->fh);
+    if (nwritten != sizeof rec_hdr) {
+	if (nwritten < 0)
+	    *err = errno;
+	else
+	    *err = WTAP_ERR_SHORT_WRITE;
+	return FALSE;
+    }
+    nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
+    if (nwritten != phdr->caplen) {
+	if (nwritten < 0)
+	    *err = errno;
+	else
+	    *err = WTAP_ERR_SHORT_WRITE;
+	return FALSE;
+    }
+    return TRUE;
+}
+
+/* Finish writing to a dump file.
+   Returns TRUE on success, FALSE on failure. */
+static gboolean ngsniffer_dump_close(wtap_dumper *wdh, int *err)
+{
+    /* EOF record */
+    char buf[6] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+    int nwritten;
+
+    nwritten = fwrite(buf, 1, 6, wdh->fh);
+    if (nwritten != 6) {
+	if (nwritten < 0)
+	    *err = errno;
+	else
+	    *err = WTAP_ERR_SHORT_WRITE;
+	return FALSE;
+    }
+    return TRUE;
 }
diff -Nru ethereal/wiretap/ngsniffer.h ethereal.sniff/wiretap/ngsniffer.h
--- ethereal/wiretap/ngsniffer.h	Thu Aug 19 07:52:55 1999
+++ ethereal.sniff/wiretap/ngsniffer.h	Thu Dec  9 11:03:18 1999
@@ -22,3 +22,5 @@
  */
 
 int ngsniffer_open(wtap *wth, int *err);
+gboolean ngsniffer_dump_open(wtap_dumper *wdh, int *err);
+int ngsniffer_dump_can_write_encap(int filetype, int encap);


-- 
There are two kinds of egotists: 1) Those who admit it  2) The rest of us