/* vms.c
- *
- * $Id$
*
* Wiretap Library
* Copyright (c) 2001 by Marc Milgram <ethereal@mmilgram.NOSPAMmail.net>
*/
#include "config.h"
#include "wtap-int.h"
-#include "buffer.h"
+#include <wsutil/buffer.h>
#include "vms.h"
#include "file_wrappers.h"
... packet seq # = nn at DD-MMM-YYYY hh:mm:ss.ss
-If there are other formats then code will have to be written in parse_vms_rec_hdr()
+If there are other formats then code will have to be written in parse_vms_packet()
to handle them.
--------------------------------------------------------------------------------
static gboolean vms_read(wtap *wth, int *err, gchar **err_info,
gint64 *data_offset);
static gboolean vms_seek_read(wtap *wth, gint64 seek_off,
- struct wtap_pkthdr *phdr, Buffer *buf, int len,
- int *err, gchar **err_info);
+ struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
static gboolean parse_single_hex_dump_line(char* rec, guint8 *buf,
long byte_offset, int in_off, int remaining_bytes);
-static gboolean parse_vms_hex_dump(FILE_T fh, int pkt_len, Buffer *buf,
- int *err, gchar **err_info);
-static gboolean parse_vms_rec_hdr(FILE_T fh, struct wtap_pkthdr *phdr,
- int *err, gchar **err_info);
+static gboolean parse_vms_packet(FILE_T fh, struct wtap_pkthdr *phdr,
+ Buffer *buf, int *err, gchar **err_info);
#ifdef TCPIPTRACE_FRAGMENTS_HAVE_HEADER_LINE
/* Seeks to the beginning of the next packet, and returns the
}
-int vms_open(wtap *wth, int *err, gchar **err_info)
+wtap_open_return_val vms_open(wtap *wth, int *err, gchar **err_info)
{
/* Look for VMS header */
if (!vms_check_file_type(wth, err, err_info)) {
if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
- return -1;
- return 0;
+ return WTAP_OPEN_ERROR;
+ return WTAP_OPEN_NOT_MINE;
}
wth->file_encap = WTAP_ENCAP_RAW_IP;
- wth->file_type = WTAP_FILE_VMS;
+ wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_VMS;
wth->snapshot_length = 0; /* not known */
wth->subtype_read = vms_read;
wth->subtype_seek_read = vms_seek_read;
- wth->tsprecision = WTAP_FILE_TSPREC_CSEC;
+ wth->file_tsprec = WTAP_TSPREC_CSEC;
- return 1;
+ return WTAP_OPEN_MINE;
}
/* Find the next packet and parse it; called from wtap_read(). */
*err = file_error(wth->fh, err_info);
return FALSE;
}
-
- /* Parse the header */
- if (!parse_vms_rec_hdr(wth->fh, &wth->phdr, err, err_info))
- return FALSE;
-
- /* Convert the ASCII hex dump to binary data */
- if (!parse_vms_hex_dump(wth->fh, wth->phdr.caplen, wth->frame_buffer, err, err_info))
- return FALSE;
-
*data_offset = offset;
- return TRUE;
+
+ /* Parse the packet */
+ return parse_vms_packet(wth->fh, &wth->phdr, wth->frame_buffer, err, err_info);
}
/* Used to read packets in random-access fashion */
static gboolean
vms_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr,
- Buffer *buf, int len, int *err, gchar **err_info)
+ Buffer *buf, int *err, gchar **err_info)
{
if (file_seek(wth->random_fh, seek_off - 1, SEEK_SET, err) == -1)
return FALSE;
- if (!parse_vms_rec_hdr(wth->random_fh, phdr, err, err_info))
- return FALSE;
-
- if (phdr->caplen != (guint32)len) {
- *err = WTAP_ERR_BAD_FILE;
- *err_info = g_strdup_printf("vms: requested length %d doesn't match length %d",
- len, phdr->caplen);
+ if (!parse_vms_packet(wth->random_fh, phdr, buf, err, err_info)) {
+ if (*err == 0)
+ *err = WTAP_ERR_SHORT_READ;
return FALSE;
}
-
- return parse_vms_hex_dump(wth->random_fh, phdr->caplen, buf, err, err_info);
+ return TRUE;
}
/* isdumpline assumes that dump lines start with some non-alphanumerics
return isspace((guchar)*line);
}
-/* Parses a packet record header. */
+/* Parses a packet record. */
static gboolean
-parse_vms_rec_hdr(FILE_T fh, struct wtap_pkthdr *phdr, int *err, gchar **err_info)
+parse_vms_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
char line[VMS_LINE_LENGTH + 1];
int num_items_scanned;
char mon[4] = {'J', 'A', 'N', 0};
gchar *p;
static const gchar months[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
+ int i;
+ int offset = 0;
+ guint8 *pd;
tm.tm_year = 1970;
tm.tm_mon = 0;
/* First look for the Format 1 type sequencing */
num_items_scanned = sscanf(p,
- "packet %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d",
- &pktnum, &tm.tm_mday, mon,
+ "packet %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d",
+ &pktnum, &tm.tm_mday, mon,
&tm.tm_year, &tm.tm_hour,
&tm.tm_min, &tm.tm_sec, &csec);
/* Next look for the Format 2 type sequencing */
if (num_items_scanned != 8) {
num_items_scanned = sscanf(p,
- "packet seq # = %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d",
- &pktnum, &tm.tm_mday, mon,
- &tm.tm_year, &tm.tm_hour,
- &tm.tm_min, &tm.tm_sec, &csec);
+ "packet seq # = %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d",
+ &pktnum, &tm.tm_mday, mon,
+ &tm.tm_year, &tm.tm_hour,
+ &tm.tm_min, &tm.tm_sec, &csec);
}
/* if unknown format then exit with error */
/* We will need to add code to handle new format */
if (num_items_scanned != 8) {
- *err = WTAP_ERR_BAD_FILE;
- *err_info = g_strdup_printf("vms: header line not valid");
+ *err = WTAP_ERR_BAD_FILE;
+ *err_info = g_strdup_printf("vms: header line not valid");
return FALSE;
}
}
- if ( (! pkt_len) && (p = strstr(line, "Length"))) {
- p += sizeof("Length ");
- while (*p && ! isdigit((guchar)*p))
- p++;
-
- if ( !*p ) {
- *err = WTAP_ERR_BAD_FILE;
- *err_info = g_strdup_printf("vms: Length field not valid");
- return FALSE;
- }
+ if ( (! pkt_len) && (p = strstr(line, "Length"))) {
+ p += sizeof("Length ");
+ while (*p && ! isdigit((guchar)*p))
+ p++;
+
+ if ( !*p ) {
+ *err = WTAP_ERR_BAD_FILE;
+ *err_info = g_strdup_printf("vms: Length field not valid");
+ return FALSE;
+ }
- pkt_len = atoi(p);
+ pkt_len = atoi(p);
break;
- }
+ }
} while (! isdumpline(line));
p = strstr(months, mon);
if (p)
- tm.tm_mon = (int) (p - months) / 3;
+ tm.tm_mon = (int) (p - months) / 3;
tm.tm_year -= 1900;
tm.tm_isdst = -1;
+ phdr->rec_type = REC_TYPE_PACKET;
phdr->presence_flags = WTAP_HAS_TS;
phdr->ts.secs = mktime(&tm);
phdr->ts.nsecs = csec * 10000000;
phdr->caplen = pkt_len;
phdr->len = pkt_len;
- return TRUE;
-}
-
-/* Converts ASCII hex dump to binary data */
-static gboolean
-parse_vms_hex_dump(FILE_T fh, int pkt_len, Buffer *buf, int *err,
- gchar **err_info)
-{
- gchar line[VMS_LINE_LENGTH + 1];
- int i;
- int offset = 0;
- guint8 *pd;
-
/* Make sure we have enough room for the packet */
- buffer_assure_space(buf, pkt_len);
- pd = buffer_start_ptr(buf);
+ ws_buffer_assure_space(buf, pkt_len);
+ pd = ws_buffer_start_ptr(buf);
/* Convert the ASCII hex dump to binary data */
for (i = 0; i < pkt_len; i += 16) {
- if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
- *err = file_error(fh, err_info);
- if (*err == 0) {
- *err = WTAP_ERR_SHORT_READ;
- }
- return FALSE;
- }
+ if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
+ *err = file_error(fh, err_info);
+ if (*err == 0) {
+ *err = WTAP_ERR_SHORT_READ;
+ }
+ return FALSE;
+ }
line[VMS_LINE_LENGTH] = '\0';
- if (i == 0) {
+ if (i == 0) {
while (! isdumpline(line)) { /* advance to start of hex data */
- if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
+ if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
*err = file_error(fh, err_info);
if (*err == 0) {
- *err = WTAP_ERR_SHORT_READ;
+ *err = WTAP_ERR_SHORT_READ;
}
return FALSE;
}
line[VMS_LINE_LENGTH] = '\0';
}
- while (line[offset] && !isxdigit((guchar)line[offset]))
- offset++;
+ while (line[offset] && !isxdigit((guchar)line[offset]))
+ offset++;
}
if (!parse_single_hex_dump_line(line, pd, i,
offset, pkt_len - i)) {
- *err = WTAP_ERR_BAD_FILE;
+ *err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("vms: hex dump not valid");
- return FALSE;
- }
+ return FALSE;
+ }
}
/* Avoid TCPIPTRACE-W-BUFFERSFUL, TCPIPtrace could not save n packets.
* errors.
* Wiretap API, we should parse those lines and return "n" as
* a packet drop count. */
if (!file_gets(line, VMS_LINE_LENGTH, fh)) {
- *err = file_error(fh, err_info);
- if (*err == 0) {
- /* There is no next line, so there's no "TCPIPtrace could not
- * save n packets" line; not an error. */
- return TRUE;
- }
- return FALSE;
+ *err = file_error(fh, err_info);
+ if (*err == 0) {
+ /* There is no next line, so there's no "TCPIPtrace could not
+ * save n packets" line; not an error. */
+ return TRUE;
+ }
+ return FALSE;
}
return TRUE;
}
value = (int)strtoul(s + 45 + in_off, NULL, 16); /* XXX - error check? */
if (value != byte_offset) {
- return FALSE;
+ return FALSE;
}
if (remaining > 16)
*/
for (i = 0; i < remaining; i++) {
- lbuf[0] = rec[offsets[i] + in_off];
- lbuf[1] = rec[offsets[i] + 1 + in_off];
+ lbuf[0] = rec[offsets[i] + in_off];
+ lbuf[1] = rec[offsets[i] + 1 + in_off];
- buf[byte_offset + i] = (guint8) strtoul(lbuf, NULL, 16);
+ buf[byte_offset + i] = (guint8) strtoul(lbuf, NULL, 16);
}
return TRUE;