diff --git a/scanner/CMakeLists.txt b/scanner/CMakeLists.txt index 827602b..f3569cc 100644 --- a/scanner/CMakeLists.txt +++ b/scanner/CMakeLists.txt @@ -4,6 +4,7 @@ add_definitions(-fPIC) include_directories(${PROJECT_SOURCE_DIR}/deps) include_directories(${PROJECT_SOURCE_DIR}/include) include_directories(${PROJECT_SOURCE_DIR}/src/inc_internal) +include_directories(${PROJECT_SOURCE_DIR}/scanner/ip_matcher) add_subdirectory(ip_matcher/IntervalIndex) diff --git a/scanner/ipport_matcher/ipport_matcher.c b/scanner/ipport_matcher/ipport_matcher.c index 65073d1..4cad90b 100644 --- a/scanner/ipport_matcher/ipport_matcher.c +++ b/scanner/ipport_matcher/ipport_matcher.c @@ -7,6 +7,7 @@ * Copyright: (c) Since 2023 Geedge Networks, Ltd. All rights reserved. *********************************************************************************************** */ +#include #include "uthash/utarray.h" #include "uthash/uthash.h" @@ -23,13 +24,15 @@ struct port_range { struct ipport_node { 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 UT_hash_handle hh; }; struct ipport_matcher { struct ipport_node *ipport_hash; + struct ip_matcher *ip_matcher; }; 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_node *node = NULL; + struct ip_rule *ip_rules = NULL; char *key = NULL; size_t key_len = 0; for (size_t i = 0; i < rule_num; i++) { - if (rules[i].ip.ip_type == IPV4) { - key = (char *)&rules[i].ip.ipv4; - key_len = 4; + if (rules[i].ip_type == IPV4) { + key = (char *)&rules[i].ipv4; + key_len = sizeof(rules[i].ipv4); } else { - key = (char *)rules[i].ip.ipv6; - key_len = 16; + key = (char *)&rules[i].ipv6; + key_len = sizeof(rules[i].ipv6); } HASH_FIND(hh, matcher->ipport_hash, key, key_len, node); if (NULL == node) { 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_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 { node->ip_type = IPV6; 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); - 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; @@ -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); } + 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; HASH_ITER(hh, matcher->ipport_hash, node, tmp_node) { 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; } @@ -125,23 +162,16 @@ int ipport_matcher_match(struct ipport_matcher *matcher, const struct ip_addr *i return -1; } - char *key = NULL; - size_t key_len = 0; + struct scan_result result; + struct ip_data ip_data = *(const struct ip_data *)ip_addr; - if (ip_addr->ip_type == IPV4) { - key = (char *)&ip_addr->ipv4; - 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) { + int n_result = ip_matcher_match(matcher->ip_matcher, &ip_data, &result, 1); + if (n_result <= 0) { return 0; } + struct ipport_node *node = result.tag; + uint16_t host_port = ntohs(port); struct port_range range; range.min_port = host_port; diff --git a/scanner/ipport_matcher/ipport_matcher.h b/scanner/ipport_matcher/ipport_matcher.h index 8dd94cc..cc088cc 100644 --- a/scanner/ipport_matcher/ipport_matcher.h +++ b/scanner/ipport_matcher/ipport_matcher.h @@ -18,12 +18,17 @@ extern "C" #include +#include "ip_matcher.h" #include "maat.h" struct ipport_rule { uuid_t rule_uuid; /* rule id */ 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 max_port; /* host order */ }; diff --git a/src/maat_ipport_plugin.c b/src/maat_ipport_plugin.c index f328d2d..3edc219 100644 --- a/src/maat_ipport_plugin.c +++ b/src/maat_ipport_plugin.c @@ -445,13 +445,15 @@ static void ipport_item_to_ipport_rule(struct ipport_item *item, struct ipport_rule *rule) { if (IPV4 == item->ip_type) { - rule->ip.ip_type= IPV4; - rule->ip.ipv4 = item->ipv4.min_ip; + rule->ip_type= IPV4; + rule->ipv4.start_ip = item->ipv4.min_ip; + rule->ipv4.end_ip = item->ipv4.max_ip; rule->min_port = item->min_port; rule->max_port = item->max_port; } else { - rule->ip.ip_type = IPV6; - memcpy(rule->ip.ipv6, item->ipv6.min_ip, sizeof(item->ipv6.min_ip)); + rule->ip_type = IPV6; + 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->max_port = item->max_port; } diff --git a/src/maat_plugin.c b/src/maat_plugin.c index 6c30b04..d3dd65f 100644 --- a/src/maat_plugin.c +++ b/src/maat_plugin.c @@ -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 n_foreign_keys = 0; - if (NULL == plugin_schema) { 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); } - return n_foreign_keys; + return plugin_schema->n_foreign; } int plugin_table_set_ex_container_schema(void *plugin_schema, int table_id, diff --git a/test/maat_framework_gtest.cpp b/test/maat_framework_gtest.cpp index 18caeb9..ef8f61b 100644 --- a/test/maat_framework_gtest.cpp +++ b/test/maat_framework_gtest.cpp @@ -5195,9 +5195,31 @@ TEST_F(IPPortPluginTable, EX_DATA) { uuid_unparse(results[0]->rule_uuid, uuid_str); 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; ipv6.ip_type = 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)); ret = maat_ipport_plugin_table_get_ex_data(maat_inst, table_name, &ipv6, port, diff --git a/test/maat_json.json b/test/maat_json.json index 513a1cf..9155994 100644 --- a/test/maat_json.json +++ b/test/maat_json.json @@ -4211,9 +4211,9 @@ "table_name": "TEST_IPPORT_PLUGIN_WITH_EXDATA", "table_content": [ {"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-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} ] }, {