Ethereal-dev: [Ethereal-dev] Improved VMS parser
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Marc Milgram <mmilgram@xxxxxxxxxxxx>
Date: 30 Jan 2002 09:30:37 -0500
In answering some questions for the engineer at Compaq who is responsible for TCPtrace, I found that there were some simple bugs in the VMS parser. One was a memory allocation error. When that bug was fixed, I found that ethereal crashed on some of the traces - due to a line of the following form (that may replace any line in the file - including the packet header line): TCPIPTRACE-W-BUFFERSFULL, TCPIPtrace could not save 2 packets. I reworked the parser to handle that error as best it could, and still accept handle the packet. If the parser can't get the timestamp for the packet, it is setting the time to near the begining of Unix time (Jan 1, 1970). Should I pick some other time? -Marc Milgram
Index: wiretap/vms.c =================================================================== RCS file: /cvsroot/ethereal/wiretap/vms.c,v retrieving revision 1.4 diff -u -r1.4 vms.c --- vms.c 2002/01/15 20:18:02 1.4 +++ vms.c 2002/01/30 14:18:59 @@ -74,7 +74,7 @@ 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 gboolean parse_single_hex_dump_line(char* rec, guint8 *buf, long byte_offset, int in_off, 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); @@ -88,6 +88,8 @@ unsigned int level = 0; while ((byte = file_getc(wth->fh)) != EOF) { + if ((level == 3) && (byte != vms_rec_magic[level])) + level += 2; /* Accept TCPtrace as well as TCPIPtrace */ if (byte == vms_rec_magic[level]) { level++; if (level >= VMS_REC_MAGIC_SIZE) { @@ -132,6 +134,8 @@ level = 0; for (i = 0; i < reclen; i++) { byte = buf[i]; + if ((level == 3) && (byte != vms_hdr_magic[level])) + level += 2; /* Accept TCPIPtrace as well as TCPtrace */ if (byte == vms_hdr_magic[level]) { level++; if (level >= VMS_HDR_MAGIC_SIZE) { @@ -185,8 +189,11 @@ /* Parse the header */ pkt_len = parse_vms_rec_hdr(wth, wth->fh, err); + if (pkt_len == -1) + return FALSE; + /* Make sure we have enough room for the packet */ - buffer_assure_space(wth->frame_buffer, wth->snapshot_length); + buffer_assure_space(wth->frame_buffer, pkt_len); buf = buffer_start_ptr(wth->frame_buffer); /* Convert the ASCII hex dump to binary data */ @@ -244,53 +251,43 @@ { char line[VMS_LINE_LENGTH]; int num_items_scanned; - int pkt_len, pktnum, csec; + int pkt_len = 0; + int pktnum; + int csec = 101; struct tm time; - char mon[4]; + char mon[4] = {'J', 'A', 'N', 0}; guchar *p; static guchar months[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"; - pkt_len = 0; + time.tm_year = 1970; + time.tm_hour = 1; + time.tm_min = 1; + time.tm_sec = 1; - /* 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 { if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) { *err = file_error(fh); - if (*err == 0) { - *err = WTAP_ERR_SHORT_READ; + if ((*err == 0) && (csec != 101)) { + *err = WTAP_ERR_SHORT_READ; } return -1; } + if ((csec == 101) && (p = strstr(line, "packet ")) + && (! strstr(line, "could not save "))) { + /* 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; + } + } if ( (! pkt_len) && (p = strstr(line, "Length"))) { p += sizeof("Length "); while (*p && ! isdigit(*p)) @@ -328,14 +325,10 @@ parse_vms_hex_dump(FILE_T fh, int pkt_len, guint8* buf, int *err) { guchar line[VMS_LINE_LENGTH]; - int i, hex_lines; + int i; 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++) { + for (i = 0; i < pkt_len; i += 16) { if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) { *err = file_error(fh); if (*err == 0) { @@ -355,12 +348,15 @@ while (line[offset] && !isxdigit(line[offset])) offset++; } - if (!parse_single_hex_dump_line(line, buf, i * 16, - offset)) { + if (!parse_single_hex_dump_line(line, buf, i, + offset, pkt_len - i)) { *err = WTAP_ERR_BAD_RECORD; return -1; } } + /* Avoid TCPIPTRACE-W-BUFFERSFUL, TCPIPtrace could not save n packets. + * errors. */ + file_gets(line, VMS_LINE_LENGTH, fh); return 0; } @@ -379,13 +375,11 @@ * 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 in_off, int remaining) { int i; char *s; @@ -402,11 +396,14 @@ return FALSE; } + if (remaining > 16) + remaining = 16; + /* Read the octets right to left, as that is how they are displayed * in VMS. */ - for (i = 0; i < 16; i++) { + for (i = 0; i < remaining; i++) { lbuf[0] = rec[offsets[i] + in_off]; lbuf[1] = rec[offsets[i] + 1 + in_off];
- Follow-Ups:
- Re: [Ethereal-dev] Improved VMS parser
- From: Guy Harris
- Re: [Ethereal-dev] Improved VMS parser
- Prev by Date: Re: [Ethereal-dev] Next release
- Next by Date: Re: [Ethereal-dev] regenerated giop plugins
- Previous by thread: Re: [Ethereal-dev] regenerated giop plugins
- Next by thread: Re: [Ethereal-dev] Improved VMS parser
- Index(es):