diff options
-rw-r--r-- | example/ndpiReader.c | 14 | ||||
-rw-r--r-- | example/ndpi_util.c | 26 | ||||
-rw-r--r-- | src/lib/protocols/stun.c | 154 |
3 files changed, 105 insertions, 89 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c index abfe5d365..8551992bf 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -1438,6 +1438,7 @@ static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth, } } +/* *********************************************** */ /** * @brief On Protocol Discover - demo callback @@ -1448,6 +1449,8 @@ static void on_protocol_discovered(struct ndpi_workflow * workflow, ; } +/* *********************************************** */ + #if 0 /** * @brief Print debug @@ -1455,7 +1458,6 @@ static void on_protocol_discovered(struct ndpi_workflow * workflow, static void debug_printf(u_int32_t protocol, void *id_struct, ndpi_log_level_t log_level, const char *format, ...) { - va_list va_ap; #ifndef WIN32 struct tm result; @@ -1489,6 +1491,8 @@ static void debug_printf(u_int32_t protocol, void *id_struct, } #endif +/* *********************************************** */ + /** * @brief Setup for detection begin */ @@ -1576,6 +1580,7 @@ static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) { } } +/* *********************************************** */ /** * @brief End of detection and free flow @@ -1584,6 +1589,7 @@ static void terminateDetection(u_int16_t thread_id) { ndpi_workflow_free(ndpi_thread_info[thread_id].workflow); } +/* *********************************************** */ /** * @brief Traffic stats format @@ -1620,6 +1626,7 @@ char* formatTraffic(float numBits, int bits, char *buf) { return(buf); } +/* *********************************************** */ /** * @brief Packets stats format @@ -1638,6 +1645,7 @@ char* formatPackets(float numPkts, char *buf) { return(buf); } +/* *********************************************** */ /** * @brief JSON function init @@ -1649,6 +1657,8 @@ static void json_init() { jArray_topStats = json_object_new_array(); } +/* *********************************************** */ + static void json_open_stats_file() { if((file_first_time && ((stats_fp = fopen(_statsFilePath,"w")) == NULL)) || @@ -1659,6 +1669,8 @@ static void json_open_stats_file() { else file_first_time = 0; } +/* *********************************************** */ + static void json_close_stats_file() { json_object *jObjFinal = json_object_new_object(); diff --git a/example/ndpi_util.c b/example/ndpi_util.c index c8e0130ff..e453a3461 100644 --- a/example/ndpi_util.c +++ b/example/ndpi_util.c @@ -246,21 +246,21 @@ int ndpi_workflow_node_cmp(const void *a, const void *b) { if( ( - (fa->src_ip == fb->src_ip ) - && (fa->src_port == fb->src_port) - && (fa->dst_ip == fb->dst_ip ) - && (fa->dst_port == fb->dst_port) - ) + (fa->src_ip == fb->src_ip ) + && (fa->src_port == fb->src_port) + && (fa->dst_ip == fb->dst_ip ) + && (fa->dst_port == fb->dst_port) + ) || ( - (fa->src_ip == fb->dst_ip ) - && (fa->src_port == fb->dst_port) - && (fa->dst_ip == fb->src_ip ) - && (fa->dst_port == fb->src_port) - ) - ) + (fa->src_ip == fb->dst_ip ) + && (fa->src_port == fb->dst_port) + && (fa->dst_ip == fb->src_ip ) + && (fa->dst_port == fb->src_port) + ) + ) return(0); - + if(fa->src_ip < fb->src_ip ) return(-1); else { if(fa->src_ip > fb->src_ip ) return(1); } if(fa->src_port < fb->src_port) return(-1); else { if(fa->src_port > fb->src_port) return(1); } if(fa->dst_ip < fb->dst_ip ) return(-1); else { if(fa->dst_ip > fb->dst_ip ) return(1); } @@ -376,10 +376,10 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow flow.src_ip = iph->saddr, flow.dst_ip = iph->daddr; flow.src_port = htons(*sport), flow.dst_port = htons(*dport); flow.hashval = hashval = flow.protocol + flow.vlan_id + flow.src_ip + flow.dst_ip + flow.src_port + flow.dst_port; + /* printf("hashval=%u [%u][%u][%u:%u][%u:%u]\n", hashval, flow.protocol, flow.vlan_id, flow.src_ip, flow.src_port, flow.dst_ip, flow.dst_port); */ idx = hashval % workflow->prefs.num_roots; ret = ndpi_tfind(&flow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp); - /* to avoid two nodes in one binary tree for a flow */ int is_changed = 0; if(ret == NULL) { diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c index b37145fd6..97cf091f0 100644 --- a/src/lib/protocols/stun.c +++ b/src/lib/protocols/stun.c @@ -76,7 +76,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * if(ntohs(h->msg_type) == 0x01 /* Binding Request */) flow->protos.stun_ssl.stun.num_binding_requests++; - // printf("[%02X][%02X][payload_length: %u]\n", payload[0], payload[1], payload_length); + /* printf("[%02X][%02X][msg_len: %u][payload_length: %u]\n", payload[0], payload[1], msg_len, payload_length); */ if(((payload[0] == 0x80) && ((msg_len+20) <= payload_length)) /* WhatsApp Voice */) { *is_whatsapp = 1; @@ -89,86 +89,90 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * if((payload[0] != 0x80) && ((msg_len+20) > payload_length)) return(NDPI_IS_NOT_STUN); - if(((payload_length == (msg_len+20)) - && ((msg_type <= 0x000b) /* http://www.3cx.com/blog/voip-howto/stun-details/ */))) { - u_int offset = 20; - - // printf("[%02X][%02X][%02X][%02X][payload_length: %u]\n", payload[offset], payload[offset+1], payload[offset+2], payload[offset+3],payload_length); - - /* - This can either be the standard RTCP or Ms Lync RTCP that - later will become Ms Lync RTP. In this case we need to - be careful before deciding about the protocol before dissecting the packet - - MS Lync = Skype - https://en.wikipedia.org/wiki/Skype_for_Business - */ - - while((offset+2) < payload_length) { - u_int16_t attribute = ntohs(*((u_int16_t*)&payload[offset])); - u_int16_t len = ntohs(*((u_int16_t*)&payload[offset+2])); - u_int16_t x = (len + 4) % 4; - - if(x != 0) - len += 4-x; - - switch(attribute) { - case 0x0008: /* Message Integrity */ - case 0x0020: /* XOR-MAPPED-ADDRESSES */ - case 0x4000: - case 0x4002: - /* These are the only messages apparently whatsapp voice can use */ - break; - - case 0x8054: /* Candidate Identifier */ - if((len == 4) - && ((offset+7) < payload_length) - && (payload[offset+5] == 0x00) - && (payload[offset+6] == 0x00) - && (payload[offset+7] == 0x00)) { - /* Either skype for business or "normal" skype with multiparty call */ + if(payload_length == (msg_len+20)) { + if(msg_type <= 0x000b) /* http://www.3cx.com/blog/voip-howto/stun-details/ */ { + u_int offset = 20; + + // printf("[%02X][%02X][%02X][%02X][payload_length: %u]\n", payload[offset], payload[offset+1], payload[offset+2], payload[offset+3],payload_length); + + /* + This can either be the standard RTCP or Ms Lync RTCP that + later will become Ms Lync RTP. In this case we need to + be careful before deciding about the protocol before dissecting the packet + + MS Lync = Skype + https://en.wikipedia.org/wiki/Skype_for_Business + */ + + while((offset+2) < payload_length) { + u_int16_t attribute = ntohs(*((u_int16_t*)&payload[offset])); + u_int16_t len = ntohs(*((u_int16_t*)&payload[offset+2])); + u_int16_t x = (len + 4) % 4; + + if(x != 0) + len += 4-x; + + switch(attribute) { + case 0x0008: /* Message Integrity */ + case 0x0020: /* XOR-MAPPED-ADDRESSES */ + case 0x4000: + case 0x4002: + /* These are the only messages apparently whatsapp voice can use */ + break; + + case 0x8054: /* Candidate Identifier */ + if((len == 4) + && ((offset+7) < payload_length) + && (payload[offset+5] == 0x00) + && (payload[offset+6] == 0x00) + && (payload[offset+7] == 0x00)) { + /* Either skype for business or "normal" skype with multiparty call */ + flow->protos.stun_ssl.stun.is_skype = 1; + return(NDPI_IS_STUN); + } + break; + + case 0x8055: /* MS Service Quality (skype?) */ + break; + + /* Proprietary fields found on skype calls */ + case 0x24DF: + case 0x3802: + case 0x8036: + case 0x8095: + case 0x0800: + /* printf("====>>>> %04X\n", attribute); */ flow->protos.stun_ssl.stun.is_skype = 1; return(NDPI_IS_STUN); + break; + + case 0x8070: /* Implementation Version */ + if((len == 4) + && ((offset+7) < payload_length) + && (payload[offset+4] == 0x00) + && (payload[offset+5] == 0x00) + && (payload[offset+6] == 0x00) + && ((payload[offset+7] == 0x02) || (payload[offset+7] == 0x03)) + ) { + flow->protos.stun_ssl.stun.is_skype = 1; + return(NDPI_IS_STUN); + } + break; + + default: + /* This means this STUN packet cannot be confused with whatsapp voice */ + /* printf("==> %04X\n", attribute); */ + can_this_be_whatsapp_voice = 0; + break; } - break; - - case 0x8055: /* MS Service Quality (skype?) */ - break; - - /* Proprietary fields found on skype calls */ - case 0x24DF: - case 0x3802: - case 0x8036: - case 0x8095: - case 0x0800: - /* printf("====>>>> %04X\n", attribute); */ - flow->protos.stun_ssl.stun.is_skype = 1; - return(NDPI_IS_STUN); - break; - - case 0x8070: /* Implementation Version */ - if((len == 4) - && ((offset+7) < payload_length) - && (payload[offset+4] == 0x00) - && (payload[offset+5] == 0x00) - && (payload[offset+6] == 0x00) - && ((payload[offset+7] == 0x02) || (payload[offset+7] == 0x03)) - ) { - flow->protos.stun_ssl.stun.is_skype = 1; - return(NDPI_IS_STUN); - } - break; - default: - /* This means this STUN packet cannot be confused with whatsapp voice */ - printf("==> %04X\n", attribute); - can_this_be_whatsapp_voice = 0; - break; + offset += len + 4; } - - offset += len + 4; + goto udp_stun_found; + } else if(msg_type == 0x0800) { + *is_whatsapp = 1; + return NDPI_IS_STUN; /* This is WhatsApp */ } - goto udp_stun_found; } if((flow->protos.stun_ssl.stun.num_udp_pkts > 0) && (msg_type <= 0x00FF)) { |