summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scanner/ip_matcher/IntervalIndex/SuccinctHash.cpp5
-rw-r--r--scanner/ip_matcher/ip_matcher.h121
-rw-r--r--test/CMakeLists.txt3
-rw-r--r--test/ip_matcher_gtest.cpp174
4 files changed, 231 insertions, 72 deletions
diff --git a/scanner/ip_matcher/IntervalIndex/SuccinctHash.cpp b/scanner/ip_matcher/IntervalIndex/SuccinctHash.cpp
index bfa8c78..7e1a69d 100644
--- a/scanner/ip_matcher/IntervalIndex/SuccinctHash.cpp
+++ b/scanner/ip_matcher/IntervalIndex/SuccinctHash.cpp
@@ -94,7 +94,8 @@ long long CSuccinctHash::init(unsigned int keys[], unsigned int values[], unsign
}
int tn=m_RT[(1U<<(m_hash_bits-8))].A;
- m_kv_ptr=new unsigned int[tn+1];
+ m_kv_ptr=new unsigned int[tn+2]();
+
FOR(i, tn+1) m_kv_ptr[i]=0;
FOR(i, num)
{
@@ -103,7 +104,7 @@ long long CSuccinctHash::init(unsigned int keys[], unsigned int values[], unsign
unsigned int idx=rank(h);
m_kv_ptr[idx]++;
}
- FOR(i, tn) m_kv_ptr[i+1]+=m_kv_ptr[i];
+ FOR(i, tn+1) m_kv_ptr[i+1]+=m_kv_ptr[i];
m_kv_array=new unsigned int[2*num];
FOR(i, num)
diff --git a/scanner/ip_matcher/ip_matcher.h b/scanner/ip_matcher/ip_matcher.h
index cc8287c..b542edd 100644
--- a/scanner/ip_matcher/ip_matcher.h
+++ b/scanner/ip_matcher/ip_matcher.h
@@ -27,92 +27,73 @@ extern "C"
{
#endif
- enum IP_TYPE
- {
- IPv4=4,
- IPv6=6
+ enum IP_TYPE {
+ IPv4 = 4,
+ IPv6 = 6
};
- /* ������ĵ���IPv4���� */
- struct ipv4_range
- {
- unsigned int start_ip; /* IP��Χ�½� */
- unsigned int end_ip; /* IP��Χ�Ͻ� */
+ struct ipv4_range {
+ unsigned int start_ip; /* lower boundary(network-order) */
+ unsigned int end_ip; /* upper boundary(network-order) */
};
- /* ������ĵ���IPv6���� */
- struct ipv6_range
- {
- unsigned int start_ip[4]; /* IP��Χ�½磬�� Big-Endian ģʽ�洢 */
- unsigned int end_ip[4]; /* IP��Χ�Ͻ磬�� Big-Endian ģʽ�洢 */
+ struct ipv6_range {
+ unsigned int start_ip[4]; /* lower boundary(network-order) */
+ unsigned int end_ip[4]; /* upper boundary(network-order) */
};
- /* ͨ�õ�ip�������� */
- struct ip_rule
- {
- enum IP_TYPE type; /* �������ͣ�ipv4��ipv6 */
- long long rule_id; /* ����ID */
- void* user_tag; /* �û��Զ������ݣ�����ʱ��ƥ�������� */
- union
- {
- struct ipv4_range ipv4_rule; /*������ĵ���IPv4����*/
- struct ipv6_range ipv6_rule; /*������ĵ���IPv6����*/
+ /* common type for ip rule */
+ struct ip_rule {
+ enum IP_TYPE type; /* IPv4 or IPv6 */
+ long long rule_id; /* rule id */
+ void *user_tag; /* point to user-defined data which will return with hit results */
+ union {
+ struct ipv4_range ipv4_rule;
+ struct ipv6_range ipv6_rule;
};
};
- /* ͨ�õĴ�ɨ���������� */
- struct ip_data
- {
- enum IP_TYPE type; /* �������ͣ�ipv4��ipv6 */
- union /* ����rule_type�������ݸ�����ipv4����ipv6 */
- {
- unsigned int ipv4; /* ipv4����*/
- unsigned int ipv6[4]; /* ipv6���ݣ��� Big-Endian ģʽ�洢*/
+ /* common type for scan data */
+ struct ip_data {
+ enum IP_TYPE type; /* IPv4 or IPv6 */
+ union {
+ unsigned int ipv4; /* network order */
+ unsigned int ipv6[4]; /* network order */
};
};
-
- /* ��������ʽ��ɨ�������� */
- struct scan_result
- {
- long long rule_id; /* �����ID */
- void * tag; /* �û��Զ������ݣ�����ʱ��ƥ�������� */
+ /* data type for scan result */
+ struct scan_result {
+ long long rule_id; /* rule id */
+ void *tag; /* point to the same address as user_tag in struct ip_rule which has same rule_id */
};
-
struct ip_matcher;
- /*
- ���ܣ���������Ĺ��������?����
- ������
- rules[in]��һ��ip����
- rule_num[in]�������������?
- mem_use[out]���ڴ�������
- ����ֵ��
- ipɨ����,���ؿ�ָ������ɨ����ʧ��
- */
- struct ip_matcher* ip_matcher_new(struct ip_rule * rules, size_t rule_num, size_t * mem_use);
-
- /*
- ���ܣ�����ipɨ�����������ip���ݽ���ɨ��
- ������
- matcher[in]��ipɨ����
- data[in]������Ĵ��?��ip����
- result[in]�����ؽ����?����
- size[in]���������Ĵ�С
- ����ֵ��
- ���н����������?<=size��������ֵΪ-1��ʾ������
-
- */
- int ip_matcher_match(struct ip_matcher* matcher, struct ip_data * data,
- struct scan_result* result, size_t size);
-
- /*
- ���ܣ�����һ��ipɨ����
- ������
- matcher[in]�������ٵ�ipɨ����ָ��
- */
- void ip_matcher_free(struct ip_matcher* matcher);
+ /**
+ * @brief create an ip_matcher instance
+ *
+ * @param rules[input]: a set of ip rules
+ * @param rule_num[input]: the number of ip rules
+ * @param mem_use[output]: memory used by ip_matcher
+ */
+ struct ip_matcher *ip_matcher_new(struct ip_rule *rules, size_t rule_num, size_t *mem_use);
+
+ /**
+ * @brief scan ip_data to find out if has matched rules in ip_matcher
+ *
+ * @param matcher[intput]: ip_matcher which created by ip_matcher_new
+ * @param data[intput]: ip_data to be scanned
+ * @param result[input]: result array to store the rule_id and user_tag if there are matching rules
+ * @param size[input]: result array size
+ */
+ int ip_matcher_match(struct ip_matcher *matcher, struct ip_data *data,
+ struct scan_result *result, size_t size);
+
+ /**
+ * @brief destroy ip_matcher instance
+ */
+ void ip_matcher_free(struct ip_matcher *matcher);
#ifdef __cplusplus
}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9c459d4..20ef57f 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -21,6 +21,9 @@ target_link_libraries(maat_framework_perf_gtest maat_frame_static gtest_static)
add_executable(adapter_hs_gtest adapter_hs_gtest.cpp)
target_link_libraries(adapter_hs_gtest maat_frame_static gtest_static)
+add_executable(ip_matcher_gtest ip_matcher_gtest.cpp)
+target_link_libraries(ip_matcher_gtest maat_frame_static gtest_static)
+
add_executable(maat_ex_data_gtest maat_ex_data_gtest.cpp)
target_link_libraries(maat_ex_data_gtest maat_frame_static gtest_static)
diff --git a/test/ip_matcher_gtest.cpp b/test/ip_matcher_gtest.cpp
new file mode 100644
index 0000000..4fbf5de
--- /dev/null
+++ b/test/ip_matcher_gtest.cpp
@@ -0,0 +1,174 @@
+#include <gtest/gtest.h>
+
+#include "log/log.h"
+#include "ip_matcher.h"
+#include "maat_utils.h"
+#include "cJSON/cJSON.h"
+
+#define MAX_ARRAY_SIZE 6
+
+struct log_handle *g_logger = NULL;
+
+TEST(ipv4_matcher_match, OneSingleIPv4Rule) {
+ const char *ip1_str = "192.168.0.1";
+ struct ip_rule rule;
+ rule.rule_id = 100;
+ rule.type = IPv4;
+ int ret = ip_format2range(4, IP_FORMAT_RANGE, ip1_str, ip1_str,
+ &rule.ipv4_rule.start_ip, &rule.ipv4_rule.end_ip);
+ size_t mem_size = 0;
+ struct ip_matcher *matcher = ip_matcher_new(&rule, 1, &mem_size);
+ ASSERT_TRUE(matcher != NULL);
+
+ struct ip_data data;
+ data.type = IPv4;
+ inet_pton(AF_INET, ip1_str, &data.ipv4);
+ data.ipv4 = ntohl(data.ipv4);
+
+ struct scan_result results[MAX_ARRAY_SIZE];
+ ret = ip_matcher_match(matcher, &data, results, MAX_ARRAY_SIZE);
+ EXPECT_EQ(ret, 1);
+ EXPECT_EQ(results[0].rule_id, 100);
+}
+
+TEST(ipv4_matcher_match, MultiSingleIPv4Rule) {
+ const char *ip1_str = "192.168.0.1";
+ const char *ip2_str = "192.168.0.2";
+ const char *ip3_str = "192.168.0.3";
+ struct ip_rule rule[3];
+ rule[0].rule_id = 100;
+ rule[0].type = IPv4;
+ int ret = ip_format2range(4, IP_FORMAT_RANGE, ip1_str, ip1_str,
+ &rule[0].ipv4_rule.start_ip, &rule[0].ipv4_rule.end_ip);
+ EXPECT_EQ(ret, 0);
+
+ rule[1].rule_id = 200;
+ rule[1].type = IPv4;
+ ret = ip_format2range(4, IP_FORMAT_RANGE, ip2_str, ip2_str,
+ &rule[1].ipv4_rule.start_ip, &rule[1].ipv4_rule.end_ip);
+ EXPECT_EQ(ret, 0);
+
+ rule[2].rule_id = 300;
+ rule[2].type = IPv4;
+ ret = ip_format2range(4, IP_FORMAT_RANGE, ip3_str, ip3_str,
+ &rule[2].ipv4_rule.start_ip, &rule[2].ipv4_rule.end_ip);
+ EXPECT_EQ(ret, 0);
+
+ size_t mem_size = 0;
+ struct ip_matcher *matcher = ip_matcher_new(rule, 3, &mem_size);
+ ASSERT_TRUE(matcher != NULL);
+
+ struct ip_data data;
+ data.type = IPv4;
+ inet_pton(AF_INET, ip1_str, &data.ipv4);
+ data.ipv4 = ntohl(data.ipv4);
+
+ struct scan_result results[MAX_ARRAY_SIZE];
+ ret = ip_matcher_match(matcher, &data, results, MAX_ARRAY_SIZE);
+ EXPECT_EQ(ret, 1);
+ EXPECT_EQ(results[0].rule_id, 100);
+
+ inet_pton(AF_INET, ip2_str, &data.ipv4);
+ data.ipv4 = ntohl(data.ipv4);
+ memset(results, 0, sizeof(results));
+ ret = ip_matcher_match(matcher, &data, results, MAX_ARRAY_SIZE);
+ EXPECT_EQ(ret, 1);
+ EXPECT_EQ(results[0].rule_id, 200);
+
+ inet_pton(AF_INET, ip3_str, &data.ipv4);
+ data.ipv4 = ntohl(data.ipv4);
+ memset(results, 0, sizeof(results));
+ ret = ip_matcher_match(matcher, &data, results, MAX_ARRAY_SIZE);
+ EXPECT_EQ(ret, 1);
+ EXPECT_EQ(results[0].rule_id, 300);
+}
+
+TEST(ipv6_matcher_match, OneSingleIPv6Rule) {
+ const char *ip1_str = "1001:da8:205:1::101";
+ const char *ip2_str = "1001:da8:205:1::101";
+ struct ip_rule rule;
+ rule.rule_id = 100;
+ rule.type = IPv6;
+ int ret = ip_format2range(6, IP_FORMAT_RANGE, ip1_str, ip2_str,
+ rule.ipv6_rule.start_ip, rule.ipv6_rule.end_ip);
+ EXPECT_EQ(ret, 0);
+
+ size_t mem_size = 0;
+ struct ip_matcher *matcher = ip_matcher_new(&rule, 1, &mem_size);
+ ASSERT_TRUE(matcher != NULL);
+
+ struct ip_data data;
+ data.type = IPv6;
+ inet_pton(AF_INET6, ip1_str, data.ipv6);
+ ipv6_ntoh(data.ipv6);
+
+ struct scan_result results[MAX_ARRAY_SIZE];
+ ret = ip_matcher_match(matcher, &data, results, MAX_ARRAY_SIZE);
+ EXPECT_EQ(ret, 1);
+ EXPECT_EQ(results[0].rule_id, 100);
+}
+
+TEST(ipv6_matcher_match, MultiSingleIPv6Rule) {
+ const char *ip1_str = "1001:da8:205:1::101";
+ const char *ip2_str = "1001:da8:205:1::102";
+ const char *ip3_str = "1001:da8:205:1::103";
+ struct ip_rule rule[3];
+ rule[0].rule_id = 100;
+ rule[0].type = IPv6;
+ int ret = ip_format2range(6, IP_FORMAT_RANGE, ip1_str, ip1_str,
+ rule[0].ipv6_rule.start_ip, rule[0].ipv6_rule.end_ip);
+ EXPECT_EQ(ret, 0);
+
+ rule[1].rule_id = 200;
+ rule[1].type = IPv6;
+ ret = ip_format2range(6, IP_FORMAT_RANGE, ip2_str, ip2_str,
+ rule[1].ipv6_rule.start_ip, rule[1].ipv6_rule.end_ip);
+ EXPECT_EQ(ret, 0);
+
+ rule[2].rule_id = 300;
+ rule[2].type = IPv6;
+ ret = ip_format2range(6, IP_FORMAT_RANGE, ip3_str, ip3_str,
+ rule[2].ipv6_rule.start_ip, rule[2].ipv6_rule.end_ip);
+ EXPECT_EQ(ret, 0);
+
+ size_t mem_size = 0;
+ struct ip_matcher *matcher = ip_matcher_new(rule, 3, &mem_size);
+ ASSERT_TRUE(matcher != NULL);
+
+ struct ip_data data;
+ data.type = IPv6;
+ inet_pton(AF_INET6, ip1_str, data.ipv6);
+ ipv6_ntoh(data.ipv6);
+
+ struct scan_result results[MAX_ARRAY_SIZE];
+ ret = ip_matcher_match(matcher, &data, results, MAX_ARRAY_SIZE);
+ EXPECT_EQ(ret, 1);
+ EXPECT_EQ(results[0].rule_id, 100);
+
+ memset(results, 0, sizeof(results));
+ inet_pton(AF_INET6, ip2_str, data.ipv6);
+ ipv6_ntoh(data.ipv6);
+ ret = ip_matcher_match(matcher, &data, results, MAX_ARRAY_SIZE);
+ EXPECT_EQ(ret, 1);
+ EXPECT_EQ(results[0].rule_id, 200);
+
+ memset(results, 0, sizeof(results));
+ inet_pton(AF_INET6, ip3_str, data.ipv6);
+ ipv6_ntoh(data.ipv6);
+ ret = ip_matcher_match(matcher, &data, results, MAX_ARRAY_SIZE);
+ EXPECT_EQ(ret, 1);
+ EXPECT_EQ(results[0].rule_id, 300);
+}
+
+int main(int argc, char **argv)
+{
+ int ret = 0;
+ ::testing::InitGoogleTest(&argc, argv);
+ g_logger = log_handle_create("./ip_matcher_gtest.log", 0);
+
+ ret = RUN_ALL_TESTS();
+
+ log_handle_destroy(g_logger);
+
+ return ret;
+} \ No newline at end of file