aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--wiretap/netmon.c90
1 files changed, 77 insertions, 13 deletions
diff --git a/wiretap/netmon.c b/wiretap/netmon.c
index 2178bc0699..7e09a7f52f 100644
--- a/wiretap/netmon.c
+++ b/wiretap/netmon.c
@@ -93,7 +93,7 @@ struct netmonrec_1_x_hdr {
* help files.
*/
struct netmonrec_2_x_hdr {
- guint64 ts_delta; /* time stamp - tenths of usecs since start of capture */
+ guint64 ts_delta; /* time stamp - usecs since start of capture */
guint32 orig_len; /* actual length of packet */
guint32 incl_len; /* number of octets captured in file */
};
@@ -199,7 +199,7 @@ int netmon_open(wtap *wth, int *err, gchar **err_info)
struct netmon_hdr hdr;
int file_type;
struct tm tm;
- int frame_table_offset;
+ guint32 frame_table_offset;
guint32 frame_table_length;
guint32 frame_table_size;
guint32 *frame_table;
@@ -463,7 +463,7 @@ static gboolean netmon_read(wtap *wth, int *err, gchar **err_info,
} hdr;
int hdr_size = 0;
int trlr_size;
- int rec_offset;
+ gint64 rec_offset;
guint8 *data_ptr;
gint64 delta = 0; /* signed - frame times can be before the nominal start */
gint64 t;
@@ -928,9 +928,12 @@ static const int wtap_encap[] = {
an error indication otherwise. */
int netmon_dump_can_write_encap(int encap)
{
- /* Per-packet encapsulations aren't supported. */
+ /*
+ * Per-packet encapsulations are supported in NetMon 2.1
+ * format.
+ */
if (encap == WTAP_ENCAP_PER_PACKET)
- return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
+ return 0;
if (encap < 0 || (unsigned) encap >= NUM_WTAP_ENCAPS || wtap_encap[encap] == -1)
return WTAP_ERR_UNSUPPORTED_ENCAP;
@@ -975,13 +978,35 @@ static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
netmon_dump_t *netmon = (netmon_dump_t *)wdh->priv;
struct netmonrec_1_x_hdr rec_1_x_hdr;
struct netmonrec_2_x_hdr rec_2_x_hdr;
- char *hdrp;
+ void *hdrp;
+ size_t rec_size;
+ struct netmonrec_2_1_trlr rec_2_x_trlr;
size_t hdr_size;
struct netmon_atm_hdr atm_hdr;
int atm_hdrsize;
gint64 secs;
gint32 nsecs;
+ if (wdh->encap == WTAP_ENCAP_PER_PACKET) {
+ /*
+ * Is this network type supported?
+ */
+ if (phdr->pkt_encap < 0 ||
+ (unsigned) phdr->pkt_encap >= NUM_WTAP_ENCAPS ||
+ wtap_encap[phdr->pkt_encap] == -1) {
+ /*
+ * No. Fail.
+ */
+ *err = WTAP_ERR_UNSUPPORTED_ENCAP;
+ return FALSE;
+ }
+
+ /*
+ * Fill in the trailer with the network type.
+ */
+ phtoles(rec_2_x_trlr.network, wtap_encap[phdr->pkt_encap]);
+ }
+
/*
* NetMon files have a capture start time in the file header,
* and have times relative to that in the packet headers;
@@ -1035,7 +1060,7 @@ static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
rec_1_x_hdr.ts_delta = htolel(secs*1000 + (nsecs + 500000)/1000000);
rec_1_x_hdr.orig_len = htoles(phdr->len + atm_hdrsize);
rec_1_x_hdr.incl_len = htoles(phdr->caplen + atm_hdrsize);
- hdrp = (char *)&rec_1_x_hdr;
+ hdrp = &rec_1_x_hdr;
hdr_size = sizeof rec_1_x_hdr;
break;
@@ -1043,7 +1068,7 @@ static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
rec_2_x_hdr.ts_delta = htolell(secs*1000000 + (nsecs + 500)/1000);
rec_2_x_hdr.orig_len = htolel(phdr->len + atm_hdrsize);
rec_2_x_hdr.incl_len = htolel(phdr->caplen + atm_hdrsize);
- hdrp = (char *)&rec_2_x_hdr;
+ hdrp = &rec_2_x_hdr;
hdr_size = sizeof rec_2_x_hdr;
break;
@@ -1054,8 +1079,15 @@ static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
return FALSE;
}
+ /*
+ * Keep track of the record size, as we need to update
+ * the current file offset.
+ */
+ rec_size = 0;
+
if (!wtap_dump_file_write(wdh, hdrp, hdr_size, err))
return FALSE;
+ rec_size += hdr_size;
if (wdh->encap == WTAP_ENCAP_ATM_PDUS) {
/*
@@ -1068,10 +1100,22 @@ static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
atm_hdr.vci = g_htons(pseudo_header->atm.vci);
if (!wtap_dump_file_write(wdh, &atm_hdr, sizeof atm_hdr, err))
return FALSE;
+ rec_size += sizeof atm_hdr;
}
if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
return FALSE;
+ rec_size += phdr->caplen;
+
+ if (wdh->encap == WTAP_ENCAP_PER_PACKET) {
+ /*
+ * Write out the trailer.
+ */
+ if (!wtap_dump_file_write(wdh, &rec_2_x_trlr,
+ sizeof rec_2_x_trlr, err))
+ return FALSE;
+ rec_size += sizeof rec_2_x_trlr;
+ }
/*
* Stash the file offset of this frame.
@@ -1098,7 +1142,7 @@ static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
netmon->frame_table[netmon->frame_table_index] =
htolel(netmon->frame_table_offset);
netmon->frame_table_index++;
- netmon->frame_table_offset += (int) hdr_size + phdr->caplen + atm_hdrsize;
+ netmon->frame_table_offset += (guint32) rec_size;
return TRUE;
}
@@ -1139,9 +1183,22 @@ static gboolean netmon_dump_close(wtap_dumper *wdh, int *err)
/*
* NetMon file version, for 2.x, is 2.0;
* for 3.0, it's 2.1.
+ *
+ * If the file encapsulation is WTAP_ENCAP_PER_PACKET,
+ * we need version 2.1.
+ *
+ * XXX - version 2.3 supports UTC time stamps; when
+ * should we use it? According to the file format
+ * documentation, NetMon 3.3 "cannot properly
+ * interpret" the UTC timestamp information; does
+ * that mean it ignores it and uses the local-time
+ * start time and time deltas, or mishandles them?
+ * Also, NetMon 3.1 and earlier can't read version
+ * 2.2, much less version 2.3.
*/
file_hdr.ver_major = 2;
- file_hdr.ver_minor = 0;
+ file_hdr.ver_minor =
+ (wdh->encap == WTAP_ENCAP_PER_PACKET) ? 1 : 0;
break;
default:
@@ -1154,7 +1211,15 @@ static gboolean netmon_dump_close(wtap_dumper *wdh, int *err)
if (!wtap_dump_file_write(wdh, magicp, magic_size, err))
return FALSE;
- file_hdr.network = htoles(wtap_encap[wdh->encap]);
+ if (wdh->encap == WTAP_ENCAP_PER_PACKET) {
+ /*
+ * We're writing NetMon 2.1 format, so the media
+ * type in the file header is irrelevant. Set it
+ * to 1, just as Network Monitor does.
+ */
+ file_hdr.network = htoles(1);
+ } else
+ file_hdr.network = htoles(wtap_encap[wdh->encap]);
tm = localtime(&netmon->first_record_time.secs);
if (tm != NULL) {
file_hdr.ts_year = htoles(1900 + tm->tm_year);
@@ -1173,8 +1238,7 @@ static gboolean netmon_dump_close(wtap_dumper *wdh, int *err)
file_hdr.ts_min = htoles(0);
file_hdr.ts_sec = htoles(0);
}
- file_hdr.ts_msec = htoles(netmon->first_record_time.nsecs/1000000);
- /* XXX - what about rounding? */
+ file_hdr.ts_msec = htoles(netmon->first_record_time.nsecs/1000000);
file_hdr.frametableoffset = htolel(netmon->frame_table_offset);
file_hdr.frametablelength =
htolel(netmon->frame_table_index * sizeof *netmon->frame_table);