summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Fisher <steve@stephen-fisher.com>2007-11-24 03:33:18 +0000
committerStephen Fisher <steve@stephen-fisher.com>2007-11-24 03:33:18 +0000
commit8c0f4111ea1b5b2c67969d3883506f0b720ec4c0 (patch)
tree536673f4585fceaba344dbcd4ac1779b210c687f
parent118f23a08a04292498560b3bcaddce00c606c12d (diff)
downloadwireshark-8c0f4111ea1b5b2c67969d3883506f0b720ec4c0.tar.gz
Initial checkin of support to read TamoSoft's CommView packet capture files
per enhancement bug #1795. svn path=/trunk/; revision=23558
-rw-r--r--wiretap/Makefile.common2
-rw-r--r--wiretap/commview.c267
-rw-r--r--wiretap/commview.h31
-rw-r--r--wiretap/file_access.c6
-rw-r--r--wiretap/wtap.h1
5 files changed, 307 insertions, 0 deletions
diff --git a/wiretap/Makefile.common b/wiretap/Makefile.common
index 7db8846269..f1fe817d3a 100644
--- a/wiretap/Makefile.common
+++ b/wiretap/Makefile.common
@@ -36,6 +36,7 @@ NONGENERATED_C_FILES = \
ber.c \
buffer.c \
catapult_dct2000.c \
+ commview.c \
cosine.c \
csids.c \
dbs-etherwatch.c \
@@ -77,6 +78,7 @@ NONGENERATED_HEADER_FILES = \
ber.h \
buffer.h \
catapult_dct2000.h \
+ commview.h \
cosine.h \
csids.h \
dbs-etherwatch.h \
diff --git a/wiretap/commview.c b/wiretap/commview.c
new file mode 100644
index 0000000000..62e734651f
--- /dev/null
+++ b/wiretap/commview.c
@@ -0,0 +1,267 @@
+/* commview.c
+ * Routines for opening CommView file format packet captures
+ * Copyright 2007, Stephen Fisher <stephentfisher@yahoo.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * Based on csids.c
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+/* A brief description of this file format is available at:
+ * http://www.tamos.com/htmlhelp/commview/logformat.htm
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include "wtap.h"
+#include "wtap-int.h"
+#include "buffer.h"
+#include "file_wrappers.h"
+#include "commview.h"
+
+typedef struct commview_header {
+ guint16 data_len;
+ guint16 source_data_len;
+ guint8 version;
+ guint16 year;
+ guint8 month;
+ guint8 day;
+ guint8 hours;
+ guint8 minutes;
+ guint8 seconds;
+ guint32 usecs;
+ guint8 flags; /* Bit-field positions defined below */
+ guint8 signal_level;
+ guint8 rate;
+ guint8 band;
+ guint8 channel;
+ guint8 direction; /* Not applicable to WiFi packets */
+ guint16 reserved; /* Unused bytes */
+} commview_header_t;
+
+#define COMMVIEW_HEADER_SIZE 24
+
+/* Bit-field positions for various fields in the flags variable of the header */
+#define FLAGS_MEDIUM 0x0F
+#define FLAGS_DECRYPTED 0x10
+#define FLAGS_BROKEN 0x20
+#define FLAGS_COMPRESSED 0x40
+#define FLAGS_RESERVED 0x80
+
+/* Capture mediums as defined by the commview file format */
+#define MEDIUM_ETHERNET 0
+#define MEDIUM_WIFI 1
+#define MEDIUM_TOKEN_RING 2
+
+int commview_open(wtap *wth, int *err, gchar **err_info _U_);
+static gboolean commview_read(wtap *wth, int *err, gchar **err_info _U_,
+ gint64 *data_offset);
+static gboolean commview_seek_read(wtap *wth, gint64 seek_off,
+ union wtap_pseudo_header *pseudo_header,
+ guchar *pd, int length, int *err,
+ gchar **err_info _U_);
+static gboolean commview_read_header(commview_header_t *cv_hdr, FILE_T fh,
+ int *err);
+
+
+int commview_open(wtap *wth, int *err, gchar **err_info _U_)
+{
+ commview_header_t cv_hdr;
+
+ if(!commview_read_header(&cv_hdr, wth->fh, err))
+ return -1;
+
+ /* If any of these fields do not match what we expect, bail out. */
+ if(cv_hdr.version != 0 ||
+ cv_hdr.year < 1970 || cv_hdr.year >= 2038 ||
+ cv_hdr.month < 1 || cv_hdr.month > 12 ||
+ cv_hdr.day < 1 || cv_hdr.day > 31 ||
+ cv_hdr.hours > 23 ||
+ cv_hdr.minutes > 59 ||
+ cv_hdr.seconds > 60 ||
+ cv_hdr.signal_level > 100 ||
+ (cv_hdr.direction != 0x00 && cv_hdr.direction != 0x01 &&
+ cv_hdr.direction != 0x02) ||
+ (cv_hdr.flags & FLAGS_RESERVED) != 0 ||
+ ((cv_hdr.flags & FLAGS_MEDIUM) != MEDIUM_ETHERNET &&
+ (cv_hdr.flags & FLAGS_MEDIUM) != MEDIUM_WIFI &&
+ (cv_hdr.flags & FLAGS_MEDIUM) != MEDIUM_TOKEN_RING) ||
+ cv_hdr.reserved != 0)
+ return 0; /* Not our kind of file */
+
+ /* No file header. Reset the fh to 0 so we can read the first packet */
+ if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
+ return -1;
+
+ /* Set up the pointers to the handlers for this file type */
+ wth->data_offset = 0;
+ wth->subtype_read = commview_read;
+ wth->subtype_seek_read = commview_seek_read;
+ wth->file_type = WTAP_FILE_COMMVIEW;
+ wth->file_encap = WTAP_ENCAP_PER_PACKET;
+ wth->tsprecision = WTAP_FILE_TSPREC_USEC;
+
+ return 1; /* Our kind of file */
+}
+
+static gboolean
+commview_read(wtap *wth, int *err, gchar **err_info _U_, gint64 *data_offset)
+{
+ commview_header_t cv_hdr;
+ struct tm tm;
+ int bytes_read;
+
+ *data_offset = wth->data_offset;
+
+ if(!commview_read_header(&cv_hdr, wth->fh, err))
+ return FALSE;
+
+ wth->data_offset += COMMVIEW_HEADER_SIZE;
+
+ switch(cv_hdr.flags & FLAGS_MEDIUM) {
+
+ case MEDIUM_ETHERNET :
+ wth->phdr.pkt_encap = WTAP_ENCAP_ETHERNET;
+ break;
+
+ case MEDIUM_WIFI :
+ wth->phdr.pkt_encap = WTAP_ENCAP_IEEE_802_11;
+ break;
+
+ case MEDIUM_TOKEN_RING :
+ wth->phdr.pkt_encap = WTAP_ENCAP_TOKEN_RING;
+ break;
+ }
+
+ buffer_assure_space(wth->frame_buffer, cv_hdr.data_len);
+ bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1,
+ cv_hdr.data_len, wth->fh);
+ if(bytes_read != cv_hdr.data_len) {
+ *err = file_error(wth->fh);
+ if(*err == 0)
+ *err = WTAP_ERR_SHORT_READ;
+ return FALSE;
+ }
+
+ tm.tm_year = cv_hdr.year - 1900;
+ tm.tm_mon = cv_hdr.month - 1;
+ tm.tm_mday = cv_hdr.day;
+ tm.tm_hour = cv_hdr.hours;
+ tm.tm_min = cv_hdr.minutes;
+ tm.tm_sec = cv_hdr.seconds;
+ tm.tm_isdst = -1;
+
+ wth->data_offset += cv_hdr.data_len;
+
+ wth->phdr.len = cv_hdr.data_len;
+ wth->phdr.caplen = cv_hdr.data_len;
+
+ wth->phdr.ts.secs = mktime(&tm);
+ wth->phdr.ts.nsecs = cv_hdr.usecs * 1000;
+
+ return TRUE;
+}
+
+static gboolean
+commview_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header
+ *pseudo_header _U_, guchar *pd, int length, int *err,
+ gchar **err_info _U_)
+{
+ commview_header_t cv_hdr;
+ int bytes_read;
+
+ if(file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
+ return FALSE;
+
+ if(!commview_read_header(&cv_hdr, wth->random_fh, err)) {
+ if(*err == 0)
+ *err = WTAP_ERR_SHORT_READ;
+
+ return FALSE;
+ }
+
+ if(length != cv_hdr.data_len) {
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("commview: record length %u doesn't match requested length %d", cv_hdr.data_len, length);
+ return FALSE;
+ }
+
+ bytes_read = file_read(pd, 1, cv_hdr.data_len, wth->random_fh);
+ if(bytes_read != cv_hdr.data_len) {
+ *err = file_error(wth->random_fh);
+ if(*err == 0)
+ *err = WTAP_ERR_SHORT_READ;
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+commview_read_header(commview_header_t *cv_hdr, FILE_T fh, int *err)
+{
+ int bytes_read = 0;
+
+ bytes_read += file_read(&cv_hdr->data_len, 2, 1, fh);
+ bytes_read += file_read(&cv_hdr->source_data_len, 2, 1, fh);
+ bytes_read += file_read(&cv_hdr->version, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->year, 2, 1, fh);
+ bytes_read += file_read(&cv_hdr->month, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->day, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->hours, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->minutes, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->seconds, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->usecs, 4, 1, fh);
+ bytes_read += file_read(&cv_hdr->flags, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->signal_level, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->rate, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->band, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->channel, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->direction, 1, 1, fh);
+ bytes_read += file_read(&cv_hdr->reserved, 2, 1, fh);
+
+ /* Convert multi-byte values from little endian to host endian format */
+ cv_hdr->data_len = GUINT16_FROM_LE(cv_hdr->data_len);
+ cv_hdr->source_data_len = GUINT16_FROM_LE(cv_hdr->source_data_len);
+ cv_hdr->year = GUINT16_FROM_LE(cv_hdr->year);
+ cv_hdr->usecs = GUINT32_FROM_LE(cv_hdr->usecs);
+
+ if(bytes_read < COMMVIEW_HEADER_SIZE) {
+ *err = file_error(fh);
+ if(*err == 0 && bytes_read > 0)
+ *err = WTAP_ERR_SHORT_READ;
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/wiretap/commview.h b/wiretap/commview.h
new file mode 100644
index 0000000000..b3dfc978c7
--- /dev/null
+++ b/wiretap/commview.h
@@ -0,0 +1,31 @@
+/* commview.h
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#ifndef __COMMVIEW_H__
+#define __COMMVIEW_H__
+
+int commview_open(wtap *wth, int *err, gchar **err_info _U_);
+
+#endif /* __COMMVIEW_H__ */
+
diff --git a/wiretap/file_access.c b/wiretap/file_access.c
index 08ca94b442..c15bbc3875 100644
--- a/wiretap/file_access.c
+++ b/wiretap/file_access.c
@@ -74,6 +74,7 @@
#include "catapult_dct2000.h"
#include "mpeg.h"
#include "netscreen.h"
+#include "commview.h"
@@ -141,6 +142,7 @@ static wtap_open_routine_t open_routines_base[] = {
vms_open,
cosine_open,
hcidump_open,
+ commview_open
};
#define N_FILE_TYPES (sizeof open_routines_base / sizeof open_routines_base[0])
@@ -567,6 +569,10 @@ static const struct file_type_info dump_open_table_base[] = {
/* WTAP_FILE_NETSCREEN */
{ "NetScreen snoop text file", "netscreen", "*.*", NULL, FALSE,
NULL, NULL },
+
+ /* WTAP_FILE_COMMVIEW */
+ { "TamoSoft CommView", "commview", "*.ncf", ".ncf", TRUE,
+ NULL, NULL }
};
gint wtap_num_file_types = sizeof(dump_open_table_base) / sizeof(struct file_type_info);
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index 79ad5a4166..030aa08456 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -250,6 +250,7 @@ extern "C" {
#define WTAP_FILE_MPEG 46
#define WTAP_FILE_K12TEXT 47
#define WTAP_FILE_NETSCREEN 48
+#define WTAP_FILE_COMMVIEW 49
#define WTAP_NUM_FILE_TYPES wtap_get_num_file_types()