From fb9213097b7978d9d9190cc8dc468d152438bfd4 Mon Sep 17 00:00:00 2001 From: guy Date: Fri, 19 Oct 2001 20:18:48 +0000 Subject: DBS Etherwatch wiretap module, from Marc Milgram. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@4042 f5534014-38df-0310-8fa8-9805f1628bb7 --- wiretap/AUTHORS | 2 +- wiretap/Makefile.am | 4 +- wiretap/Makefile.nmake | 3 +- wiretap/README | 7 +- wiretap/dbs-etherwatch.c | 366 +++++++++++++++++++++++++++++++++++++++++++++++ wiretap/dbs-etherwatch.h | 29 ++++ wiretap/file.c | 8 +- wiretap/wtap.h | 5 +- 8 files changed, 417 insertions(+), 7 deletions(-) create mode 100644 wiretap/dbs-etherwatch.c create mode 100644 wiretap/dbs-etherwatch.h (limited to 'wiretap') diff --git a/wiretap/AUTHORS b/wiretap/AUTHORS index ebb1f34d55..3f1f33c957 100644 --- a/wiretap/AUTHORS +++ b/wiretap/AUTHORS @@ -10,4 +10,4 @@ Bert Driehuis Mike Hall Daniel Thompson Chris Jepeway -Marc Milgram +Marc Milgram diff --git a/wiretap/Makefile.am b/wiretap/Makefile.am index a5ef6aa1ab..3d92ad7bfa 100644 --- a/wiretap/Makefile.am +++ b/wiretap/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Wiretap # -# $Id: Makefile.am,v 1.34 2001/10/18 20:29:56 guy Exp $ +# $Id: Makefile.am,v 1.35 2001/10/19 20:18:48 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs @@ -42,6 +42,8 @@ libwiretap_a_SOURCES = \ buffer.h \ csids.c \ csids.h \ + dbs-etherwatch.c \ + dbs-etherwatch.h \ etherpeek.c \ etherpeek.h \ file.c \ diff --git a/wiretap/Makefile.nmake b/wiretap/Makefile.nmake index f7db247482..2518be8005 100644 --- a/wiretap/Makefile.nmake +++ b/wiretap/Makefile.nmake @@ -1,5 +1,5 @@ # -# $Id: Makefile.nmake,v 1.21 2001/10/18 20:29:56 guy Exp $ +# $Id: Makefile.nmake,v 1.22 2001/10/19 20:18:48 guy Exp $ # include ..\config.nmake @@ -17,6 +17,7 @@ OBJECTS=ascend-grammar.obj \ ascend.obj \ buffer.obj \ csids.obj \ + dbs-etherwatch.obj \ etherpeek.obj \ file.obj \ file_wrappers.obj \ diff --git a/wiretap/README b/wiretap/README index cb7e6056e5..84f5f3bdfc 100644 --- a/wiretap/README +++ b/wiretap/README @@ -1,4 +1,4 @@ -$Id: README,v 1.27 2001/10/18 20:29:56 guy Exp $ +$Id: README,v 1.28 2001/10/19 20:18:48 guy Exp $ Wiretap is a library that is being developed as a future replacement for libpcap, the current standard Unix library for packet capturing. Libpcap @@ -151,6 +151,11 @@ as TCPTRACE. TCPTRACE produces an ascii text based format, that has changed slightly over time. +DBS Etherwatch (text format) +---------------------------- +Text output from DBS Etherwatch is supported. DBS Etherwatch is available +from: http://www.users.bigpond.com/dbsneddon/software.htm. + Gilbert Ramirez Guy Harris diff --git a/wiretap/dbs-etherwatch.c b/wiretap/dbs-etherwatch.c new file mode 100644 index 0000000000..e1a27b09ad --- /dev/null +++ b/wiretap/dbs-etherwatch.c @@ -0,0 +1,366 @@ +/* dbs-etherwatch.c + * + * $Id: dbs-etherwatch.c,v 1.1 2001/10/19 20:18:48 guy Exp $ + * + * Wiretap Library + * Copyright (c) 2001 by Marc Milgram + * + * 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. + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "wtap-int.h" +#include "buffer.h" +#include "dbs-etherwatch.h" +#include "file_wrappers.h" + +#include +#include +#include +#include + +/* This module reads the text output of the 'DBS-ETHERTRACE' command in VMS + * It was initially based on vms.c. + */ + +/* + Example 'TCPIPTRACE' output data: +ETHERWATCH X5-008 +42 names and addresses were loaded +Reading recorded data from PERSISTENCE +------------------------------------------------------------------------------ +>From 00-D0-C0-D2-4D-60 [MF1] to AA-00-04-00-FC-94 [PSERVB] +Protocol 08-00 00 00-00-00-00-00, 60 byte buffer at 10-OCT-2001 10:20:45.16 + [E..<8.....Ò.....]- 0-[45 00 00 3C 38 93 00 00 1D 06 D2 12 80 93 11 1A] + [...Ö.Ò...(¤.....]- 16-[80 93 80 D6 02 D2 02 03 00 28 A4 90 00 00 00 00] + [.....½.....´....]- 32-[A0 02 FF FF 95 BD 00 00 02 04 05 B4 03 03 04 01] + [......å..... ]- 48-[01 01 08 0A 90 90 E5 14 00 00 00 00] +------------------------------------------------------------------------------ +>From 00-D0-C0-D2-4D-60 [MF1] to AA-00-04-00-FC-94 [PSERVB] +Protocol 08-00 00 00-00-00-00-00, 50 byte buffer at 10-OCT-2001 10:20:45.17 + [E..(8.....Ò%....]- 0-[45 00 00 28 38 94 00 00 1D 06 D2 25 80 93 11 1A] + [...Ö.Ò...(¤.Z.4w]- 16-[80 93 80 D6 02 D2 02 03 00 28 A4 91 5A 1C 34 77] + [P.#(Ás.....´....]- 32-[50 10 23 28 C1 73 00 00 02 04 05 B4 03 03 00 00] + [.. ]- 48-[02 04] + */ + +/* Magic text to check for DBS-ETHERWATCH-ness of file */ +static const char dbs_etherwatch_hdr_magic[] = +{ 'E', 'T', 'H', 'E', 'R', 'W', 'A', 'T', 'C', 'H', ' ', ' '}; +#define DBS_ETHERWATCH_HDR_MAGIC_SIZE \ + (sizeof dbs_etherwatch_hdr_magic / sizeof dbs_etherwatch_hdr_magic[0]) + +/* Magic text for start of packet */ +static const char dbs_etherwatch_rec_magic[] = +{'F', 'r', 'o', 'm', ' '}; +#define DBS_ETHERWATCH_REC_MAGIC_SIZE \ + (sizeof dbs_etherwatch_rec_magic / sizeof dbs_etherwatch_rec_magic[0]) + +static gboolean dbs_etherwatch_read(wtap *wth, int *err, long *data_offset); +static int dbs_etherwatch_seek_read(wtap *wth, long seek_off, + union wtap_pseudo_header *pseudo_header, guint8 *pd, int len); +static gboolean parse_single_hex_dump_line(char* rec, guint8 *buf, long byte_offset); +static int parse_dbs_etherwatch_hex_dump(FILE_T fh, int pkt_len, guint8* buf, int *err); +static int parse_dbs_etherwatch_rec_hdr(wtap *wth, FILE_T fh, int *err); + + +/* Seeks to the beginning of the next packet, and returns the + byte offset. Returns -1 on failure. */ +/* XXX - Handle I/O errors. */ +static long dbs_etherwatch_seek_next_packet(wtap *wth) +{ + int byte; + unsigned int level = 0; + + while ((byte = file_getc(wth->fh)) != EOF) { + if (byte == dbs_etherwatch_rec_magic[level]) { + level++; + if (level >= DBS_ETHERWATCH_REC_MAGIC_SIZE) { + /* note: we're leaving file pointer right after the magic characters */ + return file_tell(wth->fh) + 1; + } + } else { + level = 0; + } + } + return -1; +} + +#define DBS_ETHERWATCH_HEADER_LINES_TO_CHECK 200 +#define DBS_ETHERWATCH_LINE_LENGTH 240 + +/* Look through the first part of a file to see if this is + * a DBS Ethertrace text trace file. + * + * Returns TRUE if it is, FALSE if it isn't. + */ +static gboolean dbs_etherwatch_check_file_type(wtap *wth) +{ + char buf[DBS_ETHERWATCH_LINE_LENGTH]; + int line, byte; + unsigned int reclen, i, level; + + buf[DBS_ETHERWATCH_LINE_LENGTH-1] = 0; + + for (line = 0; line < DBS_ETHERWATCH_HEADER_LINES_TO_CHECK; line++) { + if (file_gets(buf, DBS_ETHERWATCH_LINE_LENGTH, wth->fh)!=NULL){ + + reclen = strlen(buf); + if (reclen < DBS_ETHERWATCH_HDR_MAGIC_SIZE) + continue; + + level = 0; + for (i = 0; i < reclen; i++) { + byte = buf[i]; + if (byte == dbs_etherwatch_hdr_magic[level]) { + level++; + if (level >= + DBS_ETHERWATCH_HDR_MAGIC_SIZE) { + return TRUE; + } + } + else + level = 0; + } + } + else + return FALSE; + } + return FALSE; +} + + +/* XXX - return -1 on I/O error and actually do something with 'err'. */ +int dbs_etherwatch_open(wtap *wth, int *err) +{ + /* Look for DBS ETHERWATCH header */ + if (!dbs_etherwatch_check_file_type(wth)) { + return 0; + } + + wth->data_offset = 0; + wth->file_encap = WTAP_ENCAP_PER_PACKET; + wth->file_type = WTAP_FILE_DBS_ETHERWATCH; + wth->snapshot_length = 16384; /* just guessing */ + wth->subtype_read = dbs_etherwatch_read; + wth->subtype_seek_read = dbs_etherwatch_seek_read; + + return 1; +} + +/* Find the next packet and parse it; called from wtap_loop(). */ +static gboolean dbs_etherwatch_read(wtap *wth, int *err, long *data_offset) +{ + long offset = 0; + guint8 *buf; + int pkt_len; + + /* Find the next packet */ + offset = dbs_etherwatch_seek_next_packet(wth); + if (offset < 1) { + *err = 0; /* XXX - assume, for now, that it's an EOF */ + return FALSE; + } + + /* Parse the header */ + pkt_len = parse_dbs_etherwatch_rec_hdr(wth, wth->fh, err); + + /* Make sure we have enough room for the packet */ + buffer_assure_space(wth->frame_buffer, wth->snapshot_length); + buf = buffer_start_ptr(wth->frame_buffer); + + /* Convert the ASCII hex dump to binary data */ + parse_dbs_etherwatch_hex_dump(wth->fh, pkt_len, buf, err); + + wth->data_offset = offset; + *data_offset = offset; + return TRUE; +} + +/* Used to read packets in random-access fashion */ +static int +dbs_etherwatch_seek_read (wtap *wth, long seek_off, + union wtap_pseudo_header *pseudo_header, + guint8 *pd, int len) +{ + int pkt_len; + int err; + + file_seek(wth->random_fh, seek_off - 1, SEEK_SET); + + pkt_len = parse_dbs_etherwatch_rec_hdr(NULL, wth->random_fh, &err); + + if (pkt_len != len) { + return -1; + } + + parse_dbs_etherwatch_hex_dump(wth->random_fh, pkt_len, pd, &err); + + return 0; +} + +/* Parses a packet record header. */ +static int +parse_dbs_etherwatch_rec_hdr(wtap *wth, FILE_T fh, int *err) +{ + char line[DBS_ETHERWATCH_LINE_LENGTH]; + int num_items_scanned; + int pkt_len, csec; + struct tm time; + char mon[4]; + guchar *p; + static guchar months[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"; + + pkt_len = 0; + + /* Our file pointer should be on the first line containing the + * summary information for a packet. Read in that line and + * extract the useful information + */ + if (file_gets(line, DBS_ETHERWATCH_LINE_LENGTH, fh) == NULL) { + *err = file_error(fh); + if (*err == 0) { + *err = WTAP_ERR_SHORT_READ; + } + return -1; + } + + /* But that line only contains the mac addresses, so we will ignore + that line for now. Read the next line */ + if (file_gets(line, DBS_ETHERWATCH_LINE_LENGTH, fh) == NULL) { + *err = file_error(fh); + if (*err == 0) { + *err = WTAP_ERR_SHORT_READ; + } + return -1; + } + + num_items_scanned = sscanf(line+33, "%d byte buffer at %d-%3s-%d %d:%d:%d.%d", + &pkt_len, + &time.tm_mday, mon, + &time.tm_year, &time.tm_hour, &time.tm_min, + &time.tm_sec, &csec); + + if (num_items_scanned != 8) { + *err = WTAP_ERR_BAD_RECORD; + return -1; + } + + if (wth) { + p = strstr(months, mon); + if (p) + time.tm_mon = (p - months) / 3; + time.tm_year -= 1900; + + wth->phdr.ts.tv_sec = mktime(&time); + + wth->phdr.ts.tv_usec = csec * 10000; + wth->phdr.caplen = pkt_len; + wth->phdr.len = pkt_len; + wth->phdr.pkt_encap = WTAP_ENCAP_RAW_IP; + } + + return pkt_len; +} + +/* Converts ASCII hex dump to binary data */ +static int +parse_dbs_etherwatch_hex_dump(FILE_T fh, int pkt_len, guint8* buf, int *err) +{ + guchar line[DBS_ETHERWATCH_LINE_LENGTH]; + int i, hex_lines; + + /* Calculate the number of hex dump lines, each + * containing 16 bytes of data */ + hex_lines = pkt_len / 16 + ((pkt_len % 16) ? 1 : 0); + + for (i = 0; i < hex_lines; i++) { + if (file_gets(line, DBS_ETHERWATCH_LINE_LENGTH, fh) == NULL) { + *err = file_error(fh); + if (*err == 0) { + *err = WTAP_ERR_SHORT_READ; + } + return -1; + } + if (!parse_single_hex_dump_line(line, buf, i * 16)) { + *err = WTAP_ERR_BAD_RECORD; + return -1; + } + } + return 0; +} + +/* + 1 2 3 4 +0123456789012345678901234567890123456789012345 + [E..(8.....Ò.....]- 0-[45 00 00 28 38 9B 00 00 1D 06 D2 1E 80 93 11 1A] + [...Ö.Ò...(¤¿Z.4y]- 16-[80 93 80 D6 02 D2 02 03 00 28 A4 BF 5A 1C 34 79] + [P.#(ÁC...00000..]- 32-[50 10 23 28 C1 43 00 00 03 30 30 30 30 30 00 00] + [.0 ]- 48-[03 30] +*/ + +#define START_POS 28 +#define HEX_LENGTH ((16 * 2) + 15) /* sixteen clumps of 2 bytes with 15 inner spaces */ +/* Take a string representing one line from a hex dump and converts the + * text to binary data. We check the printed offset with the offset + * we are passed to validate the record. We place the bytes in the buffer + * at the specified offset. + * + * In the process, we're going to write all over the string. + * + * Returns TRUE if good hex dump, FALSE if bad. + */ +static gboolean +parse_single_hex_dump_line(char* rec, guint8 *buf, long byte_offset) { + + int pos, i; + char *s; + long value; + + + /* Get the byte_offset directly from the record */ + rec[26] = '\0'; + s = rec + 21; + value = strtol(s, NULL, 10); + + if (value != byte_offset) { + return FALSE; + } + + /* Go through the substring representing the values and: + * 1. Replace any spaces with '0's + * 2. Place \0's every 3 bytes (to terminate the string) + * + * Then read the eight sets of hex bytes + */ + + for (pos = START_POS; pos < START_POS + HEX_LENGTH; pos++) { + if (rec[pos] == ' ') { + rec[pos] = '0'; + } + } + + pos = START_POS; + for (i = 0; i < 16; i++) { + rec[pos+2] = '\0'; + + buf[byte_offset + i] = (guint8) strtoul(&rec[pos], NULL, 16); + pos += 3; + } + + return TRUE; +} diff --git a/wiretap/dbs-etherwatch.h b/wiretap/dbs-etherwatch.h new file mode 100644 index 0000000000..f025408a23 --- /dev/null +++ b/wiretap/dbs-etherwatch.h @@ -0,0 +1,29 @@ +/* toshiba.h + * + * $Id: dbs-etherwatch.h,v 1.1 2001/10/19 20:18:48 guy Exp $ + * + * Wiretap Library + * Copyright (c) 1998 by Gilbert Ramirez + * + * 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. + * + */ + +#ifndef __W_DBS_ETHERWATCH_H__ +#define __W_DBS_ETHERWATCH_H__ + +int dbs_etherwatch_open(wtap *wth, int *err); + +#endif diff --git a/wiretap/file.c b/wiretap/file.c index 9b0fb41742..24506949aa 100644 --- a/wiretap/file.c +++ b/wiretap/file.c @@ -1,6 +1,6 @@ /* file.c * - * $Id: file.c,v 1.70 2001/10/18 20:29:56 guy Exp $ + * $Id: file.c,v 1.71 2001/10/19 20:18:48 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez @@ -61,6 +61,7 @@ #include "pppdump.h" #include "etherpeek.h" #include "vms.h" +#include "dbs-etherwatch.h" /* The open_file_* routines should return: * @@ -109,6 +110,7 @@ static int (*open_routines[])(wtap *, int *) = { i4btrace_open, csids_open, vms_open, + dbs_etherwatch_open, }; #define N_FILE_TYPES (sizeof open_routines / sizeof open_routines[0]) @@ -371,6 +373,10 @@ static const struct file_type_info { /* WTAP_FILE_VMS */ { "TCPIPtrace (VMS)", NULL, NULL, NULL}, + + /* WTAP_FILE_DBS_ETHERWATCH */ + { "DBS Etherwatch (VMS)", NULL, + NULL, NULL}, }; /* Name that should be somewhat descriptive. */ diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 70f0928683..5de6e536d6 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1,6 +1,6 @@ /* wtap.h * - * $Id: wtap.h,v 1.90 2001/10/18 20:29:56 guy Exp $ + * $Id: wtap.h,v 1.91 2001/10/19 20:18:48 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez @@ -133,9 +133,10 @@ #define WTAP_FILE_ETHERPEEK_MAC_V56 25 #define WTAP_FILE_ETHERPEEK_MAC_V7 26 #define WTAP_FILE_VMS 27 +#define WTAP_FILE_DBS_ETHERWATCH 28 /* last WTAP_FILE_ value + 1 */ -#define WTAP_NUM_FILE_TYPES 28 +#define WTAP_NUM_FILE_TYPES 29 /* * Maximum packet size we'll support. -- cgit v1.2.3