From f965983c23e1c9fc4dbbd294bc39217660f7169b Mon Sep 17 00:00:00 2001 From: Nardi Ivan Date: Tue, 21 Apr 2020 20:43:29 +0200 Subject: Add basic support for some ip-in-ip tunnels Add support for 4in4, 6in6 and 4in6 encapsulations Add support for ipv6 traffic in gtp tunnels, too To allow gtp unit test, gtp detunneling flag has been globally enabled in the test suite --- example/reader_util.c | 22 ++++++++++++++++------ tests/do.sh | 4 ++-- tests/pcap/4in4tunnel.pcap | Bin 0 -> 954 bytes tests/pcap/4in6tunnel.pcap | Bin 0 -> 2276 bytes tests/pcap/6in6tunnel.pcap | Bin 0 -> 268 bytes tests/pcap/ipv6_in_gtp.pcap | Bin 0 -> 372 bytes tests/result/4in4tunnel.pcap.out | 6 ++++++ tests/result/4in6tunnel.pcap.out | 8 ++++++++ tests/result/6in6tunnel.pcap.out | 6 ++++++ tests/result/capwap.pcap.out | 4 ++-- tests/result/ipv6_in_gtp.pcap.out | 8 ++++++++ 11 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 tests/pcap/4in4tunnel.pcap create mode 100644 tests/pcap/4in6tunnel.pcap create mode 100644 tests/pcap/6in6tunnel.pcap create mode 100644 tests/pcap/ipv6_in_gtp.pcap create mode 100644 tests/result/4in4tunnel.pcap.out create mode 100644 tests/result/4in6tunnel.pcap.out create mode 100644 tests/result/6in6tunnel.pcap.out create mode 100644 tests/result/ipv6_in_gtp.pcap.out diff --git a/example/reader_util.c b/example/reader_util.c index dbce3636e..eeddeab61 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -1675,7 +1675,7 @@ struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow, ip_len = ((u_int16_t)iph->ihl * 4); iph6 = NULL; - if(iph->protocol == IPPROTO_IPV6) { + if(iph->protocol == IPPROTO_IPV6 || iph->protocol == IPPROTO_IPIP) { ip_offset += ip_len; if(ip_len > 0) goto iph_check; @@ -1707,6 +1707,12 @@ struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow, if(ndpi_handle_ipv6_extension_headers(NULL, &l4ptr, &ip_len, &proto) != 0) { return(nproto); } + if(proto == IPPROTO_IPV6 || proto == IPPROTO_IPIP) { + if(l4ptr > packet) { /* Better safe than sorry */ + ip_offset = (l4ptr - packet); + goto iph_check; + } + } iph = NULL; } else { @@ -1746,11 +1752,15 @@ struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow, if(flags & 0x02) ip_offset += 4; /* sequence_number is present (it also includes next_ext_header and pdu_number) */ if(flags & 0x01) ip_offset += 1; /* pdu_number is present */ - iph = (struct ndpi_iphdr *) &packet[ip_offset]; - - if(iph->version != IPVERSION) { - // printf("WARNING: not good (packet_id=%u)!\n", (unsigned int)workflow->stats.raw_packet_count); - goto v4_warning; + if(ip_offset < header->caplen) { + iph = (struct ndpi_iphdr *)&packet[ip_offset]; + if(iph->version == 6) { + iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset]; + iph = NULL; + } else if(iph->version != IPVERSION) { + // printf("WARNING: not good (packet_id=%u)!\n", (unsigned int)workflow->stats.raw_packet_count); + goto v4_warning; + } } } } else if((sport == TZSP_PORT) || (dport == TZSP_PORT)) { diff --git a/tests/do.sh b/tests/do.sh index 5c7ea452e..78e6216d9 100755 --- a/tests/do.sh +++ b/tests/do.sh @@ -10,7 +10,7 @@ build_results() { #echo $f # create result files if not present if [ ! -f result/$f.out ]; then - CMD="$READER -q -i pcap/$f -w result/$f.out -v 2" + CMD="$READER -q -t -i pcap/$f -w result/$f.out -v 2" $CMD fi # test fuzz target built with sanitizer on input from corpus @@ -23,7 +23,7 @@ build_results() { check_results() { for f in $PCAPS; do if [ -f result/$f.out ]; then - CMD="$READER -q -i pcap/$f -w /tmp/reader.out -v 2" + CMD="$READER -q -t -i pcap/$f -w /tmp/reader.out -v 2" $CMD NUM_DIFF=`diff result/$f.out /tmp/reader.out | wc -l` diff --git a/tests/pcap/4in4tunnel.pcap b/tests/pcap/4in4tunnel.pcap new file mode 100644 index 000000000..769ab66fb Binary files /dev/null and b/tests/pcap/4in4tunnel.pcap differ diff --git a/tests/pcap/4in6tunnel.pcap b/tests/pcap/4in6tunnel.pcap new file mode 100644 index 000000000..9a23cb33d Binary files /dev/null and b/tests/pcap/4in6tunnel.pcap differ diff --git a/tests/pcap/6in6tunnel.pcap b/tests/pcap/6in6tunnel.pcap new file mode 100644 index 000000000..c5838fd13 Binary files /dev/null and b/tests/pcap/6in6tunnel.pcap differ diff --git a/tests/pcap/ipv6_in_gtp.pcap b/tests/pcap/ipv6_in_gtp.pcap new file mode 100644 index 000000000..336fc49fc Binary files /dev/null and b/tests/pcap/ipv6_in_gtp.pcap differ diff --git a/tests/result/4in4tunnel.pcap.out b/tests/result/4in4tunnel.pcap.out new file mode 100644 index 000000000..1447acf69 --- /dev/null +++ b/tests/result/4in4tunnel.pcap.out @@ -0,0 +1,6 @@ +Unknown 5 850 1 + + + +Undetected flows: + 1 UDP 10.10.100.25:62367 -> 10.10.101.2:17000 [VLAN: 505][proto: 0/Unknown][5 pkts/850 bytes -> 0 pkts/0 bytes][Goodput ratio: 59/0][121572.07 sec] diff --git a/tests/result/4in6tunnel.pcap.out b/tests/result/4in6tunnel.pcap.out new file mode 100644 index 000000000..acea404c3 --- /dev/null +++ b/tests/result/4in6tunnel.pcap.out @@ -0,0 +1,8 @@ +Microsoft 4 2188 1 + +JA3 Host Stats: + IP Address # JA3C + 1 192.168.0.1 1 + + + 1 TCP 192.168.0.1:64455 <-> 10.10.10.1:443 [proto: 91.212/TLS.Microsoft][cat: Web/5][2 pkts/520 bytes <-> 2 pkts/1668 bytes][Goodput ratio: 43/82][< 1 sec][ALPN: h2;http/1.1][TLSv1.2][Client: www.bing.com][JA3C: 9e10692f1b7f78228b2d4e424db3a98c] diff --git a/tests/result/6in6tunnel.pcap.out b/tests/result/6in6tunnel.pcap.out new file mode 100644 index 000000000..2e4d484eb --- /dev/null +++ b/tests/result/6in6tunnel.pcap.out @@ -0,0 +1,6 @@ +Unknown 2 212 1 + + + +Undetected flows: + 1 UDP [dead::beef]:30000 -> [cafe::babe]:13000 [proto: 0/Unknown][2 pkts/212 bytes -> 0 pkts/0 bytes][Goodput ratio: 4/0][0.00 sec] diff --git a/tests/result/capwap.pcap.out b/tests/result/capwap.pcap.out index 5a500f679..aa52b65cc 100644 --- a/tests/result/capwap.pcap.out +++ b/tests/result/capwap.pcap.out @@ -1,8 +1,8 @@ DNS 2 166 1 -CAPWAP 395 98343 4 +CAPWAP 393 98074 4 1 UDP 192.168.10.9:5246 <-> 192.168.10.10:12380 [proto: 247/CAPWAP][cat: Network/14][106 pkts/26144 bytes <-> 111 pkts/37530 bytes][Goodput ratio: 83/88][169.10 sec][bytes ratio: -0.179 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 1421/1619 21349/21721 3881/4475][Pkt Len c2s/s2c min/avg/max/stddev: 106/115 247/338 1499/1499 292/381][PLAIN TEXT (Cisco Systems)] - 2 UDP 192.168.10.10:12380 <-> 192.168.10.9:5247 [proto: 247/CAPWAP][cat: Network/14][170 pkts/33465 bytes <-> 3 pkts/437 bytes][Goodput ratio: 79/71][157.99 sec][bytes ratio: 0.974 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 964/0 3999/0 858/0][Pkt Len c2s/s2c min/avg/max/stddev: 93/125 197/146 470/168 78/18] + 2 UDP 192.168.10.10:12380 <-> 192.168.10.9:5247 [proto: 247/CAPWAP][cat: Network/14][170 pkts/33465 bytes <-> 1 pkts/168 bytes][Goodput ratio: 79/75][157.99 sec][bytes ratio: 0.990 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 961/0 3999/0 859/0][Pkt Len c2s/s2c min/avg/max/stddev: 93/168 197/168 470/168 78/0] 3 UDP 192.168.10.10:12380 -> 255.255.255.255:5246 [proto: 247/CAPWAP][cat: Network/14][4 pkts/660 bytes -> 0 pkts/0 bytes][Goodput ratio: 74/0][130.41 sec][PLAIN TEXT (838.61f)] 4 UDP 192.168.10.10:49259 -> 255.255.255.255:53 [proto: 5/DNS][cat: Network/14][2 pkts/166 bytes -> 0 pkts/0 bytes][Goodput ratio: 49/0][3.00 sec][Host: cisco-capwap-controller][::][PLAIN TEXT (CAPWAP)] 5 UDP 192.168.10.9:5246 -> 192.168.10.10:12379 [proto: 247/CAPWAP][cat: Network/14][1 pkts/107 bytes -> 0 pkts/0 bytes][Goodput ratio: 60/0][< 1 sec] diff --git a/tests/result/ipv6_in_gtp.pcap.out b/tests/result/ipv6_in_gtp.pcap.out new file mode 100644 index 000000000..064b1103d --- /dev/null +++ b/tests/result/ipv6_in_gtp.pcap.out @@ -0,0 +1,8 @@ +Unknown 1 150 1 +IPsec 1 166 1 + + 1 50 [2a01:4c8:c014:144e:1:2:945b:6761]:0 -> [2a01:4c8:f000:f49::4]:0 [VLAN: 2][proto: GTP:79/IPsec][cat: VPN/2][1 pkts/166 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec] + + +Undetected flows: + 1 UDP [2607:fc20:4052:39e:490a:ea4d:17fe:e09c]:49120 -> [fd00:976a:bc67:193e::7]:25658 [VLAN: 5][proto: GTP:0/Unknown][1 pkts/150 bytes -> 0 pkts/0 bytes][Goodput ratio: 29/0][< 1 sec] -- cgit v1.2.3 From c2ebbb15add2a307458f32a47ea690150927e500 Mon Sep 17 00:00:00 2001 From: Nardi Ivan Date: Thu, 23 Apr 2020 14:24:49 +0200 Subject: Fix "division by zero" runtime error --- example/ndpiReader.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/example/ndpiReader.c b/example/ndpiReader.c index f15ee0e66..2818c2c41 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -2519,9 +2519,13 @@ static void printResults(u_int64_t processing_time_usec, u_int64_t setup_time_us else traffic_duration = (pcap_end.tv_sec*1000000 + pcap_end.tv_usec) - (pcap_start.tv_sec*1000000 + pcap_start.tv_usec); printf("\tnDPI throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); - t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)traffic_duration; - b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)traffic_duration; - + if(traffic_duration != 0) { + t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)traffic_duration; + b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)traffic_duration; + } else { + t = 0; + b = 0; + } strftime(when, sizeof(when), "%d/%b/%Y %H:%M:%S", localtime_r(&pcap_start.tv_sec, &result)); printf("\tAnalysis begin: %s\n", when); strftime(when, sizeof(when), "%d/%b/%Y %H:%M:%S", localtime_r(&pcap_end.tv_sec, &result)); -- cgit v1.2.3 From 097127c31d028bb8abae8d3aa8edcc367f17bfba Mon Sep 17 00:00:00 2001 From: Nardi Ivan Date: Fri, 24 Apr 2020 10:42:52 +0200 Subject: Fix heap-overflow error in CAPWAP detunneling code --- example/reader_util.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/example/reader_util.c b/example/reader_util.c index eeddeab61..3c1af8397 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -1810,22 +1810,26 @@ struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow, /* We dissect ONLY CAPWAP traffic */ u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr); - if((offset+40) < header->caplen) { - u_int16_t msg_len = packet[offset+1] >> 1; + if((offset+1) < header->caplen) { + uint8_t preamble = packet[offset]; - offset += msg_len; + if((preamble & 0x0F) == 0) { /* CAPWAP header */ + u_int16_t msg_len = (packet[offset+1] & 0xF8) >> 1; - if(packet[offset] == 0x02) { - /* IEEE 802.11 Data */ + offset += msg_len; - offset += 24; - /* LLC header is 8 bytes */ - type = ntohs((u_int16_t)*((u_int16_t*)&packet[offset+6])); + if((offset + 32 < header->caplen) && (packet[offset] == 0x02)) { + /* IEEE 802.11 Data */ - ip_offset = offset + 8; + offset += 24; + /* LLC header is 8 bytes */ + type = ntohs((u_int16_t)*((u_int16_t*)&packet[offset+6])); - tunnel_type = ndpi_capwap_tunnel; - goto iph_check; + ip_offset = offset + 8; + + tunnel_type = ndpi_capwap_tunnel; + goto iph_check; + } } } } -- cgit v1.2.3