(qu)b->total);
if (opt_want_lastseen) {
- time_t last = b->u.host.last_seen_mono;
+ int64_t last = b->u.host.last_seen_mono;
+ int64_t now = (int64_t)now_mono();
struct str *last_str = NULL;
- if ((now_mono() >= last) && (last > 0))
- last_str = length_of_time(now_mono() - last);
+ if ((now >= last) && (last != 0))
+ last_str = length_of_time(now - last);
str_append(buf, " <td class=\"num\">");
if (last_str == NULL) {
if (last == 0)
str_append(buf, "(never)");
else
- str_appendf(buf, "(clock error: now = %qu, last = %qu)",
- (qu)now_mono(),
- (qu)last);
+ str_appendf(buf, "(clock error: last = %qd, now = %qu)",
+ (qd)last,
+ (qu)now);
} else {
str_appendstr(buf, last_str);
str_free(last_str);
str_append(buf, ls_when);
if (h->u.host.last_seen_mono <= now_mono()) {
- ls_len = length_of_time(now_mono() - h->u.host.last_seen_mono);
+ ls_len = length_of_time((int64_t)now_mono() - h->u.host.last_seen_mono);
str_append(buf, " (");
str_appendstr(buf, ls_len);
str_free(ls_len);
str_append(buf, " ago)");
} else {
- str_append(buf, " (in the future, possible clock problem)");
+ str_appendf(buf, " (in the future, possible clock problem, "
+ "last = %qd, now = %qu)",
+ (qd)h->u.host.last_seen_mono,
+ (qu)now_mono());
}
str_appendf(buf,
struct addr addr;
char *dns;
uint8_t mac_addr[6];
- time_t last_seen_mono;
+ /* last_seen_mono is converted to/from time_t in export/import.
+ * It can be negative (due to machine reboots).
+ */
+ int64_t last_seen_mono;
struct hashtable *ports_tcp, *ports_udp, *ip_protos;
};
#include "err.h"
#include "hosts_db.h"
-/* ---------------------------------------------------------------------------
- * comparator for sorting (biggest first)
- */
-static int
-cmp(const struct bucket * const *x, const struct bucket * const *y,
- const enum sort_dir dir)
-{
- uint64_t a, b;
+static int cmp_u64(const uint64_t a, const uint64_t b) {
+ if (a < b) return (1);
+ if (a > b) return (-1);
+ return (0);
+}
+static int cmp_i64(const int64_t a, const int64_t b) {
+ if (a < b) return (1);
+ if (a > b) return (-1);
+ return (0);
+}
+
+/* Comparator for sorting 'struct bucket' */
+static int cmp(const struct bucket * const *x, const struct bucket * const *y,
+ const enum sort_dir dir) {
switch (dir) {
- case IN:
- a = (*x)->in;
- b = (*y)->in;
- break;
- case OUT:
- a = (*x)->out;
- b = (*y)->out;
- break;
- case TOTAL:
- a = (*x)->total;
- b = (*y)->total;
- break;
- case LASTSEEN:
- a = (*x)->u.host.last_seen_mono;
- b = (*y)->u.host.last_seen_mono;
- break;
- default:
- errx(1, "cmp: unknown direction: %d", dir);
+ case IN:
+ return cmp_u64((*x)->in, (*y)->in);
+ case OUT:
+ return cmp_u64((*x)->out, (*y)->out);
+ case TOTAL:
+ return cmp_u64((*x)->total, (*y)->total);
+ case LASTSEEN:
+ return cmp_i64((*x)->u.host.last_seen_mono,
+ (*y)->u.host.last_seen_mono);
+ default:
+ errx(1, "cmp: unknown direction: %d", dir);
}
-
- if (a < b) return (1);
- else if (a > b) return (-1);
- else return (0);
}
/*
all_clocks_update();
}
-time_t mono_to_real(const time_t t) {
+time_t mono_to_real(const int64_t t) {
assert(now_initialized);
- return t - clock_mono.tv_sec + clock_real.tv_sec;
+ return (time_t)(t - (int64_t)clock_mono.tv_sec + (int64_t)clock_real.tv_sec);
}
-time_t real_to_mono(const time_t t) {
+int64_t real_to_mono(const time_t t) {
assert(now_initialized);
- return t - clock_real.tv_sec + clock_mono.tv_sec;
+ return (int64_t)(t - clock_real.tv_sec + clock_mono.tv_sec);
}
void timer_start(struct timespec *t) {
time_t now_real(void);
time_t now_mono(void);
-time_t mono_to_real(const time_t t);
-time_t real_to_mono(const time_t t);
+/* Monotonic times can be negative (a time from before the machine booted) so
+ * treat them as signed. */
+time_t mono_to_real(const int64_t t);
+int64_t real_to_mono(const time_t t);
/* Emits warnings if a call is too slow. */
struct timespec;