summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2014-07-05 11:45:18 -0700
committerGuy Harris <guy@alum.mit.edu>2014-07-05 18:46:57 +0000
commit599b880e4c53613c243b0a39548968f34cdce0e3 (patch)
tree045e608111e875c1efc823f540f25018f54865d3
parent3686713e7cfe2c1b8853455370a83884aaa5fdea (diff)
downloadwireshark-599b880e4c53613c243b0a39548968f34cdce0e3.tar.gz
Handle the UTC timestamps in NetMon 2.3 files.
This addresses part of, but not all of, the issues in bug ten thousand, one hundred, and ninety: https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10190 (I'm spelling it out to make sure Gerrit doesn't think this change *does* address all the issues in that bug, and mark it as RESOLVED FIXED; I feel like I have to treat Gerrit as a dog or small child from whom I'm trying to keep a secret - "honey, I'm taking the dog to the vee eee tee".) Change-Id: Ic234130c1ea84cfaf47901485dca775e168f71d0 Reviewed-on: https://code.wireshark.org/review/2859 Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r--wiretap/netmon.c270
1 files changed, 148 insertions, 122 deletions
diff --git a/wiretap/netmon.c b/wiretap/netmon.c
index 85d82a2d22..a04d31f79a 100644
--- a/wiretap/netmon.c
+++ b/wiretap/netmon.c
@@ -181,8 +181,6 @@ static gboolean netmon_seek_read(wtap *wth, gint64 seek_off,
struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
static gboolean netmon_read_atm_pseudoheader(FILE_T fh,
union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
-static int netmon_read_rec_trailer(FILE_T fh, int trlr_size, int *err,
- gchar **err_info);
static void netmon_sequential_close(wtap *wth);
static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
const guint8 *pd, int *err);
@@ -413,33 +411,6 @@ int netmon_open(wtap *wth, int *err, gchar **err_info)
return 1;
}
-static size_t
-netmon_trailer_size(netmon_t *netmon)
-{
- if ((netmon->version_major == 2 && netmon->version_minor >= 1) ||
- netmon->version_major > 2) {
- if (netmon->version_major > 2) {
- /*
- * Asssume 2.3 format, for now.
- */
- return sizeof (struct netmonrec_2_3_trlr);
- } else {
- switch (netmon->version_minor) {
-
- case 1:
- return sizeof (struct netmonrec_2_1_trlr);
-
- case 2:
- return sizeof (struct netmonrec_2_2_trlr);
-
- default:
- return sizeof (struct netmonrec_2_3_trlr);
- }
- }
- }
- return 0; /* no trailer */
-}
-
static void
netmon_set_pseudo_header_info(int pkt_encap, struct wtap_pkthdr *phdr,
Buffer *buf)
@@ -657,24 +628,164 @@ typedef enum {
RETRY
} process_trailer_retval;
+/*
+ * Number of seconds between the UN*X epoch (January 1, 1970, 00:00:00 GMT)
+ * and the Windows NT epoch (January 1, 1601, 00:00:00 "GMT").
+ */
+#define TIME_FIXUP_CONSTANT G_GUINT64_CONSTANT(11644473600)
+
+#ifndef TIME_T_MIN
+#define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \
+ : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
+#endif
+#ifndef TIME_T_MAX
+#define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
+#endif
+
static process_trailer_retval netmon_process_rec_trailer(netmon_t *netmon,
FILE_T fh, struct wtap_pkthdr *phdr, int *err, gchar **err_info)
{
int trlr_size;
+ int bytes_read;
+ union {
+ struct netmonrec_2_1_trlr trlr_2_1;
+ struct netmonrec_2_2_trlr trlr_2_2;
+ struct netmonrec_2_3_trlr trlr_2_3;
+ } trlr;
+ guint16 network;
+ int pkt_encap;
- trlr_size = (int)netmon_trailer_size(netmon);
- if (trlr_size != 0) {
+ if ((netmon->version_major == 2 && netmon->version_minor >= 1) ||
+ netmon->version_major > 2) {
/*
* I haz a trailer.
*/
- phdr->pkt_encap = netmon_read_rec_trailer(fh,
- trlr_size, err, err_info);
- if (phdr->pkt_encap == -1)
+ if (netmon->version_major > 2) {
+ /*
+ * Asssume 2.3 format, for now.
+ */
+ trlr_size = (int)sizeof (struct netmonrec_2_3_trlr);
+ } else {
+ switch (netmon->version_minor) {
+
+ case 1:
+ trlr_size = (int)sizeof (struct netmonrec_2_1_trlr);
+ break;
+
+ case 2:
+ trlr_size = (int)sizeof (struct netmonrec_2_2_trlr);
+ break;
+
+ default:
+ trlr_size = (int)sizeof (struct netmonrec_2_3_trlr);
+ break;
+ }
+ }
+
+ errno = WTAP_ERR_CANT_READ;
+ bytes_read = file_read(&trlr, trlr_size, fh);
+ if (bytes_read != trlr_size) {
+ *err = file_error(fh, err_info);
+ if (*err == 0 && bytes_read != 0) {
+ *err = WTAP_ERR_SHORT_READ;
+ }
return FAILURE; /* error */
- if (phdr->pkt_encap == 0)
- return RETRY;
- }
+ }
+
+ network = pletoh16(trlr.trlr_2_1.network);
+ if ((network & 0xF000) == NETMON_NET_PCAP_BASE) {
+ /*
+ * Converted pcap file - the LINKTYPE_ value
+ * is the network value with 0xF000 masked off.
+ */
+ network &= 0x0FFF;
+ pkt_encap = wtap_pcap_encap_to_wtap_encap(network);
+ if (pkt_encap == WTAP_ENCAP_UNKNOWN) {
+ *err = WTAP_ERR_UNSUPPORTED_ENCAP;
+ *err_info = g_strdup_printf("netmon: converted pcap network type %u unknown or unsupported",
+ network);
+ return FAILURE; /* error */
+ }
+ } else if (network < NUM_NETMON_ENCAPS) {
+ /*
+ * Regular NetMon encapsulation.
+ */
+ pkt_encap = netmon_encap[network];
+ if (pkt_encap == WTAP_ENCAP_UNKNOWN) {
+ *err = WTAP_ERR_UNSUPPORTED_ENCAP;
+ *err_info = g_strdup_printf("netmon: network type %u unknown or unsupported",
+ network);
+ return FAILURE; /* error */
+ }
+ } else {
+ /*
+ * Special packet type for metadata.
+ */
+ switch (network) {
+
+ case NETMON_NET_NETEVENT:
+ case NETMON_NET_NETWORK_INFO_EX:
+ case NETMON_NET_PAYLOAD_HEADER:
+ case NETMON_NET_NETWORK_INFO:
+ case NETMON_NET_DNS_CACHE:
+ case NETMON_NET_NETMON_FILTER:
+ /*
+ * Just ignore those record types, for
+ * now. Tell our caller to read the next
+ * record.
+ */
+ return RETRY;
+ default:
+ *err = WTAP_ERR_UNSUPPORTED_ENCAP;
+ *err_info = g_strdup_printf("netmon: network type %u unknown or unsupported",
+ network);
+ return FAILURE; /* error */
+ }
+ }
+
+ phdr->pkt_encap = pkt_encap;
+ if (netmon->version_major > 2 || netmon->version_minor > 2) {
+ /*
+ * This code is based on the Samba code:
+ *
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * time handling functions
+ * Copyright (C) Andrew Tridgell 1992-1998
+ */
+ guint64 d;
+ gint64 secs;
+ int nsecs;
+ /* The next two lines are a fix needed for the
+ broken SCO compiler. JRA. */
+ time_t l_time_min = TIME_T_MIN;
+ time_t l_time_max = TIME_T_MAX;
+
+ d = pletoh64(trlr.trlr_2_3.utc_timestamp);
+
+ /* Split into seconds and nanoseconds. */
+ secs = d / 10000000;
+ nsecs = (int)((d % 10000000)*100);
+
+ /* Now adjust the seconds. */
+ secs -= TIME_FIXUP_CONSTANT;
+
+ if (!(l_time_min <= secs && secs <= l_time_max)) {
+ *err = WTAP_ERR_BAD_FILE;
+ *err_info = g_strdup_printf("netmon: time stamp outside supported range");
+ return FALSE;
+ }
+
+ /*
+ * Get the time as seconds and nanoseconds.
+ * and overwrite the time stamp obtained
+ * from the record header.
+ */
+ phdr->ts.secs = (time_t) secs;
+ phdr->ts.nsecs = nsecs;
+ }
+ }
return SUCCESS;
}
@@ -826,91 +937,6 @@ netmon_read_atm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
return TRUE;
}
-/*
- * Read a record trailer.
- * On success, returns the packet encapsulation type.
- * On error, returns -1 (which is WTAP_ENCAP_PER_PACKET, but we'd
- * never return that on success).
- * For metadata packets, returns 0 (which is WTAP_ENCAP_UNKNOWN, but
- * we'd never return that on success).
- */
-static int
-netmon_read_rec_trailer(FILE_T fh, int trlr_size, int *err, gchar **err_info)
-{
- int bytes_read;
- union {
- struct netmonrec_2_1_trlr trlr_2_1;
- struct netmonrec_2_2_trlr trlr_2_2;
- struct netmonrec_2_3_trlr trlr_2_3;
- } trlr;
- guint16 network;
- int pkt_encap;
-
- errno = WTAP_ERR_CANT_READ;
- bytes_read = file_read(&trlr, trlr_size, fh);
- if (bytes_read != trlr_size) {
- *err = file_error(fh, err_info);
- if (*err == 0 && bytes_read != 0) {
- *err = WTAP_ERR_SHORT_READ;
- }
- return -1; /* error */
- }
-
- network = pletoh16(trlr.trlr_2_1.network);
- if ((network & 0xF000) == NETMON_NET_PCAP_BASE) {
- /*
- * Converted pcap file - the LINKTYPE_ value
- * is the network value with 0xF000 masked off.
- */
- network &= 0x0FFF;
- pkt_encap = wtap_pcap_encap_to_wtap_encap(network);
- if (pkt_encap == WTAP_ENCAP_UNKNOWN) {
- *err = WTAP_ERR_UNSUPPORTED_ENCAP;
- *err_info = g_strdup_printf("netmon: converted pcap network type %u unknown or unsupported",
- network);
- return -1; /* error */
- }
- } else if (network < NUM_NETMON_ENCAPS) {
- /*
- * Regular NetMon encapsulation.
- */
- pkt_encap = netmon_encap[network];
- if (pkt_encap == WTAP_ENCAP_UNKNOWN) {
- *err = WTAP_ERR_UNSUPPORTED_ENCAP;
- *err_info = g_strdup_printf("netmon: network type %u unknown or unsupported",
- network);
- return -1; /* error */
- }
- } else {
- /*
- * Special packet type for metadata.
- */
- switch (network) {
-
- case NETMON_NET_NETEVENT:
- case NETMON_NET_NETWORK_INFO_EX:
- case NETMON_NET_PAYLOAD_HEADER:
- case NETMON_NET_NETWORK_INFO:
- case NETMON_NET_DNS_CACHE:
- case NETMON_NET_NETMON_FILTER:
- /*
- * Just ignore those record types, for
- * now. Tell our caller to read the next
- * record.
- */
- return 0;
-
- default:
- *err = WTAP_ERR_UNSUPPORTED_ENCAP;
- *err_info = g_strdup_printf("netmon: network type %u unknown or unsupported",
- network);
- return -1; /* error */
- }
- }
-
- return pkt_encap; /* success */
-}
-
/* Throw away the frame table used by the sequential I/O stream. */
static void
netmon_sequential_close(wtap *wth)