aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_api.h2
-rw-r--r--src/include/ndpi_protocols.h1
-rw-r--r--src/include/ndpi_typedefs.h14
-rw-r--r--src/lib/ndpi_content_match.c.inc44
-rw-r--r--src/lib/ndpi_main.c53
-rw-r--r--src/lib/ndpi_utils.c169
-rw-r--r--src/lib/protocols/http.c53
-rw-r--r--src/lib/protocols/telnet.c107
-rw-r--r--src/lib/protocols/zabbix.c63
9 files changed, 437 insertions, 69 deletions
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h
index a1c33b36e..6228a6123 100644
--- a/src/include/ndpi_api.h
+++ b/src/include/ndpi_api.h
@@ -940,6 +940,8 @@ extern "C" {
const char* ndpi_data_ratio2str(float ratio);
void ndpi_data_print_window_values(struct ndpi_analyze_struct *s); /* debug */
+
+ ndpi_url_risk ndpi_validate_url(char *url);
#ifdef __cplusplus
}
#endif
diff --git a/src/include/ndpi_protocols.h b/src/include/ndpi_protocols.h
index b42eff4c4..dd41be2a3 100644
--- a/src/include/ndpi_protocols.h
+++ b/src/include/ndpi_protocols.h
@@ -211,6 +211,7 @@ void init_nest_log_sink_dissector(struct ndpi_detection_module_struct *ndpi_stru
void init_ookla_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_modbus_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_capwap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
+void init_zabbix_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_line_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_wireguard_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_targus_getdata_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 88d9d9ae4..057fa2527 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -42,6 +42,12 @@ typedef enum {
ndpi_l4_proto_tcp_and_udp,
} ndpi_l4_proto_info;
+typedef enum {
+ ndpi_url_no_problem = 0,
+ ndpi_url_possible_xss,
+ ndpi_url_possible_sql_injection
+ } ndpi_url_risk;
+
/* NDPI_VISIT */
typedef enum {
ndpi_preorder,
@@ -1168,7 +1174,7 @@ struct ndpi_flow_struct {
*/
struct {
ndpi_http_method method;
- char *url, *content_type;
+ char *url, *content_type, *user_agent;
u_int8_t num_request_headers, num_response_headers;
u_int8_t request_version; /* 0=1.0 and 1=1.1. Create an enum for this? */
u_int16_t response_status_code; /* 200, 404, etc. */
@@ -1218,6 +1224,12 @@ struct ndpi_flow_struct {
} imo;
struct {
+ u_int8_t username_detected:1, username_found:1, skip_next:1, _pad:5;
+ u_int8_t character_id;
+ char username[32];
+ } telnet;
+
+ struct {
char answer[96];
} mdns;
diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc
index 628664a65..fe2c4848c 100644
--- a/src/lib/ndpi_content_match.c.inc
+++ b/src/lib/ndpi_content_match.c.inc
@@ -8720,6 +8720,50 @@ static ndpi_protocol_match host_match[] = {
{ "dns.google", NULL, "dns\\.google" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
// { "mozilla.cloudflare-dns.com", NULL, "mozilla\\.cloudflare-dns\\.com" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE }, /* Firefox */
{ "cloudflare-dns.com", NULL, "cloudflare-dns\\.com" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "commons.host", NULL, "commons\\.host" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.li", NULL, "doh\\.li" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns9.quad9.net", NULL, "dns9\\.quad9\\.net" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.opendns.com", NULL, "doh\\.opendns\\.com" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.dns.sb", NULL, "doh\\.dns\\.sb" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.netweaver.uk", NULL, "doh\\.netweaver\\.uk" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns.dns-over-https.com", NULL, "dns\\.dns-over-https\\.com" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "jp.tiarap.org", NULL, "jp\\.tiarap\\.org" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns.dnsoverhttps.net", NULL, "dns\\.dnsoverhttps\\.net" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.powerdns.org", NULL, "doh\\.powerdns\\.org" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "adblock.mydns.network", NULL, "adblock\\.mydns\\.network" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "jp.tiar.app", NULL, "jp\\.tiar\\.app" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.crypto.sx", NULL, "doh\\.crypto\\.sx" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns.quad9.net", NULL, "dns\\.quad9\\.net" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns.containerpi.com", NULL, "dns\\.containerpi\\.com" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "ibksturm.synology.me", NULL, "ibksturm\\.synology\\.me" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.captnemo.in", NULL, "doh\\.captnemo\\.in" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns.rubyfish.cn", NULL, "dns\\.rubyfish\\.cn" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.42l.fr", NULL, "doh\\.42l\\.fr" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns-family.adguard.com", NULL, "dns-family\\.adguard\\.com" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "appliedprivacy.net", NULL, "appliedprivacy\\.net" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.cleanbrowsing.org", NULL, "doh\\.cleanbrowsing\\.org" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns10.quad9.net", NULL, "dns10\\.quad9\\.net" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh-ch.blahdns.com", NULL, "doh-ch\\.blahdns\\.com" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.seby.io", NULL, "doh\\.seby\\.io" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns.adguard.com", NULL, "dns\\.adguard\\.com" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "ibuki.cgnat.net", NULL, "ibuki\\.cgnat\\.net" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "jcdns.fun", NULL, "jcdns\\.fun" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh-2.seby.io", NULL, "doh-2\\.seby\\.io" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.tiar.app", NULL, "doh\\.tiar\\.app" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.dnswarden.com", NULL, "doh\\.dnswarden\\.com" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh-de.blahdns.com", NULL, "doh-de\\.blahdns\\.com" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh-jp.blahdns.com", NULL, "doh-jp\\.blahdns\\.com" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.appliedprivacy.net", NULL, "doh\\.appliedprivacy\\.net" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.tiarap.org", NULL, "doh\\.tiarap\\.org" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.armadillodns.net", NULL, "doh\\.armadillodns\\.net" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns-nyc.aaflalo.me", NULL, "dns-nyc\\.aaflalo\\.me" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns.aa.net.uk", NULL, "dns\\.aa\\.net\\.uk" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns.aaflalo.me", NULL, "dns\\.aaflalo\\.me" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns11.quad9.net", NULL, "dns11\\.quad9\\.net" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "dns.nextdns.io", NULL, "dns\\.nextdns\\.io" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "doh.securedns.eu", NULL, "doh\\.securedns\\.eu" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "rdns.faelix.net", NULL, "rdns\\.faelix\\.net" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "captnemo.in", NULL, "captnemo\\.in" TLD, "DNSoverHTTPS", NDPI_PROTOCOL_DNS_OVER_HTTPS, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE },
/*
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 758a125d1..6fe1e8065 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -1769,8 +1769,6 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 5246, 5247, 0, 0, 0) /* UDP */
);
-
- /* TODO: Needs a pcap file for Zabbix */
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ZABBIX,
1 /* no subprotocol */, no_master,
no_master, "Zabbix", NDPI_PROTOCOL_CATEGORY_NETWORK,
@@ -3372,6 +3370,9 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n
/* CAPWAP */
init_capwap_dissector(ndpi_str, &a, detection_bitmask);
+ /* ZABBIX */
+ init_zabbix_dissector(ndpi_str, &a, detection_bitmask);
+
/*** Put false-positive sensitive protocols at the end ***/
/* VIBER */
@@ -3410,12 +3411,16 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n
/* WireGuard VPN */
init_wireguard_dissector(ndpi_str, &a, detection_bitmask);
- /* AMAZON_VIDEO */
+ /* Amazon_Video */
init_amazon_video_dissector(ndpi_str, &a, detection_bitmask);
/* Targus Getdata */
init_targus_getdata_dissector(ndpi_str, &a, detection_bitmask);
+#ifdef CUSTOM_NDPI_PROTOCOLS
+#include "../../../nDPI-custom/custom_ndpi_main_init.c"
+#endif
+
/* ----------------------------------------------------------------- */
ndpi_str->callback_buffer_size = a;
@@ -3517,6 +3522,9 @@ static int ndpi_handle_ipv6_extension_headers(struct ndpi_detection_module_struc
}
// the other extension headers have one byte for the next header type
// and one byte for the extension header length in 8 byte steps minus the first 8 bytes
+ if (*l4len < 2) {
+ return(1);
+ }
ehdr_len = (*l4ptr)[1];
ehdr_len *= 8;
ehdr_len += 8;
@@ -3735,6 +3743,7 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str
if(flow->http.url) ndpi_free(flow->http.url);
if(flow->http.content_type) ndpi_free(flow->http.content_type);
+ if(flow->http.user_agent) ndpi_free(flow->http.user_agent);
backup = flow->num_processed_pkts;
backup1 = flow->guessed_protocol_id;
@@ -4685,7 +4694,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
} else
flow->guessed_header_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED;
- if(flow->guessed_protocol_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS-1)) {
+ if(flow->guessed_protocol_id > NDPI_MAX_SUPPORTED_PROTOCOLS) {
/* This is a custom protocol and it has priority over everything else */
ret.master_protocol = NDPI_PROTOCOL_UNKNOWN,
ret.app_protocol = flow->guessed_protocol_id ? flow->guessed_protocol_id : flow->guessed_host_protocol_id;
@@ -4721,7 +4730,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
}
}
- if(flow->guessed_host_protocol_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS-1)) {
+ if(flow->guessed_host_protocol_id > NDPI_MAX_SUPPORTED_PROTOCOLS) {
/* This is a custom protocol and it has priority over everything else */
ret.master_protocol = NDPI_PROTOCOL_UNKNOWN, ret.app_protocol = flow->guessed_host_protocol_id;
@@ -5066,15 +5075,34 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_str,
|| strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Content-type: ", 14) == 0)) {
packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[14];
packet->content_line.len = packet->line[packet->parsed_lines].len - 14;
+
+ while((packet->content_line.len > 0) && (packet->content_line.ptr[0] == ' '))
+ packet->content_line.len--, packet->content_line.ptr++;
+
packet->http_num_headers++;
}
/* "Content-Type:" header line in HTTP AGAIN. Probably a bogus response without space after ":" */
- if(packet->line[packet->parsed_lines].len > 13
- && strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Content-type:", 13) == 0) {
+ if((packet->content_line.len == 0)
+ && (packet->line[packet->parsed_lines].len > 13)
+ && (strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Content-type:", 13) == 0)) {
packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[13];
packet->content_line.len = packet->line[packet->parsed_lines].len - 13;
packet->http_num_headers++;
}
+
+ if(packet->content_line.len > 0) {
+ /* application/json; charset=utf-8 */
+ char separator[] = { ';', '\r', '\0' };
+ int i;
+
+ for(i=0; separator[i] != '\0'; i++) {
+ char *c = memchr((char*)packet->content_line.ptr, separator[i], packet->content_line.len);
+
+ if(c != NULL)
+ packet->content_line.len = c - (char*)packet->content_line.ptr;
+ }
+ }
+
/* "Accept:" header line in HTTP request. */
if(packet->line[packet->parsed_lines].len > 8
&& strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Accept: ", 8) == 0) {
@@ -6250,8 +6278,9 @@ int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_str,
void ndpi_free_flow(struct ndpi_flow_struct *flow) {
if(flow) {
- if(flow->http.url) ndpi_free(flow->http.url);
+ if(flow->http.url) ndpi_free(flow->http.url);
if(flow->http.content_type) ndpi_free(flow->http.content_type);
+ if(flow->http.user_agent) ndpi_free(flow->http.user_agent);
if(flow->l4_proto == IPPROTO_TCP) {
if(flow->l4.tcp.tls_srv_cert_fingerprint_ctx)
@@ -6462,6 +6491,11 @@ u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndp
|| (flow->protos.ssh.hassh_server[0] == '\0'))
return(1);
break;
+
+ case NDPI_PROTOCOL_TELNET:
+ if(!flow->protos.telnet.username_detected)
+ return(1);
+ break;
}
return(0);
@@ -6494,8 +6528,7 @@ const char* ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) {
/* ******************************************************************** */
ndpi_l4_proto_info ndpi_get_l4_proto_info(struct ndpi_detection_module_struct *ndpi_struct,
- u_int16_t ndpi_proto_id) {
-
+ u_int16_t ndpi_proto_id) {
if(ndpi_proto_id < ndpi_struct->ndpi_num_supported_protocols) {
u_int16_t idx = ndpi_struct->proto_defaults[ndpi_proto_id].protoIdx;
NDPI_SELECTION_BITMASK_PROTOCOL_SIZE bm = ndpi_struct->callback_buffer[idx].ndpi_selection_bitmask;
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index dbe5d7901..a8c73e67e 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -759,11 +759,11 @@ void ndpi_user_pwd_payload_copy(u_int8_t *dest, u_int dest_len,
u_int offset,
const u_int8_t *src, u_int src_len) {
u_int i, j=0, k = dest_len-1;
-
+
for(i=offset; (i<src_len) && (j<=k); i++) {
if((j == k) || (src[i] < ' '))
break;
-
+
dest[j++] = src[i];
}
@@ -857,7 +857,7 @@ int ndpi_flow2json(struct ndpi_detection_module_struct *ndpi_struct,
u_int32_t src_v4, u_int32_t dst_v4,
struct ndpi_in6_addr *src_v6, struct ndpi_in6_addr *dst_v6,
u_int16_t src_port, u_int16_t dst_port,
- ndpi_protocol l7_protocol,
+ ndpi_protocol l7_protocol,
ndpi_serializer *serializer) {
char buf[64], src_name[32], dst_name[32];
@@ -966,12 +966,20 @@ int ndpi_flow2json(struct ndpi_detection_module_struct *ndpi_struct,
ndpi_serialize_end_of_block(serializer);
break;
+ case NDPI_PROTOCOL_TELNET:
+ ndpi_serialize_start_of_block(serializer, "telnet");
+ ndpi_serialize_string_string(serializer, "username", flow->protos.telnet.username);
+ ndpi_serialize_end_of_block(serializer);
+ break;
+
case NDPI_PROTOCOL_HTTP:
ndpi_serialize_start_of_block(serializer, "http");
if(flow->host_server_name[0] != '\0')
ndpi_serialize_string_string(serializer, "hostname", (const char*)flow->host_server_name);
ndpi_serialize_string_string(serializer, "url", flow->http.url);
ndpi_serialize_string_uint32(serializer, "code", flow->http.response_status_code);
+ ndpi_serialize_string_string(serializer, "content_type", flow->http.content_type);
+ ndpi_serialize_string_string(serializer, "user_agent", flow->http.user_agent);
ndpi_serialize_end_of_block(serializer);
break;
@@ -981,28 +989,28 @@ int ndpi_flow2json(struct ndpi_detection_module_struct *ndpi_struct,
ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password);
ndpi_serialize_end_of_block(serializer);
break;
-
+
case NDPI_PROTOCOL_MAIL_POP:
ndpi_serialize_start_of_block(serializer, "pop");
ndpi_serialize_string_string(serializer, "user", flow->protos.ftp_imap_pop_smtp.username);
ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password);
ndpi_serialize_end_of_block(serializer);
break;
-
+
case NDPI_PROTOCOL_MAIL_SMTP:
ndpi_serialize_start_of_block(serializer, "smtp");
ndpi_serialize_string_string(serializer, "user", flow->protos.ftp_imap_pop_smtp.username);
ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password);
ndpi_serialize_end_of_block(serializer);
break;
-
+
case NDPI_PROTOCOL_FTP_CONTROL:
ndpi_serialize_start_of_block(serializer, "ftp");
ndpi_serialize_string_string(serializer, "user", flow->protos.ftp_imap_pop_smtp.username);
ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password);
ndpi_serialize_end_of_block(serializer);
break;
-
+
case NDPI_PROTOCOL_SSH:
ndpi_serialize_start_of_block(serializer, "ssh");
ndpi_serialize_string_string(serializer, "client_signature", flow->protos.ssh.client_signature);
@@ -1033,7 +1041,7 @@ int ndpi_flow2json(struct ndpi_detection_module_struct *ndpi_struct,
ndpi_serialize_string_string(serializer, "issuer", flow->protos.stun_ssl.ssl.server_organization);
if(before) {
- strftime(notBefore, sizeof(notBefore), "%F %T", before);
+ strftime(notBefore, sizeof(notBefore), "%F %T", before);
ndpi_serialize_string_string(serializer, "notbefore", notBefore);
}
@@ -1053,7 +1061,7 @@ int ndpi_flow2json(struct ndpi_detection_module_struct *ndpi_struct,
ndpi_serialize_string_string(serializer, "fingerprint", buf);
}
-
+
ndpi_serialize_end_of_block(serializer);
}
}
@@ -1064,3 +1072,146 @@ int ndpi_flow2json(struct ndpi_detection_module_struct *ndpi_struct,
}
/* ********************************** */
+
+/*
+ /dv/vulnerabilities/xss_r/?name=%3Cscript%3Econsole.log%28%27JUL2D3WXHEGWRAFJE2PI7OS71Z4Z8RFUHXGNFLUFYVP6M3OL55%27%29%3Bconsole.log%28document.cookie%29%3B%3C%2Fscript%3E
+ /dv/vulnerabilities/sqli/?id=1%27+and+1%3D1+union+select+null%2C+table_name+from+information_schema.tables%23&Submit=Submit
+*/
+
+/* https://www.rosettacode.org/wiki/URL_decoding#C */
+static int ishex(int x) {
+ return(x >= '0' && x <= '9') || (x >= 'a' && x <= 'f') || (x >= 'A' && x <= 'F');
+}
+
+/* ********************************** */
+
+static int ndpi_url_decode(const char *s, char *out) {
+ char *o;
+ const char *end = s + strlen(s);
+ int c;
+
+ for(o = out; s <= end; o++) {
+ c = *s++;
+ if(c == '+') c = ' ';
+ else if(c == '%' && (!ishex(*s++)||
+ !ishex(*s++)||
+ !sscanf(s - 2, "%2x", &c)))
+ return(-1);
+
+ if(out) *o = c;
+ }
+
+ return(o - out);
+}
+
+/* ********************************** */
+
+/* #define URL_CHECK_DEBUG 1 */
+
+static int find_occurrency(char *str, char *what) {
+ char *found = strstr(str, what);
+ u_int len;
+
+#ifdef URL_CHECK_DEBUG
+ printf("%s() [%s][%s]\n", __FUNCTION__, str, what);
+#endif
+
+ if(!found) return(0);
+
+ len = strlen(what);
+
+ if((found[len] != '\0') && (found[len] != ' ')
+ && ((found == str) || (found[-1] == ' ')))
+ return(1);
+ else
+ return(find_occurrency(&found[len], what));
+}
+
+/* ********************************** */
+
+static int ndpi_check_tokens(char* query, char* keywords[]) {
+#ifdef URL_CHECK_DEBUG
+ printf("%s() [%s]\n", __FUNCTION__, query);
+#endif
+
+ for(int i=0; keywords[i] != NULL; i++) {
+ if(find_occurrency(query, keywords[i]) > 0)
+ return(1);
+ }
+
+ return(0);
+}
+
+/* ********************************** */
+
+static int ndpi_is_sql_injection(char* query) {
+ char* sql_keywords[] = { "select", "from", "where", "any", "all", "join", "inner", "left", "right", "full",
+ "table", "alter", "create", "delete", "union", "update", "drop", "group", "order",
+ "limit", "primary", "column", NULL };
+ return(ndpi_check_tokens(query, sql_keywords));
+}
+
+/* ********************************** */
+
+static int ndpi_is_xss_injection(char* query) {
+ char* js_keywords[] = { "<script>", "console.", "log.", NULL };
+ return(ndpi_check_tokens(query, js_keywords));
+}
+
+/* ********************************** */
+
+ndpi_url_risk ndpi_validate_url(char *url) {
+ char *orig_str = NULL, *str = NULL, *question_mark = strchr(url, '?');
+ ndpi_url_risk rc = ndpi_url_no_problem;
+
+ if(question_mark) {
+ char *tmp;
+
+ orig_str = str = ndpi_strdup(&question_mark[1]); /* Skip ? */
+
+ if(!str) goto validate_rc;
+
+ str = strtok_r(str, "&", &tmp);
+
+ while(str != NULL) {
+ char *value = strchr(str, '=');
+ char *decoded;
+
+ if(!value)
+ break;
+ else
+ value = &value[1];
+
+ if(value[0] != '\0') {
+ if(!(decoded = (char*)ndpi_malloc(strlen(value)+1)))
+ break;
+
+ if(ndpi_url_decode(value, decoded) < 0) {
+ /* Invalid string */
+ } else if(decoded[0] != '\0') {
+ /* Valid string */
+
+ if(ndpi_is_xss_injection(decoded))
+ rc = ndpi_url_possible_xss;
+ else if(ndpi_is_sql_injection(decoded))
+ rc = ndpi_url_possible_sql_injection;
+
+#ifdef URL_CHECK_DEBUG
+ printf("=>> [rc: %u] %s\n", rc, decoded);
+#endif
+ }
+
+ ndpi_free(decoded);
+
+ if(rc != ndpi_url_no_problem)
+ break;
+ }
+
+ str = strtok_r(NULL, "&", &tmp);
+ }
+ }
+
+ validate_rc:
+ if(orig_str) ndpi_free(orig_str);
+ return(rc);
+}
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
index b73a1aeee..2525cfbd7 100644
--- a/src/lib/protocols/http.c
+++ b/src/lib/protocols/http.c
@@ -39,7 +39,7 @@ static int ndpi_search_http_tcp_again(struct ndpi_detection_module_struct *ndpi_
#ifdef HTTP_DEBUG
printf("=> %s()\n", __FUNCTION__);
#endif
-
+
if((flow->host_server_name[0] != '\0') && (flow->http.response_status_code != 0)) {
/* stop extra processing */
flow->extra_packets_func = NULL; /* We're good now */
@@ -61,7 +61,7 @@ static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *nd
if(flow->extra_packets_func && (flow->guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN))
return; /* Nothing new to add */
-
+
/* This is HTTP and it is not a sub protocol (e.g. skype or dropbox) */
ndpi_search_tcp_or_udp(ndpi_struct, flow);
@@ -71,9 +71,9 @@ static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *nd
ndpi_set_detected_protocol(ndpi_struct, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_HTTP);
} else
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_UNKNOWN);
-
+
/* This is necessary to inform the core to call this dissector again */
- flow->check_extra_packets = 1;
+ flow->check_extra_packets = 1;
flow->max_extra_packets_to_check = 5;
flow->extra_packets_func = ndpi_search_http_tcp_again;
flow->http_detected = 1, flow->guessed_category = category;
@@ -134,9 +134,9 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
struct ndpi_packet_struct *packet = &flow->packet;
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_UNKNOWN);
-
- if(flow->http_detected && (flow->http.response_status_code != 0))
- return;
+
+ if(flow->http_detected && (flow->http.response_status_code != 0))
+ return;
#if defined(NDPI_PROTOCOL_1KXUN) || defined(NDPI_PROTOCOL_IQIYI)
/* PPStream */
@@ -200,17 +200,6 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
}
}
- if((flow->http.content_type == NULL) && (packet->content_line.len > 0)) {
- int len = packet->content_line.len + 1;
-
- flow->http.content_type = ndpi_malloc(len);
- if(flow->http.content_type) {
- strncpy(flow->http.content_type, (char*)packet->content_line.ptr,
- packet->content_line.len);
- flow->http.content_type[packet->content_line.len] = '\0';
- }
- }
-
if(packet->user_agent_line.ptr != NULL && packet->user_agent_line.len != 0) {
/**
Format examples:
@@ -276,6 +265,17 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
}
}
+ if(flow->http.user_agent == NULL) {
+ int len = packet->user_agent_line.len + 1;
+
+ flow->http.user_agent = ndpi_malloc(len);
+ if(flow->http.user_agent) {
+ strncpy(flow->http.user_agent, (char*)packet->user_agent_line.ptr,
+ packet->user_agent_line.len);
+ flow->http.user_agent[packet->user_agent_line.len] = '\0';
+ }
+ }
+
NDPI_LOG_DBG2(ndpi_struct, "User Agent Type line found %.*s\n",
packet->user_agent_line.len, packet->user_agent_line.ptr);
}
@@ -383,6 +383,17 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
NDPI_LOG_DBG2(ndpi_struct, "Content Type line found %.*s\n",
packet->content_line.len, packet->content_line.ptr);
+ if((flow->http.content_type == NULL) && (packet->content_line.len > 0)) {
+ int len = packet->content_line.len + 1;
+
+ flow->http.content_type = ndpi_malloc(len);
+ if(flow->http.content_type) {
+ strncpy(flow->http.content_type, (char*)packet->content_line.ptr,
+ packet->content_line.len);
+ flow->http.content_type[packet->content_line.len] = '\0';
+ }
+ }
+
if(flow->http_detected) {
ndpi_protocol_match_result ret_match;
@@ -491,7 +502,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
flow->http.response_status_code = 0; /* Out of range */
}
- ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
check_content_type_and_change_protocol(ndpi_struct, flow);
return;
}
@@ -615,7 +626,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
x++;
}
#endif
-
+
#if defined(NDPI_PROTOCOL_1KXUN) || defined(NDPI_PROTOCOL_IQIYI)
/* check PPStream protocol or iQiyi service
(iqiyi is delivered by ppstream) */
@@ -688,7 +699,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
flow->http_detected = 1;
NDPI_LOG_DBG2(ndpi_struct,
"HTTP START Found, we will look further for the response...\n");
- flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
+ flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
check_content_type_and_change_protocol(ndpi_struct, flow);
return;
}
diff --git a/src/lib/protocols/telnet.c b/src/lib/protocols/telnet.c
index e293fc960..59b1e4978 100644
--- a/src/lib/protocols/telnet.c
+++ b/src/lib/protocols/telnet.c
@@ -19,7 +19,7 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with nDPI. If not, see <http://www.gnu.org/licenses/>.
- *
+ *
*/
@@ -29,14 +29,66 @@
#include "ndpi_api.h"
+/* ************************************************************************ */
+
+static int search_telnet_again(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // printf("==> %s()\n", __FUNCTION__);
+
+ if(packet->payload[0] == 0xFF)
+ return(1);
+
+ if(packet->payload_packet_len > 0) {
+ int i;
+
+ if((!flow->protos.telnet.username_found)
+ && (packet->payload_packet_len > 6)) {
+
+ if(strncasecmp((char*)packet->payload, "login:", 6) == 0) {
+ flow->protos.telnet.username_found = 1;
+ }
+
+ return(1);
+ }
+
+ if(packet->payload[0] == '\r') {
+ flow->protos.telnet.username_detected = 1;
+ flow->protos.telnet.username[flow->protos.telnet.character_id] = '\0';
+ return(0);
+ }
+
+ for(i=0; i<packet->payload_packet_len; i++) {
+ if(!flow->protos.telnet.skip_next) {
+ if(flow->protos.telnet.character_id < (sizeof(flow->protos.telnet.username)-1))
+ flow->protos.telnet.username[flow->protos.telnet.character_id++] = packet->payload[i];
+ flow->protos.telnet.skip_next = 1;
+ } else
+ flow->protos.telnet.skip_next = 0;
+ }
+ }
+
+ /* Possibly more processing */
+ return(1);
+}
+
+/* ************************************************************************ */
static void ndpi_int_telnet_add_connection(struct ndpi_detection_module_struct
- *ndpi_struct, struct ndpi_flow_struct *flow)
-{
+ *ndpi_struct, struct ndpi_flow_struct *flow) {
+ flow->guessed_host_protocol_id = flow->guessed_protocol_id = NDPI_PROTOCOL_TELNET;
+
+ /* This is necessary to inform the core to call this dissector again */
+ flow->check_extra_packets = 1;
+ flow->max_extra_packets_to_check = 32;
+ flow->extra_packets_func = search_telnet_again;
+
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TELNET, NDPI_PROTOCOL_UNKNOWN);
}
-
+/* ************************************************************************ */
+
#if !defined(WIN32)
static inline
#elif defined(MINGW_GCC)
@@ -44,62 +96,62 @@ __mingw_forceinline static
#else
__forceinline static
#endif
-u_int8_t search_iac(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
-{
+u_int8_t search_iac(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &flow->packet;
u_int16_t a;
- if (packet->payload_packet_len < 3) {
- return 0;
- }
+ if(packet->payload_packet_len < 3)
+ return(0);
- if (!(packet->payload[0] == 0xff
- && packet->payload[1] > 0xf9 && packet->payload[1] != 0xff && packet->payload[2] < 0x28)) {
- return 0;
- }
+ if(!((packet->payload[0] == 0xff)
+ && (packet->payload[1] > 0xf9)
+ && (packet->payload[1] != 0xff)
+ && (packet->payload[2] < 0x28)))
+ return(0);
a = 3;
while (a < packet->payload_packet_len - 2) {
// commands start with a 0xff byte followed by a command byte >= 0xf0 and < 0xff
// command bytes 0xfb to 0xfe are followed by an option byte <= 0x28
- if (!(packet->payload[a] != 0xff ||
+ if(!(packet->payload[a] != 0xff ||
(packet->payload[a] == 0xff && (packet->payload[a + 1] >= 0xf0) && (packet->payload[a + 1] <= 0xfa)) ||
(packet->payload[a] == 0xff && (packet->payload[a + 1] >= 0xfb) && (packet->payload[a + 1] != 0xff)
- && (packet->payload[a + 2] <= 0x28)))) {
- return 0;
- }
+ && (packet->payload[a + 2] <= 0x28))))
+ return(0);
+
a++;
}
return 1;
}
-/* this detection also works asymmetrically */
-void ndpi_search_telnet_tcp(struct ndpi_detection_module_struct
- *ndpi_struct, struct ndpi_flow_struct *flow)
-{
+/* ************************************************************************ */
+/* this detection also works asymmetrically */
+void ndpi_search_telnet_tcp(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
NDPI_LOG_DBG(ndpi_struct, "search telnet\n");
- if (search_iac(ndpi_struct, flow) == 1) {
-
- if (flow->l4.tcp.telnet_stage == 2) {
+ if(search_iac(ndpi_struct, flow) == 1) {
+ if(flow->l4.tcp.telnet_stage == 2) {
NDPI_LOG_INFO(ndpi_struct, "found telnet\n");
ndpi_int_telnet_add_connection(ndpi_struct, flow);
return;
}
+
flow->l4.tcp.telnet_stage++;
NDPI_LOG_DBG2(ndpi_struct, "telnet stage %u\n", flow->l4.tcp.telnet_stage);
return;
}
- if ((flow->packet_counter < 12 && flow->l4.tcp.telnet_stage > 0) || flow->packet_counter < 6) {
+ if(((flow->packet_counter < 12) && (flow->l4.tcp.telnet_stage > 0)) || (flow->packet_counter < 6))
return;
- } else {
+ else
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
- }
+
return;
}
@@ -112,6 +164,5 @@ void init_telnet_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_i
NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
SAVE_DETECTION_BITMASK_AS_UNKNOWN,
ADD_TO_DETECTION_BITMASK);
-
*id += 1;
}
diff --git a/src/lib/protocols/zabbix.c b/src/lib/protocols/zabbix.c
new file mode 100644
index 000000000..9e67a3159
--- /dev/null
+++ b/src/lib/protocols/zabbix.c
@@ -0,0 +1,63 @@
+/*
+ * zabbix.c
+ *
+ * Copyright (C) 2019 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "ndpi_protocol_ids.h"
+
+#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_ZABBIX
+
+#include "ndpi_api.h"
+
+/* *************************************************** */
+
+static void ndpi_int_zabbix_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow/* , */
+ /* ndpi_protocol_type_t protocol_type */) {
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ZABBIX, NDPI_PROTOCOL_UNKNOWN);
+}
+
+/* *************************************************** */
+
+void ndpi_search_zabbix(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int8_t tomatch[] = { 'Z', 'B', 'X', 'D', 0x1 };
+
+ NDPI_LOG_DBG(ndpi_struct, "search Zabbix\n");
+
+ if((packet->payload_packet_len > 4)
+ && (memcmp(packet->payload, tomatch, 5) == 0))
+ ndpi_int_zabbix_add_connection(ndpi_struct, flow);
+ else
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+}
+
+/* *************************************************** */
+
+void init_zabbix_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id,
+ NDPI_PROTOCOL_BITMASK *detection_bitmask) {
+ ndpi_set_bitmask_protocol_detection("Zabbix", ndpi_struct, detection_bitmask, *id,
+ NDPI_PROTOCOL_ZABBIX,
+ ndpi_search_zabbix,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ *id += 1;
+}