Add CLI overrides for config values.

This commit is contained in:
Christian Deacon
2025-02-26 20:29:53 -05:00
parent c567a028ed
commit 9d7549e39d
6 changed files with 266 additions and 90 deletions

View File

@@ -86,7 +86,7 @@ sudo make install
![Script Build Demo](./images/build_make.gif) ![Script Build Demo](./images/build_make.gif)
## Command Line Usage ## Command Line Usage
The following command line arguments are supported. The following general command line arguments are supported.
| Name | Default | Description | | Name | Default | Description |
| ---- | ------- | ----------- | | ---- | ------- | ----------- |
@@ -97,6 +97,18 @@ The following command line arguments are supported.
| -l, --list | N/A | If set, will print the current config values and exit. | | -l, --list | N/A | If set, will print the current config values and exit. |
| -h, --help | N/A | Prints a help message. | | -h, --help | N/A | Prints a help message. |
Additionally, there are command line overrides for base config options.
| Name | Example | Description |
| ---- | ------- | ----------- |
| -v, --verbose | `-v 3` | Overrides the config's verbose value. |
| --log-file | `--log-file ./test.log` | Overrides the config's log file value. |
| -i, --interface | `-i enp1s0` | Overrides the config's interface value. |
| -u, --update-time | `-u 30` | Overrides the config's update time value. |
| -n, --no-stats | `-n 1` | Overrides the config's no stats value. |
| --stats-ps | `--stats-ps 1` | Overrides the config's stats per second value. |
| --stdout-update-time | `--stdout-update-time 500` | Overrides the config's stdout update time value. |
### Offload Information ### Offload Information
Offloading your XDP/BPF program to your system's NIC allows for the fastest packet processing you can achieve due to the NIC dropping the packets with its hardware. However, for one, there are **not** many NIC manufacturers that do support this feature **and** you're limited to the NIC's memory/processing (e.g. your BPF map sizes will be extremely limited). Additionally, there are usually stricter BPF verifier limitations for offloaded BPF programs, but you may try reaching out to the NIC's manufacturer to see if they will give you a special version of their NIC driver raising these limitations (this is what I did with one manufacturer I used). Offloading your XDP/BPF program to your system's NIC allows for the fastest packet processing you can achieve due to the NIC dropping the packets with its hardware. However, for one, there are **not** many NIC manufacturers that do support this feature **and** you're limited to the NIC's memory/processing (e.g. your BPF map sizes will be extremely limited). Additionally, there are usually stricter BPF verifier limitations for offloaded BPF programs, but you may try reaching out to the NIC's manufacturer to see if they will give you a special version of their NIC driver raising these limitations (this is what I did with one manufacturer I used).
@@ -195,8 +207,12 @@ You may additionally specified UDP header options for a filter rule which start
Here's a config example. Here's a config example.
```squidconf ```squidconf
verbose = 5;
log_file = "";
interface = "ens18"; interface = "ens18";
update_time = 15; update_time = 15;
no_stats = false;
stats_per_second = true;
filters = ( filters = (
{ {

View File

@@ -28,6 +28,11 @@ int main(int argc, char *argv[])
// Parse the command line. // Parse the command line.
cmdline_t cmd = {0}; cmdline_t cmd = {0};
cmd.cfgfile = CONFIG_DEFAULT_PATH; cmd.cfgfile = CONFIG_DEFAULT_PATH;
cmd.verbose = -1;
cmd.update_time = -1;
cmd.no_stats = -1;
cmd.stats_per_second = -1;
cmd.stdout_update_time = -1;
ParseCommandLine(&cmd, argc, argv); ParseCommandLine(&cmd, argc, argv);
@@ -44,8 +49,18 @@ int main(int argc, char *argv[])
SetCfgDefaults(&cfg); SetCfgDefaults(&cfg);
// Create overrides for config and set arguments from CLI.
config_overrides_t cfg_overrides = {0};
cfg_overrides.verbose = cmd.verbose;
cfg_overrides.log_file = cmd.log_file;
cfg_overrides.interface = cmd.interface;
cfg_overrides.update_time = cmd.update_time;
cfg_overrides.no_stats = cmd.no_stats;
cfg_overrides.stats_per_second = cmd.stats_per_second;
cfg_overrides.stdout_update_time = cmd.stdout_update_time;
// Load config. // Load config.
if ((ret = LoadConfig(&cfg, cmd.cfgfile)) != 0) if ((ret = LoadConfig(&cfg, cmd.cfgfile, &cfg_overrides)) != 0)
{ {
fprintf(stderr, "[ERROR] Failed to load config from file system (%s)(%d).\n", cmd.cfgfile, ret); fprintf(stderr, "[ERROR] Failed to load config from file system (%s)(%d).\n", cmd.cfgfile, ret);
@@ -66,6 +81,14 @@ int main(int argc, char *argv[])
PrintToolInfo(); PrintToolInfo();
} }
// Check interface.
if (cfg.interface == NULL)
{
LogMsg(&cfg, 0, 1, "[ERROR] No interface specified in config or CLI override.");
return EXIT_FAILURE;
}
LogMsg(&cfg, 2, 0, "Raising RLimit..."); LogMsg(&cfg, 2, 0, "Raising RLimit...");
// Raise RLimit. // Raise RLimit.
@@ -217,12 +240,8 @@ int main(int argc, char *argv[])
{ {
// Check if config file have been modified // Check if config file have been modified
if (stat(cmd.cfgfile, &conf_stat) == 0 && conf_stat.st_mtime > last_config_check) { if (stat(cmd.cfgfile, &conf_stat) == 0 && conf_stat.st_mtime > last_config_check) {
// Memleak fix for strdup() in LoadConfig()
// Before updating it again, we need to free the old return value
free(cfg.interface);
// Update config. // Update config.
if ((ret = LoadConfig(&cfg, cmd.cfgfile)) != 0) if ((ret = LoadConfig(&cfg, cmd.cfgfile, &cfg_overrides)) != 0)
{ {
LogMsg(&cfg, 1, 0, "[WARNING] Failed to load config after update check (%d)...\n", ret); LogMsg(&cfg, 1, 0, "[WARNING] Failed to load config after update check (%d)...\n", ret);
} }

View File

@@ -8,6 +8,15 @@ const struct option opts[] =
{ "time", required_argument, NULL, 't' }, { "time", required_argument, NULL, 't' },
{ "list", no_argument, NULL, 'l' }, { "list", no_argument, NULL, 'l' },
{ "help", no_argument, NULL, 'h' }, { "help", no_argument, NULL, 'h' },
{ "verbose", required_argument, NULL, 'v' },
{ "log-file", required_argument, NULL, 0 },
{ "interface", required_argument, NULL, 'i' },
{ "update-time", required_argument, NULL, 'u' },
{ "no-stats", required_argument, NULL, 'n' },
{ "stats-ps", required_argument, NULL, 1 },
{ "stdout-update-time", required_argument, NULL, 2 },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
}; };
@@ -22,7 +31,7 @@ void ParseCommandLine(cmdline_t *cmd, int argc, char *argv[])
{ {
int c; int c;
while ((c = getopt_long(argc, argv, "c:ost:lh", opts, NULL)) != -1) while ((c = getopt_long(argc, argv, "c:ost:lhv:i:u:n:", opts, NULL)) != -1)
{ {
switch (c) switch (c)
{ {
@@ -56,6 +65,41 @@ void ParseCommandLine(cmdline_t *cmd, int argc, char *argv[])
break; break;
case 'v':
cmd->verbose = atoi(optarg);
break;
case 0:
cmd->log_file = optarg;
break;
case 'i':
cmd->interface = optarg;
break;
case 'u':
cmd->update_time = atoi(optarg);
break;
case 'n':
cmd->no_stats = atoi(optarg);
break;
case 1:
cmd->stats_per_second = atoi(optarg);
break;
case 2:
cmd->stdout_update_time = atoi(optarg);
break;
case '?': case '?':
fprintf(stderr, "Missing argument option...\n"); fprintf(stderr, "Missing argument option...\n");

View File

@@ -12,6 +12,14 @@ struct cmdline
unsigned int time; unsigned int time;
unsigned int list : 1; unsigned int list : 1;
unsigned int help : 1; unsigned int help : 1;
int verbose;
char* log_file;
char* interface;
int update_time;
int no_stats;
int stats_per_second;
int stdout_update_time;
} typedef cmdline_t; } typedef cmdline_t;
void ParseCommandLine(cmdline_t *cmd, int argc, char *argv[]); void ParseCommandLine(cmdline_t *cmd, int argc, char *argv[]);

View File

@@ -7,10 +7,11 @@ static FILE *file;
* *
* @param cfg A pointer to the config structure. * @param cfg A pointer to the config structure.
* @param cfg_file The path to the config file. * @param cfg_file The path to the config file.
* @param overrides Overrides to use instead of config values.
* *
* @return 0 on success or 1 on error. * @return 0 on success or 1 on error.
*/ */
int LoadConfig(config__t *cfg, char *cfg_file) int LoadConfig(config__t *cfg, char *cfg_file, config_overrides_t* overrides)
{ {
// Open config file. // Open config file.
if (OpenCfg(cfg_file) != 0) if (OpenCfg(cfg_file) != 0)
@@ -25,7 +26,7 @@ int LoadConfig(config__t *cfg, char *cfg_file)
memset(cfg->filters, 0, sizeof(cfg->filters)); memset(cfg->filters, 0, sizeof(cfg->filters));
// Read config and check for errors. // Read config and check for errors.
if (ReadCfg(cfg) != 0) if (ReadCfg(cfg, overrides) != 0)
{ {
fprintf(stderr, "Error reading config file.\n"); fprintf(stderr, "Error reading config file.\n");
@@ -144,10 +145,11 @@ int OpenCfg(const char *file_name)
* Read the config file and stores values in config structure. * Read the config file and stores values in config structure.
* *
* @param cfg A pointer to the config structure. * @param cfg A pointer to the config structure.
* @param overrides Overrides to use instead of config values.
* *
* @return 0 on success or 1/-1 on error. * @return 0 on success or 1/-1 on error.
*/ */
int ReadCfg(config__t *cfg) int ReadCfg(config__t *cfg, config_overrides_t* overrides)
{ {
// Not sure why this would be set to NULL after checking for it in OpenConfig(), but just for safety. // Not sure why this would be set to NULL after checking for it in OpenConfig(), but just for safety.
if (file == NULL) if (file == NULL)
@@ -173,14 +175,21 @@ int ReadCfg(config__t *cfg)
int verbose; int verbose;
if (config_lookup_int(&conf, "verbose", &verbose) == CONFIG_TRUE) if (config_lookup_int(&conf, "verbose", &verbose) == CONFIG_TRUE || overrides->verbose > -1)
{ {
cfg->verbose = verbose; if (overrides->verbose > -1)
{
cfg->verbose = overrides->verbose;
}
else
{
cfg->verbose = verbose;
}
} }
const char* log_file; const char* log_file;
if (config_lookup_string(&conf, "log_file", &log_file) == CONFIG_TRUE) if (config_lookup_string(&conf, "log_file", &log_file) == CONFIG_TRUE || overrides->log_file != NULL)
{ {
// We must free previous value to prevent memory leak. // We must free previous value to prevent memory leak.
if (cfg->log_file != NULL) if (cfg->log_file != NULL)
@@ -189,61 +198,111 @@ int ReadCfg(config__t *cfg)
cfg->log_file = NULL; cfg->log_file = NULL;
} }
if (strlen(log_file) > 0) if (overrides->log_file != NULL)
{ {
cfg->log_file = strdup(log_file); if (strlen(overrides->log_file) > 0)
{
cfg->log_file = strdup(overrides->log_file);
}
else
{
cfg->log_file = NULL;
}
} }
else else
{ {
cfg->log_file = NULL; if (strlen(log_file) > 0)
{
cfg->log_file = strdup(log_file);
}
else
{
cfg->log_file = NULL;
}
} }
} }
// Get interface. // Get interface.
const char *interface; const char *interface;
if (!config_lookup_string(&conf, "interface", &interface)) if (config_lookup_string(&conf, "interface", &interface) == CONFIG_TRUE || overrides->interface != NULL)
{ {
LogMsg(cfg, 0, 1, "Error from LibConfig when reading 'interface' setting - %s", config_error_text(&conf)); // We must free previous value to prevent memory leak.
if (cfg->interface != NULL)
{
free(cfg->interface);
cfg->interface = NULL;
}
config_destroy(&conf); if (overrides->interface != NULL)
{
return EXIT_FAILURE; cfg->interface = strdup(overrides->interface);
}
else
{
cfg->interface = strdup(interface);
}
} }
cfg->interface = strdup(interface);
// Get auto update time. // Get auto update time.
int update_time; int update_time;
if (config_lookup_int(&conf, "update_time", &update_time) == CONFIG_TRUE) if (config_lookup_int(&conf, "update_time", &update_time) == CONFIG_TRUE || overrides->update_time > -1)
{ {
cfg->update_time = update_time; if (overrides->update_time > -1)
} {
cfg->update_time = overrides->update_time;
// Get stdout update time. }
int stdout_update_time; else
{
if (config_lookup_int(&conf, "stdout_update_time", &stdout_update_time) == CONFIG_TRUE) cfg->update_time = update_time;
{ }
cfg->stdout_update_time = stdout_update_time;
} }
// Get no stats. // Get no stats.
int no_stats; int no_stats;
if (config_lookup_bool(&conf, "no_stats", &no_stats) == CONFIG_TRUE) if (config_lookup_bool(&conf, "no_stats", &no_stats) == CONFIG_TRUE || overrides->no_stats > -1)
{ {
cfg->no_stats = no_stats; if (overrides->no_stats > -1)
{
cfg->no_stats = overrides->no_stats;
}
else
{
cfg->no_stats = no_stats;
}
} }
// Stats per second. // Stats per second.
int stats_per_second; int stats_per_second;
if (config_lookup_bool(&conf, "stats_per_second", &stats_per_second) == CONFIG_TRUE) if (config_lookup_bool(&conf, "stats_per_second", &stats_per_second) == CONFIG_TRUE || overrides->stats_per_second > -1)
{ {
cfg->stats_per_second = stats_per_second; if (overrides->stats_per_second > -1)
{
cfg->stats_per_second = overrides->stats_per_second;
}
else
{
cfg->stats_per_second = stats_per_second;
}
}
// Get stdout update time.
int stdout_update_time;
if (config_lookup_int(&conf, "stdout_update_time", &stdout_update_time) == CONFIG_TRUE || overrides->stdout_update_time > -1)
{
if (overrides->stdout_update_time > -1)
{
cfg->stdout_update_time = overrides->stdout_update_time;
}
else
{
cfg->stdout_update_time = stdout_update_time;
}
} }
// Read filters in filters_map structure. // Read filters in filters_map structure.
@@ -592,14 +651,32 @@ int ReadCfg(config__t *cfg)
*/ */
void PrintConfig(config__t* cfg) void PrintConfig(config__t* cfg)
{ {
fprintf(stdout, "Printing config...\n"); char* interface = "N/A";
fprintf(stdout, "\tGeneral Settings\n");
fprintf(stdout, "\t\tInterface Name => %s\n", cfg->interface);
fprintf(stdout, "\t\tUpdate Time => %d\n", cfg->update_time);
fprintf(stdout, "\t\tStdout Update Time => %d\n", cfg->stdout_update_time);
fprintf(stdout, "\t\tNo Stats => %d\n\n", cfg->no_stats);
fprintf(stdout, "\tFilters\n"); if (cfg->interface != NULL)
{
interface = cfg->interface;
}
char* log_file = "N/A";
if (cfg->log_file != NULL)
{
log_file = cfg->log_file;
}
printf("Printing config...\n");
printf("\tGeneral Settings\n");
printf("\t\tVerbose => %d\n", cfg->verbose);
printf("\t\tLog File => %s\n", log_file);
printf("\t\tInterface Name => %s\n", interface);
printf("\t\tUpdate Time => %d\n", cfg->update_time);
printf("\t\tNo Stats => %d\n", cfg->no_stats);
printf("\t\tStats Per Second => %d\n", cfg->stats_per_second);
printf("\t\tStdout Update Time => %d\n\n", cfg->stdout_update_time);
printf("\tFilters\n");
for (int i = 0; i < MAX_FILTERS; i++) for (int i = 0; i < MAX_FILTERS; i++)
{ {
@@ -610,27 +687,27 @@ void PrintConfig(config__t* cfg)
break; break;
} }
fprintf(stdout, "\t\tFilter #%d:\n", (i + 1)); printf("\t\tFilter #%d:\n", (i + 1));
// Main. // Main.
fprintf(stdout, "\t\t\tID => %d\n", filter->id); printf("\t\t\tID => %d\n", filter->id);
fprintf(stdout, "\t\t\tLog => %d\n", filter->log); printf("\t\t\tLog => %d\n", filter->log);
fprintf(stdout, "\t\t\tEnabled => %d\n", filter->enabled); printf("\t\t\tEnabled => %d\n", filter->enabled);
fprintf(stdout, "\t\t\tAction => %d (0 = Block, 1 = Allow).\n\n", filter->action); printf("\t\t\tAction => %d (0 = Block, 1 = Allow).\n\n", filter->action);
// IP Options. // IP Options.
fprintf(stdout, "\t\t\tIP Options\n"); printf("\t\t\tIP Options\n");
// IP addresses require additional code for string printing. // IP addresses require additional code for string printing.
struct sockaddr_in sin; struct sockaddr_in sin;
sin.sin_addr.s_addr = filter->src_ip; sin.sin_addr.s_addr = filter->src_ip;
fprintf(stdout, "\t\t\t\tSource IPv4 => %s\n", inet_ntoa(sin.sin_addr)); printf("\t\t\t\tSource IPv4 => %s\n", inet_ntoa(sin.sin_addr));
fprintf(stdout, "\t\t\t\tSource CIDR => %d\n", filter->src_cidr); printf("\t\t\t\tSource CIDR => %d\n", filter->src_cidr);
struct sockaddr_in din; struct sockaddr_in din;
din.sin_addr.s_addr = filter->dst_ip; din.sin_addr.s_addr = filter->dst_ip;
fprintf(stdout, "\t\t\t\tDestination IPv4 => %s\n", inet_ntoa(din.sin_addr)); printf("\t\t\t\tDestination IPv4 => %s\n", inet_ntoa(din.sin_addr));
fprintf(stdout, "\t\t\t\tDestination CIDR => %d\n", filter->dst_cidr); printf("\t\t\t\tDestination CIDR => %d\n", filter->dst_cidr);
struct in6_addr sin6; struct in6_addr sin6;
memcpy(&sin6, &filter->src_ip6, sizeof(sin6)); memcpy(&sin6, &filter->src_ip6, sizeof(sin6));
@@ -638,7 +715,7 @@ void PrintConfig(config__t* cfg)
char srcipv6[INET6_ADDRSTRLEN]; char srcipv6[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &sin6, srcipv6, sizeof(srcipv6)); inet_ntop(AF_INET6, &sin6, srcipv6, sizeof(srcipv6));
fprintf(stdout, "\t\t\t\tSource IPv6 => %s\n", srcipv6); printf("\t\t\t\tSource IPv6 => %s\n", srcipv6);
struct in6_addr din6; struct in6_addr din6;
memcpy(&din6, &filter->dst_ip6, sizeof(din6)); memcpy(&din6, &filter->dst_ip6, sizeof(din6));
@@ -646,44 +723,44 @@ void PrintConfig(config__t* cfg)
char dstipv6[INET6_ADDRSTRLEN]; char dstipv6[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &din6, dstipv6, sizeof(dstipv6)); inet_ntop(AF_INET6, &din6, dstipv6, sizeof(dstipv6));
fprintf(stdout, "\t\t\t\tDestination IPv6 => %s\n", dstipv6); printf("\t\t\t\tDestination IPv6 => %s\n", dstipv6);
// Other IP header information. // Other IP header information.
fprintf(stdout, "\t\t\t\tMax Length => %d\n", filter->max_len); printf("\t\t\t\tMax Length => %d\n", filter->max_len);
fprintf(stdout, "\t\t\t\tMin Length => %d\n", filter->min_len); printf("\t\t\t\tMin Length => %d\n", filter->min_len);
fprintf(stdout, "\t\t\t\tMax TTL => %d\n", filter->max_ttl); printf("\t\t\t\tMax TTL => %d\n", filter->max_ttl);
fprintf(stdout, "\t\t\t\tMin TTL => %d\n", filter->min_ttl); printf("\t\t\t\tMin TTL => %d\n", filter->min_ttl);
fprintf(stdout, "\t\t\t\tTOS => %d\n", filter->tos); printf("\t\t\t\tTOS => %d\n", filter->tos);
fprintf(stdout, "\t\t\t\tPPS => %llu\n", filter->pps); printf("\t\t\t\tPPS => %llu\n", filter->pps);
fprintf(stdout, "\t\t\t\tBPS => %llu\n", filter->bps); printf("\t\t\t\tBPS => %llu\n", filter->bps);
fprintf(stdout, "\t\t\t\tBlock Time => %llu\n\n", filter->blocktime); printf("\t\t\t\tBlock Time => %llu\n\n", filter->blocktime);
// TCP Options. // TCP Options.
fprintf(stdout, "\t\t\tTCP Options\n"); printf("\t\t\tTCP Options\n");
fprintf(stdout, "\t\t\t\tTCP Enabled => %d\n", filter->tcpopts.enabled); printf("\t\t\t\tTCP Enabled => %d\n", filter->tcpopts.enabled);
fprintf(stdout, "\t\t\t\tTCP Source Port => %d\n", filter->tcpopts.sport); printf("\t\t\t\tTCP Source Port => %d\n", filter->tcpopts.sport);
fprintf(stdout, "\t\t\t\tTCP Destination Port => %d\n", filter->tcpopts.dport); printf("\t\t\t\tTCP Destination Port => %d\n", filter->tcpopts.dport);
fprintf(stdout, "\t\t\t\tTCP URG Flag => %d\n", filter->tcpopts.urg); printf("\t\t\t\tTCP URG Flag => %d\n", filter->tcpopts.urg);
fprintf(stdout, "\t\t\t\tTCP ACK Flag => %d\n", filter->tcpopts.ack); printf("\t\t\t\tTCP ACK Flag => %d\n", filter->tcpopts.ack);
fprintf(stdout, "\t\t\t\tTCP RST Flag => %d\n", filter->tcpopts.rst); printf("\t\t\t\tTCP RST Flag => %d\n", filter->tcpopts.rst);
fprintf(stdout, "\t\t\t\tTCP PSH Flag => %d\n", filter->tcpopts.psh); printf("\t\t\t\tTCP PSH Flag => %d\n", filter->tcpopts.psh);
fprintf(stdout, "\t\t\t\tTCP SYN Flag => %d\n", filter->tcpopts.syn); printf("\t\t\t\tTCP SYN Flag => %d\n", filter->tcpopts.syn);
fprintf(stdout, "\t\t\t\tTCP FIN Flag => %d\n", filter->tcpopts.fin); printf("\t\t\t\tTCP FIN Flag => %d\n", filter->tcpopts.fin);
fprintf(stdout, "\t\t\t\tTCP ECE Flag => %d\n", filter->tcpopts.ece); printf("\t\t\t\tTCP ECE Flag => %d\n", filter->tcpopts.ece);
fprintf(stdout, "\t\t\t\tTCP CWR Flag => %d\n\n", filter->tcpopts.cwr); printf("\t\t\t\tTCP CWR Flag => %d\n\n", filter->tcpopts.cwr);
// UDP Options. // UDP Options.
fprintf(stdout, "\t\t\tUDP Options\n"); printf("\t\t\tUDP Options\n");
fprintf(stdout, "\t\t\t\tUDP Enabled => %d\n", filter->udpopts.enabled); printf("\t\t\t\tUDP Enabled => %d\n", filter->udpopts.enabled);
fprintf(stdout, "\t\t\t\tUDP Source Port => %d\n", filter->udpopts.sport); printf("\t\t\t\tUDP Source Port => %d\n", filter->udpopts.sport);
fprintf(stdout, "\t\t\t\tUDP Destination Port => %d\n\n", filter->udpopts.dport); printf("\t\t\t\tUDP Destination Port => %d\n\n", filter->udpopts.dport);
// ICMP Options. // ICMP Options.
fprintf(stdout, "\t\t\tICMP Options\n"); printf("\t\t\tICMP Options\n");
fprintf(stdout, "\t\t\t\tICMP Enabled => %d\n", filter->icmpopts.enabled); printf("\t\t\t\tICMP Enabled => %d\n", filter->icmpopts.enabled);
fprintf(stdout, "\t\t\t\tICMP Code => %d\n", filter->icmpopts.code); printf("\t\t\t\tICMP Code => %d\n", filter->icmpopts.code);
fprintf(stdout, "\t\t\t\tICMP Type => %d\n", filter->icmpopts.type); printf("\t\t\t\tICMP Type => %d\n", filter->icmpopts.type);
fprintf(stdout, "\n\n"); printf("\n\n");
} }
} }

View File

@@ -18,18 +18,30 @@ struct config
int verbose; int verbose;
char *log_file; char *log_file;
char *interface; char *interface;
u16 update_time; int update_time;
unsigned int no_stats : 1; unsigned int no_stats : 1;
unsigned int stats_per_second : 1; unsigned int stats_per_second : 1;
int stdout_update_time; int stdout_update_time;
filter_t filters[MAX_FILTERS]; filter_t filters[MAX_FILTERS];
} typedef config__t; // config_t is taken by libconfig -.- } typedef config__t; // config_t is taken by libconfig -.-
int LoadConfig(config__t *cfg, char *cfg_file); struct config_overrides
{
int verbose;
const char* log_file;
const char* interface;
int update_time;
int no_stats;
int stats_per_second;
int stdout_update_time;
} typedef config_overrides_t;
int LoadConfig(config__t *cfg, char *cfg_file, config_overrides_t* overrides);
void SetCfgDefaults(config__t *cfg); void SetCfgDefaults(config__t *cfg);
void PrintConfig(config__t* cfg); void PrintConfig(config__t* cfg);
int OpenCfg(const char *filename); int OpenCfg(const char *filename);
int ReadCfg(config__t *cfg); int ReadCfg(config__t *cfg, config_overrides_t* overrides);
#include <loader/utils/logging.h> #include <loader/utils/logging.h>