From ea47a7a43587238f7c7a65838d24bb5aaefb0b13 Mon Sep 17 00:00:00 2001 From: Christian Deacon Date: Sun, 23 Feb 2025 06:34:37 -0500 Subject: [PATCH] Cleanup and organize a lot of Loader code. --- src/loader/prog.c | 464 ++++--------------------------------- src/loader/utils/cmdline.c | 2 +- src/loader/utils/config.c | 163 +++++++++++-- src/loader/utils/config.h | 5 + src/loader/utils/helpers.c | 32 ++- src/loader/utils/helpers.h | 8 +- 6 files changed, 226 insertions(+), 448 deletions(-) diff --git a/src/loader/prog.c b/src/loader/prog.c index 2441dea..c715a5b 100644 --- a/src/loader/prog.c +++ b/src/loader/prog.c @@ -1,440 +1,82 @@ #include #include #include -#include -#include #include -#include #include -#include + #include #include #include -#include #include -#include -#include - -#include -#include -#include - -#include #include #include +#include +#include #include -// Other variables. -static u8 cont = 1; -static int filtersmap = -1; -static int statsmap = -1; - -void SignalHndl(int tmp) -{ - cont = 0; -} - -/** - * Updates the filter's BPF map. - * - * @param cfg A pointer to the config structure. - * - * @return Void -*/ -void UpdateFilters(config__t *cfg) -{ - // 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 (u8 i = 0; i < MAX_FILTERS; i++) - { - u32 key = i; - - bpf_map_delete_elem(filtersmap, &key); - } - - // Add a filter to the filter maps. - for (u32 i = 0; i < MAX_FILTERS; i++) - { - // Check if we have a valid ID. - if (cfg->filters[i].id < 1) - { - break; - } - - // Create value array (max CPUs in size) since we're using a per CPU map. - filter_t filter[MAX_CPUS]; - memset(filter, 0, sizeof(filter)); - - for (int j = 0; j < MAX_CPUS; j++) - { - filter[j] = cfg->filters[i]; - } - - // Attempt to update BPF map. - if (bpf_map_update_elem(filtersmap, &i, &filter, BPF_ANY) == -1) - { - fprintf(stderr, "Error updating BPF item #%d\n", i); - } - } -} - -/** - * Loads the config on the file system. - * - * @param cfg A pointer to the config structure. - * @param cfgfile The path to the config file. - * - * @return 0 on success or -1 on error. -*/ -int LoadConfig(config__t *cfg, char *cfgfile) -{ - // Open config file. - if (OpenCfg(cfgfile) != 0) - { - fprintf(stderr, "Error opening filters file: %s\n", cfgfile); - - return -1; - } - - SetCfgDefaults(cfg); - - memset(cfg->filters, 0, sizeof(cfg->filters)); - - // Read config and check for errors. - if (ReadCfg(cfg) != 0) - { - fprintf(stderr, "Error reading filters file.\n"); - - return -1; - } - - return 0; -} - -/** - * Finds a BPF map's FD. - * - * @param prog A pointer to the XDP program structure. - * @param mapname The name of the map to retrieve. - * - * @return The map's FD. -*/ -int FindMapFd(struct xdp_program *prog, const char *mapname) -{ - int fd = -1; - - struct bpf_object *obj = xdp_program__bpf_obj(prog); - - if (obj == NULL) - { - fprintf(stderr, "Error finding BPF object from XDP program.\n"); - - goto out; - } - - struct bpf_map *map = bpf_object__find_map_by_name(obj, mapname); - - if (!map) - { - fprintf(stderr, "Error finding eBPF map: %s\n", mapname); - - goto out; - } - - fd = bpf_map__fd(map); - - out: - return fd; -} - -/** - * Loads a BPF object file. - * - * @param filename The path to the BPF object file. - * - * @return XDP program structure (pointer) or NULL. -*/ -struct xdp_program *LoadBpfObj(const char *filename) -{ - struct xdp_program *prog = xdp_program__open_file(filename, "xdp_prog", NULL); - - if (prog == NULL) - { - // The main function handles this error. - return NULL; - } - - return prog; -} - -/** - * Attempts to attach or detach (progfd = -1) a BPF/XDP program to an interface. - * - * @param prog A pointer to the XDP program structure. - * @param ifidx The index to the interface to attach to. - * @param detach If above 0, attempts to detach XDP program. - * @param cmd A pointer to a cmdline struct that includes command line arguments (mostly checking for offload/HW mode set). - * - * @return 0 on success and 1 on error. - */ -int AttachXdp(struct xdp_program *prog, int ifidx, u8 detach, cmdline_t *cmd) -{ - int err; - - u32 mode = XDP_MODE_NATIVE; - char *smode; - - smode = "DRV/native"; - - if (cmd->offload) - { - smode = "HW/offload"; - - mode = XDP_MODE_HW; - } - else if (cmd->skb) - { - smode = "SKB/generic"; - mode = XDP_MODE_SKB; - } - - u8 exit = 0; - - while (!exit) - { - // Try loading program with current mode. - int err; - - if (detach) - { - err = xdp_program__detach(prog, ifidx, mode, 0); - } - else - { - err = xdp_program__attach(prog, ifidx, mode, 0); - } - - if (err) - { - if (err) - { - fprintf(stderr, "Could not attach with mode %s (%s) (%d).\n", smode, strerror(-err), -err); - } - - // Decrease mode. - switch (mode) - { - case XDP_MODE_HW: - mode = XDP_MODE_NATIVE; - smode = "DRV/native"; - - break; - - case XDP_MODE_NATIVE: - mode = XDP_MODE_SKB; - smode = "SKB/generic"; - - break; - - case XDP_MODE_SKB: - // Exit loop. - exit = 1; - smode = NULL; - - break; - } - - // Retry. - continue; - } - - // Success, so break current loop. - break; - } - - // If exit is set to 1 or smode is NULL, it indicates full failure. - if (exit || smode == NULL) - { - fprintf(stderr, "Error attaching XDP program.\n"); - - return 1; - } - - fprintf(stdout, "Loaded XDP program on mode %s.\n", smode); - - return 0; -} - +int cont = 1; struct stat conf_stat; int main(int argc, char *argv[]) { // Parse the command line. - cmdline_t cmd = - { - .cfgfile = "/etc/xdpfw/xdpfw.conf", - .help = 0, - .list = 0, - .offload = 0 - }; + cmdline_t cmd = {0}; + cmd.cfgfile = CONFIG_DEFAULT_PATH; ParseCommandLine(&cmd, argc, argv); - // Check for help menu. + // Check for help. if (cmd.help) { - fprintf(stdout, "Usage:\n" \ - "--config -c => Config file location (default is /etc/xdpfw/xdpfw.conf).\n" \ - "--offload -o => Tries to load the XDP program in hardware/offload mode.\n" \ - "--skb -s => Force the XDP program to load with SKB mode instead of DRV.\n" \ - "--time -t => How long to run the program for in seconds before exiting. 0 or not set = infinite.\n" \ - "--list -l => Print config details including filters (this will exit program after done).\n" \ - "--help -h => Print help menu.\n"); + PrintHelpMenu(); return EXIT_SUCCESS; } // Raise RLimit. - struct rlimit rl = {RLIM_INFINITY, RLIM_INFINITY}; + struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; if (setrlimit(RLIMIT_MEMLOCK, &rl)) { - fprintf(stderr, "Error setting rlimit.\n"); + fprintf(stderr, "Error setting rlimit. Please make sure this program is ran as root!\n"); return EXIT_FAILURE; } - // Check for --config argument. - if (cmd.cfgfile == NULL) - { - // Assign default. - cmd.cfgfile = "/etc/xdpfw/xdpfw.conf"; - } - // Initialize config. config__t cfg = {0}; SetCfgDefaults(&cfg); - // Update config. + // Load config. LoadConfig(&cfg, cmd.cfgfile); // Check for list option. if (cmd.list) { - 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); - - for (uint16_t i = 0; i < MAX_FILTERS; i++) - { - filter_t *filter = &cfg.filters[i]; - - if (filter->id < 1) - { - break; - } - - fprintf(stdout, "Filter #%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); - - // IP Options. - fprintf(stdout, "\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); - - 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); - - struct in6_addr sin6; - memcpy(&sin6, &filter->src_ip6, sizeof(sin6)); - - char srcipv6[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &sin6, srcipv6, sizeof(srcipv6)); - - fprintf(stdout, "\t\tSource IPv6 => %s\n", srcipv6); - - struct in6_addr din6; - memcpy(&din6, &filter->dst_ip6, sizeof(din6)); - - char dstipv6[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &din6, dstipv6, sizeof(dstipv6)); - - fprintf(stdout, "\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); - - // 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); - - // 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); - - // 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, "\n\n"); - } + PrintConfig(&cfg); return EXIT_SUCCESS; } - // Get device. - int ifidx; + // Get interface index. + int ifidx = if_nametoindex(cfg.interface); - if ((ifidx = if_nametoindex(cfg.interface)) < 0) + if (ifidx < 0) { fprintf(stderr, "Error finding device %s.\n", cfg.interface); return EXIT_FAILURE; } - // XDP variables. - const char *filename = "/etc/xdpfw/xdp_prog.o"; - // Load BPF object. - struct xdp_program *prog = LoadBpfObj(filename); + struct xdp_program *prog = LoadBpfObj(XDP_OBJ_PATH); if (prog == NULL) { - fprintf(stderr, "Error loading eBPF object file. File name => %s.\n", filename); + fprintf(stderr, "Error loading eBPF object file. File name => %s.\n", XDP_OBJ_PATH); return EXIT_FAILURE; } @@ -442,22 +84,25 @@ int main(int argc, char *argv[]) // Attach XDP program. if (AttachXdp(prog, ifidx, 0, &cmd)) { + fprintf(stderr, "Error attaching XDP program.\n"); + return EXIT_FAILURE; } // Retrieve BPF maps. - filtersmap = FindMapFd(prog, "filters_map"); - statsmap = FindMapFd(prog, "stats_map"); + int filters_map = FindMapFd(prog, "filters_map"); // Check for valid maps. - if (filtersmap < 0) + if (filters_map < 0) { fprintf(stderr, "Error finding 'filters_map' BPF map.\n"); return EXIT_FAILURE; } - if (statsmap < 0) + int stats_map = FindMapFd(prog, "stats_map"); + + if (stats_map < 0) { fprintf(stderr, "Error finding 'stats_map' BPF map.\n"); @@ -465,7 +110,7 @@ int main(int argc, char *argv[]) } // Update BPF maps. - UpdateFilters(&cfg); + UpdateFilters(filters_map, &cfg); // Signal. signal(SIGINT, SignalHndl); @@ -473,30 +118,30 @@ int main(int argc, char *argv[]) // Receive CPU count for stats map parsing. int cpus = get_nprocs_conf(); - unsigned int endTime = (cmd.time > 0) ? time(NULL) + cmd.time : 0; + unsigned int end_time = (cmd.time > 0) ? time(NULL) + cmd.time : 0; - // Create last updated variable. - time_t lastupdatecheck = time(NULL); - time_t lastupdated = time(NULL); + // Create last updated variables. + time_t last_update_check = time(NULL); + time_t last_config_check = time(NULL); unsigned int sleep_time = cfg.stdout_update_time * 1000; while (cont) { // Get current time. - time_t curTime = time(NULL); + time_t cur_time = time(NULL); // Check if we should end the program. - if (endTime > 0 && curTime >= endTime) + if (end_time > 0 && cur_time >= end_time) { break; } // Check for auto-update. - if (cfg.updatetime > 0 && (curTime - lastupdatecheck) > cfg.updatetime) + if (cfg.updatetime > 0 && (cur_time - last_update_check) > cfg.updatetime) { // Check if config file have been modified - if (stat(cmd.cfgfile, &conf_stat) == 0 && conf_stat.st_mtime > lastupdated) { + 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); @@ -505,54 +150,23 @@ int main(int argc, char *argv[]) LoadConfig(&cfg, cmd.cfgfile); // Update BPF maps. - UpdateFilters(&cfg); + UpdateFilters(filters_map, &cfg); // Update timer - lastupdated = time(NULL); + last_config_check = time(NULL); } // Update last updated variable. - lastupdatecheck = time(NULL); + last_update_check = time(NULL); } - // Update stats. + // Calculate and display stats if enabled. if (!cfg.nostats) { - u32 key = 0; - - stats_t stats[MAX_CPUS]; - memset(stats, 0, sizeof(stats)); - - u64 allowed = 0; - u64 dropped = 0; - u64 passed = 0; - - if (bpf_map_lookup_elem(statsmap, &key, stats) != 0) + if (CalculateStats(stats_map, cpus)) { - fprintf(stderr, "Error performing stats map lookup. Stats map FD => %d.\n", statsmap); - - continue; + fprintf(stderr, "Error calculating packet stats. Stats map FD => %d.\n", stats_map); } - - for (int i = 0; i < cpus; i++) - { - // Although this should NEVER happen, I'm seeing very strange behavior in the following GitHub issue. - // https://github.com/gamemann/XDP-Firewall/issues/10 - // Therefore, before accessing stats[i], make sure the pointer to the specific CPU ID is not NULL. - if (&stats[i] == NULL) - { - fprintf(stderr, "Stats array at CPU ID #%d is NULL! Skipping...\n", i); - - continue; - } - - allowed += stats[i].allowed; - dropped += stats[i].dropped; - passed += stats[i].passed; - } - - fflush(stdout); - fprintf(stdout, "\rAllowed: %llu | Dropped: %llu | Passed: %llu", allowed, dropped, passed); } usleep(sleep_time); diff --git a/src/loader/utils/cmdline.c b/src/loader/utils/cmdline.c index a04012c..36df207 100644 --- a/src/loader/utils/cmdline.c +++ b/src/loader/utils/cmdline.c @@ -17,7 +17,7 @@ const struct option opts[] = * @param cmd A pointer to the cmdline structure. * * @return Void -*/ + */ void ParseCommandLine(cmdline_t *cmd, int argc, char *argv[]) { int c; diff --git a/src/loader/utils/config.c b/src/loader/utils/config.c index 108490e..bffec7c 100644 --- a/src/loader/utils/config.c +++ b/src/loader/utils/config.c @@ -2,7 +2,40 @@ #include -FILE *file; +static FILE *file; + +/** + * Loads the config from the file system. + * + * @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. + */ +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); + + return -1; + } + + SetCfgDefaults(cfg); + + memset(cfg->filters, 0, sizeof(cfg->filters)); + + // Read config and check for errors. + if (ReadCfg(cfg) != 0) + { + fprintf(stderr, "Error reading filters file.\n"); + + return -1; + } + + return 0; +} /** * Sets the config structure's default values. @@ -10,7 +43,7 @@ FILE *file; * @param cfg A pointer to the config structure. * * @return Void -*/ + */ void SetCfgDefaults(config__t *cfg) { cfg->updatetime = 0; @@ -18,7 +51,7 @@ void SetCfgDefaults(config__t *cfg) cfg->nostats = 0; cfg->stdout_update_time = 1000; - for (u16 i = 0; i < MAX_FILTERS; i++) + for (int i = 0; i < MAX_FILTERS; i++) { cfg->filters[i].id = 0; cfg->filters[i].enabled = 0; @@ -26,7 +59,7 @@ void SetCfgDefaults(config__t *cfg) cfg->filters[i].src_ip = 0; cfg->filters[i].dst_ip = 0; - for (u8 j = 0; j < 4; j++) + for (int j = 0; j < 4; j++) { cfg->filters[i].src_ip6[j] = 0; cfg->filters[i].dst_ip6[j] = 0; @@ -80,11 +113,11 @@ void SetCfgDefaults(config__t *cfg) /** * Opens the config file. * - * @param filename Path to config file. + * @param file_name Path to config file. * * @return 0 on success or 1 on error. -*/ -int OpenCfg(const char *filename) + */ +int OpenCfg(const char *file_name) { // Close any existing files. if (file != NULL) @@ -94,7 +127,7 @@ int OpenCfg(const char *filename) file = NULL; } - file = fopen(filename, "r"); + file = fopen(file_name, "r"); if (file == NULL) { @@ -110,7 +143,7 @@ int OpenCfg(const char *filename) * @param cfg A pointer to the config structure. * * @return 0 on success or 1/-1 on error. -*/ + */ int ReadCfg(config__t *cfg) { // Not sure why this would be set to NULL after checking for it in OpenConfig(), but just for safety. @@ -189,7 +222,7 @@ int ReadCfg(config__t *cfg) // Set filter count. int filters = 0; - for (u8 i = 0; i < config_setting_length(setting); i++) + for (int i = 0; i < config_setting_length(setting); i++) { config_setting_t* filter = config_setting_get_elem(setting, i); @@ -251,10 +284,7 @@ int ReadCfg(config__t *cfg) inet_pton(AF_INET6, sip6, &in); - for (u8 j = 0; j < 4; j++) - { - cfg->filters[i].src_ip6[j] = in.__in6_u.__u6_addr32[j]; - } + memcpy(cfg->filters[i].src_ip6, in.__in6_u.__u6_addr32, 4); } // Destination IP (IPv6) (not required). @@ -266,10 +296,7 @@ int ReadCfg(config__t *cfg) inet_pton(AF_INET6, dip6, &in); - for (u8 j = 0; j < 4; j++) - { - cfg->filters[i].dst_ip6[j] = in.__in6_u.__u6_addr32[j]; - } + memcpy(cfg->filters[i].dst_ip6, in.__in6_u.__u6_addr32, 4); } // Minimum TTL (not required). @@ -508,4 +535,104 @@ int ReadCfg(config__t *cfg) config_destroy(&conf); return 0; +} + +/** + * Prints config settings. + * + * @param cfg A pointer to the config structure. + * + * @return void + */ +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); + + for (int i = 0; i < MAX_FILTERS; i++) + { + filter_t *filter = &cfg->filters[i]; + + if (filter->id < 1) + { + break; + } + + fprintf(stdout, "Filter #%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); + + // IP Options. + fprintf(stdout, "\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); + + 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); + + struct in6_addr sin6; + memcpy(&sin6, &filter->src_ip6, sizeof(sin6)); + + char srcipv6[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &sin6, srcipv6, sizeof(srcipv6)); + + fprintf(stdout, "\t\tSource IPv6 => %s\n", srcipv6); + + struct in6_addr din6; + memcpy(&din6, &filter->dst_ip6, sizeof(din6)); + + char dstipv6[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &din6, dstipv6, sizeof(dstipv6)); + + fprintf(stdout, "\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); + + // 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); + + // 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); + + // 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, "\n\n"); + } } \ No newline at end of file diff --git a/src/loader/utils/config.h b/src/loader/utils/config.h index f539933..04d767b 100644 --- a/src/loader/utils/config.h +++ b/src/loader/utils/config.h @@ -10,6 +10,8 @@ #include +#define CONFIG_DEFAULT_PATH "/etc/xdpfw/xdpfw.conf" + struct config { char *interface; @@ -19,6 +21,9 @@ struct config filter_t filters[MAX_FILTERS]; } typedef config__t; // config_t is taken by libconfig -.- +int LoadConfig(config__t *cfg, char *cfg_file); void SetCfgDefaults(config__t *cfg); +void PrintConfig(config__t* cfg); + int OpenCfg(const char *filename); int ReadCfg(config__t *cfg); \ No newline at end of file diff --git a/src/loader/utils/helpers.c b/src/loader/utils/helpers.c index 36d9bbc..69d97e5 100644 --- a/src/loader/utils/helpers.c +++ b/src/loader/utils/helpers.c @@ -1,12 +1,40 @@ #include +/** + * Prints help menu. + * + * @return void + */ +void PrintHelpMenu() +{ + fprintf(stdout, "Usage:\n" \ + "--config -c => Config file location (default is /etc/xdpfw/xdpfw.conf).\n" \ + "--offload -o => Tries to load the XDP program in hardware/offload mode.\n" \ + "--skb -s => Force the XDP program to load with SKB mode instead of DRV.\n" \ + "--time -t => How long to run the program for in seconds before exiting. 0 or not set = infinite.\n" \ + "--list -l => Print config details including filters (this will exit program after done).\n" \ + "--help -h => Print help menu.\n"); +} + +/** + * Handles signals from user. + * + * @param code Signal code. + * + * @return void + */ +void SignalHndl(int code) +{ + cont = 0; +} + /** * Parses an IP string with CIDR support. Stores IP in network byte order in ip.ip and CIDR in ip.cidr. * * @param ip The IP string. * * @return Returns an IP structure with IP and CIDR. -*/ + */ ip_range_t ParseIpCidr(const char *ip) { ip_range_t ret = {0}; @@ -22,7 +50,7 @@ ip_range_t ParseIpCidr(const char *ip) if (token) { - ret.cidr = (unsigned int) strtoul(token, NULL, 10); + ret.cidr = (u8) strtoul(token, NULL, 10); } } diff --git a/src/loader/utils/helpers.h b/src/loader/utils/helpers.h index 6377789..8dbf165 100644 --- a/src/loader/utils/helpers.h +++ b/src/loader/utils/helpers.h @@ -10,7 +10,11 @@ struct ip_range { u32 ip; - u32 cidr; + u8 cidr; } typedef ip_range_t; -ip_range_t ParseIpCidr(const char *ip); \ No newline at end of file +extern int cont; + +void PrintHelpMenu(); +void SignalHndl(int code); +ip_range_t ParseIpCidr(const char* ip); \ No newline at end of file