diff options
Diffstat (limited to 'wiretap')
-rw-r--r-- | wiretap/AUTHORS | 21 | ||||
-rw-r--r-- | wiretap/Makefile.am | 4 | ||||
-rw-r--r-- | wiretap/Makefile.nmake | 3 | ||||
-rw-r--r-- | wiretap/README | 14 | ||||
-rw-r--r-- | wiretap/file.c | 8 | ||||
-rw-r--r-- | wiretap/vms.c | 412 | ||||
-rw-r--r-- | wiretap/vms.h | 29 | ||||
-rw-r--r-- | wiretap/wtap.h | 5 |
8 files changed, 480 insertions, 16 deletions
diff --git a/wiretap/AUTHORS b/wiretap/AUTHORS index 75dcb13f02..ebb1f34d55 100644 --- a/wiretap/AUTHORS +++ b/wiretap/AUTHORS @@ -1,12 +1,13 @@ Authors ------- -Gilbert Ramirez <gram@xiexie.org> -Guy Harris <guy@alum.mit.edu> -Olivier Abad <oabad@cybercable.fr> -Gerald Combs <gerald@ethereal.com> -Joerg Mayer <jmayer@loplof.de> -Tim Farley <tfarley@iss.net> -Bert Driehuis <driehuis@playbeing.org> -Mike Hall <mlh@io.com> -Daniel Thompson <daniel.thompson@st.com> -Chris Jepeway <thai-dragon@eleven29.com> +Gilbert Ramirez <gram[AT]xiexie.org> +Guy Harris <guy[AT]alum.mit.edu> +Olivier Abad <oabad[AT]cybercable.fr> +Gerald Combs <gerald[AT]ethereal.com> +Joerg Mayer <jmayer[AT]loplof.de> +Tim Farley <tfarley[AT]iss.net> +Bert Driehuis <driehuis[AT]playbeing.org> +Mike Hall <mlh[AT]io.com> +Daniel Thompson <daniel.thompson[AT]st.com> +Chris Jepeway <thai-dragon[AT]eleven29.com> +Marc Milgram <mmilgram[AT]arrayinc.cmo> diff --git a/wiretap/Makefile.am b/wiretap/Makefile.am index 7ddc58db7e..a5ef6aa1ab 100644 --- a/wiretap/Makefile.am +++ b/wiretap/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Wiretap # -# $Id: Makefile.am,v 1.33 2001/04/18 21:34:22 gram Exp $ +# $Id: Makefile.am,v 1.34 2001/10/18 20:29:56 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs <gerald@zing.org> @@ -72,6 +72,8 @@ libwiretap_a_SOURCES = \ snoop.h \ toshiba.c \ toshiba.h \ + vms.c \ + vms.h \ wtap.c \ wtap.h \ wtap-int.h diff --git a/wiretap/Makefile.nmake b/wiretap/Makefile.nmake index d72790ec4f..f7db247482 100644 --- a/wiretap/Makefile.nmake +++ b/wiretap/Makefile.nmake @@ -1,5 +1,5 @@ # -# $Id: Makefile.nmake,v 1.20 2001/04/12 18:07:22 gram Exp $ +# $Id: Makefile.nmake,v 1.21 2001/10/18 20:29:56 guy Exp $ # include ..\config.nmake @@ -32,6 +32,7 @@ OBJECTS=ascend-grammar.obj \ pppdump.obj \ snoop.obj \ toshiba.obj \ + vms.obj \ wtap.obj diff --git a/wiretap/README b/wiretap/README index f8f8cc07ee..cb7e6056e5 100644 --- a/wiretap/README +++ b/wiretap/README @@ -1,4 +1,4 @@ -$Id: README,v 1.26 2000/11/22 04:07:04 gram Exp $ +$Id: README,v 1.27 2001/10/18 20:29:56 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 @@ -139,6 +139,18 @@ pppd logs (pppdump-format files) -------------------------------- Gilbert +VMS TCPTRACE +------------ +Compaq VMS's TCPIPTRACE format is supported. This is the capture program +that comes with TCP/IP or UCX as supplied by Compaq or Digital Equipment +Corporation. + +Under UCX 4.x, it is invoked as TCPIPTRACE. Under TCPIP 5.x, it is invoked +as TCPTRACE. + +TCPTRACE produces an ascii text based format, that has changed slightly over +time. + Gilbert Ramirez <gram@xiexie.org> Guy Harris <guy@alum.mit.edu> diff --git a/wiretap/file.c b/wiretap/file.c index 861c052692..9b0fb41742 100644 --- a/wiretap/file.c +++ b/wiretap/file.c @@ -1,6 +1,6 @@ /* file.c * - * $Id: file.c,v 1.69 2001/10/16 04:58:24 guy Exp $ + * $Id: file.c,v 1.70 2001/10/18 20:29:56 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -60,6 +60,7 @@ #include "csids.h" #include "pppdump.h" #include "etherpeek.h" +#include "vms.h" /* The open_file_* routines should return: * @@ -107,6 +108,7 @@ static int (*open_routines[])(wtap *, int *) = { toshiba_open, i4btrace_open, csids_open, + vms_open, }; #define N_FILE_TYPES (sizeof open_routines / sizeof open_routines[0]) @@ -365,6 +367,10 @@ static const struct file_type_info { /* WTAP_FILE_ETHERPEEK_MAC_V7 */ { "Etherpeek trace (Macintosh V7)", NULL, NULL, NULL }, + + /* WTAP_FILE_VMS */ + { "TCPIPtrace (VMS)", NULL, + NULL, NULL}, }; /* Name that should be somewhat descriptive. */ diff --git a/wiretap/vms.c b/wiretap/vms.c new file mode 100644 index 0000000000..6ad3b6e942 --- /dev/null +++ b/wiretap/vms.c @@ -0,0 +1,412 @@ +/* vms.c + * + * $Id: vms.c,v 1.1 2001/10/18 20:29:56 guy Exp $ + * + * Wiretap Library + * Copyright (c) 2001 by Marc Milgram <mmilgram@arrayinc.com> + * + * 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 "vms.h" +#include "file_wrappers.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +/* This module reads the output of the 'TCPIPTRACE' command in VMS + * It was initially based on toshiba.c. + */ + +/* + Example 'TCPIPTRACE' output data: + TCPIPtrace full display RCV packet 8 at 10-JUL-2001 14:54:19.56 + + IP Version = 4, IHL = 5, TOS = 00, Total Length = 84 = ^x0054 + IP Identifier = ^x178F, Flags (0=0,DF=0,MF=0), + Fragment Offset = 0 = ^x0000, Calculated Offset = 0 = ^x0000 + IP TTL = 64 = ^x40, Protocol = 17 = ^x11, Header Checksum = ^x4C71 + IP Source Address = 10.12.1.80 + IP Destination Address = 10.12.1.50 + + UDP Source Port = 731, UDP Destination Port = 111 + UDP Header and Datagram Length = 64 = ^x0040, Checksum = ^xB6C0 + + 50010C0A 714C1140 00008F17 54000045 0000 E..T....@.Lq...P + 27E54C3C | C0B64000 6F00DB02 | 32010C0A 0010 ...2...o.@..<L.' + 02000000 A0860100 02000000 00000000 0020 ................ + 00000000 00000000 00000000 03000000 0030 ................ + 06000000 01000000 A5860100 00000000 0040 ................ + 00000000 0050 .... + +-------------------------------------------------------------------------------- + + */ + +/* Magic text to check for VMS-ness of file */ +static const char vms_hdr_magic[] = +{ ' ', ' ', ' ', 'T', 'C', 'P', 'I', 'P', 't', 'r', 'a', 'c', 'e', ' '}; +#define VMS_HDR_MAGIC_SIZE (sizeof vms_hdr_magic / sizeof vms_hdr_magic[0]) + +/* Magic text for start of packet */ +#define vms_rec_magic vms_hdr_magic +#define VMS_REC_MAGIC_SIZE (sizeof vms_rec_magic / sizeof vms_rec_magic[0]) + +static gboolean vms_read(wtap *wth, int *err, long *data_offset); +static int vms_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, int remaining_bytes); +static int parse_vms_hex_dump(FILE_T fh, int pkt_len, guint8* buf, int *err); +static int parse_vms_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 vms_seek_next_packet(wtap *wth) +{ + int byte; + unsigned int level = 0; + + while ((byte = file_getc(wth->fh)) != EOF) { + if (byte == vms_rec_magic[level]) { + level++; + if (level >= VMS_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 VMS_HEADER_LINES_TO_CHECK 200 +#define VMS_LINE_LENGTH 240 + +/* Look through the first part of a file to see if this is + * a VMS trace file. + * + * Returns TRUE if it is, FALSE if it isn't. + * + * Leaves file handle at begining of line that contains the VMS Magic + * identifier. + */ +static gboolean vms_check_file_type(wtap *wth) +{ + char buf[VMS_LINE_LENGTH]; + int line, byte; + unsigned int reclen, i, level; + long mpos; + + buf[VMS_LINE_LENGTH-1] = 0; + + for (line = 0; line < VMS_HEADER_LINES_TO_CHECK; line++) { + mpos = file_tell(wth->fh); + if (file_gets(buf, VMS_LINE_LENGTH, wth->fh) != NULL) { + + reclen = strlen(buf); + if (reclen < VMS_HDR_MAGIC_SIZE) + continue; + + level = 0; + for (i = 0; i < reclen; i++) { + byte = buf[i]; + if (byte == vms_hdr_magic[level]) { + level++; + if (level >= VMS_HDR_MAGIC_SIZE) { + file_seek(wth->fh, mpos, SEEK_SET); + return TRUE; + } + } + else + level = 0; + } + } + else + return FALSE; + } + return FALSE; +} + + +/* XXX - return -1 on I/O error and actually do something with 'err'. */ +int vms_open(wtap *wth, int *err) +{ + /* Look for VMS header */ + if (!vms_check_file_type(wth)) { + return 0; + } + + wth->data_offset = 0; + wth->file_encap = WTAP_ENCAP_PER_PACKET; + wth->file_type = WTAP_FILE_VMS; + wth->snapshot_length = 16384; /* just guessing */ + wth->subtype_read = vms_read; + wth->subtype_seek_read = vms_seek_read; + + return 1; +} + +/* Find the next packet and parse it; called from wtap_loop(). */ +static gboolean vms_read(wtap *wth, int *err, long *data_offset) +{ + long offset = 0; + guint8 *buf; + int pkt_len; + + /* Find the next packet */ + offset = vms_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_vms_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_vms_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 +vms_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_vms_rec_hdr(NULL, wth->random_fh, &err); + + if (pkt_len != len) { + return -1; + } + + parse_vms_hex_dump(wth->random_fh, pkt_len, pd, &err); + + return 0; +} + +/* isdumpline assumes that dump lines start with some spaces followed by a + * hex number. + */ +static int +isdumpline( guchar *line ) +{ + int i = 0; + + while (i<VMS_LINE_LENGTH && !isalnum(line[i])) + i++; + + if (! isxdigit(line[i])) + return 0; + + while (i<VMS_LINE_LENGTH && isxdigit(line[i])) + i++; + + return isspace(line[i]); +} + +/* Parses a packet record header. */ +static int +parse_vms_rec_hdr(wtap *wth, FILE_T fh, int *err) +{ + char line[VMS_LINE_LENGTH]; + int num_items_scanned; + int pkt_len, pktnum, csec; + struct tm time; + char mon[4]; + guchar *p; + long mpos; + 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, VMS_LINE_LENGTH, fh) == NULL) { + *err = file_error(fh); + if (*err == 0) { + *err = WTAP_ERR_SHORT_READ; + } + return -1; + } + + p = strstr(line, "packet "); + if ( !p ) { + *err = WTAP_ERR_BAD_RECORD; + return 01; + } + + /* Find text in line starting with "packet ". */ + num_items_scanned = sscanf(p, + "packet %d at %d-%3s-%d %d:%d:%d.%d", + &pktnum, &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; + } + + /* Skip lines until one starts with a hex number */ + do { + mpos = file_tell(fh); + if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) { + *err = file_error(fh); + if (*err == 0) { + *err = WTAP_ERR_SHORT_READ; + } + return -1; + } + if ( (! pkt_len) && (p = strstr(line, "Length"))) { + p += sizeof("Length "); + while (*p && ! isdigit(*p)) + p++; + + if ( !*p ) { + *err = WTAP_ERR_BAD_RECORD; + return -1; + } + + pkt_len = atoi(p); + } + } while (! isdumpline(line)); + + file_seek(fh, mpos, SEEK_SET); + + 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_vms_hex_dump(FILE_T fh, int pkt_len, guint8* buf, int *err) +{ + guchar line[VMS_LINE_LENGTH]; + int i, hex_lines; + int offset = 0; + + /* 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, VMS_LINE_LENGTH, fh) == NULL) { + *err = file_error(fh); + if (*err == 0) { + *err = WTAP_ERR_SHORT_READ; + } + return -1; + } + if (i == 0) + while (line[offset] && !isxdigit(line[offset])) + offset++; + + if (!parse_single_hex_dump_line(line, buf, i * 16, + offset)) { + *err = WTAP_ERR_BAD_RECORD; + return -1; + } + } + return 0; +} + +/* + 1 2 3 4 +0123456789012345678901234567890123456789012345 + 50010C0A A34C0640 00009017 2C000045 0000 E..,....@.L....P + 00000000 14945E52 0A00DC02 | 32010C0A 0010 ...2....R^...... + 0000 | B4050402 00003496 00020260 0020 `....4........ +*/ + +#define START_POS 7 +#define HEX_LENGTH ((8 * 4) + 7) /* eight clumps of 4 bytes with 7 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 in_off) { + + int i; + char *s; + int value; + static int offsets[16] = {39,37,35,33,28,26,24,22,17,15,13,11,6,4,2,0}; + char lbuf[3] = {0,0,0}; + + + /* Get the byte_offset directly from the record */ + s = rec; + value = strtoul(s + 45 + in_off, NULL, 16); + + if (value != byte_offset) { + return FALSE; + } + + /* Read the octets right to left, as that is how they are displayed + * in VMS. + */ + + for (i = 0; i < 16; i++) { + lbuf[0] = rec[offsets[i] + in_off]; + lbuf[1] = rec[offsets[i] + 1 + in_off]; + + buf[byte_offset + i] = (guint8) strtoul(lbuf, NULL, 16); + } + + return TRUE; +} diff --git a/wiretap/vms.h b/wiretap/vms.h new file mode 100644 index 0000000000..08693fb429 --- /dev/null +++ b/wiretap/vms.h @@ -0,0 +1,29 @@ +/* vms.h + * + * $Id: vms.h,v 1.1 2001/10/18 20:29:56 guy Exp $ + * + * Wiretap Library + * Copyright (c) 2001 by Marc Milgram <mmilgram@arrayinc.com> + * + * 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_VMS_H__ +#define __W_VMS_H__ + +int vms_open(wtap *wth, int *err); + +#endif diff --git a/wiretap/wtap.h b/wiretap/wtap.h index fdbab173ad..70f0928683 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1,6 +1,6 @@ /* wtap.h * - * $Id: wtap.h,v 1.89 2001/10/04 08:30:36 guy Exp $ + * $Id: wtap.h,v 1.90 2001/10/18 20:29:56 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -132,9 +132,10 @@ #define WTAP_FILE_PPPDUMP 24 #define WTAP_FILE_ETHERPEEK_MAC_V56 25 #define WTAP_FILE_ETHERPEEK_MAC_V7 26 +#define WTAP_FILE_VMS 27 /* last WTAP_FILE_ value + 1 */ -#define WTAP_NUM_FILE_TYPES 27 +#define WTAP_NUM_FILE_TYPES 28 /* * Maximum packet size we'll support. |