From 4e7c563274a3651d84dc7d2b13707fcd983b5755 Mon Sep 17 00:00:00 2001 From: Christian Deacon Date: Sun, 23 Feb 2025 07:15:12 -0500 Subject: [PATCH] Add better error handling to loader. --- src/loader/prog.c | 34 ++++++++---- src/loader/utils/config.c | 107 ++++++++++++++++++++------------------ src/loader/utils/stats.h | 2 +- src/loader/utils/xdp.c | 5 +- 4 files changed, 82 insertions(+), 66 deletions(-) diff --git a/src/loader/prog.c b/src/loader/prog.c index d41701c..ad0c931 100644 --- a/src/loader/prog.c +++ b/src/loader/prog.c @@ -22,6 +22,8 @@ struct stat conf_stat; int main(int argc, char *argv[]) { + int ret; + // Parse the command line. cmdline_t cmd = {0}; cmd.cfgfile = CONFIG_DEFAULT_PATH; @@ -41,7 +43,7 @@ int main(int argc, char *argv[]) if (setrlimit(RLIMIT_MEMLOCK, &rl)) { - fprintf(stderr, "Error setting rlimit. Please make sure this program is ran as root!\n"); + fprintf(stderr, "[ERROR] Failed to raise rlimit. Please make sure this program is ran as root!\n"); return EXIT_FAILURE; } @@ -52,7 +54,12 @@ int main(int argc, char *argv[]) SetCfgDefaults(&cfg); // Load config. - LoadConfig(&cfg, cmd.cfgfile); + if ((ret = LoadConfig(&cfg, cmd.cfgfile)) != 0) + { + fprintf(stderr, "[ERROR] Failed to load config from file system (%s)(%d).\n", cmd.cfgfile, ret); + + return EXIT_FAILURE; + } // Check for list option. if (cmd.list) @@ -67,7 +74,7 @@ int main(int argc, char *argv[]) if (ifidx < 0) { - fprintf(stderr, "Error finding device %s.\n", cfg.interface); + fprintf(stderr, "[ERROR] Failed to retrieve index of interface '%s'.\n", cfg.interface); return EXIT_FAILURE; } @@ -77,15 +84,15 @@ int main(int argc, char *argv[]) if (prog == NULL) { - fprintf(stderr, "Error loading eBPF object file. File name => %s.\n", XDP_OBJ_PATH); + fprintf(stderr, "[ERROR] Failed to load eBPF object file. Object path => %s.\n", XDP_OBJ_PATH); return EXIT_FAILURE; } // Attach XDP program. - if (AttachXdp(prog, ifidx, 0, &cmd)) + if ((ret = AttachXdp(prog, ifidx, 0, &cmd)) != 0) { - fprintf(stderr, "Error attaching XDP program.\n"); + fprintf(stderr, "[ERROR] Failed to attach XDP program to interface '%s' (%d).\n", cfg.interface, ret); return EXIT_FAILURE; } @@ -96,7 +103,7 @@ int main(int argc, char *argv[]) // Check for valid maps. if (filters_map < 0) { - fprintf(stderr, "Error finding 'filters_map' BPF map.\n"); + fprintf(stderr, "[ERROR] Failed to find 'filters_map' BPF map.\n"); return EXIT_FAILURE; } @@ -105,7 +112,7 @@ int main(int argc, char *argv[]) if (stats_map < 0) { - fprintf(stderr, "Error finding 'stats_map' BPF map.\n"); + fprintf(stderr, "[ERROR] Failed to find 'stats_map' BPF map.\n"); return EXIT_FAILURE; } @@ -148,7 +155,10 @@ int main(int argc, char *argv[]) free(cfg.interface); // Update config. - LoadConfig(&cfg, cmd.cfgfile); + if ((ret = LoadConfig(&cfg, cmd.cfgfile)) != 0) + { + fprintf(stderr, "[WARNING] Failed to load config after update check (%d)\n", ret); + } // Update BPF maps. UpdateFilters(filters_map, &cfg); @@ -166,7 +176,7 @@ int main(int argc, char *argv[]) { if (CalculateStats(stats_map, cpus)) { - fprintf(stderr, "Error calculating packet stats. Stats map FD => %d.\n", stats_map); + fprintf(stderr, "[WARNING] Failed to calculate packet stats. Stats map FD => %d.\n", stats_map); } } @@ -178,7 +188,9 @@ int main(int argc, char *argv[]) // Detach XDP program. if (AttachXdp(prog, ifidx, 1, &cmd)) { - fprintf(stderr, "Failed to detach XDP program from interface '%s'.\n", cfg.interface); + fprintf(stderr, "[ERROR] Failed to detach XDP program from interface '%s'.\n", cfg.interface); + + return EXIT_FAILURE; } fprintf(stdout, "Cleaned up and exiting...\n"); diff --git a/src/loader/utils/config.c b/src/loader/utils/config.c index bffec7c..faea308 100644 --- a/src/loader/utils/config.c +++ b/src/loader/utils/config.c @@ -10,16 +10,16 @@ static FILE *file; * @param cfg A pointer to the config structure. * @param cfg_file The path to the config file. * - * @return 0 on success or -1 on error. + * @return 0 on success or 1 on error. */ int LoadConfig(config__t *cfg, char *cfg_file) { // Open config file. if (OpenCfg(cfg_file) != 0) { - fprintf(stderr, "Error opening filters file: %s\n", cfg_file); + fprintf(stderr, "Error opening config file.\n"); - return -1; + return EXIT_FAILURE; } SetCfgDefaults(cfg); @@ -29,12 +29,12 @@ int LoadConfig(config__t *cfg, char *cfg_file) // Read config and check for errors. if (ReadCfg(cfg) != 0) { - fprintf(stderr, "Error reading filters file.\n"); + fprintf(stderr, "Error reading config file.\n"); - return -1; + return EXIT_FAILURE; } - return 0; + return EXIT_SUCCESS; } /** @@ -165,7 +165,7 @@ int ReadCfg(config__t *cfg) config_destroy(&conf); - return 1; + return EXIT_FAILURE; } // Get interface. @@ -177,7 +177,7 @@ int ReadCfg(config__t *cfg) config_destroy(&conf); - return 1; + return EXIT_FAILURE; } cfg->interface = strdup(interface); @@ -534,7 +534,7 @@ int ReadCfg(config__t *cfg) config_destroy(&conf); - return 0; + return EXIT_SUCCESS; } /** @@ -546,10 +546,13 @@ int ReadCfg(config__t *cfg) */ void PrintConfig(config__t* cfg) { - fprintf(stdout, "Current Settings:\n"); - fprintf(stdout, "Interface Name => %s\n", cfg->interface); - fprintf(stdout, "Update Time => %d\n", cfg->updatetime); - fprintf(stdout, "Stdout Update Time => %d\n\n", cfg->stdout_update_time); + fprintf(stdout, "Printing config...\n"); + fprintf(stdout, "\tGeneral Settings\n"); + fprintf(stdout, "\t\tInterface Name => %s\n", cfg->interface); + fprintf(stdout, "\t\tUpdate Time => %d\n", cfg->updatetime); + fprintf(stdout, "\t\tStdout Update Time => %d\n\n", cfg->stdout_update_time); + + fprintf(stdout, "\tFiltes\n"); for (int i = 0; i < MAX_FILTERS; i++) { @@ -560,26 +563,26 @@ void PrintConfig(config__t* cfg) break; } - fprintf(stdout, "Filter #%d:\n", (i + 1)); + fprintf(stdout, "\t\tFilter #%d:\n", (i + 1)); // Main. - fprintf(stdout, "\tID => %d\n", filter->id); - fprintf(stdout, "\tEnabled => %d\n", filter->enabled); - fprintf(stdout, "\tAction => %d (0 = Block, 1 = Allow).\n\n", filter->action); + fprintf(stdout, "\t\t\tID => %d\n", filter->id); + fprintf(stdout, "\t\t\tEnabled => %d\n", filter->enabled); + fprintf(stdout, "\t\t\tAction => %d (0 = Block, 1 = Allow).\n\n", filter->action); // IP Options. - fprintf(stdout, "\tIP Options\n"); + fprintf(stdout, "\t\t\tIP Options\n"); // IP addresses require additional code for string printing. struct sockaddr_in sin; sin.sin_addr.s_addr = filter->src_ip; - fprintf(stdout, "\t\tSource IPv4 => %s\n", inet_ntoa(sin.sin_addr)); - fprintf(stdout, "\t\tSource CIDR => %d\n", filter->src_cidr); + fprintf(stdout, "\t\t\t\tSource IPv4 => %s\n", inet_ntoa(sin.sin_addr)); + fprintf(stdout, "\t\t\t\tSource CIDR => %d\n", filter->src_cidr); struct sockaddr_in din; din.sin_addr.s_addr = filter->dst_ip; - fprintf(stdout, "\t\tDestination IPv4 => %s\n", inet_ntoa(din.sin_addr)); - fprintf(stdout, "\t\tDestination CIDR => %d\n", filter->dst_cidr); + fprintf(stdout, "\t\t\t\tDestination IPv4 => %s\n", inet_ntoa(din.sin_addr)); + fprintf(stdout, "\t\t\t\tDestination CIDR => %d\n", filter->dst_cidr); struct in6_addr sin6; memcpy(&sin6, &filter->src_ip6, sizeof(sin6)); @@ -587,7 +590,7 @@ void PrintConfig(config__t* cfg) char srcipv6[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &sin6, srcipv6, sizeof(srcipv6)); - fprintf(stdout, "\t\tSource IPv6 => %s\n", srcipv6); + fprintf(stdout, "\t\t\t\tSource IPv6 => %s\n", srcipv6); struct in6_addr din6; memcpy(&din6, &filter->dst_ip6, sizeof(din6)); @@ -595,43 +598,43 @@ void PrintConfig(config__t* cfg) char dstipv6[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &din6, dstipv6, sizeof(dstipv6)); - fprintf(stdout, "\t\tDestination IPv6 => %s\n", dstipv6); + fprintf(stdout, "\t\t\t\tDestination IPv6 => %s\n", dstipv6); // Other IP header information. - fprintf(stdout, "\t\tMax Length => %d\n", filter->max_len); - fprintf(stdout, "\t\tMin Length => %d\n", filter->min_len); - fprintf(stdout, "\t\tMax TTL => %d\n", filter->max_ttl); - fprintf(stdout, "\t\tMin TTL => %d\n", filter->min_ttl); - fprintf(stdout, "\t\tTOS => %d\n", filter->tos); - fprintf(stdout, "\t\tPPS => %llu\n", filter->pps); - fprintf(stdout, "\t\tBPS => %llu\n", filter->bps); - fprintf(stdout, "\t\tBlock Time => %llu\n\n", filter->blocktime); + fprintf(stdout, "\t\t\t\tMax Length => %d\n", filter->max_len); + fprintf(stdout, "\t\t\t\tMin Length => %d\n", filter->min_len); + fprintf(stdout, "\t\t\t\tMax TTL => %d\n", filter->max_ttl); + fprintf(stdout, "\t\t\t\tMin TTL => %d\n", filter->min_ttl); + fprintf(stdout, "\t\t\t\tTOS => %d\n", filter->tos); + fprintf(stdout, "\t\t\t\tPPS => %llu\n", filter->pps); + fprintf(stdout, "\t\t\t\tBPS => %llu\n", filter->bps); + fprintf(stdout, "\t\t\t\tBlock Time => %llu\n\n", filter->blocktime); // TCP Options. - fprintf(stdout, "\tTCP Options\n"); - fprintf(stdout, "\t\tTCP Enabled => %d\n", filter->tcpopts.enabled); - fprintf(stdout, "\t\tTCP Source Port => %d\n", filter->tcpopts.sport); - fprintf(stdout, "\t\tTCP Destination Port => %d\n", filter->tcpopts.dport); - fprintf(stdout, "\t\tTCP URG Flag => %d\n", filter->tcpopts.urg); - fprintf(stdout, "\t\tTCP ACK Flag => %d\n", filter->tcpopts.ack); - fprintf(stdout, "\t\tTCP RST Flag => %d\n", filter->tcpopts.rst); - fprintf(stdout, "\t\tTCP PSH Flag => %d\n", filter->tcpopts.psh); - fprintf(stdout, "\t\tTCP SYN Flag => %d\n", filter->tcpopts.syn); - fprintf(stdout, "\t\tTCP FIN Flag => %d\n", filter->tcpopts.fin); - fprintf(stdout, "\t\tTCP ECE Flag => %d\n", filter->tcpopts.ece); - fprintf(stdout, "\t\tTCP CWR Flag => %d\n\n", filter->tcpopts.cwr); + fprintf(stdout, "\t\t\tTCP Options\n"); + fprintf(stdout, "\t\t\t\tTCP Enabled => %d\n", filter->tcpopts.enabled); + fprintf(stdout, "\t\t\t\tTCP Source Port => %d\n", filter->tcpopts.sport); + fprintf(stdout, "\t\t\t\tTCP Destination Port => %d\n", filter->tcpopts.dport); + fprintf(stdout, "\t\t\t\tTCP URG Flag => %d\n", filter->tcpopts.urg); + fprintf(stdout, "\t\t\t\tTCP ACK Flag => %d\n", filter->tcpopts.ack); + fprintf(stdout, "\t\t\t\tTCP RST Flag => %d\n", filter->tcpopts.rst); + fprintf(stdout, "\t\t\t\tTCP PSH Flag => %d\n", filter->tcpopts.psh); + fprintf(stdout, "\t\t\t\tTCP SYN Flag => %d\n", filter->tcpopts.syn); + fprintf(stdout, "\t\t\t\tTCP FIN Flag => %d\n", filter->tcpopts.fin); + fprintf(stdout, "\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); // UDP Options. - fprintf(stdout, "\tUDP Options\n"); - fprintf(stdout, "\t\tUDP Enabled => %d\n", filter->udpopts.enabled); - fprintf(stdout, "\t\tUDP Source Port => %d\n", filter->udpopts.sport); - fprintf(stdout, "\t\tUDP Destination Port => %d\n\n", filter->udpopts.dport); + fprintf(stdout, "\t\t\tUDP Options\n"); + fprintf(stdout, "\t\t\t\tUDP Enabled => %d\n", filter->udpopts.enabled); + fprintf(stdout, "\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); // ICMP Options. - fprintf(stdout, "\tICMP Options\n"); - fprintf(stdout, "\t\tICMP Enabled => %d\n", filter->icmpopts.enabled); - fprintf(stdout, "\t\tICMP Code => %d\n", filter->icmpopts.code); - fprintf(stdout, "\t\tICMP Type => %d\n", filter->icmpopts.type); + fprintf(stdout, "\t\t\tICMP Options\n"); + fprintf(stdout, "\t\t\t\tICMP Enabled => %d\n", filter->icmpopts.enabled); + fprintf(stdout, "\t\t\t\tICMP Code => %d\n", filter->icmpopts.code); + fprintf(stdout, "\t\t\t\tICMP Type => %d\n", filter->icmpopts.type); fprintf(stdout, "\n\n"); } diff --git a/src/loader/utils/stats.h b/src/loader/utils/stats.h index 02e607c..5330910 100644 --- a/src/loader/utils/stats.h +++ b/src/loader/utils/stats.h @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/src/loader/utils/xdp.c b/src/loader/utils/xdp.c index e8a04aa..9f2cd31 100644 --- a/src/loader/utils/xdp.c +++ b/src/loader/utils/xdp.c @@ -166,6 +166,7 @@ int AttachXdp(struct xdp_program *prog, int ifidx, u8 detach, cmdline_t *cmd) void UpdateFilters(int filters_map, config__t *cfg) { int i; + int ret; // Loop through all filters and delete the map. We do this in the case rules were edited and were put out of order since the key doesn't uniquely map to a specific rule. for (i = 0; i < MAX_FILTERS; i++) @@ -194,9 +195,9 @@ void UpdateFilters(int filters_map, config__t *cfg) } // Attempt to update BPF map. - if (bpf_map_update_elem(filters_map, &i, &filter, BPF_ANY) == -1) + if ((ret = bpf_map_update_elem(filters_map, &i, &filter, BPF_ANY)) != 0) { - fprintf(stderr, "Error updating BPF item #%d\n", i); + fprintf(stderr, "[WARNING] Failed to update filter #%d due to BPF update error (%d).\n", i, ret); } } } \ No newline at end of file