diff options
author | Yunchih Chen <yunchih.cat@gmail.com> | 2018-09-01 08:47:59 +0800 |
---|---|---|
committer | Yunchih Chen <yunchih.cat@gmail.com> | 2018-09-01 08:47:59 +0800 |
commit | c5b6d181707cade0785f84bbd2df17f8268f5a4a (patch) | |
tree | 9648ba7c2878fcdfb7446ff9e8cabdcf034300cf | |
parent | 148eec92611367a6fc0f688377a74f89968bf7e7 (diff) | |
download | nfcollect-c5b6d181707cade0785f84bbd2df17f8268f5a4a.tar nfcollect-c5b6d181707cade0785f84bbd2df17f8268f5a4a.tar.gz nfcollect-c5b6d181707cade0785f84bbd2df17f8268f5a4a.tar.bz2 nfcollect-c5b6d181707cade0785f84bbd2df17f8268f5a4a.tar.lz nfcollect-c5b6d181707cade0785f84bbd2df17f8268f5a4a.tar.xz nfcollect-c5b6d181707cade0785f84bbd2df17f8268f5a4a.tar.zst nfcollect-c5b6d181707cade0785f84bbd2df17f8268f5a4a.zip |
Add extract time range selection
-rw-r--r-- | bin/nfcollect.c | 3 | ||||
-rw-r--r-- | bin/nfextract.c | 76 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | include/extract.h | 2 | ||||
-rw-r--r-- | include/main.h | 10 | ||||
-rw-r--r-- | lib/common.c | 2 | ||||
-rw-r--r-- | lib/extract.c | 5 |
7 files changed, 81 insertions, 18 deletions
diff --git a/bin/nfcollect.c b/bin/nfcollect.c index f59d68f..160a21a 100644 --- a/bin/nfcollect.c +++ b/bin/nfcollect.c @@ -35,6 +35,7 @@ #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> +#include <string.h> #include <unistd.h> const char *help_text = @@ -103,7 +104,7 @@ int main(int argc, char *argv[]) { compression_flag = optarg; break; case 'd': - storage_dir = optarg; + storage_dir = strdup(optarg); break; case 'g': nfl_group_id = atoi(optarg); diff --git a/bin/nfextract.c b/bin/nfextract.c index 31e4605..fac52ae 100644 --- a/bin/nfextract.c +++ b/bin/nfextract.c @@ -34,9 +34,15 @@ #include <string.h> #include <sys/stat.h> #include <sys/types.h> +#include <string.h> +#include <time.h> #include <unistd.h> #define PROG "nfextract" +#define DATE_FORMAT_HUMAN "YYYY-MM-DD [HH:MM][:SS]" +#define DATE_FORMAT "%Y-%m-%d" +#define DATE_FORMAT_FULL DATE_FORMAT " %H:%M" +#define DATE_FORMAT_FULL2 DATE_FORMAT " %H:%M:%S" sem_t nfl_commit_queue; uint16_t nfl_group_id; @@ -45,9 +51,11 @@ const char *help_text = "Usage: " PROG " [OPTION]\n" "\n" "Options:\n" - " -d --storage_dir=<dirname> log files storage directory\n" - " -h --help print this help\n" - " -v --version print version information\n" + " -d --storage_dir=<dirname> log files storage directory\n" + " -h --help print this help\n" + " -v --version print version information\n" + " -s --since start showing entries on or newer than the specified date (format: " DATE_FORMAT_HUMAN ")\n" + " -u --until stop showing entries on or older than the specified date (format: " DATE_FORMAT_HUMAN ")\n" "\n"; void sig_handler(int signo) { @@ -55,7 +63,7 @@ void sig_handler(int signo) { puts("Terminated due to SIGHUP ..."); } -static void extract_each(const char *storage_dir, const char *filename) { +static void extract_each(const char *storage_dir, const char *filename, const time_range_t *range) { nfl_state_t trunk; // Build full path @@ -63,20 +71,22 @@ static void extract_each(const char *storage_dir, const char *filename) { sprintf(fullpath, "%s/%s", storage_dir, filename); debug("Extracting storage file: %s", fullpath); - int entries = nfl_extract_worker(fullpath, &trunk); - if (entries < 0) - return; - + int entries = nfl_extract_worker(fullpath, &trunk, range); free(fullpath); + int i = 0; + while(i < entries && trunk.store[i].timestamp < range->from) + i++; + char output[1024]; - for (int i = 0; i < entries; ++i) { + while(i < entries && trunk.store[i].timestamp < range->until) { nfl_format_output(output, &trunk.store[i]); puts((char *)output); + ++i; } } -static void extract_all(const char *storage_dir) { +static void extract_all(const char *storage_dir, const time_range_t *range) { DIR *dp; struct dirent *ep; int i, index, max_index = -1; @@ -105,15 +115,41 @@ static void extract_all(const char *storage_dir) { for (i = 0; i <= max_index; ++i) { if (trunk_files[i]) - extract_each(storage_dir, trunk_files[i]); + extract_each(storage_dir, trunk_files[i], range); free(trunk_files[i]); } } +static time_t parse_date_string(time_t default_t, const char *date) { + struct tm parsed; + char *ret; + if(!date) return default_t; + +#define PARSE(FORMAT) \ + ret = strptime(date, FORMAT, &parsed); \ + if(ret && !*ret) return mktime(&parsed); \ + + PARSE(DATE_FORMAT); + PARSE(DATE_FORMAT_FULL); + PARSE(DATE_FORMAT_FULL2); + + FATAL("Wrong date format: expected: \"" DATE_FORMAT_HUMAN "\", got: \"%s\"", date); + return -1; +} +static void populate_date_range(time_range_t *range, const char *since, const char *until) { + range->from = parse_date_string(0, since); + range->until = parse_date_string(time(NULL), until); +} + int main(int argc, char *argv[]) { char *storage_dir = NULL; + char *date_since_str = NULL, *date_until_str = NULL; + time_range_t date_range; + struct option longopts[] = {/* name, has_args, flag, val */ {"storage_dir", required_argument, NULL, 'd'}, + {"since", optional_argument, NULL, 's'}, + {"until", optional_argument, NULL, 'u'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'v'}, {0, 0, 0, 0}}; @@ -130,7 +166,16 @@ int main(int argc, char *argv[]) { exit(0); break; case 'd': - storage_dir = optarg; + if(!optarg) FATAL("Expected: --storage_dir=[PATH]"); + storage_dir = strdup(optarg); + break; + case 's': + if(!optarg) FATAL("Expected: --since=\"" DATE_FORMAT_HUMAN "\""); + date_since_str = strdup(optarg); + break; + case 'u': + if(!optarg) FATAL("Expected: --until=\"" DATE_FORMAT_HUMAN "\""); + date_until_str = strdup(optarg); break; case '?': fprintf(stderr, "Unknown argument, see --help"); @@ -147,6 +192,11 @@ int main(int argc, char *argv[]) { // register signal handler ERR(signal(SIGHUP, sig_handler) == SIG_ERR, "Could not set SIGHUP handler"); - extract_all(storage_dir); + populate_date_range(&date_range, date_since_str, date_until_str); + free(date_since_str); free(date_until_str); + + extract_all(storage_dir, &date_range); + free(storage_dir); + return 0; } diff --git a/configure.ac b/configure.ac index 66497f4..ce27d08 100644 --- a/configure.ac +++ b/configure.ac @@ -28,6 +28,7 @@ esac],[debug=false]) if test x"$debug" = x"true"; then AC_DEFINE(DEBUG, 1, [debug]) fi +AC_DEFINE(_XOPEN_SOURCE, 700) AC_CHECK_HEADERS(libnetfilter_log/libnetfilter_log.h) AC_SEARCH_LIBS(nflog_open, netfilter_log) diff --git a/include/extract.h b/include/extract.h index bb57511..da7c7bf 100644 --- a/include/extract.h +++ b/include/extract.h @@ -1,4 +1,4 @@ #pragma once #include "common.h" -int nfl_extract_worker(const char *filename, nfl_state_t *state); +int nfl_extract_worker(const char *filename, nfl_state_t *state, const time_range_t *range); diff --git a/include/main.h b/include/main.h index 88a7c8c..64ed558 100644 --- a/include/main.h +++ b/include/main.h @@ -26,12 +26,16 @@ #include <assert.h> #include <netinet/in.h> #include <netinet/ip.h> -#include <netinet/tcp.h> +#include <linux/tcp.h> #include <netinet/udp.h> #include <semaphore.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> +#include <time.h> + +#include <pthread.h> +#include <sys/types.h> #ifdef DEBUG #define DEBUG_ON 1 @@ -154,6 +158,10 @@ typedef struct _nfl_state_t { pthread_t thread; } nfl_state_t; +typedef struct _time_range_t { + time_t from, until; +} time_range_t; + // only copy size of ipv4 header + tcp header static const int nfl_recv_size = sizeof(struct iphdr) + sizeof(struct tcphdr); diff --git a/lib/common.c b/lib/common.c index c81dfdb..860ef90 100644 --- a/lib/common.c +++ b/lib/common.c @@ -78,7 +78,7 @@ uint32_t nfl_header_cksum(nfl_header_t *header) { void nfl_cal_trunk(uint32_t total_size, uint32_t *trunk_cnt, uint32_t *trunk_size) { - uint32_t pgsize = getpagesize(); + uint32_t pgsize = sysconf(_SC_PAGE_SIZE); total_size *= 1024 * 1024; // MiB assert(trunk_cnt); diff --git a/lib/extract.c b/lib/extract.c index ea10582..8907c26 100644 --- a/lib/extract.c +++ b/lib/extract.c @@ -76,7 +76,7 @@ static int nfl_extract_lz4(FILE *f, nfl_state_t *state) { return 0; } -int nfl_extract_worker(const char *filename, nfl_state_t *state) { +int nfl_extract_worker(const char *filename, nfl_state_t *state, const time_range_t *range) { FILE *f; int got = 0, ret = 0; nfl_header_t *h; @@ -91,6 +91,9 @@ int nfl_extract_worker(const char *filename, nfl_state_t *state) { got = fread(state->header, sizeof(nfl_header_t), 1, f); h = state->header; + if(h->end_time < range->from || h->start_time > range->until) + return 0; + // Check header validity WARN_RETURN(ferror(f), "%s", strerror(errno)); WARN_RETURN(got == 0 || nfl_verify_header(h) < 0, |