aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_utils.h1
-rw-r--r--src/lib/ndpi_main.c4945
-rw-r--r--src/lib/ndpi_utils.c415
3 files changed, 2707 insertions, 2654 deletions
diff --git a/src/include/ndpi_utils.h b/src/include/ndpi_utils.h
index 296bd6254..185856f3d 100644
--- a/src/include/ndpi_utils.h
+++ b/src/include/ndpi_utils.h
@@ -8,7 +8,6 @@
#define MYDBG(m, ...) \
printf(" DBG[%s:%s:%u]: \t" m "\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__);
-
// #define NDPI_ENABLE_DEBUG_POINTER_MESSAGES
// #define NDPI_ENABLE_DEBUG_INFO_MESSAGES
// #define NDPI_ENABLE_DEBUG_TRACE_MESSAGES
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index daf447d58..9f8514848 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -2018,7 +2018,7 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs
if(!(prefs & ndpi_dont_init_libgcrypt)) {
if(!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
const char *gcrypt_ver = gcry_check_version(NULL);
- if (!gcrypt_ver) {
+ if(!gcrypt_ver) {
NDPI_LOG_ERR(ndpi_str, "Error initializing libgcrypt\n");
ndpi_free(ndpi_str);
return NULL;
@@ -3498,25 +3498,25 @@ int ndpi_handle_ipv6_extension_headers(struct ndpi_detection_module_struct *ndpi
static u_int8_t ndpi_iph_is_valid_and_not_fragmented(const struct ndpi_iphdr *iph, const u_int16_t ipsize) {
- #ifdef FRAG_MAN
+#ifdef FRAG_MAN
/*
the logic has been inverted!!! returned value:
- 0: not fragmented (instead of fragmented)
- 1: packet too small
- 2: fragmented and last, reassemble
- 3: fragmented but not the last, add to buffer
+ 0: not fragmented (instead of fragmented)
+ 1: packet too small
+ 2: fragmented and last, reassemble
+ 3: fragmented but not the last, add to buffer
*/
u_int16_t tot_len = ntohs(iph->tot_len);
- if ( ipsize < iph->ihl * 4 || ipsize < tot_len || tot_len < iph->ihl * 4 )
+ if( ipsize < iph->ihl * 4 || ipsize < tot_len || tot_len < iph->ihl * 4 )
// packet too small
return(1);
- else if ((iph->frag_off & htons(0x2000)) != 0) {
+ else if((iph->frag_off & htons(0x2000)) != 0) {
// MF=1 : this is a fragment and not the last -> add to buffer
//printf("DBG(ndpi_iph_is_valid_and_not_fragmented): ipv4 fragment and not the last! (off=%u) \n", (htons(iph->frag_off) & 0x1FFF)<<3);
// MUST add to buffer
return(3);
- } else if ((iph->frag_off & htons(0x1FFF)) != 0) {
+ } else if((iph->frag_off & htons(0x1FFF)) != 0) {
// MF=0, this is (a fragment, but) the last fragment!
//printf("DBG(ndpi_iph_is_valid_and_not_fragmented): ipv4 fragment and the last! (0ff=%u) \n", (htons(iph->frag_off) & 0x1FFF)<<3);
@@ -3526,10 +3526,10 @@ static u_int8_t ndpi_iph_is_valid_and_not_fragmented(const struct ndpi_iphdr *ip
return (0);
#else // FRAG_MAN
- /*
+ /*
returned value:
- 0: fragmented
- 1: not fragmented
+ 0: fragmented
+ 1: not fragmented
*/
//#ifdef REQUIRE_FULL_PACKETS
if(ipsize < iph->ihl * 4 || ipsize < ntohs(iph->tot_len) || ntohs(iph->tot_len) < iph->ihl * 4 ||
@@ -3544,13 +3544,13 @@ static u_int8_t ndpi_iph_is_valid_and_not_fragmented(const struct ndpi_iphdr *ip
}
/*
-extract the l4 payload, if available
-returned value:
-FRAG_MAN
+ extract the l4 payload, if available
+ returned value:
+ FRAG_MAN
0: ok, extracted
1: packet too small
2,3: fragmented, ....
-else
+ else
0: ok, extracted
1: error or not available
*/
@@ -3600,7 +3600,7 @@ static u_int8_t ndpi_detection_get_l4_internal(struct ndpi_detection_module_stru
if(iph != NULL) {
u_int8_t check4Frag = ndpi_iph_is_valid_and_not_fragmented(iph, l3_len);
/* 0: not fragmented; 1: too small; 2,3: fragmented */
- if (!check4Frag) {
+ if(!check4Frag) {
u_int16_t len = ntohs(iph->tot_len);
u_int16_t hlen = (iph->ihl * 4);
@@ -3759,10 +3759,10 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str
* idea: reset detection state if a connection is unknown
*/
if(flow->packet.tcp->syn != 0 && flow->packet.tcp->ack == 0 && flow->init_finished != 0 &&
- flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+ flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
u_int8_t backup;
- u_int16_t backup1, backup2;
+ u_int16_t backup1, backup2;
backup = flow->num_processed_pkts;
backup1 = flow->guessed_protocol_id;
@@ -3812,271 +3812,212 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str
#ifdef FRAG_MAN
uint8_t ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow) {
+ struct ndpi_flow_struct *flow) {
#else // FRAG_MAN
-void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow) {
+ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow) {
#endif // FRAG_MAN
- if(!flow) {
+ if(!flow) {
#ifdef FRAG_MAN
- return 0;
+ return 0;
#else // FRAG_MAN
- return;
+ return;
#endif // FRAG_MAN
- } else {
- /* const for gcc code optimization and cleaner code */
- struct ndpi_packet_struct *packet = &flow->packet;
- const struct ndpi_iphdr *iph = packet->iph;
+ } else {
+ /* const for gcc code optimization and cleaner code */
+ struct ndpi_packet_struct *packet = &flow->packet;
+ const struct ndpi_iphdr *iph = packet->iph;
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- const struct ndpi_ipv6hdr *iphv6 = packet->iphv6;
+ const struct ndpi_ipv6hdr *iphv6 = packet->iphv6;
#endif
- const struct ndpi_tcphdr *tcph = packet->tcp;
- const struct ndpi_udphdr *udph = packet->udp;
+ const struct ndpi_tcphdr *tcph = packet->tcp;
+ const struct ndpi_udphdr *udph = packet->udp;
- packet->tcp_retransmission = 0, packet->packet_direction = 0;
+ packet->tcp_retransmission = 0, packet->packet_direction = 0;
- if(ndpi_str->direction_detect_disable) {
- packet->packet_direction = flow->packet_direction;
- } else {
- if(iph != NULL && ntohl(iph->saddr) < ntohl(iph->daddr))
- packet->packet_direction = 1;
+ if(ndpi_str->direction_detect_disable) {
+ packet->packet_direction = flow->packet_direction;
+ } else {
+ if(iph != NULL && ntohl(iph->saddr) < ntohl(iph->daddr))
+ packet->packet_direction = 1;
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- if(iphv6 != NULL && NDPI_COMPARE_IPV6_ADDRESS_STRUCTS(&iphv6->ip6_src, &iphv6->ip6_dst) != 0)
- packet->packet_direction = 1;
+ if(iphv6 != NULL && NDPI_COMPARE_IPV6_ADDRESS_STRUCTS(&iphv6->ip6_src, &iphv6->ip6_dst) != 0)
+ packet->packet_direction = 1;
#endif
- }
-
- packet->packet_lines_parsed_complete = 0;
-
- if(flow->init_finished == 0) {
- flow->init_finished = 1;
- flow->setup_packet_direction = packet->packet_direction;
- }
-
- if(tcph != NULL) {
- /* reset retried bytes here before setting it */
- packet->num_retried_bytes = 0;
+ }
- if(!ndpi_str->direction_detect_disable)
- packet->packet_direction = (ntohs(tcph->source) < ntohs(tcph->dest)) ? 1 : 0;
+ packet->packet_lines_parsed_complete = 0;
- if(tcph->syn != 0 && tcph->ack == 0 && flow->l4.tcp.seen_syn == 0 && flow->l4.tcp.seen_syn_ack == 0 &&
- flow->l4.tcp.seen_ack == 0) {
- flow->l4.tcp.seen_syn = 1;
- } else
- if(tcph->syn != 0 && tcph->ack != 0 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 0 &&
- flow->l4.tcp.seen_ack == 0) {
- flow->l4.tcp.seen_syn_ack = 1;
- } else
- if(tcph->syn == 0 && tcph->ack == 1 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 1 &&
- flow->l4.tcp.seen_ack == 0) {
- flow->l4.tcp.seen_ack = 1;
+ if(flow->init_finished == 0) {
+ flow->init_finished = 1;
+ flow->setup_packet_direction = packet->packet_direction;
}
+ if(tcph != NULL) {
+ /* reset retried bytes here before setting it */
+ packet->num_retried_bytes = 0;
+
+ if(!ndpi_str->direction_detect_disable)
+ packet->packet_direction = (ntohs(tcph->source) < ntohs(tcph->dest)) ? 1 : 0;
+
+ if(tcph->syn != 0 && tcph->ack == 0 && flow->l4.tcp.seen_syn == 0 && flow->l4.tcp.seen_syn_ack == 0 &&
+ flow->l4.tcp.seen_ack == 0) {
+ flow->l4.tcp.seen_syn = 1;
+ } else
+ if(tcph->syn != 0 && tcph->ack != 0 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 0 &&
+ flow->l4.tcp.seen_ack == 0) {
+ flow->l4.tcp.seen_syn_ack = 1;
+ } else
+ if(tcph->syn == 0 && tcph->ack == 1 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 1 &&
+ flow->l4.tcp.seen_ack == 0) {
+ flow->l4.tcp.seen_ack = 1;
+ }
+
#ifdef FRAG_MAN
- // check sequence, if there is missing packet, add it to buffer
- if ( check_for_sequence(flow, tcph) ) {
- // if here added segment to list for next elaboration
- // and skip extra processing for after...
- return 0;
- }
+ // check sequence, if there is missing packet, add it to buffer
+ if( check_for_sequence(flow, tcph) ) {
+ // if here added segment to list for next elaboration
+ // and skip extra processing for after...
+ return 0;
+ }
#endif //FRAG_MAN
- if((flow->next_tcp_seq_nr[0] == 0 && flow->next_tcp_seq_nr[1] == 0) ||
- (flow->next_tcp_seq_nr[0] == 0 || flow->next_tcp_seq_nr[1] == 0)) {
- /* initialize tcp sequence counters */
- /* the ack flag needs to be set to get valid sequence numbers from the other
- * direction. Usually it will catch the second packet syn+ack but it works
- * also for asymmetric traffic where it will use the first data packet
- *
- * if the syn flag is set add one to the sequence number,
- * otherwise use the payload length.
- */
- if(tcph->ack != 0) {
- flow->next_tcp_seq_nr[flow->packet.packet_direction] =
- ntohl(tcph->seq) + (tcph->syn ? 1 : packet->payload_packet_len);
+ if((flow->next_tcp_seq_nr[0] == 0 && flow->next_tcp_seq_nr[1] == 0) ||
+ (flow->next_tcp_seq_nr[0] == 0 || flow->next_tcp_seq_nr[1] == 0)) {
+ /* initialize tcp sequence counters */
+ /* the ack flag needs to be set to get valid sequence numbers from the other
+ * direction. Usually it will catch the second packet syn+ack but it works
+ * also for asymmetric traffic where it will use the first data packet
+ *
+ * if the syn flag is set add one to the sequence number,
+ * otherwise use the payload length.
+ */
+ if(tcph->ack != 0) {
+ flow->next_tcp_seq_nr[flow->packet.packet_direction] =
+ ntohl(tcph->seq) + (tcph->syn ? 1 : packet->payload_packet_len);
+
+ /*
+ Check to avoid discrepancies in case we analyze a flow that does not start with SYN...
+ but that is already started when nDPI being to process it. See also (***) below
+ */
+ if(flow->num_processed_pkts > 1)
+ flow->next_tcp_seq_nr[1 - flow->packet.packet_direction] = ntohl(tcph->ack_seq);
+ }
+ } 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])) >
+ ndpi_str->tcp_max_retransmission_window_size) {
+ packet->tcp_retransmission = 1;
+
+ /* 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
+ Other analyzer can use packet->payload_packet_len */
+ packet->num_retried_bytes =
+ (u_int16_t)(flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq));
+ packet->actual_payload_len = packet->payload_packet_len - packet->num_retried_bytes;
+
+ if(flow->num_processed_pkts > 1) /* See also (***) above */
+ flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
+ }
+ }
- /*
- Check to avoid discrepancies in case we analyze a flow that does not start with SYN...
- but that is already started when nDPI being to process it. See also (***) below
- */
- if(flow->num_processed_pkts > 1)
- flow->next_tcp_seq_nr[1 - flow->packet.packet_direction] = ntohl(tcph->ack_seq);
- }
- } 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])) >
- ndpi_str->tcp_max_retransmission_window_size) {
- packet->tcp_retransmission = 1;
-
- /* 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
- Other analyzer can use packet->payload_packet_len */
- packet->num_retried_bytes =
- (u_int16_t)(flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq));
- packet->actual_payload_len = packet->payload_packet_len - packet->num_retried_bytes;
-
- if(flow->num_processed_pkts > 1) /* See also (***) above */
- 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 {
+ packet->num_retried_bytes = 0;
+ 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 {
- packet->num_retried_bytes = 0;
- flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
+ if(tcph->rst) {
+ flow->next_tcp_seq_nr[0] = 0;
+ flow->next_tcp_seq_nr[1] = 0;
}
+ } else if(udph != NULL) {
+ if(!ndpi_str->direction_detect_disable)
+ packet->packet_direction = (htons(udph->source) < htons(udph->dest)) ? 1 : 0;
}
- if(tcph->rst) {
- flow->next_tcp_seq_nr[0] = 0;
- flow->next_tcp_seq_nr[1] = 0;
+ if(flow->packet_counter < MAX_PACKET_COUNTER && packet->payload_packet_len) {
+ flow->packet_counter++;
}
- } else if(udph != NULL) {
- if(!ndpi_str->direction_detect_disable)
- packet->packet_direction = (htons(udph->source) < htons(udph->dest)) ? 1 : 0;
- }
-
- if(flow->packet_counter < MAX_PACKET_COUNTER && packet->payload_packet_len) {
- flow->packet_counter++;
- }
- if(flow->packet_direction_counter[packet->packet_direction] < MAX_PACKET_COUNTER &&
- packet->payload_packet_len) {
- flow->packet_direction_counter[packet->packet_direction]++;
- }
+ if(flow->packet_direction_counter[packet->packet_direction] < MAX_PACKET_COUNTER &&
+ packet->payload_packet_len) {
+ flow->packet_direction_counter[packet->packet_direction]++;
+ }
- if(flow->byte_counter[packet->packet_direction] + packet->payload_packet_len >
- flow->byte_counter[packet->packet_direction]) {
- flow->byte_counter[packet->packet_direction] += packet->payload_packet_len;
+ if(flow->byte_counter[packet->packet_direction] + packet->payload_packet_len >
+ flow->byte_counter[packet->packet_direction]) {
+ flow->byte_counter[packet->packet_direction] += packet->payload_packet_len;
+ }
}
- }
#ifdef FRAG_MAN
- return 1;
+ return 1;
#endif // FRAG_MAN
-}
-
-/* ************************************************ */
-
-u_int32_t check_ndpi_other_flow_func(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
- void *func = NULL;
- u_int32_t a, num_calls = 0;
- u_int16_t proto_index = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoIdx;
- int16_t proto_id = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoId;
- NDPI_PROTOCOL_BITMASK detection_bitmask;
-
- NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
-
- if((proto_id != NDPI_PROTOCOL_UNKNOWN) &&
- NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
- ndpi_str->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 &&
- NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer[proto_index].detection_bitmask, detection_bitmask) != 0 &&
- (ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask & *ndpi_selection_packet) ==
- ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask) {
- if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
- (ndpi_str->proto_defaults[flow->guessed_protocol_id].func != NULL))
- ndpi_str->proto_defaults[flow->guessed_protocol_id].func(ndpi_str, flow),
- func = ndpi_str->proto_defaults[flow->guessed_protocol_id].func, num_calls++;
- }
-
- for (a = 0; a < ndpi_str->callback_buffer_size_non_tcp_udp; a++) {
- if((func != ndpi_str->callback_buffer_non_tcp_udp[a].func) &&
- (ndpi_str->callback_buffer_non_tcp_udp[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
- ndpi_str->callback_buffer_non_tcp_udp[a].ndpi_selection_bitmask &&
- NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
- ndpi_str->callback_buffer_non_tcp_udp[a].excluded_protocol_bitmask) == 0 &&
- NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer_non_tcp_udp[a].detection_bitmask, detection_bitmask) != 0) {
- if(ndpi_str->callback_buffer_non_tcp_udp[a].func != NULL)
- ndpi_str->callback_buffer_non_tcp_udp[a].func(ndpi_str, flow), num_calls++;
-
- if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
- break; /* Stop after detecting the first protocol */
- }
}
- return(num_calls);
-}
+ /* ************************************************ */
-/* ************************************************ */
+ u_int32_t check_ndpi_other_flow_func(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
+ void *func = NULL;
+ u_int32_t a, num_calls = 0;
+ u_int16_t proto_index = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoIdx;
+ int16_t proto_id = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoId;
+ NDPI_PROTOCOL_BITMASK detection_bitmask;
-static u_int32_t check_ndpi_udp_flow_func(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
- void *func = NULL;
- u_int32_t a, num_calls = 0;
- u_int16_t proto_index = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoIdx;
- int16_t proto_id = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoId;
- NDPI_PROTOCOL_BITMASK detection_bitmask;
-
- NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
-
- if((proto_id != NDPI_PROTOCOL_UNKNOWN) &&
- NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
- ndpi_str->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 &&
- NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer[proto_index].detection_bitmask, detection_bitmask) != 0 &&
- (ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask & *ndpi_selection_packet) ==
- ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask) {
- if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
- (ndpi_str->proto_defaults[flow->guessed_protocol_id].func != NULL))
- ndpi_str->proto_defaults[flow->guessed_protocol_id].func(ndpi_str, flow),
- func = ndpi_str->proto_defaults[flow->guessed_protocol_id].func, num_calls++;
- }
-
- if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
- for (a = 0; a < ndpi_str->callback_buffer_size_udp; a++) {
- if((func != ndpi_str->callback_buffer_udp[a].func) &&
- (ndpi_str->callback_buffer_udp[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
- ndpi_str->callback_buffer_udp[a].ndpi_selection_bitmask &&
- NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
- ndpi_str->callback_buffer_udp[a].excluded_protocol_bitmask) == 0 &&
- NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer_udp[a].detection_bitmask, detection_bitmask) != 0) {
- ndpi_str->callback_buffer_udp[a].func(ndpi_str, flow), num_calls++;
+ NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
- // NDPI_LOG_DBG(ndpi_str, "[UDP,CALL] dissector of protocol as callback_buffer idx = %d\n",a);
+ if((proto_id != NDPI_PROTOCOL_UNKNOWN) &&
+ NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_str->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 &&
+ NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer[proto_index].detection_bitmask, detection_bitmask) != 0 &&
+ (ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask & *ndpi_selection_packet) ==
+ ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask) {
+ if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
+ (ndpi_str->proto_defaults[flow->guessed_protocol_id].func != NULL))
+ ndpi_str->proto_defaults[flow->guessed_protocol_id].func(ndpi_str, flow),
+ func = ndpi_str->proto_defaults[flow->guessed_protocol_id].func, num_calls++;
+ }
-#ifdef DEBUG_UDP_CALLS
- {
- char buf[64];
- u_int16_t proto_id = ndpi_str->callback_buffer_udp[a].ndpi_protocol_id;
- ndpi_protocol proto = { proto_id, proto_id, 0 };
- printf("-> [UDP,CALL] dissector of protocol as callback_buffer idx = %d / %s\n",
- proto_id, ndpi_protocol2name(ndpi_str, proto, buf, sizeof(buf)));
- }
-#endif
+ for (a = 0; a < ndpi_str->callback_buffer_size_non_tcp_udp; a++) {
+ if((func != ndpi_str->callback_buffer_non_tcp_udp[a].func) &&
+ (ndpi_str->callback_buffer_non_tcp_udp[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
+ ndpi_str->callback_buffer_non_tcp_udp[a].ndpi_selection_bitmask &&
+ NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_str->callback_buffer_non_tcp_udp[a].excluded_protocol_bitmask) == 0 &&
+ NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer_non_tcp_udp[a].detection_bitmask, detection_bitmask) != 0) {
+ if(ndpi_str->callback_buffer_non_tcp_udp[a].func != NULL)
+ ndpi_str->callback_buffer_non_tcp_udp[a].func(ndpi_str, flow), num_calls++;
if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
break; /* Stop after detecting the first protocol */
- } else if(_ndpi_debug_callbacks)
- NDPI_LOG_DBG2(ndpi_str, "[UDP,SKIP] dissector of protocol as callback_buffer idx = %d\n", a);
+ }
}
- } else
- num_calls = 1;
- return(num_calls);
-}
+ return(num_calls);
+ }
-/* ************************************************ */
+ /* ************************************************ */
-static u_int32_t check_ndpi_tcp_flow_func(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
- void *func = NULL;
- u_int32_t a, num_calls = 0;
- u_int16_t proto_index = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoIdx;
- int16_t proto_id = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoId;
- NDPI_PROTOCOL_BITMASK detection_bitmask;
+ static u_int32_t check_ndpi_udp_flow_func(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
+ void *func = NULL;
+ u_int32_t a, num_calls = 0;
+ u_int16_t proto_index = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoIdx;
+ int16_t proto_id = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoId;
+ NDPI_PROTOCOL_BITMASK detection_bitmask;
- NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
+ NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
- if(flow->packet.payload_packet_len != 0) {
if((proto_id != NDPI_PROTOCOL_UNKNOWN) &&
NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
ndpi_str->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 &&
@@ -4090,1449 +4031,1512 @@ static u_int32_t check_ndpi_tcp_flow_func(struct ndpi_detection_module_struct *n
}
if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
- for (a = 0; a < ndpi_str->callback_buffer_size_tcp_payload; a++) {
- if((func != ndpi_str->callback_buffer_tcp_payload[a].func) &&
- (ndpi_str->callback_buffer_tcp_payload[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
- ndpi_str->callback_buffer_tcp_payload[a].ndpi_selection_bitmask &&
+ for (a = 0; a < ndpi_str->callback_buffer_size_udp; a++) {
+ if((func != ndpi_str->callback_buffer_udp[a].func) &&
+ (ndpi_str->callback_buffer_udp[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
+ ndpi_str->callback_buffer_udp[a].ndpi_selection_bitmask &&
NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
- ndpi_str->callback_buffer_tcp_payload[a].excluded_protocol_bitmask) == 0 &&
- NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer_tcp_payload[a].detection_bitmask,
- detection_bitmask) != 0) {
- ndpi_str->callback_buffer_tcp_payload[a].func(ndpi_str, flow), num_calls++;
+ ndpi_str->callback_buffer_udp[a].excluded_protocol_bitmask) == 0 &&
+ NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer_udp[a].detection_bitmask, detection_bitmask) != 0) {
+ ndpi_str->callback_buffer_udp[a].func(ndpi_str, flow), num_calls++;
+
+ // NDPI_LOG_DBG(ndpi_str, "[UDP,CALL] dissector of protocol as callback_buffer idx = %d\n",a);
+
+#ifdef DEBUG_UDP_CALLS
+ {
+ char buf[64];
+ u_int16_t proto_id = ndpi_str->callback_buffer_udp[a].ndpi_protocol_id;
+ ndpi_protocol proto = { proto_id, proto_id, 0 };
+ printf("-> [UDP,CALL] dissector of protocol as callback_buffer idx = %d / %s\n",
+ proto_id, ndpi_protocol2name(ndpi_str, proto, buf, sizeof(buf)));
+ }
+#endif
+
if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
break; /* Stop after detecting the first protocol */
- }
+ } else if(_ndpi_debug_callbacks)
+ NDPI_LOG_DBG2(ndpi_str, "[UDP,SKIP] dissector of protocol as callback_buffer idx = %d\n", a);
}
- }
- } else {
- /* no payload */
+ } else
+ num_calls = 1;
- num_calls = 1;
+ return(num_calls);
+ }
- if((proto_id != NDPI_PROTOCOL_UNKNOWN) &&
- NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
- ndpi_str->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 &&
- NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer[proto_index].detection_bitmask, detection_bitmask) != 0 &&
- (ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask & *ndpi_selection_packet) ==
- ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask) {
- if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
- (ndpi_str->proto_defaults[flow->guessed_protocol_id].func != NULL) &&
- ((ndpi_str->callback_buffer[flow->guessed_protocol_id].ndpi_selection_bitmask &
- NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) == 0))
- ndpi_str->proto_defaults[flow->guessed_protocol_id].func(ndpi_str, flow),
- func = ndpi_str->proto_defaults[flow->guessed_protocol_id].func, num_calls++;
- }
+ /* ************************************************ */
+
+ static u_int32_t check_ndpi_tcp_flow_func(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
+ void *func = NULL;
+ u_int32_t a, num_calls = 0;
+ u_int16_t proto_index = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoIdx;
+ int16_t proto_id = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoId;
+ NDPI_PROTOCOL_BITMASK detection_bitmask;
+
+ NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
- for (a = 0; a < ndpi_str->callback_buffer_size_tcp_no_payload; a++) {
- if((func != ndpi_str->callback_buffer_tcp_payload[a].func) &&
- (ndpi_str->callback_buffer_tcp_no_payload[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
- ndpi_str->callback_buffer_tcp_no_payload[a].ndpi_selection_bitmask &&
+ if(flow->packet.payload_packet_len != 0) {
+ if((proto_id != NDPI_PROTOCOL_UNKNOWN) &&
NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
- ndpi_str->callback_buffer_tcp_no_payload[a].excluded_protocol_bitmask) == 0 &&
- NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer_tcp_no_payload[a].detection_bitmask,
- detection_bitmask) != 0) {
- ndpi_str->callback_buffer_tcp_no_payload[a].func(ndpi_str, flow), num_calls++;
- if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
- break; /* Stop after detecting the first protocol */
+ ndpi_str->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 &&
+ NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer[proto_index].detection_bitmask, detection_bitmask) != 0 &&
+ (ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask & *ndpi_selection_packet) ==
+ ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask) {
+ if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
+ (ndpi_str->proto_defaults[flow->guessed_protocol_id].func != NULL))
+ ndpi_str->proto_defaults[flow->guessed_protocol_id].func(ndpi_str, flow),
+ func = ndpi_str->proto_defaults[flow->guessed_protocol_id].func, num_calls++;
+ }
+
+ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+ for (a = 0; a < ndpi_str->callback_buffer_size_tcp_payload; a++) {
+ if((func != ndpi_str->callback_buffer_tcp_payload[a].func) &&
+ (ndpi_str->callback_buffer_tcp_payload[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
+ ndpi_str->callback_buffer_tcp_payload[a].ndpi_selection_bitmask &&
+ NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_str->callback_buffer_tcp_payload[a].excluded_protocol_bitmask) == 0 &&
+ NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer_tcp_payload[a].detection_bitmask,
+ detection_bitmask) != 0) {
+ ndpi_str->callback_buffer_tcp_payload[a].func(ndpi_str, flow), num_calls++;
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ break; /* Stop after detecting the first protocol */
+ }
+ }
+ }
+ } else {
+ /* no payload */
+
+ num_calls = 1;
+
+ if((proto_id != NDPI_PROTOCOL_UNKNOWN) &&
+ NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_str->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 &&
+ NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer[proto_index].detection_bitmask, detection_bitmask) != 0 &&
+ (ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask & *ndpi_selection_packet) ==
+ ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask) {
+ if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
+ (ndpi_str->proto_defaults[flow->guessed_protocol_id].func != NULL) &&
+ ((ndpi_str->callback_buffer[flow->guessed_protocol_id].ndpi_selection_bitmask &
+ NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) == 0))
+ ndpi_str->proto_defaults[flow->guessed_protocol_id].func(ndpi_str, flow),
+ func = ndpi_str->proto_defaults[flow->guessed_protocol_id].func, num_calls++;
+ }
+
+ for (a = 0; a < ndpi_str->callback_buffer_size_tcp_no_payload; a++) {
+ if((func != ndpi_str->callback_buffer_tcp_payload[a].func) &&
+ (ndpi_str->callback_buffer_tcp_no_payload[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
+ ndpi_str->callback_buffer_tcp_no_payload[a].ndpi_selection_bitmask &&
+ NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_str->callback_buffer_tcp_no_payload[a].excluded_protocol_bitmask) == 0 &&
+ NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer_tcp_no_payload[a].detection_bitmask,
+ detection_bitmask) != 0) {
+ ndpi_str->callback_buffer_tcp_no_payload[a].func(ndpi_str, flow), num_calls++;
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ break; /* Stop after detecting the first protocol */
+ }
}
}
- }
- return(num_calls);
-}
+ return(num_calls);
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-u_int32_t ndpi_check_flow_func(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
- if(!flow)
- return(0);
- else if(flow->packet.tcp != NULL)
- return(check_ndpi_tcp_flow_func(ndpi_str, flow, ndpi_selection_packet));
- else if(flow->packet.udp != NULL)
- return(check_ndpi_udp_flow_func(ndpi_str, flow, ndpi_selection_packet));
- else
- return(check_ndpi_other_flow_func(ndpi_str, flow, ndpi_selection_packet));
-}
+ u_int32_t ndpi_check_flow_func(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
+ if(!flow)
+ return(0);
+ else if(flow->packet.tcp != NULL)
+ return(check_ndpi_tcp_flow_func(ndpi_str, flow, ndpi_selection_packet));
+ else if(flow->packet.udp != NULL)
+ return(check_ndpi_udp_flow_func(ndpi_str, flow, ndpi_selection_packet));
+ else
+ return(check_ndpi_other_flow_func(ndpi_str, flow, ndpi_selection_packet));
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-u_int16_t ndpi_guess_host_protocol_id(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow) {
- u_int16_t ret = NDPI_PROTOCOL_UNKNOWN;
+ u_int16_t ndpi_guess_host_protocol_id(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow) {
+ u_int16_t ret = NDPI_PROTOCOL_UNKNOWN;
- if(flow->packet.iph) {
- struct in_addr addr;
- u_int16_t sport, dport;
+ if(flow->packet.iph) {
+ struct in_addr addr;
+ u_int16_t sport, dport;
- addr.s_addr = flow->packet.iph->saddr;
+ 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;
+ 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_port_ptree_match(ndpi_str, &addr, sport);
+ /* guess host protocol */
+ 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_port_ptree_match(ndpi_str, &addr, dport);
+ if(ret == NDPI_PROTOCOL_UNKNOWN) {
+ addr.s_addr = flow->packet.iph->daddr;
+ ret = ndpi_network_port_ptree_match(ndpi_str, &addr, dport);
+ }
}
+
+ return(ret);
}
- return(ret);
-}
+ /* ********************************************************************************* */
-/* ********************************************************************************* */
+ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ u_int8_t enable_guess, u_int8_t *protocol_was_guessed) {
+ ndpi_protocol ret = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED};
-ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- u_int8_t enable_guess, u_int8_t *protocol_was_guessed) {
- ndpi_protocol ret = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED};
+ *protocol_was_guessed = 0;
- *protocol_was_guessed = 0;
+ if(flow == NULL)
+ return(ret);
- if(flow == NULL)
- return(ret);
+ /* Init defaults */
+ ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
+ ret.category = flow->category;
- /* Init defaults */
- ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
- ret.category = flow->category;
+ /* Ensure that we don't change our mind if detection is already complete */
+ if((ret.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
+ return(ret);
- /* Ensure that we don't change our mind if detection is already complete */
- if((ret.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
- return(ret);
+ /* TODO: add the remaining stage_XXXX protocols */
+ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+ u_int16_t guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN, guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
- /* TODO: add the remaining stage_XXXX protocols */
- if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
- u_int16_t guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN, guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
+ if(flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)
+ goto check_stun_export;
+ else if((flow->guessed_protocol_id == NDPI_PROTOCOL_HANGOUT_DUO) ||
+ (flow->guessed_protocol_id == NDPI_PROTOCOL_MESSENGER) ||
+ (flow->guessed_protocol_id == NDPI_PROTOCOL_WHATSAPP_CALL)) {
+ *protocol_was_guessed = 1;
+ ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_protocol_id, NDPI_PROTOCOL_UNKNOWN);
+ }
+ else if((flow->l4.tcp.tls.hello_processed == 1) &&
+ (flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0')) {
+ *protocol_was_guessed = 1;
+ ndpi_set_detected_protocol(ndpi_str, flow, NDPI_PROTOCOL_TLS, NDPI_PROTOCOL_UNKNOWN);
+ } else if(enable_guess) {
+ if((flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) && (flow->packet.l4_protocol == IPPROTO_TCP) &&
+ flow->l4.tcp.tls.hello_processed)
+ flow->guessed_protocol_id = NDPI_PROTOCOL_TLS;
+
+ guessed_protocol_id = flow->guessed_protocol_id, guessed_host_protocol_id = flow->guessed_host_protocol_id;
+
+ if((guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
+ ((flow->packet.l4_protocol == IPPROTO_UDP) &&
+ NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_host_protocol_id) &&
+ is_udp_guessable_protocol(guessed_host_protocol_id)))
+ flow->guessed_host_protocol_id = guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
+
+ /* Ignore guessed protocol if they have been discarded */
+ if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)
+ // && (guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN)
+ && (flow->packet.l4_protocol == IPPROTO_UDP) &&
+ NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_protocol_id) &&
+ is_udp_guessable_protocol(guessed_protocol_id))
+ flow->guessed_protocol_id = guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN;
+
+ if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) || (guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
+ if((guessed_protocol_id == 0) && (flow->protos.tls_quic_stun.stun.num_binding_requests > 0) &&
+ (flow->protos.tls_quic_stun.stun.num_processed_pkts > 0))
+ guessed_protocol_id = NDPI_PROTOCOL_STUN;
+
+ if(flow->host_server_name[0] != '\0') {
+ ndpi_protocol_match_result ret_match;
+
+ memset(&ret_match, 0, sizeof(ret_match));
+
+ ndpi_match_host_subprotocol(ndpi_str, flow, (char *) flow->host_server_name,
+ strlen((const char *) flow->host_server_name), &ret_match,
+ NDPI_PROTOCOL_DNS);
+
+ if(ret_match.protocol_id != NDPI_PROTOCOL_UNKNOWN)
+ guessed_host_protocol_id = ret_match.protocol_id;
+ }
- if(flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)
- goto check_stun_export;
- else if((flow->guessed_protocol_id == NDPI_PROTOCOL_HANGOUT_DUO) ||
- (flow->guessed_protocol_id == NDPI_PROTOCOL_MESSENGER) ||
- (flow->guessed_protocol_id == NDPI_PROTOCOL_WHATSAPP_CALL)) {
- *protocol_was_guessed = 1;
- ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_protocol_id, NDPI_PROTOCOL_UNKNOWN);
- }
- else if((flow->l4.tcp.tls.hello_processed == 1) &&
- (flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0')) {
- *protocol_was_guessed = 1;
- ndpi_set_detected_protocol(ndpi_str, flow, NDPI_PROTOCOL_TLS, NDPI_PROTOCOL_UNKNOWN);
- } else if(enable_guess) {
- if((flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) && (flow->packet.l4_protocol == IPPROTO_TCP) &&
- flow->l4.tcp.tls.hello_processed)
- flow->guessed_protocol_id = NDPI_PROTOCOL_TLS;
-
- guessed_protocol_id = flow->guessed_protocol_id, guessed_host_protocol_id = flow->guessed_host_protocol_id;
-
- if((guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
- ((flow->packet.l4_protocol == IPPROTO_UDP) &&
- NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_host_protocol_id) &&
- is_udp_guessable_protocol(guessed_host_protocol_id)))
- flow->guessed_host_protocol_id = guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
-
- /* Ignore guessed protocol if they have been discarded */
- if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)
- // && (guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN)
- && (flow->packet.l4_protocol == IPPROTO_UDP) &&
- NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_protocol_id) &&
- is_udp_guessable_protocol(guessed_protocol_id))
- flow->guessed_protocol_id = guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN;
-
- if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) || (guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
- if((guessed_protocol_id == 0) && (flow->protos.tls_quic_stun.stun.num_binding_requests > 0) &&
- (flow->protos.tls_quic_stun.stun.num_processed_pkts > 0))
- guessed_protocol_id = NDPI_PROTOCOL_STUN;
-
- if(flow->host_server_name[0] != '\0') {
- ndpi_protocol_match_result ret_match;
-
- memset(&ret_match, 0, sizeof(ret_match));
-
- ndpi_match_host_subprotocol(ndpi_str, flow, (char *) flow->host_server_name,
- strlen((const char *) flow->host_server_name), &ret_match,
- NDPI_PROTOCOL_DNS);
-
- if(ret_match.protocol_id != NDPI_PROTOCOL_UNKNOWN)
- guessed_host_protocol_id = ret_match.protocol_id;
+ *protocol_was_guessed = 1;
+ ndpi_int_change_protocol(ndpi_str, flow, guessed_host_protocol_id, guessed_protocol_id);
}
+ }
+ } else if(enable_guess) {
+ if(flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
+ *protocol_was_guessed = 1;
+ flow->detected_protocol_stack[1] = flow->guessed_protocol_id;
+ }
+ if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
*protocol_was_guessed = 1;
- ndpi_int_change_protocol(ndpi_str, flow, guessed_host_protocol_id, guessed_protocol_id);
+ flow->detected_protocol_stack[0] = flow->guessed_host_protocol_id;
}
- }
- } else if(enable_guess) {
- if(flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
- *protocol_was_guessed = 1;
- flow->detected_protocol_stack[1] = flow->guessed_protocol_id;
- }
- if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
- *protocol_was_guessed = 1;
- flow->detected_protocol_stack[0] = flow->guessed_host_protocol_id;
+ if(flow->detected_protocol_stack[1] == flow->detected_protocol_stack[0]) {
+ *protocol_was_guessed = 1;
+ flow->detected_protocol_stack[1] = flow->guessed_host_protocol_id;
+ }
}
- if(flow->detected_protocol_stack[1] == flow->detected_protocol_stack[0]) {
- *protocol_was_guessed = 1;
- flow->detected_protocol_stack[1] = flow->guessed_host_protocol_id;
+ if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) &&
+ (flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)) {
+ check_stun_export:
+ if(flow->protos.tls_quic_stun.stun.num_processed_pkts || flow->protos.tls_quic_stun.stun.num_udp_pkts) {
+ // if(/* (flow->protos.tls_quic_stun.stun.num_processed_pkts >= NDPI_MIN_NUM_STUN_DETECTION) */
+ *protocol_was_guessed = 1;
+ ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_STUN);
+ }
}
- }
- if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) &&
- (flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)) {
- check_stun_export:
- if(flow->protos.tls_quic_stun.stun.num_processed_pkts || flow->protos.tls_quic_stun.stun.num_udp_pkts) {
- // if(/* (flow->protos.tls_quic_stun.stun.num_processed_pkts >= NDPI_MIN_NUM_STUN_DETECTION) */
- *protocol_was_guessed = 1;
- ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_STUN);
- }
- }
+ ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
- ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
+ if(ret.master_protocol == NDPI_PROTOCOL_STUN) {
+ if(ret.app_protocol == NDPI_PROTOCOL_FACEBOOK)
+ ret.app_protocol = NDPI_PROTOCOL_MESSENGER;
+ else if(ret.app_protocol == NDPI_PROTOCOL_GOOGLE) {
+ /*
+ As Google has recently introduced Duo,
+ we need to distinguish between it and hangout
+ thing that should be handled by the STUN dissector
+ */
+ ret.app_protocol = NDPI_PROTOCOL_HANGOUT_DUO;
+ }
+ }
- if(ret.master_protocol == NDPI_PROTOCOL_STUN) {
- if(ret.app_protocol == NDPI_PROTOCOL_FACEBOOK)
- ret.app_protocol = NDPI_PROTOCOL_MESSENGER;
- else if(ret.app_protocol == NDPI_PROTOCOL_GOOGLE) {
- /*
- As Google has recently introduced Duo,
- we need to distinguish between it and hangout
- thing that should be handled by the STUN dissector
- */
- ret.app_protocol = NDPI_PROTOCOL_HANGOUT_DUO;
+ if(ret.app_protocol != NDPI_PROTOCOL_UNKNOWN) {
+ *protocol_was_guessed = 1;
+ ndpi_fill_protocol_category(ndpi_str, flow, &ret);
}
- }
- if(ret.app_protocol != NDPI_PROTOCOL_UNKNOWN) {
- *protocol_was_guessed = 1;
- ndpi_fill_protocol_category(ndpi_str, flow, &ret);
+ return(ret);
}
- return(ret);
-}
-
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-void ndpi_process_extra_packet(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- const unsigned char *packet, const unsigned short packetlen,
- const u_int64_t current_time_ms, struct ndpi_id_struct *src, struct ndpi_id_struct *dst) {
- if(flow == NULL)
- return;
+ void ndpi_process_extra_packet(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ const unsigned char *packet, const unsigned short packetlen,
+ const u_int64_t current_time_ms, struct ndpi_id_struct *src, struct ndpi_id_struct *dst) {
+ if(flow == NULL)
+ return;
- if(flow->server_id == NULL)
- flow->server_id = dst; /* Default */
+ if(flow->server_id == NULL)
+ flow->server_id = dst; /* Default */
- /* need at least 20 bytes for ip header */
- if(packetlen < 20) {
- return;
- }
+ /* need at least 20 bytes for ip header */
+ if(packetlen < 20) {
+ return;
+ }
- flow->packet.current_time_ms = current_time_ms;
+ flow->packet.current_time_ms = current_time_ms;
- /* parse packet */
- flow->packet.iph = (struct ndpi_iphdr *) packet;
- /* we are interested in ipv4 packet */
+ /* parse packet */
+ flow->packet.iph = (struct ndpi_iphdr *) packet;
+ /* we are interested in ipv4 packet */
- /* set up the packet headers for the extra packet function to use if it wants */
- if(ndpi_init_packet_header(ndpi_str, flow, packetlen) != 0)
- return;
+ /* set up the packet headers for the extra packet function to use if it wants */
+ if(ndpi_init_packet_header(ndpi_str, flow, packetlen) != 0)
+ return;
- /* detect traffic for tcp or udp only */
- flow->src = src, flow->dst = dst;
+ /* detect traffic for tcp or udp only */
+ flow->src = src, flow->dst = dst;
#ifdef FRAG_MAN
- if ( ndpi_connection_tracking(ndpi_str, flow) ) {
+ if( ndpi_connection_tracking(ndpi_str, flow) ) {
#else // FRAG_MAN
- ndpi_connection_tracking(ndpi_str, flow);
+ ndpi_connection_tracking(ndpi_str, flow);
#endif // FRAG_MAN
- /* call the extra packet function (which may add more data/info to flow) */
- if(flow->extra_packets_func) {
- if((flow->extra_packets_func(ndpi_str, flow)) == 0)
- flow->check_extra_packets = 0;
+ /* call the extra packet function (which may add more data/info to flow) */
+ if(flow->extra_packets_func) {
+ if((flow->extra_packets_func(ndpi_str, flow)) == 0)
+ flow->check_extra_packets = 0;
- if(++flow->num_extra_packets_checked == flow->max_extra_packets_to_check)
- flow->extra_packets_func = NULL; /* Enough packets detected */
- }
+ if(++flow->num_extra_packets_checked == flow->max_extra_packets_to_check)
+ flow->extra_packets_func = NULL; /* Enough packets detected */
+ }
#ifdef FRAG_MAN
- }
+ }
#endif // FRAG_MAN
-}
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-int ndpi_load_ip_category(struct ndpi_detection_module_struct *ndpi_str, const char *ip_address_and_mask,
- ndpi_protocol_category_t category) {
- patricia_node_t *node;
- struct in_addr pin;
- int bits = 32;
- char *ptr;
- char ipbuf[64];
+ int ndpi_load_ip_category(struct ndpi_detection_module_struct *ndpi_str, const char *ip_address_and_mask,
+ ndpi_protocol_category_t category) {
+ patricia_node_t *node;
+ struct in_addr pin;
+ int bits = 32;
+ char *ptr;
+ char ipbuf[64];
- strncpy(ipbuf, ip_address_and_mask, sizeof(ipbuf));
- ipbuf[sizeof(ipbuf) - 1] = '\0';
+ strncpy(ipbuf, ip_address_and_mask, sizeof(ipbuf));
+ ipbuf[sizeof(ipbuf) - 1] = '\0';
- ptr = strrchr(ipbuf, '/');
+ ptr = strrchr(ipbuf, '/');
- if(ptr) {
- *(ptr++) = '\0';
- if(atoi(ptr) >= 0 && atoi(ptr) <= 32)
- bits = atoi(ptr);
- }
+ if(ptr) {
+ *(ptr++) = '\0';
+ if(atoi(ptr) >= 0 && atoi(ptr) <= 32)
+ bits = atoi(ptr);
+ }
- if(inet_pton(AF_INET, ipbuf, &pin) != 1) {
- NDPI_LOG_DBG2(ndpi_str, "Invalid ip/ip+netmask: %s\n", ip_address_and_mask);
- return(-1);
- }
+ if(inet_pton(AF_INET, ipbuf, &pin) != 1) {
+ NDPI_LOG_DBG2(ndpi_str, "Invalid ip/ip+netmask: %s\n", ip_address_and_mask);
+ return(-1);
+ }
- if((node = add_to_ptree(ndpi_str->custom_categories.ipAddresses_shadow, AF_INET, &pin, bits)) != NULL) {
- node->value.u.uv32.user_value = (u_int16_t)category, node->value.u.uv32.additional_user_value = 0;
- }
+ if((node = add_to_ptree(ndpi_str->custom_categories.ipAddresses_shadow, AF_INET, &pin, bits)) != NULL) {
+ node->value.u.uv32.user_value = (u_int16_t)category, node->value.u.uv32.additional_user_value = 0;
+ }
- return(0);
-}
+ return(0);
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-int ndpi_load_hostname_category(struct ndpi_detection_module_struct *ndpi_str, const char *name_to_add,
- ndpi_protocol_category_t category) {
- char *name;
+ int ndpi_load_hostname_category(struct ndpi_detection_module_struct *ndpi_str, const char *name_to_add,
+ ndpi_protocol_category_t category) {
+ char *name;
- if(name_to_add == NULL)
- return(-1);
+ if(name_to_add == NULL)
+ return(-1);
- name = ndpi_strdup(name_to_add);
+ name = ndpi_strdup(name_to_add);
- if(name == NULL)
- return(-1);
+ if(name == NULL)
+ return(-1);
#if 0
- printf("===> %s() Loading %s as %u\n", __FUNCTION__, name, category);
+ printf("===> %s() Loading %s as %u\n", __FUNCTION__, name, category);
#endif
- AC_PATTERN_t ac_pattern;
- AC_ERROR_t rc;
+ AC_PATTERN_t ac_pattern;
+ AC_ERROR_t rc;
- memset(&ac_pattern, 0, sizeof(ac_pattern));
+ memset(&ac_pattern, 0, sizeof(ac_pattern));
- if(ndpi_str->custom_categories.hostnames_shadow.ac_automa == NULL) {
- ndpi_free(name);
- return(-1);
- }
-
- ac_pattern.astring = name, ac_pattern.length = strlen(ac_pattern.astring);
- ac_pattern.rep.number = (u_int32_t) category, ac_pattern.rep.category = category;;
+ if(ndpi_str->custom_categories.hostnames_shadow.ac_automa == NULL) {
+ ndpi_free(name);
+ return(-1);
+ }
- rc = ac_automata_add(ndpi_str->custom_categories.hostnames_shadow.ac_automa, &ac_pattern);
- if(rc != ACERR_DUPLICATE_PATTERN && rc != ACERR_SUCCESS) {
- ndpi_free(name);
- return(-1);
- }
+ ac_pattern.astring = name, ac_pattern.length = strlen(ac_pattern.astring);
+ ac_pattern.rep.number = (u_int32_t) category, ac_pattern.rep.category = category;;
- if(rc == ACERR_DUPLICATE_PATTERN)
- ndpi_free(name);
+ rc = ac_automata_add(ndpi_str->custom_categories.hostnames_shadow.ac_automa, &ac_pattern);
+ if(rc != ACERR_DUPLICATE_PATTERN && rc != ACERR_SUCCESS) {
+ ndpi_free(name);
+ return(-1);
+ }
- return(0);
-}
+ if(rc == ACERR_DUPLICATE_PATTERN)
+ ndpi_free(name);
-/* ********************************************************************************* */
+ return(0);
+ }
-/* Loads an IP or name category */
-int ndpi_load_category(struct ndpi_detection_module_struct *ndpi_struct, const char *ip_or_name,
- ndpi_protocol_category_t category) {
- int rv;
+ /* ********************************************************************************* */
- /* Try to load as IP address first */
- rv = ndpi_load_ip_category(ndpi_struct, ip_or_name, category);
+ /* Loads an IP or name category */
+ int ndpi_load_category(struct ndpi_detection_module_struct *ndpi_struct, const char *ip_or_name,
+ ndpi_protocol_category_t category) {
+ int rv;
- if(rv < 0) {
- /* IP load failed, load as hostname */
- rv = ndpi_load_hostname_category(ndpi_struct, ip_or_name, category);
- }
+ /* Try to load as IP address first */
+ rv = ndpi_load_ip_category(ndpi_struct, ip_or_name, category);
- return(rv);
-}
+ if(rv < 0) {
+ /* IP load failed, load as hostname */
+ rv = ndpi_load_hostname_category(ndpi_struct, ip_or_name, category);
+ }
-/* ********************************************************************************* */
+ return(rv);
+ }
-int ndpi_enable_loaded_categories(struct ndpi_detection_module_struct *ndpi_str) {
- int i;
+ /* ********************************************************************************* */
- /* First add the nDPI known categories matches */
- for (i = 0; category_match[i].string_to_match != NULL; i++)
- ndpi_load_category(ndpi_str, category_match[i].string_to_match, category_match[i].protocol_category);
+ int ndpi_enable_loaded_categories(struct ndpi_detection_module_struct *ndpi_str) {
+ int i;
- /* Free */
- ac_automata_release((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames.ac_automa,
- 1 /* free patterns strings memory */);
+ /* First add the nDPI known categories matches */
+ for (i = 0; category_match[i].string_to_match != NULL; i++)
+ ndpi_load_category(ndpi_str, category_match[i].string_to_match, category_match[i].protocol_category);
- /* Finalize */
- ac_automata_finalize((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames_shadow.ac_automa);
+ /* Free */
+ ac_automata_release((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames.ac_automa,
+ 1 /* free patterns strings memory */);
- /* Swap */
- ndpi_str->custom_categories.hostnames.ac_automa = ndpi_str->custom_categories.hostnames_shadow.ac_automa;
+ /* Finalize */
+ ac_automata_finalize((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames_shadow.ac_automa);
- /* Realloc */
- ndpi_str->custom_categories.hostnames_shadow.ac_automa = ac_automata_init(ac_match_handler);
+ /* Swap */
+ ndpi_str->custom_categories.hostnames.ac_automa = ndpi_str->custom_categories.hostnames_shadow.ac_automa;
- if(ndpi_str->custom_categories.ipAddresses != NULL)
- ndpi_Destroy_Patricia((patricia_tree_t *) ndpi_str->custom_categories.ipAddresses, free_ptree_data);
+ /* Realloc */
+ ndpi_str->custom_categories.hostnames_shadow.ac_automa = ac_automata_init(ac_match_handler);
- ndpi_str->custom_categories.ipAddresses = ndpi_str->custom_categories.ipAddresses_shadow;
- ndpi_str->custom_categories.ipAddresses_shadow = ndpi_New_Patricia(32 /* IPv4 */);
+ if(ndpi_str->custom_categories.ipAddresses != NULL)
+ ndpi_Destroy_Patricia((patricia_tree_t *) ndpi_str->custom_categories.ipAddresses, free_ptree_data);
- ndpi_str->custom_categories.categories_loaded = 1;
+ ndpi_str->custom_categories.ipAddresses = ndpi_str->custom_categories.ipAddresses_shadow;
+ ndpi_str->custom_categories.ipAddresses_shadow = ndpi_New_Patricia(32 /* IPv4 */);
- return(0);
-}
+ ndpi_str->custom_categories.categories_loaded = 1;
-/* ********************************************************************************* */
+ return(0);
+ }
-int ndpi_fill_ip_protocol_category(struct ndpi_detection_module_struct *ndpi_str, u_int32_t saddr, u_int32_t daddr,
- ndpi_protocol *ret) {
- if(ndpi_str->custom_categories.categories_loaded) {
- prefix_t prefix;
- patricia_node_t *node;
+ /* ********************************************************************************* */
- if(saddr == 0)
- node = NULL;
- else {
- /* Make sure all in network byte order otherwise compares wont work */
- fill_prefix_v4(&prefix, (struct in_addr *) &saddr, 32,
- ((patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
- node = ndpi_patricia_search_best(ndpi_str->custom_categories.ipAddresses, &prefix);
- }
+ int ndpi_fill_ip_protocol_category(struct ndpi_detection_module_struct *ndpi_str, u_int32_t saddr, u_int32_t daddr,
+ ndpi_protocol *ret) {
+ if(ndpi_str->custom_categories.categories_loaded) {
+ prefix_t prefix;
+ patricia_node_t *node;
- if(!node) {
- if(daddr != 0) {
- fill_prefix_v4(&prefix, (struct in_addr *) &daddr, 32,
+ if(saddr == 0)
+ node = NULL;
+ else {
+ /* Make sure all in network byte order otherwise compares wont work */
+ fill_prefix_v4(&prefix, (struct in_addr *) &saddr, 32,
((patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
node = ndpi_patricia_search_best(ndpi_str->custom_categories.ipAddresses, &prefix);
}
- }
- if(node) {
- ret->category = (ndpi_protocol_category_t) node->value.u.uv32.user_value;
+ if(!node) {
+ if(daddr != 0) {
+ fill_prefix_v4(&prefix, (struct in_addr *) &daddr, 32,
+ ((patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
+ node = ndpi_patricia_search_best(ndpi_str->custom_categories.ipAddresses, &prefix);
+ }
+ }
- return(1);
+ if(node) {
+ ret->category = (ndpi_protocol_category_t) node->value.u.uv32.user_value;
+
+ return(1);
+ }
}
- }
- ret->category = ndpi_get_proto_category(ndpi_str, *ret);
+ ret->category = ndpi_get_proto_category(ndpi_str, *ret);
- return(0);
-}
+ return(0);
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-void ndpi_fill_protocol_category(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- ndpi_protocol *ret) {
- if(ndpi_str->custom_categories.categories_loaded) {
- if(flow->guessed_header_category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) {
- flow->category = ret->category = flow->guessed_header_category;
- return;
- }
+ void ndpi_fill_protocol_category(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ ndpi_protocol *ret) {
+ if(ndpi_str->custom_categories.categories_loaded) {
+ if(flow->guessed_header_category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) {
+ flow->category = ret->category = flow->guessed_header_category;
+ return;
+ }
- if(flow->host_server_name[0] != '\0') {
- u_int32_t id;
- int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->host_server_name,
- strlen((char *) flow->host_server_name), &id);
+ if(flow->host_server_name[0] != '\0') {
+ u_int32_t id;
+ int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->host_server_name,
+ strlen((char *) flow->host_server_name), &id);
- if(rc == 0) {
- flow->category = ret->category = (ndpi_protocol_category_t) id;
- return;
+ if(rc == 0) {
+ flow->category = ret->category = (ndpi_protocol_category_t) id;
+ return;
+ }
}
- }
- if(flow->l4.tcp.tls.hello_processed == 1 &&
- flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0') {
- u_int32_t id;
- int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->protos.tls_quic_stun.tls_quic.client_requested_server_name,
- strlen(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name), &id);
+ if(flow->l4.tcp.tls.hello_processed == 1 &&
+ flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0') {
+ u_int32_t id;
+ int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->protos.tls_quic_stun.tls_quic.client_requested_server_name,
+ strlen(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name), &id);
- if(rc == 0) {
- flow->category = ret->category = (ndpi_protocol_category_t) id;
- return;
+ if(rc == 0) {
+ flow->category = ret->category = (ndpi_protocol_category_t) id;
+ return;
+ }
}
}
+
+ flow->category = ret->category = ndpi_get_proto_category(ndpi_str, *ret);
}
- flow->category = ret->category = ndpi_get_proto_category(ndpi_str, *ret);
-}
+ /* ********************************************************************************* */
-/* ********************************************************************************* */
-
-static void ndpi_reset_packet_line_info(struct ndpi_packet_struct *packet) {
- packet->parsed_lines = 0, packet->empty_line_position_set = 0, packet->host_line.ptr = NULL,
- packet->host_line.len = 0, packet->referer_line.ptr = NULL, packet->referer_line.len = 0,
- packet->content_line.ptr = NULL, packet->content_line.len = 0, packet->accept_line.ptr = NULL,
- packet->accept_line.len = 0, packet->user_agent_line.ptr = NULL, packet->user_agent_line.len = 0,
- packet->http_url_name.ptr = NULL, packet->http_url_name.len = 0, packet->http_encoding.ptr = NULL,
- packet->http_encoding.len = 0, packet->http_transfer_encoding.ptr = NULL, packet->http_transfer_encoding.len = 0,
- packet->http_contentlen.ptr = NULL, packet->http_contentlen.len = 0, packet->content_disposition_line.ptr = NULL,
- packet->content_disposition_line.len = 0, packet->http_cookie.ptr = NULL,
- packet->http_cookie.len = 0, packet->http_origin.len = 0, packet->http_origin.ptr = NULL,
- packet->http_x_session_type.ptr = NULL, packet->http_x_session_type.len = 0, packet->server_line.ptr = NULL,
- packet->server_line.len = 0, packet->http_method.ptr = NULL, packet->http_method.len = 0,
- packet->http_response.ptr = NULL, packet->http_response.len = 0, packet->http_num_headers = 0,
- packet->forwarded_line.ptr = NULL, packet->forwarded_line.len = 0;
-}
+ static void ndpi_reset_packet_line_info(struct ndpi_packet_struct *packet) {
+ packet->parsed_lines = 0, packet->empty_line_position_set = 0, packet->host_line.ptr = NULL,
+ packet->host_line.len = 0, packet->referer_line.ptr = NULL, packet->referer_line.len = 0,
+ packet->content_line.ptr = NULL, packet->content_line.len = 0, packet->accept_line.ptr = NULL,
+ packet->accept_line.len = 0, packet->user_agent_line.ptr = NULL, packet->user_agent_line.len = 0,
+ packet->http_url_name.ptr = NULL, packet->http_url_name.len = 0, packet->http_encoding.ptr = NULL,
+ packet->http_encoding.len = 0, packet->http_transfer_encoding.ptr = NULL, packet->http_transfer_encoding.len = 0,
+ packet->http_contentlen.ptr = NULL, packet->http_contentlen.len = 0, packet->content_disposition_line.ptr = NULL,
+ packet->content_disposition_line.len = 0, packet->http_cookie.ptr = NULL,
+ packet->http_cookie.len = 0, packet->http_origin.len = 0, packet->http_origin.ptr = NULL,
+ packet->http_x_session_type.ptr = NULL, packet->http_x_session_type.len = 0, packet->server_line.ptr = NULL,
+ packet->server_line.len = 0, packet->http_method.ptr = NULL, packet->http_method.len = 0,
+ packet->http_response.ptr = NULL, packet->http_response.len = 0, packet->http_num_headers = 0,
+ packet->forwarded_line.ptr = NULL, packet->forwarded_line.len = 0;
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-static int ndpi_is_ntop_protocol(ndpi_protocol *ret) {
- if((ret->master_protocol == NDPI_PROTOCOL_HTTP) && (ret->app_protocol == NDPI_PROTOCOL_NTOP))
- return(1);
- else
- return(0);
-}
+ static int ndpi_is_ntop_protocol(ndpi_protocol *ret) {
+ if((ret->master_protocol == NDPI_PROTOCOL_HTTP) && (ret->app_protocol == NDPI_PROTOCOL_NTOP))
+ return(1);
+ else
+ return(0);
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-static int ndpi_check_protocol_port_mismatch_exceptions(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- ndpi_default_ports_tree_node_t *expected_proto,
- ndpi_protocol *returned_proto) {
- /*
- For TLS (and other protocols) it is not simple to guess the exact protocol so before
- triggering an alert we need to make sure what we have exhausted all the possible
- options available
- */
+ static int ndpi_check_protocol_port_mismatch_exceptions(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ ndpi_default_ports_tree_node_t *expected_proto,
+ ndpi_protocol *returned_proto) {
+ /*
+ For TLS (and other protocols) it is not simple to guess the exact protocol so before
+ triggering an alert we need to make sure what we have exhausted all the possible
+ options available
+ */
- if(ndpi_is_ntop_protocol(returned_proto)) return(1);
+ if(ndpi_is_ntop_protocol(returned_proto)) return(1);
- if(returned_proto->master_protocol == NDPI_PROTOCOL_TLS) {
- switch(expected_proto->proto->protoId) {
- case NDPI_PROTOCOL_MAIL_IMAPS:
- case NDPI_PROTOCOL_MAIL_POPS:
- case NDPI_PROTOCOL_MAIL_SMTPS:
- return(1); /* This is a reasonable exception */
- break;
+ if(returned_proto->master_protocol == NDPI_PROTOCOL_TLS) {
+ switch(expected_proto->proto->protoId) {
+ case NDPI_PROTOCOL_MAIL_IMAPS:
+ case NDPI_PROTOCOL_MAIL_POPS:
+ case NDPI_PROTOCOL_MAIL_SMTPS:
+ return(1); /* This is a reasonable exception */
+ break;
+ }
}
- }
-
- return(0);
-}
-
-/* ********************************************************************************* */
-static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- ndpi_protocol *ret) {
- /*
- Skype for a host doing MS Teams means MS Teams
- (MS Teams uses Skype as transport protocol for voice/video)
- */
- if(flow) {
- /* Do not go for DNS when there is an application protocol. Example DNS.Apple */
- if((flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
- && (flow->detected_protocol_stack[0] /* app */ != flow->detected_protocol_stack[1] /* major */))
- NDPI_CLR_BIT(flow->risk, NDPI_SUSPICIOUS_DGA_DOMAIN);
+ return(0);
}
- switch(ret->app_protocol) {
- case NDPI_PROTOCOL_MSTEAMS:
- if(flow->packet.iph && flow->packet.tcp) {
- // printf("====>> NDPI_PROTOCOL_MSTEAMS\n");
-
- if(ndpi_str->msteams_cache == NULL)
- ndpi_str->msteams_cache = ndpi_lru_cache_init(1024);
+ /* ********************************************************************************* */
- if(ndpi_str->msteams_cache)
- ndpi_lru_add_to_cache(ndpi_str->msteams_cache,
- flow->packet.iph->saddr,
- (flow->packet.current_time_ms / 1000) & 0xFFFF /* 16 bit */);
+ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ ndpi_protocol *ret) {
+ /*
+ Skype for a host doing MS Teams means MS Teams
+ (MS Teams uses Skype as transport protocol for voice/video)
+ */
+ if(flow) {
+ /* Do not go for DNS when there is an application protocol. Example DNS.Apple */
+ if((flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
+ && (flow->detected_protocol_stack[0] /* app */ != flow->detected_protocol_stack[1] /* major */))
+ NDPI_CLR_BIT(flow->risk, NDPI_SUSPICIOUS_DGA_DOMAIN);
}
- break;
-
- case NDPI_PROTOCOL_SKYPE:
- case NDPI_PROTOCOL_SKYPE_CALL:
- if(flow->packet.iph
- && flow->packet.udp
- && ndpi_str->msteams_cache) {
- u_int16_t when;
- if(ndpi_lru_find_cache(ndpi_str->msteams_cache, flow->packet.iph->saddr,
- &when, 0 /* Don't remove it as it can be used for other connections */)) {
- u_int16_t tdiff = ((flow->packet.current_time_ms /1000) & 0xFFFF) - when;
+ switch(ret->app_protocol) {
+ case NDPI_PROTOCOL_MSTEAMS:
+ if(flow->packet.iph && flow->packet.tcp) {
+ // printf("====>> NDPI_PROTOCOL_MSTEAMS\n");
- if(tdiff < 60 /* sec */) {
- // printf("====>> NDPI_PROTOCOL_SKYPE(_CALL) -> NDPI_PROTOCOL_MSTEAMS [%u]\n", tdiff);
- ret->app_protocol = NDPI_PROTOCOL_MSTEAMS;
+ if(ndpi_str->msteams_cache == NULL)
+ ndpi_str->msteams_cache = ndpi_lru_cache_init(1024);
- /* Refresh cache */
+ if(ndpi_str->msteams_cache)
ndpi_lru_add_to_cache(ndpi_str->msteams_cache,
flow->packet.iph->saddr,
(flow->packet.current_time_ms / 1000) & 0xFFFF /* 16 bit */);
- }
}
- }
- break;
- } /* switch */
-
- if(flow) {
- switch(ndpi_get_proto_breed(ndpi_str, ret->app_protocol)) {
- case NDPI_PROTOCOL_UNSAFE:
- case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS:
- case NDPI_PROTOCOL_DANGEROUS:
- NDPI_SET_BIT(flow->risk, NDPI_UNSAFE_PROTOCOL);
break;
- default:
- /* Nothing to do */
+
+ case NDPI_PROTOCOL_SKYPE:
+ case NDPI_PROTOCOL_SKYPE_CALL:
+ if(flow->packet.iph
+ && flow->packet.udp
+ && ndpi_str->msteams_cache) {
+ u_int16_t when;
+
+ if(ndpi_lru_find_cache(ndpi_str->msteams_cache, flow->packet.iph->saddr,
+ &when, 0 /* Don't remove it as it can be used for other connections */)) {
+ u_int16_t tdiff = ((flow->packet.current_time_ms /1000) & 0xFFFF) - when;
+
+ if(tdiff < 60 /* sec */) {
+ // printf("====>> NDPI_PROTOCOL_SKYPE(_CALL) -> NDPI_PROTOCOL_MSTEAMS [%u]\n", tdiff);
+ ret->app_protocol = NDPI_PROTOCOL_MSTEAMS;
+
+ /* Refresh cache */
+ ndpi_lru_add_to_cache(ndpi_str->msteams_cache,
+ flow->packet.iph->saddr,
+ (flow->packet.current_time_ms / 1000) & 0xFFFF /* 16 bit */);
+ }
+ }
+ }
break;
+ } /* switch */
+
+ if(flow) {
+ switch(ndpi_get_proto_breed(ndpi_str, ret->app_protocol)) {
+ case NDPI_PROTOCOL_UNSAFE:
+ case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS:
+ case NDPI_PROTOCOL_DANGEROUS:
+ NDPI_SET_BIT(flow->risk, NDPI_UNSAFE_PROTOCOL);
+ break;
+ default:
+ /* Nothing to do */
+ break;
+ }
}
- }
-}
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow, const unsigned char *packet,
- const unsigned short packetlen, const u_int64_t current_time_ms,
- struct ndpi_id_struct *src, struct ndpi_id_struct *dst) {
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet;
- u_int32_t a, num_calls = 0;
- ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED };
+ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow, const unsigned char *packet,
+ const unsigned short packetlen, const u_int64_t current_time_ms,
+ struct ndpi_id_struct *src, struct ndpi_id_struct *dst) {
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet;
+ u_int32_t a, num_calls = 0;
+ ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED };
- if(ndpi_str->ndpi_log_level >= NDPI_LOG_TRACE)
- NDPI_LOG(flow ? flow->detected_protocol_stack[0] : NDPI_PROTOCOL_UNKNOWN, ndpi_str, NDPI_LOG_TRACE,
- "START packet processing\n");
+ if(ndpi_str->ndpi_log_level >= NDPI_LOG_TRACE)
+ NDPI_LOG(flow ? flow->detected_protocol_stack[0] : NDPI_PROTOCOL_UNKNOWN, ndpi_str, NDPI_LOG_TRACE,
+ "START packet processing\n");
- if(flow == NULL)
- return(ret);
- else
- ret.category = flow->category;
+ if(flow == NULL)
+ return(ret);
+ else
+ ret.category = flow->category;
- if(flow->fail_with_unknown) {
- // printf("%s(): FAIL_WITH_UNKNOWN\n", __FUNCTION__);
- return(ret);
- }
+ if(flow->fail_with_unknown) {
+ // printf("%s(): FAIL_WITH_UNKNOWN\n", __FUNCTION__);
+ return(ret);
+ }
- flow->num_processed_pkts++;
+ flow->num_processed_pkts++;
#ifdef FRAG_MAN
- flow->tcp_segments_management=1;
+ flow->tcp_segments_management=1;
#endif // FRAG_MAN
- /* Init default */
- ret.master_protocol = flow->detected_protocol_stack[1],
- ret.app_protocol = flow->detected_protocol_stack[0];
+ /* Init default */
+ ret.master_protocol = flow->detected_protocol_stack[1],
+ ret.app_protocol = flow->detected_protocol_stack[0];
- if(flow->server_id == NULL)
- flow->server_id = dst; /* Default */
+ if(flow->server_id == NULL)
+ flow->server_id = dst; /* Default */
- if(flow->check_extra_packets) {
- ndpi_process_extra_packet(ndpi_str, flow, packet, packetlen, current_time_ms, src, dst);
- /* Update in case of new match */
- ret.master_protocol = flow->detected_protocol_stack[1],
- ret.app_protocol = flow->detected_protocol_stack[0],
- ret.category = flow->category;
- goto invalidate_ptr;
- } else if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
- goto ret_protocols;
+ if(flow->check_extra_packets) {
+ ndpi_process_extra_packet(ndpi_str, flow, packet, packetlen, current_time_ms, src, dst);
+ /* Update in case of new match */
+ ret.master_protocol = flow->detected_protocol_stack[1],
+ ret.app_protocol = flow->detected_protocol_stack[0],
+ ret.category = flow->category;
+ goto invalidate_ptr;
+ } else 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);
- goto invalidate_ptr;
- }
+ /* 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);
+ goto invalidate_ptr;
+ }
- flow->packet.current_time_ms = current_time_ms;
+ flow->packet.current_time_ms = current_time_ms;
- /* parse packet */
- flow->packet.iph = (struct ndpi_iphdr *) packet;
- /* we are interested in ipv4 packet */
+ /* parse packet */
+ flow->packet.iph = (struct ndpi_iphdr *) packet;
+ /* we are interested in ipv4 packet */
- if(ndpi_init_packet_header(ndpi_str, flow, packetlen) != 0)
- goto invalidate_ptr;
+ if(ndpi_init_packet_header(ndpi_str, flow, packetlen) != 0)
+ goto invalidate_ptr;
- /* detect traffic for tcp or udp only */
- flow->src = src, flow->dst = dst;
+ /* detect traffic for tcp or udp only */
+ flow->src = src, flow->dst = dst;
- ndpi_connection_tracking(ndpi_str, flow);
+ ndpi_connection_tracking(ndpi_str, flow);
- /* build ndpi_selection packet bitmask */
- ndpi_selection_packet = NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC;
- if(flow->packet.iph != NULL)
- ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IP | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
+ /* build ndpi_selection packet bitmask */
+ ndpi_selection_packet = NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC;
+ 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)
- ndpi_selection_packet |=
- (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
+ 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)
- ndpi_selection_packet |=
- (NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
+ 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)
- ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD;
+ if(flow->packet.payload_packet_len != 0)
+ ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD;
- if(flow->packet.tcp_retransmission == 0)
- ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION;
+ 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)
- ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
+ 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) && (
+ if((!flow->protocol_id_already_guessed) && (
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- flow->packet.iphv6 ||
+ flow->packet.iphv6 ||
#endif
- flow->packet.iph)) {
- u_int16_t sport, dport;
- u_int8_t protocol;
- u_int8_t user_defined_proto;
+ flow->packet.iph)) {
+ u_int16_t sport, dport;
+ u_int8_t protocol;
+ u_int8_t user_defined_proto;
- flow->protocol_id_already_guessed = 1;
+ flow->protocol_id_already_guessed = 1;
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- if(flow->packet.iphv6 != NULL) {
- protocol = flow->packet.iphv6->ip6_hdr.ip6_un1_nxt;
- } else
+ if(flow->packet.iphv6 != NULL) {
+ protocol = flow->packet.iphv6->ip6_hdr.ip6_un1_nxt;
+ } else
#endif
- {
- protocol = flow->packet.iph->protocol;
- }
-
- if(flow->packet.udp)
- sport = ntohs(flow->packet.udp->source), dport = ntohs(flow->packet.udp->dest);
- else if(flow->packet.tcp)
- sport = ntohs(flow->packet.tcp->source), dport = ntohs(flow->packet.tcp->dest);
- else
- sport = dport = 0;
-
- /* guess protocol */
- flow->guessed_protocol_id =
- (int16_t) ndpi_guess_protocol_id(ndpi_str, flow, protocol, sport, dport, &user_defined_proto);
- flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_str, flow);
-
- if(ndpi_str->custom_categories.categories_loaded && flow->packet.iph) {
- ndpi_fill_ip_protocol_category(ndpi_str, flow->packet.iph->saddr, flow->packet.iph->daddr, &ret);
- flow->guessed_header_category = ret.category;
- } else
- flow->guessed_header_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED;
+ {
+ protocol = flow->packet.iph->protocol;
+ }
- 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;
- ndpi_fill_protocol_category(ndpi_str, flow, &ret);
- goto invalidate_ptr;
- }
+ if(flow->packet.udp)
+ sport = ntohs(flow->packet.udp->source), dport = ntohs(flow->packet.udp->dest);
+ else if(flow->packet.tcp)
+ sport = ntohs(flow->packet.tcp->source), dport = ntohs(flow->packet.tcp->dest);
+ else
+ sport = dport = 0;
- if(user_defined_proto && flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
- if(flow->packet.iph) {
- if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
- u_int8_t protocol_was_guessed;
+ /* guess protocol */
+ flow->guessed_protocol_id =
+ (int16_t) ndpi_guess_protocol_id(ndpi_str, flow, protocol, sport, dport, &user_defined_proto);
+ flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_str, flow);
- /* ret.master_protocol = flow->guessed_protocol_id , ret.app_protocol = flow->guessed_host_protocol_id; /\* ****** *\/ */
- ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
- }
+ if(ndpi_str->custom_categories.categories_loaded && flow->packet.iph) {
+ ndpi_fill_ip_protocol_category(ndpi_str, flow->packet.iph->saddr, flow->packet.iph->daddr, &ret);
+ flow->guessed_header_category = ret.category;
+ } else
+ flow->guessed_header_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED;
+ 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;
ndpi_fill_protocol_category(ndpi_str, flow, &ret);
goto invalidate_ptr;
}
- } else {
- /* guess host protocol */
- if(flow->packet.iph) {
- flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_str, flow);
+ if(user_defined_proto && flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
+ if(flow->packet.iph) {
+ if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
+ u_int8_t protocol_was_guessed;
- /*
- We could implement a shortcut here skipping dissectors for
- protocols we have identified by other means such as with the IP
+ /* ret.master_protocol = flow->guessed_protocol_id , ret.app_protocol = flow->guessed_host_protocol_id; /\* ****** *\/ */
+ ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
+ }
+
+ ndpi_fill_protocol_category(ndpi_str, flow, &ret);
+ goto invalidate_ptr;
+ }
+ } else {
+ /* guess host protocol */
+ if(flow->packet.iph) {
+
+ flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_str, flow);
- However we do NOT stop here and skip invoking the dissectors
- because we want to dissect the flow (e.g. dissect the TLS)
- and extract metadata.
- */
-#if SKIP_INVOKING_THE_DISSECTORS
- if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
/*
- We have identified a protocol using the IP address so
- it is not worth to dissect the traffic as we already have
- the solution
+ We could implement a shortcut here skipping dissectors for
+ protocols we have identified by other means such as with the IP
+
+ However we do NOT stop here and skip invoking the dissectors
+ because we want to dissect the flow (e.g. dissect the TLS)
+ and extract metadata.
*/
- ret.master_protocol = flow->guessed_protocol_id, ret.app_protocol = flow->guessed_host_protocol_id;
- }
+#if SKIP_INVOKING_THE_DISSECTORS
+ if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
+ /*
+ We have identified a protocol using the IP address so
+ it is not worth to dissect the traffic as we already have
+ the solution
+ */
+ ret.master_protocol = flow->guessed_protocol_id, ret.app_protocol = flow->guessed_host_protocol_id;
+ }
#endif
+ }
}
}
- }
- 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 = flow->guessed_protocol_id, ret.app_protocol = flow->guessed_host_protocol_id;
+ 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 = flow->guessed_protocol_id, ret.app_protocol = flow->guessed_host_protocol_id;
- num_calls = ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
- ndpi_fill_protocol_category(ndpi_str, flow, &ret);
- goto invalidate_ptr;
- }
+ num_calls = ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
+ ndpi_fill_protocol_category(ndpi_str, flow, &ret);
+ goto invalidate_ptr;
+ }
- num_calls = ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
+ num_calls = ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
- a = flow->packet.detected_protocol_stack[0];
- if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_str->detection_bitmask, a) == 0)
- a = NDPI_PROTOCOL_UNKNOWN;
+ a = flow->packet.detected_protocol_stack[0];
+ if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_str->detection_bitmask, a) == 0)
+ a = NDPI_PROTOCOL_UNKNOWN;
- if(a != NDPI_PROTOCOL_UNKNOWN) {
- int i;
+ if(a != NDPI_PROTOCOL_UNKNOWN) {
+ int i;
- for (i = 0; i < sizeof(flow->host_server_name); i++) {
- if(flow->host_server_name[i] != '\0')
- flow->host_server_name[i] = tolower(flow->host_server_name[i]);
- else {
- flow->host_server_name[i] = '\0';
- break;
+ for (i = 0; i < sizeof(flow->host_server_name); i++) {
+ if(flow->host_server_name[i] != '\0')
+ flow->host_server_name[i] = tolower(flow->host_server_name[i]);
+ else {
+ flow->host_server_name[i] = '\0';
+ break;
+ }
}
}
- }
- ret_protocols:
- if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) {
- ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
+ ret_protocols:
+ if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) {
+ ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
- if(ret.app_protocol == ret.master_protocol)
- ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
- } else
- ret.app_protocol = flow->detected_protocol_stack[0];
+ if(ret.app_protocol == ret.master_protocol)
+ ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
+ } else
+ ret.app_protocol = flow->detected_protocol_stack[0];
- /* Don't overwrite the category if already set */
- if((flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
- ndpi_fill_protocol_category(ndpi_str, flow, &ret);
- else
- ret.category = flow->category;
+ /* Don't overwrite the category if already set */
+ if((flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
+ ndpi_fill_protocol_category(ndpi_str, flow, &ret);
+ else
+ ret.category = flow->category;
- if((flow->num_processed_pkts == 1) && (ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) &&
- (ret.app_protocol == NDPI_PROTOCOL_UNKNOWN) && flow->packet.tcp && (flow->packet.tcp->syn == 0) &&
- (flow->guessed_protocol_id == 0)) {
- u_int8_t protocol_was_guessed;
+ if((flow->num_processed_pkts == 1) && (ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) &&
+ (ret.app_protocol == NDPI_PROTOCOL_UNKNOWN) && flow->packet.tcp && (flow->packet.tcp->syn == 0) &&
+ (flow->guessed_protocol_id == 0)) {
+ u_int8_t protocol_was_guessed;
- /*
- This is a TCP flow
- - whose first packet is NOT a SYN
- - no protocol has been detected
+ /*
+ This is a TCP flow
+ - whose first packet is NOT a SYN
+ - no protocol has been detected
- We don't see how future packets can match anything
- hence we giveup here
- */
- ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
- }
+ We don't see how future packets can match anything
+ hence we giveup here
+ */
+ ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
+ }
- if((ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN) &&
- (flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
- ret.master_protocol = ret.app_protocol;
- ret.app_protocol = flow->guessed_host_protocol_id;
- }
+ if((ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN) &&
+ (flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
+ ret.master_protocol = ret.app_protocol;
+ ret.app_protocol = flow->guessed_host_protocol_id;
+ }
- if((!flow->risk_checked) && (ret.master_protocol != NDPI_PROTOCOL_UNKNOWN)) {
- ndpi_default_ports_tree_node_t *found;
- u_int16_t *default_ports, sport, dport;
+ if((!flow->risk_checked) && (ret.master_protocol != NDPI_PROTOCOL_UNKNOWN)) {
+ ndpi_default_ports_tree_node_t *found;
+ u_int16_t *default_ports, sport, dport;
+
+ if(flow->packet.udp)
+ found = ndpi_get_guessed_protocol_id(ndpi_str, IPPROTO_UDP,
+ sport = ntohs(flow->packet.udp->source),
+ dport = ntohs(flow->packet.udp->dest)),
+ default_ports = ndpi_str->proto_defaults[ret.master_protocol].udp_default_ports;
+ else if(flow->packet.tcp)
+ found = ndpi_get_guessed_protocol_id(ndpi_str, IPPROTO_TCP,
+ sport = ntohs(flow->packet.tcp->source),
+ dport = ntohs(flow->packet.tcp->dest)),
+ default_ports = ndpi_str->proto_defaults[ret.master_protocol].tcp_default_ports;
+ else
+ found = NULL, default_ports = NULL;
+
+ if(found
+ && (found->proto->protoId != NDPI_PROTOCOL_UNKNOWN)
+ && (found->proto->protoId != ret.master_protocol)
+ && (found->proto->protoId != ret.app_protocol)
+ ) {
+ // printf("******** %u / %u\n", found->proto->protoId, ret.master_protocol);
+
+ if(!ndpi_check_protocol_port_mismatch_exceptions(ndpi_str, flow, found, &ret))
+ NDPI_SET_BIT(flow->risk, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT);
+ } else if((!ndpi_is_ntop_protocol(&ret)) && default_ports && (default_ports[0] != 0)) {
+ u_int8_t found = 0, i, num_loops = 0;
+
+ check_default_ports:
+ for(i=0; (i<MAX_DEFAULT_PORTS) && (default_ports[i] != 0); i++) {
+ if((default_ports[i] == sport) || (default_ports[i] == dport)) {
+ found = 1;
+ break;
+ }
+ } /* for */
- if(flow->packet.udp)
- found = ndpi_get_guessed_protocol_id(ndpi_str, IPPROTO_UDP,
- sport = ntohs(flow->packet.udp->source),
- dport = ntohs(flow->packet.udp->dest)),
- default_ports = ndpi_str->proto_defaults[ret.master_protocol].udp_default_ports;
- else if(flow->packet.tcp)
- found = ndpi_get_guessed_protocol_id(ndpi_str, IPPROTO_TCP,
- sport = ntohs(flow->packet.tcp->source),
- dport = ntohs(flow->packet.tcp->dest)),
- default_ports = ndpi_str->proto_defaults[ret.master_protocol].tcp_default_ports;
- else
- found = NULL, default_ports = NULL;
-
- if(found
- && (found->proto->protoId != NDPI_PROTOCOL_UNKNOWN)
- && (found->proto->protoId != ret.master_protocol)
- && (found->proto->protoId != ret.app_protocol)
- ) {
- // printf("******** %u / %u\n", found->proto->protoId, ret.master_protocol);
-
- if(!ndpi_check_protocol_port_mismatch_exceptions(ndpi_str, flow, found, &ret))
- NDPI_SET_BIT(flow->risk, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT);
- } else if((!ndpi_is_ntop_protocol(&ret)) && default_ports && (default_ports[0] != 0)) {
- u_int8_t found = 0, i, num_loops = 0;
-
- check_default_ports:
- for(i=0; (i<MAX_DEFAULT_PORTS) && (default_ports[i] != 0); i++) {
- if((default_ports[i] == sport) || (default_ports[i] == dport)) {
- found = 1;
- break;
- }
- } /* for */
+ if((num_loops == 0) && (!found)) {
+ if(flow->packet.udp)
+ default_ports = ndpi_str->proto_defaults[ret.app_protocol].udp_default_ports;
+ else
+ default_ports = ndpi_str->proto_defaults[ret.app_protocol].tcp_default_ports;
- if((num_loops == 0) && (!found)) {
- if(flow->packet.udp)
- default_ports = ndpi_str->proto_defaults[ret.app_protocol].udp_default_ports;
- else
- default_ports = ndpi_str->proto_defaults[ret.app_protocol].tcp_default_ports;
+ num_loops = 1;
+ goto check_default_ports;
+ }
- num_loops = 1;
- goto check_default_ports;
+ if(!found) {
+ // printf("******** Invalid default port\n");
+ NDPI_SET_BIT(flow->risk, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT);
+ }
}
- if(!found) {
- // printf("******** Invalid default port\n");
- NDPI_SET_BIT(flow->risk, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT);
- }
+ flow->risk_checked = 1;
}
- flow->risk_checked = 1;
- }
-
- ndpi_reconcile_protocols(ndpi_str, flow, &ret);
+ ndpi_reconcile_protocols(ndpi_str, flow, &ret);
- if(num_calls == 0)
- flow->fail_with_unknown = 1;
+ if(num_calls == 0)
+ flow->fail_with_unknown = 1;
- invalidate_ptr:
+ invalidate_ptr:
#ifdef FRAG_MAN
-if (flow->must_free[flow->packet.packet_direction] &&
- flow->packet.payload_packet_len>0 && flow->packet.payload) {
- // if the payload is allocated for segments reassembling, it must be free
- ndpi_free((void*)flow->packet.payload);
- // flow->packet.payload=NULL; done after
- flow->packet.payload_packet_len=0;
- flow->must_free[flow->packet.packet_direction]=0;
- }
+ if((flow->must_free[flow->packet.packet_direction] == 1)
+ && (flow->packet.payload_packet_len > 0)
+ && flow->packet.payload) {
+ // if the payload is allocated for segments reassembling, it must be freed
+ ndpi_free((void*)flow->packet.payload);
+ // flow->packet.payload=NULL; done after
+ flow->packet.payload_packet_len = 0;
+ flow->must_free[flow->packet.packet_direction] = 0;
+ }
#endif // FRAG_MAN
- /*
- Invalidate packet memory to avoid accessing the pointers below
- when the packet is no longer accessible
- */
- flow->packet.iph = NULL, flow->packet.tcp = NULL, flow->packet.udp = NULL, flow->packet.payload = NULL;
- ndpi_reset_packet_line_info(&flow->packet);
-
- 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) {
- u_int32_t val;
- val = 0;
+ /*
+ Invalidate packet memory to avoid accessing the pointers below
+ when the packet is no longer accessible
+ */
+ flow->packet.iph = NULL, flow->packet.tcp = NULL, flow->packet.udp = NULL, flow->packet.payload = NULL;
+ ndpi_reset_packet_line_info(&flow->packet);
- // cancel if eof, ' ' or line end chars are reached
- while (*str >= '0' && *str <= '9' && max_chars_to_read > 0) {
- val *= 10;
- val += *str - '0';
- str++;
- max_chars_to_read = max_chars_to_read - 1;
- *bytes_read = *bytes_read + 1;
+ return(ret);
}
- return(val);
-}
+ /* ********************************************************************************* */
-/* ********************************************************************************* */
+ u_int32_t ndpi_bytestream_to_number(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
+ u_int32_t val;
+ val = 0;
-#ifdef CODE_UNUSED
-u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
- u_int32_t val;
- val = 0;
- if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
- return(ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read));
- } else {
- /*use base 16 system */
- str += 2;
- max_chars_to_read -= 2;
- *bytes_read = *bytes_read + 2;
-
- while (max_chars_to_read > 0) {
- if(*str >= '0' && *str <= '9') {
- val *= 16;
- val += *str - '0';
- } else if(*str >= 'a' && *str <= 'f') {
- val *= 16;
- val += *str + 10 - 'a';
- } else if(*str >= 'A' && *str <= 'F') {
- val *= 16;
- val += *str + 10 - 'A';
- } else {
- break;
- }
+ // cancel if eof, ' ' or line end chars are reached
+ while (*str >= '0' && *str <= '9' && max_chars_to_read > 0) {
+ val *= 10;
+ val += *str - '0';
str++;
max_chars_to_read = max_chars_to_read - 1;
*bytes_read = *bytes_read + 1;
}
- }
- return(val);
-}
+ return(val);
+ }
-#endif
+ /* ********************************************************************************* */
-/* ********************************************************************************* */
+#ifdef CODE_UNUSED
+ u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
+ u_int32_t val;
+ val = 0;
+ if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
+ return(ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read));
+ } else {
+ /*use base 16 system */
+ str += 2;
+ max_chars_to_read -= 2;
+ *bytes_read = *bytes_read + 2;
+
+ while (max_chars_to_read > 0) {
+ if(*str >= '0' && *str <= '9') {
+ val *= 16;
+ val += *str - '0';
+ } else if(*str >= 'a' && *str <= 'f') {
+ val *= 16;
+ val += *str + 10 - 'a';
+ } else if(*str >= 'A' && *str <= 'F') {
+ val *= 16;
+ val += *str + 10 - 'A';
+ } else {
+ break;
+ }
+ str++;
+ max_chars_to_read = max_chars_to_read - 1;
+ *bytes_read = *bytes_read + 1;
+ }
+ }
-u_int64_t ndpi_bytestream_to_number64(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
- u_int64_t val;
- val = 0;
- // cancel if eof, ' ' or line end chars are reached
- while (max_chars_to_read > 0 && *str >= '0' && *str <= '9') {
- val *= 10;
- val += *str - '0';
- str++;
- max_chars_to_read = max_chars_to_read - 1;
- *bytes_read = *bytes_read + 1;
+ return(val);
}
- return(val);
-}
-/* ********************************************************************************* */
+#endif
-u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t *str, u_int16_t max_chars_to_read,
- u_int16_t *bytes_read) {
- u_int64_t val;
- val = 0;
- if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
- return(ndpi_bytestream_to_number64(str, max_chars_to_read, bytes_read));
- } else {
- /*use base 16 system */
- str += 2;
- max_chars_to_read -= 2;
- *bytes_read = *bytes_read + 2;
- while (max_chars_to_read > 0) {
- if(*str >= '0' && *str <= '9') {
- val *= 16;
- val += *str - '0';
- } else if(*str >= 'a' && *str <= 'f') {
- val *= 16;
- val += *str + 10 - 'a';
- } else if(*str >= 'A' && *str <= 'F') {
- val *= 16;
- val += *str + 10 - 'A';
- } else {
- break;
- }
+ /* ********************************************************************************* */
+
+ u_int64_t ndpi_bytestream_to_number64(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
+ u_int64_t val;
+ val = 0;
+ // cancel if eof, ' ' or line end chars are reached
+ while (max_chars_to_read > 0 && *str >= '0' && *str <= '9') {
+ val *= 10;
+ val += *str - '0';
str++;
max_chars_to_read = max_chars_to_read - 1;
*bytes_read = *bytes_read + 1;
}
+ return(val);
}
- return(val);
-}
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
- u_int32_t val;
- u_int16_t read = 0;
- u_int16_t oldread;
- u_int32_t c;
+ u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t *str, u_int16_t max_chars_to_read,
+ u_int16_t *bytes_read) {
+ u_int64_t val;
+ val = 0;
+ if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
+ return(ndpi_bytestream_to_number64(str, max_chars_to_read, bytes_read));
+ } else {
+ /*use base 16 system */
+ str += 2;
+ max_chars_to_read -= 2;
+ *bytes_read = *bytes_read + 2;
+ while (max_chars_to_read > 0) {
+ if(*str >= '0' && *str <= '9') {
+ val *= 16;
+ val += *str - '0';
+ } else if(*str >= 'a' && *str <= 'f') {
+ val *= 16;
+ val += *str + 10 - 'a';
+ } else if(*str >= 'A' && *str <= 'F') {
+ val *= 16;
+ val += *str + 10 - 'A';
+ } else {
+ break;
+ }
+ str++;
+ max_chars_to_read = max_chars_to_read - 1;
+ *bytes_read = *bytes_read + 1;
+ }
+ }
+ return(val);
+ }
- /* ip address must be X.X.X.X with each X between 0 and 255 */
- oldread = read;
- c = ndpi_bytestream_to_number(str, max_chars_to_read, &read);
- if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
- return(0);
+ /* ********************************************************************************* */
- read++;
- val = c << 24;
- oldread = read;
- c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
- if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
- return(0);
+ u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
+ u_int32_t val;
+ u_int16_t read = 0;
+ u_int16_t oldread;
+ u_int32_t c;
- read++;
- val = val + (c << 16);
- oldread = read;
- c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
- if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
- return(0);
+ /* ip address must be X.X.X.X with each X between 0 and 255 */
+ oldread = read;
+ c = ndpi_bytestream_to_number(str, max_chars_to_read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
+ return(0);
- read++;
- val = val + (c << 8);
- oldread = read;
- c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
- if(c > 255 || oldread == read || max_chars_to_read == read)
- return(0);
+ read++;
+ val = c << 24;
+ oldread = read;
+ c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
+ return(0);
- val = val + c;
+ read++;
+ val = val + (c << 16);
+ oldread = read;
+ c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
+ return(0);
- *bytes_read = *bytes_read + read;
+ read++;
+ val = val + (c << 8);
+ oldread = read;
+ c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read)
+ return(0);
- return(htonl(val));
-}
+ val = val + c;
-/* ********************************************************************************* */
+ *bytes_read = *bytes_read + read;
-/* internal function for every detection to parse one packet and to increase the info buffer */
-void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
- u_int32_t a;
- struct ndpi_packet_struct *packet = &flow->packet;
+ return(htonl(val));
+ }
- if((packet->payload_packet_len < 3) || (packet->payload == NULL))
- return;
+ /* ********************************************************************************* */
- if(packet->packet_lines_parsed_complete != 0)
- return;
+ /* internal function for every detection to parse one packet and to increase the info buffer */
+ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
+ u_int32_t a;
+ struct ndpi_packet_struct *packet = &flow->packet;
- packet->packet_lines_parsed_complete = 1;
- ndpi_reset_packet_line_info(packet);
+ if((packet->payload_packet_len < 3) || (packet->payload == NULL))
+ return;
- packet->line[packet->parsed_lines].ptr = packet->payload;
- packet->line[packet->parsed_lines].len = 0;
+ if(packet->packet_lines_parsed_complete != 0)
+ return;
- for (a = 0; ((a+1) < packet->payload_packet_len) && (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET); a++) {
- if((packet->payload[a] == 0x0d) && (packet->payload[a+1] == 0x0a)) {
- /* If end of line char sequence CR+NL "\r\n", process line */
+ packet->packet_lines_parsed_complete = 1;
+ ndpi_reset_packet_line_info(packet);
- if(((a + 3) < packet->payload_packet_len)
- && (packet->payload[a+2] == 0x0d)
- && (packet->payload[a+3] == 0x0a)) {
- /* \r\n\r\n */
- int diff; /* No unsigned ! */
- u_int32_t a1 = a + 4;
+ packet->line[packet->parsed_lines].ptr = packet->payload;
+ packet->line[packet->parsed_lines].len = 0;
- diff = packet->payload_packet_len - a1;
+ for (a = 0; ((a+1) < packet->payload_packet_len) && (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET); a++) {
+ if((packet->payload[a] == 0x0d) && (packet->payload[a+1] == 0x0a)) {
+ /* If end of line char sequence CR+NL "\r\n", process line */
- if(diff > 0) {
- diff = ndpi_min(diff, sizeof(flow->initial_binary_bytes));
- memcpy(&flow->initial_binary_bytes, &packet->payload[a1], diff);
- flow->initial_binary_bytes_len = diff;
- }
- }
+ if(((a + 3) < packet->payload_packet_len)
+ && (packet->payload[a+2] == 0x0d)
+ && (packet->payload[a+3] == 0x0a)) {
+ /* \r\n\r\n */
+ int diff; /* No unsigned ! */
+ u_int32_t a1 = a + 4;
- packet->line[packet->parsed_lines].len =
- (u_int16_t)(((size_t) &packet->payload[a]) - ((size_t) packet->line[packet->parsed_lines].ptr));
+ diff = packet->payload_packet_len - a1;
+
+ if(diff > 0) {
+ diff = ndpi_min(diff, sizeof(flow->initial_binary_bytes));
+ memcpy(&flow->initial_binary_bytes, &packet->payload[a1], diff);
+ flow->initial_binary_bytes_len = diff;
+ }
+ }
- /* First line of a HTTP response parsing. Expected a "HTTP/1.? ???" */
- if(packet->parsed_lines == 0 && packet->line[0].len >= NDPI_STATICSTRING_LEN("HTTP/1.X 200 ") &&
- strncasecmp((const char *) packet->line[0].ptr, "HTTP/1.", NDPI_STATICSTRING_LEN("HTTP/1.")) == 0 &&
- packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] > '0' && /* response code between 000 and 699 */
- packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] < '6') {
- packet->http_response.ptr = &packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.1 ")];
- packet->http_response.len = packet->line[0].len - NDPI_STATICSTRING_LEN("HTTP/1.1 ");
- packet->http_num_headers++;
+ packet->line[packet->parsed_lines].len =
+ (u_int16_t)(((size_t) &packet->payload[a]) - ((size_t) packet->line[packet->parsed_lines].ptr));
- /* Set server HTTP response code */
- if(packet->payload_packet_len >= 12) {
- char buf[4];
+ /* First line of a HTTP response parsing. Expected a "HTTP/1.? ???" */
+ if(packet->parsed_lines == 0 && packet->line[0].len >= NDPI_STATICSTRING_LEN("HTTP/1.X 200 ") &&
+ strncasecmp((const char *) packet->line[0].ptr, "HTTP/1.", NDPI_STATICSTRING_LEN("HTTP/1.")) == 0 &&
+ packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] > '0' && /* response code between 000 and 699 */
+ packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] < '6') {
+ packet->http_response.ptr = &packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.1 ")];
+ packet->http_response.len = packet->line[0].len - NDPI_STATICSTRING_LEN("HTTP/1.1 ");
+ packet->http_num_headers++;
/* Set server HTTP response code */
- strncpy(buf, (char *) &packet->payload[9], 3);
- buf[3] = '\0';
+ if(packet->payload_packet_len >= 12) {
+ char buf[4];
+
+ /* Set server HTTP response code */
+ strncpy(buf, (char *) &packet->payload[9], 3);
+ buf[3] = '\0';
- flow->http.response_status_code = atoi(buf);
- /* https://en.wikipedia.org/wiki/List_of_HTTP_status_codes */
- if((flow->http.response_status_code < 100) || (flow->http.response_status_code > 509))
- flow->http.response_status_code = 0; /* Out of range */
+ flow->http.response_status_code = atoi(buf);
+ /* https://en.wikipedia.org/wiki/List_of_HTTP_status_codes */
+ if((flow->http.response_status_code < 100) || (flow->http.response_status_code > 509))
+ flow->http.response_status_code = 0; /* Out of range */
+ }
}
- }
- /* "Server:" header line in HTTP response */
- if(packet->line[packet->parsed_lines].len > NDPI_STATICSTRING_LEN("Server:") + 1 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr,
- "Server:", NDPI_STATICSTRING_LEN("Server:")) == 0) {
- // some stupid clients omit a space and place the servername directly after the colon
- if(packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")] == ' ') {
- packet->server_line.ptr =
- &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:") + 1];
- packet->server_line.len =
- packet->line[packet->parsed_lines].len - (NDPI_STATICSTRING_LEN("Server:") + 1);
- } else {
- packet->server_line.ptr = &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")];
- packet->server_line.len = packet->line[packet->parsed_lines].len - NDPI_STATICSTRING_LEN("Server:");
+ /* "Server:" header line in HTTP response */
+ if(packet->line[packet->parsed_lines].len > NDPI_STATICSTRING_LEN("Server:") + 1 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr,
+ "Server:", NDPI_STATICSTRING_LEN("Server:")) == 0) {
+ // some stupid clients omit a space and place the servername directly after the colon
+ if(packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")] == ' ') {
+ packet->server_line.ptr =
+ &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:") + 1];
+ packet->server_line.len =
+ packet->line[packet->parsed_lines].len - (NDPI_STATICSTRING_LEN("Server:") + 1);
+ } else {
+ packet->server_line.ptr = &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")];
+ packet->server_line.len = packet->line[packet->parsed_lines].len - NDPI_STATICSTRING_LEN("Server:");
+ }
+ packet->http_num_headers++;
}
- packet->http_num_headers++;
- }
- /* "Host:" header line in HTTP request */
- if(packet->line[packet->parsed_lines].len > 6 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Host:", 5) == 0) {
- // some stupid clients omit a space and place the hostname directly after the colon
- if(packet->line[packet->parsed_lines].ptr[5] == ' ') {
- packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[6];
- packet->host_line.len = packet->line[packet->parsed_lines].len - 6;
- } else {
- packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[5];
- packet->host_line.len = packet->line[packet->parsed_lines].len - 5;
+ /* "Host:" header line in HTTP request */
+ if(packet->line[packet->parsed_lines].len > 6 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Host:", 5) == 0) {
+ // some stupid clients omit a space and place the hostname directly after the colon
+ if(packet->line[packet->parsed_lines].ptr[5] == ' ') {
+ packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[6];
+ packet->host_line.len = packet->line[packet->parsed_lines].len - 6;
+ } else {
+ packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[5];
+ packet->host_line.len = packet->line[packet->parsed_lines].len - 5;
+ }
+ packet->http_num_headers++;
}
- packet->http_num_headers++;
- }
- /* "X-Forwarded-For:" header line in HTTP request. Commonly used for HTTP proxies. */
- if(packet->line[packet->parsed_lines].len > 17 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "X-Forwarded-For:", 16) == 0) {
- // some stupid clients omit a space and place the hostname directly after the colon
- if(packet->line[packet->parsed_lines].ptr[16] == ' ') {
- packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[17];
- packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 17;
- } else {
- packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[16];
- packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 16;
+ /* "X-Forwarded-For:" header line in HTTP request. Commonly used for HTTP proxies. */
+ if(packet->line[packet->parsed_lines].len > 17 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "X-Forwarded-For:", 16) == 0) {
+ // some stupid clients omit a space and place the hostname directly after the colon
+ if(packet->line[packet->parsed_lines].ptr[16] == ' ') {
+ packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[17];
+ packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 17;
+ } else {
+ packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[16];
+ packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 16;
+ }
+ packet->http_num_headers++;
}
- packet->http_num_headers++;
- }
- /* "Content-Type:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 14 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Type: ", 14) == 0 ||
- 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;
+ /* "Content-Type:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 14 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Type: ", 14) == 0 ||
+ 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++;
+ 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->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++;
- }
+ packet->http_num_headers++;
+ }
+ /* "Content-Type:" header line in HTTP AGAIN. Probably a bogus response without space after ":" */
+ 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;
+ 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);
+ 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;
+ 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) {
- packet->accept_line.ptr = &packet->line[packet->parsed_lines].ptr[8];
- packet->accept_line.len = packet->line[packet->parsed_lines].len - 8;
- packet->http_num_headers++;
- }
- /* "Referer:" header line in HTTP request. */
- if(packet->line[packet->parsed_lines].len > 9 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Referer: ", 9) == 0) {
- packet->referer_line.ptr = &packet->line[packet->parsed_lines].ptr[9];
- packet->referer_line.len = packet->line[packet->parsed_lines].len - 9;
- packet->http_num_headers++;
- }
- /* "User-Agent:" header line in HTTP request. */
- if(packet->line[packet->parsed_lines].len > 12 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "User-Agent: ", 12) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "User-agent: ", 12) == 0)) {
- packet->user_agent_line.ptr = &packet->line[packet->parsed_lines].ptr[12];
- packet->user_agent_line.len = packet->line[packet->parsed_lines].len - 12;
- packet->http_num_headers++;
- }
- /* "Content-Encoding:" header line in HTTP response (and request?). */
- if(packet->line[packet->parsed_lines].len > 18 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Encoding: ", 18) == 0) {
- packet->http_encoding.ptr = &packet->line[packet->parsed_lines].ptr[18];
- packet->http_encoding.len = packet->line[packet->parsed_lines].len - 18;
- packet->http_num_headers++;
- }
- /* "Transfer-Encoding:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 19 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Transfer-Encoding: ", 19) == 0) {
- packet->http_transfer_encoding.ptr = &packet->line[packet->parsed_lines].ptr[19];
- packet->http_transfer_encoding.len = packet->line[packet->parsed_lines].len - 19;
- packet->http_num_headers++;
- }
- /* "Content-Length:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 16 &&
- ((strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Length: ", 16) == 0) ||
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "content-length: ", 16) == 0))) {
- packet->http_contentlen.ptr = &packet->line[packet->parsed_lines].ptr[16];
- packet->http_contentlen.len = packet->line[packet->parsed_lines].len - 16;
- packet->http_num_headers++;
- }
- /* "Content-Disposition"*/
- if(packet->line[packet->parsed_lines].len > 21 &&
- ((strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Disposition: ", 21) == 0))) {
- packet->content_disposition_line.ptr = &packet->line[packet->parsed_lines].ptr[21];
- packet->content_disposition_line.len = packet->line[packet->parsed_lines].len - 21;
- packet->http_num_headers++;
- }
- /* "Cookie:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 8 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Cookie: ", 8) == 0) {
- packet->http_cookie.ptr = &packet->line[packet->parsed_lines].ptr[8];
- packet->http_cookie.len = packet->line[packet->parsed_lines].len - 8;
- packet->http_num_headers++;
- }
- /* "Origin:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 8 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Origin: ", 8) == 0) {
- packet->http_origin.ptr = &packet->line[packet->parsed_lines].ptr[8];
- packet->http_origin.len = packet->line[packet->parsed_lines].len - 8;
- packet->http_num_headers++;
- }
- /* "X-Session-Type:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 16 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "X-Session-Type: ", 16) == 0) {
- packet->http_x_session_type.ptr = &packet->line[packet->parsed_lines].ptr[16];
- packet->http_x_session_type.len = packet->line[packet->parsed_lines].len - 16;
- packet->http_num_headers++;
- }
- /* Identification and counting of other HTTP headers.
- * We consider the most common headers, but there are many others,
- * which can be seen at references below:
- * - https://tools.ietf.org/html/rfc7230
- * - https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
- */
- if((packet->line[packet->parsed_lines].len > 6 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Date: ", 6) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Vary: ", 6) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "ETag: ", 6) == 0)) ||
- (packet->line[packet->parsed_lines].len > 8 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Pragma: ", 8) == 0) ||
- (packet->line[packet->parsed_lines].len > 9 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Expires: ", 9) == 0) ||
- (packet->line[packet->parsed_lines].len > 12 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Set-Cookie: ", 12) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Keep-Alive: ", 12) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Connection: ", 12) == 0)) ||
- (packet->line[packet->parsed_lines].len > 15 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Last-Modified: ", 15) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Ranges: ", 15) == 0)) ||
- (packet->line[packet->parsed_lines].len > 17 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Language: ", 17) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Encoding: ", 17) == 0)) ||
- (packet->line[packet->parsed_lines].len > 27 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr,
- "Upgrade-Insecure-Requests: ", 27) == 0)) {
- /* Just count. In the future, if needed, this if can be splited to parse these headers */
- packet->http_num_headers++;
- }
+ /* "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) {
+ packet->accept_line.ptr = &packet->line[packet->parsed_lines].ptr[8];
+ packet->accept_line.len = packet->line[packet->parsed_lines].len - 8;
+ packet->http_num_headers++;
+ }
+ /* "Referer:" header line in HTTP request. */
+ if(packet->line[packet->parsed_lines].len > 9 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Referer: ", 9) == 0) {
+ packet->referer_line.ptr = &packet->line[packet->parsed_lines].ptr[9];
+ packet->referer_line.len = packet->line[packet->parsed_lines].len - 9;
+ packet->http_num_headers++;
+ }
+ /* "User-Agent:" header line in HTTP request. */
+ if(packet->line[packet->parsed_lines].len > 12 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "User-Agent: ", 12) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "User-agent: ", 12) == 0)) {
+ packet->user_agent_line.ptr = &packet->line[packet->parsed_lines].ptr[12];
+ packet->user_agent_line.len = packet->line[packet->parsed_lines].len - 12;
+ packet->http_num_headers++;
+ }
+ /* "Content-Encoding:" header line in HTTP response (and request?). */
+ if(packet->line[packet->parsed_lines].len > 18 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Encoding: ", 18) == 0) {
+ packet->http_encoding.ptr = &packet->line[packet->parsed_lines].ptr[18];
+ packet->http_encoding.len = packet->line[packet->parsed_lines].len - 18;
+ packet->http_num_headers++;
+ }
+ /* "Transfer-Encoding:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 19 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Transfer-Encoding: ", 19) == 0) {
+ packet->http_transfer_encoding.ptr = &packet->line[packet->parsed_lines].ptr[19];
+ packet->http_transfer_encoding.len = packet->line[packet->parsed_lines].len - 19;
+ packet->http_num_headers++;
+ }
+ /* "Content-Length:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 16 &&
+ ((strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Length: ", 16) == 0) ||
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "content-length: ", 16) == 0))) {
+ packet->http_contentlen.ptr = &packet->line[packet->parsed_lines].ptr[16];
+ packet->http_contentlen.len = packet->line[packet->parsed_lines].len - 16;
+ packet->http_num_headers++;
+ }
+ /* "Content-Disposition"*/
+ if(packet->line[packet->parsed_lines].len > 21 &&
+ ((strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Disposition: ", 21) == 0))) {
+ packet->content_disposition_line.ptr = &packet->line[packet->parsed_lines].ptr[21];
+ packet->content_disposition_line.len = packet->line[packet->parsed_lines].len - 21;
+ packet->http_num_headers++;
+ }
+ /* "Cookie:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 8 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Cookie: ", 8) == 0) {
+ packet->http_cookie.ptr = &packet->line[packet->parsed_lines].ptr[8];
+ packet->http_cookie.len = packet->line[packet->parsed_lines].len - 8;
+ packet->http_num_headers++;
+ }
+ /* "Origin:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 8 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Origin: ", 8) == 0) {
+ packet->http_origin.ptr = &packet->line[packet->parsed_lines].ptr[8];
+ packet->http_origin.len = packet->line[packet->parsed_lines].len - 8;
+ packet->http_num_headers++;
+ }
+ /* "X-Session-Type:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 16 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "X-Session-Type: ", 16) == 0) {
+ packet->http_x_session_type.ptr = &packet->line[packet->parsed_lines].ptr[16];
+ packet->http_x_session_type.len = packet->line[packet->parsed_lines].len - 16;
+ packet->http_num_headers++;
+ }
+ /* Identification and counting of other HTTP headers.
+ * We consider the most common headers, but there are many others,
+ * which can be seen at references below:
+ * - https://tools.ietf.org/html/rfc7230
+ * - https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
+ */
+ if((packet->line[packet->parsed_lines].len > 6 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Date: ", 6) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Vary: ", 6) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "ETag: ", 6) == 0)) ||
+ (packet->line[packet->parsed_lines].len > 8 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Pragma: ", 8) == 0) ||
+ (packet->line[packet->parsed_lines].len > 9 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Expires: ", 9) == 0) ||
+ (packet->line[packet->parsed_lines].len > 12 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Set-Cookie: ", 12) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Keep-Alive: ", 12) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Connection: ", 12) == 0)) ||
+ (packet->line[packet->parsed_lines].len > 15 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Last-Modified: ", 15) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Ranges: ", 15) == 0)) ||
+ (packet->line[packet->parsed_lines].len > 17 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Language: ", 17) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Encoding: ", 17) == 0)) ||
+ (packet->line[packet->parsed_lines].len > 27 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr,
+ "Upgrade-Insecure-Requests: ", 27) == 0)) {
+ /* Just count. In the future, if needed, this if can be splited to parse these headers */
+ packet->http_num_headers++;
+ }
- if(packet->line[packet->parsed_lines].len == 0) {
- packet->empty_line_position = a;
- packet->empty_line_position_set = 1;
- }
+ if(packet->line[packet->parsed_lines].len == 0) {
+ packet->empty_line_position = a;
+ packet->empty_line_position_set = 1;
+ }
- if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1))
- return;
+ if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1))
+ return;
- packet->parsed_lines++;
- packet->line[packet->parsed_lines].ptr = &packet->payload[a + 2];
- packet->line[packet->parsed_lines].len = 0;
+ packet->parsed_lines++;
+ packet->line[packet->parsed_lines].ptr = &packet->payload[a + 2];
+ packet->line[packet->parsed_lines].len = 0;
- a++; /* next char in the payload */
+ a++; /* next char in the payload */
+ }
}
- }
- if(packet->parsed_lines >= 1) {
- packet->line[packet->parsed_lines].len =
- (u_int16_t)(((size_t) &packet->payload[packet->payload_packet_len]) -
- ((size_t) packet->line[packet->parsed_lines].ptr));
- packet->parsed_lines++;
+ if(packet->parsed_lines >= 1) {
+ packet->line[packet->parsed_lines].len =
+ (u_int16_t)(((size_t) &packet->payload[packet->payload_packet_len]) -
+ ((size_t) packet->line[packet->parsed_lines].ptr));
+ packet->parsed_lines++;
+ }
}
-}
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
- struct ndpi_packet_struct *packet = &flow->packet;
- u_int32_t a;
- u_int16_t end = packet->payload_packet_len;
+ void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t a;
+ u_int16_t end = packet->payload_packet_len;
- if(packet->packet_lines_parsed_complete != 0)
- return;
+ if(packet->packet_lines_parsed_complete != 0)
+ return;
- packet->packet_lines_parsed_complete = 1;
- packet->parsed_lines = 0;
+ packet->packet_lines_parsed_complete = 1;
+ packet->parsed_lines = 0;
- if(packet->payload_packet_len == 0)
- return;
+ if(packet->payload_packet_len == 0)
+ return;
- packet->line[packet->parsed_lines].ptr = packet->payload;
- packet->line[packet->parsed_lines].len = 0;
+ packet->line[packet->parsed_lines].ptr = packet->payload;
+ packet->line[packet->parsed_lines].len = 0;
- for (a = 0; a < end; a++) {
- if(packet->payload[a] == 0x0a) {
- packet->line[packet->parsed_lines].len = (u_int16_t)(
- ((size_t) &packet->payload[a]) - ((size_t) packet->line[packet->parsed_lines].ptr));
+ for (a = 0; a < end; a++) {
+ if(packet->payload[a] == 0x0a) {
+ packet->line[packet->parsed_lines].len = (u_int16_t)(
+ ((size_t) &packet->payload[a]) - ((size_t) packet->line[packet->parsed_lines].ptr));
- if(a > 0 && packet->payload[a - 1] == 0x0d)
- packet->line[packet->parsed_lines].len--;
+ if(a > 0 && packet->payload[a - 1] == 0x0d)
+ packet->line[packet->parsed_lines].len--;
- if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1))
- break;
+ if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1))
+ break;
- packet->parsed_lines++;
- packet->line[packet->parsed_lines].ptr = &packet->payload[a + 1];
- packet->line[packet->parsed_lines].len = 0;
+ packet->parsed_lines++;
+ packet->line[packet->parsed_lines].ptr = &packet->payload[a + 1];
+ packet->line[packet->parsed_lines].len = 0;
- if((a + 1) >= packet->payload_packet_len)
- break;
+ if((a + 1) >= packet->payload_packet_len)
+ break;
- //a++;
+ //a++;
+ }
}
}
-}
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- u_int16_t counter) {
- struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ u_int16_t counter) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG_DBG2(ndpi_str, "called ndpi_check_for_email_address\n");
- NDPI_LOG_DBG2(ndpi_str, "called ndpi_check_for_email_address\n");
-
- if(packet->payload_packet_len > counter && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
- (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
- (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
- packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
- NDPI_LOG_DBG2(ndpi_str, "first letter\n");
- counter++;
- while (packet->payload_packet_len > counter &&
- ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
- (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
- (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
- packet->payload[counter] == '-' || packet->payload[counter] == '_' ||
- packet->payload[counter] == '.')) {
- NDPI_LOG_DBG2(ndpi_str, "further letter\n");
+ if(packet->payload_packet_len > counter && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
+ (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
+ (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
+ packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
+ NDPI_LOG_DBG2(ndpi_str, "first letter\n");
counter++;
- if(packet->payload_packet_len > counter && packet->payload[counter] == '@') {
- NDPI_LOG_DBG2(ndpi_str, "@\n");
+ while (packet->payload_packet_len > counter &&
+ ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
+ (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
+ (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
+ packet->payload[counter] == '-' || packet->payload[counter] == '_' ||
+ packet->payload[counter] == '.')) {
+ NDPI_LOG_DBG2(ndpi_str, "further letter\n");
counter++;
- while (packet->payload_packet_len > counter &&
- ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
- (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
- (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
- packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
- NDPI_LOG_DBG2(ndpi_str, "letter\n");
+ if(packet->payload_packet_len > counter && packet->payload[counter] == '@') {
+ NDPI_LOG_DBG2(ndpi_str, "@\n");
counter++;
- if(packet->payload_packet_len > counter && packet->payload[counter] == '.') {
- NDPI_LOG_DBG2(ndpi_str, ".\n");
+ while (packet->payload_packet_len > counter &&
+ ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
+ (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
+ (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
+ packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
+ NDPI_LOG_DBG2(ndpi_str, "letter\n");
counter++;
- if(packet->payload_packet_len > counter + 1 &&
- ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') &&
- (packet->payload[counter + 1] >= 'a' && packet->payload[counter + 1] <= 'z'))) {
- NDPI_LOG_DBG2(ndpi_str, "two letters\n");
- counter += 2;
- if(packet->payload_packet_len > counter &&
- (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
- NDPI_LOG_DBG2(ndpi_str, "whitespace1\n");
- return(counter);
- } else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a' &&
- packet->payload[counter] <= 'z') {
- NDPI_LOG_DBG2(ndpi_str, "one letter\n");
- counter++;
+ if(packet->payload_packet_len > counter && packet->payload[counter] == '.') {
+ NDPI_LOG_DBG2(ndpi_str, ".\n");
+ counter++;
+ if(packet->payload_packet_len > counter + 1 &&
+ ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') &&
+ (packet->payload[counter + 1] >= 'a' && packet->payload[counter + 1] <= 'z'))) {
+ NDPI_LOG_DBG2(ndpi_str, "two letters\n");
+ counter += 2;
if(packet->payload_packet_len > counter &&
(packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
- NDPI_LOG_DBG2(ndpi_str, "whitespace2\n");
+ NDPI_LOG_DBG2(ndpi_str, "whitespace1\n");
return(counter);
} else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a' &&
packet->payload[counter] <= 'z') {
+ NDPI_LOG_DBG2(ndpi_str, "one letter\n");
counter++;
if(packet->payload_packet_len > counter &&
(packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
- NDPI_LOG_DBG2(ndpi_str, "whitespace3\n");
+ NDPI_LOG_DBG2(ndpi_str, "whitespace2\n");
return(counter);
+ } else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a' &&
+ packet->payload[counter] <= 'z') {
+ counter++;
+ if(packet->payload_packet_len > counter &&
+ (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
+ NDPI_LOG_DBG2(ndpi_str, "whitespace3\n");
+ return(counter);
+ } else {
+ return(0);
+ }
} else {
return(0);
}
@@ -5542,1544 +5546,1541 @@ u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi
} else {
return(0);
}
- } else {
- return(0);
}
}
+ return(0);
}
- return(0);
}
}
+ return(0);
}
- return(0);
-}
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct *ndpi_str, const char **file,
- const char **func, u_int32_t *line) {
- *file = "";
- *func = "";
+ void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct *ndpi_str, const char **file,
+ const char **func, u_int32_t *line) {
+ *file = "";
+ *func = "";
- if(ndpi_str->ndpi_debug_print_file != NULL)
- *file = ndpi_str->ndpi_debug_print_file;
+ if(ndpi_str->ndpi_debug_print_file != NULL)
+ *file = ndpi_str->ndpi_debug_print_file;
- if(ndpi_str->ndpi_debug_print_function != NULL)
- *func = ndpi_str->ndpi_debug_print_function;
+ if(ndpi_str->ndpi_debug_print_function != NULL)
+ *func = ndpi_str->ndpi_debug_print_function;
- *line = ndpi_str->ndpi_debug_print_line;
-}
+ *line = ndpi_str->ndpi_debug_print_line;
+ }
#endif
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-u_int8_t ndpi_detection_get_l4(const u_int8_t *l3, u_int16_t l3_len, const u_int8_t **l4_return,
- u_int16_t *l4_len_return, u_int8_t *l4_protocol_return, u_int32_t flags) {
- return(ndpi_detection_get_l4_internal(NULL, l3, l3_len, l4_return, l4_len_return, l4_protocol_return, flags));
-}
+ u_int8_t ndpi_detection_get_l4(const u_int8_t *l3, u_int16_t l3_len, const u_int8_t **l4_return,
+ u_int16_t *l4_len_return, u_int8_t *l4_protocol_return, u_int32_t flags) {
+ return(ndpi_detection_get_l4_internal(NULL, l3, l3_len, l4_return, l4_len_return, l4_protocol_return, flags));
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
- struct ndpi_id_struct *src = flow->src, *dst = flow->dst;
+ void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
+ struct ndpi_id_struct *src = flow->src, *dst = flow->dst;
- ndpi_int_change_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
+ ndpi_int_change_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
- if(src != NULL) {
- NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, upper_detected_protocol);
+ if(src != NULL) {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, upper_detected_protocol);
- if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN)
- NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, lower_detected_protocol);
- }
+ if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN)
+ NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, lower_detected_protocol);
+ }
- if(dst != NULL) {
- NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, upper_detected_protocol);
+ if(dst != NULL) {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, upper_detected_protocol);
- if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN)
- NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, lower_detected_protocol);
+ if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN)
+ NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, lower_detected_protocol);
+ }
}
-}
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-u_int16_t ndpi_get_flow_masterprotocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
- return(flow->detected_protocol_stack[1]);
-}
+ u_int16_t ndpi_get_flow_masterprotocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
+ return(flow->detected_protocol_stack[1]);
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-void ndpi_int_change_flow_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
- if(!flow)
- return;
+ void ndpi_int_change_flow_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ 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;
-}
+ 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_str, struct ndpi_flow_struct *flow,
- 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
- * except flow->packet If you want to change something here,
- * don't! Change it for the flow function and apply it here
- * as well */
+ void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ 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
+ * except flow->packet If you want to change something here,
+ * don't! Change it for the flow function and apply it here
+ * as well */
- if(!packet)
- return;
+ if(!packet)
+ return;
- packet->detected_protocol_stack[0] = upper_detected_protocol,
- packet->detected_protocol_stack[1] = lower_detected_protocol;
-}
+ packet->detected_protocol_stack[0] = upper_detected_protocol,
+ packet->detected_protocol_stack[1] = lower_detected_protocol;
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-/* generic function for changing the protocol
- *
- * what it does is:
- * 1.update the flow protocol stack with the new protocol
- * 2.update the packet protocol stack with the new protocol
- */
-void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
- if((upper_detected_protocol == NDPI_PROTOCOL_UNKNOWN) && (lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN))
- upper_detected_protocol = lower_detected_protocol;
-
- if(upper_detected_protocol == lower_detected_protocol)
- lower_detected_protocol = NDPI_PROTOCOL_UNKNOWN;
-
- if((upper_detected_protocol != NDPI_PROTOCOL_UNKNOWN) && (lower_detected_protocol == NDPI_PROTOCOL_UNKNOWN)) {
- if((flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
- (upper_detected_protocol != flow->guessed_host_protocol_id)) {
- if(ndpi_str->proto_defaults[upper_detected_protocol].can_have_a_subprotocol) {
- lower_detected_protocol = upper_detected_protocol;
- upper_detected_protocol = flow->guessed_host_protocol_id;
+ /* generic function for changing the protocol
+ *
+ * what it does is:
+ * 1.update the flow protocol stack with the new protocol
+ * 2.update the packet protocol stack with the new protocol
+ */
+ void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
+ if((upper_detected_protocol == NDPI_PROTOCOL_UNKNOWN) && (lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN))
+ upper_detected_protocol = lower_detected_protocol;
+
+ if(upper_detected_protocol == lower_detected_protocol)
+ lower_detected_protocol = NDPI_PROTOCOL_UNKNOWN;
+
+ if((upper_detected_protocol != NDPI_PROTOCOL_UNKNOWN) && (lower_detected_protocol == NDPI_PROTOCOL_UNKNOWN)) {
+ if((flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
+ (upper_detected_protocol != flow->guessed_host_protocol_id)) {
+ if(ndpi_str->proto_defaults[upper_detected_protocol].can_have_a_subprotocol) {
+ lower_detected_protocol = upper_detected_protocol;
+ upper_detected_protocol = flow->guessed_host_protocol_id;
+ }
}
}
- }
- ndpi_int_change_flow_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
- ndpi_int_change_packet_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
-}
+ ndpi_int_change_flow_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
+ ndpi_int_change_packet_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-void ndpi_int_change_category(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- ndpi_protocol_category_t protocol_category) {
- flow->category = protocol_category;
-}
+ void ndpi_int_change_category(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ ndpi_protocol_category_t protocol_category) {
+ flow->category = protocol_category;
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-/* turns a packet back to unknown */
-void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet) {
- int a;
+ /* 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_SIZE; a++)
- packet->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN;
-}
+ for (a = 0; a < NDPI_PROTOCOL_SIZE; a++)
+ packet->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN;
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow) {
- if(flow) {
- int a;
+ void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow) {
+ if(flow) {
+ int a;
- for (a = 0; a < NDPI_PROTOCOL_SIZE; a++)
- flow->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN;
+ for (a = 0; a < NDPI_PROTOCOL_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));
-}
+ void NDPI_PROTOCOL_IP_clear(ndpi_ip_addr_t *ip) {
+ memset(ip, 0, sizeof(ndpi_ip_addr_t));
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
#ifdef CODE_UNUSED
-/* NTOP */
-int NDPI_PROTOCOL_IP_is_set(const ndpi_ip_addr_t *ip) {
- return(memcmp(ip, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(ndpi_ip_addr_t)) != 0);
-}
+ /* NTOP */
+ int NDPI_PROTOCOL_IP_is_set(const ndpi_ip_addr_t *ip) {
+ return(memcmp(ip, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(ndpi_ip_addr_t)) != 0);
+ }
#endif
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-/* check if the source ip address in packet and ip are equal */
-/* NTOP */
-int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t *ip) {
+ /* check if the source ip address in packet and ip are equal */
+ /* NTOP */
+ int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t *ip) {
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- /* IPv6 */
- if(packet->iphv6 != NULL) {
- if(packet->iphv6->ip6_src.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] &&
- packet->iphv6->ip6_src.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] &&
- packet->iphv6->ip6_src.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] &&
- packet->iphv6->ip6_src.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3])
+ /* IPv6 */
+ if(packet->iphv6 != NULL) {
+ if(packet->iphv6->ip6_src.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] &&
+ packet->iphv6->ip6_src.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] &&
+ packet->iphv6->ip6_src.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] &&
+ packet->iphv6->ip6_src.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3])
+ return(1);
+ //else
+ return(0);
+ }
+#endif
+
+ /* IPv4 */
+ if(packet->iph->saddr == ip->ipv4)
return(1);
- //else
return(0);
}
-#endif
-
- /* IPv4 */
- if(packet->iph->saddr == ip->ipv4)
- return(1);
- return(0);
-}
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-/* check if the destination ip address in packet and ip are equal */
-int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t *ip) {
+ /* check if the destination ip address in packet and ip are equal */
+ int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t *ip) {
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- /* IPv6 */
- if(packet->iphv6 != NULL) {
- if(packet->iphv6->ip6_dst.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] &&
- packet->iphv6->ip6_dst.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] &&
- packet->iphv6->ip6_dst.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] &&
- packet->iphv6->ip6_dst.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3])
- return(1);
- //else
- return(0);
- }
+ /* IPv6 */
+ if(packet->iphv6 != NULL) {
+ if(packet->iphv6->ip6_dst.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] &&
+ packet->iphv6->ip6_dst.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] &&
+ packet->iphv6->ip6_dst.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] &&
+ packet->iphv6->ip6_dst.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3])
+ return(1);
+ //else
+ return(0);
+ }
#endif
- /* IPv4 */
- if(packet->iph->saddr == ip->ipv4)
- return(1);
+ /* IPv4 */
+ if(packet->iph->saddr == ip->ipv4)
+ return(1);
- return(0);
-}
+ return(0);
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-/* get the source ip address from packet and put it into ip */
-/* NTOP */
-void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t *ip) {
- NDPI_PROTOCOL_IP_clear(ip);
+ /* get the source ip address from packet and put it into ip */
+ /* NTOP */
+ void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t *ip) {
+ NDPI_PROTOCOL_IP_clear(ip);
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- /* IPv6 */
- if(packet->iphv6 != NULL) {
- ip->ipv6.u6_addr.u6_addr32[0] = packet->iphv6->ip6_src.u6_addr.u6_addr32[0];
- ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_src.u6_addr.u6_addr32[1];
- ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_src.u6_addr.u6_addr32[2];
- ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_src.u6_addr.u6_addr32[3];
+ /* IPv6 */
+ if(packet->iphv6 != NULL) {
+ ip->ipv6.u6_addr.u6_addr32[0] = packet->iphv6->ip6_src.u6_addr.u6_addr32[0];
+ ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_src.u6_addr.u6_addr32[1];
+ ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_src.u6_addr.u6_addr32[2];
+ ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_src.u6_addr.u6_addr32[3];
- } else
+ } else
#endif
- /* IPv4 */
- ip->ipv4 = packet->iph->saddr;
-}
+ /* IPv4 */
+ ip->ipv4 = packet->iph->saddr;
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-/* get the destination ip address from packet and put it into ip */
-/* NTOP */
-void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t *ip) {
- NDPI_PROTOCOL_IP_clear(ip);
+ /* get the destination ip address from packet and put it into ip */
+ /* NTOP */
+ void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t *ip) {
+ NDPI_PROTOCOL_IP_clear(ip);
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- if(packet->iphv6 != NULL) {
- ip->ipv6.u6_addr.u6_addr32[0] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[0];
- ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[1];
- ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[2];
- ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[3];
+ if(packet->iphv6 != NULL) {
+ ip->ipv6.u6_addr.u6_addr32[0] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[0];
+ ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[1];
+ ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[2];
+ ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[3];
- } else
+ } else
#endif
- ip->ipv4 = packet->iph->daddr;
-}
+ ip->ipv4 = packet->iph->daddr;
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-u_int8_t ndpi_is_ipv6(const ndpi_ip_addr_t *ip) {
+ u_int8_t ndpi_is_ipv6(const ndpi_ip_addr_t *ip) {
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- return(ip->ipv6.u6_addr.u6_addr32[1] != 0 || ip->ipv6.u6_addr.u6_addr32[2] != 0 ||
- ip->ipv6.u6_addr.u6_addr32[3] != 0);
+ return(ip->ipv6.u6_addr.u6_addr32[1] != 0 || ip->ipv6.u6_addr.u6_addr32[2] != 0 ||
+ ip->ipv6.u6_addr.u6_addr32[3] != 0);
#else
- return(0);
+ return(0);
#endif
-}
+ }
-/* ********************************************************************************* */
+ /* ********************************************************************************* */
-char *ndpi_get_ip_string(const ndpi_ip_addr_t *ip, char *buf, u_int buf_len) {
- const u_int8_t *a = (const u_int8_t *) &ip->ipv4;
+ char *ndpi_get_ip_string(const ndpi_ip_addr_t *ip, char *buf, u_int buf_len) {
+ const u_int8_t *a = (const u_int8_t *) &ip->ipv4;
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- if(ndpi_is_ipv6(ip)) {
- if(inet_ntop(AF_INET6, &ip->ipv6.u6_addr, buf, buf_len) == NULL)
- buf[0] = '\0';
+ if(ndpi_is_ipv6(ip)) {
+ if(inet_ntop(AF_INET6, &ip->ipv6.u6_addr, buf, buf_len) == NULL)
+ buf[0] = '\0';
- return(buf);
- }
+ return(buf);
+ }
#endif
- snprintf(buf, buf_len, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
+ snprintf(buf, buf_len, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
- return(buf);
-}
+ return(buf);
+ }
-/* ****************************************************** */
+ /* ****************************************************** */
-/* Returns -1 on failutre, otherwise fills parsed_ip and returns the IP version */
-int ndpi_parse_ip_string(const char *ip_str, ndpi_ip_addr_t *parsed_ip) {
- int rv = -1;
- memset(parsed_ip, 0, sizeof(*parsed_ip));
+ /* Returns -1 on failutre, otherwise fills parsed_ip and returns the IP version */
+ int ndpi_parse_ip_string(const char *ip_str, ndpi_ip_addr_t *parsed_ip) {
+ int rv = -1;
+ memset(parsed_ip, 0, sizeof(*parsed_ip));
- if(strchr(ip_str, '.')) {
- if(inet_pton(AF_INET, ip_str, &parsed_ip->ipv4) > 0)
- rv = 4;
+ if(strchr(ip_str, '.')) {
+ if(inet_pton(AF_INET, ip_str, &parsed_ip->ipv4) > 0)
+ rv = 4;
#ifdef NDPI_DETECTION_SUPPORT_IPV6
- } else {
- if(inet_pton(AF_INET6, ip_str, &parsed_ip->ipv6) > 0)
- rv = 6;
+ } else {
+ if(inet_pton(AF_INET6, ip_str, &parsed_ip->ipv6) > 0)
+ rv = 6;
#endif
- }
-
- return(rv);
-}
-
-/* ****************************************************** */
+ }
-u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t *str,
- u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
- u_int16_t val = ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read);
- return(ntohs(val));
-}
+ return(rv);
+ }
-/* ****************************************************** */
+ /* ****************************************************** */
-u_int8_t ndpi_is_proto(ndpi_protocol proto, u_int16_t p) {
- return(((proto.app_protocol == p) || (proto.master_protocol == p)) ? 1 : 0);
-}
+ u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t *str,
+ u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
+ u_int16_t val = ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read);
+ return(ntohs(val));
+ }
-/* ****************************************************** */
+ /* ****************************************************** */
-u_int16_t ndpi_get_lower_proto(ndpi_protocol proto) {
- return((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.master_protocol : proto.app_protocol);
-}
+ u_int8_t ndpi_is_proto(ndpi_protocol proto, u_int16_t p) {
+ return(((proto.app_protocol == p) || (proto.master_protocol == p)) ? 1 : 0);
+ }
-/* ****************************************************** */
+ /* ****************************************************** */
-ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow, 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_int32_t rc;
- struct in_addr addr;
- ndpi_protocol ret = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED};
- u_int8_t user_defined_proto;
+ u_int16_t ndpi_get_lower_proto(ndpi_protocol proto) {
+ return((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.master_protocol : proto.app_protocol);
+ }
- if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) {
- rc = ndpi_search_tcp_or_udp_raw(ndpi_str, flow, proto, shost, dhost, sport, dport);
+ /* ****************************************************** */
- if(rc != NDPI_PROTOCOL_UNKNOWN) {
- if(flow && (proto == IPPROTO_UDP) &&
- NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_guessable_protocol(rc))
- ;
- else {
- ret.app_protocol = rc,
- ret.master_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
+ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow, 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_int32_t rc;
+ struct in_addr addr;
+ ndpi_protocol ret = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED};
+ u_int8_t user_defined_proto;
- if(ret.app_protocol == ret.master_protocol)
- ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
+ if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) {
+ rc = ndpi_search_tcp_or_udp_raw(ndpi_str, flow, proto, shost, dhost, sport, dport);
- ret.category = ndpi_get_proto_category(ndpi_str, ret);
- return(ret);
- }
- }
+ if(rc != NDPI_PROTOCOL_UNKNOWN) {
+ if(flow && (proto == IPPROTO_UDP) &&
+ NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_guessable_protocol(rc))
+ ;
+ else {
+ ret.app_protocol = rc,
+ ret.master_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
- rc = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
- if(rc != NDPI_PROTOCOL_UNKNOWN) {
- if(flow && (proto == IPPROTO_UDP) &&
- NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_guessable_protocol(rc))
- ;
- else {
- ret.app_protocol = rc;
+ if(ret.app_protocol == ret.master_protocol)
+ ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
- if(rc == NDPI_PROTOCOL_TLS)
- goto check_guessed_skype;
- else {
ret.category = ndpi_get_proto_category(ndpi_str, ret);
return(ret);
}
}
- }
- check_guessed_skype:
- addr.s_addr = htonl(shost);
- if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE) {
- ret.app_protocol = NDPI_PROTOCOL_SKYPE;
- } else {
- addr.s_addr = htonl(dhost);
- if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE)
- ret.app_protocol = NDPI_PROTOCOL_SKYPE;
- }
- } else
- ret.app_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
-
- ret.category = ndpi_get_proto_category(ndpi_str, ret);
- return(ret);
-}
+ rc = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
+ if(rc != NDPI_PROTOCOL_UNKNOWN) {
+ if(flow && (proto == IPPROTO_UDP) &&
+ NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_guessable_protocol(rc))
+ ;
+ else {
+ ret.app_protocol = rc;
-/* ****************************************************** */
+ if(rc == NDPI_PROTOCOL_TLS)
+ goto check_guessed_skype;
+ else {
+ ret.category = ndpi_get_proto_category(ndpi_str, ret);
+ return(ret);
+ }
+ }
+ }
-char *ndpi_protocol2id(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_protocol proto, char *buf, u_int buf_len) {
- if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) {
- if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)
- snprintf(buf, buf_len, "%u.%u", proto.master_protocol, proto.app_protocol);
- else
- snprintf(buf, buf_len, "%u", proto.master_protocol);
- } else
- snprintf(buf, buf_len, "%u", proto.app_protocol);
+ check_guessed_skype:
+ addr.s_addr = htonl(shost);
+ if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE) {
+ ret.app_protocol = NDPI_PROTOCOL_SKYPE;
+ } else {
+ addr.s_addr = htonl(dhost);
+ if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE)
+ ret.app_protocol = NDPI_PROTOCOL_SKYPE;
+ }
+ } else
+ ret.app_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
- return(buf);
-}
+ ret.category = ndpi_get_proto_category(ndpi_str, ret);
+ return(ret);
+ }
-/* ****************************************************** */
+ /* ****************************************************** */
-char *ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_str,
+ char *ndpi_protocol2id(struct ndpi_detection_module_struct *ndpi_str,
ndpi_protocol proto, char *buf, u_int buf_len) {
- if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) {
- if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)
- snprintf(buf, buf_len, "%s.%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol),
- ndpi_get_proto_name(ndpi_str, proto.app_protocol));
- else
- snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol));
- } else
- snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.app_protocol));
-
- return(buf);
-}
-
-/* ****************************************************** */
-
-int ndpi_is_custom_category(ndpi_protocol_category_t category) {
- switch(category) {
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
- return(1);
- break;
+ if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) {
+ if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)
+ snprintf(buf, buf_len, "%u.%u", proto.master_protocol, proto.app_protocol);
+ else
+ snprintf(buf, buf_len, "%u", proto.master_protocol);
+ } else
+ snprintf(buf, buf_len, "%u", proto.app_protocol);
- default:
- return(0);
- break;
+ return(buf);
}
-}
-/* ****************************************************** */
+ /* ****************************************************** */
-void ndpi_category_set_name(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_protocol_category_t category,
- char *name) {
- if(!name)
- return;
-
- switch(category) {
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
- snprintf(ndpi_str->custom_category_labels[0], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
- break;
-
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
- snprintf(ndpi_str->custom_category_labels[1], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
- break;
+ char *ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_protocol proto, char *buf, u_int buf_len) {
+ if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) {
+ if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)
+ snprintf(buf, buf_len, "%s.%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol),
+ ndpi_get_proto_name(ndpi_str, proto.app_protocol));
+ else
+ snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol));
+ } else
+ snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.app_protocol));
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
- snprintf(ndpi_str->custom_category_labels[2], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
- break;
+ return(buf);
+ }
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
- snprintf(ndpi_str->custom_category_labels[3], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
- break;
+ /* ****************************************************** */
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
- snprintf(ndpi_str->custom_category_labels[4], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
- break;
+ int ndpi_is_custom_category(ndpi_protocol_category_t category) {
+ switch(category) {
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
+ return(1);
+ break;
- default:
- break;
+ default:
+ return(0);
+ break;
+ }
}
-}
-/* ****************************************************** */
+ /* ****************************************************** */
-const char *ndpi_category_get_name(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_protocol_category_t category) {
- if((!ndpi_str) || (category >= NDPI_PROTOCOL_NUM_CATEGORIES)) {
- static char b[24];
-
- if(!ndpi_str)
- snprintf(b, sizeof(b), "NULL nDPI");
- else
- snprintf(b, sizeof(b), "Invalid category %d", (int) category);
- return(b);
- }
+ void ndpi_category_set_name(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_protocol_category_t category,
+ char *name) {
+ if(!name)
+ return;
- if((category >= NDPI_PROTOCOL_CATEGORY_CUSTOM_1) && (category <= NDPI_PROTOCOL_CATEGORY_CUSTOM_5)) {
switch(category) {
case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
- return(ndpi_str->custom_category_labels[0]);
+ snprintf(ndpi_str->custom_category_labels[0], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
+ break;
+
case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
- return(ndpi_str->custom_category_labels[1]);
+ snprintf(ndpi_str->custom_category_labels[1], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
+ break;
+
case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
- return(ndpi_str->custom_category_labels[2]);
+ snprintf(ndpi_str->custom_category_labels[2], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
+ break;
+
case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
- return(ndpi_str->custom_category_labels[3]);
+ snprintf(ndpi_str->custom_category_labels[3], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
+ break;
+
case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
- return(ndpi_str->custom_category_labels[4]);
- case NDPI_PROTOCOL_NUM_CATEGORIES:
- return("Code should not use this internal constant");
+ snprintf(ndpi_str->custom_category_labels[4], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
+ break;
+
default:
- return("Unspecified");
+ break;
}
- } else
- return(categories[category]);
-}
-
-/* ****************************************************** */
+ }
-ndpi_protocol_category_t ndpi_get_proto_category(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_protocol proto) {
- if(proto.category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
- return(proto.category);
+ /* ****************************************************** */
- /* simple rule: sub protocol first, master after */
- else if((proto.master_protocol == NDPI_PROTOCOL_UNKNOWN) ||
- (ndpi_str->proto_defaults[proto.app_protocol].protoCategory != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)) {
- if(proto.app_protocol < (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
- return(ndpi_str->proto_defaults[proto.app_protocol].protoCategory);
- } else if(proto.master_protocol < (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
- return(ndpi_str->proto_defaults[proto.master_protocol].protoCategory);
+ const char *ndpi_category_get_name(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_protocol_category_t category) {
+ if((!ndpi_str) || (category >= NDPI_PROTOCOL_NUM_CATEGORIES)) {
+ static char b[24];
- return(NDPI_PROTOCOL_CATEGORY_UNSPECIFIED);
-}
+ if(!ndpi_str)
+ snprintf(b, sizeof(b), "NULL nDPI");
+ else
+ snprintf(b, sizeof(b), "Invalid category %d", (int) category);
+ return(b);
+ }
-/* ****************************************************** */
+ if((category >= NDPI_PROTOCOL_CATEGORY_CUSTOM_1) && (category <= NDPI_PROTOCOL_CATEGORY_CUSTOM_5)) {
+ switch(category) {
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
+ return(ndpi_str->custom_category_labels[0]);
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
+ return(ndpi_str->custom_category_labels[1]);
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
+ return(ndpi_str->custom_category_labels[2]);
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
+ return(ndpi_str->custom_category_labels[3]);
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
+ return(ndpi_str->custom_category_labels[4]);
+ case NDPI_PROTOCOL_NUM_CATEGORIES:
+ return("Code should not use this internal constant");
+ default:
+ return("Unspecified");
+ }
+ } else
+ return(categories[category]);
+ }
-char *ndpi_get_proto_name(struct ndpi_detection_module_struct *ndpi_str,
- u_int16_t proto_id) {
- if((proto_id >= ndpi_str->ndpi_num_supported_protocols) ||
- (proto_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) ||
- (ndpi_str->proto_defaults[proto_id].protoName == NULL))
- proto_id = NDPI_PROTOCOL_UNKNOWN;
+ /* ****************************************************** */
- return(ndpi_str->proto_defaults[proto_id].protoName);
-}
+ ndpi_protocol_category_t ndpi_get_proto_category(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_protocol proto) {
+ if(proto.category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
+ return(proto.category);
-/* ****************************************************** */
+ /* simple rule: sub protocol first, master after */
+ else if((proto.master_protocol == NDPI_PROTOCOL_UNKNOWN) ||
+ (ndpi_str->proto_defaults[proto.app_protocol].protoCategory != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)) {
+ if(proto.app_protocol < (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
+ return(ndpi_str->proto_defaults[proto.app_protocol].protoCategory);
+ } else if(proto.master_protocol < (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
+ return(ndpi_str->proto_defaults[proto.master_protocol].protoCategory);
-ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *ndpi_str,
- u_int16_t proto_id) {
- if((proto_id >= ndpi_str->ndpi_num_supported_protocols) ||
- (proto_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) ||
- (ndpi_str->proto_defaults[proto_id].protoName == NULL))
- proto_id = NDPI_PROTOCOL_UNKNOWN;
+ return(NDPI_PROTOCOL_CATEGORY_UNSPECIFIED);
+ }
- return(ndpi_str->proto_defaults[proto_id].protoBreed);
-}
+ /* ****************************************************** */
-/* ****************************************************** */
+ char *ndpi_get_proto_name(struct ndpi_detection_module_struct *ndpi_str,
+ u_int16_t proto_id) {
+ if((proto_id >= ndpi_str->ndpi_num_supported_protocols) ||
+ (proto_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) ||
+ (ndpi_str->proto_defaults[proto_id].protoName == NULL))
+ proto_id = NDPI_PROTOCOL_UNKNOWN;
-char *ndpi_get_proto_breed_name(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_protocol_breed_t breed_id) {
- switch(breed_id) {
- case NDPI_PROTOCOL_SAFE:
- return("Safe");
- break;
- case NDPI_PROTOCOL_ACCEPTABLE:
- return("Acceptable");
- break;
- case NDPI_PROTOCOL_FUN:
- return("Fun");
- break;
- case NDPI_PROTOCOL_UNSAFE:
- return("Unsafe");
- break;
- case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS:
- return("Potentially Dangerous");
- break;
- case NDPI_PROTOCOL_DANGEROUS:
- return("Dangerous");
- break;
- case NDPI_PROTOCOL_UNRATED:
- default:
- return("Unrated");
- break;
+ return(ndpi_str->proto_defaults[proto_id].protoName);
}
-}
-/* ****************************************************** */
+ /* ****************************************************** */
-int ndpi_get_protocol_id(struct ndpi_detection_module_struct *ndpi_str, char *proto) {
- int i;
+ ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *ndpi_str,
+ u_int16_t proto_id) {
+ if((proto_id >= ndpi_str->ndpi_num_supported_protocols) ||
+ (proto_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) ||
+ (ndpi_str->proto_defaults[proto_id].protoName == NULL))
+ proto_id = NDPI_PROTOCOL_UNKNOWN;
- for (i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++)
- if(strcasecmp(proto, ndpi_str->proto_defaults[i].protoName) == 0)
- return(i);
+ return(ndpi_str->proto_defaults[proto_id].protoBreed);
+ }
- return(-1);
-}
+ /* ****************************************************** */
-/* ****************************************************** */
+ char *ndpi_get_proto_breed_name(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_protocol_breed_t breed_id) {
+ switch(breed_id) {
+ case NDPI_PROTOCOL_SAFE:
+ return("Safe");
+ break;
+ case NDPI_PROTOCOL_ACCEPTABLE:
+ return("Acceptable");
+ break;
+ case NDPI_PROTOCOL_FUN:
+ return("Fun");
+ break;
+ case NDPI_PROTOCOL_UNSAFE:
+ return("Unsafe");
+ break;
+ case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS:
+ return("Potentially Dangerous");
+ break;
+ case NDPI_PROTOCOL_DANGEROUS:
+ return("Dangerous");
+ break;
+ case NDPI_PROTOCOL_UNRATED:
+ default:
+ return("Unrated");
+ break;
+ }
+ }
-int ndpi_get_category_id(struct ndpi_detection_module_struct *ndpi_str, char *cat) {
- int i;
+ /* ****************************************************** */
- for (i = 0; i < NDPI_PROTOCOL_NUM_CATEGORIES; i++) {
- const char *name = ndpi_category_get_name(ndpi_str, i);
+ int ndpi_get_protocol_id(struct ndpi_detection_module_struct *ndpi_str, char *proto) {
+ int i;
- if(strcasecmp(cat, name) == 0)
- return(i);
+ for (i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++)
+ if(strcasecmp(proto, ndpi_str->proto_defaults[i].protoName) == 0)
+ return(i);
+
+ return(-1);
}
- return(-1);
-}
+ /* ****************************************************** */
-/* ****************************************************** */
+ int ndpi_get_category_id(struct ndpi_detection_module_struct *ndpi_str, char *cat) {
+ int i;
-void ndpi_dump_protocols(struct ndpi_detection_module_struct *ndpi_str) {
- int i;
+ for (i = 0; i < NDPI_PROTOCOL_NUM_CATEGORIES; i++) {
+ const char *name = ndpi_category_get_name(ndpi_str, i);
- for (i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++)
- printf("%3d %-22s %-8s %-12s %s\n", i, ndpi_str->proto_defaults[i].protoName,
- ndpi_get_l4_proto_name(ndpi_get_l4_proto_info(ndpi_str, i)),
- ndpi_get_proto_breed_name(ndpi_str, ndpi_str->proto_defaults[i].protoBreed),
- ndpi_category_get_name(ndpi_str, ndpi_str->proto_defaults[i].protoCategory));
-}
+ if(strcasecmp(cat, name) == 0)
+ return(i);
+ }
-/* ****************************************************** */
+ return(-1);
+ }
-/*
- * Find the first occurrence of find in s, where the search is limited to the
- * first slen characters of s.
- */
-char *ndpi_strnstr(const char *s, const char *find, size_t slen) {
- char c;
- size_t len;
+ /* ****************************************************** */
+
+ void ndpi_dump_protocols(struct ndpi_detection_module_struct *ndpi_str) {
+ int i;
+
+ for (i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++)
+ printf("%3d %-22s %-8s %-12s %s\n", i, ndpi_str->proto_defaults[i].protoName,
+ ndpi_get_l4_proto_name(ndpi_get_l4_proto_info(ndpi_str, i)),
+ ndpi_get_proto_breed_name(ndpi_str, ndpi_str->proto_defaults[i].protoBreed),
+ ndpi_category_get_name(ndpi_str, ndpi_str->proto_defaults[i].protoCategory));
+ }
- if((c = *find++) != '\0') {
- len = strnlen(find, slen);
- do {
- char sc;
+ /* ****************************************************** */
+ /*
+ * Find the first occurrence of find in s, where the search is limited to the
+ * first slen characters of s.
+ */
+ char *ndpi_strnstr(const char *s, const char *find, size_t slen) {
+ char c;
+ size_t len;
+
+ if((c = *find++) != '\0') {
+ len = strnlen(find, slen);
do {
- if(slen-- < 1 || (sc = *s++) == '\0')
+ char sc;
+
+ do {
+ if(slen-- < 1 || (sc = *s++) == '\0')
+ return(NULL);
+ } while (sc != c);
+ if(len > slen)
return(NULL);
- } while (sc != c);
- if(len > slen)
- return(NULL);
- } while (strncmp(s, find, len) != 0);
- s--;
+ } while (strncmp(s, find, len) != 0);
+ s--;
+ }
+
+ return((char *) s);
}
- return((char *) s);
-}
+ /* ****************************************************** */
-/* ****************************************************** */
+ /*
+ * Same as ndpi_strnstr but case-insensitive
+ */
+ const char * ndpi_strncasestr(const char *str1, const char *str2, size_t len) {
+ size_t str1_len = strnlen(str1, len);
+ size_t str2_len = strlen(str2);
+ size_t i;
+
+ for(i = 0; i < (str1_len - str2_len + 1); i++){
+ if(str1[0] == '\0')
+ return NULL;
+ else if(strncasecmp(str1, str2, str2_len) == 0)
+ return(str1);
+
+ str1++;
+ }
-/*
- * Same as ndpi_strnstr but case-insensitive
- */
-const char * ndpi_strncasestr(const char *str1, const char *str2, size_t len) {
- size_t str1_len = strnlen(str1, len);
- size_t str2_len = strlen(str2);
- size_t i;
+ return NULL;
+ }
- for(i = 0; i < (str1_len - str2_len + 1); i++){
- if(str1[0] == '\0')
- return NULL;
- else if(strncasecmp(str1, str2, str2_len) == 0)
- return(str1);
+ /* ****************************************************** */
- str1++;
+ int ndpi_match_prefix(const u_int8_t *payload,
+ size_t payload_len, const char *str, size_t str_len) {
+ int rc = str_len <= payload_len ? memcmp(payload, str, str_len) == 0 : 0;
+
+ return(rc);
}
- return NULL;
-}
+ /* ****************************************************** */
-/* ****************************************************** */
+ int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_str, char *string_to_match,
+ u_int string_to_match_len, ndpi_protocol_match_result *ret_match,
+ u_int8_t is_host_match) {
+ AC_TEXT_t ac_input_text;
+ ndpi_automa *automa = is_host_match ? &ndpi_str->host_automa : &ndpi_str->content_automa;
+ AC_REP_t match = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED};
+ int rc;
-int ndpi_match_prefix(const u_int8_t *payload,
- size_t payload_len, const char *str, size_t str_len) {
- int rc = str_len <= payload_len ? memcmp(payload, str, str_len) == 0 : 0;
+ if((automa->ac_automa == NULL) || (string_to_match_len == 0))
+ return(NDPI_PROTOCOL_UNKNOWN);
- return(rc);
-}
+ if(!automa->ac_automa_finalized) {
+ printf("[%s:%d] [NDPI] Internal error: please call ndpi_finalize_initalization()\n", __FILE__, __LINE__);
+ return(0); /* No matches */
+ }
-/* ****************************************************** */
+ ac_input_text.astring = string_to_match, ac_input_text.length = string_to_match_len;
+ rc = ac_automata_search(((AC_AUTOMATA_t *) automa->ac_automa), &ac_input_text, &match);
-int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_str, char *string_to_match,
- u_int string_to_match_len, ndpi_protocol_match_result *ret_match,
- u_int8_t is_host_match) {
- AC_TEXT_t ac_input_text;
- ndpi_automa *automa = is_host_match ? &ndpi_str->host_automa : &ndpi_str->content_automa;
- AC_REP_t match = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED};
- int rc;
+ /*
+ As ac_automata_search can detect partial matches and continue the search process
+ in case rc == 0 (i.e. no match), we need to check if there is a partial match
+ and in this case return it
+ */
+ if((rc == 0) && (match.number != 0))
+ rc = 1;
- if((automa->ac_automa == NULL) || (string_to_match_len == 0))
- return(NDPI_PROTOCOL_UNKNOWN);
+ /* We need to take into account also rc == 0 that is used for partial matches */
+ ret_match->protocol_id = match.number, ret_match->protocol_category = match.category,
+ ret_match->protocol_breed = match.breed;
- if(!automa->ac_automa_finalized) {
- printf("[%s:%d] [NDPI] Internal error: please call ndpi_finalize_initalization()\n", __FILE__, __LINE__);
- return(0); /* No matches */
+ return(rc ? match.number : 0);
}
- ac_input_text.astring = string_to_match, ac_input_text.length = string_to_match_len;
- rc = ac_automata_search(((AC_AUTOMATA_t *) automa->ac_automa), &ac_input_text, &match);
-
- /*
- As ac_automata_search can detect partial matches and continue the search process
- in case rc == 0 (i.e. no match), we need to check if there is a partial match
- and in this case return it
- */
- if((rc == 0) && (match.number != 0))
- rc = 1;
-
- /* We need to take into account also rc == 0 that is used for partial matches */
- ret_match->protocol_id = match.number, ret_match->protocol_category = match.category,
- ret_match->protocol_breed = match.breed;
+ /* **************************************** */
- return(rc ? match.number : 0);
-}
+ static u_int8_t ndpi_is_more_generic_protocol(u_int16_t previous_proto, u_int16_t new_proto) {
+ /* Sometimes certificates are more generic than previously identified protocols */
-/* **************************************** */
+ if((previous_proto == NDPI_PROTOCOL_UNKNOWN) || (previous_proto == new_proto))
+ return(0);
-static u_int8_t ndpi_is_more_generic_protocol(u_int16_t previous_proto, u_int16_t new_proto) {
- /* Sometimes certificates are more generic than previously identified protocols */
+ switch(previous_proto) {
+ case NDPI_PROTOCOL_WHATSAPP_CALL:
+ case NDPI_PROTOCOL_WHATSAPP_FILES:
+ if(new_proto == NDPI_PROTOCOL_WHATSAPP)
+ return(1);
+ }
- if((previous_proto == NDPI_PROTOCOL_UNKNOWN) || (previous_proto == new_proto))
return(0);
-
- switch(previous_proto) {
- case NDPI_PROTOCOL_WHATSAPP_CALL:
- case NDPI_PROTOCOL_WHATSAPP_FILES:
- if(new_proto == NDPI_PROTOCOL_WHATSAPP)
- return(1);
}
- return(0);
-}
-
-/* ****************************************************** */
+ /* ****************************************************** */
-static u_int16_t ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow, char *string_to_match,
- u_int string_to_match_len, u_int16_t master_protocol_id,
- ndpi_protocol_match_result *ret_match, u_int8_t is_host_match) {
- int matching_protocol_id;
- struct ndpi_packet_struct *packet = &flow->packet;
+ static u_int16_t ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow, char *string_to_match,
+ u_int string_to_match_len, u_int16_t master_protocol_id,
+ ndpi_protocol_match_result *ret_match, u_int8_t is_host_match) {
+ int matching_protocol_id;
+ struct ndpi_packet_struct *packet = &flow->packet;
- matching_protocol_id =
- ndpi_match_string_subprotocol(ndpi_str, string_to_match, string_to_match_len, ret_match, is_host_match);
+ matching_protocol_id =
+ ndpi_match_string_subprotocol(ndpi_str, string_to_match, string_to_match_len, ret_match, is_host_match);
#ifdef DEBUG
- {
- char m[256];
- int len = ndpi_min(sizeof(m), string_to_match_len);
+ {
+ char m[256];
+ int len = ndpi_min(sizeof(m), string_to_match_len);
- strncpy(m, string_to_match, len);
- m[len] = '\0';
+ strncpy(m, string_to_match, len);
+ m[len] = '\0';
- NDPI_LOG_DBG2(ndpi_str, "[NDPI] ndpi_match_host_subprotocol(%s): %s\n", m,
- ndpi_str->proto_defaults[matching_protocol_id].protoName);
- }
+ NDPI_LOG_DBG2(ndpi_str, "[NDPI] ndpi_match_host_subprotocol(%s): %s\n", m,
+ ndpi_str->proto_defaults[matching_protocol_id].protoName);
+ }
#endif
- if((matching_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
- (!ndpi_is_more_generic_protocol(packet->detected_protocol_stack[0], matching_protocol_id))) {
- /* Move the protocol on slot 0 down one position */
- packet->detected_protocol_stack[1] = master_protocol_id,
- packet->detected_protocol_stack[0] = matching_protocol_id;
+ if((matching_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
+ (!ndpi_is_more_generic_protocol(packet->detected_protocol_stack[0], matching_protocol_id))) {
+ /* Move the protocol on slot 0 down one position */
+ packet->detected_protocol_stack[1] = master_protocol_id,
+ 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];
+ flow->detected_protocol_stack[0] = packet->detected_protocol_stack[0],
+ flow->detected_protocol_stack[1] = packet->detected_protocol_stack[1];
- if(flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
- flow->category = ret_match->protocol_category;
+ if(flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
+ flow->category = ret_match->protocol_category;
- return(packet->detected_protocol_stack[0]);
- }
+ return(packet->detected_protocol_stack[0]);
+ }
#ifdef DEBUG
- string_to_match[string_to_match_len] = '\0';
- NDPI_LOG_DBG2(ndpi_str, "[NTOP] Unable to find a match for '%s'\n", string_to_match);
+ string_to_match[string_to_match_len] = '\0';
+ NDPI_LOG_DBG2(ndpi_str, "[NTOP] Unable to find a match for '%s'\n", string_to_match);
#endif
- ret_match->protocol_id = NDPI_PROTOCOL_UNKNOWN, ret_match->protocol_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED,
- ret_match->protocol_breed = NDPI_PROTOCOL_UNRATED;
+ ret_match->protocol_id = NDPI_PROTOCOL_UNKNOWN, ret_match->protocol_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED,
+ ret_match->protocol_breed = NDPI_PROTOCOL_UNRATED;
- return(NDPI_PROTOCOL_UNKNOWN);
-}
+ return(NDPI_PROTOCOL_UNKNOWN);
+ }
-/* ****************************************************** */
+ /* ****************************************************** */
-u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- char *string_to_match, u_int string_to_match_len,
- ndpi_protocol_match_result *ret_match, u_int16_t master_protocol_id) {
- u_int16_t rc = ndpi_automa_match_string_subprotocol(ndpi_str, flow, string_to_match, string_to_match_len,
- master_protocol_id, ret_match, 1);
- ndpi_protocol_category_t id = ret_match->protocol_category;
-
- if(ndpi_get_custom_category_match(ndpi_str, string_to_match, string_to_match_len, &id) != -1) {
- /* if(id != -1) */ {
- flow->category = ret_match->protocol_category = id;
- rc = master_protocol_id;
+ u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ char *string_to_match, u_int string_to_match_len,
+ ndpi_protocol_match_result *ret_match, u_int16_t master_protocol_id) {
+ u_int16_t rc = ndpi_automa_match_string_subprotocol(ndpi_str, flow, string_to_match, string_to_match_len,
+ master_protocol_id, ret_match, 1);
+ ndpi_protocol_category_t id = ret_match->protocol_category;
+
+ if(ndpi_get_custom_category_match(ndpi_str, string_to_match, string_to_match_len, &id) != -1) {
+ /* if(id != -1) */ {
+ flow->category = ret_match->protocol_category = id;
+ rc = master_protocol_id;
+ }
}
+
+ return(rc);
}
- return(rc);
-}
+ /* **************************************** */
-/* **************************************** */
+ int ndpi_match_hostname_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
+ u_int16_t master_protocol, char *name, u_int name_len) {
+ ndpi_protocol_match_result ret_match;
+ u_int16_t subproto, what_len, i;
+ char *what;
-int ndpi_match_hostname_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
- u_int16_t master_protocol, char *name, u_int name_len) {
- ndpi_protocol_match_result ret_match;
- u_int16_t subproto, what_len, i;
- char *what;
+ if((name_len > 2) && (name[0] == '*') && (name[1] == '.'))
+ what = &name[1], what_len = name_len - 1;
+ else
+ what = name, what_len = name_len;
- if((name_len > 2) && (name[0] == '*') && (name[1] == '.'))
- what = &name[1], what_len = name_len - 1;
- else
- what = name, what_len = name_len;
+ /* Convert it first to lowercase: we assume meory is writable as in nDPI dissctors */
+ for(i=0; i<name_len; i++) what[i] = tolower(what[i]);
- /* Convert it first to lowercase: we assume meory is writable as in nDPI dissctors */
- for(i=0; i<name_len; i++) what[i] = tolower(what[i]);
+ subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, what, what_len, &ret_match, master_protocol);
- subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, what, what_len, &ret_match, master_protocol);
+ if(subproto != NDPI_PROTOCOL_UNKNOWN) {
+ ndpi_set_detected_protocol(ndpi_struct, flow, subproto, master_protocol);
+ ndpi_int_change_category(ndpi_struct, flow, ret_match.protocol_category);
+ return(1);
+ } else
+ return(0);
+ }
- if(subproto != NDPI_PROTOCOL_UNKNOWN) {
- ndpi_set_detected_protocol(ndpi_struct, flow, subproto, master_protocol);
- ndpi_int_change_category(ndpi_struct, flow, ret_match.protocol_category);
- return(1);
- } else
- return(0);
-}
+ /* ****************************************************** */
-/* ****************************************************** */
+ u_int16_t ndpi_match_content_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ char *string_to_match, u_int string_to_match_len,
+ ndpi_protocol_match_result *ret_match,
+ u_int16_t master_protocol_id) {
+ return(ndpi_automa_match_string_subprotocol(ndpi_str, flow, string_to_match, string_to_match_len,
+ master_protocol_id, ret_match, 0));
+ }
-u_int16_t ndpi_match_content_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- char *string_to_match, u_int string_to_match_len,
- ndpi_protocol_match_result *ret_match,
- u_int16_t master_protocol_id) {
- return(ndpi_automa_match_string_subprotocol(ndpi_str, flow, string_to_match, string_to_match_len,
- master_protocol_id, ret_match, 0));
-}
+ /* ****************************************************** */
-/* ****************************************************** */
+ int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_automa *automa, char *bigram_to_match) {
+ AC_TEXT_t ac_input_text;
+ AC_REP_t match = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED};
+ int rc;
-int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_automa *automa, char *bigram_to_match) {
- AC_TEXT_t ac_input_text;
- AC_REP_t match = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED};
- int rc;
+ if((automa->ac_automa == NULL) || (bigram_to_match == NULL))
+ return(-1);
- if((automa->ac_automa == NULL) || (bigram_to_match == NULL))
- return(-1);
-
- if(!automa->ac_automa_finalized) {
+ if(!automa->ac_automa_finalized) {
#if 1
- ndpi_finalize_initalization(ndpi_str);
+ ndpi_finalize_initalization(ndpi_str);
#else
- printf("[%s:%d] [NDPI] Internal error: please call ndpi_finalize_initalization()\n", __FILE__, __LINE__);
- return(0); /* No matches */
+ printf("[%s:%d] [NDPI] Internal error: please call ndpi_finalize_initalization()\n", __FILE__, __LINE__);
+ return(0); /* No matches */
#endif
- }
+ }
- ac_input_text.astring = bigram_to_match, ac_input_text.length = 2;
- rc = ac_automata_search(((AC_AUTOMATA_t *) automa->ac_automa), &ac_input_text, &match);
+ ac_input_text.astring = bigram_to_match, ac_input_text.length = 2;
+ rc = ac_automata_search(((AC_AUTOMATA_t *) automa->ac_automa), &ac_input_text, &match);
- /*
- As ac_automata_search can detect partial matches and continue the search process
- in case rc == 0 (i.e. no match), we need to check if there is a partial match
- and in this case return it
- */
- if((rc == 0) && (match.number != 0))
- rc = 1;
+ /*
+ As ac_automata_search can detect partial matches and continue the search process
+ in case rc == 0 (i.e. no match), we need to check if there is a partial match
+ and in this case return it
+ */
+ if((rc == 0) && (match.number != 0))
+ rc = 1;
- return(rc ? match.number : 0);
-}
+ return(rc ? match.number : 0);
+ }
-/* ****************************************************** */
+ /* ****************************************************** */
-void ndpi_free_flow_data(struct ndpi_flow_struct *flow) {
- if(flow) {
- u_int is_quic = flow_is_proto(flow, NDPI_PROTOCOL_QUIC);
+ void ndpi_free_flow_data(struct ndpi_flow_struct *flow) {
+ if(flow) {
+ u_int is_quic = flow_is_proto(flow, NDPI_PROTOCOL_QUIC);
- 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.content_type)
+ ndpi_free(flow->http.content_type);
- if(flow->http.request_content_type)
- ndpi_free(flow->http.request_content_type);
+ if(flow->http.request_content_type)
+ ndpi_free(flow->http.request_content_type);
- if(flow->http.user_agent)
- ndpi_free(flow->http.user_agent);
+ if(flow->http.user_agent)
+ ndpi_free(flow->http.user_agent);
- if(flow->kerberos_buf.pktbuf)
- ndpi_free(flow->kerberos_buf.pktbuf);
+ if(flow->kerberos_buf.pktbuf)
+ ndpi_free(flow->kerberos_buf.pktbuf);
- if(is_quic
- || flow_is_proto(flow, NDPI_PROTOCOL_TLS)
- || flow_is_proto(flow, NDPI_PROTOCOL_DTLS)
- ) {
- if(flow->protos.tls_quic_stun.tls_quic.server_names)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.server_names);
+ if(is_quic
+ || flow_is_proto(flow, NDPI_PROTOCOL_TLS)
+ || flow_is_proto(flow, NDPI_PROTOCOL_DTLS)
+ ) {
+ if(flow->protos.tls_quic_stun.tls_quic.server_names)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.server_names);
- if(flow->protos.tls_quic_stun.tls_quic.alpn)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.alpn);
+ if(flow->protos.tls_quic_stun.tls_quic.alpn)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.alpn);
- if(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions);
+ if(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions);
- if(flow->protos.tls_quic_stun.tls_quic.issuerDN)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.issuerDN);
+ if(flow->protos.tls_quic_stun.tls_quic.issuerDN)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.issuerDN);
- if(flow->protos.tls_quic_stun.tls_quic.subjectDN)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.subjectDN);
+ if(flow->protos.tls_quic_stun.tls_quic.subjectDN)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.subjectDN);
- if(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni);
- }
+ if(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni);
+ }
- if(flow->l4_proto == IPPROTO_TCP) {
- if(flow->l4.tcp.tls.message.buffer)
- ndpi_free(flow->l4.tcp.tls.message.buffer);
+ if(flow->l4_proto == IPPROTO_TCP) {
+ if(flow->l4.tcp.tls.message.buffer)
+ ndpi_free(flow->l4.tcp.tls.message.buffer);
#ifdef FRAG_MAN
- free_fragment(&flow->tcp_segments_list[0]);
- free_fragment(&flow->tcp_segments_list[1]);
+ free_fragment(&flow->tcp_segments_list[0]);
+ free_fragment(&flow->tcp_segments_list[1]);
#endif
+ }
}
}
-}
-void ndpi_free_flow(struct ndpi_flow_struct *flow) {
- if (flow) {
- ndpi_free_flow_data(flow);
- ndpi_free(flow);
+ void ndpi_free_flow(struct ndpi_flow_struct *flow) {
+ if(flow) {
+ ndpi_free_flow_data(flow);
+ ndpi_free(flow);
+ }
}
-}
-/* ****************************************************** */
+ /* ****************************************************** */
-char *ndpi_revision() {
- return(NDPI_GIT_RELEASE);
-}
+ char *ndpi_revision() {
+ return(NDPI_GIT_RELEASE);
+ }
-/* ****************************************************** */
+ /* ****************************************************** */
#ifdef WIN32
-/* https://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows */
-int gettimeofday(struct timeval *tp, struct timezone *tzp) {
- // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
- // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
- // until 00:00:00 January 1, 1970
- static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
+ /* https://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows */
+ int gettimeofday(struct timeval *tp, struct timezone *tzp) {
+ // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
+ // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
+ // until 00:00:00 January 1, 1970
+ static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
- SYSTEMTIME system_time;
- FILETIME file_time;
- uint64_t time;
+ SYSTEMTIME system_time;
+ FILETIME file_time;
+ uint64_t time;
- GetSystemTime(&system_time);
- SystemTimeToFileTime(&system_time, &file_time);
- time = ((uint64_t) file_time.dwLowDateTime);
- time += ((uint64_t) file_time.dwHighDateTime) << 32;
+ GetSystemTime(&system_time);
+ SystemTimeToFileTime(&system_time, &file_time);
+ time = ((uint64_t) file_time.dwLowDateTime);
+ time += ((uint64_t) file_time.dwHighDateTime) << 32;
- tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
- tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
- return(0);
-}
+ tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
+ tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
+ return(0);
+ }
#endif
-int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b) {
- int i;
+ int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b) {
+ int i;
- for (i = 0; i < NDPI_NUM_FDS_BITS; i++) {
- if(a.fds_bits[i] & b.fds_bits[i])
- return(1);
- }
+ for (i = 0; i < NDPI_NUM_FDS_BITS; i++) {
+ if(a.fds_bits[i] & b.fds_bits[i])
+ return(1);
+ }
- return(0);
-}
+ return(0);
+ }
#ifdef CODE_UNUSED
-int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a) {
- int i;
+ int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a) {
+ int i;
- for (i = 0; i < NDPI_NUM_FDS_BITS; i++)
- if(a.fds_bits[i] != 0)
- return(0);
+ for (i = 0; i < NDPI_NUM_FDS_BITS; i++)
+ if(a.fds_bits[i] != 0)
+ return(0);
- return(1);
-}
+ return(1);
+ }
-void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a) {
- int i;
+ void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a) {
+ int i;
- for (i = 0; i < NDPI_NUM_FDS_BITS; i++)
- printf("[%d=%u]", i, a.fds_bits[i]);
+ for (i = 0; i < NDPI_NUM_FDS_BITS; i++)
+ printf("[%d=%u]", i, a.fds_bits[i]);
- printf("\n");
-}
+ printf("\n");
+ }
#endif
-u_int16_t ndpi_get_api_version() {
- return(NDPI_API_VERSION);
-}
+ u_int16_t ndpi_get_api_version() {
+ return(NDPI_API_VERSION);
+ }
-const char *ndpi_get_gcrypt_version(void) {
+ const char *ndpi_get_gcrypt_version(void) {
#ifdef HAVE_LIBGCRYPT
- return gcry_check_version(NULL);
+ return gcry_check_version(NULL);
#endif
- return NULL;
-}
+ return NULL;
+ }
-ndpi_proto_defaults_t *ndpi_get_proto_defaults(struct ndpi_detection_module_struct *ndpi_str) {
- return(ndpi_str->proto_defaults);
-}
+ ndpi_proto_defaults_t *ndpi_get_proto_defaults(struct ndpi_detection_module_struct *ndpi_str) {
+ return(ndpi_str->proto_defaults);
+ }
-u_int ndpi_get_ndpi_num_supported_protocols(struct ndpi_detection_module_struct *ndpi_str) {
- return(ndpi_str->ndpi_num_supported_protocols);
-}
+ u_int ndpi_get_ndpi_num_supported_protocols(struct ndpi_detection_module_struct *ndpi_str) {
+ return(ndpi_str->ndpi_num_supported_protocols);
+ }
-u_int ndpi_get_ndpi_num_custom_protocols(struct ndpi_detection_module_struct *ndpi_str) {
- return(ndpi_str->ndpi_num_custom_protocols);
-}
+ u_int ndpi_get_ndpi_num_custom_protocols(struct ndpi_detection_module_struct *ndpi_str) {
+ return(ndpi_str->ndpi_num_custom_protocols);
+ }
-u_int ndpi_get_ndpi_detection_module_size() {
- return(sizeof(struct ndpi_detection_module_struct));
-}
+ u_int ndpi_get_ndpi_detection_module_size() {
+ return(sizeof(struct ndpi_detection_module_struct));
+ }
-void ndpi_set_debug_bitmask(struct ndpi_detection_module_struct *ndpi_str, NDPI_PROTOCOL_BITMASK debug_bitmask) {
+ void ndpi_set_debug_bitmask(struct ndpi_detection_module_struct *ndpi_str, NDPI_PROTOCOL_BITMASK debug_bitmask) {
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
- ndpi_str->debug_bitmask = debug_bitmask;
+ ndpi_str->debug_bitmask = debug_bitmask;
#endif
-}
+ }
-void ndpi_set_log_level(struct ndpi_detection_module_struct *ndpi_str, u_int l){
- ndpi_str->ndpi_log_level = l;
-}
+ void ndpi_set_log_level(struct ndpi_detection_module_struct *ndpi_str, u_int l){
+ ndpi_str->ndpi_log_level = l;
+ }
-/* ******************************************************************** */
+ /* ******************************************************************** */
-/* LRU cache */
-struct ndpi_lru_cache *ndpi_lru_cache_init(u_int32_t num_entries) {
- struct ndpi_lru_cache *c = (struct ndpi_lru_cache *) ndpi_malloc(sizeof(struct ndpi_lru_cache));
+ /* LRU cache */
+ struct ndpi_lru_cache *ndpi_lru_cache_init(u_int32_t num_entries) {
+ struct ndpi_lru_cache *c = (struct ndpi_lru_cache *) ndpi_malloc(sizeof(struct ndpi_lru_cache));
- if(!c)
- return(NULL);
+ if(!c)
+ return(NULL);
- c->entries = (struct ndpi_lru_cache_entry *) ndpi_calloc(num_entries, sizeof(struct ndpi_lru_cache_entry));
+ c->entries = (struct ndpi_lru_cache_entry *) ndpi_calloc(num_entries, sizeof(struct ndpi_lru_cache_entry));
- if(!c->entries) {
- ndpi_free(c);
- return(NULL);
- } else
- c->num_entries = num_entries;
+ if(!c->entries) {
+ ndpi_free(c);
+ return(NULL);
+ } else
+ c->num_entries = num_entries;
- return(c);
-}
+ return(c);
+ }
-void ndpi_lru_free_cache(struct ndpi_lru_cache *c) {
- ndpi_free(c->entries);
- ndpi_free(c);
-}
+ void ndpi_lru_free_cache(struct ndpi_lru_cache *c) {
+ ndpi_free(c->entries);
+ ndpi_free(c);
+ }
-u_int8_t ndpi_lru_find_cache(struct ndpi_lru_cache *c, u_int32_t key,
- u_int16_t *value, u_int8_t clean_key_when_found) {
- u_int32_t slot = key % c->num_entries;
+ u_int8_t ndpi_lru_find_cache(struct ndpi_lru_cache *c, u_int32_t key,
+ u_int16_t *value, u_int8_t clean_key_when_found) {
+ u_int32_t slot = key % c->num_entries;
- if(c->entries[slot].is_full) {
- *value = c->entries[slot].value;
- if(clean_key_when_found)
- c->entries[slot].is_full = 0;
- return(1);
- } else
- return(0);
-}
+ if(c->entries[slot].is_full) {
+ *value = c->entries[slot].value;
+ if(clean_key_when_found)
+ c->entries[slot].is_full = 0;
+ return(1);
+ } else
+ return(0);
+ }
-void ndpi_lru_add_to_cache(struct ndpi_lru_cache *c, u_int32_t key, u_int16_t value) {
- u_int32_t slot = key % c->num_entries;
+ void ndpi_lru_add_to_cache(struct ndpi_lru_cache *c, u_int32_t key, u_int16_t value) {
+ u_int32_t slot = key % c->num_entries;
- c->entries[slot].is_full = 1, c->entries[slot].key = key, c->entries[slot].value = value;
-}
+ c->entries[slot].is_full = 1, c->entries[slot].key = key, c->entries[slot].value = value;
+ }
-/* ******************************************************************** */
+ /* ******************************************************************** */
-/*
- This function tells if it's possible to further dissect a given flow
- 0 - All possible dissection has been completed
- 1 - Additional dissection is possible
-*/
-u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow) {
- u_int16_t proto =
- flow->detected_protocol_stack[1] ? flow->detected_protocol_stack[1] : flow->detected_protocol_stack[0];
+ /*
+ This function tells if it's possible to further dissect a given flow
+ 0 - All possible dissection has been completed
+ 1 - Additional dissection is possible
+ */
+ u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow) {
+ u_int16_t proto =
+ flow->detected_protocol_stack[1] ? flow->detected_protocol_stack[1] : flow->detected_protocol_stack[0];
#if 0
- printf("[DEBUG] %s(%u.%u): %u\n", __FUNCTION__,
- flow->detected_protocol_stack[0],
- flow->detected_protocol_stack[1],
- proto);
+ printf("[DEBUG] %s(%u.%u): %u\n", __FUNCTION__,
+ flow->detected_protocol_stack[0],
+ flow->detected_protocol_stack[1],
+ proto);
#endif
- switch(proto) {
- case NDPI_PROTOCOL_TLS:
- if(flow->l4.tcp.tls.certificate_processed) return(0);
+ switch(proto) {
+ case NDPI_PROTOCOL_TLS:
+ if(flow->l4.tcp.tls.certificate_processed) return(0);
- if(flow->l4.tcp.tls.num_tls_blocks <= ndpi_str->num_tls_blocks_to_follow) {
- // printf("*** %u/%u\n", flow->l4.tcp.tls.num_tls_blocks, ndpi_str->num_tls_blocks_to_follow);
- return(1);
- }
- break;
+ if(flow->l4.tcp.tls.num_tls_blocks <= ndpi_str->num_tls_blocks_to_follow) {
+ // printf("*** %u/%u\n", flow->l4.tcp.tls.num_tls_blocks, ndpi_str->num_tls_blocks_to_follow);
+ return(1);
+ }
+ break;
- case NDPI_PROTOCOL_HTTP:
- if((flow->host_server_name[0] == '\0') || (flow->http.response_status_code == 0))
- return(1);
- break;
+ case NDPI_PROTOCOL_HTTP:
+ if((flow->host_server_name[0] == '\0') || (flow->http.response_status_code == 0))
+ return(1);
+ break;
- case NDPI_PROTOCOL_DNS:
- case NDPI_PROTOCOL_MDNS:
- if(flow->protos.dns.num_answers == 0)
- return(1);
- break;
+ case NDPI_PROTOCOL_DNS:
+ case NDPI_PROTOCOL_MDNS:
+ if(flow->protos.dns.num_answers == 0)
+ return(1);
+ break;
- case NDPI_PROTOCOL_FTP_CONTROL:
- case NDPI_PROTOCOL_MAIL_POP:
- case NDPI_PROTOCOL_MAIL_IMAP:
- case NDPI_PROTOCOL_MAIL_SMTP:
- if(flow->protos.ftp_imap_pop_smtp.password[0] == '\0')
- return(1);
- break;
+ case NDPI_PROTOCOL_FTP_CONTROL:
+ case NDPI_PROTOCOL_MAIL_POP:
+ case NDPI_PROTOCOL_MAIL_IMAP:
+ case NDPI_PROTOCOL_MAIL_SMTP:
+ if(flow->protos.ftp_imap_pop_smtp.password[0] == '\0')
+ return(1);
+ break;
- case NDPI_PROTOCOL_SSH:
- if((flow->protos.ssh.hassh_client[0] == '\0') || (flow->protos.ssh.hassh_server[0] == '\0'))
- return(1);
- break;
+ case NDPI_PROTOCOL_SSH:
+ if((flow->protos.ssh.hassh_client[0] == '\0') || (flow->protos.ssh.hassh_server[0] == '\0'))
+ return(1);
+ break;
- case NDPI_PROTOCOL_TELNET:
- if(!flow->protos.telnet.password_detected)
- return(1);
- break;
+ case NDPI_PROTOCOL_TELNET:
+ if(!flow->protos.telnet.password_detected)
+ return(1);
+ break;
- case NDPI_PROTOCOL_SKYPE:
- if (flow->extra_packets_func)
- return(1);
- break;
+ case NDPI_PROTOCOL_SKYPE:
+ if(flow->extra_packets_func)
+ return(1);
+ break;
+ }
+
+ return(0);
}
- return(0);
-}
+ /* ******************************************************************** */
-/* ******************************************************************** */
+ const char *ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) {
+ switch(proto) {
+ case ndpi_l4_proto_unknown:
+ return("");
+ break;
-const char *ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) {
- switch(proto) {
- case ndpi_l4_proto_unknown:
- return("");
- break;
+ case ndpi_l4_proto_tcp_only:
+ return("TCP");
+ break;
- case ndpi_l4_proto_tcp_only:
- return("TCP");
- break;
+ case ndpi_l4_proto_udp_only:
+ return("UDP");
+ break;
- case ndpi_l4_proto_udp_only:
- return("UDP");
- break;
+ case ndpi_l4_proto_tcp_and_udp:
+ return("TCP/UDP");
+ break;
+ }
- case ndpi_l4_proto_tcp_and_udp:
- return("TCP/UDP");
- break;
+ return("");
}
- return("");
-}
+ /* ******************************************************************** */
-/* ******************************************************************** */
+ ndpi_l4_proto_info ndpi_get_l4_proto_info(struct ndpi_detection_module_struct *ndpi_struct,
+ 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;
-ndpi_l4_proto_info ndpi_get_l4_proto_info(struct ndpi_detection_module_struct *ndpi_struct,
- 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;
+ if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP)
+ return(ndpi_l4_proto_tcp_only);
+ else if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP)
+ return(ndpi_l4_proto_udp_only);
+ else if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP)
+ return(ndpi_l4_proto_tcp_and_udp);
+ }
- if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP)
- return(ndpi_l4_proto_tcp_only);
- else if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP)
- return(ndpi_l4_proto_udp_only);
- else if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP)
- return(ndpi_l4_proto_tcp_and_udp);
+ return(ndpi_l4_proto_unknown); /* default */
}
- return(ndpi_l4_proto_unknown); /* default */
-}
-
-/* ******************************************************************** */
+ /* ******************************************************************** */
-ndpi_ptree_t *ndpi_ptree_create(void) {
- ndpi_ptree_t *tree = (ndpi_ptree_t *) ndpi_malloc(sizeof(ndpi_ptree_t));
+ ndpi_ptree_t *ndpi_ptree_create(void) {
+ ndpi_ptree_t *tree = (ndpi_ptree_t *) ndpi_malloc(sizeof(ndpi_ptree_t));
- if(tree) {
- tree->v4 = ndpi_New_Patricia(32);
- tree->v6 = ndpi_New_Patricia(128);
+ if(tree) {
+ tree->v4 = ndpi_New_Patricia(32);
+ tree->v6 = ndpi_New_Patricia(128);
- if((!tree->v4) || (!tree->v6)) {
- ndpi_ptree_destroy(tree);
- return(NULL);
+ if((!tree->v4) || (!tree->v6)) {
+ ndpi_ptree_destroy(tree);
+ return(NULL);
+ }
}
- }
- return(tree);
-}
+ return(tree);
+ }
-/* ******************************************************************** */
+ /* ******************************************************************** */
-void ndpi_ptree_destroy(ndpi_ptree_t *tree) {
- if(tree) {
- if(tree->v4)
- ndpi_Destroy_Patricia(tree->v4, free_ptree_data);
- if(tree->v6)
- ndpi_Destroy_Patricia(tree->v6, free_ptree_data);
+ void ndpi_ptree_destroy(ndpi_ptree_t *tree) {
+ if(tree) {
+ if(tree->v4)
+ ndpi_Destroy_Patricia(tree->v4, free_ptree_data);
+ if(tree->v6)
+ ndpi_Destroy_Patricia(tree->v6, free_ptree_data);
- ndpi_free(tree);
+ ndpi_free(tree);
+ }
}
-}
-/* ******************************************************************** */
+ /* ******************************************************************** */
-int ndpi_ptree_insert(ndpi_ptree_t *tree, const ndpi_ip_addr_t *addr,
- u_int8_t bits, u_int64_t user_data) {
- u_int8_t is_v6 = ndpi_is_ipv6(addr);
- patricia_tree_t *ptree = is_v6 ? tree->v6 : tree->v4;
- prefix_t prefix;
- patricia_node_t *node;
+ int ndpi_ptree_insert(ndpi_ptree_t *tree, const ndpi_ip_addr_t *addr,
+ u_int8_t bits, u_int64_t user_data) {
+ u_int8_t is_v6 = ndpi_is_ipv6(addr);
+ patricia_tree_t *ptree = is_v6 ? tree->v6 : tree->v4;
+ prefix_t prefix;
+ patricia_node_t *node;
- if(bits > ptree->maxbits)
- return(-1);
+ if(bits > ptree->maxbits)
+ return(-1);
- if(is_v6)
- fill_prefix_v6(&prefix, (const struct in6_addr *) &addr->ipv6, bits, ptree->maxbits);
- else
- fill_prefix_v4(&prefix, (const struct in_addr *) &addr->ipv4, bits, ptree->maxbits);
+ if(is_v6)
+ fill_prefix_v6(&prefix, (const struct in6_addr *) &addr->ipv6, bits, ptree->maxbits);
+ else
+ fill_prefix_v4(&prefix, (const struct in_addr *) &addr->ipv4, bits, ptree->maxbits);
- /* Verify that the node does not already exist */
- node = ndpi_patricia_search_best(ptree, &prefix);
+ /* Verify that the node does not already exist */
+ node = ndpi_patricia_search_best(ptree, &prefix);
- if(node && (node->prefix->bitlen == bits))
- return(-2);
+ if(node && (node->prefix->bitlen == bits))
+ return(-2);
- node = ndpi_patricia_lookup(ptree, &prefix);
+ node = ndpi_patricia_lookup(ptree, &prefix);
- if(node != NULL) {
- node->value.u.uv64 = user_data;
+ if(node != NULL) {
+ node->value.u.uv64 = user_data;
- return(0);
+ return(0);
+ }
+
+ return(-3);
}
- return(-3);
-}
+ /* ******************************************************************** */
-/* ******************************************************************** */
+ int ndpi_ptree_match_addr(ndpi_ptree_t *tree,
+ const ndpi_ip_addr_t *addr, u_int64_t *user_data) {
+ u_int8_t is_v6 = ndpi_is_ipv6(addr);
+ patricia_tree_t *ptree = is_v6 ? tree->v6 : tree->v4;
+ prefix_t prefix;
+ patricia_node_t *node;
+ int bits = ptree->maxbits;
-int ndpi_ptree_match_addr(ndpi_ptree_t *tree,
- const ndpi_ip_addr_t *addr, u_int64_t *user_data) {
- u_int8_t is_v6 = ndpi_is_ipv6(addr);
- patricia_tree_t *ptree = is_v6 ? tree->v6 : tree->v4;
- prefix_t prefix;
- patricia_node_t *node;
- int bits = ptree->maxbits;
+ if(is_v6)
+ fill_prefix_v6(&prefix, (const struct in6_addr *) &addr->ipv6, bits, ptree->maxbits);
+ else
+ fill_prefix_v4(&prefix, (const struct in_addr *) &addr->ipv4, bits, ptree->maxbits);
- if(is_v6)
- fill_prefix_v6(&prefix, (const struct in6_addr *) &addr->ipv6, bits, ptree->maxbits);
- else
- fill_prefix_v4(&prefix, (const struct in_addr *) &addr->ipv4, bits, ptree->maxbits);
+ node = ndpi_patricia_search_best(ptree, &prefix);
- node = ndpi_patricia_search_best(ptree, &prefix);
+ if(node) {
+ *user_data = node->value.u.uv64;
- if(node) {
- *user_data = node->value.u.uv64;
+ return(0);
+ }
- return(0);
+ return(-1);
}
- return(-1);
-}
+ /* ******************************************************************** */
-/* ******************************************************************** */
+ void ndpi_md5(const u_char *data, size_t data_len, u_char hash[16]) {
+ ndpi_MD5_CTX ctx;
-void ndpi_md5(const u_char *data, size_t data_len, u_char hash[16]) {
- ndpi_MD5_CTX ctx;
-
- ndpi_MD5Init(&ctx);
- ndpi_MD5Update(&ctx, data, data_len);
- ndpi_MD5Final(hash, &ctx);
-}
+ ndpi_MD5Init(&ctx);
+ ndpi_MD5Update(&ctx, data, data_len);
+ ndpi_MD5Final(hash, &ctx);
+ }
-/* ******************************************************************** */
+ /* ******************************************************************** */
-static int enough(int a, int b) {
- u_int8_t percentage = 20;
+ static int enough(int a, int b) {
+ u_int8_t percentage = 20;
- if(b == 0) return(0);
- if(a == 0) return(1);
+ if(b == 0) return(0);
+ if(a == 0) return(1);
- if(b > (((a+1)*percentage)/100)) return(1);
+ if(b > (((a+1)*percentage)/100)) return(1);
- return(0);
-}
+ return(0);
+ }
-/* ******************************************************************** */
+ /* ******************************************************************** */
-static u_int8_t endsWith(char *str, char *ends, u_int8_t ends_len) {
- u_int str_len = str ? strlen(str) : 0;
- u_int8_t rc;
+ static u_int8_t endsWith(char *str, char *ends, u_int8_t ends_len) {
+ u_int str_len = str ? strlen(str) : 0;
+ u_int8_t rc;
- if(str_len < ends_len) return(0);
+ if(str_len < ends_len) return(0);
- rc = (strncmp(&str[str_len-ends_len], ends, ends_len) != 0) ? 0 : 1;
+ rc = (strncmp(&str[str_len-ends_len], ends, ends_len) != 0) ? 0 : 1;
#ifdef DGA_DEBUG
- printf("[DGA] %s / %s [rc: %u]\n", str, ends, rc);
+ printf("[DGA] %s / %s [rc: %u]\n", str, ends, rc);
#endif
- return(rc);
-}
+ return(rc);
+ }
-/* ******************************************************************** */
+ /* ******************************************************************** */
-int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- char *name, u_int8_t is_hostname) {
- int len, rc = 0;
- u_int8_t max_num_char_repetitions = 0, last_char = 0, num_char_repetitions = 0, num_dots = 0;
- u_int8_t max_domain_element_len = 0, curr_domain_element_len = 0, first_element_is_numeric = 1;
+ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ char *name, u_int8_t is_hostname) {
+ int len, rc = 0;
+ u_int8_t max_num_char_repetitions = 0, last_char = 0, num_char_repetitions = 0, num_dots = 0;
+ u_int8_t max_domain_element_len = 0, curr_domain_element_len = 0, first_element_is_numeric = 1;
- if(!name) return(0);
+ if(!name) return(0);
#ifdef DGA_DEBUG
- printf("[DGA] %s\n", name);
+ printf("[DGA] %s\n", name);
#endif
- len = strlen(name);
+ len = strlen(name);
- if(len >= 5) {
- int i, j, num_found = 0, num_impossible = 0, num_bigram_checks = 0, num_digits = 0, num_vowels = 0, num_words = 0;
- char tmp[128], *word, *tok_tmp;
- u_int max_tmp_len = sizeof(tmp)-1;
+ if(len >= 5) {
+ int i, j, num_found = 0, num_impossible = 0, num_bigram_checks = 0, num_digits = 0, num_vowels = 0, num_words = 0;
+ char tmp[128], *word, *tok_tmp;
+ u_int max_tmp_len = sizeof(tmp)-1;
- len = snprintf(tmp, max_tmp_len, "%s", name);
- if(len < 0) {
+ len = snprintf(tmp, max_tmp_len, "%s", name);
+ if(len < 0) {
#ifdef DGA_DEBUG
- printf("[DGA] Too short");
+ printf("[DGA] Too short");
#endif
- return(0);
- } else
- tmp[len < max_tmp_len ? len : max_tmp_len] = '\0';
+ return(0);
+ } else
+ tmp[len < max_tmp_len ? len : max_tmp_len] = '\0';
- for(i=0, j=0; (i<len) && (j<max_tmp_len); i++) {
- tmp[j] = tolower(name[i]);
+ for(i=0, j=0; (i<len) && (j<max_tmp_len); i++) {
+ tmp[j] = tolower(name[i]);
- if(tmp[j] == '.')
- num_dots++;
- else if(num_dots == 0) {
- if(!isdigit(tmp[j]))
- first_element_is_numeric = 0;
- }
+ if(tmp[j] == '.')
+ num_dots++;
+ else if(num_dots == 0) {
+ if(!isdigit(tmp[j]))
+ first_element_is_numeric = 0;
+ }
- if(last_char == tmp[j]) {
- if(++num_char_repetitions > max_num_char_repetitions)
- max_num_char_repetitions = num_char_repetitions;
- } else
- num_char_repetitions = 1, last_char = tmp[j];
-
- switch(tmp[j]) {
- case '.':
- case '-':
- case '_':
- case '/':
- case ')':
- case '(':
- case ';':
- case ':':
- case '[':
- case ']':
- case ' ':
- /*
- Domain/word separator chars
+ if(last_char == tmp[j]) {
+ if(++num_char_repetitions > max_num_char_repetitions)
+ max_num_char_repetitions = num_char_repetitions;
+ } else
+ num_char_repetitions = 1, last_char = tmp[j];
- NOTE:
- this function is used also to detect other type of issues
- such as invalid/suspiciuous user agent
- */
- if(curr_domain_element_len > max_domain_element_len)
- max_domain_element_len = curr_domain_element_len;
+ switch(tmp[j]) {
+ case '.':
+ case '-':
+ case '_':
+ case '/':
+ case ')':
+ case '(':
+ case ';':
+ case ':':
+ case '[':
+ case ']':
+ case ' ':
+ /*
+ Domain/word separator chars
- curr_domain_element_len = 0;
- break;
+ NOTE:
+ this function is used also to detect other type of issues
+ such as invalid/suspiciuous user agent
+ */
+ if(curr_domain_element_len > max_domain_element_len)
+ max_domain_element_len = curr_domain_element_len;
- default:
- curr_domain_element_len++;
- break;
- }
+ curr_domain_element_len = 0;
+ break;
- j++;
- }
+ default:
+ curr_domain_element_len++;
+ break;
+ }
+
+ j++;
+ }
- if(curr_domain_element_len > max_domain_element_len)
- max_domain_element_len = curr_domain_element_len;
+ if(curr_domain_element_len > max_domain_element_len)
+ max_domain_element_len = curr_domain_element_len;
#ifdef DGA_DEBUG
- printf("[DGA] [max_num_char_repetitions: %u][max_domain_element_len: %u]\n",
- max_num_char_repetitions, max_domain_element_len);
+ printf("[DGA] [max_num_char_repetitions: %u][max_domain_element_len: %u]\n",
+ max_num_char_repetitions, max_domain_element_len);
#endif
- if(
- (is_hostname
- && (num_dots > 5)
- && (!first_element_is_numeric)
- && (!endsWith(tmp, "in-addr.arpa", 12))
- )
- || (max_num_char_repetitions > 5 /* num or consecutive repeated chars */)
- /*
- In case of a name with too many consecutive chars an alert is triggered
- This is the case for instance of the wildcard DNS query used by NetBIOS
- (ckaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) and that can be exploited
- for reflection attacks
- - https://www.akamai.com/uk/en/multimedia/documents/state-of-the-internet/ddos-reflection-netbios-name-server-rpc-portmap-sentinel-udp-threat-advisory.pdf
- - http://ubiqx.org/cifs/NetBIOS.html
- */
- || (max_domain_element_len >= 19 /* word too long. Example bbcbedxhgjmdobdprmen.com */)
- ) {
- if(flow) NDPI_SET_BIT(flow->risk, NDPI_SUSPICIOUS_DGA_DOMAIN);
+ if(
+ (is_hostname
+ && (num_dots > 5)
+ && (!first_element_is_numeric)
+ && (!endsWith(tmp, "in-addr.arpa", 12))
+ )
+ || (max_num_char_repetitions > 5 /* num or consecutive repeated chars */)
+ /*
+ In case of a name with too many consecutive chars an alert is triggered
+ This is the case for instance of the wildcard DNS query used by NetBIOS
+ (ckaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) and that can be exploited
+ for reflection attacks
+ - https://www.akamai.com/uk/en/multimedia/documents/state-of-the-internet/ddos-reflection-netbios-name-server-rpc-portmap-sentinel-udp-threat-advisory.pdf
+ - http://ubiqx.org/cifs/NetBIOS.html
+ */
+ || (max_domain_element_len >= 19 /* word too long. Example bbcbedxhgjmdobdprmen.com */)
+ ) {
+ if(flow) NDPI_SET_BIT(flow->risk, NDPI_SUSPICIOUS_DGA_DOMAIN);
#ifdef DGA_DEBUG
- printf("[DGA] Found!");
+ printf("[DGA] Found!");
#endif
- return(1);
- }
+ return(1);
+ }
- tmp[j] = '\0';
- len = j;
+ tmp[j] = '\0';
+ len = j;
- for(word = strtok_r(tmp, ".", &tok_tmp); ; word = strtok_r(NULL, ".", &tok_tmp)) {
- if(!word) break;
+ for(word = strtok_r(tmp, ".", &tok_tmp); ; word = strtok_r(NULL, ".", &tok_tmp)) {
+ if(!word) break;
- num_words++;
+ num_words++;
- if(strlen(word) < 3) continue;
+ if(strlen(word) < 3) continue;
#ifdef DGA_DEBUG
- printf("-> %s [%s][len: %u]\n", word, name, (unsigned int)strlen(word));
+ printf("-> %s [%s][len: %u]\n", word, name, (unsigned int)strlen(word));
#endif
- for(i = 0; word[i+1] != '\0'; i++) {
- if(isdigit(word[i])) {
- num_digits++;
+ for(i = 0; word[i+1] != '\0'; i++) {
+ if(isdigit(word[i])) {
+ num_digits++;
- // if(!isdigit(word[i+1])) num_impossible++;
+ // if(!isdigit(word[i+1])) num_impossible++;
- continue;
- }
+ continue;
+ }
- switch(word[i]) {
- case '-':
- /*
- Let's check for double+consecutive --
- that are usually ok
- r2---sn-uxaxpu5ap5-2n5e.gvt1.com
- */
- if(word[i+1] == '-')
- return(0); /* Double dash */
+ switch(word[i]) {
+ case '-':
+ /*
+ Let's check for double+consecutive --
+ that are usually ok
+ r2---sn-uxaxpu5ap5-2n5e.gvt1.com
+ */
+ if(word[i+1] == '-')
+ return(0); /* Double dash */
- case '_':
- case ':':
- continue;
- break;
-
- case '.':
- continue;
- break;
- }
+ case '_':
+ case ':':
+ continue;
+ break;
+
+ case '.':
+ continue;
+ break;
+ }
- switch(word[i]) {
- case 'a':
- case 'e':
- case 'i':
- case 'o':
- case 'u':
- num_vowels++;
- break;
- }
+ switch(word[i]) {
+ case 'a':
+ case 'e':
+ case 'i':
+ case 'o':
+ case 'u':
+ num_vowels++;
+ break;
+ }
- if(isdigit(word[i+1])) {
- num_digits++;
- // num_impossible++;
- continue;
- }
+ if(isdigit(word[i+1])) {
+ num_digits++;
+ // num_impossible++;
+ continue;
+ }
- num_bigram_checks++;
+ num_bigram_checks++;
#ifdef DGA_DEBUG
- printf("-> Checking %c%c\n", word[i], word[i+1]);
+ printf("-> Checking %c%c\n", word[i], word[i+1]);
#endif
- if(ndpi_match_bigram(ndpi_str,
- &ndpi_str->impossible_bigrams_automa,
- &word[i])) {
+ if(ndpi_match_bigram(ndpi_str,
+ &ndpi_str->impossible_bigrams_automa,
+ &word[i])) {
#ifdef DGA_DEBUG
- printf("IMPOSSIBLE %s\n", &word[i]);
+ printf("IMPOSSIBLE %s\n", &word[i]);
#endif
- num_impossible++;
- } else if(ndpi_match_bigram(ndpi_str, &ndpi_str->bigrams_automa, &word[i])) {
- num_found++;
- }
+ num_impossible++;
+ } else if(ndpi_match_bigram(ndpi_str, &ndpi_str->bigrams_automa, &word[i])) {
+ num_found++;
+ }
+ } /* for */
} /* for */
- } /* for */
#ifdef DGA_DEBUG
- printf("[num_found: %u][num_impossible: %u][num_digits: %u][num_bigram_checks: %u][num_vowels: %u/%u]\n",
- num_found, num_impossible, num_digits, num_bigram_checks, num_vowels, j-num_vowels);
+ printf("[num_found: %u][num_impossible: %u][num_digits: %u][num_bigram_checks: %u][num_vowels: %u/%u]\n",
+ num_found, num_impossible, num_digits, num_bigram_checks, num_vowels, j-num_vowels);
#endif
- if(num_bigram_checks
- && ((num_found == 0) || ((num_digits > 5) && (num_words <= 3)) || enough(num_found, num_impossible)))
- rc = 1;
+ if(num_bigram_checks
+ && ((num_found == 0) || ((num_digits > 5) && (num_words <= 3)) || enough(num_found, num_impossible)))
+ rc = 1;
- if(rc && flow)
- NDPI_SET_BIT(flow->risk, NDPI_SUSPICIOUS_DGA_DOMAIN);
+ if(rc && flow)
+ NDPI_SET_BIT(flow->risk, NDPI_SUSPICIOUS_DGA_DOMAIN);
#ifdef DGA_DEBUG
- if(rc)
- printf("DGA %s [num_found: %u][num_impossible: %u]\n",
- name, num_found, num_impossible);
+ if(rc)
+ printf("DGA %s [num_found: %u][num_impossible: %u]\n",
+ name, num_found, num_impossible);
#endif
- }
+ }
#ifdef DGA_DEBUG
- printf("[DGA] Result: %u", rc);
+ printf("[DGA] Result: %u", rc);
#endif
- return(rc);
-}
+ return(rc);
+ }
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index 49f829fb1..3af0d3d23 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -57,6 +57,10 @@
// #define MATCH_DEBUG 1
+// #define DEBUG_REASSEMBLY
+
+/* ****************************************** */
+
/* implementation of the punycode check function */
int ndpi_check_punycode_string(char * buffer , int len) {
int i = 0;
@@ -74,6 +78,8 @@ int ndpi_check_punycode_string(char * buffer , int len) {
return 0;
}
+/* ****************************************** */
+
/* ftp://ftp.cc.uoc.gr/mirrors/OpenBSD/src/lib/libc/stdlib/tsearch.c */
/* find or insert datum into search tree */
void * ndpi_tsearch(const void *vkey, void **vrootp,
@@ -103,6 +109,8 @@ void * ndpi_tsearch(const void *vkey, void **vrootp,
return ((void *)q->key);
}
+/* ****************************************** */
+
/* delete node with given key */
void * ndpi_tdelete(const void *vkey, void **vrootp,
int (*compar)(const void *, const void *))
@@ -145,6 +153,8 @@ void * ndpi_tdelete(const void *vkey, void **vrootp,
return(key);
}
+/* ****************************************** */
+
/* Walk the nodes of a tree */
static void ndpi_trecurse(ndpi_node *root, void (*action)(const void *, ndpi_VISIT, int, void*), int level, void *user_data)
{
@@ -161,6 +171,8 @@ static void ndpi_trecurse(ndpi_node *root, void (*action)(const void *, ndpi_VIS
}
}
+/* ****************************************** */
+
/* Walk the nodes of a tree */
void ndpi_twalk(const void *vroot, void (*action)(const void *, ndpi_VISIT, int, void *), void *user_data)
{
@@ -170,6 +182,8 @@ void ndpi_twalk(const void *vroot, void (*action)(const void *, ndpi_VISIT, int,
ndpi_trecurse(root, action, 0, user_data);
}
+/* ****************************************** */
+
/* find a node, or return 0 */
void * ndpi_tfind(const void *vkey, void *vrootp,
int (*compar)(const void *, const void *))
@@ -987,43 +1001,43 @@ u_char* ndpi_base64_decode(const u_char *src, size_t len, size_t *out_len) {
int pad = 0;
memset(dtable, 0x80, 256);
- for (i = 0; i < sizeof(base64_table) - 1; i++)
+ for(i = 0; i < sizeof(base64_table) - 1; i++)
dtable[base64_table[i]] = (u_char) i;
dtable['='] = 0;
count = 0;
- for (i = 0; i < len; i++) {
- if (dtable[src[i]] != 0x80)
+ for(i = 0; i < len; i++) {
+ if(dtable[src[i]] != 0x80)
count++;
}
- if (count == 0 || count % 4)
+ if(count == 0 || count % 4)
return NULL;
olen = count / 4 * 3;
pos = out = ndpi_malloc(olen);
- if (out == NULL)
+ if(out == NULL)
return NULL;
count = 0;
- for (i = 0; i < len; i++) {
+ for(i = 0; i < len; i++) {
tmp = dtable[src[i]];
- if (tmp == 0x80)
+ if(tmp == 0x80)
continue;
- if (src[i] == '=')
+ if(src[i] == '=')
pad++;
block[count] = tmp;
count++;
- if (count == 4) {
+ if(count == 4) {
*pos++ = (block[0] << 2) | (block[1] >> 4);
*pos++ = (block[1] << 4) | (block[2] >> 2);
*pos++ = (block[2] << 6) | block[3];
count = 0;
- if (pad) {
- if (pad == 1)
+ if(pad) {
+ if(pad == 1)
pos--;
- else if (pad == 2)
+ else if(pad == 2)
pos -= 2;
else {
/* Invalid padding */
@@ -1507,7 +1521,7 @@ static void ndpi_compile_rce_regex() {
}
static int ndpi_is_rce_injection(char* query) {
- if (!initialized_comp_rx) {
+ if(!initialized_comp_rx) {
ndpi_compile_rce_regex();
initialized_comp_rx = 1;
}
@@ -1522,7 +1536,7 @@ static int ndpi_is_rce_injection(char* query) {
comp_rx[i]->optimized,
query, length, 0, 0, subStrVec, 30);
- if (pcreExecRet >= 0) {
+ if(pcreExecRet >= 0) {
return 1;
}
#ifdef DEBUG
@@ -1795,13 +1809,13 @@ ndpi_http_method ndpi_http_str2method(const char* method, u_int16_t method_len)
void printRawData(const uint8_t *ptr, size_t len) {
uint8_t *p=(uint8_t*)ptr;
DBGINFO("ptr=%p, len=%llu", ptr, (unsigned long long)len)
- if (p && len>0) {
+ if(p && len > 0) {
size_t ctLines=0,i,j;
char line1[ARRAYSZ_255]={0}, line2[ARRAYSZ_255]={0}, temp[ARRAYSZ_255];
snprintf(line1,sizeof(line1),"\t%05X",(unsigned int)(16*ctLines));
- for (i=0; i<len; i++) {
+ for(i=0; i<len; i++) {
- if (i>0 && i%16==0) {
+ if(i > 0 && i%16==0) {
printf("%s\t%s\n", line1,line2);
ctLines++;
snprintf(line1,ARRAYSZ_255,"\t%05X",(unsigned int)(16*ctLines));
@@ -1814,7 +1828,7 @@ void printRawData(const uint8_t *ptr, size_t len) {
p++;
}
uint8_t exv= i%16;
- for(j=exv;exv>0 && j<16;j++) {
+ for(j=exv;exv > 0 && j<16;j++) {
strncat(line1, " ", 3);
}
printf("%s\t%s\n", line1,line2);
@@ -1827,8 +1841,8 @@ void printRawData(const uint8_t *ptr, size_t len) {
void ins_sort_array(sorter_index_item_t arr[], int len) {
DBGINFO("sorting no. %u items", (unsigned)len)
- for (int i=1; i<len; i++) {
- for (int j=i; j>0 && arr[j].sort_value<arr[j-1].sort_value; j--) {
+ for(int i=1; i<len; i++) {
+ for(int j=i; j > 0 && arr[j].sort_value<arr[j-1].sort_value; j--) {
sorter_index_item_t temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
@@ -1839,16 +1853,17 @@ void ins_sort_array(sorter_index_item_t arr[], int len) {
void shell_sort_array(sorter_index_item_t arr[], int n) {
// Rearrange elements at each n/2, n/4, n/8, ... intervals
DBGINFO("sorting no. %u items", (unsigned)n)
- for (int interval = n / 2; interval > 0; interval /= 2) {
- for (int i = interval; i < n; i += 1) {
+ for(int interval = n / 2; interval > 0; interval /= 2) {
+ for(int i = interval; i < n; i += 1) {
sorter_index_item_t temp = arr[i];
int j;
- for (j = i; j >= interval && arr[j - interval].sort_value > temp.sort_value; j -= interval) {
+ for(j = i; j >= interval && arr[j - interval].sort_value > temp.sort_value; j -= interval) {
arr[j] = arr[j - interval];
- DBGTRACER("exchanged item no. %d (%d) with: %d (%d)", j, arr[j].sort_value, j-interval, temp.sort_value)
- }
- DBGTRACER("item no. %d value: %d", j, temp.sort_value)
- arr[j] = temp;
+ DBGTRACER("exchanged item no. %d (%d) with: %d (%d)", j, arr[j].sort_value, j-interval, temp.sort_value);
+ }
+
+ DBGTRACER("item no. %d value: %d", j, temp.sort_value);
+ arr[j] = temp;
}
}
}
@@ -1858,35 +1873,37 @@ void shell_sort_array(sorter_index_item_t arr[], int n) {
void free_fragment(fragments_wrapper_t *frag) {
/*
- *
- typedef struct fragment_wrapper {
- uint16_t id;
- uint8_t l4_protocol;
- uint8_t ct_frag;
- #ifdef NDPI_DETECTION_SUPPORT_IPV6
- char *flow_label; // IP6
- #endif
- fragment_t **fragments_list;
- } fragments_wrapper_t;
- *
- * */
- if (frag) {
- DBGTRACER("(frag:%p) freeing fragments list -> %p",frag, frag->fragments_list)
- if (frag->fragments_list) {
- DBGTRACER("fragments are %u.",frag->ct_frag)
- for (int y=0;y<frag->ct_frag;y++) {
- if (frag->fragments_list[y]) {
- if (frag->fragments_list[y]->data) {
- DBGPOINTER("freeing fragment item %d -> %p",y, frag->fragments_list[y])
- ndpi_free(frag->fragments_list[y]->data);
- }
- ndpi_free(frag->fragments_list[y]);
- }
- }
- DBGPOINTER("freeing fragments list -> %p",frag->fragments_list)
- ndpi_free(frag->fragments_list);
- frag->fragments_list= NULL;
- }
+ *
+ typedef struct fragment_wrapper {
+ uint16_t id;
+ uint8_t l4_protocol;
+ uint8_t ct_frag;
+ #ifdef NDPI_DETECTION_SUPPORT_IPV6
+ char *flow_label; // IP6
+ #endif
+ fragment_t **fragments_list;
+ } fragments_wrapper_t;
+ *
+ * */
+ if(frag) {
+ DBGTRACER("(frag:%p) freeing fragments list -> %p",frag, frag->fragments_list);
+ if(frag->fragments_list) {
+ DBGTRACER("fragments are %u.",frag->ct_frag);
+
+ for(int y=0;y<frag->ct_frag;y++) {
+ if(frag->fragments_list[y]) {
+ if(frag->fragments_list[y]->data) {
+ DBGPOINTER("freeing fragment item %d -> %p",y, frag->fragments_list[y]);
+ ndpi_free(frag->fragments_list[y]->data);
+ }
+
+ ndpi_free(frag->fragments_list[y]);
+ }
+ }
+ DBGPOINTER("freeing fragments list -> %p",frag->fragments_list)
+ ndpi_free(frag->fragments_list);
+ frag->fragments_list= NULL;
+ }
//reset counter and initial offset
frag->ct_frag=0;
frag->initial_offset=0;
@@ -1899,87 +1916,93 @@ uint8_t add_segment_to_buffer(struct ndpi_flow_struct *flow, struct ndpi_tcphdr
DBGINFO("[flow:%p], dir: %d, seq:%u, ack:%u, len: %ubytes",
flow, flow->packet.packet_direction, ntohl(tcph->seq), ntohl(tcph->ack_seq), flow->packet.payload_packet_len)
- if (flow->tcp_segments_management) {
- fragments_wrapper_t *fragW= &flow->tcp_segments_list[flow->packet.packet_direction];
- DBGTRACER("tcp segments management enabled (list container: %p)",fragW)
+ if(flow->tcp_segments_management) {
+ fragments_wrapper_t *fragW= &flow->tcp_segments_list[flow->packet.packet_direction];
+ DBGTRACER("tcp segments management enabled (list container: %p)", fragW);
- if (fragW->ct_frag == 0) {
- if (fragW->fragments_list)
- free_fragment(fragW);
+ if(fragW->ct_frag == 0) {
+ if(fragW->fragments_list)
+ free_fragment(fragW);
- // initialize the offset with the first fragment seq number
- fragW->initial_offset = new_expected_seq;
- DBGTRACER("initialized initial_offset: %u)",fragW->initial_offset)
- }
-
- if (flow->packet.payload_packet_len>0) {
- uint32_t seq;
-
- // allocate memory for pointer
- size_t new_len= (1+fragW->ct_frag) * sizeof(fragment_t*);
- DBGTRACER("actual fragment list ct=%d, new size: %llu", fragW->ct_frag, (unsigned long long)new_len)
-
- fragW->fragments_list = ndpi_realloc(fragW->fragments_list,(fragW->ct_frag * sizeof(fragment_t*)),new_len);
- if (fragW->fragments_list == NULL) {
- flow->tcp_segments_management= 0;
- fprintf(stderr, "[%8u] Not enough memory for new fragment \n", flow->packet_counter);
- return 0;
+ // initialize the offset with the first fragment seq number
+ fragW->initial_offset = new_expected_seq;
+ DBGTRACER("initialized initial_offset: %u)",fragW->initial_offset);
}
+
+ if(flow->packet.payload_packet_len > 0) {
+ uint32_t seq;
+
+ // allocate memory for pointer
+ size_t new_len= (1+fragW->ct_frag) * sizeof(fragment_t*);
+ DBGTRACER("actual fragment list ct=%d, new size: %llu", fragW->ct_frag, (unsigned long long)new_len);
+
+ fragW->fragments_list = ndpi_realloc(fragW->fragments_list,(fragW->ct_frag * sizeof(fragment_t*)),new_len);
+ if(fragW->fragments_list == NULL) {
+ flow->tcp_segments_management= 0;
+ // fprintf(stderr, "[%8u] Not enough memory for new fragment \n", flow->packet_counter);
+ return 0;
+ }
- DBGPOINTER("fragments_list initialized for item no. %u, list->%p i-esimo->%p",
- fragW->ct_frag, fragW->fragments_list, fragW->fragments_list[fragW->ct_frag])
-
- // allocate memory for item
- fragment_t *new_frag = (fragment_t*)ndpi_calloc(1, sizeof(fragment_t));
- if (new_frag == NULL) {
- flow->tcp_segments_management= 0;
- free_fragment(fragW);
- fprintf(stderr, "[%8u] Not enough memory for new fragment \n", flow->packet_counter);
- return 0;
- }
-
- DBGPOINTER("new_frag=> %p",new_frag)
-
- // fill item with offsetm len and data fragment/segment
- seq = (0xffffffff & ntohl(tcph->seq));
- if (seq >= fragW->initial_offset /* safety check */) {
- new_frag->offset = seq - fragW->initial_offset;
- } else {
- /* CHECK THIS CASE
- fprintf(stderr, "[%8u] Bad seq or initial offset (seq = %u, initial offset = %u)\n",
- flow->packet_counter, seq, fragW->initial_offset);
- */
- flow->tcp_segments_management= 0;
- ndpi_free(new_frag);
- free_fragment(fragW);
- return 0;
- }
+ DBGPOINTER("fragments_list initialized for item no. %u, list->%p i-esimo->%p",
+ fragW->ct_frag, fragW->fragments_list, fragW->fragments_list[fragW->ct_frag]);
+
+ // allocate memory for item
+ fragment_t *new_frag = (fragment_t*)ndpi_calloc(1, sizeof(fragment_t));
+ if(new_frag == NULL) {
+ flow->tcp_segments_management= 0;
+ free_fragment(fragW);
+ // fprintf(stderr, "[%8u] Not enough memory for new fragment \n", flow->packet_counter);
+ return 0;
+ }
+
+ DBGPOINTER("new_frag=> %p",new_frag);
+
+ // fill item with offsetm len and data fragment/segment
+ seq = (0xffffffff & ntohl(tcph->seq));
+ if(seq >= fragW->initial_offset /* safety check */) {
+ new_frag->offset = seq - fragW->initial_offset;
+ } else {
+ /* CHECK THIS CASE
+ fprintf(stderr, "[%8u] Bad seq or initial offset (seq = %u, initial offset = %u)\n",
+ flow->packet_counter, seq, fragW->initial_offset);
+ */
+ flow->tcp_segments_management= 0;
+ ndpi_free(new_frag);
+ free_fragment(fragW);
+ return 0;
+ }
- DBGTRACER("offset calculation: seq %u, init: %u, offset result: %u", ntohl(tcph->seq),
- fragW->initial_offset, new_frag->offset)
- new_frag->len= flow->packet.payload_packet_len;
+ DBGTRACER("offset calculation: seq %u, init: %u, offset result: %u", ntohl(tcph->seq),
+ fragW->initial_offset, new_frag->offset);
+ new_frag->len = flow->packet.payload_packet_len;
- new_frag->data = (void*)ndpi_calloc(new_frag->len, sizeof(char));
- DBGPOINTER("new_frag->data=> %p",new_frag->data)
- if (new_frag->data) {
- memcpy(new_frag->data,flow->packet.payload,new_frag->len);
- fragW->fragments_list[fragW->ct_frag++]= new_frag;
- } else {
- flow->tcp_segments_management= 0;
- ndpi_free(new_frag);
- free_fragment(fragW);
- fprintf(stderr, "[%8u] Not enough memory for new fragment data \n", flow->packet_counter);
- return 0;
- }
+ new_frag->data = (void*)ndpi_calloc(new_frag->len, sizeof(char));
+ DBGPOINTER("new_frag->data=> %p",new_frag->data)
+ if(new_frag->data) {
+ memcpy(new_frag->data,flow->packet.payload,new_frag->len);
+
+#ifdef DEBUG_REASSEMBLY
+ printf("[%s:%u] ==>> %s() [%p][offset: %u]\n",
+ __FILE__, __LINE__, __FUNCTION__, new_frag, new_frag->offset);
+#endif
- DBGINFO("item no. %u: %p->%p [off:%u, len:%u, data:%p]",
- fragW->ct_frag, fragW->fragments_list, *fragW->fragments_list,
- (unsigned int) new_frag->offset, (unsigned int)new_frag->len, new_frag->data)
+ fragW->fragments_list[fragW->ct_frag++]= new_frag; /* Add it to the list */
+ } else {
+ flow->tcp_segments_management= 0;
+ ndpi_free(new_frag);
+ free_fragment(fragW);
+ // fprintf(stderr, "[%8u] Not enough memory for new fragment data \n", flow->packet_counter);
+ return 0;
+ }
- return fragW->ct_frag;
- }
- }
+ DBGINFO("item no. %u: %p->%p [off:%u, len:%u, data:%p]",
+ fragW->ct_frag, fragW->fragments_list, *fragW->fragments_list,
+ (unsigned int) new_frag->offset, (unsigned int)new_frag->len, new_frag->data);
+ return fragW->ct_frag;
+ }
+ }
+
return 0;
}
@@ -1987,14 +2010,20 @@ uint8_t add_segment_to_buffer(struct ndpi_flow_struct *flow, struct ndpi_tcphdr
/* ******************************************************************** */
-uint32_t reassembly_fragment(struct ndpi_flow_struct *const flow, struct ndpi_tcphdr const * tcph, uint8_t **ret_buffer, size_t *len_buffer) {
+uint32_t reassembly_fragment(struct ndpi_flow_struct *const flow,
+ struct ndpi_tcphdr const * tcph,
+ uint8_t **ret_buffer, size_t *len_buffer) {
uint32_t ret_value = 0;
uint16_t last_item = 0;
- size_t length = 0,tot_length = 0;
+ size_t length = 0, tot_length = 0;
sorter_index_item_t *sorted_indexes;
fragments_wrapper_t *fragW;
uint8_t *buffer;
+#ifdef DEBUG_REASSEMBLY
+ printf("[%s:%u] ==>> %s()\n", __FILE__, __LINE__, __FUNCTION__);
+#endif
+
fragW = &flow->tcp_segments_list[flow->packet.packet_direction];
DBGTRACER("tcph:%p, ret_buffer:%p, len_buffer:%u", tcph, ret_buffer, len_buffer);
@@ -2002,83 +2031,87 @@ uint32_t reassembly_fragment(struct ndpi_flow_struct *const flow, struct ndpi_tc
// phase 1: calculate the size and fill the indexes array
DBGINFO("phase 1: init sorter, calculate the size of buffer to reassemble: %u items", fragW->ct_frag);
- sorted_indexes = ndpi_calloc(fragW->ct_frag, sizeof(sorter_index_item_t));
+ sorted_indexes = (sorter_index_item_t*)ndpi_calloc(fragW->ct_frag, sizeof(sorter_index_item_t));
- if (sorted_indexes == NULL) {
- fprintf(stderr, "[%8u] Not enough memory to sort the %u segments \n",
- flow->packet_counter, fragW->ct_frag);
+ if(sorted_indexes == NULL) {
+ //fprintf(stderr, "[%8u] Not enough memory to sort the %u segments \n", flow->packet_counter, fragW->ct_frag);
free_fragment(fragW);
return 0;
}
- DBGPOINTER("sorted_indexes=> %p", sorted_indexes)
+ DBGPOINTER("sorted_indexes=> %p", sorted_indexes);
- for (int i=0; i<fragW->ct_frag; i++) {
+ for(int i=0; i<fragW->ct_frag; i++) {
fragment_t *item = (fragment_t*)fragW->fragments_list[i];
-
+
sorted_indexes[i].sort_value = item->offset;
sorted_indexes[i].item_index = i;
tot_length += item->len;
-
+
DBGTRACER("segment (%d): len:%lu, offset: %u => partial buffer len: %lu",
- i, (long unsigned int)item->len, (unsigned int)item->offset, (long unsigned int)tot_length);
+ i, (long unsigned int)item->len, (unsigned int)item->offset, (long unsigned int)tot_length);
}
// phase 2: sorts fragments and check fragments and sequences
DBGINFO(" phase 2 sorting %d segments and checking",fragW->ct_frag);
- if (fragW->ct_frag>1) shell_sort_array(sorted_indexes, fragW->ct_frag);
+ if(fragW->ct_frag>1) shell_sort_array(sorted_indexes, fragW->ct_frag);
// checks
- for (uint i=0; i<fragW->ct_frag; i++) {
+ for(uint i=0; i<fragW->ct_frag; i++) {
fragment_t *item = (fragment_t*)fragW->fragments_list[ sorted_indexes[i].item_index ];
// 1: no segment offset can be > tot_length
DBGTRACER("checking %d/%d element: offset=%lu vs t_length=%lu",
i, sorted_indexes[i].item_index, (unsigned long)item->offset, (unsigned long)tot_length);
- if (item->offset > (uint32_t)tot_length) {
+ if((item->offset+item->len) > (uint32_t)tot_length) {
// update the last index of elements to elaborate
DBGINFO("stop processing at %d/%d element: len= %u; offset= %u",
i, sorted_indexes[i].item_index, (unsigned)length, (unsigned)item->offset)
- tot_length = length;
+ // tot_length = length; /* CHECK THIS CASE */
+#ifdef DEBUG_REASSEMBLY
+ printf("[%s:%u] ==>> Too long [last_item: %u][offset: %u/len: %u][%p]\n", __FILE__, __LINE__,
+ last_item, item->offset, item->len, item);
+#endif
+ tot_length = item->offset+item->len; /* CHECK THIS CASE */
+
// set the first offset to wait for the next segment
ret_value = fragW->initial_offset + item->offset;
-
break;
-
- // 2: for every len(buffer) must exists a offset fragment
- } else if (item->offset != (uint32_t)length) {
-
+ // 2: for every len(buffer) must exists a offset fragment
+ } else if(item->offset != (uint32_t)length) {
// update the last index of elements to elaborate
DBGINFO("checking %d/%d element: stop processing! len: %u; n_offset: %u",
i, sorted_indexes[i].item_index, (unsigned)length, (unsigned)item->offset);
- tot_length = length;
+ // tot_length = length; /* CHECK THIS CASE */
// set the first offset to wait for the next segment
ret_value = fragW->initial_offset + item->offset;
-
break;
-
} else {
// continue to sum length data bytes
- length+= item->len;
- last_item= i;
+ length += item->len;
+ last_item = i;
}
}
last_item++; // index to number aligment
// phase 3: allocate memory and fill the buffer
DBGINFO("phase 3: allocate memory for %u items and fill the buffer tot: %lu", last_item, (unsigned long int)tot_length);
+
+#ifdef DEBUG_REASSEMBLY
+ printf("[%s:%u] ==>> [tot_length: %u][length: %u]\n",
+ __FILE__, __LINE__, (u_int32_t)tot_length, (u_int32_t)length);
+#endif
buffer = ndpi_calloc(tot_length, sizeof(uint8_t));
- if (buffer == NULL) {
- fprintf(stderr, "[%8u] Not enough memory for buffer for %u segments \n",
- flow->packet_counter,last_item);
+ if(buffer == NULL) {
+ // fprintf(stderr, "[%8u] Not enough memory for buffer for %u segments \n", flow->packet_counter,last_item);
free_fragment(fragW);
ndpi_free(sorted_indexes);
return 0;
@@ -2086,13 +2119,29 @@ uint32_t reassembly_fragment(struct ndpi_flow_struct *const flow, struct ndpi_tc
DBGPOINTER("buffer (len:%lu)=> %p", (unsigned long)tot_length, buffer);
- for (uint i=0; i<last_item; i++) {
+ for(uint i=0; i<last_item; i++) {
fragment_t *item = (fragment_t*) fragW->fragments_list[sorted_indexes[i].item_index];
DBGINFO("copying data item no:%u of len: %lu to buffer: %p (offset:%lu)",
sorted_indexes[i].item_index, (unsigned long int)item->len, buffer,
(unsigned long int)item->offset);
+ if((item->offset+item->len) > tot_length) {
+ //#ifdef DEBUG_REASSEMBLY
+ printf("[%s:%u] ==>> Out of boundary [%u vs %u][offset: %u][len: %u][item: %u/%u]\n", __FILE__, __LINE__,
+ (u_int32_t)(item->offset+item->len), (u_int32_t)tot_length,
+ (u_int32_t)item->offset, (u_int32_t)item->len, i, last_item);
+ //#endif
+ continue;
+ } else {
+#ifdef DEBUG_REASSEMBLY
+ printf("[%s:%u] ==>> memcpy OK [%u vs %u][offset: %u][item: %u/%u]\n",
+ __FILE__, __LINE__,
+ (u_int32_t)(item->offset+item->len), (u_int32_t)tot_length,
+ item->offset, i, last_item);
+#endif
+ }
+
memcpy((void*)(buffer + item->offset), item->data, item->len);
// free memory item
@@ -2102,7 +2151,7 @@ uint32_t reassembly_fragment(struct ndpi_flow_struct *const flow, struct ndpi_tc
fragW->fragments_list[sorted_indexes[i].item_index]=NULL;
}
- if (last_item == fragW->ct_frag) {
+ if(last_item == fragW->ct_frag) {
DBGTRACER("all processed: free all memory!");
free_fragment(fragW);
} else {
@@ -2113,8 +2162,8 @@ uint32_t reassembly_fragment(struct ndpi_flow_struct *const flow, struct ndpi_tc
DBGPOINTER("old segments list: %p, new segments list: %p.",
fragW_old_list, fragW->fragments_list);
- if (!fragW->fragments_list) {
- fprintf(stderr, "[%8u] Not enough memory for new segments list \n", flow->packet_counter);
+ if(!fragW->fragments_list) {
+ // fprintf(stderr, "[%8u] Not enough memory for new segments list \n", flow->packet_counter);
free_fragment(fragW);
ndpi_free(buffer);
ndpi_free(sorted_indexes);
@@ -2122,17 +2171,17 @@ uint32_t reassembly_fragment(struct ndpi_flow_struct *const flow, struct ndpi_tc
}
// re-fill the new segments list, updating the offsets
- for (uint i = last_item; i < fragW->ct_frag; i++) {
+ for(uint i = last_item; i < fragW->ct_frag; i++) {
fragment_t *item = (fragment_t*)fragW_old_list[sorted_indexes[i].item_index];
fragW->fragments_list[i-last_item] = item;
- if (item->offset >= tot_length /* safety check */) {
+ if(item->offset >= tot_length /* safety check */) {
item->offset -= tot_length;
}
/* CHECK THIS CASE
- else {
- fprintf(stderr, "[%8u] Bad offset update (item->offset = %u, tot_length = %lu)\n",
- flow->packet_counter, item->offset, tot_length);
- }
+ else {
+ fprintf(stderr, "[%8u] Bad offset update (item->offset = %u, tot_length = %lu)\n",
+ flow->packet_counter, item->offset, tot_length);
+ }
*/
DBGTRACER("moving the item (%p), index %u - to position %u of new segments list; new offset: %u.",
@@ -2147,10 +2196,10 @@ uint32_t reassembly_fragment(struct ndpi_flow_struct *const flow, struct ndpi_tc
(unsigned)fragW->ct_frag, (unsigned)fragW->initial_offset);
DBGPOINTER("freeing old segments list: %p ", fragW_old_list)
- ndpi_free(fragW_old_list);
+ ndpi_free(fragW_old_list);
}
- if (sorted_indexes) {
+ if(sorted_indexes) {
DBGPOINTER("freeing sorter indexes: %p ", sorted_indexes);
ndpi_free(sorted_indexes);
}
@@ -2171,7 +2220,7 @@ uint32_t reassembly_fragment(struct ndpi_flow_struct *const flow, struct ndpi_tc
}
DBGINFO("returning: %d", ret_value);
- return ret_value;
+ return(ret_value);
}
/* ******************************************************************** */
@@ -2182,7 +2231,7 @@ uint8_t check_for_sequence(struct ndpi_flow_struct *flow, struct ndpi_tcphdr con
DBGINFO("## sorted flags: %d/%d ",flow->not_sorted[0],flow->not_sorted[1]);
- if (flow->next_tcp_seq_nr[flow->packet.packet_direction]) {
+ if(flow->next_tcp_seq_nr[flow->packet.packet_direction]) {
uint32_t *trigger, expected;
uint8_t *not_sorted;
@@ -2190,16 +2239,17 @@ uint8_t check_for_sequence(struct ndpi_flow_struct *flow, struct ndpi_tcphdr con
not_sorted = &flow->not_sorted[flow->packet.packet_direction];
trigger = &flow->trigger[flow->packet.packet_direction];
- DBGTRACER("dir:%d, trg:%u, next:%u", flow->packet.packet_direction,*trigger, flow->next_tcp_seq_nr[flow->packet.packet_direction]);
+ DBGTRACER("dir:%d, trg:%u, next:%u", flow->packet.packet_direction,*trigger,
+ flow->next_tcp_seq_nr[flow->packet.packet_direction]);
- expected = (*not_sorted && *trigger) ? ndpi_min(*trigger,flow->next_tcp_seq_nr[flow->packet.packet_direction]) : flow->next_tcp_seq_nr[flow->packet.packet_direction];
+ expected = (*not_sorted && *trigger) ? ndpi_min(*trigger, flow->next_tcp_seq_nr[flow->packet.packet_direction]) : flow->next_tcp_seq_nr[flow->packet.packet_direction];
- if (expected < (0xffffffff & ntohl(tcph->seq))) {
+ if(expected < (0xffffffff & ntohl(tcph->seq))) {
// segment not in order... almost 1 has been skipped! add this fragment to buffer
DBGINFO("received a segment (seq:%u) over the expected (next:%u)", (0xffffffff & ntohl(tcph->seq)), expected);
- if (add_segment_to_buffer(flow, tcph, expected)) {
- DBGTRACER("segment (seq:%u) bufferized, waiting for (next:%u)", (0xffffffff & ntohl(tcph->seq)), expected);
+ if(add_segment_to_buffer(flow, tcph, expected)) {
+ DBGTRACER("segment (seq:%u) bufferized, waiting for(next:%u)", (0xffffffff & ntohl(tcph->seq)), expected);
// set flag a save the expected sequence number
*not_sorted=1;
@@ -2208,7 +2258,7 @@ uint8_t check_for_sequence(struct ndpi_flow_struct *flow, struct ndpi_tcphdr con
}
return 1;
- } else if (expected>(0xffffffff & ntohl(tcph->seq))) {
+ } else if(expected>(0xffffffff & ntohl(tcph->seq))) {
DBGINFO("received a segment (seq:%u) minus than the expected (next:%u): retransmission!!", (0xffffffff & ntohl(tcph->seq)), flow->next_tcp_seq_nr[flow->packet.packet_direction]);
flow->packet.tcp_retransmission = 1;
@@ -2228,14 +2278,17 @@ uint8_t check_for_sequence(struct ndpi_flow_struct *flow, struct ndpi_tcphdr con
}
} else {
- DBGTRACER("seq (%u) and expected (%u) matched! sorted flag: %d", (0xffffffff & ntohl(tcph->seq)), flow->next_tcp_seq_nr[flow->packet.packet_direction], *not_sorted);
+ DBGTRACER("seq (%u) and expected (%u) matched! sorted flag: %d",
+ (0xffffffff & ntohl(tcph->seq)),
+ flow->next_tcp_seq_nr[flow->packet.packet_direction],
+ *not_sorted);
- if (*not_sorted) {
- if (add_segment_to_buffer(flow, tcph, 0)) {
+ if(*not_sorted) {
+ if(add_segment_to_buffer(flow, tcph, 0)) {
*trigger= reassembly_fragment(flow,tcph,&ret_buffer,&len_buffer);
- *not_sorted=(*trigger>0);
+ *not_sorted=(*trigger > 0);
- if (len_buffer>0) {
+ if(len_buffer > 0) {
// the previous pointers must not be free, because managed in other part
flow->packet.payload_packet_len= len_buffer;
flow->packet.payload= ret_buffer;