From 3284f581f46eb34e0655e37761d1fa2d0c61e235 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Thu, 18 Feb 2010 13:49:12 -0800 Subject: Corrected pcap's double to struct timeval conversion to be accurate to 6 decimal places. --- lua/pcap-test | 20 ++++++++++++++++++++ lua/pcap.c | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/lua/pcap-test b/lua/pcap-test index d43a938..d6c26e6 100755 --- a/lua/pcap-test +++ b/lua/pcap-test @@ -32,6 +32,26 @@ end assert(pcap) +print"test: tv to secs conversions" + +for _, tvsecs in ipairs{0, 1, 2, 3, 4, 5, 100, 788964454} do + for tvusecs=0,1000 do + local secs = pcap.tv2secs(tvsecs, tvusecs) + local _tvsecs, _tvusecs = pcap.secs2tv(secs) + if tvusecs ~= _tvusecs or tvsecs ~= _tvsecs then + if tvsecs == 0 then + print("tv in", tvsecs, tvusecs, "secs", string.format("%.8f", secs), "tv out", _tvsecs, _tvusecs) + end + end + assert(tvsecs == _tvsecs) + assert(tvusecs == _tvusecs, "diff is "..(tvusecs - _tvusecs)) + end +end + +print"+ok" + +print"pcap test" + cap = assert(pcap.open_dead()) dmp = assert(cap:dump_open("cap0.pcap")) diff --git a/lua/pcap.c b/lua/pcap.c index e2df3d0..1e6e4df 100644 --- a/lua/pcap.c +++ b/lua/pcap.c @@ -32,6 +32,7 @@ THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include "lua.h" #include "lauxlib.h" @@ -46,8 +47,20 @@ static double tv2secs(struct timeval* tv) static struct timeval* secs2tv(double secs, struct timeval* tv) { - tv->tv_sec = (time_t) secs; - tv->tv_usec = (suseconds_t) ((secs - tv->tv_sec) * 1000000); + double ipart = 0.0; + double fpart = 0.0; + + fpart = modf(secs, &ipart); + + tv->tv_sec = (time_t) ipart; + + fpart = modf(fpart * 1000000.0, &ipart); + + tv->tv_usec = (suseconds_t) ipart; + + if(fpart > 0.5) + tv->tv_usec += 1; + return tv; } @@ -361,6 +374,28 @@ static int lpcap_open_dead(lua_State *L) return checkpcapopen(L, cap, "open dead failed for unknown reason"); } +/* These don't need to be external, but are useful to test timeval conversion from lua. */ +static int lpcap_tv2secs(lua_State* L) +{ + struct timeval tv; + tv.tv_sec = luaL_checknumber(L, 1); + tv.tv_usec = luaL_checknumber(L, 2); + + lua_pushnumber(L, tv2secs(&tv)); + return 1; +} + +static int lpcap_secs2tv(lua_State* L) +{ + struct timeval tv; + double secs = luaL_checknumber(L, 1); + + secs2tv(secs, &tv); + lua_pushnumber(L, tv.tv_sec); + lua_pushnumber(L, tv.tv_usec); + return 2; +} + static const luaL_reg dumper_methods[] = { {"__gc", lpcap_dump_destroy}, @@ -383,6 +418,8 @@ static const luaL_reg pcap_module[] = { {"open_offline", lpcap_open_offline}, {"open_dead", lpcap_open_dead}, + {"tv2secs", lpcap_tv2secs}, + {"secs2tv", lpcap_secs2tv}, {NULL, NULL} }; -- cgit v1.2.1