From 15b9bfd21bf261a26215bc2a89721f822afb8ff7 Mon Sep 17 00:00:00 2001 From: Peter Haag Date: Sat, 31 Aug 2024 18:41:49 +0200 Subject: [PATCH] Change GRE cli option -G in sfcapd for -o gre option string. #559 --- man/sfcapd.1 | 12 +++++++++++ src/libnffile/conf/nfconf.c | 30 +++++++++++++++++++++++++++ src/libnffile/conf/nfconf.h | 2 ++ src/libnffile/conf/nfdump.conf.dist | 4 ++++ src/nfpcapd/nfpcapd.c | 32 ----------------------------- src/sflow/sfcapd.c | 30 +++++++++++++++++++-------- 6 files changed, 70 insertions(+), 40 deletions(-) diff --git a/man/sfcapd.1 b/man/sfcapd.1 index 41947862..a50bc95b 100755 --- a/man/sfcapd.1 +++ b/man/sfcapd.1 @@ -57,6 +57,7 @@ .Op Fl M Ar multiflowdir .Op Fl i Ar metricrate .Op Fl m Ar metricpath +.Op Fl o Ar optionlist .Op Fl e .Op Fl x Ar command .Op Fl X Ar extensionList @@ -275,6 +276,17 @@ dynamically to store all data sent by the exporter. If .Ar extensionList is given, only those elements matching the extension are processed and stored. Usually this option is not needed, unless for specific requirements. +.It Fl o Ar options +Set +.Nm +options. This is a ',' separated list of options. Available options: +.It +.Sy gre +Add GRE tunnel decoding. +.It +These options may also be defined in the +.Sy nfdump.conf +config file. Options specified on the command line overwrite the value in the config file. .It Fl m Ar metricpath Enables the flow metric exporter. Flow metric information is sent to the UNIX socket .Ar metricpath diff --git a/src/libnffile/conf/nfconf.c b/src/libnffile/conf/nfconf.c index a04f7a73..08be8a12 100644 --- a/src/libnffile/conf/nfconf.c +++ b/src/libnffile/conf/nfconf.c @@ -429,6 +429,36 @@ int SetNameserver(char *ns) { } // End of set_nameserver +int scanOptions(option_t *optionList, char *options) { + if (options == NULL) return 1; + + char *option = strtok(options, ","); + while (option != NULL) { + int valBool = 1; + char *eq = strchr(option, '='); + if (eq) { + *eq++ = '\0'; + switch (eq[0]) { + case '0': + valBool = 0; + break; + case '1': + valBool = 1; + break; + default: + LogError("Invalid bool value: %s", eq[0] ? eq : "empty value"); + } + } + if (OptSetBool(optionList, option, valBool) == 0) { + LogError("Unknown option: %s", option); + return 0; + } + option = strtok(NULL, ","); + } + return 1; + +} // End of scanOption + int OptSetBool(option_t *optionList, char *name, int valBool) { int i = 0; while (optionList[i].name != NULL) { diff --git a/src/libnffile/conf/nfconf.h b/src/libnffile/conf/nfconf.h index 10770ebc..2e2de3fd 100644 --- a/src/libnffile/conf/nfconf.h +++ b/src/libnffile/conf/nfconf.h @@ -60,6 +60,8 @@ int ConfGetValue(char *key); int SetNameserver(char *ns); +int scanOptions(option_t *optionList, char *options); + void ConfInventory(char *confFile); int OptSetBool(option_t *optionList, char *name, int valBool); diff --git a/src/libnffile/conf/nfdump.conf.dist b/src/libnffile/conf/nfdump.conf.dist index 27542ff0..f4277000 100644 --- a/src/libnffile/conf/nfdump.conf.dist +++ b/src/libnffile/conf/nfdump.conf.dist @@ -62,6 +62,10 @@ fmt.pflog = "%ts %pfact %pfrea %pfdir on %pfifn %pfrule %pr %sap -> %dap %pkt # see maxworkers in section [nfdump] # maxworkers = 16 +[sfcapd] +# define -o options +# opt.gre = 1 + [nfpcapd] # define -o options # opt.fat = 1 diff --git a/src/nfpcapd/nfpcapd.c b/src/nfpcapd/nfpcapd.c index 903024e0..a6aa8a2f 100755 --- a/src/nfpcapd/nfpcapd.c +++ b/src/nfpcapd/nfpcapd.c @@ -116,8 +116,6 @@ static int setup_pcap_file(packetParam_t *param, char *pcap_file, char *filter, static void WaitDone(void); -static int scanOptions(option_t *optionList, char *options); - /* * Functions */ @@ -258,36 +256,6 @@ static void WaitDone(void) { } // End of WaitDone -static int scanOptions(option_t *optionList, char *options) { - if (options == NULL) return 1; - - char *option = strtok(options, ","); - while (option != NULL) { - int valBool = 1; - char *eq = strchr(option, '='); - if (eq) { - *eq++ = '\0'; - switch (eq[0]) { - case '0': - valBool = 0; - break; - case '1': - valBool = 1; - break; - default: - LogError("Invalid bool value: %s", eq[0] ? eq : "empty value"); - } - } - if (OptSetBool(optionList, option, valBool) == 0) { - LogError("Unknown option: %s", option); - return 0; - } - option = strtok(NULL, ","); - } - return 1; - -} // End of scanOption - int main(int argc, char *argv[]) { sigset_t signal_set; struct sigaction sa; diff --git a/src/sflow/sfcapd.c b/src/sflow/sfcapd.c index 497362cf..8f9bc0af 100644 --- a/src/sflow/sfcapd.c +++ b/src/sflow/sfcapd.c @@ -95,6 +95,8 @@ static int verbose = 0; // Define a generic type to get data from socket or pcap file typedef ssize_t (*packet_function_t)(int, void *, size_t, int, struct sockaddr *, socklen_t *); +static option_t sfcapdOption[] = {{.name = "gre", .valBool = 0, .flags = OPTDEFAULT}, {.name = NULL}}; + /* module limited globals */ static FlowSource_t *FlowSource; @@ -111,7 +113,8 @@ static void IntHandler(int signal); static inline FlowSource_t *GetFlowSource(struct sockaddr_storage *ss); -static void run(packet_function_t receive_packet, int socket, int pfd, int rfd, time_t twin, time_t t_begin, char *time_extension, int compress, int parse_gre); +static void run(packet_function_t receive_packet, int socket, int pfd, int rfd, time_t twin, time_t t_begin, char *time_extension, int compress, + int parse_gre); /* Functions */ static void usage(char *name) { @@ -136,6 +139,7 @@ static void usage(char *name) { "-i interval\tMetric interval in s for metric exporter\n" "-m socket\t\tEnable metric exporter on socket.\n" "-M dir \t\tSet the output directory for dynamic sources.\n" + "-o options \tAdd sfcpad options, separated with ','. Available: 'gre'\n" "-P pidfile\tset the PID file\n" "-R IP[/port]\tRepeat incoming packets to IP address/port. Max 8 repeaters.\n" "-A\t\tEnable source address spoofing for packet repeater -R.\n" @@ -155,7 +159,6 @@ static void usage(char *name) { "-X \t',' separated list of extensions (numbers). Default all extensions.\n" "-V\t\tPrint version and exit.\n" "-Z\t\tAdd timezone offset to filename.\n", - "-G\t\tEnable GRE parsing.\n", name); } // End of usage @@ -267,7 +270,8 @@ static int SendRepeaterMessage(int fd, void *in_buff, size_t cnt, struct sockadd return 0; } // End of SendRepeaterMessage -static void run(packet_function_t receive_packet, int socket, int pfd, int rfd, time_t twin, time_t t_begin, char *time_extension, int compress, int parse_gre) { +static void run(packet_function_t receive_packet, int socket, int pfd, int rfd, time_t twin, time_t t_begin, char *time_extension, int compress, + int parse_gre) { struct sockaddr_storage sf_sender; socklen_t sf_sender_size = sizeof(sf_sender); @@ -447,7 +451,7 @@ int main(int argc, char **argv) { char *bindhost, *datadir, *launch_process; char *userid, *groupid, *listenport, *mcastgroup; char *Ident, *dynFlowDir, *time_extension, *pidfile, *configFile, *metricSocket; - char *extensionList; + char *extensionList, *options; packet_function_t receive_packet; repeater_t repeater[MAX_REPEATERS]; FlowSource_t *fs; @@ -486,11 +490,12 @@ int main(int argc, char **argv) { metricSocket = NULL; metricInterval = 60; extensionList = NULL; + options = NULL; workers = 0; parse_gre = 0; int c; - while ((c = getopt(argc, argv, "46AB:b:C:d:DeEf:g:hI:i:jJ:l:m:M:n:p:P:R:S:T:t:u:vVW:w:x:X:yz::Z:G")) != EOF) { + while ((c = getopt(argc, argv, "46AB:b:C:d:DeEf:g:hI:i:jJ:l:m:M:n:o:p:P:R:S:T:t:u:vVW:w:x:X:yz::Z:")) != EOF) { switch (c) { case 'h': usage(argv[0]); @@ -597,6 +602,13 @@ int main(int argc, char **argv) { case 'J': mcastgroup = optarg; break; + case 'o': + if (strlen(optarg) > 64) { + LogError("ERROR:, option string size error"); + exit(EXIT_FAILURE); + } + options = strdup(optarg); + break; case 'p': listenport = optarg; break; @@ -727,9 +739,6 @@ int main(int argc, char **argv) { exit(EXIT_FAILURE); } break; - case 'G': - parse_gre = 1; - break; default: usage(argv[0]); exit(EXIT_FAILURE); @@ -767,6 +776,11 @@ int main(int argc, char **argv) { if (ConfOpen(configFile, "sfcapd") < 0) exit(EXIT_FAILURE); + if (scanOptions(sfcapdOption, options) == 0) { + exit(EXIT_FAILURE); + } + OptGetBool(sfcapdOption, "gre", &parse_gre); + if (datadir && !AddFlowSource(&FlowSource, Ident, ANYIP, datadir)) { LogError("Failed to add default data collector directory"); exit(EXIT_FAILURE);