ipport plugin table support CIDR

This commit is contained in:
root
2024-10-17 06:37:29 +00:00
parent cc67447c4e
commit 041c32ccaa
7 changed files with 91 additions and 33 deletions

View File

@@ -4,6 +4,7 @@ add_definitions(-fPIC)
include_directories(${PROJECT_SOURCE_DIR}/deps) include_directories(${PROJECT_SOURCE_DIR}/deps)
include_directories(${PROJECT_SOURCE_DIR}/include) include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/src/inc_internal) include_directories(${PROJECT_SOURCE_DIR}/src/inc_internal)
include_directories(${PROJECT_SOURCE_DIR}/scanner/ip_matcher)
add_subdirectory(ip_matcher/IntervalIndex) add_subdirectory(ip_matcher/IntervalIndex)

View File

@@ -7,6 +7,7 @@
* Copyright: (c) Since 2023 Geedge Networks, Ltd. All rights reserved. * Copyright: (c) Since 2023 Geedge Networks, Ltd. All rights reserved.
*********************************************************************************************** ***********************************************************************************************
*/ */
#include <assert.h>
#include "uthash/utarray.h" #include "uthash/utarray.h"
#include "uthash/uthash.h" #include "uthash/uthash.h"
@@ -23,13 +24,15 @@ struct port_range {
struct ipport_node { struct ipport_node {
int ip_type; //IPV4 or IPV6 int ip_type; //IPV4 or IPV6
uint32_t ip_addr[4]; uint32_t start_ip_addr[4];
uint32_t end_ip_addr[4];
UT_array *port_range_list; //array to store <struct port_range> UT_array *port_range_list; //array to store <struct port_range>
UT_hash_handle hh; UT_hash_handle hh;
}; };
struct ipport_matcher { struct ipport_matcher {
struct ipport_node *ipport_hash; struct ipport_node *ipport_hash;
struct ip_matcher *ip_matcher;
}; };
UT_icd ut_port_range_icd = {sizeof(struct port_range), NULL, NULL, NULL}; UT_icd ut_port_range_icd = {sizeof(struct port_range), NULL, NULL, NULL};
@@ -72,34 +75,37 @@ struct ipport_matcher *ipport_matcher_new(struct ipport_rule *rules, size_t rule
struct ipport_matcher *matcher = ALLOC(struct ipport_matcher, 1); struct ipport_matcher *matcher = ALLOC(struct ipport_matcher, 1);
struct ipport_node *node = NULL; struct ipport_node *node = NULL;
struct ip_rule *ip_rules = NULL;
char *key = NULL; char *key = NULL;
size_t key_len = 0; size_t key_len = 0;
for (size_t i = 0; i < rule_num; i++) { for (size_t i = 0; i < rule_num; i++) {
if (rules[i].ip.ip_type == IPV4) { if (rules[i].ip_type == IPV4) {
key = (char *)&rules[i].ip.ipv4; key = (char *)&rules[i].ipv4;
key_len = 4; key_len = sizeof(rules[i].ipv4);
} else { } else {
key = (char *)rules[i].ip.ipv6; key = (char *)&rules[i].ipv6;
key_len = 16; key_len = sizeof(rules[i].ipv6);
} }
HASH_FIND(hh, matcher->ipport_hash, key, key_len, node); HASH_FIND(hh, matcher->ipport_hash, key, key_len, node);
if (NULL == node) { if (NULL == node) {
node = ALLOC(struct ipport_node, 1); node = ALLOC(struct ipport_node, 1);
if (rules[i].ip.ip_type == IPV4) { if (rules[i].ip_type == IPV4) {
node->ip_type = IPV4; node->ip_type = IPV4;
node->ip_addr[0] = rules[i].ip.ipv4; node->start_ip_addr[0] = rules[i].ipv4.start_ip;
node->end_ip_addr[0] = rules[i].ipv4.end_ip;
} else { } else {
node->ip_type = IPV6; node->ip_type = IPV6;
for (size_t j = 0; j < 4; j++) { for (size_t j = 0; j < 4; j++) {
node->ip_addr[j] = rules[i].ip.ipv6[j]; node->start_ip_addr[j] = rules[i].ipv6.start_ip[j];
node->end_ip_addr[j] = rules[i].ipv6.end_ip[j];
} }
} }
utarray_new(node->port_range_list, &ut_port_range_icd); utarray_new(node->port_range_list, &ut_port_range_icd);
HASH_ADD_KEYPTR(hh, matcher->ipport_hash, (char *)node->ip_addr, key_len, node); HASH_ADD_KEYPTR(hh, matcher->ipport_hash, key, key_len, node);
} }
struct port_range range; struct port_range range;
@@ -110,11 +116,42 @@ struct ipport_matcher *ipport_matcher_new(struct ipport_rule *rules, size_t rule
utarray_push_back(node->port_range_list, &range); utarray_push_back(node->port_range_list, &range);
} }
int ip_matcher_cnt = HASH_COUNT(matcher->ipport_hash);
int ip_matcher_idx = 0;
ip_rules = ALLOC(struct ip_rule, ip_matcher_cnt);
struct ipport_node *tmp_node = NULL; struct ipport_node *tmp_node = NULL;
HASH_ITER(hh, matcher->ipport_hash, node, tmp_node) { HASH_ITER(hh, matcher->ipport_hash, node, tmp_node) {
utarray_sort(node->port_range_list, compare_port_range_for_sort); utarray_sort(node->port_range_list, compare_port_range_for_sort);
struct port_range *range = utarray_front(node->port_range_list);
ip_rules[ip_matcher_idx].type = node->ip_type;
uuid_copy(ip_rules[ip_matcher_idx].rule_uuid, range->rule_uuid);
ip_rules[ip_matcher_idx].user_tag = node;
if (node->ip_type == IPV4) {
ip_rules[ip_matcher_idx].ipv4_rule.start_ip = node->start_ip_addr[0];
ip_rules[ip_matcher_idx].ipv4_rule.end_ip = node->end_ip_addr[0];
} else {
for (size_t j = 0; j < 4; j++) {
ip_rules[ip_matcher_idx].ipv6_rule.start_ip[j] = node->start_ip_addr[j];
ip_rules[ip_matcher_idx].ipv6_rule.end_ip[j] = node->end_ip_addr[j];
}
}
ip_matcher_idx++;
} }
assert(ip_matcher_idx == ip_matcher_cnt);
size_t mem_used = 0;
struct ip_matcher *ip_matcher = ip_matcher_new(ip_rules, ip_matcher_cnt, &mem_used);
if (NULL == ip_matcher) {
FREE(ip_rules);
ipport_matcher_free(matcher);
return NULL;
}
matcher->ip_matcher = ip_matcher;
return matcher; return matcher;
} }
@@ -125,23 +162,16 @@ int ipport_matcher_match(struct ipport_matcher *matcher, const struct ip_addr *i
return -1; return -1;
} }
char *key = NULL; struct scan_result result;
size_t key_len = 0; struct ip_data ip_data = *(const struct ip_data *)ip_addr;
if (ip_addr->ip_type == IPV4) { int n_result = ip_matcher_match(matcher->ip_matcher, &ip_data, &result, 1);
key = (char *)&ip_addr->ipv4; if (n_result <= 0) {
key_len = 4;
} else {
key = (char *)ip_addr->ipv6;
key_len = 16;
}
struct ipport_node *node = NULL;
HASH_FIND(hh, matcher->ipport_hash, key, key_len, node);
if (NULL == node) {
return 0; return 0;
} }
struct ipport_node *node = result.tag;
uint16_t host_port = ntohs(port); uint16_t host_port = ntohs(port);
struct port_range range; struct port_range range;
range.min_port = host_port; range.min_port = host_port;

