aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2020-05-06 12:51:44 +0200
committerLuca Deri <deri@ntop.org>2020-05-06 12:51:44 +0200
commit84f66b4d6b69d2e5a98d446d70e028d6fa560413 (patch)
tree94554c50477cf42ba91f531d8c90ff502f142eb5 /src
parent7855e0318d41d567bc9dc6acb5c1bdc814728bc2 (diff)
Introduced custom protocols with IP and (optional) port support
Example - Single IP address ip:213.75.170.11@CustomProtocol - IP address with CIDR ip:213.75.170.11/32@CustomProtocol - IP address with CIDR and port ip:213.75.170.11/32:443@CustomProtocol Please note that there are some restrictions on the port usage. They have been listed in example/protos.txt
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_api.h.in15
-rw-r--r--src/lib/ndpi_main.c64
-rw-r--r--src/lib/third_party/include/ndpi_patricia.h4
-rw-r--r--src/lib/third_party/src/ndpi_patricia.c3
4 files changed, 62 insertions, 24 deletions
diff --git a/src/include/ndpi_api.h.in b/src/include/ndpi_api.h.in
index e30164dd1..a7453f2fb 100644
--- a/src/include/ndpi_api.h.in
+++ b/src/include/ndpi_api.h.in
@@ -146,6 +146,21 @@ extern "C" {
struct in_addr *pin);
/**
+ * Returns the nDPI protocol id for IP+port-based protocol detection
+ *
+ * @par ndpi_struct = the struct created for the protocol detection
+ * @par pin = IP host address (MUST BE in network byte order):
+ * See man(7) ip for details
+ * @par port = The port (MUST BE in network byte order) or
+ * 0 if ignored
+ * @return the nDPI protocol ID
+ *
+ */
+ u_int16_t ndpi_network_port_ptree_match(struct ndpi_detection_module_struct *ndpi_struct,
+ struct in_addr *pin /* network byte order */,
+ u_int16_t port /* network byte order */);
+
+ /**
* Init single protocol match
*
* @par ndpi_mod = the struct created for the protocol detection
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 31d1c6d06..e588fa939 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -1733,7 +1733,28 @@ u_int16_t ndpi_network_ptree_match(struct ndpi_detection_module_struct *ndpi_str
fill_prefix_v4(&prefix, pin, 32, ((patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
node = ndpi_patricia_search_best(ndpi_str->protocols_ptree, &prefix);
- return(node ? node->value.user_value : NDPI_PROTOCOL_UNKNOWN);
+ return(node ? node->value.uv.user_value : NDPI_PROTOCOL_UNKNOWN);
+}
+
+/* ******************************************* */
+
+u_int16_t ndpi_network_port_ptree_match(struct ndpi_detection_module_struct *ndpi_str,
+ struct in_addr *pin /* network byte order */,
+ u_int16_t port /* network byte order */) {
+ prefix_t prefix;
+ patricia_node_t *node;
+
+ /* Make sure all in network byte order otherwise compares wont work */
+ fill_prefix_v4(&prefix, pin, 32, ((patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
+ node = ndpi_patricia_search_best(ndpi_str->protocols_ptree, &prefix);
+
+ if(node) {
+ if((node->value.uv.additional_user_value == 0)
+ || (node->value.uv.additional_user_value == port))
+ return(node->value.uv.user_value);
+ }
+
+ return(NDPI_PROTOCOL_UNKNOWN);
}
/* ******************************************* */
@@ -1816,7 +1837,7 @@ int ndpi_load_ipv4_ptree(struct ndpi_detection_module_struct *ndpi_str,
pin.s_addr = inet_addr(addr);
if((node = add_to_ptree(ndpi_str->protocols_ptree, AF_INET, &pin, cidr ? atoi(cidr) : 32 /* bits */)) != NULL) {
- node->value.user_value = protocol_id; // node->value.additional_user_value = 0 /* port */;
+ node->value.uv.user_value = protocol_id, node->value.uv.additional_user_value = 0 /* port */;
num_loaded++;
}
}
@@ -1842,7 +1863,7 @@ static void ndpi_init_ptree_ipv4(struct ndpi_detection_module_struct *ndpi_str,
pin.s_addr = htonl(host_list[i].network);
if((node = add_to_ptree(ptree, AF_INET, &pin, host_list[i].cidr /* bits */)) != NULL) {
- node->value.user_value = host_list[i].value; // node->value.additional_user_value = 0;
+ node->value.uv.user_value = host_list[i].value, node->value.uv.additional_user_value = 0;
}
}
}
@@ -1885,7 +1906,7 @@ static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndp
inet_pton(AF_INET, value, &pin);
if((node = add_to_ptree(ndpi_str->protocols_ptree, AF_INET, &pin, bits)) != NULL) {
- node->value.user_value = protocol_id; // node->value.additional_user_value = port;
+ node->value.uv.user_value = protocol_id, node->value.uv.additional_user_value = htons(port);
}
return(0);
@@ -2333,7 +2354,7 @@ int ndpi_get_custom_category_match(struct ndpi_detection_module_struct *ndpi_str
node = ndpi_patricia_search_best(ndpi_str->custom_categories.ipAddresses, &prefix);
if(node) {
- *id = node->value.user_value;
+ *id = node->value.uv.user_value;
return(0);
}
@@ -4035,15 +4056,23 @@ u_int16_t ndpi_guess_host_protocol_id(struct ndpi_detection_module_struct *ndpi_
if(flow->packet.iph) {
struct in_addr addr;
-
+ u_int16_t sport, dport;
+
addr.s_addr = flow->packet.iph->saddr;
-
+
+ if((flow->l4_proto == IPPROTO_TCP) && flow->packet.tcp)
+ sport = flow->packet.tcp->source, dport = flow->packet.tcp->dest;
+ else if((flow->l4_proto == IPPROTO_UDP) && flow->packet.udp)
+ sport = flow->packet.udp->source, dport = flow->packet.udp->dest;
+ else
+ sport = dport = 0;
+
/* guess host protocol */
- ret = ndpi_network_ptree_match(ndpi_str, &addr);
+ ret = ndpi_network_port_ptree_match(ndpi_str, &addr, sport);
if(ret == NDPI_PROTOCOL_UNKNOWN) {
addr.s_addr = flow->packet.iph->daddr;
- ret = ndpi_network_ptree_match(ndpi_str, &addr);
+ ret = ndpi_network_port_ptree_match(ndpi_str, &addr, dport);
}
}
@@ -4246,7 +4275,7 @@ int ndpi_load_ip_category(struct ndpi_detection_module_struct *ndpi_str, const c
}
if((node = add_to_ptree(ndpi_str->custom_categories.ipAddresses_shadow, AF_INET, &pin, bits)) != NULL) {
- node->value.user_value = (u_int16_t)category; // node->value.additional_user_value = 0;
+ node->value.uv.user_value = (u_int16_t)category, node->value.uv.additional_user_value = 0;
}
return(0);
@@ -4451,7 +4480,7 @@ int ndpi_fill_ip_protocol_category(struct ndpi_detection_module_struct *ndpi_str
}
if(node) {
- ret->category = (ndpi_protocol_category_t) node->value.user_value;
+ ret->category = (ndpi_protocol_category_t) node->value.uv.user_value;
return(1);
}
@@ -4660,15 +4689,8 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
} else {
/* guess host protocol */
if(flow->packet.iph) {
- struct in_addr addr;
- addr.s_addr = flow->packet.iph->saddr;
- flow->guessed_host_protocol_id = ndpi_network_ptree_match(ndpi_str, &addr);
-
- if(flow->guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN) {
- addr.s_addr = flow->packet.iph->daddr;
- flow->guessed_host_protocol_id = ndpi_network_ptree_match(ndpi_str, &addr);
- }
+ flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_str, flow);
/*
We could implement a shortcut here skipping dissectors for
@@ -6513,7 +6535,7 @@ int ndpi_ptree_insert(ndpi_ptree_t *tree, const ndpi_ip_addr_t *addr,
node = ndpi_patricia_lookup(ptree, &prefix);
if(node != NULL) {
- node->value.user_value = user_data; // node->value.additional_user_value = 0;
+ node->value.uv.user_value = user_data, node->value.uv.additional_user_value = 0;
return(0);
}
@@ -6539,7 +6561,7 @@ int ndpi_ptree_match_addr(ndpi_ptree_t *tree,
node = ndpi_patricia_search_best(ptree, &prefix);
if(node) {
- *user_data = node->value.user_value;
+ *user_data = node->value.uv.user_value;
return(0);
}
diff --git a/src/lib/third_party/include/ndpi_patricia.h b/src/lib/third_party/include/ndpi_patricia.h
index ca8d5497f..572797d35 100644
--- a/src/lib/third_party/include/ndpi_patricia.h
+++ b/src/lib/third_party/include/ndpi_patricia.h
@@ -104,7 +104,9 @@ union patricia_node_value_t {
void *user_data;
/* User-defined values */
- u_int32_t user_value;
+ struct {
+ u_int16_t user_value, additional_user_value;
+ } uv;
};
typedef struct _patricia_node_t {
diff --git a/src/lib/third_party/src/ndpi_patricia.c b/src/lib/third_party/src/ndpi_patricia.c
index 617eaada9..139c17676 100644
--- a/src/lib/third_party/src/ndpi_patricia.c
+++ b/src/lib/third_party/src/ndpi_patricia.c
@@ -513,8 +513,7 @@ ndpi_patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inc
node->bit);
#endif /* PATRICIA_DEBUG */
node = node->r;
- }
- else {
+ } else {
#ifdef PATRICIA_DEBUG
if(node->prefix)
fprintf (stderr, "patricia_search_best: take left %s/%d\n",