aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Makefile.in3
-rw-r--r--src/lib/ndpi_content_match.c.inc300
-rw-r--r--src/lib/ndpi_main.c201
-rw-r--r--src/lib/protocols/btlib.c5
-rw-r--r--src/lib/protocols/coap.c2
-rw-r--r--src/lib/protocols/csgo.c5
-rw-r--r--src/lib/protocols/directconnect.c1
-rw-r--r--src/lib/protocols/dns.c4
-rw-r--r--src/lib/protocols/dropbox.c10
-rw-r--r--src/lib/protocols/edonkey.c3
-rw-r--r--src/lib/protocols/ftp_data.c4
-rw-r--r--src/lib/protocols/gnutella.c1
-rw-r--r--src/lib/protocols/http.c2
-rw-r--r--src/lib/protocols/icecast.c2
-rw-r--r--src/lib/protocols/mail_smtp.c7
-rw-r--r--src/lib/protocols/memcached.c3
-rw-r--r--src/lib/protocols/mysql.c52
-rw-r--r--src/lib/protocols/sip.c22
-rw-r--r--src/lib/protocols/ssl.c682
19 files changed, 1068 insertions, 241 deletions
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
index cadd65ddd..65934502d 100644
--- a/src/lib/Makefile.in
+++ b/src/lib/Makefile.in
@@ -58,6 +58,9 @@ clean:
distclean: clean
/bin/rm -f Makefile
+cppcheck:
+ cppcheck --template='{file}:{line}:{severity}:{message}' --quiet --enable=all --force -I ../include *.c protocols/*.c
+
install: $(NDPI_LIBS)
mkdir -p $(DESTDIR)$(libdir)
cp $(NDPI_LIBS) $(DESTDIR)$(libdir)/
diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc
index a060182d8..537b41b5e 100644
--- a/src/lib/ndpi_content_match.c.inc
+++ b/src/lib/ndpi_content_match.c.inc
@@ -79,34 +79,295 @@ static ndpi_network host_protocol_list[] = {
/*
WhatsApp Inc.
+ List of the WhatsApp server IP addresses and ranges (https://developers.facebook.com/docs/whatsapp/network-debugging/ Dec 21, 2018)
*/
- { 0x1F0D4B00 /* 31.13.75.0/24 */, 24, NDPI_PROTOCOL_WHATSAPP },
- { 0x1F0D5600 /* 31.13.86.0/24 */, 24, NDPI_PROTOCOL_WHATSAPP },
- { 0x3216C6CC /* 50.22.198.204/30 */, 30, NDPI_PROTOCOL_WHATSAPP },
- { 0x4B7E2720 /* 75.126.39.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x6CA8AE00 /* 108.168.174.0/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x6CA8B0C0 /* 108.168.176.192/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0x6CA8B100 /* 108.168.177.0/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
{ 0x6CA8B460 /* 108.168.180.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
- { 0x9E553A00 /* 158.85.58.0/25 */, 25, NDPI_PROTOCOL_WHATSAPP },
- { 0x9E55FE40 /* 158.85.254.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
- { 0xA92C5360 /* 169.44.82.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x6CA8FE41 /* 108.168.254.65/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x6CA8FFE0 /* 108.168.255.224/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x6CA8FFE3 /* 108.168.255.227/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00135 /* 157.240.1.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00136 /* 157.240.1.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00A35 /* 157.240.10.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00A36 /* 157.240.10.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00B35 /* 157.240.11.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00B36 /* 157.240.11.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00C35 /* 157.240.12.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00C36 /* 157.240.12.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00D36 /* 157.240.13.54/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00E34 /* 157.240.14.52/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00F35 /* 157.240.15.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00F36 /* 157.240.15.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01034 /* 157.240.16.52/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01234 /* 157.240.18.52/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01335 /* 157.240.19.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01336 /* 157.240.19.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00235 /* 157.240.2.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00236 /* 157.240.2.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01434 /* 157.240.20.52/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01534 /* 157.240.21.52/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01635 /* 157.240.22.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01636 /* 157.240.22.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01735 /* 157.240.23.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01736 /* 157.240.23.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01D35 /* 157.240.29.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01D36 /* 157.240.29.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00635 /* 157.240.6.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00636 /* 157.240.6.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00735 /* 157.240.7.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00736 /* 157.240.7.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00835 /* 157.240.8.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00836 /* 157.240.8.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00935 /* 157.240.9.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00936 /* 157.240.9.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9E550060 /* 158.85.0.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9E55E0A0 /* 158.85.224.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9E55E920 /* 158.85.233.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9E55F980 /* 158.85.249.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9E55FE40 /* 158.85.254.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9E552E80 /* 158.85.46.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9E5530E0 /* 158.85.48.224/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9E5505C0 /* 158.85.5.192/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9E553A00 /* 158.85.58.0/25 */, 25, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9E553DC0 /* 158.85.61.192/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92CA700 /* 169.44.167.0/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C2400 /* 169.44.36.0/25 */, 25, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C3940 /* 169.44.57.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C3A40 /* 169.44.58.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C5000 /* 169.44.80.0/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C5280 /* 169.44.82.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C52C0 /* 169.44.82.192/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C5260 /* 169.44.82.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C5300 /* 169.44.83.0/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C5380 /* 169.44.83.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C53C0 /* 169.44.83.192/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C5360 /* 169.44.83.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C5400 /* 169.44.84.0/24 */, 24, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C5540 /* 169.44.85.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92C57A0 /* 169.44.87.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92DA9C0 /* 169.45.169.192/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92DB660 /* 169.45.182.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92DD240 /* 169.45.210.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
{ 0xA92DD6E0 /* 169.45.214.224/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
{ 0xA92DDBE0 /* 169.45.219.224/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
- { 0xA92DF860 /* 169.45.248.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
- { 0xA92F05C0 /* 169.47.5.192/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
- { 0xA92F2320 /* 169.47.35.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
- { 0xA9373CAA /* 169.55.60.170/32 */, 27, NDPI_PROTOCOL_WHATSAPP },
- { 0xA93C4F00 /* 169.60.79.0/24 */, 24, NDPI_PROTOCOL_WHATSAPP },
- { 0xA93F4C11 /* 169.63.76.0/25 */, 25, NDPI_PROTOCOL_WHATSAPP },
- { 0xA93F4940 /* 169.63.73.64/25 */, 25, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92DEDC0 /* 169.45.237.192/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92DEE20 /* 169.45.238.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92DF2C0 /* 169.45.242.192/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92DF8A0 /* 169.45.248.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92DF860 /* 169.45.248.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92D4720 /* 169.45.71.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92D4760 /* 169.45.71.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92D5780 /* 169.45.87.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92E6F90 /* 169.46.111.144/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92E34E0 /* 169.46.52.224/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F8260 /* 169.47.130.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F9100 /* 169.47.145.0/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F9980 /* 169.47.153.128/25 */, 25, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92FC0C0 /* 169.47.192.192/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92FC280 /* 169.47.194.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92FC680 /* 169.47.198.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92FD4A0 /* 169.47.212.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F2180 /* 169.47.33.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F2320 /* 169.47.35.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F2580 /* 169.47.37.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F2880 /* 169.47.40.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F2AA0 /* 169.47.42.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F2AC0 /* 169.47.42.192/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F2A60 /* 169.47.42.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F2FA0 /* 169.47.47.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F05C0 /* 169.47.5.192/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA92F0640 /* 169.47.6.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9307220 /* 169.48.114.32/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93079C0 /* 169.48.121.192/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9307A40 /* 169.48.122.64/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA930D2B0 /* 169.48.210.176/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA930D2E0 /* 169.48.210.224/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA930D340 /* 169.48.211.64/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA930D480 /* 169.48.212.128/25 */, 25, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA935FA80 /* 169.53.250.128/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA935FC40 /* 169.53.252.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA935FF40 /* 169.53.255.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9351D80 /* 169.53.29.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9353020 /* 169.53.48.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93547E0 /* 169.53.71.224/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9355140 /* 169.53.81.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA936C1A0 /* 169.54.193.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93602A0 /* 169.54.2.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA936D200 /* 169.54.210.0/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA936DE80 /* 169.54.222.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9362CE0 /* 169.54.44.224/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9363320 /* 169.54.51.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93637C0 /* 169.54.55.192/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
{ 0xA93764A0 /* 169.55.100.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9377E40 /* 169.55.126.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA937D260 /* 169.55.210.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
{ 0xA937EBA0 /* 169.55.235.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9373C94 /* 169.55.60.148/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9373CAA /* 169.55.60.170/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93743E0 /* 169.55.67.224/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9374580 /* 169.55.69.128/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9374A20 /* 169.55.74.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA9374B60 /* 169.55.75.96/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93C8180 /* 169.60.129.128/25 */, 25, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93C9300 /* 169.60.147.0/24 */, 24, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93CC540 /* 169.60.197.64/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93C4A70 /* 169.60.74.112/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93C4A80 /* 169.60.74.128/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93C4A20 /* 169.60.74.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93C4B80 /* 169.60.75.128/25 */, 25, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93C4F00 /* 169.60.79.0/24 */, 24, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93D6500 /* 169.61.101.0/24 */, 24, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93D5190 /* 169.61.81.144/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93D51E0 /* 169.61.81.224/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93D5240 /* 169.61.82.64/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93D5480 /* 169.61.84.128/25 */, 25, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93F4080 /* 169.63.64.128/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93F4920 /* 169.63.73.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93F4940 /* 169.63.73.64/26 */, 26, NDPI_PROTOCOL_WHATSAPP },
+ { 0xA93F4C00 /* 169.63.76.0/25 */, 25, NDPI_PROTOCOL_WHATSAPP },
{ 0xADC0A220 /* 173.192.162.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xADC0DB80 /* 173.192.219.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xADC0DEA0 /* 173.192.222.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xADC1E680 /* 173.193.230.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xADC1E6C0 /* 173.193.230.192/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xADC1EF00 /* 173.193.239.0/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xAE24D080 /* 174.36.208.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xAE24D220 /* 174.36.210.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xAE24FBC0 /* 174.36.251.192/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xAE25F340 /* 174.37.243.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xAE25FB00 /* 174.37.251.0/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB33CC030 /* 179.60.192.48/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB33CC031 /* 179.60.192.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB33CC033 /* 179.60.192.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB33CC134 /* 179.60.193.52/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB33CC235 /* 179.60.194.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB33CC236 /* 179.60.194.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB33CC331 /* 179.60.195.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB33CC333 /* 179.60.195.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
{ 0xB8AD8840 /* 184.173.136.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
- { 0xB93CDA35 /* 185.60.218.53/32 */, 27, NDPI_PROTOCOL_WHATSAPP },
- { 0xC60BFB20 /* 198.11.251.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB8AD9320 /* 184.173.147.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB8ADA140 /* 184.173.161.64/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB8ADAD74 /* 184.173.173.116/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB8ADB320 /* 184.173.179.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB93CD835 /* 185.60.216.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB93CD836 /* 185.60.216.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB93CD935 /* 185.60.217.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB93CD936 /* 185.60.217.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB93CDA35 /* 185.60.218.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB93CDA36 /* 185.60.218.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB93CDB35 /* 185.60.219.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB93CDB36 /* 185.60.219.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xC09BD4C0 /* 192.155.212.192/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xC60BC1B6 /* 198.11.193.182/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0xC60BFB20 /* 198.11.251.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xC6175000 /* 198.23.80.0/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
{ 0xD02B73C0 /* 208.43.115.192/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0xD02B754F /* 208.43.117.79/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
{ 0xD02B7A80 /* 208.43.122.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4033 /* 31.13.64.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4035 /* 31.13.64.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4131 /* 31.13.65.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4132 /* 31.13.65.50/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4334 /* 31.13.67.52/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4430 /* 31.13.68.48/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4434 /* 31.13.68.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D45F0 /* 31.13.69.240/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4631 /* 31.13.70.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4632 /* 31.13.70.50/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4731 /* 31.13.71.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4732 /* 31.13.71.50/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4830 /* 31.13.72.48/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4834 /* 31.13.72.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4934 /* 31.13.73.52/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4A34 /* 31.13.74.52/31 */, 31, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4B30 /* 31.13.75.48/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4B34 /* 31.13.75.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4C51 /* 31.13.76.81/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4C52 /* 31.13.76.82/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4E35 /* 31.13.78.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4E37 /* 31.13.78.55/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5030 /* 31.13.80.48/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5035 /* 31.13.80.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5130 /* 31.13.81.48/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5135 /* 31.13.81.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5233 /* 31.13.82.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5237 /* 31.13.82.55/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5331 /* 31.13.83.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5333 /* 31.13.83.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5431 /* 31.13.84.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5433 /* 31.13.84.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5531 /* 31.13.85.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5533 /* 31.13.85.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5631 /* 31.13.86.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5633 /* 31.13.86.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5730 /* 31.13.87.48/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5733 /* 31.13.87.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5831 /* 31.13.88.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5834 /* 31.13.88.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5935 /* 31.13.89.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5936 /* 31.13.89.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5A31 /* 31.13.90.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5A33 /* 31.13.90.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5B31 /* 31.13.91.49/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5B33 /* 31.13.91.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5C30 /* 31.13.92.48/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5C34 /* 31.13.92.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5D35 /* 31.13.93.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5D36 /* 31.13.93.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5E34 /* 31.13.94.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5E36 /* 31.13.94.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5F32 /* 31.13.95.50/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D5F3F /* 31.13.95.63/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x3216C6CC /* 50.22.198.204/30 */, 30, NDPI_PROTOCOL_WHATSAPP },
+ { 0x3216D280 /* 50.22.210.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x3216D220 /* 50.22.210.32/30 */, 30, NDPI_PROTOCOL_WHATSAPP },
+ { 0x3216E140 /* 50.22.225.64/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x3216EBF8 /* 50.22.235.248/30 */, 30, NDPI_PROTOCOL_WHATSAPP },
+ { 0x3216F0A0 /* 50.22.240.160/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x32175A80 /* 50.23.90.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x32613980 /* 50.97.57.128/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x4B7E0C70 /* 75.126.12.112/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0x4B7E7B40 /* 75.126.123.64/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0x4B7E8AA0 /* 75.126.138.160/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0x4B7E8D50 /* 75.126.141.80/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0x4B7E1430 /* 75.126.20.48/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0x4B7E2720 /* 75.126.39.32/27 */, 27, NDPI_PROTOCOL_WHATSAPP },
+ { 0x4B7E51C0 /* 75.126.81.192/28 */, 28, NDPI_PROTOCOL_WHATSAPP },
+ { 0x66846036 /* 102.132.96.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x66846136 /* 102.132.97.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00D36 /* 157.240.13.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00E34 /* 157.240.14.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01034 /* 157.240.16.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01234 /* 157.240.18.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF0C034 /* 157.240.192.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF0C132 /* 157.240.193.50/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF0C236 /* 157.240.194.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01434 /* 157.240.20.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01533 /* 157.240.21.51/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01534 /* 157.240.21.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01836 /* 157.240.24.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01936 /* 157.240.25.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01A36 /* 157.240.26.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01B36 /* 157.240.27.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF00336 /* 157.240.3.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x9DF01E36 /* 157.240.30.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0xB33CC134 /* 179.60.193.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4238 /* 31.13.66.56/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4334 /* 31.13.67.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4934 /* 31.13.73.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4A34 /* 31.13.74.52/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
+ { 0x1F0D4F35 /* 31.13.79.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP },
/* Files */
- { 0xB93CD835 /* 185.60.216.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP_FILES },
+ { 0xB93CD835 /* 185.60.216.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP_FILES },
+ { 0xB93CD836 /* 185.60.216.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP_FILES },
+ { 0xB93CD935 /* 185.60.217.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP_FILES },
+ { 0xB93CD936 /* 185.60.217.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP_FILES },
+ { 0xB93CDA35 /* 185.60.218.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP_FILES },
+ { 0xB93CDA36 /* 185.60.218.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP_FILES },
+ { 0xB93CDB35 /* 185.60.219.53/32 */, 32, NDPI_PROTOCOL_WHATSAPP_FILES },
+ { 0xB93CDB36 /* 185.60.219.54/32 */, 32, NDPI_PROTOCOL_WHATSAPP_FILES },
/*
WeChat
@@ -661,7 +922,12 @@ static ndpi_network host_protocol_list[] = {
{ 0x022E8A340 /* 34.232.163.64/28 */, 28, NDPI_PROTOCOL_VIBER },
{ 0x022F67200 /* 34.246.114.0/23 */, 23, NDPI_PROTOCOL_VIBER },
{ 0x3400FC00 /* 52.0.252.0/22 */, 22, NDPI_PROTOCOL_VIBER },
+ { 0x3403A746 /* 52.3.167.70/32 */, 32, NDPI_PROTOCOL_VIBER },
+ { 0x34162CEB /* 52.22.44.235/32 */, 32, NDPI_PROTOCOL_VIBER },
+ { 0x34165F0F /* 52.22.95.15/32 */, 32, NDPI_PROTOCOL_VIBER },
{ 0x3640BFF0 /* 54.64.191.240/28 */, 28, NDPI_PROTOCOL_VIBER },
+ { 0x3655545D /* 54.85.84.93/32 */, 32, NDPI_PROTOCOL_VIBER },
+ { 0x3655565D /* 54.85.86.93/32 */, 32, NDPI_PROTOCOL_VIBER },
{ 0x36A5FFD0 /* 54.165.255.208/28 */, 28, NDPI_PROTOCOL_VIBER },
{ 0x36A5FFE0 /* 54.165.255.224/27 */, 27, NDPI_PROTOCOL_VIBER },
{ 0x36DBBFA0 /* 54.219.191.160/28 */, 28, NDPI_PROTOCOL_VIBER },
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index e18c220a5..7a954a710 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -423,7 +423,8 @@ static const char* categories[] = {
"Malware",
"Advertisement",
"Banned_Site",
- "Site_Unavailable"
+ "Site_Unavailable",
+ "Allowed_Site",
};
/* ****************************************** */
@@ -545,7 +546,7 @@ ndpi_port_range * ndpi_build_default_ports_range(ndpi_port_range *ports,
ports[i].port_low = portB_low, ports[i].port_high = portB_high; i++;
ports[i].port_low = portC_low, ports[i].port_high = portC_high; i++;
ports[i].port_low = portD_low, ports[i].port_high = portD_high; i++;
- ports[i].port_low = portE_low, ports[i].port_high = portE_high; i++;
+ ports[i].port_low = portE_low, ports[i].port_high = portE_high;
return(ports);
}
@@ -564,7 +565,7 @@ ndpi_port_range * ndpi_build_default_ports(ndpi_port_range *ports,
ports[i].port_low = portB, ports[i].port_high = portB; i++;
ports[i].port_low = portC, ports[i].port_high = portC; i++;
ports[i].port_low = portD, ports[i].port_high = portD; i++;
- ports[i].port_low = portE, ports[i].port_high = portE; i++;
+ ports[i].port_low = portE, ports[i].port_high = portE;
return(ports);
}
@@ -718,8 +719,7 @@ static void addDefaultPort(struct ndpi_detection_module_struct *ndpi_mod,
ndpi_proto_defaults_t *def,
u_int8_t customUserProto,
ndpi_default_ports_tree_node_t **root,
- const char *_func, int _line)
-{
+ const char *_func, int _line) {
ndpi_default_ports_tree_node_t *ret;
u_int16_t port;
@@ -999,6 +999,7 @@ static void free_hyperscan_memory(struct hs *h) {
if(h) {
hs_free_scratch(h->scratch);
hs_free_database(h->database);
+ free(h);
}
}
@@ -2174,16 +2175,6 @@ u_int16_t ndpi_network_ptree_match(struct ndpi_detection_module_struct *ndpi_str
/* ******************************************* */
-/* u_int16_t ndpi_host_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t host /\* network byte order *\/) { */
-/* struct in_addr pin; */
-
-/* pin.s_addr = host; */
-
-/* return(ndpi_network_ptree_match(ndpi_struct, &pin)); */
-/* } */
-
-/* ******************************************* */
-
#if 0
static u_int8_t tor_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, struct in_addr *pin) {
return((ndpi_network_ptree_match(ndpi_struct, pin) == NDPI_PROTOCOL_TOR) ? 1 : 0);
@@ -2380,7 +2371,7 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(void) {
for(i=0; i<NUM_CUSTOM_CATEGORIES; i++)
snprintf(ndpi_str->custom_category_labels[i],
- CUSTOM_CATEGORY_LABEL_LEN, "User custom category %u", i+1);
+ CUSTOM_CATEGORY_LABEL_LEN, "User custom category %u", (unsigned int)(i+1));
return ndpi_str;
}
@@ -2698,8 +2689,8 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struc
struct ndpi_flow_struct *flow,
u_int8_t proto, u_int16_t sport, u_int16_t dport,
u_int8_t *user_defined_proto) {
-
*user_defined_proto = 0; /* Default */
+
if(sport && dport) {
ndpi_default_ports_tree_node_t *found = ndpi_get_guessed_protocol_id(ndpi_struct, proto, sport, dport);
@@ -2895,12 +2886,18 @@ int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_mod,
Format:
<tcp|udp>:<port>,<tcp|udp>:<port>,.....@<proto>
+ Subprotocols Format:
+ host:"<value>",host:"<value>",.....@<subproto>
+
+ IP based Subprotocols Format (<value> is IP or CIDR):
+ ip:<value>,ip:<value>,.....@<subproto>
+
Example:
tcp:80,tcp:3128@HTTP
udp:139@NETBIOS
*/
-int ndpi_load_protocols_file(struct ndpi_detection_module_struct *ndpi_mod, char* path) {
+int ndpi_load_protocols_file(struct ndpi_detection_module_struct *ndpi_mod, const char* path) {
FILE *fd;
char *buffer, *old_buffer;
int chunk_len = 512, buffer_len = chunk_len, old_buffer_len;
@@ -2909,14 +2906,14 @@ int ndpi_load_protocols_file(struct ndpi_detection_module_struct *ndpi_mod, char
fd = fopen(path, "r");
if(fd == NULL) {
- NDPI_LOG_ERR(ndpi_mod, "Unable to open file %s [%s]", path, strerror(errno));
+ NDPI_LOG_ERR(ndpi_mod, "Unable to open file %s [%s]\n", path, strerror(errno));
goto error;
}
buffer = ndpi_malloc(buffer_len);
if(buffer == NULL) {
- NDPI_LOG_ERR(ndpi_mod, "Memory allocation failure");
+ NDPI_LOG_ERR(ndpi_mod, "Memory allocation failure\n");
goto close_fd;
}
@@ -2933,7 +2930,7 @@ int ndpi_load_protocols_file(struct ndpi_detection_module_struct *ndpi_mod, char
buffer = ndpi_realloc(old_buffer, old_buffer_len, buffer_len);
if(buffer == NULL) {
- NDPI_LOG_ERR(ndpi_mod, "Memory allocation failure");
+ NDPI_LOG_ERR(ndpi_mod, "Memory allocation failure\n");
free(old_buffer);
goto close_fd;
}
@@ -3023,8 +3020,7 @@ void ndpi_set_bitmask_protocol_detection(char * label,
/* ******************************************************************** */
void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *ndpi_struct,
- const NDPI_PROTOCOL_BITMASK * dbm)
-{
+ const NDPI_PROTOCOL_BITMASK * dbm) {
NDPI_PROTOCOL_BITMASK detection_bitmask_local;
NDPI_PROTOCOL_BITMASK *detection_bitmask = &detection_bitmask_local;
u_int32_t a = 0;
@@ -3861,8 +3857,6 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_struct,
const struct ndpi_tcphdr *tcph = packet->tcp;
const struct ndpi_udphdr *udph = flow->packet.udp;
- u_int8_t proxy_enabled = 0;
-
packet->tcp_retransmission = 0, packet->packet_direction = 0;
if(ndpi_struct->direction_detect_disable) {
@@ -3907,7 +3901,7 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_struct,
flow->l4.tcp.seen_ack = 1;
}
if((flow->next_tcp_seq_nr[0] == 0 && flow->next_tcp_seq_nr[1] == 0)
- || (proxy_enabled && (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
@@ -3919,9 +3913,8 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_struct,
if(tcph->ack != 0) {
flow->next_tcp_seq_nr[flow->packet.packet_direction] =
ntohl(tcph->seq) + (tcph->syn ? 1 : packet->payload_packet_len);
- if(!proxy_enabled) {
- flow->next_tcp_seq_nr[1 -flow->packet.packet_direction] = ntohl(tcph->ack_seq);
- }
+
+ 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 */
@@ -4185,7 +4178,7 @@ static ndpi_protocol ndpi_process_partial_detection(struct ndpi_detection_module
ret.app_protocol = ret.master_protocol;
ndpi_fill_protocol_category(ndpi_struct, flow, &ret);
-
+
ndpi_int_change_protocol(ndpi_struct, flow, ret.app_protocol, ret.master_protocol);
return(ret);
@@ -4279,6 +4272,20 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st
&& (flow->protos.stun_ssl.stun.num_processed_pkts > 0))
guessed_protocol_id = NDPI_PROTOCOL_STUN;
+
+ if(flow->host_server_name[0] != '\0') {
+ ndpi_protocol_match_result ret_match;
+
+ ndpi_match_host_subprotocol(ndpi_struct, 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;
+ }
+
ndpi_int_change_protocol(ndpi_struct, flow,
guessed_host_protocol_id,
guessed_protocol_id);
@@ -4433,18 +4440,8 @@ int ndpi_load_hostname_category(struct ndpi_detection_module_struct *ndpi_struct
struct hs_list *h = (struct hs_list*)malloc(sizeof(struct hs_list));
if(h) {
- char tmp[256];
int i, j;
- for(i=0, j=0; (j<sizeof(tmp)) && (name[i] != '\0'); i++) {
- if(name[i] == '.')
- tmp[j++] = '\\';
-
- tmp[j++] = name[i];
- }
-
- tmp[j] = '\0';
-
h->expression = ndpi_strdup(name), h->id = (unsigned int)category;
if(h->expression == NULL) {
free(h);
@@ -4507,7 +4504,8 @@ int ndpi_enable_loaded_categories(struct ndpi_detection_module_struct *ndpi_str)
ndpi_str->custom_categories.hostnames = (struct hs*)malloc(sizeof(struct hs));
if(ndpi_str->custom_categories.hostnames == NULL) {
- free(expressions), free(ids);
+ free(expressions);
+ free(ids);
return(-1); /* Failed */
}
@@ -4599,9 +4597,9 @@ void ndpi_fill_protocol_category(struct ndpi_detection_module_struct *ndpi_struc
ndpi_protocol *ret) {
if(ndpi_struct->custom_categories.categories_loaded) {
if(flow->guessed_header_category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) {
- flow->category = flow->guessed_header_category;
+ flow->category = ret->category = flow->guessed_header_category;
return;
- }
+ }
if(flow->host_server_name[0] != '\0') {
unsigned long id;
@@ -4652,14 +4650,29 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
flow->num_processed_pkts++;
if(flow->server_id == NULL) flow->server_id = dst; /* Default */
- if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
- goto ret_protocols;
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) {
+ /*
+ With SSL we might want to dissect further packets to decode
+ the certificate type for instance
+ */
+ if(flow->check_extra_packets
+ /*
+ && ((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL)
+ || (flow->detected_protocol_stack[1] == NDPI_PROTOCOL_SSL))
+ */
+ ) {
+ ndpi_process_extra_packet(ndpi_struct, flow, packet, packetlen, current_tick_l, src, dst);
+ ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
+ return(ret);
+ } else
+ goto ret_protocols;
+ }
/* need at least 20 bytes for ip header */
if(packetlen < 20) {
/* reset protocol which is normally done in init_packet_header */
ndpi_int_reset_packet_protocol(&flow->packet);
- return(ret);
+ goto invalidate_ptr;
}
flow->packet.tick_timestamp_l = current_tick_l;
@@ -4670,7 +4683,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
/* we are interested in ipv4 packet */
if(ndpi_init_packet_header(ndpi_struct, flow, packetlen) != 0)
- return(ret);
+ goto invalidate_ptr;
/* detect traffic for tcp or udp only */
flow->src = src, flow->dst = dst;
@@ -4731,19 +4744,19 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_struct, flow);
if(ndpi_struct->custom_categories.categories_loaded && flow->packet.iph) {
- ndpi_protocol ret;
-
+ ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED };
+
ndpi_fill_ip_protocol_category(ndpi_struct, 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-1)) {
/* 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_struct, flow, &ret);
- return(ret);
+ goto invalidate_ptr;
}
if(user_defined_proto && flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
@@ -4754,7 +4767,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
}
ndpi_fill_protocol_category(ndpi_struct, flow, &ret);
- return(ret);
+ goto invalidate_ptr;
}
} else {
/* guess host protocol */
@@ -4784,8 +4797,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
ndpi_check_flow_func(ndpi_struct, flow, &ndpi_selection_packet);
ndpi_fill_protocol_category(ndpi_struct, flow, &ret);
-
- return(ret);
+ goto invalidate_ptr;
}
ndpi_check_flow_func(ndpi_struct, flow, &ndpi_selection_packet);
@@ -4797,10 +4809,14 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
if(a != NDPI_PROTOCOL_UNKNOWN) {
int i;
- for(i=0; (i<sizeof(flow->host_server_name)) && (flow->host_server_name[i] != '\0'); i++)
- flow->host_server_name[i] = tolower(flow->host_server_name[i]);
-
- flow->host_server_name[i] ='\0';
+ 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:
@@ -4831,6 +4847,13 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
ret = ndpi_detection_giveup(ndpi_struct, flow, 0);
}
+ invalidate_ptr:
+ /*
+ 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;
+
return(ret);
}
@@ -5030,7 +5053,8 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struc
packet->line[packet->parsed_lines].ptr = packet->payload;
packet->line[packet->parsed_lines].len = 0;
- for(a = 0; a < packet->payload_packet_len; a++) {
+ for(a = 0; (a < packet->payload_packet_len)
+ && (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET); a++) {
if((a + 1) == packet->payload_packet_len)
return; /* Return if only one byte remains (prevent invalid reads past end-of-buffer) */
@@ -5691,8 +5715,8 @@ char *ndpi_get_packet_dst_ip_string(struct ndpi_detection_module_struct *ndpi_st
/* ****************************************************** */
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 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);
}
@@ -6107,7 +6131,7 @@ static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_str
u_int16_t master_protocol_id,
ndpi_protocol_match_result *ret_match,
u_int8_t is_host_match) {
- int matching_protocol_id = NDPI_PROTOCOL_UNKNOWN;
+ int matching_protocol_id;
struct ndpi_packet_struct *packet = &flow->packet;
#ifndef HAVE_HYPERSCAN
@@ -6117,6 +6141,8 @@ static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_str
#else
struct hs *hs = (struct hs*)ndpi_struct->hyperscan;
hs_error_t status;
+
+ matching_protocol_id = NDPI_PROTOCOL_UNKNOWN;
/*
TODO HYPERSCAN
In case of match fill up ret_match and set flow protocol + category
@@ -6378,3 +6404,54 @@ int ndpi_flowv6_flow_hash(u_int8_t l4_proto, struct ndpi_in6_addr *src_ip, struc
return(0); /* OK */
}
+
+/* **************************************** */
+
+/* **************************************** */
+
+struct cipher_weakness {
+ u_int16_t cipher_id;
+ ndpi_cipher_weakness weakness_type;
+};
+
+static struct cipher_weakness safe_ssl_ciphers[] = {
+ /* https://community.qualys.com/thread/18212-how-does-qualys-determine-the-server-cipher-suites */
+ /* INSECURE */
+ { 0xc011, NDPI_CIPHER_INSECURE }, /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
+ { 0x0005, NDPI_CIPHER_INSECURE }, /* TLS_RSA_WITH_RC4_128_SHA */
+ { 0x0004, NDPI_CIPHER_INSECURE }, /* TLS_RSA_WITH_RC4_128_MD5 */
+ /* WEAK */
+ { 0x009d, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
+ { 0x003d, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
+ { 0x0035, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_256_CBC_SHA */
+ { 0x0084, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
+ { 0x009c, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
+ { 0x003c, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
+ { 0x002f, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_128_CBC_SHA */
+ { 0x0041, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
+ { 0xc012, NDPI_CIPHER_WEAK }, /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
+ { 0x0016, NDPI_CIPHER_WEAK }, /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
+ { 0x000a, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
+ { 0x0096, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_SEED_CBC_SHA */
+ { 0x0007, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_IDEA_CBC_SHA */
+
+ { 0x0, NDPI_CIPHER_SAFE } /* END */
+};
+
+u_int8_t ndpi_is_safe_ssl_cipher(u_int16_t cipher) {
+ u_int i;
+
+ for(i=0; safe_ssl_ciphers[i].cipher_id != 0; i++) {
+ if(safe_ssl_ciphers[i].cipher_id == cipher) {
+#ifdef CERTIFICATE_DEBUG
+ printf("%s %s(%04X / %u)\n",
+ (safe_ssl_ciphers[i].weakness_type == NDPI_CIPHER_WEAK) ? "WEAK" : "INSECURE",
+ __FUNCTION__, cipher, cipher);
+#endif
+
+ return(safe_ssl_ciphers[i].weakness_type);
+ }
+ }
+
+ return(NDPI_CIPHER_SAFE); /* We're safe */
+}
diff --git a/src/lib/protocols/btlib.c b/src/lib/protocols/btlib.c
index 5992c1b28..ea06a6348 100644
--- a/src/lib/protocols/btlib.c
+++ b/src/lib/protocols/btlib.c
@@ -204,8 +204,7 @@ void cb_data(bt_parse_data_cb_t *cbd,int *ret) {
if(cbd->t == 0) return;
if(cbd->t == 1) {
-
- DEBUG_TRACE(printf("%s %lld\n",cbd->buf,cbd->v.i));
+ DEBUG_TRACE(printf("%s %lld\n",cbd->buf, (long long)cbd->v.i));
if(STREQ(cbd->buf,"a.port")) {
p->a.port = (u_int16_t)(cbd->v.i & 0xffff);
@@ -234,7 +233,7 @@ void cb_data(bt_parse_data_cb_t *cbd,int *ret) {
p->h_mint = 1;
return;
}
- DEBUG_TRACE(printf("UNKNOWN %s %lld\n",cbd->buf,cbd->v.i));
+ DEBUG_TRACE(printf("UNKNOWN %s %lld\n",cbd->buf, (long long)cbd->v.i));
return;
}
if(cbd->t != 2) {
diff --git a/src/lib/protocols/coap.c b/src/lib/protocols/coap.c
index cf5061bbe..c99ab5fc1 100644
--- a/src/lib/protocols/coap.c
+++ b/src/lib/protocols/coap.c
@@ -130,7 +130,7 @@ void ndpi_search_coap (struct ndpi_detection_module_struct *ndpi_struct,
if(h->version == 1) {
if(h->type == CON || h->type == NO_CON || h->type == ACK || h->type == RST ) {
if(h->tkl < 8) {
- if((h->code >= 0 && h->code <= 5) || (h->code >= 65 && h->code <= 69) ||
+ if((/* h->code >= 0 && */ h->code <= 5) || (h->code >= 65 && h->code <= 69) ||
(h->code >= 128 && h->code <= 134) || (h->code >= 140 && h->code <= 143) ||
(h->code >= 160 && h->code <= 165)) {
diff --git a/src/lib/protocols/csgo.c b/src/lib/protocols/csgo.c
index 7f4479419..f316f96b7 100644
--- a/src/lib/protocols/csgo.c
+++ b/src/lib/protocols/csgo.c
@@ -30,6 +30,11 @@ void ndpi_search_csgo(struct ndpi_detection_module_struct* ndpi_struct, struct n
struct ndpi_packet_struct* packet = &flow->packet;
if (packet->udp != NULL) {
+ if (packet->payload_packet_len < sizeof(uint32_t)) {
+ NDPI_LOG_DBG2(ndpi_struct, "Short csgo packet\n");
+ return;
+ }
+
uint32_t w = htonl(get_u_int32_t(packet->payload, 0));
NDPI_LOG_DBG2(ndpi_struct, "CSGO: word %08x\n", w);
diff --git a/src/lib/protocols/directconnect.c b/src/lib/protocols/directconnect.c
index 5088685e4..19582724d 100644
--- a/src/lib/protocols/directconnect.c
+++ b/src/lib/protocols/directconnect.c
@@ -318,7 +318,6 @@ static void ndpi_search_directconnect_udp(struct ndpi_detection_module_struct
struct ndpi_id_struct *dst = flow->dst;
int pos, count = 0;
-
if (dst != NULL && dst->detected_directconnect_udp_port == packet->udp->dest) {
if ((u_int32_t)
(packet->tick_timestamp -
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index 1c2593feb..dc97f3fe7 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -190,11 +190,11 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd
flow->protos.dns.rsp_type = rsp_type;
/* here x points to the response "class" field */
- if((x+12) < flow->packet.payload_packet_len) {
+ if((x+12) <= flow->packet.payload_packet_len) {
x += 6;
data_len = get16(&x, flow->packet.payload);
- if(((x + data_len) < flow->packet.payload_packet_len)
+ if(((x + data_len) <= flow->packet.payload_packet_len)
&& (((rsp_type == 0x1) && (data_len == 4)) /* A */
#ifdef NDPI_DETECTION_SUPPORT_IPV6
|| ((rsp_type == 0x1c) && (data_len == 16)) /* AAAA */
diff --git a/src/lib/protocols/dropbox.c b/src/lib/protocols/dropbox.c
index 39bb96ff2..895bb0164 100644
--- a/src/lib/protocols/dropbox.c
+++ b/src/lib/protocols/dropbox.c
@@ -30,11 +30,9 @@
#define DB_LSP_PORT 17500
-
static void ndpi_int_dropbox_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
- u_int8_t due_to_correlation)
-{
+ u_int8_t due_to_correlation) {
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DROPBOX, NDPI_PROTOCOL_UNKNOWN);
}
@@ -51,8 +49,7 @@ static void ndpi_check_dropbox(struct ndpi_detection_module_struct *ndpi_struct,
if(packet->udp->dest == dropbox_port) {
if(packet->udp->source == dropbox_port) {
if(payload_len > 10) {
- if(ndpi_strnstr((const char *)packet->payload, "\"host_int\"", payload_len) != NULL) {
-
+ if(ndpi_strnstr((const char *)packet->payload, "\"host_int\"", payload_len) != NULL) {
NDPI_LOG_INFO(ndpi_struct, "found dropbox\n");
ndpi_int_dropbox_add_connection(ndpi_struct, flow, 0);
return;
@@ -60,8 +57,7 @@ static void ndpi_check_dropbox(struct ndpi_detection_module_struct *ndpi_struct,
}
} else {
if(payload_len > 10) {
- if(ndpi_strnstr((const char *)packet->payload, "Bus17Cmd", payload_len) != NULL) {
-
+ if(ndpi_strnstr((const char *)packet->payload, "Bus17Cmd", payload_len) != NULL) {
NDPI_LOG_INFO(ndpi_struct, "found dropbox\n");
ndpi_int_dropbox_add_connection(ndpi_struct, flow, 0);
return;
diff --git a/src/lib/protocols/edonkey.c b/src/lib/protocols/edonkey.c
index 547bafc5f..ca5abebad 100644
--- a/src/lib/protocols/edonkey.c
+++ b/src/lib/protocols/edonkey.c
@@ -177,7 +177,6 @@ static void ndpi_check_edonkey(struct ndpi_detection_module_struct *ndpi_struct,
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
flow->edonkey_stage = packet->packet_direction + 1;
}
-
} else {
NDPI_LOG_DBG2(ndpi_struct, "EDONKEY stage %u: \n", flow->edonkey_stage);
@@ -187,7 +186,7 @@ static void ndpi_check_edonkey(struct ndpi_detection_module_struct *ndpi_struct,
}
/* This is a packet in another direction. Check if we find the proper response. */
- if((payload_len == 0) || (ndpi_edonkey_payload_check(packet->payload, payload_len))) {
+ if(ndpi_edonkey_payload_check(packet->payload, payload_len)) {
NDPI_LOG_INFO(ndpi_struct, "found EDONKEY\n");
ndpi_int_edonkey_add_connection(ndpi_struct, flow);
} else {
diff --git a/src/lib/protocols/ftp_data.c b/src/lib/protocols/ftp_data.c
index 7c646c363..3aaf6f97e 100644
--- a/src/lib/protocols/ftp_data.c
+++ b/src/lib/protocols/ftp_data.c
@@ -62,9 +62,11 @@ static int ndpi_match_ftp_data_directory(struct ndpi_detection_module_struct *nd
;
} else
return 0;
+
+ return 1;
}
- return 1;
+ return 0;
}
static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
diff --git a/src/lib/protocols/gnutella.c b/src/lib/protocols/gnutella.c
index 5bc2980cc..75a8e534b 100644
--- a/src/lib/protocols/gnutella.c
+++ b/src/lib/protocols/gnutella.c
@@ -68,7 +68,6 @@ void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, stru
struct ndpi_id_struct *src = flow->src;
struct ndpi_id_struct *dst = flow->dst;
-
u_int16_t c;
NDPI_LOG_DBG(ndpi_struct, "search GNUTELLA\n");
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
index 33ef9e2ed..e715dd499 100644
--- a/src/lib/protocols/http.c
+++ b/src/lib/protocols/http.c
@@ -184,6 +184,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
case 'P':
switch(flow->packet.http_method.ptr[1]) {
+ case 'A': flow->http.method = NDPI_HTTP_METHOD_PATCH; break;
case 'O': flow->http.method = NDPI_HTTP_METHOD_POST; break;
case 'U': flow->http.method = NDPI_HTTP_METHOD_PUT; break;
}
@@ -414,6 +415,7 @@ static struct l_string {
STATIC_STRING_L("OPTIONS "),
STATIC_STRING_L("HEAD "),
STATIC_STRING_L("PUT "),
+ STATIC_STRING_L("PATCH "),
STATIC_STRING_L("DELETE "),
STATIC_STRING_L("CONNECT "),
STATIC_STRING_L("PROPFIND "),
diff --git a/src/lib/protocols/icecast.c b/src/lib/protocols/icecast.c
index 515d5b572..0bb87b88a 100644
--- a/src/lib/protocols/icecast.c
+++ b/src/lib/protocols/icecast.c
@@ -64,6 +64,8 @@ void ndpi_search_icecast_tcp(struct ndpi_detection_module_struct *ndpi_struct, s
goto icecast_exclude;
}
+ if(flow == NULL) return;
+
if((packet->packet_direction == flow->setup_packet_direction)
&& (flow->packet_counter < 10)) {
return;
diff --git a/src/lib/protocols/mail_smtp.c b/src/lib/protocols/mail_smtp.c
index f7fbd337c..fdc47d15c 100644
--- a/src/lib/protocols/mail_smtp.c
+++ b/src/lib/protocols/mail_smtp.c
@@ -58,13 +58,16 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct
NDPI_LOG_DBG(ndpi_struct, "search mail_smtp\n");
- if (packet->payload_packet_len > 2 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) {
+ if((packet->payload_packet_len > 2)
+ && (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET)
+ && (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a)
+ ) {
u_int8_t a;
u_int8_t bit_count = 0;
NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow,packet);
- for (a = 0; a < packet->parsed_lines; a++) {
+ for (a = 0; a < packet->parsed_lines; a++) {
// expected server responses
if (packet->line[a].len >= 3) {
if (memcmp(packet->line[a].ptr, "220", 3) == 0) {
diff --git a/src/lib/protocols/memcached.c b/src/lib/protocols/memcached.c
index e9deb5cc9..44a8b0858 100644
--- a/src/lib/protocols/memcached.c
+++ b/src/lib/protocols/memcached.c
@@ -89,7 +89,7 @@
#define MEMCACHED_MIN_MATCH 2 /* Minimum number of command/responses required */
-#define MEMCACHED_MATCH(cr) memcmp(offset, cr, cr ## _LEN)
+#define MEMCACHED_MATCH(cr) (cr ## _LEN > length || memcmp(offset, cr, cr ## _LEN))
static void ndpi_int_memcached_add_connection(struct ndpi_detection_module_struct
*ndpi_struct, struct ndpi_flow_struct *flow)
@@ -105,6 +105,7 @@ void ndpi_search_memcached(
{
struct ndpi_packet_struct *packet = &flow->packet;
const u_int8_t *offset = packet->payload;
+ const u_int16_t length = packet->payload_packet_len;
u_int8_t *matches;
NDPI_LOG_DBG(ndpi_struct, "search memcached\n");
diff --git a/src/lib/protocols/mysql.c b/src/lib/protocols/mysql.c
index d1602a2fe..1306c381d 100644
--- a/src/lib/protocols/mysql.c
+++ b/src/lib/protocols/mysql.c
@@ -29,42 +29,46 @@
#include "ndpi_api.h"
-
-static void ndpi_int_mysql_add_connection(struct ndpi_detection_module_struct
- *ndpi_struct, struct ndpi_flow_struct *flow)
-{
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MYSQL, NDPI_PROTOCOL_UNKNOWN);
-}
-
-void ndpi_search_mysql_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
-{
+void ndpi_search_mysql_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &flow->packet;
NDPI_LOG_DBG(ndpi_struct, "search MySQL\n");
if(packet->tcp) {
- if (packet->payload_packet_len > 38 //min length
- && get_u_int16_t(packet->payload, 0) == packet->payload_packet_len - 4 //first 3 bytes are length
- && get_u_int8_t(packet->payload, 2) == 0x00 //3rd byte of packet length
- && get_u_int8_t(packet->payload, 3) == 0x00 //packet sequence number is 0 for startup packet
- && get_u_int8_t(packet->payload, 5) > 0x30 //server version > 0
- && get_u_int8_t(packet->payload, 5) < 0x37 //server version < 7
- && get_u_int8_t(packet->payload, 6) == 0x2e //dot
- ) {
+ if(packet->payload_packet_len > 38 //min length
+ && get_u_int16_t(packet->payload, 0) == packet->payload_packet_len - 4 //first 3 bytes are length
+ && get_u_int8_t(packet->payload, 2) == 0x00 //3rd byte of packet length
+ && get_u_int8_t(packet->payload, 3) == 0x00 //packet sequence number is 0 for startup packet
+ && get_u_int8_t(packet->payload, 5) > 0x30 //server version > 0
+ && get_u_int8_t(packet->payload, 5) < 0x37 //server version < 7
+ && get_u_int8_t(packet->payload, 6) == 0x2e //dot
+ ) {
+#if 0
+ /* Old code */
u_int32_t a;
- for (a = 7; a + 31 < packet->payload_packet_len; a++) {
- if (packet->payload[a] == 0x00) {
- if (get_u_int8_t(packet->payload, a + 13) == 0x00 //filler byte
- && get_u_int64_t(packet->payload, a + 19) == 0x0ULL //13 more
- && get_u_int32_t(packet->payload, a + 27) == 0x0 //filler bytes
- && get_u_int8_t(packet->payload, a + 31) == 0x0) {
+
+ for(a = 7; a + 31 < packet->payload_packet_len; a++) {
+ if(packet->payload[a] == 0x00) {
+ if(get_u_int8_t(packet->payload, a + 13) == 0x00 // filler byte
+ && get_u_int64_t(packet->payload, a + 19) == 0x0ULL // 13 more
+ && get_u_int32_t(packet->payload, a + 27) == 0x0 // filler bytes
+ && get_u_int8_t(packet->payload, a + 31) == 0x0) {
NDPI_LOG_INFO(ndpi_struct, "found MySQL\n");
- ndpi_int_mysql_add_connection(ndpi_struct, flow);
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MYSQL, NDPI_PROTOCOL_UNKNOWN);
return;
}
+
break;
}
}
+#else
+ if(strncmp((const char*)&packet->payload[packet->payload_packet_len-22],
+ "mysql_", 6) == 0) {
+ NDPI_LOG_INFO(ndpi_struct, "found MySQL\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MYSQL, NDPI_PROTOCOL_UNKNOWN);
+ return;
+ }
+#endif
}
}
diff --git a/src/lib/protocols/sip.c b/src/lib/protocols/sip.c
index 1436b2cec..2583dbfdf 100644
--- a/src/lib/protocols/sip.c
+++ b/src/lib/protocols/sip.c
@@ -123,6 +123,28 @@ void ndpi_search_sip_handshake(struct ndpi_detection_module_struct
return;
}
+ if ((memcmp(packet_payload, "PUBLISH ", 8) == 0 || memcmp(packet_payload, "publish ", 8) == 0)
+ && (memcmp(&packet_payload[8], "SIP:", 4) == 0 || memcmp(&packet_payload[8], "sip:", 4) == 0)) {
+ NDPI_LOG_INFO(ndpi_struct, "found sip PUBLISH\n");
+ ndpi_int_sip_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+
+ if ((memcmp(packet_payload, "SUBSCRIBE ", 10) == 0 || memcmp(packet_payload, "subscribe ", 10) == 0)
+ && (memcmp(&packet_payload[10], "SIP:", 4) == 0 || memcmp(&packet_payload[10], "sip:", 4) == 0)) {
+ NDPI_LOG_INFO(ndpi_struct, "found sip SUBSCRIBE\n");
+ ndpi_int_sip_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+
+ /* SIP message extension RFC 3248 */
+ if ((memcmp(packet_payload, "MESSAGE ", 8) == 0 || memcmp(packet_payload, "message ", 8) == 0)
+ && (memcmp(&packet_payload[8], "SIP:", 4) == 0 || memcmp(&packet_payload[8], "sip:", 4) == 0)) {
+ NDPI_LOG_INFO(ndpi_struct, "found sip MESSAGE\n");
+ ndpi_int_sip_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+
/* Courtesy of Miguel Quesada <mquesadab@gmail.com> */
if ((memcmp(packet_payload, "OPTIONS ", 8) == 0
|| memcmp(packet_payload, "options ", 8) == 0)
diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c
index 05988a8d4..eee31e94b 100644
--- a/src/lib/protocols/ssl.c
+++ b/src/lib/protocols/ssl.c
@@ -27,7 +27,7 @@
#include "ndpi_api.h"
-// #define CERTIFICATE_DEBUG 1
+/* #define CERTIFICATE_DEBUG 1 */
#define NDPI_MAX_SSL_REQUEST_SIZE 10000
@@ -35,6 +35,204 @@
extern u_int8_t is_skype_flow(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow);
+/* **************************************** */
+
+typedef struct MD5Context {
+ uint32_t buf[4];
+ uint32_t bits[2];
+ unsigned char in[64];
+} MD5_CTX;
+
+/* **************************************** */
+
+static int is_big_endian(void) {
+ static const int n = 1;
+ return ((char *) &n)[0] == 0;
+}
+
+static void byteReverse(unsigned char *buf, unsigned longs) {
+ uint32_t t;
+
+ // Forrest: MD5 expect LITTLE_ENDIAN, swap if BIG_ENDIAN
+ if (is_big_endian()) {
+ do {
+ t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ * (uint32_t *) buf = t;
+ buf += 4;
+ } while (--longs);
+ }
+}
+
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+// Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+// initialization constants.
+static void MD5Init(MD5_CTX *ctx) {
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+static void MD5Transform(uint32_t buf[4], uint32_t const in[16]) {
+ uint32_t a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+static void MD5Update(MD5_CTX *ctx, unsigned char const *buf, unsigned len) {
+ uint32_t t;
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
+ ctx->bits[1]++;
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f;
+
+ if (t) {
+ unsigned char *p = (unsigned char *) ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ memcpy(ctx->in, buf, len);
+}
+
+static void MD5Final(unsigned char digest[16], MD5_CTX *ctx) {
+ unsigned count;
+ unsigned char *p;
+ uint32_t *c = (uint32_t*)ctx->in;
+
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ p = ctx->in + count;
+ *p++ = 0x80;
+ count = 64 - 1 - count;
+ if (count < 8) {
+ memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ memset(ctx->in, 0, 56);
+ } else {
+ memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in, 14);
+
+ c[14] = ctx->bits[0];
+ c[15] = ctx->bits[1];
+
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ byteReverse((unsigned char *) ctx->buf, 4);
+ memcpy(digest, ctx->buf, 16);
+ memset((char *) ctx, 0, sizeof(*ctx));
+}
+
+/* **************************************** */
+
static u_int32_t ndpi_ssl_refine_master_protocol(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow, u_int32_t protocol)
{
@@ -143,18 +341,42 @@ static void stripCertificateTrailer(char *buffer, int buffer_len) {
}
}
-/* Code fixes courtesy of Alexsandro Brahm <alex@digistar.com.br> */
+/* https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967 */
+
+#define JA3_STR_LEN 1024
+#define MAX_NUM_JA3 128
+
+struct ja3_info {
+ u_int16_t ssl_version;
+ u_int16_t num_cipher, cipher[MAX_NUM_JA3];
+ u_int16_t num_ssl_extension, ssl_extension[MAX_NUM_JA3];
+ u_int16_t num_elliptic_curve, elliptic_curve[MAX_NUM_JA3];
+ u_int8_t num_elliptic_curve_point_format, elliptic_curve_point_format[MAX_NUM_JA3];
+};
+
+/* **************************************** */
+
+/* code fixes courtesy of Alexsandro Brahm <alex@digistar.com.br> */
int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
char *buffer, int buffer_len) {
struct ndpi_packet_struct *packet = &flow->packet;
+ struct ja3_info ja3;
+ u_int8_t invalid_ja3 = 0;
+ u_int16_t ssl_version = (packet->payload[1] << 8) + packet->payload[2], ja3_str_len;
+ char ja3_str[JA3_STR_LEN];
+ MD5_CTX ctx;
+ u_char md5_hash[16];
+
+ flow->protos.stun_ssl.ssl.ssl_version = ssl_version;
+
+ memset(&ja3, 0, sizeof(ja3));
#ifdef CERTIFICATE_DEBUG
{
- u_int16_t ssl_version = (packet->payload[1] << 8) + packet->payload[2];
- u_int16_t ssl_len = (packet->payload[3] << 8) + packet->payload[4];
-
- printf("SSL Record [version: 0x%02X][len: %u]\n", ssl_version, ssl_len);
+ u_int16_t ssl_len = (packet->payload[3] << 8) + packet->payload[4];
+
+ printf("SSL Record [version: %u][len: %u]\n", ssl_version, ssl_len);
}
#endif
@@ -183,10 +405,84 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
if((handshake_protocol == 0x02)
|| (handshake_protocol == 0xb) /* Server Hello and Certificate message types are interesting for us */) {
u_int num_found = 0;
+ u_int16_t ssl_version = ntohs(*((u_int16_t*)&packet->payload[9]));
+
+ ja3.ssl_version = ssl_version;
+
+ if(handshake_protocol == 0x02) {
+ u_int16_t offset = 43, extension_len, j;
+ u_int8_t session_id_len = packet->payload[43];
+
+ offset += session_id_len+1;
+
+ ja3.num_cipher = 1, ja3.cipher[0] = ntohs(*((u_int16_t*)&packet->payload[offset]));
+ flow->protos.stun_ssl.ssl.server_unsafe_cipher = ndpi_is_safe_ssl_cipher(ja3.cipher[0]);
+ flow->protos.stun_ssl.ssl.server_cipher = ja3.cipher[0];
+
+#ifdef CERTIFICATE_DEBUG
+ printf("SSL [server][session_id_len: %u][cipher: %04X]\n", session_id_len, ja3.cipher[0]);
+#endif
+
+ offset += 2 + 1;
+ extension_len = ntohs(*((u_int16_t*)&packet->payload[offset]));
+
+#ifdef CERTIFICATE_DEBUG
+ printf("SSL [server][extension_len: %u]\n", extension_len);
+#endif
+ offset += 2;
+
+ for(i=0; i<extension_len; ) {
+ u_int16_t id, len;
+
+ if(offset >= (packet->payload_packet_len+4)) break;
+
+ id = ntohs(*((u_int16_t*)&packet->payload[offset]));
+ len = ntohs(*((u_int16_t*)&packet->payload[offset+2]));
+
+ if(ja3.num_ssl_extension < MAX_NUM_JA3)
+ ja3.ssl_extension[ja3.num_ssl_extension++] = id;
+
+#ifdef CERTIFICATE_DEBUG
+ printf("SSL [server][extension_id: %u]\n", id);
+#endif
+
+ i += 4 + len, offset += 4 + len;
+ }
+
+ ja3_str_len = snprintf(ja3_str, sizeof(ja3_str), "%u,", ja3.ssl_version);
+
+ for(i=0; i<ja3.num_cipher; i++)
+ ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u", (i > 0) ? "-" : "", ja3.cipher[i]);
+
+ ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, ",");
+
+ /* ********** */
- if(handshake_protocol == 0x02)
+ for(i=0; i<ja3.num_ssl_extension; i++)
+ ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u", (i > 0) ? "-" : "", ja3.ssl_extension[i]);
+
+#ifdef CERTIFICATE_DEBUG
+ printf("SSL [server] %s\n", ja3_str);
+#endif
+
+#ifdef CERTIFICATE_DEBUG
+ printf("[JA3] Server: %s \n", ja3_str);
+#endif
+
+ MD5Init(&ctx);
+ MD5Update(&ctx, (const unsigned char *)ja3_str, strlen(ja3_str));
+ MD5Final(md5_hash, &ctx);
+
+ for(i=0, j=0; i<16; i++)
+ j += snprintf(&flow->protos.stun_ssl.ssl.ja3_server[j],
+ sizeof(flow->protos.stun_ssl.ssl.ja3_server)-j, "%02x", md5_hash[i]);
+
+#ifdef CERTIFICATE_DEBUG
+ printf("[JA3] Server: %s \n", flow->protos.stun_ssl.ssl.ja3_server);
+#endif
+
flow->l4.tcp.ssl_seen_server_cert = 1;
- else
+ } else
flow->l4.tcp.ssl_seen_certificate = 1;
/* Check after handshake protocol header (5 bytes) and message header (4 bytes) */
@@ -235,6 +531,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
snprintf(flow->protos.stun_ssl.ssl.server_certificate,
sizeof(flow->protos.stun_ssl.ssl.server_certificate), "%s", buffer);
}
+
return(1 /* Server Certificate */);
}
}
@@ -242,101 +539,251 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
}
} else if(handshake_protocol == 0x01 /* Client Hello */) {
u_int offset, base_offset = 43;
+
if(base_offset + 2 <= packet->payload_packet_len) {
- u_int16_t session_id_len = packet->payload[base_offset];
+ u_int16_t session_id_len = packet->payload[base_offset];
+ u_int16_t ssl_version = ntohs(*((u_int16_t*)&packet->payload[9]));
- if((session_id_len+base_offset+2) <= total_len) {
- u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8);
- offset = base_offset + session_id_len + cypher_len + 2;
+ ja3.ssl_version = ssl_version;
- flow->l4.tcp.ssl_seen_client_cert = 1;
+ if((session_id_len+base_offset+2) <= total_len) {
+ u_int16_t cipher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8);
+ u_int16_t i, cipher_offset = base_offset + session_id_len + 3;
- if(offset < total_len) {
- u_int16_t compression_len;
- u_int16_t extensions_len;
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL [client cipher_len: %u]\n", cipher_len);
+#endif
+
+ if((cipher_offset+cipher_len) <= total_len) {
+ for(i=0; i<cipher_len;) {
+ u_int16_t *id = (u_int16_t*)&packet->payload[cipher_offset+i];
+
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL [cipher suite: %u] [%u/%u]\n", ntohs(*id), i, cipher_len);
+#endif
+ if((*id == 0) || (packet->payload[cipher_offset+i] != packet->payload[cipher_offset+i+1])) {
+ /*
+ Skip GREASE [https://tools.ietf.org/id/draft-ietf-tls-grease-01.html]
+ https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967
+ */
+
+ if(ja3.num_cipher < MAX_NUM_JA3)
+ ja3.cipher[ja3.num_cipher++] = ntohs(*id);
+ else {
+ invalid_ja3 = 1;
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL Invalid cipher %u\n", ja3.num_cipher);
+#endif
+ }
+ }
+
+ i += 2;
+ }
+ } else {
+ invalid_ja3 = 1;
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL Invalid len %u vs %u\n", (cipher_offset+cipher_len), total_len);
+#endif
+ }
+
+ offset = base_offset + session_id_len + cipher_len + 2;
+
+ flow->l4.tcp.ssl_seen_client_cert = 1;
+
+ if(offset < total_len) {
+ u_int16_t compression_len;
+ u_int16_t extensions_len;
- offset++;
- compression_len = packet->payload[offset];
- offset++;
+ offset++;
+ compression_len = packet->payload[offset];
+ offset++;
#ifdef CERTIFICATE_DEBUG
- printf("SSL [compression_len: %u]\n", compression_len);
+ printf("Client SSL [compression_len: %u]\n", compression_len);
#endif
- // offset += compression_len + 3;
- offset += compression_len;
+ // offset += compression_len + 3;
+ offset += compression_len;
- if(offset < total_len) {
- extensions_len = ntohs(*((u_int16_t*)&packet->payload[offset]));
- offset += 2;
+ if(offset < total_len) {
+ extensions_len = ntohs(*((u_int16_t*)&packet->payload[offset]));
+ offset += 2;
#ifdef CERTIFICATE_DEBUG
- printf("SSL [extensions_len: %u]\n", extensions_len);
+ printf("Client SSL [extensions_len: %u]\n", extensions_len);
#endif
- if((extensions_len+offset) <= total_len) {
- /* Move to the first extension
- Type is u_int to avoid possible overflow on extension_len addition */
- u_int extension_offset = 0;
+ if((extensions_len+offset) <= total_len) {
+ /* Move to the first extension
+ Type is u_int to avoid possible overflow on extension_len addition */
+ u_int extension_offset = 0;
+ u_int32_t md5h[4], j;
- while(extension_offset < extensions_len) {
- u_int16_t extension_id, extension_len;
+ while(extension_offset < extensions_len) {
+ u_int16_t extension_id, extension_len, extn_off = offset+extension_offset;
- extension_id = ntohs(*((u_int16_t*)&packet->payload[offset+extension_offset]));
- extension_offset += 2;
+ extension_id = ntohs(*((u_int16_t*)&packet->payload[offset+extension_offset]));
+ extension_offset += 2;
- extension_len = ntohs(*((u_int16_t*)&packet->payload[offset+extension_offset]));
- extension_offset += 2;
+ extension_len = ntohs(*((u_int16_t*)&packet->payload[offset+extension_offset]));
+ extension_offset += 2;
#ifdef CERTIFICATE_DEBUG
- printf("SSL [extension_id: %u][extension_len: %u]\n", extension_id, extension_len);
+ printf("Client SSL [extension_id: %u][extension_len: %u]\n", extension_id, extension_len);
#endif
- if(extension_id == 0) {
-#if 1
- u_int16_t len;
-
- len = (packet->payload[offset+extension_offset+3] << 8) + packet->payload[offset+extension_offset+4];
- len = (u_int)ndpi_min(len, buffer_len-1);
- strncpy(buffer, (char*)&packet->payload[offset+extension_offset+5], len);
- buffer[len] = '\0';
-#else
- /* old code */
- u_int begin = 0;
- char *server_name = (char*)&packet->payload[offset+extension_offset];
-
- while(begin < extension_len) {
- if((!ndpi_isprint(server_name[begin]))
- || ndpi_ispunct(server_name[begin])
- || ndpi_isspace(server_name[begin]))
- begin++;
- else
- break;
- }
+ if((extension_id == 0) || (packet->payload[extn_off] != packet->payload[extn_off+1])) {
+ /* Skip GREASE */
- len = (u_int)ndpi_min(extension_len-begin, buffer_len-1);
- strncpy(buffer, &server_name[begin], len);
- buffer[len] = '\0';
+ if(ja3.num_ssl_extension < MAX_NUM_JA3)
+ ja3.ssl_extension[ja3.num_ssl_extension++] = extension_id;
+ else {
+ invalid_ja3 = 1;
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL Invalid extensions %u\n", ja3.num_ssl_extension);
#endif
+ }
+ }
+
+ if(extension_id == 0 /* server name */) {
+ u_int16_t len;
+
+ len = (packet->payload[offset+extension_offset+3] << 8) + packet->payload[offset+extension_offset+4];
+ len = (u_int)ndpi_min(len, buffer_len-1);
+ strncpy(buffer, (char*)&packet->payload[offset+extension_offset+5], len);
+ buffer[len] = '\0';
+
+ stripCertificateTrailer(buffer, buffer_len);
+
+ if(!ndpi_struct->disable_metadata_export) {
+ snprintf(flow->protos.stun_ssl.ssl.client_certificate,
+ sizeof(flow->protos.stun_ssl.ssl.client_certificate), "%s", buffer);
+ }
+ } else if(extension_id == 10 /* supported groups */) {
+ u_int16_t i, s_offset = offset+extension_offset + 2;
+
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL [EllipticCurveGroups: len=%u]\n", extension_len);
+#endif
+
+ if((s_offset+extension_len-2) <= total_len) {
+ for(i=0; i<extension_len-2;) {
+ u_int16_t s_group = ntohs(*((u_int16_t*)&packet->payload[s_offset+i]));
- stripCertificateTrailer(buffer, buffer_len);
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL [EllipticCurve: %u]\n", s_group);
+#endif
+ if((s_group == 0) || (packet->payload[s_offset+i] != packet->payload[s_offset+i+1])) {
+ /* Skip GREASE */
+ if(ja3.num_elliptic_curve < MAX_NUM_JA3)
+ ja3.elliptic_curve[ja3.num_elliptic_curve++] = s_group;
+ else {
+ invalid_ja3 = 1;
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL Invalid num elliptic %u\n", ja3.num_elliptic_curve);
+#endif
+ }
+ }
- if(!ndpi_struct->disable_metadata_export) {
- snprintf(flow->protos.stun_ssl.ssl.client_certificate,
- sizeof(flow->protos.stun_ssl.ssl.client_certificate), "%s", buffer);
+ i += 2;
}
+ } else {
+ invalid_ja3 = 1;
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL Invalid len %u vs %u\n", (s_offset+extension_len-1), total_len);
+#endif
+ }
+ } else if(extension_id == 11 /* ec_point_formats groups */) {
+ u_int16_t i, s_offset = offset+extension_offset + 1;
- /* We're happy now */
- return(2 /* Client Certificate */);
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL [EllipticCurveFormat: len=%u]\n", extension_len);
+#endif
+ if((s_offset+extension_len) < total_len) {
+ for(i=0; i<extension_len-1;i++) {
+ u_int8_t s_group = packet->payload[s_offset+i];
+
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL [EllipticCurveFormat: %u]\n", s_group);
+#endif
+
+ if(ja3.num_elliptic_curve_point_format < MAX_NUM_JA3)
+ ja3.elliptic_curve_point_format[ja3.num_elliptic_curve_point_format++] = s_group;
+ else {
+ invalid_ja3 = 1;
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL Invalid num elliptic %u\n", ja3.num_elliptic_curve_point_format);
+#endif
+ }
+ }
+ } else {
+ invalid_ja3 = 1;
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL Invalid len %u vs %u\n", s_offset+extension_len, total_len);
+#endif
}
+ }
+
+ extension_offset += extension_len;
- extension_offset += extension_len;
+#ifdef CERTIFICATE_DEBUG
+ printf("Client SSL [extension_offset/len: %u/%u]\n", extension_offset, extension_len);
+#endif
+ } /* while */
+
+ if(!invalid_ja3) {
+ ja3_str_len = snprintf(ja3_str, sizeof(ja3_str), "%u,", ja3.ssl_version);
+
+ for(i=0; i<ja3.num_cipher; i++) {
+ ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u",
+ (i > 0) ? "-" : "", ja3.cipher[i]);
}
+
+ ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, ",");
+
+ /* ********** */
+
+ for(i=0; i<ja3.num_ssl_extension; i++)
+ ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u",
+ (i > 0) ? "-" : "", ja3.ssl_extension[i]);
+
+ ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, ",");
+
+ /* ********** */
+
+ for(i=0; i<ja3.num_elliptic_curve; i++)
+ ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u",
+ (i > 0) ? "-" : "", ja3.elliptic_curve[i]);
+
+ ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, ",");
+
+ for(i=0; i<ja3.num_elliptic_curve_point_format; i++)
+ ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u",
+ (i > 0) ? "-" : "", ja3.elliptic_curve_point_format[i]);
+
+#ifdef CERTIFICATE_DEBUG
+ printf("[JA3] Client: %s \n", ja3_str);
+#endif
+
+ MD5Init(&ctx);
+ MD5Update(&ctx, (const unsigned char *)ja3_str, strlen(ja3_str));
+ MD5Final(md5_hash, &ctx);
+
+ for(i=0, j=0; i<16; i++)
+ j += snprintf(&flow->protos.stun_ssl.ssl.ja3_client[j],
+ sizeof(flow->protos.stun_ssl.ssl.ja3_client)-j, "%02x", md5_hash[i]);
+
+#ifdef CERTIFICATE_DEBUG
+ printf("[JA3] Client: %s \n", flow->protos.stun_ssl.ssl.ja3_client);
+#endif
}
+
+ return(2 /* Client Certificate */);
}
}
}
}
+ }
}
}
}
@@ -345,69 +792,70 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
}
void getSSLorganization(struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow,
- char *buffer, int buffer_len) {
- struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_flow_struct *flow,
+ char *buffer, int buffer_len) {
+ struct ndpi_packet_struct *packet = &flow->packet;
- if(packet->payload[0] != 0x16 /* Handshake */)
- return;
+ if(packet->payload[0] != 0x16 /* Handshake */)
+ return;
- u_int16_t total_len = (packet->payload[3] << 8) + packet->payload[4] + 5 /* SSL Header */;
- u_int8_t handshake_protocol = packet->payload[5]; /* handshake protocol a bit misleading, it is message type according TLS specs */
+ u_int16_t total_len = (packet->payload[3] << 8) + packet->payload[4] + 5 /* SSL Header */;
+ u_int8_t handshake_protocol = packet->payload[5]; /* handshake protocol a bit misleading, it is message type according TLS specs */
- if(handshake_protocol != 0x02 && handshake_protocol != 0xb /* Server Hello and Certificate message types are interesting for us */)
- return;
+ if(handshake_protocol != 0x02 && handshake_protocol != 0xb /* Server Hello and Certificate message types are interesting for us */)
+ return;
- /* Truncate total len, search at least in incomplete packet */
- if(total_len > packet->payload_packet_len)
- total_len = packet->payload_packet_len;
+ /* Truncate total len, search at least in incomplete packet */
+ if(total_len > packet->payload_packet_len)
+ total_len = packet->payload_packet_len;
- memset(buffer, 0, buffer_len);
+ memset(buffer, 0, buffer_len);
- /* Check after handshake protocol header (5 bytes) and message header (4 bytes) */
- u_int num_found = 0;
- u_int i, j;
- for(i = 9; i < packet->payload_packet_len-4; i++) {
- /* Organization OID: 2.5.4.10 */
- if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x0a)) {
- u_int8_t type_tag = packet->payload[i+3]; // 0x0c: utf8string / 0x13: printable_string
- u_int8_t server_len = packet->payload[i+4];
-
- num_found++;
- /* what we want is subject certificate, so we bypass the issuer certificate */
- if(num_found != 2) continue;
-
- // packet is truncated... further inspection is not needed
- if(i+4+server_len >= packet->payload_packet_len) {
- break;
- }
+ /* Check after handshake protocol header (5 bytes) and message header (4 bytes) */
+ u_int num_found = 0;
+ u_int i, j;
+ for(i = 9; i < packet->payload_packet_len-4; i++) {
+ /* Organization OID: 2.5.4.10 */
+ if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x0a)) {
+ u_int8_t type_tag = packet->payload[i+3]; // 0x0c: utf8string / 0x13: printable_string
+ u_int8_t server_len = packet->payload[i+4];
- char *server_org = (char*)&packet->payload[i+5];
+ num_found++;
+ /* what we want is subject certificate, so we bypass the issuer certificate */
+ if(num_found != 2) continue;
- u_int len = (u_int)ndpi_min(server_len, buffer_len-1);
- strncpy(buffer, server_org, len);
- buffer[len] = '\0';
+ // packet is truncated... further inspection is not needed
+ if(i+4+server_len >= packet->payload_packet_len) {
+ break;
+ }
- // check if organization string are all printable
- u_int8_t is_printable = 1;
- for (j = 0; j < len; j++) {
- if(!ndpi_isprint(buffer[j])) {
- is_printable = 0;
- break;
- }
- }
+ char *server_org = (char*)&packet->payload[i+5];
+
+ u_int len = (u_int)ndpi_min(server_len, buffer_len-1);
+ strncpy(buffer, server_org, len);
+ buffer[len] = '\0';
- if(is_printable == 1) {
- snprintf(flow->protos.stun_ssl.ssl.server_organization,
- sizeof(flow->protos.stun_ssl.ssl.server_organization), "%s", buffer);
+ // check if organization string are all printable
+ u_int8_t is_printable = 1;
+ for (j = 0; j < len; j++) {
+ if(!ndpi_isprint(buffer[j])) {
+ is_printable = 0;
+ break;
+ }
+ }
+
+ if(is_printable == 1) {
+ snprintf(flow->protos.stun_ssl.ssl.server_organization,
+ sizeof(flow->protos.stun_ssl.ssl.server_organization), "%s", buffer);
#ifdef CERTIFICATE_DEBUG
- printf("Certificate origanization: %s\n", flow->protos.stun_ssl.ssl.server_organization);
+ printf("Certificate organization: %s\n", flow->protos.stun_ssl.ssl.server_organization);
#endif
- }
- }
+ }
}
+ }
}
+
int sslTryAndRetrieveServerCertificate(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &flow->packet;
@@ -745,7 +1193,7 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc
/* No whatsapp, let's try SSL */
if(sslDetectProtocolFromCertificate(ndpi_struct, flow) > 0)
return;
- }
+ }
if(packet->payload_packet_len > 40 && flow->l4.tcp.ssl_stage == 0) {
NDPI_LOG_DBG2(ndpi_struct, "first ssl packet\n");