From 9b2da1ffe8d4c8aa177663f3accf72afa92e89f4 Mon Sep 17 00:00:00 2001 From: Peter Haag Date: Sat, 11 Jan 2025 18:51:27 +0100 Subject: [PATCH] Extend timeWindow to msec format everywhere --- src/libnffile/flist.c | 7 ++- src/libnffile/util.c | 110 +++++++++++++++++++++------------------- src/libnffile/util.h | 12 ++--- src/nfdump/nfdump.c | 30 +++++------ src/nfreplay/nfreplay.c | 8 +-- 5 files changed, 84 insertions(+), 83 deletions(-) diff --git a/src/libnffile/flist.c b/src/libnffile/flist.c index c2a19264..31feba48 100755 --- a/src/libnffile/flist.c +++ b/src/libnffile/flist.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2024, Peter Haag + * Copyright (c) 2009-2025, Peter Haag * Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung * All rights reserved. * @@ -1215,9 +1215,8 @@ static int CheckTimeWindow(char *filename, timeWindow_t *searchWindow) { return 0; } - if (searchWindow->last && searchWindow->last < (stat_record.firstseen / 1000LL)) return 0; - - if (searchWindow->first && searchWindow->first > (stat_record.lastseen / 1000LL)) return 0; + if (searchWindow->msecLast && searchWindow->msecLast < stat_record.firstseen) return 0; + if (searchWindow->msecFirst && searchWindow->msecFirst > stat_record.lastseen) return 0; return 1; diff --git a/src/libnffile/util.c b/src/libnffile/util.c index a6c7af42..3e6ba2dc 100755 --- a/src/libnffile/util.c +++ b/src/libnffile/util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2023, Peter Haag + * Copyright (c) 2009-2025, Peter Haag * Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung * All rights reserved. * @@ -60,8 +60,6 @@ static int verbose = 4; /* Function prototypes */ static int check_number(char *s, int len); -static uint64_t ParseTime(char *s, time_t *t_start); - static int use_syslog = 0; #ifdef sun @@ -305,20 +303,21 @@ static int check_number(char *s, int len) { } // End of check_number // Parse ISO 8601 time string - accept legacy format -static uint64_t ParseTime(char *s, time_t *t_start) { +uint64_t ParseTime8601(const char *s) { + char *tmpString = strdup(s); /* A time string may look like: * yyyy-MM-ddThh:mm:ss.s or * 012345678901234567890 * yyyy/MM/dd.hh:mm:ss ( legacy format ) */ - char *eos = s; + char *eos = tmpString; // convert legacy format, check len for (; *eos != '\0'; eos++) { if (*eos == '/') *eos = '-'; } - if ((eos - s) < 4) { + if ((eos - tmpString) < 4) { LogError("Not a date/time string: %s", s); return 0; } @@ -326,7 +325,7 @@ static uint64_t ParseTime(char *s, time_t *t_start) { struct tm ts = {0}; ts.tm_isdst = -1; - char *p = s; + char *p = tmpString; char *q = p; // split year and parse @@ -337,15 +336,16 @@ static uint64_t ParseTime(char *s, time_t *t_start) { int num = atoi(p); if (num > 2038 || num < 1970) { LogError("Year out of range: '%i'\n", num); - *t_start = 0; + free(tmpString); return 0; } ts.tm_year = num - 1900; if (q >= eos) { ts.tm_mday = 1; - *t_start = mktime(&ts); - return 1000LL * (uint64_t)*t_start; + uint64_t timeStamp = mktime(&ts); + free(tmpString); + return 1000LL * timeStamp; } // split month and parse @@ -357,14 +357,15 @@ static uint64_t ParseTime(char *s, time_t *t_start) { num = atoi(p); if (num < 1 || num > 12) { LogError("Month out of range: '%i'\n", num); - *t_start = 0; + free(tmpString); return 0; } ts.tm_mon = num - 1; if (q >= eos) { ts.tm_mday = 1; - *t_start = mktime(&ts); - return 1000LL * (uint64_t)*t_start; + uint64_t timeStamp = mktime(&ts); + free(tmpString); + return 1000LL * timeStamp; } // split day and parse @@ -376,14 +377,15 @@ static uint64_t ParseTime(char *s, time_t *t_start) { num = atoi(p); if (num < 1 || num > 31) { LogError("Day out of range: '%i'\n", num); - *t_start = 0; + free(tmpString); return 0; } ts.tm_mday = num; if (q >= eos) { - *t_start = mktime(&ts); - return 1000LL * (uint64_t)*t_start; + uint64_t timeStamp = mktime(&ts); + free(tmpString); + return 1000LL * timeStamp; } // split hour and parse @@ -395,13 +397,14 @@ static uint64_t ParseTime(char *s, time_t *t_start) { num = atoi(p); if (num < 0 || num > 23) { LogError("Hour out of range: '%i'\n", num); - *t_start = 0; + free(tmpString); return 0; } ts.tm_hour = num; if (q >= eos) { - *t_start = mktime(&ts); - return 1000LL * (uint64_t)*t_start; + uint64_t timeStamp = mktime(&ts); + free(tmpString); + return 1000LL * timeStamp; } // split and parse minute @@ -413,13 +416,14 @@ static uint64_t ParseTime(char *s, time_t *t_start) { num = atoi(p); if (num < 0 || num > 59) { LogError("Minute out of range: '%i'\n", num); - *t_start = 0; + free(tmpString); return 0; } ts.tm_min = num; if (q >= eos) { - *t_start = mktime(&ts); - return 1000LL * (uint64_t)*t_start; + uint64_t timeStamp = mktime(&ts); + free(tmpString); + return 1000LL * timeStamp; } // split and parse second @@ -431,25 +435,25 @@ static uint64_t ParseTime(char *s, time_t *t_start) { num = atoi(p); if (num < 0 || num > 59) { LogError("Seconds out of range: '%i'\n", num); - *t_start = 0; + free(tmpString); return 0; } ts.tm_sec = num; if (q >= eos) { - *t_start = mktime(&ts); - return 1000LL * (uint64_t)*t_start; + uint64_t timeStamp = mktime(&ts); + free(tmpString); + return 1000LL * timeStamp; } // msec p = q; - *t_start = mktime(&ts); + uint64_t timeStamp = mktime(&ts); if (!check_number(p, 3)) return 0; num = atoi(p); - uint64_t tmsec = (uint64_t)(*t_start) * 1000LL + (uint64_t)num; - dbg_printf("Msec window: %llu\n", tmsec); - return tmsec; + free(tmpString); + return timeStamp + (uint64_t)num; } // End of ParseTime @@ -469,23 +473,26 @@ timeWindow_t *ScanTimeFrame(char *tstring) { } if ((p = strchr(tstring, '-')) == NULL) { - if (ParseTime(tstring, &timeWindow->first) == 0) { + timeWindow->msecFirst = ParseTime8601(tstring); + if (timeWindow->msecFirst == 0) { free(timeWindow); return NULL; } } else { *p++ = 0; - if (ParseTime(tstring, &timeWindow->first) == 0 || ParseTime(p, &timeWindow->last) == 0) { + timeWindow->msecFirst = ParseTime8601(tstring); + timeWindow->msecLast = ParseTime8601(p); + if (timeWindow->msecFirst == 0 || timeWindow->msecLast == 0) { free(timeWindow); return NULL; } } #ifdef DEVEL - if (timeWindow->first) { + if (timeWindow->msecFirst) { printf("TimeWindow first: %s\n", UNIX2ISO(timeWindow->first)); } - if (timeWindow->last) { + if (timeWindow->msecLast) { printf("TimeWindow first: %s\n", UNIX2ISO(timeWindow->last)); } #endif @@ -494,27 +501,29 @@ timeWindow_t *ScanTimeFrame(char *tstring) { } // End of ScanTimeFrame -char *TimeString(time_t start, time_t end) { +char *TimeString(uint64_t msecStart, uint64_t msecEnd) { static char datestr[255]; - char t1[64], t2[64]; - struct tm *tbuff; - if (start) { - tbuff = localtime(&start); + if (msecStart) { + time_t secs = msecStart / 1000; + struct tm *tbuff = localtime(&secs); if (!tbuff) { LogError("localtime() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno)); return "Error time convert"; } + char t1[64]; strftime(t1, 63, "%Y-%m-%d %H:%M:%S", tbuff); - tbuff = localtime(&end); + secs = msecEnd / 1000; + tbuff = localtime(&secs); if (!tbuff) { LogError("localtime() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno)); return "Error time convert"; } + char t2[64]; strftime(t2, 63, "%Y-%m-%d %H:%M:%S", tbuff); - snprintf(datestr, 254, "%s - %s", t1, t2); + snprintf(datestr, 254, "%s.%3d - %s.%3d", t1, (int)(msecStart % 1000), t2, (int)(msecEnd % 1000)); } else { snprintf(datestr, 254, "Time Window unknown"); } @@ -606,14 +615,6 @@ time_t ISO2UNIX(char *timestring) { } // End of ISO2UNIX -uint64_t ParseTime8601(char *s) { - time_t t = 0; - char *tmp = strdup(s); - uint64_t tmsec = ParseTime(tmp, &t); - free(tmp); - return tmsec; -} // End of ParseTime8601 - long getTick(void) { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); @@ -622,21 +623,24 @@ long getTick(void) { return theTick; } -char *DurationString(double duration) { +char *DurationString(uint64_t duration) { static char s[128]; - if (duration == 0.0) { + if (duration == 0) { strncpy(s, " 00:00:00.000", 128); } else { + int msec = duration % 1000; + duration /= 1000; int days = duration / 86400; int sum = 86400 * days; int hours = (duration - sum) / 3600; sum += 3600 * hours; int min = (duration - sum) / 60; - double sec = duration - sum - 60 * min; + sum += 60 * min; + int sec = duration - sum; if (days == 0) - snprintf(s, 128, " %02d:%02d:%06.3f", hours, min, sec); + snprintf(s, 128, " %02d:%02d:%02d.%03d", hours, min, sec, msec); else - snprintf(s, 128, "%2dd %02d:%02d:%06.3f", days, hours, min, sec); + snprintf(s, 128, "%2dd %02d:%02d:%02d.%03d", days, hours, min, sec, msec); } s[127] = '\0'; return s; diff --git a/src/libnffile/util.h b/src/libnffile/util.h index 4f3fe20b..899d3d4a 100755 --- a/src/libnffile/util.h +++ b/src/libnffile/util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2023, Peter Haag + * Copyright (c) 2009-2025, Peter Haag * Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung * All rights reserved. * @@ -95,8 +95,8 @@ typedef struct stringlist_s { } stringlist_t; typedef struct timeWindow_s { - time_t first; - time_t last; + uint64_t msecFirst; + uint64_t msecLast; } timeWindow_t; double t(void); @@ -129,17 +129,17 @@ void InsertString(stringlist_t *list, char *string); timeWindow_t *ScanTimeFrame(char *tstring); -char *TimeString(time_t start, time_t end); +char *TimeString(uint64_t msecStart, uint64_t msecEnd); char *UNIX2ISO(time_t t); time_t ISO2UNIX(char *timestring); -uint64_t ParseTime8601(char *s); +uint64_t ParseTime8601(const char *s); long getTick(void); -char *DurationString(double duration); +char *DurationString(uint64_t duration); #define DONT_SCALE_NUMBER 0 #define DO_SCALE_NUMBER 1 diff --git a/src/nfdump/nfdump.c b/src/nfdump/nfdump.c index 77c2ec5c..c81a46b8 100644 --- a/src/nfdump/nfdump.c +++ b/src/nfdump/nfdump.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2024, Peter Haag + * Copyright (c) 2009-2025, Peter Haag * Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung * All rights reserved. * @@ -112,7 +112,7 @@ static uint64_t total_bytes = 0; static uint64_t totalRecords = 0; static uint64_t totalPassed = 0; static uint32_t skippedBlocks = 0; -static uint64_t t_first_flow = 0, t_last_flow = 0; +static uint64_t t_firstMsec = 0, t_lastMsec = 0; static _Atomic uint32_t abortProcessing = 0; enum processType { FLOWSTAT = 1, ELEMENTSTAT, ELEMENTFLOWSTAT, SORTRECORDS, WRITEFILE, PRINTRECORD }; @@ -280,8 +280,8 @@ __attribute__((noreturn)) static void *prepareThread(void *arg) { dbg_printf("prepareThread exit\n"); pthread_exit(NULL); } - t_first_flow = nffile->stat_record->firstseen; - t_last_flow = nffile->stat_record->lastseen; + t_firstMsec = nffile->stat_record->firstseen; + t_lastMsec = nffile->stat_record->lastseen; dataHandle_t *dataHandle = NULL; uint64_t recordCnt = 0; @@ -302,8 +302,8 @@ __attribute__((noreturn)) static void *prepareThread(void *arg) { if (GetNextFile(nffile) == NULL) { done = 1; } else { - if (nffile->stat_record->firstseen < t_first_flow) t_first_flow = nffile->stat_record->firstseen; - if (nffile->stat_record->lastseen > t_last_flow) t_last_flow = nffile->stat_record->lastseen; + if (nffile->stat_record->firstseen < t_firstMsec) t_firstMsec = nffile->stat_record->firstseen; + if (nffile->stat_record->lastseen > t_lastMsec) t_lastMsec = nffile->stat_record->lastseen; } continue; } @@ -376,9 +376,9 @@ __attribute__((noreturn)) static void *filterThread(void *arg) { uint64_t twin_msecFirst, twin_msecLast; twin_msecFirst = twin_msecLast = 0; if (timeWindow) { - twin_msecFirst = timeWindow->first * 1000LL; - if (timeWindow->last) - twin_msecLast = timeWindow->last * 1000LL; + twin_msecFirst = timeWindow->msecFirst; + if (timeWindow->msecLast) + twin_msecLast = timeWindow->msecLast; else twin_msecLast = 0x7FFFFFFFFFFFFFFFLL; } @@ -1290,17 +1290,15 @@ int main(int argc, char **argv) { case MODE_NULL: case MODE_FMT: PrintSummary(&sum_stat, outputParams); - if (t_last_flow == 0) { + if (t_lastMsec == 0) { printf("Time window: \n"); } else { - t_first_flow /= 1000LL; - t_last_flow /= 1000LL; if (flist.timeWindow) { - if (flist.timeWindow->first && (flist.timeWindow->first > t_first_flow)) t_first_flow = flist.timeWindow->first; - if (flist.timeWindow->last && (flist.timeWindow->last < t_last_flow)) t_last_flow = flist.timeWindow->last; + if (flist.timeWindow->msecFirst && (flist.timeWindow->msecFirst > t_firstMsec)) t_firstMsec = flist.timeWindow->msecFirst; + if (flist.timeWindow->msecLast && (flist.timeWindow->msecLast < t_lastMsec)) t_lastMsec = flist.timeWindow->msecLast; } - double duration = (double)(t_last_flow - t_first_flow); - printf("Time window: %s, Duration:%s\n", TimeString(t_first_flow, t_last_flow), DurationString(duration)); + uint64_t durationMsec = t_lastMsec - t_firstMsec; + printf("Time window: %s, Duration:%s\n", TimeString(t_firstMsec, t_lastMsec), DurationString(durationMsec)); } printf("Total records processed: %" PRIu64 ", passed: %" PRIu64 ", Blocks skipped: %u, Bytes read: %llu\n", totalRecords, totalPassed, skippedBlocks, (unsigned long long)total_bytes); diff --git a/src/nfreplay/nfreplay.c b/src/nfreplay/nfreplay.c index 9de10bfd..53da3752 100644 --- a/src/nfreplay/nfreplay.c +++ b/src/nfreplay/nfreplay.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2024, Peter Haag + * Copyright (c) 2009-2025, Peter Haag * Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung * All rights reserved. * @@ -210,9 +210,9 @@ static void send_data(void *engine, timeWindow_t *timeWindow, uint64_t limitReco int reducer = 0; if (timeWindow) { - twin_msecFirst = timeWindow->first * 1000LL; - if (timeWindow->last) - twin_msecLast = timeWindow->last * 1000LL; + twin_msecFirst = timeWindow->msecFirst; + if (timeWindow->msecLast) + twin_msecLast = timeWindow->msecLast; else twin_msecLast = 0x7FFFFFFFFFFFFFFFLL; } else {