diff options
Diffstat (limited to 'example')
-rw-r--r-- | example/ndpiReader.c | 22 | ||||
-rw-r--r-- | example/reader_util.c | 91 | ||||
-rw-r--r-- | example/reader_util.h | 7 |
3 files changed, 69 insertions, 51 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 40219acd4..ccd154870 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -602,7 +602,7 @@ void printCSVHeader() { fprintf(csv_fp, "client_info,server_info,"); fprintf(csv_fp, "tls_version,ja3c,tls_client_unsafe,"); fprintf(csv_fp, "ja3s,tls_server_unsafe,"); - fprintf(csv_fp, "ssh_client_hassh,ssh_server_hassh"); + fprintf(csv_fp, "ssh_client_hassh,ssh_server_hassh,flow_info"); /* Joy */ if(enable_joy_stats) { @@ -1083,7 +1083,7 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa fprintf(csv_fp, "%u,%u,", flow->c_to_s_init_win, flow->s_to_c_init_win); fprintf(csv_fp, "%s,%s,", - (flow->ssh_tls.client_info[0] != '\0') ? flow->ssh_tls.client_info : "", + (flow->ssh_tls.client_requested_server_name[0] != '\0') ? flow->ssh_tls.client_requested_server_name : "", (flow->ssh_tls.server_info[0] != '\0') ? flow->ssh_tls.server_info : ""); fprintf(csv_fp, "%s,%s,%s,", @@ -1099,6 +1099,8 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa (flow->ssh_tls.client_hassh[0] != '\0') ? flow->ssh_tls.client_hassh : "", (flow->ssh_tls.server_hassh[0] != '\0') ? flow->ssh_tls.server_hassh : "" ); + + fprintf(csv_fp, ",%s", flow->info); } if((verbose != 1) && (verbose != 2)) { @@ -1205,13 +1207,15 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa flow->http.content_type, flow->http.user_agent); if(flow->ssh_tls.ssl_version != 0) fprintf(out, "[%s]", ndpi_ssl_version2str(flow->ssh_tls.ssl_version, &known_tls)); - if(flow->ssh_tls.client_info[0] != '\0') fprintf(out, "[Client: %s]", flow->ssh_tls.client_info); + if(flow->ssh_tls.client_requested_server_name[0] != '\0') fprintf(out, "[Client: %s]", flow->ssh_tls.client_requested_server_name); if(flow->ssh_tls.client_hassh[0] != '\0') fprintf(out, "[HASSH-C: %s]", flow->ssh_tls.client_hassh); if(flow->ssh_tls.ja3_client[0] != '\0') fprintf(out, "[JA3C: %s%s]", flow->ssh_tls.ja3_client, print_cipher(flow->ssh_tls.client_unsafe_cipher)); if(flow->ssh_tls.server_info[0] != '\0') fprintf(out, "[Server: %s]", flow->ssh_tls.server_info); + + if(flow->ssh_tls.server_names) fprintf(out, "[ServerNames: %s]", flow->ssh_tls.server_names); if(flow->ssh_tls.server_hassh[0] != '\0') fprintf(out, "[HASSH-S: %s]", flow->ssh_tls.server_hassh); if(flow->ssh_tls.ja3_server[0] != '\0') fprintf(out, "[JA3S: %s%s]", flow->ssh_tls.ja3_server, @@ -1220,11 +1224,7 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa if((flow->detected_protocol.master_protocol == NDPI_PROTOCOL_TLS) || (flow->detected_protocol.app_protocol == NDPI_PROTOCOL_TLS)) { - if((flow->ssh_tls.sha1_cert_fingerprint[0] == 0) - && (flow->ssh_tls.sha1_cert_fingerprint[1] == 0) - && (flow->ssh_tls.sha1_cert_fingerprint[2] == 0)) - ; /* Looks empty */ - else { + if(flow->ssh_tls.sha1_cert_fingerprint_set) { fprintf(out, "[Certificate SHA-1: "); for(i=0; i<20; i++) fprintf(out, "%s%02X", (i > 0) ? ":" : "", @@ -2049,7 +2049,7 @@ static void printFlowsStats() { newHost->host_server_info_hasht = NULL; newHost->ip_string = all_flows[i].flow->src_name; newHost->ip = all_flows[i].flow->src_ip; - newHost->dns_name = all_flows[i].flow->ssh_tls.client_info; + newHost->dns_name = all_flows[i].flow->ssh_tls.client_requested_server_name; ndpi_ja3_info *newJA3 = malloc(sizeof(ndpi_ja3_info)); newJA3->ja3 = all_flows[i].flow->ssh_tls.ja3_client; @@ -2082,7 +2082,7 @@ static void printFlowsStats() { newHost->ip = all_flows[i].flow->src_ip; newHost->ip_string = all_flows[i].flow->src_name; - newHost->dns_name = all_flows[i].flow->ssh_tls.client_info;; + newHost->dns_name = all_flows[i].flow->ssh_tls.client_requested_server_name;; ndpi_ja3_fingerprints_host *newElement = malloc(sizeof(ndpi_ja3_fingerprints_host)); newElement->ja3 = all_flows[i].flow->ssh_tls.ja3_client; @@ -2099,7 +2099,7 @@ static void printFlowsStats() { ndpi_ip_dns *newInnerElement = malloc(sizeof(ndpi_ip_dns)); newInnerElement->ip = all_flows[i].flow->src_ip; newInnerElement->ip_string = all_flows[i].flow->src_name; - newInnerElement->dns_name = all_flows[i].flow->ssh_tls.client_info; + newInnerElement->dns_name = all_flows[i].flow->ssh_tls.client_requested_server_name; HASH_ADD_INT(hostByJA3Found->ipToDNS_ht, ip, newInnerElement); } } diff --git a/example/reader_util.c b/example/reader_util.c index 1d19e8b41..b8fce9632 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -306,8 +306,6 @@ void ndpi_report_payload_stats() { } } - - /* ***************************************************** */ void ndpi_free_flow_info_half(struct ndpi_flow_info *flow) { @@ -457,9 +455,12 @@ void ndpi_flow_info_freer(void *node) { struct ndpi_flow_info *flow = (struct ndpi_flow_info*)node; ndpi_free_flow_info_half(flow); - ndpi_free_flow_data_analysis(flow); + if(flow->ssh_tls.server_names) { + ndpi_free(flow->ssh_tls.server_names); flow->ssh_tls.server_names = NULL; + } + ndpi_free(flow); } @@ -548,7 +549,7 @@ ndpi_flow_update_byte_count(struct ndpi_flow_info *flow, const void *x, if((flow->entropy.src2dst_pkt_count+flow->entropy.dst2src_pkt_count) <= max_num_packets_per_flow) { /* octet count was already incremented before processing this payload */ u_int32_t current_count; - + if(src_to_dst_direction) { current_count = flow->entropy.src2dst_l4_bytes - len; } else { @@ -558,7 +559,7 @@ ndpi_flow_update_byte_count(struct ndpi_flow_info *flow, const void *x, if(current_count < ETTA_MIN_OCTETS) { u_int32_t i; const unsigned char *data = x; - + for(i=0; i<len; i++) { if(src_to_dst_direction) { flow->entropy.src2dst_byte_count[data[i]]++; @@ -590,10 +591,10 @@ ndpi_flow_update_byte_dist_mean_var(ndpi_flow_info_t *flow, const void *x, if((flow->entropy.src2dst_pkt_count+flow->entropy.dst2src_pkt_count) <= max_num_packets_per_flow) { unsigned int i; - + for(i=0; i<len; i++) { double delta; - + if(src_to_dst_direction) { flow->entropy.src2dst_num_bytes += 1; delta = ((double)data[i] - flow->entropy.src2dst_bd_mean); @@ -617,9 +618,9 @@ float ndpi_flow_get_byte_count_entropy(const uint32_t byte_count[256], int i; float sum = 0.0; - for(i=0; i<256; i++) { + for(i=0; i<256; i++) { float tmp = (float) byte_count[i] / (float) num_bytes; - + if(tmp > FLT_EPSILON) { sum -= tmp * logf(tmp); } @@ -687,7 +688,7 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow workflow->stats.packet_len[4]++; else if(l4_packet_len >= 1500) workflow->stats.packet_len[5]++; - + if(l4_packet_len > workflow->stats.max_packet_len) workflow->stats.max_packet_len = l4_packet_len; @@ -885,7 +886,7 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow rflow->entropy.dst2src_opackets++; } } - + return(rflow); } } @@ -993,6 +994,15 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl } else if(flow->ndpi_flow->protos.kerberos.domain[0] != '\0') snprintf(flow->info, sizeof(flow->info), "%s", flow->ndpi_flow->protos.kerberos.domain); + +#if 0 + if(flow->info[0] != '\0') + printf("->> (%d) [%s][%s][%s]<<--\n", + htons(flow->src_port), + flow->ndpi_flow->protos.kerberos.domain, + flow->ndpi_flow->protos.kerberos.hostname, + flow->ndpi_flow->protos.kerberos.username); +#endif } /* HTTP */ else if((flow->detected_protocol.master_protocol == NDPI_PROTOCOL_HTTP) @@ -1007,7 +1017,8 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl snprintf(flow->telnet.username, sizeof(flow->telnet.username), "%s", flow->ndpi_flow->protos.telnet.username); snprintf(flow->telnet.password, sizeof(flow->telnet.password), "%s", flow->ndpi_flow->protos.telnet.password); } else if(is_ndpi_proto(flow, NDPI_PROTOCOL_SSH)) { - snprintf(flow->ssh_tls.client_info, sizeof(flow->ssh_tls.client_info), "%s", + snprintf(flow->ssh_tls.client_requested_server_name, + sizeof(flow->ssh_tls.client_requested_server_name), "%s", flow->ndpi_flow->protos.ssh.client_signature); snprintf(flow->ssh_tls.server_info, sizeof(flow->ssh_tls.server_info), "%s", flow->ndpi_flow->protos.ssh.server_signature); @@ -1022,10 +1033,12 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl || (flow->ndpi_flow->protos.stun_ssl.ssl.ja3_client[0] != '\0') ) { flow->ssh_tls.ssl_version = flow->ndpi_flow->protos.stun_ssl.ssl.ssl_version; - snprintf(flow->ssh_tls.client_info, sizeof(flow->ssh_tls.client_info), "%s", - flow->ndpi_flow->protos.stun_ssl.ssl.client_certificate); - snprintf(flow->ssh_tls.server_info, sizeof(flow->ssh_tls.server_info), "%s", - flow->ndpi_flow->protos.stun_ssl.ssl.server_certificate); + snprintf(flow->ssh_tls.client_requested_server_name, + sizeof(flow->ssh_tls.client_requested_server_name), "%s", + flow->ndpi_flow->protos.stun_ssl.ssl.client_requested_server_name); + + if(flow->ndpi_flow->protos.stun_ssl.ssl.server_names_len > 0) + flow->ssh_tls.server_names = ndpi_strdup(flow->ndpi_flow->protos.stun_ssl.ssl.server_names); snprintf(flow->ssh_tls.server_organization, sizeof(flow->ssh_tls.server_organization), "%s", flow->ndpi_flow->protos.stun_ssl.ssl.server_organization); flow->ssh_tls.notBefore = flow->ndpi_flow->protos.stun_ssl.ssl.notBefore; @@ -1036,9 +1049,13 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl flow->ndpi_flow->protos.stun_ssl.ssl.ja3_server); flow->ssh_tls.server_unsafe_cipher = flow->ndpi_flow->protos.stun_ssl.ssl.server_unsafe_cipher; flow->ssh_tls.server_cipher = flow->ndpi_flow->protos.stun_ssl.ssl.server_cipher; - memcpy(flow->ssh_tls.sha1_cert_fingerprint, - flow->ndpi_flow->l4.tcp.tls_sha1_certificate_fingerprint, 20); - } + + if(flow->ndpi_flow->l4.tcp.tls.fingerprint_set) { + memcpy(flow->ssh_tls.sha1_cert_fingerprint, + flow->ndpi_flow->l4.tcp.tls.sha1_certificate_fingerprint, 20); + flow->ssh_tls.sha1_cert_fingerprint_set = 1; + } + } if(flow->detection_completed && (!flow->check_extra_packets)) { if(is_ndpi_proto(flow, NDPI_PROTOCOL_UNKNOWN)) { @@ -1169,7 +1186,7 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, if(flow->entropy.flow_last_pkt_time.tv_sec) { ndpi_timer_sub(&when, &flow->entropy.flow_last_pkt_time, &tdiff); - + if(flow->iat_flow && (tdiff.tv_sec >= 0) /* Discard backward time */ ) { @@ -1186,7 +1203,7 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, ndpi_timer_sub(&when, &flow->entropy.src2dst_last_pkt_time, &tdiff); if(flow->iat_c_to_s - && (tdiff.tv_sec >= 0) /* Discard backward time */ + && (tdiff.tv_sec >= 0) /* Discard backward time */ ) { u_int32_t ms = ndpi_timeval_to_milliseconds(tdiff); @@ -1291,11 +1308,11 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, u_int enough_packets = (((proto == IPPROTO_UDP) && ((flow->src2dst_packets + flow->dst2src_packets) > max_num_udp_dissected_pkts)) || ((proto == IPPROTO_TCP) && ((flow->src2dst_packets + flow->dst2src_packets) > max_num_tcp_dissected_pkts))) ? 1 : 0; - + #if 0 - printf("%s()\n", __FUNCTION__); + printf("%s()\n", __FUNCTION__); #endif - + flow->detected_protocol = ndpi_detection_process_packet(workflow->ndpi_struct, ndpi_flow, iph ? (uint8_t *)iph : (uint8_t *)iph6, ipsize, time, src, dst); @@ -1313,14 +1330,14 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, if(ndpi_flow && ndpi_flow->check_extra_packets) flow->check_extra_packets = 1; #endif - + if(flow->detected_protocol.app_protocol == NDPI_PROTOCOL_UNKNOWN) { u_int8_t proto_guessed; - + flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow, enable_protocol_guess, &proto_guessed); } - + process_ndpi_collected_info(workflow, flow); } } @@ -1363,7 +1380,7 @@ struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow, struct ndpi_proto nproto = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; ndpi_packet_tunnel tunnel_type = ndpi_no_tunnel; - + /* lengths and offsets */ u_int16_t eth_offset = 0; u_int16_t radio_len; @@ -1512,7 +1529,7 @@ ether_type_check: type = (packet[ip_offset+2] << 8) + packet[ip_offset+3]; ip_offset += 4; vlan_packet = 1; - + // double tagging for 802.1Q while((type == 0x8100) && (ip_offset < (u_int16_t)header->caplen)) { vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF; @@ -1521,7 +1538,7 @@ ether_type_check: } recheck_type = 1; break; - + case MPLS_UNI: case MPLS_MULTI: mpls.u32 = *((uint32_t *) &packet[ip_offset]); @@ -1536,21 +1553,21 @@ ether_type_check: } recheck_type = 1; break; - + case PPPoE: workflow->stats.pppoe_count++; type = ETH_P_IP; ip_offset += 8; recheck_type = 1; break; - + default: break; } - + if(recheck_type) goto ether_type_check; - + workflow->stats.vlan_count += vlan_packet; iph_check: @@ -1632,7 +1649,7 @@ ether_type_check: u_int8_t message_type = packet[offset+1]; tunnel_type = ndpi_gtp_tunnel; - + if((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) && (message_type == 0xFF /* T-PDU */)) { @@ -1656,7 +1673,7 @@ ether_type_check: u_int16_t encapsulates = ntohs(*((u_int16_t*)&packet[offset+2])); tunnel_type = ndpi_tzsp_tunnel; - + if((version == 1) && (ts_type == 0) && (encapsulates == 1)) { u_int8_t stop = 0; @@ -1694,7 +1711,7 @@ ether_type_check: if((offset+40) < header->caplen) { u_int16_t msg_len = packet[offset+1] >> 1; - + offset += msg_len; if(packet[offset] == 0x02) { diff --git a/example/reader_util.h b/example/reader_util.h index c420ca211..55c260a54 100644 --- a/example/reader_util.h +++ b/example/reader_util.h @@ -94,7 +94,7 @@ typedef struct ndpi_ja3_info { // external hash table (host ip -> <ip string, hash table ja3c, hash table ja3s>) // used to aggregate ja3 fingerprints by hosts -typedef struct ndpi_host_ja3_fingerprints{ +typedef struct ndpi_host_ja3_fingerprints { u_int32_t ip; char *ip_string; char *dns_name; @@ -195,11 +195,12 @@ typedef struct ndpi_flow_info { struct { u_int16_t ssl_version; - char client_info[64], server_info[64], - client_hassh[33], server_hassh[33], + char client_requested_server_name[64], server_info[64], + client_hassh[33], server_hassh[33], *server_names, server_organization[64], ja3_client[33], ja3_server[33], sha1_cert_fingerprint[20]; + u_int8_t sha1_cert_fingerprint_set; time_t notBefore, notAfter; u_int16_t server_cipher; ndpi_cipher_weakness client_unsafe_cipher, server_unsafe_cipher; |