aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/ndpiReader.c141
-rw-r--r--src/include/ndpi_api.h21
-rw-r--r--src/include/ndpi_main.h2
-rw-r--r--src/include/ndpi_typedefs.h7
-rw-r--r--src/lib/ndpi_main.c199
-rw-r--r--tests/result/whatsapp_login_call.pcap.out6
6 files changed, 208 insertions, 168 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c
index 80c6a7ac1..adf8b2269 100644
--- a/example/ndpiReader.c
+++ b/example/ndpiReader.c
@@ -76,7 +76,7 @@ static char *_jsonFilePath = NULL; /**< JSON file path */
#ifdef HAVE_JSON_C
static json_object *jArray_known_flows, *jArray_unknown_flows;
#endif
-static u_int8_t live_capture = 0, full_http_dissection = 1;
+static u_int8_t live_capture = 0;
static u_int8_t undetected_flows_deleted = 0;
/**
* User preferences
@@ -176,7 +176,7 @@ typedef struct ndpi_flow {
u_int32_t packets;
// result only, not used for flow identification
- u_int16_t detected_protocol, detected_masterprotocol;
+ ndpi_protocol detected_protocol;
char host_server_name[256];
@@ -489,15 +489,17 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) {
if(flow->vlan_id > 0) fprintf(out, "[VLAN: %u]", flow->vlan_id);
- if(flow->detected_masterprotocol)
- fprintf(out, "[proto: %u.%u/%s.%s]",
- flow->detected_masterprotocol, flow->detected_protocol,
- ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_masterprotocol),
- ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol));
- else
- fprintf(out, "[proto: %u/%s]",
- flow->detected_protocol,
- ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol));
+ if(flow->detected_protocol.master_protocol) {
+ char buf[64];
+
+ fprintf(out, "[proto: %u.%u/%s]",
+ flow->detected_protocol.master_protocol, flow->detected_protocol.protocol,
+ ndpi_protocol2name(ndpi_thread_info[thread_id].ndpi_struct,
+ flow->detected_protocol, buf, sizeof(buf)));
+ } else
+ fprintf(out, "[proto: %u/%s]",
+ flow->detected_protocol.protocol,
+ ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.protocol));
fprintf(out, "[%u pkts/%llu bytes]",
flow->packets, (long long unsigned int)flow->bytes);
@@ -518,21 +520,24 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) {
json_object_object_add(jObj,"host_b.name",json_object_new_string(flow->upper_name));
json_object_object_add(jObj,"host_n.port",json_object_new_int(ntohs(flow->upper_port)));
- if(flow->detected_masterprotocol)
- json_object_object_add(jObj,"detected.masterprotocol",json_object_new_int(flow->detected_masterprotocol));
-
- json_object_object_add(jObj,"detected.protocol",json_object_new_int(flow->detected_protocol));
+ if(flow->detected_protocol.master_protocol)
+ json_object_object_add(jObj,"detected.masterprotocol",json_object_new_int(flow->detected_protocol.master_protocol));
+
+ json_object_object_add(jObj,"detected.protocol",json_object_new_int(flow->detected_protocol.protocol));
- if(flow->detected_masterprotocol) {
+ if(flow->detected_protocol.master_protocol) {
char tmp[256];
- snprintf(tmp, sizeof(tmp), "%s.%s",
- ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_masterprotocol),
- ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol));
+ snprintf(tmp, sizeof(tmp), "%s.%s",
+ ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.master_protocol),
+ ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.protocol));
- json_object_object_add(jObj,"detected.protocol.name",json_object_new_string(tmp));
+ json_object_object_add(jObj,"detected.protocol.name",
+ json_object_new_string(tmp));
} else
- json_object_object_add(jObj,"detected.protocol.name",json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol)));
+ json_object_object_add(jObj,"detected.protocol.name",
+ json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct,
+ flow->detected_protocol.protocol)));
json_object_object_add(jObj,"packets",json_object_new_int(flow->packets));
json_object_object_add(jObj,"bytes",json_object_new_int(flow->bytes));
@@ -584,7 +589,7 @@ static void node_print_unknown_proto_walker(const void *node, ndpi_VISIT which,
struct ndpi_flow *flow = *(struct ndpi_flow**)node;
u_int16_t thread_id = *((u_int16_t*)user_data);
- if(flow->detected_protocol != 0 /* UNKNOWN */) return;
+ if(flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN) return;
if((which == ndpi_preorder) || (which == ndpi_leaf)) /* Avoid walking the same node multiple times */
printFlow(thread_id, flow);
@@ -596,7 +601,7 @@ static void node_print_known_proto_walker(const void *node, ndpi_VISIT which, in
struct ndpi_flow *flow = *(struct ndpi_flow**)node;
u_int16_t thread_id = *((u_int16_t*)user_data);
- if(flow->detected_protocol == 0 /* UNKNOWN */) return;
+ if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) return;
if((which == ndpi_preorder) || (which == ndpi_leaf)) /* Avoid walking the same node multiple times */
printFlow(thread_id, flow);
@@ -612,10 +617,10 @@ static u_int16_t node_guess_undetected_protocol(u_int16_t thread_id, struct ndpi
ntohl(flow->upper_ip),
ntohs(flow->upper_port));
// printf("Guess state: %u\n", flow->detected_protocol);
- if(flow->detected_protocol != 0)
+ if(flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN)
ndpi_thread_info[thread_id].stats.guessed_flow_protocols++;
- return flow->detected_protocol;
+ return(flow->detected_protocol.protocol);
}
/* ***************************************************** */
@@ -636,15 +641,15 @@ static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int dept
if((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */
if(enable_protocol_guess) {
- if(flow->detected_protocol == 0 /* UNKNOWN */) {
+ if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) {
node_guess_undetected_protocol(thread_id, flow);
// printFlow(thread_id, flow);
}
}
- ndpi_thread_info[thread_id].stats.protocol_counter[flow->detected_protocol] += flow->packets;
- ndpi_thread_info[thread_id].stats.protocol_counter_bytes[flow->detected_protocol] += flow->bytes;
- ndpi_thread_info[thread_id].stats.protocol_flows[flow->detected_protocol]++;
+ ndpi_thread_info[thread_id].stats.protocol_counter[flow->detected_protocol.protocol] += flow->packets;
+ ndpi_thread_info[thread_id].stats.protocol_counter_bytes[flow->detected_protocol.protocol] += flow->bytes;
+ ndpi_thread_info[thread_id].stats.protocol_flows[flow->detected_protocol.protocol]++;
}
}
@@ -663,7 +668,7 @@ static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth,
/* update stats */
node_proto_guess_walker(node, which, depth, user_data);
- if (flow->detected_protocol == 0 /* UNKNOWN */ && !undetected_flows_deleted)
+ if((flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) && !undetected_flows_deleted)
undetected_flows_deleted = 1;
free_ndpi_flow(flow);
@@ -919,8 +924,7 @@ static void setupDetection(u_int16_t thread_id) {
exit(-1);
}
- if(!full_http_dissection)
- ndpi_thread_info[thread_id].ndpi_struct->http_dont_dissect_response = 1;
+ /* ndpi_thread_info[thread_id].ndpi_struct->http_dont_dissect_response = 1; */
// enable all protocols
NDPI_BITMASK_SET_ALL(all);
@@ -965,7 +969,6 @@ static unsigned int packet_processing(u_int16_t thread_id,
struct ndpi_id_struct *src, *dst;
struct ndpi_flow *flow;
struct ndpi_flow_struct *ndpi_flow = NULL;
- u_int32_t protocol = 0;
u_int8_t proto;
if(iph)
@@ -987,52 +990,47 @@ static unsigned int packet_processing(u_int16_t thread_id,
if(flow->detection_completed) return(0);
- protocol = (const u_int32_t)ndpi_detection_process_packet(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow,
- iph ? (uint8_t *)iph : (uint8_t *)iph6,
- ipsize, time, src, dst);
-
- if(protocol != NDPI_PROTOCOL_UNKNOWN)
- flow->detected_protocol = protocol, flow->detected_masterprotocol = ndpi_get_flow_masterprotocol(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow);
-
- if((flow->detected_protocol != NDPI_PROTOCOL_UNKNOWN)
+ flow->detected_protocol = ndpi_detection_process_packet(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow,
+ iph ? (uint8_t *)iph : (uint8_t *)iph6,
+ ipsize, time, src, dst);
+
+ if((flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN)
|| ((proto == IPPROTO_UDP) && (flow->packets > 8))
|| ((proto == IPPROTO_TCP) && (flow->packets > 10))) {
flow->detection_completed = 1;
- if((flow->detected_protocol == NDPI_PROTOCOL_UNKNOWN) && (ndpi_flow->num_stun_udp_pkts > 0))
+ if((flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) && (ndpi_flow->num_stun_udp_pkts > 0))
ndpi_set_detected_protocol(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow, NDPI_PROTOCOL_STUN, NDPI_PROTOCOL_UNKNOWN);
snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name);
- if((proto == IPPROTO_TCP) && (flow->detected_protocol != NDPI_PROTOCOL_DNS)) {
+ if((proto == IPPROTO_TCP) && (flow->detected_protocol.protocol != NDPI_PROTOCOL_DNS)) {
snprintf(flow->ssl.client_certificate, sizeof(flow->ssl.client_certificate), "%s", flow->ndpi_flow->protos.ssl.client_certificate);
snprintf(flow->ssl.server_certificate, sizeof(flow->ssl.server_certificate), "%s", flow->ndpi_flow->protos.ssl.server_certificate);
}
#if 0
- if((
- (flow->detected_protocol == NDPI_PROTOCOL_HTTP)
- || (flow->detected_protocol == NDPI_SERVICE_FACEBOOK)
- )
- && full_http_dissection) {
- char *method;
-
- printf("[URL] %s\n", ndpi_get_http_url(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow));
- printf("[Content-Type] %s\n", ndpi_get_http_content_type(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow));
-
- switch(ndpi_get_http_method(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow)) {
- case HTTP_METHOD_OPTIONS: method = "HTTP_METHOD_OPTIONS"; break;
- case HTTP_METHOD_GET: method = "HTTP_METHOD_GET"; break;
- case HTTP_METHOD_HEAD: method = "HTTP_METHOD_HEAD"; break;
- case HTTP_METHOD_POST: method = "HTTP_METHOD_POST"; break;
- case HTTP_METHOD_PUT: method = "HTTP_METHOD_PUT"; break;
- case HTTP_METHOD_DELETE: method = "HTTP_METHOD_DELETE"; break;
- case HTTP_METHOD_TRACE: method = "HTTP_METHOD_TRACE"; break;
- case HTTP_METHOD_CONNECT: method = "HTTP_METHOD_CONNECT"; break;
- default: method = "HTTP_METHOD_UNKNOWN"; break;
- }
+ if(verbose > 1) {
+ if(ndpi_is_proto(flow->detected_protocol, NDPI_PROTOCOL_HTTP)) {
+ char *method;
+
+ printf("[URL] %s\n", ndpi_get_http_url(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow));
+ printf("[Content-Type] %s\n", ndpi_get_http_content_type(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow));
+
+ switch(ndpi_get_http_method(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow)) {
+ case HTTP_METHOD_OPTIONS: method = "HTTP_METHOD_OPTIONS"; break;
+ case HTTP_METHOD_GET: method = "HTTP_METHOD_GET"; break;
+ case HTTP_METHOD_HEAD: method = "HTTP_METHOD_HEAD"; break;
+ case HTTP_METHOD_POST: method = "HTTP_METHOD_POST"; break;
+ case HTTP_METHOD_PUT: method = "HTTP_METHOD_PUT"; break;
+ case HTTP_METHOD_DELETE: method = "HTTP_METHOD_DELETE"; break;
+ case HTTP_METHOD_TRACE: method = "HTTP_METHOD_TRACE"; break;
+ case HTTP_METHOD_CONNECT: method = "HTTP_METHOD_CONNECT"; break;
+ default: method = "HTTP_METHOD_UNKNOWN"; break;
+ }
- printf("[Method] %s\n", method);
+ printf("[Method] %s\n", method);
+ }
}
#endif
@@ -1040,8 +1038,9 @@ static unsigned int packet_processing(u_int16_t thread_id,
if(verbose > 1) {
if(enable_protocol_guess) {
- if(flow->detected_protocol == 0 /* UNKNOWN */) {
- protocol = node_guess_undetected_protocol(thread_id, flow);
+ if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) {
+ flow->detected_protocol.protocol = node_guess_undetected_protocol(thread_id, flow),
+ flow->detected_protocol.master_protocol = NDPI_PROTOCOL_UNKNOWN;
}
}
@@ -1256,7 +1255,7 @@ static void printResults(u_int64_t tot_usec) {
if(enable_protocol_guess)
printf("\tGuessed flow protos: %-13u\n", cumulative_stats.guessed_flow_protocols);
}
- }
+ }
if(json_flag) {
#ifdef HAVE_JSON_C
@@ -1320,13 +1319,13 @@ static void printResults(u_int64_t tot_usec) {
#ifdef HAVE_JSON_C
if(json_fp) {
jObj = json_object_new_object();
-
+
json_object_object_add(jObj,"name",json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[0].ndpi_struct, i)));
json_object_object_add(jObj,"breed",json_object_new_string(ndpi_get_proto_breed_name(ndpi_thread_info[0].ndpi_struct, breed)));
json_object_object_add(jObj,"packets",json_object_new_int64(cumulative_stats.protocol_counter[i]));
json_object_object_add(jObj,"bytes",json_object_new_int64(cumulative_stats.protocol_counter_bytes[i]));
json_object_object_add(jObj,"flows",json_object_new_int(cumulative_stats.protocol_flows[i]));
-
+
json_object_array_add(jArray_detProto,jObj);
}
#endif
@@ -1352,7 +1351,7 @@ static void printResults(u_int64_t tot_usec) {
if(verbose) {
FILE *out = results_file ? results_file : stdout;
-
+
if(!json_flag) fprintf(out, "\n");
num_flows = 0;
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h
index 5ec188be5..d3fff5cfd 100644
--- a/src/include/ndpi_api.h
+++ b/src/include/ndpi_api.h
@@ -123,13 +123,13 @@ extern "C" {
* @param dst void pointer to the destination subscriber state machine
* @return returns the detected ID of the protocol
*/
- u_int16_t ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow,
- const unsigned char *packet,
- const unsigned short packetlen,
- const u_int64_t current_tick,
- struct ndpi_id_struct *src,
- struct ndpi_id_struct *dst);
+ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ const unsigned char *packet,
+ const unsigned short packetlen,
+ const u_int64_t current_tick,
+ struct ndpi_id_struct *src,
+ struct ndpi_id_struct *dst);
u_int16_t ndpi_get_flow_masterprotocol(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow);
@@ -169,10 +169,10 @@ extern "C" {
u_int8_t ndpi_detection_flow_protocol_history_contains_protocol(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
u_int16_t protocol_id);
- unsigned int ndpi_find_port_based_protocol(struct ndpi_detection_module_struct *ndpi_struct,
- u_int8_t proto, u_int32_t shost, u_int16_t sport, u_int32_t dhost, u_int16_t dport);
- unsigned int ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ ndpi_protocol ndpi_find_port_based_protocol(struct ndpi_detection_module_struct *ndpi_struct,
u_int8_t proto, u_int32_t shost, u_int16_t sport, u_int32_t dhost, u_int16_t dport);
+ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int8_t proto, u_int32_t shost, u_int16_t sport, u_int32_t dhost, u_int16_t dport);
int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow, char *string_to_match, u_int string_to_match_len);
int ndpi_match_content_subprotocol(struct ndpi_detection_module_struct *ndpi_struct,
@@ -180,6 +180,7 @@ extern "C" {
char *string_to_match, u_int string_to_match_len);
int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_struct,
ndpi_automa *automa, char *bigram_to_match);
+ char* ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol proto, char *buf, u_int buf_len);
char* ndpi_get_proto_name(struct ndpi_detection_module_struct *mod, u_int16_t proto_id);
ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t proto);
char* ndpi_get_proto_breed_name(struct ndpi_detection_module_struct *ndpi_struct, ndpi_protocol_breed_t breed_id);
diff --git a/src/include/ndpi_main.h b/src/include/ndpi_main.h
index ab869b167..adec3edf1 100644
--- a/src/include/ndpi_main.h
+++ b/src/include/ndpi_main.h
@@ -136,6 +136,8 @@ extern char *ndpi_get_packet_src_ip_string(struct ndpi_detection_module_struct *
extern char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int id);
extern u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct,
u_int8_t proto, u_int16_t sport, u_int16_t dport);
+extern u_int8_t ndpi_is_proto(ndpi_protocol p, u_int16_t proto);
+extern u_int16_t ndpi_get_lower_proto(ndpi_protocol p);
extern int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t protocol_id,
u_int16_t** tcp_master_proto,
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 7ca59fa58..8404daa2e 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -561,6 +561,12 @@ typedef struct _ndpi_automa {
u_int8_t ac_automa_finalized;
} ndpi_automa;
+typedef struct ndpi_proto {
+ u_int16_t master_protocol /* e.g. HTTP */, protocol /* e.g. FaceBook */;
+} ndpi_protocol;
+
+#define NDPI_PROTOCOL_NULL { NDPI_PROTOCOL_UNKNOWN , NDPI_PROTOCOL_UNKNOWN }
+
typedef struct ndpi_detection_module_struct {
NDPI_PROTOCOL_BITMASK detection_bitmask;
NDPI_PROTOCOL_BITMASK generic_http_packet_bitmask;
@@ -671,7 +677,6 @@ typedef struct ndpi_flow_struct {
u_int16_t guessed_protocol_id;
u_int8_t protocol_id_already_guessed:1;
- u_int8_t no_cache_protocol:1;
u_int8_t init_finished:1;
u_int8_t setup_packet_direction:1;
u_int8_t packet_direction:1; /* if ndpi_struct->direction_detect_disable == 1 */
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index e4efcfc2d..9496545cd 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -695,7 +695,7 @@ static int ndpi_add_host_url_subprotocol(struct ndpi_detection_module_struct *nd
int ndpi_add_content_subprotocol(struct ndpi_detection_module_struct *ndpi_struct,
char *value, int protocol_id,
ndpi_protocol_breed_t breed) {
- return(ndpi_string_to_automa(ndpi_struct, &ndpi_struct->content_automa,
+ return(ndpi_string_to_automa(ndpi_struct, &ndpi_struct->content_automa,
value, protocol_id, breed));
}
@@ -732,7 +732,7 @@ static void init_string_based_protocols(struct ndpi_detection_module_struct *ndp
ndpi_mod->proto_defaults[host_match[i].protocol_id].protoBreed = host_match[i].protocol_breed;
}
- ndpi_set_proto_defaults(ndpi_mod,
+ ndpi_set_proto_defaults(ndpi_mod,
ndpi_mod->proto_defaults[host_match[i].protocol_id].protoBreed,
ndpi_mod->proto_defaults[host_match[i].protocol_id].protoId,
no_master, no_master,
@@ -1241,7 +1241,7 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHATSAPP_VOICE,
no_master,
- no_master, "WhatsApp Voice",
+ no_master, "WhatsAppVoice",
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
@@ -3847,8 +3847,7 @@ __forceinline static
void ndpi_apply_flow_protocol_to_packet(struct ndpi_flow_struct *flow,
struct ndpi_packet_struct *packet)
{
- memcpy(&packet->detected_protocol_stack[0],
- &flow->detected_protocol_stack[0], sizeof(packet->detected_protocol_stack));
+ memcpy(&packet->detected_protocol_stack, &flow->detected_protocol_stack, sizeof(packet->detected_protocol_stack));
memcpy(&packet->protocol_stack_info, &flow->protocol_stack_info, sizeof(packet->protocol_stack_info));
}
@@ -3949,10 +3948,8 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str
&& flow->packet.tcp->ack == 0
&& flow->init_finished != 0
&& flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
-
memset(flow, 0, sizeof(*(flow)));
-
NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct,
NDPI_LOG_DEBUG,
"%s:%u: tcp syn packet for unknown protocol, reset detection state\n", __FUNCTION__, __LINE__);
@@ -4056,15 +4053,12 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_struct,
}
} else if(packet->payload_packet_len > 0) {
/* check tcp sequence counters */
- if(((u_int32_t)
- (ntohl(tcph->seq) -
- flow->next_tcp_seq_nr[packet->packet_direction])) >
+ if(((u_int32_t)(ntohl(tcph->seq) - flow->next_tcp_seq_nr[packet->packet_direction])) >
ndpi_struct->tcp_max_retransmission_window_size) {
packet->tcp_retransmission = 1;
-
- /*CHECK IF PARTIAL RETRY IS HAPPENENING */
+ /* CHECK IF PARTIAL RETRY IS HAPPENING */
if((flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq) < packet->payload_packet_len)) {
/* num_retried_bytes actual_payload_len hold info about the partial retry
analyzer which require this info can make use of this info
@@ -4074,17 +4068,14 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_struct,
flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
}
}
- /*normal path
- actual_payload_len is initialized to payload_packet_len during tcp header parsing itself.
- It will be changed only in case of retransmission */
- else {
-
+ /* normal path
+ actual_payload_len is initialized to payload_packet_len during tcp header parsing itself.
+ It will be changed only in case of retransmission */
+ else {
packet->num_retried_bytes = 0;
flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
}
-
-
}
if(tcph->rst) {
@@ -4285,30 +4276,30 @@ void check_ndpi_flow_func(struct ndpi_detection_module_struct *ndpi_struct,
check_ndpi_other_flow_func(ndpi_struct, flow, ndpi_selection_packet);
}
-u_int16_t ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow,
- const unsigned char *packet,
- const unsigned short packetlen,
- const u_int64_t current_tick_l,
- struct ndpi_id_struct *src,
- struct ndpi_id_struct *dst)
+ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ const unsigned char *packet,
+ const unsigned short packetlen,
+ const u_int64_t current_tick_l,
+ struct ndpi_id_struct *src,
+ struct ndpi_id_struct *dst)
{
NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet;
u_int32_t a;
+ ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN };
if(flow == NULL)
- return NDPI_PROTOCOL_UNKNOWN;
+ return(ret);
if(flow->server_id == NULL) flow->server_id = dst; /* Default */
- if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN && !flow->no_cache_protocol)
- return(flow->detected_protocol_stack[0]); /* Stop after detecting the first protocol */
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ goto ret_protocols;
/* need at least 20 bytes for ip header */
if(packetlen < 20) {
/* reset protocol which is normally done in init_packet_header */
ndpi_int_reset_packet_protocol(&flow->packet);
-
- return NDPI_PROTOCOL_UNKNOWN;
+ return(ret);
}
flow->packet.tick_timestamp_l = current_tick_l;
@@ -4323,11 +4314,11 @@ u_int16_t ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndp
#endif
/* parse packet */
- flow->packet.iph = (struct ndpi_iphdr *) packet;
+ flow->packet.iph = (struct ndpi_iphdr *)packet;
/* we are interested in ipv4 packet */
if(ndpi_init_packet_header(ndpi_struct, flow, packetlen) != 0)
- return NDPI_PROTOCOL_UNKNOWN;
+ return(ret);
/* detect traffic for tcp or udp only */
@@ -4337,28 +4328,26 @@ u_int16_t ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndp
/* build ndpi_selction packet bitmask */
ndpi_selection_packet = NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC;
- if(flow->packet.iph != NULL) {
+ if(flow->packet.iph != NULL)
ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IP | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
- }
- if(flow->packet.tcp != NULL) {
+
+ if(flow->packet.tcp != NULL)
ndpi_selection_packet |=
(NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
- }
- if(flow->packet.udp != NULL) {
+
+ if(flow->packet.udp != NULL)
ndpi_selection_packet |=
(NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
- }
- if(flow->packet.payload_packet_len != 0) {
+
+ if(flow->packet.payload_packet_len != 0)
ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD;
- }
- if(flow->packet.tcp_retransmission == 0) {
+ if(flow->packet.tcp_retransmission == 0)
ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION;
- }
+
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- if(flow->packet.iphv6 != NULL) {
+ if(flow->packet.iphv6 != NULL)
ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
- }
#endif /* NDPI_DETECTION_SUPPORT_IPV6 */
if((!flow->protocol_id_already_guessed)
@@ -4386,17 +4375,18 @@ u_int16_t ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndp
else if(flow->packet.tcp) sport = ntohs(flow->packet.tcp->source), dport = ntohs(flow->packet.tcp->dest);
else sport = dport = 0;
- flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol,
- sport, dport);
+ flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol, sport, dport);
flow->protocol_id_already_guessed = 1;
}
+#if 0
a = flow->detected_protocol_stack[0];
- if(a != NDPI_PROTOCOL_UNKNOWN && flow->no_cache_protocol) {
+ if(a != NDPI_PROTOCOL_UNKNOWN) {
NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_TRACE, "PROCESS KNOWN PROTOCOL\n");
ndpi_struct->proto_defaults[a].func(ndpi_struct, flow);
return a;
}
+#endif
check_ndpi_flow_func(ndpi_struct, flow, &ndpi_selection_packet);
@@ -4413,9 +4403,14 @@ u_int16_t ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndp
flow->host_server_name[i] ='\0';
}
- return a;
-}
+ ret_protocols:
+ if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
+ ret.master_protocol = flow->detected_protocol_stack[1], ret.protocol = flow->detected_protocol_stack[0];
+ else
+ ret.protocol = flow->detected_protocol_stack[0];
+ return(ret);
+}
u_int32_t ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read)
{
@@ -4907,9 +4902,9 @@ void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_struct
{
struct ndpi_id_struct *src = flow->src;
struct ndpi_id_struct *dst = flow->dst;
-
+
ndpi_int_change_protocol(ndpi_struct, flow, upper_detected_protocol, lower_detected_protocol);
-
+
if(src != NULL) {
NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, upper_detected_protocol);
@@ -4932,16 +4927,16 @@ u_int16_t ndpi_get_flow_masterprotocol(struct ndpi_detection_module_struct *ndpi
void ndpi_int_change_flow_protocol(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol,
+ u_int16_t upper_detected_protocol,
u_int16_t lower_detected_protocol) {
if(!flow) return;
-
+
flow->detected_protocol_stack[0] = upper_detected_protocol, flow->detected_protocol_stack[1] = lower_detected_protocol;
}
void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol,
+ u_int16_t upper_detected_protocol,
u_int16_t lower_detected_protocol) {
struct ndpi_packet_struct *packet = &flow->packet;
/* NOTE: everything below is identically to change_flow_protocol
@@ -4985,7 +4980,7 @@ u_int8_t ndpi_detection_flow_protocol_history_contains_protocol(struct ndpi_dete
*/
void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol,
+ u_int16_t upper_detected_protocol,
u_int16_t lower_detected_protocol) {
ndpi_int_change_flow_protocol(ndpi_struct, flow, upper_detected_protocol, lower_detected_protocol);
ndpi_int_change_packet_protocol(ndpi_struct, flow, upper_detected_protocol, lower_detected_protocol);
@@ -4995,7 +4990,7 @@ void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_struct,
/* turns a packet back to unknown */
void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet) {
int a;
-
+
for(a = 0; a < NDPI_PROTOCOL_HISTORY_SIZE; a++)
packet->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN;
}
@@ -5003,13 +4998,13 @@ void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet) {
void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow) {
if(flow) {
int a;
-
+
for(a = 0; a < NDPI_PROTOCOL_HISTORY_SIZE; a++) {
flow->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN;
}
}
}
-
+
void NDPI_PROTOCOL_IP_clear(ndpi_ip_addr_t * ip) {
memset(ip, 0, sizeof(ndpi_ip_addr_t));
}
@@ -5151,56 +5146,94 @@ static u_int is_port(u_int16_t sport, u_int16_t dport, u_int16_t match_port) {
/* ****************************************************** */
-unsigned int ndpi_find_port_based_protocol(struct ndpi_detection_module_struct *ndpi_struct /* NOTUSED */,
- u_int8_t proto,
- u_int32_t shost, u_int16_t sport,
- u_int32_t dhost, u_int16_t dport) {
+ndpi_protocol ndpi_find_port_based_protocol(struct ndpi_detection_module_struct *ndpi_struct /* NOTUSED */,
+ u_int8_t proto,
+ u_int32_t shost, u_int16_t sport,
+ u_int32_t dhost, u_int16_t dport) {
+ ndpi_protocol p = NDPI_PROTOCOL_NULL;
+
/* Skyfile (host 193.252.234.246 or host 10.10.102.80) */
if((shost == 0xC1FCEAF6) || (dhost == 0xC1FCEAF6)
|| (shost == 0x0A0A6650) || (dhost == 0x0A0A6650)) {
- if((sport == 4708) || (dport == 4708)) return(NDPI_PROTOCOL_SKYFILE_PREPAID);
- else if((sport == 4709) || (dport == 4709)) return(NDPI_PROTOCOL_SKYFILE_RUDICS);
- else if((sport == 4710) || (dport == 4710)) return(NDPI_PROTOCOL_SKYFILE_POSTPAID);
+ if((sport == 4708) || (dport == 4708)) p.protocol = NDPI_PROTOCOL_SKYFILE_PREPAID;
+ else if((sport == 4709) || (dport == 4709)) p.protocol = NDPI_PROTOCOL_SKYFILE_RUDICS;
+ else if((sport == 4710) || (dport == 4710)) p.protocol = NDPI_PROTOCOL_SKYFILE_POSTPAID;
}
- return(NDPI_PROTOCOL_UNKNOWN);
+ return(p);
}
/* ****************************************************** */
-unsigned int ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_struct,
- u_int8_t proto,
- u_int32_t shost /* host byte order */, u_int16_t sport,
- u_int32_t dhost /* host byte order */, u_int16_t dport) {
+u_int8_t ndpi_is_proto(ndpi_protocol p, u_int16_t proto) {
+ return(((p.protocol == proto) || (p.master_protocol == proto)) ? 1 : 0);
+}
+
+/* ****************************************************** */
+
+u_int16_t ndpi_get_lower_proto(ndpi_protocol p) {
+ return((p.master_protocol != NDPI_PROTOCOL_UNKNOWN) ? p.master_protocol : p.protocol);
+}
+
+/* ****************************************************** */
+
+ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int8_t proto,
+ u_int32_t shost /* host byte order */, u_int16_t sport,
+ u_int32_t dhost /* host byte order */, u_int16_t dport) {
unsigned int rc;
struct in_addr addr;
+ ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN };
if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) {
rc = ndpi_search_tcp_or_udp_raw(ndpi_struct, proto, shost, dhost, sport, dport);
- if(rc != NDPI_PROTOCOL_UNKNOWN) return(rc);
+ if(rc != NDPI_PROTOCOL_UNKNOWN) {
+ ret.protocol = rc;
+ return(ret);
+ }
rc = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport);
if(rc != NDPI_PROTOCOL_UNKNOWN) {
+ ret.protocol = rc;
+
if(rc == NDPI_PROTOCOL_SSL)
goto check_guessed_skype;
else
- return(rc);
+ return(ret);
}
- rc = ndpi_find_port_based_protocol(ndpi_struct, proto, shost, sport, dhost, dport);
- if(rc != NDPI_PROTOCOL_UNKNOWN) return(rc);
+ ret = ndpi_find_port_based_protocol(ndpi_struct, proto, shost, sport, dhost, dport);
+ if(ret.protocol != NDPI_PROTOCOL_UNKNOWN)
+ return(ret);
check_guessed_skype:
addr.s_addr = shost;
- if(ndpi_network_ptree_match(ndpi_struct, &addr) == NDPI_PROTOCOL_SKYPE) return(NDPI_PROTOCOL_SKYPE);
+ if(ndpi_network_ptree_match(ndpi_struct, &addr) == NDPI_PROTOCOL_SKYPE) {
+ ret.protocol = NDPI_PROTOCOL_SKYPE;
+ } else {
+ addr.s_addr = dhost;
+ if(ndpi_network_ptree_match(ndpi_struct, &addr) == NDPI_PROTOCOL_SKYPE)
+ ret.protocol = NDPI_PROTOCOL_SKYPE;
+ }
+ } else
+ ret.protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport);
- addr.s_addr = dhost;
- if(ndpi_network_ptree_match(ndpi_struct, &addr) == NDPI_PROTOCOL_SKYPE) return(NDPI_PROTOCOL_SKYPE);
+ return(ret);
+}
- return(rc);
- } else {
- return(ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport));
- }
+/* ****************************************************** */
+
+char* ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_mod,
+ ndpi_protocol proto, char *buf, u_int buf_len) {
+ if(proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) {
+ snprintf(buf, buf_len, "%s.%s",
+ ndpi_get_proto_name(ndpi_mod, proto.master_protocol),
+ ndpi_get_proto_name(ndpi_mod, proto.protocol));
+ } else
+ snprintf(buf, buf_len, "%s",
+ ndpi_get_proto_name(ndpi_mod, proto.protocol));
+
+ return(buf);
}
/* ****************************************************** */
@@ -5340,7 +5373,7 @@ static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_str
/* Move the protocol on slot 0 down one position */
packet->detected_protocol_stack[1] = packet->detected_protocol_stack[0];
packet->detected_protocol_stack[0] = matching_protocol_id;
-
+
flow->detected_protocol_stack[0] = packet->detected_protocol_stack[0],
flow->detected_protocol_stack[1] = packet->detected_protocol_stack[1];
diff --git a/tests/result/whatsapp_login_call.pcap.out b/tests/result/whatsapp_login_call.pcap.out
index 38d79e24b..88cedf98d 100644
--- a/tests/result/whatsapp_login_call.pcap.out
+++ b/tests/result/whatsapp_login_call.pcap.out
@@ -10,12 +10,12 @@ Apple 127 28102 20
WhatsApp 182 25154 2
AppleiTunes 85 28087 2
Spotify 3 258 1
-WhatsApp Voice 662 83338 2
+WhatsAppVoice 662 83338 2
1 UDP fe80::da30:62ff:fe56:1c:5353 <-> ff02::fb:5353 [proto: 8/MDNS][2 pkts/258 bytes]
2 UDP 192.168.2.1:17500 <-> 192.168.2.255:17500 [proto: 121/DropBox][4 pkts/2176 bytes]
3 ICMP 192.168.2.4:0 <-> 91.253.176.65:0 [proto: 81/ICMP][10 pkts/700 bytes]
- 4 UDP 192.168.2.4:52794 <-> 91.253.176.65:9665 [proto: 189/WhatsApp Voice][198 pkts/30418 bytes]
+ 4 UDP 192.168.2.4:52794 <-> 91.253.176.65:9665 [proto: 189/WhatsAppVoice][198 pkts/30418 bytes]
5 UDP 173.252.114.1:3478 <-> 192.168.2.4:52794 [proto: 78/STUN][5 pkts/676 bytes]
6 UDP 192.168.2.1:53 <-> 192.168.2.4:51897 [proto: 140/Apple][2 pkts/330 bytes][Host: query.ess.apple.com]
7 UDP 192.168.2.4:52794 <-> 179.60.192.48:3478 [proto: 78/STUN][5 pkts/676 bytes]
@@ -45,7 +45,7 @@ WhatsApp Voice 662 83338 2
31 TCP 192.168.2.4:49173 <-> 93.186.135.82:80 [proto: 7/HTTP][3 pkts/198 bytes]
32 TCP 192.168.2.4:49194 <-> 93.62.150.157:443 [proto: 91/SSL][3 pkts/198 bytes]
33 UDP 0.0.0.0:68 <-> 255.255.255.255:67 [proto: 18/DHCP][10 pkts/3420 bytes]
- 34 UDP 192.168.2.4:51518 <-> 91.253.176.65:9344 [proto: 189/WhatsApp Voice][464 pkts/52920 bytes]
+ 34 UDP 192.168.2.4:51518 <-> 91.253.176.65:9344 [proto: 189/WhatsAppVoice][464 pkts/52920 bytes]
35 TCP 192.168.2.4:49202 <-> 184.173.179.37:5222 [proto: 142/WhatsApp][180 pkts/24874 bytes]
36 UDP 192.168.2.1:57621 <-> 192.168.2.255:57621 [proto: 156/Spotify][3 pkts/258 bytes]
37 UDP 192.168.2.1:53 <-> 192.168.2.4:52190 [proto: 142/WhatsApp][2 pkts/280 bytes][Host: e13.whatsapp.net]