diff --git a/src/common/types.h b/src/common/types.h index d9380aa..e7615e1 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -2,7 +2,34 @@ #include -struct tcp_opts +struct filter_ip +{ + u32 src_ip; + u8 src_cidr; + + u32 dst_ip; + u8 dst_cidr; + + u32 src_ip6[4]; + u32 dst_ip6[4]; + + unsigned int do_min_ttl : 1; + u8 min_ttl; + + unsigned int do_max_ttl : 1; + u8 max_ttl; + + unsigned int do_min_len : 1; + u16 min_len; + + unsigned int do_max_len : 1; + u16 max_len; + + unsigned int do_tos : 1; + u8 tos; +} typedef filter_ip_t; + +struct filter_tcp { unsigned int enabled : 1; @@ -36,9 +63,9 @@ struct tcp_opts unsigned int do_cwr : 1; unsigned int cwr : 1; -} typedef tcp_opts_t; +} typedef filter_tcp_t; -struct udp_opts +struct filter_udp { unsigned int enabled : 1; @@ -47,9 +74,9 @@ struct udp_opts unsigned int do_dport : 1; u16 dport; -} typedef udp_opts_t; +} typedef filter_udp_t; -struct icmp_opts +struct filter_icmp { unsigned int enabled : 1; @@ -58,7 +85,7 @@ struct icmp_opts unsigned int do_type : 1; u8 type; -} typedef icmp_opts_t; +} typedef filter_icmp_t; struct filter { @@ -67,42 +94,19 @@ struct filter unsigned int enabled : 1; u8 action; - - u32 src_ip; - u8 src_cidr; - - u32 dst_ip; - u8 dst_cidr; - - u32 src_ip6[4]; - u32 dst_ip6[4]; - - unsigned int do_min_ttl : 1; - u8 min_ttl; - - unsigned int do_max_ttl : 1; - u8 max_ttl; - - unsigned int do_min_len : 1; - u16 min_len; - - unsigned int do_max_len : 1; - u16 max_len; - - unsigned int do_tos : 1; - u8 tos; + u16 block_time; unsigned int do_pps : 1; u64 pps; unsigned int do_bps : 1; u64 bps; + + filter_ip_t ip; - u64 block_time; - - tcp_opts_t tcpopts; - udp_opts_t udpopts; - icmp_opts_t icmpopts; + filter_tcp_t tcp; + filter_udp_t udp; + filter_icmp_t icmp; } __attribute__((__aligned__(8))) typedef filter_t; struct stats diff --git a/src/loader/utils/config.c b/src/loader/utils/config.c index edda0f3..06a7870 100644 --- a/src/loader/utils/config.c +++ b/src/loader/utils/config.c @@ -25,8 +25,6 @@ int load_cfg(config__t *cfg, const char* cfg_file, config_overrides_t* overrides set_cfg_defaults(cfg); - memset(cfg->filters, 0, sizeof(cfg->filters)); - char* buffer = NULL; // Read config. @@ -311,7 +309,7 @@ int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides) { for (int i = 0; i < config_setting_length(setting); i++) { - filter_t* filter = &cfg->filters[i]; + filter_rule_cfg_t* filter = &cfg->filters[i]; config_setting_t* filter_cfg = config_setting_get_elem(setting, i); @@ -322,6 +320,9 @@ int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides) continue; } + // Make sure filter is set. + filter->set = 1; + // Enabled. int enabled; @@ -346,15 +347,38 @@ int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides) filter->action = action; } + // Block time (default 1). + int block_time; + + if (config_setting_lookup_int(filter_cfg, "block_time", &block_time) == CONFIG_TRUE) + { + filter->block_time = block_time; + } + + // PPS (not required). + s64 pps; + + if (config_setting_lookup_int64(filter_cfg, "pps", &pps) == CONFIG_TRUE) + { + filter->pps = pps; + } + + // BPS (not required). + s64 bps; + + if (config_setting_lookup_int64(filter_cfg, "bps", &bps) == CONFIG_TRUE) + { + filter->bps = bps; + } + + /* IP Options */ + // Source IP (not required). const char *sip; if (config_setting_lookup_string(filter_cfg, "src_ip", &sip) == CONFIG_TRUE) { - ip_range_t ip = parse_ip_range(sip); - - filter->src_ip = ip.ip; - filter->src_cidr = ip.cidr; + filter->ip.src_ip = strdup(sip); } // Destination IP (not required). @@ -362,10 +386,7 @@ int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides) if (config_setting_lookup_string(filter_cfg, "dst_ip", &dip) == CONFIG_TRUE) { - ip_range_t ip = parse_ip_range(dip); - - filter->dst_ip = ip.ip; - filter->dst_cidr = ip.cidr; + filter->ip.dst_ip = strdup(dip); } // Source IP (IPv6) (not required). @@ -373,11 +394,7 @@ int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides) if (config_setting_lookup_string(filter_cfg, "src_ip6", &sip6) == CONFIG_TRUE) { - struct in6_addr in; - - inet_pton(AF_INET6, sip6, &in); - - memcpy(filter->src_ip6, in.__in6_u.__u6_addr32, 4); + filter->ip.src_ip6 = strdup(sip6); } // Destination IP (IPv6) (not required). @@ -385,11 +402,7 @@ int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides) if (config_setting_lookup_string(filter_cfg, "dst_ip6", &dip6) == CONFIG_TRUE) { - struct in6_addr in; - - inet_pton(AF_INET6, dip6, &in); - - memcpy(filter->dst_ip6, in.__in6_u.__u6_addr32, 4); + filter->ip.dst_ip6 = strdup(dip6); } // Minimum TTL (not required). @@ -397,8 +410,7 @@ int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides) if (config_setting_lookup_int(filter_cfg, "min_ttl", &min_ttl) == CONFIG_TRUE) { - filter->min_ttl = (u8)min_ttl; - filter->do_min_ttl = 1; + filter->ip.min_ttl = min_ttl; } // Maximum TTL (not required). @@ -406,8 +418,7 @@ int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides) if (config_setting_lookup_int(filter_cfg, "max_ttl", &max_ttl) == CONFIG_TRUE) { - filter->max_ttl = (u8)max_ttl; - filter->do_max_ttl = 1; + filter->ip.max_ttl = max_ttl; } // Minimum length (not required). @@ -415,8 +426,7 @@ int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides) if (config_setting_lookup_int(filter_cfg, "min_len", &min_len) == CONFIG_TRUE) { - filter->min_len = min_len; - filter->do_min_len = 1; + filter->ip.min_len = min_len; } // Maximum length (not required). @@ -424,8 +434,7 @@ int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides) if (config_setting_lookup_int(filter_cfg, "max_len", &max_len) == CONFIG_TRUE) { - filter->max_len = max_len; - filter->do_max_len = 1; + filter->ip.max_len = max_len; } // TOS (not required). @@ -433,195 +442,149 @@ int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides) if (config_setting_lookup_int(filter_cfg, "tos", &tos) == CONFIG_TRUE) { - filter->tos = (u8)tos; - filter->do_tos = 1; - } - - // PPS (not required). - long long pps; - - if (config_setting_lookup_int64(filter_cfg, "pps", &pps) == CONFIG_TRUE) - { - filter->pps = pps; - filter->do_pps = 1; - } - - // BPS (not required). - long long bps; - - if (config_setting_lookup_int64(filter_cfg, "bps", &bps) == CONFIG_TRUE) - { - filter->bps = bps; - filter->do_bps = 1; - } - - // Block time (default 1). - long long block_time; - - if (config_setting_lookup_int64(filter_cfg, "block_time", &block_time) == CONFIG_TRUE) - { - filter->block_time = block_time; - } - else - { - filter->block_time = 1; + filter->ip.tos = tos; } /* TCP options */ - // Enabled. - int tcpenabled; - if (config_setting_lookup_bool(filter_cfg, "tcp_enabled", &tcpenabled) == CONFIG_TRUE) + // Enabled. + int tcp_enabled; + + if (config_setting_lookup_bool(filter_cfg, "tcp_enabled", &tcp_enabled) == CONFIG_TRUE) { - filter->tcpopts.enabled = tcpenabled; + filter->tcp.enabled = tcp_enabled; } // Source port. - int tcpsport; + int tcp_sport; - if (config_setting_lookup_int(filter_cfg, "tcp_sport", &tcpsport) == CONFIG_TRUE) + if (config_setting_lookup_int(filter_cfg, "tcp_sport", &tcp_sport) == CONFIG_TRUE) { - filter->tcpopts.sport = (u16)tcpsport; - filter->tcpopts.do_sport = 1; + filter->tcp.sport = tcp_sport; } // Destination port. - int tcpdport; + int tcp_dport; - if (config_setting_lookup_int(filter_cfg, "tcp_dport", &tcpdport) == CONFIG_TRUE) + if (config_setting_lookup_int(filter_cfg, "tcp_dport", &tcp_dport) == CONFIG_TRUE) { - filter->tcpopts.dport = (u16)tcpdport; - filter->tcpopts.do_dport = 1; + filter->tcp.dport = tcp_dport; } // URG flag. - int tcpurg; + int tcp_urg; - if (config_setting_lookup_bool(filter_cfg, "tcp_urg", &tcpurg) == CONFIG_TRUE) + if (config_setting_lookup_bool(filter_cfg, "tcp_urg", &tcp_urg) == CONFIG_TRUE) { - filter->tcpopts.urg = tcpurg; - filter->tcpopts.do_urg = 1; + filter->tcp.urg = tcp_urg; } // ACK flag. - int tcpack; + int tcp_ack; - if (config_setting_lookup_bool(filter_cfg, "tcp_ack", &tcpack) == CONFIG_TRUE) + if (config_setting_lookup_bool(filter_cfg, "tcp_ack", &tcp_ack) == CONFIG_TRUE) { - filter->tcpopts.ack = tcpack; - filter->tcpopts.do_ack = 1; + filter->tcp.ack = tcp_ack; } // RST flag. - int tcprst; + int tcp_rst; - if (config_setting_lookup_bool(filter_cfg, "tcp_rst", &tcprst) == CONFIG_TRUE) + if (config_setting_lookup_bool(filter_cfg, "tcp_rst", &tcp_rst) == CONFIG_TRUE) { - filter->tcpopts.rst = tcprst; - filter->tcpopts.do_rst = 1; + filter->tcp.rst = tcp_rst; } // PSH flag. - int tcppsh; + int tcp_psh; - if (config_setting_lookup_bool(filter_cfg, "tcp_psh", &tcppsh) == CONFIG_TRUE) + if (config_setting_lookup_bool(filter_cfg, "tcp_psh", &tcp_psh) == CONFIG_TRUE) { - filter->tcpopts.psh = tcppsh; - filter->tcpopts.do_psh = 1; + filter->tcp.psh = tcp_psh; } // SYN flag. - int tcpsyn; + int tcp_syn; - if (config_setting_lookup_bool(filter_cfg, "tcp_syn", &tcpsyn) == CONFIG_TRUE) + if (config_setting_lookup_bool(filter_cfg, "tcp_syn", &tcp_syn) == CONFIG_TRUE) { - filter->tcpopts.syn = tcpsyn; - filter->tcpopts.do_syn = 1; + filter->tcp.syn = tcp_syn; } // FIN flag. - int tcpfin; + int tcp_fin; - if (config_setting_lookup_bool(filter_cfg, "tcp_fin", &tcpfin) == CONFIG_TRUE) + if (config_setting_lookup_bool(filter_cfg, "tcp_fin", &tcp_fin) == CONFIG_TRUE) { - filter->tcpopts.fin = tcpfin; - filter->tcpopts.do_fin = 1; + filter->tcp.fin = tcp_fin; } // ECE flag. - int tcpece; + int tcp_ece; - if (config_setting_lookup_bool(filter_cfg, "tcp_ece", &tcpece) == CONFIG_TRUE) + if (config_setting_lookup_bool(filter_cfg, "tcp_ece", &tcp_ece) == CONFIG_TRUE) { - filter->tcpopts.ece = tcpece; - filter->tcpopts.do_ece = 1; + filter->tcp.ece = tcp_ece; } // CWR flag. - int tcpcwr; + int tcp_cwr; - if (config_setting_lookup_bool(filter_cfg, "tcp_cwr", &tcpcwr) == CONFIG_TRUE) + if (config_setting_lookup_bool(filter_cfg, "tcp_cwr", &tcp_cwr) == CONFIG_TRUE) { - filter->tcpopts.cwr = tcpcwr; - filter->tcpopts.do_cwr = 1; + filter->tcp.cwr = tcp_cwr; } /* UDP options */ - // Enabled. - int udpenabled; - if (config_setting_lookup_bool(filter_cfg, "udp_enabled", &udpenabled) == CONFIG_TRUE) + // Enabled. + int udp_enabled; + + if (config_setting_lookup_bool(filter_cfg, "udp_enabled", &udp_enabled) == CONFIG_TRUE) { - filter->udpopts.enabled = udpenabled; + filter->udp.enabled = udp_enabled; } // Source port. - int udpsport; + int udp_sport; - if (config_setting_lookup_int(filter_cfg, "udp_sport", &udpsport) == CONFIG_TRUE) + if (config_setting_lookup_int(filter_cfg, "udp_sport", &udp_sport) == CONFIG_TRUE) { - filter->udpopts.sport = (u16)udpsport; - filter->udpopts.do_sport = 1; + filter->udp.sport = udp_sport; } // Destination port. - int udpdport; + int udp_dport; - if (config_setting_lookup_int(filter_cfg, "udp_dport", &udpdport) == CONFIG_TRUE) + if (config_setting_lookup_int(filter_cfg, "udp_dport", &udp_dport) == CONFIG_TRUE) { - filter->udpopts.dport = (u16)udpdport; - filter->udpopts.do_dport = 1; + filter->udp.dport = udp_dport; } /* ICMP options */ // Enabled. - int icmpenabled; + int icmp_enabled; - if (config_setting_lookup_bool(filter_cfg, "icmp_enabled", &icmpenabled) == CONFIG_TRUE) + if (config_setting_lookup_bool(filter_cfg, "icmp_enabled", &icmp_enabled) == CONFIG_TRUE) { - filter->icmpopts.enabled = icmpenabled; + filter->icmp.enabled = icmp_enabled; } // ICMP code. - int icmpcode; + int icmp_code; - if (config_setting_lookup_int(filter_cfg, "icmp_code", &icmpcode) == CONFIG_TRUE) + if (config_setting_lookup_int(filter_cfg, "icmp_code", &icmp_code) == CONFIG_TRUE) { - filter->icmpopts.code = (u8)icmpcode; - filter->icmpopts.do_code = 1; + filter->icmp.code = icmp_code; } // ICMP type. - int icmptype; + int icmp_type; - if (config_setting_lookup_int(filter_cfg, "icmp_type", &icmptype) == CONFIG_TRUE) + if (config_setting_lookup_int(filter_cfg, "icmp_type", &icmp_type) == CONFIG_TRUE) { - filter->icmpopts.type = (u8)icmptype; - filter->icmpopts.do_type = 1; + filter->icmp.type = icmp_type; } - - // Make sure filter is set. - filter->set = 1; } } @@ -717,7 +680,7 @@ int save_cfg(config__t* cfg, const char* file_path) { for (int i = 0; i < MAX_FILTERS; i++) { - filter_t* filter = &cfg->filters[i]; + filter_rule_cfg_t* filter = &cfg->filters[i]; if (!filter->set) { @@ -729,172 +692,229 @@ int save_cfg(config__t* cfg, const char* file_path) if (filter_cfg) { // Add enabled setting. - config_setting_t* enabled = config_setting_add(filter_cfg, "enabled", CONFIG_TYPE_BOOL); - config_setting_set_bool(enabled, filter->enabled); + if (filter->enabled > -1) + { + config_setting_t* enabled = config_setting_add(filter_cfg, "enabled", CONFIG_TYPE_BOOL); + config_setting_set_bool(enabled, filter->enabled); + } // Add log setting. - config_setting_t* log = config_setting_add(filter_cfg, "log", CONFIG_TYPE_BOOL); - config_setting_set_bool(log, filter->log); + if (filter->log > -1) + { + config_setting_t* log = config_setting_add(filter_cfg, "log", CONFIG_TYPE_BOOL); + config_setting_set_bool(log, filter->log); + } // Add action setting. - config_setting_t* action = config_setting_add(filter_cfg, "action", CONFIG_TYPE_INT); - config_setting_set_int(action, filter->action); + if (filter->action > -1) + { + config_setting_t* action = config_setting_add(filter_cfg, "action", CONFIG_TYPE_INT); + config_setting_set_int(action, filter->action); + } + + // Add block time. + if (filter->block_time > -1) + { + config_setting_t* block_time = config_setting_add(filter_cfg, "block_time", CONFIG_TYPE_INT64); + config_setting_set_int64(block_time, filter->block_time); + } + + // Add PPS. + if (filter->pps > -1) + { + config_setting_t* pps = config_setting_add(filter_cfg, "pps", CONFIG_TYPE_INT64); + config_setting_set_int64(pps, filter->pps); + } + + // Add BPS. + if (filter->bps > -1) + { + config_setting_t* bps = config_setting_add(filter_cfg, "bps", CONFIG_TYPE_INT64); + config_setting_set_int64(bps, filter->bps); + } // Add source IPv4. - if (filter->src_ip > 0) + if (filter->ip.src_ip) { - char ip_str[INET_ADDRSTRLEN]; - - inet_ntop(AF_INET, &filter->src_ip, ip_str, sizeof(ip_str)); - - char full_ip[INET_ADDRSTRLEN + 6]; - snprintf(full_ip, sizeof(full_ip), "%s/%d", ip_str, filter->src_cidr); - config_setting_t* src_ip = config_setting_add(filter_cfg, "src_ip", CONFIG_TYPE_STRING); - config_setting_set_string(src_ip, full_ip); + config_setting_set_string(src_ip, filter->ip.src_ip); } // Add destination IPv4. - if (filter->dst_ip > 0) + if (filter->ip.dst_ip) { - char ip_str[INET_ADDRSTRLEN]; - - inet_ntop(AF_INET, &filter->dst_ip, ip_str, sizeof(ip_str)); - - char full_ip[INET_ADDRSTRLEN + 6]; - snprintf(full_ip, sizeof(full_ip), "%s/%d", ip_str, filter->src_cidr); - config_setting_t* dst_ip = config_setting_add(filter_cfg, "dst_ip", CONFIG_TYPE_STRING); - config_setting_set_string(dst_ip, full_ip); + config_setting_set_string(dst_ip, filter->ip.dst_ip); } - + // Add source IPv6. - if (memcmp(filter->src_ip6, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) != 0) + if (filter->ip.src_ip6) { - char ip_str[INET6_ADDRSTRLEN]; - - inet_ntop(AF_INET, filter->src_ip6, ip_str, sizeof(ip_str)); - - //char full_ip[INET6_ADDRSTRLEN + 6]; - //snprintf(full_ip, sizeof(full_ip), "%s/%d", ip_str, filter->src_cidr6); - config_setting_t* src_ip6 = config_setting_add(filter_cfg, "src_ip6", CONFIG_TYPE_STRING); - config_setting_set_string(src_ip6, ip_str); + config_setting_set_string(src_ip6, filter->ip.src_ip6); } // Add source IPv6. - if (memcmp(filter->dst_ip6, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) != 0) + if (filter->ip.dst_ip6) { - char ip_str[INET6_ADDRSTRLEN]; - - inet_ntop(AF_INET, filter->dst_ip6, ip_str, sizeof(ip_str)); - - //char full_ip[INET6_ADDRSTRLEN + 6]; - //snprintf(full_ip, sizeof(full_ip), "%s/%d", ip_str, filter->src_cidr6); - config_setting_t* dst_ip6 = config_setting_add(filter_cfg, "dst_ip6", CONFIG_TYPE_STRING); - config_setting_set_string(dst_ip6, ip_str); + config_setting_set_string(dst_ip6, filter->ip.dst_ip6); } // Add minimum TTL. - config_setting_t* min_ttl = config_setting_add(filter_cfg, "min_ttl", CONFIG_TYPE_INT); - config_setting_set_int(min_ttl, filter->min_ttl); + if (filter->ip.min_ttl > -1) + { + config_setting_t* min_ttl = config_setting_add(filter_cfg, "min_ttl", CONFIG_TYPE_INT); + config_setting_set_int(min_ttl, filter->ip.min_ttl); + } // Add maximum TTL. - config_setting_t* max_ttl = config_setting_add(filter_cfg, "max_ttl", CONFIG_TYPE_INT); - config_setting_set_int(max_ttl, filter->max_ttl); + if (filter->ip.max_ttl > -1) + { + config_setting_t* max_ttl = config_setting_add(filter_cfg, "max_ttl", CONFIG_TYPE_INT); + config_setting_set_int(max_ttl, filter->ip.max_ttl); + } // Add minimum length. - config_setting_t* min_len = config_setting_add(filter_cfg, "min_len", CONFIG_TYPE_INT); - config_setting_set_int(min_len, filter->min_len); + if (filter->ip.min_len > -1) + { + config_setting_t* min_len = config_setting_add(filter_cfg, "min_len", CONFIG_TYPE_INT); + config_setting_set_int(min_len, filter->ip.min_len); + } // Add maximum length. - config_setting_t* max_len = config_setting_add(filter_cfg, "max_len", CONFIG_TYPE_INT); - config_setting_set_int(max_len, filter->max_len); + if (filter->ip.max_len > -1) + { + config_setting_t* max_len = config_setting_add(filter_cfg, "max_len", CONFIG_TYPE_INT); + config_setting_set_int(max_len, filter->ip.max_len); + } // Add ToS. - config_setting_t* tos = config_setting_add(filter_cfg, "tos", CONFIG_TYPE_INT); - config_setting_set_int(tos, filter->tos); + if (filter->ip.tos > -1) + { + config_setting_t* tos = config_setting_add(filter_cfg, "tos", CONFIG_TYPE_INT); + config_setting_set_int(tos, filter->ip.tos); + } - // Add PPS. - config_setting_t* pps = config_setting_add(filter_cfg, "pps", CONFIG_TYPE_INT64); - config_setting_set_int64(pps, filter->pps); - - // Add BPS. - config_setting_t* bps = config_setting_add(filter_cfg, "bps", CONFIG_TYPE_INT64); - config_setting_set_int64(bps, filter->bps); - - // Add block time. - config_setting_t* block_time = config_setting_add(filter_cfg, "block_time", CONFIG_TYPE_INT64); - config_setting_set_int64(block_time, filter->block_time); // Add TCP enabled. - config_setting_t* tcp_enabled = config_setting_add(filter_cfg, "tcp_enabled", CONFIG_TYPE_BOOL); - config_setting_set_bool(tcp_enabled, filter->tcpopts.enabled); + if (filter->tcp.enabled > -1) + { + config_setting_t* tcp_enabled = config_setting_add(filter_cfg, "tcp_enabled", CONFIG_TYPE_BOOL); + config_setting_set_bool(tcp_enabled, filter->tcp.enabled); + } // Add TCP source port. - config_setting_t* tcp_sport = config_setting_add(filter_cfg, "tcp_sport", CONFIG_TYPE_INT); - config_setting_set_int(tcp_sport, filter->tcpopts.sport); + if (filter->tcp.sport > -1) + { + config_setting_t* tcp_sport = config_setting_add(filter_cfg, "tcp_sport", CONFIG_TYPE_INT); + config_setting_set_int(tcp_sport, filter->tcp.sport); + } // Add TCP destination port. - config_setting_t* tcp_dport = config_setting_add(filter_cfg, "tcp_dport", CONFIG_TYPE_INT); - config_setting_set_int(tcp_dport, filter->tcpopts.dport); + if (filter->tcp.dport > -1) + { + config_setting_t* tcp_dport = config_setting_add(filter_cfg, "tcp_dport", CONFIG_TYPE_INT); + config_setting_set_int(tcp_dport, filter->tcp.dport); + } // Add TCP URG flag. - config_setting_t* tcp_urg = config_setting_add(filter_cfg, "tcp_urg", CONFIG_TYPE_BOOL); - config_setting_set_bool(tcp_urg, filter->tcpopts.urg); + if (filter->tcp.urg > -1) + { + config_setting_t* tcp_urg = config_setting_add(filter_cfg, "tcp_urg", CONFIG_TYPE_BOOL); + config_setting_set_bool(tcp_urg, filter->tcp.urg); + } // Add TCP ACK flag. - config_setting_t* tcp_ack = config_setting_add(filter_cfg, "tcp_ack", CONFIG_TYPE_BOOL); - config_setting_set_bool(tcp_ack, filter->tcpopts.ack); + if (filter->tcp.ack > -1) + { + config_setting_t* tcp_ack = config_setting_add(filter_cfg, "tcp_ack", CONFIG_TYPE_BOOL); + config_setting_set_bool(tcp_ack, filter->tcp.ack); + } // Add TCP RST flag. - config_setting_t* tcp_rst = config_setting_add(filter_cfg, "tcp_rst", CONFIG_TYPE_BOOL); - config_setting_set_bool(tcp_rst, filter->tcpopts.rst); + if (filter->tcp.rst > -1) + { + config_setting_t* tcp_rst = config_setting_add(filter_cfg, "tcp_rst", CONFIG_TYPE_BOOL); + config_setting_set_bool(tcp_rst, filter->tcp.rst); + } // Add TCP PSH flag. - config_setting_t* tcp_psh = config_setting_add(filter_cfg, "tcp_psh", CONFIG_TYPE_BOOL); - config_setting_set_bool(tcp_psh, filter->tcpopts.psh); + if (filter->tcp.psh > -1) + { + config_setting_t* tcp_psh = config_setting_add(filter_cfg, "tcp_psh", CONFIG_TYPE_BOOL); + config_setting_set_bool(tcp_psh, filter->tcp.psh); + } // Add TCP SYN flag. - config_setting_t* tcp_syn = config_setting_add(filter_cfg, "tcp_syn", CONFIG_TYPE_BOOL); - config_setting_set_bool(tcp_syn, filter->tcpopts.syn); + if (filter->tcp.syn > -1) + { + config_setting_t* tcp_syn = config_setting_add(filter_cfg, "tcp_syn", CONFIG_TYPE_BOOL); + config_setting_set_bool(tcp_syn, filter->tcp.syn); + } // Add TCP FIN flag. - config_setting_t* tcp_fin = config_setting_add(filter_cfg, "tcp_fin", CONFIG_TYPE_BOOL); - config_setting_set_bool(tcp_fin, filter->tcpopts.fin); + if (filter->tcp.fin > -1) + { + config_setting_t* tcp_fin = config_setting_add(filter_cfg, "tcp_fin", CONFIG_TYPE_BOOL); + config_setting_set_bool(tcp_fin, filter->tcp.fin); + } // Add TCP ECE flag. - config_setting_t* tcp_ece = config_setting_add(filter_cfg, "tcp_ece", CONFIG_TYPE_BOOL); - config_setting_set_bool(tcp_ece, filter->tcpopts.ece); + if (filter->tcp.ece > -1) + { + config_setting_t* tcp_ece = config_setting_add(filter_cfg, "tcp_ece", CONFIG_TYPE_BOOL); + config_setting_set_bool(tcp_ece, filter->tcp.ece); + } // Add TCP CWR flag. - config_setting_t* tcp_cwr = config_setting_add(filter_cfg, "tcp_cwr", CONFIG_TYPE_BOOL); - config_setting_set_bool(tcp_cwr, filter->tcpopts.cwr); + if (filter->tcp.cwr > -1) + { + config_setting_t* tcp_cwr = config_setting_add(filter_cfg, "tcp_cwr", CONFIG_TYPE_BOOL); + config_setting_set_bool(tcp_cwr, filter->tcp.cwr); + } // Add UDP enabled. - config_setting_t* udp_enabled = config_setting_add(filter_cfg, "udp_enabled", CONFIG_TYPE_BOOL); - config_setting_set_bool(udp_enabled, filter->udpopts.enabled); + if (filter->udp.enabled > -1) + { + config_setting_t* udp_enabled = config_setting_add(filter_cfg, "udp_enabled", CONFIG_TYPE_BOOL); + config_setting_set_bool(udp_enabled, filter->udp.enabled); + } // Add UDP source port. - config_setting_t* udp_sport = config_setting_add(filter_cfg, "udp_sport", CONFIG_TYPE_INT); - config_setting_set_int(udp_sport, filter->udpopts.sport); + if (filter->udp.sport > -1) + { + config_setting_t* udp_sport = config_setting_add(filter_cfg, "udp_sport", CONFIG_TYPE_INT); + config_setting_set_int(udp_sport, filter->udp.sport); + } // Add UDP destination port. - config_setting_t* udp_dport = config_setting_add(filter_cfg, "udp_dport", CONFIG_TYPE_INT); - config_setting_set_int(udp_dport, filter->udpopts.dport); + if (filter->udp.dport > -1) + { + config_setting_t* udp_dport = config_setting_add(filter_cfg, "udp_dport", CONFIG_TYPE_INT); + config_setting_set_int(udp_dport, filter->udp.dport); + } // Add ICMP enabled. - config_setting_t* icmp_enabled = config_setting_add(filter_cfg, "icmp_enabled", CONFIG_TYPE_BOOL); - config_setting_set_bool(icmp_enabled, filter->icmpopts.enabled); + if (filter->icmp.enabled > -1) + { + config_setting_t* icmp_enabled = config_setting_add(filter_cfg, "icmp_enabled", CONFIG_TYPE_BOOL); + config_setting_set_bool(icmp_enabled, filter->icmp.enabled); + } // Add ICMP code. - config_setting_t* icmp_code = config_setting_add(filter_cfg, "icmp_code", CONFIG_TYPE_INT); - config_setting_set_int(icmp_code, filter->icmpopts.code); + if (filter->icmp.code > -1) + { + config_setting_t* icmp_code = config_setting_add(filter_cfg, "icmp_code", CONFIG_TYPE_INT); + config_setting_set_int(icmp_code, filter->icmp.code); + } // Add ICMP type. - config_setting_t* icmp_type = config_setting_add(filter_cfg, "icmp_type", CONFIG_TYPE_INT); - config_setting_set_int(icmp_type, filter->icmpopts.type); + if (filter->icmp.type > -1) + { + config_setting_t* icmp_type = config_setting_add(filter_cfg, "icmp_type", CONFIG_TYPE_INT); + config_setting_set_int(icmp_type, filter->icmp.type); + } } } } @@ -945,7 +965,7 @@ int save_cfg(config__t* cfg, const char* file_path) * * @return void */ -void set_filter_defaults(filter_t* filter) +void set_filter_defaults(filter_rule_cfg_t* filter) { filter->set = 0; filter->enabled = 1; @@ -953,54 +973,68 @@ void set_filter_defaults(filter_t* filter) filter->log = 0; filter->action = 1; - filter->src_ip = 0; - filter->dst_ip = 0; - - memset(filter->src_ip6, 0, 4); - memset(filter->dst_ip6, 0, 4); - - filter->do_min_len = 0; - filter->min_len = 0; - - filter->do_max_len = 0; - filter->max_len = 65535; - - filter->do_min_ttl = 0; - filter->min_ttl = 0; - - filter->do_max_ttl = 0; - filter->max_ttl = 255; - - filter->do_tos = 0; - filter->tos = 0; - - filter->do_pps = 0; - filter->pps = 0; - - filter->do_bps = 0; - filter->bps = 0; - filter->block_time = 1; - - filter->tcpopts.enabled = 0; - filter->tcpopts.do_dport = 0; - filter->tcpopts.do_dport = 0; - filter->tcpopts.do_urg = 0; - filter->tcpopts.do_ack = 0; - filter->tcpopts.do_rst = 0; - filter->tcpopts.do_psh = 0; - filter->tcpopts.do_syn = 0; - filter->tcpopts.do_fin = 0; - filter->tcpopts.do_ece = 0; - filter->tcpopts.do_cwr = 0; - filter->udpopts.enabled = 0; - filter->udpopts.do_sport = 0; - filter->udpopts.do_dport = 0; + filter->pps = -1; + filter->bps = -1; - filter->icmpopts.enabled = 0; - filter->icmpopts.do_code = 0; - filter->icmpopts.do_type = 0; + if (filter->ip.src_ip) + { + free((void*)filter->ip.src_ip); + + filter->ip.src_ip = NULL; + } + + if (filter->ip.dst_ip) + { + free((void*)filter->ip.dst_ip); + + filter->ip.dst_ip = NULL; + } + + if (filter->ip.src_ip6) + { + free((void*)filter->ip.src_ip6); + + filter->ip.src_ip6 = NULL; + } + + if (filter->ip.dst_ip6) + { + free((void*)filter->ip.dst_ip6); + + filter->ip.dst_ip6 = NULL; + } + + filter->ip.min_ttl = -1; + filter->ip.max_ttl = -1; + + filter->ip.min_len = -1; + filter->ip.max_len = -1; + + filter->ip.tos = -1; + + filter->tcp.enabled = -1; + + filter->tcp.sport = -1; + filter->tcp.dport = -1; + + filter->tcp.urg = -1; + filter->tcp.ack = -1; + filter->tcp.rst = -1; + filter->tcp.psh = -1; + filter->tcp.syn = -1; + filter->tcp.fin = -1; + filter->tcp.ece = -1; + filter->tcp.cwr = -1; + + filter->udp.enabled = -1; + filter->udp.sport = -1; + filter->udp.dport = -1; + + filter->icmp.enabled = -1; + filter->icmp.code = -1; + filter->icmp.type = -1; } /** @@ -1023,7 +1057,7 @@ void set_cfg_defaults(config__t* cfg) for (int i = 0; i < MAX_FILTERS; i++) { - filter_t* filter = &cfg->filters[i]; + filter_rule_cfg_t* filter = &cfg->filters[i]; set_filter_defaults(filter); } @@ -1039,78 +1073,91 @@ void set_cfg_defaults(config__t* cfg) * * @return void */ -void PrintFilter(filter_t* filter, int idx) +void print_filter(filter_rule_cfg_t* filter, int idx) { printf("\tFilter #%d\n", idx); printf("\t\tEnabled => %d\n", filter->enabled); - printf("\t\tAction => %d (0 = Block, 1 = Allow).\n", filter->action); printf("\t\tLog => %d\n\n", filter->log); + printf("\t\tAction => %d (0 = Block, 1 = Allow).\n", filter->action); + printf("\t\t\tBlock Time => %d\n\n", filter->block_time); + + printf("\t\t\tPPS => %lld\n", filter->pps); + printf("\t\t\tBPS => %lld\n\n", filter->bps); + // IP Options. printf("\t\tIP Options\n"); // IP addresses require additional code for string printing. - struct sockaddr_in sin; - sin.sin_addr.s_addr = filter->src_ip; - printf("\t\t\tSource IPv4 => %s\n", inet_ntoa(sin.sin_addr)); - printf("\t\t\tSource CIDR => %d\n", filter->src_cidr); + const char* src_ip = "N/A"; - struct sockaddr_in din; - din.sin_addr.s_addr = filter->dst_ip; - printf("\t\t\tDestination IPv4 => %s\n", inet_ntoa(din.sin_addr)); - printf("\t\t\tDestination CIDR => %d\n", filter->dst_cidr); + if (filter->ip.src_ip) + { + src_ip = filter->ip.src_ip; + } - struct in6_addr sin6; - memcpy(&sin6, &filter->src_ip6, sizeof(sin6)); + printf("\t\t\tSource IPv4 => %s\n", src_ip); + + const char* dst_ip = "N/A"; + + if (filter->ip.dst_ip) + { + dst_ip = filter->ip.dst_ip; + } + + printf("\t\t\tDestination IPv4 => %s\n", dst_ip); + + const char* src_ip6 = "N/A"; + + if (filter->ip.src_ip6) + { + src_ip6 = filter->ip.src_ip6; + } + + printf("\t\t\tSource IPv6 => %s\n", src_ip6); + + const char* dst_ip6 = "N/A"; + + if (filter->ip.dst_ip6) + { + dst_ip6 = filter->ip.dst_ip6; + } + + printf("\t\t\tDestination IPv6 => %s\n", dst_ip6); - char srcipv6[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &sin6, srcipv6, sizeof(srcipv6)); + printf("\t\t\tMin TTL => %d\n", filter->ip.min_ttl); + printf("\t\t\tMax TTL => %d\n", filter->ip.max_ttl); - printf("\t\t\tSource IPv6 => %s\n", srcipv6); + printf("\t\t\tMin Length => %d\n", filter->ip.min_len); + printf("\t\t\tMax Length => %d\n", filter->ip.max_len); - struct in6_addr din6; - memcpy(&din6, &filter->dst_ip6, sizeof(din6)); - - char dstipv6[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &din6, dstipv6, sizeof(dstipv6)); - - printf("\t\t\tDestination IPv6 => %s\n", dstipv6); - - // Other IP header information. - printf("\t\t\tMax Length => %d\n", filter->max_len); - printf("\t\t\tMin Length => %d\n", filter->min_len); - printf("\t\t\tMax TTL => %d\n", filter->max_ttl); - printf("\t\t\tMin TTL => %d\n", filter->min_ttl); - printf("\t\t\tTOS => %d\n", filter->tos); - printf("\t\t\tPPS => %llu\n", filter->pps); - printf("\t\t\tBPS => %llu\n", filter->bps); - printf("\t\t\tBlock Time => %llu\n\n", filter->block_time); + printf("\t\t\tTOS => %d\n\n", filter->ip.tos); // TCP Options. printf("\t\tTCP Options\n"); - printf("\t\t\tTCP Enabled => %d\n", filter->tcpopts.enabled); - printf("\t\t\tTCP Source Port => %d\n", filter->tcpopts.sport); - printf("\t\t\tTCP Destination Port => %d\n", filter->tcpopts.dport); - printf("\t\t\tTCP URG Flag => %d\n", filter->tcpopts.urg); - printf("\t\t\tTCP ACK Flag => %d\n", filter->tcpopts.ack); - printf("\t\t\tTCP RST Flag => %d\n", filter->tcpopts.rst); - printf("\t\t\tTCP PSH Flag => %d\n", filter->tcpopts.psh); - printf("\t\t\tTCP SYN Flag => %d\n", filter->tcpopts.syn); - printf("\t\t\tTCP FIN Flag => %d\n", filter->tcpopts.fin); - printf("\t\t\tTCP ECE Flag => %d\n", filter->tcpopts.ece); - printf("\t\t\tTCP CWR Flag => %d\n\n", filter->tcpopts.cwr); + printf("\t\t\tTCP Enabled => %d\n", filter->tcp.enabled); + printf("\t\t\tTCP Source Port => %d\n", filter->tcp.sport); + printf("\t\t\tTCP Destination Port => %d\n", filter->tcp.dport); + printf("\t\t\tTCP URG Flag => %d\n", filter->tcp.urg); + printf("\t\t\tTCP ACK Flag => %d\n", filter->tcp.ack); + printf("\t\t\tTCP RST Flag => %d\n", filter->tcp.rst); + printf("\t\t\tTCP PSH Flag => %d\n", filter->tcp.psh); + printf("\t\t\tTCP SYN Flag => %d\n", filter->tcp.syn); + printf("\t\t\tTCP FIN Flag => %d\n", filter->tcp.fin); + printf("\t\t\tTCP ECE Flag => %d\n", filter->tcp.ece); + printf("\t\t\tTCP CWR Flag => %d\n\n", filter->tcp.cwr); // UDP Options. printf("\t\tUDP Options\n"); - printf("\t\t\tUDP Enabled => %d\n", filter->udpopts.enabled); - printf("\t\t\tUDP Source Port => %d\n", filter->udpopts.sport); - printf("\t\t\tUDP Destination Port => %d\n\n", filter->udpopts.dport); + printf("\t\t\tUDP Enabled => %d\n", filter->udp.enabled); + printf("\t\t\tUDP Source Port => %d\n", filter->udp.sport); + printf("\t\t\tUDP Destination Port => %d\n\n", filter->udp.dport); // ICMP Options. printf("\t\tICMP Options\n"); - printf("\t\t\tICMP Enabled => %d\n", filter->icmpopts.enabled); - printf("\t\t\tICMP Code => %d\n", filter->icmpopts.code); - printf("\t\t\tICMP Type => %d\n", filter->icmpopts.type); + printf("\t\t\tICMP Enabled => %d\n", filter->icmp.enabled); + printf("\t\t\tICMP Code => %d\n", filter->icmp.code); + printf("\t\t\tICMP Type => %d\n", filter->icmp.type); } /** @@ -1152,14 +1199,14 @@ void print_cfg(config__t* cfg) for (int i = 0; i < MAX_FILTERS; i++) { - filter_t *filter = &cfg->filters[i]; + filter_rule_cfg_t *filter = &cfg->filters[i]; if (!filter->set) { break; } - PrintFilter(filter, i + 1); + print_filter(filter, i + 1); printf("\n\n"); } @@ -1190,7 +1237,7 @@ int get_next_filter_idx(config__t* cfg) { for (int i = 0; i < MAX_FILTERS; i++) { - filter_t* filter = &cfg->filters[i]; + filter_rule_cfg_t* filter = &cfg->filters[i]; if (filter->set) { diff --git a/src/loader/utils/config.h b/src/loader/utils/config.h index 52907df..9f280ba 100644 --- a/src/loader/utils/config.h +++ b/src/loader/utils/config.h @@ -13,6 +13,75 @@ #define CONFIG_DEFAULT_PATH "/etc/xdpfw/xdpfw.conf" +struct filter_rule_ip_opts +{ + const char* src_ip; + const char* dst_ip; + + const char* src_ip6; + const char* dst_ip6; + + int min_ttl; + int max_ttl; + + int min_len; + int max_len; + + int tos; +} typedef filter_rule_ip_opts_t; + +struct filter_rule_filter_tcp +{ + int enabled; + + int sport; + int dport; + + int urg; + int ack; + int rst; + int psh; + int syn; + int fin; + int ece; + int cwr; +} typedef filter_rule_filter_tcp_t; + +struct filter_rule_filter_udp +{ + int enabled; + + int sport; + int dport; +} typedef filter_rule_filter_udp_t; + +struct filter_rule_filter_icmp +{ + int enabled; + + int code; + int type; +} typedef filter_rule_filter_icmp_t; + +struct filter_rule_cfg +{ + int set; + int log; + int enabled; + + int action; + int block_time; + + s64 pps; + s64 bps; + + filter_rule_ip_opts_t ip; + + filter_rule_filter_tcp_t tcp; + filter_rule_filter_udp_t udp; + filter_rule_filter_icmp_t icmp; +} typedef filter_rule_cfg_t; + struct config { int verbose; @@ -24,7 +93,7 @@ struct config unsigned int stats_per_second : 1; int stdout_update_time; - filter_t filters[MAX_FILTERS]; + filter_rule_cfg_t filters[MAX_FILTERS]; const char* drop_ranges[MAX_IP_RANGES]; } typedef config__t; // config_t is taken by libconfig -.- @@ -41,10 +110,10 @@ struct config_overrides } typedef config_overrides_t; void set_cfg_defaults(config__t *cfg); -void set_filter_defaults(filter_t* filter); +void set_filter_defaults(filter_rule_cfg_t* filter); void print_cfg(config__t* cfg); -void PrintFilter(filter_t* filter, int idx); +void print_filter(filter_rule_cfg_t* filter, int idx); int load_cfg(config__t *cfg, const char* cfg_file, config_overrides_t* overrides); int save_cfg(config__t* cfg, const char* file_path); diff --git a/src/loader/utils/logging.c b/src/loader/utils/logging.c index dce1917..0505ac7 100644 --- a/src/loader/utils/logging.c +++ b/src/loader/utils/logging.c @@ -134,7 +134,7 @@ int hdl_filters_rb_event(void* ctx, void* data, size_t sz) config__t* cfg = (config__t*)ctx; filter_log_event_t* e = (filter_log_event_t*)data; - filter_t* filter = &cfg->filters[e->filter_id]; + filter_rule_cfg_t* filter = &cfg->filters[e->filter_id]; if (filter == NULL) { diff --git a/src/loader/utils/xdp.c b/src/loader/utils/xdp.c index eb62931..3a66c3d 100644 --- a/src/loader/utils/xdp.c +++ b/src/loader/utils/xdp.c @@ -45,7 +45,7 @@ int get_map_fd(struct xdp_program *prog, const char *map_name) * * @return void */ -static int LibBPFSilent(enum libbpf_print_level level, const char *format, va_list args) +static int libbpf_silent(enum libbpf_print_level level, const char *format, va_list args) { return 0; } @@ -61,7 +61,7 @@ void set_libbpf_log_mode(int silent) { if (silent) { - libbpf_set_print(LibBPFSilent); + libbpf_set_print(libbpf_silent); } } @@ -221,21 +221,239 @@ void delete_filters(int map_filters) * Updates a filter rule. * * @param map_filters The filters BPF map FD. - * @param filter A pointer to the filter. + * @param filter_cfg A pointer to the filter config rule. * @param idx The filter index to insert or update. * * @return 0 on success or error value of bpf_map_update_elem(). */ -int update_filter(int map_filters, filter_t* filter, int idx) +int update_filter(int map_filters, filter_rule_cfg_t* filter_cfg, int idx) { - int ret; + filter_t filter = {0}; + + filter.set = filter_cfg->set; + + if (filter_cfg->enabled > -1) + { + filter.enabled = filter_cfg->enabled; + } + + if (filter_cfg->log > -1) + { + filter.log = filter_cfg->log; + } + + if (filter_cfg->action > -1) + { + filter.action = filter_cfg->action; + } + + if (filter_cfg->block_time > -1) + { + filter.block_time = filter_cfg->block_time; + } + + if (filter_cfg->pps > -1) + { + filter.do_pps = 1; + + filter.pps = (u64) filter_cfg->pps; + } + + if (filter_cfg->bps > -1) + { + filter.do_bps = 1; + + filter.bps = (u64) filter_cfg->bps; + } + + if (filter_cfg->ip.src_ip) + { + ip_range_t ip_range = parse_ip_range(filter_cfg->ip.src_ip); + + filter.ip.src_ip = ip_range.ip; + filter.ip.src_cidr = ip_range.cidr; + } + + if (filter_cfg->ip.dst_ip) + { + ip_range_t ip_range = parse_ip_range(filter_cfg->ip.dst_ip); + + filter.ip.dst_ip = ip_range.ip; + filter.ip.dst_cidr = ip_range.cidr; + } + + if (filter_cfg->ip.src_ip6) + { + struct in6_addr in; + + inet_pton(AF_INET6, filter_cfg->ip.src_ip6, &in); + + memcpy(filter.ip.src_ip6, in.__in6_u.__u6_addr32, 4); + } + + if (filter_cfg->ip.dst_ip6) + { + struct in6_addr in; + + inet_pton(AF_INET6, filter_cfg->ip.dst_ip6, &in); + + memcpy(filter.ip.dst_ip6, in.__in6_u.__u6_addr32, 4); + } + + if (filter_cfg->ip.min_ttl > -1) + { + filter.ip.do_min_ttl = 1; + + filter.ip.min_ttl = filter_cfg->ip.min_ttl; + } + + if (filter_cfg->ip.max_ttl > -1) + { + filter.ip.do_max_ttl = 1; + + filter.ip.max_ttl = filter_cfg->ip.max_ttl; + } + + if (filter_cfg->ip.min_len > -1) + { + filter.ip.do_min_len = 1; + + filter.ip.min_len = filter_cfg->ip.min_len; + } + + if (filter_cfg->ip.max_len > -1) + { + filter.ip.do_max_len = 1; + + filter.ip.max_len = filter_cfg->ip.max_len; + } + + if (filter_cfg->ip.tos > -1) + { + filter.ip.do_tos = 1; + + filter.ip.tos = filter_cfg->ip.tos; + } + + if (filter_cfg->tcp.enabled > -1) + { + filter.tcp.enabled = filter_cfg->tcp.enabled; + } + + if (filter_cfg->tcp.sport > -1) + { + filter.tcp.do_sport = 1; + + filter.tcp.sport = htons((u16)filter_cfg->tcp.sport); + } + + if (filter_cfg->tcp.dport > -1) + { + filter.tcp.do_dport = 1; + + filter.tcp.dport = htons((u16)filter_cfg->tcp.dport); + } + + if (filter_cfg->tcp.urg > -1) + { + filter.tcp.do_urg = 1; + + filter.tcp.urg = filter_cfg->tcp.urg; + } + + if (filter_cfg->tcp.ack > -1) + { + filter.tcp.do_ack = 1; + + filter.tcp.ack = filter_cfg->tcp.ack; + } + + if (filter_cfg->tcp.rst > -1) + { + filter.tcp.do_rst = 1; + + filter.tcp.rst = filter_cfg->tcp.rst; + } + + if (filter_cfg->tcp.psh > -1) + { + filter.tcp.do_psh = 1; + + filter.tcp.psh = filter_cfg->tcp.psh; + } + + if (filter_cfg->tcp.syn > -1) + { + filter.tcp.do_syn = 1; + + filter.tcp.syn = filter_cfg->tcp.syn; + } + + if (filter_cfg->tcp.fin > -1) + { + filter.tcp.do_fin = 1; + + filter.tcp.fin = filter_cfg->tcp.fin; + } + + if (filter_cfg->tcp.ece > -1) + { + filter.tcp.do_ece = 1; + + filter.tcp.ece = filter_cfg->tcp.ece; + } + + if (filter_cfg->tcp.cwr > -1) + { + filter.tcp.do_cwr = 1; + + filter.tcp.cwr = filter_cfg->tcp.cwr; + } + + if (filter_cfg->udp.enabled > -1) + { + filter.udp.enabled = filter_cfg->udp.enabled; + } + + if (filter_cfg->udp.sport > -1) + { + filter.udp.do_sport = 1; + + filter.udp.sport = htons((u16)filter_cfg->udp.sport); + } + + if (filter_cfg->udp.dport > -1) + { + filter.udp.do_dport = 1; + + filter.udp.dport = htons((u16)filter_cfg->udp.dport); + } + + if (filter_cfg->icmp.enabled > -1) + { + filter.icmp.enabled = filter_cfg->icmp.enabled; + } + + if (filter_cfg->icmp.code > -1) + { + filter.icmp.do_code = 1; + + filter.icmp.code = filter_cfg->icmp.code; + } + + if (filter_cfg->icmp.type > -1) + { + filter.icmp.do_type = 1; + + filter.icmp.type = filter_cfg->icmp.type; + } filter_t filter_cpus[MAX_CPUS]; memset(filter_cpus, 0, sizeof(filter_cpus)); for (int j = 0; j < MAX_CPUS; j++) { - filter_cpus[j] = *filter; + filter_cpus[j] = filter; } return bpf_map_update_elem(map_filters, &idx, &filter_cpus, BPF_ANY); @@ -261,7 +479,7 @@ void update_filters(int map_filters, config__t *cfg) // 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. delete_filter(map_filters, i); - filter_t* filter = &cfg->filters[i]; + filter_rule_cfg_t* filter = &cfg->filters[i]; // Only insert set and enabled filters. if (!filter->set || !filter->enabled) diff --git a/src/loader/utils/xdp.h b/src/loader/utils/xdp.h index a750c2b..d75ce36 100644 --- a/src/loader/utils/xdp.h +++ b/src/loader/utils/xdp.h @@ -21,7 +21,7 @@ int attach_xdp(struct xdp_program *prog, char** mode, int ifidx, int detach, int int delete_filter(int map_filters, u32 idx); void delete_filters(int map_filters); -int update_filter(int map_filters, filter_t* filter, int idx); +int update_filter(int map_filters, filter_rule_cfg_t* filter, int idx); void update_filters(int map_filters, config__t *cfg); int pin_bpf_map(struct bpf_object* obj, const char* pin_dir, const char* map_name); diff --git a/src/rule_add/prog.c b/src/rule_add/prog.c index cfe6a48..9112cd0 100644 --- a/src/rule_add/prog.c +++ b/src/rule_add/prog.c @@ -158,7 +158,7 @@ int main(int argc, char *argv[]) printf("Using 'map_filters' FD => %d...\n", map_filters); // Create new base filter and set its defaults. - filter_t new_filter = {0}; + filter_rule_cfg_t new_filter = {0}; set_filter_defaults(&new_filter); new_filter.set = 1; @@ -205,189 +205,144 @@ int main(int argc, char *argv[]) if (cli.src_ip) { - ip_range_t range = parse_ip_range(cli.src_ip); - - new_filter.src_ip = range.ip; - new_filter.src_cidr = range.cidr; + new_filter.ip.src_ip = cli.src_ip; } if (cli.dst_ip) { - ip_range_t range = parse_ip_range(cli.dst_ip); - - new_filter.dst_ip = range.ip; - new_filter.dst_cidr = range.cidr; + new_filter.ip.dst_ip = cli.dst_ip; } if (cli.src_ip6) { - struct in6_addr addr; - - if ((ret = inet_pton(AF_INET6, cli.src_ip6, &addr)) != 1) - { - fprintf(stderr, "Failed to convert source IPv6 address to decimal (%d).\n", ret); - - return EXIT_FAILURE; - } - - memcpy(new_filter.src_ip6, addr.s6_addr, sizeof(new_filter.src_ip6)); + new_filter.ip.src_ip6 = cli.src_ip6; } if (cli.dst_ip6) { - struct in6_addr addr; - - if ((ret = inet_pton(AF_INET6, cli.dst_ip6, &addr)) != 1) - { - fprintf(stderr, "Failed to convert destination IPv6 address to decimal (%d).\n", ret); - - return EXIT_FAILURE; - } - - memcpy(new_filter.dst_ip6, addr.s6_addr, sizeof(new_filter.dst_ip6)); + new_filter.ip.dst_ip6 = cli.dst_ip6; } // To Do: See if I can create a macro for below. // As long as the naming convention lines up, it should be easily possible. if (cli.pps > -1) { - new_filter.do_pps = 1; new_filter.pps = cli.pps; } if (cli.bps > -1) { - new_filter.do_bps = 1; new_filter.bps = cli.bps; } if (cli.min_ttl > -1) { - new_filter.do_min_ttl = 1; - new_filter.min_ttl = cli.min_ttl; + new_filter.ip.min_ttl = cli.min_ttl; } if (cli.max_ttl > -1) { - new_filter.do_max_ttl = 1; - new_filter.max_ttl = cli.max_ttl; + new_filter.ip.max_ttl = cli.max_ttl; } if (cli.min_len > -1) { - new_filter.do_min_len = 1; - new_filter.min_len = cli.min_len; + new_filter.ip.min_len = cli.min_len; } if (cli.max_len > -1) { - new_filter.do_max_len = 1; - new_filter.max_len = cli.max_len; + new_filter.ip.max_len = cli.max_len; } if (cli.tos > -1) { - new_filter.do_tos = 1; - new_filter.tos = cli.tos; + new_filter.ip.tos = cli.tos; } if (cli.tcp_enabled > -1) { - new_filter.tcpopts.enabled = cli.tcp_enabled; + new_filter.tcp.enabled = cli.tcp_enabled; } if (cli.tcp_sport > -1) { - new_filter.tcpopts.do_sport = 1; - new_filter.tcpopts.sport = cli.tcp_sport; + new_filter.tcp.sport = cli.tcp_sport; } if (cli.tcp_dport > -1) { - new_filter.tcpopts.do_dport = 1; - new_filter.tcpopts.dport = cli.tcp_dport; + new_filter.tcp.dport = cli.tcp_dport; } if (cli.tcp_urg > -1) { - new_filter.tcpopts.do_urg = 1; - new_filter.tcpopts.urg = cli.tcp_urg; + new_filter.tcp.urg = cli.tcp_urg; } if (cli.tcp_ack > -1) { - new_filter.tcpopts.do_ack = 1; - new_filter.tcpopts.ack = cli.tcp_ack; + new_filter.tcp.ack = cli.tcp_ack; } if (cli.tcp_rst > -1) { - new_filter.tcpopts.do_rst = 1; - new_filter.tcpopts.rst = cli.tcp_rst; + new_filter.tcp.rst = cli.tcp_rst; } if (cli.tcp_psh > -1) { - new_filter.tcpopts.do_psh = 1; - new_filter.tcpopts.psh = cli.tcp_psh; + new_filter.tcp.psh = cli.tcp_psh; } if (cli.tcp_syn > -1) { - new_filter.tcpopts.do_syn = 1; - new_filter.tcpopts.syn = cli.tcp_syn; + new_filter.tcp.syn = cli.tcp_syn; } if (cli.tcp_fin > -1) { - new_filter.tcpopts.do_fin = 1; - new_filter.tcpopts.fin = cli.tcp_fin; + new_filter.tcp.fin = cli.tcp_fin; } if (cli.tcp_ece > -1) { - new_filter.tcpopts.do_ece = 1; - new_filter.tcpopts.ece = cli.tcp_ece; + new_filter.tcp.ece = cli.tcp_ece; } if (cli.tcp_cwr > -1) { - new_filter.tcpopts.do_cwr = 1; - new_filter.tcpopts.cwr = cli.tcp_cwr; + new_filter.tcp.cwr = cli.tcp_cwr; } if (cli.udp_enabled > -1) { - new_filter.udpopts.enabled = cli.udp_enabled; + new_filter.udp.enabled = cli.udp_enabled; } if (cli.udp_sport > -1) { - new_filter.udpopts.do_sport = 1; - new_filter.udpopts.sport = cli.udp_sport; + new_filter.udp.sport = cli.udp_sport; } if (cli.udp_dport > -1) { - new_filter.udpopts.do_dport = 1; - new_filter.udpopts.dport = cli.udp_dport; + new_filter.udp.dport = cli.udp_dport; } if (cli.icmp_enabled > -1) { - new_filter.icmpopts.enabled = cli.icmp_enabled; + new_filter.icmp.enabled = cli.icmp_enabled; } if (cli.icmp_code > -1) { - new_filter.icmpopts.do_code = 1; - new_filter.icmpopts.code = cli.icmp_code; + new_filter.icmp.code = cli.icmp_code; } if (cli.icmp_type > -1) { - new_filter.icmpopts.do_type = 1; - new_filter.icmpopts.type = cli.icmp_type; + new_filter.icmp.type = cli.icmp_type; } // Set filter at index. diff --git a/src/rule_del/prog.c b/src/rule_del/prog.c index 38d1971..625adda 100644 --- a/src/rule_del/prog.c +++ b/src/rule_del/prog.c @@ -99,7 +99,7 @@ int main(int argc, char *argv[]) // So we need to loop through each and ignore disabled rules. for (int i = 0; i < MAX_FILTERS; i++) { - filter_t* filter = &cfg.filters[i]; + filter_rule_cfg_t* filter = &cfg.filters[i]; if (!filter->set || !filter->enabled) { diff --git a/src/xdp/prog.c b/src/xdp/prog.c index 1d9ce0e..2f4302e 100644 --- a/src/xdp/prog.c +++ b/src/xdp/prog.c @@ -299,44 +299,44 @@ int xdp_prog_main(struct xdp_md *ctx) if (iph6) { // Source address. - if (filter->src_ip6[0] != 0 && (iph6->saddr.in6_u.u6_addr32[0] != filter->src_ip6[0] || iph6->saddr.in6_u.u6_addr32[1] != filter->src_ip6[1] || iph6->saddr.in6_u.u6_addr32[2] != filter->src_ip6[2] || iph6->saddr.in6_u.u6_addr32[3] != filter->src_ip6[3])) + if (filter->ip.src_ip6[0] != 0 && (iph6->saddr.in6_u.u6_addr32[0] != filter->ip.src_ip6[0] || iph6->saddr.in6_u.u6_addr32[1] != filter->ip.src_ip6[1] || iph6->saddr.in6_u.u6_addr32[2] != filter->ip.src_ip6[2] || iph6->saddr.in6_u.u6_addr32[3] != filter->ip.src_ip6[3])) { continue; } // Destination address. - if (filter->dst_ip6[0] != 0 && (iph6->daddr.in6_u.u6_addr32[0] != filter->dst_ip6[0] || iph6->daddr.in6_u.u6_addr32[1] != filter->dst_ip6[1] || iph6->daddr.in6_u.u6_addr32[2] != filter->dst_ip6[2] || iph6->daddr.in6_u.u6_addr32[3] != filter->dst_ip6[3])) + if (filter->ip.dst_ip6[0] != 0 && (iph6->daddr.in6_u.u6_addr32[0] != filter->ip.dst_ip6[0] || iph6->daddr.in6_u.u6_addr32[1] != filter->ip.dst_ip6[1] || iph6->daddr.in6_u.u6_addr32[2] != filter->ip.dst_ip6[2] || iph6->daddr.in6_u.u6_addr32[3] != filter->ip.dst_ip6[3])) { continue; } #ifdef ALLOW_SINGLE_IP_V4_V6 - if (filter->src_ip != 0 || filter->dst_ip != 0) + if (filter->ip.src_ip != 0 || filter->ip.dst_ip != 0) { continue; } #endif // Max TTL length. - if (filter->do_max_ttl && filter->max_ttl > iph6->hop_limit) + if (filter->ip.do_max_ttl && filter->ip.max_ttl > iph6->hop_limit) { continue; } // Min TTL length. - if (filter->do_min_ttl && filter->min_ttl < iph6->hop_limit) + if (filter->ip.do_min_ttl && filter->ip.min_ttl < iph6->hop_limit) { continue; } // Max packet length. - if (filter->do_max_len && filter->max_len > (ntohs(iph6->payload_len) + sizeof(struct ethhdr))) + if (filter->ip.do_max_len && filter->ip.max_len > (ntohs(iph6->payload_len) + sizeof(struct ethhdr))) { continue; } // Min packet length. - if (filter->do_min_len && filter->min_len < (ntohs(iph6->payload_len) + sizeof(struct ethhdr))) + if (filter->ip.do_min_len && filter->ip.min_len < (ntohs(iph6->payload_len) + sizeof(struct ethhdr))) { continue; } @@ -344,68 +344,66 @@ int xdp_prog_main(struct xdp_md *ctx) else if (iph) { // Source address. - if (filter->src_ip) + if (filter->ip.src_ip) { - if (filter->src_cidr == 32 && iph->saddr != filter->src_ip) + if (filter->ip.src_cidr == 32 && iph->saddr != filter->ip.src_ip) { continue; } - if (!is_ip_in_range(iph->saddr, filter->src_ip, filter->src_cidr)) + if (!is_ip_in_range(iph->saddr, filter->ip.src_ip, filter->ip.src_cidr)) { continue; } - - } // Destination address. - if (filter->dst_ip) + if (filter->ip.dst_ip) { - if (filter->dst_cidr == 32 && iph->daddr != filter->dst_ip) + if (filter->ip.dst_cidr == 32 && iph->daddr != filter->ip.dst_ip) { continue; } - if (!is_ip_in_range(iph->daddr, filter->dst_ip, filter->dst_cidr)) + if (!is_ip_in_range(iph->daddr, filter->ip.dst_ip, filter->ip.dst_cidr)) { continue; } } #ifdef ALLOW_SINGLE_IP_V4_V6 - if ((filter->src_ip6[0] != 0 || filter->src_ip6[1] != 0 || filter->src_ip6[2] != 0 || filter->src_ip6[3] != 0) || (filter->dst_ip6[0] != 0 || filter->dst_ip6[1] != 0 || filter->dst_ip6[2] != 0 || filter->dst_ip6[3] != 0)) + if ((filter->ip.src_ip6[0] != 0 || filter->ip.src_ip6[1] != 0 || filter->ip.src_ip6[2] != 0 || filter->ip.src_ip6[3] != 0) || (filter->ip.dst_ip6[0] != 0 || filter->ip.dst_ip6[1] != 0 || filter->ip.dst_ip6[2] != 0 || filter->ip.dst_ip6[3] != 0)) { continue; } #endif // TOS. - if (filter->do_tos && filter->tos != iph->tos) + if (filter->ip.do_tos && filter->ip.tos != iph->tos) { continue; } // Max TTL length. - if (filter->do_max_ttl && filter->max_ttl < iph->ttl) + if (filter->ip.do_max_ttl && filter->ip.max_ttl < iph->ttl) { continue; } // Min TTL length. - if (filter->do_min_ttl && filter->min_ttl > iph->ttl) + if (filter->ip.do_min_ttl && filter->ip.min_ttl > iph->ttl) { continue; } // Max packet length. - if (filter->do_max_len && filter->max_len < (ntohs(iph->tot_len) + sizeof(struct ethhdr))) + if (filter->ip.do_max_len && filter->ip.max_len < (ntohs(iph->tot_len) + sizeof(struct ethhdr))) { continue; } // Min packet length. - if (filter->do_min_len && filter->min_len > (ntohs(iph->tot_len) + sizeof(struct ethhdr))) + if (filter->ip.do_min_len && filter->ip.min_len > (ntohs(iph->tot_len) + sizeof(struct ethhdr))) { continue; } @@ -424,7 +422,7 @@ int xdp_prog_main(struct xdp_md *ctx) } // Do TCP options. - if (filter->tcpopts.enabled) + if (filter->tcp.enabled) { if (!tcph) { @@ -432,66 +430,66 @@ int xdp_prog_main(struct xdp_md *ctx) } // Source port. - if (filter->tcpopts.do_sport && htons(filter->tcpopts.sport) != tcph->source) + if (filter->tcp.do_sport && filter->tcp.sport != tcph->source) { continue; } // Destination port. - if (filter->tcpopts.do_dport && htons(filter->tcpopts.dport) != tcph->dest) + if (filter->tcp.do_dport && filter->tcp.dport != tcph->dest) { continue; } // URG flag. - if (filter->tcpopts.do_urg && filter->tcpopts.urg != tcph->urg) + if (filter->tcp.do_urg && filter->tcp.urg != tcph->urg) { continue; } // ACK flag. - if (filter->tcpopts.do_ack && filter->tcpopts.ack != tcph->ack) + if (filter->tcp.do_ack && filter->tcp.ack != tcph->ack) { continue; } // RST flag. - if (filter->tcpopts.do_rst && filter->tcpopts.rst != tcph->rst) + if (filter->tcp.do_rst && filter->tcp.rst != tcph->rst) { continue; } // PSH flag. - if (filter->tcpopts.do_psh && filter->tcpopts.psh != tcph->psh) + if (filter->tcp.do_psh && filter->tcp.psh != tcph->psh) { continue; } // SYN flag. - if (filter->tcpopts.do_syn && filter->tcpopts.syn != tcph->syn) + if (filter->tcp.do_syn && filter->tcp.syn != tcph->syn) { continue; } // FIN flag. - if (filter->tcpopts.do_fin && filter->tcpopts.fin != tcph->fin) + if (filter->tcp.do_fin && filter->tcp.fin != tcph->fin) { continue; } // ECE flag. - if (filter->tcpopts.do_ece && filter->tcpopts.ece != tcph->ece) + if (filter->tcp.do_ece && filter->tcp.ece != tcph->ece) { continue; } // CWR flag. - if (filter->tcpopts.do_cwr && filter->tcpopts.cwr != tcph->cwr) + if (filter->tcp.do_cwr && filter->tcp.cwr != tcph->cwr) { continue; } } - else if (filter->udpopts.enabled) + else if (filter->udp.enabled) { if (!udph) { @@ -499,30 +497,30 @@ int xdp_prog_main(struct xdp_md *ctx) } // Source port. - if (filter->udpopts.do_sport && htons(filter->udpopts.sport) != udph->source) + if (filter->udp.do_sport && filter->udp.sport != udph->source) { continue; } // Destination port. - if (filter->udpopts.do_dport && htons(filter->udpopts.dport) != udph->dest) + if (filter->udp.do_dport && filter->udp.dport != udph->dest) { continue; } } - else if (filter->icmpopts.enabled) + else if (filter->icmp.enabled) { if (icmph) { // Code. - if (filter->icmpopts.do_code && filter->icmpopts.code != icmph->code) + if (filter->icmp.do_code && filter->icmp.code != icmph->code) { continue; } // Type. - if (filter->icmpopts.do_type && filter->icmpopts.type != icmph->type) + if (filter->icmp.do_type && filter->icmp.type != icmph->type) { continue; } @@ -530,13 +528,13 @@ int xdp_prog_main(struct xdp_md *ctx) else if (icmp6h) { // Code. - if (filter->icmpopts.do_code && filter->icmpopts.code != icmp6h->icmp6_code) + if (filter->icmp.do_code && filter->icmp.code != icmp6h->icmp6_code) { continue; } // Type. - if (filter->icmpopts.do_type && filter->icmpopts.type != icmp6h->icmp6_type) + if (filter->icmp.do_type && filter->icmp.type != icmp6h->icmp6_type) { continue; }