aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2015-04-20 18:27:41 -0700
committerGuy Harris <guy@alum.mit.edu>2015-04-21 01:28:15 +0000
commit8b720910d2ae04aab24709cf30363e9f064e2c63 (patch)
tree62da61102824a5a03f02a73c6fdfe34777c3d32e
parentc35f2ccb4433718416551cc7a85afb0860529d57 (diff)
Calculate *Peek tagged timestamps in fixed-point.
Add a variant of filetime_to_nstime() that takes a value that's like a FILETIME but in units of nanoseconds rather than tenths of a microsecond, and use that. (It looks as if they might just get FILETIME values from the OS and multiply them by 100, as the nanosecond-FILETIME values appear to be multiples of 100 in the captures I've seen, but they might have chosen nanosecond resolution in case they need to support a higher-resolution time stamp source, so we don't assume that the values will always be a multiple of 100.) Change-Id: If6a1cb2cb673688b042eb113b79cfd267f5454a5 Reviewed-on: https://code.wireshark.org/review/8150 Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r--wiretap/peektagged.c24
-rw-r--r--wsutil/nstime.c92
-rw-r--r--wsutil/nstime.h5
3 files changed, 78 insertions, 43 deletions
diff --git a/wiretap/peektagged.c b/wiretap/peektagged.c
index 8d9806899e..51bd43af62 100644
--- a/wiretap/peektagged.c
+++ b/wiretap/peektagged.c
@@ -462,16 +462,6 @@ wtap_open_return_val peektagged_open(wtap *wth, int *err, gchar **err_info)
}
/*
- * Time stamps appear to be in nanoseconds since the Windows epoch
- * as used in FILETIMEs, i.e. midnight, January 1, 1601.
- *
- * This magic number came from "nt_time_to_nstime()" in "packet-smb.c".
- * 1970-1601 is 369; I'm not sure what the extra 3 days and 6 hours are
- * that are being subtracted.
- */
-#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
-
-/*
* Read the packet.
*
* XXX - we should supply the additional radio information;
@@ -499,7 +489,7 @@ peektagged_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
guint32 data_rate_or_mcs_index = 0;
struct ieee_802_11_phdr ieee_802_11;
int skip_len = 0;
- double t;
+ guint64 t;
timestamp.upper = 0;
timestamp.lower = 0;
@@ -678,12 +668,12 @@ peektagged_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
phdr->caplen = sliceLength;
/* calculate and fill in packet time stamp */
- t = (double) timestamp.lower +
- (double) timestamp.upper * 4294967296.0;
- t *= 1.0e-9;
- t -= TIME_FIXUP_CONSTANT;
- phdr->ts.secs = (time_t) t;
- phdr->ts.nsecs = (guint32) ((t - phdr->ts.secs)*1000000000);
+ t = (((guint64) timestamp.upper) << 32) + timestamp.lower;
+ if (!nsfiletime_to_nstime(&phdr->ts, t)) {
+ *err = WTAP_ERR_BAD_FILE;
+ *err_info = g_strdup_printf("peektagged: time stamp outside supported range");
+ return -1;
+ }
switch (wth->file_encap) {
diff --git a/wsutil/nstime.c b/wsutil/nstime.c
index 28693273f0..f2450489f2 100644
--- a/wsutil/nstime.c
+++ b/wsutil/nstime.c
@@ -183,10 +183,19 @@ double nstime_to_msec(const nstime_t *nstime)
double nstime_to_sec(const nstime_t *nstime)
{
- return ((double)nstime->secs + (double)nstime->nsecs/1000000000);
+ return ((double)nstime->secs + (double)nstime->nsecs/NS_PER_S);
}
/*
+ * This code is based on the Samba code:
+ *
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * time handling functions
+ * Copyright (C) Andrew Tridgell 1992-1998
+ */
+
+/*
* Number of seconds between the UN*X epoch (January 1, 1970, 00:00:00 GMT)
* and the Windows NT epoch (January 1, 1601 in the proleptic Gregorian
* calendar, 00:00:00 "GMT")
@@ -217,37 +226,25 @@ double nstime_to_sec(const nstime_t *nstime)
#define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
#endif
-/*
- * function: filetime_to_nstime
- * converts a Windows FILETIME value to an nstime_t
- * returns TRUE if the conversion succeeds, FALSE if it doesn't
- * (for example, with a 32-bit time_t, the time overflows or
- * underflows time_t)
- */
-gboolean
-filetime_to_nstime(nstime_t *nstime, guint64 filetime)
+static gboolean
+common_filetime_to_nstime(nstime_t *nstime, guint64 ftsecs, int nsecs)
{
- /*
- * This code is based on the Samba code:
- *
- * Unix SMB/Netbios implementation.
- * Version 1.9.
- * time handling functions
- * Copyright (C) Andrew Tridgell 1992-1998
- */
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;
- /* Split into seconds and nanoseconds. */
- secs = filetime / 10000000;
- nsecs = (int)((filetime % 10000000)*100);
-
- /* Now adjust the seconds. */
- secs -= TIME_FIXUP_CONSTANT;
+ /*
+ * Shift the seconds from the Windows epoch to the UN*X epoch.
+ * ftsecs's value should fit in a 64-bit signed variable, as
+ * ftsecs is derived from a 64-bit fractions-of-a-second value,
+ * and is far from the maximum 64-bit signed value, and
+ * TIME_FIXUP_CONSTANT is also far from the maximum 64-bit
+ * signed value, so the difference between them should also
+ * fit in a 64-bit signed value.
+ */
+ secs = (gint64)ftsecs - TIME_FIXUP_CONSTANT;
if (!(l_time_min <= secs && secs <= l_time_max)) {
/* The result won't fit in a time_t */
@@ -263,6 +260,50 @@ filetime_to_nstime(nstime_t *nstime, guint64 filetime)
}
/*
+ * function: filetime_to_nstime
+ * converts a Windows FILETIME value to an nstime_t
+ * returns TRUE if the conversion succeeds, FALSE if it doesn't
+ * (for example, with a 32-bit time_t, the time overflows or
+ * underflows time_t)
+ */
+gboolean
+filetime_to_nstime(nstime_t *nstime, guint64 filetime)
+{
+ guint64 ftsecs;
+ int nsecs;
+
+ /*
+ * Split into seconds and tenths of microseconds, and
+ * then convert tenths of microseconds to nanoseconds.
+ */
+ ftsecs = filetime / 10000000;
+ nsecs = (int)((filetime % 10000000)*100);
+
+ return common_filetime_to_nstime(nstime, ftsecs, nsecs);
+}
+
+/*
+ * function: nsfiletime_to_nstime
+ * converts a Windows FILETIME-like value, but given in nanoseconds
+ * rather than 10ths of microseconds, to an nstime_t
+ * returns TRUE if the conversion succeeds, FALSE if it doesn't
+ * (for example, with a 32-bit time_t, the time overflows or
+ * underflows time_t)
+ */
+gboolean
+nsfiletime_to_nstime(nstime_t *nstime, guint64 nsfiletime)
+{
+ guint64 ftsecs;
+ int nsecs;
+
+ /* Split into seconds and nanoseconds. */
+ ftsecs = nsfiletime / NS_PER_S;
+ nsecs = (int)(nsfiletime % NS_PER_S);
+
+ return common_filetime_to_nstime(nstime, ftsecs, nsecs);
+}
+
+/*
* Editor modelines
*
* Local Variables:
@@ -274,4 +315,3 @@ filetime_to_nstime(nstime_t *nstime, guint64 filetime)
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/
-
diff --git a/wsutil/nstime.h b/wsutil/nstime.h
index c72daa19c6..4145ac583c 100644
--- a/wsutil/nstime.h
+++ b/wsutil/nstime.h
@@ -106,6 +106,11 @@ WS_DLL_PUBLIC double nstime_to_sec(const nstime_t *nstime);
FALSE on failure */
WS_DLL_PUBLIC gboolean filetime_to_nstime(nstime_t *nstime, guint64 filetime);
+/** converts time like Windows FILETIME, but expressed in nanoseconds
+ rather than tenths of microseconds, to nstime, returns TRUE on success,
+ FALSE on failure */
+WS_DLL_PUBLIC gboolean nsfiletime_to_nstime(nstime_t *nstime, guint64 nsfiletime);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */