Ethereal-dev: [Ethereal-dev] VMS TCPIPtrace
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Marc Milgram <marc.milgram@xxxxxxxxxx>
Date: Thu, 18 Oct 2001 15:23:47 -0400
Hello, This is an implementation of a VMS TCPIPtrace decoder wiretap module. -Marc Milgram <mmilgram[AT]arrayinc.com> Index: AUTHORS =================================================================== RCS file: /cvsroot/ethereal/AUTHORS,v retrieving revision 1.336 diff -u -r1.336 AUTHORS --- AUTHORS 2001/10/18 08:23:24 1.336 +++ AUTHORS 2001/10/18 19:20:17 @@ -829,6 +829,10 @@ UCP fixes } +Marc Milgram <mmilgram[AT]arrayinc.com> { + VMS TCPIPtrace wiretap module +} + Alain Magloire <alainm[AT]rcsm.ece.mcgill.ca> was kind enough to give his permission to use his version of snprintf.c. Index: doc/editcap.pod =================================================================== RCS file: /cvsroot/ethereal/doc/editcap.pod,v retrieving revision 1.10 diff -u -r1.10 doc/editcap.pod --- doc/editcap.pod 2001/07/12 19:59:40 1.10 +++ doc/editcap.pod 2001/10/18 19:20:17 @@ -26,13 +26,13 @@ B<snoop> (including B<Shomiti>) and B<atmsnoop>, B<LanAlyzer>, B<Sniffer> (compressed or uncompressed), Microsoft B<Network Monitor>, AIX's B<iptrace>, B<NetXray>, B<Sniffer Pro>, B<RADCOM>'s WAN/LAN -analyzer, B<Lucent/Ascend> router debug output, HP-UX's B<nettl>, and -the dump output from B<Toshiba's> ISDN routers. There is no need to -tell B<Editcap> what type of file you are reading; it will determine the -file type by itself. B<Editcap> is also capable of reading any of these -file formats if they are compressed using gzip. B<Editcap> recognizes -this directly from the file; the '.gz' extension is not required for -this purpose. +analyzer, B<Lucent/Ascend> router debug output, HP-UX's B<nettl>, the +dump output from B<Toshiba's> ISDN routers, and the output from VMS's +B<TCPIPtrace> utility. There is no need to tell B<Editcap> what type +of file you are reading; it will determine the file type by itself. +B<Editcap> is also capable of reading any of these file formats if they +are compressed using gzip. B<Editcap> recognizes this directly from the +file; the '.gz' extension is not required for this purpose. By default, it writes the capture file in B<libpcap> format, and writes all of the packets in the capture file to the output file. The B<-F> Index: doc/ethereal.pod.template =================================================================== RCS file: /cvsroot/ethereal/doc/ethereal.pod.template,v retrieving revision 1.216 diff -u -r1.216 doc/ethereal.pod.template --- doc/ethereal.pod.template 2001/10/15 03:54:05 1.216 +++ doc/ethereal.pod.template 2001/10/18 19:20:18 @@ -40,9 +40,10 @@ Microsoft B<Network Monitor>, AIX's B<iptrace>, B<NetXray>, B<Sniffer Pro>, B<Etherpeek>, B<RADCOM>'s WAN/LAN analyzer, B<Lucent/Ascend> router debug output, HP-UX's B<nettl>, the dump output from B<Toshiba's> -ISDN routers, the output from B<i4btrace> from the ISDN4BSD project, the -output in B<IPLog> format from the Cisco Secure Intrusion Detection -System, and B<pppd logs> (pppdump format). There is no need to tell +ISDN routers, the output from VMS's B<TCPIPtrace> utility, the output +from B<i4btrace> from the ISDN4BSD project, the output in B<IPLog> +format from the Cisco Secure Intrusion Detection System, and +B<pppd logs> (pppdump format). There is no need to tell B<Ethereal> what type of file you are reading; it will determine the file type by itself. B<Ethereal> is also capable of reading any of these file formats if they are compressed using gzip. B<Ethereal> Index: doc/mergecap.pod =================================================================== RCS file: /cvsroot/ethereal/doc/mergecap.pod,v retrieving revision 1.3 diff -u -r1.3 doc/mergecap.pod --- doc/mergecap.pod 2001/07/14 19:28:11 1.3 +++ doc/mergecap.pod 2001/10/18 19:20:18 @@ -23,13 +23,13 @@ B<Shomiti>) and B<atmsnoop>, B<LanAlyzer>, B<Sniffer> (compressed or uncompressed), Microsoft B<Network Monitor>, AIX's B<iptrace>, B<NetXray>, B<Sniffer Pro>, B<RADCOM>'s WAN/LAN analyzer, -B<Lucent/Ascend> router debug output, HP-UX's B<nettl>, and the dump -output from B<Toshiba's> ISDN routers. There is no need to tell -B<Mergecap> what type of file you are reading; it will determine the -file type by itself. B<Mergecap> is also capable of reading any of -these file formats if they are compressed using gzip. B<Mergecap> -recognizes this directly from the file; the '.gz' extension is not -required for this purpose. +B<Lucent/Ascend> router debug output, HP-UX's B<nettl>, the dump output +from B<Toshiba's> ISDN routers, and the output from VMS's B<TCPIPtrace> +utility. There is no need to tell B<Mergecap> what type of file you are +reading; it will determine the file type by itself. B<Mergecap> is also +capable of reading any of these file formats if they are compressed using +gzip. B<Mergecap> recognizes this directly from the file; the '.gz' +extension is not required for this purpose. By default, it writes the capture file in B<libpcap> format, and writes all of the packets in both input capture files to the output file. The Index: doc/tethereal.pod.template =================================================================== RCS file: /cvsroot/ethereal/doc/tethereal.pod.template,v retrieving revision 1.32 diff -u -r1.32 doc/tethereal.pod.template --- doc/tethereal.pod.template 2001/10/11 01:21:50 1.32 +++ doc/tethereal.pod.template 2001/10/18 19:20:18 @@ -39,13 +39,14 @@ uncompressed), Microsoft B<Network Monitor>, AIX's B<iptrace>, B<NetXray>, B<Sniffer Pro>, B<Etherpeek>, B<RADCOM>'s WAN/LAN analyzer, B<Lucent/Ascend> router debug output, HP-UX's B<nettl>, the dump output -from B<Toshiba's> ISDN routers, the output from B<i4btrace> from the -ISDN4BSD project, and output in IPLog format from the Cisco Secure -Intrusion Detection System. There is no need to tell B<Tethereal> what -type of file you are reading; it will determine the file type by itself. -B<Tethereal> is also capable of reading any of these file formats if -they are compressed using gzip. B<Tethereal> recognizes this directly -from the file; the '.gz' extension is not required for this purpose. +from B<Toshiba's> ISDN routers, the output from VMS's B<TCPIPtrace> +utility, the output from B<i4btrace> from the ISDN4BSD project, and +output in IPLog format from the Cisco Secure Intrusion Detection System. +There is no need to tell B<Tethereal> what type of file you are reading; +it will determine the file type by itself. B<Tethereal> is also capable +of reading any of these file formats if they are compressed using gzip. +B<Tethereal> recognizes this directly from the file; the '.gz' extension +is not required for this purpose. If the B<-w> flag is not specified, B<Tethereal> prints a decoded form of the packets it captures or reads; otherwise, it writes those packets Index: wiretap/AUTHORS =================================================================== RCS file: /cvsroot/ethereal/wiretap/AUTHORS,v retrieving revision 1.14 diff -u -r1.14 wiretap/AUTHORS --- wiretap/AUTHORS 2001/04/17 00:46:06 1.14 +++ wiretap/AUTHORS 2001/10/18 19:20:18 @@ -10,3 +10,4 @@ Mike Hall <mlh@xxxxxx> Daniel Thompson <daniel.thompson@xxxxxx> Chris Jepeway <thai-dragon@xxxxxxxxxxxx> +Marc Milgram <mmilgram@xxxxxxxxxxxx> Index: wiretap/Makefile.am =================================================================== RCS file: /cvsroot/ethereal/wiretap/Makefile.am,v retrieving revision 1.33 diff -u -r1.33 wiretap/Makefile.am --- wiretap/Makefile.am 2001/04/18 21:34:22 1.33 +++ wiretap/Makefile.am 2001/10/18 19:20:18 @@ -72,6 +72,8 @@ snoop.h \ toshiba.c \ toshiba.h \ + vms.c \ + vms.h \ wtap.c \ wtap.h \ wtap-int.h Index: wiretap/Makefile.nmake =================================================================== RCS file: /cvsroot/ethereal/wiretap/Makefile.nmake,v retrieving revision 1.20 diff -u -r1.20 wiretap/Makefile.nmake --- wiretap/Makefile.nmake 2001/04/12 18:07:22 1.20 +++ wiretap/Makefile.nmake 2001/10/18 19:20:18 @@ -32,6 +32,7 @@ pppdump.obj \ snoop.obj \ toshiba.obj \ + vms.obj \ wtap.obj Index: wiretap/README =================================================================== RCS file: /cvsroot/ethereal/wiretap/README,v retrieving revision 1.26 diff -u -r1.26 wiretap/README --- wiretap/README 2000/11/22 04:07:04 1.26 +++ wiretap/README 2001/10/18 19:20:19 @@ -139,6 +139,20 @@ -------------------------------- 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@xxxxxxxxxx> Guy Harris <guy@xxxxxxxxxxxx> + + Index: wiretap/file.c =================================================================== RCS file: /cvsroot/ethereal/wiretap/file.c,v retrieving revision 1.69 diff -u -r1.69 wiretap/file.c --- wiretap/file.c 2001/10/16 04:58:24 1.69 +++ wiretap/file.c 2001/10/18 19:20:19 @@ -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 @@ toshiba_open, i4btrace_open, csids_open, + vms_open, }; #define N_FILE_TYPES (sizeof open_routines / sizeof open_routines[0]) @@ -365,6 +367,10 @@ /* 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. */ Index: wiretap/wtap.h =================================================================== RCS file: /cvsroot/ethereal/wiretap/wtap.h,v retrieving revision 1.89 diff -u -r1.89 wiretap/wtap.h --- wiretap/wtap.h 2001/10/04 08:30:36 1.89 +++ wiretap/wtap.h 2001/10/18 19:20:19 @@ -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. /* vms.c * * $Id$ * * Wiretap Library * Copyright (c) 2001 by Marc Milgram <mmilgram@xxxxxxxxxxxx> * * 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 [email protected] 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, int *data_offset); static int vms_seek_read(wtap *wth, int seek_off, union wtap_pseudo_header *pseudo_header, guint8 *pd, int len);static gboolean parse_single_hex_dump_line(char* rec, guint8 *buf, int 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 int 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, int *data_offset) { int 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 intvms_seek_read (wtap *wth, int 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( char *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]; char *p; long mpos; static char 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) { char 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..,[email protected] 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, int 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; } /* vms.h * * $Id$ * * Wiretap Library * Copyright (c) 2001 by Marc Milgram <mmilgram@xxxxxxxxxxxx> * * 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
- Follow-Ups:
- Re: [Ethereal-dev] VMS TCPIPtrace
- From: Guy Harris
- Re: [Ethereal-dev] VMS TCPIPtrace
- Prev by Date: Re: [Ethereal-dev] A new user guide with A4 and US Letter PDFsreleased
- Next by Date: Re: [Ethereal-dev] VMS TCPIPtrace
- Previous by thread: Re: [Ethereal-dev] tiny idl2eth patch
- Next by thread: Re: [Ethereal-dev] VMS TCPIPtrace
- Index(es):