diff options
-rw-r--r-- | epan/dissectors/packet-windows-common.c | 38 | ||||
-rw-r--r-- | wiretap/netmon.c | 47 | ||||
-rw-r--r-- | wsutil/nstime.c | 76 | ||||
-rw-r--r-- | wsutil/nstime.h | 4 |
4 files changed, 86 insertions, 79 deletions
diff --git a/epan/dissectors/packet-windows-common.c b/epan/dissectors/packet-windows-common.c index 4d19ce8367..fd0d302f25 100644 --- a/epan/dissectors/packet-windows-common.c +++ b/epan/dissectors/packet-windows-common.c @@ -1109,20 +1109,6 @@ value_string_ext ms_country_codes_ext = VALUE_STRING_EXT_INIT(ms_country_codes); /*module_t* module;*/ /*pref_t* sid_display_hex;*/ -#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 - -/* - * 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) - /* * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits, * to an "nstime_t". @@ -1147,12 +1133,6 @@ static gboolean nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv, gboolean onesec_resolution) { 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; if (filetime_high == 0) return FALSE; @@ -1163,23 +1143,7 @@ nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv, gbo d *= 10000000; } - /* 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)) - return FALSE; - - /* - * Get the time as seconds and nanoseconds. - */ - tv->secs = (time_t) secs; - tv->nsecs = nsecs; - - return TRUE; + return filetime_to_nstime(tv, d); } int diff --git a/wiretap/netmon.c b/wiretap/netmon.c index 9a4ad1e999..73bc49259a 100644 --- a/wiretap/netmon.c +++ b/wiretap/netmon.c @@ -441,20 +441,6 @@ typedef enum { RETRY } process_record_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_record_retval netmon_process_record(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) @@ -747,43 +733,20 @@ netmon_process_record(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, 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 utcsecs; - /* 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. */ - utcsecs = d / 10000000; - nsecs = (int)((d % 10000000)*100); - - /* Now adjust the seconds. */ - utcsecs -= 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 FAILURE; - } - /* * Get the time as seconds and nanoseconds. * and overwrite the time stamp obtained * from the record header. */ - phdr->ts.secs = (time_t) utcsecs; - phdr->ts.nsecs = nsecs; + if (!filetime_to_nstime(&phdr->ts, d)) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup_printf("netmon: time stamp outside supported range"); + return FAILURE; + } } } diff --git a/wsutil/nstime.c b/wsutil/nstime.c index 439f31a783..ff6626abc1 100644 --- a/wsutil/nstime.c +++ b/wsutil/nstime.c @@ -187,6 +187,82 @@ double nstime_to_sec(const nstime_t *nstime) } /* + * 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") + * + * This is + * + * 369*365.25*24*60*60-(3*24*60*60+6*60*60) + * + * 1970-1601 is 369; 365.25 is the average length of a year in days, + * including leap years. + * + * 3 days are subtracted because 1700, 1800, and 1900 were not leap + * years, as, while they're all evenly divisible by 4, they're also + * evently divisible by 100, but not evently divisible by 400, so + * we need to compensate for using the average length of a year in + * days, which assumes a leap year every 4 years, *including* every + * 100 years. + * + * I'm not sure what the extra 6 hours are that are being subtracted. + */ +#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 + +/* + * 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) +{ + /* + * 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; + + if (!(l_time_min <= secs && secs <= l_time_max)) { + /* The result won't fit in a time_t */ + return FALSE; + } + + /* + * Get the time as seconds and nanoseconds. + */ + nstime->secs = (time_t) secs; + nstime->nsecs = nsecs; + return TRUE; +} + +/* * Editor modelines * * Local Variables: diff --git a/wsutil/nstime.h b/wsutil/nstime.h index a74457c8b6..c72daa19c6 100644 --- a/wsutil/nstime.h +++ b/wsutil/nstime.h @@ -102,6 +102,10 @@ WS_DLL_PUBLIC double nstime_to_msec(const nstime_t *nstime); /** converts nstime to double, time base is seconds */ WS_DLL_PUBLIC double nstime_to_sec(const nstime_t *nstime); +/** converts Windows FILETIME to nstime, returns TRUE on success, + FALSE on failure */ +WS_DLL_PUBLIC gboolean filetime_to_nstime(nstime_t *nstime, guint64 filetime); + #ifdef __cplusplus } #endif /* __cplusplus */ |