Fixed segfault crashes and improved code.

This commit is contained in:
Christian Deacon
2020-05-05 16:35:24 +00:00
parent ef1bb56c89
commit 66364a1f6b
3 changed files with 209 additions and 162 deletions

View File

@@ -28,13 +28,12 @@ void SetConfigDefaults(struct config_map *cfg)
cfg->filters[i].min_ttl = 0; cfg->filters[i].min_ttl = 0;
cfg->filters[i].max_ttl = 255; cfg->filters[i].max_ttl = 255;
cfg->filters[i].tos = 0; cfg->filters[i].tos = 0;
cfg->filters[i].protocol = 0;
cfg->filters[i].tcpopts.enabled = 0; cfg->filters[i].tcpopts.enabled = 0;
cfg->filters[i].udpopts.enabled = 0; cfg->filters[i].udpopts.enabled = 0;
cfg->filters[i].icmpopts.enabled = 0; cfg->filters[i].icmpopts.enabled = 0;
for (uint16_t j = 0; i < MAX_PCKT_LENGTH; i++) for (uint16_t j = 0; j < MAX_PCKT_LENGTH - 1; j++)
{ {
cfg->filters[i].payloadMatch[j] = 0; cfg->filters[i].payloadMatch[j] = 0;
} }
@@ -105,7 +104,7 @@ int ReadConfig(struct config_map *cfg)
// Get auto update time. // Get auto update time.
int updateTime; int updateTime;
if (!config_lookup_bool(&conf, "updatetime", &updateTime)) if (!config_lookup_int(&conf, "updatetime", &updateTime))
{ {
fprintf(stderr, "Error from LibConfig when reading 'updatetime' setting - %s\n\n", config_error_text(&conf)); fprintf(stderr, "Error from LibConfig when reading 'updatetime' setting - %s\n\n", config_error_text(&conf));
@@ -139,7 +138,7 @@ int ReadConfig(struct config_map *cfg)
// Enabled. // Enabled.
int enabled; int enabled;
if (config_setting_lookup_bool(filter, "enabled", &enabled) != 0) if (config_setting_lookup_bool(filter, "enabled", &enabled) == CONFIG_FALSE)
{ {
// Print error and stop from existing this rule any further. // Print error and stop from existing this rule any further.
fprintf(stderr, "Error from LibConfig when reading 'enabled' setting from filters array #%d. Error - %s\n\n", filters, config_error_text(&conf)); fprintf(stderr, "Error from LibConfig when reading 'enabled' setting from filters array #%d. Error - %s\n\n", filters, config_error_text(&conf));
@@ -152,7 +151,7 @@ int ReadConfig(struct config_map *cfg)
// Action (required). // Action (required).
int action; int action;
if (config_setting_lookup_int(filter, "action", &action) != 0) if (config_setting_lookup_int(filter, "action", &action) == CONFIG_FALSE)
{ {
fprintf(stderr, "Error from LibConfig when reading 'action' setting from filters array #%d. Error - %s\n\n", filters, config_error_text(&conf)); fprintf(stderr, "Error from LibConfig when reading 'action' setting from filters array #%d. Error - %s\n\n", filters, config_error_text(&conf));
@@ -179,26 +178,12 @@ int ReadConfig(struct config_map *cfg)
cfg->filters[i].dstIP = inet_addr(dIP); cfg->filters[i].dstIP = inet_addr(dIP);
} }
// Protocol (required).
int protocol;
if (!config_setting_lookup_int(filter, "protocol", &protocol))
{
fprintf(stderr, "Error from LibConfig when reading 'protocol' setting from filters array #%d. Error - %s\n\n", filters, config_error_text(&conf));
cfg->filters[i].enabled = 0;
continue;
}
cfg->filters[i].protocol = protocol;
// Minimum TTL (not required). // Minimum TTL (not required).
int min_ttl; int min_ttl;
if (config_setting_lookup_int(filter, "min_ttl", &min_ttl)) if (config_setting_lookup_int(filter, "min_ttl", &min_ttl))
{ {
cfg->filters[i].min_ttl = min_ttl; cfg->filters[i].min_ttl = (uint8_t)min_ttl;
} }
// Maximum TTL (not required). // Maximum TTL (not required).
@@ -206,7 +191,7 @@ int ReadConfig(struct config_map *cfg)
if (config_setting_lookup_int(filter, "max_ttl", &max_ttl)) if (config_setting_lookup_int(filter, "max_ttl", &max_ttl))
{ {
cfg->filters[i].max_ttl = max_ttl; cfg->filters[i].max_ttl = (uint8_t)max_ttl;
} }
// Minimum length (not required). // Minimum length (not required).
@@ -230,7 +215,7 @@ int ReadConfig(struct config_map *cfg)
if (config_setting_lookup_int(filter, "tos", &tos)) if (config_setting_lookup_int(filter, "tos", &tos))
{ {
cfg->filters[i].tos = tos; cfg->filters[i].tos = (uint8_t)tos;
} }
// Payload match. // Payload match.
@@ -262,10 +247,14 @@ int ReadConfig(struct config_map *cfg)
// Check TCP options. // Check TCP options.
if (tcpopts != NULL) if (tcpopts != NULL)
{ {
for (uint16_t j = 0; j < config_setting_length(tcpopts); j++)
{
config_setting_t* tcp = config_setting_get_elem(tcpopts, j);
// Enabled. // Enabled.
int enabled; int enabled;
if (config_setting_lookup_bool(tcpopts, "enabled", &enabled)) if (config_setting_lookup_bool(tcp, "enabled", &enabled))
{ {
cfg->filters[i].tcpopts.enabled = enabled; cfg->filters[i].tcpopts.enabled = enabled;
} }
@@ -273,7 +262,7 @@ int ReadConfig(struct config_map *cfg)
// Source port. // Source port.
long long sport; long long sport;
if (config_setting_lookup_int64(tcpopts, "sport", &sport)) if (config_setting_lookup_int64(tcp, "sport", &sport))
{ {
cfg->filters[i].tcpopts.sport = (uint16_t)sport; cfg->filters[i].tcpopts.sport = (uint16_t)sport;
} }
@@ -281,7 +270,7 @@ int ReadConfig(struct config_map *cfg)
// Destination port. // Destination port.
long long dport; long long dport;
if (config_setting_lookup_int64(tcpopts, "dport", &dport)) if (config_setting_lookup_int64(tcp, "dport", &dport))
{ {
cfg->filters[i].tcpopts.dport = (uint16_t)dport; cfg->filters[i].tcpopts.dport = (uint16_t)dport;
} }
@@ -289,7 +278,7 @@ int ReadConfig(struct config_map *cfg)
// URG flag. // URG flag.
int urg; int urg;
if (config_setting_lookup_bool(tcpopts, "urg", &urg)) if (config_setting_lookup_bool(tcp, "urg", &urg))
{ {
cfg->filters[i].tcpopts.urg = urg; cfg->filters[i].tcpopts.urg = urg;
} }
@@ -297,7 +286,7 @@ int ReadConfig(struct config_map *cfg)
// ACK flag. // ACK flag.
int ack; int ack;
if (config_setting_lookup_bool(tcpopts, "ack", &ack)) if (config_setting_lookup_bool(tcp, "ack", &ack))
{ {
cfg->filters[i].tcpopts.ack = ack; cfg->filters[i].tcpopts.ack = ack;
} }
@@ -305,7 +294,7 @@ int ReadConfig(struct config_map *cfg)
// RST flag. // RST flag.
int rst; int rst;
if (config_setting_lookup_bool(tcpopts, "rst", &rst)) if (config_setting_lookup_bool(tcp, "rst", &rst))
{ {
cfg->filters[i].tcpopts.rst = rst; cfg->filters[i].tcpopts.rst = rst;
} }
@@ -313,7 +302,7 @@ int ReadConfig(struct config_map *cfg)
// PSH flag. // PSH flag.
int psh; int psh;
if (config_setting_lookup_bool(tcpopts, "psh", &psh)) if (config_setting_lookup_bool(tcp, "psh", &psh))
{ {
cfg->filters[i].tcpopts.psh = psh; cfg->filters[i].tcpopts.psh = psh;
} }
@@ -321,7 +310,7 @@ int ReadConfig(struct config_map *cfg)
// SYN flag. // SYN flag.
int syn; int syn;
if (config_setting_lookup_bool(tcpopts, "syn", &syn)) if (config_setting_lookup_bool(tcp, "syn", &syn))
{ {
cfg->filters[i].tcpopts.syn = syn; cfg->filters[i].tcpopts.syn = syn;
} }
@@ -329,11 +318,12 @@ int ReadConfig(struct config_map *cfg)
// FIN flag. // FIN flag.
int fin; int fin;
if (config_setting_lookup_bool(tcpopts, "fin", &fin)) if (config_setting_lookup_bool(tcp, "fin", &fin))
{ {
cfg->filters[i].tcpopts.fin = fin; cfg->filters[i].tcpopts.fin = fin;
} }
} }
}
// Check for UDP options. // Check for UDP options.
config_setting_t* udpopts = config_setting_lookup(filter, "udpopts"); config_setting_t* udpopts = config_setting_lookup(filter, "udpopts");
@@ -341,10 +331,14 @@ int ReadConfig(struct config_map *cfg)
// Check UDP options. // Check UDP options.
if (udpopts != NULL) if (udpopts != NULL)
{ {
for (uint16_t j = 0; j < config_setting_length(udpopts); j++)
{
config_setting_t* udp = config_setting_get_elem(udpopts, j);
// Enabled. // Enabled.
int enabled; int enabled;
if (config_setting_lookup_bool(udpopts, "enabled", &enabled)) if (config_setting_lookup_bool(udp, "enabled", &enabled))
{ {
cfg->filters[i].udpopts.enabled = enabled; cfg->filters[i].udpopts.enabled = enabled;
} }
@@ -352,7 +346,7 @@ int ReadConfig(struct config_map *cfg)
// Source port. // Source port.
long long sport; long long sport;
if (config_setting_lookup_int64(udpopts, "sport", &sport)) if (config_setting_lookup_int64(udp, "sport", &sport))
{ {
cfg->filters[i].udpopts.sport = (uint16_t)sport; cfg->filters[i].udpopts.sport = (uint16_t)sport;
} }
@@ -360,11 +354,12 @@ int ReadConfig(struct config_map *cfg)
// Destination port. // Destination port.
long long dport; long long dport;
if (config_setting_lookup_int64(udpopts, "dport", &dport)) if (config_setting_lookup_int64(udp, "dport", &dport))
{ {
cfg->filters[i].udpopts.dport = (uint16_t)dport; cfg->filters[i].udpopts.dport = (uint16_t)dport;
} }
} }
}
// Check for ICMP options. // Check for ICMP options.
config_setting_t* icmpopts = config_setting_lookup(filter, "icmpopts"); config_setting_t* icmpopts = config_setting_lookup(filter, "icmpopts");
@@ -372,10 +367,14 @@ int ReadConfig(struct config_map *cfg)
// Check UDP options. // Check UDP options.
if (icmpopts != NULL) if (icmpopts != NULL)
{ {
for (uint16_t j = 0; j < config_setting_length(icmpopts); j++)
{
config_setting_t* icmp = config_setting_get_elem(icmpopts, j);
// Enabled. // Enabled.
int enabled; int enabled;
if (config_setting_lookup_bool(icmpopts, "enabled", &enabled)) if (config_setting_lookup_bool(icmp, "enabled", &enabled))
{ {
cfg->filters[i].icmpopts.enabled = enabled; cfg->filters[i].icmpopts.enabled = enabled;
} }
@@ -383,17 +382,18 @@ int ReadConfig(struct config_map *cfg)
// ICMP code. // ICMP code.
int code; int code;
if (config_setting_lookup_int(icmpopts, "code", &code)) if (config_setting_lookup_int(icmp, "code", &code))
{ {
cfg->filters[i].icmpopts.code = code; cfg->filters[i].icmpopts.code = (uint8_t)code;
} }
// ICMP type. // ICMP type.
int type; int type;
if (config_setting_lookup_int(icmpopts, "type", &type)) if (config_setting_lookup_int(icmp, "type", &type))
{ {
cfg->filters[i].icmpopts.type = type; cfg->filters[i].icmpopts.type = (uint8_t)type;
}
} }
} }

View File

@@ -46,7 +46,6 @@ struct filter
uint32_t srcIP; uint32_t srcIP;
uint32_t dstIP; uint32_t dstIP;
uint8_t protocol;
uint8_t min_ttl; uint8_t min_ttl;
uint8_t max_ttl; uint8_t max_ttl;

View File

@@ -3,10 +3,10 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <getopt.h>
#include <signal.h> #include <signal.h>
#include <inttypes.h> #include <inttypes.h>
#include <time.h> #include <time.h>
#include <getopt.h>
#include <net/if.h> #include <net/if.h>
#include <linux/if_link.h> #include <linux/if_link.h>
@@ -45,7 +45,7 @@ void parse_command_line(int argc, char *argv[])
{ {
int c; int c;
while ((c = getopt_long(argc, argv, "c:hl", opts, 0)) != -1) while ((c = getopt_long(argc, argv, "c:lh", opts, NULL)) != -1)
{ {
switch (c) switch (c)
{ {
@@ -54,10 +54,23 @@ void parse_command_line(int argc, char *argv[])
break; break;
case 'l':
list = 1;
break;
case 'h':
help = 1;
break;
case '?': case '?':
fprintf(stderr, "Missing argument option...\n"); fprintf(stderr, "Missing argument option...\n");
break; break;
default:
break;
} }
} }
} }
@@ -241,6 +254,38 @@ static int xdp_attach(int ifindex, uint32_t *xdp_flags, int prog_fd)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
void SetConfigDefaultsX(struct config_map *cfg)
{
cfg->updateTime = 0;
cfg->interface = "eth0";
for (uint16_t i = 0; i < MAX_FILTERS; i++)
{
cfg->filters[i].enabled = 0;
cfg->filters[i].action = 0;
cfg->filters[i].srcIP = 0;
cfg->filters[i].dstIP = 0;
cfg->filters[i].min_id = 0;
cfg->filters[i].max_id = 4294967295;
cfg->filters[i].min_len = 0;
cfg->filters[i].max_len = 65535;
cfg->filters[i].min_ttl = 0;
cfg->filters[i].max_ttl = 255;
cfg->filters[i].tos = 0;
cfg->filters[i].tcpopts.enabled = 0;
cfg->filters[i].udpopts.enabled = 0;
cfg->filters[i].icmpopts.enabled = 0;
for (uint16_t j = 0; i < MAX_PCKT_LENGTH; i++)
{
cfg->filters[i].payloadMatch[j] = 0;
}
cfg->filters[i].payloadLen = 0;
}
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// Parse the command line. // Parse the command line.
@@ -254,7 +299,7 @@ int main(int argc, char *argv[])
"--list -l => Print config details including filters (this will exit program after done).\n" \ "--list -l => Print config details including filters (this will exit program after done).\n" \
"--help -h => Print help menu.\n"); "--help -h => Print help menu.\n");
exit(EXIT_SUCCESS); return EXIT_SUCCESS;
} }
// Check for --config argument. // Check for --config argument.
@@ -265,85 +310,85 @@ int main(int argc, char *argv[])
} }
// Initialize config. // Initialize config.
struct config_map conf; struct config_map *conf = malloc(sizeof(struct config_map));
SetConfigDefaults(&conf); SetConfigDefaults(conf);
// Create last updated variable. // Create last updated variable.
time_t lastUpdated = time(NULL); time_t lastUpdated = time(NULL);
// Update config. // Update config.
update_config(&conf, configFile); update_config(conf, configFile);
// Check for list option. // Check for list option.
if (list) if (list)
{ {
fprintf(stdout, "Details:\n"); fprintf(stdout, "Details:\n");
fprintf(stdout, "Interface Name => %s\n", conf.interface); fprintf(stdout, "Interface Name => %s\n", conf->interface);
fprintf(stdout, "Update Time => %" PRIu16 "\n", conf.updateTime); fprintf(stdout, "Update Time => %" PRIu16 "\n", conf->updateTime);
fprintf(stdout, "Filters Count => %" PRIu16 "\n\n", conf.filterCount); fprintf(stdout, "Filters Count => %" PRIu16 "\n\n", conf->filterCount);
for (uint16_t i = 0; i < conf.filterCount; i++) for (uint16_t i = 0; i < conf->filterCount; i++)
{ {
fprintf(stdout, "Filter #" PRIu16 ":\n"); fprintf(stdout, "Filter #%" PRIu16 ":\n", (i + 1));
// Main. // Main.
fprintf(stdout, "Enabled => %" PRIu8 "\n", conf.filters[i].enabled); fprintf(stdout, "Enabled => %" PRIu8 "\n", conf->filters[i].enabled);
fprintf(stdout, "Action => %" PRIu8 " (0 = Block, 1 = Allow).\n", conf.filters[i].action); fprintf(stdout, "Action => %" PRIu8 " (0 = Block, 1 = Allow).\n", conf->filters[i].action);
// IP addresses. // IP addresses.
struct sockaddr_in sin; struct sockaddr_in sin;
sin.sin_addr.s_addr = conf.filters[i].srcIP; sin.sin_addr.s_addr = conf->filters[i].srcIP;
fprintf(stdout, "Source IP => %s\n", inet_ntoa(sin.sin_addr)); fprintf(stdout, "Source IP => %s\n", inet_ntoa(sin.sin_addr));
struct sockaddr_in din; struct sockaddr_in din;
din.sin_addr.s_addr = conf.filters[i].dstIP; din.sin_addr.s_addr = conf->filters[i].dstIP;
fprintf(stdout, "Destination IP => %s\n", inet_ntoa(din.sin_addr)); fprintf(stdout, "Destination IP => %s\n", inet_ntoa(din.sin_addr));
// Other IP header information. // Other IP header information.
fprintf(stdout, "Max Length => %" PRIu16 "\n", conf.filters[i].max_len); fprintf(stdout, "Max Length => %" PRIu16 "\n", conf->filters[i].max_len);
fprintf(stdout, "Min Length => %" PRIu16 "\n", conf.filters[i].min_len); fprintf(stdout, "Min Length => %" PRIu16 "\n", conf->filters[i].min_len);
fprintf(stdout, "Max TTL => %" PRIu8 "\n", conf.filters[i].max_ttl); fprintf(stdout, "Max TTL => %" PRIu8 "\n", conf->filters[i].max_ttl);
fprintf(stdout, "Min TTL => %" PRIu8 "\n", conf.filters[i].min_ttl); fprintf(stdout, "Min TTL => %" PRIu8 "\n", conf->filters[i].min_ttl);
fprintf(stdout, "Max ID => %" PRIu32 "\n", conf.filters[i].max_id); fprintf(stdout, "Max ID => %" PRIu32 "\n", conf->filters[i].max_id);
fprintf(stdout, "Min ID => %" PRIu32 "\n", conf.filters[i].min_id); fprintf(stdout, "Min ID => %" PRIu32 "\n", conf->filters[i].min_id);
fprintf(stdout, "TOS => %" PRIu8 "\n", conf.filters[i].tos); fprintf(stdout, "TOS => %" PRIu8 "\n\n", conf->filters[i].tos);
// TCP Options. // TCP Options.
fprintf(stdout, "TCP Enabled => %" PRIu8 "\n", conf.filters[i].tcpopts.enabled); fprintf(stdout, "TCP Enabled => %" PRIu8 "\n", conf->filters[i].tcpopts.enabled);
fprintf(stdout, "TCP Source Port => %" PRIu16 "\n", conf.filters[i].tcpopts.sport); fprintf(stdout, "TCP Source Port => %" PRIu16 "\n", conf->filters[i].tcpopts.sport);
fprintf(stdout, "TCP Destination Port => %" PRIu16 "\n", conf.filters[i].tcpopts.dport); fprintf(stdout, "TCP Destination Port => %" PRIu16 "\n", conf->filters[i].tcpopts.dport);
fprintf(stdout, "TCP URG Flag => %" PRIu8 "\n", conf.filters[i].tcpopts.urg); fprintf(stdout, "TCP URG Flag => %" PRIu8 "\n", conf->filters[i].tcpopts.urg);
fprintf(stdout, "TCP ACK Flag => %" PRIu8 "\n", conf.filters[i].tcpopts.ack); fprintf(stdout, "TCP ACK Flag => %" PRIu8 "\n", conf->filters[i].tcpopts.ack);
fprintf(stdout, "TCP RST Flag => %" PRIu8 "\n", conf.filters[i].tcpopts.rst); fprintf(stdout, "TCP RST Flag => %" PRIu8 "\n", conf->filters[i].tcpopts.rst);
fprintf(stdout, "TCP PSH Flag => %" PRIu8 "\n", conf.filters[i].tcpopts.psh); fprintf(stdout, "TCP PSH Flag => %" PRIu8 "\n", conf->filters[i].tcpopts.psh);
fprintf(stdout, "TCP SYN Flag => %" PRIu8 "\n", conf.filters[i].tcpopts.syn); fprintf(stdout, "TCP SYN Flag => %" PRIu8 "\n", conf->filters[i].tcpopts.syn);
fprintf(stdout, "TCP FIN Flag => %" PRIu8 "\n", conf.filters[i].tcpopts.fin); fprintf(stdout, "TCP FIN Flag => %" PRIu8 "\n\n", conf->filters[i].tcpopts.fin);
// UDP Options. // UDP Options.
fprintf(stdout, "UDP Enabled => %" PRIu8 "\n", conf.filters[i].udpopts.enabled); fprintf(stdout, "UDP Enabled => %" PRIu8 "\n", conf->filters[i].udpopts.enabled);
fprintf(stdout, "UDP Source Port => %" PRIu16 "\n", conf.filters[i].udpopts.sport); fprintf(stdout, "UDP Source Port => %" PRIu16 "\n", conf->filters[i].udpopts.sport);
fprintf(stdout, "UDP Destination Port => %" PRIu16 "\n", conf.filters[i].udpopts.dport); fprintf(stdout, "UDP Destination Port => %" PRIu16 "\n\n", conf->filters[i].udpopts.dport);
// ICMP Options. // ICMP Options.
fprintf(stdout, "ICMP Enabled => %" PRIu8 "\n", conf.filters[i].icmpopts.enabled); fprintf(stdout, "ICMP Enabled => %" PRIu8 "\n", conf->filters[i].icmpopts.enabled);
fprintf(stdout, "ICMP Code => %" PRIu8 "\n", conf.filters[i].icmpopts.code); fprintf(stdout, "ICMP Code => %" PRIu8 "\n", conf->filters[i].icmpopts.code);
fprintf(stdout, "ICMP Type => %" PRIu8 "\n", conf.filters[i].icmpopts.type); fprintf(stdout, "ICMP Type => %" PRIu8 "\n", conf->filters[i].icmpopts.type);
fprintf(stdout, "\n"); fprintf(stdout, "\n\n");
} }
exit(EXIT_SUCCESS); return EXIT_SUCCESS;
} }
// Get device. // Get device.
int dev; int dev;
if ((dev = if_nametoindex(conf.interface)) < 0) if ((dev = if_nametoindex(conf->interface)) < 0)
{ {
fprintf(stderr, "Error finding device %s.\n", conf.interface); fprintf(stderr, "Error finding device %s.\n", conf->interface);
exit(EXIT_FAILURE); return EXIT_FAILURE;
} }
// XDP variables. // XDP variables.
@@ -360,13 +405,13 @@ int main(int argc, char *argv[])
{ {
fprintf(stderr, "Error loading eBPF object file. File name => %s.\n", filename); fprintf(stderr, "Error loading eBPF object file. File name => %s.\n", filename);
exit(EXIT_FAILURE); return EXIT_FAILURE;
} }
// Attach XDP program to device. // Attach XDP program to device.
if (xdp_attach(dev, &xdpflags, prog_fd) != 0) if (xdp_attach(dev, &xdpflags, prog_fd) != 0)
{ {
exit(EXIT_FAILURE); return EXIT_FAILURE;
} }
// Check for valid maps. // Check for valid maps.
@@ -374,14 +419,14 @@ int main(int argc, char *argv[])
{ {
fprintf(stderr, "Error finding 'filters_map' BPF map\n"); fprintf(stderr, "Error finding 'filters_map' BPF map\n");
exit(EXIT_FAILURE); return EXIT_FAILURE;
} }
if (count_map_fd < 0) if (count_map_fd < 0)
{ {
fprintf(stderr, "Error finding 'count_map' BPF map.\n"); fprintf(stderr, "Error finding 'count_map' BPF map.\n");
exit(EXIT_FAILURE); return EXIT_FAILURE;
} }
// Signal. // Signal.
@@ -393,13 +438,13 @@ int main(int argc, char *argv[])
time_t curTime = time(NULL); time_t curTime = time(NULL);
// Check for auto-update. // Check for auto-update.
if (conf.updateTime > 0 && (curTime - lastUpdated) > conf.updateTime) if (conf->updateTime > 0 && (curTime - lastUpdated) > conf->updateTime)
{ {
// Update config. // Update config.
update_config(&conf, configFile); update_config(conf, configFile);
// Update BPF maps. // Update BPF maps.
update_BPF(&conf); update_BPF(conf);
// Update last updated variable. // Update last updated variable.
lastUpdated = time(NULL); lastUpdated = time(NULL);
@@ -411,11 +456,14 @@ int main(int argc, char *argv[])
// Detach XDP program. // Detach XDP program.
if (xdp_detach(dev, xdpflags) != 0) if (xdp_detach(dev, xdpflags) != 0)
{ {
fprintf(stderr, "Error removing XDP program from device %s\n", conf.interface); fprintf(stderr, "Error removing XDP program from device %s\n", conf->interface);
exit(EXIT_FAILURE); return EXIT_FAILURE;
} }
// Free config.
free(conf);
// Exit program successfully. // Exit program successfully.
exit(EXIT_SUCCESS); return EXIT_SUCCESS;
} }