In a Network Monitor capture file, get the starting offsets of frames

from the frame table - Network Monitor 2.x, at least, doesn't always
write frame N+1 right after frame N.

To do that, we need to mallocate a big array to hold the frame table,
and free it when we close the capture file; this requires that we have
capture-file-type-specific close routines as well as
capture-file-type-specific read routines - we let it the pointer to that
routine be null if it's not needed.  Given that, we might as well get
rid of the switch statement in "wtap_close()", in favor of using
capture-file-type-specific close routines, as per the comment before
that switch statement.

svn path=/trunk/; revision=1740
This commit is contained in:
Guy Harris 2000-03-22 07:06:59 +00:00
parent 8d47efa6f9
commit 005588b8b9
11 changed files with 124 additions and 86 deletions

View File

@ -1,6 +1,6 @@
/* ascend.c
*
* $Id: ascend.c,v 1.12 2000/01/22 06:22:35 guy Exp $
* $Id: ascend.c,v 1.13 2000/03/22 07:06:56 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@ -82,6 +82,7 @@ static const char ascend_w2magic[] = { 'W', 'D', '_', 'D', 'I', 'A', 'L', 'O', '
#define ASCEND_W2_SIZE (sizeof ascend_w2magic / sizeof ascend_w2magic[0])
static int ascend_read(wtap *wth, int *err);
static void ascend_close(wtap *wth);
/* Seeks to the beginning of the next packet, and returns the
byte offset. Returns -1 on failure. A valid offset is 0; since
@ -149,6 +150,7 @@ int ascend_open(wtap *wth, int *err)
wth->file_type = WTAP_FILE_ASCEND;
wth->snapshot_length = ASCEND_MAX_PKT_LEN;
wth->subtype_read = ascend_read;
wth->subtype_close = ascend_close;
wth->capture.ascend = g_malloc(sizeof(ascend_t));
/* MAXen and Pipelines report the time since reboot. In order to keep
@ -212,3 +214,8 @@ int ascend_seek_read (FILE *fh, int seek_off, guint8 *pd, int len)
file_seek(fh, seek_off - 1, SEEK_SET);
return parse_ascend(fh, pd, NULL, NULL, len);
}
static void ascend_close(wtap *wth)
{
g_free(wth->capture.ascend);
}

View File

@ -1,6 +1,6 @@
/* file.c
*
* $Id: file.c,v 1.48 2000/02/03 06:29:07 guy Exp $
* $Id: file.c,v 1.49 2000/03/22 07:06:58 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@ -151,6 +151,7 @@ wtap* wtap_open_offline(const char *filename, int *err)
/* initialization */
wth->file_encap = WTAP_ENCAP_UNKNOWN;
wth->data_offset = 0;
wth->subtype_close = NULL;
/* Try all file types */
for (i = 0; i < N_FILE_TYPES; i++) {

View File

@ -1,6 +1,6 @@
/* lanalyzer.c
*
* $Id: lanalyzer.c,v 1.20 2000/01/22 06:22:38 guy Exp $
* $Id: lanalyzer.c,v 1.21 2000/03/22 07:06:58 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@ -49,6 +49,7 @@
#define BOARD_325TR 227 /* LANalyzer 325TR (Token-ring) */
static int lanalyzer_read(wtap *wth, int *err);
static void lanalyzer_close(wtap *wth);
int lanalyzer_open(wtap *wth, int *err)
{
@ -86,6 +87,7 @@ int lanalyzer_open(wtap *wth, int *err)
wth->file_type = WTAP_FILE_LANALYZER;
wth->capture.lanalyzer = g_malloc(sizeof(lanalyzer_t));
wth->subtype_read = lanalyzer_read;
wth->subtype_close = lanalyzer_close;
wth->snapshot_length = 0;
/* Read records until we find the start of packets */
@ -294,3 +296,9 @@ static int lanalyzer_read(wtap *wth, int *err)
return data_offset;
}
static void
lanalyzer_close(wtap *wth)
{
g_free(wth->capture.lanalyzer);
}

View File

@ -1,6 +1,6 @@
/* libpcap.c
*
* $Id: libpcap.c,v 1.32 2000/02/19 08:00:06 guy Exp $
* $Id: libpcap.c,v 1.33 2000/03/22 07:06:58 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@ -88,6 +88,7 @@ struct pcaprec_modified_hdr {
static int libpcap_read(wtap *wth, int *err);
static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr);
static void libpcap_close(wtap *wth);
static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
const u_char *pd, int *err);
@ -259,6 +260,7 @@ int libpcap_open(wtap *wth, int *err)
wth->capture.pcap->version_major = hdr.version_major;
wth->capture.pcap->version_minor = hdr.version_minor;
wth->subtype_read = libpcap_read;
wth->subtype_close = libpcap_close;
wth->file_encap = pcap_encap[hdr.network];
wth->snapshot_length = hdr.snaplen;
@ -454,6 +456,12 @@ adjust_header(wtap *wth, struct pcaprec_hdr *hdr)
}
}
static void
libpcap_close(wtap *wth)
{
g_free(wth->capture.pcap);
}
int wtap_pcap_encap_to_wtap_encap(int encap)
{
if (encap < 0 || encap >= NUM_PCAP_ENCAPS)

View File

@ -1,6 +1,6 @@
/* netmon.c
*
* $Id: netmon.c,v 1.25 2000/02/19 08:00:05 guy Exp $
* $Id: netmon.c,v 1.26 2000/03/22 07:06:54 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@ -95,6 +95,7 @@ struct netmonrec_2_x_hdr {
};
static int netmon_read(wtap *wth, int *err);
static void netmon_close(wtap *wth);
static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
const u_char *pd, int *err);
static gboolean netmon_dump_close(wtap_dumper *wdh, int *err);
@ -121,8 +122,8 @@ int netmon_open(wtap *wth, int *err)
};
#define NUM_NETMON_ENCAPS (sizeof netmon_encap / sizeof netmon_encap[0])
struct tm tm;
int frame_table_offset;
guint32 frame_table_length;
guint32 first_frame_table_entry;
/* Read in the string that should be at the start of a Network
* Monitor file */
@ -180,6 +181,7 @@ int netmon_open(wtap *wth, int *err)
wth->file_type = file_type;
wth->capture.netmon = g_malloc(sizeof(netmon_t));
wth->subtype_read = netmon_read;
wth->subtype_close = netmon_close;
wth->file_encap = netmon_encap[hdr.network];
wth->snapshot_length = 16384; /* XXX - not available in header */
/*
@ -213,48 +215,49 @@ int netmon_open(wtap *wth, int *err)
wth->capture.netmon->version_major = hdr.ver_major;
/*
* The "frame index table" appears to come after the last
* packet; remember its offset, so we know when we have no
* more packets to read.
* Get the offset of the frame index table.
*/
wth->capture.netmon->end_offset = pletohl(&hdr.frametableoffset);
frame_table_offset = pletohl(&hdr.frametableoffset);
/*
* It appears that some NetMon 2.x files don't have the
* first packet starting exactly 128 bytes into the file.
* So we read the first entry from the frame table, and
* use that as the offset of the first packet.
*
* First, make sure the frame table has at least one entry
* in it....
* Furthermore, it also appears that there are "holes" in
* the file, i.e. frame N+1 doesn't always follow immediately
* after frame N.
*
* Therefore, we must read the frame table, and use the offsets
* in it as the offsets of the frames.
*/
frame_table_length = pletohl(&hdr.frametablelength);
if (frame_table_length < sizeof first_frame_table_entry) {
wth->capture.netmon->frame_table_size = frame_table_length / sizeof (guint32);
if ((wth->capture.netmon->frame_table_size * sizeof (guint32)) != frame_table_length) {
g_message("netmon: frame table length is %u, which is not a multiple of the size of an entry",
frame_table_length);
*err = WTAP_ERR_UNSUPPORTED;
return -1;
}
if (wth->capture.netmon->frame_table_size == 0) {
g_message("netmon: frame table length is %u, which means it's less than one entry in size",
frame_table_length);
*err = WTAP_ERR_UNSUPPORTED;
return -1;
}
/*
* Now read that entry. (It appears that the N+1st frame immediately
* follows the Nth frame, so we don't need any entries after the
* first entry.)
*/
wth->capture.netmon->frame_table = g_malloc(frame_table_length);
errno = WTAP_ERR_CANT_READ;
file_seek(wth->fh, wth->capture.netmon->end_offset, SEEK_SET);
bytes_read = file_read(&first_frame_table_entry, 1,
sizeof first_frame_table_entry, wth->fh);
if (bytes_read != sizeof first_frame_table_entry) {
file_seek(wth->fh, frame_table_offset, SEEK_SET);
bytes_read = file_read(wth->capture.netmon->frame_table, 1,
frame_table_length, wth->fh);
if (bytes_read != frame_table_length) {
*err = file_error(wth->fh);
if (*err != 0)
return -1;
return 0;
}
/* Seek to the beginning of the data records. */
wth->data_offset = pletohl(&first_frame_table_entry);
file_seek(wth->fh, wth->data_offset, SEEK_SET);
/* Set up to start reading at the first frame. */
wth->capture.netmon->current_frame = 0;
return 1;
}
@ -262,6 +265,7 @@ int netmon_open(wtap *wth, int *err)
/* Read the next packet */
static int netmon_read(wtap *wth, int *err)
{
netmon_t *netmon = wth->capture.netmon;
guint32 packet_size = 0;
int bytes_read;
union {
@ -275,12 +279,24 @@ static int netmon_read(wtap *wth, int *err)
double t;
/* Have we reached the end of the packet data? */
if (wth->data_offset >= wth->capture.netmon->end_offset) {
if (netmon->current_frame >= netmon->frame_table_size) {
/* Yes. */
return 0;
}
/* Seek to the beginning of the current record, if we're
not there already (seeking to the current position
may still cause a seek and a read of the underlying file,
so we don't want to do it unconditionally). */
data_offset = netmon->frame_table[netmon->current_frame];
if (wth->data_offset != data_offset) {
wth->data_offset = data_offset;
file_seek(wth->fh, wth->data_offset, SEEK_SET);
}
netmon->current_frame++;
/* Read record header. */
switch (wth->capture.netmon->version_major) {
switch (netmon->version_major) {
case 1:
hdr_size = sizeof (struct netmonrec_1_x_hdr);
@ -291,6 +307,7 @@ static int netmon_read(wtap *wth, int *err)
break;
}
errno = WTAP_ERR_CANT_READ;
bytes_read = file_read(&hdr, 1, hdr_size, wth->fh);
if (bytes_read != hdr_size) {
*err = file_error(wth->fh);
@ -304,7 +321,7 @@ static int netmon_read(wtap *wth, int *err)
}
wth->data_offset += hdr_size;
switch (wth->capture.netmon->version_major) {
switch (netmon->version_major) {
case 1:
packet_size = pletohs(&hdr.hdr_1_x.incl_len);
@ -338,8 +355,8 @@ static int netmon_read(wtap *wth, int *err)
}
wth->data_offset += packet_size;
t = (double)wth->capture.netmon->start_usecs;
switch (wth->capture.netmon->version_major) {
t = (double)netmon->start_usecs;
switch (netmon->version_major) {
case 1:
t += ((double)pletohl(&hdr.hdr_1_x.ts_delta))*1000;
@ -352,10 +369,10 @@ static int netmon_read(wtap *wth, int *err)
}
secs = (time_t)(t/1000000);
usecs = (guint32)(t - secs*1000000);
wth->phdr.ts.tv_sec = wth->capture.netmon->start_secs + secs;
wth->phdr.ts.tv_sec = netmon->start_secs + secs;
wth->phdr.ts.tv_usec = usecs;
wth->phdr.caplen = packet_size;
switch (wth->capture.netmon->version_major) {
switch (netmon->version_major) {
case 1:
wth->phdr.len = pletohs(&hdr.hdr_1_x.orig_len);
@ -370,6 +387,13 @@ static int netmon_read(wtap *wth, int *err)
return data_offset;
}
static void
netmon_close(wtap *wth)
{
g_free(wth->capture.netmon->frame_table);
g_free(wth->capture.netmon);
}
static const int wtap_encap[] = {
-1, /* WTAP_ENCAP_UNKNOWN -> unsupported */
1, /* WTAP_ENCAP_ETHERNET -> NDIS Ethernet */

View File

@ -1,6 +1,6 @@
/* nettl.c
*
* $Id: nettl.c,v 1.8 2000/03/01 10:25:14 oabad Exp $
* $Id: nettl.c,v 1.9 2000/03/22 07:06:56 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@ -67,6 +67,7 @@ struct nettlrec_ns_ls_ip_hdr {
/* header is followed by data and once again the total length (2 bytes) ! */
static int nettl_read(wtap *wth, int *err);
static void nettl_close(wtap *wth);
int nettl_open(wtap *wth, int *err)
{
@ -110,6 +111,7 @@ int nettl_open(wtap *wth, int *err)
wth->file_type = WTAP_FILE_NETTL;
wth->capture.nettl = g_malloc(sizeof(nettl_t));
wth->subtype_read = nettl_read;
wth->subtype_close = nettl_close;
wth->snapshot_length = 16384; /* not available in header, only in frame */
wth->capture.nettl->start = 0;
@ -268,3 +270,8 @@ static int nettl_read(wtap *wth, int *err)
}
return data_offset;
}
static void nettl_close(wtap *wth)
{
g_free(wth->capture.nettl);
}

View File

@ -1,6 +1,6 @@
/* netxray.c
*
* $Id: netxray.c,v 1.24 2000/02/19 08:00:04 guy Exp $
* $Id: netxray.c,v 1.25 2000/03/22 07:06:55 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@ -91,6 +91,7 @@ struct netxrayrec_2_x_hdr {
};
static int netxray_read(wtap *wth, int *err);
static void netxray_close(wtap *wth);
static gboolean netxray_dump_1_1(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
const u_char *pd, int *err);
static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err);
@ -186,6 +187,7 @@ int netxray_open(wtap *wth, int *err)
wth->file_type = file_type;
wth->capture.netxray = g_malloc(sizeof(netxray_t));
wth->subtype_read = netxray_read;
wth->subtype_close = netxray_close;
wth->file_encap = netxray_encap[hdr.network];
wth->snapshot_length = 16384; /* XXX - not available in header */
wth->capture.netxray->start_time = pletohl(&hdr.start_time);
@ -295,6 +297,12 @@ reread:
return data_offset;
}
static void
netxray_close(wtap *wth)
{
g_free(wth->capture.netxray);
}
static const int wtap_encap[] = {
-1, /* WTAP_ENCAP_UNKNOWN -> unsupported */
0, /* WTAP_ENCAP_ETHERNET -> NDIS Ethernet */

View File

@ -1,6 +1,6 @@
/* ngsniffer.c
*
* $Id: ngsniffer.c,v 1.36 2000/02/19 08:00:07 guy Exp $
* $Id: ngsniffer.c,v 1.37 2000/03/22 07:06:57 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@ -247,6 +247,7 @@ struct frame4_rec {
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 void ngsniffer_close(wtap *wth);
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);
@ -370,6 +371,7 @@ int ngsniffer_open(wtap *wth, int *err)
wth->file_type = WTAP_FILE_NGSNIFFER;
wth->capture.ngsniffer = g_malloc(sizeof(ngsniffer_t));
wth->subtype_read = ngsniffer_read;
wth->subtype_close = ngsniffer_close;
wth->snapshot_length = 16384; /* not available in header, only in frame */
wth->capture.ngsniffer->timeunit = Usec[version.timeunit];
wth->file_encap = sniffer_encap[version.network];
@ -638,6 +640,12 @@ found:
return data_offset;
}
static void
ngsniffer_close(wtap *wth)
{
g_free(wth->capture.ngsniffer);
}
static const int wtap_encap[] = {
-1, /* WTAP_ENCAP_UNKNOWN -> unsupported */
1, /* WTAP_ENCAP_ETHERNET */

View File

@ -1,6 +1,6 @@
/* radcom.c
*
* $Id: radcom.c,v 1.18 2000/02/19 08:00:04 guy Exp $
* $Id: radcom.c,v 1.19 2000/03/22 07:06:56 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@ -68,6 +68,7 @@ struct radcomrec_hdr {
};
static int radcom_read(wtap *wth, int *err);
static void radcom_close(wtap *wth);
int radcom_open(wtap *wth, int *err)
{
@ -135,6 +136,7 @@ int radcom_open(wtap *wth, int *err)
wth->file_type = WTAP_FILE_RADCOM;
wth->capture.radcom = g_malloc(sizeof(radcom_t));
wth->subtype_read = radcom_read;
wth->subtype_close = radcom_close;
wth->snapshot_length = 16384; /* not available in header, only in frame */
tm.tm_year = pletohs(&start_date.year)-1900;
@ -301,3 +303,9 @@ static int radcom_read(wtap *wth, int *err)
return data_offset;
}
static void
radcom_close(wtap *wth)
{
g_free(wth->capture.radcom);
}

View File

@ -1,6 +1,6 @@
/* wtap.c
*
* $Id: wtap.c,v 1.37 2000/01/22 06:22:44 guy Exp $
* $Id: wtap.c,v 1.38 2000/03/22 07:06:55 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@ -189,50 +189,8 @@ const char *wtap_strerror(int err)
void wtap_close(wtap *wth)
{
/* free up memory. If any capture structure ever allocates
* its own memory, it would be better to make a *close() function
* for each filetype, like pcap_close(0, lanalyzer_close(), etc.
* But for now this will work. */
switch(wth->file_type) {
case WTAP_FILE_PCAP:
case WTAP_FILE_PCAP_MODIFIED:
g_free(wth->capture.pcap);
break;
case WTAP_FILE_LANALYZER:
g_free(wth->capture.lanalyzer);
break;
case WTAP_FILE_NGSNIFFER:
g_free(wth->capture.ngsniffer);
break;
case WTAP_FILE_RADCOM:
g_free(wth->capture.radcom);
break;
case WTAP_FILE_NETMON_1_x:
case WTAP_FILE_NETMON_2_x:
g_free(wth->capture.netmon);
break;
case WTAP_FILE_NETXRAY_1_0:
case WTAP_FILE_NETXRAY_1_1:
case WTAP_FILE_NETXRAY_2_001:
g_free(wth->capture.netxray);
break;
case WTAP_FILE_ASCEND:
g_free(wth->capture.ascend);
break;
case WTAP_FILE_NETTL:
g_free(wth->capture.nettl);
break;
/* default:
nothing */
}
if (wth->subtype_close != NULL)
(*wth->subtype_close)(wth);
file_close(wth->fh);

View File

@ -1,6 +1,6 @@
/* wtap.h
*
* $Id: wtap.h,v 1.64 2000/02/19 08:00:08 guy Exp $
* $Id: wtap.h,v 1.65 2000/03/22 07:06:59 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@ -185,8 +185,8 @@ typedef struct {
guint32 start_usecs;
guint8 version_major;
guint32 *frame_table;
int frame_table_size;
int current_frame;
int end_offset;
} netmon_t;
typedef struct {
@ -342,6 +342,7 @@ typedef struct wtap {
} capture;
subtype_read_func subtype_read;
void (*subtype_close)(struct wtap*);
int file_encap; /* per-file, for those
file formats that have
per-file encapsulation