diff --git a/include/tins/timestamp.h b/include/tins/timestamp.h index 3d66cb4..274ae7d 100644 --- a/include/tins/timestamp.h +++ b/include/tins/timestamp.h @@ -30,21 +30,21 @@ #ifndef TINS_TIMESTAMP_H #define TINS_TIMESTAMP_H -#ifdef _WIN32 - #include -#else - #include -#endif +#include +#include "macros.h" #include "cxxstd.h" #if TINS_IS_CXX11 #include #endif +struct timeval; + namespace Tins { + /** * \brief Represents a packet timestamp. */ -class Timestamp { +class TINS_API Timestamp { public: #ifdef _WIN32 typedef long seconds_type; @@ -57,21 +57,12 @@ public: /** * \brief Constructs a Timestamp which will hold the current time. */ - static Timestamp current_time() { - #ifdef _WIN32 - //fixme - return Timestamp(); - #else - timeval tv; - gettimeofday(&tv, 0); - return tv; - #endif - } + static Timestamp current_time(); /** - * Default constructs the timestamp. + * Default constructs a timestamp. */ - Timestamp() : tv() {} + Timestamp(); #if TINS_IS_CXX11 /** @@ -79,47 +70,42 @@ public: */ template Timestamp(const std::chrono::duration& ts) { - using std::chrono::duration_cast; - using std::chrono::microseconds; - using std::chrono::seconds; - - tv.tv_sec = duration_cast(ts).count(); - tv.tv_usec = duration_cast( - ts - seconds(tv.tv_sec)).count(); + timestamp_ = std::chrono::duration_cast(ts).count(); } #endif /** - * Constructs a timestamp from a timeval object. - * \param time_val The timeval object. + * Constructs a timestamp from a timeval struct. + * + * \param time_val The timeval struct */ - Timestamp(const timeval& time_val) : tv(time_val) {} + Timestamp(const timeval& time_val); /** * Returns the amount of seconds in this timestamp. */ - seconds_type seconds() const { - return tv.tv_sec; - } + seconds_type seconds() const; /** - * Returns the amount of microseconds in this timestamp. + * \brief Returns the rest of the time in this timestamp in microseconds + * + * This is, after subtracting the seconds part, how many microseconds are + * left in this timestamp */ - microseconds_type microseconds() const { - return tv.tv_usec; - } + microseconds_type microseconds() const; #if TINS_IS_CXX11 /** * Converts this Timestamp to a std::chrono::microseconds */ operator std::chrono::microseconds() const { - return std::chrono::seconds(seconds()) + - std::chrono::microseconds(microseconds()); + return std::chrono::microseconds(timestamp_); } #endif private: - timeval tv; + Timestamp(uint64_t value); + + uint64_t timestamp_; }; } // Tins diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4f362fb..58bdeb5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,6 +60,7 @@ ADD_LIBRARY( tcp_ip/stream_follower.cpp tcp_ip/stream_identifier.cpp tcp_stream.cpp + timestamp.cpp udp.cpp utils.cpp dot11/dot11_base.cpp diff --git a/src/timestamp.cpp b/src/timestamp.cpp new file mode 100644 index 0000000..0da6af6 --- /dev/null +++ b/src/timestamp.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2016, Matias Fontanini + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef _WIN32 + #include + #include +#else + #include +#endif +#include "timestamp.h" + +namespace Tins { + +const int MICROSECONDS_IN_SECOND = 1000000; + +Timestamp Timestamp::current_time() { + #ifdef _WIN32 + FILETIME file_time; + GetSystemTimeAsFileTime(&file_time); + uint64_t timestamp = file_time.dwHighDateTime; + timestamp = timestamp << 32; + timestamp |= file_time.dwLowDateTime; + // Convert to microseconds + timestamp /= 10; + // Change the epoch to POSIX epoch + timestamp -= 11644473600000000ULL; + return Timestamp(timestamp); + #else + timeval tv; + gettimeofday(&tv, 0); + return tv; + #endif +} + + +Timestamp::Timestamp() +: timestamp_(0) { + +} + +Timestamp::Timestamp(const timeval& time_val) { + timestamp_ = time_val.tv_sec * MICROSECONDS_IN_SECOND + time_val.tv_usec; +} + +Timestamp::Timestamp(uint64_t value) +: timestamp_(value) { + +} + +Timestamp::seconds_type Timestamp::seconds() const { + return timestamp_ / MICROSECONDS_IN_SECOND; +} + +Timestamp::microseconds_type Timestamp::microseconds() const { + return timestamp_ % MICROSECONDS_IN_SECOND; +} + +} // Tins