View File

@@ -18,12 +18,17 @@ extern "C"
#include <stddef.h> #include <stddef.h>
#include "ip_matcher.h"
#include "maat.h" #include "maat.h"
struct ipport_rule { struct ipport_rule {
uuid_t rule_uuid; /* rule id */ uuid_t rule_uuid; /* rule id */
void *user_tag; /* point to user-defined data which will return with hit results */ void *user_tag; /* point to user-defined data which will return with hit results */
struct ip_addr ip; int ip_type;
union {
struct ipv4_range ipv4;
struct ipv6_range ipv6;
};
uint16_t min_port; /* host order */ uint16_t min_port; /* host order */
uint16_t max_port; /* host order */ uint16_t max_port; /* host order */
}; };

View File

@@ -445,13 +445,15 @@ static void
ipport_item_to_ipport_rule(struct ipport_item *item, struct ipport_rule *rule) ipport_item_to_ipport_rule(struct ipport_item *item, struct ipport_rule *rule)
{ {
if (IPV4 == item->ip_type) { if (IPV4 == item->ip_type) {
rule->ip.ip_type= IPV4; rule->ip_type= IPV4;
rule->ip.ipv4 = item->ipv4.min_ip; rule->ipv4.start_ip = item->ipv4.min_ip;
rule->ipv4.end_ip = item->ipv4.max_ip;
rule->min_port = item->min_port; rule->min_port = item->min_port;
rule->max_port = item->max_port; rule->max_port = item->max_port;
} else { } else {
rule->ip.ip_type = IPV6; rule->ip_type = IPV6;
memcpy(rule->ip.ipv6, item->ipv6.min_ip, sizeof(item->ipv6.min_ip)); memcpy(rule->ipv6.start_ip, item->ipv6.min_ip, sizeof(item->ipv6.min_ip));
memcpy(rule->ipv6.end_ip, item->ipv6.max_ip, sizeof(item->ipv6.max_ip));
rule->min_port = item->min_port; rule->min_port = item->min_port;
rule->max_port = item->max_port; rule->max_port = item->max_port;
} }

View File

@@ -224,8 +224,6 @@ void plugin_table_all_callback_finish(struct plugin_schema *plugin_schema)
int plugin_table_get_foreign_names(struct plugin_schema *plugin_schema, char foreign_names[MAX_FOREIGN_CLMN_NUM][MAX_FOREIGN_NAME_LEN + 1]) int plugin_table_get_foreign_names(struct plugin_schema *plugin_schema, char foreign_names[MAX_FOREIGN_CLMN_NUM][MAX_FOREIGN_NAME_LEN + 1])
{ {
int n_foreign_keys = 0;
if (NULL == plugin_schema) { if (NULL == plugin_schema) {
return -1; return -1;
} }
@@ -234,7 +232,7 @@ int plugin_table_get_foreign_names(struct plugin_schema *plugin_schema, char for
strncpy(foreign_names[i], plugin_schema->foreign_names[i], MAX_FOREIGN_NAME_LEN); strncpy(foreign_names[i], plugin_schema->foreign_names[i], MAX_FOREIGN_NAME_LEN);
} }
return n_foreign_keys; return plugin_schema->n_foreign;
} }
int plugin_table_set_ex_container_schema(void *plugin_schema, int table_id, int plugin_table_set_ex_container_schema(void *plugin_schema, int table_id,

View File

@@ -5195,9 +5195,31 @@ TEST_F(IPPortPluginTable, EX_DATA) {
uuid_unparse(results[0]->rule_uuid, uuid_str); uuid_unparse(results[0]->rule_uuid, uuid_str);
EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000103"); EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000103");
ret = inet_pton(AF_INET, "192.168.100.4", &ipv4.ipv4);
EXPECT_EQ(ret, 1);
port = htons(150);
memset(results, 0, sizeof(results));
ret = maat_ipport_plugin_table_get_ex_data(maat_inst, table_name, &ipv4, port,
(void **)results, ARRAY_SIZE);
EXPECT_EQ(ret, 1);
uuid_unparse(results[0]->rule_uuid, uuid_str);
EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000102");
struct ip_addr ipv6; struct ip_addr ipv6;
ipv6.ip_type = IPv6; ipv6.ip_type = IPv6;
inet_pton(AF_INET6, "2001:db8:1234::5210", ipv6.ipv6); inet_pton(AF_INET6, "2001:db8:1234::5210", ipv6.ipv6);
port = htons(255);
memset(results, 0, sizeof(results));
ret = maat_ipport_plugin_table_get_ex_data(maat_inst, table_name, &ipv6, port,
(void**)results, ARRAY_SIZE);
EXPECT_EQ(ret, 1);
uuid_unparse(results[0]->rule_uuid, uuid_str);
EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000104");
ipv6.ip_type = IPv6;
inet_pton(AF_INET6, "2001:db8:1234::5213", ipv6.ipv6);
port = htons(255);
memset(results, 0, sizeof(results)); memset(results, 0, sizeof(results));
ret = maat_ipport_plugin_table_get_ex_data(maat_inst, table_name, &ipv6, port, ret = maat_ipport_plugin_table_get_ex_data(maat_inst, table_name, &ipv6, port,

View File

@@ -4211,9 +4211,9 @@
"table_name": "TEST_IPPORT_PLUGIN_WITH_EXDATA", "table_name": "TEST_IPPORT_PLUGIN_WITH_EXDATA",
"table_content": [ "table_content": [
{"uuid":"00000000-0000-0000-0000-000000000101", "ip":"192.168.100.1", "port":"0-255", "is_valid":1}, {"uuid":"00000000-0000-0000-0000-000000000101", "ip":"192.168.100.1", "port":"0-255", "is_valid":1},
{"uuid":"00000000-0000-0000-0000-000000000102", "ip":"192.168.100.2", "port":"100-200", "is_valid":1}, {"uuid":"00000000-0000-0000-0000-000000000102", "ip":"192.168.100.2-192.168.100.5", "port":"100-200", "is_valid":1},
{"uuid":"00000000-0000-0000-0000-000000000103", "ip":"192.168.100.1", "port":"255-300", "is_valid":1}, {"uuid":"00000000-0000-0000-0000-000000000103", "ip":"192.168.100.1", "port":"255-300", "is_valid":1},
{"uuid":"00000000-0000-0000-0000-000000000104", "ip":"2001:db8:1234::5210", "port":"255-512", "is_valid":1} {"uuid":"00000000-0000-0000-0000-000000000104", "ip":"2001:db8:1234::5210-2001:db8:1234::5215", "port":"255-512", "is_valid":1}
] ]
}, },
{ {