From e124565c5887d2f1a138dc0677a54522a401791b Mon Sep 17 00:00:00 2001 From: dmiller Date: Wed, 13 Jan 2016 20:53:39 +0000 Subject: [PATCH] Use time_t instead of long and double for storing uptime Fixes #275. This results in fewer casts and less subtraction than the previous method, and should still be portable. Only division and subtraction and difftime are performed on the value, so it will not overflow. And the TCP timestamp itself is a 32-bit value, so it can't refer to a time farther in the past than the 32-bit epoch. One explicit cast (to long long) is used in order to ensure the format string can handle any conceivable value according to the compiler and avoid a warning message. --- osscan2.cc | 24 +++++++++++++----------- osscan2.h | 2 +- output.cc | 10 +++++----- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/osscan2.cc b/osscan2.cc index c6584e8ae..38d3e51af 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -2551,7 +2551,7 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) { 5) Same with ~100/sec */ if (hss->si.ts_seqclass == TS_SEQ_UNKNOWN && hss->si.responses >= 2) { - double lastboot = 0.0; + time_t uptime = 0; avg_ts_hz = 0.0; for (i = 0; i < hss->si.responses - 1; i++) { double dhz; @@ -2563,31 +2563,33 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) { if (avg_ts_hz > 0 && avg_ts_hz < 5.66) { /* relatively wide range because sampling time so short and frequency so slow */ hss->si.ts_seqclass = TS_SEQ_2HZ; - lastboot = (double) hss->seq_send_times[0].tv_sec - (hss->si.timestamps[0] / 2); - hss->si.lastboot = hss->seq_send_times[0].tv_sec - (hss->si.timestamps[0] / 2); + uptime = hss->si.timestamps[0] / 2; } else if (avg_ts_hz > 70 && avg_ts_hz < 150) { hss->si.ts_seqclass = TS_SEQ_100HZ; - lastboot = (double) hss->seq_send_times[0].tv_sec - (hss->si.timestamps[0] / 100); + uptime = hss->si.timestamps[0] / 100; } else if (avg_ts_hz > 724 && avg_ts_hz < 1448) { hss->si.ts_seqclass = TS_SEQ_1000HZ; - lastboot = (double) hss->seq_send_times[0].tv_sec - (hss->si.timestamps[0] / 1000); + uptime = hss->si.timestamps[0] / 1000; } else if (avg_ts_hz > 0) { hss->si.ts_seqclass = TS_SEQ_OTHER_NUM; - lastboot = (double) hss->seq_send_times[0].tv_sec - (hss->si.timestamps[0] / (unsigned int)(0.5 + avg_ts_hz)); + uptime = hss->si.timestamps[0] / (unsigned int)(0.5 + avg_ts_hz); } - if (lastboot != 0.0 && (hss->seq_send_times[0].tv_sec - lastboot > 63072000)) { + if (uptime > 63072000) { /* Up 2 years? Perhaps, but they're probably lying. */ if (o.debugging) { - log_write(LOG_STDOUT, "Ignoring claimed %s uptime of %lu days\n", - hss->target->targetipstr(), (hss->seq_send_times[0].tv_sec - hss->si.lastboot) / 86400); + /* long long is probably excessive for number of days, but sick of + * truncation warnings and finding the right format string for time_t + */ + log_write(LOG_STDOUT, "Ignoring claimed %s uptime of %lld days\n", + hss->target->targetipstr(), (long long) (uptime / 86400)); } - lastboot = 0; + uptime = 0; } - hss->si.lastboot = (long) lastboot; + hss->si.lastboot = hss->seq_send_times[0].tv_sec - uptime; } switch (hss->si.ts_seqclass) { diff --git a/osscan2.h b/osscan2.h index a0efda29b..f4f48a650 100644 --- a/osscan2.h +++ b/osscan2.h @@ -200,7 +200,7 @@ struct seq_info { u32 timestamps[NUM_SEQ_SAMPLES]; int index; u16 ipids[NUM_SEQ_SAMPLES]; - long lastboot; /* 0 means unknown */ + time_t lastboot; /* 0 means unknown */ }; /* Different kinds of Ipids. */ diff --git a/output.cc b/output.cc index e7b259162..705fd67c0 100644 --- a/output.cc +++ b/output.cc @@ -1989,17 +1989,17 @@ void printosscanoutput(Target *currenths) { if (currenths->seq.lastboot) { char tmbuf[128]; struct timeval tv; - time_t lastboot; - lastboot = (time_t) currenths->seq.lastboot; - strncpy(tmbuf, ctime(&lastboot), sizeof(tmbuf)); + double uptime; + strncpy(tmbuf, ctime(¤ths->seq.lastboot), sizeof(tmbuf)); chomp(tmbuf); gettimeofday(&tv, NULL); + uptime = difftime(tv.tv_sec, currenths->seq.lastboot); if (o.verbose) log_write(LOG_PLAIN, "Uptime guess: %.3f days (since %s)\n", - (double) (tv.tv_sec - currenths->seq.lastboot) / 86400, + uptime / 86400, tmbuf); xml_open_start_tag("uptime"); - xml_attribute("seconds", "%li", tv.tv_sec - currenths->seq.lastboot); + xml_attribute("seconds", "%.0f", uptime); xml_attribute("lastboot", "%s", tmbuf); xml_close_empty_tag(); xml_newline();