aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap/snoop.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>1998-11-15 05:29:17 +0000
committerGuy Harris <guy@alum.mit.edu>1998-11-15 05:29:17 +0000
commit86bf1fc851b5564f5700a937de3213e8354aa52e (patch)
tree46a497072e194a9ed5f20733549362347c4d6eef /wiretap/snoop.c
parent8efdf8a74c3f0c32a380d15aeed0a3f6aff56a29 (diff)
Add support to wiretap for reading Sun "snoop" capture files.
That requires that, in the packet-reading loop, we pass to the callback routine the offset in the file of a packet's data, because we can no longer compute that offset by subtracting the size of the captured packet data from the offset in the file after the data was read - "snoop" may stick padding in after the packet data to align packet headers on 4-byte boundaries. Doing that required that we arrange that we do that for "libpcap" capture files as well; the cleanest way to do that was to write our own code for reading "libpcap" capture files, rather than using the "libpcap" code to do it. Make "wtap_dispatch_cb()" and "pcap_dispatch_cb()" static to "file.c", as they're not used elsewhere. If we're using wiretap, don't define in "file.h" stuff used only when we're not using wiretap. Update the wiretap README to reflect Gilbert's and my recent changes. Clean up some memory leaks in "wiretap/lanalyzer.c" and "wiretap/ngsniffer.c", where the capture-file-format-specific data wasn't freed if the open failed. svn path=/trunk/; revision=91
Diffstat (limited to 'wiretap/snoop.c')
-rw-r--r--wiretap/snoop.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/wiretap/snoop.c b/wiretap/snoop.c
new file mode 100644
index 0000000000..c43f9f5f38
--- /dev/null
+++ b/wiretap/snoop.c
@@ -0,0 +1,154 @@
+/* snoop.c
+ *
+ * $Id: snoop.c,v 1.1 1998/11/15 05:29:14 guy Exp $
+ *
+ * Wiretap Library
+ * Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
+ *
+ * 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.
+ *
+ */
+#include "wtap.h"
+#include "snoop.h"
+#include <netinet/in.h>
+
+/* See RFC 1761 for a description of the "snoop" file format. */
+
+/* Magic number in "snoop" files. */
+static char snoop_magic[] = {
+ 's', 'n', 'o', 'o', 'p', '\0', '\0', '\0'
+};
+
+/* "snoop" file header (minus magic number). */
+struct snoop_hdr {
+ guint32 version; /* version number (should be 2) */
+ guint32 network; /* network type */
+};
+
+/* "snoop" record header. */
+struct snooprec_hdr {
+ guint32 orig_len; /* actual length of packet */
+ guint32 incl_len; /* number of octets captured in file */
+ guint32 rec_len; /* length of record */
+ guint32 cum_drops; /* cumulative number of dropped packets */
+ guint32 ts_sec; /* timestamp seconds */
+ guint32 ts_usec; /* timestamp microseconds */
+};
+
+/* Returns WTAP_FILE_SNOOP on success, WTAP_FILE_UNKNOWN on failure */
+int snoop_open(wtap *wth)
+{
+ int bytes_read;
+ char magic[sizeof snoop_magic];
+ struct snoop_hdr hdr;
+ static const int snoop_encap[] = {
+ WTAP_ENCAP_NONE, /* IEEE 802.3 */
+ WTAP_ENCAP_NONE, /* IEEE 802.4 Token Bus */
+ WTAP_ENCAP_TR,
+ WTAP_ENCAP_NONE, /* IEEE 802.6 Metro Net */
+ WTAP_ENCAP_ETHERNET,
+ WTAP_ENCAP_NONE, /* HDLC */
+ WTAP_ENCAP_NONE, /* Character Synchronous */
+ WTAP_ENCAP_NONE, /* IBM Channel-to-Channel */
+ WTAP_ENCAP_FDDI,
+ WTAP_ENCAP_NONE /* Other */
+ };
+ #define NUM_SNOOP_ENCAPS (sizeof snoop_encap / sizeof snoop_encap[0])
+
+ /* Read in the string that should be at the start of a "snoop" file */
+ fseek(wth->fh, 0, SEEK_SET);
+ bytes_read = fread(magic, 1, sizeof magic, wth->fh);
+
+ if (bytes_read != sizeof magic) {
+ return WTAP_FILE_UNKNOWN;
+ }
+
+ if (memcmp(magic, snoop_magic, sizeof snoop_magic) != 0) {
+ return WTAP_FILE_UNKNOWN;
+ }
+
+ /* Read the rest of the header. */
+ bytes_read = fread(&hdr, 1, sizeof hdr, wth->fh);
+ if (bytes_read != sizeof hdr) {
+ return WTAP_FILE_UNKNOWN;
+ }
+
+ hdr.version = ntohl(hdr.version);
+ if (hdr.version != 2) {
+ /* We only support version 2. */
+ return WTAP_FILE_UNKNOWN;
+ }
+ hdr.network = ntohl(hdr.network);
+ if (hdr.network >= NUM_SNOOP_ENCAPS) {
+ g_error("snoop: network type %d unknown", hdr.network);
+ return WTAP_FILE_UNKNOWN;
+ }
+
+ /* This is a snoop file */
+ wth->subtype_read = snoop_read;
+ wth->encapsulation = snoop_encap[hdr.network];
+ wth->snapshot_length = 16384; /* XXX - not available in header */
+ /*wth->frame_number = 0;*/
+ /*wth->file_byte_offset = 0x10b;*/
+
+ return WTAP_FILE_SNOOP;
+}
+
+/* Read the next packet */
+int snoop_read(wtap *wth)
+{
+ int packet_size;
+ int bytes_read;
+ struct snooprec_hdr hdr;
+ int data_offset;
+
+ /* Read record header. */
+ bytes_read = fread(&hdr, 1, sizeof hdr, wth->fh);
+ if (bytes_read != sizeof hdr) {
+ if (bytes_read != 0) {
+ g_error("snoop_read: not enough packet header data (%d bytes)",
+ bytes_read);
+ return -1;
+ }
+ return 0;
+ }
+
+ packet_size = ntohl(hdr.incl_len);
+ buffer_assure_space(&wth->frame_buffer, packet_size);
+ data_offset = ftell(wth->fh);
+ bytes_read = fread(buffer_start_ptr(&wth->frame_buffer), 1,
+ packet_size, wth->fh);
+
+ if (bytes_read != packet_size) {
+ if (ferror(wth->fh)) {
+ g_error("snoop_read: fread for data: read error\n");
+ } else {
+ g_error("snoop_read: fread for data: %d bytes out of %d",
+ bytes_read, packet_size);
+ }
+ return -1;
+ }
+
+ wth->phdr.ts.tv_sec = ntohl(hdr.ts_sec);
+ wth->phdr.ts.tv_usec = ntohl(hdr.ts_usec);
+ wth->phdr.caplen = packet_size;
+ wth->phdr.len = ntohl(hdr.orig_len);
+
+ /* Skip over the padding. */
+ fseek(wth->fh, ntohl(hdr.rec_len) - (sizeof hdr + packet_size),
+ SEEK_CUR);
+
+ return data_offset;
+}