aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Makefile.am158
-rw-r--r--src/lib/ndpi_content_match.c.inc7410
-rw-r--r--src/lib/ndpi_main.c5706
-rw-r--r--src/lib/protocols/afp.c75
-rw-r--r--src/lib/protocols/aimini.c283
-rw-r--r--src/lib/protocols/applejuice.c57
-rw-r--r--src/lib/protocols/armagetron.c102
-rw-r--r--src/lib/protocols/attic/flash.c93
-rw-r--r--src/lib/protocols/attic/ftp.c469
-rw-r--r--src/lib/protocols/attic/manolito.c180
-rw-r--r--src/lib/protocols/attic/popo.c86
-rw-r--r--src/lib/protocols/attic/secondlife.c123
-rw-r--r--src/lib/protocols/ayiya.c67
-rw-r--r--src/lib/protocols/battlefield.c118
-rw-r--r--src/lib/protocols/bgp.c57
-rw-r--r--src/lib/protocols/bittorrent.c469
-rw-r--r--src/lib/protocols/btlib.c509
-rw-r--r--src/lib/protocols/btlib.h147
-rw-r--r--src/lib/protocols/ciscovpn.c70
-rw-r--r--src/lib/protocols/citrix.c93
-rw-r--r--src/lib/protocols/collectd.c53
-rw-r--r--src/lib/protocols/corba.c48
-rw-r--r--src/lib/protocols/crossfire.c85
-rw-r--r--src/lib/protocols/dcerpc.c54
-rw-r--r--src/lib/protocols/dhcp.c60
-rw-r--r--src/lib/protocols/dhcpv6.c60
-rw-r--r--src/lib/protocols/directconnect.c474
-rw-r--r--src/lib/protocols/directdownloadlink.c737
-rw-r--r--src/lib/protocols/dns.c300
-rw-r--r--src/lib/protocols/dofus.c149
-rw-r--r--src/lib/protocols/dropbox.c77
-rw-r--r--src/lib/protocols/edonkey.c211
-rw-r--r--src/lib/protocols/fasttrack.c82
-rw-r--r--src/lib/protocols/fiesta.c97
-rw-r--r--src/lib/protocols/filetopia.c83
-rw-r--r--src/lib/protocols/florensia.c122
-rw-r--r--src/lib/protocols/ftp_control.c999
-rw-r--r--src/lib/protocols/ftp_data.c275
-rw-r--r--src/lib/protocols/gnutella.c375
-rw-r--r--src/lib/protocols/gtp.c85
-rw-r--r--src/lib/protocols/guildwars.c71
-rw-r--r--src/lib/protocols/h323.c97
-rw-r--r--src/lib/protocols/halflife2_and_mods.c65
-rw-r--r--src/lib/protocols/http.c981
-rw-r--r--src/lib/protocols/http_activesync.c54
-rw-r--r--src/lib/protocols/iax.c94
-rw-r--r--src/lib/protocols/icecast.c91
-rw-r--r--src/lib/protocols/imesh.c294
-rw-r--r--src/lib/protocols/ipp.c112
-rw-r--r--src/lib/protocols/irc.c804
-rw-r--r--src/lib/protocols/jabber.c311
-rw-r--r--src/lib/protocols/kerberos.c82
-rw-r--r--src/lib/protocols/kontiki.c65
-rw-r--r--src/lib/protocols/ldap.c101
-rw-r--r--src/lib/protocols/lotus_notes.c87
-rw-r--r--src/lib/protocols/mail_imap.c293
-rw-r--r--src/lib/protocols/mail_pop.c204
-rw-r--r--src/lib/protocols/mail_smtp.c180
-rw-r--r--src/lib/protocols/maplestory.c87
-rw-r--r--src/lib/protocols/mdns.c146
-rw-r--r--src/lib/protocols/meebo.c165
-rw-r--r--src/lib/protocols/megaco.c49
-rw-r--r--src/lib/protocols/mgcp.c102
-rw-r--r--src/lib/protocols/mms.c80
-rw-r--r--src/lib/protocols/msn.c563
-rw-r--r--src/lib/protocols/mssql.c61
-rw-r--r--src/lib/protocols/mysql.c70
-rw-r--r--src/lib/protocols/netbios.c368
-rw-r--r--src/lib/protocols/netflow.c93
-rw-r--r--src/lib/protocols/nfs.c86
-rw-r--r--src/lib/protocols/noe.c52
-rw-r--r--src/lib/protocols/non_tcp_udp.c108
-rw-r--r--src/lib/protocols/ntp.c68
-rw-r--r--src/lib/protocols/openft.c56
-rw-r--r--src/lib/protocols/openvpn.c69
-rw-r--r--src/lib/protocols/oracle.c62
-rw-r--r--src/lib/protocols/oscar.c273
-rw-r--r--src/lib/protocols/pando.c157
-rw-r--r--src/lib/protocols/pcanywhere.c55
-rw-r--r--src/lib/protocols/postgres.c120
-rw-r--r--src/lib/protocols/pplive.c220
-rw-r--r--src/lib/protocols/ppstream.c105
-rw-r--r--src/lib/protocols/pptp.c61
-rw-r--r--src/lib/protocols/qq.c665
-rw-r--r--src/lib/protocols/quake.c91
-rw-r--r--src/lib/protocols/radius.c76
-rw-r--r--src/lib/protocols/rdp.c56
-rw-r--r--src/lib/protocols/redis.c92
-rw-r--r--src/lib/protocols/rsync.c56
-rw-r--r--src/lib/protocols/rtcp.c52
-rw-r--r--src/lib/protocols/rtmp.c92
-rw-r--r--src/lib/protocols/rtp.c325
-rw-r--r--src/lib/protocols/rtsp.c120
-rw-r--r--src/lib/protocols/sflow.c49
-rw-r--r--src/lib/protocols/shoutcast.c107
-rw-r--r--src/lib/protocols/sip.c200
-rw-r--r--src/lib/protocols/skinny.c63
-rw-r--r--src/lib/protocols/skype.c122
-rw-r--r--src/lib/protocols/smb.c57
-rw-r--r--src/lib/protocols/snmp.c126
-rw-r--r--src/lib/protocols/socks4.c96
-rw-r--r--src/lib/protocols/socks5.c92
-rw-r--r--src/lib/protocols/socrates.c80
-rw-r--r--src/lib/protocols/sopcast.c219
-rw-r--r--src/lib/protocols/soulseek.c286
-rw-r--r--src/lib/protocols/spotify.c128
-rw-r--r--src/lib/protocols/ssdp.c70
-rw-r--r--src/lib/protocols/ssh.c68
-rw-r--r--src/lib/protocols/ssl.c637
-rw-r--r--src/lib/protocols/stealthnet.c58
-rw-r--r--src/lib/protocols/steam.c286
-rw-r--r--src/lib/protocols/stun.c188
-rw-r--r--src/lib/protocols/syslog.c130
-rw-r--r--src/lib/protocols/tcp_udp.c78
-rw-r--r--src/lib/protocols/tds.c91
-rw-r--r--src/lib/protocols/teamspeak.c65
-rw-r--r--src/lib/protocols/teamviewer.c100
-rw-r--r--src/lib/protocols/telegram.c68
-rw-r--r--src/lib/protocols/telnet.c107
-rw-r--r--src/lib/protocols/tftp.c70
-rw-r--r--src/lib/protocols/thunder.c211
-rw-r--r--src/lib/protocols/tor.c109
-rw-r--r--src/lib/protocols/tvants.c78
-rw-r--r--src/lib/protocols/tvuplayer.c153
-rw-r--r--src/lib/protocols/twitter.c63
-rw-r--r--src/lib/protocols/usenet.c105
-rw-r--r--src/lib/protocols/veohtv.c116
-rw-r--r--src/lib/protocols/vhua.c68
-rw-r--r--src/lib/protocols/viber.c48
-rw-r--r--src/lib/protocols/vmware.c45
-rw-r--r--src/lib/protocols/vnc.c67
-rw-r--r--src/lib/protocols/warcraft3.c100
-rw-r--r--src/lib/protocols/whoisdas.c60
-rw-r--r--src/lib/protocols/winmx.c104
-rw-r--r--src/lib/protocols/world_of_kung_fu.c58
-rw-r--r--src/lib/protocols/world_of_warcraft.c210
-rw-r--r--src/lib/protocols/xbox.c103
-rw-r--r--src/lib/protocols/xdmcp.c69
-rw-r--r--src/lib/protocols/yahoo.c434
-rw-r--r--src/lib/protocols/zattoo.c235
-rw-r--r--src/lib/protocols/zmq.c100
-rw-r--r--src/lib/third_party/include/actypes.h135
-rw-r--r--src/lib/third_party/include/ahocorasick.h69
-rw-r--r--src/lib/third_party/include/node.h66
-rw-r--r--src/lib/third_party/include/patricia.h302
-rw-r--r--src/lib/third_party/include/sort.h6
-rw-r--r--src/lib/third_party/src/ahocorasick.c391
-rw-r--r--src/lib/third_party/src/node.c260
-rw-r--r--src/lib/third_party/src/patricia.c1076
-rw-r--r--src/lib/third_party/src/sort.c130
150 files changed, 38197 insertions, 0 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
new file mode 100644
index 000000000..2ecf1e2ac
--- /dev/null
+++ b/src/lib/Makefile.am
@@ -0,0 +1,158 @@
+lib_LTLIBRARIES = libndpi.la
+
+CFLAGS += -fPIC -DPIC
+libndpi_la_CPPFLAGS = -I$(top_srcdir)/src/include/ -I$(top_srcdir)/src/lib/third_party/include/
+libndpi_la_LDFLAGS = -version-info 1:0:0 -export-symbols $(top_srcdir)/libndpi.sym
+
+libndpi_la_includedir = $(includedir)/libndpi-@VERSION@/libndpi
+
+libndpi_la_include_HEADERS = ../include/ndpi_api.h \
+ ../include/linux_compat.h \
+ ../include/ndpi_define.h \
+ ../include/ndpi_main.h \
+ ../include/ndpi_protocol_ids.h \
+ ../include/ndpi_protocols.h \
+ ../include/ndpi_typedefs.h \
+ ../include/ndpi_unix.h \
+ ../include/ndpi_win32.h
+
+libndpi_la_SOURCES = ndpi_content_match.c.inc \
+ ndpi_main.c \
+ protocols/afp.c \
+ protocols/aimini.c \
+ protocols/applejuice.c \
+ protocols/armagetron.c \
+ protocols/ayiya.c \
+ protocols/battlefield.c \
+ protocols/bgp.c \
+ protocols/bittorrent.c \
+ protocols/ciscovpn.c \
+ protocols/citrix.c \
+ protocols/collectd.c \
+ protocols/corba.c \
+ protocols/crossfire.c \
+ protocols/dcerpc.c \
+ protocols/dhcp.c \
+ protocols/dhcpv6.c \
+ protocols/directconnect.c \
+ protocols/directdownloadlink.c \
+ protocols/dns.c \
+ protocols/dofus.c \
+ protocols/dropbox.c \
+ protocols/edonkey.c \
+ protocols/fasttrack.c \
+ protocols/fiesta.c \
+ protocols/filetopia.c \
+ protocols/florensia.c \
+ protocols/ftp_control.c \
+ protocols/ftp_data.c \
+ protocols/gnutella.c \
+ protocols/gtp.c \
+ protocols/guildwars.c \
+ protocols/h323.c \
+ protocols/halflife2_and_mods.c \
+ protocols/http_activesync.c \
+ protocols/http.c \
+ protocols/iax.c \
+ protocols/icecast.c \
+ protocols/imesh.c \
+ protocols/ipp.c \
+ protocols/irc.c \
+ protocols/jabber.c \
+ protocols/kerberos.c \
+ protocols/kontiki.c \
+ protocols/ldap.c \
+ protocols/lotus_notes.c \
+ protocols/mail_imap.c \
+ protocols/mail_pop.c \
+ protocols/mail_smtp.c \
+ protocols/maplestory.c \
+ protocols/mdns.c \
+ protocols/meebo.c \
+ protocols/megaco.c \
+ protocols/mgcp.c \
+ protocols/mms.c \
+ protocols/msn.c \
+ protocols/mssql.c \
+ protocols/mysql.c \
+ protocols/netbios.c \
+ protocols/netflow.c \
+ protocols/nfs.c \
+ protocols/noe.c \
+ protocols/non_tcp_udp.c \
+ protocols/ntp.c \
+ protocols/openft.c \
+ protocols/openvpn.c \
+ protocols/oracle.c \
+ protocols/oscar.c \
+ protocols/pando.c \
+ protocols/pcanywhere.c \
+ protocols/postgres.c \
+ protocols/pplive.c \
+ protocols/ppstream.c \
+ protocols/pptp.c \
+ protocols/qq.c \
+ protocols/quake.c \
+ protocols/radius.c \
+ protocols/rdp.c \
+ protocols/redis.c \
+ protocols/rsync.c \
+ protocols/rtcp.c \
+ protocols/rtmp.c \
+ protocols/rtp.c \
+ protocols/rtsp.c \
+ protocols/sflow.c \
+ protocols/shoutcast.c \
+ protocols/sip.c \
+ protocols/skinny.c \
+ protocols/skype.c \
+ protocols/smb.c \
+ protocols/snmp.c \
+ protocols/socks4.c \
+ protocols/socks5.c \
+ protocols/socrates.c \
+ protocols/sopcast.c \
+ protocols/soulseek.c \
+ protocols/spotify.c \
+ protocols/ssdp.c \
+ protocols/ssh.c \
+ protocols/ssl.c \
+ protocols/stealthnet.c \
+ protocols/steam.c \
+ protocols/stun.c \
+ protocols/syslog.c \
+ protocols/tcp_udp.c \
+ protocols/tds.c \
+ protocols/teamspeak.c \
+ protocols/teamviewer.c \
+ protocols/telegram.c \
+ protocols/telnet.c \
+ protocols/tftp.c \
+ protocols/thunder.c \
+ protocols/tor.c \
+ protocols/tvants.c \
+ protocols/tvuplayer.c \
+ protocols/twitter.c \
+ protocols/usenet.c \
+ protocols/veohtv.c \
+ protocols/viber.c \
+ protocols/vhua.c \
+ protocols/vmware.c \
+ protocols/vnc.c \
+ protocols/warcraft3.c \
+ protocols/whoisdas.c \
+ protocols/winmx.c \
+ protocols/world_of_kung_fu.c \
+ protocols/world_of_warcraft.c \
+ protocols/xbox.c \
+ protocols/xdmcp.c \
+ protocols/yahoo.c \
+ protocols/zattoo.c \
+ protocols/zmq.c \
+ third_party/include/actypes.h \
+ third_party/include/ahocorasick.h \
+ third_party/include/node.h \
+ third_party/include/sort.h \
+ third_party/src/ahocorasick.c \
+ third_party/src/node.c \
+ third_party/src/sort.c
diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc
new file mode 100644
index 000000000..3b4693fc3
--- /dev/null
+++ b/src/lib/ndpi_content_match.c.inc
@@ -0,0 +1,7410 @@
+/*
+ * ndpi_content_match.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+typedef struct {
+ char *string_to_match, *proto_name;
+ int protocol_id;
+ ndpi_protocol_breed_t protocol_breed;
+} ndpi_protocol_match;
+
+typedef struct {
+ u_int32_t network;
+ u_int8_t cidr;
+ u_int8_t value;
+} ndpi_network;
+
+/* ****************************************************** */
+
+static ndpi_network host_protocol_list[] = {
+ /*
+ Citrix GotoMeeting (AS16815, AS21866)
+ 216.115.208.0/20
+ 216.219.112.0/20
+ */
+ { 0xD873D000 /* 216.115.208.0 */, 20, NDPI_PROTOCOL_CITRIX_ONLINE },
+ { 0xD8DB7000 /* 216.219.112.0 */, 20, NDPI_PROTOCOL_CITRIX_ONLINE },
+
+ /*
+ Webex
+ 66.114.160.0/20
+ */
+ { 0x4272A000 /* 66.114.160.0 */, 20, NDPI_PROTOCOL_WEBEX },
+
+ /*
+ Viber
+ 54.171.62.0/24
+ */
+ { 0x36AB3E00 /* 54.171.62.0 */, 24, NDPI_PROTOCOL_VIBER },
+
+ /*
+ Apple (FaceTime, iMessage,...)
+ 17.0.0.0/8
+ */
+ { 0x11000000 /* 17.0.0.0 */, 8, NDPI_SERVICE_APPLE },
+
+ /*
+ Dropbox
+ 108.160.160.0/20
+ 199.47.216.0/22
+ */
+ { 0x6CA0A000 /* 108.160.160.0 */, 20, NDPI_PROTOCOL_DROPBOX },
+ { 0xC72FD800 /* 199.47.216.0 */, 22, NDPI_PROTOCOL_DROPBOX },
+ { 0x6CA0A000 /* 108.160.160.0 */, 20, NDPI_PROTOCOL_DROPBOX },
+
+ /*
+ Skype
+ 157.56.0.0/14, 157.60.0.0/16, 157.54.0.0/15
+ */
+ { 0x9D380000 /* 157.56.0.0 */, 14, NDPI_PROTOCOL_SKYPE },
+ { 0x9D3C0000 /* 157.60.0.0 */, 16, NDPI_PROTOCOL_SKYPE },
+ { 0x9D360000 /* 157.54.0.0/ */, 15, NDPI_PROTOCOL_SKYPE },
+
+ /*
+ Google
+ 173.194.0.0/16
+ */
+ { 0xADC20000 /* 173.194.0.0 */, 16, NDPI_SERVICE_GOOGLE },
+
+ /*
+ Ubuntu One
+ 91.189.89.0/21 (255.255.248.0)
+ */
+ { 0x5BBD5900 /* 91.189.89.0 */, 21, NDPI_PROTOCOL_UBUNTUONE},
+
+ /*
+ Telegram
+ route: 149.154.164.0/22
+ descr: Telegram Messenger Amsterdam Network
+ origin: AS62041
+ mnt-by: MNT-TELEGRAM
+ source: RIPE # Filtered
+
+ route: 149.154.168.0/22
+ descr: Telegram Messenger DC5 Network
+ origin: AS62014
+ mnt-by: MNT-TELEGRAM
+ source: RIPE # Filtered
+
+ http://myip.ms/view/web_hosting/363906/Telegram_Messenger_Network.html
+ */
+ { 0x959AA400 /* 149.154.164.0/22 */, 22, NDPI_PROTOCOL_TELEGRAM},
+ { 0x959AA800 /* 149.154.168.0/22 */, 22, NDPI_PROTOCOL_TELEGRAM},
+
+ /* Skype */
+ { 0x17600000, 14, NDPI_PROTOCOL_SKYPE },
+ { 0x17613000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0x17614000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0x17616000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0x17622000, 21, NDPI_PROTOCOL_SKYPE },
+ { 0x17622800, 22, NDPI_PROTOCOL_SKYPE },
+ { 0x17623800, 21, NDPI_PROTOCOL_SKYPE },
+ { 0x17624000, 18, NDPI_PROTOCOL_SKYPE },
+ { 0x17640000, 15, NDPI_PROTOCOL_SKYPE },
+ { 0x17660000, 16, NDPI_PROTOCOL_SKYPE },
+ { 0x17674000, 18, NDPI_PROTOCOL_SKYPE },
+ { 0x17678000, 17, NDPI_PROTOCOL_SKYPE },
+ { 0x40040000, 18, NDPI_PROTOCOL_SKYPE },
+ { 0x41340000, 14, NDPI_PROTOCOL_SKYPE },
+ { 0x4134A000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0x41362800, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x41364200, 23, NDPI_PROTOCOL_SKYPE },
+ { 0x41364400, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x41365200, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x41365500, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x41365A00, 23, NDPI_PROTOCOL_SKYPE },
+ { 0x41372C00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x41377500, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x4137E600, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x4137E700, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x42779000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0x46250000, 17, NDPI_PROTOCOL_SKYPE },
+ { 0x46258000, 18, NDPI_PROTOCOL_SKYPE },
+ { 0x46259600, 23, NDPI_PROTOCOL_SKYPE },
+ { 0x5EF54000, 18, NDPI_PROTOCOL_SKYPE },
+ { 0x5EF54C00, 23, NDPI_PROTOCOL_SKYPE },
+ { 0x5EF55200, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x68280000, 13, NDPI_PROTOCOL_SKYPE },
+ { 0x68920000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0x68928000, 17, NDPI_PROTOCOL_SKYPE },
+ { 0x68D00000, 13, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD1000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD1000, 21, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD1700, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD4000, 18, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD4000, 21, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD4200, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD4500, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD4600, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD4E00, 23, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD5000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD6000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD7000, 21, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD7800, 22, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD7C00, 22, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD0100, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD0500, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD0600, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD0800, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD0C00, 22, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD1200, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD1500, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD1800, 21, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD2000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD2100, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD2200, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD3D00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD3E00, 23, NDPI_PROTOCOL_SKYPE },
+ { 0x83FD8000, 17, NDPI_PROTOCOL_SKYPE },
+ { 0x84F50000, 16, NDPI_PROTOCOL_SKYPE },
+ { 0x84F59C00, 22, NDPI_PROTOCOL_SKYPE },
+ { 0x84F5A000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0x86AA0000, 16, NDPI_PROTOCOL_SKYPE },
+ { 0x86AA8000, 21, NDPI_PROTOCOL_SKYPE },
+ { 0x86AA8800, 21, NDPI_PROTOCOL_SKYPE },
+ { 0x86AAD900, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x89740000, 15, NDPI_PROTOCOL_SKYPE },
+ { 0x89748000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0x8974A000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0x89870000, 16, NDPI_PROTOCOL_SKYPE },
+ { 0x8A5B0000, 16, NDPI_PROTOCOL_SKYPE },
+ { 0x8A5B0000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0x8A5B1000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0x8A5B2000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0x9D370000, 16, NDPI_PROTOCOL_SKYPE },
+ { 0x9D380000, 16, NDPI_PROTOCOL_SKYPE },
+ { 0x9D3C1700, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x9D3C1F00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xA7DCF000, 22, NDPI_PROTOCOL_SKYPE },
+ { 0xA83D0000, 16, NDPI_PROTOCOL_SKYPE },
+ { 0xA83E0000, 15, NDPI_PROTOCOL_SKYPE },
+ { 0xA83F8000, 17, NDPI_PROTOCOL_SKYPE },
+ { 0xBFE80000, 13, NDPI_PROTOCOL_SKYPE },
+ { 0xC030E100, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xC0549F00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xC054A000, 23, NDPI_PROTOCOL_SKYPE },
+ { 0xC0C59D00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xC1954000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0xC1DD7100, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xC6310800, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xC6C88200, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xC6CEA400, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xC71E1000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0xC73C1C00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xC74AD200, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xC7675A00, 23, NDPI_PROTOCOL_SKYPE },
+ { 0xC7677A00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xC7F23000, 21, NDPI_PROTOCOL_SKYPE },
+ { 0xCA59E000, 21, NDPI_PROTOCOL_SKYPE },
+ { 0xCC4F8700, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xCC4FB300, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xCC4FC300, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xCC4FC500, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xCC4FFC00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xCC5F6000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0xCC988C00, 23, NDPI_PROTOCOL_SKYPE },
+ { 0xCE8AA800, 21, NDPI_PROTOCOL_SKYPE },
+ { 0xCEBFE000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E0000, 16, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E0000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E2000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E2900, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E3000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E3A00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E3E00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E4000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E4800, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E4D00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E6000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E6200, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E8000, 17, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2E8000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0xCF2EE000, 20, NDPI_PROTOCOL_SKYPE },
+ { 0xCF448000, 18, NDPI_PROTOCOL_SKYPE },
+ { 0xCF52FA00, 23, NDPI_PROTOCOL_SKYPE },
+ { 0xD0448800, 21, NDPI_PROTOCOL_SKYPE },
+ { 0xD04C2D00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xD04C2E00, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xD0540000, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xD0540100, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xD0540200, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xD0540300, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xD1017000, 23, NDPI_PROTOCOL_SKYPE },
+ { 0xD1B98000, 22, NDPI_PROTOCOL_SKYPE },
+ { 0xD1B9F000, 22, NDPI_PROTOCOL_SKYPE },
+ { 0xD1F0C000, 19, NDPI_PROTOCOL_SKYPE },
+ { 0xD5C78000, 18, NDPI_PROTOCOL_SKYPE },
+ { 0xD820B400, 22, NDPI_PROTOCOL_SKYPE },
+ { 0xD820F000, 22, NDPI_PROTOCOL_SKYPE },
+ { 0xD820F200, 24, NDPI_PROTOCOL_SKYPE },
+ { 0xD821F000, 22, NDPI_PROTOCOL_SKYPE },
+ { 0xD4A10800, 24, NDPI_PROTOCOL_SKYPE },
+ { 0x012A1231, 32, NDPI_PROTOCOL_TOR },
+ { 0x01E69FA1, 32, NDPI_PROTOCOL_TOR },
+ { 0x020DE985, 32, NDPI_PROTOCOL_TOR },
+ { 0x021D88C5, 32, NDPI_PROTOCOL_TOR },
+ { 0x0221585B, 32, NDPI_PROTOCOL_TOR },
+ { 0x023E1975, 32, NDPI_PROTOCOL_TOR },
+ { 0x0255D62F, 32, NDPI_PROTOCOL_TOR },
+ { 0x025B6A07, 32, NDPI_PROTOCOL_TOR },
+ { 0x025CB2FE, 32, NDPI_PROTOCOL_TOR },
+ { 0x025DFEE6, 32, NDPI_PROTOCOL_TOR },
+ { 0x025E83A7, 32, NDPI_PROTOCOL_TOR },
+ { 0x02683058, 32, NDPI_PROTOCOL_TOR },
+ { 0x026AEE77, 32, NDPI_PROTOCOL_TOR },
+ { 0x026B16BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x028BD8A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x02D9E930, 32, NDPI_PROTOCOL_TOR },
+ { 0x02E18D86, 32, NDPI_PROTOCOL_TOR },
+ { 0x02E1E75C, 32, NDPI_PROTOCOL_TOR },
+ { 0x02E688B0, 32, NDPI_PROTOCOL_TOR },
+ { 0x02E6A4FE, 32, NDPI_PROTOCOL_TOR },
+ { 0x02E7F51D, 32, NDPI_PROTOCOL_TOR },
+ { 0x02EAEAFB, 32, NDPI_PROTOCOL_TOR },
+ { 0x02EB2A85, 32, NDPI_PROTOCOL_TOR },
+ { 0x02F04269, 32, NDPI_PROTOCOL_TOR },
+ { 0x02F0667E, 32, NDPI_PROTOCOL_TOR },
+ { 0x02F0DA7F, 32, NDPI_PROTOCOL_TOR },
+ { 0x02F183CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x02F1A8DE, 32, NDPI_PROTOCOL_TOR },
+ { 0x02F2F217, 32, NDPI_PROTOCOL_TOR },
+ { 0x02F2FBEB, 32, NDPI_PROTOCOL_TOR },
+ { 0x02F4CD37, 32, NDPI_PROTOCOL_TOR },
+ { 0x02F779C1, 32, NDPI_PROTOCOL_TOR },
+ { 0x0422C8FD, 32, NDPI_PROTOCOL_TOR },
+ { 0x0422C8FD, 32, NDPI_PROTOCOL_TOR },
+ { 0x0501547D, 32, NDPI_PROTOCOL_TOR },
+ { 0x05021027, 32, NDPI_PROTOCOL_TOR },
+ { 0x050902CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x050906A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x05091513, 32, NDPI_PROTOCOL_TOR },
+ { 0x05091ADB, 32, NDPI_PROTOCOL_TOR },
+ { 0x05091ADB, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509254B, 32, NDPI_PROTOCOL_TOR },
+ { 0x05092771, 32, NDPI_PROTOCOL_TOR },
+ { 0x05092B03, 32, NDPI_PROTOCOL_TOR },
+ { 0x05092B50, 32, NDPI_PROTOCOL_TOR },
+ { 0x05093176, 32, NDPI_PROTOCOL_TOR },
+ { 0x05093394, 32, NDPI_PROTOCOL_TOR },
+ { 0x050933AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509362C, 32, NDPI_PROTOCOL_TOR },
+ { 0x05093B4E, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509437C, 32, NDPI_PROTOCOL_TOR },
+ { 0x05094F06, 32, NDPI_PROTOCOL_TOR },
+ { 0x05094F9A, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509501C, 32, NDPI_PROTOCOL_TOR },
+ { 0x050953CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x05095812, 32, NDPI_PROTOCOL_TOR },
+ { 0x050959BD, 32, NDPI_PROTOCOL_TOR },
+ { 0x05096C4A, 32, NDPI_PROTOCOL_TOR },
+ { 0x05096C56, 32, NDPI_PROTOCOL_TOR },
+ { 0x05096E85, 32, NDPI_PROTOCOL_TOR },
+ { 0x05096EEC, 32, NDPI_PROTOCOL_TOR },
+ { 0x050975D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x05097B51, 32, NDPI_PROTOCOL_TOR },
+ { 0x050981DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x05098A9B, 32, NDPI_PROTOCOL_TOR },
+ { 0x05098CC3, 32, NDPI_PROTOCOL_TOR },
+ { 0x050997F1, 32, NDPI_PROTOCOL_TOR },
+ { 0x05099C11, 32, NDPI_PROTOCOL_TOR },
+ { 0x05099E44, 32, NDPI_PROTOCOL_TOR },
+ { 0x05099E4B, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509A92E, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509A92E, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509BF34, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509C38C, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509D4CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509D642, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509E35E, 32, NDPI_PROTOCOL_TOR },
+ { 0x0509EAEE, 32, NDPI_PROTOCOL_TOR },
+ { 0x050D3E81, 32, NDPI_PROTOCOL_TOR },
+ { 0x050E066C, 32, NDPI_PROTOCOL_TOR },
+ { 0x050E30B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x050E476B, 32, NDPI_PROTOCOL_TOR },
+ { 0x050ECAE6, 32, NDPI_PROTOCOL_TOR },
+ { 0x0513A267, 32, NDPI_PROTOCOL_TOR },
+ { 0x0513B30A, 32, NDPI_PROTOCOL_TOR },
+ { 0x0513EC45, 32, NDPI_PROTOCOL_TOR },
+ { 0x0522B70F, 32, NDPI_PROTOCOL_TOR },
+ { 0x0522B7CD, 32, NDPI_PROTOCOL_TOR },
+ { 0x0522B7CF, 32, NDPI_PROTOCOL_TOR },
+ { 0x05272D98, 32, NDPI_PROTOCOL_TOR },
+ { 0x05273CF1, 32, NDPI_PROTOCOL_TOR },
+ { 0x0527465F, 32, NDPI_PROTOCOL_TOR },
+ { 0x05274C24, 32, NDPI_PROTOCOL_TOR },
+ { 0x05274CB6, 32, NDPI_PROTOCOL_TOR },
+ { 0x05274DD0, 32, NDPI_PROTOCOL_TOR },
+ { 0x05274E65, 32, NDPI_PROTOCOL_TOR },
+ { 0x05274FB5, 32, NDPI_PROTOCOL_TOR },
+ { 0x0527501C, 32, NDPI_PROTOCOL_TOR },
+ { 0x05275087, 32, NDPI_PROTOCOL_TOR },
+ { 0x05275087, 32, NDPI_PROTOCOL_TOR },
+ { 0x052752C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x052753D9, 32, NDPI_PROTOCOL_TOR },
+ { 0x052754D9, 32, NDPI_PROTOCOL_TOR },
+ { 0x052756CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x0527579C, 32, NDPI_PROTOCOL_TOR },
+ { 0x05275808, 32, NDPI_PROTOCOL_TOR },
+ { 0x05275813, 32, NDPI_PROTOCOL_TOR },
+ { 0x05275836, 32, NDPI_PROTOCOL_TOR },
+ { 0x0527597C, 32, NDPI_PROTOCOL_TOR },
+ { 0x05277240, 32, NDPI_PROTOCOL_TOR },
+ { 0x05277A42, 32, NDPI_PROTOCOL_TOR },
+ { 0x05277A42, 32, NDPI_PROTOCOL_TOR },
+ { 0x052A0AE5, 32, NDPI_PROTOCOL_TOR },
+ { 0x052C634D, 32, NDPI_PROTOCOL_TOR },
+ { 0x052C63A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x052C6B17, 32, NDPI_PROTOCOL_TOR },
+ { 0x052D4824, 32, NDPI_PROTOCOL_TOR },
+ { 0x052D4909, 32, NDPI_PROTOCOL_TOR },
+ { 0x052D4D11, 32, NDPI_PROTOCOL_TOR },
+ { 0x052D617F, 32, NDPI_PROTOCOL_TOR },
+ { 0x052D626F, 32, NDPI_PROTOCOL_TOR },
+ { 0x052D634B, 32, NDPI_PROTOCOL_TOR },
+ { 0x052D688D, 32, NDPI_PROTOCOL_TOR },
+ { 0x052D6CBD, 32, NDPI_PROTOCOL_TOR },
+ { 0x0536FAC4, 32, NDPI_PROTOCOL_TOR },
+ { 0x0538E13D, 32, NDPI_PROTOCOL_TOR },
+ { 0x0538E4D0, 32, NDPI_PROTOCOL_TOR },
+ { 0x053D223F, 32, NDPI_PROTOCOL_TOR },
+ { 0x053D260B, 32, NDPI_PROTOCOL_TOR },
+ { 0x053DA005, 32, NDPI_PROTOCOL_TOR },
+ { 0x054F44A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x054F44A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x054F47C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x054F4E61, 32, NDPI_PROTOCOL_TOR },
+ { 0x054F51C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x054F56A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x056476A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x056565E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x05656652, 32, NDPI_PROTOCOL_TOR },
+ { 0x05656746, 32, NDPI_PROTOCOL_TOR },
+ { 0x0567688C, 32, NDPI_PROTOCOL_TOR },
+ { 0x0567E82F, 32, NDPI_PROTOCOL_TOR },
+ { 0x05685A1D, 32, NDPI_PROTOCOL_TOR },
+ { 0x05686A26, 32, NDPI_PROTOCOL_TOR },
+ { 0x0581F54D, 32, NDPI_PROTOCOL_TOR },
+ { 0x0581FAAD, 32, NDPI_PROTOCOL_TOR },
+ { 0x058706AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x05873DD1, 32, NDPI_PROTOCOL_TOR },
+ { 0x05873DDA, 32, NDPI_PROTOCOL_TOR },
+ { 0x05875517, 32, NDPI_PROTOCOL_TOR },
+ { 0x05878F54, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587917D, 32, NDPI_PROTOCOL_TOR },
+ { 0x058794AB, 32, NDPI_PROTOCOL_TOR },
+ { 0x058798B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x058798D0, 32, NDPI_PROTOCOL_TOR },
+ { 0x05879ACF, 32, NDPI_PROTOCOL_TOR },
+ { 0x05879B79, 32, NDPI_PROTOCOL_TOR },
+ { 0x05879E65, 32, NDPI_PROTOCOL_TOR },
+ { 0x05879F04, 32, NDPI_PROTOCOL_TOR },
+ { 0x05879F6E, 32, NDPI_PROTOCOL_TOR },
+ { 0x05879FCF, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587A046, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587A21C, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587A2D9, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587A393, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587A5E1, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587B1B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587B209, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587B5D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587B818, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587B991, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587BA49, 32, NDPI_PROTOCOL_TOR },
+ { 0x0587BA9D, 32, NDPI_PROTOCOL_TOR },
+ { 0x058B66B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x0591316A, 32, NDPI_PROTOCOL_TOR },
+ { 0x05922138, 32, NDPI_PROTOCOL_TOR },
+ { 0x05930EA4, 32, NDPI_PROTOCOL_TOR },
+ { 0x0593158F, 32, NDPI_PROTOCOL_TOR },
+ { 0x05937036, 32, NDPI_PROTOCOL_TOR },
+ { 0x0595FA35, 32, NDPI_PROTOCOL_TOR },
+ { 0x0595FAA4, 32, NDPI_PROTOCOL_TOR },
+ { 0x0595FE6D, 32, NDPI_PROTOCOL_TOR },
+ { 0x0595FE72, 32, NDPI_PROTOCOL_TOR },
+ { 0x0596CC95, 32, NDPI_PROTOCOL_TOR },
+ { 0x0596D5F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x0596DE9A, 32, NDPI_PROTOCOL_TOR },
+ { 0x0596EF88, 32, NDPI_PROTOCOL_TOR },
+ { 0x05A4F0C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x05A6DDC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x05A72D58, 32, NDPI_PROTOCOL_TOR },
+ { 0x05A76C53, 32, NDPI_PROTOCOL_TOR },
+ { 0x05A79195, 32, NDPI_PROTOCOL_TOR },
+ { 0x05AC8CC1, 32, NDPI_PROTOCOL_TOR },
+ { 0x05AF714C, 32, NDPI_PROTOCOL_TOR },
+ { 0x05AFC17A, 32, NDPI_PROTOCOL_TOR },
+ { 0x05AFC245, 32, NDPI_PROTOCOL_TOR },
+ { 0x05B256DC, 32, NDPI_PROTOCOL_TOR },
+ { 0x05BD82BB, 32, NDPI_PROTOCOL_TOR },
+ { 0x05BD8738, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C4007B, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C40181, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C404D0, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C40A96, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C40BD0, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C40C4F, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C40C9C, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C40C9F, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C40D1A, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C40E33, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C40EEA, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C41405, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C41455, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C41AC6, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C44134, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C441E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C4426D, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C469E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C4C4A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C4E3A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C4E51D, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C78181, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C782BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C785C1, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C78E5D, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C78E7C, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C78EC3, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C78EE6, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C78EEC, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C7A208, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C7A51B, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C7A621, 32, NDPI_PROTOCOL_TOR },
+ { 0x05C7A78A, 32, NDPI_PROTOCOL_TOR },
+ { 0x05E4618A, 32, NDPI_PROTOCOL_TOR },
+ { 0x05E4CC86, 32, NDPI_PROTOCOL_TOR },
+ { 0x05F6674A, 32, NDPI_PROTOCOL_TOR },
+ { 0x05F91F00, 32, NDPI_PROTOCOL_TOR },
+ { 0x05F99676, 32, NDPI_PROTOCOL_TOR },
+ { 0x05FE818A, 32, NDPI_PROTOCOL_TOR },
+ { 0x05FF57A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x05FF57D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x081C576C, 32, NDPI_PROTOCOL_TOR },
+ { 0x0C845D90, 32, NDPI_PROTOCOL_TOR },
+ { 0x0E20584A, 32, NDPI_PROTOCOL_TOR },
+ { 0x0EA2AFC9, 32, NDPI_PROTOCOL_TOR },
+ { 0x0EC771B3, 32, NDPI_PROTOCOL_TOR },
+ { 0x0ECAE0FB, 32, NDPI_PROTOCOL_TOR },
+ { 0x0ECAE0FB, 32, NDPI_PROTOCOL_TOR },
+ { 0x0F7EF324, 32, NDPI_PROTOCOL_TOR },
+ { 0x12520388, 32, NDPI_PROTOCOL_TOR },
+ { 0x125203C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x125203CD, 32, NDPI_PROTOCOL_TOR },
+ { 0x127D01DE, 32, NDPI_PROTOCOL_TOR },
+ { 0x12B5051C, 32, NDPI_PROTOCOL_TOR },
+ { 0x12B50525, 32, NDPI_PROTOCOL_TOR },
+ { 0x12BB0144, 32, NDPI_PROTOCOL_TOR },
+ { 0x12BD4791, 32, NDPI_PROTOCOL_TOR },
+ { 0x12E400BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x12EE0155, 32, NDPI_PROTOCOL_TOR },
+ { 0x12EE0255, 32, NDPI_PROTOCOL_TOR },
+ { 0x12EF008C, 32, NDPI_PROTOCOL_TOR },
+ { 0x12EF009B, 32, NDPI_PROTOCOL_TOR },
+ { 0x12F3001E, 32, NDPI_PROTOCOL_TOR },
+ { 0x17159AC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x17162143, 32, NDPI_PROTOCOL_TOR },
+ { 0x17198709, 32, NDPI_PROTOCOL_TOR },
+ { 0x1750E204, 32, NDPI_PROTOCOL_TOR },
+ { 0x1758E805, 32, NDPI_PROTOCOL_TOR },
+ { 0x175B15E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x175B420B, 32, NDPI_PROTOCOL_TOR },
+ { 0x175C1308, 32, NDPI_PROTOCOL_TOR },
+ { 0x175C144D, 32, NDPI_PROTOCOL_TOR },
+ { 0x175C154A, 32, NDPI_PROTOCOL_TOR },
+ { 0x175C1A72, 32, NDPI_PROTOCOL_TOR },
+ { 0x175CDC55, 32, NDPI_PROTOCOL_TOR },
+ { 0x175E1BE3, 32, NDPI_PROTOCOL_TOR },
+ { 0x175E2B4C, 32, NDPI_PROTOCOL_TOR },
+ { 0x175E3FA2, 32, NDPI_PROTOCOL_TOR },
+ { 0x175E6595, 32, NDPI_PROTOCOL_TOR },
+ { 0x175ED723, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F092F, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F2687, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F26A0, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F27A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F2B1D, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F2B49, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F2B4B, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F2B4C, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F2B4D, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F2B52, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F6E41, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F6F50, 32, NDPI_PROTOCOL_TOR },
+ { 0x175F70C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x1763514C, 32, NDPI_PROTOCOL_TOR },
+ { 0x1766A02E, 32, NDPI_PROTOCOL_TOR },
+ { 0x177A8D00, 32, NDPI_PROTOCOL_TOR },
+ { 0x17E283AF, 32, NDPI_PROTOCOL_TOR },
+ { 0x17E28484, 32, NDPI_PROTOCOL_TOR },
+ { 0x17E94164, 32, NDPI_PROTOCOL_TOR },
+ { 0x17E96B78, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EE11E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EEE636, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EF045E, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EF0590, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EF0A90, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EF1378, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EF1378, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EF1399, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EF1B1C, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EF1D41, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EF1D41, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EF1DE2, 32, NDPI_PROTOCOL_TOR },
+ { 0x17EF7165, 32, NDPI_PROTOCOL_TOR },
+ { 0x17FA079F, 32, NDPI_PROTOCOL_TOR },
+ { 0x17FC36AA, 32, NDPI_PROTOCOL_TOR },
+ { 0x17FE8026, 32, NDPI_PROTOCOL_TOR },
+ { 0x17FEA584, 32, NDPI_PROTOCOL_TOR },
+ { 0x17FEA5FA, 32, NDPI_PROTOCOL_TOR },
+ { 0x17FEA6DE, 32, NDPI_PROTOCOL_TOR },
+ { 0x17FEA7E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x17FFC32F, 32, NDPI_PROTOCOL_TOR },
+ { 0x17FFCC6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x17FFF26D, 32, NDPI_PROTOCOL_TOR },
+ { 0x18015D49, 32, NDPI_PROTOCOL_TOR },
+ { 0x18041FF9, 32, NDPI_PROTOCOL_TOR },
+ { 0x18048A52, 32, NDPI_PROTOCOL_TOR },
+ { 0x18084CAE, 32, NDPI_PROTOCOL_TOR },
+ { 0x180AEB3E, 32, NDPI_PROTOCOL_TOR },
+ { 0x180CFAC8, 32, NDPI_PROTOCOL_TOR },
+ { 0x180D9384, 32, NDPI_PROTOCOL_TOR },
+ { 0x1810444C, 32, NDPI_PROTOCOL_TOR },
+ { 0x1811131D, 32, NDPI_PROTOCOL_TOR },
+ { 0x18140EAF, 32, NDPI_PROTOCOL_TOR },
+ { 0x18153FC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x18157F86, 32, NDPI_PROTOCOL_TOR },
+ { 0x18158EEB, 32, NDPI_PROTOCOL_TOR },
+ { 0x1815BE96, 32, NDPI_PROTOCOL_TOR },
+ { 0x1815EACE, 32, NDPI_PROTOCOL_TOR },
+ { 0x18166B48, 32, NDPI_PROTOCOL_TOR },
+ { 0x1816B6B0, 32, NDPI_PROTOCOL_TOR },
+ { 0x18228E2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x1833357C, 32, NDPI_PROTOCOL_TOR },
+ { 0x1834CE43, 32, NDPI_PROTOCOL_TOR },
+ { 0x1834DF47, 32, NDPI_PROTOCOL_TOR },
+ { 0x1834F2AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x183E84AB, 32, NDPI_PROTOCOL_TOR },
+ { 0x183ECD0A, 32, NDPI_PROTOCOL_TOR },
+ { 0x18405FB8, 32, NDPI_PROTOCOL_TOR },
+ { 0x18446509, 32, NDPI_PROTOCOL_TOR },
+ { 0x185AC5F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x18601285, 32, NDPI_PROTOCOL_TOR },
+ { 0x186339F8, 32, NDPI_PROTOCOL_TOR },
+ { 0x1868D868, 32, NDPI_PROTOCOL_TOR },
+ { 0x186BDA67, 32, NDPI_PROTOCOL_TOR },
+ { 0x187950A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x1880EB2A, 32, NDPI_PROTOCOL_TOR },
+ { 0x18815804, 32, NDPI_PROTOCOL_TOR },
+ { 0x188628E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x1886424B, 32, NDPI_PROTOCOL_TOR },
+ { 0x1886A34A, 32, NDPI_PROTOCOL_TOR },
+ { 0x1887456F, 32, NDPI_PROTOCOL_TOR },
+ { 0x188CE8A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x18943BB9, 32, NDPI_PROTOCOL_TOR },
+ { 0x18973BA8, 32, NDPI_PROTOCOL_TOR },
+ { 0x189C1043, 32, NDPI_PROTOCOL_TOR },
+ { 0x18A0A2C8, 32, NDPI_PROTOCOL_TOR },
+ { 0x18A2F56C, 32, NDPI_PROTOCOL_TOR },
+ { 0x18A57BA7, 32, NDPI_PROTOCOL_TOR },
+ { 0x18A6420B, 32, NDPI_PROTOCOL_TOR },
+ { 0x18AA2AAE, 32, NDPI_PROTOCOL_TOR },
+ { 0x18B5AF66, 32, NDPI_PROTOCOL_TOR },
+ { 0x18B93E50, 32, NDPI_PROTOCOL_TOR },
+ { 0x18BB1408, 32, NDPI_PROTOCOL_TOR },
+ { 0x18BE411A, 32, NDPI_PROTOCOL_TOR },
+ { 0x18C05C02, 32, NDPI_PROTOCOL_TOR },
+ { 0x18C1E947, 32, NDPI_PROTOCOL_TOR },
+ { 0x18C4398A, 32, NDPI_PROTOCOL_TOR },
+ { 0x18CB1026, 32, NDPI_PROTOCOL_TOR },
+ { 0x18CBAD0C, 32, NDPI_PROTOCOL_TOR },
+ { 0x18D48CD3, 32, NDPI_PROTOCOL_TOR },
+ { 0x18D67228, 32, NDPI_PROTOCOL_TOR },
+ { 0x18D921A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x18DCAE5D, 32, NDPI_PROTOCOL_TOR },
+ { 0x18E94A6F, 32, NDPI_PROTOCOL_TOR },
+ { 0x18EFCCC4, 32, NDPI_PROTOCOL_TOR },
+ { 0x18FBC42B, 32, NDPI_PROTOCOL_TOR },
+ { 0x18FC70B1, 32, NDPI_PROTOCOL_TOR },
+ { 0x1B6D75D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x1B78549C, 32, NDPI_PROTOCOL_TOR },
+ { 0x1B7C7C7A, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F036525, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F07B826, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F07B84C, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F07BADF, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F088004, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F0A4D53, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F0B41C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F0BF184, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1018A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F10AE02, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F11CDA0, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1269A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F12A967, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F12B428, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F12FBBE, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F13D492, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F17E469, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F180C17, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1979DC, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1E2413, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1E2E44, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1F4A40, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1F4A71, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1F4B54, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1F4BB5, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1F4CA9, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1F4DDE, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1F4E31, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1F4E8D, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F1F4F98, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F205448, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F21B915, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F22B6B1, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F2AA922, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F2CE29C, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F2D7B2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F30B0E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F326CF7, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F338AC8, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F81A64E, 32, NDPI_PROTOCOL_TOR },
+ { 0x1F86556D, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FAC1FCF, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FB29AE6, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FB8C367, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FB8C370, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FB91BCB, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FC06934, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FC06C42, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FC0E4B9, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FC18B0E, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FC9B5F1, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FCC966A, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FCC968A, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FCC9866, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FCF8399, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FCFF1A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FD2636A, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FD263D2, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FD2694A, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FD269BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FD26E3A, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FD26E82, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FD27FBA, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FDC0580, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FDC0586, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FDC0599, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FDC05C8, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FDC073F, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FDC078F, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FDC07C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FDC2AC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x1FDC326D, 32, NDPI_PROTOCOL_TOR },
+ { 0x20D7A24A, 32, NDPI_PROTOCOL_TOR },
+ { 0x23007F34, 32, NDPI_PROTOCOL_TOR },
+ { 0x23007F34, 32, NDPI_PROTOCOL_TOR },
+ { 0x2437F025, 32, NDPI_PROTOCOL_TOR },
+ { 0x2450B024, 32, NDPI_PROTOCOL_TOR },
+ { 0x25007B98, 32, NDPI_PROTOCOL_TOR },
+ { 0x25007BCF, 32, NDPI_PROTOCOL_TOR },
+ { 0x2501C2B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x2501D288, 32, NDPI_PROTOCOL_TOR },
+ { 0x2501D569, 32, NDPI_PROTOCOL_TOR },
+ { 0x2501D799, 32, NDPI_PROTOCOL_TOR },
+ { 0x25041A62, 32, NDPI_PROTOCOL_TOR },
+ { 0x25041BED, 32, NDPI_PROTOCOL_TOR },
+ { 0x2505A41C, 32, NDPI_PROTOCOL_TOR },
+ { 0x250B231C, 32, NDPI_PROTOCOL_TOR },
+ { 0x250B231C, 32, NDPI_PROTOCOL_TOR },
+ { 0x250B480D, 32, NDPI_PROTOCOL_TOR },
+ { 0x2511AD98, 32, NDPI_PROTOCOL_TOR },
+ { 0x251816D1, 32, NDPI_PROTOCOL_TOR },
+ { 0x2518F260, 32, NDPI_PROTOCOL_TOR },
+ { 0x25223476, 32, NDPI_PROTOCOL_TOR },
+ { 0x25223A38, 32, NDPI_PROTOCOL_TOR },
+ { 0x252C2C0B, 32, NDPI_PROTOCOL_TOR },
+ { 0x252EB809, 32, NDPI_PROTOCOL_TOR },
+ { 0x25304046, 32, NDPI_PROTOCOL_TOR },
+ { 0x2530417A, 32, NDPI_PROTOCOL_TOR },
+ { 0x2530417A, 32, NDPI_PROTOCOL_TOR },
+ { 0x253043AA, 32, NDPI_PROTOCOL_TOR },
+ { 0x25304A4B, 32, NDPI_PROTOCOL_TOR },
+ { 0x25304E9F, 32, NDPI_PROTOCOL_TOR },
+ { 0x25305130, 32, NDPI_PROTOCOL_TOR },
+ { 0x253056A0, 32, NDPI_PROTOCOL_TOR },
+ { 0x25305A99, 32, NDPI_PROTOCOL_TOR },
+ { 0x2530782F, 32, NDPI_PROTOCOL_TOR },
+ { 0x253078C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x253110CB, 32, NDPI_PROTOCOL_TOR },
+ { 0x253A70B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B0227, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B02BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B0EC9, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B1D49, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B24C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B2675, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B2E9F, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B2F1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B2F1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B4365, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B6052, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B60BF, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B63BF, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B640B, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B69D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B69E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B6FC0, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B704A, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B7493, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B7614, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B7662, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B76F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B794E, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B7B8E, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B7D1D, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B85D0, 32, NDPI_PROTOCOL_TOR },
+ { 0x253B9010, 32, NDPI_PROTOCOL_TOR },
+ { 0x253BA2DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x254BA34C, 32, NDPI_PROTOCOL_TOR },
+ { 0x254CCFC4, 32, NDPI_PROTOCOL_TOR },
+ { 0x256E0D88, 32, NDPI_PROTOCOL_TOR },
+ { 0x256E3C0F, 32, NDPI_PROTOCOL_TOR },
+ { 0x256EF1F9, 32, NDPI_PROTOCOL_TOR },
+ { 0x25718DEE, 32, NDPI_PROTOCOL_TOR },
+ { 0x2571B30C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25723407, 32, NDPI_PROTOCOL_TOR },
+ { 0x25780229, 32, NDPI_PROTOCOL_TOR },
+ { 0x25784275, 32, NDPI_PROTOCOL_TOR },
+ { 0x2578A080, 32, NDPI_PROTOCOL_TOR },
+ { 0x2578AC86, 32, NDPI_PROTOCOL_TOR },
+ { 0x2578AC88, 32, NDPI_PROTOCOL_TOR },
+ { 0x2578ACF2, 32, NDPI_PROTOCOL_TOR },
+ { 0x257B700E, 32, NDPI_PROTOCOL_TOR },
+ { 0x257B70FD, 32, NDPI_PROTOCOL_TOR },
+ { 0x257B756F, 32, NDPI_PROTOCOL_TOR },
+ { 0x257B924B, 32, NDPI_PROTOCOL_TOR },
+ { 0x2582E385, 32, NDPI_PROTOCOL_TOR },
+ { 0x2582E386, 32, NDPI_PROTOCOL_TOR },
+ { 0x2585814C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25869E3E, 32, NDPI_PROTOCOL_TOR },
+ { 0x258B03AB, 32, NDPI_PROTOCOL_TOR },
+ { 0x258B03E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x258B0C33, 32, NDPI_PROTOCOL_TOR },
+ { 0x258B0D4E, 32, NDPI_PROTOCOL_TOR },
+ { 0x258B166E, 32, NDPI_PROTOCOL_TOR },
+ { 0x258F094A, 32, NDPI_PROTOCOL_TOR },
+ { 0x25904351, 32, NDPI_PROTOCOL_TOR },
+ { 0x2591FF60, 32, NDPI_PROTOCOL_TOR },
+ { 0x259267E1, 32, NDPI_PROTOCOL_TOR },
+ { 0x25928712, 32, NDPI_PROTOCOL_TOR },
+ { 0x25929590, 32, NDPI_PROTOCOL_TOR },
+ { 0x25939A1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x2599010A, 32, NDPI_PROTOCOL_TOR },
+ { 0x25993585, 32, NDPI_PROTOCOL_TOR },
+ { 0x259DA955, 32, NDPI_PROTOCOL_TOR },
+ { 0x259DC059, 32, NDPI_PROTOCOL_TOR },
+ { 0x259DC2D2, 32, NDPI_PROTOCOL_TOR },
+ { 0x259DC30D, 32, NDPI_PROTOCOL_TOR },
+ { 0x259DC353, 32, NDPI_PROTOCOL_TOR },
+ { 0x259DC38F, 32, NDPI_PROTOCOL_TOR },
+ { 0x259DC3B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x259DC4DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB0012, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB007E, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB0255, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB02E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB02E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB0303, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB0408, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB04DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB052C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB056D, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB074A, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB094F, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB115F, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB122B, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB122B, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB126D, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB12B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB143B, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB144F, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB151C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB159D, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB15B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB1657, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB1683, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB17E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB17E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB1E4E, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB1F27, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB2693, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB27D2, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB33D2, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB3F72, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB4275, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB604E, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB611F, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB615F, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB62B9, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB638F, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB63C1, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB666C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB66BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB675B, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB679C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB692B, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB6941, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB6944, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB6B5B, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB6BD2, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB6BD2, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB6C50, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB6D13, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB6D3A, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB6D45, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB6E3F, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB6ED8, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB7224, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB728C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB732F, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB7487, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB76EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB7C84, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB7CC6, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB7DCF, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB7DCF, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB7DE4, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB7E15, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB8244, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB82E2, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BB89E1, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BBB023, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BBB040, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BBB404, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BBB41C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BBB441, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BBC635, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BBC69F, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BBEFBF, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BBF36D, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BBF428, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BBF6DD, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BC44E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BED50A, 32, NDPI_PROTOCOL_TOR },
+ { 0x25BF8A2B, 32, NDPI_PROTOCOL_TOR },
+ { 0x25C08768, 32, NDPI_PROTOCOL_TOR },
+ { 0x25C2350B, 32, NDPI_PROTOCOL_TOR },
+ { 0x25C3C530, 32, NDPI_PROTOCOL_TOR },
+ { 0x25C86205, 32, NDPI_PROTOCOL_TOR },
+ { 0x25C863FB, 32, NDPI_PROTOCOL_TOR },
+ { 0x25C939D9, 32, NDPI_PROTOCOL_TOR },
+ { 0x25C98337, 32, NDPI_PROTOCOL_TOR },
+ { 0x25C9DF9D, 32, NDPI_PROTOCOL_TOR },
+ { 0x25CCA01C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25CD0983, 32, NDPI_PROTOCOL_TOR },
+ { 0x25CD0B95, 32, NDPI_PROTOCOL_TOR },
+ { 0x25D13BC6, 32, NDPI_PROTOCOL_TOR },
+ { 0x25D14A11, 32, NDPI_PROTOCOL_TOR },
+ { 0x25D16FE5, 32, NDPI_PROTOCOL_TOR },
+ { 0x25D3561F, 32, NDPI_PROTOCOL_TOR },
+ { 0x25DC233D, 32, NDPI_PROTOCOL_TOR },
+ { 0x25DDA125, 32, NDPI_PROTOCOL_TOR },
+ { 0x25DDA137, 32, NDPI_PROTOCOL_TOR },
+ { 0x25DDA2E2, 32, NDPI_PROTOCOL_TOR },
+ { 0x25DDA2E2, 32, NDPI_PROTOCOL_TOR },
+ { 0x25DDA5E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x25DDA5F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x25DDC114, 32, NDPI_PROTOCOL_TOR },
+ { 0x25DDC5B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x25E48203, 32, NDPI_PROTOCOL_TOR },
+ { 0x25E48424, 32, NDPI_PROTOCOL_TOR },
+ { 0x25E60143, 32, NDPI_PROTOCOL_TOR },
+ { 0x25EB30F7, 32, NDPI_PROTOCOL_TOR },
+ { 0x25EB312E, 32, NDPI_PROTOCOL_TOR },
+ { 0x25EB317C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25EB3443, 32, NDPI_PROTOCOL_TOR },
+ { 0x25EB3753, 32, NDPI_PROTOCOL_TOR },
+ { 0x25EB3C39, 32, NDPI_PROTOCOL_TOR },
+ { 0x25EB3C3C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25EB3E07, 32, NDPI_PROTOCOL_TOR },
+ { 0x25F71635, 32, NDPI_PROTOCOL_TOR },
+ { 0x25F732A7, 32, NDPI_PROTOCOL_TOR },
+ { 0x25F7348C, 32, NDPI_PROTOCOL_TOR },
+ { 0x25F735A2, 32, NDPI_PROTOCOL_TOR },
+ { 0x25FC0CBA, 32, NDPI_PROTOCOL_TOR },
+ { 0x25FCBE85, 32, NDPI_PROTOCOL_TOR },
+ { 0x264D16FB, 32, NDPI_PROTOCOL_TOR },
+ { 0x266C0A8C, 32, NDPI_PROTOCOL_TOR },
+ { 0x26825026, 32, NDPI_PROTOCOL_TOR },
+ { 0x26825039, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E5001C, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E5001D, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E54621, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E54622, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E5462A, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E5462A, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E54633, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E54634, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E54635, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E54636, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E5463D, 32, NDPI_PROTOCOL_TOR },
+ { 0x26E54F02, 32, NDPI_PROTOCOL_TOR },
+ { 0x27775DC9, 32, NDPI_PROTOCOL_TOR },
+ { 0x294885AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x294D88FA, 32, NDPI_PROTOCOL_TOR },
+ { 0x2985828E, 32, NDPI_PROTOCOL_TOR },
+ { 0x29B619B5, 32, NDPI_PROTOCOL_TOR },
+ { 0x29D4257A, 32, NDPI_PROTOCOL_TOR },
+ { 0x29D7F1EA, 32, NDPI_PROTOCOL_TOR },
+ { 0x29DF358D, 32, NDPI_PROTOCOL_TOR },
+ { 0x29F201F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x2A02EFEA, 32, NDPI_PROTOCOL_TOR },
+ { 0x2A7010C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x2A701341, 32, NDPI_PROTOCOL_TOR },
+ { 0x2A7013C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x2BFA082A, 32, NDPI_PROTOCOL_TOR },
+ { 0x2BFA0842, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E04009C, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E0418A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E0419D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E0422F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E0427EB, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E0437B1, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E043C6A, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E0457AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E046723, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E046A12, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E046ACF, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E046F7C, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E0474B0, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E047AA2, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E047AAD, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E04AE34, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E04B777, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E04FDC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E051DC4, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E051E05, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E055F13, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E059971, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E09C314, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E0ACDFC, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E0EF5CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E10EA83, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E113FD6, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E138E1D, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E138E7E, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E14F675, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E167BDE, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E1746C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E17551F, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E1C449E, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E1C4581, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E1C6E81, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E1C6EF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E1CCAD6, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E1CCF78, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E20E8EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E20EABD, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E2423D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E24251B, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E2425B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E2425D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E24271A, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E2639C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E263E1E, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E263F07, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E26E9F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E26FA27, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E2779BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E298244, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E298454, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E2B325C, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E2D0F7B, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E2F133A, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E37146D, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E3B27B9, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E3B3A75, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E3B8EEC, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E3B9439, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E3B9998, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E3BB9D7, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E3BF04E, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E48594D, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E49F960, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E691148, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E6960BE, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E69AC56, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E69E8BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E6C27DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E76110C, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E762709, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E76A38F, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E76E5C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E7E47AA, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E7FC664, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E7FCB2F, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E7FD0F8, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E800457, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E802D63, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E802D76, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E80D52B, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E81138F, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E8115E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E817C16, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E84BCDD, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E92E027, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E95120A, 32, NDPI_PROTOCOL_TOR },
+ { 0x2E97D0D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA25245, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA26191, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA340CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA341A0, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA3449C, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA34C20, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA34CFA, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA3DB56, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA5C560, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA5DDA6, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA5DDA6, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA5DFD6, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA5DFD9, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA5DFE3, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA5F08F, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA5F2A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA5F9E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA5FAEB, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA6A127, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA7F533, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA7F545, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EA7F5AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB5EEA4, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB61224, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB6126F, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB612F5, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB61303, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB61563, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB66ABE, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB6845A, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB6D01C, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB7D9F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB7DA8D, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB7DBC4, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB7DC84, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EB9E185, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EBB039C, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EBC0425, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EBC0A17, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EBC2510, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EBC2AB0, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EC29854, 32, NDPI_PROTOCOL_TOR },
+ { 0x2ED80D2F, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EDF485B, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EDF4FDF, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EDF8DA7, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EDFCD19, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EDFF71E, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EE26D30, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EE26EB9, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EE360DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EE4045B, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EE4C713, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EE5EEAC, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EE90046, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EE9EDBB, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EEBE346, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EEC95E0, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EEF62AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EEF6472, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EEF6B4A, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EEF6CC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EEF75B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EF2623D, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EF48AFB, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EF5C841, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EF61484, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EF6220C, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EF623E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EF62E1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EF659A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EF66CAE, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EF66FCF, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EF9258F, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EFC1838, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EFC18F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EFC19F9, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EFC1A02, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EFC98C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x2EFE4BA8, 32, NDPI_PROTOCOL_TOR },
+ { 0x2F376EBC, 32, NDPI_PROTOCOL_TOR },
+ { 0x31CD342B, 32, NDPI_PROTOCOL_TOR },
+ { 0x31D4A626, 32, NDPI_PROTOCOL_TOR },
+ { 0x31D4ADDE, 32, NDPI_PROTOCOL_TOR },
+ { 0x31D4C271, 32, NDPI_PROTOCOL_TOR },
+ { 0x320163E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x32070872, 32, NDPI_PROTOCOL_TOR },
+ { 0x32073D6A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207A1DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207B03B, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207B03B, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207B03C, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207B03D, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207B03D, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207B03E, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207B83A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207C27A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207D2DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207F36B, 32, NDPI_PROTOCOL_TOR },
+ { 0x3207F36B, 32, NDPI_PROTOCOL_TOR },
+ { 0x32092FEE, 32, NDPI_PROTOCOL_TOR },
+ { 0x321F4CC3, 32, NDPI_PROTOCOL_TOR },
+ { 0x321FFF5E, 32, NDPI_PROTOCOL_TOR },
+ { 0x322300F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x322554A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x322B0AF0, 32, NDPI_PROTOCOL_TOR },
+ { 0x322B38B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x322EF39B, 32, NDPI_PROTOCOL_TOR },
+ { 0x32354A02, 32, NDPI_PROTOCOL_TOR },
+ { 0x32355AFB, 32, NDPI_PROTOCOL_TOR },
+ { 0x323995CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x3245A0C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x3248C4CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x324C9FDA, 32, NDPI_PROTOCOL_TOR },
+ { 0x324EC501, 32, NDPI_PROTOCOL_TOR },
+ { 0x324F2036, 32, NDPI_PROTOCOL_TOR },
+ { 0x32511947, 32, NDPI_PROTOCOL_TOR },
+ { 0x32532059, 32, NDPI_PROTOCOL_TOR },
+ { 0x32582849, 32, NDPI_PROTOCOL_TOR },
+ { 0x3258C0F5, 32, NDPI_PROTOCOL_TOR },
+ { 0x325A0246, 32, NDPI_PROTOCOL_TOR },
+ { 0x325DF89A, 32, NDPI_PROTOCOL_TOR },
+ { 0x325DF9E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x326F05DE, 32, NDPI_PROTOCOL_TOR },
+ { 0x326FC86F, 32, NDPI_PROTOCOL_TOR },
+ { 0x32710FAD, 32, NDPI_PROTOCOL_TOR },
+ { 0x327375B9, 32, NDPI_PROTOCOL_TOR },
+ { 0x32737A44, 32, NDPI_PROTOCOL_TOR },
+ { 0x3273E93E, 32, NDPI_PROTOCOL_TOR },
+ { 0x32740095, 32, NDPI_PROTOCOL_TOR },
+ { 0x327403DF, 32, NDPI_PROTOCOL_TOR },
+ { 0x3274048D, 32, NDPI_PROTOCOL_TOR },
+ { 0x32740599, 32, NDPI_PROTOCOL_TOR },
+ { 0x32740AF2, 32, NDPI_PROTOCOL_TOR },
+ { 0x327415AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x32741D36, 32, NDPI_PROTOCOL_TOR },
+ { 0x32741D36, 32, NDPI_PROTOCOL_TOR },
+ { 0x327420D9, 32, NDPI_PROTOCOL_TOR },
+ { 0x3274222C, 32, NDPI_PROTOCOL_TOR },
+ { 0x32742806, 32, NDPI_PROTOCOL_TOR },
+ { 0x32742AF5, 32, NDPI_PROTOCOL_TOR },
+ { 0x32742E14, 32, NDPI_PROTOCOL_TOR },
+ { 0x32742FAB, 32, NDPI_PROTOCOL_TOR },
+ { 0x3274312E, 32, NDPI_PROTOCOL_TOR },
+ { 0x3274320C, 32, NDPI_PROTOCOL_TOR },
+ { 0x3274320C, 32, NDPI_PROTOCOL_TOR },
+ { 0x32743687, 32, NDPI_PROTOCOL_TOR },
+ { 0x32743830, 32, NDPI_PROTOCOL_TOR },
+ { 0x327556D3, 32, NDPI_PROTOCOL_TOR },
+ { 0x328293BF, 32, NDPI_PROTOCOL_TOR },
+ { 0x328C5DDF, 32, NDPI_PROTOCOL_TOR },
+ { 0x328F6411, 32, NDPI_PROTOCOL_TOR },
+ { 0x3294BED5, 32, NDPI_PROTOCOL_TOR },
+ { 0x3298F1C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x32A4685A, 32, NDPI_PROTOCOL_TOR },
+ { 0x32A84435, 32, NDPI_PROTOCOL_TOR },
+ { 0x32B12972, 32, NDPI_PROTOCOL_TOR },
+ { 0x32B1AF1A, 32, NDPI_PROTOCOL_TOR },
+ { 0x32B5B129, 32, NDPI_PROTOCOL_TOR },
+ { 0x32C18F2A, 32, NDPI_PROTOCOL_TOR },
+ { 0x32C701B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x32F11E91, 32, NDPI_PROTOCOL_TOR },
+ { 0x32F57C83, 32, NDPI_PROTOCOL_TOR },
+ { 0x32F74BCD, 32, NDPI_PROTOCOL_TOR },
+ { 0x32F7C37C, 32, NDPI_PROTOCOL_TOR },
+ { 0x32F90236, 32, NDPI_PROTOCOL_TOR },
+ { 0x32FAC9FE, 32, NDPI_PROTOCOL_TOR },
+ { 0x32FAD011, 32, NDPI_PROTOCOL_TOR },
+ { 0x32FADAA1, 32, NDPI_PROTOCOL_TOR },
+ { 0x32FF615D, 32, NDPI_PROTOCOL_TOR },
+ { 0x340A7D8C, 32, NDPI_PROTOCOL_TOR },
+ { 0x364023F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x3640E586, 32, NDPI_PROTOCOL_TOR },
+ { 0x3641ACFE, 32, NDPI_PROTOCOL_TOR },
+ { 0x3641CE17, 32, NDPI_PROTOCOL_TOR },
+ { 0x3641CE2C, 32, NDPI_PROTOCOL_TOR },
+ { 0x3641CE34, 32, NDPI_PROTOCOL_TOR },
+ { 0x3641CE39, 32, NDPI_PROTOCOL_TOR },
+ { 0x3641CE3C, 32, NDPI_PROTOCOL_TOR },
+ { 0x3641CE43, 32, NDPI_PROTOCOL_TOR },
+ { 0x3641CE4A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3641CE4F, 32, NDPI_PROTOCOL_TOR },
+ { 0x3642A01A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3642ED8D, 32, NDPI_PROTOCOL_TOR },
+ { 0x36431231, 32, NDPI_PROTOCOL_TOR },
+ { 0x36441DAA, 32, NDPI_PROTOCOL_TOR },
+ { 0x3645C64F, 32, NDPI_PROTOCOL_TOR },
+ { 0x3649DA8A, 32, NDPI_PROTOCOL_TOR },
+ { 0x364D068C, 32, NDPI_PROTOCOL_TOR },
+ { 0x364D6EBC, 32, NDPI_PROTOCOL_TOR },
+ { 0x364D7868, 32, NDPI_PROTOCOL_TOR },
+ { 0x364D7DC1, 32, NDPI_PROTOCOL_TOR },
+ { 0x364F7EC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x3652C35E, 32, NDPI_PROTOCOL_TOR },
+ { 0x36542A9B, 32, NDPI_PROTOCOL_TOR },
+ { 0x36546A29, 32, NDPI_PROTOCOL_TOR },
+ { 0x36568324, 32, NDPI_PROTOCOL_TOR },
+ { 0x36571DA1, 32, NDPI_PROTOCOL_TOR },
+ { 0x36583B2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x36583F17, 32, NDPI_PROTOCOL_TOR },
+ { 0x3658A5E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x365D2B6D, 32, NDPI_PROTOCOL_TOR },
+ { 0x365E89A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x365E8BA7, 32, NDPI_PROTOCOL_TOR },
+ { 0x365EF005, 32, NDPI_PROTOCOL_TOR },
+ { 0x365EF097, 32, NDPI_PROTOCOL_TOR },
+ { 0x365EF100, 32, NDPI_PROTOCOL_TOR },
+ { 0x365EF1A2, 32, NDPI_PROTOCOL_TOR },
+ { 0x365EF1A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x365EF1AB, 32, NDPI_PROTOCOL_TOR },
+ { 0x365EF1B5, 32, NDPI_PROTOCOL_TOR },
+ { 0x365EF1B8, 32, NDPI_PROTOCOL_TOR },
+ { 0x3692143E, 32, NDPI_PROTOCOL_TOR },
+ { 0x3692CB7D, 32, NDPI_PROTOCOL_TOR },
+ { 0x36941FE1, 32, NDPI_PROTOCOL_TOR },
+ { 0x36946DAA, 32, NDPI_PROTOCOL_TOR },
+ { 0x36949610, 32, NDPI_PROTOCOL_TOR },
+ { 0x3695F2AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x369A0E1A, 32, NDPI_PROTOCOL_TOR },
+ { 0x36A49C46, 32, NDPI_PROTOCOL_TOR },
+ { 0x36AB5EF9, 32, NDPI_PROTOCOL_TOR },
+ { 0x36AD6890, 32, NDPI_PROTOCOL_TOR },
+ { 0x36AF0DB5, 32, NDPI_PROTOCOL_TOR },
+ { 0x36AF5145, 32, NDPI_PROTOCOL_TOR },
+ { 0x36B9A3E2, 32, NDPI_PROTOCOL_TOR },
+ { 0x36BB371D, 32, NDPI_PROTOCOL_TOR },
+ { 0x36BBEF10, 32, NDPI_PROTOCOL_TOR },
+ { 0x36BF1132, 32, NDPI_PROTOCOL_TOR },
+ { 0x36BF7203, 32, NDPI_PROTOCOL_TOR },
+ { 0x36BF80E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x36C25AB0, 32, NDPI_PROTOCOL_TOR },
+ { 0x36D05F8F, 32, NDPI_PROTOCOL_TOR },
+ { 0x36D5A676, 32, NDPI_PROTOCOL_TOR },
+ { 0x36E035C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x36E44160, 32, NDPI_PROTOCOL_TOR },
+ { 0x36E8A7C8, 32, NDPI_PROTOCOL_TOR },
+ { 0x36EBF7DC, 32, NDPI_PROTOCOL_TOR },
+ { 0x36EDB868, 32, NDPI_PROTOCOL_TOR },
+ { 0x36FBC11C, 32, NDPI_PROTOCOL_TOR },
+ { 0x36FBD0B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x36FC6132, 32, NDPI_PROTOCOL_TOR },
+ { 0x3A0775BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x3A604E5D, 32, NDPI_PROTOCOL_TOR },
+ { 0x3AB78278, 32, NDPI_PROTOCOL_TOR },
+ { 0x3B656242, 32, NDPI_PROTOCOL_TOR },
+ { 0x3BA79B3B, 32, NDPI_PROTOCOL_TOR },
+ { 0x3BB14C69, 32, NDPI_PROTOCOL_TOR },
+ { 0x3C230879, 32, NDPI_PROTOCOL_TOR },
+ { 0x3CEA7764, 32, NDPI_PROTOCOL_TOR },
+ { 0x3CF2B70F, 32, NDPI_PROTOCOL_TOR },
+ { 0x3CF8A2B3, 32, NDPI_PROTOCOL_TOR },
+ { 0x3D56E640, 32, NDPI_PROTOCOL_TOR },
+ { 0x3D5A3C79, 32, NDPI_PROTOCOL_TOR },
+ { 0x3DCD303F, 32, NDPI_PROTOCOL_TOR },
+ { 0x3DDB7725, 32, NDPI_PROTOCOL_TOR },
+ { 0x3DE6AE3B, 32, NDPI_PROTOCOL_TOR },
+ { 0x3DE6C615, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E040D0D, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E1E7D29, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E2BAF76, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E2C7FB8, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E315C96, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E3F9D4E, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E3FEFD7, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4B8EA6, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4B8FA7, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4B9617, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4B9DC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4B9FF9, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4BB91A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4BBB2A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4BD198, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4BEBDE, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4BF147, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4BF17F, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4BF74A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4BFB9D, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4BFDF7, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4C20B3, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4C2C95, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E4D554A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E5C6F2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E6C249B, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E6C2530, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E6CAB4C, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E70C338, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E71DF9A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E71FA27, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E71FAB4, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E7A36A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E8D24D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E8D251E, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E8D2574, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E8D2CCE, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E8D2E36, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E8D2EC1, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E8F7968, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E8F8DEE, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E8F91BE, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E8FDE16, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E92842F, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E93FB15, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E9502BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E950D39, 32, NDPI_PROTOCOL_TOR },
+ { 0x3E982BCB, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EA803D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EB0EFE5, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EB287DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EB5EEBA, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EB63D99, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EC5289B, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ECA279D, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ECB0AE6, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ECC6EC6, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED22410, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED22552, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED24579, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED245EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED24A37, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED24A89, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED24A8F, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED24ABA, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED24AC9, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED24C60, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2522C, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED252A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED252B1, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED25404, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED25414, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED25C0B, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED25C0B, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED28438, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED28990, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED289E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED289E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2AA0A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2AA1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2AA8F, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2AC5E, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2B6BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2B6EF, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2BCDA, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2BD22, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2C698, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2CC3D, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2CE19, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2CE19, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2CE35, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2D3ED, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2ECAE, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2ED55, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2EE32, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2F088, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2F3A7, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2F3B1, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED2FCAF, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED448F3, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED45233, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED454E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED45975, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED6063D, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED8D048, 32, NDPI_PROTOCOL_TOR },
+ { 0x3ED97CFD, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EDA4B01, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EDB2E85, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EDBB62A, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EDC8781, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EDC88FD, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EDC9457, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EDC945E, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EDC9460, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EDC9461, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EDCB113, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EE1CA01, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EE2FA55, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EE47585, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EF1F052, 32, NDPI_PROTOCOL_TOR },
+ { 0x3EFF6FC3, 32, NDPI_PROTOCOL_TOR },
+ { 0x3F770D78, 32, NDPI_PROTOCOL_TOR },
+ { 0x3F8EF878, 32, NDPI_PROTOCOL_TOR },
+ { 0x3FE761E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x3FE7B589, 32, NDPI_PROTOCOL_TOR },
+ { 0x3FF95AF8, 32, NDPI_PROTOCOL_TOR },
+ { 0x400535AF, 32, NDPI_PROTOCOL_TOR },
+ { 0x40167D28, 32, NDPI_PROTOCOL_TOR },
+ { 0x4022A5ED, 32, NDPI_PROTOCOL_TOR },
+ { 0x403AC85C, 32, NDPI_PROTOCOL_TOR },
+ { 0x403EF9DE, 32, NDPI_PROTOCOL_TOR },
+ { 0x404552A0, 32, NDPI_PROTOCOL_TOR },
+ { 0x40478F7C, 32, NDPI_PROTOCOL_TOR },
+ { 0x404A7772, 32, NDPI_PROTOCOL_TOR },
+ { 0x404E969E, 32, NDPI_PROTOCOL_TOR },
+ { 0x405713F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x405F3C4B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4071201D, 32, NDPI_PROTOCOL_TOR },
+ { 0x40712CCE, 32, NDPI_PROTOCOL_TOR },
+ { 0x407E2B54, 32, NDPI_PROTOCOL_TOR },
+ { 0x40801EE8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4096D384, 32, NDPI_PROTOCOL_TOR },
+ { 0x40ED332E, 32, NDPI_PROTOCOL_TOR },
+ { 0x40FB0E11, 32, NDPI_PROTOCOL_TOR },
+ { 0x4113B2B1, 32, NDPI_PROTOCOL_TOR },
+ { 0x411DE8C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4124628D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4132CB05, 32, NDPI_PROTOCOL_TOR },
+ { 0x415E2693, 32, NDPI_PROTOCOL_TOR },
+ { 0x416FBA42, 32, NDPI_PROTOCOL_TOR },
+ { 0x41B57080, 32, NDPI_PROTOCOL_TOR },
+ { 0x41B57159, 32, NDPI_PROTOCOL_TOR },
+ { 0x41B57188, 32, NDPI_PROTOCOL_TOR },
+ { 0x41B57BFE, 32, NDPI_PROTOCOL_TOR },
+ { 0x41B57F76, 32, NDPI_PROTOCOL_TOR },
+ { 0x41BF4B1E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4207CDA4, 32, NDPI_PROTOCOL_TOR },
+ { 0x42088235, 32, NDPI_PROTOCOL_TOR },
+ { 0x4208A63E, 32, NDPI_PROTOCOL_TOR },
+ { 0x421F2F84, 32, NDPI_PROTOCOL_TOR },
+ { 0x421FD0F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x422DF72A, 32, NDPI_PROTOCOL_TOR },
+ { 0x424217DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x4244A7E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x42558348, 32, NDPI_PROTOCOL_TOR },
+ { 0x426CCBC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x426D18CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x426F0210, 32, NDPI_PROTOCOL_TOR },
+ { 0x426F0214, 32, NDPI_PROTOCOL_TOR },
+ { 0x42746CB3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4275090A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4283C0D3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4289E293, 32, NDPI_PROTOCOL_TOR },
+ { 0x4292C11F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4294745A, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AB5188, 32, NDPI_PROTOCOL_TOR },
+ { 0x42ABB3C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AC0A43, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AC0CAE, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AC0CFE, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AC216A, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AC21DC, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AFD3F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AFD3F9, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AFD695, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AFD695, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AFD94E, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AFDC99, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AFDD18, 32, NDPI_PROTOCOL_TOR },
+ { 0x42AFDF91, 32, NDPI_PROTOCOL_TOR },
+ { 0x42B4C1DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x42C428FC, 32, NDPI_PROTOCOL_TOR },
+ { 0x42DC03B3, 32, NDPI_PROTOCOL_TOR },
+ { 0x42E421F8, 32, NDPI_PROTOCOL_TOR },
+ { 0x42E42752, 32, NDPI_PROTOCOL_TOR },
+ { 0x42E42772, 32, NDPI_PROTOCOL_TOR },
+ { 0x42E42CCC, 32, NDPI_PROTOCOL_TOR },
+ { 0x42E42FFE, 32, NDPI_PROTOCOL_TOR },
+ { 0x42E436C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x42E43B18, 32, NDPI_PROTOCOL_TOR },
+ { 0x42E43E5B, 32, NDPI_PROTOCOL_TOR },
+ { 0x42F64BA7, 32, NDPI_PROTOCOL_TOR },
+ { 0x42F8CC47, 32, NDPI_PROTOCOL_TOR },
+ { 0x4300A951, 32, NDPI_PROTOCOL_TOR },
+ { 0x4301F94A, 32, NDPI_PROTOCOL_TOR },
+ { 0x43125C8D, 32, NDPI_PROTOCOL_TOR },
+ { 0x43172B2E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4317B5ED, 32, NDPI_PROTOCOL_TOR },
+ { 0x4355853B, 32, NDPI_PROTOCOL_TOR },
+ { 0x43564FB9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4395F029, 32, NDPI_PROTOCOL_TOR },
+ { 0x439EE2CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x43A58EE2, 32, NDPI_PROTOCOL_TOR },
+ { 0x43A864B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x43A92D7F, 32, NDPI_PROTOCOL_TOR },
+ { 0x43AD3984, 32, NDPI_PROTOCOL_TOR },
+ { 0x43AD4C19, 32, NDPI_PROTOCOL_TOR },
+ { 0x43B43F19, 32, NDPI_PROTOCOL_TOR },
+ { 0x43B799D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x43CD598E, 32, NDPI_PROTOCOL_TOR },
+ { 0x43CD704A, 32, NDPI_PROTOCOL_TOR },
+ { 0x43D7FF8C, 32, NDPI_PROTOCOL_TOR },
+ { 0x43DC16BF, 32, NDPI_PROTOCOL_TOR },
+ { 0x43F43639, 32, NDPI_PROTOCOL_TOR },
+ { 0x43F98A71, 32, NDPI_PROTOCOL_TOR },
+ { 0x43FDF527, 32, NDPI_PROTOCOL_TOR },
+ { 0x43FF09CB, 32, NDPI_PROTOCOL_TOR },
+ { 0x440440C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x440859BD, 32, NDPI_PROTOCOL_TOR },
+ { 0x44094F72, 32, NDPI_PROTOCOL_TOR },
+ { 0x440FB66B, 32, NDPI_PROTOCOL_TOR },
+ { 0x442300D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x44238420, 32, NDPI_PROTOCOL_TOR },
+ { 0x44240EFA, 32, NDPI_PROTOCOL_TOR },
+ { 0x44342124, 32, NDPI_PROTOCOL_TOR },
+ { 0x4434AFBE, 32, NDPI_PROTOCOL_TOR },
+ { 0x443A307C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4440A1EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x44416405, 32, NDPI_PROTOCOL_TOR },
+ { 0x44429AD6, 32, NDPI_PROTOCOL_TOR },
+ { 0x44432303, 32, NDPI_PROTOCOL_TOR },
+ { 0x44472E8A, 32, NDPI_PROTOCOL_TOR },
+ { 0x445011A0, 32, NDPI_PROTOCOL_TOR },
+ { 0x44590067, 32, NDPI_PROTOCOL_TOR },
+ { 0x4461BFC0, 32, NDPI_PROTOCOL_TOR },
+ { 0x44669EA3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4468364B, 32, NDPI_PROTOCOL_TOR },
+ { 0x44706295, 32, NDPI_PROTOCOL_TOR },
+ { 0x4471943A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4494A2D8, 32, NDPI_PROTOCOL_TOR },
+ { 0x449528B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x44B7A9A7, 32, NDPI_PROTOCOL_TOR },
+ { 0x44BB40FC, 32, NDPI_PROTOCOL_TOR },
+ { 0x44E003CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x44E003CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x44E4F314, 32, NDPI_PROTOCOL_TOR },
+ { 0x44E7DBD4, 32, NDPI_PROTOCOL_TOR },
+ { 0x44E9EBD9, 32, NDPI_PROTOCOL_TOR },
+ { 0x450C569F, 32, NDPI_PROTOCOL_TOR },
+ { 0x450D2623, 32, NDPI_PROTOCOL_TOR },
+ { 0x451B5416, 32, NDPI_PROTOCOL_TOR },
+ { 0x451C5230, 32, NDPI_PROTOCOL_TOR },
+ { 0x451C5A69, 32, NDPI_PROTOCOL_TOR },
+ { 0x452731C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4532A549, 32, NDPI_PROTOCOL_TOR },
+ { 0x453EA2B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x45402255, 32, NDPI_PROTOCOL_TOR },
+ { 0x454027B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x454030A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x45403430, 32, NDPI_PROTOCOL_TOR },
+ { 0x4543FC87, 32, NDPI_PROTOCOL_TOR },
+ { 0x45596485, 32, NDPI_PROTOCOL_TOR },
+ { 0x455A97E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x455D7F39, 32, NDPI_PROTOCOL_TOR },
+ { 0x45722B5C, 32, NDPI_PROTOCOL_TOR },
+ { 0x45733217, 32, NDPI_PROTOCOL_TOR },
+ { 0x4573C28D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4588E954, 32, NDPI_PROTOCOL_TOR },
+ { 0x458A00E2, 32, NDPI_PROTOCOL_TOR },
+ { 0x458AB189, 32, NDPI_PROTOCOL_TOR },
+ { 0x458D2BC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x45928DBA, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A26B05, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A28B09, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A323DE, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A3640C, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4C3F0, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4C4EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4C524, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4C620, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4C696, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4CD93, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4CEB0, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4CFEA, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4D108, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4D197, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4D312, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4D4B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4D6FA, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4D852, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4DD41, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4DD4E, 32, NDPI_PROTOCOL_TOR },
+ { 0x45A4DD99, 32, NDPI_PROTOCOL_TOR },
+ { 0x45AC94F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x45AC9C67, 32, NDPI_PROTOCOL_TOR },
+ { 0x45ACE727, 32, NDPI_PROTOCOL_TOR },
+ { 0x45B57E1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x45C38CAE, 32, NDPI_PROTOCOL_TOR },
+ { 0x45C456D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x45C4AE92, 32, NDPI_PROTOCOL_TOR },
+ { 0x45C5AF23, 32, NDPI_PROTOCOL_TOR },
+ { 0x45C5AF24, 32, NDPI_PROTOCOL_TOR },
+ { 0x45F5523E, 32, NDPI_PROTOCOL_TOR },
+ { 0x460F3C1D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4618CF2E, 32, NDPI_PROTOCOL_TOR },
+ { 0x462438C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x46261F79, 32, NDPI_PROTOCOL_TOR },
+ { 0x462C2054, 32, NDPI_PROTOCOL_TOR },
+ { 0x463D61E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x463D61E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x463FAA56, 32, NDPI_PROTOCOL_TOR },
+ { 0x46551FF2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4663CC61, 32, NDPI_PROTOCOL_TOR },
+ { 0x4670A038, 32, NDPI_PROTOCOL_TOR },
+ { 0x4670A341, 32, NDPI_PROTOCOL_TOR },
+ { 0x467176E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x46721018, 32, NDPI_PROTOCOL_TOR },
+ { 0x46A22F33, 32, NDPI_PROTOCOL_TOR },
+ { 0x46A2595A, 32, NDPI_PROTOCOL_TOR },
+ { 0x46A56AAE, 32, NDPI_PROTOCOL_TOR },
+ { 0x46A923AD, 32, NDPI_PROTOCOL_TOR },
+ { 0x46B5013D, 32, NDPI_PROTOCOL_TOR },
+ { 0x46BB9A33, 32, NDPI_PROTOCOL_TOR },
+ { 0x46BED043, 32, NDPI_PROTOCOL_TOR },
+ { 0x470EB6E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x47139515, 32, NDPI_PROTOCOL_TOR },
+ { 0x4713954E, 32, NDPI_PROTOCOL_TOR },
+ { 0x47139BBB, 32, NDPI_PROTOCOL_TOR },
+ { 0x47139D7F, 32, NDPI_PROTOCOL_TOR },
+ { 0x47139DD5, 32, NDPI_PROTOCOL_TOR },
+ { 0x47236A50, 32, NDPI_PROTOCOL_TOR },
+ { 0x4738B62B, 32, NDPI_PROTOCOL_TOR },
+ { 0x474BC940, 32, NDPI_PROTOCOL_TOR },
+ { 0x474F591F, 32, NDPI_PROTOCOL_TOR },
+ { 0x474F9691, 32, NDPI_PROTOCOL_TOR },
+ { 0x475ACDF8, 32, NDPI_PROTOCOL_TOR },
+ { 0x475F28FC, 32, NDPI_PROTOCOL_TOR },
+ { 0x47872D47, 32, NDPI_PROTOCOL_TOR },
+ { 0x47A59723, 32, NDPI_PROTOCOL_TOR },
+ { 0x47A79A15, 32, NDPI_PROTOCOL_TOR },
+ { 0x47AE3E2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x47B1E232, 32, NDPI_PROTOCOL_TOR },
+ { 0x47B76C25, 32, NDPI_PROTOCOL_TOR },
+ { 0x47B8FBE9, 32, NDPI_PROTOCOL_TOR },
+ { 0x47B9233B, 32, NDPI_PROTOCOL_TOR },
+ { 0x47B9AB0D, 32, NDPI_PROTOCOL_TOR },
+ { 0x47C3DB07, 32, NDPI_PROTOCOL_TOR },
+ { 0x47C5EB05, 32, NDPI_PROTOCOL_TOR },
+ { 0x47C5FE48, 32, NDPI_PROTOCOL_TOR },
+ { 0x47C772A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x47CAB8E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x47CC7AF0, 32, NDPI_PROTOCOL_TOR },
+ { 0x47D7CE97, 32, NDPI_PROTOCOL_TOR },
+ { 0x47DBB265, 32, NDPI_PROTOCOL_TOR },
+ { 0x47DE7EC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x47E0883A, 32, NDPI_PROTOCOL_TOR },
+ { 0x47E6FD44, 32, NDPI_PROTOCOL_TOR },
+ { 0x47E7BE7B, 32, NDPI_PROTOCOL_TOR },
+ { 0x47EB4AB7, 32, NDPI_PROTOCOL_TOR },
+ { 0x47F5506C, 32, NDPI_PROTOCOL_TOR },
+ { 0x47FB9E4B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4800E332, 32, NDPI_PROTOCOL_TOR },
+ { 0x480EB0AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x480EB1A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x480EB30A, 32, NDPI_PROTOCOL_TOR },
+ { 0x480EB3A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x480EB552, 32, NDPI_PROTOCOL_TOR },
+ { 0x480EB83D, 32, NDPI_PROTOCOL_TOR },
+ { 0x480EBAE2, 32, NDPI_PROTOCOL_TOR },
+ { 0x481AD093, 32, NDPI_PROTOCOL_TOR },
+ { 0x481DA212, 32, NDPI_PROTOCOL_TOR },
+ { 0x482E9BBA, 32, NDPI_PROTOCOL_TOR },
+ { 0x48332350, 32, NDPI_PROTOCOL_TOR },
+ { 0x48344B1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x48345B16, 32, NDPI_PROTOCOL_TOR },
+ { 0x48345B1D, 32, NDPI_PROTOCOL_TOR },
+ { 0x48345B1E, 32, NDPI_PROTOCOL_TOR },
+ { 0x48358586, 32, NDPI_PROTOCOL_TOR },
+ { 0x484200E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4845E5D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4845F863, 32, NDPI_PROTOCOL_TOR },
+ { 0x484E8BB9, 32, NDPI_PROTOCOL_TOR },
+ { 0x48531759, 32, NDPI_PROTOCOL_TOR },
+ { 0x4859E93A, 32, NDPI_PROTOCOL_TOR },
+ { 0x485DF597, 32, NDPI_PROTOCOL_TOR },
+ { 0x488184C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x488313EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x48A0F076, 32, NDPI_PROTOCOL_TOR },
+ { 0x48AEAC8D, 32, NDPI_PROTOCOL_TOR },
+ { 0x48B13B6E, 32, NDPI_PROTOCOL_TOR },
+ { 0x48C0D011, 32, NDPI_PROTOCOL_TOR },
+ { 0x48C105B0, 32, NDPI_PROTOCOL_TOR },
+ { 0x48C5C123, 32, NDPI_PROTOCOL_TOR },
+ { 0x48D1B426, 32, NDPI_PROTOCOL_TOR },
+ { 0x48D1DB9A, 32, NDPI_PROTOCOL_TOR },
+ { 0x48D8ECC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x48DCAD6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x48DE8A0C, 32, NDPI_PROTOCOL_TOR },
+ { 0x48E1295B, 32, NDPI_PROTOCOL_TOR },
+ { 0x48EFE271, 32, NDPI_PROTOCOL_TOR },
+ { 0x48F9B964, 32, NDPI_PROTOCOL_TOR },
+ { 0x48FAD50D, 32, NDPI_PROTOCOL_TOR },
+ { 0x48FD5C2C, 32, NDPI_PROTOCOL_TOR },
+ { 0x49041E43, 32, NDPI_PROTOCOL_TOR },
+ { 0x49043472, 32, NDPI_PROTOCOL_TOR },
+ { 0x4906D179, 32, NDPI_PROTOCOL_TOR },
+ { 0x4908B6E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x490B9E26, 32, NDPI_PROTOCOL_TOR },
+ { 0x490F96AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x490FFEF1, 32, NDPI_PROTOCOL_TOR },
+ { 0x49134ECD, 32, NDPI_PROTOCOL_TOR },
+ { 0x491610C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x492574A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4926F8B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x49274DA6, 32, NDPI_PROTOCOL_TOR },
+ { 0x492C8639, 32, NDPI_PROTOCOL_TOR },
+ { 0x492D254B, 32, NDPI_PROTOCOL_TOR },
+ { 0x492FF6DF, 32, NDPI_PROTOCOL_TOR },
+ { 0x49304E30, 32, NDPI_PROTOCOL_TOR },
+ { 0x49308BE2, 32, NDPI_PROTOCOL_TOR },
+ { 0x498400F7, 32, NDPI_PROTOCOL_TOR },
+ { 0x4984FA0B, 32, NDPI_PROTOCOL_TOR },
+ { 0x49A3EC5F, 32, NDPI_PROTOCOL_TOR },
+ { 0x49A5F4EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x49A64EFD, 32, NDPI_PROTOCOL_TOR },
+ { 0x49A69CAC, 32, NDPI_PROTOCOL_TOR },
+ { 0x49AA0647, 32, NDPI_PROTOCOL_TOR },
+ { 0x49AC98E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x49C08B3F, 32, NDPI_PROTOCOL_TOR },
+ { 0x49C0E718, 32, NDPI_PROTOCOL_TOR },
+ { 0x49C6A499, 32, NDPI_PROTOCOL_TOR },
+ { 0x49C7CBB9, 32, NDPI_PROTOCOL_TOR },
+ { 0x49CAE19F, 32, NDPI_PROTOCOL_TOR },
+ { 0x49D03060, 32, NDPI_PROTOCOL_TOR },
+ { 0x49D0409E, 32, NDPI_PROTOCOL_TOR },
+ { 0x49D0A2E1, 32, NDPI_PROTOCOL_TOR },
+ { 0x49D932BB, 32, NDPI_PROTOCOL_TOR },
+ { 0x49DE0E0A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A03A527, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A323644, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A3BA760, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A3BCC47, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A436379, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A47FA54, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A5203E0, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A536574, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A561813, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A5B1B8D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A5B1B8E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A5E43C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A5FBB69, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A60E7B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A621760, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A65C9F9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A677F7F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A6DF071, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A74BA78, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A79B693, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A7CAB14, 32, NDPI_PROTOCOL_TOR },
+ { 0x4A8AA23A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4AB9DBC9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4AC09417, 32, NDPI_PROTOCOL_TOR },
+ { 0x4AC14C45, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACEB5A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFE03F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFE03F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFE7BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFE7FA, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFE998, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFECC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFED2C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFEDA7, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFEDA7, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFF207, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFF86E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFF9A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ACFFB6D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4AD045C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4AD04E82, 32, NDPI_PROTOCOL_TOR },
+ { 0x4AD2C50C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B013890, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B09754D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B435766, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B451E4D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B488B38, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B4F23FE, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B50A0EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B5169DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B52A04D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B54A327, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B6189EA, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B642932, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B65602F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B7650AB, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B76EED4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B77E8C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B7F0F49, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B82033A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B849247, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B8567ED, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B8FB432, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B91CDB1, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B965B14, 32, NDPI_PROTOCOL_TOR },
+ { 0x4B965B15, 32, NDPI_PROTOCOL_TOR },
+ { 0x4BA665D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4BB117FE, 32, NDPI_PROTOCOL_TOR },
+ { 0x4BB38B1A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4BB3AFC4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4BB66C77, 32, NDPI_PROTOCOL_TOR },
+ { 0x4BB93208, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C0A8078, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C0CDB68, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C17D13D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C1ACBF3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C1CD1A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C1CEA17, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C400D9B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C490364, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C4903AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C493996, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C4AB2F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C4ADB8A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C4C08E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C4F2E66, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C55CFD4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C5BCBA2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C5BE269, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C5CE1D8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C5DD733, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C63DE9C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C66C7AA, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C6A2761, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C702F3C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C7153C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C732D7C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C73829B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C778735, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C7A13E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C7BBBD2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C7C660E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C7CAF69, 32, NDPI_PROTOCOL_TOR },
+ { 0x4C7E0D52, 32, NDPI_PROTOCOL_TOR },
+ { 0x4CAA4864, 32, NDPI_PROTOCOL_TOR },
+ { 0x4CAEFDD2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4CB28C0E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4CB9120F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4CBAB2BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x4CBC4252, 32, NDPI_PROTOCOL_TOR },
+ { 0x4CBFD7D7, 32, NDPI_PROTOCOL_TOR },
+ { 0x4CD11461, 32, NDPI_PROTOCOL_TOR },
+ { 0x4CD90D94, 32, NDPI_PROTOCOL_TOR },
+ { 0x4CD90D94, 32, NDPI_PROTOCOL_TOR },
+ { 0x4CD995F0, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D00C9A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D01045C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D04EB00, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D06EDF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D0A7CF0, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D0AAEE8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D0AD0A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D0C1CB8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D0C1CB8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D0C65BB, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D0C84CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D0DB854, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D0DBCEF, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D142DA8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D1430C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D145762, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D149215, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D149784, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D14C9D3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D1505EA, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D15295E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D154971, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D154D67, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D15D971, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D170724, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D170A99, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D171AE2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D176F1E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D250CBF, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D2588A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D25B87E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D25DA91, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D25F08E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D292F5B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D2DFD87, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D2F7D6F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D2FD16E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D32EB4C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D343FC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D3856DC, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D396860, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D3A033E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D3AD4A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D40D46F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D422DE3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D422E18, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D44245D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D463F8D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D48932F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D489696, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D4E77D3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D51F029, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D56C546, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D56CC64, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6220E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D66D762, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D69D0D9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6D8A2A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6D8A2B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6D8A2C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6D8B1A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6D8B1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6D8B1C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6D8B57, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6D8D8A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6D8D8B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6D8D8C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D6DB99C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D765894, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D7B5606, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D834130, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D86A910, 32, NDPI_PROTOCOL_TOR },
+ { 0x4D98FB30, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DAA0102, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DAE88F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DAEB4C5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DAEF986, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DC5A34D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DCBDD5B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DCF4DB2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DCF6FCE, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DDF4BCF, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DE4A752, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DE4AF4A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DE9EE82, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DEA31CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DEA947A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF30962, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF4FEE3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF4FEE4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF4FEE5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF4FEE6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF6D813, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF7B5A2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF7B5A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF7B5A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF7B5A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF7B5A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF7B5A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DF7B5A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DFB6AF8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4DFEAE40, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E08A504, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E0D3D36, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E1506A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E18DA8A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E1B6E57, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E1FA429, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E227847, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2917A2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E29E9C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2A9D62, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2B689D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2B752E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2B8EB1, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2D136A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E1188, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E2BDD, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E2DF2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E337C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E350B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E3C1E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E40F5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E4229, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E50F7, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E512D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E5F14, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E69F1, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E6A6F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E6B0F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E70DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E7B22, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E7BAC, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E943A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E970B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E9713, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2E989E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2EA78D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2EB0A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2EC54B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2EDA0B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2EDC82, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2EDD7D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2EE185, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2EEFB7, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2EF724, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2EF729, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F0406, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F10A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F126E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F1BF6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F2323, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F273C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F27BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F297D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F2CBC, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F2CD4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F31EB, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F325C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F35B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F3DDE, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F405B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F49B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F5462, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F5699, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F5D0C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F5DC8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F5F9C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F8606, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F8B62, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F9199, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F94AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2F963D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FA559, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FA844, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FABA6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FACF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FAE9B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FBAF3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FBC04, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FBFDD, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FC5AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FD81C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FDABE, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FDBA6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FDE4A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FE0DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FE208, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FE568, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E2FE56B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E301266, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E30213F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E30E5E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E314714, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E337866, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E339FA4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E341CCA, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E344588, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E345BC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E34709C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E3500BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E3543BB, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E3578C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E35D113, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E36B32D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E36B849, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E37167F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E371BD3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E37EECD, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E382816, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E38837E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E448EF1, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E455699, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E460AE6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E559863, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E55C395, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E582ECD, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E5A0FE5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E5A8252, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E5E71A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E5EC2DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E5EFD61, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E66CF73, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E6A9813, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E6BE9E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E6BED10, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E6BEFD5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E6BFE79, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E6C3F2C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E6C3F2E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E6EA0B9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E6F4E8C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E6FEE6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E73B49D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E787A3F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E81891C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E81A639, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E81B421, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E833886, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E8B7228, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E8D50EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E8E8EF6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E8E918D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E8EAF46, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E91349D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E9BA97A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E9C75EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E9C77C8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E9DC871, 32, NDPI_PROTOCOL_TOR },
+ { 0x4E9F3CC3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EC0BD4C, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EC0F14B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EC1067E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EC128CD, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EC128FE, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EC14F78, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EC15603, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EC1674D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EC1A442, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EC6B4CD, 32, NDPI_PROTOCOL_TOR },
+ { 0x4ECD5081, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EDA527F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EDD8C72, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EE030F7, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EE0F0C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EE2A060, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EE588B8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EE96597, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EEC369E, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EEF7556, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EF7B665, 32, NDPI_PROTOCOL_TOR },
+ { 0x4EF8D759, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F4771F0, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F501132, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F59660B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F621F2A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F660402, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F6D109F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F6D94CB, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F6F13C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F6F51A0, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F6FDA32, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F700984, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F716914, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F780A62, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F78282D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F7851B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F825F7B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F861BFF, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F86EAC8, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F86EB05, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F86FF23, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F87465A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F881D2B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F882ABE, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F8BBDB9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F8C27CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F8C2975, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F8C2976, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F8C4005, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F8E6A54, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F8FB36A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F8FB572, 32, NDPI_PROTOCOL_TOR },
+ { 0x4F8FBC46, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FA04C99, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FA0A26A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FA438F1, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FA45FB4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FA5B4F3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FA5DFD1, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FAC1212, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FAC1CCD, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FACC120, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FACCC24, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FACF908, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FB73E97, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FBD0233, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FC17B35, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FC3BA9D, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FC5C597, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FC8C7B3, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FCA6B3A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FCB519B, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FD446F9, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FD62F35, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FD6C9C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FD6E742, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FD7DEA0, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FDCC79F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FE25CA4, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FE2CDCD, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FE2DAE6, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FE3BBBF, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FE478A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FE4EA15, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FE5C024, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FE755CF, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FEA50ED, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FEB63B5, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FEC5A62, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FECD8B0, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FF15810, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FF19FF7, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FF1D2DC, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FF1D690, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FF2515A, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FF35735, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FF5435F, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FF58FAB, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FF6CF32, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FF77321, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FF87986, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FFBF5CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x4FFF9947, 32, NDPI_PROTOCOL_TOR },
+ { 0x50025741, 32, NDPI_PROTOCOL_TOR },
+ { 0x5004F810, 32, NDPI_PROTOCOL_TOR },
+ { 0x500593F5, 32, NDPI_PROTOCOL_TOR },
+ { 0x500C5EB8, 32, NDPI_PROTOCOL_TOR },
+ { 0x502A9965, 32, NDPI_PROTOCOL_TOR },
+ { 0x502AA456, 32, NDPI_PROTOCOL_TOR },
+ { 0x50390AA9, 32, NDPI_PROTOCOL_TOR },
+ { 0x50393FB3, 32, NDPI_PROTOCOL_TOR },
+ { 0x50397C3A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5042877B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5043AC13, 32, NDPI_PROTOCOL_TOR },
+ { 0x504459B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x50445CF9, 32, NDPI_PROTOCOL_TOR },
+ { 0x50478577, 32, NDPI_PROTOCOL_TOR },
+ { 0x504786B5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5049D3D9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5049F28E, 32, NDPI_PROTOCOL_TOR },
+ { 0x504EF251, 32, NDPI_PROTOCOL_TOR },
+ { 0x504EF656, 32, NDPI_PROTOCOL_TOR },
+ { 0x504F1707, 32, NDPI_PROTOCOL_TOR },
+ { 0x5051111F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5051F378, 32, NDPI_PROTOCOL_TOR },
+ { 0x5051F3E2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5051F3EB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5052D7D2, 32, NDPI_PROTOCOL_TOR },
+ { 0x50555448, 32, NDPI_PROTOCOL_TOR },
+ { 0x505554DE, 32, NDPI_PROTOCOL_TOR },
+ { 0x505554F0, 32, NDPI_PROTOCOL_TOR },
+ { 0x50565329, 32, NDPI_PROTOCOL_TOR },
+ { 0x50565CB5, 32, NDPI_PROTOCOL_TOR },
+ { 0x50565D80, 32, NDPI_PROTOCOL_TOR },
+ { 0x5059C09E, 32, NDPI_PROTOCOL_TOR },
+ { 0x505A2B81, 32, NDPI_PROTOCOL_TOR },
+ { 0x505A2BDD, 32, NDPI_PROTOCOL_TOR },
+ { 0x50631FF8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5063FE73, 32, NDPI_PROTOCOL_TOR },
+ { 0x50642620, 32, NDPI_PROTOCOL_TOR },
+ { 0x50642CDB, 32, NDPI_PROTOCOL_TOR },
+ { 0x50642CFD, 32, NDPI_PROTOCOL_TOR },
+ { 0x50642D9C, 32, NDPI_PROTOCOL_TOR },
+ { 0x50648003, 32, NDPI_PROTOCOL_TOR },
+ { 0x5064BD03, 32, NDPI_PROTOCOL_TOR },
+ { 0x5064CC04, 32, NDPI_PROTOCOL_TOR },
+ { 0x5064CE96, 32, NDPI_PROTOCOL_TOR },
+ { 0x506573AA, 32, NDPI_PROTOCOL_TOR },
+ { 0x506C8F13, 32, NDPI_PROTOCOL_TOR },
+ { 0x506DA2EA, 32, NDPI_PROTOCOL_TOR },
+ { 0x506DE134, 32, NDPI_PROTOCOL_TOR },
+ { 0x506E2316, 32, NDPI_PROTOCOL_TOR },
+ { 0x506E37C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x506FEC0F, 32, NDPI_PROTOCOL_TOR },
+ { 0x50709921, 32, NDPI_PROTOCOL_TOR },
+ { 0x5071010B, 32, NDPI_PROTOCOL_TOR },
+ { 0x50743860, 32, NDPI_PROTOCOL_TOR },
+ { 0x50764CC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x50807E83, 32, NDPI_PROTOCOL_TOR },
+ { 0x50814072, 32, NDPI_PROTOCOL_TOR },
+ { 0x50868F7F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5087E176, 32, NDPI_PROTOCOL_TOR },
+ { 0x508874C1, 32, NDPI_PROTOCOL_TOR },
+ { 0x50894240, 32, NDPI_PROTOCOL_TOR },
+ { 0x508AEC03, 32, NDPI_PROTOCOL_TOR },
+ { 0x508AEFF3, 32, NDPI_PROTOCOL_TOR },
+ { 0x508B637B, 32, NDPI_PROTOCOL_TOR },
+ { 0x508B727D, 32, NDPI_PROTOCOL_TOR },
+ { 0x508C6003, 32, NDPI_PROTOCOL_TOR },
+ { 0x508F6A3C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5093219D, 32, NDPI_PROTOCOL_TOR },
+ { 0x509325F7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5098EF17, 32, NDPI_PROTOCOL_TOR },
+ { 0x50990704, 32, NDPI_PROTOCOL_TOR },
+ { 0x50A19C30, 32, NDPI_PROTOCOL_TOR },
+ { 0x50A20720, 32, NDPI_PROTOCOL_TOR },
+ { 0x50A32958, 32, NDPI_PROTOCOL_TOR },
+ { 0x50A770EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x50AB1353, 32, NDPI_PROTOCOL_TOR },
+ { 0x50AB285B, 32, NDPI_PROTOCOL_TOR },
+ { 0x50C3B7F0, 32, NDPI_PROTOCOL_TOR },
+ { 0x50CAAF5A, 32, NDPI_PROTOCOL_TOR },
+ { 0x50CAEE20, 32, NDPI_PROTOCOL_TOR },
+ { 0x50CB102E, 32, NDPI_PROTOCOL_TOR },
+ { 0x50D4A2ED, 32, NDPI_PROTOCOL_TOR },
+ { 0x50D87BFC, 32, NDPI_PROTOCOL_TOR },
+ { 0x50DA9F57, 32, NDPI_PROTOCOL_TOR },
+ { 0x50DAD94E, 32, NDPI_PROTOCOL_TOR },
+ { 0x50DB0244, 32, NDPI_PROTOCOL_TOR },
+ { 0x50DB8C29, 32, NDPI_PROTOCOL_TOR },
+ { 0x50DC5274, 32, NDPI_PROTOCOL_TOR },
+ { 0x50DCE66B, 32, NDPI_PROTOCOL_TOR },
+ { 0x50DCF46B, 32, NDPI_PROTOCOL_TOR },
+ { 0x50DFA940, 32, NDPI_PROTOCOL_TOR },
+ { 0x50DFB670, 32, NDPI_PROTOCOL_TOR },
+ { 0x50DFD0F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x50E500D2, 32, NDPI_PROTOCOL_TOR },
+ { 0x50EDE24B, 32, NDPI_PROTOCOL_TOR },
+ { 0x50EEE5A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F08096, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F080E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F086F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F08D97, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F1D942, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F1DA9A, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F1DCDD, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F1DE24, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F1DE62, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F4F39E, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F63BE9, 32, NDPI_PROTOCOL_TOR },
+ { 0x50F8D083, 32, NDPI_PROTOCOL_TOR },
+ { 0x50FEDB30, 32, NDPI_PROTOCOL_TOR },
+ { 0x50FF0BD3, 32, NDPI_PROTOCOL_TOR },
+ { 0x50FF0BE0, 32, NDPI_PROTOCOL_TOR },
+ { 0x50FF0BED, 32, NDPI_PROTOCOL_TOR },
+ { 0x5102C521, 32, NDPI_PROTOCOL_TOR },
+ { 0x5102ECA5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5104655D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5104676A, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046810, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046852, 32, NDPI_PROTOCOL_TOR },
+ { 0x510469C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046B24, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046B44, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046BBE, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046BE3, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046CC7, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046D2F, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046D7D, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046DD0, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046DFA, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046E5D, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046E95, 32, NDPI_PROTOCOL_TOR },
+ { 0x51046F6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x51047930, 32, NDPI_PROTOCOL_TOR },
+ { 0x510479B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x510479DE, 32, NDPI_PROTOCOL_TOR },
+ { 0x510479E0, 32, NDPI_PROTOCOL_TOR },
+ { 0x510479F3, 32, NDPI_PROTOCOL_TOR },
+ { 0x51047D81, 32, NDPI_PROTOCOL_TOR },
+ { 0x51047E79, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070777, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070865, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070A11, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070A1D, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070A1D, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070A44, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070AFB, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070B46, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070BFD, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070D54, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070D5A, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070DF8, 32, NDPI_PROTOCOL_TOR },
+ { 0x51070EF6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5107103B, 32, NDPI_PROTOCOL_TOR },
+ { 0x510A9F12, 32, NDPI_PROTOCOL_TOR },
+ { 0x511115F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5114849E, 32, NDPI_PROTOCOL_TOR },
+ { 0x51148B91, 32, NDPI_PROTOCOL_TOR },
+ { 0x5115F642, 32, NDPI_PROTOCOL_TOR },
+ { 0x511932A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x511CC585, 32, NDPI_PROTOCOL_TOR },
+ { 0x511E9858, 32, NDPI_PROTOCOL_TOR },
+ { 0x511E9858, 32, NDPI_PROTOCOL_TOR },
+ { 0x511F5A52, 32, NDPI_PROTOCOL_TOR },
+ { 0x513842D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5139852A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5139D087, 32, NDPI_PROTOCOL_TOR },
+ { 0x514080DE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5140E6FD, 32, NDPI_PROTOCOL_TOR },
+ { 0x51475D6A, 32, NDPI_PROTOCOL_TOR },
+ { 0x51533A04, 32, NDPI_PROTOCOL_TOR },
+ { 0x51544C43, 32, NDPI_PROTOCOL_TOR },
+ { 0x51569E1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x515900C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x515900C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x515900C5, 32, NDPI_PROTOCOL_TOR },
+ { 0x515900C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x515900C7, 32, NDPI_PROTOCOL_TOR },
+ { 0x515900C8, 32, NDPI_PROTOCOL_TOR },
+ { 0x515900C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x515900CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x515900CB, 32, NDPI_PROTOCOL_TOR },
+ { 0x515900CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x51596058, 32, NDPI_PROTOCOL_TOR },
+ { 0x51596059, 32, NDPI_PROTOCOL_TOR },
+ { 0x51596535, 32, NDPI_PROTOCOL_TOR },
+ { 0x515CACE7, 32, NDPI_PROTOCOL_TOR },
+ { 0x515F0522, 32, NDPI_PROTOCOL_TOR },
+ { 0x515F3444, 32, NDPI_PROTOCOL_TOR },
+ { 0x5160DB54, 32, NDPI_PROTOCOL_TOR },
+ { 0x5161B784, 32, NDPI_PROTOCOL_TOR },
+ { 0x5163F715, 32, NDPI_PROTOCOL_TOR },
+ { 0x51669B3F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5166F93D, 32, NDPI_PROTOCOL_TOR },
+ { 0x516A0C3C, 32, NDPI_PROTOCOL_TOR },
+ { 0x516B907F, 32, NDPI_PROTOCOL_TOR },
+ { 0x516D69B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x51853556, 32, NDPI_PROTOCOL_TOR },
+ { 0x518D6888, 32, NDPI_PROTOCOL_TOR },
+ { 0x519840EA, 32, NDPI_PROTOCOL_TOR },
+ { 0x519FC5DE, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A64037, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A98234, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A982D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A988CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A98D5C, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A98D5E, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A9957C, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A99864, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A999A7, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A99F52, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A9A86A, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A9AFA4, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A9B42B, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A9B92C, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A9D13A, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A9D20B, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A9D72F, 32, NDPI_PROTOCOL_TOR },
+ { 0x51A9FFEB, 32, NDPI_PROTOCOL_TOR },
+ { 0x51AA95F0, 32, NDPI_PROTOCOL_TOR },
+ { 0x51AAD96B, 32, NDPI_PROTOCOL_TOR },
+ { 0x51AAFFB8, 32, NDPI_PROTOCOL_TOR },
+ { 0x51AC174F, 32, NDPI_PROTOCOL_TOR },
+ { 0x51ADF051, 32, NDPI_PROTOCOL_TOR },
+ { 0x51AEE712, 32, NDPI_PROTOCOL_TOR },
+ { 0x51B0E436, 32, NDPI_PROTOCOL_TOR },
+ { 0x51B73F2E, 32, NDPI_PROTOCOL_TOR },
+ { 0x51B8EB2B, 32, NDPI_PROTOCOL_TOR },
+ { 0x51BAF377, 32, NDPI_PROTOCOL_TOR },
+ { 0x51BB1C09, 32, NDPI_PROTOCOL_TOR },
+ { 0x51BBD20D, 32, NDPI_PROTOCOL_TOR },
+ { 0x51BF7137, 32, NDPI_PROTOCOL_TOR },
+ { 0x51C93CED, 32, NDPI_PROTOCOL_TOR },
+ { 0x51CB9655, 32, NDPI_PROTOCOL_TOR },
+ { 0x51CD17DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x51D91056, 32, NDPI_PROTOCOL_TOR },
+ { 0x51D974C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x51D987C8, 32, NDPI_PROTOCOL_TOR },
+ { 0x51D99D5A, 32, NDPI_PROTOCOL_TOR },
+ { 0x51DA5B9A, 32, NDPI_PROTOCOL_TOR },
+ { 0x51DA6D6A, 32, NDPI_PROTOCOL_TOR },
+ { 0x51DA6DC3, 32, NDPI_PROTOCOL_TOR },
+ { 0x51DAEBA2, 32, NDPI_PROTOCOL_TOR },
+ { 0x51DB33CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x51DCA3CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x51DD555D, 32, NDPI_PROTOCOL_TOR },
+ { 0x51DFD766, 32, NDPI_PROTOCOL_TOR },
+ { 0x51E735A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x51E75573, 32, NDPI_PROTOCOL_TOR },
+ { 0x51E7A4A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x51E7E226, 32, NDPI_PROTOCOL_TOR },
+ { 0x51E9E3A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x51F285B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x51F6CAA9, 32, NDPI_PROTOCOL_TOR },
+ { 0x51F777FC, 32, NDPI_PROTOCOL_TOR },
+ { 0x52018046, 32, NDPI_PROTOCOL_TOR },
+ { 0x5206BA74, 32, NDPI_PROTOCOL_TOR },
+ { 0x5209EEF6, 32, NDPI_PROTOCOL_TOR },
+ { 0x520CAF74, 32, NDPI_PROTOCOL_TOR },
+ { 0x520DF0B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5213FC52, 32, NDPI_PROTOCOL_TOR },
+ { 0x52145714, 32, NDPI_PROTOCOL_TOR },
+ { 0x52173C4E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5219BB97, 32, NDPI_PROTOCOL_TOR },
+ { 0x521CC556, 32, NDPI_PROTOCOL_TOR },
+ { 0x521E7362, 32, NDPI_PROTOCOL_TOR },
+ { 0x521F29D7, 32, NDPI_PROTOCOL_TOR },
+ { 0x52239D60, 32, NDPI_PROTOCOL_TOR },
+ { 0x522BA860, 32, NDPI_PROTOCOL_TOR },
+ { 0x522DB96B, 32, NDPI_PROTOCOL_TOR },
+ { 0x522FE271, 32, NDPI_PROTOCOL_TOR },
+ { 0x52303D0C, 32, NDPI_PROTOCOL_TOR },
+ { 0x52343FD9, 32, NDPI_PROTOCOL_TOR },
+ { 0x52424777, 32, NDPI_PROTOCOL_TOR },
+ { 0x52449E7C, 32, NDPI_PROTOCOL_TOR },
+ { 0x52450ECF, 32, NDPI_PROTOCOL_TOR },
+ { 0x52453232, 32, NDPI_PROTOCOL_TOR },
+ { 0x52462723, 32, NDPI_PROTOCOL_TOR },
+ { 0x524805A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x52483D51, 32, NDPI_PROTOCOL_TOR },
+ { 0x5248765A, 32, NDPI_PROTOCOL_TOR },
+ { 0x52493309, 32, NDPI_PROTOCOL_TOR },
+ { 0x5249DF9D, 32, NDPI_PROTOCOL_TOR },
+ { 0x524A04F3, 32, NDPI_PROTOCOL_TOR },
+ { 0x524C4802, 32, NDPI_PROTOCOL_TOR },
+ { 0x52502163, 32, NDPI_PROTOCOL_TOR },
+ { 0x525088B9, 32, NDPI_PROTOCOL_TOR },
+ { 0x52532E63, 32, NDPI_PROTOCOL_TOR },
+ { 0x525EF2DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x525EFBCB, 32, NDPI_PROTOCOL_TOR },
+ { 0x525EFBCC, 32, NDPI_PROTOCOL_TOR },
+ { 0x525EFBE3, 32, NDPI_PROTOCOL_TOR },
+ { 0x525F42CB, 32, NDPI_PROTOCOL_TOR },
+ { 0x525F6B33, 32, NDPI_PROTOCOL_TOR },
+ { 0x525FEBF9, 32, NDPI_PROTOCOL_TOR },
+ { 0x52624850, 32, NDPI_PROTOCOL_TOR },
+ { 0x52668ED2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5270985F, 32, NDPI_PROTOCOL_TOR },
+ { 0x52736339, 32, NDPI_PROTOCOL_TOR },
+ { 0x52747803, 32, NDPI_PROTOCOL_TOR },
+ { 0x52761386, 32, NDPI_PROTOCOL_TOR },
+ { 0x5276F21E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5276F24F, 32, NDPI_PROTOCOL_TOR },
+ { 0x527E663F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5280FFFC, 32, NDPI_PROTOCOL_TOR },
+ { 0x52821A24, 32, NDPI_PROTOCOL_TOR },
+ { 0x5282285C, 32, NDPI_PROTOCOL_TOR },
+ { 0x52886403, 32, NDPI_PROTOCOL_TOR },
+ { 0x528B5EFC, 32, NDPI_PROTOCOL_TOR },
+ { 0x528B6271, 32, NDPI_PROTOCOL_TOR },
+ { 0x52921BD1, 32, NDPI_PROTOCOL_TOR },
+ { 0x529EEB26, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A1321E, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A13526, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A15B0D, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A16D47, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A1B614, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A1D257, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A1D4D1, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A1DF89, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A1EFB1, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A1FCA2, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A41BE4, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A50F97, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A58E4F, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A5C581, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A898B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A92496, 32, NDPI_PROTOCOL_TOR },
+ { 0x52A99B48, 32, NDPI_PROTOCOL_TOR },
+ { 0x52B1EEF0, 32, NDPI_PROTOCOL_TOR },
+ { 0x52B419BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x52B583A0, 32, NDPI_PROTOCOL_TOR },
+ { 0x52B6B40F, 32, NDPI_PROTOCOL_TOR },
+ { 0x52B70EC3, 32, NDPI_PROTOCOL_TOR },
+ { 0x52C0F11E, 32, NDPI_PROTOCOL_TOR },
+ { 0x52C409DF, 32, NDPI_PROTOCOL_TOR },
+ { 0x52C40E41, 32, NDPI_PROTOCOL_TOR },
+ { 0x52C5D42F, 32, NDPI_PROTOCOL_TOR },
+ { 0x52C79B59, 32, NDPI_PROTOCOL_TOR },
+ { 0x52C7C0A7, 32, NDPI_PROTOCOL_TOR },
+ { 0x52CBC340, 32, NDPI_PROTOCOL_TOR },
+ { 0x52D300C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x52D3138F, 32, NDPI_PROTOCOL_TOR },
+ { 0x52D3C9BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x52D3DF03, 32, NDPI_PROTOCOL_TOR },
+ { 0x52D8FE03, 32, NDPI_PROTOCOL_TOR },
+ { 0x52D91190, 32, NDPI_PROTOCOL_TOR },
+ { 0x52DB0959, 32, NDPI_PROTOCOL_TOR },
+ { 0x52DC5914, 32, NDPI_PROTOCOL_TOR },
+ { 0x52DD64C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x52DD6500, 32, NDPI_PROTOCOL_TOR },
+ { 0x52DD693D, 32, NDPI_PROTOCOL_TOR },
+ { 0x52DF08FC, 32, NDPI_PROTOCOL_TOR },
+ { 0x52DF0A44, 32, NDPI_PROTOCOL_TOR },
+ { 0x52DF0B22, 32, NDPI_PROTOCOL_TOR },
+ { 0x52DF179B, 32, NDPI_PROTOCOL_TOR },
+ { 0x52E08A09, 32, NDPI_PROTOCOL_TOR },
+ { 0x52E33F62, 32, NDPI_PROTOCOL_TOR },
+ { 0x52E4FC14, 32, NDPI_PROTOCOL_TOR },
+ { 0x52E53CF5, 32, NDPI_PROTOCOL_TOR },
+ { 0x52E58A1F, 32, NDPI_PROTOCOL_TOR },
+ { 0x52E97597, 32, NDPI_PROTOCOL_TOR },
+ { 0x52EA8DC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x52EBD32A, 32, NDPI_PROTOCOL_TOR },
+ { 0x52EC7EF6, 32, NDPI_PROTOCOL_TOR },
+ { 0x52EC89EB, 32, NDPI_PROTOCOL_TOR },
+ { 0x52EDD8E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x52EED0AD, 32, NDPI_PROTOCOL_TOR },
+ { 0x52EF14AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x52F1EC57, 32, NDPI_PROTOCOL_TOR },
+ { 0x52F298D3, 32, NDPI_PROTOCOL_TOR },
+ { 0x52F313CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x52F34F09, 32, NDPI_PROTOCOL_TOR },
+ { 0x52F4B127, 32, NDPI_PROTOCOL_TOR },
+ { 0x52F5C791, 32, NDPI_PROTOCOL_TOR },
+ { 0x52F76775, 32, NDPI_PROTOCOL_TOR },
+ { 0x52FA311C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5306C520, 32, NDPI_PROTOCOL_TOR },
+ { 0x5306EE3D, 32, NDPI_PROTOCOL_TOR },
+ { 0x531BFBEF, 32, NDPI_PROTOCOL_TOR },
+ { 0x53244725, 32, NDPI_PROTOCOL_TOR },
+ { 0x532CE6B0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5335F24A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5338EA93, 32, NDPI_PROTOCOL_TOR },
+ { 0x53451C51, 32, NDPI_PROTOCOL_TOR },
+ { 0x534C9E3E, 32, NDPI_PROTOCOL_TOR },
+ { 0x534E1005, 32, NDPI_PROTOCOL_TOR },
+ { 0x535269F0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5352C0E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5352F4DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x53530B96, 32, NDPI_PROTOCOL_TOR },
+ { 0x535352B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x53542E39, 32, NDPI_PROTOCOL_TOR },
+ { 0x53556653, 32, NDPI_PROTOCOL_TOR },
+ { 0x5355D16B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5355FC5B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5357C9F9, 32, NDPI_PROTOCOL_TOR },
+ { 0x53591FF9, 32, NDPI_PROTOCOL_TOR },
+ { 0x535D3740, 32, NDPI_PROTOCOL_TOR },
+ { 0x53638E4F, 32, NDPI_PROTOCOL_TOR },
+ { 0x53650553, 32, NDPI_PROTOCOL_TOR },
+ { 0x5365431F, 32, NDPI_PROTOCOL_TOR },
+ { 0x537560B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x53809409, 32, NDPI_PROTOCOL_TOR },
+ { 0x5380C8F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5382722D, 32, NDPI_PROTOCOL_TOR },
+ { 0x53857F91, 32, NDPI_PROTOCOL_TOR },
+ { 0x5386DFC1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5387F0D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x538C0BFC, 32, NDPI_PROTOCOL_TOR },
+ { 0x538FDBD4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5390693A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5391EDE0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5391F1E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5391F3D7, 32, NDPI_PROTOCOL_TOR },
+ { 0x539354E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x53957C88, 32, NDPI_PROTOCOL_TOR },
+ { 0x53957C88, 32, NDPI_PROTOCOL_TOR },
+ { 0x53957C89, 32, NDPI_PROTOCOL_TOR },
+ { 0x53957C89, 32, NDPI_PROTOCOL_TOR },
+ { 0x53957E1D, 32, NDPI_PROTOCOL_TOR },
+ { 0x53957F8C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5395F9A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5396023D, 32, NDPI_PROTOCOL_TOR },
+ { 0x53961097, 32, NDPI_PROTOCOL_TOR },
+ { 0x539610F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x53961184, 32, NDPI_PROTOCOL_TOR },
+ { 0x5396527A, 32, NDPI_PROTOCOL_TOR },
+ { 0x539C0058, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A05F63, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A19832, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A2026F, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A2BC64, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A2C060, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A2CD44, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A34DC3, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A3C9A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A59347, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A6EA5C, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A6EA6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A7B923, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A7B964, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A7E46B, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A8C8CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A91607, 32, NDPI_PROTOCOL_TOR },
+ { 0x53A92DE7, 32, NDPI_PROTOCOL_TOR },
+ { 0x53AB9437, 32, NDPI_PROTOCOL_TOR },
+ { 0x53ABBE6A, 32, NDPI_PROTOCOL_TOR },
+ { 0x53AEFA7D, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D19271, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D454DF, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D460B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D46270, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D46344, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D4637B, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D46612, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D4687C, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D46891, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D47185, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D47ED3, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D4A8BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x53D8F8E0, 32, NDPI_PROTOCOL_TOR },
+ { 0x53DE8DEB, 32, NDPI_PROTOCOL_TOR },
+ { 0x53E2EEA8, 32, NDPI_PROTOCOL_TOR },
+ { 0x53E334A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x53E45D4C, 32, NDPI_PROTOCOL_TOR },
+ { 0x53E71225, 32, NDPI_PROTOCOL_TOR },
+ { 0x53E941D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x53E98714, 32, NDPI_PROTOCOL_TOR },
+ { 0x53E9A8E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x53ECD04E, 32, NDPI_PROTOCOL_TOR },
+ { 0x53ED1577, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F03D90, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F042A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F077B0, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F65317, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F6A4BB, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F6D985, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F74E5A, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F80E85, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F88441, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F8A214, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F8B2D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x53F946BE, 32, NDPI_PROTOCOL_TOR },
+ { 0x53FA5511, 32, NDPI_PROTOCOL_TOR },
+ { 0x53FB40E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x53FB515D, 32, NDPI_PROTOCOL_TOR },
+ { 0x53FB5AA6, 32, NDPI_PROTOCOL_TOR },
+ { 0x53FB864C, 32, NDPI_PROTOCOL_TOR },
+ { 0x53FD36CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x53FDBBDA, 32, NDPI_PROTOCOL_TOR },
+ { 0x53FE5430, 32, NDPI_PROTOCOL_TOR },
+ { 0x53FF6645, 32, NDPI_PROTOCOL_TOR },
+ { 0x53FFCBAC, 32, NDPI_PROTOCOL_TOR },
+ { 0x540A6F0A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5413B234, 32, NDPI_PROTOCOL_TOR },
+ { 0x5413B3E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5413B450, 32, NDPI_PROTOCOL_TOR },
+ { 0x54162AF6, 32, NDPI_PROTOCOL_TOR },
+ { 0x54191CBA, 32, NDPI_PROTOCOL_TOR },
+ { 0x541B5EF7, 32, NDPI_PROTOCOL_TOR },
+ { 0x541EBB28, 32, NDPI_PROTOCOL_TOR },
+ { 0x541FC855, 32, NDPI_PROTOCOL_TOR },
+ { 0x54284D55, 32, NDPI_PROTOCOL_TOR },
+ { 0x542862BB, 32, NDPI_PROTOCOL_TOR },
+ { 0x54287046, 32, NDPI_PROTOCOL_TOR },
+ { 0x542AA5A2, 32, NDPI_PROTOCOL_TOR },
+ { 0x542D4C0A, 32, NDPI_PROTOCOL_TOR },
+ { 0x542D4C0B, 32, NDPI_PROTOCOL_TOR },
+ { 0x542D4C0C, 32, NDPI_PROTOCOL_TOR },
+ { 0x542D4C0D, 32, NDPI_PROTOCOL_TOR },
+ { 0x542E3EBA, 32, NDPI_PROTOCOL_TOR },
+ { 0x54303AC3, 32, NDPI_PROTOCOL_TOR },
+ { 0x54321453, 32, NDPI_PROTOCOL_TOR },
+ { 0x54380652, 32, NDPI_PROTOCOL_TOR },
+ { 0x54382C54, 32, NDPI_PROTOCOL_TOR },
+ { 0x5439BD00, 32, NDPI_PROTOCOL_TOR },
+ { 0x543BE658, 32, NDPI_PROTOCOL_TOR },
+ { 0x543C046D, 32, NDPI_PROTOCOL_TOR },
+ { 0x544815A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5448B905, 32, NDPI_PROTOCOL_TOR },
+ { 0x5448D5DD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5448DFC7, 32, NDPI_PROTOCOL_TOR },
+ { 0x544980C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x544A0BDE, 32, NDPI_PROTOCOL_TOR },
+ { 0x544A7D55, 32, NDPI_PROTOCOL_TOR },
+ { 0x544AACE8, 32, NDPI_PROTOCOL_TOR },
+ { 0x544B0C49, 32, NDPI_PROTOCOL_TOR },
+ { 0x5454D02F, 32, NDPI_PROTOCOL_TOR },
+ { 0x545C18D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x545C18D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x545C6C78, 32, NDPI_PROTOCOL_TOR },
+ { 0x54674A57, 32, NDPI_PROTOCOL_TOR },
+ { 0x5468A93B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5469DCFF, 32, NDPI_PROTOCOL_TOR },
+ { 0x546A4A9E, 32, NDPI_PROTOCOL_TOR },
+ { 0x546CCDB5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5470EE3A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5470EE3A, 32, NDPI_PROTOCOL_TOR },
+ { 0x54711102, 32, NDPI_PROTOCOL_TOR },
+ { 0x5471F5B1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5472F1DF, 32, NDPI_PROTOCOL_TOR },
+ { 0x54732E95, 32, NDPI_PROTOCOL_TOR },
+ { 0x5475164A, 32, NDPI_PROTOCOL_TOR },
+ { 0x54767531, 32, NDPI_PROTOCOL_TOR },
+ { 0x547688FC, 32, NDPI_PROTOCOL_TOR },
+ { 0x54779B30, 32, NDPI_PROTOCOL_TOR },
+ { 0x5477EDED, 32, NDPI_PROTOCOL_TOR },
+ { 0x547BB3B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x547D73EA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5481A36E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5481DC92, 32, NDPI_PROTOCOL_TOR },
+ { 0x548524F3, 32, NDPI_PROTOCOL_TOR },
+ { 0x548A010A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5493E1C8, 32, NDPI_PROTOCOL_TOR },
+ { 0x54947094, 32, NDPI_PROTOCOL_TOR },
+ { 0x5499DCA5, 32, NDPI_PROTOCOL_TOR },
+ { 0x549CFEEC, 32, NDPI_PROTOCOL_TOR },
+ { 0x549FE146, 32, NDPI_PROTOCOL_TOR },
+ { 0x549FEA53, 32, NDPI_PROTOCOL_TOR },
+ { 0x549FEA53, 32, NDPI_PROTOCOL_TOR },
+ { 0x54A202DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x54AD608B, 32, NDPI_PROTOCOL_TOR },
+ { 0x54AEB5BD, 32, NDPI_PROTOCOL_TOR },
+ { 0x54AFCF54, 32, NDPI_PROTOCOL_TOR },
+ { 0x54AFF159, 32, NDPI_PROTOCOL_TOR },
+ { 0x54B35824, 32, NDPI_PROTOCOL_TOR },
+ { 0x54B46D3C, 32, NDPI_PROTOCOL_TOR },
+ { 0x54B67B82, 32, NDPI_PROTOCOL_TOR },
+ { 0x54B75D03, 32, NDPI_PROTOCOL_TOR },
+ { 0x54B77113, 32, NDPI_PROTOCOL_TOR },
+ { 0x54B771CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x54B7F756, 32, NDPI_PROTOCOL_TOR },
+ { 0x54BA9896, 32, NDPI_PROTOCOL_TOR },
+ { 0x54BAD4B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x54C14BF3, 32, NDPI_PROTOCOL_TOR },
+ { 0x54C80821, 32, NDPI_PROTOCOL_TOR },
+ { 0x54C808AF, 32, NDPI_PROTOCOL_TOR },
+ { 0x54C808CF, 32, NDPI_PROTOCOL_TOR },
+ { 0x54C80AD1, 32, NDPI_PROTOCOL_TOR },
+ { 0x54C849EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x54C84DF3, 32, NDPI_PROTOCOL_TOR },
+ { 0x54C852A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x54C853D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x54C90487, 32, NDPI_PROTOCOL_TOR },
+ { 0x54C923CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x54CA3612, 32, NDPI_PROTOCOL_TOR },
+ { 0x54D08C30, 32, NDPI_PROTOCOL_TOR },
+ { 0x54D10F3F, 32, NDPI_PROTOCOL_TOR },
+ { 0x54D14924, 32, NDPI_PROTOCOL_TOR },
+ { 0x54D358E2, 32, NDPI_PROTOCOL_TOR },
+ { 0x54D7D347, 32, NDPI_PROTOCOL_TOR },
+ { 0x54DBAAE7, 32, NDPI_PROTOCOL_TOR },
+ { 0x54DBC1BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x54E26D6D, 32, NDPI_PROTOCOL_TOR },
+ { 0x54EA9B51, 32, NDPI_PROTOCOL_TOR },
+ { 0x54EA9B51, 32, NDPI_PROTOCOL_TOR },
+ { 0x54EA9B52, 32, NDPI_PROTOCOL_TOR },
+ { 0x54EA9B52, 32, NDPI_PROTOCOL_TOR },
+ { 0x54F270BE, 32, NDPI_PROTOCOL_TOR },
+ { 0x54F41F34, 32, NDPI_PROTOCOL_TOR },
+ { 0x54F520C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x54F52108, 32, NDPI_PROTOCOL_TOR },
+ { 0x54F8529C, 32, NDPI_PROTOCOL_TOR },
+ { 0x54F86B2C, 32, NDPI_PROTOCOL_TOR },
+ { 0x54F8805F, 32, NDPI_PROTOCOL_TOR },
+ { 0x54F9C0D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x54FA6A0D, 32, NDPI_PROTOCOL_TOR },
+ { 0x54FB736F, 32, NDPI_PROTOCOL_TOR },
+ { 0x54FB7CF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x550180C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5502F728, 32, NDPI_PROTOCOL_TOR },
+ { 0x55037656, 32, NDPI_PROTOCOL_TOR },
+ { 0x5504E453, 32, NDPI_PROTOCOL_TOR },
+ { 0x55082B53, 32, NDPI_PROTOCOL_TOR },
+ { 0x550AC409, 32, NDPI_PROTOCOL_TOR },
+ { 0x550AC40C, 32, NDPI_PROTOCOL_TOR },
+ { 0x550AC6EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x550AC8E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x550AC92F, 32, NDPI_PROTOCOL_TOR },
+ { 0x550ACA57, 32, NDPI_PROTOCOL_TOR },
+ { 0x550ACB47, 32, NDPI_PROTOCOL_TOR },
+ { 0x550ACBC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x550AD2C7, 32, NDPI_PROTOCOL_TOR },
+ { 0x550AD335, 32, NDPI_PROTOCOL_TOR },
+ { 0x550ADBA7, 32, NDPI_PROTOCOL_TOR },
+ { 0x550AED68, 32, NDPI_PROTOCOL_TOR },
+ { 0x550AF0FA, 32, NDPI_PROTOCOL_TOR },
+ { 0x550EF020, 32, NDPI_PROTOCOL_TOR },
+ { 0x550EF021, 32, NDPI_PROTOCOL_TOR },
+ { 0x550EF022, 32, NDPI_PROTOCOL_TOR },
+ { 0x550EF023, 32, NDPI_PROTOCOL_TOR },
+ { 0x550EF0BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x550EF0BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5511185F, 32, NDPI_PROTOCOL_TOR },
+ { 0x551184F5, 32, NDPI_PROTOCOL_TOR },
+ { 0x551184F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x55118DAE, 32, NDPI_PROTOCOL_TOR },
+ { 0x551194E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5511A451, 32, NDPI_PROTOCOL_TOR },
+ { 0x5511B149, 32, NDPI_PROTOCOL_TOR },
+ { 0x5511BE4D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5511BE4D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5511BE4F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5511BE4F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5511BE52, 32, NDPI_PROTOCOL_TOR },
+ { 0x5511BE53, 32, NDPI_PROTOCOL_TOR },
+ { 0x5511F893, 32, NDPI_PROTOCOL_TOR },
+ { 0x551590E2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5516679A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5517911A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5517F393, 32, NDPI_PROTOCOL_TOR },
+ { 0x5518D772, 32, NDPI_PROTOCOL_TOR },
+ { 0x5518D773, 32, NDPI_PROTOCOL_TOR },
+ { 0x5518D774, 32, NDPI_PROTOCOL_TOR },
+ { 0x5518D775, 32, NDPI_PROTOCOL_TOR },
+ { 0x5519090B, 32, NDPI_PROTOCOL_TOR },
+ { 0x55192D93, 32, NDPI_PROTOCOL_TOR },
+ { 0x55192F35, 32, NDPI_PROTOCOL_TOR },
+ { 0x55192FB4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5519305B, 32, NDPI_PROTOCOL_TOR },
+ { 0x55195F5B, 32, NDPI_PROTOCOL_TOR },
+ { 0x55195F95, 32, NDPI_PROTOCOL_TOR },
+ { 0x55196777, 32, NDPI_PROTOCOL_TOR },
+ { 0x5519829A, 32, NDPI_PROTOCOL_TOR },
+ { 0x55198A5D, 32, NDPI_PROTOCOL_TOR },
+ { 0x551995BF, 32, NDPI_PROTOCOL_TOR },
+ { 0x55199678, 32, NDPI_PROTOCOL_TOR },
+ { 0x5519994F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5519C155, 32, NDPI_PROTOCOL_TOR },
+ { 0x5519C444, 32, NDPI_PROTOCOL_TOR },
+ { 0x5519CB2A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5519D0C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5519D256, 32, NDPI_PROTOCOL_TOR },
+ { 0x551EA9E1, 32, NDPI_PROTOCOL_TOR },
+ { 0x551EF8C1, 32, NDPI_PROTOCOL_TOR },
+ { 0x551FBA5D, 32, NDPI_PROTOCOL_TOR },
+ { 0x551FBAD3, 32, NDPI_PROTOCOL_TOR },
+ { 0x551FBAFD, 32, NDPI_PROTOCOL_TOR },
+ { 0x55455D2E, 32, NDPI_PROTOCOL_TOR },
+ { 0x55496286, 32, NDPI_PROTOCOL_TOR },
+ { 0x55510502, 32, NDPI_PROTOCOL_TOR },
+ { 0x55513A3B, 32, NDPI_PROTOCOL_TOR },
+ { 0x55580BF3, 32, NDPI_PROTOCOL_TOR },
+ { 0x55581C88, 32, NDPI_PROTOCOL_TOR },
+ { 0x555D1259, 32, NDPI_PROTOCOL_TOR },
+ { 0x555DCBB6, 32, NDPI_PROTOCOL_TOR },
+ { 0x555DDACC, 32, NDPI_PROTOCOL_TOR },
+ { 0x55719152, 32, NDPI_PROTOCOL_TOR },
+ { 0x55728560, 32, NDPI_PROTOCOL_TOR },
+ { 0x55775204, 32, NDPI_PROTOCOL_TOR },
+ { 0x5577532C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5577538D, 32, NDPI_PROTOCOL_TOR },
+ { 0x557FC146, 32, NDPI_PROTOCOL_TOR },
+ { 0x558DC913, 32, NDPI_PROTOCOL_TOR },
+ { 0x558F5F32, 32, NDPI_PROTOCOL_TOR },
+ { 0x5596D244, 32, NDPI_PROTOCOL_TOR },
+ { 0x559F71E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x559FD180, 32, NDPI_PROTOCOL_TOR },
+ { 0x559FD19A, 32, NDPI_PROTOCOL_TOR },
+ { 0x559FD2EF, 32, NDPI_PROTOCOL_TOR },
+ { 0x559FD337, 32, NDPI_PROTOCOL_TOR },
+ { 0x55A452E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x55A8FF49, 32, NDPI_PROTOCOL_TOR },
+ { 0x55A8FFCA, 32, NDPI_PROTOCOL_TOR },
+ { 0x55AB1623, 32, NDPI_PROTOCOL_TOR },
+ { 0x55B0BCF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x55B0E108, 32, NDPI_PROTOCOL_TOR },
+ { 0x55B1669A, 32, NDPI_PROTOCOL_TOR },
+ { 0x55B2425E, 32, NDPI_PROTOCOL_TOR },
+ { 0x55B2CDC4, 32, NDPI_PROTOCOL_TOR },
+ { 0x55B2F435, 32, NDPI_PROTOCOL_TOR },
+ { 0x55B35A3B, 32, NDPI_PROTOCOL_TOR },
+ { 0x55B42652, 32, NDPI_PROTOCOL_TOR },
+ { 0x55B4F715, 32, NDPI_PROTOCOL_TOR },
+ { 0x55C35D4D, 32, NDPI_PROTOCOL_TOR },
+ { 0x55C51E77, 32, NDPI_PROTOCOL_TOR },
+ { 0x55C6B4EF, 32, NDPI_PROTOCOL_TOR },
+ { 0x55CAE1D1, 32, NDPI_PROTOCOL_TOR },
+ { 0x55CC0B35, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D2AB44, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D408E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D414C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D42B5E, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D45466, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D610D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D617BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D61DD5, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D62891, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D62CAC, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6349C, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D636FE, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D63E30, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D64469, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D646BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D64748, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6492C, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D650F9, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D665E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D66C81, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D673D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D67EF9, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D680C7, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D68211, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6909F, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D69242, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D692DD, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D69748, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D69C1C, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6C1EA, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6C3C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6CEDB, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6D38C, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6DC01, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6E066, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6E20F, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6ECCF, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D6F0DF, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D82298, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D84A33, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D85282, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D8EF08, 32, NDPI_PROTOCOL_TOR },
+ { 0x55D96A51, 32, NDPI_PROTOCOL_TOR },
+ { 0x55DA8B87, 32, NDPI_PROTOCOL_TOR },
+ { 0x55DE7764, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E00DE3, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E23FF3, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E23FF3, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E272EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E3B85B, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E4C664, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E52799, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E56B0F, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E5DB15, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E6FB1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E9156D, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E92788, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E9EC02, 32, NDPI_PROTOCOL_TOR },
+ { 0x55E9F05E, 32, NDPI_PROTOCOL_TOR },
+ { 0x55EA0282, 32, NDPI_PROTOCOL_TOR },
+ { 0x55F262DD, 32, NDPI_PROTOCOL_TOR },
+ { 0x55F2F9AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x55F3CFC9, 32, NDPI_PROTOCOL_TOR },
+ { 0x55F4D455, 32, NDPI_PROTOCOL_TOR },
+ { 0x55F5023D, 32, NDPI_PROTOCOL_TOR },
+ { 0x55FB5633, 32, NDPI_PROTOCOL_TOR },
+ { 0x5600D6BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x56017832, 32, NDPI_PROTOCOL_TOR },
+ { 0x5608E378, 32, NDPI_PROTOCOL_TOR },
+ { 0x560DA7C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x56137EFA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5616F4E3, 32, NDPI_PROTOCOL_TOR },
+ { 0x56187315, 32, NDPI_PROTOCOL_TOR },
+ { 0x561BF297, 32, NDPI_PROTOCOL_TOR },
+ { 0x562C1E07, 32, NDPI_PROTOCOL_TOR },
+ { 0x5634AE44, 32, NDPI_PROTOCOL_TOR },
+ { 0x5634AE44, 32, NDPI_PROTOCOL_TOR },
+ { 0x56387108, 32, NDPI_PROTOCOL_TOR },
+ { 0x5638E449, 32, NDPI_PROTOCOL_TOR },
+ { 0x563A3DBE, 32, NDPI_PROTOCOL_TOR },
+ { 0x563B1526, 32, NDPI_PROTOCOL_TOR },
+ { 0x563B15A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x563B15FB, 32, NDPI_PROTOCOL_TOR },
+ { 0x563B4616, 32, NDPI_PROTOCOL_TOR },
+ { 0x563B7752, 32, NDPI_PROTOCOL_TOR },
+ { 0x563B7753, 32, NDPI_PROTOCOL_TOR },
+ { 0x563E75AB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5649B3AA, 32, NDPI_PROTOCOL_TOR },
+ { 0x566187BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x56660386, 32, NDPI_PROTOCOL_TOR },
+ { 0x56679157, 32, NDPI_PROTOCOL_TOR },
+ { 0x5667972F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5667A17E, 32, NDPI_PROTOCOL_TOR },
+ { 0x566A2A77, 32, NDPI_PROTOCOL_TOR },
+ { 0x56791818, 32, NDPI_PROTOCOL_TOR },
+ { 0x567B34BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x567EB91B, 32, NDPI_PROTOCOL_TOR },
+ { 0x567FBE92, 32, NDPI_PROTOCOL_TOR },
+ { 0x5681D4E1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5681D4E1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5697D436, 32, NDPI_PROTOCOL_TOR },
+ { 0x569A0B2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x569BD0C5, 32, NDPI_PROTOCOL_TOR },
+ { 0x569F0B08, 32, NDPI_PROTOCOL_TOR },
+ { 0x56A1DCE0, 32, NDPI_PROTOCOL_TOR },
+ { 0x56A2550C, 32, NDPI_PROTOCOL_TOR },
+ { 0x56A27142, 32, NDPI_PROTOCOL_TOR },
+ { 0x56AE29E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x56AF9CFB, 32, NDPI_PROTOCOL_TOR },
+ { 0x56B00DD2, 32, NDPI_PROTOCOL_TOR },
+ { 0x56B03E45, 32, NDPI_PROTOCOL_TOR },
+ { 0x56B1719D, 32, NDPI_PROTOCOL_TOR },
+ { 0x56B3ED06, 32, NDPI_PROTOCOL_TOR },
+ { 0x56B43BD3, 32, NDPI_PROTOCOL_TOR },
+ { 0x56B7FF53, 32, NDPI_PROTOCOL_TOR },
+ { 0x56BABA50, 32, NDPI_PROTOCOL_TOR },
+ { 0x56BDAAC7, 32, NDPI_PROTOCOL_TOR },
+ { 0x56CDFD45, 32, NDPI_PROTOCOL_TOR },
+ { 0x56D0805A, 32, NDPI_PROTOCOL_TOR },
+ { 0x56D39F39, 32, NDPI_PROTOCOL_TOR },
+ { 0x56D9692B, 32, NDPI_PROTOCOL_TOR },
+ { 0x56EB2C1D, 32, NDPI_PROTOCOL_TOR },
+ { 0x57214983, 32, NDPI_PROTOCOL_TOR },
+ { 0x5740620E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5743BBE2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5743F359, 32, NDPI_PROTOCOL_TOR },
+ { 0x574823EF, 32, NDPI_PROTOCOL_TOR },
+ { 0x574849E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x574855D9, 32, NDPI_PROTOCOL_TOR },
+ { 0x574855D9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5748EFBB, 32, NDPI_PROTOCOL_TOR },
+ { 0x574933FE, 32, NDPI_PROTOCOL_TOR },
+ { 0x574A4C6A, 32, NDPI_PROTOCOL_TOR },
+ { 0x574E6298, 32, NDPI_PROTOCOL_TOR },
+ { 0x574F4F5E, 32, NDPI_PROTOCOL_TOR },
+ { 0x574FA117, 32, NDPI_PROTOCOL_TOR },
+ { 0x574FBE6A, 32, NDPI_PROTOCOL_TOR },
+ { 0x574FE6A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x57518B76, 32, NDPI_PROTOCOL_TOR },
+ { 0x5751943D, 32, NDPI_PROTOCOL_TOR },
+ { 0x575C404F, 32, NDPI_PROTOCOL_TOR },
+ { 0x575C7E3B, 32, NDPI_PROTOCOL_TOR },
+ { 0x57628430, 32, NDPI_PROTOCOL_TOR },
+ { 0x57629FE7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5762B23D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5762B905, 32, NDPI_PROTOCOL_TOR },
+ { 0x5762CE46, 32, NDPI_PROTOCOL_TOR },
+ { 0x5762FADE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5762FAF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x57660FD8, 32, NDPI_PROTOCOL_TOR },
+ { 0x576837CB, 32, NDPI_PROTOCOL_TOR },
+ { 0x57686A90, 32, NDPI_PROTOCOL_TOR },
+ { 0x57688562, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A0364, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A0E9F, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A10D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A1108, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A120D, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A14F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A154D, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A20BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A2567, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A2FBE, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A3528, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A3786, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A8C18, 32, NDPI_PROTOCOL_TOR },
+ { 0x576A945A, 32, NDPI_PROTOCOL_TOR },
+ { 0x576ABDEE, 32, NDPI_PROTOCOL_TOR },
+ { 0x576ABF5F, 32, NDPI_PROTOCOL_TOR },
+ { 0x576ABF9D, 32, NDPI_PROTOCOL_TOR },
+ { 0x576AD0EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x576AF976, 32, NDPI_PROTOCOL_TOR },
+ { 0x576AF9F8, 32, NDPI_PROTOCOL_TOR },
+ { 0x57706F89, 32, NDPI_PROTOCOL_TOR },
+ { 0x5772AA67, 32, NDPI_PROTOCOL_TOR },
+ { 0x5775DB84, 32, NDPI_PROTOCOL_TOR },
+ { 0x5775DB8C, 32, NDPI_PROTOCOL_TOR },
+ { 0x57765454, 32, NDPI_PROTOCOL_TOR },
+ { 0x577654B5, 32, NDPI_PROTOCOL_TOR },
+ { 0x577654F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x577658DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x57765B8C, 32, NDPI_PROTOCOL_TOR },
+ { 0x57765D7A, 32, NDPI_PROTOCOL_TOR },
+ { 0x57765EE7, 32, NDPI_PROTOCOL_TOR },
+ { 0x577670AD, 32, NDPI_PROTOCOL_TOR },
+ { 0x57767286, 32, NDPI_PROTOCOL_TOR },
+ { 0x577674E3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5776760C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5777BA76, 32, NDPI_PROTOCOL_TOR },
+ { 0x5779348B, 32, NDPI_PROTOCOL_TOR },
+ { 0x57793492, 32, NDPI_PROTOCOL_TOR },
+ { 0x57793497, 32, NDPI_PROTOCOL_TOR },
+ { 0x577FA5F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x578B21D9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5791BA0E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5792CEEC, 32, NDPI_PROTOCOL_TOR },
+ { 0x57954623, 32, NDPI_PROTOCOL_TOR },
+ { 0x57969A86, 32, NDPI_PROTOCOL_TOR },
+ { 0x5796CE37, 32, NDPI_PROTOCOL_TOR },
+ { 0x579737CB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5798EDA7, 32, NDPI_PROTOCOL_TOR },
+ { 0x579B0B3B, 32, NDPI_PROTOCOL_TOR },
+ { 0x579E1829, 32, NDPI_PROTOCOL_TOR },
+ { 0x579E8E9E, 32, NDPI_PROTOCOL_TOR },
+ { 0x579F41E5, 32, NDPI_PROTOCOL_TOR },
+ { 0x579FA892, 32, NDPI_PROTOCOL_TOR },
+ { 0x57A0D2C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x57A2CCAC, 32, NDPI_PROTOCOL_TOR },
+ { 0x57A3F603, 32, NDPI_PROTOCOL_TOR },
+ { 0x57A47E10, 32, NDPI_PROTOCOL_TOR },
+ { 0x57A62B46, 32, NDPI_PROTOCOL_TOR },
+ { 0x57A87901, 32, NDPI_PROTOCOL_TOR },
+ { 0x57A97C46, 32, NDPI_PROTOCOL_TOR },
+ { 0x57AC1458, 32, NDPI_PROTOCOL_TOR },
+ { 0x57AE61DF, 32, NDPI_PROTOCOL_TOR },
+ { 0x57AE69FB, 32, NDPI_PROTOCOL_TOR },
+ { 0x57AEE582, 32, NDPI_PROTOCOL_TOR },
+ { 0x57AEEF6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x57AEF49C, 32, NDPI_PROTOCOL_TOR },
+ { 0x57B2A7F3, 32, NDPI_PROTOCOL_TOR },
+ { 0x57B362F3, 32, NDPI_PROTOCOL_TOR },
+ { 0x57B38736, 32, NDPI_PROTOCOL_TOR },
+ { 0x57BA1D87, 32, NDPI_PROTOCOL_TOR },
+ { 0x57BC52C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x57BC6D89, 32, NDPI_PROTOCOL_TOR },
+ { 0x57BCC2CB, 32, NDPI_PROTOCOL_TOR },
+ { 0x57BD56C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x57C1B3EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x57C1D00E, 32, NDPI_PROTOCOL_TOR },
+ { 0x57C62255, 32, NDPI_PROTOCOL_TOR },
+ { 0x57CBC2D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x57CFD9D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x57D430C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x57D8ABB3, 32, NDPI_PROTOCOL_TOR },
+ { 0x57D93E0E, 32, NDPI_PROTOCOL_TOR },
+ { 0x57DAA8EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x57E0D2F3, 32, NDPI_PROTOCOL_TOR },
+ { 0x57E43BBD, 32, NDPI_PROTOCOL_TOR },
+ { 0x57E611F5, 32, NDPI_PROTOCOL_TOR },
+ { 0x57E6196D, 32, NDPI_PROTOCOL_TOR },
+ { 0x57E619AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x57E6335F, 32, NDPI_PROTOCOL_TOR },
+ { 0x57E64E6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x57E70AEB, 32, NDPI_PROTOCOL_TOR },
+ { 0x57E77410, 32, NDPI_PROTOCOL_TOR },
+ { 0x57EC1B9B, 32, NDPI_PROTOCOL_TOR },
+ { 0x57ECC3B9, 32, NDPI_PROTOCOL_TOR },
+ { 0x57ECC7A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x57ECD389, 32, NDPI_PROTOCOL_TOR },
+ { 0x57EFA26E, 32, NDPI_PROTOCOL_TOR },
+ { 0x57F38E21, 32, NDPI_PROTOCOL_TOR },
+ { 0x57F4FFDA, 32, NDPI_PROTOCOL_TOR },
+ { 0x57FB8C5D, 32, NDPI_PROTOCOL_TOR },
+ { 0x57FE635F, 32, NDPI_PROTOCOL_TOR },
+ { 0x580F9CD8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5811212D, 32, NDPI_PROTOCOL_TOR },
+ { 0x58401AEB, 32, NDPI_PROTOCOL_TOR },
+ { 0x58404EF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5840805B, 32, NDPI_PROTOCOL_TOR },
+ { 0x58412604, 32, NDPI_PROTOCOL_TOR },
+ { 0x5841F49C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5843639C, 32, NDPI_PROTOCOL_TOR },
+ { 0x58458580, 32, NDPI_PROTOCOL_TOR },
+ { 0x584862F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x584931A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x58493380, 32, NDPI_PROTOCOL_TOR },
+ { 0x584C5C8E, 32, NDPI_PROTOCOL_TOR },
+ { 0x584D2F56, 32, NDPI_PROTOCOL_TOR },
+ { 0x584DC1AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x584DCB92, 32, NDPI_PROTOCOL_TOR },
+ { 0x584E47B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5850B95D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5850D6BD, 32, NDPI_PROTOCOL_TOR },
+ { 0x58526C1A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5856D7D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x58574E68, 32, NDPI_PROTOCOL_TOR },
+ { 0x585BD594, 32, NDPI_PROTOCOL_TOR },
+ { 0x58614DFF, 32, NDPI_PROTOCOL_TOR },
+ { 0x58690051, 32, NDPI_PROTOCOL_TOR },
+ { 0x58719D6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x58726D58, 32, NDPI_PROTOCOL_TOR },
+ { 0x5872759B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5872E33E, 32, NDPI_PROTOCOL_TOR },
+ { 0x587E6C2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x587F6026, 32, NDPI_PROTOCOL_TOR },
+ { 0x588201AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x58823273, 32, NDPI_PROTOCOL_TOR },
+ { 0x58864FB5, 32, NDPI_PROTOCOL_TOR },
+ { 0x588678F8, 32, NDPI_PROTOCOL_TOR },
+ { 0x58869115, 32, NDPI_PROTOCOL_TOR },
+ { 0x58894FA1, 32, NDPI_PROTOCOL_TOR },
+ { 0x58959A20, 32, NDPI_PROTOCOL_TOR },
+ { 0x58982F2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5898FFF5, 32, NDPI_PROTOCOL_TOR },
+ { 0x58996247, 32, NDPI_PROTOCOL_TOR },
+ { 0x5899A4FF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5899AB6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5899B4A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x589F4697, 32, NDPI_PROTOCOL_TOR },
+ { 0x589F53F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x58A3E58B, 32, NDPI_PROTOCOL_TOR },
+ { 0x58A5F4A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x58A6C0B5, 32, NDPI_PROTOCOL_TOR },
+ { 0x58A8F257, 32, NDPI_PROTOCOL_TOR },
+ { 0x58B0042F, 32, NDPI_PROTOCOL_TOR },
+ { 0x58B0B407, 32, NDPI_PROTOCOL_TOR },
+ { 0x58B256CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x58B99B86, 32, NDPI_PROTOCOL_TOR },
+ { 0x58B9E31D, 32, NDPI_PROTOCOL_TOR },
+ { 0x58BA120C, 32, NDPI_PROTOCOL_TOR },
+ { 0x58BB785A, 32, NDPI_PROTOCOL_TOR },
+ { 0x58BBBAD8, 32, NDPI_PROTOCOL_TOR },
+ { 0x58BBE53B, 32, NDPI_PROTOCOL_TOR },
+ { 0x58BD8A61, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C3CF75, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C60910, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C61304, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C617B3, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6194C, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6195C, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C628A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C63352, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C63436, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C636D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6388C, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C64689, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C664E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C664E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C66D95, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C66DE5, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C66E98, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C66F77, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C67565, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6789B, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C67FE6, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C682D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C69A70, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6A363, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6A364, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6AF4C, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6C187, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6C259, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6C633, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6CFDE, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C6D6E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x58C8F312, 32, NDPI_PROTOCOL_TOR },
+ { 0x58CC71BD, 32, NDPI_PROTOCOL_TOR },
+ { 0x58D0CD8A, 32, NDPI_PROTOCOL_TOR },
+ { 0x58D90267, 32, NDPI_PROTOCOL_TOR },
+ { 0x58D92CAE, 32, NDPI_PROTOCOL_TOR },
+ { 0x58D94FCA, 32, NDPI_PROTOCOL_TOR },
+ { 0x58D98F35, 32, NDPI_PROTOCOL_TOR },
+ { 0x58D9ABE1, 32, NDPI_PROTOCOL_TOR },
+ { 0x58E44C31, 32, NDPI_PROTOCOL_TOR },
+ { 0x59004F17, 32, NDPI_PROTOCOL_TOR },
+ { 0x5900641C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5900878D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5900AD14, 32, NDPI_PROTOCOL_TOR },
+ { 0x5900E463, 32, NDPI_PROTOCOL_TOR },
+ { 0x5900E570, 32, NDPI_PROTOCOL_TOR },
+ { 0x5900EA67, 32, NDPI_PROTOCOL_TOR },
+ { 0x5900EC30, 32, NDPI_PROTOCOL_TOR },
+ { 0x5900F2EF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5900F7A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x59039E31, 32, NDPI_PROTOCOL_TOR },
+ { 0x590CF9FD, 32, NDPI_PROTOCOL_TOR },
+ { 0x590D5330, 32, NDPI_PROTOCOL_TOR },
+ { 0x590E57D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x590F649D, 32, NDPI_PROTOCOL_TOR },
+ { 0x590F6BF1, 32, NDPI_PROTOCOL_TOR },
+ { 0x590FC872, 32, NDPI_PROTOCOL_TOR },
+ { 0x59108C47, 32, NDPI_PROTOCOL_TOR },
+ { 0x5910B09E, 32, NDPI_PROTOCOL_TOR },
+ { 0x59122A65, 32, NDPI_PROTOCOL_TOR },
+ { 0x5912AC8B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5912AD29, 32, NDPI_PROTOCOL_TOR },
+ { 0x5912AE45, 32, NDPI_PROTOCOL_TOR },
+ { 0x5912AE56, 32, NDPI_PROTOCOL_TOR },
+ { 0x5912BE6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5916602F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5916613A, 32, NDPI_PROTOCOL_TOR },
+ { 0x591661C1, 32, NDPI_PROTOCOL_TOR },
+ { 0x591B0DD9, 32, NDPI_PROTOCOL_TOR },
+ { 0x591B4114, 32, NDPI_PROTOCOL_TOR },
+ { 0x591B5146, 32, NDPI_PROTOCOL_TOR },
+ { 0x591F3905, 32, NDPI_PROTOCOL_TOR },
+ { 0x5924EB42, 32, NDPI_PROTOCOL_TOR },
+ { 0x59284795, 32, NDPI_PROTOCOL_TOR },
+ { 0x592E64A2, 32, NDPI_PROTOCOL_TOR },
+ { 0x592E6524, 32, NDPI_PROTOCOL_TOR },
+ { 0x592E65B5, 32, NDPI_PROTOCOL_TOR },
+ { 0x59410727, 32, NDPI_PROTOCOL_TOR },
+ { 0x59412546, 32, NDPI_PROTOCOL_TOR },
+ { 0x59438C76, 32, NDPI_PROTOCOL_TOR },
+ { 0x59438C76, 32, NDPI_PROTOCOL_TOR },
+ { 0x5943B32A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5943FE26, 32, NDPI_PROTOCOL_TOR },
+ { 0x5944BDD0, 32, NDPI_PROTOCOL_TOR },
+ { 0x594669E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5949B1EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5949D520, 32, NDPI_PROTOCOL_TOR },
+ { 0x594A6CCE, 32, NDPI_PROTOCOL_TOR },
+ { 0x594D88AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5959FD25, 32, NDPI_PROTOCOL_TOR },
+ { 0x5962E64C, 32, NDPI_PROTOCOL_TOR },
+ { 0x59639B85, 32, NDPI_PROTOCOL_TOR },
+ { 0x59669393, 32, NDPI_PROTOCOL_TOR },
+ { 0x5967B502, 32, NDPI_PROTOCOL_TOR },
+ { 0x5967B832, 32, NDPI_PROTOCOL_TOR },
+ { 0x5969C582, 32, NDPI_PROTOCOL_TOR },
+ { 0x596AF415, 32, NDPI_PROTOCOL_TOR },
+ { 0x596C560B, 32, NDPI_PROTOCOL_TOR },
+ { 0x596C58E3, 32, NDPI_PROTOCOL_TOR },
+ { 0x596E9CF7, 32, NDPI_PROTOCOL_TOR },
+ { 0x596F1444, 32, NDPI_PROTOCOL_TOR },
+ { 0x5978777D, 32, NDPI_PROTOCOL_TOR },
+ { 0x59829E95, 32, NDPI_PROTOCOL_TOR },
+ { 0x59845CDA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5985A952, 32, NDPI_PROTOCOL_TOR },
+ { 0x598619DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x59869680, 32, NDPI_PROTOCOL_TOR },
+ { 0x59879056, 32, NDPI_PROTOCOL_TOR },
+ { 0x598C623C, 32, NDPI_PROTOCOL_TOR },
+ { 0x598E23D1, 32, NDPI_PROTOCOL_TOR },
+ { 0x59910E6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x599B990F, 32, NDPI_PROTOCOL_TOR },
+ { 0x599C3EBE, 32, NDPI_PROTOCOL_TOR },
+ { 0x599C5DDC, 32, NDPI_PROTOCOL_TOR },
+ { 0x599ED03F, 32, NDPI_PROTOCOL_TOR },
+ { 0x599F568B, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A0DE85, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A257B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A3ABFA, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A3B9BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A3D14F, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A3D14F, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A3DD97, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A3DD97, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A3E00A, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A3E0A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A3E0BB, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A3E31C, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A6EAF6, 32, NDPI_PROTOCOL_TOR },
+ { 0x59A9A5E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x59B08CBE, 32, NDPI_PROTOCOL_TOR },
+ { 0x59B08D09, 32, NDPI_PROTOCOL_TOR },
+ { 0x59B34E19, 32, NDPI_PROTOCOL_TOR },
+ { 0x59B37F7C, 32, NDPI_PROTOCOL_TOR },
+ { 0x59B3F11E, 32, NDPI_PROTOCOL_TOR },
+ { 0x59B891D7, 32, NDPI_PROTOCOL_TOR },
+ { 0x59BA8F86, 32, NDPI_PROTOCOL_TOR },
+ { 0x59BB8ED0, 32, NDPI_PROTOCOL_TOR },
+ { 0x59BC6DD2, 32, NDPI_PROTOCOL_TOR },
+ { 0x59BFC7F5, 32, NDPI_PROTOCOL_TOR },
+ { 0x59CF8537, 32, NDPI_PROTOCOL_TOR },
+ { 0x59CF8799, 32, NDPI_PROTOCOL_TOR },
+ { 0x59E31A37, 32, NDPI_PROTOCOL_TOR },
+ { 0x59E7763D, 32, NDPI_PROTOCOL_TOR },
+ { 0x59EA8D65, 32, NDPI_PROTOCOL_TOR },
+ { 0x59EA9DFE, 32, NDPI_PROTOCOL_TOR },
+ { 0x59EA9DFE, 32, NDPI_PROTOCOL_TOR },
+ { 0x59EE455D, 32, NDPI_PROTOCOL_TOR },
+ { 0x59EE4D04, 32, NDPI_PROTOCOL_TOR },
+ { 0x59EE4E6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x59EEAC6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x59EFDAB4, 32, NDPI_PROTOCOL_TOR },
+ { 0x59F8A679, 32, NDPI_PROTOCOL_TOR },
+ { 0x59F8AC10, 32, NDPI_PROTOCOL_TOR },
+ { 0x59F985A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x59FB968E, 32, NDPI_PROTOCOL_TOR },
+ { 0x59FC0125, 32, NDPI_PROTOCOL_TOR },
+ { 0x59FC028C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A09C850, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A0A8BC7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A0B5036, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A18B154, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A1B3C6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A1D82F0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A1D9B54, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A20BA49, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A28F78E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A3CABF0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A3FA178, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A914577, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A921D38, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A92B569, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A951B7A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A95517A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5A9B17DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AB0A48F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AB50D30, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AB88EE0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AB8A455, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AB8DE74, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AB8DE75, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AB8DE76, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AC04EC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5ADB84FD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AE14054, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AE150DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AE1558C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AE2B287, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AE4CA9F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5AE7989F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B025570, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B02F637, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B041823, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B05878B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B06757C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B09C013, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B0A081A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B0A45D7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B0A7B54, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B0CD9A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B0CEB4D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B0D634C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B0E755F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B0F4794, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B120251, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B129DE3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B152C3D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B21CED5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B225C74, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B25E831, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B265CAF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B2C7D98, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B2DE1A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B3249DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B334FF1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B336B45, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B33E422, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B33FBDE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B343F6F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B36DE01, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B3B5350, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B3D4574, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B3D52E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B3DF13E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B3EE54E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B406D9B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B406F83, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B40EADB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B41538E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B4160F6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B424E8B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B4254DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B42CC01, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B434C46, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B4D127A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B4F6E29, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B52ED7F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B605C06, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B60BC9F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B614084, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B6DF7AD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B711952, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B77D141, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B77E5A1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B790114, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B791043, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B7915E0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B791C40, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B794CCC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B794CCF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B795210, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B795219, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B79545C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B795582, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B7964C8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B7968A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B796AB2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B79734F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B797422, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B799255, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B799275, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B799341, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B799FC4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B79A5DF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B79A698, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B79A921, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B79B857, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B79C584, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B79CF22, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B79E9F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B7A640D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B7BC8A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B7BC8EB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B7EFFCD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B88A44D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B8A448F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B8A9B09, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B8C31D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B917635, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B927903, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B927A2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B95AD4F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B9A9932, 32, NDPI_PROTOCOL_TOR },
+ { 0x5B9BBD6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BB9C8DD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BB9E123, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BBA2710, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BBC7D80, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BBDB576, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BBE754D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BC2546A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BC25A27, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BC25A67, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BC7C54C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BC85544, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BCA2D9C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BCBD4EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BCDAD52, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BCE8E46, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD05448, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD26A1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD33ED4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD5082B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD50854, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD50859, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD50874, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD508EB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD508EB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD508EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD6A8F0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD6CB90, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BD6CBE9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BDBED13, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BDBED6E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BDBEDCF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BDBEDDA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BDBEDE5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BDBEDF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BDBEEDD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BDCA33E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BDD6F07, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BDEDA85, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE09509, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE09521, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE0952D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE09537, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE25911, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE434BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE49734, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE4B382, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE5141B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE6CCC6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE8D912, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BE97444, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BEA1630, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BEAE223, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BECEF87, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BECEF8C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BED34AA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BEDF43E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BEDF73E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BEE3C64, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BF0E5C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BFA7026, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BFA73B9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BFAF20A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5BFAF267, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C002464, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C0124D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C01DCB8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C07A833, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C0A3BD5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C0EC83C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C14074D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C14CB4C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C15F357, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C18851F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C18851F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C27F38B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C27F62D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C2869CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C32581A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C34249B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3C05EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3C05EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3F582D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3F582F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3F6E7C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3FAB2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3FABCF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3FAC96, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3FAE24, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3FAE46, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3FAE47, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C3FAF05, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C484CE3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C487B89, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C48FF4A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C4A357A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C4AE372, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C4B0EC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C4C7C06, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C4CC040, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C4D2D74, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C4DB1FE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C59AD55, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C5B7942, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C5B9C44, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C645773, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C647BD0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C68349B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C6893A0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C6977C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C6AE25D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C6C364C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C6C7829, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C6D0707, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C6F8E21, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C81AF11, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C83BD03, 32, NDPI_PROTOCOL_TOR },
+ { 0x5C89D859, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CC240C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CC328D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CC941B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CC94BCD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CCA214F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CCD15C1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CD13085, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CD3AE6A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CD6A588, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CD6ADD8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE016C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE0352, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE0466, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE04B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE0935, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE0946, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE1385, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE1482, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE1625, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE1671, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE19E1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE1A24, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE1A51, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE1C5A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE1C8F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE1CF3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE1D22, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE2211, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE2643, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE27B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE2DC7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE45BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDE9993, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDEA236, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDEACE5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDEB57B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDEC022, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CDECC60, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CE09A94, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CE0A09F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CE0B392, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CE10C0D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CE169B5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CE389A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CE4B19B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CE52412, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CE59221, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CE68415, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CE86216, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CED16DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CF31ED0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CF34569, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CF3BC10, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CF6147E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CF733A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CF79DB0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CF96241, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CF98F77, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CF9BCF6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CFC2031, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CFE18CB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CFE3951, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CFEB874, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CFFC311, 32, NDPI_PROTOCOL_TOR },
+ { 0x5CFFCF59, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D134D18, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D1F9BAF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D328CAA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D48650E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D515FF8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D5A73BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D5B3291, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D5CCC06, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D5E922B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D5FE37F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D5FE3F5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D5FE405, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D5FE433, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D5FE452, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D63058C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D64A738, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D6797A7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D688049, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D68A671, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D68D13D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D68D19E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D68D3A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D68D4FD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D73569C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D735EF3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D735EF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D73F102, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D760C01, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D7C3305, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D7E65DF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D804CF1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D81945A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D8456CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D84AC51, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D867771, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D8712F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D8BDD63, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D98C554, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D9C28A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5D9C4AEF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DA33850, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DA7F5B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DAE5A1E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DAE5D15, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DAE5D3F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DAF0C52, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DB49A5E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DB49C54, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DB49C63, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DB49D28, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DB49D9A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DB81566, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DB842E3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DB9654C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DB965AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DB96DBF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DBAC8D5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DBCA2EB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DBF0D22, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DC06F39, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DC0AAC8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DC0CA0C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DC16D99, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DC2904C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DC5E303, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DC5F098, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DC8C66B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DCBFB93, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DCD0C3A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DCF14E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DCF46AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DD3F085, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DD47CEB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DD71649, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DD740AF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DDA6C31, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DDB7692, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DDC0F3B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DDC7449, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DDCD36F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DDCEB0C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DDF509D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DDFCC89, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DE44D4E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DE62635, 32, NDPI_PROTOCOL_TOR },
+ { 0x5DE95360, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E05D57B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E09C10C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E104BE2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E137BC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E160545, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E168F9E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E16A01D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E170291, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E1712A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17141C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E1714BE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17194E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E171E35, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E172434, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E172599, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E1730BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17360C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17381F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E1746DE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E175892, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E176919, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17A2E3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17AB60, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17C221, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17C636, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17CCAF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17D0BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17D2A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17ECBB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E17FC1F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E188C4A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E22964B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E29C2EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E2D3BF0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E33CEA8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E46889C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E4BCF64, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E4F89B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E4FB906, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E6412A2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E6635B1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E663CAC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E67AF55, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E716902, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E71E6DD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E7CF603, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E7EB201, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E878697, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E88612A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E8DACF0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E8EF18A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E8EF1F1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E8EF21E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E8EF5CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E8EF5E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E9B5D2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E9ED927, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E9FCE6E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5E9FDCF2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EAE9EF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EB4D2CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EB4D8D9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EB4E868, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EB51414, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EB95202, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EBC1C88, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EBC39EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EBEE03A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EC6440D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EC66247, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EC66411, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EC73365, 32, NDPI_PROTOCOL_TOR },
+ { 0x5ED0E3DD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5ED2001C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5ED2BE2C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5ED3C0CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5ED61659, 32, NDPI_PROTOCOL_TOR },
+ { 0x5ED6179F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5ED9C67E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5ED9FE19, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EDA142C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EDC49D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EDD6472, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EDD9651, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EE19A57, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EE4560B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EE4DEC0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EE6CB1F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EE72228, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF23915, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF23926, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF239A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF239A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF239C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF239D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF23A46, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2C6A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2CC84, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2D178, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2D1F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2DE1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2DED7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2F342, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2F3A2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2F617, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2F618, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2FB70, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2FC29, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2FE51, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2FE51, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF2FEBF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EF72982, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EFD0E62, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EFD4CD2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EFE1877, 32, NDPI_PROTOCOL_TOR },
+ { 0x5EFE30C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F122587, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F17F611, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F182884, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F1931B0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F1BE179, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F1C5963, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F1EAD45, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F1F1B6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F1F2E02, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F25A84D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F40CB0E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F477EE6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F480939, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F4892AD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F491AE8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F4931BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F49EB59, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F4D914B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F4E3856, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F4F19B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F4F605F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F4F89F8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F500A2E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F52F5EA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F549049, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F5494AD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F54C634, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F54C806, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F54D17E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F550367, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F5503BF, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F5505D3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F55075A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F5508E2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F550A47, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F550E4F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F551449, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F55150E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F5517BD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F552522, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F55256F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F552673, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F55271C, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F552A24, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F553605, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F553C17, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F594A54, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F599862, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F5A0C37, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F5B83B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F61A0CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F69A188, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F6A1BC6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F6D7A90, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F7008D0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F71E203, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F72385D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F741FDB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F76808A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F802BA4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8137AD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F81CD53, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820959, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820959, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820979, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8209BE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820A0F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820B05, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820B0F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820B2A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820B2E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820B93, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820BA2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820BAA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820BD6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820C2F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820C77, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820F60, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820F61, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820FFB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820FFC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820FFD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F820FFE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8387B3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F83EA02, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8429AB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F843460, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F851927, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F872D77, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8BE024, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8C2AB7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8D5392, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8DE895, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8EA13F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8EAD12, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8FACD4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8FACD6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8FACF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8FC191, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F8FE1C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F91E0D0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F9A1849, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F9A58FC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F9A6A86, 32, NDPI_PROTOCOL_TOR },
+ { 0x5F9D0C83, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FA01056, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FA9BC67, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FAAB5D0, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FACEC76, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FAEE547, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD3079E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD31B0A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD349ED, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD3629F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD38811, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD38A1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD3A923, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD3CD97, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD3D865, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD3DE93, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD3E1A7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD3E408, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD3E59E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD3E781, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD3F153, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD701B5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72C66, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72C69, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72C6E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72C6F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72C7A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72C91, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72CBA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72CBB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72CBD, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72CC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72CE8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72CF9, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72D2F, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72D41, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72D44, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72D80, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72D8E, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72DBC, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72DC3, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72DC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72E24, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72E54, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72E5A, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72E67, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72E7B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72E96, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72EF4, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72F75, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72F80, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72F8B, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72F96, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72FB1, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72FBB, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72FC7, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72FCE, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72FD8, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FD72FF2, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FDC69CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FDC822D, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FDE9C03, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FDE9C04, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FDEE336, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FDFD887, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FEEE099, 32, NDPI_PROTOCOL_TOR },
+ { 0x5FEFE676, 32, NDPI_PROTOCOL_TOR },
+ { 0x601390C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x601CBD5E, 32, NDPI_PROTOCOL_TOR },
+ { 0x601F430F, 32, NDPI_PROTOCOL_TOR },
+ { 0x60210687, 32, NDPI_PROTOCOL_TOR },
+ { 0x60238283, 32, NDPI_PROTOCOL_TOR },
+ { 0x60253C3F, 32, NDPI_PROTOCOL_TOR },
+ { 0x6028292D, 32, NDPI_PROTOCOL_TOR },
+ { 0x60290DA2, 32, NDPI_PROTOCOL_TOR },
+ { 0x6029718C, 32, NDPI_PROTOCOL_TOR },
+ { 0x602A211B, 32, NDPI_PROTOCOL_TOR },
+ { 0x602CBD64, 32, NDPI_PROTOCOL_TOR },
+ { 0x602CBD65, 32, NDPI_PROTOCOL_TOR },
+ { 0x602CBD66, 32, NDPI_PROTOCOL_TOR },
+ { 0x602F411A, 32, NDPI_PROTOCOL_TOR },
+ { 0x602FE214, 32, NDPI_PROTOCOL_TOR },
+ { 0x602FE215, 32, NDPI_PROTOCOL_TOR },
+ { 0x602FE216, 32, NDPI_PROTOCOL_TOR },
+ { 0x602FEC7E, 32, NDPI_PROTOCOL_TOR },
+ { 0x60303837, 32, NDPI_PROTOCOL_TOR },
+ { 0x60341169, 32, NDPI_PROTOCOL_TOR },
+ { 0x60362A0F, 32, NDPI_PROTOCOL_TOR },
+ { 0x607E6009, 32, NDPI_PROTOCOL_TOR },
+ { 0x607E605A, 32, NDPI_PROTOCOL_TOR },
+ { 0x607E6688, 32, NDPI_PROTOCOL_TOR },
+ { 0x607E69DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x607E6E3C, 32, NDPI_PROTOCOL_TOR },
+ { 0x607E6E3C, 32, NDPI_PROTOCOL_TOR },
+ { 0x607E76E3, 32, NDPI_PROTOCOL_TOR },
+ { 0x607E7AA6, 32, NDPI_PROTOCOL_TOR },
+ { 0x607E7F58, 32, NDPI_PROTOCOL_TOR },
+ { 0x60E26D05, 32, NDPI_PROTOCOL_TOR },
+ { 0x60E29C48, 32, NDPI_PROTOCOL_TOR },
+ { 0x60E53297, 32, NDPI_PROTOCOL_TOR },
+ { 0x60E6398D, 32, NDPI_PROTOCOL_TOR },
+ { 0x60E85742, 32, NDPI_PROTOCOL_TOR },
+ { 0x60E932CF, 32, NDPI_PROTOCOL_TOR },
+ { 0x60EE056F, 32, NDPI_PROTOCOL_TOR },
+ { 0x60EE23B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x60F19A42, 32, NDPI_PROTOCOL_TOR },
+ { 0x60FA5604, 32, NDPI_PROTOCOL_TOR },
+ { 0x60FD4E6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x60FF47C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x6155B286, 32, NDPI_PROTOCOL_TOR },
+ { 0x61570E0F, 32, NDPI_PROTOCOL_TOR },
+ { 0x61573D40, 32, NDPI_PROTOCOL_TOR },
+ { 0x615D1FB9, 32, NDPI_PROTOCOL_TOR },
+ { 0x615F20B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x61664AC2, 32, NDPI_PROTOCOL_TOR },
+ { 0x61664F0E, 32, NDPI_PROTOCOL_TOR },
+ { 0x616B8418, 32, NDPI_PROTOCOL_TOR },
+ { 0x616B867F, 32, NDPI_PROTOCOL_TOR },
+ { 0x616B8A44, 32, NDPI_PROTOCOL_TOR },
+ { 0x616B8B1C, 32, NDPI_PROTOCOL_TOR },
+ { 0x616B8B6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x616B8E85, 32, NDPI_PROTOCOL_TOR },
+ { 0x616B8EDA, 32, NDPI_PROTOCOL_TOR },
+ { 0x616B8EEA, 32, NDPI_PROTOCOL_TOR },
+ { 0x61761E24, 32, NDPI_PROTOCOL_TOR },
+ { 0x62181813, 32, NDPI_PROTOCOL_TOR },
+ { 0x62185496, 32, NDPI_PROTOCOL_TOR },
+ { 0x621CA618, 32, NDPI_PROTOCOL_TOR },
+ { 0x621CF5EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x6241C4D2, 32, NDPI_PROTOCOL_TOR },
+ { 0x6245AA0A, 32, NDPI_PROTOCOL_TOR },
+ { 0x626538B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x626D3882, 32, NDPI_PROTOCOL_TOR },
+ { 0x626D7511, 32, NDPI_PROTOCOL_TOR },
+ { 0x62726199, 32, NDPI_PROTOCOL_TOR },
+ { 0x6274DF81, 32, NDPI_PROTOCOL_TOR },
+ { 0x627C74C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x628E2F36, 32, NDPI_PROTOCOL_TOR },
+ { 0x6296DFDD, 32, NDPI_PROTOCOL_TOR },
+ { 0x629B1EED, 32, NDPI_PROTOCOL_TOR },
+ { 0x629D1940, 32, NDPI_PROTOCOL_TOR },
+ { 0x629D41CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x62B436C1, 32, NDPI_PROTOCOL_TOR },
+ { 0x62B790F7, 32, NDPI_PROTOCOL_TOR },
+ { 0x62C1C54A, 32, NDPI_PROTOCOL_TOR },
+ { 0x62C774D0, 32, NDPI_PROTOCOL_TOR },
+ { 0x62C925BF, 32, NDPI_PROTOCOL_TOR },
+ { 0x62C99217, 32, NDPI_PROTOCOL_TOR },
+ { 0x62CEB470, 32, NDPI_PROTOCOL_TOR },
+ { 0x62CEB64E, 32, NDPI_PROTOCOL_TOR },
+ { 0x62D2A4C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x62D6F355, 32, NDPI_PROTOCOL_TOR },
+ { 0x62D8A86C, 32, NDPI_PROTOCOL_TOR },
+ { 0x62D99D4C, 32, NDPI_PROTOCOL_TOR },
+ { 0x62DA3282, 32, NDPI_PROTOCOL_TOR },
+ { 0x62DA372F, 32, NDPI_PROTOCOL_TOR },
+ { 0x62E0DAEE, 32, NDPI_PROTOCOL_TOR },
+ { 0x62E7895E, 32, NDPI_PROTOCOL_TOR },
+ { 0x62E818A7, 32, NDPI_PROTOCOL_TOR },
+ { 0x62EC4BEC, 32, NDPI_PROTOCOL_TOR },
+ { 0x62F5A7CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x62F62CE0, 32, NDPI_PROTOCOL_TOR },
+ { 0x62F81DE9, 32, NDPI_PROTOCOL_TOR },
+ { 0x62FC8D6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x62FFC9AB, 32, NDPI_PROTOCOL_TOR },
+ { 0x630615BE, 32, NDPI_PROTOCOL_TOR },
+ { 0x633F1919, 32, NDPI_PROTOCOL_TOR },
+ { 0x635AD476, 32, NDPI_PROTOCOL_TOR },
+ { 0x635F8924, 32, NDPI_PROTOCOL_TOR },
+ { 0x6363E834, 32, NDPI_PROTOCOL_TOR },
+ { 0x6366B2AD, 32, NDPI_PROTOCOL_TOR },
+ { 0x63E1049C, 32, NDPI_PROTOCOL_TOR },
+ { 0x63E4AB0B, 32, NDPI_PROTOCOL_TOR },
+ { 0x63EA2BA0, 32, NDPI_PROTOCOL_TOR },
+ { 0x6424B8E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x6425681C, 32, NDPI_PROTOCOL_TOR },
+ { 0x65339B42, 32, NDPI_PROTOCOL_TOR },
+ { 0x6562AEE2, 32, NDPI_PROTOCOL_TOR },
+ { 0x65634096, 32, NDPI_PROTOCOL_TOR },
+ { 0x658CD912, 32, NDPI_PROTOCOL_TOR },
+ { 0x658EC26D, 32, NDPI_PROTOCOL_TOR },
+ { 0x65B090B8, 32, NDPI_PROTOCOL_TOR },
+ { 0x65BB0480, 32, NDPI_PROTOCOL_TOR },
+ { 0x6706D5C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x670AC532, 32, NDPI_PROTOCOL_TOR },
+ { 0x670AC764, 32, NDPI_PROTOCOL_TOR },
+ { 0x67101A47, 32, NDPI_PROTOCOL_TOR },
+ { 0x67193810, 32, NDPI_PROTOCOL_TOR },
+ { 0x67298435, 32, NDPI_PROTOCOL_TOR },
+ { 0x67F05B07, 32, NDPI_PROTOCOL_TOR },
+ { 0x67FAB895, 32, NDPI_PROTOCOL_TOR },
+ { 0x68091CA1, 32, NDPI_PROTOCOL_TOR },
+ { 0x6820195D, 32, NDPI_PROTOCOL_TOR },
+ { 0x68218AAE, 32, NDPI_PROTOCOL_TOR },
+ { 0x6828018F, 32, NDPI_PROTOCOL_TOR },
+ { 0x68288AA6, 32, NDPI_PROTOCOL_TOR },
+ { 0x6829028B, 32, NDPI_PROTOCOL_TOR },
+ { 0x68311642, 32, NDPI_PROTOCOL_TOR },
+ { 0x68804E6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x68804E6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x68804E6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x68804E6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6880AB3E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6880E1CB, 32, NDPI_PROTOCOL_TOR },
+ { 0x68821999, 32, NDPI_PROTOCOL_TOR },
+ { 0x68830974, 32, NDPI_PROTOCOL_TOR },
+ { 0x68830C8B, 32, NDPI_PROTOCOL_TOR },
+ { 0x68830EAF, 32, NDPI_PROTOCOL_TOR },
+ { 0x68831377, 32, NDPI_PROTOCOL_TOR },
+ { 0x68831C36, 32, NDPI_PROTOCOL_TOR },
+ { 0x68831E06, 32, NDPI_PROTOCOL_TOR },
+ { 0x688322AA, 32, NDPI_PROTOCOL_TOR },
+ { 0x688322AC, 32, NDPI_PROTOCOL_TOR },
+ { 0x68832D66, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883335D, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883378D, 32, NDPI_PROTOCOL_TOR },
+ { 0x688337B8, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883387F, 32, NDPI_PROTOCOL_TOR },
+ { 0x68833A42, 32, NDPI_PROTOCOL_TOR },
+ { 0x68833F50, 32, NDPI_PROTOCOL_TOR },
+ { 0x68833F8F, 32, NDPI_PROTOCOL_TOR },
+ { 0x688341E1, 32, NDPI_PROTOCOL_TOR },
+ { 0x688342C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x68834956, 32, NDPI_PROTOCOL_TOR },
+ { 0x68834ACF, 32, NDPI_PROTOCOL_TOR },
+ { 0x68835F18, 32, NDPI_PROTOCOL_TOR },
+ { 0x68836C07, 32, NDPI_PROTOCOL_TOR },
+ { 0x68836ED5, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883722B, 32, NDPI_PROTOCOL_TOR },
+ { 0x68837248, 32, NDPI_PROTOCOL_TOR },
+ { 0x688375E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x68837B10, 32, NDPI_PROTOCOL_TOR },
+ { 0x68837D54, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883811E, 32, NDPI_PROTOCOL_TOR },
+ { 0x68838182, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883862F, 32, NDPI_PROTOCOL_TOR },
+ { 0x68839A74, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883A6F3, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883AC2E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883B5AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883CC93, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883CE17, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883D523, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883E7F1, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883F0A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x6883F537, 32, NDPI_PROTOCOL_TOR },
+ { 0x689C39C7, 32, NDPI_PROTOCOL_TOR },
+ { 0x689C6F36, 32, NDPI_PROTOCOL_TOR },
+ { 0x689CE01C, 32, NDPI_PROTOCOL_TOR },
+ { 0x689CE053, 32, NDPI_PROTOCOL_TOR },
+ { 0x689CEE74, 32, NDPI_PROTOCOL_TOR },
+ { 0x689CFD47, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A2167C, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A762FD, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A76304, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A7630C, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A76458, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A764A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A766F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A76734, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A7695C, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A76A2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A76B8E, 32, NDPI_PROTOCOL_TOR },
+ { 0x68A823A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x68AE61BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x68C81056, 32, NDPI_PROTOCOL_TOR },
+ { 0x68C81056, 32, NDPI_PROTOCOL_TOR },
+ { 0x68C812B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x68C812B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x68C8148E, 32, NDPI_PROTOCOL_TOR },
+ { 0x68C81841, 32, NDPI_PROTOCOL_TOR },
+ { 0x68CEC114, 32, NDPI_PROTOCOL_TOR },
+ { 0x68CF802A, 32, NDPI_PROTOCOL_TOR },
+ { 0x68CF846D, 32, NDPI_PROTOCOL_TOR },
+ { 0x68CF84C9, 32, NDPI_PROTOCOL_TOR },
+ { 0x68CF92C8, 32, NDPI_PROTOCOL_TOR },
+ { 0x68CF940C, 32, NDPI_PROTOCOL_TOR },
+ { 0x68DBB8A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x68DD4C83, 32, NDPI_PROTOCOL_TOR },
+ { 0x68E0AF68, 32, NDPI_PROTOCOL_TOR },
+ { 0x68E80163, 32, NDPI_PROTOCOL_TOR },
+ { 0x68E80321, 32, NDPI_PROTOCOL_TOR },
+ { 0x68E80323, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EADC47, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC0067, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC0658, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC084A, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC1197, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC191C, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC239C, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC26E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC27DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC2CD2, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC323E, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC3672, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC5353, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC5629, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC575A, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC5DE1, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC6452, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC6E0D, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC8E5D, 32, NDPI_PROTOCOL_TOR },
+ { 0x68EC95F9, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ECAE0E, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ECB3DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ECB3F0, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ECB847, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ECD5C1, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ECE860, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ECFDEC, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED8054, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED8134, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED8134, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED814E, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED818E, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED818E, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED834B, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED834B, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED836B, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED8D6D, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED8DC1, 32, NDPI_PROTOCOL_TOR },
+ { 0x68ED98C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x68F44B5B, 32, NDPI_PROTOCOL_TOR },
+ { 0x68F4DFCC, 32, NDPI_PROTOCOL_TOR },
+ { 0x68F5274A, 32, NDPI_PROTOCOL_TOR },
+ { 0x68FBD208, 32, NDPI_PROTOCOL_TOR },
+ { 0x699551A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x699AB5D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x69EDDE72, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB91C19, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB91C71, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB91C71, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB91CAA, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB91D5D, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB91EEE, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB91F81, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB91F81, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB92697, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB9273A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB9273A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB930D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x6AB930D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA109A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA1228, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA12F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA1892, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA18FE, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA1C21, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA1D04, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA1D2A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA1E34, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA7229, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA7541, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABA7541, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB23EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB24B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB259E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB259E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB26C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB2974, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB2B6E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB2D9C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB2F11, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB3444, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB37EF, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB5EFE, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB5EFE, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB60FA, 32, NDPI_PROTOCOL_TOR },
+ { 0x6ABB6773, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B021E0D, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B060491, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B14B34B, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B812529, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B9614F1, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B961BC8, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B961F6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B962336, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B96268A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B9635B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B96AA3A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B988F3E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B9B748F, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B9EFF15, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B9EFF15, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B9EFF16, 32, NDPI_PROTOCOL_TOR },
+ { 0x6B9EFF16, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BA150C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BA151BB, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BA151D0, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BA154B9, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BA19E11, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BA1B357, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA2047, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA3234, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA330E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA41C5, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA4E2A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA4F93, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA5C89, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA5CED, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA5D0D, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA5D20, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA5D75, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA60EB, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA676F, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA6CDE, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA72CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA78D6, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA8F75, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA9607, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA9950, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAA9ED4, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAABC9B, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAAC021, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAAC442, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAACC21, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAAE84B, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAAF57F, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAAF6CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAAF721, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BAAFBB6, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BB5A60B, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BB5AE16, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BB613F9, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BB68374, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BB68388, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BB683CF, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BB683D3, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BBF2C9A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BBF2ECC, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BBF3FB8, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BBF6245, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BBF6CCB, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BBF7EB8, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BC4142E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6BCB324B, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C009C8F, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C00C1EF, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C00CFF0, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C00DF0E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C071024, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C0724B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C0CB2EB, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C0E531F, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C137138, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C1D6B46, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C1D75F5, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C1E388E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C1E3970, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C1F2805, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C1FDC6E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C203114, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C2D5D5E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C309E93, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C32EBB6, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C33B8DC, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3504D1, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C35822A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C36A4AF, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C38BD9D, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3A90E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3B02D0, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3B0BE1, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DA16F, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DA1E3, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DA457, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DA539, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DA646, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DA6C7, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DA7F0, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DA82C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DB16E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DB1C3, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DB22E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DB233, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DB2D8, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DB3D8, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DB691, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DB6EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DB91A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DB988, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DBCB4, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DC563, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DC6A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DC6CF, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DC7B0, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DC7CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DD0AB, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DD150, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DD27B, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DD35E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DD466, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DF237, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DFB84, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C3DFCED, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C45A572, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C59AF93, 32, NDPI_PROTOCOL_TOR },
+ { 0x6C6FAA05, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CA6A1BA, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CA6A89E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CA6A8A7, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CA8033C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CAA8A76, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CB49FFC, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CB9E23E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CCC2E0E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CD0E579, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CD20668, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CF0B68C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CF72296, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CF7F4CC, 32, NDPI_PROTOCOL_TOR },
+ { 0x6CF857F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D00AA2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D00DC98, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D163429, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D44AE3C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D44BF85, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D454311, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4565A5, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D49345A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4A0058, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4A9795, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4AC247, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4AC27C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4AC3BE, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4AC865, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4ACC77, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4ACE0C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4ACE15, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4BB84D, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D4BBD44, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D5A17DD, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D5AFAB0, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D5B68E8, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D5B6C94, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D5B7013, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D5B7DC3, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D5E6002, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D5FD279, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D5FD442, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D646686, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D64FC83, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D682CD1, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D696DA2, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D6A38E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D6B239A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D6CDE14, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D6F9E13, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D78943C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D78AD30, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D78B4F5, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D78B611, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D824D50, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D825345, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D984A8C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6D9BDAB1, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA1226E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA3E9A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA3EA02, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA3EA04, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA3EA05, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA3EA07, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA3EA08, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA3EA09, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA3EBF6, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA3EBFC, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA4ECE7, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA78802, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA9001D, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA917CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA921A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DA92DE2, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DAD3BB4, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DB6971F, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DBD0643, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DBD834C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DBD8F96, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DBDB40F, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DBE4755, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DBE6DE4, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC074AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC0CFE9, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC16B54, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC18057, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC2D95A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC41236, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC50D36, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC53F2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC95A10, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC9830B, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC99A8D, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DC9C2DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DCB6C42, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DCEBA61, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DD412CD, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DD414AD, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DDA7515, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DE4963C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DE6E02A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DE6EC59, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DE6EC5F, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DE6ECAD, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DE97B2C, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DE97FE9, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DEB32A3, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DEC568A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DEF301A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DEF3098, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DEF30AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DEF3103, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DEF3C35, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DF150E7, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DF63848, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DFB8A1A, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DFF2ED7, 32, NDPI_PROTOCOL_TOR },
+ { 0x6DFF69AD, 32, NDPI_PROTOCOL_TOR },
+ { 0x6E42E657, 32, NDPI_PROTOCOL_TOR },
+ { 0x6E42E657, 32, NDPI_PROTOCOL_TOR },
+ { 0x6E5D17AA, 32, NDPI_PROTOCOL_TOR },
+ { 0x6EAE2B88, 32, NDPI_PROTOCOL_TOR },
+ { 0x6EAFF9CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x6F458D7B, 32, NDPI_PROTOCOL_TOR },
+ { 0x6F45A280, 32, NDPI_PROTOCOL_TOR },
+ { 0x6F59A849, 32, NDPI_PROTOCOL_TOR },
+ { 0x6F677B5E, 32, NDPI_PROTOCOL_TOR },
+ { 0x6F67ACCD, 32, NDPI_PROTOCOL_TOR },
+ { 0x6F76B165, 32, NDPI_PROTOCOL_TOR },
+ { 0x6FF8167F, 32, NDPI_PROTOCOL_TOR },
+ { 0x70769CA3, 32, NDPI_PROTOCOL_TOR },
+ { 0x7078955A, 32, NDPI_PROTOCOL_TOR },
+ { 0x707899D7, 32, NDPI_PROTOCOL_TOR },
+ { 0x70CDFABD, 32, NDPI_PROTOCOL_TOR },
+ { 0x71A37584, 32, NDPI_PROTOCOL_TOR },
+ { 0x7225CECB, 32, NDPI_PROTOCOL_TOR },
+ { 0x724DE973, 32, NDPI_PROTOCOL_TOR },
+ { 0x72860615, 32, NDPI_PROTOCOL_TOR },
+ { 0x72BD691E, 32, NDPI_PROTOCOL_TOR },
+ { 0x7342A640, 32, NDPI_PROTOCOL_TOR },
+ { 0x7346F182, 32, NDPI_PROTOCOL_TOR },
+ { 0x73BB4A5B, 32, NDPI_PROTOCOL_TOR },
+ { 0x73BB9A6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x75124BEB, 32, NDPI_PROTOCOL_TOR },
+ { 0x751263F9, 32, NDPI_PROTOCOL_TOR },
+ { 0x760C8552, 32, NDPI_PROTOCOL_TOR },
+ { 0x768D03A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x76AC0D55, 32, NDPI_PROTOCOL_TOR },
+ { 0x76C1C25F, 32, NDPI_PROTOCOL_TOR },
+ { 0x76D0C22A, 32, NDPI_PROTOCOL_TOR },
+ { 0x76D0F817, 32, NDPI_PROTOCOL_TOR },
+ { 0x76D3C1BE, 32, NDPI_PROTOCOL_TOR },
+ { 0x76D3C2E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x77092F46, 32, NDPI_PROTOCOL_TOR },
+ { 0x77EDA418, 32, NDPI_PROTOCOL_TOR },
+ { 0x77F64734, 32, NDPI_PROTOCOL_TOR },
+ { 0x781DD933, 32, NDPI_PROTOCOL_TOR },
+ { 0x78339DD3, 32, NDPI_PROTOCOL_TOR },
+ { 0x7839A32E, 32, NDPI_PROTOCOL_TOR },
+ { 0x783B2AC8, 32, NDPI_PROTOCOL_TOR },
+ { 0x783BA789, 32, NDPI_PROTOCOL_TOR },
+ { 0x784AE0A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x7890BEA2, 32, NDPI_PROTOCOL_TOR },
+ { 0x7936AF32, 32, NDPI_PROTOCOL_TOR },
+ { 0x794953C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x7954959D, 32, NDPI_PROTOCOL_TOR },
+ { 0x79623AD3, 32, NDPI_PROTOCOL_TOR },
+ { 0x79628113, 32, NDPI_PROTOCOL_TOR },
+ { 0x7963582E, 32, NDPI_PROTOCOL_TOR },
+ { 0x7963B8C8, 32, NDPI_PROTOCOL_TOR },
+ { 0x7972B51D, 32, NDPI_PROTOCOL_TOR },
+ { 0x797AA193, 32, NDPI_PROTOCOL_TOR },
+ { 0x79D1E5D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x79D34C57, 32, NDPI_PROTOCOL_TOR },
+ { 0x79D3C2E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x7A744433, 32, NDPI_PROTOCOL_TOR },
+ { 0x7B01A089, 32, NDPI_PROTOCOL_TOR },
+ { 0x7B64357A, 32, NDPI_PROTOCOL_TOR },
+ { 0x7B6CE046, 32, NDPI_PROTOCOL_TOR },
+ { 0x7BDDB10E, 32, NDPI_PROTOCOL_TOR },
+ { 0x7C0DAC95, 32, NDPI_PROTOCOL_TOR },
+ { 0x7C18F2DD, 32, NDPI_PROTOCOL_TOR },
+ { 0x7C67D84F, 32, NDPI_PROTOCOL_TOR },
+ { 0x7C6DE896, 32, NDPI_PROTOCOL_TOR },
+ { 0x7C951525, 32, NDPI_PROTOCOL_TOR },
+ { 0x7CA9666D, 32, NDPI_PROTOCOL_TOR },
+ { 0x7CA981CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x7CF8F9F5, 32, NDPI_PROTOCOL_TOR },
+ { 0x7CF8F9F7, 32, NDPI_PROTOCOL_TOR },
+ { 0x7CF8F9FA, 32, NDPI_PROTOCOL_TOR },
+ { 0x7CF8F9FD, 32, NDPI_PROTOCOL_TOR },
+ { 0x7D1E5578, 32, NDPI_PROTOCOL_TOR },
+ { 0x7D352C26, 32, NDPI_PROTOCOL_TOR },
+ { 0x7D83BD18, 32, NDPI_PROTOCOL_TOR },
+ { 0x7D83BD2C, 32, NDPI_PROTOCOL_TOR },
+ { 0x7DECCCB2, 32, NDPI_PROTOCOL_TOR },
+ { 0x7DFF021E, 32, NDPI_PROTOCOL_TOR },
+ { 0x7E08CD97, 32, NDPI_PROTOCOL_TOR },
+ { 0x7E460792, 32, NDPI_PROTOCOL_TOR },
+ { 0x7E57F79D, 32, NDPI_PROTOCOL_TOR },
+ { 0x8006E06B, 32, NDPI_PROTOCOL_TOR },
+ { 0x800CB13B, 32, NDPI_PROTOCOL_TOR },
+ { 0x800CE238, 32, NDPI_PROTOCOL_TOR },
+ { 0x800CE238, 32, NDPI_PROTOCOL_TOR },
+ { 0x800CE252, 32, NDPI_PROTOCOL_TOR },
+ { 0x800CE252, 32, NDPI_PROTOCOL_TOR },
+ { 0x801F0022, 32, NDPI_PROTOCOL_TOR },
+ { 0x801F0022, 32, NDPI_PROTOCOL_TOR },
+ { 0x801F0027, 32, NDPI_PROTOCOL_TOR },
+ { 0x80270844, 32, NDPI_PROTOCOL_TOR },
+ { 0x80278E14, 32, NDPI_PROTOCOL_TOR },
+ { 0x80278E15, 32, NDPI_PROTOCOL_TOR },
+ { 0x80348069, 32, NDPI_PROTOCOL_TOR },
+ { 0x8034A014, 32, NDPI_PROTOCOL_TOR },
+ { 0x80392F1E, 32, NDPI_PROTOCOL_TOR },
+ { 0x803B1279, 32, NDPI_PROTOCOL_TOR },
+ { 0x804490CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x80473391, 32, NDPI_PROTOCOL_TOR },
+ { 0x804910C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x804F35F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x804FBA39, 32, NDPI_PROTOCOL_TOR },
+ { 0x80752B5C, 32, NDPI_PROTOCOL_TOR },
+ { 0x80752B61, 32, NDPI_PROTOCOL_TOR },
+ { 0x80752B61, 32, NDPI_PROTOCOL_TOR },
+ { 0x807F2860, 32, NDPI_PROTOCOL_TOR },
+ { 0x8082CC5B, 32, NDPI_PROTOCOL_TOR },
+ { 0x8087BD74, 32, NDPI_PROTOCOL_TOR },
+ { 0x80AD374E, 32, NDPI_PROTOCOL_TOR },
+ { 0x80B1AA5A, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7227A, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C72305, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C723BF, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C729EE, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C72A6C, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C72C2E, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C72EDC, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C733D0, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C737CF, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C73947, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C73F21, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7404F, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C74471, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C748B6, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C74AE2, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C753BB, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7579B, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C75F79, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C75F7E, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C76AE6, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C77A68, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C77A76, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C77B13, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C782E3, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C78407, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C78548, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7859A, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C78BEC, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C79053, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C794F3, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C797C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C79A84, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7A56E, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7A5D4, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7A88E, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7AEF7, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7AF45, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7B364, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7B654, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7B73B, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7D4DC, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7D647, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7D9F3, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7E434, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7ECBE, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7F0C1, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7F24B, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7F4CE, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7FA9F, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7FCC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x80C7FD9C, 32, NDPI_PROTOCOL_TOR },
+ { 0x80D002E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x80DF5C53, 32, NDPI_PROTOCOL_TOR },
+ { 0x80E81239, 32, NDPI_PROTOCOL_TOR },
+ { 0x80ED9D72, 32, NDPI_PROTOCOL_TOR },
+ { 0x810A78C1, 32, NDPI_PROTOCOL_TOR },
+ { 0x811583C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x81400893, 32, NDPI_PROTOCOL_TOR },
+ { 0x817B0706, 32, NDPI_PROTOCOL_TOR },
+ { 0x817B0706, 32, NDPI_PROTOCOL_TOR },
+ { 0x817B0707, 32, NDPI_PROTOCOL_TOR },
+ { 0x817B0707, 32, NDPI_PROTOCOL_TOR },
+ { 0x817B0708, 32, NDPI_PROTOCOL_TOR },
+ { 0x817B0708, 32, NDPI_PROTOCOL_TOR },
+ { 0x817B0727, 32, NDPI_PROTOCOL_TOR },
+ { 0x817B0727, 32, NDPI_PROTOCOL_TOR },
+ { 0x817FFED5, 32, NDPI_PROTOCOL_TOR },
+ { 0x818200B7, 32, NDPI_PROTOCOL_TOR },
+ { 0x8185081F, 32, NDPI_PROTOCOL_TOR },
+ { 0x81BB3621, 32, NDPI_PROTOCOL_TOR },
+ { 0x81F1A1FA, 32, NDPI_PROTOCOL_TOR },
+ { 0x81F480A9, 32, NDPI_PROTOCOL_TOR },
+ { 0x820FBD2D, 32, NDPI_PROTOCOL_TOR },
+ { 0x82192C69, 32, NDPI_PROTOCOL_TOR },
+ { 0x823FAD7E, 32, NDPI_PROTOCOL_TOR },
+ { 0x824B51FB, 32, NDPI_PROTOCOL_TOR },
+ { 0x824BB225, 32, NDPI_PROTOCOL_TOR },
+ { 0x827B031B, 32, NDPI_PROTOCOL_TOR },
+ { 0x827E8EAB, 32, NDPI_PROTOCOL_TOR },
+ { 0x8284B17E, 32, NDPI_PROTOCOL_TOR },
+ { 0x82950E1F, 32, NDPI_PROTOCOL_TOR },
+ { 0x8295C80C, 32, NDPI_PROTOCOL_TOR },
+ { 0x8295CB6B, 32, NDPI_PROTOCOL_TOR },
+ { 0x8295DC7D, 32, NDPI_PROTOCOL_TOR },
+ { 0x82B417E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x82B43F96, 32, NDPI_PROTOCOL_TOR },
+ { 0x82B84B76, 32, NDPI_PROTOCOL_TOR },
+ { 0x82FD157B, 32, NDPI_PROTOCOL_TOR },
+ { 0x82FF48A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x82FF49CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x82FF49CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x82FF8242, 32, NDPI_PROTOCOL_TOR },
+ { 0x83488818, 32, NDPI_PROTOCOL_TOR },
+ { 0x83488A0B, 32, NDPI_PROTOCOL_TOR },
+ { 0x83AD8008, 32, NDPI_PROTOCOL_TOR },
+ { 0x83BC180E, 32, NDPI_PROTOCOL_TOR },
+ { 0x83BC28BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x83BC28BD, 32, NDPI_PROTOCOL_TOR },
+ { 0x83BC28BD, 32, NDPI_PROTOCOL_TOR },
+ { 0x83D79EED, 32, NDPI_PROTOCOL_TOR },
+ { 0x83D7A8F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x83D7ACD6, 32, NDPI_PROTOCOL_TOR },
+ { 0x83D7B062, 32, NDPI_PROTOCOL_TOR },
+ { 0x84D83602, 32, NDPI_PROTOCOL_TOR },
+ { 0x84E69651, 32, NDPI_PROTOCOL_TOR },
+ { 0x84F81E0C, 32, NDPI_PROTOCOL_TOR },
+ { 0x84FBE6E3, 32, NDPI_PROTOCOL_TOR },
+ { 0x86001A20, 32, NDPI_PROTOCOL_TOR },
+ { 0x86036F77, 32, NDPI_PROTOCOL_TOR },
+ { 0x8603C987, 32, NDPI_PROTOCOL_TOR },
+ { 0x8603EA32, 32, NDPI_PROTOCOL_TOR },
+ { 0x86227D25, 32, NDPI_PROTOCOL_TOR },
+ { 0x86227D44, 32, NDPI_PROTOCOL_TOR },
+ { 0x862293AF, 32, NDPI_PROTOCOL_TOR },
+ { 0x8622D0E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x8631E0BC, 32, NDPI_PROTOCOL_TOR },
+ { 0x865B4E8F, 32, NDPI_PROTOCOL_TOR },
+ { 0x865D88B1, 32, NDPI_PROTOCOL_TOR },
+ { 0x86604111, 32, NDPI_PROTOCOL_TOR },
+ { 0x866370A8, 32, NDPI_PROTOCOL_TOR },
+ { 0x8666C865, 32, NDPI_PROTOCOL_TOR },
+ { 0x866A03FE, 32, NDPI_PROTOCOL_TOR },
+ { 0x867703A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x8679405D, 32, NDPI_PROTOCOL_TOR },
+ { 0x8679436A, 32, NDPI_PROTOCOL_TOR },
+ { 0x86A95CDB, 32, NDPI_PROTOCOL_TOR },
+ { 0x86E2441D, 32, NDPI_PROTOCOL_TOR },
+ { 0x86F993AE, 32, NDPI_PROTOCOL_TOR },
+ { 0x86FFEF3D, 32, NDPI_PROTOCOL_TOR },
+ { 0x88A8C999, 32, NDPI_PROTOCOL_TOR },
+ { 0x88F307AF, 32, NDPI_PROTOCOL_TOR },
+ { 0x88F30E86, 32, NDPI_PROTOCOL_TOR },
+ { 0x88F3E072, 32, NDPI_PROTOCOL_TOR },
+ { 0x88F3E072, 32, NDPI_PROTOCOL_TOR },
+ { 0x898708E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x899306B0, 32, NDPI_PROTOCOL_TOR },
+ { 0x89CD25DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x89CD7C23, 32, NDPI_PROTOCOL_TOR },
+ { 0x89E0E221, 32, NDPI_PROTOCOL_TOR },
+ { 0x89E23B7F, 32, NDPI_PROTOCOL_TOR },
+ { 0x89E2952B, 32, NDPI_PROTOCOL_TOR },
+ { 0x89F87A44, 32, NDPI_PROTOCOL_TOR },
+ { 0x8A640AD1, 32, NDPI_PROTOCOL_TOR },
+ { 0x8A6E2D26, 32, NDPI_PROTOCOL_TOR },
+ { 0x8A807C37, 32, NDPI_PROTOCOL_TOR },
+ { 0x8A80A9EC, 32, NDPI_PROTOCOL_TOR },
+ { 0x8B0E0DEC, 32, NDPI_PROTOCOL_TOR },
+ { 0x8B4E8DF7, 32, NDPI_PROTOCOL_TOR },
+ { 0x8B5B466B, 32, NDPI_PROTOCOL_TOR },
+ { 0x8C716E0B, 32, NDPI_PROTOCOL_TOR },
+ { 0x8C795022, 32, NDPI_PROTOCOL_TOR },
+ { 0x8C79502A, 32, NDPI_PROTOCOL_TOR },
+ { 0x8CB4BEBF, 32, NDPI_PROTOCOL_TOR },
+ { 0x8CBA4630, 32, NDPI_PROTOCOL_TOR },
+ { 0x8CC0DA8B, 32, NDPI_PROTOCOL_TOR },
+ { 0x8D0015F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x8D009B6D, 32, NDPI_PROTOCOL_TOR },
+ { 0x8D00AF95, 32, NDPI_PROTOCOL_TOR },
+ { 0x8D142144, 32, NDPI_PROTOCOL_TOR },
+ { 0x8D142145, 32, NDPI_PROTOCOL_TOR },
+ { 0x8D14214F, 32, NDPI_PROTOCOL_TOR },
+ { 0x8D369FB8, 32, NDPI_PROTOCOL_TOR },
+ { 0x8D466911, 32, NDPI_PROTOCOL_TOR },
+ { 0x8D8A8A88, 32, NDPI_PROTOCOL_TOR },
+ { 0x8D8A8DD0, 32, NDPI_PROTOCOL_TOR },
+ { 0x8D8AC2E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x8DFFA58A, 32, NDPI_PROTOCOL_TOR },
+ { 0x8DFFA77A, 32, NDPI_PROTOCOL_TOR },
+ { 0x8DFFBDA1, 32, NDPI_PROTOCOL_TOR },
+ { 0x8E0420C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x8E0433E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x8E04CF3B, 32, NDPI_PROTOCOL_TOR },
+ { 0x8E04D0A7, 32, NDPI_PROTOCOL_TOR },
+ { 0x8E04D519, 32, NDPI_PROTOCOL_TOR },
+ { 0x8E04D571, 32, NDPI_PROTOCOL_TOR },
+ { 0x8E04D726, 32, NDPI_PROTOCOL_TOR },
+ { 0x8E04D757, 32, NDPI_PROTOCOL_TOR },
+ { 0x8E36B0B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x8E69D044, 32, NDPI_PROTOCOL_TOR },
+ { 0x8FB128C0, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C0626, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C063B, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C0849, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C0B64, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C0E91, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C1DD0, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C1EA7, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C25F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C27CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C2879, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C3225, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C357D, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C3635, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C4042, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C498C, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C5044, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C5B87, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C6007, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C6439, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C6E67, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C6E67, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C7055, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C7EB3, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C7FA5, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C8023, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C832A, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C95CB, 32, NDPI_PROTOCOL_TOR },
+ { 0x904C9C65, 32, NDPI_PROTOCOL_TOR },
+ { 0x904CA35D, 32, NDPI_PROTOCOL_TOR },
+ { 0x904CB037, 32, NDPI_PROTOCOL_TOR },
+ { 0x904CB6CA, 32, NDPI_PROTOCOL_TOR },
+ { 0x904CC3E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x904CC728, 32, NDPI_PROTOCOL_TOR },
+ { 0x904CCB75, 32, NDPI_PROTOCOL_TOR },
+ { 0x904CF413, 32, NDPI_PROTOCOL_TOR },
+ { 0x904CFD04, 32, NDPI_PROTOCOL_TOR },
+ { 0x91DC000F, 32, NDPI_PROTOCOL_TOR },
+ { 0x92002090, 32, NDPI_PROTOCOL_TOR },
+ { 0x92002A3A, 32, NDPI_PROTOCOL_TOR },
+ { 0x92002A6E, 32, NDPI_PROTOCOL_TOR },
+ { 0x920048B4, 32, NDPI_PROTOCOL_TOR },
+ { 0x920049B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x923434C7, 32, NDPI_PROTOCOL_TOR },
+ { 0x9234419F, 32, NDPI_PROTOCOL_TOR },
+ { 0x92344BB3, 32, NDPI_PROTOCOL_TOR },
+ { 0x923490FC, 32, NDPI_PROTOCOL_TOR },
+ { 0x92349273, 32, NDPI_PROTOCOL_TOR },
+ { 0x925A1CB7, 32, NDPI_PROTOCOL_TOR },
+ { 0x9273A850, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B915A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B983AF, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B983EF, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B988DF, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B98D39, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B98F90, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B996DB, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B99939, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B99FF1, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B9A2EB, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B9B440, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B9B70D, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B9B99A, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B9BDC5, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B9FB5A, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B9FDCA, 32, NDPI_PROTOCOL_TOR },
+ { 0x92B9FDCA, 32, NDPI_PROTOCOL_TOR },
+ { 0x92FF39E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x93459FC4, 32, NDPI_PROTOCOL_TOR },
+ { 0x93660115, 32, NDPI_PROTOCOL_TOR },
+ { 0x9366D8F2, 32, NDPI_PROTOCOL_TOR },
+ { 0x93AFBB8F, 32, NDPI_PROTOCOL_TOR },
+ { 0x93DEA58B, 32, NDPI_PROTOCOL_TOR },
+ { 0x93E5081A, 32, NDPI_PROTOCOL_TOR },
+ { 0x946429FB, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB1431, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB2832, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB2BE9, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB2D87, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB431B, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB4566, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB4D64, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB53C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB5884, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB71E6, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB7DD3, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB809C, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FB97BD, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FBBEE5, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FBCE86, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FBCF24, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FBD7E9, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FBD7F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FBE30E, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FBED4F, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FBF597, 32, NDPI_PROTOCOL_TOR },
+ { 0x94FBFEE5, 32, NDPI_PROTOCOL_TOR },
+ { 0x9509001B, 32, NDPI_PROTOCOL_TOR },
+ { 0x9509003B, 32, NDPI_PROTOCOL_TOR },
+ { 0x9509003C, 32, NDPI_PROTOCOL_TOR },
+ { 0x951436DA, 32, NDPI_PROTOCOL_TOR },
+ { 0x958405BD, 32, NDPI_PROTOCOL_TOR },
+ { 0x959A9810, 32, NDPI_PROTOCOL_TOR },
+ { 0x959A9879, 32, NDPI_PROTOCOL_TOR },
+ { 0x959A9A92, 32, NDPI_PROTOCOL_TOR },
+ { 0x959A9D50, 32, NDPI_PROTOCOL_TOR },
+ { 0x959A9E7A, 32, NDPI_PROTOCOL_TOR },
+ { 0x959A9EE4, 32, NDPI_PROTOCOL_TOR },
+ { 0x959A9F57, 32, NDPI_PROTOCOL_TOR },
+ { 0x959A9FAC, 32, NDPI_PROTOCOL_TOR },
+ { 0x95ACC7F4, 32, NDPI_PROTOCOL_TOR },
+ { 0x95D2AB45, 32, NDPI_PROTOCOL_TOR },
+ { 0x95D2ADF7, 32, NDPI_PROTOCOL_TOR },
+ { 0x95D2BAC6, 32, NDPI_PROTOCOL_TOR },
+ { 0x95FF6DC9, 32, NDPI_PROTOCOL_TOR },
+ { 0x96659DFA, 32, NDPI_PROTOCOL_TOR },
+ { 0x968C0522, 32, NDPI_PROTOCOL_TOR },
+ { 0x971B08A4, 32, NDPI_PROTOCOL_TOR },
+ { 0x971DFD3F, 32, NDPI_PROTOCOL_TOR },
+ { 0x971FA3B8, 32, NDPI_PROTOCOL_TOR },
+ { 0x9741F79A, 32, NDPI_PROTOCOL_TOR },
+ { 0x97507745, 32, NDPI_PROTOCOL_TOR },
+ { 0x97507758, 32, NDPI_PROTOCOL_TOR },
+ { 0x9750800C, 32, NDPI_PROTOCOL_TOR },
+ { 0x9750A491, 32, NDPI_PROTOCOL_TOR },
+ { 0x97E04B76, 32, NDPI_PROTOCOL_TOR },
+ { 0x97E2D38D, 32, NDPI_PROTOCOL_TOR },
+ { 0x97E5201B, 32, NDPI_PROTOCOL_TOR },
+ { 0x97E65FF1, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC049E, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC0506, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC061B, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC0670, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC06C2, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC06C6, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC07B1, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC0B72, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC0E61, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC160C, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC171F, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC172C, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC1839, 32, NDPI_PROTOCOL_TOR },
+ { 0x97EC18E4, 32, NDPI_PROTOCOL_TOR },
+ { 0x97ECDA43, 32, NDPI_PROTOCOL_TOR },
+ { 0x97ECDD2C, 32, NDPI_PROTOCOL_TOR },
+ { 0x97ECDE1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x97ECDE1B, 32, NDPI_PROTOCOL_TOR },
+ { 0x97ECDED9, 32, NDPI_PROTOCOL_TOR },
+ { 0x97FC2A46, 32, NDPI_PROTOCOL_TOR },
+ { 0x99782A89, 32, NDPI_PROTOCOL_TOR },
+ { 0x997925A6, 32, NDPI_PROTOCOL_TOR },
+ { 0x997938DD, 32, NDPI_PROTOCOL_TOR },
+ { 0x99793A49, 32, NDPI_PROTOCOL_TOR },
+ { 0x997FFB43, 32, NDPI_PROTOCOL_TOR },
+ { 0x9A23AFE1, 32, NDPI_PROTOCOL_TOR },
+ { 0x9A7F3C42, 32, NDPI_PROTOCOL_TOR },
+ { 0x9A7F3D62, 32, NDPI_PROTOCOL_TOR },
+ { 0x9A7F3D8D, 32, NDPI_PROTOCOL_TOR },
+ { 0x9B5EA7C4, 32, NDPI_PROTOCOL_TOR },
+ { 0x9BD2EF58, 32, NDPI_PROTOCOL_TOR },
+ { 0x9C38FAE3, 32, NDPI_PROTOCOL_TOR },
+ { 0x9D0757B8, 32, NDPI_PROTOCOL_TOR },
+ { 0x9D07CA47, 32, NDPI_PROTOCOL_TOR },
+ { 0x9D07D224, 32, NDPI_PROTOCOL_TOR },
+ { 0x9D07DEE2, 32, NDPI_PROTOCOL_TOR },
+ { 0x9D0EF604, 32, NDPI_PROTOCOL_TOR },
+ { 0x9E3AA97E, 32, NDPI_PROTOCOL_TOR },
+ { 0x9E554D57, 32, NDPI_PROTOCOL_TOR },
+ { 0x9EB53326, 32, NDPI_PROTOCOL_TOR },
+ { 0x9EB552B2, 32, NDPI_PROTOCOL_TOR },
+ { 0x9EB560E3, 32, NDPI_PROTOCOL_TOR },
+ { 0x9EDE8F19, 32, NDPI_PROTOCOL_TOR },
+ { 0x9EFFD4B3, 32, NDPI_PROTOCOL_TOR },
+ { 0x9EFFD729, 32, NDPI_PROTOCOL_TOR },
+ { 0x9F94B55A, 32, NDPI_PROTOCOL_TOR },
+ { 0xA0612F1E, 32, NDPI_PROTOCOL_TOR },
+ { 0xA1357425, 32, NDPI_PROTOCOL_TOR },
+ { 0xA1357898, 32, NDPI_PROTOCOL_TOR },
+ { 0xA135A068, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2D3D985, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2D3E0E9, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2D813ED, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DA417E, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DA760C, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DAD084, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DAE92B, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DB02B1, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DC2FB8, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DC38BA, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DCD94C, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DCDA6D, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DCF1DF, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DDC939, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2DEA01D, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F307B4, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F317DD, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F320CA, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F323FB, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F32725, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F328A1, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F33089, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F33543, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F3354B, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F33EEF, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F348C6, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F3499C, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F35F80, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F364E1, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F3656E, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F367AE, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F371B6, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F37479, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F37734, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F377F6, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F37BDC, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F386E0, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F38B4E, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F38E6B, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F3969C, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F396E5, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F3971B, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F39C7A, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F3A25C, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F3F878, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F3FD76, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F418ED, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F419BA, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F419D6, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F41A09, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F41A9D, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F41D7C, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F422A9, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F52912, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F5D9D0, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F5DC86, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F5DC8C, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F74807, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F7481B, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F748C7, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F748C8, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F748C9, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F748D4, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F748D5, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F748D8, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F748D9, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F7494A, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F749CC, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F749CE, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F809ED, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F80B06, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F80BB0, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F88C65, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F88E67, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F88F29, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F8A033, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F8A053, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F8A090, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F8A097, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F8A1D5, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F8A3CA, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2F8A50E, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2FAE9C2, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2FAEA7D, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2FB463A, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2FB463A, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2FCCC3E, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2FCF079, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2FCF17B, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2FCF20D, 32, NDPI_PROTOCOL_TOR },
+ { 0xA2FE4436, 32, NDPI_PROTOCOL_TOR },
+ { 0xA40FA707, 32, NDPI_PROTOCOL_TOR },
+ { 0xA4272AFE, 32, NDPI_PROTOCOL_TOR },
+ { 0xA57B94C7, 32, NDPI_PROTOCOL_TOR },
+ { 0xA5FEFF10, 32, NDPI_PROTOCOL_TOR },
+ { 0xA5FEFF10, 32, NDPI_PROTOCOL_TOR },
+ { 0xA6460F0E, 32, NDPI_PROTOCOL_TOR },
+ { 0xA6465E6A, 32, NDPI_PROTOCOL_TOR },
+ { 0xA646CF02, 32, NDPI_PROTOCOL_TOR },
+ { 0xA646D4B5, 32, NDPI_PROTOCOL_TOR },
+ { 0xA64E0721, 32, NDPI_PROTOCOL_TOR },
+ { 0xA65215C8, 32, NDPI_PROTOCOL_TOR },
+ { 0xA6540737, 32, NDPI_PROTOCOL_TOR },
+ { 0xA6540794, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7397143, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7582348, 32, NDPI_PROTOCOL_TOR },
+ { 0xA758283F, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7582898, 32, NDPI_PROTOCOL_TOR },
+ { 0xA75828C8, 32, NDPI_PROTOCOL_TOR },
+ { 0xA75829BB, 32, NDPI_PROTOCOL_TOR },
+ { 0xA75829C2, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7582BF6, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7582C32, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7582C33, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7582C34, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7587066, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7587D43, 32, NDPI_PROTOCOL_TOR },
+ { 0xA77202C0, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7720390, 32, NDPI_PROTOCOL_TOR },
+ { 0xA77203A6, 32, NDPI_PROTOCOL_TOR },
+ { 0xA772243E, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7722489, 32, NDPI_PROTOCOL_TOR },
+ { 0xA77229D3, 32, NDPI_PROTOCOL_TOR },
+ { 0xA77229D3, 32, NDPI_PROTOCOL_TOR },
+ { 0xA77229D4, 32, NDPI_PROTOCOL_TOR },
+ { 0xA77229D4, 32, NDPI_PROTOCOL_TOR },
+ { 0xA772423D, 32, NDPI_PROTOCOL_TOR },
+ { 0xA77243CC, 32, NDPI_PROTOCOL_TOR },
+ { 0xA77243D4, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7724418, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7724726, 32, NDPI_PROTOCOL_TOR },
+ { 0xA77247BD, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7726116, 32, NDPI_PROTOCOL_TOR },
+ { 0xA772629A, 32, NDPI_PROTOCOL_TOR },
+ { 0xA772712E, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7727130, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7727288, 32, NDPI_PROTOCOL_TOR },
+ { 0xA77272D1, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7729864, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7A02CC2, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7A02CE2, 32, NDPI_PROTOCOL_TOR },
+ { 0xA7A0A39A, 32, NDPI_PROTOCOL_TOR },
+ { 0xA83ED9D8, 32, NDPI_PROTOCOL_TOR },
+ { 0xA867C3FA, 32, NDPI_PROTOCOL_TOR },
+ { 0xA896FB0F, 32, NDPI_PROTOCOL_TOR },
+ { 0xA8EB91AF, 32, NDPI_PROTOCOL_TOR },
+ { 0xA8EB9238, 32, NDPI_PROTOCOL_TOR },
+ { 0xA8EB9239, 32, NDPI_PROTOCOL_TOR },
+ { 0xA8EB935E, 32, NDPI_PROTOCOL_TOR },
+ { 0xA8EB9361, 32, NDPI_PROTOCOL_TOR },
+ { 0xA8EB9664, 32, NDPI_PROTOCOL_TOR },
+ { 0xA8EB9A60, 32, NDPI_PROTOCOL_TOR },
+ { 0xA8EB9CA2, 32, NDPI_PROTOCOL_TOR },
+ { 0xA9E57D1B, 32, NDPI_PROTOCOL_TOR },
+ { 0xA9E57D1B, 32, NDPI_PROTOCOL_TOR },
+ { 0xAA4BA251, 32, NDPI_PROTOCOL_TOR },
+ { 0xAA4BA257, 32, NDPI_PROTOCOL_TOR },
+ { 0xAA4BA3B4, 32, NDPI_PROTOCOL_TOR },
+ { 0xAB19C109, 32, NDPI_PROTOCOL_TOR },
+ { 0xAB19C114, 32, NDPI_PROTOCOL_TOR },
+ { 0xAB19C14D, 32, NDPI_PROTOCOL_TOR },
+ { 0xAB19C14E, 32, NDPI_PROTOCOL_TOR },
+ { 0xAB19C1EB, 32, NDPI_PROTOCOL_TOR },
+ { 0xAB655D88, 32, NDPI_PROTOCOL_TOR },
+ { 0xAC07A4C5, 32, NDPI_PROTOCOL_TOR },
+ { 0xACF51678, 32, NDPI_PROTOCOL_TOR },
+ { 0xACF520B9, 32, NDPI_PROTOCOL_TOR },
+ { 0xACF520BA, 32, NDPI_PROTOCOL_TOR },
+ { 0xACF521F9, 32, NDPI_PROTOCOL_TOR },
+ { 0xACF52416, 32, NDPI_PROTOCOL_TOR },
+ { 0xACF53C64, 32, NDPI_PROTOCOL_TOR },
+ { 0xACF5DB85, 32, NDPI_PROTOCOL_TOR },
+ { 0xACFE0D7C, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD08664C, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD0B116C, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD0D8D1C, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD10B454, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD12E604, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD16F0E2, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD172ADB, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD1C491B, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD2C23B2, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD2C3ACA, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD2DE436, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD304BF6, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD30B617, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD335037, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD33C620, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD36711E, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD40C757, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD427043, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD45B52A, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD469914, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD46DD71, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD4717F9, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD479C14, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD49717D, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD4CA387, 32, NDPI_PROTOCOL_TOR },
+ { 0xAD5980AC, 32, NDPI_PROTOCOL_TOR },
+ { 0xADA0B4BD, 32, NDPI_PROTOCOL_TOR },
+ { 0xADA103A9, 32, NDPI_PROTOCOL_TOR },
+ { 0xADA48BC3, 32, NDPI_PROTOCOL_TOR },
+ { 0xADA4CEB5, 32, NDPI_PROTOCOL_TOR },
+ { 0xADA4DBFA, 32, NDPI_PROTOCOL_TOR },
+ { 0xADA5F099, 32, NDPI_PROTOCOL_TOR },
+ { 0xADA71245, 32, NDPI_PROTOCOL_TOR },
+ { 0xADC769FE, 32, NDPI_PROTOCOL_TOR },
+ { 0xADD0C4D7, 32, NDPI_PROTOCOL_TOR },
+ { 0xADD0FBB2, 32, NDPI_PROTOCOL_TOR },
+ { 0xADD56C74, 32, NDPI_PROTOCOL_TOR },
+ { 0xADD5719B, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE45AE0, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE45B5B, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE65550, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE68199, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE683CF, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE683CF, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE686EE, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE68ABF, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE68E82, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE694EC, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE69504, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE69A5A, 32, NDPI_PROTOCOL_TOR },
+ { 0xADE69AB8, 32, NDPI_PROTOCOL_TOR },
+ { 0xADECF938, 32, NDPI_PROTOCOL_TOR },
+ { 0xADECFAD3, 32, NDPI_PROTOCOL_TOR },
+ { 0xADECFF8E, 32, NDPI_PROTOCOL_TOR },
+ { 0xADEF4FD2, 32, NDPI_PROTOCOL_TOR },
+ { 0xADF279C7, 32, NDPI_PROTOCOL_TOR },
+ { 0xADF66823, 32, NDPI_PROTOCOL_TOR },
+ { 0xADF6FE86, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFED0A8, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFED842, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFED843, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFED844, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFED845, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFC24D, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFC41E, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFCD71, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFD1B5, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFD2CD, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFD3AF, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFDA6A, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFDCAB, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFDD60, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFE28E, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFE455, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFE459, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFE486, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFE8C0, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFE93C, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFED6B, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFED6B, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFEDA5, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFF217, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFF259, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFF574, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFF64E, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFF6A2, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFF7F7, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFF812, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFF869, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFF9DE, 32, NDPI_PROTOCOL_TOR },
+ { 0xADFFFAF0, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE03A82A, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE064AC1, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE15F745, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE1D40A4, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE2DB58A, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE32F679, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE3E4833, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE3F713C, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE463C5C, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE475A25, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE5F6BA7, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE60D6AE, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE6208CA, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE6328BE, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE6C43BC, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE6D6112, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE7E102D, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE886956, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE8AC693, 32, NDPI_PROTOCOL_TOR },
+ { 0xAE8FF3F7, 32, NDPI_PROTOCOL_TOR },
+ { 0xAF648B8C, 32, NDPI_PROTOCOL_TOR },
+ { 0xAF8741DE, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00901D3, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00904CE, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0090574, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0091051, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0091948, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00926C6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0092E8D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00932F0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB009368E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0095425, 32, NDPI_PROTOCOL_TOR },
+ { 0xB009558D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0095AD7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0096708, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0096714, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0096B68, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00977A7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0097DD1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0098BFC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0098C6C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0098FC8, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0098FD0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00991C2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0099344, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00994B0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0099D4D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB009B42F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB009C0AB, 32, NDPI_PROTOCOL_TOR },
+ { 0xB009ED02, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63C8, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63C8, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63C9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63C9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CA, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CA, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CB, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CB, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CE, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CE, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CF, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63CF, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63D0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63D0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63D1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A63D1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A6BB4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00A74A9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00AFA4F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00AFDDB, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00AFE87, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00C1D0C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00C6B1E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00E717E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00F49B5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB00FBBA1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01C0978, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01C0B2A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01C1F79, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01C305E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01C36D5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01F1C3F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01F2395, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01F323D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01F4255, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01F7158, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01F7494, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01F7827, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01F989F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01F9CC7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01FB509, 32, NDPI_PROTOCOL_TOR },
+ { 0xB01FBF1A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB024237E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0245D6B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB02496F6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0249F29, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0268C0D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03515A2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0357FC2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB035E825, 32, NDPI_PROTOCOL_TOR },
+ { 0xB038EC53, 32, NDPI_PROTOCOL_TOR },
+ { 0xB038ECAD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB038ED5A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB038EDBF, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03A59BC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03A60C7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03A61C9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03A6462, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03A6711, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03A6A59, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03A6AC0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03A7317, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03A7816, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03A799F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03A9FAF, 32, NDPI_PROTOCOL_TOR },
+ { 0xB03D89DD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB043AC1E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB049E604, 32, NDPI_PROTOCOL_TOR },
+ { 0xB04D1A58, 32, NDPI_PROTOCOL_TOR },
+ { 0xB04D226A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB04D2746, 32, NDPI_PROTOCOL_TOR },
+ { 0xB04D29B7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB05019F4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB063C782, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0678035, 32, NDPI_PROTOCOL_TOR },
+ { 0xB06A3636, 32, NDPI_PROTOCOL_TOR },
+ { 0xB06A6B2F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB06CA0F1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB06CA0F2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB06CA0FD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB072F82F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0744531, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0746831, 32, NDPI_PROTOCOL_TOR },
+ { 0xB075128D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB07B065E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB07B0665, 32, NDPI_PROTOCOL_TOR },
+ { 0xB07B1C1F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB07B1C22, 32, NDPI_PROTOCOL_TOR },
+ { 0xB07EF45B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB07EFC0B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB07EFC0C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0BCDE53, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0BD2641, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0BD77B6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0C17D30, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0C20E92, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0C62CC4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0C65C86, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0C6642D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0C67537, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0C7E07F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0C7E590, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0D496A3, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0DD2E35, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0DECAC3, 32, NDPI_PROTOCOL_TOR },
+ { 0xB0E2DAFF, 32, NDPI_PROTOCOL_TOR },
+ { 0xB10648C6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB12F6D15, 32, NDPI_PROTOCOL_TOR },
+ { 0xB15C1B98, 32, NDPI_PROTOCOL_TOR },
+ { 0xB18D1209, 32, NDPI_PROTOCOL_TOR },
+ { 0xB194ACC4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB1BC41E6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB1CD10C8, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2011DB1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB202DFF0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB202E307, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2031B59, 32, NDPI_PROTOCOL_TOR },
+ { 0xB204CFB7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2067327, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2070DE7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB20BA25E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2102D5A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB210D038, 32, NDPI_PROTOCOL_TOR },
+ { 0xB210D039, 32, NDPI_PROTOCOL_TOR },
+ { 0xB211AA0B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB211AA13, 32, NDPI_PROTOCOL_TOR },
+ { 0xB212106C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21211CC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21211EA, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21253D7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2128308, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2143710, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2143712, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2151456, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2157245, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21572B9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2182081, 32, NDPI_PROTOCOL_TOR },
+ { 0xB218CF5C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21944AC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21968A9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2198DE6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21A57B7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21A76A9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21A8269, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21AB707, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21AC341, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21B383A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21B78E5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB21B7ACB, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220225B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2202C9D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2203E91, 32, NDPI_PROTOCOL_TOR },
+ { 0xB22064D7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220784B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2207A41, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2208FAF, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2208FAF, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220B560, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220B561, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220B562, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220B563, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220D861, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220D892, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220DBC5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220DC0C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220DC18, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220DD97, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220DDCF, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220DE15, 32, NDPI_PROTOCOL_TOR },
+ { 0xB220EE9E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2212397, 32, NDPI_PROTOCOL_TOR },
+ { 0xB22170AB, 32, NDPI_PROTOCOL_TOR },
+ { 0xB22EA34B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E0999, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E0E7F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E0E97, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E102A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E12D7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E1384, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E1A53, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E2520, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E27CA, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E2E07, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E3405, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E354B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E36E3, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E38A3, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E3910, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E3A50, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E414D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E4DB6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E4E51, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E507C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E5660, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E56CE, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E5A6F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E5D24, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E5EF3, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E60A0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E64C1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E6892, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E6DA4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E6E8D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E6F30, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E7047, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E769A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E83D8, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E9871, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23E9E9C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EA3E3, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EA7B2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EADCB, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EB2E4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EB893, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EBA9B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EBD4F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EC4B1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EC658, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EC6D5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EC7E2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EC927, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23ECC5B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23ECC63, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23ED1FC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23ED47B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23ED986, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23ED9E9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EDAA0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EDE81, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EE525, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EE5D1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EE707, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EEA99, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EEB68, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EEE78, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EF11E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EF140, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EF877, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EFB08, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EFC52, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23EFCEA, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F00A1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F1030, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F2E61, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F3D43, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F41B3, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F4AC4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F4AF5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F5E90, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F604F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F6122, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F65C5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F6E97, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F749D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F91E2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23F9A5D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23FA2D4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB23FD133, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24021FC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB246D353, 32, NDPI_PROTOCOL_TOR },
+ { 0xB248584D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB249D276, 32, NDPI_PROTOCOL_TOR },
+ { 0xB249D2F0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24A67E4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24D627C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24D7B29, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24ED425, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24EEAC3, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F8540, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F8623, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F86B7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F86B7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F86C4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F88E6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F8B11, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F8B2E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F8D6C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F8EE0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F901C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F901C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F9D24, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F9D24, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F9F93, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24F9FE0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FA039, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FA198, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FA1B1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FA1ED, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FA1ED, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FA3A9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FA515, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FA858, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FAAAD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FAAB5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FAAB5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FB060, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FB072, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FB0B9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FB5E6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB24FBCD4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2520865, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2522270, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2522871, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2524269, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2534549, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2560A58, 32, NDPI_PROTOCOL_TOR },
+ { 0xB281AD8F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB289B71D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB28C33AD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB28C33AD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB28C6812, 32, NDPI_PROTOCOL_TOR },
+ { 0xB28CC54B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB28E0705, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2A23DD6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2A242D4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2A2C21E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2A2C252, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2A2C2D2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2A2C505, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2A746AA, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AA6FC2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AF83C2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AF8B8A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AF8B8A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AF8B8B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AF8B8B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AF8B8C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AF8B8C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AF8B8D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AF8B8D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AF8B8E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2AF8B8E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2BA743C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2BED2D1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2BFC29E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2C0BBAF, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2C3EA94, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2C7EAC0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2C861B6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2C8CBEE, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2C8EE97, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2C92FF5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2C98985, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2C9B19C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2CA6B7B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2CB9302, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2CB9A4F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2CBBF12, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D13297, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D13363, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D134A2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D3238A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D808F5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D83B33, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D85C75, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D9B820, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D9B943, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D9BB05, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D9BB06, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2D9BB27, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2DBF5D6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2EEDF43, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2EEE084, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2EEE16C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2EEE19E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2EEE40C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2EEED2C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2EF3CAC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2EFB113, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FAF3D9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FD60A6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE0615, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE08BB, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE0987, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE1486, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE1486, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE16E4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE193E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE19A5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE1AF4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE1C14, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE1E56, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE1FAD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE1FD1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE23E0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE25C5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE2805, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE2BF4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE2C5B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE2C5B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE2C87, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE2C87, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE2CEA, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE2CEA, 32, NDPI_PROTOCOL_TOR },
+ { 0xB2FE3765, 32, NDPI_PROTOCOL_TOR },
+ { 0xB300C293, 32, NDPI_PROTOCOL_TOR },
+ { 0xB32B8522, 32, NDPI_PROTOCOL_TOR },
+ { 0xB36FE5E8, 32, NDPI_PROTOCOL_TOR },
+ { 0xB3E8F4B7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB4DE4452, 32, NDPI_PROTOCOL_TOR },
+ { 0xB529C599, 32, NDPI_PROTOCOL_TOR },
+ { 0xB529DB75, 32, NDPI_PROTOCOL_TOR },
+ { 0xB52E9531, 32, NDPI_PROTOCOL_TOR },
+ { 0xB5A073AC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB6A70430, 32, NDPI_PROTOCOL_TOR },
+ { 0xB7574B02, 32, NDPI_PROTOCOL_TOR },
+ { 0xB75806AD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8129B07, 32, NDPI_PROTOCOL_TOR },
+ { 0xB812D6D9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8230910, 32, NDPI_PROTOCOL_TOR },
+ { 0xB827A1D3, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8486A34, 32, NDPI_PROTOCOL_TOR },
+ { 0xB84E9433, 32, NDPI_PROTOCOL_TOR },
+ { 0xB85EE222, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8645406, 32, NDPI_PROTOCOL_TOR },
+ { 0xB869CB85, 32, NDPI_PROTOCOL_TOR },
+ { 0xB869DC18, 32, NDPI_PROTOCOL_TOR },
+ { 0xB869EB44, 32, NDPI_PROTOCOL_TOR },
+ { 0xB86A6DF4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB86AD762, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8944B0F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB89BBBCD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8A3447D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8A48472, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8A4F401, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8A4F601, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8AA68F7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8AF118B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8AF2873, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8B07919, 32, NDPI_PROTOCOL_TOR },
+ { 0xB8B705CB, 32, NDPI_PROTOCOL_TOR },
+ { 0xB904E322, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9050983, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9053482, 32, NDPI_PROTOCOL_TOR },
+ { 0xB905355D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB907944E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB908EC83, 32, NDPI_PROTOCOL_TOR },
+ { 0xB908ED1B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB908EDD0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB908EE42, 32, NDPI_PROTOCOL_TOR },
+ { 0xB908EE8B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB908EE8C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90A1DF7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90A4750, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90BA670, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90C0C85, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90C0E76, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90D259E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90D2631, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90D2684, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90D26B9, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90D27C5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90E1C6A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90E1F3B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90EB80D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90EB9F0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB90FF47C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9103C53, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9107C88, 32, NDPI_PROTOCOL_TOR },
+ { 0xB910AC9B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB910AD54, 32, NDPI_PROTOCOL_TOR },
+ { 0xB910AD56, 32, NDPI_PROTOCOL_TOR },
+ { 0xB910C8B0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB910C91C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB911908A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB911B8E4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9129404, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9135724, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9156432, 32, NDPI_PROTOCOL_TOR },
+ { 0xB915671F, 32, NDPI_PROTOCOL_TOR },
+ { 0xB915D8A6, 32, NDPI_PROTOCOL_TOR },
+ { 0xB915D908, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9163F22, 32, NDPI_PROTOCOL_TOR },
+ { 0xB918EBCD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB919D8ED, 32, NDPI_PROTOCOL_TOR },
+ { 0xB91A7CB4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB91A9C1C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB91A9C1D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB91BAF18, 32, NDPI_PROTOCOL_TOR },
+ { 0xB91F644B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9222102, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9246491, 32, NDPI_PROTOCOL_TOR },
+ { 0xB92592AC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB925E2C5, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9262FE0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB928870A, 32, NDPI_PROTOCOL_TOR },
+ { 0xB92DC039, 32, NDPI_PROTOCOL_TOR },
+ { 0xB92DC069, 32, NDPI_PROTOCOL_TOR },
+ { 0xB92DC0BC, 32, NDPI_PROTOCOL_TOR },
+ { 0xB92DC1F2, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9310ED3, 32, NDPI_PROTOCOL_TOR },
+ { 0xB932BFFA, 32, NDPI_PROTOCOL_TOR },
+ { 0xB932E9E0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB935A306, 32, NDPI_PROTOCOL_TOR },
+ { 0xB936EE88, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9385426, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9395219, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D8932, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D8932, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D8949, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D8949, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D942E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D9450, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D945D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D9474, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D948D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D948E, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D94B7, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D94BD, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D94C1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D94E4, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D956D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D9574, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D9576, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D9577, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D95B0, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93D95C1, 32, NDPI_PROTOCOL_TOR },
+ { 0xB93FBC7C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB941C85D, 32, NDPI_PROTOCOL_TOR },
+ { 0xB941CD12, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9453693, 32, NDPI_PROTOCOL_TOR },
+ { 0xB9453744, 32, NDPI_PROTOCOL_TOR },
+ { 0xB948B169, 32, NDPI_PROTOCOL_TOR },
+ { 0xB948E86B, 32, NDPI_PROTOCOL_TOR },
+ { 0xB948F791, 32, NDPI_PROTOCOL_TOR },
+ { 0xB94B382C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB94B382C, 32, NDPI_PROTOCOL_TOR },
+ { 0xB94B3874, 32, NDPI_PROTOCOL_TOR },
+ { 0xB94B3874, 32, NDPI_PROTOCOL_TOR },
+ { 0xB952C8E0, 32, NDPI_PROTOCOL_TOR },
+ { 0xBA160C6E, 32, NDPI_PROTOCOL_TOR },
+ { 0xBA1A4002, 32, NDPI_PROTOCOL_TOR },
+ { 0xBA6B7BAE, 32, NDPI_PROTOCOL_TOR },
+ { 0xBB3B6D26, 32, NDPI_PROTOCOL_TOR },
+ { 0xBB3F6418, 32, NDPI_PROTOCOL_TOR },
+ { 0xBB5F2203, 32, NDPI_PROTOCOL_TOR },
+ { 0xBBD34A78, 32, NDPI_PROTOCOL_TOR },
+ { 0xBBFEE732, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC0262D8, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC04F2B2, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC060D5B, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC06497F, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC18F4FF, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC208F85, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC20F2F4, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC28209A, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC2821D9, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC2825C8, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC2833E8, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC283512, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC283B50, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC283C8E, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC283CF2, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC284C73, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC286345, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC286BCD, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC2880F6, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC2899F2, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC28B34A, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC28CE05, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC28EBD7, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC28F839, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC2AFD0B, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC322E9A, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC3CC333, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC3E5662, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC499110, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC4DD834, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC4ED027, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC553281, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC57A8F9, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC5D117B, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC5DD54B, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC5FF78C, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC603CB8, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC607AC3, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC617F79, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC62D521, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC6450C9, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC67690F, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC676B47, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC6CD29D, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC6D5CC5, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC717278, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC728C79, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC769BEF, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC780C35, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC78EBA5, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC78EFF1, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC78FD27, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC7A05A1, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC7AD504, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC7B2F13, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC7C951D, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC7E5D51, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC7E5D5F, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC817CFA, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC860642, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC860C22, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC860CEC, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC864432, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC864BD3, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8653AB, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A01E5, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A01E5, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A0931, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A0931, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A09D0, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A09D0, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A110F, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A110F, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A5886, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A58A8, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A6574, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A6A8A, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A703C, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A70E2, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A7976, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A7DD1, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8A7DD1, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8D5359, 32, NDPI_PROTOCOL_TOR },
+ { 0xBC8E70F6, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA5033F, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA5033F, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA519D2, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA51A0D, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA51A0D, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA53B2B, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA55E69, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA57B5F, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA57BF4, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA58822, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA58A8D, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA58AB5, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA58AB5, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA5919D, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA5A4A3, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA5A4A3, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA5C181, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA5C88A, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA5D59C, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA5E828, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA5EC12, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA5F1D8, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA609DA, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA60CD4, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA60DE6, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA61250, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA61286, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA6234D, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA624A3, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA625AD, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA625D7, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA62B21, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA62B3D, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA62BC8, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA62D23, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA62EAB, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA63064, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA630B1, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA63152, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA631B4, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA63271, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA63575, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA638B3, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA63C9E, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA63E18, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA73D86, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA745E0, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCA8225A, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCAE49D9, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCAE5D48, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCAEA791, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCAEB379, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCAED97F, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCB55D55, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCB7841D, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCBA10EC, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCC02309, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCC0A86E, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCC1632B, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCC1C8F8, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCC2C9AE, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCC30886, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCC348B3, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCC3D1FD, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCCAFCC1, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCD519EA, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCD58F17, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCD65D16, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCDF3258, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE23EAE, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE294A1, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2957C, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2AB6F, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2ACAA, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2BB8A, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2BD35, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2BE71, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2BF12, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2C030, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2C5E0, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2C7A0, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2C8D8, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2CEC8, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2D6B1, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2D98E, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2DC10, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2DCE2, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2DDF3, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2E196, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2E396, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2E839, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2FA52, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2FDB5, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE2FE59, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE3C986, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE3E068, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE4234B, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE43194, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE63CF6, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE65B87, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE6A6EB, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE6DFB2, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE8B717, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCE94947, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF17195, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF17251, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF18C77, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF18C86, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF18C94, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF18D13, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF18D15, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF18D87, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF18DAA, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF423AB, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF64BB2, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF6CC43, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCF764B8, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCFF1E24, 32, NDPI_PROTOCOL_TOR },
+ { 0xBCFF70E0, 32, NDPI_PROTOCOL_TOR },
+ { 0xBD446D80, 32, NDPI_PROTOCOL_TOR },
+ { 0xBDD4A056, 32, NDPI_PROTOCOL_TOR },
+ { 0xBDF2D9EF, 32, NDPI_PROTOCOL_TOR },
+ { 0xBE03A993, 32, NDPI_PROTOCOL_TOR },
+ { 0xBE589587, 32, NDPI_PROTOCOL_TOR },
+ { 0xBE78E41E, 32, NDPI_PROTOCOL_TOR },
+ { 0xBE7B2D60, 32, NDPI_PROTOCOL_TOR },
+ { 0xBE7B2F74, 32, NDPI_PROTOCOL_TOR },
+ { 0xBEBD7608, 32, NDPI_PROTOCOL_TOR },
+ { 0xBEC0A60C, 32, NDPI_PROTOCOL_TOR },
+ { 0xBEE25D6B, 32, NDPI_PROTOCOL_TOR },
+ { 0xBF151340, 32, NDPI_PROTOCOL_TOR },
+ { 0xBF6502EB, 32, NDPI_PROTOCOL_TOR },
+ { 0xBF6598A6, 32, NDPI_PROTOCOL_TOR },
+ { 0xBFEFD3DC, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0009D29, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0031CF2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0031EDF, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0039416, 32, NDPI_PROTOCOL_TOR },
+ { 0xC003941B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC00396AA, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0039DD4, 32, NDPI_PROTOCOL_TOR },
+ { 0xC003A076, 32, NDPI_PROTOCOL_TOR },
+ { 0xC003A4E3, 32, NDPI_PROTOCOL_TOR },
+ { 0xC003ACEC, 32, NDPI_PROTOCOL_TOR },
+ { 0xC003AD58, 32, NDPI_PROTOCOL_TOR },
+ { 0xC003B1A7, 32, NDPI_PROTOCOL_TOR },
+ { 0xC003B426, 32, NDPI_PROTOCOL_TOR },
+ { 0xC003C9E2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC003C9F9, 32, NDPI_PROTOCOL_TOR },
+ { 0xC003D27D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC00C211A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC00C211B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC01E202C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0223B30, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0223F89, 32, NDPI_PROTOCOL_TOR },
+ { 0xC022E022, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0264C03, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0266D90, 32, NDPI_PROTOCOL_TOR },
+ { 0xC02A7410, 32, NDPI_PROTOCOL_TOR },
+ { 0xC02A74A1, 32, NDPI_PROTOCOL_TOR },
+ { 0xC02BF408, 32, NDPI_PROTOCOL_TOR },
+ { 0xC02BF408, 32, NDPI_PROTOCOL_TOR },
+ { 0xC02BF42A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC02BF42A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC02C1E28, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0405266, 32, NDPI_PROTOCOL_TOR },
+ { 0xC043DE05, 32, NDPI_PROTOCOL_TOR },
+ { 0xC045177C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0455E39, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0479724, 32, NDPI_PROTOCOL_TOR },
+ { 0xC047DAA0, 32, NDPI_PROTOCOL_TOR },
+ { 0xC047F524, 32, NDPI_PROTOCOL_TOR },
+ { 0xC047F589, 32, NDPI_PROTOCOL_TOR },
+ { 0xC047F589, 32, NDPI_PROTOCOL_TOR },
+ { 0xC047F5D7, 32, NDPI_PROTOCOL_TOR },
+ { 0xC049EC12, 32, NDPI_PROTOCOL_TOR },
+ { 0xC049EF53, 32, NDPI_PROTOCOL_TOR },
+ { 0xC051842E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC051DC5B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC051DDA2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC051F91F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0571C1C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0571C52, 32, NDPI_PROTOCOL_TOR },
+ { 0xC057E0BD, 32, NDPI_PROTOCOL_TOR },
+ { 0xC05BEBE6, 32, NDPI_PROTOCOL_TOR },
+ { 0xC05F1A3A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC05F1B8F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC05F2889, 32, NDPI_PROTOCOL_TOR },
+ { 0xC05F2CA9, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0630289, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0630289, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0630620, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0630852, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0630B30, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0630F7A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0630FDC, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063259C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0632B71, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0632B9C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0632BCE, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063681B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063914E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0639A18, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0639A4B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0639A50, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0639AEA, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063A866, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063A93D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063BA5E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063C1C1, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063D48B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063D497, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063F665, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063F7EA, 32, NDPI_PROTOCOL_TOR },
+ { 0xC063FA8F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC07247DE, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0794208, 32, NDPI_PROTOCOL_TOR },
+ { 0xC079AA4B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC07CFA53, 32, NDPI_PROTOCOL_TOR },
+ { 0xC087A8FB, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0965E31, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0979A8E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0999AF4, 32, NDPI_PROTOCOL_TOR },
+ { 0xC09B506F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC09B5365, 32, NDPI_PROTOCOL_TOR },
+ { 0xC09B5736, 32, NDPI_PROTOCOL_TOR },
+ { 0xC09B5874, 32, NDPI_PROTOCOL_TOR },
+ { 0xC09B5D65, 32, NDPI_PROTOCOL_TOR },
+ { 0xC09B5F7A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC09B5F7A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC09B5FDE, 32, NDPI_PROTOCOL_TOR },
+ { 0xC09DC04F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC09DEFF3, 32, NDPI_PROTOCOL_TOR },
+ { 0xC09DFD7D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0A0C16E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0A264D5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0A2650F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0A3E033, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0AB3D72, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0B82075, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0B8502A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0B85175, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0B851A0, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0B85280, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0B8555C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0B858CF, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0B85E6F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0BB6A92, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0C8EC20, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0D28AA3, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0D28AAB, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0D2C7B1, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0D2CC27, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0D2CEBD, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0D2E780, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0D2F0D9, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0E28C77, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0E38B12, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0E38F11, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0E3E71B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0EB4E13, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0EB4EDB, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0EDD411, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F158B5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F183E9, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1863E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F192D5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F19438, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1B238, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1B41B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1B4A3, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1B57A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1C4B2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1C66A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1C7D0, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1CAD6, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1CEAB, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1D063, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1D265, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1D878, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1E9CB, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1E9F2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F1FC3F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F37E51, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F9380B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F93EB7, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F93F97, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0F93F9C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0FC828E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC0FEA81A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC101C19C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC106DE6E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC107B1DF, 32, NDPI_PROTOCOL_TOR },
+ { 0xC10B722B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC10B722D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC10B722E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC10B722F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC10B8978, 32, NDPI_PROTOCOL_TOR },
+ { 0xC10BA4F3, 32, NDPI_PROTOCOL_TOR },
+ { 0xC10BA6C2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC10BA6C2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC10C4907, 32, NDPI_PROTOCOL_TOR },
+ { 0xC10D6125, 32, NDPI_PROTOCOL_TOR },
+ { 0xC10E9FCC, 32, NDPI_PROTOCOL_TOR },
+ { 0xC117F4F4, 32, NDPI_PROTOCOL_TOR },
+ { 0xC118D194, 32, NDPI_PROTOCOL_TOR },
+ { 0xC118D27E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC119019D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC11CE446, 32, NDPI_PROTOCOL_TOR },
+ { 0xC121D817, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1220201, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1233435, 32, NDPI_PROTOCOL_TOR },
+ { 0xC12598C7, 32, NDPI_PROTOCOL_TOR },
+ { 0xC12598F1, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1530139, 32, NDPI_PROTOCOL_TOR },
+ { 0xC15A0C56, 32, NDPI_PROTOCOL_TOR },
+ { 0xC15A0C57, 32, NDPI_PROTOCOL_TOR },
+ { 0xC15A0C58, 32, NDPI_PROTOCOL_TOR },
+ { 0xC15A0C59, 32, NDPI_PROTOCOL_TOR },
+ { 0xC15A0C5A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC15FE4E8, 32, NDPI_PROTOCOL_TOR },
+ { 0xC15FF2D5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC168DC23, 32, NDPI_PROTOCOL_TOR },
+ { 0xC168DC36, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1698632, 32, NDPI_PROTOCOL_TOR },
+ { 0xC169869C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC16B131E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC16B5538, 32, NDPI_PROTOCOL_TOR },
+ { 0xC16B5539, 32, NDPI_PROTOCOL_TOR },
+ { 0xC16B553D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC16B553E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC16E9D97, 32, NDPI_PROTOCOL_TOR },
+ { 0xC16F1A16, 32, NDPI_PROTOCOL_TOR },
+ { 0xC16F8D6E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC188CC75, 32, NDPI_PROTOCOL_TOR },
+ { 0xC189ADD9, 32, NDPI_PROTOCOL_TOR },
+ { 0xC18A7603, 32, NDPI_PROTOCOL_TOR },
+ { 0xC18A7608, 32, NDPI_PROTOCOL_TOR },
+ { 0xC18AD865, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1960E3E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC196791A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1967942, 32, NDPI_PROTOCOL_TOR },
+ { 0xC19A0D98, 32, NDPI_PROTOCOL_TOR },
+ { 0xC19D73FA, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A3DC8F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A48535, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A4D955, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A744, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A745, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A746, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A747, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A748, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A749, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A74A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A74B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A74C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A74D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A74E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A74F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A750, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A751, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A752, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A753, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A754, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A755, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A756, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A757, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A758, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A759, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A75A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A75B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A75C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A75D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1A6A75E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1AE0614, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1B69035, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1B763D5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1BEA835, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1CB312E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1DB24CF, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1E0A32B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC1F66F3E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC20EB3B8, 32, NDPI_PROTOCOL_TOR },
+ { 0xC2173CFA, 32, NDPI_PROTOCOL_TOR },
+ { 0xC230DA31, 32, NDPI_PROTOCOL_TOR },
+ { 0xC2601297, 32, NDPI_PROTOCOL_TOR },
+ { 0xC2680064, 32, NDPI_PROTOCOL_TOR },
+ { 0xC26DCED4, 32, NDPI_PROTOCOL_TOR },
+ { 0xC276346F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC276D253, 32, NDPI_PROTOCOL_TOR },
+ { 0xC27EC6E4, 32, NDPI_PROTOCOL_TOR },
+ { 0xC296A84F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC296A85F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC296A86C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC2A6A031, 32, NDPI_PROTOCOL_TOR },
+ { 0xC313AE72, 32, NDPI_PROTOCOL_TOR },
+ { 0xC313AE73, 32, NDPI_PROTOCOL_TOR },
+ { 0xC31DA8CE, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3236D3D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC325BE55, 32, NDPI_PROTOCOL_TOR },
+ { 0xC328B523, 32, NDPI_PROTOCOL_TOR },
+ { 0xC32EB925, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3409582, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3474454, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3527C6F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC358543B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC35BED96, 32, NDPI_PROTOCOL_TOR },
+ { 0xC36E061F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC36E09E8, 32, NDPI_PROTOCOL_TOR },
+ { 0xC38AF902, 32, NDPI_PROTOCOL_TOR },
+ { 0xC38CFE59, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3947CC7, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A057B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A05CD, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A0937, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A0A9B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A0C42, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A0D0A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A0D60, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A0E28, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A0F75, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A2A65, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A40D6, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A411D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A43E5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A4682, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A4B54, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A4BA5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A4DC8, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A4E71, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A4E73, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A516C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A516E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A51E3, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A51F5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A5258, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A533C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A57E7, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A5B8B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A610A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6111, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A611B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A61A0, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6775, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6886, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6935, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6939, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6B56, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6B97, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6C4E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6D1E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6D34, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6D9D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6DCB, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6DDD, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A6E4C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A7095, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A72B9, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A742B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A74E8, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A75A3, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A76AC, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A7763, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A79C6, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A79EA, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A7BDE, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A7E2B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A7EA5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A7FF6, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A803A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A8097, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39A8879, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39AA671, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39AA671, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39AAF14, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39AB416, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39AD7F0, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39ADDED, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39AE205, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39AE93A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39AF076, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39AFB5E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC39FA2C2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3A6C926, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3A97DE2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3A9C4BC, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3A9CF36, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3A9D8BF, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3B2B57B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3B40BC4, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3BFE9DD, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3C6F2C2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3CAD33B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3D21DED, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3E1D31A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3E42DB0, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3E44B83, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3E6A853, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3EA9856, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3F25002, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3FAA3B1, 32, NDPI_PROTOCOL_TOR },
+ { 0xC3FBFCE2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC4252C59, 32, NDPI_PROTOCOL_TOR },
+ { 0xC55752E7, 32, NDPI_PROTOCOL_TOR },
+ { 0xC5E7DDD3, 32, NDPI_PROTOCOL_TOR },
+ { 0xC60C50BB, 32, NDPI_PROTOCOL_TOR },
+ { 0xC60C5B69, 32, NDPI_PROTOCOL_TOR },
+ { 0xC60C68D0, 32, NDPI_PROTOCOL_TOR },
+ { 0xC60F4FC5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC61799A1, 32, NDPI_PROTOCOL_TOR },
+ { 0xC617B141, 32, NDPI_PROTOCOL_TOR },
+ { 0xC617BB9E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC617F7CC, 32, NDPI_PROTOCOL_TOR },
+ { 0xC61B447E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC61B562B, 32, NDPI_PROTOCOL_TOR },
+ { 0xC61B562D, 32, NDPI_PROTOCOL_TOR },
+ { 0xC61B6D24, 32, NDPI_PROTOCOL_TOR },
+ { 0xC6257224, 32, NDPI_PROTOCOL_TOR },
+ { 0xC62E8E4A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC62E9933, 32, NDPI_PROTOCOL_TOR },
+ { 0xC6329148, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63291CF, 32, NDPI_PROTOCOL_TOR },
+ { 0xC6329228, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63292FC, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63293EF, 32, NDPI_PROTOCOL_TOR },
+ { 0xC632957F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63295A0, 32, NDPI_PROTOCOL_TOR },
+ { 0xC632970A, 32, NDPI_PROTOCOL_TOR },
+ { 0xC6329766, 32, NDPI_PROTOCOL_TOR },
+ { 0xC6329811, 32, NDPI_PROTOCOL_TOR },
+ { 0xC6329C4E, 32, NDPI_PROTOCOL_TOR },
+ { 0xC632B758, 32, NDPI_PROTOCOL_TOR },
+ { 0xC632BF5F, 32, NDPI_PROTOCOL_TOR },
+ { 0xC632E716, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63482DA, 32, NDPI_PROTOCOL_TOR },
+ { 0xC634A041, 32, NDPI_PROTOCOL_TOR },
+ { 0xC634A090, 32, NDPI_PROTOCOL_TOR },
+ { 0xC634C827, 32, NDPI_PROTOCOL_TOR },
+ { 0xC634F4ED, 32, NDPI_PROTOCOL_TOR },
+ { 0xC634F7A0, 32, NDPI_PROTOCOL_TOR },
+ { 0xC634F7A2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC634F7F7, 32, NDPI_PROTOCOL_TOR },
+ { 0xC634F7FA, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A601C, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A6079, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A66EA, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A6793, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A6793, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A6AF5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A6AF5, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A6B34, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A6B34, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A6B35, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A6D52, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A73D2, 32, NDPI_PROTOCOL_TOR },
+ { 0xC63A7FC9, 32, NDPI_PROTOCOL_TOR },
+ { 0xC6475142, 32, NDPI_PROTOCOL_TOR },
+ { 0xC648E7E9, 32, NDPI_PROTOCOL_TOR },
+ { 0xC6493247, 32, NDPI_PROTOCOL_TOR },
+ { 0xC64A38BF, 32, NDPI_PROTOCOL_TOR },
+ { 0xC64A3A10, 32, NDPI_PROTOCOL_TOR },
+{ 0xC64A3ACE, 32, NDPI_PROTOCOL_TOR },
+{ 0xC64A3C1A, 32, NDPI_PROTOCOL_TOR },
+{ 0xC64A3E6B, 32, NDPI_PROTOCOL_TOR },
+{ 0xC654A10C, 32, NDPI_PROTOCOL_TOR },
+{ 0xC654F0E5, 32, NDPI_PROTOCOL_TOR },
+{ 0xC654F96A, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6609B03, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6623103, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6623495, 32, NDPI_PROTOCOL_TOR },
+{ 0xC662358D, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6649014, 32, NDPI_PROTOCOL_TOR },
+{ 0xC664904B, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6649470, 32, NDPI_PROTOCOL_TOR },
+{ 0xC664947B, 32, NDPI_PROTOCOL_TOR },
+{ 0xC664959F, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6649B36, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6649BC2, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6697D25, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6697DB2, 32, NDPI_PROTOCOL_TOR },
+{ 0xC669D0A4, 32, NDPI_PROTOCOL_TOR },
+{ 0xC669DF92, 32, NDPI_PROTOCOL_TOR },
+{ 0xC68F88ED, 32, NDPI_PROTOCOL_TOR },
+{ 0xC693141D, 32, NDPI_PROTOCOL_TOR },
+{ 0xC693174D, 32, NDPI_PROTOCOL_TOR },
+{ 0xC69451A7, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6A7895C, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6A78F95, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6B49609, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6C74845, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6C76BDC, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6C77079, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6C77231, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6C775A4, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6C77A11, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6CD713B, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6D36392, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6D37ABF, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6D37B5C, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6D37CD6, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6D37DF2, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6D37E53, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6F464C8, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6F46963, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6F53294, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6F53C28, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6F53C93, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6F53CC2, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6F53E68, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6F53FE4, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6FC9957, 32, NDPI_PROTOCOL_TOR },
+{ 0xC6FC996B, 32, NDPI_PROTOCOL_TOR },
+{ 0xC710BF3A, 32, NDPI_PROTOCOL_TOR },
+{ 0xC71355FC, 32, NDPI_PROTOCOL_TOR },
+{ 0xC713D5B0, 32, NDPI_PROTOCOL_TOR },
+{ 0xC726567A, 32, NDPI_PROTOCOL_TOR },
+{ 0xC73A530A, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7579AFF, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7737387, 32, NDPI_PROTOCOL_TOR },
+{ 0xC773CDF1, 32, NDPI_PROTOCOL_TOR },
+{ 0xC773CDF2, 32, NDPI_PROTOCOL_TOR },
+{ 0xC773CDF3, 32, NDPI_PROTOCOL_TOR },
+{ 0xC773CDF5, 32, NDPI_PROTOCOL_TOR },
+{ 0xC773CDF8, 32, NDPI_PROTOCOL_TOR },
+{ 0xC77FE240, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7A78088, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7A7A1C3, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7A7C679, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7BC649A, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7BCC235, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7C173D1, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7C1FD31, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7C3C116, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7C3F83C, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7C3F890, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7C3F9D4, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7CA151D, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7FEEE2C, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7FEEE34, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7FEEE34, 32, NDPI_PROTOCOL_TOR },
+{ 0xC7FFDF58, 32, NDPI_PROTOCOL_TOR },
+{ 0xC811D20C, 32, NDPI_PROTOCOL_TOR },
+{ 0xC8628B17, 32, NDPI_PROTOCOL_TOR },
+{ 0xC86CEC4B, 32, NDPI_PROTOCOL_TOR },
+{ 0xC8B55A41, 32, NDPI_PROTOCOL_TOR },
+{ 0xC8DFD4D2, 32, NDPI_PROTOCOL_TOR },
+{ 0xC906897F, 32, NDPI_PROTOCOL_TOR },
+{ 0xC91BEB7F, 32, NDPI_PROTOCOL_TOR },
+{ 0xC9AA12B7, 32, NDPI_PROTOCOL_TOR },
+{ 0xC9D46CB8, 32, NDPI_PROTOCOL_TOR },
+{ 0xC9DA72A2, 32, NDPI_PROTOCOL_TOR },
+{ 0xCA07F408, 32, NDPI_PROTOCOL_TOR },
+{ 0xCA3C4220, 32, NDPI_PROTOCOL_TOR },
+{ 0xCA4A2C0F, 32, NDPI_PROTOCOL_TOR },
+{ 0xCA536AB3, 32, NDPI_PROTOCOL_TOR },
+{ 0xCA55E922, 32, NDPI_PROTOCOL_TOR },
+{ 0xCAAB9C54, 32, NDPI_PROTOCOL_TOR },
+{ 0xCAAC1039, 32, NDPI_PROTOCOL_TOR },
+{ 0xCB56CAA7, 32, NDPI_PROTOCOL_TOR },
+{ 0xCB56CD2E, 32, NDPI_PROTOCOL_TOR },
+{ 0xCB6DE90F, 32, NDPI_PROTOCOL_TOR },
+{ 0xCB71AC95, 32, NDPI_PROTOCOL_TOR },
+{ 0xCB71AC98, 32, NDPI_PROTOCOL_TOR },
+{ 0xCB71AC9A, 32, NDPI_PROTOCOL_TOR },
+{ 0xCB7B3001, 32, NDPI_PROTOCOL_TOR },
+{ 0xCB7E7B52, 32, NDPI_PROTOCOL_TOR },
+{ 0xCB8A63DA, 32, NDPI_PROTOCOL_TOR },
+{ 0xCB98C302, 32, NDPI_PROTOCOL_TOR },
+{ 0xCB99CEA6, 32, NDPI_PROTOCOL_TOR },
+{ 0xCBA16711, 32, NDPI_PROTOCOL_TOR },
+{ 0xCBB2850B, 32, NDPI_PROTOCOL_TOR },
+{ 0xCBCEEDC5, 32, NDPI_PROTOCOL_TOR },
+{ 0xCBD9AD92, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC089C8E, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC093747, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC0B3283, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC1025F4, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC11382A, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC11382A, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC1B382D, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC1B382D, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC1B3ACA, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC2D1E7A, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC2D1E7D, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC2DB6E2, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC534638, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC55BF1E, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC59C10A, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC7C5382, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC7C5382, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC7C5386, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC7C5386, 32, NDPI_PROTOCOL_TOR },
+{ 0xCC91512D, 32, NDPI_PROTOCOL_TOR },
+{ 0xCCC21D04, 32, NDPI_PROTOCOL_TOR },
+{ 0xCCF67A48, 32, NDPI_PROTOCOL_TOR },
+{ 0xCDA85485, 32, NDPI_PROTOCOL_TOR },
+{ 0xCDB973EA, 32, NDPI_PROTOCOL_TOR },
+{ 0xCDB97A98, 32, NDPI_PROTOCOL_TOR },
+{ 0xCE2876E5, 32, NDPI_PROTOCOL_TOR },
+{ 0xCE374A00, 32, NDPI_PROTOCOL_TOR },
+{ 0xCE374A01, 32, NDPI_PROTOCOL_TOR },
+{ 0xCE48C698, 32, NDPI_PROTOCOL_TOR },
+{ 0xCEAE7054, 32, NDPI_PROTOCOL_TOR },
+{ 0xCEBE9906, 32, NDPI_PROTOCOL_TOR },
+{ 0xCF268613, 32, NDPI_PROTOCOL_TOR },
+{ 0xCF6CDABA, 32, NDPI_PROTOCOL_TOR },
+{ 0xCF9E0F72, 32, NDPI_PROTOCOL_TOR },
+{ 0xCFACD159, 32, NDPI_PROTOCOL_TOR },
+{ 0xCFBD72D7, 32, NDPI_PROTOCOL_TOR },
+{ 0xCFC046FA, 32, NDPI_PROTOCOL_TOR },
+{ 0xCFC9DFC3, 32, NDPI_PROTOCOL_TOR },
+{ 0xCFC9DFC4, 32, NDPI_PROTOCOL_TOR },
+{ 0xCFC9DFC5, 32, NDPI_PROTOCOL_TOR },
+{ 0xCFE54199, 32, NDPI_PROTOCOL_TOR },
+{ 0xCFF44B8E, 32, NDPI_PROTOCOL_TOR },
+{ 0xCFF4526D, 32, NDPI_PROTOCOL_TOR },
+{ 0xCFF4526D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD041B5BD, 32, NDPI_PROTOCOL_TOR },
+{ 0xD0421E1B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD049CCE4, 32, NDPI_PROTOCOL_TOR },
+{ 0xD04FD17C, 32, NDPI_PROTOCOL_TOR },
+{ 0xD04FD34D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD0509A27, 32, NDPI_PROTOCOL_TOR },
+{ 0xD0526625, 32, NDPI_PROTOCOL_TOR },
+{ 0xD053DF22, 32, NDPI_PROTOCOL_TOR },
+{ 0xD053DFE5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD0549BCD, 32, NDPI_PROTOCOL_TOR },
+{ 0xD0549BF3, 32, NDPI_PROTOCOL_TOR },
+{ 0xD0549BF7, 32, NDPI_PROTOCOL_TOR },
+{ 0xD056FB58, 32, NDPI_PROTOCOL_TOR },
+{ 0xD05B798E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD065161A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD06F2350, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1063507, 32, NDPI_PROTOCOL_TOR },
+{ 0xD106441D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD10685EE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD111BF75, 32, NDPI_PROTOCOL_TOR },
+{ 0xD12C72B2, 32, NDPI_PROTOCOL_TOR },
+{ 0xD133A319, 32, NDPI_PROTOCOL_TOR },
+{ 0xD133BFBE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1709F3C, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC25, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC25, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC26, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC26, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC27, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC27, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC28, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC28, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC29, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC29, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC2A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD177BC2A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD17BA242, 32, NDPI_PROTOCOL_TOR },
+{ 0xD17E47E9, 32, NDPI_PROTOCOL_TOR },
+{ 0xD17E4854, 32, NDPI_PROTOCOL_TOR },
+{ 0xD17E6907, 32, NDPI_PROTOCOL_TOR },
+{ 0xD18D23E8, 32, NDPI_PROTOCOL_TOR },
+{ 0xD18D242A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD18D2ECC, 32, NDPI_PROTOCOL_TOR },
+{ 0xD18D328A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD18D34EF, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1942E81, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1942E82, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1942E82, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1945576, 32, NDPI_PROTOCOL_TOR },
+{ 0xD19F8A13, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1A221CF, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1B5E383, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1D01A29, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1D04F05, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1D2D215, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1DE08C4, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1DE1EF1, 32, NDPI_PROTOCOL_TOR },
+{ 0xD1FA02FE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD217021E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD23625E2, 32, NDPI_PROTOCOL_TOR },
+{ 0xD2A6194E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD2C33DFC, 32, NDPI_PROTOCOL_TOR },
+{ 0xD2D37ACC, 32, NDPI_PROTOCOL_TOR },
+{ 0xD2FBD989, 32, NDPI_PROTOCOL_TOR },
+{ 0xD31AF36D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD31C8EEF, 32, NDPI_PROTOCOL_TOR },
+{ 0xD31FC4F8, 32, NDPI_PROTOCOL_TOR },
+{ 0xD3CA291F, 32, NDPI_PROTOCOL_TOR },
+{ 0xD407C247, 32, NDPI_PROTOCOL_TOR },
+{ 0xD407DC06, 32, NDPI_PROTOCOL_TOR },
+{ 0xD40A5604, 32, NDPI_PROTOCOL_TOR },
+{ 0xD40CCB27, 32, NDPI_PROTOCOL_TOR },
+{ 0xD41010B8, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4106821, 32, NDPI_PROTOCOL_TOR },
+{ 0xD411664D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD41824CD, 32, NDPI_PROTOCOL_TOR },
+{ 0xD41890BC, 32, NDPI_PROTOCOL_TOR },
+{ 0xD421F581, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE209, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE3AC, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE3AC, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE445, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE459, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE5D1, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE5D1, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE745, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE784, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE80D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE8F6, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FE97E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FEA54, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FEB57, 32, NDPI_PROTOCOL_TOR },
+{ 0xD42FECDB, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4305435, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4339C5A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4339C8F, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4339C9E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4339C9E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4339F4E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4339F72, 32, NDPI_PROTOCOL_TOR },
+{ 0xD438D698, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4402044, 32, NDPI_PROTOCOL_TOR },
+{ 0xD447EECB, 32, NDPI_PROTOCOL_TOR },
+{ 0xD447F805, 32, NDPI_PROTOCOL_TOR },
+{ 0xD447F945, 32, NDPI_PROTOCOL_TOR },
+{ 0xD447F945, 32, NDPI_PROTOCOL_TOR },
+{ 0xD447F981, 32, NDPI_PROTOCOL_TOR },
+{ 0xD447FC6D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD447FC74, 32, NDPI_PROTOCOL_TOR },
+{ 0xD447FDE2, 32, NDPI_PROTOCOL_TOR },
+{ 0xD44AFEF3, 32, NDPI_PROTOCOL_TOR },
+{ 0xD44DE210, 32, NDPI_PROTOCOL_TOR },
+{ 0xD44DE2F5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4532F5B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD45394CD, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4539A21, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4539A21, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4539E05, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4539E14, 32, NDPI_PROTOCOL_TOR },
+{ 0xD453A298, 32, NDPI_PROTOCOL_TOR },
+{ 0xD453A7AF, 32, NDPI_PROTOCOL_TOR },
+{ 0xD453AAFC, 32, NDPI_PROTOCOL_TOR },
+{ 0xD453B07A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD453B07D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD453BECB, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4554F44, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4554F47, 32, NDPI_PROTOCOL_TOR },
+{ 0xD45CDB0F, 32, NDPI_PROTOCOL_TOR },
+{ 0xD467903A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD46A09CE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD46B9591, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4722F34, 32, NDPI_PROTOCOL_TOR },
+{ 0xD472303A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4726D21, 32, NDPI_PROTOCOL_TOR },
+{ 0xD472FA12, 32, NDPI_PROTOCOL_TOR },
+{ 0xD472FE5B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4758F4A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD475B46B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4763E03, 32, NDPI_PROTOCOL_TOR },
+{ 0xD47CB453, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4810454, 32, NDPI_PROTOCOL_TOR },
+{ 0xD48110B6, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4811AF6, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4812A09, 32, NDPI_PROTOCOL_TOR },
+{ 0xD48132F6, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4813431, 32, NDPI_PROTOCOL_TOR },
+{ 0xD495D15B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD49F5B16, 32, NDPI_PROTOCOL_TOR },
+{ 0xD49F70C4, 32, NDPI_PROTOCOL_TOR },
+{ 0xD49F8F53, 32, NDPI_PROTOCOL_TOR },
+{ 0xD49FB1C6, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4A4EF79, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4B733DE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4BA59A2, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4BBC8AA, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4C04A64, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4C04A65, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4C63318, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4C6C924, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4C6E391, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4E054E3, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4E059FD, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4E326F7, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4E38BC3, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4E3F876, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4E81D65, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4FAA0B2, 32, NDPI_PROTOCOL_TOR },
+{ 0xD4FAA0BB, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5095DAE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD52C58EA, 32, NDPI_PROTOCOL_TOR },
+{ 0xD52F2397, 32, NDPI_PROTOCOL_TOR },
+{ 0xD52F4B43, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5317328, 32, NDPI_PROTOCOL_TOR },
+{ 0xD53D957D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD53D957E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD540E2E6, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5430E91, 32, NDPI_PROTOCOL_TOR },
+{ 0xD54951D2, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5497087, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5582A31, 32, NDPI_PROTOCOL_TOR },
+{ 0xD55F1536, 32, NDPI_PROTOCOL_TOR },
+{ 0xD55F153B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD56B4D04, 32, NDPI_PROTOCOL_TOR },
+{ 0xD56C6947, 32, NDPI_PROTOCOL_TOR },
+{ 0xD56C69FD, 32, NDPI_PROTOCOL_TOR },
+{ 0xD56CD7EE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD56FF097, 32, NDPI_PROTOCOL_TOR },
+{ 0xD57086D3, 32, NDPI_PROTOCOL_TOR },
+{ 0xD570C73F, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5713D6A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5717790, 32, NDPI_PROTOCOL_TOR },
+{ 0xD571D5BE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5724869, 32, NDPI_PROTOCOL_TOR },
+{ 0xD57293E0, 32, NDPI_PROTOCOL_TOR },
+{ 0xD572966F, 32, NDPI_PROTOCOL_TOR },
+{ 0xD572E864, 32, NDPI_PROTOCOL_TOR },
+{ 0xD57F85A7, 32, NDPI_PROTOCOL_TOR },
+{ 0xD57F921B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD585639C, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5856D29, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5856DA5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5857B97, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58845ED, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5884715, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5884B2A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5885261, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5885674, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58857F5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5885A9B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5885CA9, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58A653C, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58A66D1, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58A6E58, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58A71E8, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58D8818, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58D8D93, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58D95E3, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58D9EED, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58E2E79, 32, NDPI_PROTOCOL_TOR },
+{ 0xD58F7A02, 32, NDPI_PROTOCOL_TOR },
+{ 0xD59B0490, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5A3482F, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5A348A2, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5A54610, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5A54F22, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5A54FF3, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5A55106, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5A5551E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5A55546, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5A555F9, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5AFD83B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5B39EF1, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5B73821, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5B7388C, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5B9E355, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5BA07E8, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5BB54BE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5BB6FFE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5BC77C9, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5C489E3, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5C5167C, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5C52469, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5D0BCCB, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5D3FC58, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5DE7461, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5E3FAF5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5EFC519, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5EFD329, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5EFD414, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5EFD6AF, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5EFD8DE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5EFD912, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5EFDA14, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5EFDA93, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5EFF9DB, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5F05E3A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5F06C19, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5F53D3D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5FBBB37, 32, NDPI_PROTOCOL_TOR },
+{ 0xD5FBC7AE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD80CC652, 32, NDPI_PROTOCOL_TOR },
+{ 0xD80CC653, 32, NDPI_PROTOCOL_TOR },
+{ 0xD80F0122, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8116382, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8116390, 32, NDPI_PROTOCOL_TOR },
+{ 0xD811654F, 32, NDPI_PROTOCOL_TOR },
+{ 0xD81169CB, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8116EE7, 32, NDPI_PROTOCOL_TOR },
+{ 0xD818AEF5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8425592, 32, NDPI_PROTOCOL_TOR },
+{ 0xD873031A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD873063A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD892E107, 32, NDPI_PROTOCOL_TOR },
+{ 0xD89A71F4, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8A13759, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8BAC1C9, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8BD9264, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8BD9575, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8BD9666, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8BD9718, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8C3851B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8DA860C, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8DAD8C2, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8DD24F4, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8E6E69C, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8E6E6F7, 32, NDPI_PROTOCOL_TOR },
+{ 0xD8F455D3, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90833AD, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90B39E2, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90B7727, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90CC7BE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90CC7D1, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90CCB2E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90CCC59, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90CCC68, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90CCC93, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90CD075, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90D4A29, 32, NDPI_PROTOCOL_TOR },
+{ 0xD90DC505, 32, NDPI_PROTOCOL_TOR },
+{ 0xD910B514, 32, NDPI_PROTOCOL_TOR },
+{ 0xD910B614, 32, NDPI_PROTOCOL_TOR },
+{ 0xD91318D8, 32, NDPI_PROTOCOL_TOR },
+{ 0xD91318E9, 32, NDPI_PROTOCOL_TOR },
+{ 0xD917011B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD91A1259, 32, NDPI_PROTOCOL_TOR },
+{ 0xD91BB67D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD92287E1, 32, NDPI_PROTOCOL_TOR },
+{ 0xD92287E7, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9251373, 32, NDPI_PROTOCOL_TOR },
+{ 0xD92855C2, 32, NDPI_PROTOCOL_TOR },
+{ 0xD928FEB1, 32, NDPI_PROTOCOL_TOR },
+{ 0xD943154D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD945FE58, 32, NDPI_PROTOCOL_TOR },
+{ 0xD946BD91, 32, NDPI_PROTOCOL_TOR },
+{ 0xD946BF0D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD948141E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD94FB23C, 32, NDPI_PROTOCOL_TOR },
+{ 0xD94FB532, 32, NDPI_PROTOCOL_TOR },
+{ 0xD94FB538, 32, NDPI_PROTOCOL_TOR },
+{ 0xD94FB65F, 32, NDPI_PROTOCOL_TOR },
+{ 0xD94FBE19, 32, NDPI_PROTOCOL_TOR },
+{ 0xD954FBD5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD95597B5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD95EEEF5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD970833A, 32, NDPI_PROTOCOL_TOR },
+{ 0xD97293F5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD972DA12, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9730A85, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9730A86, 32, NDPI_PROTOCOL_TOR },
+{ 0xD97729D5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD97BFEEE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD98090A0, 32, NDPI_PROTOCOL_TOR },
+{ 0xD991C735, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9924B24, 32, NDPI_PROTOCOL_TOR },
+{ 0xD99454B4, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9A0122D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9A013EC, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9A05C43, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9A07E32, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9A083B0, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9A276FE, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9AACD71, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9ACB392, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9ACBE13, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9ACBE13, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9ACFFE5, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9AD4A5B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9BCEA09, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9BDC5F4, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9BF49C3, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9BF6813, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9BFF274, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9C3AA91, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9C504DC, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9C553A2, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9C556AD, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9C55B91, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9C55B91, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9C55BA4, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9C5B52D, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9D075D3, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9D11257, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9D27158, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9D28C5F, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9D2A52B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9D39FA1, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9E40B41, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9E46874, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9E76B72, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9E94FC8, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9E94FC8, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9EA6B0B, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9F595B7, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9F63320, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9F76904, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9F7DE9C, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9F7E61F, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9F9203E, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9FBD765, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9FD96F6, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9FD9F48, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9FE3DAC, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9FE47CC, 32, NDPI_PROTOCOL_TOR },
+{ 0xD9FEB60F, 32, NDPI_PROTOCOL_TOR },
+{ 0xDAA1200E, 32, NDPI_PROTOCOL_TOR },
+{ 0xDAE7EBDB, 32, NDPI_PROTOCOL_TOR },
+{ 0xDAE868DC, 32, NDPI_PROTOCOL_TOR },
+{ 0xDAE868DD, 32, NDPI_PROTOCOL_TOR },
+{ 0xDAFAF536, 32, NDPI_PROTOCOL_TOR },
+{ 0xDB4F067A, 32, NDPI_PROTOCOL_TOR },
+{ 0xDB59C4CA, 32, NDPI_PROTOCOL_TOR },
+{ 0xDB6DCB40, 32, NDPI_PROTOCOL_TOR },
+{ 0xDB75CE2E, 32, NDPI_PROTOCOL_TOR },
+{ 0xDB791014, 32, NDPI_PROTOCOL_TOR },
+{ 0xDBA189F3, 32, NDPI_PROTOCOL_TOR },
+{ 0xDBA4C22E, 32, NDPI_PROTOCOL_TOR },
+{ 0xDBAD0E54, 32, NDPI_PROTOCOL_TOR },
+{ 0xDC39428E, 32, NDPI_PROTOCOL_TOR },
+{ 0xDC87FE3F, 32, NDPI_PROTOCOL_TOR },
+{ 0xDC898752, 32, NDPI_PROTOCOL_TOR },
+{ 0xDC9387F3, 32, NDPI_PROTOCOL_TOR },
+{ 0xDC9DC3F3, 32, NDPI_PROTOCOL_TOR },
+{ 0xDCE97BAC, 32, NDPI_PROTOCOL_TOR },
+{ 0xDCE9AF0E, 32, NDPI_PROTOCOL_TOR },
+{ 0xDCFD1CE1, 32, NDPI_PROTOCOL_TOR },
+{ 0xDCFF85C3, 32, NDPI_PROTOCOL_TOR },
+{ 0xDD7132CB, 32, NDPI_PROTOCOL_TOR },
+{ 0xDD9E95C5, 32, NDPI_PROTOCOL_TOR },
+{ 0xDE047C92, 32, NDPI_PROTOCOL_TOR },
+{ 0xDE0C7C9A, 32, NDPI_PROTOCOL_TOR },
+{ 0xDE7294F8, 32, NDPI_PROTOCOL_TOR },
+{ 0xDEEB761A, 32, NDPI_PROTOCOL_TOR },
+{ 0xDF1273E5, 32, NDPI_PROTOCOL_TOR },
+{ 0xDF85F4CA, 32, NDPI_PROTOCOL_TOR },
+{ 0xDFE57B41, 32, NDPI_PROTOCOL_TOR },
+{ 0x0, 0, 0 }
+};
+
+/* ****************************************************** */
+
+/*
+ Host-based match
+
+ HTTP: Server: field
+ HTTPS: Server certificate name
+ */
+
+ndpi_protocol_match host_match[] = {
+ { "amazon.", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE },
+ { "amazon.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE },
+ { "images-amazon.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE },
+ { "amazonaws.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE },
+ { "amazon-adsystem.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".apple.com", "Apple", NDPI_SERVICE_APPLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".mzstatic.com", "Apple", NDPI_SERVICE_APPLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".icloud.com", "AppleiCloud", NDPI_SERVICE_APPLE_ICLOUD, NDPI_PROTOCOL_ACCEPTABLE },
+ { "itunes.apple.com", "AppleiTunes", NDPI_SERVICE_APPLE_ITUNES, NDPI_PROTOCOL_FUN },
+ { ".cnn.c", "CNN", NDPI_SERVICE_CNN, NDPI_PROTOCOL_FUN },
+ { ".cnn.net", "CNN", NDPI_SERVICE_CNN, NDPI_PROTOCOL_FUN },
+ { ".dropbox.com", "DropBox", NDPI_SERVICE_DROPBOX, NDPI_PROTOCOL_SAFE },
+ { ".ebay.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".ebaystatic.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".ebaydesc.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".ebayrtm.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".facebook.com", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN },
+ { ".fbcdn.net", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN },
+ { "fbcdn-", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, /* fbcdn-video-a-akamaihd.net */
+ { ".gstatic.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".googlesyndication.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".googletagservices.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".2mdn.net", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".doubleclick.net", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, /* Ads */
+ { "googleads.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { "google-analytics.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { "googleusercontent.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { "googleadservices.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { "googleapis.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { "ggpht.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { "maps.google.", "GoogleMaps", NDPI_SERVICE_GOOGLE_MAPS, NDPI_PROTOCOL_ACCEPTABLE },
+ { "maps.gstatic.com", "GoogleMaps", NDPI_SERVICE_GOOGLE_MAPS, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".gmail.", "GMail", NDPI_SERVICE_GMAIL, NDPI_PROTOCOL_SAFE },
+ { "mail.google.", "GMail", NDPI_SERVICE_GMAIL, NDPI_PROTOCOL_SAFE },
+ { ".grooveshark.com", "GrooveShark", NDPI_SERVICE_GROOVESHARK, NDPI_PROTOCOL_FUN },
+ { ".last.fm", "LastFM", NDPI_SERVICE_LASTFM, NDPI_PROTOCOL_FUN },
+ { "msn.com", "MSN", NDPI_SERVICE_MSN, NDPI_PROTOCOL_FUN },
+ { "netflix.com", "NetFlix", NDPI_SERVICE_NETFLIX, NDPI_PROTOCOL_FUN },
+ { "nflxext.com", "NetFlix", NDPI_SERVICE_NETFLIX, NDPI_PROTOCOL_FUN },
+ { "nflximg.com", "NetFlix", NDPI_SERVICE_NETFLIX, NDPI_PROTOCOL_FUN },
+ { "nflximg.net", "NetFlix", NDPI_SERVICE_NETFLIX, NDPI_PROTOCOL_FUN },
+
+ { ".skype.", "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".skypeassets.", "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".skypedata.", "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".skypeecs-", /* no final . */ "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".tuenti.com", "Tuenti", NDPI_SERVICE_TUENTI, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".twttr.com", "Twitter", NDPI_SERVICE_TWITTER, NDPI_PROTOCOL_ACCEPTABLE },
+ { "twitter.", "Twitter", NDPI_SERVICE_TWITTER, NDPI_PROTOCOL_ACCEPTABLE },
+ { "twimg.com", "Twitter", NDPI_SERVICE_TWITTER, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".viber.com", "Viber", NDPI_SERVICE_VIBER, NDPI_PROTOCOL_ACCEPTABLE },
+ { "wikipedia.", "Wikipedia", NDPI_SERVICE_WIKIPEDIA, NDPI_PROTOCOL_ACCEPTABLE },
+ { "wikimedia.", "Wikipedia", NDPI_SERVICE_WIKIPEDIA, NDPI_PROTOCOL_ACCEPTABLE },
+ { "mediawiki.", "Wikipedia", NDPI_SERVICE_WIKIPEDIA, NDPI_PROTOCOL_ACCEPTABLE },
+ { "wikimediafoundation.", "Wikipedia", NDPI_SERVICE_WIKIPEDIA, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".whatsapp.net", "WhatsApp", NDPI_SERVICE_WHATSAPP, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".yahoo.", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE },
+ { "yimg.com", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE },
+ { "yahooapis.", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE },
+ { "youtube.", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN },
+ { ".googlevideo.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN },
+ { ".ytimg.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN },
+ { "youtube-nocookie.", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN },
+ { ".vevo.com", "Vevo", NDPI_SERVICE_VEVO, NDPI_PROTOCOL_FUN },
+ { ".google.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".spotify.", "Spotify", NDPI_PROTOCOL_SPOTIFY, NDPI_PROTOCOL_FUN },
+ { ".pandora.com", "Pandora", NDPI_SERVICE_PANDORA, NDPI_PROTOCOL_FUN },
+ { ".torproject.org", "Tor", NDPI_PROTOCOL_TOR, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS },
+ { NULL, 0 }
+};
+
+
+/*
+ Mime-type content match match
+*/
+ndpi_protocol_match content_match[] = {
+ { "audio/mpeg", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN },
+ { "audio/x-mpeg", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN },
+ { "audio/mpeg3", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN },
+ { "audio/mp4a", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN },
+ { "video/mpeg", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN },
+ { "video/nsv", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN },
+ { "misc/ultravox", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN },
+ { "audio/ogg", NULL, NDPI_CONTENT_OGG, NDPI_PROTOCOL_FUN },
+ { "video/ogg", NULL, NDPI_CONTENT_OGG, NDPI_PROTOCOL_FUN },
+ { "application/ogg", NULL, NDPI_CONTENT_OGG, NDPI_PROTOCOL_FUN },
+ { "video/flv", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN },
+ { "video/x-flv", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN },
+ { "application/x-fcs", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN },
+ { "application/x-shockwave-flash", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_ACCEPTABLE },
+ { "video/flash", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN },
+ { "application/flv", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN },
+ { "flv-application/octet-stream", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN },
+ { "application/futuresplash", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN },
+ { "video/quicktime", NULL, NDPI_CONTENT_QUICKTIME, NDPI_PROTOCOL_FUN },
+ { "video/mp4", NULL, NDPI_CONTENT_QUICKTIME, NDPI_PROTOCOL_FUN },
+ { "video/x-m4v", NULL, NDPI_CONTENT_QUICKTIME, NDPI_PROTOCOL_FUN },
+ { "audio/x-pn-realaudio", NULL, NDPI_CONTENT_REALMEDIA, NDPI_PROTOCOL_FUN },
+ { "application/vnd.rn-realmedia", NULL, NDPI_CONTENT_REALMEDIA, NDPI_PROTOCOL_FUN },
+ { "video/x-ms-", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN },
+ { "asf", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN },
+ { "asx", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN },
+ { "video/x-msvideo", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN },
+ { "audio/x-wav", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN },
+ { "application/vnd.ms.wms-hdr.asfv1", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN },
+ { "NSPlayer/", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN },
+ { "application/x-mms-framed", NULL, NDPI_CONTENT_MMS, NDPI_PROTOCOL_FUN },
+ { "Xbox Live Client/", NULL, NDPI_PROTOCOL_XBOX, NDPI_PROTOCOL_FUN },
+ { "Windows-Update-Agent", NULL, NDPI_PROTOCOL_WINDOWS_UPDATE, NDPI_PROTOCOL_FUN },
+ { "audio/webm", NULL, NDPI_CONTENT_WEBM, NDPI_PROTOCOL_FUN },
+ { "video/webm", NULL, NDPI_CONTENT_WEBM, NDPI_PROTOCOL_FUN },
+ { "application/x-rtsp-tunnelled", NULL, NDPI_PROTOCOL_RTSP, NDPI_PROTOCOL_FUN },
+ { NULL, 0 }
+};
+
+/* ****************************************************** */
+
+/*
+ Tor
+ The tor protocol uses SSL to contact peers so it could be exchanged with
+ standard SSL. However the host names such as
+
+ - www.fgd2iwya7vinfutj5wq5we.com
+ - www.qbtxzhetq4s2f.com
+ - www.fgd2iwya7vinfutj5wq5we.net
+
+ In essence www.<name>.com|net
+
+ To do things properly we should check if host name in the certificate
+ exists or if the IP address of the SSL peer resolves to a name. Unfortunately
+ for performance reasons we can't afford to do a DNS lookup in nDPI (however apps
+ can do it if possible) and thus we have created a heuristic algorithm that tries
+ to check the host name (in the SSL certificate) to see if it looks like a
+ random name or a real name. We cannot use a dictionary (how can the kernel read a file?)
+ and this we use bigrams distribution to decide if the string looks like a
+ word or just random chars.
+
+ http://www3.nd.edu/~busiforc/handouts/cryptography/Letter%20Frequencies.html
+*/
+
+static const char *ndpi_en_bigrams[] = {
+ "aa", "ba", "ca", "da", "ea", "fa", "ga", "ha", "ia", "ja", "ka", "la", "ma", "na", "oa", "pa", "qa",
+ "ra", "sa", "ta", "ua", "va", "wa", "xa", "ya", "za", "ab", "bb", "db", "eb", "fb", "gb", "hb", "ib",
+ "kb", "lb", "mb", "nb", "ob", "pb", "rb", "sb", "tb", "ub", "wb", "yb", "ac", "bc", "cc", "dc", "ec",
+ "fc", "gc", "hc", "ic", "kc", "lc", "mc", "nc", "oc", "pc", "rc", "sc", "tc", "uc", "wc", "xc", "yc",
+ "ad", "bd", "cd", "dd", "ed", "fd", "gd", "hd", "id", "kd", "ld", "md", "nd", "od", "pd", "rd", "sd",
+ "td", "ud", "wd", "xd", "yd", "zd", "ae", "be", "ce", "de", "ee", "fe", "ge", "he", "ie", "je", "ke",
+ "le", "me", "ne", "oe", "pe", "re", "se", "te", "ue", "ve", "we", "xe", "ye", "ze", "af", "bf", "df",
+ "ef", "ff", "gf", "hf", "if", "kf", "lf", "mf", "nf", "of", "pf", "rf", "sf", "tf", "uf", "wf", "xf",
+ "yf", "zf", "ag", "bg", "dg", "eg", "fg", "gg", "hg", "ig", "kg", "lg", "ng", "og", "pg", "rg", "sg",
+ "tg", "ug", "wg", "yg", "ah", "bh", "ch", "dh", "eh", "fh", "gh", "hh", "ih", "kh", "lh", "mh", "nh",
+ "oh", "ph", "rh", "sh", "th", "uh", "wh", "xh", "yh", "ai", "bi", "ci", "di", "ei", "fi", "gi", "hi",
+ "ii", "ji", "ki", "li", "mi", "ni", "oi", "pi", "qi", "ri", "si", "ti", "ui", "vi", "wi", "xi", "yi",
+ "zi", "aj", "bj", "dj", "ej", "fj", "gj", "hj", "ij", "jj", "kj", "lj", "nj", "oj", "pj", "rj", "sj",
+ "tj", "uj", "wj", "yj", "ak", "ck", "dk", "ek", "gk", "ik", "kk", "lk", "mk", "nk", "ok", "pk", "rk",
+ "sk", "tk", "uk", "wk", "yk", "zk", "al", "bl", "cl", "dl", "el", "fl", "gl", "hl", "il", "kl", "ll",
+ "ml", "nl", "ol", "pl", "rl", "sl", "tl", "ul", "vl", "wl", "xl", "yl", "zl", "am", "bm", "cm", "dm",
+ "em", "fm", "gm", "hm", "im", "km", "lm", "mm", "nm", "om", "pm", "rm", "sm", "tm", "um", "wm", "xm",
+ "ym", "zm", "an", "bn", "cn", "dn", "en", "fn", "gn", "hn", "in", "kn", "ln", "mn", "nn", "on", "pn",
+ "rn", "sn", "tn", "un", "wn", "xn", "yn", "ao", "bo", "co", "do", "eo", "fo", "go", "ho", "io", "jo",
+ "ko", "lo", "mo", "no", "oo", "po", "ro", "so", "to", "uo", "vo", "wo", "xo", "yo", "zo", "ap", "bp",
+ "dp", "ep", "fp", "gp", "hp", "ip", "kp", "lp", "mp", "np", "op", "pp", "rp", "sp", "tp", "up", "wp",
+ "xp", "yp", "zp", "aq", "cq", "dq", "eq", "hq", "iq", "nq", "oq", "qq", "rq", "sq", "uq", "xq", "ar",
+ "br", "cr", "dr", "er", "fr", "gr", "hr", "ir", "kr", "lr", "mr", "nr", "or", "pr", "rr", "sr", "tr",
+ "ur", "vr", "wr", "xr", "yr", "as", "bs", "cs", "ds", "es", "fs", "gs", "hs", "is", "ks", "ls", "ms",
+ "ns", "os", "ps", "rs", "ss", "ts", "us", "vs", "ws", "xs", "ys", "at", "bt", "ct", "dt", "et", "ft",
+ "gt", "ht", "it", "kt", "lt", "mt", "nt", "ot", "pt", "rt", "st", "tt", "ut", "wt", "xt", "yt", "zt",
+ "au", "bu", "cu", "du", "eu", "fu", "gu", "hu", "iu", "ju", "ku", "lu", "mu", "nu", "ou", "pu", "qu",
+ "ru", "su", "tu", "uu", "vu", "wu", "xu", "yu", "zu", "av", "bv", "dv", "ev", "iv", "lv", "mv", "nv",
+ "ov", "rv", "sv", "tv", "uv", "vv", "zv", "aw", "bw", "dw", "ew", "fw", "gw", "hw", "iw", "kw", "lw",
+ "mw", "nw", "ow", "pw", "rw", "sw", "tw", "uw", "ww", "xw", "yw", "zw", "ax", "ex", "ix", "nx", "ox",
+ "rx", "ux", "xx", "yx", "ay", "by", "cy", "dy", "ey", "fy", "gy", "hy", "ky", "ly", "my", "ny", "oy",
+ "py", "ry", "sy", "ty", "uy", "vy", "wy", "xy", "yy", "zy", "az", "bz", "cz", "dz", "ez", "gz", "iz",
+ "lz", "nz", "oz", "pz", "rz", "tz", "uz", "zz", NULL };
+
+static const char *ndpi_en_impossible_bigrams[] = {
+ "bk", "bq", "bx", "cb", "cf", "cg", "cj", "cp", "cv", "cw", "cx", "dx", "fk", "fq", "fv", "fx", "ee",
+ "fz", "gq", "gv", "gx", "hh", "hk", "hv", "hx", "hz", "iy", "jb", "jc", "jd", "jf", "jg", "jh", "jk",
+ "jl", "jm", "jn", "jp", "jq", "jr", "js", "jt", "jv", "jw", "jx", "jy", "jz", "kg", "kq", "kv", "kx",
+ "kz", "lq", "lx", "mg", "mj", "mq", "mx", "mz", "pq", "pv", "px", "qb", "qc", "qd", "qe", "qf", "ii",
+ "qg", "qh", "qj", "qk", "ql", "qm", "qn", "qo", "qp", "qr", "qs", "qt", "qv", "qw", "qx", "qy", "uu",
+ "qz", "sx", "sz", "tq", "tx", "vb", "vc", "vd", "vf", "vg", "vh", "vj", "vk", "vm", "vn", "vp", "bw",
+ "vq", "vt", "vw", "vx", "vz", "wq", "wv", "wx", "wz", "xb", "xg", "xj", "xk", "xv", "xz", "xw", "yd", "yp",
+ "yj", "yq", "yv", "yz", "yw", "zb", "zc", "zg", "zh", "zj", "zn", "zq", "zr", "zs", "zx", "wh", "wk",
+ "wb", "zk", "kp", "zk", "xy",
+ NULL };
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
new file mode 100644
index 000000000..22892c474
--- /dev/null
+++ b/src/lib/ndpi_main.c
@@ -0,0 +1,5706 @@
+/*
+ * ndpi_main.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ * Copyright (C) 2009-11 - ipoque GmbH
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#ifndef __KERNEL__
+#include <stdlib.h>
+#include <errno.h>
+#endif
+
+#include "ahocorasick.h"
+#include "ndpi_api.h"
+
+
+#ifndef __KERNEL__
+#include "../../config.h"
+#endif
+
+// #define DEBUG
+
+#ifdef __KERNEL__
+#include <linux/version.h>
+#define printf printk
+#else
+#include <time.h>
+#ifndef WIN32
+#include <unistd.h>
+#endif
+#endif
+
+#include "ndpi_content_match.c.inc"
+#include "third_party/include/patricia.h"
+#include "third_party/src/patricia.c"
+
+#ifdef WIN32
+/* http://social.msdn.microsoft.com/Forums/uk/vcgeneral/thread/963aac07-da1a-4612-be4a-faac3f1d65ca */
+#ifndef strtok_r
+#define strtok_r(a,b,c) strtok(a,b)
+#endif
+#endif
+
+#ifdef __KERNEL__
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)
+static inline char _tolower(const char c)
+{
+ return c | 0x20;
+}
+
+static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
+{
+ unsigned long long acc;
+ int ok;
+
+ if(base == 0) {
+ if(s[0] == '0') {
+ if(_tolower(s[1]) == 'x' && isxdigit(s[2]))
+ base = 16;
+ else
+ base = 8;
+ } else
+ base = 10;
+ }
+ if(base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
+ s += 2;
+
+ acc = 0;
+ ok = 0;
+ while (*s) {
+ unsigned int val;
+
+ if('0' <= *s && *s <= '9')
+ val = *s - '0';
+ else if('a' <= _tolower(*s) && _tolower(*s) <= 'f')
+ val = _tolower(*s) - 'a' + 10;
+ else if(*s == '\n') {
+ if(*(s + 1) == '\0')
+ break;
+ else
+ return -EINVAL;
+ } else
+ return -EINVAL;
+
+ if(val >= base)
+ return -EINVAL;
+ if(acc > div_u64(ULLONG_MAX - val, base))
+ return -ERANGE;
+ acc = acc * base + val;
+ ok = 1;
+
+ s++;
+ }
+ if(!ok)
+ return -EINVAL;
+ *res = acc;
+ return 0;
+}
+
+int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
+{
+ if(s[0] == '+')
+ s++;
+ return _kstrtoull(s, base, res);
+}
+int kstrtoll(const char *s, unsigned int base, long long *res)
+{
+ unsigned long long tmp;
+ int rv;
+
+ if(s[0] == '-') {
+ rv = _kstrtoull(s + 1, base, &tmp);
+ if(rv < 0)
+ return rv;
+ if((long long)(-tmp) >= 0)
+ return -ERANGE;
+ *res = -tmp;
+ } else {
+ rv = kstrtoull(s, base, &tmp);
+ if(rv < 0)
+ return rv;
+ if((long long)tmp < 0)
+ return -ERANGE;
+ *res = tmp;
+ }
+ return 0;
+}
+int kstrtoint(const char *s, unsigned int base, int *res)
+{
+ long long tmp;
+ int rv;
+
+ rv = kstrtoll(s, base, &tmp);
+ if(rv < 0)
+ return rv;
+ if(tmp != (long long)(int)tmp)
+ return -ERANGE;
+ *res = tmp;
+ return 0;
+}
+#endif
+
+int atoi(const char *str) {
+ int rc;
+
+ if(kstrtoint(str, 0, &rc) == 0 /* Success */)
+ return(rc);
+ else
+ return(0);
+}
+#endif
+
+/* ftp://ftp.cc.uoc.gr/mirrors/OpenBSD/src/lib/libc/stdlib/tsearch.c */
+/* find or insert datum into search tree */
+void *
+ndpi_tsearch(const void *vkey, void **vrootp,
+ int (*compar)(const void *, const void *))
+{
+ ndpi_node *q;
+ char *key = (char *)vkey;
+ ndpi_node **rootp = (ndpi_node **)vrootp;
+
+ if(rootp == (ndpi_node **)0)
+ return ((void *)0);
+ while (*rootp != (ndpi_node *)0) { /* Knuth's T1: */
+ int r;
+
+ if((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
+ return ((void *)*rootp); /* we found it! */
+ rootp = (r < 0) ?
+ &(*rootp)->left : /* T3: follow left branch */
+ &(*rootp)->right; /* T4: follow right branch */
+ }
+ q = (ndpi_node *) ndpi_malloc(sizeof(ndpi_node)); /* T5: key not found */
+ if(q != (ndpi_node *)0) { /* make new node */
+ *rootp = q; /* link new node to old */
+ q->key = key; /* initialize new node */
+ q->left = q->right = (ndpi_node *)0;
+ }
+ return ((void *)q);
+}
+
+/* delete node with given key */
+void *
+ndpi_tdelete(const void *vkey, void **vrootp,
+ int (*compar)(const void *, const void *))
+{
+ ndpi_node **rootp = (ndpi_node **)vrootp;
+ char *key = (char *)vkey;
+ ndpi_node *p = (ndpi_node *)1;
+ ndpi_node *q;
+ ndpi_node *r;
+ int cmp;
+
+ if(rootp == (ndpi_node **)0 || *rootp == (ndpi_node *)0)
+ return ((ndpi_node *)0);
+ while ((cmp = (*compar)(key, (*rootp)->key)) != 0) {
+ p = *rootp;
+ rootp = (cmp < 0) ?
+ &(*rootp)->left : /* follow left branch */
+ &(*rootp)->right; /* follow right branch */
+ if(*rootp == (ndpi_node *)0)
+ return ((void *)0); /* key not found */
+ }
+ r = (*rootp)->right; /* D1: */
+ if((q = (*rootp)->left) == (ndpi_node *)0) /* Left (ndpi_node *)0? */
+ q = r;
+ else if(r != (ndpi_node *)0) { /* Right link is null? */
+ if(r->left == (ndpi_node *)0) { /* D2: Find successor */
+ r->left = q;
+ q = r;
+ } else { /* D3: Find (ndpi_node *)0 link */
+ for (q = r->left; q->left != (ndpi_node *)0; q = r->left)
+ r = q;
+ r->left = q->right;
+ q->left = (*rootp)->left;
+ q->right = (*rootp)->right;
+ }
+ }
+ ndpi_free((ndpi_node *) *rootp); /* D4: Free node */
+ *rootp = q; /* link parent to new node */
+ return(p);
+}
+
+/* Walk the nodes of a tree */
+static void
+ndpi_trecurse(ndpi_node *root, void (*action)(const void *, ndpi_VISIT, int, void*), int level, void *user_data)
+{
+ if(root->left == (ndpi_node *)0 && root->right == (ndpi_node *)0)
+ (*action)(root, ndpi_leaf, level, user_data);
+ else {
+ (*action)(root, ndpi_preorder, level, user_data);
+ if(root->left != (ndpi_node *)0)
+ ndpi_trecurse(root->left, action, level + 1, user_data);
+ (*action)(root, ndpi_postorder, level, user_data);
+ if(root->right != (ndpi_node *)0)
+ ndpi_trecurse(root->right, action, level + 1, user_data);
+ (*action)(root, ndpi_endorder, level, user_data);
+ }
+}
+
+/* Walk the nodes of a tree */
+void
+ndpi_twalk(const void *vroot, void (*action)(const void *, ndpi_VISIT, int, void *), void *user_data)
+{
+ ndpi_node *root = (ndpi_node *)vroot;
+
+ if(root != (ndpi_node *)0 && action != (void (*)(const void *, ndpi_VISIT, int, void*))0)
+ ndpi_trecurse(root, action, 0, user_data);
+}
+
+/* find a node, or return 0 */
+void *
+ndpi_tfind(const void *vkey, void *vrootp,
+ int (*compar)(const void *, const void *))
+{
+ char *key = (char *)vkey;
+ ndpi_node **rootp = (ndpi_node **)vrootp;
+
+ if(rootp == (ndpi_node **)0)
+ return ((ndpi_node *)0);
+ while (*rootp != (ndpi_node *)0) { /* T1: */
+ int r;
+ if((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
+ return (*rootp); /* key found */
+ rootp = (r < 0) ?
+ &(*rootp)->left : /* T3: follow left branch */
+ &(*rootp)->right; /* T4: follow right branch */
+ }
+ return (ndpi_node *)0;
+}
+
+/* ****************************************** */
+
+/* Walk the nodes of a tree */
+static void ndpi_tdestroy_recurse(ndpi_node* root, void (*free_action)(void *)) {
+ if(root->left != NULL)
+ ndpi_tdestroy_recurse(root->left, free_action);
+ if(root->right != NULL)
+ ndpi_tdestroy_recurse(root->right, free_action);
+
+ (*free_action) ((void *) root->key);
+ ndpi_free(root);
+}
+
+void ndpi_tdestroy(void *vrootp, void (*freefct)(void *)) {
+ ndpi_node *root = (ndpi_node *) vrootp;
+
+ if(root != NULL)
+ ndpi_tdestroy_recurse(root, freefct);
+}
+
+/* ****************************************** */
+
+u_int8_t ndpi_net_match(u_int32_t ip_to_check,
+ u_int32_t net,
+ u_int32_t num_bits) {
+ u_int32_t mask = 0;
+
+ mask = ~(~mask >> num_bits);
+
+ return(((ip_to_check & mask) == (net & mask)) ? 1 : 0);
+}
+
+u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst,
+ u_int32_t net, u_int32_t num_bits) {
+ return(ndpi_net_match(src, net, num_bits) || ndpi_net_match(dst, net, num_bits));
+}
+
+/* ****************************************** */
+
+static void *(*_ndpi_malloc)(unsigned long size);
+static void (*_ndpi_free)(void *ptr);
+
+/* ****************************************** */
+
+#ifdef WIN32
+/* http://opensource.apple.com/source/Libc/Libc-186/string.subproj/strcasecmp.c */
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+static const u_char charmap[] = {
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+ '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+ '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+ '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+ '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+ '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+ '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+ '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+ '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+ '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
+ '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
+ '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
+ '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
+ '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+};
+
+int
+strcasecmp(s1, s2)
+ const char *s1, *s2;
+{
+ register const u_char *cm = charmap,
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ while (cm[*us1] == cm[*us2++])
+ if(*us1++ == '\0')
+ return (0);
+ return (cm[*us1] - cm[*--us2]);
+}
+
+int
+strncasecmp(s1, s2, n)
+ const char *s1, *s2;
+ register size_t n;
+{
+ if(n != 0) {
+ register const u_char *cm = charmap,
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ do {
+ if(cm[*us1] != cm[*us2++])
+ return (cm[*us1] - cm[*--us2]);
+ if(*us1++ == '\0')
+ break;
+ } while (--n != 0);
+ }
+ return (0);
+}
+
+#endif
+
+/* ****************************************** */
+
+/* Forward */
+static void addDefaultPort(ndpi_port_range *range,
+ ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root);
+static int removeDefaultPort(ndpi_port_range *range,
+ ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root);
+
+/* ****************************************** */
+
+void* ndpi_malloc(unsigned long size) { return(_ndpi_malloc(size)); }
+
+/* ****************************************** */
+
+void* ndpi_calloc(unsigned long count, unsigned long size) {
+ unsigned long len = count*size;
+ void *p = ndpi_malloc(len);
+
+ if(p)
+ memset(p, 0, len);
+
+ return(p);
+}
+
+/* ****************************************** */
+
+void ndpi_free(void *ptr) { _ndpi_free(ptr); }
+
+/* ****************************************** */
+
+void *ndpi_realloc(void *ptr, size_t old_size, size_t new_size) {
+ void *ret = ndpi_malloc(new_size);
+
+ if(!ret)
+ return(ret);
+ else {
+ memcpy(ret, ptr, old_size);
+ ndpi_free(ptr);
+ return(ret);
+ }
+}
+/* ****************************************** */
+
+char *ndpi_strdup(const char *s) {
+ int len = strlen(s);
+ char *m = ndpi_malloc(len+1);
+
+ if(m) {
+ memcpy(m, s, len);
+ m[len] = '\0';
+ }
+
+ return(m);
+}
+
+/* ****************************************** */
+
+u_int32_t ndpi_detection_get_sizeof_ndpi_flow_struct(void)
+{
+ return sizeof(struct ndpi_flow_struct);
+}
+
+/* ****************************************** */
+
+u_int32_t ndpi_detection_get_sizeof_ndpi_id_struct(void)
+{
+ return sizeof(struct ndpi_id_struct);
+}
+
+/* ******************************************************************** */
+
+char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int id) {
+ return((id >= ndpi_mod->ndpi_num_supported_protocols) ? NULL : ndpi_mod->proto_defaults[id].protoName);
+}
+
+/* ******************************************************************** */
+
+ndpi_port_range* ndpi_build_default_ports_range(ndpi_port_range *ports,
+ u_int16_t portA_low, u_int16_t portA_high,
+ u_int16_t portB_low, u_int16_t portB_high,
+ u_int16_t portC_low, u_int16_t portC_high,
+ u_int16_t portD_low, u_int16_t portD_high,
+ u_int16_t portE_low, u_int16_t portE_high) {
+ int i = 0;
+
+ ports[i].port_low = portA_low, ports[i].port_high = portA_high; i++;
+ 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++;
+
+ return(ports);
+}
+
+/* ******************************************************************** */
+
+ndpi_port_range* ndpi_build_default_ports(ndpi_port_range *ports,
+ u_int16_t portA,
+ u_int16_t portB,
+ u_int16_t portC,
+ u_int16_t portD,
+ u_int16_t portE) {
+ int i = 0;
+
+ ports[i].port_low = portA, ports[i].port_high = portA; i++;
+ 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++;
+
+ return(ports);
+}
+
+/* ******************************************************************** */
+
+void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod,
+ ndpi_protocol_breed_t breed, u_int16_t protoId,
+ u_int16_t tcp_master_protoId[2], u_int16_t udp_master_protoId[2],
+ char *protoName,
+ ndpi_port_range *tcpDefPorts, ndpi_port_range *udpDefPorts) {
+ char *name = ndpi_strdup(protoName);
+ int j;
+
+ if(protoId >= NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS) {
+ printf("[NDPI] %s(protoId=%d): INTERNAL ERROR\n", __FUNCTION__, protoId);
+ ndpi_free(name);
+ return;
+ }
+
+ ndpi_mod->proto_defaults[protoId].protoName = name,
+ ndpi_mod->proto_defaults[protoId].protoId = protoId,
+ ndpi_mod->proto_defaults[protoId].protoBreed = breed;
+
+ memcpy(&ndpi_mod->proto_defaults[protoId].master_tcp_protoId, tcp_master_protoId, 2*sizeof(u_int16_t));
+ memcpy(&ndpi_mod->proto_defaults[protoId].master_udp_protoId, udp_master_protoId, 2*sizeof(u_int16_t));
+
+ for(j=0; j<MAX_DEFAULT_PORTS; j++) {
+ if(udpDefPorts[j].port_low != 0) addDefaultPort(&udpDefPorts[j], &ndpi_mod->proto_defaults[protoId], &ndpi_mod->udpRoot);
+ if(tcpDefPorts[j].port_low != 0) addDefaultPort(&tcpDefPorts[j], &ndpi_mod->proto_defaults[protoId], &ndpi_mod->tcpRoot);
+ }
+
+#if 0
+ printf("%s(%d, %s, %p) [%s]\n",
+ __FUNCTION__,
+ protoId,
+ ndpi_mod->proto_defaults[protoId].protoName,
+ ndpi_mod,
+ ndpi_mod->proto_defaults[1].protoName);
+#endif
+}
+
+/* ******************************************************************** */
+
+static int ndpi_default_ports_tree_node_t_cmp(const void *a, const void *b) {
+ ndpi_default_ports_tree_node_t *fa = (ndpi_default_ports_tree_node_t*)a;
+ ndpi_default_ports_tree_node_t *fb = (ndpi_default_ports_tree_node_t*)b;
+
+ //printf("[NDPI] %s(%d, %d)\n", __FUNCTION__, fa->default_port, fb->default_port);
+
+ return((fa->default_port == fb->default_port) ? 0 : ((fa->default_port < fb->default_port) ? -1 : 1));
+}
+
+/* ******************************************************************** */
+
+void ndpi_default_ports_tree_node_t_walker(const void *node, const ndpi_VISIT which, const int depth) {
+ ndpi_default_ports_tree_node_t *f = *(ndpi_default_ports_tree_node_t **)node;
+
+
+ printf("<%d>Walk on node %s (%u)\n",
+ depth,
+ which == ndpi_preorder?"ndpi_preorder":
+ which == ndpi_postorder?"ndpi_postorder":
+ which == ndpi_endorder?"ndpi_endorder":
+ which == ndpi_leaf?"ndpi_leaf": "unknown",
+ f->default_port);
+}
+
+/* ******************************************************************** */
+
+static void addDefaultPort(ndpi_port_range *range,
+ ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root) {
+ ndpi_default_ports_tree_node_t *ret;
+ u_int16_t port;
+
+ // printf("[NDPI] %s(%d)\n", __FUNCTION__, port);
+
+ for(port=range->port_low; port<=range->port_high; port++) {
+ ndpi_default_ports_tree_node_t *node = (ndpi_default_ports_tree_node_t*)ndpi_malloc(sizeof(ndpi_default_ports_tree_node_t));
+
+ if(!node) {
+ printf("[NDPI] %s(): not enough memory\n", __FUNCTION__);
+ break;
+ }
+
+ node->proto = def, node->default_port = port;
+ ret = *(ndpi_default_ports_tree_node_t**)ndpi_tsearch(node, (void*)root, ndpi_default_ports_tree_node_t_cmp); /* Add it to the tree */
+
+ if(ret != node) {
+ printf("[NDPI] %s(): found duplicate for port %u: overwriting it with new value\n", __FUNCTION__, port);
+
+ ret->proto = def;
+ ndpi_free(node);
+ }
+ }
+}
+
+/* ****************************************************** */
+
+/*
+ NOTE
+
+ This function must be called with a semaphore set, this in order to avoid
+ changing the datastrutures while using them
+*/
+static int removeDefaultPort(ndpi_port_range *range,
+ ndpi_proto_defaults_t *def,
+ ndpi_default_ports_tree_node_t **root) {
+ ndpi_default_ports_tree_node_t node;
+ ndpi_default_ports_tree_node_t *ret;
+ u_int16_t port;
+
+ for(port=range->port_low; port<=range->port_high; port++) {
+ node.proto = def, node.default_port = port;
+ ret = *(ndpi_default_ports_tree_node_t**)ndpi_tdelete(&node, (void*)root,
+ ndpi_default_ports_tree_node_t_cmp); /* Add it to the tree */
+
+ if(ret != NULL) {
+ ndpi_free((ndpi_default_ports_tree_node_t*)ret);
+ return(0);
+ }
+ }
+
+ return(-1);
+}
+
+/* ****************************************************** */
+
+static int ndpi_string_to_automa(struct ndpi_detection_module_struct *ndpi_struct,
+ ndpi_automa *automa,
+ char *value, int protocol_id,
+ ndpi_protocol_breed_t breed) {
+ AC_PATTERN_t ac_pattern;
+
+ if(protocol_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) {
+ printf("[NDPI] %s(protoId=%d): INTERNAL ERROR\n", __FUNCTION__, protocol_id);
+ return(-1);
+ }
+
+ if(automa->ac_automa == NULL) return(-2);
+ ac_pattern.astring = value;
+ ac_pattern.rep.number = protocol_id;
+ ac_pattern.length = strlen(ac_pattern.astring);
+ ac_automata_add(((AC_AUTOMATA_t*)automa->ac_automa), &ac_pattern);
+
+ return(0);
+}
+
+/* ****************************************************** */
+
+static int ndpi_add_host_url_subprotocol(struct ndpi_detection_module_struct *ndpi_struct,
+ char *value, int protocol_id,
+ ndpi_protocol_breed_t breed) {
+ return(ndpi_string_to_automa(ndpi_struct, &ndpi_struct->host_automa,
+ value, protocol_id, breed));
+}
+
+/* ****************************************************** */
+
+int ndpi_add_content_subprotocol(struct ndpi_detection_module_struct *ndpi_struct,
+ char *value, int protocol_id,
+ ndpi_protocol_breed_t breed) {
+ return(ndpi_string_to_automa(ndpi_struct, &ndpi_struct->content_automa, value, protocol_id, breed));
+}
+
+/* ****************************************************** */
+
+/*
+ NOTE
+
+ This function must be called with a semaphore set, this in order to avoid
+ changing the datastrutures while using them
+*/
+static int ndpi_remove_host_url_subprotocol(struct ndpi_detection_module_struct *ndpi_struct,
+ char *value, int protocol_id) {
+
+ printf("[NDPI] Missing implementation of %s()\n", __FUNCTION__);
+ return(-1);
+}
+
+/* ******************************************************************** */
+
+static void init_string_based_protocols(struct ndpi_detection_module_struct *ndpi_mod) {
+ int i;
+
+ for(i=0; host_match[i].string_to_match != NULL; i++) {
+ ndpi_add_host_url_subprotocol(ndpi_mod, host_match[i].string_to_match,
+ host_match[i].protocol_id, host_match[i].protocol_breed);
+
+ if(ndpi_mod->proto_defaults[host_match[i].protocol_id].protoName == NULL) {
+ ndpi_mod->proto_defaults[host_match[i].protocol_id].protoName = ndpi_strdup(host_match[i].proto_name);
+ ndpi_mod->proto_defaults[host_match[i].protocol_id].protoId = host_match[i].protocol_id;
+ ndpi_mod->proto_defaults[host_match[i].protocol_id].protoBreed = host_match[i].protocol_breed;
+ }
+ }
+
+ for(i=0; content_match[i].string_to_match != NULL; i++)
+ ndpi_add_content_subprotocol(ndpi_mod, content_match[i].string_to_match,
+ content_match[i].protocol_id,
+ content_match[i].protocol_breed);
+
+ for(i=0; ndpi_en_bigrams[i] != NULL; i++)
+ ndpi_string_to_automa(ndpi_mod, &ndpi_mod->bigrams_automa,
+ (char*)ndpi_en_bigrams[i],
+ 1, NDPI_PROTOCOL_UNRATED);
+
+ for(i=0; ndpi_en_impossible_bigrams[i] != NULL; i++)
+ ndpi_string_to_automa(ndpi_mod, &ndpi_mod->impossible_bigrams_automa,
+ (char*)ndpi_en_impossible_bigrams[i],
+ 1, NDPI_PROTOCOL_UNRATED);
+}
+
+/* ******************************************************************** */
+
+/* This function is used to map protocol name and default ports and it MUST
+ be updated whenever a new protocol is added to NDPI.
+
+ Do NOT add web services (NDPI_SERVICE_xxx) here.
+*/
+static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndpi_mod) {
+ int i;
+ ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS];
+ u_int16_t no_master[2] = { NDPI_PROTOCOL_NO_MASTER_PROTO, NDPI_PROTOCOL_NO_MASTER_PROTO },
+ custom_master[2], custom_master1[2];
+
+ /* Reset all settings */
+ memset(ndpi_mod->proto_defaults, 0, sizeof(ndpi_mod->proto_defaults));
+
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNRATED, NDPI_PROTOCOL_UNKNOWN,
+ no_master,
+ no_master, "Unknown",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_FTP_CONTROL,
+ no_master,
+ no_master, "FTP_CONTROL",
+ ndpi_build_default_ports(ports_a, 21, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_FTP_DATA,
+ no_master,
+ no_master, "FTP_DATA",
+ ndpi_build_default_ports(ports_a, 20, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_MAIL_POP,
+ no_master,
+ no_master, "POP3",
+ ndpi_build_default_ports(ports_a, 110, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MAIL_POPS,
+ no_master,
+ no_master, "POPS",
+ ndpi_build_default_ports(ports_a, 995, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_MAIL_SMTP,
+ no_master,
+ no_master, "SMTP",
+ ndpi_build_default_ports(ports_a, 25, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MAIL_SMTPS,
+ no_master,
+ no_master, "SMTPS",
+ ndpi_build_default_ports(ports_a, 465, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_MAIL_IMAP,
+ no_master,
+ no_master, "IMAP",
+ ndpi_build_default_ports(ports_a, 143, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MAIL_IMAPS,
+ no_master,
+ no_master, "IMAPS",
+ ndpi_build_default_ports(ports_a, 993, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DNS,
+ no_master,
+ no_master, "DNS",
+ ndpi_build_default_ports(ports_a, 53, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 53, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IPP,
+ no_master,
+ no_master, "IPP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP,
+ no_master,
+ no_master, "HTTP",
+ ndpi_build_default_ports(ports_a, 80, 0 /* ntop */, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MDNS,
+ no_master,
+ no_master, "MDNS",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 5353, 5354, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NTP,
+ no_master,
+ no_master, "NTP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 123, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NETBIOS,
+ no_master,
+ no_master, "NetBIOS",
+ ndpi_build_default_ports(ports_a, 139, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 137, 138, 139, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NFS,
+ no_master,
+ no_master, "NFS",
+ ndpi_build_default_ports(ports_a, 2049, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 2049, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SSDP,
+ no_master,
+ no_master, "SSDP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_BGP,
+ no_master,
+ no_master, "BGP",
+ ndpi_build_default_ports(ports_a, 2605, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SNMP,
+ no_master,
+ no_master, "SNMP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 161, 162, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_XDMCP,
+ no_master,
+ no_master, "XDMCP",
+ ndpi_build_default_ports(ports_a, 177, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 177, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SMB,
+ no_master,
+ no_master, "SMB",
+ ndpi_build_default_ports(ports_a, 445, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SYSLOG,
+ no_master,
+ no_master, "Syslog",
+ ndpi_build_default_ports(ports_a, 514, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 514, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DHCP,
+ no_master,
+ no_master, "DHCP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 67, 68, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_POSTGRES,
+ no_master,
+ no_master, "PostgreSQL",
+ ndpi_build_default_ports(ports_a, 5432, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MYSQL,
+ no_master,
+ no_master, "MySQL",
+ ndpi_build_default_ports(ports_a, 3306, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNRATED, NDPI_PROTOCOL_TDS,
+ no_master,
+ no_master, "TDS",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK,
+ no_master,
+ no_master, "Direct_Download_Link",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_APPLEJUICE,
+ no_master,
+ no_master, "AppleJuice",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_DIRECTCONNECT,
+ no_master,
+ no_master, "DirectConnect",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_SOCRATES,
+ no_master,
+ no_master, "Socrates",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_WINMX,
+ no_master,
+ no_master, "WinMX",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VMWARE,
+ no_master,
+ no_master, "VMware",
+ ndpi_build_default_ports(ports_a, 903, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 902, 903, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_FILETOPIA,
+ no_master,
+ no_master, "Filetopia",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_IMESH,
+ no_master,
+ no_master, "iMESH",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_KONTIKI,
+ no_master,
+ no_master, "Kontiki",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_OPENFT,
+ no_master,
+ no_master, "OpenFT",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_FASTTRACK,
+ no_master,
+ no_master, "FastTrack",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_GNUTELLA,
+ no_master,
+ no_master, "Gnutella",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_EDONKEY,
+ no_master,
+ no_master, "eDonkey",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_BITTORRENT,
+ no_master,
+ no_master, "BitTorrent",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_EPP,
+ no_master,
+ no_master, "EPP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_AVI,
+ no_master,
+ no_master, "AVI",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_CONTENT_FLASH,
+ no_master,
+ no_master, "Flash",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_OGG,
+ no_master,
+ no_master, "OggVorbis",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_MPEG,
+ no_master,
+ no_master, "MPEG",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_QUICKTIME,
+ no_master,
+ no_master, "QuickTime",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_REALMEDIA,
+ no_master,
+ no_master, "RealMedia",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_WINDOWSMEDIA,
+ no_master,
+ no_master, "WindowsMedia",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_CONTENT_MMS,
+ no_master,
+ no_master, "MMS",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_XBOX,
+ no_master,
+ no_master, "Xbox",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_QQ,
+ no_master,
+ no_master, "QQ",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_MOVE,
+ no_master,
+ no_master, "Move",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_RTSP,
+ no_master,
+ no_master, "RTSP",
+ ndpi_build_default_ports(ports_a, 554, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 554, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_ICECAST,
+ no_master,
+ no_master, "IceCast",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_PPLIVE,
+ no_master,
+ no_master, "PPLive",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_PPSTREAM,
+ no_master,
+ no_master, "PPStream",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_ZATTOO,
+ no_master,
+ no_master, "Zattoo",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SHOUTCAST,
+ no_master,
+ no_master, "ShoutCast",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SOPCAST,
+ no_master,
+ no_master, "Sopcast",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_TVANTS,
+ no_master,
+ no_master, "Tvants",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_TVUPLAYER,
+ no_master,
+ no_master, "TVUplayer",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV,
+ no_master,
+ no_master, "HTTP_APPLICATION_VEOHTV",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_QQLIVE,
+ no_master,
+ no_master, "QQLive",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_THUNDER,
+ no_master,
+ no_master, "Thunder",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SOULSEEK,
+ no_master,
+ no_master, "Soulseek",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+
+ custom_master[0] = NDPI_PROTOCOL_SSL, custom_master[1] = NDPI_PROTOCOL_UNKNOWN;
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SSL_NO_CERT,
+ custom_master, no_master, "SSL_No_Cert",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IRC,
+ no_master,
+ no_master, "IRC",
+ ndpi_build_default_ports(ports_a, 194, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 194, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AYIYA,
+ no_master,
+ no_master, "Ayiya",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 5072, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_UNENCRYPED_JABBER,
+ no_master,
+ no_master, "Unencryped_Jabber",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MSN,
+ no_master,
+ no_master, "MSN",
+ ndpi_build_default_ports(ports_a, 1863, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_OSCAR,
+ no_master,
+ no_master, "Oscar",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_YAHOO,
+ no_master,
+ no_master, "Yahoo",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_BATTLEFIELD,
+ no_master,
+ no_master, "BattleField",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_QUAKE,
+ no_master,
+ no_master, "Quake",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_VRRP,
+ no_master,
+ no_master, "VRRP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_STEAM,
+ no_master,
+ no_master, "Steam",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_HALFLIFE2,
+ no_master,
+ no_master, "HalfLife2",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_WORLDOFWARCRAFT,
+ no_master,
+ no_master, "WorldOfWarcraft",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_TELNET,
+ no_master,
+ no_master, "Telnet",
+ ndpi_build_default_ports(ports_a, 23, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+
+ custom_master[0] = NDPI_PROTOCOL_SIP, custom_master[1] = NDPI_PROTOCOL_H323;
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_STUN,
+ no_master, custom_master, "STUN",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_IP_IPSEC,
+ no_master,
+ no_master, "IPsec",
+ ndpi_build_default_ports(ports_a, 500, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 500, 4500, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_GRE,
+ no_master,
+ no_master, "GRE",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_ICMP,
+ no_master,
+ no_master, "ICMP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_IGMP,
+ no_master,
+ no_master, "IGMP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_EGP,
+ no_master,
+ no_master, "EGP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_SCTP,
+ no_master,
+ no_master, "SCTP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_OSPF,
+ no_master,
+ no_master, "OSPF",
+ ndpi_build_default_ports(ports_a, 2604, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_IP_IN_IP,
+ no_master,
+ no_master, "IP_in_IP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTP,
+ no_master,
+ no_master, "RTP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RDP,
+ no_master,
+ no_master, "RDP",
+ ndpi_build_default_ports(ports_a, 3389, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VNC,
+ no_master,
+ no_master, "VNC",
+ ndpi_build_default_ports(ports_a, 5900, 5901, 5800, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_PCANYWHERE,
+ no_master,
+ no_master, "PcAnywhere",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+
+ custom_master[0] = NDPI_PROTOCOL_SSL_NO_CERT, custom_master[1] = NDPI_PROTOCOL_UNKNOWN;
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_SSL,
+ no_master, custom_master, "SSL",
+ ndpi_build_default_ports(ports_a, 443, 3001 /* ntop */, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SSH,
+ no_master,
+ no_master, "SSH",
+ ndpi_build_default_ports(ports_a, 22, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_USENET,
+ no_master,
+ no_master, "Usenet",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MGCP,
+ no_master,
+ no_master, "MGCP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IAX,
+ no_master,
+ no_master, "IAX",
+ ndpi_build_default_ports(ports_a, 4569, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 4569, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TFTP,
+ no_master,
+ no_master, "TFTP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AFP,
+ no_master,
+ no_master, "AFP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_STEALTHNET,
+ no_master,
+ no_master, "Stealthnet",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_AIMINI,
+ no_master,
+ no_master, "Aimini",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SIP,
+ no_master,
+ no_master,
+ "SIP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 5060, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TRUPHONE,
+ no_master,
+ no_master, "TruPhone",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_ICMPV6,
+ no_master,
+ no_master, "ICMPV6",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DHCPV6,
+ no_master,
+ no_master, "DHCPV6",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_ARMAGETRON,
+ no_master,
+ no_master, "Armagetron",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_CROSSFIRE,
+ no_master,
+ no_master, "Crossfire",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_DOFUS,
+ no_master,
+ no_master, "Dofus",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNRATED, NDPI_PROTOCOL_FIESTA,
+ no_master,
+ no_master, "Fiesta",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_FLORENSIA,
+ no_master,
+ no_master, "Florensia",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_GUILDWARS,
+ no_master,
+ no_master, "Guildwars",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC,
+ no_master,
+ no_master, "HTTP_Application_ActiveSync",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_KERBEROS,
+ no_master,
+ no_master, "Kerberos",
+ ndpi_build_default_ports(ports_a, 88, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 88, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_LDAP,
+ no_master,
+ no_master, "LDAP",
+ ndpi_build_default_ports(ports_a, 389, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 389, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_MAPLESTORY,
+ no_master,
+ no_master, "MapleStory",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MSSQL,
+ no_master,
+ no_master, "MsSQL",
+ ndpi_build_default_ports(ports_a, 1433, 1434, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_PPTP,
+ no_master,
+ no_master, "PPTP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_WARCRAFT3,
+ no_master,
+ no_master, "Warcraft3",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_WORLD_OF_KUNG_FU,
+ no_master,
+ no_master, "WorldOfKungFu",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MEEBO,
+ no_master,
+ no_master, "Meebo", /* Remove */
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DROPBOX,
+ no_master,
+ no_master, "DropBox",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 17500, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKYPE,
+ no_master,
+ no_master, "Skype",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DCERPC,
+ no_master,
+ no_master, "DCE_RPC",
+ ndpi_build_default_ports(ports_a, 135, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NETFLOW,
+ no_master,
+ no_master, "NetFlow",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 2055, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SFLOW,
+ no_master,
+ no_master, "sFlow",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 6343, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP_CONNECT,
+ no_master,
+ no_master, "HTTP_Connect",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP_PROXY,
+ no_master,
+ no_master, "HTTP_Proxy",
+ ndpi_build_default_ports(ports_a, 8080, 3128, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CITRIX,
+ no_master,
+ no_master, "Citrix",
+ ndpi_build_default_ports(ports_a, 1494, 2598, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKYFILE_PREPAID,
+ no_master,
+ no_master, "SkyFile_PrePaid",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKYFILE_RUDICS,
+ no_master,
+ no_master, "SkyFile_Rudics",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKYFILE_POSTPAID,
+ no_master,
+ no_master, "SkyFile_PostPaid",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CITRIX_ONLINE,
+ no_master,
+ no_master, "Citrix_Online",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WEBEX,
+ no_master,
+ no_master, "Webex",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RADIUS,
+ no_master,
+ no_master, "Radius",
+ ndpi_build_default_ports(ports_a, 1812, 1813, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 1812, 1813, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WINDOWS_UPDATE,
+ no_master,
+ no_master, "WindowsUpdate",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TEAMVIEWER,
+ no_master,
+ no_master, "TeamViewer",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_LOTUS_NOTES,
+ no_master,
+ no_master, "LotusNotes",
+ ndpi_build_default_ports(ports_a, 1352, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SAP,
+ no_master,
+ no_master, "SAP",
+ ndpi_build_default_ports(ports_a, 3201, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); /* Missing dissector: port based only */
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_GTP,
+ no_master,
+ no_master, "GTP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 2152, 2123, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_UPNP,
+ no_master,
+ no_master, "UPnP",
+ ndpi_build_default_ports(ports_a, 1780, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 1900, 0, 0, 0, 0) /* UDP */); /* Missing dissector: port based only */
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TELEGRAM,
+ no_master,
+ no_master, "Telegram",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+
+ custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN;
+ custom_master1[0] = NDPI_PROTOCOL_DNS, custom_master1[1] = NDPI_PROTOCOL_UNKNOWN;
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE,
+ NDPI_SERVICE_GOOGLE,
+ custom_master, custom_master1,
+ "Google",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+
+ custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN;
+ custom_master1[0] = NDPI_PROTOCOL_DNS, custom_master1[1] = NDPI_PROTOCOL_UNKNOWN;
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE,
+ NDPI_SERVICE_APPLE,
+ custom_master, custom_master1,
+ "Apple",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+
+ custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN;
+ custom_master1[0] = NDPI_PROTOCOL_DNS, custom_master1[1] = NDPI_PROTOCOL_UNKNOWN;
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE,
+ NDPI_SERVICE_APPLE_ICLOUD,
+ custom_master, custom_master1,
+ "AppleiCloud",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+
+ custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN;
+ custom_master1[0] = NDPI_PROTOCOL_DNS, custom_master1[1] = NDPI_PROTOCOL_UNKNOWN;
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN,
+ NDPI_SERVICE_APPLE_ITUNES,
+ custom_master, custom_master1,
+ "AppleiTunes",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+
+ /* http://en.wikipedia.org/wiki/Link-local_Multicast_Name_Resolution */
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_LLMNR,
+ no_master,
+ no_master, "LLMNR",
+ ndpi_build_default_ports(ports_a, 5355, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 5355, 0, 0, 0, 0) /* UDP */); /* Missing dissector: port based only */
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_REMOTE_SCAN,
+ no_master,
+ no_master, "RemoteScan",
+ ndpi_build_default_ports(ports_a, 6077, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 6078, 0, 0, 0, 0) /* UDP */); /* Missing dissector: port based only */
+
+ custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN;
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SPOTIFY,
+ custom_master, no_master, "Spotify",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 57621, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_CONTENT_WEBM,
+ no_master,
+ no_master, "WebM", /* Courtesy of Shreeram Ramamoorthy Swaminathan <shreeram <shreeram1985@yahoo.co.in> */
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_H323,
+ no_master,
+ no_master,
+ "H323",
+ ndpi_build_default_ports(ports_a, 1719, 1720, 3478, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 1719, 1720, 3478, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_OPENVPN,
+ no_master,
+ no_master, "OpenVPN",
+ ndpi_build_default_ports(ports_a, 1194, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 1194, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NOE,
+ no_master,
+ no_master, "NOE",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_CISCOVPN,
+ no_master,
+ no_master, "CiscoVPN",
+ ndpi_build_default_ports(ports_a, 10000, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 10000, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TEAMSPEAK,
+ no_master,
+ no_master, "TeamSpeak",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_TOR,
+ no_master,
+ no_master, "TOR",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKINNY,
+ no_master,
+ no_master, "CiscoSkinny",
+ ndpi_build_default_ports(ports_a, 2000, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTCP,
+ no_master,
+ no_master, "RTCP",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RSYNC,
+ no_master,
+ no_master, "RSYNC",
+ ndpi_build_default_ports(ports_a, 873, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ORACLE,
+ no_master,
+ no_master, "Oracle",
+ ndpi_build_default_ports(ports_a, 1521, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CORBA,
+ no_master,
+ no_master, "Corba",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_UBUNTUONE,
+ no_master,
+ no_master, "UbuntuONE",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHOIS_DAS,
+ no_master,
+ no_master, "Whois-DAS",
+ ndpi_build_default_ports(ports_a, 43, 4343, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_COLLECTD,
+ no_master,
+ no_master, "Collectd",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 25826, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOCKS5,
+ no_master,
+ no_master, "SOCKS5",
+ ndpi_build_default_ports(ports_a, 1080, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 1080, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOCKS4,
+ no_master,
+ no_master, "SOCKS4",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTMP,
+ no_master,
+ no_master, "RTMP",
+ ndpi_build_default_ports(ports_a, 1935, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_PANDO,
+ no_master,
+ no_master, "Pando_Media_Booster",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VIBER,
+ no_master,
+ no_master, "Viber",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MEGACO,
+ no_master,
+ no_master, "Megaco",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 2944 , 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_REDIS,
+ no_master,
+ no_master, "Redis",
+ ndpi_build_default_ports(ports_a, 6379, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ZMQ,
+ no_master,
+ no_master, "ZeroMQ",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_SERVICE_TWITTER,
+ no_master,
+ no_master, "Twitter",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_VHUA,
+ no_master,
+ no_master, "VHUA",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 58267, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_SERVICE_FACEBOOK,
+ no_master,
+ no_master, "Facebook",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_SERVICE_FACEBOOK_CHAT,
+ no_master,
+ no_master, "FacebookChat",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_SERVICE_PANDORA,
+ no_master,
+ no_master, "Pandora",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+
+ init_string_based_protocols(ndpi_mod);
+
+ for(i=0; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++) {
+ if(ndpi_mod->proto_defaults[i].protoName == NULL) {
+ printf("[NDPI] %s(missing protoId=%d) INTERNAL ERROR: not all protocols have been initialized\n", __FUNCTION__, i);
+ }
+ }
+}
+
+/* ****************************************************** */
+
+static int ac_match_handler(AC_MATCH_t *m, void *param) {
+ int *matching_protocol_id = (int*)param;
+
+ /* Stopping to the first match. We might consider searching
+ * for the more specific match, paying more cpu cycles. */
+ *matching_protocol_id = m->patterns[0].rep.number;
+
+ return 1; /* 0 to continue searching, !0 to stop */
+}
+
+/* ******************************************************************** */
+
+#ifdef NDPI_PROTOCOL_TOR
+
+static int fill_prefix_v4(prefix_t *p, struct in_addr *a, int b, int mb) {
+ do {
+ if(b < 0 || b > mb)
+ return(-1);
+
+ memcpy(&p->add.sin, a, (mb+7)/8);
+ p->family = AF_INET;
+ p->bitlen = b;
+ p->ref_count = 0;
+ } while (0);
+
+ return(0);
+}
+
+/* ******************************************* */
+
+u_int16_t ndpi_network_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, struct in_addr *pin) {
+ prefix_t prefix;
+ patricia_node_t *node;
+
+ fill_prefix_v4(&prefix, pin, 32, ((patricia_tree_t*)ndpi_struct->protocols_ptree)->maxbits);
+ node = ndpi_patricia_search_best(ndpi_struct->protocols_ptree, &prefix);
+
+ return(node ? node->value.user_value : NDPI_PROTOCOL_UNKNOWN);
+}
+
+/* ******************************************* */
+
+u_int16_t ndpi_host_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t host) {
+ struct in_addr pin;
+
+ pin.s_addr = host;
+
+ return(ndpi_network_ptree_match(ndpi_struct, &pin));
+}
+
+/* ******************************************* */
+
+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);
+}
+
+/* ******************************************* */
+
+u_int8_t ndpi_is_tor_flow(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(packet->tcp != NULL) {
+ if(flow->packet.iph) {
+ if(tor_ptree_match(ndpi_struct, (struct in_addr *)&packet->iph->saddr)
+ || tor_ptree_match(ndpi_struct, (struct in_addr *)&packet->iph->daddr)) {
+ return(1);
+ }
+ }
+ }
+
+ return(0);
+}
+
+/* ******************************************* */
+
+static patricia_node_t* add_to_ptree(patricia_tree_t *tree, int family,
+ void *addr, int bits) {
+ prefix_t prefix;
+ patricia_node_t *node;
+
+ fill_prefix_v4(&prefix, (struct in_addr*)addr, bits, tree->maxbits);
+
+ node = ndpi_patricia_lookup(tree, &prefix);
+
+ return(node);
+}
+/* ******************************************* */
+
+static void ndpi_init_ptree_ipv4(struct ndpi_detection_module_struct *ndpi_str,
+ void *ptree, ndpi_network host_list[]) {
+ int i;
+
+ for(i=0; host_list[i].network != 0x0; i++) {
+ struct in_addr pin;
+ patricia_node_t *node;
+
+ pin.s_addr = host_list[i].network;
+ if((node = add_to_ptree(ptree, AF_INET, &pin, host_list[i].cidr /* bits */)) != NULL)
+ node->value.user_value = host_list[i].value;
+ }
+}
+#endif
+
+/* ******************************************************************** */
+
+struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_per_second,
+ void* (*__ndpi_malloc)(unsigned long size),
+ void (*__ndpi_free)(void *ptr),
+ ndpi_debug_function_ptr ndpi_debug_printf)
+{
+ struct ndpi_detection_module_struct *ndpi_str;
+
+ _ndpi_malloc = __ndpi_malloc;
+ _ndpi_free = __ndpi_free;
+
+ ndpi_str = ndpi_malloc(sizeof(struct ndpi_detection_module_struct));
+
+ if(ndpi_str == NULL) {
+ ndpi_debug_printf(0, NULL, NDPI_LOG_DEBUG, "ndpi_init_detection_module initial malloc failed\n");
+ return NULL;
+ }
+ memset(ndpi_str, 0, sizeof(struct ndpi_detection_module_struct));
+
+ if((ndpi_str->protocols_ptree = ndpi_New_Patricia(32 /* IPv4 */)) != NULL)
+ ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, host_protocol_list);
+
+ NDPI_BITMASK_RESET(ndpi_str->detection_bitmask);
+#ifdef NDPI_ENABLE_DEBUG_MESSAGES
+ ndpi_str->ndpi_debug_printf = ndpi_debug_printf;
+ ndpi_str->user_data = NULL;
+#endif
+
+ ndpi_str->match_dns_host_names = 1; /*
+ Set it to 0 to increase library speed avoid
+ matching host names
+ */
+ ndpi_str->ticks_per_second = ticks_per_second;
+ ndpi_str->tcp_max_retransmission_window_size = NDPI_DEFAULT_MAX_TCP_RETRANSMISSION_WINDOW_SIZE;
+ ndpi_str->directconnect_connection_ip_tick_timeout =
+ NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT * ticks_per_second;
+
+ ndpi_str->rtsp_connection_timeout = NDPI_RTSP_CONNECTION_TIMEOUT * ticks_per_second;
+ ndpi_str->tvants_connection_timeout = NDPI_TVANTS_CONNECTION_TIMEOUT * ticks_per_second;
+ ndpi_str->irc_timeout = NDPI_IRC_CONNECTION_TIMEOUT * ticks_per_second;
+ ndpi_str->gnutella_timeout = NDPI_GNUTELLA_CONNECTION_TIMEOUT * ticks_per_second;
+
+ ndpi_str->battlefield_timeout = NDPI_BATTLEFIELD_CONNECTION_TIMEOUT * ticks_per_second;
+
+ ndpi_str->thunder_timeout = NDPI_THUNDER_CONNECTION_TIMEOUT * ticks_per_second;
+ ndpi_str->yahoo_detect_http_connections = NDPI_YAHOO_DETECT_HTTP_CONNECTIONS;
+
+ ndpi_str->yahoo_lan_video_timeout = NDPI_YAHOO_LAN_VIDEO_TIMEOUT * ticks_per_second;
+ ndpi_str->zattoo_connection_timeout = NDPI_ZATTOO_CONNECTION_TIMEOUT * ticks_per_second;
+ ndpi_str->jabber_stun_timeout = NDPI_JABBER_STUN_TIMEOUT * ticks_per_second;
+ ndpi_str->jabber_file_transfer_timeout = NDPI_JABBER_FT_TIMEOUT * ticks_per_second;
+ ndpi_str->soulseek_connection_ip_tick_timeout = NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT * ticks_per_second;
+
+ ndpi_str->ndpi_num_supported_protocols = NDPI_MAX_SUPPORTED_PROTOCOLS;
+ ndpi_str->ndpi_num_custom_protocols = 0;
+
+ ndpi_str->host_automa.ac_automa = ac_automata_init(ac_match_handler);
+ ndpi_str->content_automa.ac_automa = ac_automata_init(ac_match_handler);
+ ndpi_str->bigrams_automa.ac_automa = ac_automata_init(ac_match_handler);
+ ndpi_str->impossible_bigrams_automa.ac_automa = ac_automata_init(ac_match_handler);
+
+ ndpi_init_protocol_defaults(ndpi_str);
+ return ndpi_str;
+}
+
+/* *********************************************** */
+
+static void free_ptree_data(void *data) { ; }
+
+/* ****************************************************** */
+
+void ndpi_exit_detection_module(struct ndpi_detection_module_struct
+ *ndpi_struct, void (*ndpi_free) (void *ptr)) {
+ if(ndpi_struct != NULL) {
+ int i;
+
+ for(i=0; i<(int)ndpi_struct->ndpi_num_supported_protocols; i++) {
+ if(ndpi_struct->proto_defaults[i].protoName)
+ ndpi_free(ndpi_struct->proto_defaults[i].protoName);
+ }
+
+ if(ndpi_struct->protocols_ptree)
+ ndpi_Destroy_Patricia((patricia_tree_t*)ndpi_struct->protocols_ptree, free_ptree_data);
+
+ ndpi_tdestroy(ndpi_struct->udpRoot, ndpi_free);
+ ndpi_tdestroy(ndpi_struct->tcpRoot, ndpi_free);
+
+ if(ndpi_struct->host_automa.ac_automa != NULL)
+ ac_automata_release((AC_AUTOMATA_t*)ndpi_struct->host_automa.ac_automa);
+
+ if(ndpi_struct->content_automa.ac_automa != NULL)
+ ac_automata_release((AC_AUTOMATA_t*)ndpi_struct->content_automa.ac_automa);
+
+ if(ndpi_struct->bigrams_automa.ac_automa != NULL)
+ ac_automata_release((AC_AUTOMATA_t*)ndpi_struct->bigrams_automa.ac_automa);
+
+ if(ndpi_struct->impossible_bigrams_automa.ac_automa != NULL)
+ ac_automata_release((AC_AUTOMATA_t*)ndpi_struct->impossible_bigrams_automa.ac_automa);
+
+ ndpi_free(ndpi_struct);
+ }
+}
+
+/* ****************************************************** */
+
+int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t protocol_id,
+ u_int16_t** tcp_master_proto,
+ u_int16_t** udp_master_proto) {
+ if(protocol_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) {
+ *tcp_master_proto = *udp_master_proto = NDPI_PROTOCOL_UNKNOWN;
+ return(-1);
+ }
+
+ *tcp_master_proto = ndpi_struct->proto_defaults[protocol_id].master_tcp_protoId,
+ *udp_master_proto = ndpi_struct->proto_defaults[protocol_id].master_udp_protoId;
+
+ return(0);
+}
+
+/* ****************************************************** */
+
+u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int8_t proto, u_int16_t sport, u_int16_t dport) {
+ const void *ret;
+ ndpi_default_ports_tree_node_t node;
+
+ if(sport && dport) {
+ node.default_port = sport;
+ ret = ndpi_tfind(&node,
+ (proto == IPPROTO_TCP) ? (void*)&ndpi_struct->tcpRoot : (void*)&ndpi_struct->udpRoot,
+ ndpi_default_ports_tree_node_t_cmp);
+
+ if(ret == NULL) {
+ node.default_port = dport;
+ ret = ndpi_tfind(&node,
+ (proto == IPPROTO_TCP) ? (void*)&ndpi_struct->tcpRoot : (void*)&ndpi_struct->udpRoot,
+ ndpi_default_ports_tree_node_t_cmp);
+ }
+
+ if(ret != NULL) {
+ ndpi_default_ports_tree_node_t *found = *(ndpi_default_ports_tree_node_t**)ret;
+
+ return(found->proto->protoId);
+ }
+ } else {
+ /* No TCP/UDP */
+
+ switch(proto) {
+ case NDPI_IPSEC_PROTOCOL_ESP:
+ case NDPI_IPSEC_PROTOCOL_AH:
+ return(NDPI_PROTOCOL_IP_IPSEC);
+ break;
+ case NDPI_GRE_PROTOCOL_TYPE:
+ return(NDPI_PROTOCOL_IP_GRE);
+ break;
+ case NDPI_ICMP_PROTOCOL_TYPE:
+ return(NDPI_PROTOCOL_IP_ICMP);
+ break;
+ case NDPI_IGMP_PROTOCOL_TYPE:
+ return(NDPI_PROTOCOL_IP_IGMP);
+ break;
+ case NDPI_EGP_PROTOCOL_TYPE:
+ return(NDPI_PROTOCOL_IP_EGP);
+ break;
+ case NDPI_SCTP_PROTOCOL_TYPE:
+ return(NDPI_PROTOCOL_IP_SCTP);
+ break;
+ case NDPI_OSPF_PROTOCOL_TYPE:
+ return(NDPI_PROTOCOL_IP_OSPF);
+ break;
+ case NDPI_IPIP_PROTOCOL_TYPE:
+ return(NDPI_PROTOCOL_IP_IP_IN_IP);
+ break;
+ case NDPI_ICMPV6_PROTOCOL_TYPE:
+ return(NDPI_PROTOCOL_IP_ICMPV6);
+ break;
+ case 112:
+ return(NDPI_PROTOCOL_IP_VRRP);
+ break;
+ }
+ }
+
+ return(NDPI_PROTOCOL_UNKNOWN);
+}
+
+/* ******************************************************************** */
+
+#if 0
+#ifndef __KERNEL__
+static int add_proto_default_port(u_int16_t **ports, u_int16_t new_port,
+ ndpi_proto_defaults_t *def,
+ ndpi_default_ports_tree_node_t *root) {
+ u_int num_ports, i;
+
+ if(*ports == NULL) {
+ ndpi_port_range range = { new_port, new_port };
+
+ addDefaultPort(&range, def, &root);
+ return(0);
+ }
+
+ for(num_ports=0; (*ports)[num_ports] != 0; num_ports++)
+ ;
+
+ if(num_ports >= MAX_DEFAULT_PORTS) {
+ printf("Too many ports defined: ignored port %d\n", new_port);
+ return(-1);
+ } else {
+ u_int16_t *new_ports = (u_int16_t*)ndpi_malloc(num_ports+1);
+ ndpi_port_range range;
+
+ if(new_ports == NULL) {
+ printf("Not enough memory\n");
+ return(-2);
+ }
+
+ for(i=0; i<num_ports; i++)
+ new_ports[i] = (*ports)[i];
+
+ new_ports[i++] = new_port;
+ new_ports[i++] = 0;
+
+ ndpi_free(*ports);
+ *ports = new_ports;
+
+ range.port_low = range.port_high = new_port;
+ addDefaultPort(&range, def, &root);
+ return(0);
+ }
+}
+#endif
+#endif
+
+/* ******************************************************************** */
+
+u_int ndpi_get_num_supported_protocols(struct ndpi_detection_module_struct *ndpi_mod) {
+ return(ndpi_mod->ndpi_num_supported_protocols);
+}
+
+/* ******************************************************************** */
+
+int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_mod, char* rule, u_int8_t do_add) {
+ char *at, *proto, *elem;
+ ndpi_proto_defaults_t *def;
+ int subprotocol_id, i;
+
+ at = strrchr(rule, '@');
+ if(at == NULL) {
+ printf("Invalid rule '%s'\n", rule);
+ return(-1);
+ } else
+ at[0] = 0, proto = &at[1];
+
+ for(i=0, def = NULL; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++) {
+ if(strcasecmp(ndpi_mod->proto_defaults[i].protoName, proto) == 0) {
+ def = &ndpi_mod->proto_defaults[i];
+ subprotocol_id = i;
+ break;
+ }
+ }
+
+ if(def == NULL) {
+ if(!do_add) {
+ /* We need to remove a rule */
+ printf("Unable to find protocol '%s': skipping rule '%s'\n", proto, rule);
+ return(-3);
+ } else {
+ ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS];
+ u_int16_t no_master[2] = { NDPI_PROTOCOL_NO_MASTER_PROTO, NDPI_PROTOCOL_NO_MASTER_PROTO };
+
+ if(ndpi_mod->ndpi_num_custom_protocols >= (NDPI_MAX_NUM_CUSTOM_PROTOCOLS-1)) {
+ printf("Too many protocols defined (%u): skipping protocol %s\n",
+ ndpi_mod->ndpi_num_custom_protocols, proto);
+ return(-2);
+ }
+
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE,
+ ndpi_mod->ndpi_num_supported_protocols,
+ no_master,
+ no_master,
+ ndpi_strdup(proto),
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ def = &ndpi_mod->proto_defaults[ndpi_mod->ndpi_num_supported_protocols];
+ subprotocol_id = ndpi_mod->ndpi_num_supported_protocols;
+ ndpi_mod->ndpi_num_supported_protocols++, ndpi_mod->ndpi_num_custom_protocols++;
+ }
+ }
+
+ while((elem = strsep(&rule, ",")) != NULL) {
+ char *attr = elem, *value = NULL;
+ ndpi_port_range range;
+ int is_tcp = 0, is_udp = 0;
+
+ if(strncmp(attr, "tcp:", 4) == 0)
+ is_tcp = 1, value = &attr[4];
+ else if(strncmp(attr, "udp:", 4) == 0)
+ is_udp = 1, value = &attr[4];
+ else if(strncmp(attr, "host:", 5) == 0) {
+ /* host:"<value>",host:"<value>",.....@<subproto> */
+ value = &attr[5];
+ if(value[0] == '"') value++; /* remove leading " */
+ if(value[strlen(value)-1] == '"') value[strlen(value)-1] = '\0'; /* remove trailing " */
+ }
+
+ if(is_tcp || is_udp) {
+ if(sscanf(value, "%u-%u", (unsigned int *)&range.port_low, (unsigned int *)&range.port_high) != 2)
+ range.port_low = range.port_high = atoi(&elem[4]);
+ if(do_add)
+ addDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot);
+ else
+ removeDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot);
+ } else {
+ if(do_add)
+ ndpi_add_host_url_subprotocol(ndpi_mod, value, subprotocol_id, NDPI_PROTOCOL_ACCEPTABLE);
+ else
+ ndpi_remove_host_url_subprotocol(ndpi_mod, value, subprotocol_id);
+ }
+ }
+
+ return(0);
+}
+
+/* ******************************************************************** */
+
+/*
+ Format:
+ <tcp|udp>:<port>,<tcp|udp>:<port>,.....@<proto>
+
+ Example:
+ tcp:80,tcp:3128@HTTP
+ udp:139@NETBIOS
+
+*/
+int ndpi_load_protocols_file(struct ndpi_detection_module_struct *ndpi_mod, char* path) {
+#ifdef __KERNEL__
+ return(0);
+#else
+ FILE *fd = fopen(path, "r");
+ int i;
+
+ if(fd == NULL) {
+ printf("Unable to open file %s [%s]", path, strerror(errno));
+ return(-1);
+ }
+
+ while(fd) {
+ char buffer[512], *line;
+
+ if(!(line = fgets(buffer, sizeof(buffer), fd)))
+ break;
+
+ if(((i = strlen(line)) <= 1) || (line[0] == '#'))
+ continue;
+ else
+ line[i-1] = '\0';
+
+ ndpi_handle_rule(ndpi_mod, line, 1);
+ }
+
+ fclose(fd);
+
+#if 0
+ printf("\nTCP:\n");
+ ndpi_twalk(ndpi_mod->tcpRoot, ndpi_default_ports_tree_node_t_walker, NULL);
+ printf("\nUDP:\n");
+ ndpi_twalk(ndpi_mod->udpRoot, ndpi_default_ports_tree_node_t_walker, NULL);
+#endif
+#endif
+
+ return(0);
+}
+
+/* ntop */
+void ndpi_set_bitmask_protocol_detection( char * label,
+ struct ndpi_detection_module_struct *ndpi_struct,
+ const NDPI_PROTOCOL_BITMASK * detection_bitmask,
+ const u_int32_t idx,
+ u_int16_t ndpi_protocol_id,
+ void (*func) (struct ndpi_detection_module_struct *, struct ndpi_flow_struct *flow),
+ const NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_bitmask,
+ u_int8_t b_save_bitmask_unknow,
+ u_int8_t b_add_detection_bitmask)
+{
+ /*
+ Compare specify protocol bitmask with main detection bitmask
+ */
+ if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(*detection_bitmask, ndpi_protocol_id) != 0) {
+ // #ifdef DEBUG
+ NDPI_LOG(0, ndpi_struct, NDPI_LOG_DEBUG,"[NDPI] ndpi_set_bitmask_protocol_detection: %s : [callback_buffer] idx= %u, [proto_defaults] protocol_id=%u\n", label, idx, ndpi_protocol_id);
+ // #endif
+ /*
+ Set funcition and index protocol within proto_default strcuture for port protocol detection
+ and callback_buffer function for DPI protocol detection
+ */
+ ndpi_struct->proto_defaults[ndpi_protocol_id].protoIdx = idx;
+
+ ndpi_struct->proto_defaults[ndpi_protocol_id].func =
+ ndpi_struct->callback_buffer[idx].func = func;
+ /*
+ Set ndpi_selection_bitmask for protocol
+ */
+ ndpi_struct->callback_buffer[idx].ndpi_selection_bitmask = ndpi_selection_bitmask;
+
+ /*
+ Reset protocol detection bitmask via NDPI_PROTOCOL_UNKNOWN and than add specify protocol bitmast to callback
+ buffer.
+ */
+ if (b_save_bitmask_unknow) NDPI_SAVE_AS_BITMASK(ndpi_struct->callback_buffer[idx].detection_bitmask, NDPI_PROTOCOL_UNKNOWN);
+ if (b_add_detection_bitmask) NDPI_ADD_PROTOCOL_TO_BITMASK(ndpi_struct->callback_buffer[idx].detection_bitmask, ndpi_protocol_id);
+
+ NDPI_SAVE_AS_BITMASK(ndpi_struct->callback_buffer[idx].excluded_protocol_bitmask, ndpi_protocol_id);
+ }
+}
+
+/* ******************************************************************** */
+
+void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *ndpi_struct,
+ const NDPI_PROTOCOL_BITMASK * dbm)
+{
+ NDPI_PROTOCOL_BITMASK detection_bitmask_local;
+ NDPI_PROTOCOL_BITMASK *detection_bitmask = &detection_bitmask_local;
+ u_int32_t a = 0;
+
+ NDPI_BITMASK_SET(detection_bitmask_local, *dbm);
+ NDPI_BITMASK_SET(ndpi_struct->detection_bitmask, *dbm);
+
+ /* set this here to zero to be interrupt safe */
+ ndpi_struct->callback_buffer_size = 0;
+
+
+#ifdef NDPI_PROTOCOL_HTTP
+ ndpi_set_bitmask_protocol_detection("HTTP",ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_HTTP,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ ndpi_set_bitmask_protocol_detection("HTTP_PROXY", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_HTTP_PROXY,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+#ifdef NDPI_CONTENT_MPEG
+ ndpi_set_bitmask_protocol_detection("MPEG", ndpi_struct, detection_bitmask, a++,
+ NDPI_CONTENT_MPEG,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_CONTENT_FLASH
+ ndpi_set_bitmask_protocol_detection("FLASH", ndpi_struct, detection_bitmask, a++,
+ NDPI_CONTENT_FLASH,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_CONTENT_QUICKTIME
+ ndpi_set_bitmask_protocol_detection("QUICKTIME", ndpi_struct, detection_bitmask, a++,
+ NDPI_CONTENT_QUICKTIME,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_CONTENT_REALMEDIA
+ ndpi_set_bitmask_protocol_detection("REALMEDIA", ndpi_struct, detection_bitmask, a++,
+ NDPI_CONTENT_REALMEDIA,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_CONTENT_WINDOWSMEDIA
+ ndpi_set_bitmask_protocol_detection("WINDOWSMEDIA", ndpi_struct, detection_bitmask, a++,
+ NDPI_CONTENT_WINDOWSMEDIA,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_CONTENT_MMS
+ ndpi_set_bitmask_protocol_detection("MMS", ndpi_struct, detection_bitmask, a++,
+ NDPI_CONTENT_MMS,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_XBOX
+ ndpi_set_bitmask_protocol_detection("XBOX", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_XBOX,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_WINDOWS_UPDATE
+ ndpi_set_bitmask_protocol_detection("WINDOWS_UPDATE", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_WINDOWS_UPDATE,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_QQ
+ ndpi_set_bitmask_protocol_detection("QQ", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_QQ,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_CONTENT_AVI
+ ndpi_set_bitmask_protocol_detection("AVI", ndpi_struct, detection_bitmask, a++,
+ NDPI_CONTENT_AVI,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_CONTENT_OGG
+ ndpi_set_bitmask_protocol_detection("OGG", ndpi_struct, detection_bitmask, a++,
+ NDPI_CONTENT_OGG,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_MOVE
+ ndpi_set_bitmask_protocol_detection("MOVE", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_MOVE,
+ ndpi_search_http_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+ /*Update excluded protocol bitmask*/
+ NDPI_BITMASK_SET(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask,
+ ndpi_struct->callback_buffer[a].detection_bitmask);
+
+ /*Delete protocol from exluded protocol bitmask*/
+ NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask,
+ NDPI_PROTOCOL_UNKNOWN);
+
+ NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask,
+ NDPI_PROTOCOL_QQ);
+
+#ifdef NDPI_CONTENT_FLASH
+ NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask,
+ NDPI_CONTENT_FLASH);
+#endif
+
+ NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask,
+ NDPI_CONTENT_MMS);
+ // #ifdef NDPI_PROTOCOL_RTSP
+ // NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask,
+ // NDPI_PROTOCOL_RTSP);
+ // #endif
+ NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask,
+ NDPI_PROTOCOL_XBOX);
+
+ NDPI_BITMASK_SET(ndpi_struct->generic_http_packet_bitmask,
+ ndpi_struct->callback_buffer[a].detection_bitmask);
+
+ NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->generic_http_packet_bitmask, NDPI_PROTOCOL_UNKNOWN);
+
+ /* Update callback_buffer index */
+ a++;
+#endif
+
+
+#ifdef NDPI_PROTOCOL_SSL
+ ndpi_set_bitmask_protocol_detection("SSL", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_SSL,
+ ndpi_search_ssl_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+
+#ifdef NDPI_PROTOCOL_STUN
+ ndpi_set_bitmask_protocol_detection("STUN", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_STUN,
+ ndpi_search_stun,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_RTP
+ ndpi_set_bitmask_protocol_detection("RTP", ndpi_struct, detection_bitmask,a,
+ NDPI_PROTOCOL_RTP,
+ ndpi_search_rtp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+ /* consider also real protocol for detection select in main loop */
+ ndpi_struct->callback_buffer[a].detection_feature = NDPI_SELECT_DETECTION_WITH_REAL_PROTOCOL;
+ /* Update callback_buffer index */
+ a++;
+#endif
+
+#ifdef NDPI_PROTOCOL_RTSP
+ ndpi_set_bitmask_protocol_detection("RTSP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_RTSP,
+ ndpi_search_rtsp_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_RDP
+ ndpi_set_bitmask_protocol_detection("RDP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_RDP,
+ ndpi_search_rdp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_SIP
+ ndpi_set_bitmask_protocol_detection("SIP", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_SIP,
+ ndpi_search_sip,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,/* Fix courtesy of Miguel Quesada <mquesadab@gmail.com> */
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_BITTORRENT
+ ndpi_set_bitmask_protocol_detection("BITTORRENT", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_BITTORRENT,
+ ndpi_search_bittorrent,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_EDONKEY
+ ndpi_set_bitmask_protocol_detection("EDONKEY", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_EDONKEY,
+ ndpi_search_edonkey,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_FASTTRACK
+ ndpi_set_bitmask_protocol_detection("FASTTRACK", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_FASTTRACK,
+ ndpi_search_fasttrack_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_GNUTELLA
+ ndpi_set_bitmask_protocol_detection("GNUTELLA", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_GNUTELLA,
+ ndpi_search_gnutella,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_WINMX
+ ndpi_set_bitmask_protocol_detection("WINMX", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_WINMX,
+ ndpi_search_winmx_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_DIRECTCONNECT
+ ndpi_set_bitmask_protocol_detection("DIRECTCONNECT", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_DIRECTCONNECT,
+ ndpi_search_directconnect,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_MSN
+
+ NDPI_BITMASK_RESET(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask);
+
+ ndpi_set_bitmask_protocol_detection("MSN", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_MSN,
+ ndpi_search_msn,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_YAHOO
+ ndpi_set_bitmask_protocol_detection("YAHOO", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_YAHOO,
+ ndpi_search_yahoo,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_OSCAR
+ ndpi_set_bitmask_protocol_detection("OSCAR", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_OSCAR,
+ ndpi_search_oscar,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_APPLEJUICE
+ ndpi_set_bitmask_protocol_detection("APPLEJUICE", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_APPLEJUICE,
+ ndpi_search_applejuice_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_SOULSEEK
+ ndpi_set_bitmask_protocol_detection("SOULSEEK", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_SOULSEEK,
+ ndpi_search_soulseek_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_IRC
+ ndpi_set_bitmask_protocol_detection("IRC", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_IRC,
+ ndpi_search_irc_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER
+ ndpi_set_bitmask_protocol_detection("UNENCRYPED_JABBER", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_UNENCRYPED_JABBER,
+ ndpi_search_jabber_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_MAIL_POP
+ ndpi_set_bitmask_protocol_detection("MAIL_POP", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_MAIL_POP,
+ ndpi_search_mail_pop_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_MAIL_IMAP
+ ndpi_set_bitmask_protocol_detection("MAIL_IMAP", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_MAIL_IMAP,
+ ndpi_search_mail_imap_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_MAIL_SMTP
+ ndpi_set_bitmask_protocol_detection("MAIL_SMTP", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_MAIL_SMTP,
+ ndpi_search_mail_smtp_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_USENET
+ ndpi_set_bitmask_protocol_detection("USENET", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_USENET,
+ ndpi_search_usenet_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_DNS
+ ndpi_set_bitmask_protocol_detection("DNS", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_DNS,
+ ndpi_search_dns,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_FILETOPIA
+ ndpi_set_bitmask_protocol_detection("FILETOPIA", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_FILETOPIA,
+ ndpi_search_filetopia_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_VMWARE
+ ndpi_set_bitmask_protocol_detection("VMWARE", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_VMWARE,
+ ndpi_search_vmware,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_IMESH
+ ndpi_set_bitmask_protocol_detection("IMESH", ndpi_struct, detection_bitmask,a++,
+ NDPI_PROTOCOL_IMESH,
+ ndpi_search_imesh_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_CONTENT_MMS
+ ndpi_set_bitmask_protocol_detection("NDPI_CONTENT_MMS", ndpi_struct, detection_bitmask,a++,
+ NDPI_CONTENT_MMS,
+ ndpi_search_mms_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#if defined(NDPI_PROTOCOL_IP_IPSEC) || defined(NDPI_PROTOCOL_IP_GRE) || defined(NDPI_PROTOCOL_IP_ICMP) || defined(NDPI_PROTOCOL_IP_IGMP) || defined(NDPI_PROTOCOL_IP_EGP) || defined(NDPI_PROTOCOL_IP_SCTP) || defined(NDPI_PROTOCOL_IP_OSPF) || defined(NDPI_PROTOCOL_IP_IP_IN_IP) || defined(NDPI_PROTOCOL_IP_ICMPV6)
+
+ /* always add non tcp/udp if one protocol is compiled in */
+ NDPI_SAVE_AS_BITMASK(ndpi_struct->callback_buffer[a].detection_bitmask, NDPI_PROTOCOL_UNKNOWN);
+
+ ndpi_set_bitmask_protocol_detection("IP_IPSEC", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_IP_IPSEC,
+ ndpi_search_in_non_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ ndpi_set_bitmask_protocol_detection("IP_GRE", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_IP_GRE,
+ ndpi_search_in_non_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ ndpi_set_bitmask_protocol_detection("IP_ICMP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_IP_ICMP,
+ ndpi_search_in_non_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ ndpi_set_bitmask_protocol_detection("IP_IGMP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_IP_IGMP,
+ ndpi_search_in_non_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ ndpi_set_bitmask_protocol_detection("IP_EGP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_IP_EGP,
+ ndpi_search_in_non_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ ndpi_set_bitmask_protocol_detection("IP_SCTP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_IP_SCTP,
+ ndpi_search_in_non_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ ndpi_set_bitmask_protocol_detection("IP_OSPF", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_IP_OSPF,
+ ndpi_search_in_non_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ ndpi_set_bitmask_protocol_detection("IP_IP_IN_IP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_IP_IP_IN_IP,
+ ndpi_search_in_non_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ ndpi_set_bitmask_protocol_detection("IP_ICMPV6", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_IP_ICMPV6,
+ ndpi_search_in_non_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6,
+ NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ // NDPI_BITMASK_RESET(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask);
+#endif
+
+
+#ifdef NDPI_PROTOCOL_TVANTS
+ ndpi_set_bitmask_protocol_detection("TVANTS", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_TVANTS,
+ ndpi_search_tvants_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_SOPCAST
+ ndpi_set_bitmask_protocol_detection("SOPCAST", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SOPCAST,
+ ndpi_search_sopcast,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_TVUPLAYER
+ ndpi_set_bitmask_protocol_detection("TVUPLAYER", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_TVUPLAYER,
+ ndpi_search_tvuplayer,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_PPSTREAM
+ ndpi_set_bitmask_protocol_detection("PPSTREAM", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_PPSTREAM,
+ ndpi_search_ppstream,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_PPLIVE
+ ndpi_set_bitmask_protocol_detection("PPLIVE", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_PPLIVE,
+ ndpi_search_pplive,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_IAX
+ ndpi_set_bitmask_protocol_detection("IAX", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_IAX,
+ ndpi_search_iax,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_MGCP
+ ndpi_set_bitmask_protocol_detection("MGCP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_MGCP,
+ ndpi_search_mgcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_ZATTOO
+ ndpi_set_bitmask_protocol_detection("ZATTOO", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_ZATTOO,
+ ndpi_search_zattoo,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_QQ
+ ndpi_set_bitmask_protocol_detection("QQ", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_QQ,
+ ndpi_search_qq,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_SSH
+ ndpi_set_bitmask_protocol_detection("SSH", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SSH,
+ ndpi_search_ssh_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_AYIYA
+ ndpi_set_bitmask_protocol_detection("AYIYA", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_AYIYA,
+ ndpi_search_ayiya,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_THUNDER
+ ndpi_set_bitmask_protocol_detection("THUNDER", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_THUNDER,
+ ndpi_search_thunder,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_VNC
+ ndpi_set_bitmask_protocol_detection("VNC", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_VNC,
+ ndpi_search_vnc_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_TEAMVIEWER
+ ndpi_set_bitmask_protocol_detection("TEAMVIEWER", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_TEAMVIEWER,
+ ndpi_search_teamview,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_DHCP
+ ndpi_set_bitmask_protocol_detection("DHCP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_DHCP,
+ ndpi_search_dhcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_SOCRATES
+ ndpi_set_bitmask_protocol_detection("SOCRATES", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SOCRATES,
+ ndpi_search_socrates,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_STEAM
+ ndpi_set_bitmask_protocol_detection("STEAM", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_STEAM,
+ ndpi_search_steam,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_HALFLIFE2
+ ndpi_set_bitmask_protocol_detection("HALFLIFE2", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_HALFLIFE2,
+ ndpi_search_halflife2,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_XBOX
+ ndpi_set_bitmask_protocol_detection("XBOX", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_XBOX,
+ ndpi_search_xbox,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC
+ ndpi_set_bitmask_protocol_detection("HTTP_APPLICATION_ACTIVESYNC", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC,
+ ndpi_search_activesync,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_SMB
+ ndpi_set_bitmask_protocol_detection("SMB", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SMB,
+ ndpi_search_smb_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_TELNET
+ ndpi_set_bitmask_protocol_detection("TELNET", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_TELNET,
+ ndpi_search_telnet_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_NTP
+ ndpi_set_bitmask_protocol_detection("NTP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_NTP,
+ ndpi_search_ntp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_NFS
+ ndpi_set_bitmask_protocol_detection("NFS", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_NFS,
+ ndpi_search_nfs,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_SSDP
+ ndpi_set_bitmask_protocol_detection("SSDP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SSDP,
+ ndpi_search_ssdp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_WORLDOFWARCRAFT
+ ndpi_set_bitmask_protocol_detection("WORLDOFWARCRAFT", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_WORLDOFWARCRAFT,
+ ndpi_search_worldofwarcraft,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_POSTGRES
+ ndpi_set_bitmask_protocol_detection("POSTGRES", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_POSTGRES,
+ ndpi_search_postgres_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_MYSQL
+ ndpi_set_bitmask_protocol_detection("MYSQL", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_MYSQL,
+ ndpi_search_mysql_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_BGP
+ ndpi_set_bitmask_protocol_detection("BGP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_BGP,
+ ndpi_search_bgp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_QUAKE
+ ndpi_set_bitmask_protocol_detection("QUAKE", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_QUAKE,
+ ndpi_search_quake,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_BATTLEFIELD
+ ndpi_set_bitmask_protocol_detection("BATTLEFIELD", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_BATTLEFIELD,
+ ndpi_search_battlefield,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_PCANYWHERE
+ ndpi_set_bitmask_protocol_detection("PCANYWHERE", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_PCANYWHERE,
+ ndpi_search_pcanywhere,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_SNMP
+ ndpi_set_bitmask_protocol_detection("SNMP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SNMP,
+ ndpi_search_snmp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_KONTIKI
+ ndpi_set_bitmask_protocol_detection("KONTIKI", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_KONTIKI,
+ ndpi_search_kontiki,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_ICECAST
+ ndpi_set_bitmask_protocol_detection("ICECAST", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_ICECAST,
+ ndpi_search_icecast_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_SHOUTCAST
+ ndpi_set_bitmask_protocol_detection("SHOUTCAST", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SHOUTCAST,
+ ndpi_search_shoutcast_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV
+ ndpi_set_bitmask_protocol_detection("HTTP_APPLICATION_VEOHTV", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV,
+ ndpi_search_veohtv_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_KERBEROS
+ ndpi_set_bitmask_protocol_detection("KERBEROS", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_KERBEROS,
+ ndpi_search_kerberos,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_OPENFT
+ ndpi_set_bitmask_protocol_detection("OPENFT", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_OPENFT,
+ ndpi_search_openft_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_SYSLOG
+ ndpi_set_bitmask_protocol_detection("SYSLOG", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SYSLOG,
+ ndpi_search_syslog,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_TDS
+ ndpi_set_bitmask_protocol_detection("TDS", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_TDS,
+ ndpi_search_tds_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK
+ ndpi_set_bitmask_protocol_detection("DIRECT_DOWNLOAD_LINK", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK,
+ ndpi_search_direct_download_link_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_NETBIOS
+ ndpi_set_bitmask_protocol_detection("NETBIOS", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_NETBIOS,
+ ndpi_search_netbios,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_MDNS
+ ndpi_set_bitmask_protocol_detection("MDNS", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_MDNS,
+ ndpi_search_mdns,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_IPP
+ ndpi_set_bitmask_protocol_detection("IPP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_IPP,
+ ndpi_search_ipp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_LDAP
+ ndpi_set_bitmask_protocol_detection("LDAP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_LDAP,
+ ndpi_search_ldap,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_WARCRAFT3
+ ndpi_set_bitmask_protocol_detection("WARCRAFT3", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_WARCRAFT3,
+ ndpi_search_warcraft3,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_XDMCP
+ ndpi_set_bitmask_protocol_detection("XDMCP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_XDMCP,
+ ndpi_search_xdmcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_TFTP
+ ndpi_set_bitmask_protocol_detection("TFTP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_TFTP,
+ ndpi_search_tftp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_MSSQL
+ ndpi_set_bitmask_protocol_detection("MSSQL", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_MSSQL,
+ ndpi_search_mssql,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_PPTP
+ ndpi_set_bitmask_protocol_detection("PPTP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_PPTP,
+ ndpi_search_pptp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_STEALTHNET
+ ndpi_set_bitmask_protocol_detection("STEALTHNET", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_STEALTHNET,
+ ndpi_search_stealthnet,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_DHCPV6
+ ndpi_set_bitmask_protocol_detection("DHCPV6", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_DHCPV6,
+ ndpi_search_dhcpv6_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_MEEBO
+ ndpi_set_bitmask_protocol_detection("Meebo", ndpi_struct, detection_bitmask, a,
+ NDPI_PROTOCOL_MEEBO,
+ ndpi_search_meebo,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+ /* Add protocol bitmask dependencies to detected bitmask*/
+#ifdef NDPI_CONTENT_FLASH
+ NDPI_ADD_PROTOCOL_TO_BITMASK(ndpi_struct->callback_buffer[a].detection_bitmask, NDPI_CONTENT_FLASH);
+#endif
+ a++;
+#endif
+
+#ifdef NDPI_PROTOCOL_AFP
+ ndpi_set_bitmask_protocol_detection("AFP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_AFP,
+ ndpi_search_afp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_AIMINI
+ ndpi_set_bitmask_protocol_detection("AIMINI", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_AIMINI,
+ ndpi_search_aimini,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_FLORENSIA
+ ndpi_set_bitmask_protocol_detection("FLORENSIA", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_FLORENSIA,
+ ndpi_search_florensia,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_MAPLESTORY
+ ndpi_set_bitmask_protocol_detection("MAPLESTORY", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_MAPLESTORY,
+ ndpi_search_maplestory,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_DOFUS
+ ndpi_set_bitmask_protocol_detection("DOFUS", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_DOFUS,
+ ndpi_search_dofus,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_WORLD_OF_KUNG_FU
+ ndpi_set_bitmask_protocol_detection("WORLD_OF_KUNG_FU", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_WORLD_OF_KUNG_FU,
+ ndpi_search_world_of_kung_fu,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_FIESTA
+ ndpi_set_bitmask_protocol_detection("FIESTA", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_FIESTA,
+ ndpi_search_fiesta,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_CROSSFIRE
+ ndpi_set_bitmask_protocol_detection("CROSSFIRE", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_CROSSFIRE,
+ ndpi_search_crossfire_tcp_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_GUILDWARS
+ ndpi_set_bitmask_protocol_detection("GUILDWARS", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_GUILDWARS,
+ ndpi_search_guildwars_tcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+#ifdef NDPI_PROTOCOL_ARMAGETRON
+ ndpi_set_bitmask_protocol_detection("ARMAGETRON", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_ARMAGETRON,
+ ndpi_search_armagetron_udp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_DROPBOX
+ ndpi_set_bitmask_protocol_detection("DROPBOX", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_DROPBOX,
+ ndpi_search_dropbox,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_SPOTIFY
+ ndpi_set_bitmask_protocol_detection("SPOTIFY", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SPOTIFY,
+ ndpi_search_spotify,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_SKYPE
+ ndpi_set_bitmask_protocol_detection("SKYPE", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SKYPE,
+ ndpi_search_skype,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_RADIUS
+ ndpi_set_bitmask_protocol_detection("RADIUS", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_RADIUS,
+ ndpi_search_radius,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_CITRIX
+ ndpi_set_bitmask_protocol_detection("CITRIX", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_CITRIX,
+ ndpi_search_citrix,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_LOTUS_NOTES
+ ndpi_set_bitmask_protocol_detection("LOTUS_NOTES", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_LOTUS_NOTES,
+ ndpi_search_lotus_notes,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_GTP
+ ndpi_set_bitmask_protocol_detection("GTP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_GTP,
+ ndpi_search_gtp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_DCERPC
+ ndpi_set_bitmask_protocol_detection("DCERPC", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_DCERPC,
+ ndpi_search_dcerpc,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_NETFLOW
+ ndpi_set_bitmask_protocol_detection("NETFLOW", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_NETFLOW,
+ ndpi_search_netflow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_SFLOW
+ ndpi_set_bitmask_protocol_detection("SFLOW", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SFLOW,
+ ndpi_search_sflow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_H323
+ ndpi_set_bitmask_protocol_detection("H323", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_H323,
+ ndpi_search_h323,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_OPENVPN
+ ndpi_set_bitmask_protocol_detection("OPENVPN", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_OPENVPN,
+ ndpi_search_openvpn,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_NOE
+ ndpi_set_bitmask_protocol_detection("NOE", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_NOE,
+ ndpi_search_noe,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_CISCOVPN
+ ndpi_set_bitmask_protocol_detection("CISCOVPN", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_CISCOVPN,
+ ndpi_search_ciscovpn,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_TEAMSPEAK
+ ndpi_set_bitmask_protocol_detection("TEAMSPEAK", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_TEAMSPEAK,
+ ndpi_search_teamspeak,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_VIBER
+ ndpi_set_bitmask_protocol_detection("VIBER", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_VIBER,
+ ndpi_search_viber,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_TOR
+ ndpi_set_bitmask_protocol_detection("TOR", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_TOR,
+ ndpi_search_tor,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_SKINNY
+ ndpi_set_bitmask_protocol_detection("SKINNY", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_SKINNY,
+ ndpi_search_skinny,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_RTCP
+ ndpi_set_bitmask_protocol_detection("RTCP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_RTCP,
+ ndpi_search_rtcp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_RSYNC
+ ndpi_set_bitmask_protocol_detection("RSYNC", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_RSYNC,
+ ndpi_search_rsync,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_WHOIS_DAS
+ ndpi_set_bitmask_protocol_detection("WHOIS_DAS", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_WHOIS_DAS,
+ ndpi_search_whois_das,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_ORACLE
+ ndpi_set_bitmask_protocol_detection("ORACLE", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_ORACLE,
+ ndpi_search_oracle,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_CORBA
+ ndpi_set_bitmask_protocol_detection("CORBA", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_CORBA,
+ ndpi_search_corba,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_RTMP
+ ndpi_set_bitmask_protocol_detection("RTMP", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_RTMP,
+ ndpi_search_rtmp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_FTP_CONTROL
+ ndpi_set_bitmask_protocol_detection("FTP_CONTROL", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_FTP_CONTROL,
+ ndpi_search_ftp_control,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_FTP_DATA
+ ndpi_set_bitmask_protocol_detection("FTP_DATA", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_FTP_DATA,
+ ndpi_search_ftp_data,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_PANDO
+ ndpi_set_bitmask_protocol_detection("PANDO", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_PANDO,
+ ndpi_search_pando,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_MEGACO
+ ndpi_set_bitmask_protocol_detection("MEGACO", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_MEGACO,
+ ndpi_search_megaco,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_REDIS
+ ndpi_set_bitmask_protocol_detection("REDIS", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_REDIS,
+ ndpi_search_redis,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_VHUA
+ ndpi_set_bitmask_protocol_detection("VHUA", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_VHUA,
+ ndpi_search_vhua,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_ZMQ
+ ndpi_set_bitmask_protocol_detection("ZMQ", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_ZMQ,
+ ndpi_search_zmq, /* TODO: add UDP support */
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+
+#ifdef NDPI_SERVICE_TWITTER
+ ndpi_set_bitmask_protocol_detection("TWITTER", ndpi_struct, detection_bitmask, a++,
+ NDPI_SERVICE_TWITTER,
+ ndpi_search_twitter,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+#ifdef NDPI_PROTOCOL_TELEGRAM
+ ndpi_set_bitmask_protocol_detection("TELEGRAM", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_TELEGRAM,
+ ndpi_search_telegram,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
+ ndpi_struct->callback_buffer_size = a;
+
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG,
+ "callback_buffer_size is %u\n", ndpi_struct->callback_buffer_size);
+
+ /* now build the specific buffer for tcp, udp and non_tcp_udp */
+ ndpi_struct->callback_buffer_size_tcp_payload = 0;
+ ndpi_struct->callback_buffer_size_tcp_no_payload = 0;
+ for (a = 0; a < ndpi_struct->callback_buffer_size; a++) {
+ if((ndpi_struct->callback_buffer[a].ndpi_selection_bitmask
+ & (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP |
+ NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP |
+ NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC)) != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG,
+ "callback_buffer_tcp_payload, adding buffer %u as entry %u\n", a,
+ ndpi_struct->callback_buffer_size_tcp_payload);
+
+ memcpy(&ndpi_struct->callback_buffer_tcp_payload[ndpi_struct->callback_buffer_size_tcp_payload],
+ &ndpi_struct->callback_buffer[a], sizeof(struct ndpi_call_function_struct));
+ ndpi_struct->callback_buffer_size_tcp_payload++;
+
+ if((ndpi_struct->
+ callback_buffer[a].ndpi_selection_bitmask & NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG,
+ "\tcallback_buffer_tcp_no_payload, additional adding buffer %u to no_payload process\n", a);
+
+ memcpy(&ndpi_struct->callback_buffer_tcp_no_payload
+ [ndpi_struct->callback_buffer_size_tcp_no_payload], &ndpi_struct->callback_buffer[a],
+ sizeof(struct ndpi_call_function_struct));
+ ndpi_struct->callback_buffer_size_tcp_no_payload++;
+ }
+ }
+ }
+
+ ndpi_struct->callback_buffer_size_udp = 0;
+ for (a = 0; a < ndpi_struct->callback_buffer_size; a++) {
+ if((ndpi_struct->callback_buffer[a].ndpi_selection_bitmask & (NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP |
+ NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP |
+ NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC))
+ != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG,
+ "callback_buffer_size_udp: adding buffer : %u as entry %u\n", a, ndpi_struct->callback_buffer_size_udp);
+
+ memcpy(&ndpi_struct->callback_buffer_udp[ndpi_struct->callback_buffer_size_udp],
+ &ndpi_struct->callback_buffer[a], sizeof(struct ndpi_call_function_struct));
+ ndpi_struct->callback_buffer_size_udp++;
+ }
+ }
+
+ ndpi_struct->callback_buffer_size_non_tcp_udp = 0;
+ for (a = 0; a < ndpi_struct->callback_buffer_size; a++) {
+ if((ndpi_struct->callback_buffer[a].ndpi_selection_bitmask & (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP |
+ NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP |
+ NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP))
+ == 0
+ || (ndpi_struct->
+ callback_buffer[a].ndpi_selection_bitmask & NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC) != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG,
+ "callback_buffer_non_tcp_udp: adding buffer : %u as entry %u\n", a, ndpi_struct->callback_buffer_size_non_tcp_udp);
+
+ memcpy(&ndpi_struct->callback_buffer_non_tcp_udp[ndpi_struct->callback_buffer_size_non_tcp_udp],
+ &ndpi_struct->callback_buffer[a], sizeof(struct ndpi_call_function_struct));
+ ndpi_struct->callback_buffer_size_non_tcp_udp++;
+ }
+ }
+}
+
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+/* handle extension headers in IPv6 packets
+ * arguments:
+ * l4ptr: pointer to the byte following the initial IPv6 header
+ * l4len: the length of the IPv6 packet excluding the IPv6 header
+ * nxt_hdr: next header value from the IPv6 header
+ * result:
+ * l4ptr: pointer to the start of the actual packet payload
+ * l4len: length of the actual payload
+ * nxt_hdr: protocol of the actual payload
+ * returns 0 upon success and 1 upon failure
+ */
+static int ndpi_handle_ipv6_extension_headers(struct ndpi_detection_module_struct *ndpi_struct,
+ const u_int8_t ** l4ptr, u_int16_t * l4len, u_int8_t * nxt_hdr)
+{
+ while ((*nxt_hdr == 0 || *nxt_hdr == 43 || *nxt_hdr == 44 || *nxt_hdr == 60 || *nxt_hdr == 135 || *nxt_hdr == 59)) {
+ u_int16_t ehdr_len;
+
+ // no next header
+ if(*nxt_hdr == 59) {
+ return 1;
+ }
+ // fragment extension header has fixed size of 8 bytes and the first byte is the next header type
+ if(*nxt_hdr == 44) {
+ if(*l4len < 8) {
+ return 1;
+ }
+ *nxt_hdr = (*l4ptr)[0];
+ *l4len -= 8;
+ (*l4ptr) += 8;
+ continue;
+ }
+ // the other extension headers have one byte for the next header type
+ // and one byte for the extension header length in 8 byte steps minus the first 8 bytes
+ ehdr_len = (*l4ptr)[1];
+ ehdr_len *= 8;
+ ehdr_len += 8;
+
+ if(*l4len < ehdr_len) {
+ return 1;
+ }
+ *nxt_hdr = (*l4ptr)[0];
+ *l4len -= ehdr_len;
+ (*l4ptr) += ehdr_len;
+ }
+ return 0;
+}
+#endif /* NDPI_DETECTION_SUPPORT_IPV6 */
+
+
+static u_int8_t ndpi_iph_is_valid_and_not_fragmented(const struct ndpi_iphdr *iph, const u_int16_t ipsize)
+{
+ //#ifdef REQUIRE_FULL_PACKETS
+ if(ipsize < iph->ihl * 4 ||
+ ipsize < ntohs(iph->tot_len) || ntohs(iph->tot_len) < iph->ihl * 4 || (iph->frag_off & htons(0x1FFF)) != 0) {
+ return 0;
+ }
+ //#endif
+
+ return 1;
+}
+
+static u_int8_t ndpi_detection_get_l4_internal(struct ndpi_detection_module_struct *ndpi_struct,
+ const u_int8_t * l3, u_int16_t l3_len, const u_int8_t ** l4_return, u_int16_t * l4_len_return,
+ u_int8_t * l4_protocol_return, u_int32_t flags)
+{
+ const struct ndpi_iphdr *iph = NULL;
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ const struct ndpi_ipv6hdr *iph_v6 = NULL;
+#endif
+ u_int16_t l4len = 0;
+ const u_int8_t *l4ptr = NULL;
+ u_int8_t l4protocol = 0;
+
+ if(l3 == NULL || l3_len < sizeof(struct ndpi_iphdr))
+ return 1;
+
+ iph = (const struct ndpi_iphdr *) l3;
+
+ if(iph->version == 4 && iph->ihl >= 5) {
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv4 header\n");
+ }
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ else if(iph->version == 6 && l3_len >= sizeof(struct ndpi_ipv6hdr)) {
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv6 header\n");
+ iph_v6 = (const struct ndpi_ipv6hdr *) iph;
+ iph = NULL;
+ }
+#endif
+ else {
+ return 1;
+ }
+
+ if((flags & NDPI_DETECTION_ONLY_IPV6) && iph != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv4 header found but excluded by flag\n");
+ return 1;
+ }
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ else if((flags & NDPI_DETECTION_ONLY_IPV4) && iph_v6 != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv6 header found but excluded by flag\n");
+ return 1;
+ }
+#endif
+
+ if(iph != NULL && ndpi_iph_is_valid_and_not_fragmented(iph, l3_len)) {
+ u_int16_t len = ntohs(iph->tot_len);
+ u_int16_t hlen = (iph->ihl * 4);
+
+ l4ptr = (((const u_int8_t *) iph) + iph->ihl * 4);
+
+ if(len == 0) len = l3_len;
+
+ l4len = (len > hlen) ? (len - hlen) : 0;
+ l4protocol = iph->protocol;
+ }
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ else if(iph_v6 != NULL && (l3_len - sizeof(struct ndpi_ipv6hdr)) >= ntohs(iph_v6->payload_len)) {
+ l4ptr = (((const u_int8_t *) iph_v6) + sizeof(struct ndpi_ipv6hdr));
+ l4len = ntohs(iph_v6->payload_len);
+ l4protocol = iph_v6->nexthdr;
+
+ // we need to handle IPv6 extension headers if present
+ if(ndpi_handle_ipv6_extension_headers(ndpi_struct, &l4ptr, &l4len, &l4protocol) != 0) {
+ return 1;
+ }
+
+ }
+#endif
+ else {
+ return 1;
+ }
+
+ if(l4_return != NULL) {
+ *l4_return = l4ptr;
+ }
+
+ if(l4_len_return != NULL) {
+ *l4_len_return = l4len;
+ }
+
+ if(l4_protocol_return != NULL) {
+ *l4_protocol_return = l4protocol;
+ }
+
+ return 0;
+}
+
+#if !defined(WIN32)
+#define ATTRIBUTE_ALWAYS_INLINE static inline
+#else
+__forceinline static
+#endif
+void ndpi_apply_flow_protocol_to_packet(struct ndpi_flow_struct *flow,
+ struct ndpi_packet_struct *packet)
+{
+ memcpy(&packet->detected_protocol_stack[0],
+ &flow->detected_protocol_stack[0], sizeof(packet->detected_protocol_stack));
+#if NDPI_PROTOCOL_HISTORY_SIZE > 1
+ memcpy(&packet->protocol_stack_info, &flow->protocol_stack_info, sizeof(packet->protocol_stack_info));
+#endif
+}
+
+static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ unsigned short packetlen)
+{
+ const struct ndpi_iphdr *decaps_iph = NULL;
+ u_int16_t l3len;
+ u_int16_t l4len;
+ const u_int8_t *l4ptr;
+ u_int8_t l4protocol;
+ u_int8_t l4_result;
+
+ /* reset payload_packet_len, will be set if ipv4 tcp or udp */
+ flow->packet.payload_packet_len = 0;
+ flow->packet.l4_packet_len = 0;
+ flow->packet.l3_packet_len = packetlen;
+
+ flow->packet.tcp = NULL;
+ flow->packet.udp = NULL;
+ flow->packet.generic_l4_ptr = NULL;
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ flow->packet.iphv6 = NULL;
+#endif /* NDPI_DETECTION_SUPPORT_IPV6 */
+
+ if(flow) {
+ ndpi_apply_flow_protocol_to_packet(flow, &flow->packet);
+ } else {
+ ndpi_int_reset_packet_protocol(&flow->packet);
+ }
+
+ l3len = flow->packet.l3_packet_len;
+
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ if(flow->packet.iph != NULL) {
+#endif /* NDPI_DETECTION_SUPPORT_IPV6 */
+
+ decaps_iph =flow->packet.iph;
+
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ }
+#endif /* NDPI_DETECTION_SUPPORT_IPV6 */
+
+ if(decaps_iph->version == 4 && decaps_iph->ihl >= 5) {
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv4 header\n");
+ }
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ else if(decaps_iph->version == 6 && l3len >= sizeof(struct ndpi_ipv6hdr) &&
+ (ndpi_struct->ip_version_limit & NDPI_DETECTION_ONLY_IPV4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv6 header\n");
+ flow->packet.iphv6 = (struct ndpi_ipv6hdr *)flow->packet.iph;
+ flow->packet.iph = NULL;
+ }
+#endif
+ else {
+ flow->packet.iph = NULL;
+ return 1;
+ }
+
+
+ /* needed:
+ * - unfragmented packets
+ * - ip header <= packet len
+ * - ip total length >= packet len
+ */
+
+
+ l4ptr = NULL;
+ l4len = 0;
+ l4protocol = 0;
+
+ l4_result =
+ ndpi_detection_get_l4_internal(ndpi_struct, (const u_int8_t *) decaps_iph, l3len, &l4ptr, &l4len, &l4protocol, 0);
+
+ if(l4_result != 0) {
+ return 1;
+ }
+
+ flow->packet.l4_protocol = l4protocol;
+ flow->packet.l4_packet_len = l4len;
+
+ /* tcp / udp detection */
+ if(l4protocol == 6 /* TCP */ &&flow->packet.l4_packet_len >= 20 /* min size of tcp */ ) {
+ /* tcp */
+ flow->packet.tcp = (struct ndpi_tcphdr *) l4ptr;
+
+ if(flow->packet.l4_packet_len >=flow->packet.tcp->doff * 4) {
+ flow->packet.payload_packet_len =
+ flow->packet.l4_packet_len -flow->packet.tcp->doff * 4;
+ flow->packet.actual_payload_len =flow->packet.payload_packet_len;
+ flow->packet.payload = ((u_int8_t *)flow->packet.tcp) + (flow->packet.tcp->doff * 4);
+
+ /* check for new tcp syn packets, here
+ * idea: reset detection state if a connection is unknown
+ */
+ if(flow && flow->packet.tcp->syn != 0
+ && flow->packet.tcp->ack == 0
+ && flow->init_finished != 0
+ && flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+
+ memset(flow, 0, sizeof(*(flow)));
+
+
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct,
+ NDPI_LOG_DEBUG,
+ "%s:%u: tcp syn packet for unknown protocol, reset detection state\n", __FUNCTION__, __LINE__);
+
+ }
+ } else {
+ /* tcp header not complete */
+ flow->packet.tcp = NULL;
+ }
+ } else if(l4protocol == 17 /* udp */ &&flow->packet.l4_packet_len >= 8 /* size of udp */ ) {
+ flow->packet.udp = (struct ndpi_udphdr *) l4ptr;
+ flow->packet.payload_packet_len =flow->packet.l4_packet_len - 8;
+ flow->packet.payload = ((u_int8_t *)flow->packet.udp) + 8;
+ } else {
+ flow->packet.generic_l4_ptr = l4ptr;
+ }
+ return 0;
+}
+
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ /* const for gcc code optimisation and cleaner code */
+ struct ndpi_packet_struct *packet = &flow->packet;
+ const struct ndpi_iphdr *iph = packet->iph;
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ const struct ndpi_ipv6hdr *iphv6 = packet->iphv6;
+#endif
+ const struct ndpi_tcphdr *tcph = packet->tcp;
+ const struct ndpi_udphdr *udph = flow->packet.udp;
+
+ //struct ndpi_unique_flow_struct unique_flow;
+ //uint8_t new_connection;
+
+ u_int8_t proxy_enabled = 0;
+
+ packet->tcp_retransmission = 0, packet->packet_direction = 0;
+
+ if(ndpi_struct->direction_detect_disable) {
+ packet->packet_direction = flow->packet_direction;
+ } else {
+ if(iph != NULL && iph->saddr < iph->daddr)
+ packet->packet_direction = 1;
+
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ if(iphv6 != NULL && NDPI_COMPARE_IPV6_ADDRESS_STRUCTS(&iphv6->saddr, &iphv6->daddr) != 0)
+ packet->packet_direction = 1;
+#endif
+ }
+
+ packet->packet_lines_parsed_complete = 0;
+ if(flow == NULL)
+ return;
+
+ if(flow->init_finished == 0) {
+ flow->init_finished = 1;
+ flow->setup_packet_direction = packet->packet_direction;
+ }
+
+ if(tcph != NULL) {
+ /* reset retried bytes here before setting it */
+ packet->num_retried_bytes = 0;
+
+ if(!ndpi_struct->direction_detect_disable)
+ packet->packet_direction = (tcph->source < tcph->dest) ? 1 : 0;
+
+ if(tcph->syn != 0 && tcph->ack == 0 && flow->l4.tcp.seen_syn == 0 && flow->l4.tcp.seen_syn_ack == 0
+ && flow->l4.tcp.seen_ack == 0) {
+ flow->l4.tcp.seen_syn = 1;
+ }
+ if(tcph->syn != 0 && tcph->ack != 0 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 0
+ && flow->l4.tcp.seen_ack == 0) {
+ flow->l4.tcp.seen_syn_ack = 1;
+ }
+ if(tcph->syn == 0 && tcph->ack == 1 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 1
+ && flow->l4.tcp.seen_ack == 0) {
+ flow->l4.tcp.seen_ack = 1;
+ }
+ if((flow->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))) {
+ /* initalize tcp sequence counters */
+ /* the ack flag needs to be set to get valid sequence numbers from the other
+ * direction. Usually it will catch the second packet syn+ack but it works
+ * also for asymmetric traffic where it will use the first data packet
+ *
+ * if the syn flag is set add one to the sequence number,
+ * otherwise use the payload length.
+ */
+ if(tcph->ack != 0) {
+ flow->next_tcp_seq_nr[flow->packet.packet_direction] =
+ ntohl(tcph->seq) + (tcph->syn ? 1 : packet->payload_packet_len);
+ if(!proxy_enabled) {
+ flow->next_tcp_seq_nr[1 -flow->packet.packet_direction] = ntohl(tcph->ack_seq);
+ }
+ }
+ } else if(packet->payload_packet_len > 0) {
+ /* check tcp sequence counters */
+ if(((u_int32_t)
+ (ntohl(tcph->seq) -
+ flow->next_tcp_seq_nr[packet->packet_direction])) >
+ ndpi_struct->tcp_max_retransmission_window_size) {
+
+ packet->tcp_retransmission = 1;
+
+
+ /*CHECK IF PARTIAL RETRY IS HAPPENENING */
+ if((flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq) < packet->payload_packet_len)) {
+ /* num_retried_bytes actual_payload_len hold info about the partial retry
+ analyzer which require this info can make use of this info
+ Other analyzer can use packet->payload_packet_len */
+ packet->num_retried_bytes = (u_int16_t)(flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq));
+ packet->actual_payload_len = packet->payload_packet_len - packet->num_retried_bytes;
+ flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
+ }
+ }
+ /*normal path
+ actual_payload_len is initialized to payload_packet_len during tcp header parsing itself.
+ It will be changed only in case of retransmission */
+ else {
+
+
+ packet->num_retried_bytes = 0;
+ flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
+ }
+
+
+ }
+
+ if(tcph->rst) {
+ flow->next_tcp_seq_nr[0] = 0;
+ flow->next_tcp_seq_nr[1] = 0;
+ }
+ } else if(udph != NULL) {
+ if(!ndpi_struct->direction_detect_disable)
+ packet->packet_direction = (udph->source < udph->dest) ? 1 : 0;
+ }
+
+ if(flow->packet_counter < MAX_PACKET_COUNTER && packet->payload_packet_len) {
+ flow->packet_counter++;
+ }
+
+ if(flow->packet_direction_counter[packet->packet_direction] < MAX_PACKET_COUNTER && packet->payload_packet_len) {
+ flow->packet_direction_counter[packet->packet_direction]++;
+ }
+
+ if(flow->byte_counter[packet->packet_direction] + packet->payload_packet_len >
+ flow->byte_counter[packet->packet_direction]) {
+ flow->byte_counter[packet->packet_direction] += packet->payload_packet_len;
+ }
+}
+
+void check_ndpi_other_flow_func(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
+ void *func = NULL;
+ u_int32_t a;
+ u_int16_t proto_index = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoIdx;
+ int16_t proto_id = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoId;
+ NDPI_PROTOCOL_BITMASK detection_bitmask;
+
+ NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
+
+ if((proto_id != NDPI_PROTOCOL_UNKNOWN)
+ && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_struct->callback_buffer[proto_index].excluded_protocol_bitmask) == 0
+ && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer[proto_index].detection_bitmask,
+ detection_bitmask) != 0
+ && (ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask
+ & *ndpi_selection_packet) == ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask) {
+ if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)
+ && (ndpi_struct->proto_defaults[flow->guessed_protocol_id].func != NULL))
+ ndpi_struct->proto_defaults[flow->guessed_protocol_id].func(ndpi_struct, flow),
+ func = ndpi_struct->proto_defaults[flow->guessed_protocol_id].func;
+ }
+
+ for (a = 0; a < ndpi_struct->callback_buffer_size_non_tcp_udp; a++) {
+ if((func != ndpi_struct->callback_buffer_non_tcp_udp[a].func)
+ && (ndpi_struct->callback_buffer_non_tcp_udp[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
+ ndpi_struct->callback_buffer_non_tcp_udp[a].ndpi_selection_bitmask
+ && (flow == NULL
+ ||
+ NDPI_BITMASK_COMPARE
+ (flow->excluded_protocol_bitmask,
+ ndpi_struct->callback_buffer_non_tcp_udp[a].excluded_protocol_bitmask) == 0)
+ && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer_non_tcp_udp[a].detection_bitmask,
+ detection_bitmask) != 0) {
+
+ if(ndpi_struct->callback_buffer_non_tcp_udp[a].func != NULL)
+ ndpi_struct->callback_buffer_non_tcp_udp[a].func(ndpi_struct, flow);
+
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ break; /* Stop after detecting the first protocol */
+ }
+ }
+}
+
+
+void check_ndpi_udp_flow_func(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
+ void *func = NULL;
+ u_int32_t a;
+ u_int16_t proto_index = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoIdx;
+ int16_t proto_id = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoId;
+ NDPI_PROTOCOL_BITMASK detection_bitmask;
+
+ NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
+
+ if((proto_id != NDPI_PROTOCOL_UNKNOWN)
+ && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_struct->callback_buffer[proto_index].excluded_protocol_bitmask) == 0
+ && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer[proto_index].detection_bitmask,
+ detection_bitmask) != 0
+ && (ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask
+ & *ndpi_selection_packet) == ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask) {
+ if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)
+ && (ndpi_struct->proto_defaults[flow->guessed_protocol_id].func != NULL))
+ ndpi_struct->proto_defaults[flow->guessed_protocol_id].func(ndpi_struct, flow),
+ func = ndpi_struct->proto_defaults[flow->guessed_protocol_id].func;
+ }
+
+ for (a = 0; a < ndpi_struct->callback_buffer_size_udp; a++) {
+ if((func != ndpi_struct->callback_buffer_tcp_payload[a].func)
+ && (ndpi_struct->callback_buffer_udp[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
+ ndpi_struct->callback_buffer_udp[a].ndpi_selection_bitmask
+ && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_struct->callback_buffer_udp[a].excluded_protocol_bitmask) == 0
+ && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer_udp[a].detection_bitmask,
+ detection_bitmask) != 0) {
+ ndpi_struct->callback_buffer_udp[a].func(ndpi_struct, flow);
+ // NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "[UDP,CALL] dissector of protocol as callback_buffer idx = %d\n",a);
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ break; /* Stop after detecting the first protocol */
+ } else
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG,
+ "[UDP,SKIP] dissector of protocol as callback_buffer idx = %d\n",a);
+ }
+}
+
+
+void check_ndpi_tcp_flow_func(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
+ void *func = NULL;
+ u_int32_t a;
+ u_int16_t proto_index = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoIdx;
+ int16_t proto_id = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoId;
+ NDPI_PROTOCOL_BITMASK detection_bitmask;
+
+ NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
+
+ if(flow->packet.payload_packet_len != 0) {
+ if((proto_id != NDPI_PROTOCOL_UNKNOWN)
+ && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_struct->callback_buffer[proto_index].excluded_protocol_bitmask) == 0
+ && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer[proto_index].detection_bitmask,
+ detection_bitmask) != 0
+ && (ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask
+ & *ndpi_selection_packet) == ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask) {
+ if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)
+ && (ndpi_struct->proto_defaults[flow->guessed_protocol_id].func != NULL))
+ ndpi_struct->proto_defaults[flow->guessed_protocol_id].func(ndpi_struct, flow),
+ func = ndpi_struct->proto_defaults[flow->guessed_protocol_id].func;
+ }
+
+ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+ for (a = 0; a < ndpi_struct->callback_buffer_size_tcp_payload; a++) {
+ if((func != ndpi_struct->callback_buffer_tcp_payload[a].func)
+ && (ndpi_struct->callback_buffer_tcp_payload[a].ndpi_selection_bitmask
+ & *ndpi_selection_packet) == ndpi_struct->callback_buffer_tcp_payload[a].ndpi_selection_bitmask
+ && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_struct->callback_buffer_tcp_payload[a].excluded_protocol_bitmask) == 0
+ && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer_tcp_payload[a].detection_bitmask,
+ detection_bitmask) != 0) {
+ ndpi_struct->callback_buffer_tcp_payload[a].func(ndpi_struct, flow);
+
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ break; /* Stop after detecting the first protocol */
+ }
+ }
+ }
+ } else {
+ /* no payload */
+ if((proto_id != NDPI_PROTOCOL_UNKNOWN)
+ && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_struct->callback_buffer[proto_index].excluded_protocol_bitmask) == 0
+ && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer[proto_index].detection_bitmask,
+ detection_bitmask) != 0
+ && (ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask
+ & *ndpi_selection_packet) == ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask) {
+ if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)
+ && (ndpi_struct->proto_defaults[flow->guessed_protocol_id].func != NULL)
+ && ((ndpi_struct->callback_buffer[flow->guessed_protocol_id].ndpi_selection_bitmask & NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) == 0))
+ ndpi_struct->proto_defaults[flow->guessed_protocol_id].func(ndpi_struct, flow),
+ func = ndpi_struct->proto_defaults[flow->guessed_protocol_id].func;
+ }
+
+ for (a = 0; a < ndpi_struct->callback_buffer_size_tcp_no_payload; a++) {
+ if((func != ndpi_struct->callback_buffer_tcp_payload[a].func)
+ && (ndpi_struct->callback_buffer_tcp_no_payload[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
+ ndpi_struct->callback_buffer_tcp_no_payload[a].ndpi_selection_bitmask
+ && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_struct->
+ callback_buffer_tcp_no_payload[a].excluded_protocol_bitmask) == 0
+ && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer_tcp_no_payload[a].detection_bitmask,
+ detection_bitmask) != 0) {
+ ndpi_struct->callback_buffer_tcp_no_payload[a].func(ndpi_struct, flow);
+
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ break; /* Stop after detecting the first protocol */
+ }
+ }
+ }
+}
+
+void check_ndpi_flow_func(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
+ if(flow->packet.tcp != NULL)
+ check_ndpi_tcp_flow_func(ndpi_struct, flow, ndpi_selection_packet);
+ else if(flow->packet.udp != NULL)
+ check_ndpi_udp_flow_func(ndpi_struct, flow, ndpi_selection_packet);
+ else
+ check_ndpi_other_flow_func(ndpi_struct, flow, ndpi_selection_packet);
+}
+
+unsigned int ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ const unsigned char *packet,
+ const unsigned short packetlen,
+ const u_int64_t current_tick_l,
+ struct ndpi_id_struct *src,
+ struct ndpi_id_struct *dst)
+{
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet;
+ u_int32_t a;
+
+ if(flow == NULL)
+ return NDPI_PROTOCOL_UNKNOWN;
+
+ if(flow->server_id == NULL) flow->server_id = dst; /* Default */
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN && !flow->no_cache_protocol)
+ return(flow->detected_protocol_stack[0]); /* Stop after detecting the first protocol */
+
+ /* 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 NDPI_PROTOCOL_UNKNOWN;
+ }
+
+ flow->packet.tick_timestamp_l = current_tick_l;
+#ifdef __KERNEL__
+ {
+ u_int64_t d = current_tick_l;
+ do_div(d,1000);
+ flow->packet.tick_timestamp = d;
+ }
+#else
+ flow->packet.tick_timestamp = current_tick_l/1000;
+#endif
+
+ /* parse packet */
+ flow->packet.iph = (struct ndpi_iphdr *) packet;
+ /* we are interested in ipv4 packet */
+
+ if(ndpi_init_packet_header(ndpi_struct, flow, packetlen) != 0)
+ return NDPI_PROTOCOL_UNKNOWN;
+
+ /* detect traffic for tcp or udp only */
+
+ flow->src = src, flow->dst = dst;
+
+ ndpi_connection_tracking(ndpi_struct, flow);
+
+ /* build ndpi_selction packet bitmask */
+ ndpi_selection_packet = NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC;
+ if(flow->packet.iph != NULL) {
+ ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IP | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
+ }
+ if(flow->packet.tcp != NULL) {
+ ndpi_selection_packet |=
+ (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
+ }
+ if(flow->packet.udp != NULL) {
+ ndpi_selection_packet |=
+ (NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
+ }
+ if(flow->packet.payload_packet_len != 0) {
+ ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD;
+ }
+
+ if(flow->packet.tcp_retransmission == 0) {
+ ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION;
+ }
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ if(flow->packet.iphv6 != NULL) {
+ ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
+ }
+#endif /* NDPI_DETECTION_SUPPORT_IPV6 */
+
+ if((!flow->protocol_id_already_guessed)
+ && (
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ flow->packet.iphv6 ||
+#endif
+ flow->packet.iph)) {
+ u_int16_t sport, dport;
+ u_int8_t protocol;
+ u_int32_t saddr, daddr;
+
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ if(flow->packet.iphv6 != NULL) {
+ protocol = flow->packet.iphv6->nexthdr, saddr = 0, daddr = 0;
+ } else
+#endif
+ {
+ protocol = flow->packet.iph->protocol;
+ saddr = ntohl(flow->packet.iph->saddr);
+ daddr = ntohl(flow->packet.iph->daddr);
+ }
+
+ if(flow->packet.udp) sport = ntohs(flow->packet.udp->source), dport = ntohs(flow->packet.udp->dest);
+ else if(flow->packet.tcp) sport = ntohs(flow->packet.tcp->source), dport = ntohs(flow->packet.tcp->dest);
+ else sport = dport = 0;
+
+ flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol,
+ sport, dport);
+ flow->protocol_id_already_guessed = 1;
+ }
+
+ a = flow->detected_protocol_stack[0];
+ if(a != NDPI_PROTOCOL_UNKNOWN && flow->no_cache_protocol) {
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_TRACE, "PROCESS KNOWN PROTOCOL\n");
+ ndpi_struct->proto_defaults[a].func(ndpi_struct, flow);
+ return a;
+ }
+
+ check_ndpi_flow_func(ndpi_struct, flow, &ndpi_selection_packet);
+
+ a = flow->packet.detected_protocol_stack[0];
+ if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, a) == 0)
+ a = NDPI_PROTOCOL_UNKNOWN;
+
+ 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';
+ }
+
+ return a;
+}
+
+
+u_int32_t ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read)
+{
+ u_int32_t val;
+ val = 0;
+ // cancel if eof, ' ' or line end chars are reached
+ while (*str >= '0' && *str <= '9' && max_chars_to_read > 0) {
+ val *= 10;
+ val += *str - '0';
+ str++;
+ max_chars_to_read = max_chars_to_read - 1;
+ *bytes_read = *bytes_read + 1;
+ }
+ return (val);
+}
+
+u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read)
+{
+ u_int32_t val;
+ val = 0;
+ if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
+ return ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read);
+ } else {
+ /*use base 16 system */
+ str += 2;
+ max_chars_to_read -= 2;
+ *bytes_read = *bytes_read + 2;
+ while (max_chars_to_read > 0) {
+
+ if(*str >= '0' && *str <= '9') {
+ val *= 16;
+ val += *str - '0';
+ } else if(*str >= 'a' && *str <= 'f') {
+ val *= 16;
+ val += *str + 10 - 'a';
+ } else if(*str >= 'A' && *str <= 'F') {
+ val *= 16;
+ val += *str + 10 - 'A';
+ } else {
+ break;
+ }
+ str++;
+ max_chars_to_read = max_chars_to_read - 1;
+ *bytes_read = *bytes_read + 1;
+ }
+ }
+ return (val);
+}
+
+
+u_int64_t ndpi_bytestream_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read)
+{
+ u_int64_t val;
+ val = 0;
+ // cancel if eof, ' ' or line end chars are reached
+ while (max_chars_to_read > 0 && *str >= '0' && *str <= '9') {
+ val *= 10;
+ val += *str - '0';
+ str++;
+ max_chars_to_read = max_chars_to_read - 1;
+ *bytes_read = *bytes_read + 1;
+ }
+ return (val);
+}
+
+u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read)
+{
+ u_int64_t val;
+ val = 0;
+ if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
+ return ndpi_bytestream_to_number64(str, max_chars_to_read, bytes_read);
+ } else {
+ /*use base 16 system */
+ str += 2;
+ max_chars_to_read -= 2;
+ *bytes_read = *bytes_read + 2;
+ while (max_chars_to_read > 0) {
+
+ if(*str >= '0' && *str <= '9') {
+ val *= 16;
+ val += *str - '0';
+ } else if(*str >= 'a' && *str <= 'f') {
+ val *= 16;
+ val += *str + 10 - 'a';
+ } else if(*str >= 'A' && *str <= 'F') {
+ val *= 16;
+ val += *str + 10 - 'A';
+ } else {
+ break;
+ }
+ str++;
+ max_chars_to_read = max_chars_to_read - 1;
+ *bytes_read = *bytes_read + 1;
+ }
+ }
+ return (val);
+}
+
+
+u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read)
+{
+ u_int32_t val;
+ u_int16_t read = 0;
+ u_int16_t oldread;
+ u_int32_t c;
+ /* ip address must be X.X.X.X with each X between 0 and 255 */
+ oldread = read;
+ c = ndpi_bytestream_to_number(str, max_chars_to_read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
+ return 0;
+ read++;
+ val = c << 24;
+ oldread = read;
+ c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
+ return 0;
+ read++;
+ val = val + (c << 16);
+ oldread = read;
+ c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
+ return 0;
+ read++;
+ val = val + (c << 8);
+ oldread = read;
+ c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read)
+ return 0;
+ val = val + c;
+
+ *bytes_read = *bytes_read + read;
+
+ return htonl(val);
+}
+
+/* internal function for every detection to parse one packet and to increase the info buffer */
+void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ u_int32_t a;
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t end = packet->payload_packet_len - 1;
+ if(packet->packet_lines_parsed_complete != 0)
+ return;
+
+ packet->packet_lines_parsed_complete = 1;
+ packet->parsed_lines = 0;
+
+ packet->empty_line_position_set = 0;
+
+ packet->host_line.ptr = NULL;
+ packet->host_line.len = 0;
+ packet->referer_line.ptr = NULL;
+ packet->referer_line.len = 0;
+ packet->content_line.ptr = NULL;
+ packet->content_line.len = 0;
+ packet->accept_line.ptr = NULL;
+ packet->accept_line.len = 0;
+ packet->user_agent_line.ptr = NULL;
+ packet->user_agent_line.len = 0;
+ packet->http_url_name.ptr = NULL;
+ packet->http_url_name.len = 0;
+ packet->http_encoding.ptr = NULL;
+ packet->http_encoding.len = 0;
+ packet->http_transfer_encoding.ptr = NULL;
+ packet->http_transfer_encoding.len = 0;
+ packet->http_contentlen.ptr = NULL;
+ packet->http_contentlen.len = 0;
+ packet->http_cookie.ptr = NULL;
+ packet->http_cookie.len = 0;
+ packet->http_origin.len = 0;
+ packet->http_origin.ptr = NULL;
+ packet->http_x_session_type.ptr = NULL;
+ packet->http_x_session_type.len = 0;
+ packet->server_line.ptr = NULL;
+ packet->server_line.len = 0;
+ packet->http_method.ptr = NULL;
+ packet->http_method.len = 0;
+ packet->http_response.ptr = NULL;
+ packet->http_response.len = 0;
+
+ if((packet->payload_packet_len == 0)
+ || (packet->payload == NULL))
+ return;
+
+ packet->line[packet->parsed_lines].ptr = packet->payload;
+ packet->line[packet->parsed_lines].len = 0;
+
+ for (a = 0; a < end; a++) {
+ if(get_u_int16_t(packet->payload, a) == ntohs(0x0d0a)) {
+ packet->line[packet->parsed_lines].len = (u_int16_t)(((unsigned long) &packet->payload[a]) - ((unsigned long) packet->line[packet->parsed_lines].ptr));
+
+ if(packet->parsed_lines == 0 && packet->line[0].len >= NDPI_STATICSTRING_LEN("HTTP/1.1 200 ") &&
+ memcmp(packet->line[0].ptr, "HTTP/1.", NDPI_STATICSTRING_LEN("HTTP/1.")) == 0 &&
+ packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] > '0' &&
+ packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] < '6') {
+ packet->http_response.ptr = &packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.1 ")];
+ packet->http_response.len = packet->line[0].len - NDPI_STATICSTRING_LEN("HTTP/1.1 ");
+ NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG,
+ "ndpi_parse_packet_line_info: HTTP response parsed: \"%.*s\"\n",
+ packet->http_response.len, packet->http_response.ptr);
+ }
+ if(packet->line[packet->parsed_lines].len > NDPI_STATICSTRING_LEN("Server:") + 1
+ && memcmp(packet->line[packet->parsed_lines].ptr, "Server:", NDPI_STATICSTRING_LEN("Server:")) == 0) {
+ // some stupid clients omit a space and place the servername directly after the colon
+ if(packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")] == ' ') {
+ packet->server_line.ptr =
+ &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:") + 1];
+ packet->server_line.len =
+ packet->line[packet->parsed_lines].len - (NDPI_STATICSTRING_LEN("Server:") + 1);
+ } else {
+ packet->server_line.ptr = &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")];
+ packet->server_line.len = packet->line[packet->parsed_lines].len - NDPI_STATICSTRING_LEN("Server:");
+ }
+ }
+
+ if(packet->line[packet->parsed_lines].len > 6
+ && memcmp(packet->line[packet->parsed_lines].ptr, "Host:", 5) == 0) {
+ // some stupid clients omit a space and place the hostname directly after the colon
+ if(packet->line[packet->parsed_lines].ptr[5] == ' ') {
+ packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[6];
+ packet->host_line.len = packet->line[packet->parsed_lines].len - 6;
+ } else {
+ packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[5];
+ packet->host_line.len = packet->line[packet->parsed_lines].len - 5;
+ }
+ }
+
+ if(packet->line[packet->parsed_lines].len > 17
+ && memcmp(packet->line[packet->parsed_lines].ptr, "X-Forwarded-For:", 16) == 0) {
+ // some stupid clients omit a space and place the hostname directly after the colon
+ if(packet->line[packet->parsed_lines].ptr[16] == ' ') {
+ packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[17];
+ packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 17;
+ } else {
+ packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[16];
+ packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 16;
+ }
+ }
+
+ if(packet->line[packet->parsed_lines].len > 14
+ &&
+ (memcmp
+ (packet->line[packet->parsed_lines].ptr, "Content-Type: ",
+ 14) == 0 || memcmp(packet->line[packet->parsed_lines].ptr, "Content-type: ", 14) == 0)) {
+ packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[14];
+ packet->content_line.len = packet->line[packet->parsed_lines].len - 14;
+ }
+
+ if(packet->line[packet->parsed_lines].len > 13
+ && memcmp(packet->line[packet->parsed_lines].ptr, "Content-type:", 13) == 0) {
+ packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[13];
+ packet->content_line.len = packet->line[packet->parsed_lines].len - 13;
+ }
+
+ if(packet->line[packet->parsed_lines].len > 8
+ && memcmp(packet->line[packet->parsed_lines].ptr, "Accept: ", 8) == 0) {
+ packet->accept_line.ptr = &packet->line[packet->parsed_lines].ptr[8];
+ packet->accept_line.len = packet->line[packet->parsed_lines].len - 8;
+ }
+
+ if(packet->line[packet->parsed_lines].len > 9
+ && memcmp(packet->line[packet->parsed_lines].ptr, "Referer: ", 9) == 0) {
+ packet->referer_line.ptr = &packet->line[packet->parsed_lines].ptr[9];
+ packet->referer_line.len = packet->line[packet->parsed_lines].len - 9;
+ }
+
+ if(packet->line[packet->parsed_lines].len > 12
+ && (memcmp(packet->line[packet->parsed_lines].ptr, "User-Agent: ", 12) == 0 ||
+ memcmp(packet->line[packet->parsed_lines].ptr, "User-agent: ", 12) == 0)) {
+ packet->user_agent_line.ptr = &packet->line[packet->parsed_lines].ptr[12];
+ packet->user_agent_line.len = packet->line[packet->parsed_lines].len - 12;
+ }
+
+ if(packet->line[packet->parsed_lines].len > 18
+ && memcmp(packet->line[packet->parsed_lines].ptr, "Content-Encoding: ", 18) == 0) {
+ packet->http_encoding.ptr = &packet->line[packet->parsed_lines].ptr[18];
+ packet->http_encoding.len = packet->line[packet->parsed_lines].len - 18;
+ }
+
+ if(packet->line[packet->parsed_lines].len > 19
+ && memcmp(packet->line[packet->parsed_lines].ptr, "Transfer-Encoding: ", 19) == 0) {
+ packet->http_transfer_encoding.ptr = &packet->line[packet->parsed_lines].ptr[19];
+ packet->http_transfer_encoding.len = packet->line[packet->parsed_lines].len - 19;
+ }
+ if(packet->line[packet->parsed_lines].len > 16
+ && ((memcmp(packet->line[packet->parsed_lines].ptr, "Content-Length: ", 16) == 0)
+ || (memcmp(packet->line[packet->parsed_lines].ptr, "content-length: ", 16) == 0))) {
+ packet->http_contentlen.ptr = &packet->line[packet->parsed_lines].ptr[16];
+ packet->http_contentlen.len = packet->line[packet->parsed_lines].len - 16;
+ }
+ if(packet->line[packet->parsed_lines].len > 8
+ && memcmp(packet->line[packet->parsed_lines].ptr, "Cookie: ", 8) == 0) {
+ packet->http_cookie.ptr = &packet->line[packet->parsed_lines].ptr[8];
+ packet->http_cookie.len = packet->line[packet->parsed_lines].len - 8;
+ }
+ if(packet->line[packet->parsed_lines].len > 8
+ && memcmp(packet->line[packet->parsed_lines].ptr, "Origin: ", 8) == 0) {
+ packet->http_origin.ptr = &packet->line[packet->parsed_lines].ptr[8];
+ packet->http_origin.len = packet->line[packet->parsed_lines].len - 8;
+ }
+ if(packet->line[packet->parsed_lines].len > 16
+ && memcmp(packet->line[packet->parsed_lines].ptr, "X-Session-Type: ", 16) == 0) {
+ packet->http_x_session_type.ptr = &packet->line[packet->parsed_lines].ptr[16];
+ packet->http_x_session_type.len = packet->line[packet->parsed_lines].len - 16;
+ }
+
+
+ if(packet->line[packet->parsed_lines].len == 0) {
+ packet->empty_line_position = a;
+ packet->empty_line_position_set = 1;
+ }
+
+ if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1)) {
+ return;
+ }
+
+ packet->parsed_lines++;
+ packet->line[packet->parsed_lines].ptr = &packet->payload[a + 2];
+ packet->line[packet->parsed_lines].len = 0;
+
+ if((a + 2) >= packet->payload_packet_len) {
+
+ return;
+ }
+ a++;
+ }
+ }
+
+ if(packet->parsed_lines >= 1) {
+ packet->line[packet->parsed_lines].len
+ = (u_int16_t)(((unsigned long) &packet->payload[packet->payload_packet_len]) -
+ ((unsigned long) packet->line[packet->parsed_lines].ptr));
+ packet->parsed_lines++;
+ }
+}
+
+void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t a;
+ u_int16_t end = packet->payload_packet_len;
+ if(packet->packet_lines_parsed_complete != 0)
+ return;
+
+
+
+ packet->packet_lines_parsed_complete = 1;
+ packet->parsed_lines = 0;
+
+ if(packet->payload_packet_len == 0)
+ return;
+
+ packet->line[packet->parsed_lines].ptr = packet->payload;
+ packet->line[packet->parsed_lines].len = 0;
+
+ for (a = 0; a < end; a++) {
+ if(packet->payload[a] == 0x0a) {
+ packet->line[packet->parsed_lines].len = (u_int16_t)(
+ ((unsigned long) &packet->payload[a]) -
+ ((unsigned long) packet->line[packet->parsed_lines].ptr));
+ if(a > 0 && packet->payload[a-1] == 0x0d)
+ packet->line[packet->parsed_lines].len--;
+
+ if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1)) {
+ break;
+ }
+
+ packet->parsed_lines++;
+ packet->line[packet->parsed_lines].ptr = &packet->payload[a + 1];
+ packet->line[packet->parsed_lines].len = 0;
+
+ if((a + 1) >= packet->payload_packet_len) {
+ break;
+ }
+ //a++;
+ }
+ }
+}
+
+
+u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, u_int16_t counter)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "called ndpi_check_for_email_address\n");
+
+ if(packet->payload_packet_len > counter && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z')
+ || (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z')
+ || (packet->payload[counter] >= '0' && packet->payload[counter] <= '9')
+ || packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "first letter\n");
+ counter++;
+ while (packet->payload_packet_len > counter
+ && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z')
+ || (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z')
+ || (packet->payload[counter] >= '0' && packet->payload[counter] <= '9')
+ || packet->payload[counter] == '-' || packet->payload[counter] == '_'
+ || packet->payload[counter] == '.')) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "further letter\n");
+ counter++;
+ if(packet->payload_packet_len > counter && packet->payload[counter] == '@') {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "@\n");
+ counter++;
+ while (packet->payload_packet_len > counter
+ && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z')
+ || (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z')
+ || (packet->payload[counter] >= '0' && packet->payload[counter] <= '9')
+ || packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "letter\n");
+ counter++;
+ if(packet->payload_packet_len > counter && packet->payload[counter] == '.') {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, ".\n");
+ counter++;
+ if(packet->payload_packet_len > counter + 1
+ && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z')
+ && (packet->payload[counter + 1] >= 'a' && packet->payload[counter + 1] <= 'z'))) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "two letters\n");
+ counter += 2;
+ if(packet->payload_packet_len > counter
+ && (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "whitespace1\n");
+ return counter;
+ } else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a'
+ && packet->payload[counter] <= 'z') {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "one letter\n");
+ counter++;
+ if(packet->payload_packet_len > counter
+ && (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "whitespace2\n");
+ return counter;
+ } else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a'
+ && packet->payload[counter] <= 'z') {
+ counter++;
+ if(packet->payload_packet_len > counter
+ && (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "whitespace3\n");
+ return counter;
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ }
+ }
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
+
+#ifdef NDPI_ENABLE_DEBUG_MESSAGES
+void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct
+ *ndpi_struct, const char **file, const char **func, u_int32_t * line)
+{
+ *file = "";
+ *func = "";
+
+ if(ndpi_struct->ndpi_debug_print_file != NULL)
+ *file = ndpi_struct->ndpi_debug_print_file;
+
+ if(ndpi_struct->ndpi_debug_print_function != NULL)
+ *func = ndpi_struct->ndpi_debug_print_function;
+
+ *line = ndpi_struct->ndpi_debug_print_line;
+}
+#endif
+u_int8_t ndpi_detection_get_l4(const u_int8_t * l3, u_int16_t l3_len, const u_int8_t ** l4_return, u_int16_t * l4_len_return,
+ u_int8_t * l4_protocol_return, u_int32_t flags)
+{
+ return ndpi_detection_get_l4_internal(NULL, l3, l3_len, l4_return, l4_len_return, l4_protocol_return, flags);
+}
+
+void ndpi_int_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type)
+{
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ ndpi_int_change_protocol(ndpi_struct, flow, detected_protocol, protocol_type);
+
+ if(src != NULL) {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, detected_protocol);
+ }
+ if(dst != NULL) {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, detected_protocol);
+ }
+}
+
+void ndpi_int_change_flow_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type)
+{
+#if NDPI_PROTOCOL_HISTORY_SIZE > 1
+ u_int8_t a;
+ u_int8_t stack_size;
+ u_int8_t new_is_real = 0;
+ u_int16_t preserve_bitmask;
+#endif
+
+ if(!flow)
+ return;
+
+#if NDPI_PROTOCOL_HISTORY_SIZE > 1
+ stack_size = flow->protocol_stack_info.current_stack_size_minus_one + 1;
+
+ /* here are the rules for stack manipulations:
+ * 1.if the new protocol is a real protocol, insert it at the position
+ * of the top-most real protocol or below the last non-unknown correlated
+ * protocol.
+ * 2.if the new protocol is not real, put it on top of stack but if there is
+ * a real protocol in the stack, make sure at least one real protocol remains
+ * in the stack
+ */
+
+ if(protocol_type == NDPI_CORRELATED_PROTOCOL) {
+ u_int16_t saved_real_protocol = NDPI_PROTOCOL_UNKNOWN;
+
+ if(stack_size == NDPI_PROTOCOL_HISTORY_SIZE) {
+ /* check whether we will lost real protocol information due to shifting */
+ u_int16_t real_protocol = flow->protocol_stack_info.entry_is_real_protocol;
+
+ for (a = 0; a < stack_size; a++) {
+ if(real_protocol & 1)
+ break;
+ real_protocol >>= 1;
+ }
+
+ if(a == (stack_size - 1)) {
+ /* oh, only one real protocol at the end, store it and insert it later */
+ saved_real_protocol = flow->detected_protocol_stack[stack_size - 1];
+ }
+ } else {
+ flow->protocol_stack_info.current_stack_size_minus_one++;
+ stack_size++;
+ }
+
+ /* now shift and insert */
+ for (a = stack_size - 1; a > 0; a--) {
+ flow->detected_protocol_stack[a] = flow->detected_protocol_stack[a - 1];
+ }
+
+ flow->protocol_stack_info.entry_is_real_protocol <<= 1;
+
+ /* now set the new protocol */
+
+ flow->detected_protocol_stack[0] = detected_protocol;
+
+ /* restore real protocol */
+ if(saved_real_protocol != NDPI_PROTOCOL_UNKNOWN) {
+ flow->detected_protocol_stack[stack_size - 1] = saved_real_protocol;
+ flow->protocol_stack_info.entry_is_real_protocol |= 1 << (stack_size - 1);
+ }
+ /* done */
+ } else {
+ u_int8_t insert_at = 0;
+
+ if(!(flow->protocol_stack_info.entry_is_real_protocol & 1)) {
+ u_int16_t real_protocol = flow->protocol_stack_info.entry_is_real_protocol;
+
+ for (a = 0; a < stack_size; a++) {
+ if(real_protocol & 1)
+ break;
+ real_protocol >>= 1;
+ }
+
+ insert_at = a;
+ }
+
+ if(insert_at >= stack_size) {
+ /* no real protocol found, insert it at the bottom */
+
+ insert_at = stack_size - 1;
+ }
+
+ if(stack_size < NDPI_PROTOCOL_HISTORY_SIZE) {
+ flow->protocol_stack_info.current_stack_size_minus_one++;
+ stack_size++;
+ }
+
+ /* first shift all stacks */
+ for (a = stack_size - 1; a > insert_at; a--) {
+ flow->detected_protocol_stack[a] = flow->detected_protocol_stack[a - 1];
+ }
+
+ preserve_bitmask = (1 << insert_at) - 1;
+
+ new_is_real = (flow->protocol_stack_info.entry_is_real_protocol & (~preserve_bitmask)) << 1;
+ new_is_real |= flow->protocol_stack_info.entry_is_real_protocol & preserve_bitmask;
+
+ flow->protocol_stack_info.entry_is_real_protocol = new_is_real;
+
+ /* now set the new protocol */
+
+ flow->detected_protocol_stack[insert_at] = detected_protocol;
+
+ /* and finally update the additional stack information */
+
+ flow->protocol_stack_info.entry_is_real_protocol |= 1 << insert_at;
+ }
+#else
+ flow->detected_protocol_stack[0] = detected_protocol;
+ flow->detected_subprotocol_stack[0] = detected_subprotocol;
+#endif
+}
+
+void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ /* NOTE: everything below is identically to change_flow_protocol
+ * except flow->packet If you want to change something here,
+ * don't! Change it for the flow function and apply it here
+ * as well */
+#if NDPI_PROTOCOL_HISTORY_SIZE > 1
+ u_int8_t a;
+ u_int8_t stack_size;
+ u_int16_t new_is_real = 0;
+ u_int16_t preserve_bitmask;
+#endif
+
+ if(!packet)
+ return;
+
+#if NDPI_PROTOCOL_HISTORY_SIZE > 1
+ stack_size = packet->protocol_stack_info.current_stack_size_minus_one + 1;
+
+ /* here are the rules for stack manipulations:
+ * 1.if the new protocol is a real protocol, insert it at the position
+ * of the top-most real protocol or below the last non-unknown correlated
+ * protocol.
+ * 2.if the new protocol is not real, put it on top of stack but if there is
+ * a real protocol in the stack, make sure at least one real protocol remains
+ * in the stack
+ */
+
+ if(protocol_type == NDPI_CORRELATED_PROTOCOL) {
+ u_int16_t saved_real_protocol = NDPI_PROTOCOL_UNKNOWN;
+
+ if(stack_size == NDPI_PROTOCOL_HISTORY_SIZE) {
+ /* check whether we will lost real protocol information due to shifting */
+ u_int16_t real_protocol = packet->protocol_stack_info.entry_is_real_protocol;
+
+ for (a = 0; a < stack_size; a++) {
+ if(real_protocol & 1)
+ break;
+ real_protocol >>= 1;
+ }
+
+ if(a == (stack_size - 1)) {
+ /* oh, only one real protocol at the end, store it and insert it later */
+ saved_real_protocol = packet->detected_protocol_stack[stack_size - 1];
+ }
+ } else {
+ packet->protocol_stack_info.current_stack_size_minus_one++;
+ stack_size++;
+ }
+
+ /* now shift and insert */
+ for (a = stack_size - 1; a > 0; a--) {
+ packet->detected_protocol_stack[a] = packet->detected_protocol_stack[a - 1];
+ }
+
+ packet->protocol_stack_info.entry_is_real_protocol <<= 1;
+
+ /* now set the new protocol */
+
+ packet->detected_protocol_stack[0] = detected_protocol;
+
+ /* restore real protocol */
+ if(saved_real_protocol != NDPI_PROTOCOL_UNKNOWN) {
+ packet->detected_protocol_stack[stack_size - 1] = saved_real_protocol;
+ packet->protocol_stack_info.entry_is_real_protocol |= 1 << (stack_size - 1);
+ }
+ /* done */
+ } else {
+ u_int8_t insert_at = 0;
+
+ if(!(packet->protocol_stack_info.entry_is_real_protocol & 1)) {
+ u_int16_t real_protocol = packet->protocol_stack_info.entry_is_real_protocol;
+
+ for (a = 0; a < stack_size; a++) {
+ if(real_protocol & 1)
+ break;
+ real_protocol >>= 1;
+ }
+
+ insert_at = a;
+ }
+
+ if(insert_at >= stack_size) {
+ /* no real protocol found, insert it at the first unknown protocol */
+
+ insert_at = stack_size - 1;
+ }
+
+ if(stack_size < NDPI_PROTOCOL_HISTORY_SIZE) {
+ packet->protocol_stack_info.current_stack_size_minus_one++;
+ stack_size++;
+ }
+
+ /* first shift all stacks */
+ for (a = stack_size - 1; a > insert_at; a--) {
+ packet->detected_protocol_stack[a] = packet->detected_protocol_stack[a - 1];
+ }
+
+ preserve_bitmask = (1 << insert_at) - 1;
+
+ new_is_real = (packet->protocol_stack_info.entry_is_real_protocol & (~preserve_bitmask)) << 1;
+ new_is_real |= packet->protocol_stack_info.entry_is_real_protocol & preserve_bitmask;
+
+ packet->protocol_stack_info.entry_is_real_protocol = (u_int8_t)new_is_real;
+
+ /* now set the new protocol */
+
+ packet->detected_protocol_stack[insert_at] = detected_protocol;
+
+ /* and finally update the additional stack information */
+
+ packet->protocol_stack_info.entry_is_real_protocol |= 1 << insert_at;
+ }
+#else
+ packet->detected_protocol_stack[0] = detected_protocol;
+ packet->detected_subprotocol_stack[0] = detected_subprotocol;
+#endif
+}
+
+
+/*
+ * this function returns the real protocol of the flow. Actually it
+ * accesses the packet stack since this is what leaves the library but
+ * it could also use the flow stack.
+ */
+u_int16_t ndpi_detection_get_real_protocol_of_flow(struct ndpi_detection_module_struct * ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+#if NDPI_PROTOCOL_HISTORY_SIZE > 1
+ u_int8_t a;
+ u_int8_t stack_size;
+ u_int16_t real_protocol;
+#endif
+
+ if(!packet)
+ return NDPI_PROTOCOL_UNKNOWN;
+
+#if NDPI_PROTOCOL_HISTORY_SIZE > 1
+ stack_size = packet->protocol_stack_info.current_stack_size_minus_one + 1;
+ real_protocol = packet->protocol_stack_info.entry_is_real_protocol;
+
+ for (a = 0; a < stack_size; a++) {
+ if(real_protocol & 1)
+ return packet->detected_protocol_stack[a];
+ real_protocol >>= 1;
+ }
+
+ return NDPI_PROTOCOL_UNKNOWN;
+#else
+ return packet->detected_protocol_stack[0];
+#endif
+}
+
+/*
+ * this function checks whether a protocol can be found in the
+ * history. Actually it accesses the packet stack since this is what
+ * leaves the library but it could also use the flow stack.
+ */
+u_int8_t ndpi_detection_flow_protocol_history_contains_protocol(struct ndpi_detection_module_struct * ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int16_t protocol_id)
+{
+ u_int8_t a;
+ u_int8_t stack_size;
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(!packet)
+ return 0;
+
+#if NDPI_PROTOCOL_HISTORY_SIZE > 1
+ stack_size = packet->protocol_stack_info.current_stack_size_minus_one + 1;
+#else
+ stack_size = 1;
+#endif
+
+ for (a = 0; a < stack_size; a++) {
+ if(packet->detected_protocol_stack[a] == protocol_id)
+ return 1;
+ }
+
+ return 0;
+}
+
+/* generic function for setting a protocol for a flow
+ *
+ * what it does is:
+ * 1.call ndpi_int_change_protocol
+ * 2.set protocol in detected bitmask for src and dst
+ */
+void ndpi_int_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type);
+
+/* generic function for changing the flow protocol
+ *
+ * what it does is:
+ * 1.update the flow protocol stack with the new protocol
+ */
+void ndpi_int_change_flow_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type);
+
+/* generic function for changing the packetprotocol
+ *
+ * what it does is:
+ * 1.update the packet protocol stack with the new protocol
+ */
+void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type);
+
+/* generic function for changing the protocol
+ *
+ * what it does is:
+ * 1.update the flow protocol stack with the new protocol
+ * 2.update the packet protocol stack with the new protocol
+ */
+void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int16_t detected_protocol,
+ ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_change_flow_protocol(ndpi_struct, flow, detected_protocol, protocol_type);
+ ndpi_int_change_packet_protocol(ndpi_struct, flow, detected_protocol, protocol_type);
+}
+
+
+/* turns a packet back to unknown */
+void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet) {
+ packet->detected_protocol_stack[0] = NDPI_PROTOCOL_UNKNOWN;
+
+#if NDPI_PROTOCOL_HISTORY_SIZE > 1
+ packet->protocol_stack_info.current_stack_size_minus_one = 0;
+ packet->protocol_stack_info.entry_is_real_protocol = 0;
+#endif
+}
+
+void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow)
+{
+ if(flow) {
+ flow->detected_protocol_stack[0] = NDPI_PROTOCOL_UNKNOWN;
+
+#if NDPI_PROTOCOL_HISTORY_SIZE > 1
+ flow->protocol_stack_info.current_stack_size_minus_one = 0;
+ flow->protocol_stack_info.entry_is_real_protocol = 0;
+#endif
+ }
+}
+
+void NDPI_PROTOCOL_IP_clear(ndpi_ip_addr_t * ip)
+{
+ memset(ip, 0, sizeof(ndpi_ip_addr_t));
+}
+
+/* NTOP */
+int NDPI_PROTOCOL_IP_is_set(const ndpi_ip_addr_t * ip)
+{
+ return memcmp(ip, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(ndpi_ip_addr_t)) != 0;
+}
+
+/* check if the source ip address in packet and ip are equal */
+/* NTOP */
+int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip)
+{
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ if(packet->iphv6 != NULL) {
+ if(packet->iphv6->saddr.ndpi_v6_u.u6_addr64[0] == ip->ipv6.ndpi_v6_u.u6_addr64[0] &&
+ packet->iphv6->saddr.ndpi_v6_u.u6_addr64[1] == ip->ipv6.ndpi_v6_u.u6_addr64[1]) {
+
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+#endif
+ if(packet->iph->saddr == ip->ipv4) {
+ return 1;
+ }
+ return 0;
+}
+
+/* check if the destination ip address in packet and ip are equal */
+int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip)
+{
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ if(packet->iphv6 != NULL) {
+ if(packet->iphv6->daddr.ndpi_v6_u.u6_addr64[0] == ip->ipv6.ndpi_v6_u.u6_addr64[0] &&
+ packet->iphv6->daddr.ndpi_v6_u.u6_addr64[1] == ip->ipv6.ndpi_v6_u.u6_addr64[1]) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+#endif
+ if(packet->iph->daddr == ip->ipv4) {
+ return 1;
+ }
+ return 0;
+}
+
+/* get the source ip address from packet and put it into ip */
+/* NTOP */
+void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip)
+{
+ NDPI_PROTOCOL_IP_clear(ip);
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ if(packet->iphv6 != NULL) {
+ ip->ipv6.ndpi_v6_u.u6_addr64[0] = packet->iphv6->saddr.ndpi_v6_u.u6_addr64[0];
+ ip->ipv6.ndpi_v6_u.u6_addr64[1] = packet->iphv6->saddr.ndpi_v6_u.u6_addr64[1];
+ } else
+#endif
+ ip->ipv4 = packet->iph->saddr;
+}
+
+/* get the destination ip address from packet and put it into ip */
+/* NTOP */
+void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip)
+{
+ NDPI_PROTOCOL_IP_clear(ip);
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ if(packet->iphv6 != NULL) {
+ ip->ipv6.ndpi_v6_u.u6_addr64[0] = packet->iphv6->daddr.ndpi_v6_u.u6_addr64[0];
+ ip->ipv6.ndpi_v6_u.u6_addr64[1] = packet->iphv6->daddr.ndpi_v6_u.u6_addr64[1];
+ } else
+#endif
+ ip->ipv4 = packet->iph->daddr;
+}
+
+#ifdef NDPI_ENABLE_DEBUG_MESSAGES
+/* get the string representation of ip
+ * returns a pointer to a static string
+ * only valid until the next call of this function */
+char *ndpi_get_ip_string(struct ndpi_detection_module_struct *ndpi_struct,
+ const ndpi_ip_addr_t * ip)
+{
+ const u_int8_t *a = (const u_int8_t *) &ip->ipv4;
+
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ if(ip->ipv6.ndpi_v6_u.u6_addr32[1] != 0 || ip->ipv6.ndpi_v6_u.u6_addr64[1] != 0) {
+ const u_int16_t *b = ip->ipv6.ndpi_v6_u.u6_addr16;
+ snprintf(ndpi_struct->ip_string, 32, "%x:%x:%x:%x:%x:%x:%x:%x",
+ ntohs(b[0]), ntohs(b[1]), ntohs(b[2]), ntohs(b[3]),
+ ntohs(b[4]), ntohs(b[5]), ntohs(b[6]), ntohs(b[7]));
+ return ndpi_struct->ip_string;
+ }
+#endif
+ snprintf(ndpi_struct->ip_string, 32, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
+ return ndpi_struct->ip_string;
+
+}
+
+
+/* get the string representation of the source ip address from packet */
+char *ndpi_get_packet_src_ip_string(struct ndpi_detection_module_struct *ndpi_struct,
+ const struct ndpi_packet_struct *packet)
+{
+ ndpi_ip_addr_t ip;
+ ndpi_packet_src_ip_get(packet, &ip);
+ return ndpi_get_ip_string(ndpi_struct, &ip);
+}
+
+/* get the string representation of the destination ip address from packet */
+char *ndpi_get_packet_dst_ip_string(struct ndpi_detection_module_struct *ndpi_struct,
+ const struct ndpi_packet_struct *packet)
+{
+ ndpi_ip_addr_t ip;
+ ndpi_packet_dst_ip_get(packet, &ip);
+ return ndpi_get_ip_string(ndpi_struct, &ip);
+}
+#endif /* NDPI_ENABLE_DEBUG_MESSAGES */
+
+/* ****************************************************** */
+
+u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read)
+{
+ u_int16_t val = ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read);
+ return ntohs(val);
+}
+
+/* ****************************************************** */
+
+#if 0
+#ifndef __KERNEL__
+static u_int is_port(u_int16_t sport, u_int16_t dport, u_int16_t match_port) {
+ return(((match_port == sport) || (match_port == dport)) ? 1 : 0);
+}
+#endif
+#endif
+
+/* ****************************************************** */
+
+unsigned int ndpi_find_port_based_protocol(struct ndpi_detection_module_struct *ndpi_struct /* NOTUSED */,
+ u_int8_t proto,
+ u_int32_t shost, u_int16_t sport,
+ u_int32_t dhost, u_int16_t dport) {
+ /* Skyfile (host 193.252.234.246 or host 10.10.102.80) */
+ if((shost == 0xC1FCEAF6) || (dhost == 0xC1FCEAF6)
+ || (shost == 0x0A0A6650) || (dhost == 0x0A0A6650)) {
+ if((sport == 4708) || (dport == 4708)) return(NDPI_PROTOCOL_SKYFILE_PREPAID);
+ else if((sport == 4709) || (dport == 4709)) return(NDPI_PROTOCOL_SKYFILE_RUDICS);
+ else if((sport == 4710) || (dport == 4710)) return(NDPI_PROTOCOL_SKYFILE_POSTPAID);
+ }
+
+ return(NDPI_PROTOCOL_UNKNOWN);
+}
+
+/* ****************************************************** */
+
+unsigned int ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int8_t proto,
+ u_int32_t shost /* host byte order */, u_int16_t sport,
+ u_int32_t dhost /* host byte order */, u_int16_t dport) {
+ unsigned int rc;
+ struct in_addr addr;
+
+ if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) {
+ rc = ndpi_search_tcp_or_udp_raw(ndpi_struct, proto, shost, dhost, sport, dport);
+ if(rc != NDPI_PROTOCOL_UNKNOWN) return(rc);
+
+ rc = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport);
+ if(rc != NDPI_PROTOCOL_UNKNOWN) {
+ if(rc == NDPI_PROTOCOL_SSL)
+ goto check_guessed_skype;
+ else
+ return(rc);
+ }
+
+ rc = ndpi_find_port_based_protocol(ndpi_struct, proto, shost, sport, dhost, dport);
+ if(rc != NDPI_PROTOCOL_UNKNOWN) return(rc);
+
+ check_guessed_skype:
+ addr.s_addr = shost;
+ if(ndpi_network_ptree_match(ndpi_struct, &addr) == NDPI_PROTOCOL_SKYPE) return(NDPI_PROTOCOL_SKYPE);
+
+ addr.s_addr = dhost;
+ if(ndpi_network_ptree_match(ndpi_struct, &addr) == NDPI_PROTOCOL_SKYPE) return(NDPI_PROTOCOL_SKYPE);
+
+ return(rc);
+ } else {
+ return(ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport));
+ }
+}
+
+/* ****************************************************** */
+
+char* ndpi_get_proto_name(struct ndpi_detection_module_struct *ndpi_mod, u_int16_t proto_id) {
+ if((proto_id >= ndpi_mod->ndpi_num_supported_protocols)
+ || ((proto_id < (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
+ && (ndpi_mod->proto_defaults[proto_id].protoName == NULL)))
+ proto_id = NDPI_PROTOCOL_UNKNOWN;
+
+ return(ndpi_mod->proto_defaults[proto_id].protoName);
+}
+
+/* ****************************************************** */
+
+ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *ndpi_mod,
+ u_int16_t proto_id) {
+ if((proto_id >= ndpi_mod->ndpi_num_supported_protocols)
+ || ((proto_id < (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
+ && (ndpi_mod->proto_defaults[proto_id].protoName == NULL)))
+ proto_id = NDPI_PROTOCOL_UNKNOWN;
+
+ return(ndpi_mod->proto_defaults[proto_id].protoBreed);
+}
+
+/* ****************************************************** */
+
+char* ndpi_get_proto_breed_name(struct ndpi_detection_module_struct *ndpi_mod,
+ ndpi_protocol_breed_t breed_id) {
+ switch(breed_id) {
+ case NDPI_PROTOCOL_SAFE:
+ return("Safe");
+ break;
+ case NDPI_PROTOCOL_ACCEPTABLE:
+ return("Acceptable");
+ break;
+ case NDPI_PROTOCOL_FUN:
+ return("Fun");
+ break;
+ case NDPI_PROTOCOL_UNSAFE:
+ return("Unsafe");
+ break;
+ case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS:
+ return("Dangerous");
+ break;
+
+ case NDPI_PROTOCOL_UNRATED:
+ default:
+ return("Unrated");
+ break;
+ }
+}
+
+/* ****************************************************** */
+
+int ndpi_get_protocol_id(struct ndpi_detection_module_struct *ndpi_mod, char *proto) {
+ int i;
+
+ for(i=0; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++)
+ if(strcasecmp(proto, ndpi_mod->proto_defaults[i].protoName) == 0)
+ return(i);
+
+ return(-1);
+}
+
+/* ****************************************************** */
+
+void ndpi_dump_protocols(struct ndpi_detection_module_struct *ndpi_mod) {
+ int i;
+
+ for(i=0; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++)
+ printf("[%3d] %s\n", i, ndpi_mod->proto_defaults[i].protoName);
+}
+
+/* ****************************************************** */
+
+/*
+ * Find the first occurrence of find in s, where the search is limited to the
+ * first slen characters of s.
+ */
+char* ndpi_strnstr(const char *s, const char *find, size_t slen) {
+ char c, sc;
+ size_t len;
+
+ if((c = *find++) != '\0') {
+ len = strlen(find);
+ do {
+ do {
+ if(slen-- < 1 || (sc = *s++) == '\0')
+ return (NULL);
+ } while (sc != c);
+ if(len > slen)
+ return (NULL);
+ } while (strncmp(s, find, len) != 0);
+ s--;
+ }
+ return ((char *)s);
+}
+
+/* ****************************************************** */
+
+static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct,
+ ndpi_automa *automa,
+ struct ndpi_flow_struct *flow,
+ char *string_to_match, u_int string_to_match_len) {
+ int matching_protocol_id;
+ struct ndpi_packet_struct *packet = &flow->packet;
+ AC_TEXT_t ac_input_text;
+
+ if((automa->ac_automa == NULL) || (string_to_match_len== 0)) return(NDPI_PROTOCOL_UNKNOWN);
+
+ if(!automa->ac_automa_finalized) {
+ ac_automata_finalize((AC_AUTOMATA_t*)automa->ac_automa);
+ automa->ac_automa_finalized = 1;
+ }
+
+ matching_protocol_id = NDPI_PROTOCOL_UNKNOWN;
+
+ ac_input_text.astring = string_to_match, ac_input_text.length = string_to_match_len;
+ ac_automata_search (((AC_AUTOMATA_t*)automa->ac_automa), &ac_input_text, (void*)&matching_protocol_id);
+
+ ac_automata_reset(((AC_AUTOMATA_t*)automa->ac_automa));
+
+#ifdef DEBUG
+ {
+ char m[256];
+ int len = ndpi_min(sizeof(m), string_to_match_len);
+
+ strncpy(m, string_to_match, len);
+ m[len] = '\0';
+
+ printf("[NDPI] ndpi_match_string_subprotocol(%s): %s\n", m, ndpi_struct->proto_defaults[matching_protocol_id].protoName);
+ }
+#endif
+
+ if(matching_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
+ packet->detected_protocol_stack[0] = matching_protocol_id;
+
+ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
+ flow->detected_protocol_stack[0] = packet->detected_protocol_stack[0];
+
+ return(packet->detected_protocol_stack[0]);
+ }
+
+#ifdef DEBUG
+ string_to_match[string_to_match_len] = '\0';
+ printf("[NTOP] Unable to find a match for '%s'\n", string_to_match);
+#endif
+
+ return(NDPI_PROTOCOL_UNKNOWN);
+}
+
+/* ****************************************************** */
+
+int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ char *string_to_match, u_int string_to_match_len) {
+ return(ndpi_automa_match_string_subprotocol(ndpi_struct, &ndpi_struct->host_automa,
+ flow, string_to_match, string_to_match_len));
+}
+
+/* ****************************************************** */
+
+int ndpi_match_content_subprotocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ char *string_to_match, u_int string_to_match_len) {
+ return(ndpi_automa_match_string_subprotocol(ndpi_struct, &ndpi_struct->content_automa,
+ flow, string_to_match, string_to_match_len));
+}
+
+/* ****************************************************** */
+
+int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_struct,
+ ndpi_automa *automa, char *bigram_to_match) {
+ AC_TEXT_t ac_input_text;
+ int ret = 0;
+
+ if((automa->ac_automa == NULL) || (bigram_to_match == NULL))
+ return(ret);
+
+ if(!automa->ac_automa_finalized) {
+ ac_automata_finalize((AC_AUTOMATA_t*)automa->ac_automa);
+ automa->ac_automa_finalized = 1;
+ }
+
+ ac_input_text.astring = bigram_to_match, ac_input_text.length = 2;
+ ac_automata_search(((AC_AUTOMATA_t*)automa->ac_automa), &ac_input_text, (void*)&ret);
+ ac_automata_reset(((AC_AUTOMATA_t*)automa->ac_automa));
+
+ return(ret);
+}
+
+/* ****************************************************** */
+
+void ndpi_free_flow(struct ndpi_flow_struct *flow) {
+ if(flow) {
+ if(flow->http.url) ndpi_free(flow->http.url);
+ if(flow->http.content_type) ndpi_free(flow->http.content_type);
+ ndpi_free(flow);
+ }
+}
+
+/* ****************************************************** */
+
+#ifndef __KERNEL__
+char* ndpi_revision() {
+ return(NDPI_SVN_RELEASE);
+}
+#endif
+
+/* ****************************************************** */
+
+#ifdef WIN32
+
+/*
+ int pthread_mutex_init(pthread_mutex_t *mutex, void *unused) {
+ unused = NULL;
+ *mutex = CreateMutex(NULL, FALSE, NULL);
+ return *mutex == NULL ? -1 : 0;
+ }
+
+ int pthread_mutex_destroy(pthread_mutex_t *mutex) {
+ return CloseHandle(*mutex) == 0 ? -1 : 0;
+ }
+
+ int pthread_mutex_lock(pthread_mutex_t *mutex) {
+ return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
+ }
+
+ int pthread_mutex_unlock(pthread_mutex_t *mutex) {
+ return ReleaseMutex(*mutex) == 0 ? -1 : 0;
+ }
+*/
+/* http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/port/gettimeofday.c;h=75a91993b74414c0a1c13a2a09ce739cb8aa8a08;hb=HEAD */
+int gettimeofday(struct timeval * tp, struct timezone * tzp) {
+ /* FILETIME of Jan 1 1970 00:00:00. */
+ const unsigned __int64 epoch = (__int64)(116444736000000000);
+
+ FILETIME file_time;
+ SYSTEMTIME system_time;
+ ULARGE_INTEGER ularge;
+
+ GetSystemTime(&system_time);
+ SystemTimeToFileTime(&system_time, &file_time);
+ ularge.LowPart = file_time.dwLowDateTime;
+ ularge.HighPart = file_time.dwHighDateTime;
+
+ tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L);
+ tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
+
+ return 0;
+}
+#endif
+
+int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b) {
+ int i;
+
+ for(i=0; i<NDPI_NUM_FDS_BITS; i++) {
+ if(a.fds_bits[i] & b.fds_bits[i])
+ return(1);
+ }
+
+ return(0);
+}
+
+int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a) {
+ int i;
+
+ for(i=0; i<NDPI_NUM_FDS_BITS; i++)
+ if(a.fds_bits[i] != 0)
+ return(0);
+
+ return(1);
+}
+
+void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a) {
+ int i;
+
+ for(i=0; i<NDPI_NUM_FDS_BITS; i++)
+ printf("[%d=%u]", i, a.fds_bits[i]);
+
+ printf("\n");
+}
+
+
+#ifdef WIN32
+/* http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/strsep.c */
+
+/*
+ * Get next token from string *stringp, where tokens are possibly-empty
+ * strings separated by characters from delim.
+ *
+ * Writes NULs into the string at *stringp to end tokens.
+ * delim need not remain constant from call to call.
+ * On return, *stringp points past the last NUL written (if there might
+ * be further tokens), or is NULL (if there are definitely no more tokens).
+ *
+ * If *stringp is NULL, strsep returns NULL.
+ */
+char* strsep(char **stringp, const char *delim) {
+ char *s;
+ const char *spanp;
+ int c, sc;
+ char *tok;
+
+ if((s = *stringp) == NULL)
+ return (NULL);
+ for (tok = s;;) {
+ c = *s++;
+ spanp = delim;
+ do {
+ if((sc = *spanp++) == c) {
+ if(c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *stringp = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
+#endif
+
+
diff --git a/src/lib/protocols/afp.c b/src/lib/protocols/afp.c
new file mode 100644
index 000000000..b400f53c5
--- /dev/null
+++ b/src/lib/protocols/afp.c
@@ -0,0 +1,75 @@
+/*
+ * afp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_AFP
+
+static void ndpi_int_afp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_AFP, NDPI_REAL_PROTOCOL);
+}
+
+
+void ndpi_search_afp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // struct ndpi_id_struct *src = flow->src;
+// struct ndpi_id_struct *dst = flow->dst;
+
+
+ /*
+ * this will detect the OpenSession command of the Data Stream Interface (DSI) protocol
+ * which is exclusively used by the Apple Filing Protocol (AFP) on TCP/IP networks
+ */
+ if (packet->payload_packet_len >= 22 && get_u_int16_t(packet->payload, 0) == htons(0x0004) &&
+ get_u_int16_t(packet->payload, 2) == htons(0x0001) && get_u_int32_t(packet->payload, 4) == 0 &&
+ get_u_int32_t(packet->payload, 8) == htonl(packet->payload_packet_len - 16) &&
+ get_u_int32_t(packet->payload, 12) == 0 && get_u_int16_t(packet->payload, 16) == htons(0x0104)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP: DSI OpenSession detected.\n");
+ ndpi_int_afp_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ /*
+ * detection of GetStatus command of DSI protocl
+ */
+ if (packet->payload_packet_len >= 18 && get_u_int16_t(packet->payload, 0) == htons(0x0003) &&
+ get_u_int16_t(packet->payload, 2) == htons(0x0001) && get_u_int32_t(packet->payload, 4) == 0 &&
+ get_u_int32_t(packet->payload, 8) == htonl(packet->payload_packet_len - 16) &&
+ get_u_int32_t(packet->payload, 12) == 0 && get_u_int16_t(packet->payload, 16) == htons(0x0f00)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP: DSI GetStatus detected.\n");
+ ndpi_int_afp_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+
+ NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_AFP);
+}
+
+#endif
diff --git a/src/lib/protocols/aimini.c b/src/lib/protocols/aimini.c
new file mode 100644
index 000000000..165ee2fc4
--- /dev/null
+++ b/src/lib/protocols/aimini.c
@@ -0,0 +1,283 @@
+/*
+ * aimini.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_AIMINI
+
+
+static void ndpi_int_aimini_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
+ ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_AIMINI, protocol_type);
+}
+
+
+static u_int8_t is_special_aimini_host(struct ndpi_int_one_line_struct host_line)
+{
+ if (host_line.ptr != NULL && host_line.len >= NDPI_STATICSTRING_LEN("X.X.X.X.aimini.net")) {
+ if ((get_u_int32_t(host_line.ptr, 0) & htonl(0x00ff00ff)) == htonl(0x002e002e) &&
+ (get_u_int32_t(host_line.ptr, 4) & htonl(0x00ff00ff)) == htonl(0x002e002e) &&
+ memcmp(&host_line.ptr[8], "aimini.net", NDPI_STATICSTRING_LEN("aimini.net")) == 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void ndpi_search_aimini(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "search aimini.\n");
+
+ if (packet->udp != NULL) {
+ if (flow->l4.udp.aimini_stage == 0) {
+ if (packet->payload_packet_len == 64 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010b) {
+ flow->l4.udp.aimini_stage = 1;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 1.\n");
+ return;
+ }
+ if (packet->payload_packet_len == 136
+ && (ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9 || ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165)) {
+ flow->l4.udp.aimini_stage = 4;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 4.\n");
+ return;
+ }
+ if (packet->payload_packet_len == 88 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101) {
+ flow->l4.udp.aimini_stage = 7;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 7.\n");
+ return;
+ }
+ if (packet->payload_packet_len == 104 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102) {
+ flow->l4.udp.aimini_stage = 10;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 10.\n");
+ return;
+ }
+ if (packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca) {
+ flow->l4.udp.aimini_stage = 13;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 13.\n");
+ return;
+ }
+ if (packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c) {
+ flow->l4.udp.aimini_stage = 16;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 16.\n");
+ return;
+ }
+ }
+ /* first packet chronology: (len, value): (64, 0x010b), (>100, 0x0115), (16, 0x010c || 64, 0x010b || 88, 0x0115),
+ * (16, 0x010c || 64, 0x010b || >100, 0x0115)
+ */
+ if (flow->l4.udp.aimini_stage == 1 && packet->payload_packet_len > 100
+ && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0115) {
+ flow->l4.udp.aimini_stage = 2;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 2.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 2 &&
+ ((packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 0) == htons(0x010c)) ||
+ (packet->payload_packet_len == 64 && get_u_int16_t(packet->payload, 0) == htons(0x010b)) ||
+ (packet->payload_packet_len == 88 && get_u_int16_t(packet->payload, 0) == ntohs(0x0115)))) {
+ flow->l4.udp.aimini_stage = 3;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 3.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 3
+ && ((packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c)
+ || (packet->payload_packet_len == 64 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010b)
+ || (packet->payload_packet_len > 100 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0115))) {
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "found aimini (64, 0x010b), (>300, 0x0115), "
+ "(16, 0x010c || 64, 0x010b), (16, 0x010c || 64, 0x010b || >100, 0x0115).\n");
+ ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ /* second packet chronology: (len, value): (136, 0x01c9), (136, 0x01c9),(136, 0x01c9),(136, 0x01c9 || 32, 0x01ca) */
+
+ if (flow->l4.udp.aimini_stage == 4 && packet->payload_packet_len == 136
+ && (ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9 || ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165)) {
+ flow->l4.udp.aimini_stage = 5;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 5.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 5 && (packet->payload_packet_len == 136
+ && (ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9
+ || ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165))) {
+ flow->l4.udp.aimini_stage = 6;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 6.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 6 && ((packet->payload_packet_len == 136
+ && ((ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165)
+ || ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9))
+ || (packet->payload_packet_len == 32
+ && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca))) {
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
+ "found aimini (136, 0x01c9), (136, 0x01c9)," "(136, 0x01c9),(136, 0x01c9 || 32, 0x01ca).\n");
+ ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ /* third packet chronology: (len, value): (88, 0x0101), (88, 0x0101),(88, 0x0101),(88, 0x0101) */
+
+ if (flow->l4.udp.aimini_stage == 7 && packet->payload_packet_len == 88
+ && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101) {
+ flow->l4.udp.aimini_stage = 8;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 8.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 8
+ && (packet->payload_packet_len == 88 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101)) {
+ flow->l4.udp.aimini_stage = 9;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 9.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 9
+ && (packet->payload_packet_len == 88 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101)) {
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
+ "found aimini (88, 0x0101), (88, 0x0101)," "(88, 0x0101),(88, 0x0101).\n");
+ ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ /* fourth packet chronology: (len, value): (104, 0x0102), (104, 0x0102), (104, 0x0102), (104, 0x0102) */
+
+ if (flow->l4.udp.aimini_stage == 10 && packet->payload_packet_len == 104
+ && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102) {
+ flow->l4.udp.aimini_stage = 11;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 11.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 11
+ && (packet->payload_packet_len == 104 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102)) {
+ flow->l4.udp.aimini_stage = 12;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 12.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 12
+ && ((packet->payload_packet_len == 104 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102)
+ || (packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca))) {
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
+ "found aimini (104, 0x0102), (104, 0x0102), " "(104, 0x0102), (104, 0x0102).\n");
+ ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ /* fifth packet chronology (len, value): (32,0x01ca), (32,0x01ca), (32,0x01ca), ((136, 0x0166) || (32,0x01ca)) */
+
+ if (flow->l4.udp.aimini_stage == 13 && packet->payload_packet_len == 32
+ && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca) {
+ flow->l4.udp.aimini_stage = 14;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 14.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 14
+ && ((packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca)
+ || (packet->payload_packet_len == 136 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0166))) {
+ flow->l4.udp.aimini_stage = 15;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 15.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 15
+ && ((packet->payload_packet_len == 136 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0166)
+ || (packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca))) {
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
+ "found aimini (32,0x01ca), (32,0x01ca), (32,0x01ca), ((136, 0x0166)||(32,0x01ca)).\n");
+ ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ /* sixth packet chronology (len, value): (16, 0x010c), (16, 0x010c), (16, 0x010c), (16, 0x010c) */
+
+ if (flow->l4.udp.aimini_stage == 16 && packet->payload_packet_len == 16
+ && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c) {
+ flow->l4.udp.aimini_stage = 17;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 17.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 17
+ && (packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c)) {
+ flow->l4.udp.aimini_stage = 18;
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 18.\n");
+ return;
+ }
+ if (flow->l4.udp.aimini_stage == 18
+ && (packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c)) {
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
+ "found aimini (16, 0x010c), (16, 0x010c), (16, 0x010c), (16, 0x010c).\n");
+ ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ } else if (packet->tcp != NULL) {
+ if ((packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /player/") &&
+ (memcmp(packet->payload, "GET /player/", NDPI_STATICSTRING_LEN("GET /player/")) == 0)) ||
+ (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /play/?fid=") &&
+ (memcmp(packet->payload, "GET /play/?fid=", NDPI_STATICSTRING_LEN("GET /play/?fid=")) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "HTTP packet detected.\n");
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->host_line.ptr != NULL && packet->host_line.len > 11
+ && (memcmp(&packet->host_line.ptr[packet->host_line.len - 11], ".aimini.net", 11) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "AIMINI HTTP traffic detected.\n");
+ ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ if (packet->payload_packet_len > 100) {
+ if (memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0) {
+ if (memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /")], "play/",
+ NDPI_STATICSTRING_LEN("play/")) == 0 ||
+ memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /")], "download/",
+ NDPI_STATICSTRING_LEN("download/")) == 0) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (is_special_aimini_host(packet->host_line) == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
+ "AIMINI HTTP traffic detected.\n");
+ ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ } else if (memcmp(packet->payload, "POST /", NDPI_STATICSTRING_LEN("POST /")) == 0) {
+ if (memcmp(&packet->payload[NDPI_STATICSTRING_LEN("POST /")], "upload/",
+ NDPI_STATICSTRING_LEN("upload/")) == 0) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (is_special_aimini_host(packet->host_line) == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
+ "AIMINI HTTP traffic detected.\n");
+ ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "exclude aimini.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_AIMINI);
+
+}
+#endif
diff --git a/src/lib/protocols/applejuice.c b/src/lib/protocols/applejuice.c
new file mode 100644
index 000000000..d989d571b
--- /dev/null
+++ b/src/lib/protocols/applejuice.c
@@ -0,0 +1,57 @@
+/*
+ * applejuice.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_APPLEJUICE
+
+
+static void ndpi_int_applejuice_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_APPLEJUICE, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_applejuice_tcp(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_APPLEJUICE, ndpi_struct, NDPI_LOG_DEBUG, "search applejuice.\n");
+
+ if ((packet->payload_packet_len > 7) && (packet->payload[6] == 0x0d)
+ && (packet->payload[7] == 0x0a)
+ && (memcmp(packet->payload, "ajprot", 6) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_APPLEJUICE, ndpi_struct, NDPI_LOG_DEBUG, "detected applejuice.\n");
+ ndpi_int_applejuice_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_APPLEJUICE, ndpi_struct, NDPI_LOG_DEBUG, "exclude applejuice.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_APPLEJUICE);
+}
+
+#endif
diff --git a/src/lib/protocols/armagetron.c b/src/lib/protocols/armagetron.c
new file mode 100644
index 000000000..6c5064fda
--- /dev/null
+++ b/src/lib/protocols/armagetron.c
@@ -0,0 +1,102 @@
+/*
+ * armagetron.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+/* include files */
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_ARMAGETRON
+
+
+static void ndpi_int_armagetron_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_ARMAGETRON, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_armagetron_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "search armagetron.\n");
+
+
+ if (packet->payload_packet_len > 10) {
+ /* login request */
+ if (get_u_int32_t(packet->payload, 0) == htonl(0x000b0000)) {
+ const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4));
+ if (dataLength == 0 || dataLength * 2 + 8 != packet->payload_packet_len)
+ goto exclude;
+ if (get_u_int16_t(packet->payload, 6) == htons(0x0008)
+ && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "detected armagetron.\n");
+ ndpi_int_armagetron_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ /* sync_msg */
+ if (packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 0) == htons(0x001c)
+ && get_u_int16_t(packet->payload, 2) != 0) {
+ const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4));
+ if (dataLength != 4)
+ goto exclude;
+ if (get_u_int32_t(packet->payload, 6) == htonl(0x00000500) && get_u_int32_t(packet->payload, 6 + 4) == htonl(0x00010000)
+ && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "detected armagetron.\n");
+ ndpi_int_armagetron_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ /* net_sync combination */
+ if (packet->payload_packet_len > 50 && get_u_int16_t(packet->payload, 0) == htons(0x0018)
+ && get_u_int16_t(packet->payload, 2) != 0) {
+ u_int16_t val;
+ const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4));
+ if (dataLength == 0 || dataLength * 2 + 8 > packet->payload_packet_len)
+ goto exclude;
+ val = get_u_int16_t(packet->payload, 6 + 2);
+ if (val == get_u_int16_t(packet->payload, 6 + 6)) {
+ val = ntohs(get_u_int16_t(packet->payload, 6 + 8));
+ if ((6 + 10 + val + 4) < packet->payload_packet_len
+ && (get_u_int32_t(packet->payload, 6 + 10 + val) == htonl(0x00010000)
+ || get_u_int32_t(packet->payload, 6 + 10 + val) == htonl(0x00000001))
+ && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "detected armagetron.\n");
+ ndpi_int_armagetron_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+ }
+
+ exclude:
+ NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "exclude armagetron.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ARMAGETRON);
+}
+
+#endif
diff --git a/src/lib/protocols/attic/flash.c b/src/lib/protocols/attic/flash.c
new file mode 100644
index 000000000..e6b89a185
--- /dev/null
+++ b/src/lib/protocols/attic/flash.c
@@ -0,0 +1,93 @@
+/*
+ * flash.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_FLASH
+
+static void ndpi_int_flash_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FLASH, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_flash(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (flow->l4.tcp.flash_stage == 0 && packet->payload_packet_len > 0
+ && (packet->payload[0] == 0x03 || packet->payload[0] == 0x06)) {
+ flow->l4.tcp.flash_bytes = packet->payload_packet_len;
+ if (packet->tcp->psh == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG, "FLASH pass 1: \n");
+ flow->l4.tcp.flash_stage = packet->packet_direction + 1;
+
+ NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG,
+ "FLASH pass 1: flash_stage: %u, flash_bytes: %u\n", flow->l4.tcp.flash_stage,
+ flow->l4.tcp.flash_bytes);
+ return;
+ } else if (packet->tcp->psh != 0 && flow->l4.tcp.flash_bytes == 1537) {
+ NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG,
+ "FLASH hit: flash_stage: %u, flash_bytes: %u\n", flow->l4.tcp.flash_stage,
+ flow->l4.tcp.flash_bytes);
+ flow->l4.tcp.flash_stage = 3;
+ ndpi_int_flash_add_connection(ndpi_struct, flow);
+ return;
+ }
+ } else if (flow->l4.tcp.flash_stage == 1 + packet->packet_direction) {
+ flow->l4.tcp.flash_bytes += packet->payload_packet_len;
+ if (packet->tcp->psh != 0 && flow->l4.tcp.flash_bytes == 1537) {
+ NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG,
+ "FLASH hit: flash_stage: %u, flash_bytes: %u\n", flow->l4.tcp.flash_stage,
+ flow->l4.tcp.flash_bytes);
+ flow->l4.tcp.flash_stage = 3;
+ ndpi_int_flash_add_connection(ndpi_struct, flow);
+ return;
+ } else if (packet->tcp->psh == 0 && flow->l4.tcp.flash_bytes < 1537) {
+ NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG,
+ "FLASH pass 2: flash_stage: %u, flash_bytes: %u\n", flow->l4.tcp.flash_stage,
+ flow->l4.tcp.flash_bytes);
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG,
+ "FLASH might be excluded: flash_stage: %u, flash_bytes: %u, packet_direction: %u\n",
+ flow->l4.tcp.flash_stage, flow->l4.tcp.flash_bytes, packet->packet_direction);
+
+#ifdef NDPI_PROTOCOL_HTTP
+ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP) != 0) {
+#endif /* NDPI_PROTOCOL_HTTP */
+ NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG, "FLASH: exclude\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FLASH);
+#ifdef NDPI_PROTOCOL_HTTP
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG, "FLASH avoid early exclude from http\n");
+ }
+#endif /* NDPI_PROTOCOL_HTTP */
+
+}
+#endif
diff --git a/src/lib/protocols/attic/ftp.c b/src/lib/protocols/attic/ftp.c
new file mode 100644
index 000000000..f48f3e946
--- /dev/null
+++ b/src/lib/protocols/attic/ftp.c
@@ -0,0 +1,469 @@
+/*
+ * ftp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#include "ndpi_utils.h"
+
+#ifdef NDPI_PROTOCOL_FTP
+
+
+static void ndpi_int_ftp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FTP, NDPI_REAL_PROTOCOL);
+}
+
+/**
+ * checks for possible FTP command
+ * not all valid commands are tested, it just need to be 3 or 4 characters followed by a space if the
+ * packet is longer
+ *
+ * this functions is not used to accept, just to not reject
+ */
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+u_int8_t ndpi_int_check_possible_ftp_command(const struct ndpi_packet_struct *packet)
+{
+ if (packet->payload_packet_len < 3)
+ return 0;
+
+ if ((packet->payload[0] < 'a' || packet->payload[0] > 'z') &&
+ (packet->payload[0] < 'A' || packet->payload[0] > 'Z'))
+ return 0;
+ if ((packet->payload[1] < 'a' || packet->payload[1] > 'z') &&
+ (packet->payload[1] < 'A' || packet->payload[1] > 'Z'))
+ return 0;
+ if ((packet->payload[2] < 'a' || packet->payload[2] > 'z') &&
+ (packet->payload[2] < 'A' || packet->payload[2] > 'Z'))
+ return 0;
+
+ if (packet->payload_packet_len > 3) {
+ if ((packet->payload[3] < 'a' || packet->payload[3] > 'z') &&
+ (packet->payload[3] < 'A' || packet->payload[3] > 'Z') && packet->payload[3] != ' ')
+ return 0;
+
+ if (packet->payload_packet_len > 4) {
+ if (packet->payload[3] != ' ' && packet->payload[4] != ' ')
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/**
+ * ftp replies are are 3-digit number followed by space or hyphen
+ */
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+u_int8_t ndpi_int_check_possible_ftp_reply(const struct ndpi_packet_struct *packet)
+{
+ if (packet->payload_packet_len < 5)
+ return 0;
+
+ if (packet->payload[3] != ' ' && packet->payload[3] != '-')
+ return 0;
+
+ if (packet->payload[0] < '0' || packet->payload[0] > '9')
+ return 0;
+ if (packet->payload[1] < '0' || packet->payload[1] > '9')
+ return 0;
+ if (packet->payload[2] < '0' || packet->payload[2] > '9')
+ return 0;
+
+ return 1;
+}
+
+/**
+ * check for continuation replies
+ * there is no real indication whether it is a continuation message, we just
+ * require that there are at least 5 ascii characters
+ */
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+u_int8_t ndpi_int_check_possible_ftp_continuation_reply(const struct ndpi_packet_struct *packet)
+{
+ u_int16_t i;
+
+ if (packet->payload_packet_len < 5)
+ return 0;
+
+ for (i = 0; i < 5; i++) {
+ if (packet->payload[i] < ' ' || packet->payload[i] > 127)
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * these are the commands we tracking and expecting to see
+ */
+enum {
+ FTP_USER_CMD = 1 << 0,
+ FTP_FEAT_CMD = 1 << 1,
+ FTP_COMMANDS = ((1 << 2) - 1),
+ FTP_220_CODE = 1 << 2,
+ FTP_331_CODE = 1 << 3,
+ FTP_211_CODE = 1 << 4,
+ FTP_CODES = ((1 << 5) - 1 - FTP_COMMANDS)
+};
+
+/*
+ return 0 if nothing has been detected
+ return 1 if a pop packet
+*/
+
+static u_int8_t search_ftp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ u_int8_t current_ftp_code = 0;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ /* initiate client direction flag */
+ if (flow->packet_counter == 1) {
+ if (flow->l4.tcp.seen_syn) {
+ flow->l4.tcp.ftp_client_direction = flow->setup_packet_direction;
+ } else {
+ /* no syn flag seen so guess */
+ if (packet->payload_packet_len > 0) {
+ if (packet->payload[0] >= '0' && packet->payload[0] <= '9') {
+ /* maybe server side */
+ flow->l4.tcp.ftp_client_direction = 1 - packet->packet_direction;
+ } else {
+ flow->l4.tcp.ftp_client_direction = packet->packet_direction;
+ }
+ }
+ }
+ }
+
+ if (packet->packet_direction == flow->l4.tcp.ftp_client_direction) {
+ if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("USER ") &&
+ (memcmp(packet->payload, "USER ", NDPI_STATICSTRING_LEN("USER ")) == 0 ||
+ memcmp(packet->payload, "user ", NDPI_STATICSTRING_LEN("user ")) == 0)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP: found USER command\n");
+ flow->l4.tcp.ftp_codes_seen |= FTP_USER_CMD;
+ current_ftp_code = FTP_USER_CMD;
+ } else if (packet->payload_packet_len >= NDPI_STATICSTRING_LEN("FEAT") &&
+ (memcmp(packet->payload, "FEAT", NDPI_STATICSTRING_LEN("FEAT")) == 0 ||
+ memcmp(packet->payload, "feat", NDPI_STATICSTRING_LEN("feat")) == 0)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP: found FEAT command\n");
+ flow->l4.tcp.ftp_codes_seen |= FTP_FEAT_CMD;
+ current_ftp_code = FTP_FEAT_CMD;
+ } else if (!ndpi_int_check_possible_ftp_command(packet)) {
+ return 0;
+ }
+ } else {
+ if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("220 ") &&
+ (memcmp(packet->payload, "220 ", NDPI_STATICSTRING_LEN("220 ")) == 0 ||
+ memcmp(packet->payload, "220-", NDPI_STATICSTRING_LEN("220-")) == 0)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP: found 220 reply code\n");
+ flow->l4.tcp.ftp_codes_seen |= FTP_220_CODE;
+ current_ftp_code = FTP_220_CODE;
+ } else if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("331 ") &&
+ (memcmp(packet->payload, "331 ", NDPI_STATICSTRING_LEN("331 ")) == 0 ||
+ memcmp(packet->payload, "331-", NDPI_STATICSTRING_LEN("331-")) == 0)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP: found 331 reply code\n");
+ flow->l4.tcp.ftp_codes_seen |= FTP_331_CODE;
+ current_ftp_code = FTP_331_CODE;
+ } else if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("211 ") &&
+ (memcmp(packet->payload, "211 ", NDPI_STATICSTRING_LEN("211 ")) == 0 ||
+ memcmp(packet->payload, "211-", NDPI_STATICSTRING_LEN("211-")) == 0)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP: found 211reply code\n");
+ flow->l4.tcp.ftp_codes_seen |= FTP_211_CODE;
+ current_ftp_code = FTP_211_CODE;
+ } else if (!ndpi_int_check_possible_ftp_reply(packet)) {
+ if ((flow->l4.tcp.ftp_codes_seen & FTP_CODES) == 0 ||
+ (!ndpi_int_check_possible_ftp_continuation_reply(packet))) {
+ return 0;
+ }
+ }
+ }
+
+ if ((flow->l4.tcp.ftp_codes_seen & FTP_COMMANDS) != 0 && (flow->l4.tcp.ftp_codes_seen & FTP_CODES) != 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP detected\n");
+ ndpi_int_ftp_add_connection(ndpi_struct, flow);
+ return 1;
+ }
+
+ /* if no valid code has been seen for the first packets reject */
+ if (flow->l4.tcp.ftp_codes_seen == 0 && flow->packet_counter > 3)
+ return 0;
+
+ /* otherwise wait more packets, wait more for traffic on known ftp port */
+ if ((packet->packet_direction == flow->setup_packet_direction && packet->tcp && packet->tcp->dest == htons(21)) ||
+ (packet->packet_direction != flow->setup_packet_direction && packet->tcp && packet->tcp->source == htons(21))) {
+ /* flow to known ftp port */
+
+ /* wait much longer if this was a 220 code, initial messages might be long */
+ if (current_ftp_code == FTP_220_CODE) {
+ if (flow->packet_counter > 40)
+ return 0;
+ } else {
+ if (flow->packet_counter > 20)
+ return 0;
+ }
+ } else {
+ /* wait much longer if this was a 220 code, initial messages might be long */
+ if (current_ftp_code == FTP_220_CODE) {
+ if (flow->packet_counter > 20)
+ return 0;
+ } else {
+ if (flow->packet_counter > 10)
+ return 0;
+ }
+ }
+
+ return 2;
+}
+
+
+static void search_passive_ftp_mode(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *dst = flow->dst;
+ struct ndpi_id_struct *src = flow->src;
+ u_int16_t plen;
+ u_int8_t i;
+ u_int32_t ftp_ip;
+
+
+ // TODO check if normal passive mode also needs adaption for ipv6
+ if (packet->payload_packet_len > 3 && ndpi_mem_cmp(packet->payload, "227 ", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP passive mode initial string\n");
+
+ plen = 4; //=4 for "227 "
+ while (1) {
+ if (plen >= packet->payload_packet_len) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "plen >= packet->payload_packet_len, return\n");
+ return;
+ }
+ if (packet->payload[plen] == '(') {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "found (. break.\n");
+ break;
+ }
+ /* if (!isalnum(packet->payload[plen])) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "no alpha numeric symbol --> break.\n");
+ return;
+ }*/
+ plen++;
+ }
+ plen++;
+
+ if (plen >= packet->payload_packet_len)
+ return;
+
+
+ ftp_ip = 0;
+ for (i = 0; i < 4; i++) {
+ u_int16_t oldplen = plen;
+ ftp_ip =
+ (ftp_ip << 8) +
+ ndpi_bytestream_to_number(&packet->payload[plen], packet->payload_packet_len - plen, &plen);
+ if (oldplen == plen || plen >= packet->payload_packet_len) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP passive mode %u value parse failed\n",
+ i);
+ return;
+ }
+ if (packet->payload[plen] != ',') {
+
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "FTP passive mode %u value parse failed, char ',' is missing\n", i);
+ return;
+ }
+ plen++;
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "FTP passive mode %u value parsed, ip is now: %u\n", i, ftp_ip);
+
+ }
+ if (dst != NULL) {
+ dst->ftp_ip.ipv4 = htonl(ftp_ip);
+ dst->ftp_timer = packet->tick_timestamp;
+ dst->ftp_timer_set = 1;
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to dst");
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP PASSIVE MODE FOUND: use Server %s\n",
+ ndpi_get_ip_string(ndpi_struct, &dst->ftp_ip));
+ }
+ if (src != NULL) {
+ src->ftp_ip.ipv4 = packet->iph->daddr;
+ src->ftp_timer = packet->tick_timestamp;
+ src->ftp_timer_set = 1;
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to src");
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP PASSIVE MODE FOUND: use Server %s\n",
+ ndpi_get_ip_string(ndpi_struct, &src->ftp_ip));
+ }
+ return;
+ }
+
+ if (packet->payload_packet_len > 34 && ndpi_mem_cmp(packet->payload, "229 Entering Extended Passive Mode", 34) == 0) {
+ if (dst != NULL) {
+ ndpi_packet_src_ip_get(packet, &dst->ftp_ip);
+ dst->ftp_timer = packet->tick_timestamp;
+ dst->ftp_timer_set = 1;
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to dst");
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "FTP Extended PASSIVE MODE FOUND: use Server %s\n", ndpi_get_ip_string(ndpi_struct, &dst->ftp_ip));
+ }
+ if (src != NULL) {
+ ndpi_packet_dst_ip_get(packet, &src->ftp_ip);
+ src->ftp_timer = packet->tick_timestamp;
+ src->ftp_timer_set = 1;
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to src");
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "FTP Extended PASSIVE MODE FOUND: use Server %s\n", ndpi_get_ip_string(ndpi_struct, &src->ftp_ip));
+ }
+ return;
+ }
+}
+
+
+static void search_active_ftp_mode(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ if (packet->payload_packet_len > 5
+ && (ndpi_mem_cmp(packet->payload, "PORT ", 5) == 0 || ndpi_mem_cmp(packet->payload, "EPRT ", 5) == 0)) {
+
+ //src->local_ftp_data_port = htons(data_port_number);
+ if (src != NULL) {
+ ndpi_packet_dst_ip_get(packet, &src->ftp_ip);
+ src->ftp_timer = packet->tick_timestamp;
+ src->ftp_timer_set = 1;
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP ACTIVE MODE FOUND, command is %.*s\n", 4,
+ packet->payload);
+ }
+ if (dst != NULL) {
+ ndpi_packet_src_ip_get(packet, &dst->ftp_ip);
+ dst->ftp_timer = packet->tick_timestamp;
+ dst->ftp_timer_set = 1;
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP ACTIVE MODE FOUND, command is %.*s\n", 4,
+ packet->payload);
+ }
+ }
+ return;
+}
+
+
+void ndpi_search_ftp_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+
+
+ if (src != NULL && ndpi_packet_dst_ip_eql(packet, &src->ftp_ip)
+ && packet->tcp->syn != 0 && packet->tcp->ack == 0
+ && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask,
+ NDPI_PROTOCOL_FTP) != 0 && src->ftp_timer_set != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "possible ftp data, src!= 0.\n");
+
+ if (((u_int32_t)
+ (packet->tick_timestamp - src->ftp_timer)) >= ndpi_struct->ftp_connection_timeout) {
+ src->ftp_timer_set = 0;
+ } else if (ntohs(packet->tcp->dest) > 1024
+ && (ntohs(packet->tcp->source) > 1024 || ntohs(packet->tcp->source) == 20)) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "detected FTP data stream.\n");
+ ndpi_int_ftp_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ if (dst != NULL && ndpi_packet_src_ip_eql(packet, &dst->ftp_ip)
+ && packet->tcp->syn != 0 && packet->tcp->ack == 0
+ && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask,
+ NDPI_PROTOCOL_FTP) != 0 && dst->ftp_timer_set != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "possible ftp data; dst!= 0.\n");
+
+ if (((u_int32_t)
+ (packet->tick_timestamp - dst->ftp_timer)) >= ndpi_struct->ftp_connection_timeout) {
+ dst->ftp_timer_set = 0;
+
+ } else if (ntohs(packet->tcp->dest) > 1024
+ && (ntohs(packet->tcp->source) > 1024 || ntohs(packet->tcp->source) == 20)) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "detected FTP data stream.\n");
+ ndpi_int_ftp_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ // ftp data asymmetrically
+
+
+ /* skip packets without payload */
+ if (packet->payload_packet_len == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "FTP test skip because of data connection or zero byte packet_payload.\n");
+ return;
+ }
+ /* skip excluded connections */
+
+ // we test for FTP connection and search for passive mode
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_FTP) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "detected ftp command mode. going to test data mode.\n");
+ search_passive_ftp_mode(ndpi_struct, flow);
+
+ search_active_ftp_mode(ndpi_struct, flow);
+ return;
+ }
+
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && search_ftp(ndpi_struct, flow) != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "unknown. need next packet.\n");
+
+ return;
+ }
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FTP);
+ NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude ftp.\n");
+
+}
+
+#endif
diff --git a/src/lib/protocols/attic/manolito.c b/src/lib/protocols/attic/manolito.c
new file mode 100644
index 000000000..f4ffba0cc
--- /dev/null
+++ b/src/lib/protocols/attic/manolito.c
@@ -0,0 +1,180 @@
+/*
+ * manolito.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_MANOLITO
+
+static void ndpi_int_manolito_add_connection(struct
+ ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MANOLITO, NDPI_REAL_PROTOCOL);
+
+
+ if (src != NULL) {
+ if (packet->udp != NULL) {
+ src->manolito_last_pkt_arrival_time = packet->tick_timestamp;
+ }
+ }
+ if (dst != NULL) {
+ if (packet->udp != NULL) {
+ dst->manolito_last_pkt_arrival_time = packet->tick_timestamp;
+ }
+ }
+}
+
+/*
+ return 0 if nothing has been detected
+ return 1 if it is a megaupload packet
+*/
+u_int8_t search_manolito_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
+u_int8_t search_manolito_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src = flow->src;
+ // struct ndpi_id_struct *dst = flow->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO TCP DETECTION\n");
+
+ if (flow->l4.tcp.manolito_stage == 0 && packet->payload_packet_len > 6) {
+ if (memcmp(packet->payload, "SIZ ", 4) != 0)
+ goto end_manolito_nothing_found;
+
+ flow->l4.tcp.manolito_stage = 1 + packet->packet_direction;
+ NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO Stage 1.\n");
+ goto end_manolito_maybe_hit;
+
+ } else if ((flow->l4.tcp.manolito_stage == 2 - packet->packet_direction)
+ && packet->payload_packet_len > 4) {
+ if (memcmp(packet->payload, "STR ", 4) != 0)
+ goto end_manolito_nothing_found;
+ NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO Stage 2.\n");
+ flow->l4.tcp.manolito_stage = 3 + packet->packet_direction;
+ goto end_manolito_maybe_hit;
+
+ } else if ((flow->l4.tcp.manolito_stage == 4 - packet->packet_direction) && packet->payload_packet_len > 5) {
+ if (memcmp(packet->payload, "MD5 ", 4) != 0)
+ goto end_manolito_nothing_found;
+ NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO Stage 3.\n");
+ flow->l4.tcp.manolito_stage = 5 + packet->packet_direction;
+ goto end_manolito_maybe_hit;
+
+ } else if ((flow->l4.tcp.manolito_stage == 6 - packet->packet_direction) && packet->payload_packet_len == 4) {
+
+ if (memcmp(packet->payload, "GO!!", 4) != 0)
+ goto end_manolito_nothing_found;
+ NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO Stage 4.\n");
+ goto end_manolito_found;
+ }
+ //NDPI_LOG(NDPI_PROTOCOL_MANOLITO,ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO FLOW STAGE %d\n", flow->l4.tcp.manolito_stage);
+ goto end_manolito_nothing_found;
+
+ end_manolito_found:
+ NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO FOUND\n");
+ ndpi_int_manolito_add_connection(ndpi_struct, flow);
+ return 1;
+
+ end_manolito_maybe_hit:
+ NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO maybe hit.\n");
+ return 2;
+
+ end_manolito_nothing_found:
+ NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO NOTHING FOUND\n");
+ return 0;
+}
+
+void ndpi_search_manolito_tcp_udp(struct
+ ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+
+ if (packet->tcp != NULL) {
+ if (search_manolito_tcp(ndpi_struct, flow) != 0)
+ return;
+ } else if (packet->udp != NULL) {
+ if (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_MANOLITO) {
+ if (src != NULL) {
+ src->manolito_last_pkt_arrival_time = packet->tick_timestamp;
+ }
+ if (dst != NULL) {
+ dst->manolito_last_pkt_arrival_time = packet->tick_timestamp;
+ }
+ return;
+ } else if (packet->udp->source == htons(41170)
+ || packet->udp->dest == htons(41170)) {
+ if (src != NULL && src->manolito_last_pkt_arrival_time != 0
+ && (packet->tick_timestamp - src->manolito_last_pkt_arrival_time <
+ ndpi_struct->manolito_subscriber_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO: UDP detected \n");
+ ndpi_int_manolito_add_connection(ndpi_struct, flow);
+ return;
+ } else if (src != NULL
+ && (packet->tick_timestamp - src->manolito_last_pkt_arrival_time) >=
+ ndpi_struct->manolito_subscriber_timeout) {
+ src->manolito_last_pkt_arrival_time = 0;
+ }
+
+ if (dst != NULL && dst->manolito_last_pkt_arrival_time != 0
+ && (packet->tick_timestamp - dst->manolito_last_pkt_arrival_time <
+ ndpi_struct->manolito_subscriber_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO: UDP detected \n");
+ ndpi_int_manolito_add_connection(ndpi_struct, flow);
+ return;
+ } else if (dst != NULL
+ && (packet->tick_timestamp - dst->manolito_last_pkt_arrival_time) >=
+ ndpi_struct->manolito_subscriber_timeout) {
+ dst->manolito_last_pkt_arrival_time = 0;
+ }
+
+ if ((packet->payload_packet_len == 20 && htons(0x3d4b) == get_u_int16_t(packet->payload, 0)
+ && packet->payload[2] == 0xd9 && htons(0xedbb) == get_u_int16_t(packet->payload, 16))
+ || (packet->payload_packet_len == 25 && htons(0x3e4a) == get_u_int16_t(packet->payload, 0)
+ && htons(0x092f) == get_u_int16_t(packet->payload, 20) && packet->payload[22] == 0x20)
+ || (packet->payload_packet_len == 20 && !get_u_int16_t(packet->payload, 2) && !get_u_int32_t(packet->payload, 8)
+ && !get_u_int16_t(packet->payload, 18) && get_u_int16_t(packet->payload, 0))
+ ) { //20B pkt is For PING
+ NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO: UDP detected \n");
+ ndpi_int_manolito_add_connection(ndpi_struct, flow);
+ return;
+ } else if (flow->packet_counter < 7) {
+ return;
+ }
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MANOLITO);
+}
+#endif
diff --git a/src/lib/protocols/attic/popo.c b/src/lib/protocols/attic/popo.c
new file mode 100644
index 000000000..b5c45ea2b
--- /dev/null
+++ b/src/lib/protocols/attic/popo.c
@@ -0,0 +1,86 @@
+/*
+ * popo.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_POPO
+
+static void ndpi_int_popo_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_POPO, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_popo_tcp_udp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ if (packet->tcp != NULL) {
+ if ((packet->payload_packet_len == 20)
+ && get_u_int32_t(packet->payload, 0) == htonl(0x0c000000)
+ && get_u_int32_t(packet->payload, 4) == htonl(0x01010000)
+ && get_u_int32_t(packet->payload, 8) == htonl(0x06000000)
+ && get_u_int32_t(packet->payload, 12) == 0 && get_u_int32_t(packet->payload, 16) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_POPO, ndpi_struct, NDPI_LOG_DEBUG, "POPO detected\n");
+ ndpi_int_popo_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_POPO) != 0) {
+#define NDPI_POPO_IP_SUBNET_START ( (220 << 24) + (181 << 16) + (28 << 8) + 220)
+#define NDPI_POPO_IP_SUBNET_END ( (220 << 24) + (181 << 16) + (28 << 8) + 238)
+
+ /* may match the first payload ip packet only ... */
+
+ if (ntohl(packet->iph->daddr) >= NDPI_POPO_IP_SUBNET_START
+ && ntohl(packet->iph->daddr) <= NDPI_POPO_IP_SUBNET_END) {
+ NDPI_LOG(NDPI_PROTOCOL_POPO, ndpi_struct, NDPI_LOG_DEBUG, "POPO ip subnet detected\n");
+ ndpi_int_popo_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+
+ if (packet->payload_packet_len > 13 && packet->payload_packet_len == get_l32(packet->payload, 0)
+ && !get_l16(packet->payload, 12)) {
+ register u_int16_t ii;
+ for (ii = 14; ii < 50 && ii < packet->payload_packet_len - 8; ++ii) {
+ if (packet->payload[ii] == '@')
+ if (!memcmp(&packet->payload[ii + 1], "163.com", 7)
+ || (ii <= packet->payload_packet_len - 13 && !memcmp(&packet->payload[ii + 1], "popo.163.com", 12))) {
+ NDPI_LOG(NDPI_PROTOCOL_POPO, ndpi_struct, NDPI_LOG_DEBUG, "POPO detected.\n");
+ ndpi_int_popo_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_POPO);
+}
+
+#endif
diff --git a/src/lib/protocols/attic/secondlife.c b/src/lib/protocols/attic/secondlife.c
new file mode 100644
index 000000000..1d43231e0
--- /dev/null
+++ b/src/lib/protocols/attic/secondlife.c
@@ -0,0 +1,123 @@
+/*
+ * secondlife.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_utils.h"
+#ifdef NDPI_PROTOCOL_SECONDLIFE
+
+static void ndpi_int_secondlife_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SECONDLIFE, protocol_type);
+}
+
+void ndpi_search_secondlife(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ // if ((ntohs(packet->udp->dest) == 12035 || ntohs(packet->udp->dest) == 12036 || (ntohs(packet->udp->dest) >= 13000 && ntohs(packet->udp->dest) <= 13050)) //port
+ // && packet->payload_packet_len > 6 // min length with no extra header, high frequency and 1 byte message body
+ // && get_u_int8_t(packet->payload, 0) == 0x40 // reliable packet
+ // && ntohl(get_u_int32_t(packet->payload, 1)) == 0x00000001 // sequence number equals 1
+ // //ntohl (get_u_int32_t (packet->payload, 5)) == 0x00FFFF00 // no extra header, low frequency message - can't use, message may have higher frequency
+ // ) {
+ // NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life detected.\n");
+ // ndpi_int_secondlife_add_connection(ndpi_struct, flow);
+ // return;
+ // }
+
+ if (packet->tcp != NULL) {
+ if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /")
+ && memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life HTTP 'GET /'' found.\n");
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->user_agent_line.ptr != NULL
+ && packet->user_agent_line.len >
+ NDPI_STATICSTRING_LEN
+ ("Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/532.4 (KHTML, like Gecko) SecondLife/")
+ && memcmp(&packet->user_agent_line.ptr[NDPI_STATICSTRING_LEN
+ ("Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/532.4 (KHTML, like Gecko) ")],
+ "SecondLife/", NDPI_STATICSTRING_LEN("SecondLife/")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG,
+ "Second Life TCP HTTP User Agent detected.\n");
+ ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ if (packet->host_line.ptr != NULL && packet->host_line.len > NDPI_STATICSTRING_LEN(".agni.lindenlab.com:")) {
+ u_int8_t x;
+ for (x = 2; x < 6; x++) {
+ if (packet->host_line.ptr[packet->host_line.len - (1 + x)] == ':') {
+ if ((1 + x + NDPI_STATICSTRING_LEN(".agni.lindenlab.com")) < packet->host_line.len
+ && memcmp(&packet->host_line.ptr[packet->host_line.len -
+ (1 + x + NDPI_STATICSTRING_LEN(".agni.lindenlab.com"))],
+ ".agni.lindenlab.com", NDPI_STATICSTRING_LEN(".agni.lindenlab.com")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG,
+ "Second Life TCP HTTP Host detected.\n");
+ ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (packet->udp != NULL) {
+ if (packet->payload_packet_len == 46
+ && memcmp(packet->payload, "\x40\x00\x00\x00\x01\x00\xff\xff\x00\x03", 10) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life 0xffff0003 detected.\n");
+ ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 54
+ && memcmp(packet->payload, "\x40\x00\x00\x00\x01\x00\xff\xff\x00\x52", 10) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life 0xffff0052 detected.\n");
+ ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 58
+ && memcmp(packet->payload, "\x40\x00\x00\x00\x01\x00\xff\xff\x00\xa9", 10) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life 0xffff00a9 detected.\n");
+ ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len > 54 && memcmp(packet->payload, "\x40\x00\x00\x00\x01\x00\x08", 7) == 0 &&
+ get_u_int32_t(packet->payload, packet->payload_packet_len - 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life 0x08 detected.\n");
+ ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+
+ NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SECONDLIFE);
+}
+
+#endif
diff --git a/src/lib/protocols/ayiya.c b/src/lib/protocols/ayiya.c
new file mode 100644
index 000000000..c4d1a26ad
--- /dev/null
+++ b/src/lib/protocols/ayiya.c
@@ -0,0 +1,67 @@
+/*
+ * ayiya.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ http://en.wikipedia.org/wiki/Anything_In_Anything
+ http://tools.ietf.org/html/rfc4891
+*/
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_AYIYA
+
+struct ayiya {
+ u_int8_t flags[3];
+ u_int8_t next_header;
+ u_int32_t epoch;
+ u_int8_t identity[16];
+ u_int8_t signature[20];
+};
+
+void ndpi_search_ayiya(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(packet->udp && (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)) {
+ /* Ayiya is udp based, port 5072 */
+ if ((packet->udp->source == htons(5072) || packet->udp->dest == htons(5072))
+ /* check for ayiya new packet */
+ && (packet->payload_packet_len > 44)
+ ) {
+ /* FINISH */
+ struct ayiya *a = (struct ayiya*)packet->payload;
+ u_int32_t epoch = ntohl(a->epoch), now;
+ u_int32_t fireyears = 86400 * 365 * 5;
+
+ now = flow->packet.tick_timestamp;
+
+ if((epoch >= (now - fireyears)) && (epoch <= (now+86400 /* 1 day */)))
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_AYIYA, NDPI_REAL_PROTOCOL);
+
+ return;
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_AYIYA);
+ }
+}
+#endif
diff --git a/src/lib/protocols/battlefield.c b/src/lib/protocols/battlefield.c
new file mode 100644
index 000000000..374dcb61b
--- /dev/null
+++ b/src/lib/protocols/battlefield.c
@@ -0,0 +1,118 @@
+/*
+ * battlefield.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_BATTLEFIELD
+
+
+static void ndpi_int_battlefield_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_BATTLEFIELD, NDPI_REAL_PROTOCOL);
+
+ if (src != NULL) {
+ src->battlefield_ts = packet->tick_timestamp;
+ }
+ if (dst != NULL) {
+ dst->battlefield_ts = packet->tick_timestamp;
+ }
+}
+
+void ndpi_search_battlefield(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_BATTLEFIELD) {
+ if (src != NULL && ((u_int32_t)
+ (packet->tick_timestamp - src->battlefield_ts) < ndpi_struct->battlefield_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct, NDPI_LOG_DEBUG,
+ "battlefield : save src connection packet detected\n");
+ src->battlefield_ts = packet->tick_timestamp;
+ } else if (dst != NULL && ((u_int32_t)
+ (packet->tick_timestamp - dst->battlefield_ts) < ndpi_struct->battlefield_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct, NDPI_LOG_DEBUG,
+ "battlefield : save dst connection packet detected\n");
+ dst->battlefield_ts = packet->tick_timestamp;
+ }
+ return;
+ }
+
+ if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_BATTLEFIELD)) {
+ if (flow->l4.udp.battlefield_stage == 0 || flow->l4.udp.battlefield_stage == 1 + packet->packet_direction) {
+ if (packet->payload_packet_len > 8 && get_u_int16_t(packet->payload, 0) == htons(0xfefd)) {
+ flow->l4.udp.battlefield_msg_id = get_u_int32_t(packet->payload, 2);
+ flow->l4.udp.battlefield_stage = 1 + packet->packet_direction;
+ return;
+ }
+ } else if (flow->l4.udp.battlefield_stage == 2 - packet->packet_direction) {
+ if (packet->payload_packet_len > 8 && get_u_int32_t(packet->payload, 0) == flow->l4.udp.battlefield_msg_id) {
+ NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct,
+ NDPI_LOG_DEBUG, "Battlefield message and reply detected.\n");
+ ndpi_int_battlefield_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+
+ if (flow->l4.udp.battlefield_stage == 0) {
+ if (packet->payload_packet_len == 46 && packet->payload[2] == 0 && packet->payload[4] == 0
+ && get_u_int32_t(packet->payload, 7) == htonl(0x98001100)) {
+ flow->l4.udp.battlefield_stage = 3 + packet->packet_direction;
+ return;
+ }
+ } else if (flow->l4.udp.battlefield_stage == 4 - packet->packet_direction) {
+ if (packet->payload_packet_len == 7
+ && (packet->payload[0] == 0x02 || packet->payload[packet->payload_packet_len - 1] == 0xe0)) {
+ NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct, NDPI_LOG_DEBUG,
+ "Battlefield message and reply detected.\n");
+ ndpi_int_battlefield_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ if (packet->payload_packet_len == 18 && memcmp(&packet->payload[5], "battlefield2\x00", 13) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct, NDPI_LOG_DEBUG, "Battlefield 2 hello packet detected.\n");
+ ndpi_int_battlefield_add_connection(ndpi_struct, flow);
+ return;
+ } else if (packet->payload_packet_len > 10 &&
+ (memcmp(packet->payload, "\x11\x20\x00\x01\x00\x00\x50\xb9\x10\x11", 10) == 0
+ || memcmp(packet->payload, "\x11\x20\x00\x01\x00\x00\x30\xb9\x10\x11", 10) == 0
+ || memcmp(packet->payload, "\x11\x20\x00\x01\x00\x00\xa0\x98\x00\x11", 10) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct, NDPI_LOG_DEBUG, "Battlefield safe pattern detected.\n");
+ ndpi_int_battlefield_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BATTLEFIELD);
+ return;
+}
+
+#endif
diff --git a/src/lib/protocols/bgp.c b/src/lib/protocols/bgp.c
new file mode 100644
index 000000000..8d4f00ab4
--- /dev/null
+++ b/src/lib/protocols/bgp.c
@@ -0,0 +1,57 @@
+/*
+ * bgp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_BGP
+
+
+static void ndpi_int_bgp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_BGP, NDPI_REAL_PROTOCOL);
+}
+
+/* this detection also works asymmetrically */
+void ndpi_search_bgp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len > 18 &&
+ get_u_int64_t(packet->payload, 0) == 0xffffffffffffffffULL &&
+ get_u_int64_t(packet->payload, 8) == 0xffffffffffffffffULL &&
+ ntohs(get_u_int16_t(packet->payload, 16)) <= packet->payload_packet_len &&
+ (packet->tcp->dest == htons(179) || packet->tcp->source == htons(179))
+ && packet->payload[18] < 5) {
+ NDPI_LOG(NDPI_PROTOCOL_BGP, ndpi_struct, NDPI_LOG_DEBUG, "BGP detected.\n");
+ ndpi_int_bgp_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BGP);
+}
+
+#endif
diff --git a/src/lib/protocols/bittorrent.c b/src/lib/protocols/bittorrent.c
new file mode 100644
index 000000000..4be42548f
--- /dev/null
+++ b/src/lib/protocols/bittorrent.c
@@ -0,0 +1,469 @@
+/*
+ * bittorrent.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_BITTORRENT
+#define NDPI_PROTOCOL_UNSAFE_DETECTION 0
+#define NDPI_PROTOCOL_SAFE_DETECTION 1
+
+#define NDPI_PROTOCOL_PLAIN_DETECTION 0
+#define NDPI_PROTOCOL_WEBSEED_DETECTION 2
+static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
+ const u_int8_t save_detection, const u_int8_t encrypted_connection,
+ ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BITTORRENT, protocol_type);
+}
+
+static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src = flow->src;
+ // struct ndpi_id_struct *dst = flow->dst;
+
+ u_int16_t a = 0;
+
+ if (packet->payload_packet_len == 1 && packet->payload[0] == 0x13) {
+ /* reset stage back to 0 so we will see the next packet here too */
+ flow->bittorrent_stage = 0;
+ return 0;
+ }
+ if (flow->packet_counter == 2 && packet->payload_packet_len > 20) {
+
+ if (memcmp(&packet->payload[0], "BitTorrent protocol", 19) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT,
+ ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
+ NDPI_REAL_PROTOCOL);
+ return 1;
+ }
+ }
+
+
+ if (packet->payload_packet_len > 20) {
+ /* test for match 0x13+"BitTorrent protocol" */
+ if (packet->payload[0] == 0x13) {
+ if (memcmp(&packet->payload[1], "BitTorrent protocol", 19) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT,
+ ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
+ NDPI_REAL_PROTOCOL);
+ return 1;
+ }
+ }
+ }
+
+ if (packet->payload_packet_len > 23 && memcmp(packet->payload, "GET /webseed?info_hash=", 23) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
+ NDPI_LOG_TRACE, "BT: plain webseed BitTorrent protocol detected\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION,
+ NDPI_CORRELATED_PROTOCOL);
+ return 1;
+ }
+ /* seen Azureus as server for webseed, possibly other servers existing, to implement */
+ /* is Server: hypertracker Bittorrent? */
+ /* no asymmetric detection possible for answer of pattern "GET /data?fid=". */
+ if (packet->payload_packet_len > 60
+ && memcmp(packet->payload, "GET /data?fid=", 14) == 0 && memcmp(&packet->payload[54], "&size=", 6) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
+ NDPI_LOG_TRACE, "BT: plain Bitcomet persistent seed protocol detected\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION,
+ NDPI_CORRELATED_PROTOCOL);
+ return 1;
+ }
+
+
+ if (packet->payload_packet_len > 90 && (memcmp(packet->payload, "GET ", 4) == 0
+ || memcmp(packet->payload, "POST ", 5) == 0)) {
+ const u_int8_t *ptr = &packet->payload[4];
+ u_int16_t len = packet->payload_packet_len - 4;
+ a = 0;
+
+
+ /* parse complete get packet here into line structure elements */
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ /* answer to this pattern is HTTP....Server: hypertracker */
+ if (packet->user_agent_line.ptr != NULL
+ && ((packet->user_agent_line.len > 8 && memcmp(packet->user_agent_line.ptr, "Azureus ", 8) == 0)
+ || (packet->user_agent_line.len >= 10 && memcmp(packet->user_agent_line.ptr, "BitTorrent", 10) == 0)
+ || (packet->user_agent_line.len >= 11 && memcmp(packet->user_agent_line.ptr, "BTWebClient", 11) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
+ NDPI_LOG_TRACE, "Azureus /Bittorrent user agent line detected\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION,
+ NDPI_CORRELATED_PROTOCOL);
+ return 1;
+ }
+
+ if (packet->user_agent_line.ptr != NULL
+ && (packet->user_agent_line.len >= 9 && memcmp(packet->user_agent_line.ptr, "Shareaza ", 9) == 0)
+ && (packet->parsed_lines > 8 && packet->line[8].ptr != 0
+ && packet->line[8].len >= 9 && memcmp(packet->line[8].ptr, "X-Queue: ", 9) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
+ NDPI_LOG_TRACE, "Bittorrent Shareaza detected.\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION,
+ NDPI_CORRELATED_PROTOCOL);
+ return 1;
+ }
+
+ /* this is a self built client, not possible to catch asymmetrically */
+ if ((packet->parsed_lines == 10 || (packet->parsed_lines == 11 && packet->line[11].len == 0))
+ && packet->user_agent_line.ptr != NULL
+ && packet->user_agent_line.len > 12
+ && memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 ",
+ 12) == 0
+ && packet->host_line.ptr != NULL
+ && packet->host_line.len >= 7
+ && packet->line[2].ptr != NULL
+ && packet->line[2].len > 14
+ && memcmp(packet->line[2].ptr, "Keep-Alive: 300", 15) == 0
+ && packet->line[3].ptr != NULL
+ && packet->line[3].len > 21
+ && memcmp(packet->line[3].ptr, "Connection: Keep-alive", 22) == 0
+ && packet->line[4].ptr != NULL
+ && packet->line[4].len > 10
+ && (memcmp(packet->line[4].ptr, "Accpet: */*", 11) == 0
+ || memcmp(packet->line[4].ptr, "Accept: */*", 11) == 0)
+
+ && packet->line[5].ptr != NULL
+ && packet->line[5].len > 12
+ && memcmp(packet->line[5].ptr, "Range: bytes=", 13) == 0
+ && packet->line[7].ptr != NULL
+ && packet->line[7].len > 15
+ && memcmp(packet->line[7].ptr, "Pragma: no-cache", 16) == 0
+ && packet->line[8].ptr != NULL
+ && packet->line[8].len > 22 && memcmp(packet->line[8].ptr, "Cache-Control: no-cache", 23) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "Bitcomet LTS detected\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
+ NDPI_CORRELATED_PROTOCOL);
+ return 1;
+
+ }
+
+ /* FlashGet pattern */
+ if (packet->parsed_lines == 8
+ && packet->user_agent_line.ptr != NULL
+ && packet->user_agent_line.len > (sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1)
+ && memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 (compatible; MSIE 6.0;",
+ sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) == 0
+ && packet->host_line.ptr != NULL
+ && packet->host_line.len >= 7
+ && packet->line[2].ptr != NULL
+ && packet->line[2].len == 11
+ && memcmp(packet->line[2].ptr, "Accept: */*", 11) == 0
+ && packet->line[3].ptr != NULL && packet->line[3].len >= (sizeof("Referer: ") - 1)
+ && memcmp(packet->line[3].ptr, "Referer: ", sizeof("Referer: ") - 1) == 0
+ && packet->line[5].ptr != NULL
+ && packet->line[5].len > 13
+ && memcmp(packet->line[5].ptr, "Range: bytes=", 13) == 0
+ && packet->line[6].ptr != NULL
+ && packet->line[6].len > 21 && memcmp(packet->line[6].ptr, "Connection: Keep-Alive", 22) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "FlashGet detected\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
+ NDPI_CORRELATED_PROTOCOL);
+ return 1;
+
+ }
+ if (packet->parsed_lines == 7
+ && packet->user_agent_line.ptr != NULL
+ && packet->user_agent_line.len > (sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1)
+ && memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 (compatible; MSIE 6.0;",
+ sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) == 0
+ && packet->host_line.ptr != NULL
+ && packet->host_line.len >= 7
+ && packet->line[2].ptr != NULL
+ && packet->line[2].len == 11
+ && memcmp(packet->line[2].ptr, "Accept: */*", 11) == 0
+ && packet->line[3].ptr != NULL && packet->line[3].len >= (sizeof("Referer: ") - 1)
+ && memcmp(packet->line[3].ptr, "Referer: ", sizeof("Referer: ") - 1) == 0
+ && packet->line[5].ptr != NULL
+ && packet->line[5].len > 21 && memcmp(packet->line[5].ptr, "Connection: Keep-Alive", 22) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "FlashGet detected\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
+ NDPI_CORRELATED_PROTOCOL);
+ return 1;
+
+ }
+
+ /* answer to this pattern is not possible to implement asymmetrically */
+ while (1) {
+ if (len < 50 || ptr[0] == 0x0d) {
+ goto ndpi_end_bt_tracker_check;
+ }
+ if (memcmp(ptr, "info_hash=", 10) == 0) {
+ break;
+ }
+ len--;
+ ptr++;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
+ NDPI_LOG_TRACE, " BT stat: tracker info hash found\n");
+
+ /* len is > 50, so save operation here */
+ len -= 10;
+ ptr += 10;
+
+ /* parse bt hash */
+ for (a = 0; a < 20; a++) {
+ if (len < 3) {
+ goto ndpi_end_bt_tracker_check;
+ }
+ if (*ptr == '%') {
+ u_int8_t x1 = 0xFF;
+ u_int8_t x2 = 0xFF;
+
+
+ if (ptr[1] >= '0' && ptr[1] <= '9') {
+ x1 = ptr[1] - '0';
+ }
+ if (ptr[1] >= 'a' && ptr[1] <= 'f') {
+ x1 = 10 + ptr[1] - 'a';
+ }
+ if (ptr[1] >= 'A' && ptr[1] <= 'F') {
+ x1 = 10 + ptr[1] - 'A';
+ }
+
+ if (ptr[2] >= '0' && ptr[2] <= '9') {
+ x2 = ptr[2] - '0';
+ }
+ if (ptr[2] >= 'a' && ptr[2] <= 'f') {
+ x2 = 10 + ptr[2] - 'a';
+ }
+ if (ptr[2] >= 'A' && ptr[2] <= 'F') {
+ x2 = 10 + ptr[2] - 'A';
+ }
+
+ if (x1 == 0xFF || x2 == 0xFF) {
+ goto ndpi_end_bt_tracker_check;
+ }
+ ptr += 3;
+ len -= 3;
+ } else if (*ptr >= 32 && *ptr < 127) {
+ ptr++;
+ len--;
+ } else {
+ goto ndpi_end_bt_tracker_check;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
+ NDPI_LOG_TRACE, " BT stat: tracker info hash parsed\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
+ NDPI_CORRELATED_PROTOCOL);
+ return 1;
+ }
+
+ ndpi_end_bt_tracker_check:
+
+ if (packet->payload_packet_len == 80) {
+ /* Warez 80 Bytes Packet
+ * +----------------+---------------+-----------------+-----------------+
+ * |20 BytesPattern | 32 Bytes Value| 12 BytesPattern | 16 Bytes Data |
+ * +----------------+---------------+-----------------+-----------------+
+ * 20 BytesPattern : 4c 00 00 00 ff ff ff ff 57 00 00 00 00 00 00 00 20 00 00 00
+ * 12 BytesPattern : 28 23 00 00 01 00 00 00 10 00 00 00
+ * */
+ static const char pattern_20_bytes[20] = { 0x4c, 0x00, 0x00, 0x00, 0xff,
+ 0xff, 0xff, 0xff, 0x57, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00
+ };
+ static const char pattern_12_bytes[12] = { 0x28, 0x23, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00
+ };
+
+ /* did not see this pattern anywhere */
+ if ((memcmp(&packet->payload[0], pattern_20_bytes, 20) == 0)
+ && (memcmp(&packet->payload[52], pattern_12_bytes, 12) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
+ NDPI_LOG_TRACE, "BT: Warez - Plain BitTorrent protocol detected\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
+ NDPI_REAL_PROTOCOL);
+ return 1;
+ }
+ }
+
+ else if (packet->payload_packet_len > 50) {
+ if (memcmp(packet->payload, "GET", 3) == 0) {
+
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ /* haven't fount this pattern anywhere */
+ if (packet->host_line.ptr != NULL
+ && packet->host_line.len >= 9 && memcmp(packet->host_line.ptr, "ip2p.com:", 9) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT,
+ ndpi_struct, NDPI_LOG_TRACE,
+ "BT: Warez - Plain BitTorrent protocol detected due to Host: ip2p.com: pattern\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION,
+ NDPI_CORRELATED_PROTOCOL);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/*Search for BitTorrent commands*/
+static void ndpi_int_search_bittorrent_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if (packet->payload_packet_len == 0) {
+ return;
+ }
+
+ if (flow->bittorrent_stage == 0 && packet->payload_packet_len != 0) {
+ /* exclude stage 0 detection from next run */
+ flow->bittorrent_stage = 1;
+ if (ndpi_int_search_bittorrent_tcp_zero(ndpi_struct, flow) != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_DEBUG,
+ "stage 0 has detected something, returning\n");
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_DEBUG,
+ "stage 0 has no direct detection, fall through\n");
+ }
+ return;
+}
+
+void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ /* This is broadcast */
+ if(packet->iph
+ && ((packet->iph->saddr == 0xFFFFFFFF) || (packet->iph->daddr == 0xFFFFFFFF)))
+ return;
+
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_BITTORRENT) {
+ /* check for tcp retransmission here */
+
+ if ((packet->tcp != NULL)
+ && (packet->tcp_retransmission == 0 || packet->num_retried_bytes)) {
+ ndpi_int_search_bittorrent_tcp(ndpi_struct, flow);
+ }
+ else if(packet->udp != NULL) {
+ if((ntohs(packet->udp->source) < 1024)
+ || (ntohs(packet->udp->dest) < 1024) /* High ports only */)
+ return;
+
+ /*
+ Check for uTP http://www.bittorrent.org/beps/bep_0029.html
+
+ wireshark/epan/dissectors/packet-bt-utp.c
+ */
+
+ if(packet->payload_packet_len >= 23 /* min header size */) {
+ /* Check if this is protocol v0 */
+ u_int8_t v0_extension = packet->payload[17];
+ u_int8_t v0_flags = packet->payload[18];
+
+ /* Check if this is protocol v1 */
+ u_int8_t v1_version = packet->payload[0];
+ u_int8_t v1_extension = packet->payload[1];
+ u_int32_t v1_window_size = *((u_int32_t*)&packet->payload[12]);
+
+ if((packet->payload[0]== 0x60)
+ && (packet->payload[1]== 0x0)
+ && (packet->payload[2]== 0x0)
+ && (packet->payload[3]== 0x0)
+ && (packet->payload[4]== 0x0)) {
+ /* Heuristic */
+ goto bittorrent_found;
+ } else if(((v1_version & 0x0f) == 1)
+ && ((v1_version >> 4) < 5 /* ST_NUM_STATES */)
+ && (v1_extension < 3 /* EXT_NUM_EXT */)
+ && (v1_window_size < 32768 /* 32k */)
+ ) {
+ goto bittorrent_found;
+ } else if((v0_flags < 6 /* ST_NUM_STATES */)
+ && (v0_extension < 3 /* EXT_NUM_EXT */)) {
+ u_int32_t ts = ntohl(*((u_int32_t*)&(packet->payload[4])));
+ u_int32_t now;
+
+#ifndef __KERNEL__
+ now = (u_int32_t)time(NULL);
+#else
+ struct timespec t;
+
+ getnstimeofday(&t);
+ now = t.tv_sec;
+#endif
+
+ if((ts < (now+86400)) && (ts > (now-86400))) {
+ goto bittorrent_found;
+ }
+ }
+ }
+
+ flow->bittorrent_stage++;
+
+ if(flow->bittorrent_stage < 10) {
+ if(packet->payload_packet_len > 19 /* min size */) {
+ if(ndpi_strnstr((const char *)packet->payload, ":target20:", packet->payload_packet_len)
+ || ndpi_strnstr((const char *)packet->payload, ":find_node1:", packet->payload_packet_len)
+ || ndpi_strnstr((const char *)packet->payload, "d1:ad2:id20:", packet->payload_packet_len)
+ || ndpi_strnstr((const char *)packet->payload, ":info_hash20:", packet->payload_packet_len)
+ || ndpi_strnstr((const char *)packet->payload, ":filter64", packet->payload_packet_len)
+ || ndpi_strnstr((const char *)packet->payload, "d1:rd2:id20:", packet->payload_packet_len)
+ || ndpi_strnstr((const char *)packet->payload, "BitTorrent protocol", packet->payload_packet_len)
+ ) {
+ bittorrent_found:
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT,
+ ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
+ NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+ return;
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BITTORRENT);
+ }
+ }
+}
+#endif
diff --git a/src/lib/protocols/btlib.c b/src/lib/protocols/btlib.c
new file mode 100644
index 000000000..6442c7db7
--- /dev/null
+++ b/src/lib/protocols/btlib.c
@@ -0,0 +1,509 @@
+/*
+ * btlib.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ * Contributed by Vitaly Lavrov <vel21ripn@gmail.com>
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef NDPI_NO_STD_INC
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <strings.h>
+
+typedef unsigned char u_int8_t;
+typedef unsigned short int u_int16_t;
+typedef unsigned long long int u_int64_t;
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <arpa/inet.h>
+#endif
+
+typedef signed long long int i_int64_t;
+
+#include "btlib.h"
+
+#ifndef __KERNEL__
+
+int bt_parse_debug = 0;
+
+static char *printXb(char *s,const u_int8_t *b,int l) {
+ int i;
+ for(i=0; i < l; i++)
+ snprintf(&s[i*2],41,"%02x",b[i]);
+ return s;
+}
+
+static char *print20b(char *s,const u_int8_t *b) {
+ snprintf(s,41,"%08x%08x%08x%08x%08x",
+ htonl(*(u_int32_t*)b),
+ htonl(*(u_int32_t*)(b+4)),
+ htonl(*(u_int32_t*)(b+8)),
+ htonl(*(u_int32_t*)(b+12)),
+ htonl(*(u_int32_t*)(b+16)));
+ return s;
+}
+
+static char *print_id_ip_p(char *s, const struct bt_nodes_data *b) {
+ u_int8_t *p = (void*)b;
+ print20b(s,b->id);
+ snprintf(s+40,39," %d.%d.%d.%d:%u",
+ p[20], p[21], p[22], p[23], htons(b->port));
+ return s;
+}
+
+static char *print_ip_p(char *s, const struct bt_ipv4p *b,int np) {
+ const u_int8_t *p = (const void*)b;
+ snprintf(s,39,!np ? "%d.%d.%d.%d:%u":"%d.%d.%d.%d",
+ p[0], p[1], p[2], p[3], htons(b->port));
+ return s;
+}
+
+static char *print_ip6_p(char *s, const struct bt_ipv6p *b,int np) {
+ u_int16_t *p = (void*)b;
+ snprintf(s,79,!np ? "%x:%x:%x:%x:%x:%x:%x:%x.%u":"%x:%x:%x:%x:%x:%x:%x:%x",
+ htons(p[0]), htons(p[1]), htons(p[2]), htons(p[3]),
+ htons(p[4]), htons(p[5]), htons(p[6]), htons(p[7]),
+ htons(b->port));
+ return s;
+}
+
+static char *print_id_ip6_p(char *s,const struct bt_nodes6_data *b) {
+ return print_ip6_p(s,(struct bt_ipv6p *)&b->ip,0);
+}
+
+
+void dump_bt_proto_struct(struct bt_parse_protocol *p) {
+ char b20h[128];
+ int i;
+
+ if(p->y_e && p->e_msg) {
+ printf("Error %s/%u\n", p->e_msg, p->e_len);
+ }
+ if(p->y_q) {
+ printf("Query ");
+ if(p->q_ping) printf("ping\n");
+ if(p->q_g_peers) printf("get_peers\n");
+ if(p->q_f_node) printf("find_node\n");
+ if(p->q_a_peer) printf("announce_peer\n");
+ }
+ if(p->y_r)
+ printf("Reply\n");
+
+ if(p->t) printf("\tt\t%llx\n",p->t);
+ if(p->v) printf("\tv\t%llx\n",p->v);
+ if(p->ip) printf("\tIP\t%s\n",print_ip_p(b20h,p->ip,0));
+
+ if(p->a.port) printf("\tport\t%d\n",htons(p->a.port));
+ if(p->a.id) printf("\tID\t%s\n",print20b(b20h,p->a.id));
+ if(p->a.target) printf("\ttarget\t%s\n",print20b(b20h,p->a.target));
+ if(p->a.token) printf("\ttoken\t%s\n",printXb(b20h,p->a.token,p->a.t_len));
+ if(p->a.info_hash) printf("\ti_hash\t%s\n",print20b(b20h,p->a.info_hash));
+ if(p->a.name && p->a.name_len) printf("\tname\t%.*s\n",p->a.name_len,p->a.name);
+
+ if(p->r.ip) printf("\tip\t%s\n",print_ip_p(b20h,p->r.ip,1));
+ if(p->r.port) printf("\tport\t%d\n",htons(p->r.port));
+ if(p->r.id) printf("\tID\t%s\n",print20b(b20h,p->r.id));
+ if(p->r.token) printf("\ttoken\t%s\n",printXb(b20h,p->r.token,p->r.t_len));
+ if(p->r.name && p->r.name_len) printf("\tname\t%.*s\n",p->r.name_len,p->r.name);
+ if(p->r.values && p->r.nv) {
+ struct bt_ipv4p2 *n = (struct bt_ipv4p2 *)p->r.values;
+ for(i=0;i < p->r.nv; i++,n++) {
+ printf("\tvalues\t%s\n", print_ip_p(b20h,&n->d,0));
+ }
+ }
+ if(p->r.values6 && p->r.nv6) {
+ struct bt_ipv6p2 *n = (struct bt_ipv6p2 *)p->r.values6;
+ for(i=0;i < p->r.nv6; i++,n++) {
+ printf("\tvalues6\t%s\n", print_ip6_p(b20h,&n->d,0));
+ }
+ }
+ if(p->r.nodes && p->r.nn) {
+ for(i=0;i < p->r.nn; i++) {
+ printf("\tnodes\t%s\n",print_id_ip_p(b20h,p->r.nodes+i));
+ }
+ }
+ if(p->r.nodes6 && p->r.nn6) {
+ for(i=0;i < p->r.nn6; i++) {
+ printf("\tnodes6\t%s\n",print_id_ip6_p(b20h,p->r.nodes6+i));
+ }
+ }
+
+ if(p->peers && p->n_peers) {
+ for(i=0;i < p->n_peers; i++) {
+ printf("\tpeers\t%s\n",print_ip_p(b20h,p->peers+i,0));
+ }
+ }
+
+ if(p->interval) printf("\tinterval\t%d\n",p->interval);
+ if(p->min_interval) printf("\tmin interval\t%d\n",p->min_interval);
+}
+
+static void _print_safe_str(char *msg,char *k,const u_int8_t *s,size_t l) {
+ static const char *th="0123456789abcdef?";
+ char *buf = (char*)ndpi_malloc((size_t)(l*3+2));
+
+ int sl = l;
+ if(buf) {
+ char *b = buf;
+ for(;l > 0; s++,l--) {
+ if(*s < ' ' || *s >= 127) {
+ *b++ = '%';
+ *b++ = th[(*s >> 4)&0xf];
+ *b++ = th[(*s)&0xf];
+ } else *b++ = *s;
+ }
+ *b = 0;
+
+ printf("%s %s %s len %d\n",msg,k,buf ? buf:"",sl);
+
+ ndpi_free(buf);
+ }
+}
+
+static void print_safe_str(char *msg,bt_parse_data_cb_t *cbd) {
+ _print_safe_str(msg,cbd->buf,cbd->v.s.s,cbd->v.s.l);
+}
+#define DEBUG_TRACE(cmd) { if(bt_parse_debug) cmd; }
+#else
+#define DEBUG_TRACE(cmd,args...)
+#endif /* __KERNEL */
+
+#define STREQ(a,b) !strcmp(a,b)
+
+
+void cb_data(bt_parse_data_cb_t *cbd,int *ret) {
+ struct bt_parse_protocol *p = &(cbd->p);
+ const u_int8_t *s;
+ const char *ss;
+
+ if(cbd->t == 0) return;
+
+ if(cbd->t == 1) {
+
+ DEBUG_TRACE(printf("%s %lld\n",cbd->buf,cbd->v.i));
+
+ if(STREQ(cbd->buf,"a.port")) {
+ p->a.port = (u_int16_t)(cbd->v.i & 0xffff);
+ return;
+ }
+ if(
+ STREQ(cbd->buf,"a.implied_port") ||
+ STREQ(cbd->buf,"a.noseed") ||
+ STREQ(cbd->buf,"a.scrape") ||
+ STREQ(cbd->buf,"a.seed") ||
+ STREQ(cbd->buf,"a.vote")
+ ) {
+ return;
+ }
+ if(STREQ(cbd->buf,"r.port") || STREQ(cbd->buf,"r.p")) {
+ p->r.port = (u_int16_t)(cbd->v.i & 0xffff);
+ return;
+ }
+ if(STREQ(cbd->buf,"interval")) {
+ p->interval = (u_int16_t)(cbd->v.i & 0x7fffffff);
+ p->h_int = 1;
+ return;
+ }
+ if(STREQ(cbd->buf,"min interval")) {
+ p->min_interval = (u_int16_t)(cbd->v.i & 0x7fffffff);
+ p->h_mint = 1;
+ return;
+ }
+ DEBUG_TRACE(printf("UNKNOWN %s %lld\n",cbd->buf,cbd->v.i));
+ return;
+ }
+ if(cbd->t != 2) {
+ DEBUG_TRACE(printf("BUG! t=%d %s\n",cbd->t,cbd->buf));
+ return;
+ }
+ DEBUG_TRACE(print_safe_str("",cbd));
+
+ s = cbd->v.s.s;
+ ss = (char *)s;
+
+ if(STREQ(cbd->buf,"a.id")) {
+ p->a.id = s;
+ return;
+ }
+ if(STREQ(cbd->buf,"a.info_hash")) {
+ p->a.info_hash = s;
+ return;
+ }
+ if(STREQ(cbd->buf,"a.target")) {
+ p->a.target = s;
+ return;
+ }
+ if(STREQ(cbd->buf,"a.token")) {
+ p->a.token = s;
+ p->a.t_len = cbd->v.s.l;
+ return;
+ }
+ if(STREQ(cbd->buf,"a.name")) {
+ p->a.name = s;
+ p->a.name_len = cbd->v.s.l;
+ return;
+ }
+ if(STREQ(cbd->buf,"a.want")) {
+ return;
+ }
+
+ if(STREQ(cbd->buf,"r.id")) {
+ p->r.id = s;
+ return;
+ }
+ if(STREQ(cbd->buf,"r.ip")) {
+ if(cbd->v.s.l != 4) {
+ DEBUG_TRACE(printf("BUG! r.ip with port\n"));
+ return;
+ }
+ p->r.ip = (struct bt_ipv4p *)s;
+ return;
+ }
+ if(STREQ(cbd->buf,"r.token")) {
+ p->r.token = s;
+ p->r.t_len = cbd->v.s.l;
+ return;
+ }
+ if(STREQ(cbd->buf,"r.values")) {
+ if(cbd->v.s.l == 18) {
+ if(!p->r.values6) {
+ p->r.values6 = s;
+ p->r.nv6 = 1;
+ } else {
+ if(s != p->r.values6+(p->r.nv6*21)) {
+ // DEBUG_TRACE(printf("BUG! r.values6 not in list! %08x %08x \n", p->r.values+(p->r.nv6*21),s));
+ return;
+ }
+ p->r.nv6++;
+ }
+ return;
+ }
+ if(cbd->v.s.l == 6) {
+ if(!p->r.values) {
+ p->r.values = s;
+ p->r.nv = 1;
+ } else {
+ if(s != p->r.values+(p->r.nv*8)) {
+ // DEBUG_TRACE(printf("BUG! r.values not in list! %u \n",s-p->r.values+(p->r.nv*8)));
+ return;
+ }
+ p->r.nv++;
+ }
+ return;
+ }
+ return;
+ }
+
+ if(STREQ(cbd->buf,"r.name") || STREQ(cbd->buf,"r.n")) {
+ p->r.name = s;
+ p->r.name_len = cbd->v.s.l;
+ return;
+ }
+ if(STREQ(cbd->buf,"r.nodes")) {
+ if(cbd->v.s.l % 26) {
+ // DEBUG_TRACE(printf("BUG! r.nodes length %d not %% 26\n",cbd->v.s.l));
+ return;
+ }
+ p->r.nodes = (struct bt_nodes_data *)s;
+ p->r.nn = cbd->v.s.l / 26;
+ return;
+ }
+ if(STREQ(cbd->buf,"r.nodes6")) {
+ if(cbd->v.s.l % 38) {
+ // DEBUG_TRACE(printf("BUG! r.nodes length %d not %% 38\n",cbd->v.s.l));
+ return;
+ }
+ p->r.nodes6 = (struct bt_nodes6_data *)s;
+ p->r.nn6 = cbd->v.s.l / 38;
+ return;
+ }
+
+ if(cbd->buf[0] == 'y' && !cbd->buf[1]) {
+ if(cbd->v.s.l != 1) return;
+ if(*ss == 'q') { p->y_q = 1; return; }
+ if(*ss == 'r') { p->y_r = 1; return; }
+ if(*ss == 'e') { p->y_e = 1; return; }
+ return;
+ }
+ if(cbd->buf[0] == 'q' && !cbd->buf[1]) {
+ if(!strncmp(ss,"announce_peer",13)) {
+ p->q_a_peer = 1;
+ return;
+ }
+ if(!strncmp(ss,"find_node",9)) {
+ p->q_f_node = 1;
+ return;
+ }
+ if(!strncmp(ss,"get_peers",9)) {
+ p->q_g_peers = 1;
+ return;
+ }
+ if(!strncmp(ss,"ping",4)) {
+ p->q_ping = 1;
+ return;
+ }
+ if(!strncmp(ss,"vote",4)) {
+ return;
+ }
+ }
+ if(STREQ(cbd->buf,"ip")) {
+ if(cbd->v.s.l != 6) {
+ // DEBUG_TRACE(printf("BUG! r.ip w/o port\n"));
+ }
+ p->ip = (struct bt_ipv4p *)s;
+ p->h_ip = 1;
+ return;
+ }
+ if(STREQ(cbd->buf,"peers")) {
+ if(cbd->v.s.l % 6) return;
+ p->peers = (struct bt_ipv4p *)s;
+ p->n_peers = cbd->v.s.l / 6;
+ return;
+ }
+ if((*cbd->buf == 't' || *cbd->buf == 'v') && !cbd->buf[1]) {
+ u_int64_t d = *(u_int64_t*)s;
+ switch(cbd->v.s.l) {
+ case 2:
+ d &= 0xffffllu; d = htons(d); break;
+ case 4:
+ d &= 0xffffffffllu; d = htonl(d); break;
+ case 6:
+ d &= 0xffffffffffffllu; d = (htonl(d & 0xffffffff) << 16) |
+ (htons(d >> 32) & 0xffff);
+ break;
+ case 8: d = ((u_int64_t)htonl(d & 0xffffffff) << 32) |
+ htonl(d >> 32);
+ break;
+ default: d = 0;
+ }
+ if(*cbd->buf == 'v') cbd->p.v = d;
+ else cbd->p.t = d;
+ return;
+ }
+
+ if(cbd->buf[0] == 'e' && !cbd->buf[0]) {
+ p->e_msg = s;
+ p->e_len = cbd->v.s.l;
+ return;
+ }
+ // DEBUG_TRACE(print_safe_str("UKNOWN",cbd));
+}
+
+
+const u_int8_t *bt_decode(const u_int8_t *b, size_t *l, int *ret, bt_parse_data_cb_t *cbd) {
+
+ unsigned int n=0,neg=0;
+ i_int64_t d = 0;
+ register u_int8_t c;
+
+ if(*l == 0) return NULL;
+ if(cbd->level > BDEC_MAXDEPT) goto bad_data;
+ c = *b++; (*l)--;
+ if(c == 'i') { // integer
+ while(*l) {
+ c = *b++; (*l)--;
+ n++;
+ if(c == '-') {
+ if(n != 1) goto bad_data;
+ n--;
+ neg=1;
+ continue;
+ }
+ if(c >= '0' && c <= '9') {
+ if(c == '0' && n > 1 && !d && *b != 'e') goto bad_data;
+ d *= 10;
+ d += c-'0';
+ continue;
+ }
+ if(c != 'e') goto bad_data;
+ break;
+ }
+ if(neg) d=-d;
+ cbd->t = 1;
+ cbd->v.i = neg ? -d:d;
+ return b;
+ }
+ if(c >= '1' && c <= '9') { //string
+ d=c-'0';
+ while(*l) {
+ c = *b++; (*l)--;
+ n++;
+ if(c >= '0' && c <= '9') {
+ if(c == '0' && n > 1 && d == 0) goto bad_data;
+ d *= 10;
+ d += c-'0';
+ continue;
+ }
+ if(c != ':') goto bad_data;
+ break;
+ }
+ if(d > *l) goto bad_data;
+ cbd->t = 2;
+ cbd->v.s.s = b;
+ cbd->v.s.l = d;
+ b += d;
+ *l -= d;
+ return b;
+ }
+ if(c == 'l') {
+ cbd->level++;
+ do {
+ b = bt_decode(b,l,ret,cbd);
+ if(*ret < 0 || *l == 0) goto bad_data;
+ cb_data(cbd,ret);
+ if(*ret < 0) goto bad_data;
+ cbd->t = 0;
+ } while (*b != 'e' && *l != 0);
+ b++; (*l)--;
+ cbd->level--;
+ return b;
+ }
+ if(c == 'd') {
+ cbd->level++;
+ do {
+ char *ls = cbd->buf + strlen(cbd->buf);
+ int l1 = ls != cbd->buf ? 1:0;
+ if(!(*b >= '1' && *b <= '9')) goto bad_data;
+ b = bt_decode(b,l,ret,cbd);
+ if(*ret < 0 || *l == 0) goto bad_data;
+ if(ls+cbd->v.s.l+l1 < &cbd->buf[sizeof(cbd->buf)-1]) {
+ if(l1) ls[0]='.';
+ strncpy(ls+l1,(char *)cbd->v.s.s,cbd->v.s.l);
+ ls[cbd->v.s.l+l1]=0;
+ }
+ b = bt_decode(b,l,ret,cbd);
+ if(*ret < 0 || *l == 0) goto bad_data;
+ cb_data(cbd,ret);
+ if(*ret < 0) goto bad_data;
+ cbd->t = 0;
+ *ls = 0;
+ } while (*b != 'e' && l != 0);
+
+ b++; (*l)--;
+ cbd->level--;
+ return b;
+ }
+ bad_data:
+ *ret=-1;
+ return b;
+}
diff --git a/src/lib/protocols/btlib.h b/src/lib/protocols/btlib.h
new file mode 100644
index 000000000..cc2928155
--- /dev/null
+++ b/src/lib/protocols/btlib.h
@@ -0,0 +1,147 @@
+/*
+ * btlib.h
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ * Contributed by Vitaly Lavrov <vel21ripn@gmail.com>
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define BDEC_MAXDEPT 8
+
+
+typedef struct b_elem_s {
+ const u_int8_t *s;
+ size_t l;
+} b_elem_s_t;
+
+struct __attribute__ ((__packed__)) bt_nodes_data {
+ u_int8_t id[20] ;
+ u_int32_t ip;
+ u_int16_t port;
+};
+
+struct __attribute__ ((__packed__)) bt_ipv4p {
+ u_int32_t ip;
+ u_int16_t port;
+};
+
+struct __attribute__ ((__packed__)) bt_ipv4p2 {
+ struct bt_ipv4p d;
+ u_int8_t pad[2];
+};
+
+struct __attribute__ ((__packed__)) bt_nodes6_data {
+ u_int8_t id[20] ;
+ u_int32_t ip[4];
+ u_int16_t port;
+};
+
+struct __attribute__ ((__packed__)) bt_ipv6p {
+ u_int32_t ip[4];
+ u_int16_t port;
+};
+
+struct __attribute__ ((__packed__)) bt_ipv6p2 {
+ struct bt_ipv6p d;
+ u_int8_t pad[3];
+};
+
+/*
+
+ a.id S r.id S
+ a.info_hash S r.ip ipv4
+ a.name S r.nodes x(id,ipv4,port)
+ -a.noseed 0|1 r.n S name of file
+ a.port N r.p port
+ -a.scrape 0|1 r.token S
+ -a.seed 0|1 r.values x(ipv4,port)
+ a.target S
+ a.token S -a.vote N
+ -a.want n4|n6
+
+ q announce_peer q find_node
+ q get_peers q ping
+ -q vote
+
+ ip ipv4+port interval N
+ min interval N peers x(ipv4,port)
+ t 2/4/8b v 4/6b
+
+ e S y e y r y q
+
+ */
+
+struct bt_parse_protocol {
+ u_int16_t y_e:1, y_r:1, y_q:1,
+ q_a_peer:1,q_f_node:1,
+ q_g_peers:1,q_ping:1,
+ h_int:1,h_mint:1,h_ip:1;
+ struct {
+ const u_int8_t *id, // 20
+ *info_hash, // 20
+ *target, // 20
+ *token, // 20|8
+ *name; // varlen
+ u_int16_t name_len;
+ u_int16_t port;
+ u_int16_t t_len;
+ } a;
+ struct {
+ const u_int8_t *id, // 20
+ *token, // 20|8
+ *values, // (6+2)*x
+ *values6, // (18_3)*x
+ *name; // varlen
+ struct bt_ipv4p *ip;
+ struct bt_nodes_data *nodes;
+ struct bt_nodes6_data *nodes6;
+ u_int16_t name_len;
+ u_int16_t nn; // nodes num
+ u_int16_t nv; // valuse num
+ u_int16_t nn6; // nodes6 num
+ u_int16_t nv6; // valuse6 num
+ u_int16_t port;
+ u_int16_t t_len;
+ } r;
+ int interval,min_interval;
+ struct bt_ipv4p *peers;
+ int n_peers;
+ struct bt_ipv4p *ip;
+ const u_int8_t *e_msg;
+ u_int16_t e_len;
+ u_int64_t t,v;
+};
+
+typedef struct bt_parse_data_cb {
+ struct bt_parse_protocol p;
+ char buf[64];
+ int level;
+ int t;
+ union {
+ i_int64_t i;
+ b_elem_s_t s;
+ } v;
+} bt_parse_data_cb_t;
+
+#ifndef __KERNEL__
+extern int bt_parse_debug;
+void dump_bt_proto_struct(struct bt_parse_protocol *p);
+#endif
+const u_int8_t *bt_decode(const u_int8_t *b, size_t *l, int *ret, bt_parse_data_cb_t *cbd);
+
diff --git a/src/lib/protocols/ciscovpn.c b/src/lib/protocols/ciscovpn.c
new file mode 100644
index 000000000..9245a6aaa
--- /dev/null
+++ b/src/lib/protocols/ciscovpn.c
@@ -0,0 +1,70 @@
+/*
+ * ciscovpn.c
+ * Copyright (C) 2013 by Remy Mudingay <mudingay@ill.fr>
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_CISCOVPN
+
+static void ndpi_int_ciscovpn_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CISCOVPN, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_ciscovpn(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t udport = 0, usport = 0;
+ u_int16_t tdport = 0, tsport = 0;
+
+
+ NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "search CISCOVPN.\n");
+
+ if(packet->tcp != NULL) {
+ tsport = ntohs(packet->tcp->source), tdport = ntohs(packet->tcp->dest);
+ NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "calculated CISCOVPN over tcp ports.\n");
+ }
+ if(packet->udp != NULL) {
+ usport = ntohs(packet->udp->source), udport = ntohs(packet->udp->dest);
+ NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "calculated CISCOVPN over udp ports.\n");
+ }
+
+ if((tdport == 10000 && tsport == 10000) ||
+ ((tsport == 443 || tdport == 443) &&
+ (packet->payload[0] == 0x17 &&
+ packet->payload[1] == 0x01 &&
+ packet->payload[2] == 0x00 &&
+ packet->payload[3] == 0x00)
+ )
+ )
+
+ {
+ /* This is a good query 17010000*/
+ NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "found CISCOVPN.\n");
+ ndpi_int_ciscovpn_add_connection(ndpi_struct, flow);
+ }
+ else if(
+ (
+ (usport == 10000 && udport == 10000)
+ &&
+ (packet->payload[0] == 0xfe &&
+ packet->payload[1] == 0x57 &&
+ packet->payload[2] == 0x7e &&
+ packet->payload[3] == 0x2b)
+ )
+ )
+ {
+
+
+ /* This is a good query fe577e2b */
+ NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "found CISCOVPN.\n");
+ ndpi_int_ciscovpn_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "exclude CISCOVPN.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CISCOVPN);
+ }
+
+}
+#endif
diff --git a/src/lib/protocols/citrix.c b/src/lib/protocols/citrix.c
new file mode 100644
index 000000000..1cae9f9e5
--- /dev/null
+++ b/src/lib/protocols/citrix.c
@@ -0,0 +1,93 @@
+/*
+ * citrix.c
+ *
+ * Copyright (C) 2012-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_CITRIX
+
+/* ************************************ */
+
+static void ndpi_check_citrix(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+#if 0
+ printf("[len=%u][%02X %02X %02X %02X]\n", payload_len,
+ packet->payload[0] & 0xFF,
+ packet->payload[1] & 0xFF,
+ packet->payload[2] & 0xFF,
+ packet->payload[3] & 0xFF);
+#endif
+
+ if(packet->tcp != NULL) {
+ flow->l4.tcp.citrix_packet_id++;
+
+ if((flow->l4.tcp.citrix_packet_id == 3)
+ /* We have seen the 3-way handshake */
+ && flow->l4.tcp.seen_syn
+ && flow->l4.tcp.seen_syn_ack
+ && flow->l4.tcp.seen_ack) {
+ if(payload_len == 6) {
+ char citrix_header[] = { 0x07, 0x07, 0x49, 0x43, 0x41, 0x00 };
+
+ if(memcmp(packet->payload, citrix_header, sizeof(citrix_header)) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_CITRIX, ndpi_struct, NDPI_LOG_DEBUG, "Found citrix.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CITRIX, NDPI_REAL_PROTOCOL);
+ }
+
+ return;
+ } else if(payload_len > 4) {
+ char citrix_header[] = { 0x1a, 0x43, 0x47, 0x50, 0x2f, 0x30, 0x31 };
+
+ if((memcmp(packet->payload, citrix_header, sizeof(citrix_header)) == 0)
+ || (ndpi_strnstr((const char *)packet->payload, "Citrix.TcpProxyService", payload_len) != NULL)) {
+ NDPI_LOG(NDPI_PROTOCOL_CITRIX, ndpi_struct, NDPI_LOG_DEBUG, "Found citrix.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CITRIX, NDPI_REAL_PROTOCOL);
+ }
+
+ return;
+ }
+
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CITRIX);
+ } else if(flow->l4.tcp.citrix_packet_id > 3)
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CITRIX);
+
+ return;
+ }
+}
+
+void ndpi_search_citrix(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_CITRIX, ndpi_struct, NDPI_LOG_DEBUG, "citrix detection...\n");
+
+ /* skip marked packets */
+ if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_CITRIX)
+ ndpi_check_citrix(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/collectd.c b/src/lib/protocols/collectd.c
new file mode 100644
index 000000000..eee805d5c
--- /dev/null
+++ b/src/lib/protocols/collectd.c
@@ -0,0 +1,53 @@
+/*
+ * collectd.c
+ *
+ * Copyright (C) 2014 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_COLLECTD
+
+void ndpi_search_collectd(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int len = 0;
+
+ NDPI_LOG(NDPI_PROTOCOL_COLLECTD, ndpi_struct, NDPI_LOG_DEBUG, "search collectd.\n");
+
+ if (packet->udp == NULL) return;
+
+
+ while(len < packet->payload_packet_len) {
+ // u_int16_t elem_type = ntohs(*((u_int16_t*)&packet->payload[len]));
+ u_int16_t elem_len = ntohs(*((u_int16_t*)&packet->payload[len+2]));
+
+ if (elem_len == 0) break;
+
+ len += elem_len;
+ }
+
+ if(len == packet->payload_packet_len) {
+ NDPI_LOG(NDPI_PROTOCOL_COLLECTD, ndpi_struct, NDPI_LOG_DEBUG, "found COLLECTD.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_COLLECTD, NDPI_REAL_PROTOCOL);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_COLLECTD, ndpi_struct, NDPI_LOG_DEBUG, "exclude COLLECTD.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_COLLECTD);
+ }
+}
+#endif
diff --git a/src/lib/protocols/corba.c b/src/lib/protocols/corba.c
new file mode 100644
index 000000000..050d1035d
--- /dev/null
+++ b/src/lib/protocols/corba.c
@@ -0,0 +1,48 @@
+/*
+ * corba.c
+ *
+ * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ *
+ * This module is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_CORBA
+static void ndpi_int_corba_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CORBA, NDPI_CORRELATED_PROTOCOL);
+}
+void ndpi_search_corba(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_CORBA, ndpi_struct, NDPI_LOG_DEBUG, "search for CORBA.\n");
+ if(packet->tcp != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_CORBA, ndpi_struct, NDPI_LOG_DEBUG, "calculating CORBA over tcp.\n");
+ /* Corba General Inter-ORB Protocol -> GIOP */
+ if ((packet->payload_packet_len >= 24 && packet->payload_packet_len <= 144) &&
+ memcmp(packet->payload, "GIOP", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_CORBA, ndpi_struct, NDPI_LOG_DEBUG, "found corba.\n");
+ ndpi_int_corba_add_connection(ndpi_struct, flow);
+ }
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_CORBA, ndpi_struct, NDPI_LOG_DEBUG, "exclude CORBA.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CORBA);
+ }
+}
+#endif
diff --git a/src/lib/protocols/crossfire.c b/src/lib/protocols/crossfire.c
new file mode 100644
index 000000000..cb5b3520f
--- /dev/null
+++ b/src/lib/protocols/crossfire.c
@@ -0,0 +1,85 @@
+/*
+ * crossfire.c
+ *
+ * Copyright (C) 2012-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+/* include files */
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_CROSSFIRE
+
+
+static void ndpi_int_crossfire_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type)
+{
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CROSSFIRE, protocol_type);
+}
+
+void ndpi_search_crossfire_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_CROSSFIRE, ndpi_struct, NDPI_LOG_DEBUG, "search crossfire.\n");
+
+
+ if (packet->udp != 0) {
+ if (packet->payload_packet_len == 25 && get_u_int32_t(packet->payload, 0) == ntohl(0xc7d91999)
+ && get_u_int16_t(packet->payload, 4) == ntohs(0x0200)
+ && get_u_int16_t(packet->payload, 22) == ntohs(0x7d00)
+ ) {
+ NDPI_LOG(NDPI_PROTOCOL_CROSSFIRE, ndpi_struct, NDPI_LOG_DEBUG, "Crossfire: found udp packet.\n");
+ ndpi_int_crossfire_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ } else if (packet->tcp != 0) {
+
+ if (packet->payload_packet_len > 4 && memcmp(packet->payload, "GET /", 5) == 0) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->parsed_lines == 8
+ && (packet->line[0].ptr != NULL && packet->line[0].len >= 30
+ && (memcmp(&packet->payload[5], "notice/login_big", 16) == 0
+ || memcmp(&packet->payload[5], "notice/login_small", 18) == 0))
+ && memcmp(&packet->payload[packet->line[0].len - 19], "/index.asp HTTP/1.", 18) == 0
+ && (packet->host_line.ptr != NULL && packet->host_line.len >= 13
+ && (memcmp(packet->host_line.ptr, "crossfire", 9) == 0
+ || memcmp(packet->host_line.ptr, "www.crossfire", 13) == 0))
+ ) {
+ NDPI_LOG(NDPI_PROTOCOL_CROSSFIRE, ndpi_struct, NDPI_LOG_DEBUG, "Crossfire: found HTTP request.\n");
+ ndpi_int_crossfire_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_CROSSFIRE, ndpi_struct, NDPI_LOG_DEBUG, "exclude crossfire.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CROSSFIRE);
+}
+
+
+
+#endif
diff --git a/src/lib/protocols/dcerpc.c b/src/lib/protocols/dcerpc.c
new file mode 100644
index 000000000..5879aec6d
--- /dev/null
+++ b/src/lib/protocols/dcerpc.c
@@ -0,0 +1,54 @@
+/*
+ * dcerpc.c
+ *
+ * Copyright (C) 2011-13 by ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_DCERPC
+
+static void ndpi_int_dcerpc_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DCERPC, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_dcerpc(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+ if((packet->tcp != NULL)
+ && (packet->payload_packet_len > 64)
+ && ((ntohs(packet->tcp->source) == 135) || (ntohs(packet->tcp->dest) == 135))
+ && (packet->payload[0] == 0x05) /* version 5 */
+ && (packet->payload[2] < 16) /* Packet type */
+ ) {
+ NDPI_LOG(NDPI_PROTOCOL_DCERPC, ndpi_struct, NDPI_LOG_DEBUG, "DCERPC match\n");
+ ndpi_int_dcerpc_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DCERPC);
+}
+
+#endif
diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c
new file mode 100644
index 000000000..b623a6a15
--- /dev/null
+++ b/src/lib/protocols/dhcp.c
@@ -0,0 +1,60 @@
+/*
+ * dhcp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_DHCP
+
+static void ndpi_int_dhcp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DHCP, NDPI_REAL_PROTOCOL);
+}
+
+
+void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ /* this detection also works for asymmetric dhcp traffic */
+
+ /*check standard DHCP 0.0.0.0:68 -> 255.255.255.255:67 */
+ if (packet->payload_packet_len >= 244 && (packet->udp->source == htons(67)
+ || packet->udp->source == htons(68))
+ && (packet->udp->dest == htons(67) || packet->udp->dest == htons(68))
+ && get_u_int32_t(packet->payload, 236) == htonl(0x63825363)
+ && get_u_int16_t(packet->payload, 240) == htons(0x3501)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_DHCP, ndpi_struct, NDPI_LOG_DEBUG, "DHCP request\n");
+
+ ndpi_int_dhcp_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DHCP);
+}
+#endif
diff --git a/src/lib/protocols/dhcpv6.c b/src/lib/protocols/dhcpv6.c
new file mode 100644
index 000000000..b0c23c9c9
--- /dev/null
+++ b/src/lib/protocols/dhcpv6.c
@@ -0,0 +1,60 @@
+/*
+ * dhcpv6.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+/* include files */
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_DHCPV6
+
+static void ndpi_int_dhcpv6_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DHCPV6, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_dhcpv6_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len >= 4 &&
+ (packet->udp->source == htons(546) || packet->udp->source == htons(547)) &&
+ (packet->udp->dest == htons(546) || packet->udp->dest == htons(547)) &&
+ packet->payload[0] >= 1 && packet->payload[0] <= 13) {
+
+ NDPI_LOG(NDPI_PROTOCOL_DHCPV6, ndpi_struct, NDPI_LOG_DEBUG, "DHCPv6 detected.\n");
+ ndpi_int_dhcpv6_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_DHCPV6, ndpi_struct, NDPI_LOG_DEBUG, "DHCPv6 excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DHCPV6);
+}
+
+#endif
diff --git a/src/lib/protocols/directconnect.c b/src/lib/protocols/directconnect.c
new file mode 100644
index 000000000..624f57e58
--- /dev/null
+++ b/src/lib/protocols/directconnect.c
@@ -0,0 +1,474 @@
+/*
+ * directconnect.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_DIRECTCONNECT
+
+//#define NDPI_DEBUG_DIRECTCONNECT
+//#define NDPI_DIRECTCONNECT_PORT_DEBUG
+//#define NDPI_DEBUG_DIRECTCONNECT_CONN
+
+
+#define DIRECT_CONNECT_TYPE_HUB 0
+#define DIRECT_CONNECT_TYPE_PEER 1
+#define DIRECT_CONNECT_ADC_PEER 2
+
+static u_int32_t skip_unknown_headers(const u_int8_t * payload, u_int32_t payload_len, u_int32_t pos)
+{
+ u_int32_t i = pos;
+ while (i < payload_len && payload[i] != 0x0a)
+ i++;
+
+ i++;
+ return i;
+
+}
+
+static u_int16_t parse_binf_message(struct ndpi_detection_module_struct
+ *ndpi_struct, const u_int8_t * payload, int payload_len)
+{
+ u_int32_t i = 4;
+ u_int16_t bytes_read = 0;
+ u_int16_t ssl_port = 0;
+ while (i < payload_len) {
+ i = skip_unknown_headers(payload, payload_len, i);
+ if ((i + 30) < payload_len) {
+ if (memcmp(&payload[i], "DCTM", 4) == 0) {
+ if (memcmp(&payload[i + 15], "ADCS", 4) == 0) {
+ ssl_port = ntohs_ndpi_bytestream_to_number(&payload[i + 25], 5, &bytes_read);
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "directconnect ssl port parsed %d", ssl_port);
+
+ }
+ }
+ } else {
+ break;
+ }
+
+ }
+ return ssl_port;
+}
+
+static void ndpi_int_directconnect_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ const u_int8_t connection_type)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL);
+
+ if (src != NULL) {
+ src->directconnect_last_safe_access_time = packet->tick_timestamp;
+ if (connection_type == DIRECT_CONNECT_TYPE_PEER) {
+ if (packet->tcp != NULL
+ && flow->setup_packet_direction != packet->packet_direction && src->detected_directconnect_port == 0) {
+ src->detected_directconnect_port = packet->tcp->source;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "directconnect tcp PORT %u for src\n", ntohs(src->detected_directconnect_port));
+ }
+ if (packet->udp != NULL && src->detected_directconnect_udp_port == 0) {
+ src->detected_directconnect_udp_port = packet->udp->source;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "directconnect udp PORT %u for src\n", ntohs(src->detected_directconnect_port));
+
+ }
+ }
+
+ }
+ if (dst != NULL) {
+ dst->directconnect_last_safe_access_time = packet->tick_timestamp;
+ if (connection_type == DIRECT_CONNECT_TYPE_PEER) {
+ if (packet->tcp != NULL
+ && flow->setup_packet_direction == packet->packet_direction && dst->detected_directconnect_port == 0) {
+ /* DST PORT MARKING CAN LEAD TO PORT MISSDETECTIONS
+ * seen at large customer http servers, where someone has send faked DC tcp packets
+ * to the server
+ */
+
+ /*
+ dst->detected_directconnect_port = packet->tcp->dest;
+ NDPI_LOG (NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "directconnect tcp PORT %u for dst\n",
+ ntohs (dst->detected_directconnect_port));
+ */
+ }
+ }
+ }
+}
+
+static void ndpi_search_directconnect_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ if (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_DIRECTCONNECT) {
+ if (packet->payload_packet_len >= 40 && memcmp(&packet->payload[0], "BINF", 4) == 0) {
+ u_int16_t ssl_port = 0;
+ ssl_port = parse_binf_message(ndpi_struct, &packet->payload[4], packet->payload_packet_len - 4);
+ if (dst != NULL && ssl_port) {
+ dst->detected_directconnect_ssl_port = ssl_port;
+ }
+ if (src != NULL && ssl_port) {
+ src->detected_directconnect_ssl_port = ssl_port;
+ }
+
+
+ }
+ if ((packet->payload_packet_len >= 38 && packet->payload_packet_len <= 42)
+ && memcmp(&packet->payload[0], "DCTM", 4) == 0 && memcmp(&packet->payload[15], "ADCS", 4) == 0) {
+ u_int16_t bytes_read = 0;
+ if (dst != NULL) {
+ dst->detected_directconnect_ssl_port =
+ ntohs_ndpi_bytestream_to_number(&packet->payload[25], 5, &bytes_read);
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "directconnect ssl port parsed %d", ntohs(dst->detected_directconnect_ssl_port));
+ }
+ if (src != NULL) {
+ src->detected_directconnect_ssl_port =
+ ntohs_ndpi_bytestream_to_number(&packet->payload[25], 5, &bytes_read);
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "directconnect ssl port parsed %d", ntohs(src->detected_directconnect_ssl_port));
+ }
+
+
+ }
+ return;
+
+ }
+ if (src != NULL) {
+ if (src->detected_directconnect_port == packet->tcp->source) {
+ if ((u_int32_t)
+ (packet->tick_timestamp -
+ src->directconnect_last_safe_access_time) < ndpi_struct->directconnect_connection_ip_tick_timeout) {
+ ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL);
+ src->directconnect_last_safe_access_time = packet->tick_timestamp;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "marking using dc port\n %d", ntohs(src->detected_directconnect_port));
+ return;
+ } else {
+ src->detected_directconnect_port = 0;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "resetting src port due to timeout");
+ return;
+ }
+ }
+ if (src->detected_directconnect_ssl_port == packet->tcp->dest) {
+ if ((u_int32_t)
+ (packet->tick_timestamp -
+ src->directconnect_last_safe_access_time) < ndpi_struct->directconnect_connection_ip_tick_timeout) {
+ ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL);
+ src->directconnect_last_safe_access_time = packet->tick_timestamp;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "marking using dc port\n %d", ntohs(src->detected_directconnect_ssl_port));
+ return;
+ } else {
+ src->detected_directconnect_ssl_port = 0;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "resetting src port due to timeout");
+ return;
+ }
+ }
+
+ }
+
+ if (dst != NULL) {
+ if (dst->detected_directconnect_port == packet->tcp->dest) {
+ if ((u_int32_t)
+ (packet->tick_timestamp -
+ dst->directconnect_last_safe_access_time) < ndpi_struct->directconnect_connection_ip_tick_timeout) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL);
+ dst->directconnect_last_safe_access_time = packet->tick_timestamp;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "marking using dc port\n %d", ntohs(dst->detected_directconnect_port));
+ return;
+ } else {
+ dst->detected_directconnect_port = 0;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "resetting dst port due to timeout");
+ return;
+ }
+ }
+ if (dst->detected_directconnect_ssl_port == packet->tcp->dest) {
+ if ((u_int32_t)
+ (packet->tick_timestamp -
+ dst->directconnect_last_safe_access_time) < ndpi_struct->directconnect_connection_ip_tick_timeout) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL);
+ dst->directconnect_last_safe_access_time = packet->tick_timestamp;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "marking using dc port\n %d", ntohs(dst->detected_directconnect_ssl_port));
+
+ return;
+ } else {
+ dst->detected_directconnect_ssl_port = 0;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "resetting dst port due to timeout");
+ return;
+ }
+ }
+
+ }
+
+ if (flow->directconnect_stage == 0) {
+
+ if (packet->payload_packet_len > 6) {
+ if (packet->payload[0] == '$'
+ && packet->payload[packet->payload_packet_len - 1] == '|'
+ && (memcmp(&packet->payload[1], "Lock ", 5) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "maybe first dc connect to hub detected\n");
+ flow->directconnect_stage = 1;
+ return;
+ }
+ if (packet->payload_packet_len > 7
+ && packet->payload[0] == '$'
+ && packet->payload[packet->payload_packet_len - 1] == '|'
+ && (memcmp(&packet->payload[1], "MyNick ", 7) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "maybe first dc connect between peers detected\n");
+ flow->directconnect_stage = 2;
+ return;
+ }
+
+ }
+ if (packet->payload_packet_len >= 11) {
+ /* did not see this pattern in any trace */
+ if (memcmp(&packet->payload[0], "HSUP ADBAS0", 11) == 0
+ || memcmp(&packet->payload[0], "HSUP ADBASE", 11) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "found directconnect HSUP ADBAS0 E\n");
+ ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_HUB);
+ return;
+ /* did not see this pattern in any trace */
+ } else if (memcmp(&packet->payload[0], "CSUP ADBAS0", 11) == 0 ||
+ memcmp(&packet->payload[0], "CSUP ADBASE", 11) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "found directconnect CSUP ADBAS0 E\n");
+ ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_ADC_PEER);
+ return;
+
+ }
+
+ }
+
+ } else if (flow->directconnect_stage == 1) {
+ if (packet->payload_packet_len >= 11) {
+ /* did not see this pattern in any trace */
+ if (memcmp(&packet->payload[0], "HSUP ADBAS0", 11) == 0
+ || memcmp(&packet->payload[0], "HSUP ADBASE", 11) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "found directconnect HSUP ADBAS E in second packet\n");
+ ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_HUB);
+
+ return;
+ /* did not see this pattern in any trace */
+ } else if (memcmp(&packet->payload[0], "CSUP ADBAS0", 11) == 0 ||
+ memcmp(&packet->payload[0], "CSUP ADBASE", 11) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "found directconnect HSUP ADBAS0 E in second packet\n");
+ ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_ADC_PEER);
+
+
+ return;
+
+ }
+ }
+ /* get client hello answer or server message */
+ if (packet->payload_packet_len > 6) {
+ if ((packet->payload[0] == '$' || packet->payload[0] == '<')
+ && packet->payload[packet->payload_packet_len - 1] == '|') {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, NDPI_LOG_DEBUG, "second dc detected\n");
+ ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_HUB);
+
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, NDPI_LOG_DEBUG, "second dc not detected\n");
+ }
+
+ }
+ } else if (flow->directconnect_stage == 2) {
+ /* get client hello answer or server message */
+ if (packet->payload_packet_len > 6) {
+ if (packet->payload[0] == '$' && packet->payload[packet->payload_packet_len - 1] == '|') {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "second dc between peers detected\n");
+
+
+ ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_PEER);
+
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "second dc between peers not detected\n");
+ }
+ }
+
+ }
+
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DIRECTCONNECT);
+
+}
+
+static void ndpi_search_directconnect_udp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ 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 -
+ dst->directconnect_last_safe_access_time) < ndpi_struct->directconnect_connection_ip_tick_timeout) {
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL);
+ dst->directconnect_last_safe_access_time = packet->tick_timestamp;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "marking using dc udp port\n %d", ntohs(dst->detected_directconnect_udp_port));
+ return;
+ } else {
+ dst->detected_directconnect_udp_port = 0;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "resetting dst udp port due to timeout");
+ return;
+ }
+ }
+
+ if (packet->payload_packet_len > 58) {
+ if (src != NULL
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_DIRECTCONNECT)) {
+ if (packet->payload[0] == '$'
+ && packet->payload[packet->payload_packet_len - 1] == '|'
+ && memcmp(&packet->payload[1], "SR ", 3) == 0) {
+ pos = packet->payload_packet_len - 2;
+ if (packet->payload[pos] == ')') {
+ while (pos > 0 && packet->payload[pos] != '(' && count < 21) {
+ pos--;
+ count++;
+ }
+ if (packet->payload[pos] == '(') {
+ pos = pos - 44;
+ if (pos > 2 && memcmp(&packet->payload[pos], "TTH:", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, NDPI_LOG_DEBUG, "dc udp detected\n");
+ ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_PEER);
+ return;
+ }
+ }
+ }
+ flow->directconnect_stage++;
+
+ if (flow->directconnect_stage < 3) {
+
+
+ return;
+ }
+
+ }
+
+ }
+ if (dst != NULL
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_DIRECTCONNECT)) {
+ if (packet->payload[0] == '$'
+ && packet->payload[packet->payload_packet_len - 1] == '|'
+ && memcmp(&packet->payload[1], "SR ", 3) == 0) {
+ pos = packet->payload_packet_len - 2;
+ if (packet->payload[pos] == ')') {
+ while (pos > 0 && packet->payload[pos] != '(' && count < 21) {
+ pos--;
+ count++;
+ }
+ if (packet->payload[pos] == '(') {
+ pos = pos - 44;
+ if (pos > 2 && memcmp(&packet->payload[pos], "TTH:", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, NDPI_LOG_DEBUG, "dc udp detected\n");
+ ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_PEER);
+ return;
+ }
+ }
+ }
+ flow->directconnect_stage++;
+ if (flow->directconnect_stage < 3)
+ return;
+
+ }
+ }
+
+ }
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, NDPI_LOG_DEBUG,
+ "excluded at stage %d \n", flow->directconnect_stage);
+
+
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DIRECTCONNECT);
+
+
+}
+
+void ndpi_search_directconnect(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_DIRECTCONNECT) {
+ if (src != NULL && ((u_int32_t)
+ (packet->tick_timestamp -
+ src->directconnect_last_safe_access_time) <
+ ndpi_struct->directconnect_connection_ip_tick_timeout)) {
+ src->directconnect_last_safe_access_time = packet->tick_timestamp;
+
+ } else if (dst != NULL && ((u_int32_t)
+ (packet->tick_timestamp -
+ dst->directconnect_last_safe_access_time) <
+ ndpi_struct->directconnect_connection_ip_tick_timeout)) {
+ dst->directconnect_last_safe_access_time = packet->tick_timestamp;
+ } else {
+ packet->detected_protocol_stack[0] = NDPI_PROTOCOL_UNKNOWN;
+ NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct,
+ NDPI_LOG_DEBUG, "directconnect: skipping as unknown due to timeout\n");
+ }
+ return;
+ }
+
+ if (packet->tcp != NULL) {
+ ndpi_search_directconnect_tcp(ndpi_struct, flow);
+ } else if (packet->udp != NULL) {
+ ndpi_search_directconnect_udp(ndpi_struct, flow);
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/directdownloadlink.c b/src/lib/protocols/directdownloadlink.c
new file mode 100644
index 000000000..5c8de52c0
--- /dev/null
+++ b/src/lib/protocols/directdownloadlink.c
@@ -0,0 +1,737 @@
+/*
+ * directdownloadlink.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-14svn - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK
+
+
+#ifdef NDPI_DEBUG_DIRECT_DOWNLOAD_LINK
+//#define NDPI_DEBUG_DIRECT_DOWNLOAD_LINK_NOTHING_FOUND
+//#define NDPI_DEBUG_DIRECT_DOWNLOAD_LINK_PACKET_TOO_SMALL
+#define NDPI_DEBUG_DIRECT_DOWNLOAD_LINK_IP
+#endif
+
+static void ndpi_int_direct_download_link_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, NDPI_CORRELATED_PROTOCOL);
+
+ flow->l4.tcp.ddlink_server_direction = packet->packet_direction;
+}
+
+
+
+/*
+ return 0 if nothing has been detected
+ return 1 if it is a megaupload packet
+*/
+u_int8_t search_ddl_domains(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ u_int16_t filename_start = 0;
+ u_int8_t i = 1;
+ u_int16_t host_line_len_without_port;
+
+ if (packet->payload_packet_len < 100) {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: Packet too small.\n");
+ goto end_ddl_nothing_found;
+ }
+
+
+
+ if (memcmp(packet->payload, "POST ", 5) == 0) {
+ filename_start = 5; // POST
+ NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: POST FOUND\n");
+ } else if (memcmp(packet->payload, "GET ", 4) == 0) {
+ filename_start = 4; // GET
+ NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: GET FOUND\n");
+ } else {
+ goto end_ddl_nothing_found;
+ }
+ // parse packet
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if (packet->host_line.ptr == NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: NO HOST FOUND\n");
+ goto end_ddl_nothing_found;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: Host: found\n");
+
+ if (packet->line[0].len < 9 + filename_start
+ || memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct,
+ NDPI_LOG_DEBUG, "DDL: PACKET NOT HTTP CONFORM.\nXXX%.*sXXX\n",
+ 8, &packet->line[0].ptr[packet->line[0].len - 9]);
+ goto end_ddl_nothing_found;
+ }
+ // BEGIN OF AUTOMATED CODE GENERATION
+ // first see if we have ':port' at the end of the line
+ host_line_len_without_port = packet->host_line.len;
+ if (host_line_len_without_port >= i && packet->host_line.ptr[host_line_len_without_port - i] >= '0'
+ && packet->host_line.ptr[packet->host_line.len - i] <= '9') {
+ i = 2;
+ while (host_line_len_without_port >= i && packet->host_line.ptr[host_line_len_without_port - i] >= '0'
+ && packet->host_line.ptr[host_line_len_without_port - i] <= '9') {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: number found\n");
+ i++;
+ }
+ if (host_line_len_without_port >= i && packet->host_line.ptr[host_line_len_without_port - i] == ':') {
+ NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: ':' found\n");
+ host_line_len_without_port = host_line_len_without_port - i;
+ }
+ }
+ // then start automated code generation
+
+ if (host_line_len_without_port >= 0 + 4
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 4], ".com", 4) == 0) {
+ if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'd') {
+ if (host_line_len_without_port >= 5 + 6 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 6], "4share", 6) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 6 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 6 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 8 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 8], "fileclou", 8) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 5
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 5], "uploa", 5) == 0) {
+ if (host_line_len_without_port >= 10 + 6 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 6], "files-", 6) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 10 - 6 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 10 - 6 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 10 + 4 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 4], "mega", 4) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 10 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 5], "rapid", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 10 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 5], "turbo", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'o') {
+ if (host_line_len_without_port >= 5 + 6 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 6], "badong", 6) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 6 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 6 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 5], "fileh", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'g') {
+ if (host_line_len_without_port >= 5 + 2
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 2], "in", 2) == 0) {
+ if (host_line_len_without_port >= 7 + 4
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 7 - 4], "shar", 4) == 0) {
+ if (host_line_len_without_port >= 11 + 4 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 11 - 4], "best", 4) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 11 - 4 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 11 - 4 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 11 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 11 - 5], "quick", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 11 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 11 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 7 + 6 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 7 - 6], "upload", 6) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 7 - 6 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 7 - 6 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 5 + 7 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 7], "sharebi", 7) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 4 + 8 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 8], "bigfilez", 8) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 4 - 8 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 4 - 8 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'e') {
+ if (host_line_len_without_port >= 5 + 3
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 3], "fil", 3) == 0) {
+ if (host_line_len_without_port >= 8 + 2
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 2], "mo", 2) == 0) {
+ if (host_line_len_without_port >= 10 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 5], "china", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 8 + 2 + 1
+ && (packet->host_line.ptr[host_line_len_without_port - 8 - 2 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 8 - 2 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ }
+ if (host_line_len_without_port >= 8 + 3 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 3], "hot", 3) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 8 - 3 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 8 - 3 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 8 + 6 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 6], "keepmy", 6) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 8 - 6 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 8 - 6 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 8 + 1
+ && packet->host_line.ptr[host_line_len_without_port - 8 - 1] == 'e') {
+ if (host_line_len_without_port >= 9 + 3 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 3], "sav", 3) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 9 - 3 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 9 - 3 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 9 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 5], "sendm", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 9 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 9 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 8 + 8 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 8], "sharebig", 8) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 8 - 8 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 8 - 8 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 8 + 3 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 3], "up-", 3) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 8 - 3 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 8 - 3 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 5 + 1 && packet->host_line.ptr[host_line_len_without_port - 5 - 1] == 'r') {
+ if (host_line_len_without_port >= 6 + 3
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 6 - 3], "sha", 3) == 0) {
+ if (host_line_len_without_port >= 9 + 1
+ && packet->host_line.ptr[host_line_len_without_port - 9 - 1] == '-') {
+ if (host_line_len_without_port >= 10 + 4 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 4], "easy",
+ 4) == 0 && (packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] ==
+ '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 10 + 4 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 4], "fast",
+ 4) == 0 && (packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] ==
+ '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 10 + 4 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 4], "live",
+ 4) == 0 && (packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] ==
+ '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 9 + 4 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 4], "ftp2", 4) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 9 + 4 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 4], "gige", 4) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 9 + 4 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 4], "mega", 4) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 9 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 5], "rapid", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 9 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 9 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 6 + 7 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 6 - 7], "mediafi", 7) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 6 - 7 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 6 - 7 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 5 + 7 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 7], "gigasiz", 7) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 8 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 8], "sendspac", 8) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 7 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 7], "sharebe", 7) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 11 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 11], "sharebigfli", 11) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 11 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 11 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 8 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 8], "fileserv", 8) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 's') {
+ if (host_line_len_without_port >= 5 + 1 && packet->host_line.ptr[host_line_len_without_port - 5 - 1] == 'e') {
+ if (host_line_len_without_port >= 6 + 10 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 6 - 10], "depositfil",
+ 10) == 0 && (packet->host_line.ptr[host_line_len_without_port - 6 - 10 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 6 - 10 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 6 + 8 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 6 - 8], "megashar", 8) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 6 - 8 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 6 - 8 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 5 + 10 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 10], "fileupyour", 10) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 4 + 11 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 11], "filefactory", 11) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 4 - 11 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 4 - 11 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 't') {
+ if (host_line_len_without_port >= 5 + 8 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 8], "filefron", 8) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 10 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 10], "uploadingi", 10) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 11 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 11], "yourfilehos", 11) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 11 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 11 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'r') {
+ if (host_line_len_without_port >= 5 + 8 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 8], "mytempdi", 8) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 10 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 10], "uploadpowe", 10) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 4 + 9 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 9], "mega.1280", 9) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 4 + 9 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 9], "filesonic", 9) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 0 + 4
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 4], ".net", 4) == 0) {
+ if (host_line_len_without_port >= 4 + 7 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 7], "badongo", 7) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'd') {
+ if (host_line_len_without_port >= 5 + 3
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 3], "loa", 3) == 0) {
+ if (host_line_len_without_port >= 8 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 5], "fast-", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 8 + 2
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 2], "up", 2) == 0) {
+ if (host_line_len_without_port >= 10 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 5], "file-", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 10 + 6 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 6], "simple",
+ 6) == 0 && (packet->host_line.ptr[host_line_len_without_port - 10 - 6 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 10 - 6 - 1] ==
+ '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 10 + 3 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 3], "wii", 3) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 10 - 3 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 10 - 3 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 5 + 7 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 7], "filesen", 7) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 4 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 5], "filer", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 4 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 4 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 4 + 9 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 9], "livedepot", 9) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'e') {
+ if (host_line_len_without_port >= 5 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 5], "mofil", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 17 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 17], "odsiebie.najlepsz",
+ 17) == 0 && (packet->host_line.ptr[host_line_len_without_port - 5 - 17 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 17 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 5 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 5], "zshar", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 0 + 1 && packet->host_line.ptr[host_line_len_without_port - 0 - 1] == 'u') {
+ if (host_line_len_without_port >= 1 + 6 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 6], "data.h", 6) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 1 - 6 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 1 - 6 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 1 + 2
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 2], ".r", 2) == 0) {
+ if (host_line_len_without_port >= 3 + 10 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 10], "filearchiv", 10) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 3 - 10 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 3 - 10 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 3 + 8 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 8], "filepost", 8) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 3 - 8 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 3 - 8 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 3 + 7 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 7], "ifolder", 7) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 3 - 7 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 3 - 7 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 0 + 11 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 11], "filehost.tv", 11) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 0 - 11 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 0 - 11 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 0 + 3
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 3], ".to", 3) == 0) {
+ if (host_line_len_without_port >= 3 + 1 && packet->host_line.ptr[host_line_len_without_port - 3 - 1] == 'e') {
+ if (host_line_len_without_port >= 4 + 7 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 7], "filesaf", 7) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 4 + 8 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 8], "sharebas", 8) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 4 - 8 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 4 - 8 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 3 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 5], "files", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 3 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 3 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 3 + 1 && packet->host_line.ptr[host_line_len_without_port - 3 - 1] == 'd') {
+ if (host_line_len_without_port >= 4 + 3
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 3], "loa", 3) == 0) {
+ if (host_line_len_without_port >= 7 + 7 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 7 - 7], "file-up", 7) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 7 - 7 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 7 - 7 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 4 + 3 + 1
+ && (packet->host_line.ptr[host_line_len_without_port - 4 - 3 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 4 - 3 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ }
+ if (host_line_len_without_port >= 4 + 7 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 7], "uploade", 7) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 0 + 1 && packet->host_line.ptr[host_line_len_without_port - 0 - 1] == 'z') {
+ if (host_line_len_without_port >= 1 + 14 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 14], "leteckaposta.c", 14) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 1 - 14 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 1 - 14 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 1 + 12 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 12], "yourfiles.bi", 12) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 1 - 12 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 1 - 12 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 0 + 1 && packet->host_line.ptr[host_line_len_without_port - 0 - 1] == 'n') {
+ if (host_line_len_without_port >= 1 + 9 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 9], "netload.i", 9) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 1 - 9 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 1 - 9 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 1 + 2
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 2], ".v", 2) == 0) {
+ if (host_line_len_without_port >= 3 + 7 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 7], "4shared", 7) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 3 - 7 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 3 - 7 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 3 + 9 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 9], "megashare", 9) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 3 - 9 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 3 - 9 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 0 + 3
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 3], ".de", 3) == 0) {
+ if (host_line_len_without_port >= 3 + 5
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 5], "share", 5) == 0) {
+ if (host_line_len_without_port >= 8 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 5], "rapid", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ if (host_line_len_without_port >= 8 + 5 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 5], "ultra", 5) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 3 + 15 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 15], "uploadyourfiles", 15) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 3 - 15 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 3 - 15 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ goto end_ddl_nothing_found;
+ }
+ if (host_line_len_without_port >= 0 + 14 + 1
+ && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 14], "speedshare.org", 14) == 0
+ && (packet->host_line.ptr[host_line_len_without_port - 0 - 14 - 1] == ' '
+ || packet->host_line.ptr[host_line_len_without_port - 0 - 14 - 1] == '.')) {
+ goto end_ddl_found;
+ }
+ // END OF AUTOMATED CODE GENERATION
+
+ /* This is the hard way. We do this in order to find the download of services when other
+ domains are involved. This is not significant if ddl is blocked. --> then the link can not be started because
+ the ads are not viewed. But when ddl is only limited then the download is the important part.
+ */
+
+ end_ddl_nothing_found:
+ NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG,
+ "Nothing Found\n");
+ return 0;
+
+ end_ddl_found:
+ NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: DIRECT DOWNLOAD LINK FOUND\n");
+ ndpi_int_direct_download_link_add_connection(ndpi_struct, flow);
+ return 1;
+}
+
+
+void ndpi_search_direct_download_link_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+#if 0
+ if (ndpi_struct->direct_download_link_counter_callback != NULL) {
+ if (packet->detected_protocol == NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK) {
+ /* skip packets not requests from the client to the server */
+ if (packet->packet_direction == flow->l4.tcp.ddlink_server_direction) {
+ search_ddl_domains(ndpi_struct, flow); // do the detection again in order to get the URL in keep alive streams
+ } else {
+ // just count the packet
+ ndpi_struct->direct_download_link_counter_callback(flow->hash_id_number, packet->l3_packet_len);
+ }
+ }
+ return;
+ }
+#endif
+ // do not detect again if it is already ddl
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK) {
+ if (search_ddl_domains(ndpi_struct, flow) != 0) {
+ return;
+ }
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK);
+ }
+
+}
+#endif
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
new file mode 100644
index 000000000..071039340
--- /dev/null
+++ b/src/lib/protocols/dns.c
@@ -0,0 +1,300 @@
+/*
+ * dns.c
+ *
+ * Copyright (C) 2012-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_DNS
+
+static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) {
+ if(payload[i] == 0x00)
+ return(1);
+ else if(payload[i] == 0xC0)
+ return(2);
+ else {
+ u_int8_t len = payload[i];
+ u_int8_t off = len + 1;
+
+ if(off == 0) /* Bad packet */
+ return(0);
+ else
+ return(off + getNameLength(i+off, payload, payloadLen));
+ }
+}
+
+/* *********************************************** */
+
+static char* ndpi_intoa_v4(unsigned int addr, char* buf, u_short bufLen) {
+ char *cp, *retStr;
+ uint byte;
+ int n;
+
+ cp = &buf[bufLen];
+ *--cp = '\0';
+
+ n = 4;
+ do {
+ byte = addr & 0xff;
+ *--cp = byte % 10 + '0';
+ byte /= 10;
+ if(byte > 0) {
+ *--cp = byte % 10 + '0';
+ byte /= 10;
+ if(byte > 0)
+ *--cp = byte + '0';
+ }
+ *--cp = '.';
+ addr >>= 8;
+ } while (--n > 0);
+
+ /* Convert the string to lowercase */
+ retStr = (char*)(cp+1);
+
+ return(retStr);
+}
+
+/* *********************************************** */
+
+static u_int16_t get16(int *i, const u_int8_t *payload) {
+ u_int16_t v = *(u_int16_t*)&payload[*i];
+
+ (*i) += 2;
+
+ return(ntohs(v));
+}
+
+/* *********************************************** */
+
+struct dns_packet_header {
+ u_int16_t transaction_id, flags, num_queries, answer_rrs, authority_rrs, additional_rrs;
+} __attribute__((packed));
+
+void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t dport = 0, sport = 0;
+
+#define NDPI_MAX_DNS_REQUESTS 16
+
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "search DNS.\n");
+
+ if (packet->udp != NULL) {
+ sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest);
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over UDP.\n");
+ } else if(packet->tcp != NULL) {
+ sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over tcp.\n");
+ }
+
+ if(((dport == 53) || (sport == 53) || (dport == 5355))
+ && (packet->payload_packet_len > sizeof(struct dns_packet_header))) {
+ int i = packet->tcp ? 2 : 0;
+ struct dns_packet_header header, *dns = (struct dns_packet_header*)&packet->payload[i];
+ u_int8_t is_query, ret_code, is_dns = 0;
+ u_int32_t a_record[NDPI_MAX_DNS_REQUESTS] = { 0 }, query_offset, num_a_records = 0;
+
+ header.flags = ntohs(dns->flags);
+ header.transaction_id = ntohs(dns->transaction_id);
+ header.num_queries = ntohs(dns->num_queries);
+ header.answer_rrs = ntohs(dns->answer_rrs);
+ header.authority_rrs = ntohs(dns->authority_rrs);
+ header.additional_rrs = ntohs(dns->additional_rrs);
+ is_query = (header.flags & 0x8000) ? 0 : 1;
+ ret_code = is_query ? 0 : (header.flags & 0x0F);
+ i += sizeof(struct dns_packet_header);
+ query_offset = i;
+
+ if(is_query) {
+ /* DNS Request */
+ if((header.num_queries > 0) && (header.num_queries <= NDPI_MAX_DNS_REQUESTS)
+ && (((header.flags & 0x2800) == 0x2800 /* Dynamic DNS Update */)
+ || ((header.answer_rrs == 0) && (header.authority_rrs == 0)))) {
+ /* This is a good query */
+ is_dns = 1;
+
+ if(header.num_queries > 0) {
+ while(i < packet->payload_packet_len) {
+ if(packet->payload[i] == '\0') {
+ i++;
+ flow->protos.dns.query_type = get16(&i, packet->payload);
+ break;
+ } else
+ i++;
+ }
+ }
+ }
+ } else {
+ /* DNS Reply */
+
+ flow->server_id = flow->dst;
+
+ if((header.num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */
+ && (((header.answer_rrs > 0) && (header.answer_rrs <= NDPI_MAX_DNS_REQUESTS))
+ || ((header.authority_rrs > 0) && (header.authority_rrs <= NDPI_MAX_DNS_REQUESTS))
+ || ((header.additional_rrs > 0) && (header.additional_rrs <= NDPI_MAX_DNS_REQUESTS)))
+ ) {
+ /* This is a good reply */
+ is_dns = 1;
+
+ i++;
+
+ if(packet->payload[i] != '\0') {
+ while((i < packet->payload_packet_len)
+ && (packet->payload[i] != '\0')) {
+ i++;
+ }
+
+ i++;
+ }
+
+ i += 4;
+
+ if(header.answer_rrs > 0) {
+ u_int16_t rsp_type /*, rsp_class */;
+ u_int16_t num;
+
+ for(num = 0; num < header.answer_rrs; num++) {
+ u_int16_t data_len;
+
+ if((i+6) >= packet->payload_packet_len) {
+ break;
+ }
+
+ if((data_len = getNameLength(i, packet->payload, packet->payload_packet_len)) == 0) {
+ break;
+ } else
+ i += data_len;
+
+ rsp_type = get16(&i, packet->payload);
+ // rsp_class = get16(&i, packet->payload);
+
+ i += 4;
+ data_len = get16(&i, packet->payload);
+
+ if((data_len <= 1) || (data_len > (packet->payload_packet_len-i))) {
+ break;
+ }
+
+ flow->protos.dns.rsp_type = rsp_type;
+
+ if(rsp_type == 1 /* A */) {
+ if(data_len == 4) {
+ u_int32_t v = ntohl(*((u_int32_t*)&packet->payload[i]));
+
+ if(num_a_records < (NDPI_MAX_DNS_REQUESTS-1))
+ a_record[num_a_records++] = v;
+ else
+ break; /* One record is enough */
+ }
+ }
+
+ if(data_len == 0) {
+ break;
+ }
+
+ i += data_len;
+ } /* for */
+ }
+ }
+
+ if((header.num_queries <= NDPI_MAX_DNS_REQUESTS)
+ && ((header.answer_rrs == 0)
+ || (header.authority_rrs == 0)
+ || (header.additional_rrs == 0))
+ && (ret_code != 0 /* 0 == OK */)
+ ) {
+ /* This is a good reply */
+ is_dns = 1;
+ }
+ }
+
+ if(is_dns) {
+ int j = 0;
+
+ flow->protos.dns.num_queries = (u_int8_t)header.num_queries,
+ flow->protos.dns.num_answers = (u_int8_t)(header.answer_rrs+header.authority_rrs+header.additional_rrs),
+ flow->protos.dns.ret_code = ret_code;
+
+ i = query_offset+1;
+
+ while((i < packet->payload_packet_len)
+ && (j < (sizeof(flow->host_server_name)-1))
+ && (packet->payload[i] != '\0')) {
+ flow->host_server_name[j] = tolower(packet->payload[i]);
+ if(flow->host_server_name[j] < ' ')
+ flow->host_server_name[j] = '.';
+ j++, i++;
+ }
+
+ if(a_record != 0) {
+ char a_buf[32];
+ int i;
+
+ for(i=0; i<num_a_records; i++) {
+ j += snprintf((char*)&flow->host_server_name[j], sizeof(flow->host_server_name)-1-j, "%s%s",
+ (i == 0) ? "@" : ";",
+ ndpi_intoa_v4(a_record[i], a_buf, sizeof(a_buf)));
+ }
+ }
+
+ flow->host_server_name[j] = '\0';
+
+ if(j > 0) {
+#ifdef DEBUG
+ printf("==> %s\n", flow->host_server_name);
+#endif
+
+ if(ndpi_struct->match_dns_host_names)
+ ndpi_match_string_subprotocol(ndpi_struct, flow,
+ (char *)flow->host_server_name,
+ strlen((const char*)flow->host_server_name));
+ }
+
+ i++;
+
+ memcpy(&flow->protos.dns.query_type, &packet->payload[i], 2);
+ flow->protos.dns.query_type = ntohs(flow->protos.dns.query_type), i += 2;
+
+ memcpy(&flow->protos.dns.query_class, &packet->payload[i], 2);
+ flow->protos.dns.query_class = ntohs(flow->protos.dns.query_class), i += 2;
+
+#ifdef DEBUG
+ printf("%s [type=%04X][class=%04X]\n", flow->host_server_name, flow->protos.dns.query_type, flow->protos.dns.query_class);
+#endif
+
+ if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+ /*
+ Do not set the protocol with DNS if ndpi_match_string_subprotocol() has
+ matched a subprotocol
+ */
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, (dport == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_REAL_PROTOCOL);
+ }
+ } else {
+ flow->protos.dns.bad_packet = 1;
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
+ }
+ }
+}
+#endif
diff --git a/src/lib/protocols/dofus.c b/src/lib/protocols/dofus.c
new file mode 100644
index 000000000..43d9c9f73
--- /dev/null
+++ b/src/lib/protocols/dofus.c
@@ -0,0 +1,149 @@
+/*
+ * dofus.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_DOFUS
+
+static void ndpi_dofus_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DOFUS, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_dofus(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ /* Dofus v 1.x.x */
+ if (packet->payload_packet_len == 13 && get_u_int16_t(packet->payload, 1) == ntohs(0x0508)
+ && get_u_int16_t(packet->payload, 5) == ntohs(0x04a0)
+ && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == ntohs(0x0194)) {
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n");
+ ndpi_dofus_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len == 3 && memcmp(packet->payload, "HG", 2) == 0
+ && packet->payload[packet->payload_packet_len - 1] == 0) {
+ flow->l4.tcp.dofus_stage = 1;
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n");
+ return;
+ }
+ if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len == 35 && memcmp(packet->payload, "HC", 2) == 0
+ && packet->payload[packet->payload_packet_len - 1] == 0) {
+ flow->l4.tcp.dofus_stage = 1;
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n");
+ return;
+ }
+ if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len > 2 && packet->payload[0] == 'A'
+ && (packet->payload[1] == 'x' || packet->payload[1] == 'X')
+ && packet->payload[packet->payload_packet_len - 1] == 0) {
+ flow->l4.tcp.dofus_stage = 1;
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n");
+ return;
+ }
+ if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len == 12 && memcmp(packet->payload, "Af", 2) == 0
+ && packet->payload[packet->payload_packet_len - 1] == 0) {
+ flow->l4.tcp.dofus_stage = 1;
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n");
+ return;
+ }
+ if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len > 2 && memcmp(packet->payload, "Ad", 2)
+ && packet->payload[packet->payload_packet_len - 1] == 0) {
+ flow->l4.tcp.dofus_stage = 1;
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n");
+ return;
+ }
+ if (packet->payload_packet_len == 11 && memcmp(packet->payload, "AT", 2) == 0 && packet->payload[10] == 0x00) {
+ if (flow->l4.tcp.dofus_stage == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n");
+ ndpi_dofus_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ if (flow->l4.tcp.dofus_stage == 1 && packet->payload_packet_len == 5
+ && packet->payload[0] == 'A' && packet->payload[4] == 0x00 && (packet->payload[1] == 'T'
+ || packet->payload[1] == 'k')) {
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus asym.\n");
+ ndpi_dofus_add_connection(ndpi_struct, flow);
+ return;
+ }
+ /* end Dofus 1.x.x */
+
+
+ /* Dofus 2.0 */
+ if ((packet->payload_packet_len == 11 || packet->payload_packet_len == 13 || packet->payload_packet_len == 49)
+ && get_u_int32_t(packet->payload, 0) == ntohl(0x00050800)
+ && get_u_int16_t(packet->payload, 4) == ntohs(0x0005)
+ && get_u_int16_t(packet->payload, 8) == ntohs(0x0005)
+ && packet->payload[10] == 0x18) {
+ if (packet->payload_packet_len == 13
+ && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) != ntohs(0x0194)) {
+ goto exclude;
+ }
+ if (packet->payload_packet_len == 49 && ntohs(get_u_int16_t(packet->payload, 15)) + 17 != packet->payload_packet_len) {
+ goto exclude;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n");
+ ndpi_dofus_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len >= 41 && get_u_int16_t(packet->payload, 0) == ntohs(0x01b9) && packet->payload[2] == 0x26) {
+ u_int16_t len, len2;
+ len = ntohs(get_u_int16_t(packet->payload, 3));
+ if ((len + 5 + 2) > packet->payload_packet_len)
+ goto exclude;
+ len2 = ntohs(get_u_int16_t(packet->payload, 5 + len));
+ if (5 + len + 2 + len2 == packet->payload_packet_len) {
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n");
+ ndpi_dofus_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ if (packet->payload_packet_len == 56
+ && memcmp(packet->payload, "\x00\x11\x35\x02\x03\x00\x93\x96\x01\x00", 10) == 0) {
+ u_int16_t len, len2;
+ len = ntohs(get_u_int16_t(packet->payload, 10));
+ if ((len + 12 + 2) > packet->payload_packet_len)
+ goto exclude;
+ len2 = ntohs(get_u_int16_t(packet->payload, 12 + len));
+ if ((12 + len + 2 + len2 + 1) > packet->payload_packet_len)
+ goto exclude;
+ if (12 + len + 2 + len2 + 1 == packet->payload_packet_len && packet->payload[12 + len + 2 + len2] == 0x01) {
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n");
+ ndpi_dofus_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ exclude:
+ NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "exclude dofus.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DOFUS);
+}
+
+#endif
diff --git a/src/lib/protocols/dropbox.c b/src/lib/protocols/dropbox.c
new file mode 100644
index 000000000..e4ef2e0ce
--- /dev/null
+++ b/src/lib/protocols/dropbox.c
@@ -0,0 +1,77 @@
+/*
+ * dropbox.c
+ *
+ * Copyright (C) 2011-13 by ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_DROPBOX
+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)
+{
+ ndpi_int_add_connection(ndpi_struct, flow,
+ NDPI_PROTOCOL_DROPBOX,
+ due_to_correlation ? NDPI_CORRELATED_PROTOCOL : NDPI_REAL_PROTOCOL);
+}
+
+
+static void ndpi_check_dropbox(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // const u_int8_t *packet_payload = packet->payload;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ if(packet->udp != NULL) {
+ u_int16_t dropbox_port = htons(17500);
+
+ if((packet->udp->source == dropbox_port)
+ && (packet->udp->dest == dropbox_port)) {
+ if(payload_len > 2) {
+ if(strncmp((const char *)packet->payload, "{\"", 2) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_DROPBOX, ndpi_struct, NDPI_LOG_DEBUG, "Found dropbox.\n");
+ ndpi_int_dropbox_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+ }
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_DROPBOX, ndpi_struct, NDPI_LOG_DEBUG, "exclude dropbox.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DROPBOX);
+}
+
+void ndpi_search_dropbox(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_DROPBOX, ndpi_struct, NDPI_LOG_DEBUG, "dropbox detection...\n");
+
+ /* skip marked packets */
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_DROPBOX) {
+ if (packet->tcp_retransmission == 0) {
+ ndpi_check_dropbox(ndpi_struct, flow);
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/edonkey.c b/src/lib/protocols/edonkey.c
new file mode 100644
index 000000000..d452c7348
--- /dev/null
+++ b/src/lib/protocols/edonkey.c
@@ -0,0 +1,211 @@
+/*
+ * edonkey.c
+ *
+ * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
+ *
+ * The signature is based on the Libprotoident library.
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_EDONKEY
+static void ndpi_int_edonkey_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_EDONKEY, NDPI_REAL_PROTOCOL);
+}
+
+static int ndpi_edonkey_payload_check(const u_int8_t *data, u_int32_t len) {
+
+ if ((len >= 4) && (data[0] == 0xe3) && (data[2] == 0x00) && (data[3] == 0x00))
+ return 1;
+
+ if ((len >= 4) && (data[0] == 0xc5) && (data[2] == 0x00) && (data[3] == 0x00))
+ return 1;
+
+ if ((len >= 2) && (data[0] == 0xe5) && (data[1] == 0x43))
+ return 1;
+
+ if ((len >= 4) && (data[0] == 0xe5) && (data[1] == 0x08) && (data[2] == 0x78) && (data[3] == 0xda))
+ return 1;
+
+ if ((len >= 4) && (data[0] == 0xe5) && (data[1] == 0x28) && (data[2] == 0x78) && (data[3] == 0xda))
+ return 1;
+
+ if ((len >= 2) && (data[0] == 0xc5) && (data[1] == 0x90))
+ return 1;
+
+ if ((len >= 2) && (data[0] == 0xc5) && (data[1] == 0x91))
+ return 1;
+
+ if ((len == 2) && (data[0] == 0xc5) && (data[1] == 0x92))
+ return 1;
+
+ if ((len == 2) && (data[0] == 0xc5) && (data[1] == 0x93))
+ return 1;
+
+ if ((len >= 38 && len <= 70) && (data[0] == 0xc5) && (data[1] == 0x94))
+ return 1;
+
+ if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x9a))
+ return 1;
+
+ if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x9b))
+ return 1;
+
+ if ((len == 6) && (data[0] == 0xe3) && (data[1] == 0x96))
+ return 1;
+
+ if ((len <= 34 && ((len - 2) % 4 == 0)) && (data[0] == 0xe3) && (data[1] == 0x97))
+ return 1;
+
+ if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x92))
+ return 1;
+
+ if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x94))
+ return 1;
+
+ if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x98))
+ return 1;
+
+ if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x99))
+ return 1;
+
+ if ((len == 6) && (data[0] == 0xe3) && (data[1] == 0xa2))
+ return 1;
+
+ if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0xa3))
+ return 1;
+
+ if ((len == 27) && (data[0] == 0xe4) && (data[1] == 0x00))
+ return 1;
+
+ if ((len == 529) && (data[0] == 0xe4) && (data[1] == 0x08))
+ return 1;
+
+ if ((len == 18) && (data[0] == 0xe4) && (data[1] == 0x01) && (data[2] == 0x00) && (data[3] == 0x00))
+ return 1;
+
+ if ((len == 523) && (data[0] == 0xe4) && (data[1] == 0x09))
+ return 1;
+
+ if ((len == 35) && (data[0] == 0xe4) && (data[1] == 0x21))
+ return 1;
+
+ if ((len == 19) && (data[0] == 0xe4) && (data[1] == 0x4b))
+ return 1;
+
+ if ((len >= 2) && (data[0] == 0xe4) && (data[1] == 0x11))
+ return 1;
+
+ if ((len == 22 || len == 38 || len == 28) && (data[0] == 0xe4) && (data[1] == 0x19))
+ return 1;
+
+ if ((len == 35) && (data[0] == 0xe4) && (data[1] == 0x20))
+ return 1;
+
+ if ((len == 27) && (data[0] == 0xe4) && (data[1] == 0x18))
+ return 1;
+
+ if ((len == 27) && (data[0] == 0xe4) && (data[1] == 0x10))
+ return 1;
+
+ if ((len == 6) && (data[0] == 0xe4) && (data[1] == 0x58))
+ return 1;
+
+ if ((len == 4) && (data[0] == 0xe4) && (data[1] == 0x50))
+ return 1;
+
+ if ((len == 36) && (data[0] == 0xe4) && (data[1] == 0x52))
+ return 1;
+
+ if ((len == 48) && (data[0] == 0xe4) && (data[1] == 0x40))
+ return 1;
+
+ if ((len == 225) && (data[0] == 0xe4) && (data[1] == 0x43))
+ return 1;
+
+ if ((len == 19) && (data[0] == 0xe4) && (data[1] == 0x48))
+ return 1;
+
+ if ((len == 119 || len == 69 || len == 294) && (data[0] == 0xe4) && (data[1] == 0x29))
+ return 1;
+
+ if ((len == 119 || len == 69 || len == 294 || len == 44 || len == 269) && (data[0] == 0xe4) && (data[1] == 0x28))
+ return 1;
+
+ return 0;
+}
+
+static void ndpi_check_edonkey(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Break after 20 packets. */
+ if (flow->packet_counter > 20) {
+ NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "Exclude EDONKEY.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_EDONKEY);
+ return;
+ }
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->edonkey_stage == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "EDONKEY stage 0: \n");
+
+ if (ndpi_edonkey_payload_check(packet->payload, payload_len)) {
+ NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "Possible EDONKEY request detected, we will look further for the response...\n");
+
+ /* 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(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "EDONKEY stage %u: \n", flow->edonkey_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->edonkey_stage - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* 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))) {
+ NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "Found EDONKEY.\n");
+ ndpi_int_edonkey_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to EDONKEY, resetting the stage to 0...\n");
+ flow->edonkey_stage = 0;
+ }
+
+ }
+}
+
+void ndpi_search_edonkey(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "EDONKEY detection...\n");
+
+ /* skip marked packets */
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_EDONKEY) {
+ if (packet->tcp_retransmission == 0) {
+ ndpi_check_edonkey(ndpi_struct, flow);
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/fasttrack.c b/src/lib/protocols/fasttrack.c
new file mode 100644
index 000000000..0e0ff1988
--- /dev/null
+++ b/src/lib/protocols/fasttrack.c
@@ -0,0 +1,82 @@
+/*
+ * fasttrack.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_FASTTRACK
+
+
+
+static void ndpi_int_fasttrack_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FASTTRACK, NDPI_CORRELATED_PROTOCOL);
+}
+
+
+void ndpi_search_fasttrack_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len > 6 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) {
+ NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "detected 0d0a at the end of the packet.\n");
+
+ if (memcmp(packet->payload, "GIVE ", 5) == 0 && packet->payload_packet_len >= 8) {
+ u_int16_t i;
+ for (i = 5; i < (packet->payload_packet_len - 2); i++) {
+ // make shure that the argument to GIVE is numeric
+ if (!(packet->payload[i] >= '0' && packet->payload[i] <= '9')) {
+ goto exclude_fasttrack;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "FASTTRACK GIVE DETECTED\n");
+ ndpi_int_fasttrack_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ if (packet->payload_packet_len > 50 && memcmp(packet->payload, "GET /", 5) == 0) {
+ u_int8_t a = 0;
+ NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "detected GET /. \n");
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ for (a = 0; a < packet->parsed_lines; a++) {
+ if ((packet->line[a].len > 17 && memcmp(packet->line[a].ptr, "X-Kazaa-Username: ", 18) == 0)
+ || (packet->line[a].len > 23 && memcmp(packet->line[a].ptr, "User-Agent: PeerEnabler/", 24) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE,
+ "detected X-Kazaa-Username: || User-Agent: PeerEnabler/\n");
+ ndpi_int_fasttrack_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+ }
+
+ exclude_fasttrack:
+ NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "fasttrack/kazaa excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FASTTRACK);
+}
+#endif
diff --git a/src/lib/protocols/fiesta.c b/src/lib/protocols/fiesta.c
new file mode 100644
index 000000000..2b09ac9f7
--- /dev/null
+++ b/src/lib/protocols/fiesta.c
@@ -0,0 +1,97 @@
+/*
+ * fiesta.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+/* include files */
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_FIESTA
+
+
+static void ndpi_int_fiesta_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FIESTA, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_fiesta(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "search fiesta.\n");
+
+ if (flow->l4.tcp.fiesta_stage == 0 && packet->payload_packet_len == 5
+ && get_u_int16_t(packet->payload, 0) == ntohs(0x0407)
+ && (packet->payload[2] == 0x08)
+ && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "maybe fiesta symmetric, first packet.\n");
+ flow->l4.tcp.fiesta_stage = 1 + packet->packet_direction;
+ goto maybe_fiesta;
+ }
+ if (flow->l4.tcp.fiesta_stage == (2 - packet->packet_direction)
+ && ((packet->payload_packet_len > 1 && packet->payload_packet_len - 1 == packet->payload[0])
+ || (packet->payload_packet_len > 3 && packet->payload[0] == 0
+ && get_l16(packet->payload, 1) == packet->payload_packet_len - 3))) {
+ NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "Maybe fiesta.\n");
+ goto maybe_fiesta;
+ }
+ if (flow->l4.tcp.fiesta_stage == (1 + packet->packet_direction)) {
+ if (packet->payload_packet_len == 4 && get_u_int32_t(packet->payload, 0) == htonl(0x03050c01)) {
+ goto add_fiesta;
+ }
+ if (packet->payload_packet_len == 5 && get_u_int32_t(packet->payload, 0) == htonl(0x04030c01)
+ && packet->payload[4] == 0) {
+ goto add_fiesta;
+ }
+ if (packet->payload_packet_len == 6 && get_u_int32_t(packet->payload, 0) == htonl(0x050e080b)) {
+ goto add_fiesta;
+ }
+ if (packet->payload_packet_len == 100 && packet->payload[0] == 0x63 && packet->payload[61] == 0x52
+ && packet->payload[81] == 0x5a && get_u_int16_t(packet->payload, 1) == htons(0x3810)
+ && get_u_int16_t(packet->payload, 62) == htons(0x6f75)) {
+ goto add_fiesta;
+ }
+ if (packet->payload_packet_len > 3 && packet->payload_packet_len - 1 == packet->payload[0]
+ && get_u_int16_t(packet->payload, 1) == htons(0x140c)) {
+ goto add_fiesta;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "exclude fiesta.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FIESTA);
+ return;
+
+ maybe_fiesta:
+ NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "Stage is set to %d.\n", flow->l4.tcp.fiesta_stage);
+ return;
+
+ add_fiesta:
+ NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "detected fiesta.\n");
+ ndpi_int_fiesta_add_connection(ndpi_struct, flow);
+ return;
+}
+#endif
diff --git a/src/lib/protocols/filetopia.c b/src/lib/protocols/filetopia.c
new file mode 100644
index 000000000..d9ba1e820
--- /dev/null
+++ b/src/lib/protocols/filetopia.c
@@ -0,0 +1,83 @@
+/*
+ * filetopia.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_FILETOPIA
+
+
+static void ndpi_int_filetopia_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FILETOPIA, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_filetopia_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (flow->l4.tcp.filetopia_stage == 0) {
+ if (packet->payload_packet_len >= 50 && packet->payload_packet_len <= 70
+ && packet->payload[0] == 0x03 && packet->payload[1] == 0x9a
+ && packet->payload[3] == 0x22 && packet->payload[packet->payload_packet_len - 1] == 0x2b) {
+ NDPI_LOG(NDPI_PROTOCOL_FILETOPIA, ndpi_struct, NDPI_LOG_DEBUG, "Filetopia stage 1 detected\n");
+ flow->l4.tcp.filetopia_stage = 1;
+ return;
+ }
+
+ } else if (flow->l4.tcp.filetopia_stage == 1) {
+ if (packet->payload_packet_len >= 100 && packet->payload[0] == 0x03
+ && packet->payload[1] == 0x9a && (packet->payload[3] == 0x22 || packet->payload[3] == 0x23)) {
+
+ int i;
+ for (i = 0; i < 10; i++) { // check 10 bytes for valid ASCII printable characters
+ if (!(packet->payload[5 + i] >= 0x20 && packet->payload[5 + i] <= 0x7e)) {
+ goto end_filetopia_nothing_found;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_FILETOPIA, ndpi_struct, NDPI_LOG_DEBUG, "Filetopia stage 2 detected\n");
+ flow->l4.tcp.filetopia_stage = 2;
+ return;
+ }
+
+
+ } else if (flow->l4.tcp.filetopia_stage == 2) {
+ if (packet->payload_packet_len >= 4 && packet->payload_packet_len <= 100
+ && packet->payload[0] == 0x03 && packet->payload[1] == 0x9a
+ && (packet->payload[3] == 0x22 || packet->payload[3] == 0x23)) {
+ NDPI_LOG(NDPI_PROTOCOL_FILETOPIA, ndpi_struct, NDPI_LOG_DEBUG, "Filetopia detected\n");
+ ndpi_int_filetopia_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ }
+
+ end_filetopia_nothing_found:
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FILETOPIA);
+}
+
+#endif
diff --git a/src/lib/protocols/florensia.c b/src/lib/protocols/florensia.c
new file mode 100644
index 000000000..7f253cb6f
--- /dev/null
+++ b/src/lib/protocols/florensia.c
@@ -0,0 +1,122 @@
+/*
+ * florensia.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_FLORENSIA
+
+
+static void ndpi_florensia_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FLORENSIA, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_florensia(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "search florensia.\n");
+
+ if (packet->tcp != NULL) {
+ if (packet->payload_packet_len == 5 && get_l16(packet->payload, 0) == packet->payload_packet_len
+ && packet->payload[2] == 0x65 && packet->payload[4] == 0xff) {
+ if (flow->florensia_stage == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "found florensia.\n");
+ ndpi_florensia_add_connection(ndpi_struct, flow);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia -> stage is set to 1.\n");
+ flow->florensia_stage = 1;
+ return;
+ }
+ if (packet->payload_packet_len > 8 && get_l16(packet->payload, 0) == packet->payload_packet_len
+ && get_u_int16_t(packet->payload, 2) == htons(0x0201) && get_u_int32_t(packet->payload, 4) == htonl(0xFFFFFFFF)) {
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia -> stage is set to 1.\n");
+ flow->florensia_stage = 1;
+ return;
+ }
+ if (packet->payload_packet_len == 406 && get_l16(packet->payload, 0) == packet->payload_packet_len
+ && packet->payload[2] == 0x63) {
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia -> stage is set to 1.\n");
+ flow->florensia_stage = 1;
+ return;
+ }
+ if (packet->payload_packet_len == 12 && get_l16(packet->payload, 0) == packet->payload_packet_len
+ && get_u_int16_t(packet->payload, 2) == htons(0x0301)) {
+ if (flow->florensia_stage == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "found florensia.\n");
+ ndpi_florensia_add_connection(ndpi_struct, flow);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia -> stage is set to 1.\n");
+ flow->florensia_stage = 1;
+ return;
+ }
+
+ if (flow->florensia_stage == 1) {
+ if (packet->payload_packet_len == 8 && get_l16(packet->payload, 0) == packet->payload_packet_len
+ && get_u_int16_t(packet->payload, 2) == htons(0x0302) && get_u_int32_t(packet->payload, 4) == htonl(0xFFFFFFFF)) {
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "found florensia asymmetrically.\n");
+ ndpi_florensia_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len == 24 && get_l16(packet->payload, 0) == packet->payload_packet_len
+ && get_u_int16_t(packet->payload, 2) == htons(0x0202)
+ && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) == htonl(0xFFFFFFFF)) {
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "found florensia.\n");
+ ndpi_florensia_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (flow->packet_counter < 10 && get_l16(packet->payload, 0) == packet->payload_packet_len) {
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia.\n");
+ return;
+ }
+ }
+ }
+
+ if (packet->udp != NULL) {
+ if (flow->florensia_stage == 0 && packet->payload_packet_len == 6
+ && get_u_int16_t(packet->payload, 0) == ntohs(0x0503) && get_u_int32_t(packet->payload, 2) == htonl(0xFFFF0000)) {
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia -> stage is set to 1.\n");
+ flow->florensia_stage = 1;
+ return;
+ }
+ if (flow->florensia_stage == 1 && packet->payload_packet_len == 8
+ && get_u_int16_t(packet->payload, 0) == ntohs(0x0500) && get_u_int16_t(packet->payload, 4) == htons(0x4191)) {
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "found florensia.\n");
+ ndpi_florensia_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "exclude florensia.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FLORENSIA);
+}
+
+#endif
diff --git a/src/lib/protocols/ftp_control.c b/src/lib/protocols/ftp_control.c
new file mode 100644
index 000000000..a757902dc
--- /dev/null
+++ b/src/lib/protocols/ftp_control.c
@@ -0,0 +1,999 @@
+/*
+ * ftp_control.c
+ *
+ * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_FTP_CONTROL
+
+static void ndpi_int_ftp_control_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FTP_CONTROL, NDPI_REAL_PROTOCOL);
+}
+
+static int ndpi_ftp_control_check_request(const u_int8_t *payload) {
+
+ if (match_first_bytes(payload, "ABOR")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "ACCT")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "ADAT")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "ALLO")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "APPE")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "AUTH")) {
+ return 1;
+ }
+ if (match_first_bytes(payload, "CCC")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "CDUP")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "CONF")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "CWD")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "DELE")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "ENC")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "EPRT")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "EPSV")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "FEAT")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "HELP")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "LANG")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "LIST")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "LPRT")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "LPSV")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "MDTM")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "MIC")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "MKD")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "MLSD")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "MLST")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "MODE")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "NLST")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "NOOP")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "OPTS")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "PASS")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "PASV")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "PBSZ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "PORT")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "PROT")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "PWD")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "QUIT")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "REIN")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "REST")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "RETR")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "RMD")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "RNFR")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "RNTO")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "SITE")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "SIZE")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "SMNT")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "STAT")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "STOR")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "STOU")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "STRU")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "SYST")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "TYPE")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "USER")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "XCUP")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "XMKD")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "XPWD")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "XRCP")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "XRMD")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "XRSQ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "XSEM")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "XSEN")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "HOST")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "abor")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "acct")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "adat")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "allo")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "appe")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "auth")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "ccc")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "cdup")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "conf")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "cwd")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "dele")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "enc")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "eprt")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "epsv")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "feat")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "help")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "lang")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "list")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "lprt")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "lpsv")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "mdtm")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "mic")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "mkd")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "mlsd")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "mlst")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "mode")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "nlst")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "noop")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "opts")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "pass")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "pasv")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "pbsz")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "port")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "prot")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "pwd")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "quit")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "rein")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "rest")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "retr")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "rmd")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "rnfr")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "rnto")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "site")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "size")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "smnt")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "stat")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "stor")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "stou")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "stru")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "syst")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "type")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "user")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "xcup")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "xmkd")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "xpwd")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "xrcp")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "xrmd")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "xrsq")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "xsem")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "xsen")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "host")) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int ndpi_ftp_control_check_response(const u_int8_t *payload) {
+
+ if (match_first_bytes(payload, "110-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "120-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "125-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "150-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "202-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "211-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "212-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "213-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "214-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "215-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "220-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "221-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "225-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "226-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "227-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "228-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "229-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "230-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "231-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "232-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "250-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "257-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "331-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "332-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "350-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "421-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "425-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "426-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "430-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "434-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "450-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "451-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "452-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "501-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "502-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "503-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "504-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "530-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "532-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "550-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "551-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "552-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "553-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "631-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "632-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "633-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "10054-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "10060-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "10061-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "10066-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "10068-")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "110 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "120 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "125 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "150 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "202 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "211 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "212 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "213 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "214 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "215 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "220 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "221 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "225 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "226 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "227 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "228 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "229 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "230 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "231 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "232 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "250 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "257 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "331 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "332 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "350 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "421 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "425 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "426 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "430 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "434 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "450 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "451 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "452 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "501 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "502 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "503 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "504 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "530 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "532 ")) {
+ return 1;
+ }
+ if (match_first_bytes(payload, "550 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "551 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "552 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "553 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "631 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "632 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "633 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "10054 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "10060 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "10061 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "10066 ")) {
+ return 1;
+ }
+
+ if (match_first_bytes(payload, "10068 ")) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Exclude SMTP, which uses similar commands. */
+ if (packet->tcp->dest == htons(25) || packet->tcp->source == htons(25)) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Exclude FTP_CONTROL.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FTP_CONTROL);
+ return;
+ }
+
+ /* Break after 20 packets. */
+ if (flow->packet_counter > 20) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Exclude FTP_CONTROL.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FTP_CONTROL);
+ return;
+ }
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->ftp_control_stage == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "FTP_CONTROL stage 0: \n");
+
+ if ((payload_len > 0) && ndpi_ftp_control_check_request(packet->payload)) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Possible FTP_CONTROL request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->ftp_control_stage = packet->packet_direction + 1;
+ }
+
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "FTP_CONTROL stage %u: \n", flow->ftp_control_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->ftp_control_stage - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len > 0) && ndpi_ftp_control_check_response(packet->payload)) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Found FTP_CONTROL.\n");
+ ndpi_int_ftp_control_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to FTP_CONTROL, resetting the stage to 0...\n");
+ flow->ftp_control_stage = 0;
+ }
+
+ }
+}
+
+void ndpi_search_ftp_control(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "FTP_CONTROL detection...\n");
+
+ /* skip marked packets */
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_FTP_CONTROL) {
+ if (packet->tcp_retransmission == 0) {
+ ndpi_check_ftp_control(ndpi_struct, flow);
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/ftp_data.c b/src/lib/protocols/ftp_data.c
new file mode 100644
index 000000000..2bb77e1ec
--- /dev/null
+++ b/src/lib/protocols/ftp_data.c
@@ -0,0 +1,275 @@
+/*
+ * ftp_data.c
+ *
+ * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
+ * Copyright (C) 2014 - ntop.org
+ *
+ * The signature is based on the Libprotoident library.
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_FTP_DATA
+static void ndpi_int_ftp_data_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FTP_DATA, NDPI_REAL_PROTOCOL);
+}
+
+static int ndpi_match_ftp_data_port(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(packet->tcp->dest == htons(20) || packet->tcp->source == htons(20)) {
+ return 1;
+ }
+
+ return 0;
+
+}
+
+static int ndpi_match_ftp_data_directory(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ if((payload_len >= 4)
+ && ((packet->payload[0] == '-') || (packet->payload[0] == 'd'))
+ && ((packet->payload[1] == '-') || (packet->payload[1] == 'r'))
+ && ((packet->payload[2] == '-') || (packet->payload[2] == 'w'))
+ && ((packet->payload[3] == '-') || (packet->payload[3] == 'x'))) {
+
+ return 1;
+ }
+
+ return 0;
+
+}
+
+static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ /* A FTP packet is pretty long so 256 is a bit consrvative but it should be OK */
+ if(packet->payload_packet_len < 256)
+ return 0;
+
+ /* RIFF is a meta-format for storing AVI and WAV files */
+ if(match_first_bytes(packet->payload, "RIFF"))
+ return 1;
+
+ /* MZ is a .exe file */
+ if((packet->payload[0] == 'M') && (packet->payload[1] == 'Z') && (packet->payload[3] == 0x00))
+ return 1;
+
+ /* Ogg files */
+ if(match_first_bytes(packet->payload, "OggS"))
+ return 1;
+
+ /* ZIP files */
+ if((packet->payload[0] == 'P') && (packet->payload[1] == 'K') && (packet->payload[2] == 0x03) && (packet->payload[3] == 0x04))
+ return 1;
+
+ /* MPEG files */
+ if((packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x01) && (packet->payload[3] == 0xba))
+ return 1;
+
+ /* RAR files */
+ if(match_first_bytes(packet->payload, "Rar!"))
+ return 1;
+
+ /* EBML */
+ if((packet->payload[0] == 0x1a) && (packet->payload[1] == 0x45) && (packet->payload[2] == 0xdf) && (packet->payload[3] == 0xa3))
+ return 1;
+
+ /* JPG */
+ if((packet->payload[0] == 0xff) && (packet->payload[1] ==0xd8))
+ return 1;
+
+ /* GIF */
+ if(match_first_bytes(packet->payload, "GIF8"))
+ return 1;
+
+ /* PHP scripts */
+ if((packet->payload[0] == 0x3c) && (packet->payload[1] == 0x3f) && (packet->payload[2] == 0x70) && (packet->payload[3] == 0x68))
+ return 1;
+
+ /* Unix scripts */
+ if((packet->payload[0] == 0x23) && (packet->payload[1] == 0x21) && (packet->payload[2] == 0x2f) && (packet->payload[3] == 0x62))
+ return 1;
+
+ /* PDFs */
+ if(match_first_bytes(packet->payload, "%PDF"))
+ return 1;
+
+ /* PNG */
+ if((packet->payload[0] == 0x89) && (packet->payload[1] == 'P') && (packet->payload[2] == 'N') && (packet->payload[3] == 'G'))
+ return 1;
+
+ /* HTML */
+ if(match_first_bytes(packet->payload, "<htm"))
+ return 1;
+ if((packet->payload[0] == 0x0a) && (packet->payload[1] == '<') && (packet->payload[2] == '!') && (packet->payload[3] == 'D'))
+ return 1;
+
+ /* 7zip */
+ if((packet->payload[0] == 0x37) && (packet->payload[1] == 0x7a) && (packet->payload[2] == 0xbc) && (packet->payload[3] == 0xaf))
+ return 1;
+
+ /* gzip */
+ if((packet->payload[0] == 0x1f) && (packet->payload[1] == 0x8b) && (packet->payload[2] == 0x08))
+ return 1;
+
+ /* XML */
+ if(match_first_bytes(packet->payload, "<!DO"))
+ return 1;
+
+ /* FLAC */
+ if(match_first_bytes(packet->payload, "fLaC"))
+ return 1;
+
+ /* MP3 */
+ if((packet->payload[0] == 'I') && (packet->payload[1] == 'D') && (packet->payload[2] == '3') && (packet->payload[3] == 0x03))
+ return 1;
+ if(match_first_bytes(packet->payload, "\xff\xfb\x90\xc0"))
+ return 1;
+
+ /* RPM */
+ if((packet->payload[0] == 0xed) && (packet->payload[1] == 0xab) && (packet->payload[2] == 0xee) && (packet->payload[3] == 0xdb))
+ return 1;
+
+ /* Wz Patch */
+ if(match_first_bytes(packet->payload, "WzPa"))
+ return 1;
+
+ /* Flash Video */
+ if((packet->payload[0] == 'F') && (packet->payload[1] == 'L') && (packet->payload[2] == 'V') && (packet->payload[3] == 0x01))
+ return 1;
+
+ /* .BKF (Microsoft Tape Format) */
+ if(match_first_bytes(packet->payload, "TAPE"))
+ return 1;
+
+ /* MS Office Doc file - this is unpleasantly geeky */
+ if((packet->payload[0] == 0xd0) && (packet->payload[1] == 0xcf) && (packet->payload[2] == 0x11) && (packet->payload[3] == 0xe0))
+ return 1;
+
+ /* ASP */
+ if((packet->payload[0] == 0x3c) && (packet->payload[1] == 0x25) && (packet->payload[2] == 0x40) && (packet->payload[3] == 0x20))
+ return 1;
+
+ /* WMS file */
+ if((packet->payload[0] == 0x3c) && (packet->payload[1] == 0x21) && (packet->payload[2] == 0x2d) && (packet->payload[3] == 0x2d))
+ return 1;
+
+ /* ar archive, typically .deb files */
+ if(match_first_bytes(packet->payload, "!<ar"))
+ return 1;
+
+ /* Raw XML (skip jabber-like traffic as this is not FTP but unencrypted jabber) */
+ if((match_first_bytes(packet->payload, "<?xm"))
+ && (ndpi_strnstr((const char *)packet->payload, "jabber", packet->payload_packet_len) == NULL))
+ return 1;
+
+ if(match_first_bytes(packet->payload, "<iq "))
+ return 1;
+
+ /* SPF */
+ if(match_first_bytes(packet->payload, "SPFI"))
+ return 1;
+
+ /* ABIF - Applied Biosystems */
+ if(match_first_bytes(packet->payload, "ABIF"))
+ return 1;
+
+ /* bzip2 - other digits are also possible instead of 9 */
+ if((packet->payload[0] == 'B') && (packet->payload[1] == 'Z') && (packet->payload[2] == 'h') && (packet->payload[3] == '9'))
+ return 1;
+
+ /* Some other types of files */
+
+ if((packet->payload[0] == '<') && (packet->payload[1] == 'c') && (packet->payload[2] == 'f'))
+ return 1;
+ if((packet->payload[0] == '<') && (packet->payload[1] == 'C') && (packet->payload[2] == 'F'))
+ return 1;
+ if(match_first_bytes(packet->payload, ".tem"))
+ return 1;
+ if(match_first_bytes(packet->payload, ".ite"))
+ return 1;
+ if(match_first_bytes(packet->payload, ".lef"))
+ return 1;
+
+ return 0;
+}
+
+static void ndpi_check_ftp_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if(flow->ftp_data_stage == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "FTP_DATA stage 0: \n");
+
+ if((payload_len > 0) && (ndpi_match_file_header(ndpi_struct, flow) || ndpi_match_ftp_data_directory(ndpi_struct, flow) || ndpi_match_ftp_data_port(ndpi_struct, flow))) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "Possible FTP_DATA request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->ftp_data_stage = packet->packet_direction + 1;
+ }
+
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "FTP_DATA stage %u: \n", flow->ftp_data_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if((flow->ftp_data_stage - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if(payload_len == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "Found FTP_DATA.\n");
+ ndpi_int_ftp_data_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to FTP_DATA, resetting the stage to 0...\n");
+ flow->ftp_data_stage = 0;
+ }
+
+ }
+}
+
+void ndpi_search_ftp_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ /* Break after 20 packets. */
+ if(flow->packet_counter > 20) {
+ NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "Exclude FTP_DATA.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FTP_DATA);
+ return;
+ }
+
+ /* skip marked or retransmitted packets */
+ if(packet->tcp_retransmission != 0) {
+ return;
+ }
+
+ if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_FTP_DATA) {
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "FTP_DATA detection...\n");
+ ndpi_check_ftp_data(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/gnutella.c b/src/lib/protocols/gnutella.c
new file mode 100644
index 000000000..022df6e3d
--- /dev/null
+++ b/src/lib/protocols/gnutella.c
@@ -0,0 +1,375 @@
+/*
+ * gnutella.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+/* include files */
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_GNUTELLA
+
+static void ndpi_int_gnutella_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ ndpi_protocol_type_t protocol_type)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_GNUTELLA, protocol_type);
+
+ if (src != NULL) {
+ src->gnutella_ts = packet->tick_timestamp;
+ if (packet->udp != NULL) {
+ if (!src->detected_gnutella_udp_port1) {
+ src->detected_gnutella_udp_port1 = (packet->udp->source);
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct,
+ NDPI_LOG_DEBUG, "GNUTELLA UDP PORT1 DETECTED as %u\n",
+ src->detected_gnutella_udp_port1);
+
+ } else if ((ntohs(packet->udp->source) != src->detected_gnutella_udp_port1)
+ && !src->detected_gnutella_udp_port2) {
+ src->detected_gnutella_udp_port2 = (packet->udp->source);
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct,
+ NDPI_LOG_DEBUG, "GNUTELLA UDP PORT2 DETECTED as %u\n",
+ src->detected_gnutella_udp_port2);
+
+ }
+ }
+ }
+ if (dst != NULL) {
+ dst->gnutella_ts = packet->tick_timestamp;
+ }
+}
+
+void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ u_int16_t c;
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_GNUTELLA) {
+ if (src != NULL && ((u_int32_t)
+ (packet->tick_timestamp - src->gnutella_ts) < ndpi_struct->gnutella_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct,
+ NDPI_LOG_DEBUG, "gnutella : save src connection packet detected\n");
+ src->gnutella_ts = packet->tick_timestamp;
+ } else if (dst != NULL && ((u_int32_t)
+ (packet->tick_timestamp - dst->gnutella_ts) < ndpi_struct->gnutella_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct,
+ NDPI_LOG_DEBUG, "gnutella : save dst connection packet detected\n");
+ dst->gnutella_ts = packet->tick_timestamp;
+ }
+ if (src != NULL && (packet->tick_timestamp - src->gnutella_ts) > ndpi_struct->gnutella_timeout) {
+ src->detected_gnutella_udp_port1 = 0;
+ src->detected_gnutella_udp_port2 = 0;
+ }
+ if (dst != NULL && (packet->tick_timestamp - dst->gnutella_ts) > ndpi_struct->gnutella_timeout) {
+ dst->detected_gnutella_udp_port1 = 0;
+ dst->detected_gnutella_udp_port2 = 0;
+ }
+
+ return;
+ }
+
+ /* skip packets without payload */
+ if (packet->payload_packet_len < 2) {
+ return;
+ }
+ if (packet->tcp != NULL) {
+ /* this case works asymmetrically */
+ if (packet->payload_packet_len > 10 && memcmp(packet->payload, "GNUTELLA/", 9) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "GNUTELLA DETECTED\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ /* this case works asymmetrically */
+ if (packet->payload_packet_len > 17 && memcmp(packet->payload, "GNUTELLA CONNECT/", 17) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "GNUTELLA DETECTED\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0)
+ || (memcmp(packet->payload, "GET /uri-res/", 13) == 0)
+ )) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ for (c = 0; c < packet->parsed_lines; c++) {
+ if ((packet->line[c].len > 19 && memcmp(packet->line[c].ptr, "User-Agent: Gnutella", 20) == 0)
+ || (packet->line[c].len > 10 && memcmp(packet->line[c].ptr, "X-Gnutella-", 11) == 0)
+ || (packet->line[c].len > 7 && memcmp(packet->line[c].ptr, "X-Queue:", 8) == 0)
+ || (packet->line[c].len > 36 && memcmp(packet->line[c].ptr,
+ "Content-Type: application/x-gnutella-", 37) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "DETECTED GNUTELLA GET.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+ if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET / HTTP", 9) == 0))) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if ((packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > 15
+ && memcmp(packet->user_agent_line.ptr, "BearShare Lite ", 15) == 0)
+ || (packet->accept_line.ptr != NULL && packet->accept_line.len > 24
+ && memcmp(packet->accept_line.ptr, "application n/x-gnutella", 24) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "DETECTED GNUTELLA GET.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ }
+
+ }
+ /* haven't found this pattern in any trace. */
+ if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0)
+ || (memcmp(packet->payload, "GET /uri-res/", 13) == 0))) {
+ c = 8;
+ while (c < (packet->payload_packet_len - 9)) {
+ if (packet->payload[c] == '?')
+ break;
+ c++;
+ }
+
+ if (c < (packet->payload_packet_len - 9) && memcmp(&packet->payload[c], "urn:sha1:", 9) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE,
+ "detected GET /get/ or GET /uri-res/.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ }
+
+ }
+
+ /* answer to this packet is HTTP/1.1 ..... Content-Type: application/x-gnutella-packets,
+ * it is searched in the upper paragraph. */
+ if (packet->payload_packet_len > 30 && memcmp(packet->payload, "HEAD /gnutella/push-proxy?", 26) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected HEAD /gnutella/push-proxy?\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ /* haven't found any trace with this pattern */
+ if (packet->payload_packet_len == 46
+ && memcmp(packet->payload, "\x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a", 10) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE,
+ "detected \x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ /* haven't found any trace with this pattern */
+ if (packet->payload_packet_len > 250 && memcmp(packet->payload, "GET /gnutella/", 14) == 0)
+ //PATTERN IS :: GET /gnutella/tigertree/v3?urn:tree:tiger/:
+ {
+ const u_int16_t end = packet->payload_packet_len - 3;
+
+ c = 13;
+ while (c < end) {
+ if ((memcmp(&packet->payload[14], "tigertree/", 10) == 0)
+ || (end - c > 18 && memcmp(&packet->payload[c], "\r\nUser-Agent: Foxy", 18) == 0)
+ || (end - c > 44
+ && memcmp(&packet->payload[c],
+ "\r\nAccept: application/tigertree-breadthfirst",
+ 44) == 0) || (end - c > 10 && memcmp(&packet->payload[c], "\r\nX-Queue:", 10) == 0)
+ || (end - c > 13 && memcmp(&packet->payload[c], "\r\nX-Features:", 13) == 0)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA,
+ ndpi_struct, NDPI_LOG_TRACE, "FOXY :: GNUTELLA GET 2 DETECTED\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+
+ c++;
+ }
+ }
+ /* haven't found any trace with this pattern */
+ if (packet->payload_packet_len > 1 && packet->payload[packet->payload_packet_len - 1] == 0x0a
+ && packet->payload[packet->payload_packet_len - 2] == 0x0a) {
+ if (packet->payload_packet_len > 3 && memcmp(packet->payload, "GIV", 3) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "MORPHEUS GIV DETECTED\n");
+ /* Not Excludeing the flow now.. We shall Check the next Packet too for Gnutella Patterns */
+ return;
+ }
+ }
+ /* might be super tricky new ssl gnutella transmission, but the certificate is strange... */
+ if (packet->payload_packet_len == 46 && get_u_int32_t(packet->payload, 0) == htonl(0x802c0103) &&
+ get_u_int32_t(packet->payload, 4) == htonl(0x01000300) && get_u_int32_t(packet->payload, 8) == htonl(0x00002000) &&
+ get_u_int16_t(packet->payload, 12) == htons(0x0034)) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected gnutella len == 46.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 49 &&
+ memcmp(packet->payload, "\x80\x2f\x01\x03\x01\x00\x06\x00\x00\x00\x20\x00\x00\x34\x00\x00\xff\x4d\x6c",
+ 19) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected gnutella len == 49.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 89 && memcmp(&packet->payload[43], "\x20\x4d\x6c", 3) == 0 &&
+ memcmp(packet->payload, "\x16\x03\x01\x00\x54\x01\x00\x00\x50\x03\x01\x4d\x6c", 13) == 0 &&
+ memcmp(&packet->payload[76], "\x00\x02\x00\x34\x01\x00\x00\x05", 8) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE,
+ "detected gnutella asymmetrically len == 388.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ } else if (packet->payload_packet_len == 82) {
+ if (get_u_int32_t(packet->payload, 0) == htonl(0x16030100)
+ && get_u_int32_t(packet->payload, 4) == htonl(0x4d010000)
+ && get_u_int16_t(packet->payload, 8) == htons(0x4903)
+ && get_u_int16_t(packet->payload, 76) == htons(0x0002)
+ && get_u_int32_t(packet->payload, 78) == htonl(0x00340100)) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected len == 82.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ } else if (packet->udp != NULL) {
+ if (src != NULL && (packet->udp->source == src->detected_gnutella_udp_port1 ||
+ packet->udp->source == src->detected_gnutella_udp_port2) &&
+ (packet->tick_timestamp - src->gnutella_ts) < ndpi_struct->gnutella_timeout) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "port based detection\n\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ }
+ /* observations:
+ * all the following patterns send out many packets which are the only ones of their flows,
+ * often on the very beginning of the traces, or flows with many packets in one direction only.
+ * but then suddenly, one gets an answer as you can see in netpeker-gnutella-rpc.pcap packet 11483.
+ * Maybe gnutella tries to send out keys?
+ */
+ if (packet->payload_packet_len == 23 && packet->payload[15] == 0x00
+ && packet->payload[16] == 0x41 && packet->payload[17] == 0x01
+ && packet->payload[18] == 0x00 && packet->payload[19] == 0x00
+ && packet->payload[20] == 0x00 && packet->payload[21] == 0x00 && packet->payload[22] == 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
+ "detected gnutella udp, len = 23.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+
+ return;
+ }
+ if (packet->payload_packet_len == 35 && packet->payload[25] == 0x49
+ && packet->payload[26] == 0x50 && packet->payload[27] == 0x40
+ && packet->payload[28] == 0x83 && packet->payload[29] == 0x53
+ && packet->payload[30] == 0x43 && packet->payload[31] == 0x50 && packet->payload[32] == 0x41) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
+ "detected gnutella udp, len = 35.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 32
+ && (memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00\x4c\x49\x4d\x45", 11) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
+ "detected gnutella udp, len = 32.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 34 && (memcmp(&packet->payload[25], "SCP@", 4) == 0)
+ && (memcmp(&packet->payload[30], "DNA@", 4) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
+ "detected gnutella udp, len = 34.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if ((packet->payload_packet_len == 73 || packet->payload_packet_len == 96)
+ && memcmp(&packet->payload[32], "urn:sha1:", 9) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
+ "detected gnutella udp, len = 73,96.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ if (memcmp(packet->payload, "GND", 3) == 0) {
+ if ((packet->payload_packet_len == 8 && (memcmp(&packet->payload[6], "\x01\x00", 2) == 0))
+ || (packet->payload_packet_len == 11 && (memcmp(&packet->payload[6], "\x01\x01\x08\x50\x49", 5)
+ == 0)) || (packet->payload_packet_len == 17
+ &&
+ (memcmp
+ (&packet->payload[6], "\x01\x01\x4c\x05\x50",
+ 5) == 0))
+ || (packet->payload_packet_len == 28
+ && (memcmp(&packet->payload[6], "\x01\x01\x54\x0f\x51\x4b\x52\x50\x06\x52", 10) == 0))
+ || (packet->payload_packet_len == 41
+ && (memcmp(&packet->payload[6], "\x01\x01\x5c\x1b\x50\x55\x53\x48\x48\x10", 10) == 0))
+ || (packet->payload_packet_len > 200 && packet->payload_packet_len < 300 && packet->payload[3] == 0x03)
+ || (packet->payload_packet_len > 300 && (packet->payload[3] == 0x01 || packet->payload[3] == 0x03))) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
+ "detected gnutella udp, GND.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+ if ((packet->payload_packet_len == 32)
+ && memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00", 7) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
+ "detected gnutella udp, len = 32 ii.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if ((packet->payload_packet_len == 23)
+ && memcmp(&packet->payload[16], "\x00\x01\x00\x00\x00\x00\x00", 7) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
+ "detected gnutella udp, len = 23 ii.\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ //neonet detection follows
+
+ /* haven't found any trace with this pattern */
+ if (packet->tcp != NULL && ntohs(packet->tcp->source) >= 1024 && ntohs(packet->tcp->dest) >= 1024) {
+ if (flow->l4.tcp.gnutella_stage == 0) {
+ if (flow->packet_counter == 1
+ && (packet->payload_packet_len == 11
+ || packet->payload_packet_len == 33 || packet->payload_packet_len == 37)) {
+ flow->l4.tcp.gnutella_msg_id[0] = packet->payload[4];
+ flow->l4.tcp.gnutella_msg_id[1] = packet->payload[6];
+ flow->l4.tcp.gnutella_msg_id[2] = packet->payload[8];
+ flow->l4.tcp.gnutella_stage = 1 + packet->packet_direction;
+ return;
+ }
+ } else if (flow->l4.tcp.gnutella_stage == 1 + packet->packet_direction) {
+ if (flow->packet_counter == 2 && (packet->payload_packet_len == 33 || packet->payload_packet_len == 22)
+ && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0]
+ && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2]
+ && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4]
+ && NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_GNUTELLA)) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct,
+ NDPI_LOG_TRACE, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ } else if (flow->l4.tcp.gnutella_stage == 2 - packet->packet_direction) {
+ if (flow->packet_counter == 2 && (packet->payload_packet_len == 10 || packet->payload_packet_len == 75)
+ && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0]
+ && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2]
+ && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4]
+ && NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_GNUTELLA)) {
+ NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct,
+ NDPI_LOG_TRACE, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GNUTELLA);
+}
+#endif
diff --git a/src/lib/protocols/gtp.c b/src/lib/protocols/gtp.c
new file mode 100644
index 000000000..b9aee7a97
--- /dev/null
+++ b/src/lib/protocols/gtp.c
@@ -0,0 +1,85 @@
+/*
+ * gtp.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_GTP
+
+struct gtp_header_generic {
+ u_int8_t flags, message_type;
+ u_int16_t message_len;
+ u_int32_t teid;
+};
+
+static void ndpi_check_gtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // const u_int8_t *packet_payload = packet->payload;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+#if 0
+ printf("[len=%u][%02X %02X %02X %02X]\n", payload_len,
+ packet->payload[0] & 0xFF,
+ packet->payload[1] & 0xFF,
+ packet->payload[2] & 0xFF,
+ packet->payload[3] & 0xFF);
+#endif
+
+ if((packet->udp != NULL) && (payload_len > sizeof(struct gtp_header_generic))) {
+ u_int32_t gtp_u = ntohs(2152);
+ u_int32_t gtp_c = ntohs(2123);
+ u_int32_t gtp_v0 = ntohs(3386);
+
+ if((packet->udp->source == gtp_u) || (packet->udp->dest == gtp_u)
+ || (packet->udp->source == gtp_c) || (packet->udp->dest == gtp_c)
+ || (packet->udp->source == gtp_v0) || (packet->udp->dest == gtp_v0)
+ ) {
+ struct gtp_header_generic *gtp = (struct gtp_header_generic*)packet->payload;
+ u_int8_t gtp_version = (gtp->flags & 0xE0) >> 5;
+
+ if((gtp_version == 0) || (gtp_version == 1) || (gtp_version == 2)) {
+ u_int16_t message_len = ntohs(gtp->message_len);
+
+ if(message_len <= (payload_len-sizeof(struct gtp_header_generic))) {
+ NDPI_LOG(NDPI_PROTOCOL_GTP, ndpi_struct, NDPI_LOG_DEBUG, "Found gtp.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_GTP, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GTP);
+ return;
+}
+
+void ndpi_search_gtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_GTP, ndpi_struct, NDPI_LOG_DEBUG, "gtp detection...\n");
+
+ /* skip marked packets */
+ if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_GTP)
+ ndpi_check_gtp(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/guildwars.c b/src/lib/protocols/guildwars.c
new file mode 100644
index 000000000..b5dda0cdf
--- /dev/null
+++ b/src/lib/protocols/guildwars.c
@@ -0,0 +1,71 @@
+/*
+ * guildwars.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+/* include files */
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_GUILDWARS
+
+
+static void ndpi_int_guildwars_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_GUILDWARS, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_guildwars_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "search guildwars.\n");
+
+ if (packet->payload_packet_len == 64 && get_u_int16_t(packet->payload, 1) == ntohs(0x050c)
+ && memcmp(&packet->payload[50], "@2&P", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 29.350: found.\n");
+ ndpi_int_guildwars_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 1) == ntohs(0x040c)
+ && get_u_int16_t(packet->payload, 4) == ntohs(0xa672)
+ && packet->payload[8] == 0x01 && packet->payload[12] == 0x04) {
+ NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 29.350: found.\n");
+ ndpi_int_guildwars_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len == 21 && get_u_int16_t(packet->payload, 0) == ntohs(0x0100)
+ && get_u_int32_t(packet->payload, 5) == ntohl(0xf1001000)
+ && packet->payload[9] == 0x01) {
+ NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 216.107.245.50: found.\n");
+ ndpi_int_guildwars_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "exclude guildwars.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GUILDWARS);
+}
+
+#endif
diff --git a/src/lib/protocols/h323.c b/src/lib/protocols/h323.c
new file mode 100644
index 000000000..9d2fac8c8
--- /dev/null
+++ b/src/lib/protocols/h323.c
@@ -0,0 +1,97 @@
+/*
+ * h323.c
+ *
+ * Copyright (C) 2015 ntop.org
+ * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_H323
+
+struct tpkt {
+ u_int8_t version, reserved;
+ u_int16_t len;
+};
+
+void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t dport = 0, sport = 0;
+
+ NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "search H323.\n");
+
+ if(packet->tcp != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over tcp.\n");
+
+ /* H323 */
+ if((packet->payload[0] == 0x03)
+ && (packet->payload[1] == 0x00)
+ && (packet->payload[2] == 0x00)) {
+ struct tpkt *t = (struct tpkt*)packet->payload;
+ u_int16_t len = ntohs(t->len);
+
+ if(packet->payload_packet_len == len) {
+ /*
+ We need to check if this packet is in reality
+ a RDP (Remote Desktop) packet encapsulated on TPTK
+ */
+
+ if(packet->payload[4] == (packet->payload_packet_len - sizeof(struct tpkt) - 1)) {
+ /* ISO 8073/X.224 */
+ if((packet->payload[5] == 0xE0 /* CC Connect Request */)
+ || (packet->payload[5] == 0xD0 /* CC Connect Confirm */)) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RDP, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+ flow->l4.tcp.h323_valid_packets++;
+
+ if(flow->l4.tcp.h323_valid_packets >= 2) {
+ NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_REAL_PROTOCOL);
+ }
+ } else {
+ /* This is not H.323 */
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_H323);
+ }
+ }
+ } else if(packet->udp != NULL) {
+ sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest);
+ NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over udp.\n");
+
+ if(packet->payload[0] == 0x80 && packet->payload[1] == 0x08 && (packet->payload[2] == 0xe7 || packet->payload[2] == 0x26) &&
+ packet->payload[4] == 0x00 && packet->payload[5] == 0x00)
+ {
+ NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ /* H323 */
+ if(sport == 1719 || dport == 1719)
+ {
+ if(packet->payload[0] == 0x16 && packet->payload[1] == 0x80 && packet->payload[4] == 0x06 && packet->payload[5] == 0x00)
+ {
+ NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ else if(packet->payload_packet_len >= 20 || packet->payload_packet_len <= 117)
+ {
+ NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ else
+ {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_H323);
+ return;
+ }
+ }
+ }
+
+}
+#endif
diff --git a/src/lib/protocols/halflife2_and_mods.c b/src/lib/protocols/halflife2_and_mods.c
new file mode 100644
index 000000000..2644950c9
--- /dev/null
+++ b/src/lib/protocols/halflife2_and_mods.c
@@ -0,0 +1,65 @@
+/*
+ * halflife2_and_mods.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_HALFLIFE2
+
+
+static void ndpi_int_halflife2_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HALFLIFE2, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_halflife2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (flow->l4.udp.halflife2_stage == 0) {
+ if (packet->payload_packet_len >= 20
+ && get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF
+ && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) == htonl(0x30303000)) {
+ flow->l4.udp.halflife2_stage = 1 + packet->packet_direction;
+ NDPI_LOG(NDPI_PROTOCOL_HALFLIFE2, ndpi_struct, NDPI_LOG_DEBUG,
+ "halflife2 client req detected, waiting for server reply\n");
+ return;
+ }
+ } else if (flow->l4.udp.halflife2_stage == 2 - packet->packet_direction) {
+ if (packet->payload_packet_len >= 20
+ && get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF
+ && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) == htonl(0x30303000)) {
+ ndpi_int_halflife2_add_connection(ndpi_struct, flow);
+ NDPI_LOG(NDPI_PROTOCOL_HALFLIFE2, ndpi_struct, NDPI_LOG_DEBUG, "halflife2 server reply detected\n");
+ return;
+ }
+ }
+
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HALFLIFE2);
+}
+
+#endif
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
new file mode 100644
index 000000000..3c4cfe128
--- /dev/null
+++ b/src/lib/protocols/http.c
@@ -0,0 +1,981 @@
+/*
+ * http.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_HTTP
+
+static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int32_t protocol) {
+
+ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+ /* This is HTTP and it is not a sub protocol (e.g. skype or dropbox) */
+
+ ndpi_search_tcp_or_udp(ndpi_struct, flow);
+
+ /* If no custom protocol has been detected */
+ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+ if(protocol != NDPI_PROTOCOL_HTTP) {
+ ndpi_search_tcp_or_udp(ndpi_struct, flow);
+ ndpi_int_add_connection(ndpi_struct, flow, protocol, NDPI_CORRELATED_PROTOCOL);
+ } else {
+ ndpi_int_reset_protocol(flow);
+ ndpi_int_add_connection(ndpi_struct, flow, protocol, NDPI_REAL_PROTOCOL);
+ }
+ }
+
+ flow->http_detected = 1;
+ }
+
+}
+
+#ifdef NDPI_CONTENT_FLASH
+static void flash_check_http_payload(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ const u_int8_t *pos;
+
+ if(packet->empty_line_position_set == 0 || (packet->empty_line_position + 10) > (packet->payload_packet_len))
+ return;
+
+ pos = &packet->payload[packet->empty_line_position] + 2;
+
+
+ if(memcmp(pos, "FLV", 3) == 0 && pos[3] == 0x01 && (pos[4] == 0x01 || pos[4] == 0x04 || pos[4] == 0x05)
+ && pos[5] == 0x00 && pos[6] == 0x00 && pos[7] == 0x00 && pos[8] == 0x09) {
+
+ NDPI_LOG(NDPI_CONTENT_FLASH, ndpi_struct, NDPI_LOG_DEBUG, "Flash content in http detected\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_FLASH);
+ }
+}
+#endif
+
+#ifdef NDPI_CONTENT_AVI
+static void avi_check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+ NDPI_LOG(NDPI_CONTENT_AVI, ndpi_struct, NDPI_LOG_DEBUG, "called avi_check_http_payload: %u %u %u\n",
+ packet->empty_line_position_set, flow->l4.tcp.http_empty_line_seen, packet->empty_line_position);
+
+ if(packet->empty_line_position_set == 0 && flow->l4.tcp.http_empty_line_seen == 0)
+ return;
+
+ if(packet->empty_line_position_set != 0 && ((packet->empty_line_position + 20) > (packet->payload_packet_len))
+ && flow->l4.tcp.http_empty_line_seen == 0) {
+ flow->l4.tcp.http_empty_line_seen = 1;
+ return;
+ }
+
+ if(flow->l4.tcp.http_empty_line_seen == 1) {
+ if(packet->payload_packet_len > 20 && memcmp(packet->payload, "RIFF", 4) == 0
+ && memcmp(packet->payload + 8, "AVI LIST", 8) == 0) {
+ NDPI_LOG(NDPI_CONTENT_AVI, ndpi_struct, NDPI_LOG_DEBUG, "Avi content in http detected\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_AVI);
+ }
+ flow->l4.tcp.http_empty_line_seen = 0;
+ return;
+ }
+
+ if(packet->empty_line_position_set != 0) {
+ // check for avi header
+ // for reference see http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/avirifffilereference.asp
+ u_int32_t p = packet->empty_line_position + 2;
+
+ NDPI_LOG(NDPI_CONTENT_AVI, ndpi_struct, NDPI_LOG_DEBUG, "p = %u\n", p);
+
+ if((p + 16) <= packet->payload_packet_len && memcmp(&packet->payload[p], "RIFF", 4) == 0
+ && memcmp(&packet->payload[p + 8], "AVI LIST", 8) == 0) {
+ NDPI_LOG(NDPI_CONTENT_AVI, ndpi_struct, NDPI_LOG_DEBUG, "Avi content in http detected\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_AVI);
+ }
+ }
+}
+#endif
+
+#ifdef NDPI_PROTOCOL_TEAMVIEWER
+static void teamviewer_check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ const u_int8_t *pos;
+
+ NDPI_LOG(NDPI_PROTOCOL_TEAMVIEWER, ndpi_struct, NDPI_LOG_DEBUG, "called teamviewer_check_http_payload: %u %u %u\n",
+ packet->empty_line_position_set, flow->l4.tcp.http_empty_line_seen, packet->empty_line_position);
+
+ if(packet->empty_line_position_set == 0 || (packet->empty_line_position + 5) > (packet->payload_packet_len))
+ return;
+
+ pos = &packet->payload[packet->empty_line_position] + 2;
+
+ if(pos[0] == 0x17 && pos[1] == 0x24) {
+ NDPI_LOG(NDPI_PROTOCOL_TEAMVIEWER, ndpi_struct, NDPI_LOG_DEBUG, "TeamViewer content in http detected\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TEAMVIEWER);
+ }
+}
+#endif
+
+
+#ifdef NDPI_PROTOCOL_RTSP
+static void rtsp_parse_packet_acceptline(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(packet->accept_line.len >= 28 && memcmp(packet->accept_line.ptr, "application/x-rtsp-tunnelled", 28) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "RTSP accept line detected\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTSP);
+ }
+}
+#endif
+
+static void setHttpUserAgent(struct ndpi_flow_struct *flow, char *ua) {
+ if(!strcmp(ua, "Windows NT 5.0")) ua = "Windows 2000";
+ else if(!strcmp(ua, "Windows NT 5.1")) ua = "Windows XP";
+ else if(!strcmp(ua, "Windows NT 5.2")) ua = "Windows Server 2003";
+ else if(!strcmp(ua, "Windows NT 6.0")) ua = "Windows Vista";
+ // else if(!strcmp(ua, "Windows NT 7.0")) ua = "Windows 7";
+ else if(!strcmp(ua, "Windows NT 6.1")) ua = "Windows 7";
+ else if(!strcmp(ua, "Windows NT 6.2")) ua = "Windows 8";
+ else if(!strcmp(ua, "Windows NT 6.3")) ua = "Windows 8.1";
+
+ //printf("==> %s\n", ua);
+ snprintf((char*)flow->detected_os, sizeof(flow->detected_os), "%s", ua);
+}
+
+static void parseHttpSubprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ // int i = 0;
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(packet->iph /* IPv4 only */) {
+ /*
+ Twitter Inc. TWITTER-NETWORK (NET-199-59-148-0-1) 199.59.148.0 - 199.59.151.255
+ 199.59.148.0/22
+ */
+ if(((ntohl(packet->iph->saddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC73B9400 /* 199.59.148.0 */)
+ || ((ntohl(packet->iph->daddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC73B9400 /* 199.59.148.0 */)) {
+ packet->detected_protocol_stack[0] = NDPI_SERVICE_TWITTER;
+ return;
+ }
+
+ /*
+ CIDR: 69.53.224.0/19
+ OriginAS: AS2906
+ NetName: NETFLIX-INC
+ */
+ if(((ntohl(packet->iph->saddr) & 0xFFFFE000 /* 255.255.224.0 */) == 0x4535E000 /* 69.53.224.0 */)
+ || ((ntohl(packet->iph->daddr) & 0xFFFFE000 /* 255.255.224.0 */) == 0x4535E000 /* 69.53.224.0 */)) {
+ packet->detected_protocol_stack[0] = NDPI_SERVICE_NETFLIX;
+ return;
+ }
+ }
+
+ if((flow->l4.tcp.http_stage == 0)
+ || (flow->http.url && flow->http_detected)) {
+ /* Try matching subprotocols */
+ // ndpi_match_string_subprotocol(ndpi_struct, flow, (char*)packet->host_line.ptr, packet->host_line.len);
+
+ if(ndpi_struct->http_dissect_response) {
+ if(flow->http.url && flow->http_detected)
+ ndpi_match_string_subprotocol(ndpi_struct, flow, (char *)&flow->http.url[7], strlen((const char *)&flow->http.url[7]));
+ } else
+ ndpi_match_string_subprotocol(ndpi_struct, flow, (char *)flow->host_server_name, strlen((const char *)flow->host_server_name));
+ }
+}
+
+/*
+ NOTE
+
+ ndpi_parse_packet_line_info @ ndpi_main.c
+ is the code that parses the packet
+*/
+static void check_content_type_and_change_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
+#ifdef NDPI_CONTENT_MPEG
+ struct ndpi_packet_struct *packet = &flow->packet;
+#endif
+#ifdef NDPI_CONTENT_AVI
+#endif
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ u_int8_t a;
+
+ if(ndpi_struct->http_dissect_response) {
+ if((flow->http.url == NULL)
+ && (packet->http_url_name.len > 0)
+ && (packet->host_line.len > 0)) {
+ int len = packet->http_url_name.len + packet->host_line.len + 7 + 1; /* "http://" */
+
+ flow->http.url = ndpi_malloc(len);
+ if(flow->http.url) {
+ strncpy(flow->http.url, "http://", 7);
+ strncpy(&flow->http.url[7], (char*)packet->host_line.ptr, packet->host_line.len);
+ strncpy(&flow->http.url[7+packet->host_line.len], (char*)packet->http_url_name.ptr,
+ packet->http_url_name.len);
+ flow->http.url[len-1] = '\0';
+ }
+
+ if(flow->packet.http_method.len < 3)
+ flow->http.method = HTTP_METHOD_UNKNOWN;
+ else {
+ switch(flow->packet.http_method.ptr[0]) {
+ case 'O': flow->http.method = HTTP_METHOD_OPTIONS; break;
+ case 'G': flow->http.method = HTTP_METHOD_GET; break;
+ case 'H': flow->http.method = HTTP_METHOD_HEAD; break;
+
+ case 'P':
+ switch(flow->packet.http_method.ptr[1]) {
+ case 'O': flow->http.method = HTTP_METHOD_POST; break;
+ case 'U': flow->http.method = HTTP_METHOD_PUT; break;
+ }
+ break;
+
+ case 'D': flow->http.method = HTTP_METHOD_DELETE; break;
+ case 'T': flow->http.method = HTTP_METHOD_TRACE; break;
+ case 'C': flow->http.method = HTTP_METHOD_CONNECT; break;
+ default:
+ flow->http.method = HTTP_METHOD_UNKNOWN;
+ break;
+ }
+ }
+ }
+
+ if((flow->http.content_type == NULL) && (packet->content_line.len > 0)) {
+ int len = packet->content_line.len + 1;
+
+ flow->http.content_type = ndpi_malloc(len);
+ if(flow->http.content_type) {
+ strncpy(flow->http.content_type, (char*)packet->content_line.ptr,
+ packet->content_line.len);
+ flow->http.content_type[packet->content_line.len] = '\0';
+ }
+ }
+ }
+
+ if(packet->user_agent_line.ptr != NULL && packet->user_agent_line.len != 0) {
+ /* Format:
+ Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) ....
+ */
+ if(packet->user_agent_line.len > 7) {
+ char ua[256];
+ u_int mlen = ndpi_min(packet->user_agent_line.len, sizeof(ua)-1);
+
+ strncpy(ua, (const char *)packet->user_agent_line.ptr, mlen);
+ ua[mlen] = '\0';
+
+ if(strncmp(ua, "Mozilla", 7) == 0) {
+ char *parent = strchr(ua, '(');
+
+ if(parent) {
+ char *token, *end;
+
+ parent++;
+ end = strchr(parent, ')');
+ if(end) end[0] = '\0';
+
+ token = strsep(&parent, ";");
+ if(token) {
+ if((strcmp(token, "X11") == 0)
+ || (strcmp(token, "compatible") == 0)
+ || (strcmp(token, "Linux") == 0)
+ || (strcmp(token, "Macintosh") == 0)
+ ) {
+ token = strsep(&parent, ";");
+ if(token && (token[0] == ' ')) token++; /* Skip space */
+
+ if(token
+ && ((strcmp(token, "U") == 0)
+ || (strncmp(token, "MSIE", 4) == 0))) {
+ token = strsep(&parent, ";");
+ if(token && (token[0] == ' ')) token++; /* Skip space */
+
+ if(token && (strncmp(token, "Update", 6) == 0)) {
+ token = strsep(&parent, ";");
+
+ if(token && (token[0] == ' ')) token++; /* Skip space */
+
+ if(token && (strncmp(token, "AOL", 3) == 0)) {
+ token = strsep(&parent, ";");
+
+ if(token && (token[0] == ' ')) token++; /* Skip space */
+ }
+ }
+ }
+ }
+
+ if(token)
+ setHttpUserAgent(flow, token);
+ }
+ }
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "User Agent Type Line found %.*s\n",
+ packet->user_agent_line.len, packet->user_agent_line.ptr);
+
+ if((!ndpi_struct->http_dissect_response) || flow->http_detected)
+ ndpi_match_content_subprotocol(ndpi_struct, flow,
+ (char*)packet->user_agent_line.ptr,
+ packet->user_agent_line.len);
+ }
+
+ /* check for host line */
+ if(packet->host_line.ptr != NULL) {
+ u_int len;
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HOST Line found %.*s\n",
+ packet->host_line.len, packet->host_line.ptr);
+
+ if((!ndpi_struct->http_dissect_response) || flow->http_detected)
+ ndpi_match_content_subprotocol(ndpi_struct, flow,
+ (char*)packet->host_line.ptr,
+ packet->host_line.len);
+
+ /* Copy result for nDPI apps */
+ len = ndpi_min(packet->host_line.len, sizeof(flow->host_server_name)-1);
+ strncpy((char*)flow->host_server_name, (char*)packet->host_line.ptr, len);
+ flow->host_server_name[len] = '\0', flow->server_id = flow->dst;
+
+ len = ndpi_min(packet->forwarded_line.len, sizeof(flow->nat_ip)-1);
+ strncpy((char*)flow->nat_ip, (char*)packet->forwarded_line.ptr, len);
+ flow->nat_ip[len] = '\0';
+
+ if(!ndpi_struct->http_dissect_response)
+ parseHttpSubprotocol(ndpi_struct, flow);
+
+ if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
+ && ((!ndpi_struct->http_dissect_response) || flow->http_detected))
+ ndpi_match_string_subprotocol(ndpi_struct, flow,
+ (char *)flow->host_server_name,
+ strlen((const char *)flow->host_server_name));
+
+ if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
+ && ((!ndpi_struct->http_dissect_response) || flow->http_detected)
+ && (packet->http_origin.len > 0))
+ ndpi_match_string_subprotocol(ndpi_struct, flow,
+ (char *)packet->http_origin.ptr,
+ packet->http_origin.len);
+
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) {
+ if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_HTTP) {
+ ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0]);
+ return; /* We have identified a sub-protocol so we're done */
+ }
+ }
+ }
+
+ if(ndpi_struct->http_dissect_response && flow->http_detected)
+ parseHttpSubprotocol(ndpi_struct, flow);
+
+ /* check for accept line */
+ if(packet->accept_line.ptr != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Accept Line found %.*s\n",
+ packet->accept_line.len, packet->accept_line.ptr);
+#ifdef NDPI_PROTOCOL_RTSP
+ if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_RTSP) != 0) {
+ rtsp_parse_packet_acceptline(ndpi_struct, flow);
+ }
+#endif
+ }
+
+ /* search for line startin with "Icy-MetaData" */
+#ifdef NDPI_CONTENT_MPEG
+ for (a = 0; a < packet->parsed_lines; a++) {
+ if(packet->line[a].len > 11 && memcmp(packet->line[a].ptr, "Icy-MetaData", 12) == 0) {
+ NDPI_LOG(NDPI_CONTENT_MPEG, ndpi_struct, NDPI_LOG_DEBUG, "MPEG: Icy-MetaData found.\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_MPEG);
+ return;
+ }
+ }
+#ifdef NDPI_CONTENT_AVI
+#endif
+#endif
+
+ if(packet->content_line.ptr != NULL && packet->content_line.len != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Content Type Line found %.*s\n",
+ packet->content_line.len, packet->content_line.ptr);
+
+ if((!ndpi_struct->http_dissect_response) || flow->http_detected)
+ ndpi_match_content_subprotocol(ndpi_struct, flow, (char*)packet->content_line.ptr, packet->content_line.len);
+ }
+
+ /* check user agent here too */
+}
+
+static void check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "called check_http_payload.\n");
+
+#ifdef NDPI_CONTENT_FLASH
+ if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_CONTENT_FLASH) != 0)
+ flash_check_http_payload(ndpi_struct, flow);
+#endif
+#ifdef NDPI_CONTENT_AVI
+ if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_CONTENT_AVI) != 0)
+ avi_check_http_payload(ndpi_struct, flow);
+#endif
+#ifdef NDPI_PROTOCOL_TEAMVIEWER
+ teamviewer_check_http_payload(ndpi_struct, flow);
+#endif
+
+}
+
+/**
+ * this functions checks whether the packet begins with a valid http request
+ * @param ndpi_struct
+ * @returnvalue 0 if no valid request has been found
+ * @returnvalue >0 indicates start of filename but not necessarily in packet limit
+ */
+static u_int16_t http_request_url_offset(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "====>>>> HTTP: %c%c%c%c [len: %u]\n",
+ packet->payload[0], packet->payload[1], packet->payload[2], packet->payload[3],
+ packet->payload_packet_len);
+
+ /* FIRST PAYLOAD PACKET FROM CLIENT */
+ /* check if the packet starts with POST or GET */
+ if(packet->payload_packet_len >= 4 && memcmp(packet->payload, "GET ", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: GET FOUND\n");
+ return 4;
+ } else if(packet->payload_packet_len >= 5 && memcmp(packet->payload, "POST ", 5) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: POST FOUND\n");
+ return 5;
+ } else if(packet->payload_packet_len >= 8 && memcmp(packet->payload, "OPTIONS ", 8) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: OPTIONS FOUND\n");
+ return 8;
+ } else if(packet->payload_packet_len >= 5 && memcmp(packet->payload, "HEAD ", 5) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: HEAD FOUND\n");
+ return 5;
+ } else if(packet->payload_packet_len >= 4 && memcmp(packet->payload, "PUT ", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: PUT FOUND\n");
+ return 4;
+ } else if(packet->payload_packet_len >= 7 && memcmp(packet->payload, "DELETE ", 7) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: DELETE FOUND\n");
+ return 7;
+ } else if(packet->payload_packet_len >= 8 && memcmp(packet->payload, "CONNECT ", 8) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: CONNECT FOUND\n");
+ return 8;
+ } else if(packet->payload_packet_len >= 9 && memcmp(packet->payload, "PROPFIND ", 9) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: PROFIND FOUND\n");
+ return 9;
+ } else if(packet->payload_packet_len >= 7 && memcmp(packet->payload, "REPORT ", 7) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: REPORT FOUND\n");
+ return 7;
+ }
+
+ return 0;
+}
+
+static void http_bitmask_exclude(struct ndpi_flow_struct *flow)
+{
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP);
+#ifdef NDPI_PROTOCOL_WINDOWS_UPDATE
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WINDOWS_UPDATE);
+#endif
+#ifdef NDPI_CONTENT_MPEG
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_MPEG);
+#endif
+#ifdef NDPI_CONTENT_QUICKTIME
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_QUICKTIME);
+#endif
+#ifdef NDPI_CONTENT_WINDOWSMEDIA
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_WINDOWSMEDIA);
+#endif
+#ifdef NDPI_CONTENT_REALMEDIA
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_REALMEDIA);
+#endif
+#ifdef NDPI_CONTENT_AVI
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_AVI);
+#endif
+#ifdef NDPI_CONTENT_OGG
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_OGG);
+#endif
+#ifdef NDPI_PROTOCOL_MOVE
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MOVE);
+#endif
+#ifdef NDPI_PROTOCOL_XBOX
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_XBOX);
+#endif
+}
+
+void _org_ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ u_int16_t filename_start;
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "search http\n");
+
+ /* set client-server_direction */
+ if(flow->l4.tcp.http_setup_dir == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "initializes http to stage: 1 \n");
+ flow->l4.tcp.http_setup_dir = 1 + packet->packet_direction;
+ }
+
+ if(NDPI_COMPARE_PROTOCOL_TO_BITMASK
+ (ndpi_struct->generic_http_packet_bitmask, packet->detected_protocol_stack[0]) != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "protocol might be detected earlier as http jump to payload type detection\n");
+ goto http_parse_detection;
+ }
+
+ if(flow->l4.tcp.http_setup_dir == 1 + packet->packet_direction) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "http stage: 1\n");
+
+ if(flow->l4.tcp.http_wait_for_retransmission) {
+ if(!packet->tcp_retransmission) {
+ if(flow->packet_counter <= 5) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "still waiting for retransmission\n");
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "retransmission not found, exclude\n");
+ http_bitmask_exclude(flow);
+ return;
+ }
+ }
+ }
+
+ if(flow->l4.tcp.http_stage == 0) {
+ filename_start = http_request_url_offset(ndpi_struct, flow);
+ if(filename_start == 0) {
+ if(packet->payload_packet_len >= 7 && memcmp(packet->payload, "HTTP/1.", 7) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP response found (truncated flow ?)\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "filename not found, exclude\n");
+ http_bitmask_exclude(flow);
+ return;
+ }
+ // parse packet
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if(packet->parsed_lines <= 1) {
+ /* parse one more packet .. */
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "just one line, search next packet\n");
+
+ packet->http_method.ptr = packet->line[0].ptr;
+ packet->http_method.len = filename_start - 1;
+ flow->l4.tcp.http_stage = 1;
+ return;
+ }
+ // parsed_lines > 1 here
+ if(packet->line[0].len >= (9 + filename_start)
+ && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) {
+ u_int16_t proto_id;
+
+ packet->http_url_name.ptr = &packet->payload[filename_start];
+ packet->http_url_name.len = packet->line[0].len - (filename_start + 9);
+
+ packet->http_method.ptr = packet->line[0].ptr;
+ packet->http_method.len = filename_start - 1;
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "http structure detected, adding\n");
+
+ if(filename_start == 8 && (memcmp(packet->payload, "CONNECT ", 8) == 0)) /* nathan@getoffmalawn.com */
+ proto_id = NDPI_PROTOCOL_HTTP_CONNECT;
+ else {
+ if((packet->http_url_name.len > 7) && (!strncmp((const char*)packet->http_url_name.ptr, "http://", 7)))
+ proto_id = NDPI_PROTOCOL_HTTP_PROXY;
+ else {
+ proto_id = NDPI_PROTOCOL_HTTP;
+ }
+ }
+
+ ndpi_int_http_add_connection(ndpi_struct, flow, proto_id);
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+ /* HTTP found, look for host... */
+ if(packet->host_line.ptr != NULL) {
+ /* aaahh, skip this direction and wait for a server reply here */
+ flow->l4.tcp.http_stage = 2;
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP START HOST found\n");
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP START HOST found\n");
+
+ /* host not found, check in next packet after */
+ flow->l4.tcp.http_stage = 1;
+ return;
+ }
+ } else if(flow->l4.tcp.http_stage == 1) {
+ /* SECOND PAYLOAD TRAFFIC FROM CLIENT, FIRST PACKET MIGHT HAVE BEEN HTTP... */
+ /* UNKNOWN TRAFFIC, HERE FOR HTTP again.. */
+ // parse packet
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if(packet->parsed_lines <= 1) {
+ /* wait some packets in case request is split over more than 2 packets */
+ if(flow->packet_counter < 5) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "line still not finished, search next packet\n");
+ return;
+ } else {
+ /* stop parsing here */
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "HTTP: PACKET DOES NOT HAVE A LINE STRUCTURE\n");
+ http_bitmask_exclude(flow);
+ return;
+ }
+ }
+ // http://www.slideshare.net/DSPIP/rtsp-analysis-wireshark
+ if(packet->line[0].len >= 9 && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) {
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "HTTP START HTTP found in 2. packet, check host here...\n");
+ /* HTTP found, look for host... */
+ flow->l4.tcp.http_stage = 2;
+
+ return;
+ }
+ }
+ } else {
+ /* We have received a response for a previously identified partial HTTP request */
+
+ if((packet->parsed_lines == 1) && (packet->packet_direction == 1 /* server -> client */)) {
+ /*
+ In apache if you do "GET /\n\n" the response comes without any header so we can assume that
+ this can be the case
+ */
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ return;
+ }
+
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: REQUEST NOT HTTP CONFORM\n");
+ http_bitmask_exclude(flow);
+ return;
+
+ http_parse_detection:
+ if(flow->l4.tcp.http_setup_dir == 1 + packet->packet_direction) {
+ /* we have something like http here, so check for host and content type if possible */
+ if(flow->l4.tcp.http_stage == 0 || flow->l4.tcp.http_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP RUN MAYBE NEXT GET/POST...\n");
+ // parse packet
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ /* check for url here */
+ filename_start = http_request_url_offset(ndpi_struct, flow);
+ if(filename_start != 0 && packet->parsed_lines > 1 && packet->line[0].len >= (9 + filename_start)
+ && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) {
+ packet->http_url_name.ptr = &packet->payload[filename_start];
+ packet->http_url_name.len = packet->line[0].len - (filename_start + 9);
+
+ packet->http_method.ptr = packet->line[0].ptr;
+ packet->http_method.len = filename_start - 1;
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "next http action, "
+ "resetting to http and search for other protocols later.\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ }
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+ /* HTTP found, look for host... */
+ if(packet->host_line.ptr != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "HTTP RUN MAYBE NEXT HOST found, skipping all packets from this direction\n");
+ /* aaahh, skip this direction and wait for a server reply here */
+ flow->l4.tcp.http_stage = 2;
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "HTTP RUN MAYBE NEXT HOST NOT found, scanning one more packet from this direction\n");
+ flow->l4.tcp.http_stage = 1;
+ } else if(flow->l4.tcp.http_stage == 1) {
+ // parse packet and maybe find a packet info with host ptr,...
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP RUN second packet scanned\n");
+ /* HTTP found, look for host... */
+ flow->l4.tcp.http_stage = 2;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "HTTP skipping client packets after second packet\n");
+ return;
+ }
+ /* server response */
+ if(flow->l4.tcp.http_stage > 0) {
+ /* first packet from server direction, might have a content line */
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+
+ if(packet->empty_line_position_set != 0 || flow->l4.tcp.http_empty_line_seen == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "empty line. check_http_payload.\n");
+ check_http_payload(ndpi_struct, flow);
+ }
+
+ if(flow->l4.tcp.http_stage == 2) {
+ flow->l4.tcp.http_stage = 3;
+ } else {
+ flow->l4.tcp.http_stage = 0;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "HTTP response first or second packet scanned,new stage is: %u\n", flow->l4.tcp.http_stage);
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP response next packet skipped\n");
+ }
+}
+
+/*************************************************************************************************/
+
+static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t filename_start;
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->l4.tcp.http_stage == 0) {
+ flow->http_detected = 0;
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP stage %d: \n",
+ flow->l4.tcp.http_stage);
+
+ filename_start = http_request_url_offset(ndpi_struct, flow);
+
+
+ if (filename_start == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "Filename HTTP not found, we look for possible truncate flow...\n");
+ if (packet->payload_packet_len >= 7 && memcmp(packet->payload, "HTTP/1.", 7) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "HTTP response found (truncated flow ?)\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Exclude HTTP\n");
+ http_bitmask_exclude(flow);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "Filename HTTP found: %d, we look for line info..\n", filename_start);
+
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if (packet->parsed_lines <= 1) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "Found just one line, we will look further for the next packet...\n");
+
+ packet->http_method.ptr = packet->line[0].ptr;
+ packet->http_method.len = filename_start - 1;
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "Found more than one line, we look further for the next packet...\n");
+
+ if(packet->line[0].len >= (9 + filename_start)
+ && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) {
+
+ packet->http_url_name.ptr = &packet->payload[filename_start];
+ packet->http_url_name.len = packet->line[0].len - (filename_start + 9);
+
+ packet->http_method.ptr = packet->line[0].ptr;
+ packet->http_method.len = filename_start - 1;
+
+ if((packet->http_url_name.len > 7)
+ && (!strncmp((const char*) packet->http_url_name.ptr, "http://", 7))) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP_PROXY Found.\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_PROXY);
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+ }
+
+ if(filename_start == 8 && (memcmp(packet->payload, "CONNECT ", 8) == 0)) /* nathan@getoffmalawn.com */
+ {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP_CONNECT Found.\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_CONNECT);
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "HTTP START Found, we will look for sub-protocols (content and host)...\n");
+
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+
+ if(packet->host_line.ptr != NULL) {
+ /*
+ nDPI is pretty scrupoulous about HTTP so it waits until the
+ HTTP response is received just to check that it conforms
+ with the HTTP specs. However this might be a waste of time as
+ in 99.99% of the cases is like that.
+ */
+
+ if(!ndpi_struct->http_dissect_response) {
+ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) /* No subprotocol found */
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ } else {
+ flow->http_detected = 1;
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "HTTP START Found, we will look further for the response...\n");
+ flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
+ }
+
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: REQUEST NOT HTTP CONFORM\n");
+ http_bitmask_exclude(flow);
+ } else if ((flow->l4.tcp.http_stage == 1) || (flow->l4.tcp.http_stage == 2)) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP stage %u: \n",
+ flow->l4.tcp.http_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, if http is detected do nothing now and return,
+ * otherwise check the second packet for the http request . */
+ if ((flow->l4.tcp.http_stage - packet->packet_direction) == 1) {
+
+ if (flow->http_detected)
+ return;
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ " SECOND PAYLOAD TRAFFIC FROM CLIENT, FIRST PACKET MIGHT HAVE BEEN HTTP...UNKNOWN TRAFFIC, HERE FOR HTTP again.. \n");
+
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if (packet->parsed_lines <= 1) {
+ /* wait some packets in case request is split over more than 2 packets */
+ if (flow->packet_counter < 5) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "line still not finished, search next packet\n");
+ return;
+ } else {
+ /* stop parsing here */
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "HTTP: PACKET DOES NOT HAVE A LINE STRUCTURE\n");
+ http_bitmask_exclude(flow);
+ return;
+ }
+ }
+ // http://www.slideshare.net/DSPIP/rtsp-analysis-wireshark
+ if (packet->line[0].len >= 9
+ && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Found HTTP.\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "HTTP START Found in 2. packet, we will look further for the response....\n");
+ flow->http_detected = 1;
+ }
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ /* We have received a response for a previously identified partial HTTP request */
+
+ if ((packet->parsed_lines == 1) && (packet->packet_direction == 1 /* server -> client */)) {
+ /*
+ In apache if you do "GET /\n\n" the response comes without any header so we can assume that
+ this can be the case
+ */
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Found HTTP. (apache)\n");
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+ return;
+ }
+
+ /* If we already detected the http request, we can add the connection and then check for the sub-protocol*/
+ if (flow->http_detected)
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+
+ /* Parse packet line and we look for the subprotocols */
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+
+ if (packet->empty_line_position_set != 0 || flow->l4.tcp.http_empty_line_seen == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "empty line. check_http_payload.\n");
+ check_http_payload(ndpi_struct, flow);
+ }
+
+ flow->l4.tcp.http_stage = 0;
+ return;
+ }
+
+}
+
+void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ /* Break after 20 packets. */
+ if (flow->packet_counter > 20) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Exclude HTTP.\n");
+ http_bitmask_exclude(flow);
+ return;
+ }
+
+ if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) {
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP detection...\n");
+ ndpi_check_http_tcp(ndpi_struct, flow);
+}
+
+/* ********************************* */
+
+ndpi_http_method ndpi_get_http_method(struct ndpi_detection_module_struct *ndpi_mod,
+ struct ndpi_flow_struct *flow) {
+ if(!flow)
+ return(HTTP_METHOD_UNKNOWN);
+ else
+ return(flow->http.method);
+}
+
+/* ********************************* */
+
+char* ndpi_get_http_url(struct ndpi_detection_module_struct *ndpi_mod,
+ struct ndpi_flow_struct *flow) {
+ if((!flow) || (!flow->http.url))
+ return("");
+ else
+ return(flow->http.url);
+}
+
+/* ********************************* */
+
+char* ndpi_get_http_content_type(struct ndpi_detection_module_struct *ndpi_mod,
+ struct ndpi_flow_struct *flow) {
+ if((!flow) || (!flow->http.content_type))
+ return("");
+ else
+ return(flow->http.content_type);
+}
+
+#endif
diff --git a/src/lib/protocols/http_activesync.c b/src/lib/protocols/http_activesync.c
new file mode 100644
index 000000000..fd115ced6
--- /dev/null
+++ b/src/lib/protocols/http_activesync.c
@@ -0,0 +1,54 @@
+/*
+ * http_activesync.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC
+static void ndpi_int_activesync_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC, NDPI_CORRELATED_PROTOCOL);
+}
+
+void ndpi_search_activesync(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if (packet->tcp != NULL) {
+
+ if (packet->payload_packet_len > 150
+ && ((memcmp(packet->payload, "OPTIONS /Microsoft-Server-ActiveSync?", 37) == 0)
+ || (memcmp(packet->payload, "POST /Microsoft-Server-ActiveSync?", 34) == 0))) {
+ ndpi_int_activesync_add_connection(ndpi_struct, flow);
+ NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC, ndpi_struct, NDPI_LOG_DEBUG,
+ " flow marked as ActiveSync \n");
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC, ndpi_struct, NDPI_LOG_DEBUG, "exclude activesync\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC);
+
+}
+#endif
diff --git a/src/lib/protocols/iax.c b/src/lib/protocols/iax.c
new file mode 100644
index 000000000..d7a01b51c
--- /dev/null
+++ b/src/lib/protocols/iax.c
@@ -0,0 +1,94 @@
+/*
+ * iax.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_IAX
+
+#define NDPI_IAX_MAX_INFORMATION_ELEMENTS 15
+
+static void ndpi_int_iax_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_IAX, NDPI_REAL_PROTOCOL);
+}
+
+static void ndpi_search_setup_iax(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int8_t i;
+ u_int16_t packet_len;
+
+ if ( /* 1. iax is udp based, port 4569 */
+ (packet->udp->source == htons(4569) || packet->udp->dest == htons(4569))
+ /* check for iax new packet */
+ && packet->payload_packet_len >= 12
+ /* check for dst call id == 0, do not check for highest bit (packet retransmission) */
+ // && (ntohs(get_u_int16_t(packet->payload, 2)) & 0x7FFF) == 0
+ /* check full IAX packet */
+ && (packet->payload[0] & 0x80) != 0
+ /* outbound seq == 0 */
+ && packet->payload[8] == 0
+ /* inbound seq == 0 || 1 */
+ && (packet->payload[9] == 0 || packet->payload[9] == 0x01)
+ /* */
+ && packet->payload[10] == 0x06
+ /* IAX type: 0-15 */
+ && packet->payload[11] <= 15) {
+
+ if (packet->payload_packet_len == 12) {
+ NDPI_LOG(NDPI_PROTOCOL_IAX, ndpi_struct, NDPI_LOG_DEBUG, "found IAX.\n");
+ ndpi_int_iax_add_connection(ndpi_struct, flow);
+ return;
+ }
+ packet_len = 12;
+ for (i = 0; i < NDPI_IAX_MAX_INFORMATION_ELEMENTS; i++) {
+ packet_len = packet_len + 2 + packet->payload[packet_len + 1];
+ if (packet_len == packet->payload_packet_len) {
+ NDPI_LOG(NDPI_PROTOCOL_IAX, ndpi_struct, NDPI_LOG_DEBUG, "found IAX.\n");
+ ndpi_int_iax_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet_len > packet->payload_packet_len) {
+ break;
+ }
+ }
+
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IAX);
+
+}
+
+void ndpi_search_iax(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // struct ndpi_flow_struct *flow=ndpi_struct->flow;
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if(packet->udp
+ && (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN))
+ ndpi_search_setup_iax(ndpi_struct, flow);
+}
+#endif
diff --git a/src/lib/protocols/icecast.c b/src/lib/protocols/icecast.c
new file mode 100644
index 000000000..49c6f5fc5
--- /dev/null
+++ b/src/lib/protocols/icecast.c
@@ -0,0 +1,91 @@
+/*
+ * icecast.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_ICECAST
+
+static void ndpi_int_icecast_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_ICECAST, NDPI_CORRELATED_PROTOCOL);
+}
+
+void ndpi_search_icecast_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int8_t i;
+
+ NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "search icecast.\n");
+
+ if ((packet->payload_packet_len < 500 &&
+ packet->payload_packet_len >= 7 && memcmp(packet->payload, "SOURCE ", 7) == 0)
+ || flow->l4.tcp.icecast_stage) {
+ ndpi_parse_packet_line_info_any(ndpi_struct, flow);
+ NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast lines=%d\n", packet->parsed_lines);
+ for (i = 0; i < packet->parsed_lines; i++) {
+ if (packet->line[i].ptr != NULL && packet->line[i].len > 4
+ && memcmp(packet->line[i].ptr, "ice-", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast detected.\n");
+ ndpi_int_icecast_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ if (packet->parsed_lines < 1 && !flow->l4.tcp.icecast_stage) {
+ flow->l4.tcp.icecast_stage = 1;
+ return;
+ }
+ }
+#ifdef NDPI_PROTOCOL_HTTP
+ if (NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct, flow, NDPI_PROTOCOL_HTTP)) {
+ goto icecast_exclude;
+ }
+#endif
+
+ if (packet->packet_direction == flow->setup_packet_direction && flow->packet_counter < 10) {
+ return;
+ }
+
+ if (packet->packet_direction != flow->setup_packet_direction) {
+ /* server answer, now test Server for Icecast */
+
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if (packet->server_line.ptr != NULL && packet->server_line.len > NDPI_STATICSTRING_LEN("Icecast") &&
+ memcmp(packet->server_line.ptr, "Icecast", NDPI_STATICSTRING_LEN("Icecast")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast detected.\n");
+ /* TODO maybe store the previous protocol type as subtype?
+ * e.g. ogg or mpeg
+ */
+ ndpi_int_icecast_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ icecast_exclude:
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ICECAST);
+ NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast excluded.\n");
+}
+#endif
diff --git a/src/lib/protocols/imesh.c b/src/lib/protocols/imesh.c
new file mode 100644
index 000000000..1e2238fca
--- /dev/null
+++ b/src/lib/protocols/imesh.c
@@ -0,0 +1,294 @@
+/*
+ * imesh.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_IMESH
+
+
+static void ndpi_int_imesh_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_IMESH, protocol_type);
+}
+
+
+void ndpi_search_imesh_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if (packet->udp != NULL) {
+
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "UDP FOUND\n");
+
+ // this is the login packet
+ if (packet->payload_packet_len == 28 && (get_u_int32_t(packet->payload, 0)) == htonl(0x02000000) &&
+ get_u_int32_t(packet->payload, 24) == 0 &&
+ (packet->udp->dest == htons(1864) || packet->udp->source == htons(1864))) {
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh Login detected\n");
+ ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 36) {
+ if (get_u_int32_t(packet->payload, 0) == htonl(0x02000000) && packet->payload[4] != 0 &&
+ packet->payload[5] == 0 && get_u_int16_t(packet->payload, 6) == htons(0x0083) &&
+ get_u_int32_t(packet->payload, 24) == htonl(0x40000000) &&
+ (packet->payload[packet->payload_packet_len - 1] == packet->payload[packet->payload_packet_len - 5] ||
+ packet->payload[packet->payload_packet_len - 1] - 1 == packet->payload[packet->payload_packet_len - 5]
+ || packet->payload[packet->payload_packet_len - 1] ==
+ packet->payload[packet->payload_packet_len - 5] - 1)) {
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh detected\n");
+ ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (get_u_int16_t(packet->payload, 0) == htons(0x0200) && get_u_int16_t(packet->payload, 2) != 0 &&
+ get_u_int32_t(packet->payload, 4) == htonl(0x02000083) && get_u_int32_t(packet->payload, 24) == htonl(0x40000000) &&
+ (packet->payload[packet->payload_packet_len - 1] == packet->payload[packet->payload_packet_len - 5] ||
+ packet->payload[packet->payload_packet_len - 1] - 1 == packet->payload[packet->payload_packet_len - 5]
+ || packet->payload[packet->payload_packet_len - 1] ==
+ packet->payload[packet->payload_packet_len - 5] - 1)) {
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh detected\n");
+ ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ if (packet->payload_packet_len == 24 && get_u_int16_t(packet->payload, 0) == htons(0x0200)
+ && get_u_int16_t(packet->payload, 2) != 0 && get_u_int32_t(packet->payload, 4) == htonl(0x03000084) &&
+ (packet->payload[packet->payload_packet_len - 1] == packet->payload[packet->payload_packet_len - 5] ||
+ packet->payload[packet->payload_packet_len - 1] - 1 == packet->payload[packet->payload_packet_len - 5] ||
+ packet->payload[packet->payload_packet_len - 1] == packet->payload[packet->payload_packet_len - 5] - 1)) {
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh detected\n");
+ ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 32 && get_u_int32_t(packet->payload, 0) == htonl(0x02000000) &&
+ get_u_int16_t(packet->payload, 21) == 0 && get_u_int16_t(packet->payload, 26) == htons(0x0100)) {
+ if (get_u_int32_t(packet->payload, 4) == htonl(0x00000081) && packet->payload[11] == packet->payload[15] &&
+ get_l16(packet->payload, 24) == htons(packet->udp->source)) {
+ /* packet->payload[28] = source address */
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh detected\n");
+ ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (get_u_int32_t(packet->payload, 4) == htonl(0x01000082)) {
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh detected\n");
+ ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh UDP packetlen: %d\n",
+ packet->payload_packet_len);
+
+ }
+
+ if (packet->tcp != NULL) {
+ if (packet->payload_packet_len == 64 && get_u_int32_t(packet->payload, 0) == htonl(0x40000000) &&
+ get_u_int32_t(packet->payload, 4) == 0 && get_u_int32_t(packet->payload, 8) == htonl(0x0000fcff) &&
+ get_u_int32_t(packet->payload, 12) == htonl(0x04800100) && get_u_int32_t(packet->payload, 45) == htonl(0xff020000) &&
+ get_u_int16_t(packet->payload, 49) == htons(0x001a)) {
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "found imesh.\n");
+ ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 95 && get_u_int32_t(packet->payload, 0) == htonl(0x5f000000) &&
+ get_u_int16_t(packet->payload, 4) == 0 && get_u_int16_t(packet->payload, 7) == htons(0x0004) &&
+ get_u_int32_t(packet->payload, 20) == 0 && get_u_int32_t(packet->payload, 28) == htonl(0xc8000400) &&
+ packet->payload[9] == 0x80 && get_u_int32_t(packet->payload, 10) == get_u_int32_t(packet->payload, 24)) {
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "found imesh.\n");
+ ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 28 && get_u_int32_t(packet->payload, 0) == htonl(0x1c000000) &&
+ get_u_int16_t(packet->payload, 10) == htons(0xfcff) && get_u_int32_t(packet->payload, 12) == htonl(0x07801800) &&
+ (get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == htons(0x1900) ||
+ get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == htons(0x1a00))) {
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "found imesh.\n");
+ ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "TCP FOUND :: Payload %u\n",
+ packet->payload_packet_len);
+
+ if (packet->actual_payload_len == 0) {
+ return;
+ }
+ if ((packet->actual_payload_len == 8 || packet->payload_packet_len == 10) /* PATTERN:: 04 00 00 00 00 00 00 00 [00 00] */
+ &&get_u_int32_t(packet->payload, 0) == htonl(0x04000000)
+ && get_u_int32_t(packet->payload, 4) == 0) {
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if (packet->actual_payload_len == 10 /* PATTERN:: ?? ?? 04|00 00 64|00 00 */
+ && (packet->payload[2] == 0x04 || packet->payload[2] == 0x00)
+ && packet->payload[3] == 0x00 && (packet->payload[4] == 0x00 || packet->payload[4] == 0x64)
+ && packet->payload[5] == 0x00
+ && (packet->payload[2] != packet->payload[4]) /* We do not want that the packet is ?? ?? 00 00 00 00 */
+ ) {
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if (packet->actual_payload_len == 2 && packet->payload[0] == 0x06 && packet->payload[1] == 0x00) {
+ flow->l4.tcp.imesh_stage++;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if (packet->actual_payload_len == 10 /* PATTERN:: 06 00 04|00 00 01|00 00 01|00 00 ?? 00 */
+ && packet->payload[0] == 0x06
+ && packet->payload[1] == 0x00 && (packet->payload[2] == 0x04 || packet->payload[2] == 0x00)
+ && packet->payload[3] == 0x00 && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01)
+ && packet->payload[5] == 0x00 && (packet->payload[6] == 0x01 || packet->payload[6] == 0x00)
+ && packet->payload[7] == 0x00 && packet->payload[9] == 0x00
+ && (packet->payload[2] || packet->payload[4] || packet->payload[6]) /* We do not want that the packet is all 06 00 00 ... */
+ ) {
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if (packet->actual_payload_len == 24 && packet->payload[0] == 0x06 // PATTERN :: 06 00 12 00 00 00 34 00 00
+ && packet->payload[1] == 0x00
+ && packet->payload[2] == 0x12
+ && packet->payload[3] == 0x00
+ && packet->payload[4] == 0x00
+ && packet->payload[5] == 0x00
+ && packet->payload[6] == 0x34 && packet->payload[7] == 0x00 && packet->payload[8] == 0x00) {
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if (packet->actual_payload_len == 8 /* PATTERN:: 06|00 00 02 00 00 00 33 00 */
+ && (packet->payload[0] == 0x06 || packet->payload[0] == 0x00)
+ && packet->payload[1] == 0x00
+ && packet->payload[2] == 0x02
+ && packet->payload[3] == 0x00
+ && packet->payload[4] == 0x00
+ && packet->payload[5] == 0x00 && packet->payload[6] == 0x33 && packet->payload[7] == 0x00) {
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if (packet->payload_packet_len == 6 /* PATTERN:: 02 00 00 00 33 00 */
+ && packet->payload[0] == 0x02
+ && packet->payload[1] == 0x00
+ && packet->payload[2] == 0x00
+ && packet->payload[3] == 0x00 && packet->payload[4] == 0x33 && packet->payload[5] == 0x00) {
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if (packet->actual_payload_len == 12 && packet->payload[0] == 0x06 // PATTERN : 06 00 06 00 00 00 64 00
+ && packet->payload[1] == 0x00
+ && packet->payload[2] == 0x06
+ && packet->payload[3] == 0x00
+ && packet->payload[4] == 0x00
+ && packet->payload[5] == 0x00 && packet->payload[6] == 0x64 && packet->payload[7] == 0x00) {
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if (packet->actual_payload_len == 10 /* PATTERN:: 06 00 04|01 00 00 00 01|00 00 ?? 00 */
+ && packet->payload[0] == 0x06
+ && packet->payload[1] == 0x00 && (packet->payload[2] == 0x04 || packet->payload[2] == 0x01)
+ && packet->payload[3] == 0x00
+ && packet->payload[4] == 0x00
+ && packet->payload[5] == 0x00 && (packet->payload[6] == 0x01 || packet->payload[6] == 0x00)
+ && packet->payload[7] == 0x00
+ /* && packet->payload[8]==0x00 */
+ && packet->payload[9] == 0x00) {
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if ((packet->actual_payload_len == 64 || packet->actual_payload_len == 52 /* PATTERN:: [len] 00 00 00 00 */
+ || packet->actual_payload_len == 95)
+ && get_u_int16_t(packet->payload, 0) == (packet->actual_payload_len)
+ && packet->payload[1] == 0x00 && packet->payload[2] == 0x00
+ && packet->payload[3] == 0x00 && packet->payload[4] == 0x00) {
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if (packet->actual_payload_len == 6 && packet->payload[0] == 0x06 // PATTERN : 06 00 04|6c 00|01 00 00
+ && packet->payload[1] == 0x00 && (packet->payload[2] == 0x04 || packet->payload[2] == 0x6c)
+ && (packet->payload[3] == 0x00 || packet->payload[3] == 0x01)
+ && packet->payload[4] == 0x00 && packet->payload[5] == 0x00) {
+
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if (packet->actual_payload_len == 6 /* PATTERN:: [len] ?? ee 00 00 00 */
+ && get_u_int16_t(packet->payload, 0) == (packet->actual_payload_len)
+ && packet->payload[2] == 0xee
+ && packet->payload[3] == 0x00 && packet->payload[4] == 0x00 && packet->payload[5] == 0x00) {
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ } else if (packet->actual_payload_len == 10 /* PATTERN:: 06 00 00 00 00 00 00 00 */
+ && packet->payload[0] == 0x06
+ && packet->payload[1] == 0x00
+ && packet->payload[2] == 0x00
+ && packet->payload[3] == 0x00
+ && packet->payload[4] == 0x00
+ && packet->payload[5] == 0x00 && packet->payload[6] == 0x00 && packet->payload[7] == 0x00) {
+ flow->l4.tcp.imesh_stage += 2;
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG,
+ "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
+ }
+
+
+ /* http login */
+ if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("POST /registration") &&
+ memcmp(packet->payload, "POST /registration", NDPI_STATICSTRING_LEN("POST /registration")) == 0) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->parsed_lines > 6 &&
+ packet->host_line.ptr != NULL &&
+ packet->host_line.len == NDPI_STATICSTRING_LEN("login.bearshare.com") &&
+ packet->line[1].ptr != NULL &&
+ packet->line[1].len == NDPI_STATICSTRING_LEN("Authorization: Basic Og==") &&
+ packet->line[4].ptr != NULL &&
+ packet->line[4].len == NDPI_STATICSTRING_LEN("Accept-Encoding: identity") &&
+ memcmp(packet->line[1].ptr, "Authorization: Basic Og==",
+ NDPI_STATICSTRING_LEN("Authorization: Basic Og==")) == 0 &&
+ memcmp(packet->host_line.ptr, "login.bearshare.com",
+ NDPI_STATICSTRING_LEN("login.bearshare.com")) == 0 &&
+ memcmp(packet->line[4].ptr, "Accept-Encoding: identity",
+ NDPI_STATICSTRING_LEN("Accept-Encoding: identity")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh Login detected\n");
+ ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ /*give one packet tolerance for detection */
+ if((flow->l4.tcp.imesh_stage >= 4)
+ && (flow->l4.tcp.seen_syn && flow->l4.tcp.seen_syn_ack && flow->l4.tcp.seen_ack) /* We have seen the 3-way handshake */)
+ {
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "found imesh.\n");
+ ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+ if ((flow->packet_counter < 5) || packet->actual_payload_len == 0) {
+ return;
+ }
+ //imesh_not_found_end:
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IMESH);
+ NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh excluded at stage %d\n",
+ packet->tcp != NULL ? flow->l4.tcp.imesh_stage : 0);
+
+}
+#endif
diff --git a/src/lib/protocols/ipp.c b/src/lib/protocols/ipp.c
new file mode 100644
index 000000000..72a75bc2a
--- /dev/null
+++ b/src/lib/protocols/ipp.c
@@ -0,0 +1,112 @@
+/*
+ * ipp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_IPP
+
+static void ndpi_int_ipp_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_IPP, protocol_type);
+}
+
+void ndpi_search_ipp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ u_int8_t i;
+
+ NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "search ipp\n");
+ if (packet->payload_packet_len > 20) {
+
+ NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG,
+ "searching for a payload with a pattern like 'number(1to8)blanknumber(1to3)ipp://.\n");
+ /* this pattern means that there is a printer saying that his state is idle,
+ * means that he is not printing anything at the moment */
+ i = 0;
+
+ if (packet->payload[i] < '0' || packet->payload[i] > '9') {
+ NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "payload does not begin with a number.\n");
+ goto search_for_next_pattern;
+ }
+
+ for (;;) {
+ i++;
+ if (!((packet->payload[i] >= '0' && packet->payload[i] <= '9') ||
+ (packet->payload[i] >= 'a' && packet->payload[i] <= 'f') ||
+ (packet->payload[i] >= 'A' && packet->payload[i] <= 'F')) || i > 8) {
+ NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG,
+ "read symbols while the symbol is a number.\n");
+ break;
+ }
+ }
+
+ if (packet->payload[i++] != ' ') {
+ NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "there is no blank following the number.\n");
+ goto search_for_next_pattern;
+ }
+
+ if (packet->payload[i] < '0' || packet->payload[i] > '9') {
+ NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "no number following the blank.\n");
+ goto search_for_next_pattern;
+ }
+
+ for (;;) {
+ i++;
+ if (packet->payload[i] < '0' || packet->payload[i] > '9' || i > 12) {
+ NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG,
+ "read symbols while the symbol is a number.\n");
+ break;
+ }
+ }
+
+ if (memcmp(&packet->payload[i], " ipp://", 7) != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "the string ' ipp://' does not follow.\n");
+ goto search_for_next_pattern;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "found ipp\n");
+ ndpi_int_ipp_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ search_for_next_pattern:
+
+ if (packet->payload_packet_len > 3 && memcmp(packet->payload, "POST", 4) == 0) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->content_line.ptr != NULL && packet->content_line.len > 14
+ && memcmp(packet->content_line.ptr, "application/ipp", 15) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "found ipp via POST ... application/ipp.\n");
+ ndpi_int_ipp_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "no ipp detected.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IPP);
+}
+
+#endif
diff --git a/src/lib/protocols/irc.c b/src/lib/protocols/irc.c
new file mode 100644
index 000000000..1947c3ac9
--- /dev/null
+++ b/src/lib/protocols/irc.c
@@ -0,0 +1,804 @@
+/*
+ * irc.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_IRC
+#define NDPI_IRC_FIND_LESS(time_err,less) {int t1 = 0; \
+ u_int32_t timestamp = time_err[0]; \
+ for(t1=0;t1 < NDPI_PROTOCOL_IRC_MAXPORT;t1++) { \
+ if(timestamp > time_err[t1]) { \
+ timestamp = time_err[t1]; \
+ less = t1;}}}
+
+static void ndpi_int_irc_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_IRC, NDPI_REAL_PROTOCOL);
+}
+
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+u_int8_t ndpi_is_duplicate(struct ndpi_id_struct *id_t, u_int16_t port)
+{
+ int index = 0;
+ while (index < id_t->irc_number_of_port) {
+ if (port == id_t->irc_port[index])
+ return 1;
+ index++;
+ }
+ return 0;
+}
+
+static u_int8_t ndpi_check_for_NOTICE_or_PRIVMSG(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+ //
+ u_int16_t i;
+ u_int8_t number_of_lines_to_be_searched_for = 0;
+ for (i = 0; i < packet->payload_packet_len - 7; i++) {
+ if (packet->payload[i] == 'N' || packet->payload[i] == 'P') {
+ if (memcmp(&packet->payload[i + 1], "OTICE ", 6) == 0 || memcmp(&packet->payload[i + 1], "RIVMSG ", 7) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "found NOTICE or PRIVMSG\n");
+ return 1;
+ }
+ }
+ if (packet->payload[i] == 0x0a) {
+ number_of_lines_to_be_searched_for++;
+ if (number_of_lines_to_be_searched_for == 2) {
+ return 0;
+ }
+ }
+ }
+ return 0;
+
+}
+
+static u_int8_t ndpi_check_for_Nickname(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t i, packetl = packet->payload_packet_len;
+
+ if (packetl < 4) {
+ return 0;
+ }
+
+ for (i = 0; i < (packetl - 4); i++) {
+ if (packet->payload[i] == 'N' || packet->payload[i] == 'n') {
+ if ((((packetl - (i + 1)) >= 4) && memcmp(&packet->payload[i + 1], "ick=", 4) == 0)
+ || (((packetl - (i + 1)) >= 8) && (memcmp(&packet->payload[i + 1], "ickname=", 8) == 0))
+ || (((packetl - (i + 1)) >= 8) && (memcmp(&packet->payload[i + 1], "ickName=", 8) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "found HTTP IRC Nickname pattern\n");
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static u_int8_t ndpi_check_for_cmd(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t i;
+
+ if (packet->payload_packet_len < 4) {
+ return 0;
+ }
+
+ for (i = 0; i < packet->payload_packet_len - 4; i++) {
+ if (packet->payload[i] == 'c') {
+ if (memcmp(&packet->payload[i + 1], "md=", 3) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "found HTTP IRC cmd pattern \n");
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static u_int8_t ndpi_check_for_IRC_traces(const u_int8_t * ptr, u_int16_t len)
+{
+ u_int16_t i;
+
+ if (len < 4) {
+ return 0;
+ }
+
+ for (i = 0; i < len - 4; i++) {
+ if (ptr[i] == 'i') {
+ if (memcmp(&ptr[i + 1], "rc.", 3) == 0) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+u_int8_t ndpi_search_irc_ssl_detect_ninty_percent_but_very_fast(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG,
+ "called ndpi_search_irc_ssl_detect_ninty_percent_but_very_fast\n");
+
+ /* case 1: len 1460, len 1460, len 1176 several times in one direction, than len = 4, 4096, 8192 in the other direction */
+ if (packet->payload_packet_len == 1460
+ && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0) || (flow->l4.tcp.irc_stage2 == 3
+ && flow->l4.tcp.irc_direction ==
+ 1 + packet->packet_direction))) {
+ flow->l4.tcp.irc_stage2 = 1;
+ flow->l4.tcp.irc_direction = 1 + packet->packet_direction;
+ return 1;
+ }
+ if (packet->payload_packet_len == 1460 && flow->l4.tcp.irc_stage2 == 1
+ && flow->l4.tcp.irc_direction == 1 + packet->packet_direction) {
+ flow->l4.tcp.irc_stage2 = 2;
+ return 1;
+ }
+ if (packet->payload_packet_len == 1176 && flow->l4.tcp.irc_stage2 == 2
+ && flow->l4.tcp.irc_direction == 1 + packet->packet_direction) {
+ flow->l4.tcp.irc_stage2 = 3;
+ flow->l4.tcp.irc_0x1000_full = 1;
+ return 1;
+ }
+ if (packet->payload_packet_len == 4 && (flow->l4.tcp.irc_stage2 == 3 || flow->l4.tcp.irc_0x1000_full == 1)
+ && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 0x1000
+ || ntohs(get_u_int16_t(packet->payload, 2)) ==
+ 0x2000)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1460,1460,1176,<-4096||8192");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return 1;
+ }
+ /* case 2: len 1448, len 1448, len 1200 several times in one direction, than len = 4, 4096, 8192 in the other direction */
+ if (packet->payload_packet_len == 1448
+ && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0) || (flow->l4.tcp.irc_stage2 == 6
+ && flow->l4.tcp.irc_direction ==
+ 1 + packet->packet_direction))) {
+ flow->l4.tcp.irc_stage2 = 4;
+ flow->l4.tcp.irc_direction = 1 + packet->packet_direction;
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "len = 1448 first\n");
+ return 1;
+ }
+ if (packet->payload_packet_len == 1448 && flow->l4.tcp.irc_stage2 == 4
+ && flow->l4.tcp.irc_direction == 1 + packet->packet_direction) {
+ flow->l4.tcp.irc_stage2 = 5;
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "len = 1448 second \n");
+ return 1;
+ }
+ if (packet->payload_packet_len == 1200 && flow->l4.tcp.irc_stage2 == 5
+ && flow->l4.tcp.irc_direction == 1 + packet->packet_direction) {
+ flow->l4.tcp.irc_stage2 = 6;
+ flow->l4.tcp.irc_0x1000_full = 1;
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "len = 1200 \n");
+ return 1;
+ }
+ if (packet->payload_packet_len == 4 && (flow->l4.tcp.irc_stage2 == 6 || flow->l4.tcp.irc_0x1000_full == 1)
+ && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 0x1000
+ || ntohs(get_u_int16_t(packet->payload, 2)) ==
+ 0x2000)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1448,1448,1200,<-4096||8192");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return 1;
+ }
+ /* case 3: several packets with len 1380, 1200, 1024, 1448, 1248,
+ * than one packet in the other direction with the len or two times the len. */
+ if (packet->payload_packet_len == 1380 && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0)
+ || (flow->l4.tcp.irc_stage2 == 7
+ && flow->l4.tcp.irc_direction == 1 + packet->packet_direction))) {
+ flow->l4.tcp.irc_stage2 = 7;
+ flow->l4.tcp.irc_direction = 1 + packet->packet_direction;
+ return 1;
+ }
+ if (packet->payload_packet_len == 4 && flow->l4.tcp.irc_stage2 == 7
+ && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 1380
+ || ntohs(get_u_int16_t(packet->payload, 2)) ==
+ 2760)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1380,<-1380||2760");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return 1;
+ }
+ if (packet->payload_packet_len == 1200 && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0)
+ || (flow->l4.tcp.irc_stage2 == 8
+ && flow->l4.tcp.irc_direction == 1 + packet->packet_direction))) {
+ flow->l4.tcp.irc_stage2 = 8;
+ flow->l4.tcp.irc_direction = 1 + packet->packet_direction;
+ return 1;
+ }
+ if (packet->payload_packet_len == 4 && flow->l4.tcp.irc_stage2 == 8
+ && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 1200
+ || ntohs(get_u_int16_t(packet->payload, 2)) ==
+ 2400)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1200,<-1200||2400");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return 1;
+ }
+ if (packet->payload_packet_len == 1024 && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0)
+ || (flow->l4.tcp.irc_stage2 == 9
+ && flow->l4.tcp.irc_direction == 1 + packet->packet_direction))) {
+ flow->l4.tcp.irc_stage2 = 9;
+ flow->l4.tcp.irc_direction = 1 + packet->packet_direction;
+ return 1;
+ }
+ if (packet->payload_packet_len == 4 && (flow->l4.tcp.irc_stage2 == 9 || flow->l4.tcp.irc_stage2 == 15)
+ && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 1024
+ || ntohs(get_u_int16_t(packet->payload, 2)) ==
+ 2048)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1024,<-1024||2048");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return 1;
+ }
+ if (packet->payload_packet_len == 1248 && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0)
+ || (flow->l4.tcp.irc_stage2 == 10
+ && flow->l4.tcp.irc_direction == 1 + packet->packet_direction))) {
+ flow->l4.tcp.irc_stage2 = 10;
+ flow->l4.tcp.irc_direction = 1 + packet->packet_direction;
+ return 1;
+ }
+ if (packet->payload_packet_len == 4 && flow->l4.tcp.irc_stage2 == 10
+ && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 1248
+ || ntohs(get_u_int16_t(packet->payload, 2)) ==
+ 2496)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1248,<-1248||2496");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return 1;
+ }
+ if (packet->payload_packet_len == 1448
+ && (flow->l4.tcp.irc_stage2 == 5 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) {
+ flow->l4.tcp.irc_stage2 = 11;
+ return 1;
+ }
+ if (packet->payload_packet_len == 4
+ && (flow->l4.tcp.irc_stage2 == 4 || flow->l4.tcp.irc_stage2 == 5 || flow->l4.tcp.irc_stage2 == 11
+ || flow->l4.tcp.irc_stage2 == 13)
+ && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 1448
+ || ntohs(get_u_int16_t(packet->payload, 2)) ==
+ 2896)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1448,<-1448||2896");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return 1;
+ }
+ /* case 4 : five packets with len = 1448, one with len 952, than one packet from other direction len = 8192 */
+ if (packet->payload_packet_len == 1448
+ && (flow->l4.tcp.irc_stage2 == 11 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) {
+ flow->l4.tcp.irc_stage2 = 12;
+ return 1;
+ }
+ if (packet->payload_packet_len == 1448
+ && (flow->l4.tcp.irc_stage2 == 12 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) {
+ flow->l4.tcp.irc_stage2 = 13;
+ return 1;
+ }
+ if (packet->payload_packet_len == 952
+ && (flow->l4.tcp.irc_stage2 == 13 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) {
+ flow->l4.tcp.irc_stage2 = 14;
+ return 1;
+ }
+ if (packet->payload_packet_len == 4
+ && flow->l4.tcp.irc_stage2 == 14
+ && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && ntohs(get_u_int16_t(packet->payload, 2)) == 8192) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "IRC SSL detected: ->1448,1448,1448,1448,1448,952,<-8192");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return 1;
+ }
+ /* case 5: len 1024, len 1448, len 1448, len 1200, len 1448, len 600 */
+ if (packet->payload_packet_len == 1448
+ && (flow->l4.tcp.irc_stage2 == 9 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) {
+ flow->l4.tcp.irc_stage2 = 15;
+ return 1;
+ }
+ if (packet->payload_packet_len == 1448
+ && (flow->l4.tcp.irc_stage2 == 15 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) {
+ flow->l4.tcp.irc_stage2 = 16;
+ return 1;
+ }
+ if (packet->payload_packet_len == 1200
+ && (flow->l4.tcp.irc_stage2 == 16 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) {
+ flow->l4.tcp.irc_stage2 = 17;
+ return 1;
+ }
+ if (packet->payload_packet_len == 1448
+ && (flow->l4.tcp.irc_stage2 == 17 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) {
+ flow->l4.tcp.irc_stage2 = 18;
+ return 1;
+ }
+ if (packet->payload_packet_len == 600
+ && (flow->l4.tcp.irc_stage2 == 18 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) {
+ flow->l4.tcp.irc_stage2 = 19;
+ return 1;
+ }
+ if (packet->payload_packet_len == 4
+ && flow->l4.tcp.irc_stage2 == 19
+ && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && ntohs(get_u_int16_t(packet->payload, 2)) == 7168) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "IRC SSL detected: ->1024,1448,1448,1200,1448,600,<-7168");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return 1;
+ }
+ /* -> 1024, 1380, -> 2404 */
+ if (packet->payload_packet_len == 1380
+ && (flow->l4.tcp.irc_stage2 == 9 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) {
+ flow->l4.tcp.irc_stage2 = 20;
+ return 1;
+ }
+ if (packet->payload_packet_len == 4
+ && flow->l4.tcp.irc_stage2 == 20
+ && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && ntohs(get_u_int16_t(packet->payload, 2)) == 2404) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1024,1380 <-2404");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return 1;
+
+ }
+ return 0;
+}
+
+
+void ndpi_search_irc_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+ int less;
+ u_int16_t c = 0;
+ u_int16_t c1 = 0;
+ u_int16_t port = 0;
+ u_int16_t sport = 0;
+ u_int16_t dport = 0;
+ u_int16_t counter = 0;
+ u_int16_t i = 0;
+ u_int16_t j = 0;
+ u_int16_t k = 0;
+ u_int16_t h;
+ u_int16_t http_content_ptr_len = 0;
+ u_int8_t space = 0;
+
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "irc : search irc\n");
+ if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && flow->packet_counter > 70) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "exclude irc, packet_counter > 70\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IRC);
+ return;
+ }
+ if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && flow->packet_counter > 30 &&
+ flow->l4.tcp.irc_stage2 == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "packet_counter > 30, exclude irc.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IRC);
+ return;
+ }
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_IRC) {
+ if (src != NULL && ((u_int32_t)
+ (packet->tick_timestamp - src->irc_ts) < ndpi_struct->irc_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "irc : save src connection packet detected\n");
+ src->irc_ts = packet->tick_timestamp;
+ } else if (dst != NULL && ((u_int32_t)
+ (packet->tick_timestamp - dst->irc_ts) < ndpi_struct->irc_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "irc : save dst connection packet detected\n");
+ dst->irc_ts = packet->tick_timestamp;
+ }
+ }
+
+ if (((dst != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_IRC)
+ && ((u_int32_t)
+ (packet->tick_timestamp - dst->irc_ts)) <
+ ndpi_struct->irc_timeout)) || (src != NULL
+ &&
+ NDPI_COMPARE_PROTOCOL_TO_BITMASK
+ (src->detected_protocol_bitmask, NDPI_PROTOCOL_IRC)
+ && ((u_int32_t)
+ (packet->tick_timestamp - src->irc_ts)) < ndpi_struct->irc_timeout)) {
+ if (packet->tcp != NULL) {
+ sport = packet->tcp->source;
+ dport = packet->tcp->dest;
+ }
+ if (dst != NULL) {
+ for (counter = 0; counter < dst->irc_number_of_port; counter++) {
+ if (dst->irc_port[counter] == sport || dst->irc_port[counter] == dport) {
+ dst->last_time_port_used[counter] = packet->tick_timestamp;
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "dest port matched with the DCC port and the flow is marked as IRC");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+ if (src != NULL) {
+ for (counter = 0; counter < src->irc_number_of_port; counter++) {
+ if (src->irc_port[counter] == sport || src->irc_port[counter] == dport) {
+ src->last_time_port_used[counter] = packet->tick_timestamp;
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "Source port matched with the DCC port and the flow is marked as IRC");
+ return;
+ }
+ }
+ }
+ }
+
+
+
+ if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC
+ && flow->packet_counter == 2 && (packet->payload_packet_len > 400 && packet->payload_packet_len < 1381)) {
+ for (c1 = 50; c1 < packet->payload_packet_len - 23; c1++) {
+ if (packet->payload[c1] == 'i' || packet->payload[c1] == 'd') {
+ if ((memcmp(&packet->payload[c1], "irc.hackthissite.org0", 21)
+ == 0)
+ || (memcmp(&packet->payload[c1], "irc.gamepad.ca1", 15) == 0)
+ || (memcmp(&packet->payload[c1], "dungeon.axenet.org0", 19)
+ == 0)
+ || (memcmp(&packet->payload[c1], "dazed.nuggethaus.net", 20)
+ == 0)
+ || (memcmp(&packet->payload[c1], "irc.indymedia.org", 17)
+ == 0)
+ || (memcmp(&packet->payload[c1], "irc.cccp-project.net", 20)
+ == 0)
+ || (memcmp(&packet->payload[c1], "dirc.followell.net0", 19)
+ == 0)
+ || (memcmp(&packet->payload[c1], "irc.discostars.de1", 18)
+ == 0)
+ || (memcmp(&packet->payload[c1], "irc.rizon.net", 13) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "IRC SSL detected with :- irc.hackthissite.org0 | irc.gamepad.ca1 | dungeon.axenet.org0 "
+ "| dazed.nuggethaus.net | irc.indymedia.org | irc.discostars.de1 ");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ break;
+ }
+ }
+ }
+ }
+ if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC &&
+ ndpi_search_irc_ssl_detect_ninty_percent_but_very_fast(ndpi_struct, flow) != 0) {
+ return;
+ }
+
+ if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && flow->packet_counter < 20
+ && packet->payload_packet_len >= 8) {
+ if (get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x0a
+ || (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0a00)) {
+ if (memcmp(packet->payload, ":", 1) == 0) {
+ if (packet->payload[packet->payload_packet_len - 2] != 0x0d
+ && packet->payload[packet->payload_packet_len - 1] == 0x0a) {
+ ndpi_parse_packet_line_info_any(ndpi_struct, flow);
+ } else if (packet->payload[packet->payload_packet_len - 2] == 0x0d) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ } else {
+ flow->l4.tcp.irc_3a_counter++;
+ }
+ for (i = 0; i < packet->parsed_lines; i++) {
+ if (packet->line[i].ptr[0] == ':') {
+ flow->l4.tcp.irc_3a_counter++;
+ if (flow->l4.tcp.irc_3a_counter == 7) { /* ':' == 0x3a */
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "0x3a. seven times. found irc.");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ goto detected_irc;
+ }
+ }
+ }
+ if (flow->l4.tcp.irc_3a_counter == 7) { /* ':' == 0x3a */
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "0x3a. seven times. found irc.");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ goto detected_irc;
+ }
+ }
+ if ((memcmp(packet->payload, "USER ", 5) == 0)
+ || (memcmp(packet->payload, "NICK ", 5) == 0)
+ || (memcmp(packet->payload, "PASS ", 5) == 0)
+ || (memcmp(packet->payload, ":", 1) == 0 && ndpi_check_for_NOTICE_or_PRIVMSG(ndpi_struct, flow) != 0)
+ || (memcmp(packet->payload, "PONG ", 5) == 0)
+ || (memcmp(packet->payload, "PING ", 5) == 0)
+ || (memcmp(packet->payload, "JOIN ", 5) == 0)
+ || (memcmp(packet->payload, "NOTICE ", 7) == 0)
+ || (memcmp(packet->payload, "PRIVMSG ", 8) == 0)
+ || (memcmp(packet->payload, "VERSION ", 8) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "USER, NICK, PASS, NOTICE, PRIVMSG one time");
+ if (flow->l4.tcp.irc_stage == 2) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "found irc");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ flow->l4.tcp.irc_stage = 3;
+ }
+ if (flow->l4.tcp.irc_stage == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "second time, stage=2");
+ flow->l4.tcp.irc_stage = 2;
+ }
+ if (flow->l4.tcp.irc_stage == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "first time, stage=1");
+ flow->l4.tcp.irc_stage = 1;
+ }
+ /* irc packets can have either windows line breaks (0d0a) or unix line breaks (0a) */
+ if (packet->payload[packet->payload_packet_len - 2] == 0x0d
+ && packet->payload[packet->payload_packet_len - 1] == 0x0a) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->parsed_lines > 1) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "packet contains more than one line");
+ for (c = 1; c < packet->parsed_lines; c++) {
+ if (packet->line[c].len > 4 && (memcmp(packet->line[c].ptr, "NICK ", 5) == 0
+ || memcmp(packet->line[c].ptr, "USER ", 5) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct,
+ NDPI_LOG_TRACE, "two icq signal words in the same packet");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ flow->l4.tcp.irc_stage = 3;
+ return;
+ }
+ }
+ }
+
+ } else if (packet->payload[packet->payload_packet_len - 1] == 0x0a) {
+ ndpi_parse_packet_line_info_any(ndpi_struct, flow);
+ if (packet->parsed_lines > 1) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "packet contains more than one line");
+ for (c = 1; c < packet->parsed_lines; c++) {
+ if (packet->line[c].len > 4 && (memcmp(packet->line[c].ptr, "NICK ", 5) == 0
+ || memcmp(packet->line[c].ptr, "USER ",
+ 5) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "two icq signal words in the same packet");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ flow->l4.tcp.irc_stage = 3;
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Trying to primarily detect the HTTP Web based IRC chat patterns based on the HTTP headers
+ * during the User login time.When the HTTP data gets posted using the POST method ,patterns
+ * will be searched in the HTTP content.
+ */
+ if ((flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC) && (flow->l4.tcp.irc_stage == 0)
+ && (packet->payload_packet_len > 5)) {
+ //HTTP POST Method being employed
+ if (memcmp(packet->payload, "POST ", 5) == 0) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->parsed_lines) {
+ u_int16_t http_header_len = (packet->line[packet->parsed_lines - 1].ptr - packet->payload) + 2;
+ if (packet->payload_packet_len > http_header_len) {
+ http_content_ptr_len = packet->payload_packet_len - http_header_len;
+ }
+ if ((ndpi_check_for_IRC_traces(packet->line[0].ptr, packet->line[0].len))
+ || ((packet->http_url_name.ptr)
+ && (ndpi_check_for_IRC_traces(packet->http_url_name.ptr, packet->http_url_name.len)))
+ || ((packet->referer_line.ptr)
+ && (ndpi_check_for_IRC_traces(packet->referer_line.ptr, packet->referer_line.len)))) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "IRC detected from the Http URL/ Referer header ");
+ flow->l4.tcp.irc_stage = 1;
+ // HTTP POST Request body is not in the same packet.
+ if (!http_content_ptr_len) {
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ if ((flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC) && (flow->l4.tcp.irc_stage == 1)) {
+ if ((((packet->payload_packet_len - http_content_ptr_len) > 10)
+ && (memcmp(packet->payload + http_content_ptr_len, "interface=", 10) == 0)
+ && (ndpi_check_for_Nickname(ndpi_struct, flow) != 0))
+ || (((packet->payload_packet_len - http_content_ptr_len) > 5)
+ && (memcmp(packet->payload + http_content_ptr_len, "item=", 5) == 0)
+ && (ndpi_check_for_cmd(ndpi_struct, flow) != 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC Nickname, cmd, one time");
+ ndpi_int_irc_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ detected_irc:
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "detected_irc:");
+
+ if (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_IRC) {
+ /* maybe this can be deleted at the end */
+
+ if (packet->payload[packet->payload_packet_len - 2] != 0x0d
+ && packet->payload[packet->payload_packet_len - 1] == 0x0a) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG,
+ "ndpi_parse_packet_line_info_any(ndpi_struct, flow);");
+ ndpi_parse_packet_line_info_any(ndpi_struct, flow);
+ } else if (packet->payload[packet->payload_packet_len - 2] == 0x0d) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ } else {
+ return;
+ }
+ for (i = 0; i < packet->parsed_lines; i++) {
+ if (packet->line[i].len > 6 && memcmp(packet->line[i].ptr, "NOTICE ", 7) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "NOTICE");
+ for (j = 7; j < packet->line[i].len - 8; j++) {
+ if (packet->line[i].ptr[j] == ':') {
+ if (memcmp(&packet->line[i].ptr[j + 1], "DCC SEND ", 9) == 0
+ || memcmp(&packet->line[i].ptr[j + 1], "DCC CHAT ", 9) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "found NOTICE and DCC CHAT or DCC SEND.");
+ }
+ }
+ }
+ }
+ if (packet->payload_packet_len > 0 && packet->payload[0] == 0x3a /* 0x3a = ':' */ ) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "3a");
+ for (j = 1; j < packet->line[i].len - 9; j++) {
+ if (packet->line[i].ptr[j] == ' ') {
+ j++;
+ if (packet->line[i].ptr[j] == 'P') {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "P");
+ j++;
+ if (memcmp(&packet->line[i].ptr[j], "RIVMSG ", 7) == 0)
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "RIVMSG");
+ h = j + 7;
+ goto read_privmsg;
+ }
+ }
+ }
+ }
+ if (packet->line[i].len > 7 && (memcmp(packet->line[i].ptr, "PRIVMSG ", 8) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "PRIVMSG ");
+ h = 7;
+ read_privmsg:
+ for (j = h; j < packet->line[i].len - 9; j++) {
+ if (packet->line[i].ptr[j] == ':') {
+ if (memcmp(&packet->line[i].ptr[j + 1], "xdcc ", 5) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "xdcc should match.");
+ }
+ j += 2;
+ if (memcmp(&packet->line[i].ptr[j], "DCC ", 4) == 0) {
+ j += 4;
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "found DCC.");
+ if (memcmp(&packet->line[i].ptr[j], "SEND ", 5) == 0
+ || (memcmp(&packet->line[i].ptr[j], "CHAT", 4) == 0)
+ || (memcmp(&packet->line[i].ptr[j], "chat", 4) == 0)
+ || (memcmp(&packet->line[i].ptr[j], "sslchat", 7) == 0)
+ || (memcmp(&packet->line[i].ptr[j], "TSEND", 5) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "found CHAT,chat,sslchat,TSEND.");
+ j += 4;
+
+ while (packet->line[i].len > j &&
+ ((packet->line[i].ptr[j] >= 'a' && packet->line[i].ptr[j] <= 'z')
+ || (packet->line[i].ptr[j] >= 'A' && packet->line[i].ptr[j] <= 'Z')
+ || (packet->line[i].ptr[j] >= '0' && packet->line[i].ptr[j] <= '9')
+ || (packet->line[i].ptr[j] >= ' ')
+ || (packet->line[i].ptr[j] >= '.')
+ || (packet->line[i].ptr[j] >= '-'))) {
+
+ if (packet->line[i].ptr[j] == ' ') {
+ space++;
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "space %u.", space);
+ }
+ if (space == 3) {
+ j++;
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "read port.");
+ if (src != NULL) {
+ k = j;
+ port =
+ ntohs_ndpi_bytestream_to_number
+ (&packet->line[i].ptr[j], packet->payload_packet_len - j, &j);
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "port %u.",
+ port);
+ j = k;
+ // hier jetzt überlegen, wie die ports abgespeichert werden sollen
+ if (src->irc_number_of_port < NDPI_PROTOCOL_IRC_MAXPORT)
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE,
+ "src->irc_number_of_port < NDPI_PROTOCOL_IRC_MAXPORT.");
+ if (src->irc_number_of_port < NDPI_PROTOCOL_IRC_MAXPORT && port != 0) {
+ if (!ndpi_is_duplicate(src, port)) {
+ src->irc_port[src->irc_number_of_port]
+ = port;
+ src->irc_number_of_port++;
+ NDPI_LOG
+ (NDPI_PROTOCOL_IRC,
+ ndpi_struct,
+ NDPI_LOG_DEBUG, "found port=%d",
+ ntohs(get_u_int16_t(src->irc_port, 0)));
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG,
+ "jjeeeeeeeeeeeeeeeeeeeeeeeee");
+ }
+ src->irc_ts = packet->tick_timestamp;
+ } else if (port != 0 && src->irc_number_of_port == NDPI_PROTOCOL_IRC_MAXPORT) {
+ if (!ndpi_is_duplicate(src, port)) {
+ less = 0;
+ NDPI_IRC_FIND_LESS(src->last_time_port_used, less);
+ src->irc_port[less] = port;
+ NDPI_LOG
+ (NDPI_PROTOCOL_IRC,
+ ndpi_struct,
+ NDPI_LOG_DEBUG, "found port=%d",
+ ntohs(get_u_int16_t(src->irc_port, 0)));
+ }
+ src->irc_ts = packet->tick_timestamp;
+ }
+ if (dst == NULL) {
+ break;
+ }
+ }
+ if (dst != NULL) {
+ port = ntohs_ndpi_bytestream_to_number
+ (&packet->line[i].ptr[j], packet->payload_packet_len - j, &j);
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "port %u.",
+ port);
+ // hier das gleiche wie oben.
+ /* hier werden NDPI_PROTOCOL_IRC_MAXPORT ports pro irc flows mitgespeichert. könnte man denn nicht ein-
+ * fach an die dst oder src einen flag setzten, dass dieser port für eine bestimmte
+ * zeit ein irc-port bleibt?
+ */
+ if (dst->irc_number_of_port < NDPI_PROTOCOL_IRC_MAXPORT && port != 0) {
+ if (!ndpi_is_duplicate(dst, port)) {
+ dst->irc_port[dst->irc_number_of_port]
+ = port;
+ dst->irc_number_of_port++;
+ NDPI_LOG
+ (NDPI_PROTOCOL_IRC,
+ ndpi_struct,
+ NDPI_LOG_DEBUG, "found port=%d",
+ ntohs(get_u_int16_t(dst->irc_port, 0)));
+ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG,
+ "juuuuuuuuuuuuuuuu");
+ }
+ dst->irc_ts = packet->tick_timestamp;
+ } else if (port != 0 && dst->irc_number_of_port == NDPI_PROTOCOL_IRC_MAXPORT) {
+ if (!ndpi_is_duplicate(dst, port)) {
+ less = 0;
+ NDPI_IRC_FIND_LESS(dst->last_time_port_used, less);
+ dst->irc_port[less] = port;
+
+ NDPI_LOG
+ (NDPI_PROTOCOL_IRC,
+ ndpi_struct,
+ NDPI_LOG_DEBUG, "found port=%d",
+ ntohs(get_u_int16_t(dst->irc_port, 0)));
+ }
+ dst->irc_ts = packet->tick_timestamp;
+ }
+
+ break;
+ }
+ }
+
+
+ j++;
+ }
+
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/jabber.c b/src/lib/protocols/jabber.c
new file mode 100644
index 000000000..7b78febb1
--- /dev/null
+++ b/src/lib/protocols/jabber.c
@@ -0,0 +1,311 @@
+/*
+ * jabber.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER
+struct jabber_string {
+ char *string;
+ u_int ndpi_protocol;
+};
+
+static struct jabber_string jabber_strings[] = {
+#ifdef NDPI_PROTOCOL_TRUPHONE
+ { "='im.truphone.com'", NDPI_PROTOCOL_TRUPHONE },
+ { "=\"im.truphone.com\"", NDPI_PROTOCOL_TRUPHONE },
+#endif
+
+#ifdef NDPI_SERVICE_FACEBOOK_CHAT
+ { "to='chat.facebook.com'", NDPI_SERVICE_FACEBOOK_CHAT },
+#endif
+ { NULL, 0 }
+};
+
+static void ndpi_int_jabber_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int32_t protocol, ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, protocol, protocol_type);
+}
+
+static void check_content_type_and_change_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, u_int16_t x)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ int i, left = packet->payload_packet_len-x;
+
+ if(left <= 0) return;
+
+ for(i=0; jabber_strings[i].string != NULL; i++) {
+ if(ndpi_strnstr((const char*)&packet->payload[x], jabber_strings[i].string, left) != NULL) {
+ ndpi_int_jabber_add_connection(ndpi_struct, flow, jabber_strings[i].ndpi_protocol, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+}
+
+void ndpi_search_jabber_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ u_int16_t x;
+
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_TRACE, "JABBER detection....\n");
+
+ /* search for jabber file transfer */
+ /* this part is working asymmetrically */
+ if (packet->tcp != NULL && packet->tcp->syn != 0 && packet->payload_packet_len == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "check jabber syn\n");
+ if (src != NULL && src->jabber_file_transfer_port[0] != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
+ "src jabber ft port set, ports are: %u, %u\n", ntohs(src->jabber_file_transfer_port[0]),
+ ntohs(src->jabber_file_transfer_port[1]));
+ if (((u_int32_t)
+ (packet->tick_timestamp - src->jabber_stun_or_ft_ts)) >= ndpi_struct->jabber_file_transfer_timeout) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
+ NDPI_LOG_DEBUG, "JABBER src stun timeout %u %u\n", src->jabber_stun_or_ft_ts,
+ packet->tick_timestamp);
+ src->jabber_file_transfer_port[0] = 0;
+ src->jabber_file_transfer_port[1] = 0;
+ } else if (src->jabber_file_transfer_port[0] == packet->tcp->dest
+ || src->jabber_file_transfer_port[0] == packet->tcp->source
+ || src->jabber_file_transfer_port[1] == packet->tcp->dest
+ || src->jabber_file_transfer_port[1] == packet->tcp->source) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
+ "found jabber file transfer.\n");
+
+ ndpi_int_jabber_add_connection(ndpi_struct, flow,
+ NDPI_PROTOCOL_UNENCRYPED_JABBER, NDPI_CORRELATED_PROTOCOL);
+ }
+ }
+ if (dst != NULL && dst->jabber_file_transfer_port[0] != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
+ "dst jabber ft port set, ports are: %u, %u\n", ntohs(dst->jabber_file_transfer_port[0]),
+ ntohs(dst->jabber_file_transfer_port[1]));
+ if (((u_int32_t)
+ (packet->tick_timestamp - dst->jabber_stun_or_ft_ts)) >= ndpi_struct->jabber_file_transfer_timeout) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
+ NDPI_LOG_DEBUG, "JABBER dst stun timeout %u %u\n", dst->jabber_stun_or_ft_ts,
+ packet->tick_timestamp);
+ dst->jabber_file_transfer_port[0] = 0;
+ dst->jabber_file_transfer_port[1] = 0;
+ } else if (dst->jabber_file_transfer_port[0] == packet->tcp->dest
+ || dst->jabber_file_transfer_port[0] == packet->tcp->source
+ || dst->jabber_file_transfer_port[1] == packet->tcp->dest
+ || dst->jabber_file_transfer_port[1] == packet->tcp->source) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
+ "found jabber file transfer.\n");
+
+ ndpi_int_jabber_add_connection(ndpi_struct, flow,
+ NDPI_PROTOCOL_UNENCRYPED_JABBER, NDPI_CORRELATED_PROTOCOL);
+ }
+ }
+ return;
+ }
+
+ if (packet->tcp != 0 && packet->payload_packet_len == 0) {
+ return;
+ }
+
+
+ /* this part parses a packet and searches for port=. it works asymmetrically. */
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNENCRYPED_JABBER) {
+ u_int16_t lastlen;
+ u_int16_t j_port = 0;
+ /* check for google jabber voip connections ... */
+ /* need big packet */
+ if (packet->payload_packet_len < 100) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "packet too small, return.\n");
+ return;
+ }
+ /* need message to or type for file-transfer */
+ if (memcmp(packet->payload, "<iq from=\"", 8) == 0 || memcmp(packet->payload, "<iq from=\'", 8) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER <iq from=\".\n");
+ lastlen = packet->payload_packet_len - 11;
+ for (x = 10; x < lastlen; x++) {
+ if (packet->payload[x] == 'p') {
+ if (memcmp(&packet->payload[x], "port=", 5) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "port=\n");
+ if (src != NULL) {
+ src->jabber_stun_or_ft_ts = packet->tick_timestamp;
+ }
+
+ if (dst != NULL) {
+ dst->jabber_stun_or_ft_ts = packet->tick_timestamp;
+ }
+ x += 6;
+ j_port = ntohs_ndpi_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x);
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
+ NDPI_LOG_DEBUG, "JABBER port : %u\n", ntohs(j_port));
+ if (src != NULL) {
+ if (src->jabber_file_transfer_port[0] == 0 || src->jabber_file_transfer_port[0] == j_port) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
+ NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[0] = j_port = %u;\n",
+ ntohs(j_port));
+ src->jabber_file_transfer_port[0] = j_port;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
+ NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[1] = j_port = %u;\n",
+ ntohs(j_port));
+ src->jabber_file_transfer_port[1] = j_port;
+ }
+ }
+ if (dst != NULL) {
+ if (dst->jabber_file_transfer_port[0] == 0 || dst->jabber_file_transfer_port[0] == j_port) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
+ NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[0] = j_port = %u;\n",
+ ntohs(j_port));
+ dst->jabber_file_transfer_port[0] = j_port;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
+ NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[1] = j_port = %u;\n",
+ ntohs(j_port));
+ dst->jabber_file_transfer_port[1] = j_port;
+ }
+ }
+ }
+
+
+ }
+ }
+
+ } else if (memcmp(packet->payload, "<iq to=\"", 8) == 0 || memcmp(packet->payload, "<iq to=\'", 8) == 0
+ || memcmp(packet->payload, "<iq type=", 9) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER <iq to=\"/type=\"\n");
+ lastlen = packet->payload_packet_len - 21;
+ for (x = 8; x < lastlen; x++) {
+ /* invalid character */
+ if (packet->payload[x] < 32 || packet->payload[x] > 127) {
+ return;
+ }
+ if (packet->payload[x] == '@') {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER @\n");
+ break;
+ }
+ }
+ if (x >= lastlen) {
+ return;
+ }
+
+ lastlen = packet->payload_packet_len - 10;
+ for (; x < lastlen; x++) {
+ if (packet->payload[x] == 'p') {
+ if (memcmp(&packet->payload[x], "port=", 5) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "port=\n");
+ if (src != NULL) {
+ src->jabber_stun_or_ft_ts = packet->tick_timestamp;
+ }
+
+ if (dst != NULL) {
+ dst->jabber_stun_or_ft_ts = packet->tick_timestamp;
+ }
+
+ x += 6;
+ j_port = ntohs_ndpi_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x);
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
+ NDPI_LOG_DEBUG, "JABBER port : %u\n", ntohs(j_port));
+
+ if (src != NULL && src->jabber_voice_stun_used_ports < JABBER_MAX_STUN_PORTS - 1) {
+ if (packet->payload[5] == 'o') {
+ src->jabber_voice_stun_port[src->jabber_voice_stun_used_ports++]
+ = j_port;
+ } else {
+ if (src->jabber_file_transfer_port[0] == 0
+ || src->jabber_file_transfer_port[0] == j_port) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
+ "src->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port));
+ src->jabber_file_transfer_port[0] = j_port;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
+ NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[1] = j_port = %u;\n",
+ ntohs(j_port));
+ src->jabber_file_transfer_port[1] = j_port;
+ }
+ }
+ }
+
+ if (dst != NULL && dst->jabber_voice_stun_used_ports < JABBER_MAX_STUN_PORTS - 1) {
+ if (packet->payload[5] == 'o') {
+ dst->jabber_voice_stun_port[dst->jabber_voice_stun_used_ports++]
+ = j_port;
+ } else {
+ if (dst->jabber_file_transfer_port[0] == 0
+ || dst->jabber_file_transfer_port[0] == j_port) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
+ "dst->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port));
+ dst->jabber_file_transfer_port[0] = j_port;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
+ NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[1] = j_port = %u;\n",
+ ntohs(j_port));
+ dst->jabber_file_transfer_port[1] = j_port;
+ }
+ }
+ }
+ return;
+ }
+ }
+ }
+ }
+ return;
+ }
+
+
+ /* search for jabber here */
+ /* this part is working asymmetrically */
+ if ((packet->payload_packet_len > 13 && memcmp(packet->payload, "<?xml version=", 14) == 0)
+ || (packet->payload_packet_len >= NDPI_STATICSTRING_LEN("<stream:stream ")
+ && memcmp(packet->payload, "<stream:stream ", NDPI_STATICSTRING_LEN("<stream:stream ")) == 0)) {
+ int start = packet->payload_packet_len-13;
+
+ if(ndpi_strnstr((const char *)&packet->payload[13], "xmlns:stream='http://etherx.jabber.org/streams'", start)
+ || ndpi_strnstr((const char *)&packet->payload[13], "xmlns:stream=\"http://etherx.jabber.org/streams\"", start)) {
+
+ /* Protocol family */
+ ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER, NDPI_REAL_PROTOCOL);
+
+ /* search for subprotocols */
+ check_content_type_and_change_protocol(ndpi_struct, flow, 13);
+ return;
+ }
+ }
+
+ if (flow->packet_counter < 3) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
+ NDPI_LOG_DEBUG, "packet_counter: %u\n", flow->packet_counter);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_TRACE, "JABBER Excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER);
+
+#ifdef NDPI_PROTOCOL_TRUPHONE
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TRUPHONE);
+#endif
+}
+
+#endif
diff --git a/src/lib/protocols/kerberos.c b/src/lib/protocols/kerberos.c
new file mode 100644
index 000000000..b04265fc5
--- /dev/null
+++ b/src/lib/protocols/kerberos.c
@@ -0,0 +1,82 @@
+/*
+ * kerberos.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+/* include files */
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_KERBEROS
+
+static void ndpi_int_kerberos_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_KERBEROS, NDPI_REAL_PROTOCOL);
+}
+
+
+void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ /* I have observed 0a,0c,0d,0e at packet->payload[19/21], maybe there are other possibilities */
+ if (packet->payload_packet_len >= 4 && ntohl(get_u_int32_t(packet->payload, 0)) == packet->payload_packet_len - 4) {
+ if (packet->payload_packet_len > 19 &&
+ packet->payload[14] == 0x05 &&
+ (packet->payload[19] == 0x0a ||
+ packet->payload[19] == 0x0c || packet->payload[19] == 0x0d || packet->payload[19] == 0x0e)) {
+ NDPI_LOG(NDPI_PROTOCOL_KERBEROS, ndpi_struct, NDPI_LOG_DEBUG, "found KERBEROS\n");
+ ndpi_int_kerberos_add_connection(ndpi_struct, flow);
+ return;
+
+ }
+ if (packet->payload_packet_len > 21 &&
+ packet->payload[16] == 0x05 &&
+ (packet->payload[21] == 0x0a ||
+ packet->payload[21] == 0x0c || packet->payload[21] == 0x0d || packet->payload[21] == 0x0e)) {
+ NDPI_LOG(NDPI_PROTOCOL_KERBEROS, ndpi_struct, NDPI_LOG_DEBUG, "found KERBEROS\n");
+ ndpi_int_kerberos_add_connection(ndpi_struct, flow);
+ return;
+
+ }
+
+
+
+ }
+
+
+
+
+
+
+
+
+ NDPI_LOG(NDPI_PROTOCOL_KERBEROS, ndpi_struct, NDPI_LOG_DEBUG, "no KERBEROS detected.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_KERBEROS);
+}
+
+#endif
diff --git a/src/lib/protocols/kontiki.c b/src/lib/protocols/kontiki.c
new file mode 100644
index 000000000..72ba1acab
--- /dev/null
+++ b/src/lib/protocols/kontiki.c
@@ -0,0 +1,65 @@
+/*
+ * kontiki.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_KONTIKI
+
+static void ndpi_int_kontiki_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_KONTIKI, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_kontiki(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ if (packet->payload_packet_len == 4 && (get_u_int32_t(packet->payload, 0) == htonl(0x02010100))) {
+ NDPI_LOG(NDPI_PROTOCOL_KONTIKI, ndpi_struct, NDPI_LOG_DEBUG, "Kontiki UDP detected.\n");
+ ndpi_int_kontiki_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len > 0 && packet->payload[0] == 0x02) {
+
+ if (packet->payload_packet_len == 20 && (get_u_int32_t(packet->payload, 16) == htonl(0x02040100))) {
+ NDPI_LOG(NDPI_PROTOCOL_KONTIKI, ndpi_struct, NDPI_LOG_DEBUG, "Kontiki UDP detected.\n");
+ ndpi_int_kontiki_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len == 16 && (get_u_int32_t(packet->payload, 12) == htonl(0x000004e4))) {
+ NDPI_LOG(NDPI_PROTOCOL_KONTIKI, ndpi_struct, NDPI_LOG_DEBUG, "Kontiki UDP detected.\n");
+ ndpi_int_kontiki_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_KONTIKI);
+}
+
+#endif
diff --git a/src/lib/protocols/ldap.c b/src/lib/protocols/ldap.c
new file mode 100644
index 000000000..44313156e
--- /dev/null
+++ b/src/lib/protocols/ldap.c
@@ -0,0 +1,101 @@
+/*
+ * ldap.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+/* include files */
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_LDAP
+
+static void ndpi_int_ldap_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_LDAP, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_ldap(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+// u_int16_t dport;
+
+
+
+ NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "search ldap\n");
+
+
+ if (packet->payload_packet_len >= 14 && packet->payload[0] == 0x30) {
+
+ // simple type
+ if (packet->payload[1] == 0x0c && packet->payload_packet_len == 14 &&
+ packet->payload[packet->payload_packet_len - 1] == 0x00 && packet->payload[2] == 0x02) {
+
+ if (packet->payload[3] == 0x01 &&
+ (packet->payload[5] == 0x60 || packet->payload[5] == 0x61) && packet->payload[6] == 0x07) {
+ NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "found ldap simple type 1\n");
+ ndpi_int_ldap_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ if (packet->payload[3] == 0x02 &&
+ (packet->payload[6] == 0x60 || packet->payload[6] == 0x61) && packet->payload[7] == 0x07) {
+ NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "found ldap simple type 2\n");
+ ndpi_int_ldap_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ // normal type
+ if (packet->payload[1] == 0x84 && packet->payload_packet_len >= 0x84 &&
+ packet->payload[2] == 0x00 && packet->payload[3] == 0x00 && packet->payload[6] == 0x02) {
+
+ if (packet->payload[7] == 0x01 &&
+ (packet->payload[9] == 0x60 || packet->payload[9] == 0x61 || packet->payload[9] == 0x63 ||
+ packet->payload[9] == 0x64) && packet->payload[10] == 0x84) {
+
+ NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "found ldap type 1\n");
+ ndpi_int_ldap_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ if (packet->payload[7] == 0x02 &&
+ (packet->payload[10] == 0x60 || packet->payload[10] == 0x61 || packet->payload[10] == 0x63 ||
+ packet->payload[10] == 0x64) && packet->payload[11] == 0x84) {
+
+ NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "found ldap type 2\n");
+ ndpi_int_ldap_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+
+
+ NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "ldap excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_LDAP);
+}
+
+#endif
diff --git a/src/lib/protocols/lotus_notes.c b/src/lib/protocols/lotus_notes.c
new file mode 100644
index 000000000..6294bce20
--- /dev/null
+++ b/src/lib/protocols/lotus_notes.c
@@ -0,0 +1,87 @@
+/*
+ * lotus_notes.c
+ *
+ * Copyright (C) 2012-15 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_LOTUS_NOTES
+
+/* ************************************ */
+
+static void ndpi_check_lotus_notes(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // const u_int8_t *packet_payload = packet->payload;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ if(packet->tcp != NULL) {
+ flow->l4.tcp.lotus_notes_packet_id++;
+
+#if 0
+ printf("[lotus_notes_packet_id: %u][len=%u][%02X %02X %02X %02X %02X %02X %02X %02X]\n",
+ flow->l4.tcp.lotus_notes_packet_id, payload_len,
+ packet->payload[6] & 0xFF,
+ packet->payload[7] & 0xFF,
+ packet->payload[8] & 0xFF,
+ packet->payload[9] & 0xFF,
+ packet->payload[10] & 0xFF,
+ packet->payload[11] & 0xFF,
+ packet->payload[12] & 0xFF,
+ packet->payload[13] & 0xFF
+ );
+#endif
+
+ if((flow->l4.tcp.lotus_notes_packet_id == 1)
+ /* We have seen the 3-way handshake */
+ && flow->l4.tcp.seen_syn
+ && flow->l4.tcp.seen_syn_ack
+ && flow->l4.tcp.seen_ack) {
+ if(payload_len > 16) {
+ char lotus_notes_header[] = { 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0x02, 0x0F };
+
+ if(memcmp(&packet->payload[6], lotus_notes_header, sizeof(lotus_notes_header)) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_LOTUS_NOTES, ndpi_struct, NDPI_LOG_DEBUG, "Found lotus_notes.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_LOTUS_NOTES, NDPI_REAL_PROTOCOL);
+ }
+
+ return;
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_LOTUS_NOTES);
+ } else if(flow->l4.tcp.lotus_notes_packet_id > 3)
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_LOTUS_NOTES);
+
+ return;
+ }
+}
+
+void ndpi_search_lotus_notes(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_LOTUS_NOTES, ndpi_struct, NDPI_LOG_DEBUG, "lotus_notes detection...\n");
+
+ /* skip marked packets */
+ if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_LOTUS_NOTES)
+ ndpi_check_lotus_notes(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/mail_imap.c b/src/lib/protocols/mail_imap.c
new file mode 100644
index 000000000..11a02a8f5
--- /dev/null
+++ b/src/lib/protocols/mail_imap.c
@@ -0,0 +1,293 @@
+/*
+ * mail_imap.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_MAIL_IMAP
+
+static void ndpi_int_mail_imap_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_IMAP, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t i = 0;
+ u_int16_t space_pos = 0;
+ u_int16_t command_start = 0;
+ u_int8_t saw_command = 0;
+ /* const u_int8_t *command = 0; */
+
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "search IMAP.\n");
+
+ if (packet->payload_packet_len >= 4 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) {
+ // the DONE command appears without a tag
+ if (packet->payload_packet_len == 6 && ((packet->payload[0] == 'D' || packet->payload[0] == 'd')
+ && (packet->payload[1] == 'O' || packet->payload[1] == 'o')
+ && (packet->payload[2] == 'N' || packet->payload[2] == 'n')
+ && (packet->payload[3] == 'E' || packet->payload[3] == 'e'))) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ } else {
+
+ if (flow->l4.tcp.mail_imap_stage < 4) {
+ // search for the first space character (end of the tag)
+ while (i < 20 && i < packet->payload_packet_len) {
+ if (i > 0 && packet->payload[i] == ' ') {
+ space_pos = i;
+ break;
+ }
+ if (!((packet->payload[i] >= 'a' && packet->payload[i] <= 'z') ||
+ (packet->payload[i] >= 'A' && packet->payload[i] <= 'Z') ||
+ (packet->payload[i] >= '0' && packet->payload[i] <= '9') || packet->payload[i] == '*')) {
+ goto imap_excluded;
+ }
+ i++;
+ }
+ if (space_pos == 0 || space_pos == (packet->payload_packet_len - 1)) {
+ goto imap_excluded;
+ }
+ // now walk over a possible mail number to the next space
+ i++;
+ if (i < packet->payload_packet_len && (packet->payload[i] >= '0' && packet->payload[i] <= '9')) {
+ while (i < 20 && i < packet->payload_packet_len) {
+ if (i > 0 && packet->payload[i] == ' ') {
+ space_pos = i;
+ break;
+ }
+ if (!(packet->payload[i] >= '0' && packet->payload[i] <= '9')) {
+ goto imap_excluded;
+ }
+ i++;
+ }
+ if (space_pos == 0 || space_pos == (packet->payload_packet_len - 1)) {
+ goto imap_excluded;
+ }
+ }
+ command_start = space_pos + 1;
+ /* command = &(packet->payload[command_start]); */
+ } else {
+ command_start = 0;
+ /* command = &(packet->payload[command_start]); */
+ }
+
+ if ((command_start + 3) < packet->payload_packet_len) {
+ if ((packet->payload[command_start] == 'O' || packet->payload[command_start] == 'o')
+ && (packet->payload[command_start + 1] == 'K' || packet->payload[command_start + 1] == 'k')
+ && packet->payload[command_start + 2] == ' ') {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ } else if ((packet->payload[command_start] == 'U' || packet->payload[command_start] == 'u')
+ && (packet->payload[command_start + 1] == 'I' || packet->payload[command_start + 1] == 'i')
+ && (packet->payload[command_start + 2] == 'D' || packet->payload[command_start + 2] == 'd')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ }
+ }
+ if ((command_start + 10) < packet->payload_packet_len) {
+ if ((packet->payload[command_start] == 'C' || packet->payload[command_start] == 'c')
+ && (packet->payload[command_start + 1] == 'A' || packet->payload[command_start + 1] == 'a')
+ && (packet->payload[command_start + 2] == 'P' || packet->payload[command_start + 2] == 'p')
+ && (packet->payload[command_start + 3] == 'A' || packet->payload[command_start + 3] == 'a')
+ && (packet->payload[command_start + 4] == 'B' || packet->payload[command_start + 4] == 'b')
+ && (packet->payload[command_start + 5] == 'I' || packet->payload[command_start + 5] == 'i')
+ && (packet->payload[command_start + 6] == 'L' || packet->payload[command_start + 6] == 'l')
+ && (packet->payload[command_start + 7] == 'I' || packet->payload[command_start + 7] == 'i')
+ && (packet->payload[command_start + 8] == 'T' || packet->payload[command_start + 8] == 't')
+ && (packet->payload[command_start + 9] == 'Y' || packet->payload[command_start + 9] == 'y')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ }
+ }
+ if ((command_start + 8) < packet->payload_packet_len) {
+ if ((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's')
+ && (packet->payload[command_start + 1] == 'T' || packet->payload[command_start + 1] == 't')
+ && (packet->payload[command_start + 2] == 'A' || packet->payload[command_start + 2] == 'a')
+ && (packet->payload[command_start + 3] == 'R' || packet->payload[command_start + 3] == 'r')
+ && (packet->payload[command_start + 4] == 'T' || packet->payload[command_start + 4] == 't')
+ && (packet->payload[command_start + 5] == 'T' || packet->payload[command_start + 5] == 't')
+ && (packet->payload[command_start + 6] == 'L' || packet->payload[command_start + 6] == 'l')
+ && (packet->payload[command_start + 7] == 'S' || packet->payload[command_start + 7] == 's')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ }
+ }
+ if ((command_start + 5) < packet->payload_packet_len) {
+ if ((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l')
+ && (packet->payload[command_start + 1] == 'O' || packet->payload[command_start + 1] == 'o')
+ && (packet->payload[command_start + 2] == 'G' || packet->payload[command_start + 2] == 'g')
+ && (packet->payload[command_start + 3] == 'I' || packet->payload[command_start + 3] == 'i')
+ && (packet->payload[command_start + 4] == 'N' || packet->payload[command_start + 4] == 'n')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ } else if ((packet->payload[command_start] == 'F' || packet->payload[command_start] == 'f')
+ && (packet->payload[command_start + 1] == 'E' || packet->payload[command_start + 1] == 'e')
+ && (packet->payload[command_start + 2] == 'T' || packet->payload[command_start + 2] == 't')
+ && (packet->payload[command_start + 3] == 'C' || packet->payload[command_start + 3] == 'c')
+ && (packet->payload[command_start + 4] == 'H' || packet->payload[command_start + 4] == 'h')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ } else if ((packet->payload[command_start] == 'F' || packet->payload[command_start] == 'f')
+ && (packet->payload[command_start + 1] == 'L' || packet->payload[command_start + 1] == 'l')
+ && (packet->payload[command_start + 2] == 'A' || packet->payload[command_start + 2] == 'a')
+ && (packet->payload[command_start + 3] == 'G' || packet->payload[command_start + 3] == 'g')
+ && (packet->payload[command_start + 4] == 'S' || packet->payload[command_start + 4] == 's')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ } else if ((packet->payload[command_start] == 'C' || packet->payload[command_start] == 'c')
+ && (packet->payload[command_start + 1] == 'H' || packet->payload[command_start + 1] == 'h')
+ && (packet->payload[command_start + 2] == 'E' || packet->payload[command_start + 2] == 'e')
+ && (packet->payload[command_start + 3] == 'C' || packet->payload[command_start + 3] == 'c')
+ && (packet->payload[command_start + 4] == 'K' || packet->payload[command_start + 4] == 'k')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ } else if ((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's')
+ && (packet->payload[command_start + 1] == 'T' || packet->payload[command_start + 1] == 't')
+ && (packet->payload[command_start + 2] == 'O' || packet->payload[command_start + 2] == 'o')
+ && (packet->payload[command_start + 3] == 'R' || packet->payload[command_start + 3] == 'r')
+ && (packet->payload[command_start + 4] == 'E' || packet->payload[command_start + 4] == 'e')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ }
+ }
+ if ((command_start + 12) < packet->payload_packet_len) {
+ if ((packet->payload[command_start] == 'A' || packet->payload[command_start] == 'a')
+ && (packet->payload[command_start + 1] == 'U' || packet->payload[command_start + 1] == 'u')
+ && (packet->payload[command_start + 2] == 'T' || packet->payload[command_start + 2] == 't')
+ && (packet->payload[command_start + 3] == 'H' || packet->payload[command_start + 3] == 'h')
+ && (packet->payload[command_start + 4] == 'E' || packet->payload[command_start + 4] == 'e')
+ && (packet->payload[command_start + 5] == 'N' || packet->payload[command_start + 5] == 'n')
+ && (packet->payload[command_start + 6] == 'T' || packet->payload[command_start + 6] == 't')
+ && (packet->payload[command_start + 7] == 'I' || packet->payload[command_start + 7] == 'i')
+ && (packet->payload[command_start + 8] == 'C' || packet->payload[command_start + 8] == 'c')
+ && (packet->payload[command_start + 9] == 'A' || packet->payload[command_start + 9] == 'a')
+ && (packet->payload[command_start + 10] == 'T' || packet->payload[command_start + 10] == 't')
+ && (packet->payload[command_start + 11] == 'E' || packet->payload[command_start + 11] == 'e')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ }
+ }
+ if ((command_start + 9) < packet->payload_packet_len) {
+ if ((packet->payload[command_start] == 'N' || packet->payload[command_start] == 'n')
+ && (packet->payload[command_start + 1] == 'A' || packet->payload[command_start + 1] == 'a')
+ && (packet->payload[command_start + 2] == 'M' || packet->payload[command_start + 2] == 'm')
+ && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e')
+ && (packet->payload[command_start + 4] == 'S' || packet->payload[command_start + 4] == 's')
+ && (packet->payload[command_start + 5] == 'P' || packet->payload[command_start + 5] == 'p')
+ && (packet->payload[command_start + 6] == 'A' || packet->payload[command_start + 6] == 'a')
+ && (packet->payload[command_start + 7] == 'C' || packet->payload[command_start + 7] == 'c')
+ && (packet->payload[command_start + 8] == 'E' || packet->payload[command_start + 8] == 'e')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ }
+ }
+ if ((command_start + 4) < packet->payload_packet_len) {
+ if ((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l')
+ && (packet->payload[command_start + 1] == 'S' || packet->payload[command_start + 1] == 's')
+ && (packet->payload[command_start + 2] == 'U' || packet->payload[command_start + 2] == 'u')
+ && (packet->payload[command_start + 3] == 'B' || packet->payload[command_start + 3] == 'b')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ } else if ((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l')
+ && (packet->payload[command_start + 1] == 'I' || packet->payload[command_start + 1] == 'i')
+ && (packet->payload[command_start + 2] == 'S' || packet->payload[command_start + 2] == 's')
+ && (packet->payload[command_start + 3] == 'T' || packet->payload[command_start + 3] == 't')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ } else if ((packet->payload[command_start] == 'N' || packet->payload[command_start] == 'n')
+ && (packet->payload[command_start + 1] == 'O' || packet->payload[command_start + 1] == 'o')
+ && (packet->payload[command_start + 2] == 'O' || packet->payload[command_start + 2] == 'o')
+ && (packet->payload[command_start + 3] == 'P' || packet->payload[command_start + 3] == 'p')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ } else if ((packet->payload[command_start] == 'I' || packet->payload[command_start] == 'i')
+ && (packet->payload[command_start + 1] == 'D' || packet->payload[command_start + 1] == 'd')
+ && (packet->payload[command_start + 2] == 'L' || packet->payload[command_start + 2] == 'l')
+ && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ }
+ }
+ if ((command_start + 6) < packet->payload_packet_len) {
+ if ((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's')
+ && (packet->payload[command_start + 1] == 'E' || packet->payload[command_start + 1] == 'e')
+ && (packet->payload[command_start + 2] == 'L' || packet->payload[command_start + 2] == 'l')
+ && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e')
+ && (packet->payload[command_start + 4] == 'C' || packet->payload[command_start + 4] == 'c')
+ && (packet->payload[command_start + 5] == 'T' || packet->payload[command_start + 5] == 't')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ } else if ((packet->payload[command_start] == 'E' || packet->payload[command_start] == 'e')
+ && (packet->payload[command_start + 1] == 'X' || packet->payload[command_start + 1] == 'x')
+ && (packet->payload[command_start + 2] == 'I' || packet->payload[command_start + 2] == 'i')
+ && (packet->payload[command_start + 3] == 'S' || packet->payload[command_start + 3] == 's')
+ && (packet->payload[command_start + 4] == 'T' || packet->payload[command_start + 4] == 't')
+ && (packet->payload[command_start + 5] == 'S' || packet->payload[command_start + 5] == 's')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ } else if ((packet->payload[command_start] == 'A' || packet->payload[command_start] == 'a')
+ && (packet->payload[command_start + 1] == 'P' || packet->payload[command_start + 1] == 'p')
+ && (packet->payload[command_start + 2] == 'P' || packet->payload[command_start + 2] == 'p')
+ && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e')
+ && (packet->payload[command_start + 4] == 'N' || packet->payload[command_start + 4] == 'n')
+ && (packet->payload[command_start + 5] == 'D' || packet->payload[command_start + 5] == 'd')) {
+ flow->l4.tcp.mail_imap_stage += 1;
+ saw_command = 1;
+ }
+ }
+
+ }
+
+ if (saw_command == 1) {
+ if (flow->l4.tcp.mail_imap_stage == 3 || flow->l4.tcp.mail_imap_stage == 5) {
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "mail imap identified\n");
+ ndpi_int_mail_imap_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+
+ if (packet->payload_packet_len > 1 && packet->payload[packet->payload_packet_len - 1] == ' ') {
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG,
+ "maybe a split imap command -> need next packet and imap_stage is set to 4.\n");
+ flow->l4.tcp.mail_imap_stage = 4;
+ return;
+ }
+
+ imap_excluded:
+
+ // skip over possible authentication hashes etc. that cannot be identified as imap commands or responses
+ // if the packet count is low enough and at least one command or response was seen before
+ if ((packet->payload_packet_len >= 2 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a)
+ && flow->packet_counter < 6 && flow->l4.tcp.mail_imap_stage >= 1) {
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG,
+ "no imap command or response but packet count < 6 and imap stage >= 1 -> skip\n");
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "exclude IMAP.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAIL_IMAP);
+}
+#endif
diff --git a/src/lib/protocols/mail_pop.c b/src/lib/protocols/mail_pop.c
new file mode 100644
index 000000000..522d4948e
--- /dev/null
+++ b/src/lib/protocols/mail_pop.c
@@ -0,0 +1,204 @@
+/*
+ * mail_pop.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_MAIL_POP
+
+#define POP_BIT_AUTH 0x0001
+#define POP_BIT_APOP 0x0002
+#define POP_BIT_USER 0x0004
+#define POP_BIT_PASS 0x0008
+#define POP_BIT_CAPA 0x0010
+#define POP_BIT_LIST 0x0020
+#define POP_BIT_STAT 0x0040
+#define POP_BIT_UIDL 0x0080
+#define POP_BIT_RETR 0x0100
+#define POP_BIT_DELE 0x0200
+#define POP_BIT_STLS 0x0400
+
+
+static void ndpi_int_mail_pop_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_POP, NDPI_REAL_PROTOCOL);
+}
+
+
+static int ndpi_int_mail_pop_check_for_client_commands(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len > 4) {
+ if ((packet->payload[0] == 'A' || packet->payload[0] == 'a')
+ && (packet->payload[1] == 'U' || packet->payload[1] == 'u')
+ && (packet->payload[2] == 'T' || packet->payload[2] == 't')
+ && (packet->payload[3] == 'H' || packet->payload[3] == 'h')) {
+ flow->l4.tcp.pop_command_bitmask |= POP_BIT_AUTH;
+ return 1;
+ } else if ((packet->payload[0] == 'A' || packet->payload[0] == 'a')
+ && (packet->payload[1] == 'P' || packet->payload[1] == 'p')
+ && (packet->payload[2] == 'O' || packet->payload[2] == 'o')
+ && (packet->payload[3] == 'P' || packet->payload[3] == 'p')) {
+ flow->l4.tcp.pop_command_bitmask |= POP_BIT_APOP;
+ return 1;
+ } else if ((packet->payload[0] == 'U' || packet->payload[0] == 'u')
+ && (packet->payload[1] == 'S' || packet->payload[1] == 's')
+ && (packet->payload[2] == 'E' || packet->payload[2] == 'e')
+ && (packet->payload[3] == 'R' || packet->payload[3] == 'r')) {
+ flow->l4.tcp.pop_command_bitmask |= POP_BIT_USER;
+ return 1;
+ } else if ((packet->payload[0] == 'P' || packet->payload[0] == 'p')
+ && (packet->payload[1] == 'A' || packet->payload[1] == 'a')
+ && (packet->payload[2] == 'S' || packet->payload[2] == 's')
+ && (packet->payload[3] == 'S' || packet->payload[3] == 's')) {
+ flow->l4.tcp.pop_command_bitmask |= POP_BIT_PASS;
+ return 1;
+ } else if ((packet->payload[0] == 'C' || packet->payload[0] == 'c')
+ && (packet->payload[1] == 'A' || packet->payload[1] == 'a')
+ && (packet->payload[2] == 'P' || packet->payload[2] == 'p')
+ && (packet->payload[3] == 'A' || packet->payload[3] == 'a')) {
+ flow->l4.tcp.pop_command_bitmask |= POP_BIT_CAPA;
+ return 1;
+ } else if ((packet->payload[0] == 'L' || packet->payload[0] == 'l')
+ && (packet->payload[1] == 'I' || packet->payload[1] == 'i')
+ && (packet->payload[2] == 'S' || packet->payload[2] == 's')
+ && (packet->payload[3] == 'T' || packet->payload[3] == 't')) {
+ flow->l4.tcp.pop_command_bitmask |= POP_BIT_LIST;
+ return 1;
+ } else if ((packet->payload[0] == 'S' || packet->payload[0] == 's')
+ && (packet->payload[1] == 'T' || packet->payload[1] == 't')
+ && (packet->payload[2] == 'A' || packet->payload[2] == 'a')
+ && (packet->payload[3] == 'T' || packet->payload[3] == 't')) {
+ flow->l4.tcp.pop_command_bitmask |= POP_BIT_STAT;
+ return 1;
+ } else if ((packet->payload[0] == 'U' || packet->payload[0] == 'u')
+ && (packet->payload[1] == 'I' || packet->payload[1] == 'i')
+ && (packet->payload[2] == 'D' || packet->payload[2] == 'd')
+ && (packet->payload[3] == 'L' || packet->payload[3] == 'l')) {
+ flow->l4.tcp.pop_command_bitmask |= POP_BIT_UIDL;
+ return 1;
+ } else if ((packet->payload[0] == 'R' || packet->payload[0] == 'r')
+ && (packet->payload[1] == 'E' || packet->payload[1] == 'e')
+ && (packet->payload[2] == 'T' || packet->payload[2] == 't')
+ && (packet->payload[3] == 'R' || packet->payload[3] == 'r')) {
+ flow->l4.tcp.pop_command_bitmask |= POP_BIT_RETR;
+ return 1;
+ } else if ((packet->payload[0] == 'D' || packet->payload[0] == 'd')
+ && (packet->payload[1] == 'E' || packet->payload[1] == 'e')
+ && (packet->payload[2] == 'L' || packet->payload[2] == 'l')
+ && (packet->payload[3] == 'E' || packet->payload[3] == 'e')) {
+ flow->l4.tcp.pop_command_bitmask |= POP_BIT_DELE;
+ return 1;
+ } else if ((packet->payload[0] == 'S' || packet->payload[0] == 's')
+ && (packet->payload[1] == 'T' || packet->payload[1] == 't')
+ && (packet->payload[2] == 'L' || packet->payload[2] == 'l')
+ && (packet->payload[3] == 'S' || packet->payload[3] == 's')) {
+ flow->l4.tcp.pop_command_bitmask |= POP_BIT_STLS;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+
+void ndpi_search_mail_pop_tcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+ u_int8_t a = 0;
+ u_int8_t bit_count = 0;
+
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG, "search mail_pop\n");
+
+
+
+ if ((packet->payload_packet_len > 3
+ && (packet->payload[0] == '+' && (packet->payload[1] == 'O' || packet->payload[1] == 'o')
+ && (packet->payload[2] == 'K' || packet->payload[2] == 'k')))
+ || (packet->payload_packet_len > 4
+ && (packet->payload[0] == '-' && (packet->payload[1] == 'E' || packet->payload[1] == 'e')
+ && (packet->payload[2] == 'R' || packet->payload[2] == 'r')
+ && (packet->payload[3] == 'R' || packet->payload[3] == 'r')))) {
+ // +OK or -ERR seen
+ flow->l4.tcp.mail_pop_stage += 1;
+ } else if (!ndpi_int_mail_pop_check_for_client_commands(ndpi_struct, flow)) {
+ goto maybe_split_pop;
+ }
+
+ if (packet->payload_packet_len > 2 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) {
+
+ // count the bits set in the bitmask
+ if (flow->l4.tcp.pop_command_bitmask != 0) {
+ for (a = 0; a < 16; a++) {
+ bit_count += (flow->l4.tcp.pop_command_bitmask >> a) & 0x01;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG,
+ "mail_pop +OK/-ERR responses: %u, unique commands: %u\n", flow->l4.tcp.mail_pop_stage, bit_count);
+
+ if ((bit_count + flow->l4.tcp.mail_pop_stage) >= 3) {
+ if (flow->l4.tcp.mail_pop_stage > 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG, "mail_pop identified\n");
+ ndpi_int_mail_pop_add_connection(ndpi_struct, flow);
+ return;
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+
+ } else {
+ // first part of a split packet
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG,
+ "mail_pop command without line ending -> skip\n");
+ return;
+ }
+
+
+ maybe_split_pop:
+
+ if (((packet->payload_packet_len > 2 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a)
+ || flow->l4.tcp.pop_command_bitmask != 0 || flow->l4.tcp.mail_pop_stage != 0) && flow->packet_counter < 12) {
+ // maybe part of a split pop packet
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG,
+ "maybe part of split mail_pop packet -> skip\n");
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG, "exclude mail_pop\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAIL_POP);
+}
+#endif
diff --git a/src/lib/protocols/mail_smtp.c b/src/lib/protocols/mail_smtp.c
new file mode 100644
index 000000000..e6ee4b1c8
--- /dev/null
+++ b/src/lib/protocols/mail_smtp.c
@@ -0,0 +1,180 @@
+/*
+ * mail_smtp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_MAIL_SMTP
+
+#define SMTP_BIT_220 0x01
+#define SMTP_BIT_250 0x02
+#define SMTP_BIT_235 0x04
+#define SMTP_BIT_334 0x08
+#define SMTP_BIT_354 0x10
+#define SMTP_BIT_HELO_EHLO 0x20
+#define SMTP_BIT_MAIL 0x40
+#define SMTP_BIT_RCPT 0x80
+#define SMTP_BIT_AUTH 0x100
+#define SMTP_BIT_STARTTLS 0x200
+#define SMTP_BIT_DATA 0x400
+#define SMTP_BIT_NOOP 0x800
+#define SMTP_BIT_RSET 0x1000
+#define SMTP_BIT_TlRM 0x2000
+
+static void ndpi_int_mail_smtp_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_SMTP, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_SMTP, ndpi_struct, NDPI_LOG_DEBUG, "search mail_smtp.\n");
+
+
+ if (packet->payload_packet_len > 2 && 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++) {
+
+ // expected server responses
+ if (packet->line[a].len >= 3) {
+ if (memcmp(packet->line[a].ptr, "220", 3) == 0) {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_220;
+ } else if (memcmp(packet->line[a].ptr, "250", 3) == 0) {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_250;
+ } else if (memcmp(packet->line[a].ptr, "235", 3) == 0) {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_235;
+ } else if (memcmp(packet->line[a].ptr, "334", 3) == 0) {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_334;
+ } else if (memcmp(packet->line[a].ptr, "354", 3) == 0) {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_354;
+ }
+ }
+ // expected client requests
+ if (packet->line[a].len >= 5) {
+ if ((((packet->line[a].ptr[0] == 'H' || packet->line[a].ptr[0] == 'h')
+ && (packet->line[a].ptr[1] == 'E' || packet->line[a].ptr[1] == 'e'))
+ || ((packet->line[a].ptr[0] == 'E' || packet->line[a].ptr[0] == 'e')
+ && (packet->line[a].ptr[1] == 'H' || packet->line[a].ptr[1] == 'h')))
+ && (packet->line[a].ptr[2] == 'L' || packet->line[a].ptr[2] == 'l')
+ && (packet->line[a].ptr[3] == 'O' || packet->line[a].ptr[3] == 'o')
+ && packet->line[a].ptr[4] == ' ') {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_HELO_EHLO;
+ } else if ((packet->line[a].ptr[0] == 'M' || packet->line[a].ptr[0] == 'm')
+ && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a')
+ && (packet->line[a].ptr[2] == 'I' || packet->line[a].ptr[2] == 'i')
+ && (packet->line[a].ptr[3] == 'L' || packet->line[a].ptr[3] == 'l')
+ && packet->line[a].ptr[4] == ' ') {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_MAIL;
+ } else if ((packet->line[a].ptr[0] == 'R' || packet->line[a].ptr[0] == 'r')
+ && (packet->line[a].ptr[1] == 'C' || packet->line[a].ptr[1] == 'c')
+ && (packet->line[a].ptr[2] == 'P' || packet->line[a].ptr[2] == 'p')
+ && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't')
+ && packet->line[a].ptr[4] == ' ') {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_RCPT;
+ } else if ((packet->line[a].ptr[0] == 'A' || packet->line[a].ptr[0] == 'a')
+ && (packet->line[a].ptr[1] == 'U' || packet->line[a].ptr[1] == 'u')
+ && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't')
+ && (packet->line[a].ptr[3] == 'H' || packet->line[a].ptr[3] == 'h')
+ && packet->line[a].ptr[4] == ' ') {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_AUTH;
+ }
+ }
+
+ if (packet->line[a].len >= 8) {
+ if ((packet->line[a].ptr[0] == 'S' || packet->line[a].ptr[0] == 's')
+ && (packet->line[a].ptr[1] == 'T' || packet->line[a].ptr[1] == 't')
+ && (packet->line[a].ptr[2] == 'A' || packet->line[a].ptr[2] == 'a')
+ && (packet->line[a].ptr[3] == 'R' || packet->line[a].ptr[3] == 'r')
+ && (packet->line[a].ptr[4] == 'T' || packet->line[a].ptr[0] == 't')
+ && (packet->line[a].ptr[5] == 'T' || packet->line[a].ptr[1] == 't')
+ && (packet->line[a].ptr[6] == 'L' || packet->line[a].ptr[2] == 'l')
+ && (packet->line[a].ptr[7] == 'S' || packet->line[a].ptr[3] == 's')) {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_STARTTLS;
+ }
+ }
+
+ if (packet->line[a].len >= 4) {
+ if ((packet->line[a].ptr[0] == 'D' || packet->line[a].ptr[0] == 'd')
+ && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a')
+ && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't')
+ && (packet->line[a].ptr[3] == 'A' || packet->line[a].ptr[3] == 'a')) {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_DATA;
+ } else if ((packet->line[a].ptr[0] == 'N' || packet->line[a].ptr[0] == 'n')
+ && (packet->line[a].ptr[1] == 'O' || packet->line[a].ptr[1] == 'o')
+ && (packet->line[a].ptr[2] == 'O' || packet->line[a].ptr[2] == 'o')
+ && (packet->line[a].ptr[3] == 'P' || packet->line[a].ptr[3] == 'p')) {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_NOOP;
+ } else if ((packet->line[a].ptr[0] == 'R' || packet->line[a].ptr[0] == 'r')
+ && (packet->line[a].ptr[1] == 'S' || packet->line[a].ptr[1] == 's')
+ && (packet->line[a].ptr[2] == 'E' || packet->line[a].ptr[2] == 'e')
+ && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't')) {
+ flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_RSET;
+ }
+ }
+
+ }
+
+ // now count the bits set in the bitmask
+ if (flow->l4.tcp.smtp_command_bitmask != 0) {
+ for (a = 0; a < 16; a++) {
+ bit_count += (flow->l4.tcp.smtp_command_bitmask >> a) & 0x01;
+ }
+ }
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_SMTP, ndpi_struct, NDPI_LOG_DEBUG, "seen smtp commands and responses: %u.\n",
+ bit_count);
+
+ if (bit_count >= 3) {
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_SMTP, ndpi_struct, NDPI_LOG_DEBUG, "mail smtp identified\n");
+ ndpi_int_mail_smtp_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (bit_count >= 1 && flow->packet_counter < 12) {
+ return;
+ }
+ }
+ /* when the first or second packets are split into two packets, those packets are ignored. */
+ if (flow->packet_counter <= 4 &&
+ packet->payload_packet_len >= 4 &&
+ (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a
+ || memcmp(packet->payload, "220", 3) == 0 || memcmp(packet->payload, "EHLO", 4) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_SMTP, ndpi_struct, NDPI_LOG_DEBUG, "maybe SMTP, need next packet.\n");
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_SMTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude smtp\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAIL_SMTP);
+
+}
+#endif
diff --git a/src/lib/protocols/maplestory.c b/src/lib/protocols/maplestory.c
new file mode 100644
index 000000000..e9d89d1da
--- /dev/null
+++ b/src/lib/protocols/maplestory.c
@@ -0,0 +1,87 @@
+/*
+ * maplestory.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_MAPLESTORY
+
+static void ndpi_int_maplestory_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
+ ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAPLESTORY, protocol_type);
+}
+
+
+void ndpi_search_maplestory(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+
+ if (packet->payload_packet_len == 16
+ && (ntohl(get_u_int32_t(packet->payload, 0)) == 0x0e003a00 || ntohl(get_u_int32_t(packet->payload, 0)) == 0x0e003b00
+ || ntohl(get_u_int32_t(packet->payload, 0)) == 0x0e004200)
+ && ntohs(get_u_int16_t(packet->payload, 4)) == 0x0100 && (packet->payload[6] == 0x32 || packet->payload[6] == 0x33)) {
+ NDPI_LOG(NDPI_PROTOCOL_MAPLESTORY, ndpi_struct, NDPI_LOG_DEBUG, "found maplestory.\n");
+ ndpi_int_maplestory_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /maple")
+ && memcmp(packet->payload, "GET /maple", NDPI_STATICSTRING_LEN("GET /maple")) == 0) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ /* Maplestory update */
+ if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /maple/patch")
+ && packet->payload[NDPI_STATICSTRING_LEN("GET /maple")] == '/') {
+ if (packet->user_agent_line.ptr != NULL && packet->host_line.ptr != NULL
+ && packet->user_agent_line.len == NDPI_STATICSTRING_LEN("Patcher")
+ && packet->host_line.len > NDPI_STATICSTRING_LEN("patch.")
+ && memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /maple/")], "patch",
+ NDPI_STATICSTRING_LEN("patch")) == 0
+ && memcmp(packet->user_agent_line.ptr, "Patcher", NDPI_STATICSTRING_LEN("Patcher")) == 0
+ && memcmp(packet->host_line.ptr, "patch.", NDPI_STATICSTRING_LEN("patch.")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MAPLESTORY, ndpi_struct, NDPI_LOG_DEBUG, "found maplestory update.\n");
+ ndpi_int_maplestory_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ } else if (packet->user_agent_line.ptr != NULL && packet->user_agent_line.len == NDPI_STATICSTRING_LEN("AspINet")
+ && memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /maple")], "story/",
+ NDPI_STATICSTRING_LEN("story/")) == 0
+ && memcmp(packet->user_agent_line.ptr, "AspINet", NDPI_STATICSTRING_LEN("AspINet")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MAPLESTORY, ndpi_struct, NDPI_LOG_DEBUG, "found maplestory update.\n");
+ ndpi_int_maplestory_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_MAPLESTORY, ndpi_struct, NDPI_LOG_DEBUG, "exclude maplestory.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAPLESTORY);
+
+}
+#endif
diff --git a/src/lib/protocols/mdns.c b/src/lib/protocols/mdns.c
new file mode 100644
index 000000000..9b9b72582
--- /dev/null
+++ b/src/lib/protocols/mdns.c
@@ -0,0 +1,146 @@
+/*
+ * mdns.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_MDNS
+
+#define NDPI_MAX_MDNS_REQUESTS 128
+
+/*
+This module should detect MDNS
+*/
+
+static void ndpi_int_mdns_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MDNS, NDPI_REAL_PROTOCOL);
+}
+
+static int ndpi_int_check_mdns_payload(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if ((packet->payload[2] & 0x80) == 0 &&
+ ntohs(get_u_int16_t(packet->payload, 4)) <= NDPI_MAX_MDNS_REQUESTS &&
+ ntohs(get_u_int16_t(packet->payload, 6)) <= NDPI_MAX_MDNS_REQUESTS) {
+
+ NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, NDPI_LOG_DEBUG, "found MDNS with question query.\n");
+
+ return 1;
+ } else if ((packet->payload[2] & 0x80) != 0 &&
+ ntohs(get_u_int16_t(packet->payload, 4)) == 0 &&
+ ntohs(get_u_int16_t(packet->payload, 6)) <= NDPI_MAX_MDNS_REQUESTS &&
+ ntohs(get_u_int16_t(packet->payload, 6)) != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, NDPI_LOG_DEBUG, "found MDNS with answer query.\n");
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void ndpi_search_mdns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ u_int16_t dport;
+// const u_int16_t sport=ntohs(packet->udp->source);
+
+ /* check if UDP and */
+ if (packet->udp != NULL) {
+ /*read destination port */
+ dport = ntohs(packet->udp->dest);
+
+ NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, NDPI_LOG_DEBUG, "MDNS udp start \n");
+
+
+
+ /*check standard MDNS to port 5353 */
+ /*took this information from http://www.it-administrator.de/lexikon/multicast-dns.html */
+
+ if (dport == 5353 && packet->payload_packet_len >= 12) {
+
+ NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, NDPI_LOG_DEBUG, "found MDNS with destination port 5353\n");
+
+ /* MDNS header is similar to dns header */
+ /* dns header
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ID |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | QDCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ANCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | NSCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ARCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *
+ * dns query check: query: QR set, ancount = 0, nscount = 0, QDCOUNT < MAX_MDNS, ARCOUNT < MAX_MDNS
+ *
+ */
+
+ /* mdns protocol must have destination address 224.0.0.251 */
+ /* took this information from http://www.it-administrator.de/lexikon/multicast-dns.html */
+
+ if (packet->iph != NULL && ntohl(packet->iph->daddr) == 0xe00000fb) {
+
+ NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct,
+ NDPI_LOG_DEBUG, "found MDNS with destination address 224.0.0.251 (=0xe00000fb)\n");
+
+ if (ndpi_int_check_mdns_payload(ndpi_struct, flow) == 1) {
+ ndpi_int_mdns_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ if (packet->iphv6 != NULL) {
+ const u_int32_t *daddr = packet->iphv6->daddr.ndpi_v6_u.u6_addr32;
+ if (daddr[0] == htonl(0xff020000) && daddr[1] == 0 && daddr[2] == 0 && daddr[3] == htonl(0xfb)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct,
+ NDPI_LOG_DEBUG, "found MDNS with destination address ff02::fb\n");
+
+ if (ndpi_int_check_mdns_payload(ndpi_struct, flow) == 1) {
+ ndpi_int_mdns_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+#endif
+
+ }
+ }
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MDNS);
+}
+#endif
diff --git a/src/lib/protocols/meebo.c b/src/lib/protocols/meebo.c
new file mode 100644
index 000000000..a54cb311e
--- /dev/null
+++ b/src/lib/protocols/meebo.c
@@ -0,0 +1,165 @@
+/*
+ * meebo.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_MEEBO
+
+static void ndpi_int_meebo_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MEEBO, NDPI_CORRELATED_PROTOCOL);
+}
+
+
+
+
+void ndpi_search_meebo(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "search meebo.\n");
+
+ /* catch audio/video flows which are flash (rtmp) */
+ if (
+#ifdef NDPI_CONTENT_FLASH
+ packet->detected_protocol_stack[0] == NDPI_CONTENT_FLASH
+#else
+ (packet->tcp->source == htons(1935) || packet->tcp->dest == htons(1935))
+#endif
+ ) {
+
+ /* TODO: once we have an amf decoder we can more directly access the rtmp fields
+ * if so, we may also exclude earlier */
+ if (packet->payload_packet_len > 900) {
+ if (memcmp(packet->payload + 116, "tokbox/", NDPI_STATICSTRING_LEN("tokbox/")) == 0 ||
+ memcmp(packet->payload + 316, "tokbox/", NDPI_STATICSTRING_LEN("tokbox/")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "found meebo/tokbox flash flow.\n");
+ ndpi_int_meebo_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ if (flow->packet_counter < 16 && flow->packet_direction_counter[flow->setup_packet_direction] < 6) {
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "need next packet.\n");
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "exclude meebo.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MEEBO);
+ return;
+ }
+
+ if ((
+#ifdef NDPI_PROTOCOL_HTTP
+ packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP ||
+#endif
+ ((packet->payload_packet_len > 3 && memcmp(packet->payload, "GET ", 4) == 0)
+ || (packet->payload_packet_len > 4 && memcmp(packet->payload, "POST ", 5) == 0))
+ ) && flow->packet_counter == 1) {
+ u_int8_t host_or_referer_match = 0;
+
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->host_line.ptr != NULL
+ && packet->host_line.len >= 9
+ && memcmp(&packet->host_line.ptr[packet->host_line.len - 9], "meebo.com", 9) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found Meebo host\n");
+ host_or_referer_match = 1;
+ } else if (packet->host_line.ptr != NULL
+ && packet->host_line.len >= 10
+ && memcmp(&packet->host_line.ptr[packet->host_line.len - 10], "tokbox.com", 10) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found tokbox host\n");
+ /* set it to 2 to avoid having plain tokbox traffic detected as meebo */
+ host_or_referer_match = 2;
+ } else if (packet->host_line.ptr != NULL && packet->host_line.len >= NDPI_STATICSTRING_LEN("74.114.28.110")
+ && memcmp(&packet->host_line.ptr[packet->host_line.len - NDPI_STATICSTRING_LEN("74.114.28.110")],
+ "74.114.28.110", NDPI_STATICSTRING_LEN("74.114.28.110")) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found meebo IP\n");
+ host_or_referer_match = 1;
+ } else if (packet->referer_line.ptr != NULL &&
+ packet->referer_line.len >= NDPI_STATICSTRING_LEN("http://www.meebo.com/") &&
+ memcmp(packet->referer_line.ptr, "http://www.meebo.com/",
+ NDPI_STATICSTRING_LEN("http://www.meebo.com/")) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found meebo referer\n");
+ host_or_referer_match = 1;
+ } else if (packet->referer_line.ptr != NULL &&
+ packet->referer_line.len >= NDPI_STATICSTRING_LEN("http://mee.tokbox.com/") &&
+ memcmp(packet->referer_line.ptr, "http://mee.tokbox.com/",
+ NDPI_STATICSTRING_LEN("http://mee.tokbox.com/")) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found tokbox referer\n");
+ host_or_referer_match = 1;
+ } else if (packet->referer_line.ptr != NULL &&
+ packet->referer_line.len >= NDPI_STATICSTRING_LEN("http://74.114.28.110/") &&
+ memcmp(packet->referer_line.ptr, "http://74.114.28.110/",
+ NDPI_STATICSTRING_LEN("http://74.114.28.110/")) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found meebo IP referer\n");
+ host_or_referer_match = 1;
+ }
+
+ if (host_or_referer_match) {
+ if (host_or_referer_match == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG,
+ "Found Meebo traffic based on host/referer\n");
+ ndpi_int_meebo_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_MEEBO) {
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG,
+ "in case that ssl meebo has been detected return.\n");
+ return;
+ }
+
+ if (flow->packet_counter < 5 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSL) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "ssl not yet excluded. need next packet.\n");
+ return;
+ }
+#ifdef NDPI_CONTENT_FLASH
+ if (flow->packet_counter < 5 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN &&
+ !NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct, flow, NDPI_CONTENT_FLASH)) {
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "flash not yet excluded. need next packet.\n");
+ return;
+ }
+#endif
+
+ NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "exclude meebo.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MEEBO);
+}
+#endif
diff --git a/src/lib/protocols/megaco.c b/src/lib/protocols/megaco.c
new file mode 100644
index 000000000..ca8d26380
--- /dev/null
+++ b/src/lib/protocols/megaco.c
@@ -0,0 +1,49 @@
+/*
+ * megaco.c
+ *
+ * Copyright (C) 2014 by Gianluca Costa http://www.capanalysis.net
+ * Copyright (C) 2012-15 - ntop.org
+ *
+ * This module is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_MEGACO
+
+void ndpi_search_megaco(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_MEGACO, ndpi_struct, NDPI_LOG_DEBUG, "search for MEGACO.\n");
+
+ if(packet->udp != NULL) {
+ if((packet->payload_packet_len > 4 && packet->payload[0] == '!' && packet->payload[1] == '/' &&
+ packet->payload[2] == '1' && packet->payload[3] == ' ' && packet->payload[4] == '[')
+ || (packet->payload_packet_len > 9 && packet->payload[0] == 'M' && packet->payload[1] == 'E' &&
+ packet->payload[2] == 'G' && packet->payload[3] == 'A' && packet->payload[4] == 'C' &&
+ packet->payload[5] == 'O' && packet->payload[6] == '/' &&
+ packet->payload[7] == '1' && packet->payload[8] == ' ' && packet->payload[9] == '[')) {
+ NDPI_LOG(NDPI_PROTOCOL_MEGACO, ndpi_struct, NDPI_LOG_DEBUG, "found MEGACO.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MEGACO, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_MEGACO, ndpi_struct, NDPI_LOG_DEBUG, "exclude MEGACO.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MEGACO);
+}
+
+#endif
diff --git a/src/lib/protocols/mgcp.c b/src/lib/protocols/mgcp.c
new file mode 100644
index 000000000..c749f007b
--- /dev/null
+++ b/src/lib/protocols/mgcp.c
@@ -0,0 +1,102 @@
+/*
+ * mgcp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_MGCP
+
+static void ndpi_int_mgcp_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MGCP, NDPI_REAL_PROTOCOL);
+}
+
+
+
+#if !defined(WIN32)
+ static inline
+#else
+__forceinline static
+#endif
+ void ndpi_search_mgcp_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ /* information about MGCP taken from http://en.wikipedia.org/wiki/MGCP */
+
+ u_int16_t pos = 4;
+
+ if (packet->payload_packet_len < 8) {
+ goto mgcp_excluded;
+ }
+
+ /* packet must end with 0x0d0a or with 0x0a */
+ if (packet->payload[packet->payload_packet_len - 1] != 0x0a
+ && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) != htons(0x0d0a)) {
+ goto mgcp_excluded;
+ }
+
+
+
+ if (packet->payload[0] != 'A' && packet->payload[0] != 'C' && packet->payload[0] != 'D' &&
+ packet->payload[0] != 'E' && packet->payload[0] != 'M' && packet->payload[0] != 'N' &&
+ packet->payload[0] != 'R') {
+ goto mgcp_excluded;
+ }
+ if (memcmp(packet->payload, "AUEP ", 5) != 0 && memcmp(packet->payload, "AUCX ", 5) != 0 &&
+ memcmp(packet->payload, "CRCX ", 5) != 0 && memcmp(packet->payload, "DLCX ", 5) != 0 &&
+ memcmp(packet->payload, "EPCF ", 5) != 0 && memcmp(packet->payload, "MDCX ", 5) != 0 &&
+ memcmp(packet->payload, "NTFY ", 5) != 0 && memcmp(packet->payload, "RQNT ", 5) != 0 &&
+ memcmp(packet->payload, "RSIP ", 5) != 0) {
+ goto mgcp_excluded;
+ }
+ // now search for string "MGCP " in the rest of the message
+ while ((pos + 5) < packet->payload_packet_len) {
+ if (memcmp(&packet->payload[pos], "MGCP ", 5) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MGCP, ndpi_struct, NDPI_LOG_DEBUG, "MGCP match.\n");
+ ndpi_int_mgcp_add_connection(ndpi_struct, flow);
+ return;
+ }
+ pos++;
+ }
+
+ mgcp_excluded:
+ NDPI_LOG(NDPI_PROTOCOL_MGCP, ndpi_struct, NDPI_LOG_DEBUG, "exclude MGCP.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MGCP);
+}
+
+
+void ndpi_search_mgcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+ ndpi_search_mgcp_connection(ndpi_struct, flow);
+
+}
+#endif
diff --git a/src/lib/protocols/mms.c b/src/lib/protocols/mms.c
new file mode 100644
index 000000000..00f2cb764
--- /dev/null
+++ b/src/lib/protocols/mms.c
@@ -0,0 +1,80 @@
+/*
+ * mms.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_CONTENT_MMS
+
+
+static void ndpi_int_mms_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_CONTENT_MMS, NDPI_REAL_PROTOCOL);
+}
+
+
+void ndpi_search_mms_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ /* search MSMMS packets */
+ if (packet->payload_packet_len >= 20) {
+ if (flow->l4.tcp.mms_stage == 0 && packet->payload[4] == 0xce
+ && packet->payload[5] == 0xfa && packet->payload[6] == 0x0b
+ && packet->payload[7] == 0xb0 && packet->payload[12] == 0x4d
+ && packet->payload[13] == 0x4d && packet->payload[14] == 0x53 && packet->payload[15] == 0x20) {
+ NDPI_LOG(NDPI_CONTENT_MMS, ndpi_struct, NDPI_LOG_DEBUG, "MMS: MSMMS Request found \n");
+ flow->l4.tcp.mms_stage = 1 + packet->packet_direction;
+ return;
+ }
+
+ if (flow->l4.tcp.mms_stage == 2 - packet->packet_direction
+ && packet->payload[4] == 0xce && packet->payload[5] == 0xfa
+ && packet->payload[6] == 0x0b && packet->payload[7] == 0xb0
+ && packet->payload[12] == 0x4d && packet->payload[13] == 0x4d
+ && packet->payload[14] == 0x53 && packet->payload[15] == 0x20) {
+ NDPI_LOG(NDPI_CONTENT_MMS, ndpi_struct, NDPI_LOG_DEBUG, "MMS: MSMMS Response found \n");
+ ndpi_int_mms_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+#ifdef NDPI_PROTOCOL_HTTP
+ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP) != 0) {
+#endif /* NDPI_PROTOCOL_HTTP */
+ NDPI_LOG(NDPI_CONTENT_MMS, ndpi_struct, NDPI_LOG_DEBUG, "MMS: exclude\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_MMS);
+
+#ifdef NDPI_PROTOCOL_HTTP
+ } else {
+ NDPI_LOG(NDPI_CONTENT_MMS, ndpi_struct, NDPI_LOG_DEBUG, "MMS avoid early exclude from http\n");
+ }
+#endif /* NDPI_PROTOCOL_HTTP */
+
+}
+#endif
diff --git a/src/lib/protocols/msn.c b/src/lib/protocols/msn.c
new file mode 100644
index 000000000..a34367071
--- /dev/null
+++ b/src/lib/protocols/msn.c
@@ -0,0 +1,563 @@
+/*
+ * msn.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_MSN
+
+#define MAX_PACKETS_FOR_MSN 100
+static void ndpi_int_msn_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
+ ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MSN, protocol_type);
+}
+
+static u_int8_t ndpi_int_find_xmsn(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if (packet->parsed_lines > 3) {
+ u_int16_t i;
+ for (i = 2; i < packet->parsed_lines; i++) {
+ if (packet->line[i].ptr != NULL && packet->line[i].len > NDPI_STATICSTRING_LEN("X-MSN") &&
+ memcmp(packet->line[i].ptr, "X-MSN", NDPI_STATICSTRING_LEN("X-MSN")) == 0) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ u_int16_t plen;
+ u_int16_t status = 0;
+
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN tcp detection...\n");
+#ifdef NDPI_PROTOCOL_SSL
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "msn ssl ft test\n");
+ if (flow->packet_counter < 10) {
+ }
+
+ if (flow->packet_counter == 7 && packet->payload_packet_len > 300) {
+ if (memcmp(packet->payload + 24, "MSNSLP", 6) == 0
+ || (get_u_int32_t(packet->payload, 0) == htonl(0x30000000) && get_u_int32_t(packet->payload, 4) == 0x00000000)) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "detected MSN File Transfer, ifdef ssl.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ if (flow->packet_counter >= 5 && flow->packet_counter <= 10 && (get_u_int32_t(packet->payload, 0) == htonl(0x18000000)
+ && get_u_int32_t(packet->payload, 4) == 0x00000000)) {
+ flow->l4.tcp.msn_ssl_ft++;
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "increased msn ft ssl stage to: %u at packet nr: %u\n", flow->l4.tcp.msn_ssl_ft,
+ flow->packet_counter);
+ if (flow->l4.tcp.msn_ssl_ft == 2) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "detected MSN File Transfer, ifdef ssl 2.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ }
+ return;
+ }
+ }
+#endif
+
+
+
+ /* we detect the initial connection only ! */
+ /* match: "VER " ..... "CVR" x 0x0d 0x0a
+ * len should be small, lets say less than 100 bytes
+ * x is now "0", but can be increased
+ */
+ /* now we have a look at the first packet only. */
+ if (flow->packet_counter == 1
+#ifdef NDPI_PROTOCOL_SSL
+ || ((packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) && flow->packet_counter <= 3)
+#endif
+ ) {
+
+ /* this part is working asymmetrically */
+ if (packet->payload_packet_len > 32 && (packet->payload[0] == 0x02 || packet->payload[0] == 0x00)
+ && (ntohl(get_u_int32_t(packet->payload, 8)) == 0x2112a442 || ntohl(get_u_int32_t(packet->payload, 4)) == 0x2112a442)
+ && ((ntohl(get_u_int32_t(packet->payload, 24)) == 0x000f0004 && ntohl(get_u_int32_t(packet->payload, 28)) == 0x72c64bc6)
+ || (ntohl(get_u_int32_t(packet->payload, 20)) == 0x000f0004
+ && ntohl(get_u_int32_t(packet->payload, 24)) == 0x72c64bc6))) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "found MSN in packets that also contain voice.messenger.live.com.\n");
+
+ /* TODO this is an alternative pattern for video detection */
+ /* if (packet->payload_packet_len > 100 &&
+ get_u_int16_t(packet->payload, 86) == htons(0x05dc)) { */
+ if (packet->payload_packet_len > 101 && packet->payload[101] == 0x02) {
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ } else {
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ }
+
+ return;
+ }
+
+ /* this case works asymmetrically */
+ if (packet->payload_packet_len > 10 && packet->payload_packet_len < 100) {
+ if (get_u_int8_t(packet->payload, packet->payload_packet_len - 2) == 0x0d
+ && get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x0a) {
+ /* The MSNP string is used in XBOX clients. */
+ if (memcmp(packet->payload, "VER ", 4) == 0) {
+
+ if (memcmp(&packet->payload[packet->payload_packet_len - 6], "CVR",
+ 3) == 0 || memcmp(&packet->payload[packet->payload_packet_len - 8], "MSNP", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "found MSN by pattern VER...CVR/MSNP ODOA.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (memcmp(&packet->payload[4], "MSNFT", 5) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "found MSN FT by pattern VER MSNFT...0d0a.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ }
+ }
+
+ if (
+#ifdef NDPI_PROTOCOL_HTTP
+ packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP ||
+#endif
+ memcmp(packet->payload, "GET ", NDPI_STATICSTRING_LEN("GET ")) == 0 ||
+ memcmp(packet->payload, "POST ", NDPI_STATICSTRING_LEN("POST ")) == 0) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->user_agent_line.ptr != NULL &&
+ packet->user_agent_line.len > NDPI_STATICSTRING_LEN("Messenger/") &&
+ memcmp(packet->user_agent_line.ptr, "Messenger/", NDPI_STATICSTRING_LEN("Messenger/")) == 0) {
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+#ifdef NDPI_PROTOCOL_HTTP
+ /* we have to examine two http packets */
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP) {
+ }
+#endif
+ /* not seen this pattern in any trace */
+ /* now test for http login, at least 100 a bytes packet */
+ if (packet->payload_packet_len > 100) {
+ if (
+#ifdef NDPI_PROTOCOL_HTTP
+ packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP ||
+#endif
+ memcmp(packet->payload, "POST http://", 12) == 0) {
+ /* scan packet if not already done... */
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if (packet->content_line.ptr != NULL &&
+ ((packet->content_line.len == NDPI_STATICSTRING_LEN("application/x-msn-messenger") &&
+ memcmp(packet->content_line.ptr, "application/x-msn-messenger",
+ NDPI_STATICSTRING_LEN("application/x-msn-messenger")) == 0) ||
+ (packet->content_line.len >= NDPI_STATICSTRING_LEN("text/x-msnmsgr") &&
+ memcmp(packet->content_line.ptr, "text/x-msnmsgr",
+ NDPI_STATICSTRING_LEN("text/x-msnmsgr")) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "found MSN by pattern POST http:// .... application/x-msn-messenger.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+
+ /* now test for http login that uses a gateway, at least 400 a bytes packet */
+ /* for this case the asymmetric detection is asym (1) */
+ if (packet->payload_packet_len > 400) {
+ if ((
+#ifdef NDPI_PROTOCOL_HTTP
+ packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP ||
+#endif
+ (memcmp(packet->payload, "POST ", 5) == 0))) {
+ u_int16_t c;
+ if (memcmp(&packet->payload[5], "http://", 7) == 0) {
+ /*
+ * We are searching for a paten "POST http://gateway.messenger.hotmail.com/gateway/gateway.dll" or
+ * "POST http://<some ip addres here like 172.0.0.0>/gateway/gateway.dll"
+ * POST http:// is 12 byte so we are searching for 13 to 70 byte for this paten.
+ */
+ for (c = 13; c < 50; c++) {
+ if (memcmp(&packet->payload[c], "/", 1) == 0) {
+ if (memcmp(&packet->payload[c], "/gateway/gateway.dll", 20) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "found pattern http://.../gateway/gateway.ddl.\n");
+ status = 1;
+ break;
+ }
+ }
+ }
+ } else if ((memcmp(&packet->payload[5], "/gateway/gateway.dll", 20) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "found pattern http://.../gateway/gateway.ddl.\n");
+ status = 1;
+ }
+ }
+ if (status) {
+ u_int16_t a;
+
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if (packet->content_line.ptr != NULL
+ &&
+ ((packet->content_line.len == 23
+ && memcmp(packet->content_line.ptr, "text/xml; charset=utf-8", 23) == 0)
+ ||
+ (packet->content_line.len == 24
+ && memcmp(packet->content_line.ptr, "text/html; charset=utf-8", 24) == 0)
+ ||
+ (packet->content_line.len == 33
+ && memcmp(packet->content_line.ptr, "application/x-www-form-urlencoded", 33) == 0)
+ )) {
+ if ((src != NULL
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_MSN)
+ != 0) || (dst != NULL
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask,
+ NDPI_PROTOCOL_MSN)
+ != 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "found MSN with pattern text/xml; charset=utf-8.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ for (a = 0; a < packet->parsed_lines; a++) {
+ if (packet->line[a].len >= 4 &&
+ (memcmp(packet->line[a].ptr, "CVR ", 4) == 0
+ || memcmp(packet->line[a].ptr, "VER ",
+ 4) == 0 || memcmp(packet->line[a].ptr, "ANS ", 4) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "found MSN with pattern text/sml; charset0utf-8.\n");
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct,
+ NDPI_LOG_TRACE, "MSN xml CVS / VER / ANS found\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+ }
+ }
+ /* asym (1) ; possibly occurs in symmetric cases also. */
+ if (flow->packet_counter <= 10 &&
+ (flow->packet_direction_counter[0] <= 2 || flow->packet_direction_counter[1] <= 2)
+ && packet->payload_packet_len > 100) {
+ /* not necessary to check the length, because this has been done : >400. */
+ if (
+#ifdef NDPI_PROTOCOL_HTTP
+ packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP ||
+#endif
+ (memcmp(packet->payload, "HTTP/1.0 200 OK", 15) == 0) ||
+ (memcmp(packet->payload, "HTTP/1.1 200 OK", 15) == 0)
+ ) {
+
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if (packet->content_line.ptr != NULL &&
+ ((packet->content_line.len == NDPI_STATICSTRING_LEN("application/x-msn-messenger") &&
+ memcmp(packet->content_line.ptr, "application/x-msn-messenger",
+ NDPI_STATICSTRING_LEN("application/x-msn-messenger")) == 0) ||
+ (packet->content_line.len >= NDPI_STATICSTRING_LEN("text/x-msnmsgr") &&
+ memcmp(packet->content_line.ptr, "text/x-msnmsgr",
+ NDPI_STATICSTRING_LEN("text/x-msnmsgr")) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "HTTP/1.0 200 OK .... application/x-msn-messenger.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ if (ndpi_int_find_xmsn(ndpi_struct, flow) == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "HTTP/1.0 200 OK .... X-MSN.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+
+
+ /* did not find any trace with this pattern !!!!! */
+ /* now block proxy connection */
+ if (packet->payload_packet_len >= 42) {
+ if (memcmp(packet->payload, "CONNECT messenger.hotmail.com:1863 HTTP/1.", 42) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "found MSN with pattern CONNECT messenger.hotmail.com:1863 HTTP/1..\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+
+ if (packet->payload_packet_len >= 18) {
+
+ if (memcmp(packet->payload, "USR ", 4) == 0 || memcmp(packet->payload, "ANS ", 4) == 0) {
+ /* now we must see a number */
+ const u_int16_t endlen = packet->payload_packet_len - 12;
+ plen = 4;
+ while (1) {
+ if (packet->payload[plen] == ' ') {
+ break;
+ }
+ if (packet->payload[plen] < '0' || packet->payload[plen] > '9') {
+ goto ndpi_msn_exclude;
+ }
+ plen++;
+ if (plen >= endlen) {
+ goto ndpi_msn_exclude;
+ }
+ }
+
+ while (plen < endlen) {
+ if (ndpi_check_for_email_address(ndpi_struct, flow, plen) != 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found mail address\n");
+ break;
+ }
+ if (packet->payload_packet_len > plen + 1
+ && (packet->payload[plen] < 20 || packet->payload[plen] > 128)) {
+ goto ndpi_msn_exclude;
+ }
+ plen++;
+ if (plen >= endlen) {
+ goto ndpi_msn_exclude;
+ }
+
+ }
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "found MSN with pattern USR/ANS ...mail_address.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ }
+
+ /* finished examining the first packet only. */
+
+
+ /* asym (1) ; possibly occurs in symmetric cases also. */
+ if (flow->packet_counter <= 10 &&
+ (flow->packet_direction_counter[0] <= 2 || flow->packet_direction_counter[1] <= 2) &&
+ packet->payload_packet_len > 100) {
+ /* not necessary to check the length, because this has been done : >400. */
+ if (
+#ifdef NDPI_PROTOCOL_HTTP
+ packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP ||
+#endif
+ (memcmp(packet->payload, "HTTP/1.0 200 OK", 15) == 0) ||
+ (memcmp(packet->payload, "HTTP/1.1 200 OK", 15) == 0)
+ ) {
+
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if (packet->content_line.ptr != NULL &&
+ ((packet->content_line.len == NDPI_STATICSTRING_LEN("application/x-msn-messenger") &&
+ memcmp(packet->content_line.ptr, "application/x-msn-messenger",
+ NDPI_STATICSTRING_LEN("application/x-msn-messenger")) == 0) ||
+ (packet->content_line.len >= NDPI_STATICSTRING_LEN("text/x-msnmsgr") &&
+ memcmp(packet->content_line.ptr, "text/x-msnmsgr", NDPI_STATICSTRING_LEN("text/x-msnmsgr")) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
+ "HTTP/1.0 200 OK .... application/x-msn-messenger.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ if (ndpi_int_find_xmsn(ndpi_struct, flow) == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "HTTP/1.0 200 OK .... X-MSN.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+
+
+
+
+ /* finished examining the secone packet only */
+ /* direct user connection (file transfer,...) */
+
+ if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) != 0)
+ || (dst != NULL
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) != 0)) {
+ if (flow->packet_counter == 1 &&
+ packet->payload_packet_len > 12 && memcmp(packet->payload, "recipientid=", 12) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "detected file transfer.\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+ /* MSN File Transfer of MSN 8.1 and 8.5
+ * first packet with length 4 and pattern 0x04000000
+ * second packet (in the same direction), with length 56 and pattern 0x00000000 from payload[16]
+ * third packet (in the opposite direction to 1 & 2), with length 4 and pattern 0x30000000
+ */
+ if (flow->l4.tcp.msn_stage == 0) {
+ /* asymmetric detection to this pattern is asym (2) */
+ if ((packet->payload_packet_len == 4 || packet->payload_packet_len == 8)
+ && get_u_int32_t(packet->payload, 0) == htonl(0x04000000)) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "maybe first TCP MSN detected\n");
+
+ if (packet->payload_packet_len == 8 && get_u_int32_t(packet->payload, 4) == htonl(0x666f6f00)) {
+ flow->l4.tcp.msn_stage = 5 + packet->packet_direction;
+ return;
+ }
+
+ flow->l4.tcp.msn_stage = 1 + packet->packet_direction;
+ return;
+ }
+ /* asymmetric detection to this pattern is asym (2) */
+ } else if (flow->l4.tcp.msn_stage == 1 + packet->packet_direction) {
+ if (packet->payload_packet_len > 10 && get_u_int32_t(packet->payload, 0) == htonl(0x666f6f00)) {
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 1\n");
+ return;
+ }
+ /* did not see this pattern in any trace */
+ if (packet->payload_packet_len == 56 && get_u_int32_t(packet->payload, 16) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "maybe Second TCP MSN detected\n");
+ flow->l4.tcp.msn_stage = 3 + packet->packet_direction;
+ return;
+ }
+
+
+ } else if (flow->l4.tcp.msn_stage == 2 - packet->packet_direction
+ && packet->payload_packet_len == 4 && get_u_int32_t(packet->payload, 0) == htonl(0x30000000)) {
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 2\n");
+ return;
+ } else if ((flow->l4.tcp.msn_stage == 3 + packet->packet_direction)
+ || (flow->l4.tcp.msn_stage == 4 - packet->packet_direction)) {
+ if (packet->payload_packet_len == 4 && get_u_int32_t(packet->payload, 0) == htonl(0x30000000)) {
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 2\n");
+ return;
+ }
+ } else if (flow->l4.tcp.msn_stage == 6 - packet->packet_direction) {
+ if ((packet->payload_packet_len == 4) &&
+ (get_u_int32_t(packet->payload, 0) == htonl(0x10000000) || get_u_int32_t(packet->payload, 0) == htonl(0x30000000))) {
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 3\n");
+ return;
+ }
+ } else if (flow->l4.tcp.msn_stage == 5 + packet->packet_direction) {
+ if ((packet->payload_packet_len == 20) && get_u_int32_t(packet->payload, 0) == htonl(0x10000000)) {
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 3\n");
+ return;
+ }
+ }
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "msn 7.\n");
+ if (flow->packet_counter <= MAX_PACKETS_FOR_MSN) {
+ if (packet->tcp->source == htons(443)
+ || packet->tcp->dest == htons(443)) {
+ if (packet->payload_packet_len > 300) {
+ if (memcmp(&packet->payload[40], "INVITE MSNMSGR", 14) == 0
+ || memcmp(&packet->payload[56], "INVITE MSNMSGR", 14) == 0
+ || memcmp(&packet->payload[172], "INVITE MSNMSGR", 14) == 0) {
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 3\n");
+ return;
+ }
+ }
+ return;
+ }
+ /* For no
+ n port 443 flows exclude flow bitmask after first packet itself */
+ }
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN tcp excluded.\n");
+ ndpi_msn_exclude:
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSN);
+}
+
+
+
+static void ndpi_search_udp_msn_misc(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+
+ /* do we have an msn login ? */
+ if ((src == NULL || NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) == 0)
+ && (dst == NULL
+ || NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) == 0)) {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSN);
+ return;
+ }
+
+ /* asymmetric ft detection works */
+ if (packet->payload_packet_len == 20
+ && get_u_int32_t(packet->payload, 4) == 0 && packet->payload[9] == 0
+ && get_u_int16_t(packet->payload, 10) == htons(0x0100)) {
+ NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "msn udp misc data connection detected\n");
+ ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ }
+
+ /* asymmetric detection working. */
+ return;
+ //}
+}
+
+
+void ndpi_search_msn(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ /* this if request should always be true */
+ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSN) == 0) {
+ /* we deal with tcp now */
+ if (packet->tcp != NULL) {
+ /* msn can use http or ssl for connection. That's why every http, ssl and ukn packet must enter in the msn detection */
+ /* the detection can swich out the http or the ssl detection. In this case we need not check those protocols */
+ // need to do the ceck when protocol == http too (POST /gateway ...)
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN
+#if defined(NDPI_PROTOCOL_HTTP)
+ || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP
+#endif
+#if defined(NDPI_PROTOCOL_SSL)
+ || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL
+#endif
+#if defined(NDPI_PROTOCOL_STUN)
+ || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN
+#endif
+ ) {
+ ndpi_search_msn_tcp(ndpi_struct, flow);
+ }
+ } else if (packet->udp != NULL) {
+ ndpi_search_udp_msn_misc(ndpi_struct, flow);
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/mssql.c b/src/lib/protocols/mssql.c
new file mode 100644
index 000000000..15f2ab210
--- /dev/null
+++ b/src/lib/protocols/mssql.c
@@ -0,0 +1,61 @@
+/*
+ * mssql.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+/* include files */
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_MSSQL
+
+static void ndpi_int_mssql_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MSSQL, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_mssql(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+
+
+ NDPI_LOG(NDPI_PROTOCOL_MSSQL, ndpi_struct, NDPI_LOG_DEBUG, "search mssql.\n");
+
+
+ if (packet->payload_packet_len > 51 && ntohs(get_u_int32_t(packet->payload, 0)) == 0x1201
+ && ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len
+ && ntohl(get_u_int32_t(packet->payload, 4)) == 0x00000100 && memcmp(&packet->payload[41], "sqlexpress", 10) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_MSSQL, ndpi_struct, NDPI_LOG_DEBUG, "found mssql.\n");
+ ndpi_int_mssql_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+
+ NDPI_LOG(NDPI_PROTOCOL_MSSQL, ndpi_struct, NDPI_LOG_DEBUG, "exclude mssql.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSSQL);
+}
+#endif
diff --git a/src/lib/protocols/mysql.c b/src/lib/protocols/mysql.c
new file mode 100644
index 000000000..107b1888e
--- /dev/null
+++ b/src/lib/protocols/mysql.c
@@ -0,0 +1,70 @@
+/*
+ * mysql.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_MYSQL
+
+static void ndpi_int_mysql_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MYSQL, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_mysql_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len > 37 //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
+ ) {
+ 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) {
+ NDPI_LOG(NDPI_PROTOCOL_MYSQL, ndpi_struct, NDPI_LOG_DEBUG, "MySQL detected.\n");
+ ndpi_int_mysql_add_connection(ndpi_struct, flow);
+ return;
+ }
+ break;
+ }
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MYSQL);
+
+}
+
+#endif
diff --git a/src/lib/protocols/netbios.c b/src/lib/protocols/netbios.c
new file mode 100644
index 000000000..41f13b0f6
--- /dev/null
+++ b/src/lib/protocols/netbios.c
@@ -0,0 +1,368 @@
+/*
+ * netbios.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_NETBIOS
+
+/* The function below has been inherited by tcpdump */
+static int netbios_name_interpret(char *in, char *out, u_int out_len) {
+ int ret, len;
+ char *b;
+
+ len = (*in++)/2;
+ b = out;
+ *out=0;
+
+ if(len > (out_len-1) || len < 1)
+ return(-1);
+
+ while (len--) {
+ if(in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
+ *out = 0;
+ return(-1);
+ }
+
+ *out = ((in[0]-'A')<<4) + (in[1]-'A');
+ in += 2;
+ out++;
+ }
+ ret = *(--out);
+ *out = 0;
+
+ /* Courtesy of Roberto F. De Luca <deluca@tandar.cnea.gov.ar> */
+ /* Trim trailing whitespace from the returned string */
+ for(out--; out>=b && *out==' '; out--) *out = '\0';
+
+ return(ret);
+}
+
+
+static void ndpi_int_netbios_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NETBIOS, NDPI_REAL_PROTOCOL);
+}
+
+
+void ndpi_search_netbios(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ u_int16_t dport;
+
+ if (packet->udp != NULL) {
+ dport = ntohs(packet->udp->dest);
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, "netbios udp start\n");
+
+ /*check standard NETBIOS over udp to port 137 */
+ if ((dport == 137 || 0) && packet->payload_packet_len >= 50) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG, "found netbios port 137 and payload_packet_len 50\n");
+
+ if (ntohs(get_u_int16_t(packet->payload, 2)) == 0 &&
+ ntohs(get_u_int16_t(packet->payload, 4)) == 1 &&
+ ntohs(get_u_int16_t(packet->payload, 6)) == 0 &&
+ ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG, "found netbios with questions = 1 and answers = 0, authority = 0 \n");
+
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload[2] == 0x80 &&
+ ntohs(get_u_int16_t(packet->payload, 4)) == 1 &&
+ ntohs(get_u_int16_t(packet->payload, 6)) == 0 &&
+ ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 1) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG, "found netbios with questions = 1 and answers, authority, additional = 0 \n");
+
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (ntohs(get_u_int16_t(packet->payload, 2)) == 0x4000 &&
+ ntohs(get_u_int16_t(packet->payload, 4)) == 1 &&
+ ntohs(get_u_int16_t(packet->payload, 6)) == 0 &&
+ ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 1) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG, "found netbios with questions = 1 and answers = 0, authority = 0 \n");
+
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (ntohs(get_u_int16_t(packet->payload, 2)) == 0x8400 &&
+ ntohs(get_u_int16_t(packet->payload, 4)) == 0 &&
+ ntohs(get_u_int16_t(packet->payload, 6)) == 1 &&
+ ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG,
+ "found netbios with flag 8400 questions = 0 and answers = 1, authority, additional = 0 \n");
+
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (ntohs(get_u_int16_t(packet->payload, 2)) == 0x8500 &&
+ ntohs(get_u_int16_t(packet->payload, 4)) == 0 &&
+ ntohs(get_u_int16_t(packet->payload, 6)) == 1 &&
+ ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG,
+ "found netbios with flag 8500 questions = 0 and answers = 1, authority, additional = 0 \n");
+
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (ntohs(get_u_int16_t(packet->payload, 2)) == 0x2910 &&
+ ntohs(get_u_int16_t(packet->payload, 4)) == 1 &&
+ ntohs(get_u_int16_t(packet->payload, 6)) == 0 &&
+ ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 1) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG,
+ "found netbios with flag 2910, questions = 1 and answers, authority=0, additional = 1 \n");
+
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (ntohs(get_u_int16_t(packet->payload, 2)) == 0xAD86 &&
+ ntohs(get_u_int16_t(packet->payload, 4)) == 0 &&
+ ntohs(get_u_int16_t(packet->payload, 6)) == 1 &&
+ ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG,
+ "found netbios with flag ad86 questions = 0 and answers = 1, authority, additional = 0 \n");
+
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (ntohs(get_u_int16_t(packet->payload, 2)) == 0x0110 &&
+ ntohs(get_u_int16_t(packet->payload, 4)) == 1 &&
+ ntohs(get_u_int16_t(packet->payload, 6)) == 0 &&
+ ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG,
+ "found netbios with flag 0110 questions = 1 and answers = 0, authority, additional = 0 \n");
+
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ if ((ntohs(get_u_int16_t(packet->payload, 2)) & 0xf800) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, "possible netbios name query request\n");
+
+ if (get_u_int16_t(packet->payload, 4) == htons(1) &&
+ get_u_int16_t(packet->payload, 6) == 0 &&
+ get_u_int16_t(packet->payload, 8) == 0 && get_u_int16_t(packet->payload, 10) == 0) {
+
+ /* name is encoded as described in rfc883 */
+ u_int8_t name_length = packet->payload[12];
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "possible netbios name query request, one question\n");
+
+ if (packet->payload_packet_len == 12 + 1 + name_length + 1 + 2 + 2) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "possible netbios name query request, length matches\n");
+
+ /* null terminated? */
+ if (packet->payload[12 + name_length + 1] == 0 &&
+ get_u_int16_t(packet->payload, 12 + name_length + 2) == htons(0x0020) &&
+ get_u_int16_t(packet->payload, 12 + name_length + 4) == htons(0x0001)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "found netbios name query request\n");
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+ } else if ((ntohs(get_u_int16_t(packet->payload, 2)) & 0xf800) == 0x8000) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "possible netbios name query response\n");
+
+ if (get_u_int16_t(packet->payload, 4) == 0 &&
+ get_u_int16_t(packet->payload, 6) == htons(1) &&
+ get_u_int16_t(packet->payload, 8) == 0 && get_u_int16_t(packet->payload, 10) == 0) {
+
+ /* name is encoded as described in rfc883 */
+ u_int8_t name_length = packet->payload[12];
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "possible netbios positive name query response, one answer\n");
+
+ if (packet->payload_packet_len >= 12 + 1 + name_length + 1 + 2 + 2) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "possible netbios name query response, length matches\n");
+
+ /* null terminated? */
+ if (packet->payload[12 + name_length + 1] == 0 &&
+ get_u_int16_t(packet->payload, 12 + name_length + 2) == htons(0x0020) &&
+ get_u_int16_t(packet->payload, 12 + name_length + 4) == htons(0x0001)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "found netbios name query response\n");
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ } else if (get_u_int16_t(packet->payload, 4) == 0 &&
+ get_u_int16_t(packet->payload, 6) == 0 &&
+ get_u_int16_t(packet->payload, 8) == 0 && get_u_int16_t(packet->payload, 10) == 0) {
+
+ /* name is encoded as described in rfc883 */
+ u_int8_t name_length = packet->payload[12];
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "possible netbios negative name query response, one answer\n");
+
+ if (packet->payload_packet_len >= 12 + 1 + name_length + 1 + 2 + 2) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "possible netbios name query response, length matches\n");
+
+ /* null terminated? */
+ if (packet->payload[12 + name_length + 1] == 0 &&
+ get_u_int16_t(packet->payload, 12 + name_length + 2) == htons(0x000A) &&
+ get_u_int16_t(packet->payload, 12 + name_length + 4) == htons(0x0001)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "found netbios name query response\n");
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ } else if (get_u_int16_t(packet->payload, 4) == 0 &&
+ get_u_int16_t(packet->payload, 6) == 0 &&
+ get_u_int16_t(packet->payload, 8) == htons(1) && get_u_int16_t(packet->payload, 10) == htons(1)) {
+
+ /* name is encoded as described in rfc883 */
+ u_int8_t name_length = packet->payload[12];
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "possible netbios redirect name query response, one answer\n");
+
+ if (packet->payload_packet_len >= 12 + 1 + name_length + 1 + 2 + 2) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "possible netbios name query response, length matches\n");
+
+ /* null terminated? */
+ if (packet->payload[12 + name_length + 1] == 0 &&
+ get_u_int16_t(packet->payload, 12 + name_length + 2) == htons(0x0002) &&
+ get_u_int16_t(packet->payload, 12 + name_length + 4) == htons(0x0001)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG,
+ "found netbios name query response\n");
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+ }
+ /* TODO: extend according to rfc1002 */
+ }
+
+ /*check standard NETBIOS over udp to port 138 */
+
+ /*netbios header token from http://www.protocolbase.net/protocols/protocol_NBDGM.php */
+
+ if ((dport == 138) &&
+ packet->payload_packet_len >= 14 &&
+ ntohs(get_u_int16_t(packet->payload, 10)) == packet->payload_packet_len - 14) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG, "found netbios port 138 and payload length >= 112 \n");
+
+ if (packet->payload[0] >= 0x11 && packet->payload[0] <= 0x16) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG, "found netbios with MSG-type 0x11,0x12,0x13,0x14,0x15 or 0x16\n");
+
+ if (ntohl(get_u_int32_t(packet->payload, 4)) == ntohl(packet->iph->saddr)) {
+ char name[32];
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG, "found netbios with checked ip-address.\n");
+
+ if(netbios_name_interpret((char*)&packet->payload[14], name, sizeof(name)) > 0)
+ snprintf((char*)flow->host_server_name, sizeof(flow->host_server_name), "%s", name);
+
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+ }
+
+ if (packet->tcp != NULL) {
+ dport = ntohs(packet->tcp->dest);
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, "netbios tcp start\n");
+
+ /* destination port must be 139 */
+ if (dport == 139) {
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, "found netbios with destination port 139\n");
+
+ /* payload_packet_len must be 72 */
+ if (packet->payload_packet_len == 72) {
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG, "found netbios with payload_packen_len = 72. \n");
+
+ if (packet->payload[0] == 0x81 && packet->payload[1] == 0 && ntohs(get_u_int16_t(packet->payload, 2)) == 68) {
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct,
+ NDPI_LOG_DEBUG,
+ "found netbios with session request = 81, flags=0 and length od following bytes = 68. \n");
+
+ ndpi_int_netbios_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, "exclude netbios\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NETBIOS);
+
+}
+#endif
diff --git a/src/lib/protocols/netflow.c b/src/lib/protocols/netflow.c
new file mode 100644
index 000000000..ccf275a8b
--- /dev/null
+++ b/src/lib/protocols/netflow.c
@@ -0,0 +1,93 @@
+/*
+ * netflow.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_NETFLOW
+
+#ifndef __KERNEL__
+#ifdef WIN32
+extern int gettimeofday(struct timeval * tp, struct timezone * tzp);
+#endif
+#define do_gettimeofday(a) gettimeofday(a, NULL)
+#endif
+
+static void ndpi_check_netflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // const u_int8_t *packet_payload = packet->payload;
+ u_int32_t payload_len = packet->payload_packet_len;
+ time_t now;
+ struct timeval now_tv;
+
+ if((packet->udp != NULL) && (payload_len >= 24)) {
+ u_int16_t version = (packet->payload[0] << 8) + packet->payload[1], uptime_offset;
+ u_int32_t when, *_when;
+ u_int16_t n = (packet->payload[2] << 8) + packet->payload[3];
+
+ switch(version) {
+ case 1:
+ case 5:
+ case 7:
+ case 9:
+ {
+ u_int16_t num_flows = n;
+
+ if((num_flows == 0) || (num_flows > 30))
+ return;
+ }
+ uptime_offset = 8;
+ break;
+ case 10: /* IPFIX */
+ {
+ u_int16_t ipfix_len = n;
+
+ if(ipfix_len != payload_len)
+ return;
+ }
+ uptime_offset = 4;
+ break;
+ default:
+ return;
+ }
+
+ _when = (u_int32_t*)&packet->payload[uptime_offset]; /* Sysuptime */
+ when = ntohl(*_when);
+
+ do_gettimeofday(&now_tv);
+ now = now_tv.tv_sec;
+
+ if(((version == 1) && (when == 0))
+ || ((when >= 946684800 /* 1/1/2000 */) && (when <= now))) {
+ NDPI_LOG(NDPI_PROTOCOL_NETFLOW, ndpi_struct, NDPI_LOG_DEBUG, "Found netflow.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NETFLOW, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+}
+
+void ndpi_search_netflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ NDPI_LOG(NDPI_PROTOCOL_NETFLOW, ndpi_struct, NDPI_LOG_DEBUG, "netflow detection...\n");
+ ndpi_check_netflow(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/nfs.c b/src/lib/protocols/nfs.c
new file mode 100644
index 000000000..0a3fde84b
--- /dev/null
+++ b/src/lib/protocols/nfs.c
@@ -0,0 +1,86 @@
+/*
+ * nfs.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_NFS
+
+static void ndpi_int_nfs_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NFS, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_nfs(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ u_int8_t offset = 0;
+ if (packet->tcp != NULL)
+ offset = 4;
+
+ if (packet->payload_packet_len < (40 + offset))
+ goto exclude_nfs;
+
+ NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS user match stage 1\n");
+
+
+ if (offset != 0 && get_u_int32_t(packet->payload, 0) != htonl(0x80000000 + packet->payload_packet_len - 4))
+ goto exclude_nfs;
+
+ NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS user match stage 2\n");
+
+ if (get_u_int32_t(packet->payload, 4 + offset) != 0)
+ goto exclude_nfs;
+
+ NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS user match stage 3\n");
+
+ if (get_u_int32_t(packet->payload, 8 + offset) != htonl(0x02))
+ goto exclude_nfs;
+
+ NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS match stage 3\n");
+
+ if (get_u_int32_t(packet->payload, 12 + offset) != htonl(0x000186a5)
+ && get_u_int32_t(packet->payload, 12 + offset) != htonl(0x000186a3)
+ && get_u_int32_t(packet->payload, 12 + offset) != htonl(0x000186a0))
+ goto exclude_nfs;
+
+ NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS match stage 4\n");
+
+ if (ntohl(get_u_int32_t(packet->payload, 16 + offset)) > 4)
+ goto exclude_nfs;
+
+ NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS match\n");
+
+ ndpi_int_nfs_add_connection(ndpi_struct, flow);
+ return;
+
+ exclude_nfs:
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NFS);
+}
+
+#endif
diff --git a/src/lib/protocols/noe.c b/src/lib/protocols/noe.c
new file mode 100644
index 000000000..218201b9a
--- /dev/null
+++ b/src/lib/protocols/noe.c
@@ -0,0 +1,52 @@
+/*
+ * noe.c (Alcatel new office environment)
+ *
+ * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+
+#ifdef NDPI_PROTOCOL_NOE
+static void ndpi_int_noe_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NOE, NDPI_CORRELATED_PROTOCOL);
+}
+
+void ndpi_search_noe(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "search for NOE.\n");
+
+ if(packet->udp != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over udp.\n");
+
+ if (packet->payload_packet_len == 1 && ( packet->payload[0] == 0x05 || packet->payload[0] == 0x04 )) {
+ NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "found noe.\n");
+ ndpi_int_noe_add_connection(ndpi_struct, flow);
+ return;
+ } else if((packet->payload_packet_len == 5 || packet->payload_packet_len == 12) &&
+ (packet->payload[0] == 0x07 ) &&
+ (packet->payload[1] == 0x00 ) &&
+ (packet->payload[2] != 0x00 ) &&
+ (packet->payload[3] == 0x00 )) {
+ NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "found noe.\n");
+ ndpi_int_noe_add_connection(ndpi_struct, flow);
+ } else if((packet->payload_packet_len >= 25) &&
+ (packet->payload[0] == 0x00 &&
+ packet->payload[1] == 0x06 &&
+ packet->payload[2] == 0x62 &&
+ packet->payload[3] == 0x6c)) {
+ NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "found noe.\n");
+ ndpi_int_noe_add_connection(ndpi_struct, flow);
+ }
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "exclude NOE.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NOE);
+ }
+}
+#endif
diff --git a/src/lib/protocols/non_tcp_udp.c b/src/lib/protocols/non_tcp_udp.c
new file mode 100644
index 000000000..bb48b88a2
--- /dev/null
+++ b/src/lib/protocols/non_tcp_udp.c
@@ -0,0 +1,108 @@
+/*
+ * non_tcp_udp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#if defined(NDPI_PROTOCOL_IP_IPSEC) || defined(NDPI_PROTOCOL_IP_GRE) || defined(NDPI_PROTOCOL_IP_ICMP) || defined(NDPI_PROTOCOL_IP_IGMP) || defined(NDPI_PROTOCOL_IP_EGP) || defined(NDPI_PROTOCOL_IP_SCTP) || defined(NDPI_PROTOCOL_IP_OSPF) || defined(NDPI_PROTOCOL_IP_IP_IN_IP)
+
+#define set_protocol_and_bmask(nprot) \
+ { \
+ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask,nprot) != 0) \
+ { \
+ ndpi_int_add_connection(ndpi_struct, flow, \
+ nprot, \
+ NDPI_REAL_PROTOCOL); \
+ } \
+ }
+
+
+void ndpi_search_in_non_tcp_udp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if (packet->iph == NULL) {
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ if (packet->iphv6 == NULL)
+#endif
+ return;
+ }
+
+ switch (packet->l4_protocol) {
+#ifdef NDPI_PROTOCOL_IP_IPSEC
+ case NDPI_IPSEC_PROTOCOL_ESP:
+ case NDPI_IPSEC_PROTOCOL_AH:
+ set_protocol_and_bmask(NDPI_PROTOCOL_IP_IPSEC);
+ break;
+#endif /* NDPI_PROTOCOL_IP_IPSEC */
+#ifdef NDPI_PROTOCOL_IP_GRE
+ case NDPI_GRE_PROTOCOL_TYPE:
+ set_protocol_and_bmask(NDPI_PROTOCOL_IP_GRE);
+ break;
+#endif /* NDPI_PROTOCOL_IP_GRE */
+#ifdef NDPI_PROTOCOL_IP_ICMP
+ case NDPI_ICMP_PROTOCOL_TYPE:
+ set_protocol_and_bmask(NDPI_PROTOCOL_IP_ICMP);
+ break;
+#endif /* NDPI_PROTOCOL_IP_ICMP */
+#ifdef NDPI_PROTOCOL_IP_IGMP
+ case NDPI_IGMP_PROTOCOL_TYPE:
+ set_protocol_and_bmask(NDPI_PROTOCOL_IP_IGMP);
+ break;
+#endif /* NDPI_PROTOCOL_IP_IGMP */
+#ifdef NDPI_PROTOCOL_IP_EGP
+ case NDPI_EGP_PROTOCOL_TYPE:
+ set_protocol_and_bmask(NDPI_PROTOCOL_IP_EGP);
+ break;
+#endif /* NDPI_PROTOCOL_IP_EGP */
+#ifdef NDPI_PROTOCOL_IP_SCTP
+ case NDPI_SCTP_PROTOCOL_TYPE:
+ set_protocol_and_bmask(NDPI_PROTOCOL_IP_SCTP);
+ break;
+#endif /* NDPI_PROTOCOL_IP_SCTP */
+#ifdef NDPI_PROTOCOL_IP_OSPF
+ case NDPI_OSPF_PROTOCOL_TYPE:
+ set_protocol_and_bmask(NDPI_PROTOCOL_IP_OSPF);
+ break;
+#endif /* NDPI_PROTOCOL_IP_OSPF */
+#ifdef NDPI_PROTOCOL_IP_IP_IN_IP
+ case NDPI_IPIP_PROTOCOL_TYPE:
+ set_protocol_and_bmask(NDPI_PROTOCOL_IP_IP_IN_IP);
+ break;
+#endif /* NDPI_PROTOCOL_IP_IP_IN_IP */
+#ifdef NDPI_PROTOCOL_IP_ICMPV6
+ case NDPI_ICMPV6_PROTOCOL_TYPE:
+ set_protocol_and_bmask(NDPI_PROTOCOL_IP_ICMPV6);
+ break;
+#endif /* NDPI_PROTOCOL_IP_ICMPV6 */
+#ifdef NDPI_PROTOCOL_IP_VRRP
+ case 112:
+ set_protocol_and_bmask(NDPI_PROTOCOL_IP_VRRP);
+ break;
+#endif /* NDPI_PROTOCOL_IP_VRRP */
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/ntp.c b/src/lib/protocols/ntp.c
new file mode 100644
index 000000000..7d19968c5
--- /dev/null
+++ b/src/lib/protocols/ntp.c
@@ -0,0 +1,68 @@
+/*
+ * ntp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_NTP
+
+static void ndpi_int_ntp_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NTP, NDPI_REAL_PROTOCOL);
+}
+
+/* detection also works asymmetrically */
+
+void ndpi_search_ntp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (!(packet->udp->dest == htons(123) || packet->udp->source == htons(123)))
+ goto exclude_ntp;
+
+ NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP port detected\n");
+
+ if (packet->payload_packet_len != 48)
+ goto exclude_ntp;
+
+ NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP length detected\n");
+
+
+ if ((((packet->payload[0] & 0x38) >> 3) <= 4)) {
+ NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "detected NTP.");
+ ndpi_int_ntp_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+
+
+ exclude_ntp:
+ NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NTP);
+}
+
+#endif
diff --git a/src/lib/protocols/openft.c b/src/lib/protocols/openft.c
new file mode 100644
index 000000000..6f4e94bc5
--- /dev/null
+++ b/src/lib/protocols/openft.c
@@ -0,0 +1,56 @@
+/*
+ * openft.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_OPENFT
+
+static void ndpi_int_openft_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OPENFT, NDPI_CORRELATED_PROTOCOL);
+}
+
+void ndpi_search_openft_tcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len > 5 && memcmp(packet->payload, "GET /", 5) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_OPENFT, ndpi_struct, NDPI_LOG_DEBUG, "HTTP packet detected.\n");
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->parsed_lines >= 2
+ && packet->line[1].len > 13 && memcmp(packet->line[1].ptr, "X-OpenftAlias:", 14) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_OPENFT, ndpi_struct, NDPI_LOG_DEBUG, "OpenFT detected.\n");
+ ndpi_int_openft_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OPENFT);
+}
+#endif
diff --git a/src/lib/protocols/openvpn.c b/src/lib/protocols/openvpn.c
new file mode 100644
index 000000000..df13356ff
--- /dev/null
+++ b/src/lib/protocols/openvpn.c
@@ -0,0 +1,69 @@
+/*
+ * h323.c
+ *
+ * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ *
+ */
+
+#include "ndpi_api.h"
+
+
+#ifdef NDPI_PROTOCOL_OPENVPN
+
+void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct,
+ struct ndpi_flow_struct* flow) {
+ struct ndpi_packet_struct* packet = &flow->packet;
+ u_int16_t dport = 0, sport = 0;
+
+ if (packet->udp != NULL) {
+
+ sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest);
+
+ if ((packet->payload_packet_len >= 25) && (sport == 443 || dport == 443) &&
+ (packet->payload[0] == 0x17 && packet->payload[1] == 0x01 &&
+ packet->payload[2] == 0x00 && packet->payload[3] == 0x00)) {
+ NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG,
+ "found openvpn udp 443.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN,
+ NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ if ( ( (packet->payload_packet_len > 40) ||
+ (packet->payload_packet_len <= 14) ) && // hard-reset
+ (sport == 1194 || dport == 1194) &&
+ (packet->payload[0] == 0x30 || packet->payload[0] == 0x31 ||
+ packet->payload[0] == 0x32 || packet->payload[0] == 0x33 ||
+ packet->payload[0] == 0x34 || packet->payload[0] == 0x35 ||
+ packet->payload[0] == 0x36 || packet->payload[0] == 0x37 ||
+ packet->payload[0] == 0x38 || packet->payload[0] == 0x39)) {
+ NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG,
+ "found openvpn broadcast udp STD.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN,
+ NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ }
+
+ if (packet->tcp != NULL) {
+
+ sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
+
+ if ((packet->payload_packet_len >= 40) &&
+ (sport == 1194 || dport == 1194) &&
+ ((packet->payload[0] == 0x00) && (packet->payload[1] == 0x2a) &&
+ (packet->payload[2] == 0x38))) {
+ NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG,
+ "found openvpn broadcast udp STD.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN,
+ NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask,
+ NDPI_PROTOCOL_OPENVPN);
+}
+
+#endif
diff --git a/src/lib/protocols/oracle.c b/src/lib/protocols/oracle.c
new file mode 100644
index 000000000..e6df77930
--- /dev/null
+++ b/src/lib/protocols/oracle.c
@@ -0,0 +1,62 @@
+/*
+ * oracle.c
+ *
+ * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ *
+ * This module is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+
+#ifdef NDPI_PROTOCOL_ORACLE
+static void ndpi_int_oracle_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_ORACLE, NDPI_CORRELATED_PROTOCOL);
+}
+
+void ndpi_search_oracle(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t dport = 0, sport = 0;
+
+ NDPI_LOG(NDPI_PROTOCOL_ORACLE, ndpi_struct, NDPI_LOG_DEBUG, "search for ORACLE.\n");
+
+ if(packet->tcp != NULL) {
+ sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
+ NDPI_LOG(NDPI_PROTOCOL_ORACLE, ndpi_struct, NDPI_LOG_DEBUG, "calculating ORACLE over tcp.\n");
+ /* Oracle Database 9g,10g,11g */
+ if ((dport == 1521 || sport == 1521)
+ && (((packet->payload[0] == 0x07) && (packet->payload[1] == 0xff) && (packet->payload[2] == 0x00))
+ || ((packet->payload_packet_len >= 232) && ((packet->payload[0] == 0x00) || (packet->payload[0] == 0x01))
+ && (packet->payload[1] != 0x00)
+ && (packet->payload[2] == 0x00)
+ && (packet->payload[3] == 0x00)))) {
+ NDPI_LOG(NDPI_PROTOCOL_ORACLE, ndpi_struct, NDPI_LOG_DEBUG, "found oracle.\n");
+ ndpi_int_oracle_add_connection(ndpi_struct, flow);
+ } else if (packet->payload_packet_len == 213 && packet->payload[0] == 0x00 &&
+ packet->payload[1] == 0xd5 && packet->payload[2] == 0x00 &&
+ packet->payload[3] == 0x00 ) {
+ NDPI_LOG(NDPI_PROTOCOL_ORACLE, ndpi_struct, NDPI_LOG_DEBUG, "found oracle.\n");
+ ndpi_int_oracle_add_connection(ndpi_struct, flow);
+ }
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_ORACLE, ndpi_struct, NDPI_LOG_DEBUG, "exclude ORACLE.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ORACLE);
+ }
+}
+#endif
diff --git a/src/lib/protocols/oscar.c b/src/lib/protocols/oscar.c
new file mode 100644
index 000000000..c9ec58eba
--- /dev/null
+++ b/src/lib/protocols/oscar.c
@@ -0,0 +1,273 @@
+/*
+ * oscar.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+
+#ifdef NDPI_PROTOCOL_OSCAR
+
+static void ndpi_int_oscar_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR, protocol_type);
+
+ if (src != NULL) {
+ src->oscar_last_safe_access_time = packet->tick_timestamp;
+ }
+ if (dst != NULL) {
+ dst->oscar_last_safe_access_time = packet->tick_timestamp;
+ }
+}
+
+static void ndpi_search_oscar_tcp_connect(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+ if (packet->payload_packet_len >= 10 && packet->payload[0] == 0x2a) {
+
+ /* if is a oscar connection, 10 bytes long */
+
+ /* OSCAR Connection :: Connection detected at initial packets only
+ * +----+----+------+------+---------------+
+ * |0x2a|Code|SeqNum|PktLen|ProtcolVersion |
+ * +----+----+------+------+---------------+
+ * Code 1 Byte : 0x01 Oscar Connection
+ * SeqNum and PktLen are 2 Bytes each and ProtcolVersion: 0x00000001
+ * */
+ if (get_u_int8_t(packet->payload, 1) == 0x01 && get_u_int16_t(packet->payload, 4) == htons(packet->payload_packet_len - 6)
+ && get_u_int32_t(packet->payload, 6) == htonl(0x0000000001)) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Connection FOUND \n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ /* OSCAR IM
+ * +----+----+------+------+----------+-----------+
+ * |0x2a|Code|SeqNum|PktLen|FNACfamily|FNACsubtype|
+ * +----+----+------+------+----------+-----------+
+ * Code 1 Byte : 0x02 SNAC Header Code;
+ * SeqNum and PktLen are 2 Bytes each
+ * FNACfamily 2 Byte : 0x0004 IM Messaging
+ * FNACEsubtype 2 Byte : 0x0006 IM Outgoing Message, 0x000c IM Message Acknowledgment
+ * */
+ if (packet->payload[1] == 0x02
+ && ntohs(get_u_int16_t(packet->payload, 4)) >=
+ packet->payload_packet_len - 6 && get_u_int16_t(packet->payload, 6) == htons(0x0004)
+ && (get_u_int16_t(packet->payload, 8) == htons(0x0006)
+ || get_u_int16_t(packet->payload, 8) == htons(0x000c))) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR IM Detected \n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+
+ /* detect http connections */
+ if (packet->payload_packet_len >= 18) {
+ if ((packet->payload[0] == 'P') && (memcmp(packet->payload, "POST /photo/upload", 18) == 0)) {
+ NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet);
+ if (packet->host_line.len >= 18 && packet->host_line.ptr != NULL) {
+ if (memcmp(packet->host_line.ptr, "lifestream.aol.com", 18) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG,
+ "OSCAR over HTTP found, POST method\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+ }
+ if (packet->payload_packet_len > 40) {
+ if ((packet->payload[0] == 'G') && (memcmp(packet->payload, "GET /", 5) == 0)) {
+ if ((memcmp(&packet->payload[5], "aim/fetchEvents?aimsid=", 23) == 0) ||
+ (memcmp(&packet->payload[5], "aim/startSession?", 17) == 0) ||
+ (memcmp(&packet->payload[5], "aim/gromit/aim_express", 22) == 0) ||
+ (memcmp(&packet->payload[5], "b/ss/aolwpaim", 13) == 0) ||
+ (memcmp(&packet->payload[5], "hss/storage/aimtmpshare", 23) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR over HTTP found, GET /aim/\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+
+ if ((memcmp(&packet->payload[5], "aim", 3) == 0) || (memcmp(&packet->payload[5], "im", 2) == 0)) {
+ NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet);
+ if (packet->user_agent_line.len > 15 && packet->user_agent_line.ptr != NULL &&
+ ((memcmp(packet->user_agent_line.ptr, "mobileAIM/", 10) == 0) ||
+ (memcmp(packet->user_agent_line.ptr, "ICQ/", 4) == 0) ||
+ (memcmp(packet->user_agent_line.ptr, "mobileICQ/", 10) == 0) ||
+ (memcmp(packet->user_agent_line.ptr, "AIM%20Free/", NDPI_STATICSTRING_LEN("AIM%20Free/")) == 0) ||
+ (memcmp(packet->user_agent_line.ptr, "AIM/", 4) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR over HTTP found\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet);
+ if (packet->referer_line.ptr != NULL && packet->referer_line.len >= 22) {
+
+ if (memcmp(&packet->referer_line.ptr[packet->referer_line.len - NDPI_STATICSTRING_LEN("WidgetMain.swf")],
+ "WidgetMain.swf", NDPI_STATICSTRING_LEN("WidgetMain.swf")) == 0) {
+ u_int16_t i;
+ for (i = 0; i < (packet->referer_line.len - 22); i++) {
+ if (packet->referer_line.ptr[i] == 'a') {
+ if (memcmp(&packet->referer_line.ptr[i + 1], "im/gromit/aim_express", 21) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG,
+ "OSCAR over HTTP found : aim/gromit/aim_express\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (memcmp(packet->payload, "CONNECT ", 8) == 0) {
+ if (memcmp(packet->payload, "CONNECT login.icq.com:443 HTTP/1.", 33) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR ICQ-HTTP FOUND\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ if (memcmp(packet->payload, "CONNECT login.oscar.aol.com:5190 HTTP/1.", 40) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR AIM-HTTP FOUND\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+
+ }
+ }
+
+ if (packet->payload_packet_len > 43
+ && memcmp(packet->payload, "GET http://http.proxy.icq.com/hello HTTP/1.", 43) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR ICQ-HTTP PROXY FOUND\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+
+ if (packet->payload_packet_len > 46
+ && memcmp(packet->payload, "GET http://aimhttp.oscar.aol.com/hello HTTP/1.", 46) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR AIM-HTTP PROXY FOUND\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+
+ if (packet->payload_packet_len > 5 && get_u_int32_t(packet->payload, 0) == htonl(0x05010003)) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "Maybe OSCAR Picturetransfer\n");
+ return;
+ }
+
+ if (packet->payload_packet_len == 10 && get_u_int32_t(packet->payload, 0) == htonl(0x05000001) &&
+ get_u_int32_t(packet->payload, 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "Maybe OSCAR Picturetransfer\n");
+ return;
+ }
+
+ if (packet->payload_packet_len >= 70 &&
+ memcmp(&packet->payload[packet->payload_packet_len - 26],
+ "\x67\x00\x65\x00\x74\x00\x43\x00\x61\x00\x74\x00\x61\x00\x6c\x00\x6f\x00\x67", 19) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_OSCAR) != 0) {
+
+ if (flow->packet_counter == 1
+ &&
+ ((packet->payload_packet_len == 9
+ && memcmp(packet->payload, "\x00\x09\x00\x00\x83\x01\xc0\x00\x00", 9) == 0)
+ || (packet->payload_packet_len == 13
+ && (memcmp(packet->payload, "\x00\x0d\x00\x87\x01\xc0", 6) == 0
+ || memcmp(packet->payload, "\x00\x0d\x00\x87\x01\xc1", 6) == 0)))) {
+ flow->oscar_video_voice = 1;
+ }
+ if (flow->oscar_video_voice && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len
+ && packet->payload[2] == 0x00 && packet->payload[3] == 0x00) {
+ }
+
+ if (packet->payload_packet_len >= 70 && ntohs(get_u_int16_t(packet->payload, 4)) == packet->payload_packet_len) {
+ if (memcmp(packet->payload, "OFT", 3) == 0 &&
+ ((packet->payload[3] == '3' && ((memcmp(&packet->payload[4], "\x01\x00\x01\x01", 4) == 0)
+ || (memcmp(&packet->payload[6], "\x01\x01\x00", 3) == 0)))
+ || (packet->payload[3] == '2' && ((memcmp(&packet->payload[6], "\x01\x01", 2)
+ == 0)
+ )))) {
+ // FILE TRANSFER PATTERN:: OFT3 or OFT2
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR FILE TRANSFER\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ if (memcmp(packet->payload, "ODC2", 4) == 0 && memcmp(&packet->payload[6], "\x00\x01\x00\x06", 4) == 0) {
+ //PICTURE TRANSFER PATTERN EXMAPLE::
+ //4f 44 43 32 00 4c 00 01 00 06 00 00 00 00 00 00 ODC2.L..........
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ if (packet->payload_packet_len > 40 && (memcmp(&packet->payload[2], "\x04\x4a\x00", 3) == 0)
+ && (memcmp(&packet->payload[6], "\x00\x00", 2) == 0)
+ && packet->payload[packet->payload_packet_len - 15] == 'F'
+ && packet->payload[packet->payload_packet_len - 12] == 'L'
+ && (memcmp(&packet->payload[packet->payload_packet_len - 6], "DEST", 4) == 0)
+ && (memcmp(&packet->payload[packet->payload_packet_len - 2], "\x00\x00", 2) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ if (ntohs(packet->tcp->dest) == 443 || ntohs(packet->tcp->source) == 443) {
+ flow->oscar_ssl_voice_stage = 1;
+ }
+ return;
+
+ }
+ }
+ if (flow->packet_counter < 3 && packet->payload_packet_len > 11 && (memcmp(packet->payload, "\x00\x37\x04\x4a", 4)
+ || memcmp(packet->payload, "\x00\x0a\x04\x4a",
+ 4))) {
+ return;
+ }
+
+
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_OSCAR) {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OSCAR);
+ return;
+ }
+}
+
+void ndpi_search_oscar(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ if (packet->tcp != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR :: TCP\n");
+ ndpi_search_oscar_tcp_connect(ndpi_struct, flow);
+ }
+}
+#endif
diff --git a/src/lib/protocols/pando.c b/src/lib/protocols/pando.c
new file mode 100644
index 000000000..c409982de
--- /dev/null
+++ b/src/lib/protocols/pando.c
@@ -0,0 +1,157 @@
+/*
+ * pando.c
+ *
+ * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
+ *
+ * The signature is based on the Libprotoident library.
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_PANDO
+static void ndpi_int_pando_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PANDO, NDPI_REAL_PROTOCOL);
+}
+
+static void ndpi_check_pando_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "\x0ePan")) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n");
+ ndpi_int_pando_add_connection(ndpi_struct, flow);
+ }
+}
+
+static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->pando_stage == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "PANDO stage 0: \n");
+
+ if ((payload_len >= 4) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x09)) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->pando_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
+ return;
+ }
+
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "UDPA")) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->pando_stage = packet->packet_direction + 3; // packet_direction 0: stage 3, packet_direction 1: stage 4
+ return;
+ }
+
+ if ((payload_len > 0) && (match_first_bytes(packet->payload, "UDPR") || match_first_bytes(packet->payload, "UDPE"))) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->pando_stage = packet->packet_direction + 5; // packet_direction 0: stage 5, packet_direction 1: stage 6
+ return;
+ }
+
+ } else if ((flow->pando_stage == 1) || (flow->pando_stage == 2)) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "PANDO stage %u: \n", flow->pando_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->pando_stage - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len == 0) || ((payload_len >= 4) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x09))) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n");
+ ndpi_int_pando_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PANDO, resetting the stage to 0...\n");
+ flow->pando_stage = 0;
+ }
+
+ } else if ((flow->pando_stage == 3) || (flow->pando_stage == 4)) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "PANDO stage %u: \n", flow->pando_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->pando_stage - packet->packet_direction) == 3) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len == 0) || match_first_bytes(packet->payload, "UDPR") || match_first_bytes(packet->payload, "UDPE")) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n");
+ ndpi_int_pando_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PANDO, resetting the stage to 0...\n");
+ flow->pando_stage = 0;
+ }
+
+ } else if ((flow->pando_stage == 5) || (flow->pando_stage == 6)) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "PANDO stage %u: \n", flow->pando_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->pando_stage - packet->packet_direction) == 5) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "UDPA")) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n");
+ ndpi_int_pando_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PANDO, resetting the stage to 0...\n");
+ flow->pando_stage = 0;
+ }
+ }
+}
+
+void ndpi_search_pando(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ /* Break after 20 packets. */
+ if (flow->packet_counter > 20) {
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_TRACE, "PANDO excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PANDO);
+ return;
+ }
+
+ /* skip marked or retransmitted packets */
+ if (packet->tcp_retransmission != 0) {
+ return;
+ }
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_PANDO) {
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_TRACE, "PANDO detection...\n");
+ ndpi_check_pando_tcp(ndpi_struct, flow);
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_PANDO) {
+ return;
+ }
+
+ ndpi_check_pando_udp(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/pcanywhere.c b/src/lib/protocols/pcanywhere.c
new file mode 100644
index 000000000..a86785cd2
--- /dev/null
+++ b/src/lib/protocols/pcanywhere.c
@@ -0,0 +1,55 @@
+/*
+ * pcanywhere.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_PCANYWHERE
+
+static void ndpi_int_pcanywhere_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PCANYWHERE, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_pcanywhere(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->udp != NULL && packet->udp->dest == htons(5632)
+ && packet->payload_packet_len == 2
+ && (memcmp(packet->payload, "NQ", 2) == 0 || memcmp(packet->payload, "ST", 2) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_PCANYWHERE, ndpi_struct, NDPI_LOG_DEBUG,
+ "PC Anywhere name or status query detected.\n");
+ ndpi_int_pcanywhere_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PCANYWHERE);
+}
+
+#endif
diff --git a/src/lib/protocols/postgres.c b/src/lib/protocols/postgres.c
new file mode 100644
index 000000000..bd078d8cd
--- /dev/null
+++ b/src/lib/protocols/postgres.c
@@ -0,0 +1,120 @@
+/*
+ * postgres.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_POSTGRES
+
+
+static void ndpi_int_postgres_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_POSTGRES, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_postgres_tcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ u_int16_t size;
+
+ if (flow->l4.tcp.postgres_stage == 0) {
+ //SSL
+ if (packet->payload_packet_len > 7 &&
+ packet->payload[4] == 0x04 &&
+ packet->payload[5] == 0xd2 &&
+ packet->payload[6] == 0x16 &&
+ packet->payload[7] == 0x2f && ntohl(get_u_int32_t(packet->payload, 0)) == packet->payload_packet_len) {
+ flow->l4.tcp.postgres_stage = 1 + packet->packet_direction;
+ return;
+ }
+ //no SSL
+ if (packet->payload_packet_len > 7 &&
+ //protocol version number - to be updated
+ ntohl(get_u_int32_t(packet->payload, 4)) < 0x00040000 &&
+ ntohl(get_u_int32_t(packet->payload, 0)) == packet->payload_packet_len) {
+ flow->l4.tcp.postgres_stage = 3 + packet->packet_direction;
+ return;
+ }
+ } else {
+ if (flow->l4.tcp.postgres_stage == 2 - packet->packet_direction) {
+ //SSL accepted
+ if (packet->payload_packet_len == 1 && packet->payload[0] == 'S') {
+ NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "PostgreSQL detected, SSL accepted.\n");
+ ndpi_int_postgres_add_connection(ndpi_struct, flow);
+ return;
+ }
+ //SSL denied
+ if (packet->payload_packet_len == 1 && packet->payload[0] == 'N') {
+ NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "PostgreSQL detected, SSL denied.\n");
+ ndpi_int_postgres_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ //no SSL
+ if (flow->l4.tcp.postgres_stage == 4 - packet->packet_direction)
+ if (packet->payload_packet_len > 8 &&
+ ntohl(get_u_int32_t(packet->payload, 5)) < 10 &&
+ ntohl(get_u_int32_t(packet->payload, 1)) == packet->payload_packet_len - 1 && packet->payload[0] == 0x52) {
+ NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "PostgreSQL detected, no SSL.\n");
+ ndpi_int_postgres_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (flow->l4.tcp.postgres_stage == 6
+ && ntohl(get_u_int32_t(packet->payload, 1)) == packet->payload_packet_len - 1 && packet->payload[0] == 'p') {
+ NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "found postgres asymmetrically.\n");
+ ndpi_int_postgres_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (flow->l4.tcp.postgres_stage == 5 && packet->payload[0] == 'R') {
+ if (ntohl(get_u_int32_t(packet->payload, 1)) == packet->payload_packet_len - 1) {
+ NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "found postgres asymmetrically.\n");
+ ndpi_int_postgres_add_connection(ndpi_struct, flow);
+ return;
+ }
+ size = (u_int16_t)ntohl(get_u_int32_t(packet->payload, 1)) + 1;
+ if (packet->payload[size - 1] == 'S') {
+ if ((size + get_u_int32_t(packet->payload, (size + 1))) == packet->payload_packet_len) {
+ NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "found postgres asymmetrically.\n");
+ ndpi_int_postgres_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ size += get_u_int32_t(packet->payload, (size + 1)) + 1;
+ if (packet->payload[size - 1] == 'S') {
+ NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "found postgres asymmetrically.\n");
+ ndpi_int_postgres_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_POSTGRES);
+}
+
+#endif
diff --git a/src/lib/protocols/pplive.c b/src/lib/protocols/pplive.c
new file mode 100644
index 000000000..1cd880503
--- /dev/null
+++ b/src/lib/protocols/pplive.c
@@ -0,0 +1,220 @@
+/*
+ * pplive.c
+ *
+ * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
+ *
+ * The signature is mostly based on the Libprotoident library
+ * except the detection of HTTP Steam flows.
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_PPLIVE
+static void ndpi_int_pplive_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PPLIVE, NDPI_REAL_PROTOCOL);
+}
+
+static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->pplive_stage1 == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n");
+
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->pplive_stage1 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
+ return;
+ }
+
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x42\x01")) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->pplive_stage1 = packet->packet_direction + 3; // packet_direction 0: stage 3, packet_direction 1: stage 4
+ return;
+ }
+
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "\x1c\x1c\x32\x01")) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->pplive_stage1 = packet->packet_direction + 5; // packet_direction 0: stage 5, packet_direction 1: stage 6
+ return;
+ }
+
+ } else if ((flow->pplive_stage1 == 1) || (flow->pplive_stage1 == 2)) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage %u: \n", flow->pplive_stage1);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->pplive_stage1 - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len > 0) && (match_first_bytes(packet->payload, "\xe9\x03\x42\x01") || match_first_bytes(packet->payload, "\xe9\x03\x41\x01"))) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n");
+ ndpi_int_pplive_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PPLIVE, resetting the stage to 0...\n");
+ flow->pplive_stage1 = 0;
+ }
+
+ } else if ((flow->pplive_stage1 == 3) || (flow->pplive_stage1 == 4)) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage %u: \n", flow->pplive_stage1);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->pplive_stage1 - packet->packet_direction) == 3) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n");
+ ndpi_int_pplive_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PPLIVE, resetting the stage to 0...\n");
+ flow->pplive_stage1 = 0;
+ }
+ } else if ((flow->pplive_stage1 == 5) || (flow->pplive_stage1 == 6)) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage %u: \n", flow->pplive_stage1);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->pplive_stage1 - packet->packet_direction) == 5) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "\x1c\x1c\x32\x01")) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n");
+ ndpi_int_pplive_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PPLIVE, resetting the stage to 0...\n");
+ flow->pplive_stage1 = 0;
+ }
+ }
+
+}
+
+static void ndpi_check_pplive_udp2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->pplive_stage2 == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n");
+
+ if ((payload_len == 57) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->pplive_stage2 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
+ }
+
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage %u: \n", flow->pplive_stage2);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->pplive_stage2 - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if (payload_len == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n");
+ ndpi_int_pplive_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PPLIVE, resetting the stage to 0...\n");
+ flow->pplive_stage2 = 0;
+ }
+
+ }
+}
+
+static void ndpi_check_pplive_udp3(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->pplive_stage3 == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n");
+
+ if ((payload_len == 94) && (packet->udp->dest == htons(5041) || packet->udp->source == htons(5041) || packet->udp->dest == htons(8303) || packet->udp->source == htons(8303))) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->pplive_stage3 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
+ return;
+ }
+
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage %u: \n", flow->pplive_stage3);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->pplive_stage3 - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len == 0) || (payload_len == 49) ||(payload_len == 94)) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n");
+ ndpi_int_pplive_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PPLIVE, resetting the stage to 0...\n");
+ flow->pplive_stage3 = 0;
+ }
+ }
+
+}
+
+void ndpi_search_pplive(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ /* Break after 20 packets. */
+ if (flow->packet_counter > 20) {
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Exclude PPLIVE.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PPLIVE);
+ return;
+ }
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_PPLIVE) {
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE detection...\n");
+ ndpi_check_pplive_udp1(ndpi_struct, flow);
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_PPLIVE) {
+ return;
+ }
+
+ ndpi_check_pplive_udp2(ndpi_struct, flow);
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_PPLIVE) {
+ return;
+ }
+
+ ndpi_check_pplive_udp3(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/ppstream.c b/src/lib/protocols/ppstream.c
new file mode 100644
index 000000000..06c3c4045
--- /dev/null
+++ b/src/lib/protocols/ppstream.c
@@ -0,0 +1,105 @@
+/*
+ * ppstream.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_PPSTREAM
+
+static void ndpi_int_ppstream_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PPSTREAM, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_ppstream(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+
+ /* check TCP Connections -> Videodata */
+ if (packet->tcp != NULL) {
+ if (packet->payload_packet_len >= 60 && get_u_int32_t(packet->payload, 52) == 0
+ && memcmp(packet->payload, "PSProtocol\x0", 11) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, "found ppstream over tcp.\n");
+ ndpi_int_ppstream_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ if (packet->udp != NULL) {
+ if (packet->payload_packet_len > 2 && packet->payload[2] == 0x43
+ && ((packet->payload_packet_len - 4 == get_l16(packet->payload, 0))
+ || (packet->payload_packet_len == get_l16(packet->payload, 0))
+ || (packet->payload_packet_len >= 6 && packet->payload_packet_len - 6 == get_l16(packet->payload, 0)))) {
+ flow->l4.udp.ppstream_stage++;
+ if (flow->l4.udp.ppstream_stage == 5) {
+ NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG,
+ "found ppstream over udp pattern len, 43.\n");
+ ndpi_int_ppstream_add_connection(ndpi_struct, flow);
+ return;
+ }
+ return;
+ }
+
+ if (flow->l4.udp.ppstream_stage == 0
+ && packet->payload_packet_len > 4 && ((packet->payload_packet_len - 4 == get_l16(packet->payload, 0))
+ || (packet->payload_packet_len == get_l16(packet->payload, 0))
+ || (packet->payload_packet_len >= 6
+ && packet->payload_packet_len - 6 == get_l16(packet->payload,
+ 0)))) {
+
+ if (packet->payload[2] == 0x00 && packet->payload[3] == 0x00 && packet->payload[4] == 0x03) {
+ flow->l4.udp.ppstream_stage = 7;
+ NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, "need next packet I.\n");
+ return;
+ }
+ }
+
+ if (flow->l4.udp.ppstream_stage == 7
+ && packet->payload_packet_len > 4 && packet->payload[3] == 0x00
+ && ((packet->payload_packet_len - 4 == get_l16(packet->payload, 0))
+ || (packet->payload_packet_len == get_l16(packet->payload, 0))
+ || (packet->payload_packet_len >= 6 && packet->payload_packet_len - 6 == get_l16(packet->payload, 0)))
+ && (packet->payload[2] == 0x00 && packet->payload[4] == 0x03)) {
+ NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG,
+ "found ppstream over udp with pattern Vb.\n");
+ ndpi_int_ppstream_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+
+
+
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, "exclude ppstream.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PPSTREAM);
+}
+#endif
diff --git a/src/lib/protocols/pptp.c b/src/lib/protocols/pptp.c
new file mode 100644
index 000000000..c5ad6c8b9
--- /dev/null
+++ b/src/lib/protocols/pptp.c
@@ -0,0 +1,61 @@
+/*
+ * pptp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+/* include files */
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_PPTP
+
+static void ndpi_int_pptp_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PPTP, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_pptp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len >= 10 && get_u_int16_t(packet->payload, 0) == htons(packet->payload_packet_len)
+ && get_u_int16_t(packet->payload, 2) == htons(0x0001) /* message type: control message */
+ &&get_u_int32_t(packet->payload, 4) == htonl(0x1a2b3c4d) /* cookie: correct */
+ &&(get_u_int16_t(packet->payload, 8) == htons(0x0001) /* control type: start-control-connection-request */
+ )) {
+
+ NDPI_LOG(NDPI_PROTOCOL_PPTP, ndpi_struct, NDPI_LOG_DEBUG, "found pptp.\n");
+ ndpi_int_pptp_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_PPTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude pptp.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PPTP);
+}
+#endif
diff --git a/src/lib/protocols/qq.c b/src/lib/protocols/qq.c
new file mode 100644
index 000000000..17c5268d9
--- /dev/null
+++ b/src/lib/protocols/qq.c
@@ -0,0 +1,665 @@
+/*
+ * qq.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_QQ
+
+static void ndpi_int_qq_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_QQ, protocol_type);
+}
+
+
+/*
+ * a qq client packet looks like this:
+ *
+ * TCP packets starts with 16 bit length, then the normal packets follows
+ *
+ * 0 1 byte packet tag (usually 0x02)
+ * 1 2 byte client tag (client version)
+ * 3 2 byte command
+ * 5 2 byte sequence number
+ * 7 4 byte userid
+ * 11 x bytes data
+ * LAST 1 byte packet tail (usually 0x03)
+ *
+ * a qq server packet looks like this:
+ *
+ * TCP packets starts with 16 bit length, then the normal packets follows
+ *
+ * 0 1 byte packet tag (usually 0x02)
+ * 1 2 byte source tag (client version, might also be a server id)
+ * 3 2 byte command (usually reply to client request, so same command id)
+ * 5 2 byte sequence number
+ * LAST 1 byte packet tail (usually 0x03)
+ *
+ * NOTE: there are other qq versions which uses different packet types!
+ */
+
+/*
+ * these are some currently known client ids (or server ids)
+ * new ids might be added here if the traffic is really QQ
+ */
+static const u_int16_t ndpi_valid_qq_versions[] = {
+ 0x0100, 0x05a5, 0x062e, 0x06d5, 0x072e, 0x0801, 0x087d, 0x08d2, 0x0961,
+ 0x0a1d, 0x0b07, 0x0b2f, 0x0b35, 0x0b37, 0x0c0b, 0x0c0d, 0x0c21, 0x0c49,
+ 0x0d05, 0x0d51, 0x0d55, 0x0d61, 0x0e1b, 0x0e35, 0x0f15, 0x0f4b, 0x0f5f,
+ 0x1105, 0x111b, 0x111d, 0x1131, 0x113f, 0x115b, 0x1203, 0x1205, 0x120b,
+ 0x1251, 0x1412, 0x1441, 0x1501, 0x1549, 0x163a, 0x1801, 0x180d, 0x1c27,
+ 0x1e0d
+};
+
+/**
+ * this functions checks whether the packet is a valid qq packet
+ * it can handle tcp and udp packets
+ */
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+u_int8_t ndpi_is_valid_qq_packet(const struct ndpi_packet_struct *packet)
+{
+ u_int8_t real_start = 0;
+ u_int16_t command;
+ u_int8_t ids, found = 0;
+ u_int16_t version_id;
+
+ if (packet->payload_packet_len < 9)
+ return 0;
+
+ /* for tcp the length is prefixed */
+ if (packet->tcp) {
+ if (ntohs(get_u_int16_t(packet->payload, 0)) != packet->payload_packet_len) {
+ return 0;
+ }
+ real_start = 2;
+ }
+
+ /* packet usually starts with 0x02 */
+ if (packet->payload[real_start] != 0x02) {
+ return 0;
+ }
+
+ /* packet usually ends with 0x03 */
+ if (packet->payload[packet->payload_packet_len - 1] != 0x03) {
+ return 0;
+ }
+
+ version_id = ntohs(get_u_int16_t(packet->payload, real_start + 1));
+
+ if (version_id == 0) {
+ return 0;
+ }
+
+ /* check for known version id */
+ for (ids = 0; ids < sizeof(ndpi_valid_qq_versions) / sizeof(ndpi_valid_qq_versions[0]); ids++) {
+ if (version_id == ndpi_valid_qq_versions[ids]) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ return 0;
+
+ command = ntohs(get_u_int16_t(packet->payload, real_start + 3));
+
+ /* these are some known commands, not all need to be checked
+ since many are used with already established connections */
+
+ switch (command) {
+ case 0x0091: /* get server */
+ case 0x00ba: /* login token */
+ case 0x00dd: /* password verify */
+ case 0x00e5:
+ case 0x00a4:
+ case 0x0030:
+ case 0x001d:
+ case 0x0001:
+ case 0x0062:
+ case 0x0002:
+ case 0x0022:
+ case 0x0029:
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return 1;
+}
+
+/*
+ * some file transfer packets look like this
+ *
+ * 0 1 byte packet tag (usually 0x04)
+ * 1 2 byte client tag (client version)
+ * 3 2 byte length (this is speculative)
+ * LAST 1 byte packet tail (usually 0x03)
+ *
+ */
+/**
+ * this functions checks whether the packet is a valid qq file transfer packet
+ * it can handle tcp and udp packets
+ */
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+u_int8_t ndpi_is_valid_qq_ft_packet(const struct ndpi_packet_struct *packet)
+{
+ u_int8_t ids, found = 0;
+ u_int16_t version_id;
+
+ if (packet->payload_packet_len < 9)
+ return 0;
+
+ /* file transfer packets may start with 0x00 (control), 0x03 (data), 0x04 (agent) */
+
+ if (packet->payload[0] != 0x04 && packet->payload[0] != 0x03 && packet->payload[0] != 0x00) {
+ return 0;
+ }
+
+ version_id = ntohs(get_u_int16_t(packet->payload, 1));
+
+ if (version_id == 0) {
+ return 0;
+ }
+
+ /* check for known version id */
+ for (ids = 0; ids < sizeof(ndpi_valid_qq_versions) / sizeof(ndpi_valid_qq_versions[0]); ids++) {
+ if (version_id == ndpi_valid_qq_versions[ids]) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ return 0;
+
+ if (packet->payload[0] == 0x04) {
+
+ if (ntohs(get_u_int16_t(packet->payload, 3)) != packet->payload_packet_len) {
+ return 0;
+ }
+
+ /* packet usually ends with 0x03 */
+ if (packet->payload[packet->payload_packet_len - 1] != 0x03) {
+ return 0;
+ }
+ } else if (packet->payload[0] == 0x03) {
+ /* TODO currently not detected */
+ return 0;
+ } else if (packet->payload[0] == 0x00) {
+
+ /* packet length check, there might be other lengths */
+ if (packet->payload_packet_len != 84) {
+ return 0;
+ }
+
+ /* packet usually ends with 0x0c ? */
+ if (packet->payload[packet->payload_packet_len - 1] != 0x0c) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void ndpi_search_qq_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ static const u_int16_t p8000_patt_02[12] = // maybe version numbers
+ { 0x1549, 0x1801, 0x180d, 0x0961, 0x01501, 0x0e35, 0x113f, 0x0b37, 0x1131, 0x163a, 0x1e0d };
+ u_int16_t no_of_patterns = 11, index = 0;
+
+
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "search qq udp.\n");
+
+
+ if (flow->qq_stage <= 3) {
+ if ((packet->payload_packet_len == 27 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0300
+ && packet->payload[2] == 0x01)
+ || (packet->payload_packet_len == 84 && ((ntohs(get_u_int16_t(packet->payload, 0)) == 0x000e
+ && packet->payload[2] == 0x35)
+ || (ntohs(get_u_int16_t(packet->payload, 0)) == 0x0015
+ && packet->payload[2] == 0x01)
+ || (ntohs(get_u_int16_t(packet->payload, 0)) == 0x000b
+ && packet->payload[2] == 0x37)
+ || (ntohs(get_u_int16_t(packet->payload, 0)) == 0x0015
+ && packet->payload[2] == 0x49)))
+ || (packet->payload_packet_len > 10
+ && ((get_u_int16_t(packet->payload, 0) == htons(0x000b) && packet->payload[2] == 0x37)
+ || (get_u_int32_t(packet->payload, 0) == htonl(0x04163a00)
+ && packet->payload[packet->payload_packet_len - 1] == 0x03
+ && packet->payload[4] == packet->payload_packet_len)))) {
+ /*
+ if (flow->qq_stage == 3 && flow->detected_protocol == NDPI_PROTOCOL_QQ) {
+ if (flow->packet_direction_counter[0] > 0 && flow->packet_direction_counter[1] > 0) {
+ flow->protocol_subtype = NDPI_PROTOCOL_QQ_SUBTYPE_AUDIO;
+ return;
+ } else if (flow->packet_counter < 10) {
+ return;
+ }
+ } */
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG,
+ "found qq udp pattern 030001 or 000e35 four times.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+ if (packet->payload_packet_len > 2 && (packet->payload[0] == 0x02 || packet->payload[0] == 0x04)) {
+ u_int16_t pat = ntohs(get_u_int16_t(packet->payload, 1));
+ for (index = 0; index < no_of_patterns; index++) {
+ if (pat == p8000_patt_02[index] && packet->payload[packet->payload_packet_len - 1] == 0x03) {
+ flow->qq_stage++;
+ // maybe we can test here packet->payload[4] == packet->payload_packet_len
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG,
+ "found qq udp pattern 02 ... 03 four times.\n");
+ /*
+ if (packet->payload[0] == 0x04) {
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ } */
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+ }
+ }
+ if (packet->payload_packet_len == 84 && (packet->payload[0] == 0 || packet->payload[0] == 0x03)) {
+ u_int16_t pat = ntohs(get_u_int16_t(packet->payload, 1));
+ for (index = 0; index < no_of_patterns; index++) {
+ if (pat == p8000_patt_02[index]) {
+ flow->qq_stage++;
+ /*
+ if (flow->qq_stage == 3 && flow->packet_direction_counter[0] > 0 &&
+ flow->packet_direction_counter[1] > 0) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern four times.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ } else */ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern four times.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+ }
+ }
+ if (packet->payload_packet_len > 2 && packet->payload[0] == 0x04
+ && ((ntohs(get_u_int16_t(packet->payload, 1)) == 0x1549
+ || ntohs(get_u_int16_t(packet->payload, 1)) == 0x1801 || ntohs(get_u_int16_t(packet->payload, 1)) == 0x0961)
+ ||
+ (packet->payload_packet_len > 16
+ && (ntohs(get_u_int16_t(packet->payload, 1)) == 0x180d || ntohs(get_u_int16_t(packet->payload, 1)) == 0x096d)
+ && ntohl(get_u_int32_t(packet->payload, 12)) == 0x28000000
+ && ntohs(get_u_int16_t(packet->payload, 3)) == packet->payload_packet_len))
+ && packet->payload[packet->payload_packet_len - 1] == 0x03) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG,
+ "found qq udp pattern 04 1159 ... 03 four times.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+ if (packet->payload_packet_len > 2 && (packet->payload[0] == 0x06 || packet->payload[0] == 0x02)
+ && ntohs(get_u_int16_t(packet->payload, 1)) == 0x0100
+ && (packet->payload[packet->payload_packet_len - 1] == 0x00
+ || packet->payload[packet->payload_packet_len - 1] == 0x03)) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG,
+ "found qq udp pattern 02/06 0100 ... 03/00 four times.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+
+ if (packet->payload_packet_len > 2 && (packet->payload[0] == 0x02)
+ && ntohs(get_u_int16_t(packet->payload, 1)) == 0x1131 && packet->payload[packet->payload_packet_len - 1] == 0x03) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG,
+ "found qq udp pattern 02 1131 ... 03 four times.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+
+ if (packet->payload_packet_len > 5 && get_u_int16_t(packet->payload, 0) == htons(0x0203) &&
+ ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len &&
+ get_u_int16_t(packet->payload, 4) == htons(0x0b0b)) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG,
+ "found qq udp pattern 0203[packet_length_0b0b] three times.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+
+ if (packet->udp->dest == htons(9000) || packet->udp->source == htons(9000)) {
+ if (packet->payload_packet_len > 3
+ && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0202
+ && ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG,
+ "found qq udp pattern 02 02 <length> four times.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+
+ }
+ }
+
+ if (ndpi_is_valid_qq_packet(packet)) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over udp.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq packet stage %d\n", flow->qq_stage);
+ return;
+ }
+
+ if (ndpi_is_valid_qq_ft_packet(packet)) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq ft over udp.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+
+ if (flow->qq_stage && flow->packet_counter <= 5) {
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "QQ excluded\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QQ);
+}
+
+
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+void ndpi_search_qq_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+
+ u_int16_t i = 0;
+ // u_int16_t a = 0;
+
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "search qq tcp.\n");
+
+ if (packet->payload_packet_len == 39 && get_u_int32_t(packet->payload, 0) == htonl(0x27000000) &&
+ get_u_int16_t(packet->payload, 4) == htons(0x0014) && get_u_int32_t(packet->payload, 11) != 0 &&
+ get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == htons(0x0000)) {
+ if (flow->qq_stage == 4) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp - maybe ft/audio/video.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ flow->qq_stage = 4;
+ return;
+ }
+
+ if ((packet->payload_packet_len > 4 && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len
+ && get_u_int16_t(packet->payload, 2) == htons(0x0212) && packet->payload[4] == 0x0b)
+ || (packet->payload_packet_len > 6 && packet->payload[0] == 0x02
+ && packet->payload[packet->payload_packet_len - 1] == 0x03
+ && ntohs(get_u_int16_t(packet->payload, 1)) == packet->payload_packet_len
+ && (get_u_int16_t(packet->payload, 3) == htons(0x0605) || get_u_int16_t(packet->payload, 3) == htons(0x0608))
+ && packet->payload[5] == 0x00)
+ || (packet->payload_packet_len > 9 && get_u_int32_t(packet->payload, 0) == htonl(0x04154900)
+ && get_l16(packet->payload, 4) == packet->payload_packet_len
+ && packet->payload[packet->payload_packet_len - 1] == 0x03)
+ || (packet->payload_packet_len > 9 && get_u_int32_t(packet->payload, 0) == htonl(0x040e3500)
+ && get_l16(packet->payload, 4) == packet->payload_packet_len
+ && packet->payload[9] == 0x33 && packet->payload[packet->payload_packet_len - 1] == 0x03)
+ || (packet->payload_packet_len > 9 && get_u_int32_t(packet->payload, 0) == htonl(0x040e0215)
+ && get_l16(packet->payload, 4) == packet->payload_packet_len
+ && packet->payload[9] == 0x33 && packet->payload[packet->payload_packet_len - 1] == 0x03)
+ || (packet->payload_packet_len > 6 && get_u_int32_t(packet->payload, 2) == htonl(0x020d5500)
+ && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len
+ && packet->payload[packet->payload_packet_len - 1] == 0x03)
+ || (packet->payload_packet_len > 6 && get_u_int16_t(packet->payload, 0) == htons(0x0418)
+ && packet->payload[2] == 0x01
+ && ntohs(get_u_int16_t(packet->payload, 3)) == packet->payload_packet_len
+ && packet->payload[packet->payload_packet_len - 1] == 0x03)
+ || (packet->payload_packet_len > 6 && get_u_int16_t(packet->payload, 0) == htons(0x0411)
+ && packet->payload[2] == 0x31
+ && ntohs(get_u_int16_t(packet->payload, 3)) == packet->payload_packet_len
+ && packet->payload[packet->payload_packet_len - 1] == 0x03)
+ || (packet->payload_packet_len > 6 && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len
+ && get_u_int16_t(packet->payload, 2) == htons(0x0211) && packet->payload[4] == 0x31
+ && packet->payload[packet->payload_packet_len - 1] == 0x03)
+ || (packet->payload_packet_len > 6 && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len
+ && get_u_int16_t(packet->payload, 2) == htons(0x0218) && packet->payload[4] == 0x01
+ && packet->payload[packet->payload_packet_len - 1] == 0x03)
+ || (packet->payload_packet_len > 10 && get_u_int32_t(packet->payload, 0) == htonl(0x04163a00)
+ && packet->payload[packet->payload_packet_len - 1] == 0x03
+ && packet->payload[4] == packet->payload_packet_len)
+ ) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+
+ if (ndpi_is_valid_qq_packet(packet)) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+
+ if (ndpi_is_valid_qq_ft_packet(packet)) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq ft over tcp.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+
+ if (packet->payload_packet_len == 2) {
+ flow->l4.tcp.qq_nxt_len = ntohs(get_u_int16_t(packet->payload, 0));
+ return;
+ }
+ if (packet->payload_packet_len > 5 && (((flow->l4.tcp.qq_nxt_len == packet->payload_packet_len + 2)
+ && packet->payload[0] == 0x02
+ && packet->payload[packet->payload_packet_len - 1] == 0x03
+ && get_u_int16_t(packet->payload, 1) == htons(0x0f5f))
+ || (ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len
+ && packet->payload[2] == 0x02
+ && packet->payload[packet->payload_packet_len - 1] == 0x03
+ && get_u_int16_t(packet->payload, 3) == htons(0x0f5f)))) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern 02 ... 03 four times.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+
+ }
+ if (packet->payload_packet_len > 2 && packet->payload[0] == 0x04 && ((get_u_int16_t(packet->payload, 1) == htons(0x1549)
+ || get_u_int16_t(packet->payload,
+ 1) == htons(0x1801)
+ || get_u_int16_t(packet->payload,
+ 1) == htons(0x0961))
+ || (packet->payload_packet_len > 16
+ && (get_u_int16_t(packet->payload, 1) ==
+ htons(0x180d)
+ || get_u_int16_t(packet->payload,
+ 1) == htons(0x096d))
+ && get_u_int32_t(packet->payload,
+ 12) == htonl(0x28000000)
+ && ntohs(get_u_int16_t(packet->payload, 3)) ==
+ packet->payload_packet_len))
+ && packet->payload[packet->payload_packet_len - 1] == 0x03) {
+ flow->qq_stage++;
+ if (flow->qq_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG,
+ "found qq udp pattern 04 1159 ... 03 four times.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ return;
+ }
+
+
+
+ if (packet->payload_packet_len > 100
+ && ((memcmp(packet->payload, "GET", 3) == 0) || (memcmp(packet->payload, "POST", 4) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found GET or POST.\n");
+ if (memcmp(packet->payload, "GET /qqfile/qq", 14) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp GET /qqfile/qq.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if (packet->user_agent_line.ptr != NULL
+ && (packet->user_agent_line.len > 7 && memcmp(packet->user_agent_line.ptr, "QQClient", 8) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp GET...QQClient\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ for (i = 0; i < packet->parsed_lines; i++) {
+ if (packet->line[i].len > 3 && memcmp(packet->line[i].ptr, "QQ: ", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp GET...QQ: \n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ if (packet->host_line.ptr != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "host line ptr\n");
+ if (packet->host_line.len > 11 && memcmp(&packet->host_line.ptr[0], "www.qq.co.za", 12) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp Host: www.qq.co.za\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+ if (flow->qq_stage == 0 && packet->payload_packet_len == 82
+ && get_u_int32_t(packet->payload, 0) == htonl(0x0000004e) && get_u_int32_t(packet->payload, 4) == htonl(0x01010000)) {
+ for (i = 8; i < 82; i++) {
+ if (packet->payload[i] != 0x00) {
+ break;
+ }
+ if (i == 81) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq Mail.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ }
+ if (flow->qq_stage == 0 && packet->payload_packet_len == 182 && get_u_int32_t(packet->payload, 0) == htonl(0x000000b2)
+ && get_u_int32_t(packet->payload, 4) == htonl(0x01020000)
+ && get_u_int32_t(packet->payload, 8) == htonl(0x04015151) && get_u_int32_t(packet->payload, 12) == htonl(0x4d61696c)) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq Mail.\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 204 && flow->qq_stage == 0 && get_u_int32_t(packet->payload, 200) == htonl(0xfbffffff)) {
+ for (i = 0; i < 200; i++) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "i = %u\n", i);
+ if (packet->payload[i] != 0) {
+ break;
+ }
+ if (i == 199) {
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq chat or file transfer\n");
+ ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ }
+#ifdef NDPI_PROTOCOL_HTTP
+ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP) != 0) {
+#endif /* NDPI_PROTOCOL_HTTP */
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QQ);
+ NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "QQ tcp excluded; len %u\n",
+ packet->payload_packet_len);
+
+#ifdef NDPI_PROTOCOL_HTTP
+ }
+#endif /* NDPI_PROTOCOL_HTTP */
+
+}
+
+
+void ndpi_search_qq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if (packet->udp != NULL && flow->detected_protocol_stack[0] != NDPI_PROTOCOL_QQ)
+ ndpi_search_qq_udp(ndpi_struct, flow);
+
+ if (packet->tcp != NULL && flow->detected_protocol_stack[0] != NDPI_PROTOCOL_QQ)
+ ndpi_search_qq_tcp(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/quake.c b/src/lib/protocols/quake.c
new file mode 100644
index 000000000..18a027970
--- /dev/null
+++ b/src/lib/protocols/quake.c
@@ -0,0 +1,91 @@
+/*
+ * quake.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_QUAKE
+
+static void ndpi_int_quake_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_QUAKE, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_quake(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if ((packet->payload_packet_len == 14
+ && get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "getInfo", 7) == 0)
+ || (packet->payload_packet_len == 17
+ && get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "challenge", 9) == 0)
+ || (packet->payload_packet_len > 20
+ && packet->payload_packet_len < 30
+ && get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "getServers", 10) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake IV detected.\n");
+ ndpi_int_quake_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ /* Quake III/Quake Live */
+ if (packet->payload_packet_len == 15 && get_u_int32_t(packet->payload, 0) == 0xffffffff
+ && memcmp(&packet->payload[4], "getinfo", NDPI_STATICSTRING_LEN("getinfo")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n");
+ ndpi_int_quake_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len == 16 && get_u_int32_t(packet->payload, 0) == 0xffffffff
+ && memcmp(&packet->payload[4], "getchallenge", NDPI_STATICSTRING_LEN("getchallenge")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n");
+ ndpi_int_quake_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len > 20 && packet->payload_packet_len < 30
+ && get_u_int32_t(packet->payload, 0) == 0xffffffff
+ && memcmp(&packet->payload[4], "getservers", NDPI_STATICSTRING_LEN("getservers")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n");
+ ndpi_int_quake_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+
+
+ /* ports for startup packet:
+ Quake I 26000 (starts with 0x8000)
+ Quake II 27910
+ Quake III 27960 (increases with each player)
+ Quake IV 27650
+ Quake World 27500
+ Quake Wars ?????
+ */
+
+ NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUAKE);
+}
+
+#endif
diff --git a/src/lib/protocols/radius.c b/src/lib/protocols/radius.c
new file mode 100644
index 000000000..0b7698a94
--- /dev/null
+++ b/src/lib/protocols/radius.c
@@ -0,0 +1,76 @@
+/*
+ * radius.c
+ *
+ * Copyright (C) 2012-15 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_RADIUS
+
+struct radius_header {
+ u_int8_t code;
+ u_int8_t packet_id;
+ u_int16_t len;
+};
+
+static void ndpi_check_radius(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // const u_int8_t *packet_payload = packet->payload;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+#if 0
+ printf("[len=%u][%02X %02X %02X %02X]\n", payload_len,
+ packet->payload[0] & 0xFF,
+ packet->payload[1] & 0xFF,
+ packet->payload[2] & 0xFF,
+ packet->payload[3] & 0xFF);
+#endif
+
+ if(packet->udp != NULL) {
+ struct radius_header *h = (struct radius_header*)packet->payload;
+ u_int len = ntohs(h->len);
+
+ if((payload_len > sizeof(struct radius_header))
+ && (h->code > 0)
+ && (h->code <= 5)
+ && (len == payload_len)) {
+ NDPI_LOG(NDPI_PROTOCOL_RADIUS, ndpi_struct, NDPI_LOG_DEBUG, "Found radius.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RADIUS, NDPI_REAL_PROTOCOL);
+
+ return;
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RADIUS);
+ return;
+ }
+}
+
+void ndpi_search_radius(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_RADIUS, ndpi_struct, NDPI_LOG_DEBUG, "radius detection...\n");
+
+ /* skip marked packets */
+ if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_RADIUS)
+ ndpi_check_radius(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/rdp.c b/src/lib/protocols/rdp.c
new file mode 100644
index 000000000..02bbb86e5
--- /dev/null
+++ b/src/lib/protocols/rdp.c
@@ -0,0 +1,56 @@
+/*
+ * rdp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_RDP
+
+static void ndpi_int_rdp_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RDP, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_rdp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len > 10
+ && get_u_int8_t(packet->payload, 0) > 0
+ && get_u_int8_t(packet->payload, 0) < 4 && get_u_int16_t(packet->payload, 2) == ntohs(packet->payload_packet_len)
+ && get_u_int8_t(packet->payload, 4) == packet->payload_packet_len - 5
+ && get_u_int8_t(packet->payload, 5) == 0xe0
+ && get_u_int16_t(packet->payload, 6) == 0 && get_u_int16_t(packet->payload, 8) == 0 && get_u_int8_t(packet->payload, 10) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_RDP, ndpi_struct, NDPI_LOG_DEBUG, "RDP detected.\n");
+ ndpi_int_rdp_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RDP);
+}
+
+#endif
diff --git a/src/lib/protocols/redis.c b/src/lib/protocols/redis.c
new file mode 100644
index 000000000..a47778b48
--- /dev/null
+++ b/src/lib/protocols/redis.c
@@ -0,0 +1,92 @@
+/*
+ * redis.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_REDIS
+
+static void ndpi_int_redis_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_REDIS, NDPI_REAL_PROTOCOL);
+}
+
+
+static void ndpi_check_redis(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ if(payload_len == 0) return; /* Shouldn't happen */
+
+ /* Break after 20 packets. */
+ if(flow->packet_counter > 20) {
+ NDPI_LOG(NDPI_PROTOCOL_REDIS, ndpi_struct, NDPI_LOG_DEBUG, "Exclude Redis.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_REDIS);
+ return;
+ }
+
+ if(packet->packet_direction == 0)
+ flow->redis_s2d_first_char = packet->payload[0];
+ else
+ flow->redis_d2s_first_char = packet->payload[0];
+
+ if((flow->redis_s2d_first_char != '\0') && (flow->redis_d2s_first_char != '\0')) {
+ /*
+ *1
+ $4
+ PING
+ +PONG
+ *3
+ $3
+ SET
+ $19
+ dns.cache.127.0.0.1
+ $9
+ localhost
+ +OK
+ */
+
+ if(((flow->redis_s2d_first_char == '*')
+ && ((flow->redis_d2s_first_char == '+') || (flow->redis_d2s_first_char == ':')))
+ || ((flow->redis_d2s_first_char == '*')
+ && ((flow->redis_s2d_first_char == '+') || (flow->redis_s2d_first_char == ':')))) {
+ NDPI_LOG(NDPI_PROTOCOL_REDIS, ndpi_struct, NDPI_LOG_DEBUG, "Found Redis.\n");
+ ndpi_int_redis_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_REDIS, ndpi_struct, NDPI_LOG_DEBUG, "Exclude Redis.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_REDIS);
+ }
+ } else
+ return; /* Too early */
+}
+
+void ndpi_search_redis(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_REDIS, ndpi_struct, NDPI_LOG_DEBUG, "Redis detection...\n");
+
+ /* skip marked packets */
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_REDIS) {
+ if (packet->tcp_retransmission == 0) {
+ ndpi_check_redis(ndpi_struct, flow);
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/rsync.c b/src/lib/protocols/rsync.c
new file mode 100644
index 000000000..7caa09e0a
--- /dev/null
+++ b/src/lib/protocols/rsync.c
@@ -0,0 +1,56 @@
+/*
+ * rsync.c
+ *
+ * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ *
+ * This module is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+
+#ifdef NDPI_PROTOCOL_RSYNC
+static void ndpi_int_rsync_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RSYNC, NDPI_CORRELATED_PROTOCOL);
+}
+
+void ndpi_search_rsync(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_RSYNC, ndpi_struct, NDPI_LOG_DEBUG, "search for RSYNC.\n");
+
+ if(packet->tcp != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_RSYNC, ndpi_struct, NDPI_LOG_DEBUG, "calculating RSYNC over tcp.\n");
+ /*
+ * Should match: memcmp(packet->payload, "@RSYN NCD: 28", 14) == 0)
+ */
+ if (packet->payload_packet_len == 12 && packet->payload[0] == 0x40 &&
+ packet->payload[1] == 0x52 && packet->payload[2] == 0x53 &&
+ packet->payload[3] == 0x59 && packet->payload[4] == 0x4e &&
+ packet->payload[5] == 0x43 && packet->payload[6] == 0x44 &&
+ packet->payload[7] == 0x3a ) {
+ NDPI_LOG(NDPI_PROTOCOL_RSYNC, ndpi_struct, NDPI_LOG_DEBUG, "found rsync.\n");
+ ndpi_int_rsync_add_connection(ndpi_struct, flow);
+ }
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_RSYNC, ndpi_struct, NDPI_LOG_DEBUG, "exclude RSYNC.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RSYNC);
+ }
+}
+#endif
diff --git a/src/lib/protocols/rtcp.c b/src/lib/protocols/rtcp.c
new file mode 100644
index 000000000..02875648a
--- /dev/null
+++ b/src/lib/protocols/rtcp.c
@@ -0,0 +1,52 @@
+/*
+ * rtcp.c (RTP Control Protocol)
+ *
+ * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_RTCP
+static void ndpi_int_rtcp_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTCP, NDPI_CORRELATED_PROTOCOL);
+}
+
+void ndpi_search_rtcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t dport = 0, sport = 0;
+
+ NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "search for RTCP.\n");
+
+ if(packet->tcp != NULL) {
+ sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
+ NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over tcp.\n");
+
+ if(packet->payload_packet_len > 13 && (sport == 554 || dport == 554) &&
+ packet->payload[0] == 0x00 && packet->payload[1] == 0x00 &&
+ packet->payload[2] == 0x01 && packet->payload[3] == 0x01 &&
+ packet->payload[4] == 0x08 && packet->payload[5] == 0x0a &&
+ packet->payload[6] == 0x00 && packet->payload[7] == 0x01) {
+ NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "found rtcp.\n");
+ ndpi_int_rtcp_add_connection(ndpi_struct, flow);
+ }
+ } else if(packet->udp != NULL) {
+ sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest);
+ NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over udp.\n");
+ if(((packet->payload_packet_len >= 28 || packet->payload_packet_len <= 1200) &&
+ ((packet->payload[0] == 0x80) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9)) && (packet->payload[2] == 0x00)))
+ || (((packet->payload[0] == 0x81) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9))
+ && (packet->payload[2] == 0x00)))) {
+ NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "found rtcp.\n");
+ ndpi_int_rtcp_add_connection(ndpi_struct, flow);
+ }
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "exclude RTCP.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTCP);
+ }
+}
+#endif
diff --git a/src/lib/protocols/rtmp.c b/src/lib/protocols/rtmp.c
new file mode 100644
index 000000000..6ebb5ebf2
--- /dev/null
+++ b/src/lib/protocols/rtmp.c
@@ -0,0 +1,92 @@
+/*
+ * rtmp.c
+ *
+ * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
+ *
+ * The signature is based on the Libprotoident library.
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_RTMP
+static void ndpi_int_rtmp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTMP, NDPI_REAL_PROTOCOL);
+}
+
+static void ndpi_check_rtmp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Break after 20 packets. */
+ if (flow->packet_counter > 20) {
+ NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "Exclude RTMP.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTMP);
+ return;
+ }
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->rtmp_stage == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "RTMP stage 0: \n");
+
+ if ((payload_len >= 4) && ((packet->payload[0] == 0x03) || (packet->payload[0] == 0x06))) {
+ NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "Possible RTMP request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->rtmp_stage = packet->packet_direction + 1;
+ }
+
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "RTMP stage %u: \n", flow->rtmp_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->rtmp_stage - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len >= 4) && ((packet->payload[0] == 0x03) || (packet->payload[0] == 0x06) || (packet->payload[0] == 0x08) || (packet->payload[0] == 0x09) || (packet->payload[0] == 0x0a))) {
+ NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "Found RTMP.\n");
+ ndpi_int_rtmp_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to RTMP, resetting the stage to 0...\n");
+ flow->rtmp_stage = 0;
+ }
+
+ }
+}
+
+void ndpi_search_rtmp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "RTMP detection...\n");
+
+ /* skip marked packets */
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_RTMP) {
+ if (packet->tcp_retransmission == 0) {
+ ndpi_check_rtmp(ndpi_struct, flow);
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/rtp.c b/src/lib/protocols/rtp.c
new file mode 100644
index 000000000..1e1a82a8b
--- /dev/null
+++ b/src/lib/protocols/rtp.c
@@ -0,0 +1,325 @@
+/*
+ * rtp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_RTP
+
+
+static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ const u_int8_t * payload, const u_int16_t payload_len)
+{
+ //struct ndpi_packet_struct *packet = &flow->packet;
+ u_int8_t payload_type = payload[1] & 0x7F;
+ u_int32_t *ssid = (u_int32_t*)&payload[8];
+
+ /* Check whether this is an RTP flow */
+ if((payload_len >= 12)
+ && ((payload[0] & 0xFF) == 0x80) /* RTP magic byte[1] */
+ && ((payload_type < 72) || (payload_type > 76))
+ && (payload_type < 128 /* http://anonsvn.wireshark.org/wireshark/trunk/epan/dissectors/packet-rtp.c */)
+ && (*ssid != 0)
+ ) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "Found rtp.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTP, NDPI_REAL_PROTOCOL);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP);
+ }
+}
+
+void ndpi_search_rtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if((packet->udp != NULL)
+ && (ntohs(packet->udp->source) > 1023)
+ && (ntohs(packet->udp->dest) > 1023))
+ ndpi_rtp_search(ndpi_struct, flow, packet->payload, packet->payload_packet_len);
+}
+
+#if 0
+/* Original (messy) OpenDPI code */
+
+#define RTP_MAX_OUT_OF_ORDER 11
+
+static void ndpi_int_rtp_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTP, NDPI_REAL_PROTOCOL);
+}
+
+/*
+ * maintenance of current highest sequence number, cycle count, packet counter
+ * adapted from RFC3550 Appendix A.1
+ *
+ * In their formulation, it is not possible to represent "no packets sent yet". This is fixed here by defining
+ * baseseq to be the sequence number of the first packet minus 1 (in other words, the sequence number of the
+ * zeroth packet).
+ *
+ * Note: As described in the RFC, the number of packets received includes retransmitted packets.
+ * This means the "packets lost" count (seq_num-isn+1)-received can become negative.
+ *
+ * include_current_packet should be
+ * 1, if the current packet should count towards the total, or
+ * 0, if it it regarded as belonging to the previous reporting interval
+ */
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+void init_seq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
+ u_int8_t direction, u_int16_t seq, u_int8_t include_current_packet)
+{
+ flow->rtp_seqnum[direction] = seq;
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "rtp_seqnum[%u] = %u\n", direction, seq);
+}
+
+/* returns difference between old and new highest sequence number */
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+u_int16_t update_seq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
+ u_int8_t direction, u_int16_t seq)
+{
+ u_int16_t delta = seq - flow->rtp_seqnum[direction];
+
+
+ if (delta < RTP_MAX_OUT_OF_ORDER) { /* in order, with permissible gap */
+ flow->rtp_seqnum[direction] = seq;
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "rtp_seqnum[%u] = %u (increased by %u)\n",
+ direction, seq, delta);
+ return delta;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "retransmission (dir %u, seqnum %u)\n",
+ direction, seq);
+ return 0;
+ }
+}
+
+static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ const u_int8_t * payload, const u_int16_t payload_len)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ u_int8_t stage;
+ u_int16_t seqnum = ntohs(get_u_int16_t(payload, 2));
+
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "search rtp.\n");
+
+ if (payload_len == 4 && get_u_int32_t(packet->payload, 0) == 0 && flow->packet_counter < 8) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "need next packet, maybe ClearSea out calls.\n");
+ return;
+ }
+
+ if (payload_len == 5 && memcmp(payload, "hello", 5) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "need next packet, initial hello packet of SIP out calls.\n");
+ return;
+ }
+
+ if (payload_len == 1 && payload[0] == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "need next packet, payload_packet_len == 1 && payload[0] == 0.\n");
+ return;
+ }
+
+ if (payload_len == 3 && memcmp(payload, "png", 3) == 0) {
+ /* weird packet found in Ninja GlobalIP trace */
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "skipping packet with len = 3 and png payload.\n");
+ return;
+ }
+
+ if (payload_len < 12) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "minimal packet size for rtp packets: 12.\n");
+ goto exclude_rtp;
+ }
+
+ if (payload_len == 12 && get_u_int32_t(payload, 0) == 0 && get_u_int32_t(payload, 4) == 0 && get_u_int32_t(payload, 8) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "skipping packet with len = 12 and only 0-bytes.\n");
+ return;
+ }
+
+ if ((payload[0] & 0xc0) == 0xc0 || (payload[0] & 0xc0) == 0x40 || (payload[0] & 0xc0) == 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "version = 3 || 1 || 0, maybe first rtp packet.\n");
+ return;
+ }
+
+ if ((payload[0] & 0xc0) != 0x80) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct,
+ NDPI_LOG_DEBUG, "rtp version must be 2, first two bits of a packets must be 10.\n");
+ goto exclude_rtp;
+ }
+
+ /* rtp_payload_type are the last seven bits of the second byte */
+ if (flow->rtp_payload_type[packet->packet_direction] != (payload[1] & 0x7F)) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "payload_type has changed, reset stages.\n");
+ packet->packet_direction == 0 ? (flow->rtp_stage1 = 0) : (flow->rtp_stage2 = 0);
+ }
+ /* first bit of first byte is not part of payload_type */
+ flow->rtp_payload_type[packet->packet_direction] = payload[1] & 0x7F;
+
+ stage = (packet->packet_direction == 0 ? flow->rtp_stage1 : flow->rtp_stage2);
+
+ if (stage > 0) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct,
+ NDPI_LOG_DEBUG, "stage = %u.\n", packet->packet_direction == 0 ? flow->rtp_stage1 : flow->rtp_stage2);
+ if (flow->rtp_ssid[packet->packet_direction] != get_u_int32_t(payload, 8)) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "ssid has changed, goto exclude rtp.\n");
+ goto exclude_rtp;
+ }
+
+ if (seqnum == flow->rtp_seqnum[packet->packet_direction]) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "maybe \"retransmission\", need next packet.\n");
+ return;
+ } else if ((u_int16_t) (seqnum - flow->rtp_seqnum[packet->packet_direction]) < RTP_MAX_OUT_OF_ORDER) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "new packet has larger sequence number (within valid range)\n");
+ update_seq(ndpi_struct, flow, packet->packet_direction, seqnum);
+ } else if ((u_int16_t) (flow->rtp_seqnum[packet->packet_direction] - seqnum) < RTP_MAX_OUT_OF_ORDER) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "new packet has smaller sequence number (within valid range)\n");
+ init_seq(ndpi_struct, flow, packet->packet_direction, seqnum, 1);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "sequence number diff is too big, goto exclude rtp.\n");
+ goto exclude_rtp;
+ }
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct,
+ NDPI_LOG_DEBUG, "rtp_ssid[%u] = %u.\n", packet->packet_direction,
+ flow->rtp_ssid[packet->packet_direction]);
+ flow->rtp_ssid[packet->packet_direction] = get_u_int32_t(payload, 8);
+ if (flow->packet_counter < 3) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "packet_counter < 3, need next packet.\n");
+ }
+ init_seq(ndpi_struct, flow, packet->packet_direction, seqnum, 1);
+ }
+ if (seqnum <= 3) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct,
+ NDPI_LOG_DEBUG, "sequence_number = %u, too small, need next packet, return.\n", seqnum);
+ return;
+ }
+
+ if (stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "add connection I.\n");
+ ndpi_int_rtp_add_connection(ndpi_struct, flow);
+ } else {
+ packet->packet_direction == 0 ? flow->rtp_stage1++ : flow->rtp_stage2++;
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "stage[%u]++; need next packet.\n",
+ packet->packet_direction);
+ }
+ return;
+
+ exclude_rtp:
+#ifdef NDPI_PROTOCOL_STUN
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN
+ || packet->real_protocol_read_only == NDPI_PROTOCOL_STUN) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "STUN: is detected, need next packet.\n");
+ return;
+ }
+#endif /* NDPI_PROTOCOL_STUN */
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP);
+}
+
+
+void ndpi_search_rtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+ if (packet->udp) {
+ ndpi_rtp_search(ndpi_struct, flow, packet->payload, packet->payload_packet_len);
+ } else if (packet->tcp) {
+
+ /* skip special packets seen at yahoo traces */
+ if (packet->payload_packet_len >= 20 && ntohs(get_u_int16_t(packet->payload, 2)) + 20 == packet->payload_packet_len &&
+ packet->payload[0] == 0x90 && packet->payload[1] >= 0x01 && packet->payload[1] <= 0x07) {
+ if (flow->packet_counter == 2)
+ flow->l4.tcp.rtp_special_packets_seen = 1;
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
+ "skipping STUN-like, special yahoo packets with payload[0] == 0x90.\n");
+ return;
+ }
+#ifdef NDPI_PROTOCOL_STUN
+ /* TODO the rtp detection sometimes doesn't exclude rtp
+ * so for TCP flows only run the detection if STUN has been
+ * detected (or RTP is already detected)
+ * If flows will be seen which start directly with RTP
+ * we can remove this restriction
+ */
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN
+ || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_RTP) {
+
+ /* RTP may be encapsulated in TCP packets */
+
+ if (packet->payload_packet_len >= 2 && ntohs(get_u_int16_t(packet->payload, 0)) + 2 == packet->payload_packet_len) {
+
+ /* TODO there could be several RTP packets in a single TCP packet so maybe the detection could be
+ * improved by checking only the RTP packet of given length */
+
+ ndpi_rtp_search(ndpi_struct, flow, packet->payload + 2, packet->payload_packet_len - 2);
+
+ return;
+ }
+ }
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && flow->l4.tcp.rtp_special_packets_seen == 1) {
+
+ if (packet->payload_packet_len >= 4 && ntohl(get_u_int32_t(packet->payload, 0)) + 4 == packet->payload_packet_len) {
+
+ /* TODO there could be several RTP packets in a single TCP packet so maybe the detection could be
+ * improved by checking only the RTP packet of given length */
+
+ ndpi_rtp_search(ndpi_struct, flow, packet->payload + 4, packet->payload_packet_len - 4);
+
+ return;
+ }
+ }
+
+ if (NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct, flow, NDPI_PROTOCOL_STUN)) {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "STUN not yet excluded, need next packet.\n");
+ }
+#else
+ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP);
+#endif
+ }
+}
+#endif
+
+#endif /* NDPI_PROTOCOL_RTP */
+
diff --git a/src/lib/protocols/rtsp.c b/src/lib/protocols/rtsp.c
new file mode 100644
index 000000000..2614f0c6f
--- /dev/null
+++ b/src/lib/protocols/rtsp.c
@@ -0,0 +1,120 @@
+/*
+ * rtsp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_RTSP
+#ifndef NDPI_PROTOCOL_RTP
+#error RTSP requires RTP detection to work correctly
+#endif
+#ifndef NDPI_PROTOCOL_RTSP
+#error RTSP requires RTSP detection to work correctly
+#endif
+#ifndef NDPI_PROTOCOL_RDP
+#error RTSP requires RDP detection to work correctly
+#endif
+
+static void ndpi_int_rtsp_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTSP, protocol_type);
+}
+
+/* this function searches for a rtsp-"handshake" over tcp or udp. */
+void ndpi_search_rtsp_tcp_udp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_TRACE, "RTSP detection...\n");
+
+ if (flow->rtsprdt_stage == 0
+#ifdef NDPI_PROTOCOL_RTCP
+ && !(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_RTCP)
+#endif
+ ) {
+ flow->rtsprdt_stage = 1 + packet->packet_direction;
+ NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "maybe handshake 1; need next packet, return.\n");
+ return;
+ }
+
+ if (flow->packet_counter < 3 && flow->rtsprdt_stage == 1 + packet->packet_direction) {
+
+ NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "maybe handshake 2; need next packet.\n");
+ return;
+ }
+
+ if (packet->payload_packet_len > 20 && flow->rtsprdt_stage == 2 - packet->packet_direction) {
+ char buf[32] = { 0 };
+ u_int len = packet->payload_packet_len;
+
+ if(len >= (sizeof(buf)-1)) len = sizeof(buf)-1;
+ strncpy(buf, (const char*)packet->payload, len);
+
+ // RTSP Server Message
+ if((memcmp(packet->payload, "RTSP/1.0 ", 9) == 0)
+ || (strstr(buf, "rtsp://") != NULL)) {
+ NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_TRACE, "found RTSP/1.0 .\n");
+ if (dst != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_TRACE, "found dst.\n");
+ ndpi_packet_src_ip_get(packet, &dst->rtsp_ip_address);
+ dst->rtsp_timer = packet->tick_timestamp;
+ dst->rtsp_ts_set = 1;
+ }
+ if (src != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_TRACE, "found src.\n");
+ ndpi_packet_dst_ip_get(packet, &src->rtsp_ip_address);
+ src->rtsp_timer = packet->tick_timestamp;
+ src->rtsp_ts_set = 1;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_TRACE, "RTSP detected.\n");
+ flow->rtsp_control_flow = 1;
+ ndpi_int_rtsp_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ if (packet->udp != NULL && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN
+ && ((NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP) == 0)
+#ifdef NDPI_PROTOCOL_RTCP
+ || (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTCP) == 0)
+#endif
+ )) {
+ NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG,
+ "maybe RTSP RTP, RTSP RTCP, RDT; need next packet.\n");
+ return;
+ }
+
+
+ NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "didn't find handshake, exclude.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTSP);
+ return;
+}
+
+
+#endif
diff --git a/src/lib/protocols/sflow.c b/src/lib/protocols/sflow.c
new file mode 100644
index 000000000..980867634
--- /dev/null
+++ b/src/lib/protocols/sflow.c
@@ -0,0 +1,49 @@
+/*
+ * sflow.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_SFLOW
+
+static void ndpi_check_sflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // const u_int8_t *packet_payload = packet->payload;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ if((packet->udp != NULL)
+ && (payload_len >= 24)
+ /* Version */
+ && (packet->payload[0] == 0) && (packet->payload[1] == 0) && (packet->payload[2] == 0)
+ && ((packet->payload[3] == 2) || (packet->payload[3] == 5))) {
+ NDPI_LOG(NDPI_PROTOCOL_SFLOW, ndpi_struct, NDPI_LOG_DEBUG, "Found sflow.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SFLOW, NDPI_REAL_PROTOCOL);
+ return;
+ }
+}
+
+void ndpi_search_sflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ NDPI_LOG(NDPI_PROTOCOL_SFLOW, ndpi_struct, NDPI_LOG_DEBUG, "sflow detection...\n");
+ ndpi_check_sflow(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/shoutcast.c b/src/lib/protocols/shoutcast.c
new file mode 100644
index 000000000..f700db330
--- /dev/null
+++ b/src/lib/protocols/shoutcast.c
@@ -0,0 +1,107 @@
+/*
+ * shoutcast.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_SHOUTCAST
+
+static void ndpi_int_shoutcast_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SHOUTCAST, NDPI_CORRELATED_PROTOCOL);
+}
+
+void ndpi_search_shoutcast_tcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+ NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "search shoutcast.\n");
+
+ if (flow->packet_counter == 1) {
+/* this case in paul_upload_oddcast_002.pcap */
+ if (packet->payload_packet_len >= 6
+ && packet->payload_packet_len < 80 && memcmp(packet->payload, "123456", 6) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 1, \"123456\".\n");
+ return;
+ }
+ if (flow->packet_counter < 3
+#ifdef NDPI_PROTOCOL_HTTP
+ && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP
+#endif
+ ) {
+ NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG,
+ "http detected, need next packet for shoutcast detection.\n");
+ if (packet->payload_packet_len > 4
+ && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) != htonl(0x0d0a0d0a)) {
+ NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "segmented packet found.\n");
+ flow->l4.tcp.shoutcast_stage = 1 + packet->packet_direction;
+ }
+ return;
+ }
+
+
+ /* else
+ goto exclude_shoutcast; */
+
+ }
+ /* evtl. für asym detection noch User-Agent:Winamp dazunehmen. */
+ if (packet->payload_packet_len > 11 && memcmp(packet->payload, "ICY 200 OK\x0d\x0a", 12) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "found shoutcast by ICY 200 OK.\n");
+ ndpi_int_shoutcast_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (flow->l4.tcp.shoutcast_stage == 1 + packet->packet_direction
+ && flow->packet_direction_counter[packet->packet_direction] < 5) {
+ return;
+ }
+
+ if (flow->packet_counter == 2) {
+ if (packet->payload_packet_len == 2 && memcmp(packet->payload, "\x0d\x0a", 2) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 1 continuation.\n");
+ return;
+ } else if (packet->payload_packet_len > 3 && memcmp(&packet->payload[0], "OK2", 3) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 2, OK2 found.\n");
+ return;
+ } else
+ goto exclude_shoutcast;
+ } else if (flow->packet_counter == 3 || flow->packet_counter == 4) {
+ if (packet->payload_packet_len > 3 && memcmp(&packet->payload[0], "OK2", 3) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 2, OK2 found.\n");
+ return;
+ } else if (packet->payload_packet_len > 4 && memcmp(&packet->payload[0], "icy-", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast detected.\n");
+ ndpi_int_shoutcast_add_connection(ndpi_struct, flow);
+ return;
+ } else
+ goto exclude_shoutcast;
+ }
+
+ exclude_shoutcast:
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SHOUTCAST);
+ NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast excluded.\n");
+}
+#endif
diff --git a/src/lib/protocols/sip.c b/src/lib/protocols/sip.c
new file mode 100644
index 000000000..201d2b23f
--- /dev/null
+++ b/src/lib/protocols/sip.c
@@ -0,0 +1,200 @@
+/*
+ * sip.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_SIP
+static void ndpi_int_sip_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int8_t due_to_correlation)
+{
+
+ ndpi_int_add_connection(ndpi_struct, flow,
+ NDPI_PROTOCOL_SIP,
+ due_to_correlation ? NDPI_CORRELATED_PROTOCOL : NDPI_REAL_PROTOCOL);
+}
+
+
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+void ndpi_search_sip_handshake(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+ const u_int8_t *packet_payload = packet->payload;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+
+ if (payload_len > 4) {
+ /* search for STUN Turn ChannelData Prefix */
+ u_int16_t message_len = ntohs(get_u_int16_t(packet->payload, 2));
+ if (payload_len - 4 == message_len) {
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found STUN TURN ChannelData prefix.\n");
+ payload_len -= 4;
+ packet_payload += 4;
+ }
+ }
+#ifndef NDPI_PROTOCOL_YAHOO
+ if (payload_len >= 14 && packet_payload[payload_len - 2] == 0x0d && packet_payload[payload_len - 1] == 0x0a)
+#endif
+#ifdef NDPI_PROTOCOL_YAHOO
+ if (payload_len >= 14)
+#endif
+ {
+
+ if ((memcmp(packet_payload, "NOTIFY ", 7) == 0 || memcmp(packet_payload, "notify ", 7) == 0)
+ && (memcmp(&packet_payload[7], "SIP:", 4) == 0 || memcmp(&packet_payload[7], "sip:", 4) == 0)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip NOTIFY.\n");
+ ndpi_int_sip_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+
+ if ((memcmp(packet_payload, "REGISTER ", 9) == 0 || memcmp(packet_payload, "register ", 9) == 0)
+ && (memcmp(&packet_payload[9], "SIP:", 4) == 0 || memcmp(&packet_payload[9], "sip:", 4) == 0)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip REGISTER.\n");
+ ndpi_int_sip_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+
+ if ((memcmp(packet_payload, "INVITE ", 7) == 0 || memcmp(packet_payload, "invite ", 7) == 0)
+ && (memcmp(&packet_payload[7], "SIP:", 4) == 0 || memcmp(&packet_payload[7], "sip:", 4) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip INVITE.\n");
+ ndpi_int_sip_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+
+ /* seen this in second direction on the third position,
+ * maybe it could be deleted, if somebody sees it in the first direction,
+ * please delete this comment.
+ */
+
+ /*
+ if (memcmp(packet_payload, "SIP/2.0 200 OK", 14) == 0 || memcmp(packet_payload, "sip/2.0 200 OK", 14) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip SIP/2.0 0K.\n");
+ ndpi_int_sip_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+ */
+ if (memcmp(packet_payload, "SIP/2.0 ", 8) == 0 || memcmp(packet_payload, "sip/2.0 ", 8) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip SIP/2.0 *.\n");
+ ndpi_int_sip_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+
+ if ((memcmp(packet_payload, "BYE ", 4) == 0 || memcmp(packet_payload, "bye ", 4) == 0)
+ && (memcmp(&packet_payload[4], "SIP:", 4) == 0 || memcmp(&packet_payload[4], "sip:", 4) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip BYE.\n");
+ ndpi_int_sip_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+
+ if ((memcmp(packet_payload, "ACK ", 4) == 0 || memcmp(packet_payload, "ack ", 4) == 0)
+ && (memcmp(&packet_payload[4], "SIP:", 4) == 0 || memcmp(&packet_payload[4], "sip:", 4) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip ACK.\n");
+ ndpi_int_sip_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+
+ if ((memcmp(packet_payload, "CANCEL ", 7) == 0 || memcmp(packet_payload, "cancel ", 7) == 0)
+ && (memcmp(&packet_payload[4], "SIP:", 7) == 0 || memcmp(&packet_payload[4], "sip:", 7) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip CANCEL.\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)
+ && (memcmp(&packet_payload[8], "SIP:", 4) == 0
+ || memcmp(&packet_payload[8], "sip:", 4) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip OPTIONS.\n");
+ ndpi_int_sip_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+ }
+
+ /* add bitmask for tcp only, some stupid udp programs
+ * send a very few (< 10 ) packets before invite (mostly a 0x0a0x0d, but just search the first 3 payload_packets here */
+ if (packet->udp != NULL && flow->packet_counter < 20) {
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "need next packet.\n");
+ return;
+ }
+#ifdef NDPI_PROTOCOL_STUN
+ /* for STUN flows we need some more packets */
+ if (packet->udp != NULL && flow->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN && flow->packet_counter < 40) {
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "need next STUN packet.\n");
+ return;
+ }
+#endif
+
+ if (payload_len == 4 && get_u_int32_t(packet_payload, 0) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "maybe sip. need next packet.\n");
+ return;
+ }
+#ifdef NDPI_PROTOCOL_YAHOO
+ if (payload_len > 30 && packet_payload[0] == 0x90
+ && packet_payload[3] == payload_len - 20 && get_u_int32_t(packet_payload, 4) == 0
+ && get_u_int32_t(packet_payload, 8) == 0) {
+ flow->sip_yahoo_voice = 1;
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "maybe sip yahoo. need next packet.\n");
+ }
+ if (flow->sip_yahoo_voice && flow->packet_counter < 10) {
+ return;
+ }
+#endif
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "exclude sip.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SIP);
+ return;
+
+
+}
+
+void ndpi_search_sip(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // struct ndpi_flow_struct *flow = ndpi_struct->flow;
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "sip detection...\n");
+
+ /* skip marked packets */
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SIP) {
+ if (packet->tcp_retransmission == 0) {
+ ndpi_search_sip_handshake(ndpi_struct, flow);
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/skinny.c b/src/lib/protocols/skinny.c
new file mode 100644
index 000000000..5e35f11f5
--- /dev/null
+++ b/src/lib/protocols/skinny.c
@@ -0,0 +1,63 @@
+/*
+ * skinny.c
+ *
+ * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ *
+ * This module is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+
+#ifdef NDPI_PROTOCOL_SKINNY
+static void ndpi_int_skinny_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKINNY, NDPI_CORRELATED_PROTOCOL);
+}
+
+void ndpi_search_skinny(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t dport = 0, sport = 0;
+ const char pattern_9_bytes[9] = { 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ const char pattern_8_bytes[8] = { 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ const char keypadmsg_8_bytes[8] = { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ const char selectmsg_8_bytes[8] = { 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ NDPI_LOG(NDPI_PROTOCOL_SKINNY, ndpi_struct, NDPI_LOG_DEBUG, "search for SKINNY.\n");
+
+ if(packet->tcp != NULL) {
+ sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
+ NDPI_LOG(NDPI_PROTOCOL_SKINNY, ndpi_struct, NDPI_LOG_DEBUG, "calculating SKINNY over tcp.\n");
+ if (dport == 2000 && ((packet->payload_packet_len == 24 &&
+ memcmp(&packet->payload[0], keypadmsg_8_bytes, 8) == 0)
+ || ((packet->payload_packet_len == 64) && memcmp(&packet->payload[0], pattern_8_bytes, 8) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_SKINNY, ndpi_struct, NDPI_LOG_DEBUG, "found skinny.\n");
+ ndpi_int_skinny_add_connection(ndpi_struct, flow);
+ } else if (sport == 2000 && ((packet->payload_packet_len == 28 &&
+ memcmp(&packet->payload[0], selectmsg_8_bytes, 8) == 0 ) ||
+ (packet->payload_packet_len == 44 &&
+ memcmp(&packet->payload[0], pattern_9_bytes, 9) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_SKINNY, ndpi_struct, NDPI_LOG_DEBUG, "found skinny.\n");
+ ndpi_int_skinny_add_connection(ndpi_struct, flow);
+ }
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_SKINNY, ndpi_struct, NDPI_LOG_DEBUG, "exclude SKINNY.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SKINNY);
+ }
+}
+#endif
diff --git a/src/lib/protocols/skype.c b/src/lib/protocols/skype.c
new file mode 100644
index 000000000..8d2a3a72b
--- /dev/null
+++ b/src/lib/protocols/skype.c
@@ -0,0 +1,122 @@
+/*
+ * skype.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_SKYPE
+
+
+static u_int8_t is_skype_host(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t host) {
+ struct in_addr pin;
+
+ pin.s_addr = host;
+
+ return((ndpi_network_ptree_match(ndpi_struct, &pin) == NDPI_PROTOCOL_SKYPE) ? 1 : 0);
+}
+
+u_int8_t is_skype_flow(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(packet->iph) {
+ /*
+ Skype connections are identified by some SSL-like communications
+ without SSL certificate being exchanged
+ */
+ if(is_skype_host(ndpi_struct, ntohl(packet->iph->saddr))
+ || is_skype_host(ndpi_struct, ntohl(packet->iph->daddr))) {
+ return(1);
+ }
+ }
+
+ return(0);
+}
+
+static void ndpi_check_skype(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // const u_int8_t *packet_payload = packet->payload;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /*
+ Skype AS8220
+ 212.161.8.0/24
+ */
+ if(is_skype_flow(ndpi_struct, flow)) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ if(packet->udp != NULL) {
+ flow->l4.udp.skype_packet_id++;
+
+ if(flow->l4.udp.skype_packet_id < 5) {
+ /* skype-to-skype */
+ if(((payload_len == 3) && ((packet->payload[2] & 0x0F)== 0x0d))
+ || ((payload_len >= 16)
+ && (packet->payload[0] != 0x30) /* Avoid invalid SNMP detection */
+ && (packet->payload[2] == 0x02))) {
+ NDPI_LOG(NDPI_PROTOCOL_SKYPE, ndpi_struct, NDPI_LOG_DEBUG, "Found skype.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE, NDPI_REAL_PROTOCOL);
+ }
+
+ return;
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SKYPE);
+ return;
+ } else if(packet->tcp != NULL) {
+ flow->l4.tcp.skype_packet_id++;
+
+ if(flow->l4.tcp.skype_packet_id < 3) {
+ ; /* Too early */
+ } else if((flow->l4.tcp.skype_packet_id == 3)
+ /* We have seen the 3-way handshake */
+ && flow->l4.tcp.seen_syn
+ && flow->l4.tcp.seen_syn_ack
+ && flow->l4.tcp.seen_ack) {
+ if((payload_len == 8) || (payload_len == 3)) {
+ //printf("[SKYPE] %u/%u\n", ntohs(packet->tcp->source), ntohs(packet->tcp->dest));
+
+ NDPI_LOG(NDPI_PROTOCOL_SKYPE, ndpi_struct, NDPI_LOG_DEBUG, "Found skype.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE, NDPI_REAL_PROTOCOL);
+ }
+
+ /* printf("[SKYPE] [id: %u][len: %d]\n", flow->l4.tcp.skype_packet_id, payload_len); */
+ } else
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SKYPE);
+
+ return;
+ }
+}
+
+void ndpi_search_skype(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_SKYPE, ndpi_struct, NDPI_LOG_DEBUG, "skype detection...\n");
+
+ /* skip marked packets */
+ if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SKYPE)
+ ndpi_check_skype(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/smb.c b/src/lib/protocols/smb.c
new file mode 100644
index 000000000..031572ead
--- /dev/null
+++ b/src/lib/protocols/smb.c
@@ -0,0 +1,57 @@
+/*
+ * smb.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_SMB
+
+static void ndpi_int_smb_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SMB, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_smb_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(packet && packet->tcp) {
+ NDPI_LOG(NDPI_PROTOCOL_SMB, ndpi_struct, NDPI_LOG_DEBUG, "search SMB.\n");
+
+ if (packet->tcp->dest == htons(445)
+ && packet->payload_packet_len > (32 + 4 + 4)
+ && (packet->payload_packet_len - 4) == ntohl(get_u_int32_t(packet->payload, 0))
+ && get_u_int32_t(packet->payload, 4) == htonl(0xff534d42)) {
+ NDPI_LOG(NDPI_PROTOCOL_SMB, ndpi_struct, NDPI_LOG_DEBUG, "found SMB.\n");
+ ndpi_int_smb_add_connection(ndpi_struct, flow);
+ return;
+
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_SMB, ndpi_struct, NDPI_LOG_DEBUG, "exclude SMB.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SMB);
+}
+
+#endif
diff --git a/src/lib/protocols/snmp.c b/src/lib/protocols/snmp.c
new file mode 100644
index 000000000..2ddf21229
--- /dev/null
+++ b/src/lib/protocols/snmp.c
@@ -0,0 +1,126 @@
+/*
+ * snmp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_SNMP
+
+static void ndpi_int_snmp_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SNMP, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_snmp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len > 32 && packet->payload[0] == 0x30) {
+ int offset;
+ switch (packet->payload[1]) {
+ case 0x81:
+ offset = 3;
+ break;
+ case 0x82:
+ offset = 4;
+ break;
+ default:
+ if (packet->payload[1] > 0x82) {
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded, second byte is > 0x82\n");
+ goto excl;
+ }
+ offset = 2;
+ }
+
+ if (get_u_int16_t(packet->payload, offset) != htons(0x0201)) {
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded, 0x0201 pattern not found\n");
+ goto excl;
+ }
+
+ if (packet->payload[offset + 2] >= 0x04) {
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded, version > 3\n");
+ goto excl;
+ }
+
+ if (flow->l4.udp.snmp_stage == 0) {
+ if (packet->udp->dest == htons(161) || packet->udp->dest == htons(162)) {
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP detected due to port.\n");
+ ndpi_int_snmp_add_connection(ndpi_struct, flow);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP stage 0.\n");
+ if (packet->payload[offset + 2] == 3) {
+ flow->l4.udp.snmp_msg_id = ntohs(get_u_int32_t(packet->payload, offset + 8));
+ } else if (packet->payload[offset + 2] == 0) {
+ flow->l4.udp.snmp_msg_id = get_u_int8_t(packet->payload, offset + 15);
+ } else {
+ flow->l4.udp.snmp_msg_id = ntohs(get_u_int16_t(packet->payload, offset + 15));
+ }
+ flow->l4.udp.snmp_stage = 1 + packet->packet_direction;
+ return;
+ } else if (flow->l4.udp.snmp_stage == 1 + packet->packet_direction) {
+ if (packet->payload[offset + 2] == 0) {
+ if (flow->l4.udp.snmp_msg_id != get_u_int8_t(packet->payload, offset + 15) - 1) {
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG,
+ "SNMP v1 excluded, message ID doesn't match\n");
+ goto excl;
+ }
+ }
+ } else if (flow->l4.udp.snmp_stage == 2 - packet->packet_direction) {
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP stage 1-2.\n");
+ if (packet->payload[offset + 2] == 3) {
+ if (flow->l4.udp.snmp_msg_id != ntohs(get_u_int32_t(packet->payload, offset + 8))) {
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG,
+ "SNMP v3 excluded, message ID doesn't match\n");
+ goto excl;
+ }
+ } else if (packet->payload[offset + 2] == 0) {
+ if (flow->l4.udp.snmp_msg_id != get_u_int8_t(packet->payload, offset + 15)) {
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG,
+ "SNMP v1 excluded, message ID doesn't match\n");
+ goto excl;
+ }
+ } else {
+ if (flow->l4.udp.snmp_msg_id != ntohs(get_u_int16_t(packet->payload, offset + 15))) {
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG,
+ "SNMP v2 excluded, message ID doesn't match\n");
+ goto excl;
+ }
+ }
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP detected.\n");
+ ndpi_int_snmp_add_connection(ndpi_struct, flow);
+ return;
+ }
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded.\n");
+ }
+ excl:
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SNMP);
+
+}
+
+#endif
diff --git a/src/lib/protocols/socks4.c b/src/lib/protocols/socks4.c
new file mode 100644
index 000000000..e89f7050c
--- /dev/null
+++ b/src/lib/protocols/socks4.c
@@ -0,0 +1,96 @@
+/*
+ * socks4.c
+ *
+ * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
+ *
+ * The signature is based on the Libprotoident library.
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_SOCKS4
+static void ndpi_int_socks4_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SOCKS4, NDPI_REAL_PROTOCOL);
+}
+
+static void ndpi_check_socks4(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Break after 20 packets. */
+ if (flow->packet_counter > 20) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "Exclude SOCKS4.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOCKS4);
+ return;
+ }
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->socks4_stage == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS4 stage 0: \n");
+
+ /*Octets 3 and 4 contain the port number, port 80 and 25 for now. */
+ if ((payload_len == 9) &&
+ (((packet->payload[0] == 0x04) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x50))
+ ||
+ ((packet->payload[0] == 0x04) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x19)))) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "Possible SOCKS4 request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->socks4_stage = packet->packet_direction + 1;
+ }
+
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS4 stage %u: \n", flow->socks4_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->socks4_stage - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if (payload_len == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "Found SOCKS4.\n");
+ ndpi_int_socks4_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to SOCKS4, resetting the stage to 0...\n");
+ flow->socks4_stage = 0;
+ }
+
+ }
+}
+
+void ndpi_search_socks4(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS4 detection...\n");
+
+ /* skip marked packets */
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SOCKS4) {
+ if (packet->tcp_retransmission == 0) {
+ ndpi_check_socks4(ndpi_struct, flow);
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/socks5.c b/src/lib/protocols/socks5.c
new file mode 100644
index 000000000..7aa4c90a1
--- /dev/null
+++ b/src/lib/protocols/socks5.c
@@ -0,0 +1,92 @@
+/*
+ * socks5.c
+ *
+ * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
+ *
+ * The signature is based on the Libprotoident library.
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_SOCKS5
+static void ndpi_int_socks5_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SOCKS5, NDPI_REAL_PROTOCOL);
+}
+
+static void ndpi_check_socks5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Break after 20 packets. */
+ if (flow->packet_counter > 20) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "Exclude SOCKS5.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOCKS5);
+ return;
+ }
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->socks5_stage == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS5 stage 0: \n");
+
+ if ((payload_len == 3) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00)) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "Possible SOCKS5 request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->socks5_stage = packet->packet_direction + 1;
+ }
+
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS5 stage %u: \n", flow->socks5_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->socks5_stage - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len == 0) || ((payload_len == 2) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x00))) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "Found SOCKS5.\n");
+ ndpi_int_socks5_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to SOCKS5, resetting the stage to 0...\n");
+ flow->socks5_stage = 0;
+ }
+
+ }
+}
+
+void ndpi_search_socks5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS5 detection...\n");
+
+ /* skip marked packets */
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SOCKS5) {
+ if (packet->tcp_retransmission == 0) {
+ ndpi_check_socks5(ndpi_struct, flow);
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/socrates.c b/src/lib/protocols/socrates.c
new file mode 100644
index 000000000..c433580fc
--- /dev/null
+++ b/src/lib/protocols/socrates.c
@@ -0,0 +1,80 @@
+/*
+ * socrates.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_SOCRATES
+
+
+static void ndpi_socrates_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SOCRATES, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_socrates(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+
+ NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "search socrates.\n");
+ if (packet->udp != NULL) {
+ if (packet->payload_packet_len > 9 && packet->payload[0] == 0xfe
+ && packet->payload[packet->payload_packet_len - 1] == 0x05) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "found fe.\n");
+
+ NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "len match.\n");
+ if (memcmp(&packet->payload[2], "socrates", 8) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "found socrates udp.\n");
+ ndpi_socrates_add_connection(ndpi_struct, flow);
+ }
+
+ }
+ } else if (packet->tcp != NULL) {
+ if (packet->payload_packet_len > 13 && packet->payload[0] == 0xfe
+ && packet->payload[packet->payload_packet_len - 1] == 0x05) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "found fe.\n");
+ if (packet->payload_packet_len == ntohl(get_u_int32_t(packet->payload, 2))) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "len match.\n");
+ if (memcmp(&packet->payload[6], "socrates", 8) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "found socrates tcp.\n");
+ ndpi_socrates_add_connection(ndpi_struct, flow);
+ }
+ }
+ }
+ }
+
+
+
+
+ NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "exclude socrates.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOCRATES);
+}
+
+#endif
diff --git a/src/lib/protocols/sopcast.c b/src/lib/protocols/sopcast.c
new file mode 100644
index 000000000..363caba42
--- /dev/null
+++ b/src/lib/protocols/sopcast.c
@@ -0,0 +1,219 @@
+/*
+ * sopcast.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_SOPCAST
+
+
+static void ndpi_int_sopcast_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SOPCAST, NDPI_REAL_PROTOCOL);
+}
+
+/**
+ * this function checks for sopcast tcp pattern
+ *
+ * NOTE: if you add more patterns please keep the number of if levels
+ * low, it is already complex enough
+ */
+
+#if !defined(WIN32)
+ static inline
+#else
+__forceinline static
+#endif
+ u_int8_t ndpi_int_is_sopcast_tcp(const u_int8_t * payload, const u_int16_t payload_len)
+{
+ if (payload_len != 54)
+ return 0;
+
+ if (payload[2] != payload[3] - 4 && payload[2] != payload[3] + 4)
+ return 0;
+
+ if (payload[2] != payload[4] - 1 && payload[2] != payload[4] + 1)
+ return 0;
+
+ if (payload[25] != payload[25 + 16 - 1] + 1 && payload[25] != payload[25 + 16 - 1] - 1) {
+
+ if (payload[3] != payload[25] &&
+ payload[3] != payload[25] - 4 && payload[3] != payload[25] + 4 && payload[3] != payload[25] - 21) {
+ return 0;
+ }
+ }
+
+ if (payload[4] != payload[28] ||
+ payload[28] != payload[30] ||
+ payload[30] != payload[31] ||
+ get_u_int16_t(payload, 30) != get_u_int16_t(payload, 32) || get_u_int16_t(payload, 32) != get_u_int16_t(payload, 34)) {
+
+ if ((payload[2] != payload[5] - 1 && payload[2] != payload[5] + 1) ||
+ payload[2] != payload[25] ||
+ payload[4] != payload[28] ||
+ payload[4] != payload[31] ||
+ payload[4] != payload[32] ||
+ payload[4] != payload[33] ||
+ payload[4] != payload[34] ||
+ payload[4] != payload[35] || payload[4] != payload[30] || payload[2] != payload[36]) {
+ return 0;
+ }
+ }
+
+ if (payload[42] != payload[53])
+ return 0;
+
+ if (payload[45] != payload[46] + 1 && payload[45] != payload[46] - 1)
+ return 0;
+
+ if (payload[45] != payload[49] || payload[46] != payload[50] || payload[47] != payload[51])
+ return 0;
+
+ return 1;
+}
+
+static void ndpi_search_sopcast_tcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if (flow->packet_counter == 1 && packet->payload_packet_len == 54 && get_u_int16_t(packet->payload, 0) == ntohs(0x0036)) {
+ if (ndpi_int_is_sopcast_tcp(packet->payload, packet->payload_packet_len)) {
+ NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast TCP \n");
+ ndpi_int_sopcast_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "exclude sopcast TCP. \n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOPCAST);
+
+
+}
+
+static void ndpi_search_sopcast_udp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "search sopcast. \n");
+
+
+ if (packet->payload_packet_len == 52 && packet->payload[0] == 0xff
+ && packet->payload[1] == 0xff && packet->payload[2] == 0x01
+ && packet->payload[8] == 0x02 && packet->payload[9] == 0xff
+ && packet->payload[10] == 0x00 && packet->payload[11] == 0x2c
+ && packet->payload[12] == 0x00 && packet->payload[13] == 0x00 && packet->payload[14] == 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if I. \n");
+ ndpi_int_sopcast_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if ((packet->payload_packet_len == 80 || packet->payload_packet_len == 28 || packet->payload_packet_len == 94)
+ && packet->payload[0] == 0x00 && (packet->payload[2] == 0x02 || packet->payload[2] == 0x01)
+ && packet->payload[8] == 0x01 && packet->payload[9] == 0xff
+ && packet->payload[10] == 0x00 && packet->payload[11] == 0x14
+ && packet->payload[12] == 0x00 && packet->payload[13] == 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if II. \n");
+ ndpi_int_sopcast_add_connection(ndpi_struct, flow);
+ return;
+ }
+ /* this case has been seen once. Please revome this comment, if you see it another time */
+ if (packet->payload_packet_len == 60 && packet->payload[0] == 0x00
+ && packet->payload[2] == 0x01
+ && packet->payload[8] == 0x03 && packet->payload[9] == 0xff
+ && packet->payload[10] == 0x00 && packet->payload[11] == 0x34
+ && packet->payload[12] == 0x00 && packet->payload[13] == 0x00 && packet->payload[14] == 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if III. \n");
+ ndpi_int_sopcast_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len == 42 && packet->payload[0] == 0x00
+ && packet->payload[1] == 0x02 && packet->payload[2] == 0x01
+ && packet->payload[3] == 0x07 && packet->payload[4] == 0x03
+ && packet->payload[8] == 0x06
+ && packet->payload[9] == 0x01 && packet->payload[10] == 0x00
+ && packet->payload[11] == 0x22 && packet->payload[12] == 0x00 && packet->payload[13] == 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if IV. \n");
+ ndpi_int_sopcast_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len == 28 && packet->payload[0] == 0x00
+ && packet->payload[1] == 0x0c && packet->payload[2] == 0x01
+ && packet->payload[3] == 0x07 && packet->payload[4] == 0x00
+ && packet->payload[8] == 0x01
+ && packet->payload[9] == 0x01 && packet->payload[10] == 0x00
+ && packet->payload[11] == 0x14 && packet->payload[12] == 0x00 && packet->payload[13] == 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if V. \n");
+ ndpi_int_sopcast_add_connection(ndpi_struct, flow);
+ return;
+ }
+ /* this case has been seen once. Please revome this comment, if you see it another time */
+ if (packet->payload_packet_len == 286 && packet->payload[0] == 0x00
+ && packet->payload[1] == 0x02 && packet->payload[2] == 0x01
+ && packet->payload[3] == 0x07 && packet->payload[4] == 0x03
+ && packet->payload[8] == 0x06
+ && packet->payload[9] == 0x01 && packet->payload[10] == 0x01
+ && packet->payload[11] == 0x16 && packet->payload[12] == 0x00 && packet->payload[13] == 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if VI. \n");
+ ndpi_int_sopcast_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len == 76 && packet->payload[0] == 0xff
+ && packet->payload[1] == 0xff && packet->payload[2] == 0x01
+ && packet->payload[8] == 0x0c && packet->payload[9] == 0xff
+ && packet->payload[10] == 0x00 && packet->payload[11] == 0x44
+ && packet->payload[16] == 0x01 && packet->payload[15] == 0x01
+ && packet->payload[12] == 0x00 && packet->payload[13] == 0x00 && packet->payload[14] == 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if VII. \n");
+ ndpi_int_sopcast_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ /* Attention please: no asymmetric detection necessary. This detection works asymmetrically as well. */
+
+ NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "exclude sopcast. \n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOPCAST);
+
+
+
+}
+
+void ndpi_search_sopcast(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if (packet->udp != NULL)
+ ndpi_search_sopcast_udp(ndpi_struct, flow);
+ if (packet->tcp != NULL)
+ ndpi_search_sopcast_tcp(ndpi_struct, flow);
+
+}
+#endif
diff --git a/src/lib/protocols/soulseek.c b/src/lib/protocols/soulseek.c
new file mode 100644
index 000000000..061acfa51
--- /dev/null
+++ b/src/lib/protocols/soulseek.c
@@ -0,0 +1,286 @@
+/*
+ * soulseek.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_SOULSEEK
+
+static void ndpi_int_soulseek_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SOULSEEK, NDPI_REAL_PROTOCOL);
+
+ if (src != NULL) {
+ src->soulseek_last_safe_access_time = packet->tick_timestamp;
+ }
+ if (dst != NULL) {
+ dst->soulseek_last_safe_access_time = packet->tick_timestamp;
+ }
+
+ return;
+}
+
+void ndpi_search_soulseek_tcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "Soulseek: search soulseec tcp \n");
+
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SOULSEEK) {
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "packet marked as Soulseek\n");
+ if (src != NULL)
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG,
+ " SRC bitmask: %u, packet tick %llu , last safe access timestamp: %llu\n",
+ NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_SOULSEEK)
+ != 0 ? 1 : 0, (u_int64_t) packet->tick_timestamp, (u_int64_t) src->soulseek_last_safe_access_time);
+ if (dst != NULL)
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG,
+ " DST bitmask: %u, packet tick %llu , last safe ts: %llu\n",
+ NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_SOULSEEK)
+ != 0 ? 1 : 0, (u_int64_t) packet->tick_timestamp, (u_int64_t) dst->soulseek_last_safe_access_time);
+
+ if (packet->payload_packet_len == 431) {
+ if (dst != NULL) {
+ dst->soulseek_last_safe_access_time = packet->tick_timestamp;
+ }
+ return;
+ }
+ if (packet->payload_packet_len == 12 && get_l32(packet->payload, 4) == 0x02) {
+ if (src != NULL) {
+ src->soulseek_last_safe_access_time = packet->tick_timestamp;
+ if (packet->tcp != NULL && src->soulseek_listen_port == 0) {
+ src->soulseek_listen_port = get_l32(packet->payload, 8);
+ return;
+ }
+ }
+ }
+
+ if (src != NULL && ((u_int32_t)
+ (packet->tick_timestamp -
+ src->soulseek_last_safe_access_time) <
+ ndpi_struct->soulseek_connection_ip_tick_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG,
+ "Soulseek: SRC update last safe access time and SKIP_FOR_TIME \n");
+ src->soulseek_last_safe_access_time = packet->tick_timestamp;
+ }
+
+ if (dst != NULL && ((u_int32_t)
+ (packet->tick_timestamp -
+ dst->soulseek_last_safe_access_time) <
+ ndpi_struct->soulseek_connection_ip_tick_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG,
+ "Soulseek: DST update last safe access time and SKIP_FOR_TIME \n");
+ dst->soulseek_last_safe_access_time = packet->tick_timestamp;
+ }
+ }
+
+
+ if (dst != NULL && dst->soulseek_listen_port != 0 && dst->soulseek_listen_port == ntohs(packet->tcp->dest)
+ && ((u_int32_t)
+ (packet->tick_timestamp - dst->soulseek_last_safe_access_time) <
+ ndpi_struct->soulseek_connection_ip_tick_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG,
+ "Soulseek: Plain detection on Port : %u packet_tick_timestamp: %u soulseeek_last_safe_access_time: %u soulseek_connection_ip_ticktimeout: %u\n",
+ dst->soulseek_listen_port, packet->tick_timestamp,
+ dst->soulseek_last_safe_access_time, ndpi_struct->soulseek_connection_ip_tick_timeout);
+ ndpi_int_soulseek_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ if (flow->l4.tcp.soulseek_stage == 0) {
+
+ u_int32_t index = 0;
+
+ if (packet->payload_packet_len >= 12 && packet->payload_packet_len < 300 && get_l32(packet->payload, 4) == 1) {
+ while (!get_u_int16_t(packet->payload, index + 2)
+ && (index + get_l32(packet->payload, index)) < packet->payload_packet_len - 4) {
+ if (get_l32(packet->payload, index) < 8) /*Minimum soulsek login msg is 8B */
+ break;
+
+ if (index + get_l32(packet->payload, index) + 4 <= index) {
+ /* avoid overflow */
+ break;
+ }
+
+ index += get_l32(packet->payload, index) + 4;
+ }
+ if (index + get_l32(packet->payload, index) ==
+ packet->payload_packet_len - 4 && !get_u_int16_t(packet->payload, 10)) {
+ /*This structure seems to be soulseek proto */
+ index = get_l32(packet->payload, 8) + 12; // end of "user name"
+ if ((index + 4) <= packet->payload_packet_len && !get_u_int16_t(packet->payload, index + 2)) // for passwd len
+ {
+ index += get_l32(packet->payload, index) + 4; //end of "Passwd"
+ if ((index + 4 + 4) <= packet->payload_packet_len && !get_u_int16_t(packet->payload, index + 6)) // to read version,hashlen
+ {
+ index += get_l32(packet->payload, index + 4) + 8; // enf of "hash value"
+ if (index == get_l32(packet->payload, 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK,
+ ndpi_struct, NDPI_LOG_DEBUG, "Soulseek Login Detected\n");
+ ndpi_int_soulseek_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+ }
+ }
+ if (packet->payload_packet_len > 8
+ && packet->payload_packet_len < 200 && get_l32(packet->payload, 0) == packet->payload_packet_len - 4) {
+ //Server Messages:
+ const u_int32_t msgcode = get_l32(packet->payload, 4);
+
+ if (msgcode == 0x7d) {
+ flow->l4.tcp.soulseek_stage = 1 + packet->packet_direction;
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "Soulseek Messages Search\n");
+ return;
+ } else if (msgcode == 0x02 && packet->payload_packet_len == 12) {
+ const u_int32_t soulseek_listen_port = get_l32(packet->payload, 8);
+
+ if (src != NULL) {
+ src->soulseek_last_safe_access_time = packet->tick_timestamp;
+
+ if (packet->tcp != NULL && src->soulseek_listen_port == 0) {
+ src->soulseek_listen_port = soulseek_listen_port;
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct,
+ NDPI_LOG_DEBUG, "\n Listen Port Saved : %u", src->soulseek_listen_port);
+ ndpi_int_soulseek_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ }
+ //Peer Messages : Peer Init Message Detection
+ if (get_l32(packet->payload, 0) == packet->payload_packet_len - 4) {
+ const u_int32_t typelen = get_l32(packet->payload, packet->payload_packet_len - 9);
+ const u_int8_t type = packet->payload[packet->payload_packet_len - 5];
+ const u_int32_t namelen = get_l32(packet->payload, 5);
+ if (packet->payload[4] == 0x01 && typelen == 1
+ && namelen <= packet->payload_packet_len
+ && (4 + 1 + 4 + namelen + 4 + 1 + 4) ==
+ packet->payload_packet_len && (type == 'F' || type == 'P' || type == 'D')) {
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected\n");
+ ndpi_int_soulseek_add_connection(ndpi_struct, flow);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "1\n");
+ }
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "3\n");
+ //Peer Message : Pierce Firewall
+ if (packet->payload_packet_len == 9 && get_l32(packet->payload, 0) == 5
+ && packet->payload[4] <= 0x10 && get_u_int32_t(packet->payload, 5) != 0x00000000) {
+ flow->l4.tcp.soulseek_stage = 1 + packet->packet_direction;
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_TRACE, "Soulseek Size 9 Pierce Firewall\n");
+ return;
+ }
+
+ }
+
+ if (packet->payload_packet_len > 25 && packet->payload[4] == 0x01 && !get_u_int16_t(packet->payload, 7)
+ && !get_u_int16_t(packet->payload, 2)) {
+ const u_int32_t usrlen = get_l32(packet->payload, 5);
+
+ if (usrlen <= packet->payload_packet_len - 4 + 1 + 4 + 4 + 1 + 4) {
+ const u_int32_t typelen = get_l32(packet->payload, 4 + 1 + 4 + usrlen);
+ const u_int8_t type = packet->payload[4 + 1 + 4 + usrlen + 4];
+ if (typelen == 1 && (type == 'F' || type == 'P' || type == 'D')) {
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct,
+ NDPI_LOG_DEBUG, "soulseek detected Pattern command(D|P|F).\n");
+ ndpi_int_soulseek_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+
+ } else if (flow->l4.tcp.soulseek_stage == 2 - packet->packet_direction) {
+ if (packet->payload_packet_len > 8) {
+ if ((packet->payload[0] || packet->payload[1]) && get_l32(packet->payload, 4) == 9) {
+ /* 9 is search result */
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected Second Pkt\n");
+ ndpi_int_soulseek_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (get_l32(packet->payload, 0) == packet->payload_packet_len - 4) {
+ const u_int32_t msgcode = get_l32(packet->payload, 4);
+ if (msgcode == 0x03 && packet->payload_packet_len >= 12) //Server Message : Get Peer Address
+ {
+ const u_int32_t usrlen = get_l32(packet->payload, 8);
+ if (usrlen <= packet->payload_packet_len && 4 + 4 + 4 + usrlen == packet->payload_packet_len) {
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct,
+ NDPI_LOG_DEBUG, "Soulseek Request Get Peer Address Detected\n");
+ ndpi_int_soulseek_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+ }
+
+ if (packet->payload_packet_len == 8 && get_l32(packet->payload, 4) == 0x00000004) {
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected\n");
+ ndpi_int_soulseek_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ if (packet->payload_packet_len == 4
+ && get_u_int16_t(packet->payload, 2) == 0x00 && get_u_int16_t(packet->payload, 0) != 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected\n");
+ ndpi_int_soulseek_add_connection(ndpi_struct, flow);
+ return;
+ } else if (packet->payload_packet_len == 4) {
+ flow->l4.tcp.soulseek_stage = 3;
+ return;
+ }
+ } else if (flow->l4.tcp.soulseek_stage == 1 + packet->packet_direction) {
+ if (packet->payload_packet_len > 8) {
+ if (packet->payload[4] == 0x03 && get_l32(packet->payload, 5) == 0x00000031) {
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct,
+ NDPI_LOG_DEBUG, "soulseek detected Second Pkt with SIGNATURE :: 0x0331000000 \n");
+ ndpi_int_soulseek_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+ if (flow->l4.tcp.soulseek_stage == 3 && packet->payload_packet_len == 8 && !get_u_int32_t(packet->payload, 4)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected bcz of 8B pkt\n");
+ ndpi_int_soulseek_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (flow->l4.tcp.soulseek_stage && flow->packet_counter < 11) {
+ } else {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOULSEEK);
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/spotify.c b/src/lib/protocols/spotify.c
new file mode 100644
index 000000000..43ed5ec92
--- /dev/null
+++ b/src/lib/protocols/spotify.c
@@ -0,0 +1,128 @@
+/*
+ * spotify.c
+ *
+ * Copyright (C) 2011-13 by ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_SPOTIFY
+static void ndpi_int_spotify_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int8_t due_to_correlation)
+{
+ ndpi_int_add_connection(ndpi_struct, flow,
+ NDPI_PROTOCOL_SPOTIFY,
+ due_to_correlation ? NDPI_CORRELATED_PROTOCOL : NDPI_REAL_PROTOCOL);
+}
+
+
+static void ndpi_check_spotify(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // const u_int8_t *packet_payload = packet->payload;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ if(packet->udp != NULL) {
+ u_int16_t spotify_port = htons(57621);
+
+ if((packet->udp->source == spotify_port)
+ && (packet->udp->dest == spotify_port)) {
+ if(payload_len > 2) {
+ if(memcmp(packet->payload, "SpotUdp", 7) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SPOTIFY, ndpi_struct, NDPI_LOG_DEBUG, "Found spotify udp dissector.\n");
+ ndpi_int_spotify_add_connection(ndpi_struct, flow, 0);
+ return;
+ }
+ }
+ }
+ } else if(packet->tcp != NULL) {
+
+ if(packet->payload[0] == 0x00 && packet->payload[1] == 0x04 &&
+ packet->payload[2] == 0x00 && packet->payload[3] == 0x00&&
+ packet->payload[6] == 0x52 && packet->payload[7] == 0x0e &&
+ packet->payload[8] == 0x50 ) {
+ NDPI_LOG(NDPI_PROTOCOL_SPOTIFY, ndpi_struct, NDPI_LOG_DEBUG, "Found spotify tcp dissector.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SPOTIFY, NDPI_REAL_PROTOCOL);
+ }
+
+
+ if(packet->iph /* IPv4 Only: we need to support packet->iphv6 at some point */) {
+ /* if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) */ {
+ /*
+ Spotify
+
+ 78.31.8.0 - 78.31.15.255 (78.31.8.0/22)
+ AS29017
+
+ 193.235.232.0 - 193.235.235.255 (193.235.232.0/22)
+ AS29017
+
+ 194.132.196.0 - 194.132.199.255 (194.132.198.147/22)
+ AS43650
+
+ 194.132.176.0 - 194.132.179.255 (194.132.176.0/22)
+ AS43650
+
+ 194.132.162.0 - 194.132.163.255 (194.132.162.0/24)
+ AS43650
+ */
+
+ //printf("%08X - %08X\n", ntohl(packet->iph->saddr), ntohl(packet->iph->daddr));
+ if(((ntohl(packet->iph->saddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0x4E1F0800 /* 78.31.8.0 */)
+ || ((ntohl(packet->iph->daddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0x4E1F0800 /* 78.31.8.0 */)
+ /* **** */
+ || ((ntohl(packet->iph->saddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC1EBE800 /* 193.235.232.0 */)
+ || ((ntohl(packet->iph->daddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC1EBE800 /* 193.235.232.0 */)
+ /* **** */
+ || ((ntohl(packet->iph->saddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC284C400 /* 194.132.196.0 */)
+ || ((ntohl(packet->iph->daddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC284C400 /* 194.132.196.0 */)
+ /* **** */
+ || ((ntohl(packet->iph->saddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC284A200 /* 194.132.162.0 */)
+ || ((ntohl(packet->iph->daddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC284A200 /* 194.132.162.0 */)
+ ) {
+ NDPI_LOG(NDPI_PROTOCOL_SPOTIFY, ndpi_struct, NDPI_LOG_DEBUG, "Found spotify via ip range.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SPOTIFY, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_SPOTIFY, ndpi_struct, NDPI_LOG_DEBUG, "exclude spotify.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SPOTIFY);
+}
+
+void ndpi_search_spotify(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_SPOTIFY, ndpi_struct, NDPI_LOG_DEBUG, "spotify detection...\n");
+
+ /* skip marked packets */
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SPOTIFY) {
+ if (packet->tcp_retransmission == 0) {
+ ndpi_check_spotify(ndpi_struct, flow);
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/ssdp.c b/src/lib/protocols/ssdp.c
new file mode 100644
index 000000000..83ce102d4
--- /dev/null
+++ b/src/lib/protocols/ssdp.c
@@ -0,0 +1,70 @@
+/*
+ * ssdp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_SSDP
+
+
+static void ndpi_int_ssdp_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSDP, NDPI_REAL_PROTOCOL);
+}
+
+/* this detection also works asymmetrically */
+void ndpi_search_ssdp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_SSDP, ndpi_struct, NDPI_LOG_DEBUG, "search ssdp.\n");
+ if (packet->udp != NULL) {
+
+ if (packet->payload_packet_len > 100) {
+ if ((memcmp(packet->payload, "M-SEARCH * HTTP/1.1", 19) == 0)
+ || memcmp(packet->payload, "NOTIFY * HTTP/1.1", 17) == 0) {
+
+
+ NDPI_LOG(NDPI_PROTOCOL_SSDP, ndpi_struct, NDPI_LOG_DEBUG, "found ssdp.\n");
+ ndpi_int_ssdp_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+#define SSDP_HTTP "HTTP/1.1 200 OK\r\n"
+ if(memcmp(packet->payload, SSDP_HTTP, strlen(SSDP_HTTP)) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SSDP, ndpi_struct, NDPI_LOG_DEBUG, "found ssdp.\n");
+ ndpi_int_ssdp_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_SSDP, ndpi_struct, NDPI_LOG_DEBUG, "ssdp excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSDP);
+}
+
+#endif
diff --git a/src/lib/protocols/ssh.c b/src/lib/protocols/ssh.c
new file mode 100644
index 000000000..f659294a2
--- /dev/null
+++ b/src/lib/protocols/ssh.c
@@ -0,0 +1,68 @@
+/*
+ * ssh.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_SSH
+
+static void ndpi_int_ssh_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSH, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+
+ if (flow->l4.tcp.ssh_stage == 0) {
+ if (packet->payload_packet_len > 7 && packet->payload_packet_len < 100
+ && memcmp(packet->payload, "SSH-", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SSH, ndpi_struct, NDPI_LOG_DEBUG, "ssh stage 0 passed\n");
+ flow->l4.tcp.ssh_stage = 1 + packet->packet_direction;
+ return;
+ }
+ } else if (flow->l4.tcp.ssh_stage == (2 - packet->packet_direction)) {
+ if (packet->payload_packet_len > 7 && packet->payload_packet_len < 100
+ && memcmp(packet->payload, "SSH-", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_SSH, ndpi_struct, NDPI_LOG_DEBUG, "found ssh\n");
+ ndpi_int_ssh_add_connection(ndpi_struct, flow);
+ return;
+
+ }
+
+
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_SSH, ndpi_struct, NDPI_LOG_DEBUG, "excluding ssh at stage %d\n", flow->l4.tcp.ssh_stage);
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSH);
+}
+
+#endif
diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c
new file mode 100644
index 000000000..c61c039c1
--- /dev/null
+++ b/src/lib/protocols/ssl.c
@@ -0,0 +1,637 @@
+/*
+ * ssl.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+// #define CERTIFICATE_DEBUG 1
+
+#ifdef NDPI_PROTOCOL_SSL
+
+#define NDPI_MAX_SSL_REQUEST_SIZE 10000
+
+/* Skype.c */
+extern u_int8_t is_skype_flow(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow);
+
+static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, u_int32_t protocol)
+{
+ if((protocol != NDPI_PROTOCOL_SSL)
+ && (protocol != NDPI_PROTOCOL_SSL_NO_CERT)) {
+ ndpi_int_add_connection(ndpi_struct, flow, protocol, NDPI_CORRELATED_PROTOCOL);
+ } else {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if((flow->protos.ssl.client_certificate[0] != '\0')
+ || (flow->protos.ssl.server_certificate[0] != '\0')
+ || (flow->host_server_name[0] != '\0'))
+ protocol = NDPI_PROTOCOL_SSL;
+ else
+ protocol = NDPI_PROTOCOL_SSL_NO_CERT;
+
+ if(packet->tcp != NULL) {
+ switch(protocol) {
+ case NDPI_PROTOCOL_SSL:
+ case NDPI_PROTOCOL_SSL_NO_CERT:
+ {
+ /*
+ In case of SSL there are probably sub-protocols
+ such as IMAPS that can be otherwise detected
+ */
+ u_int16_t sport = ntohs(packet->tcp->source);
+ u_int16_t dport = ntohs(packet->tcp->dest);
+
+ if((sport == 465) || (dport == 465)) protocol = NDPI_PROTOCOL_MAIL_SMTPS;
+ else if((sport == 993) || (dport == 993)) protocol = NDPI_PROTOCOL_MAIL_IMAPS;
+ else if((sport == 995) || (dport == 995)) protocol = NDPI_PROTOCOL_MAIL_POPS;
+ }
+ break;
+ }
+
+ if((protocol == NDPI_PROTOCOL_SSL_NO_CERT)
+ && is_skype_flow(ndpi_struct, flow)) {
+ protocol = NDPI_PROTOCOL_SKYPE;
+ }
+ }
+
+ ndpi_int_add_connection(ndpi_struct, flow, protocol, NDPI_REAL_PROTOCOL);
+ }
+}
+
+/* Can't call libc functions from kernel space, define some stub instead */
+
+#define ndpi_isalpha(ch) (((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z'))
+#define ndpi_isdigit(ch) ((ch) >= '0' && (ch) <= '9')
+#define ndpi_isspace(ch) (((ch) >= '\t' && (ch) <= '\r') || ((ch) == ' '))
+#define ndpi_isprint(ch) ((ch) >= 0x20 && (ch) <= 0x7e)
+#define ndpi_ispunct(ch) (((ch) >= '!' && (ch) <= '/') || \
+ ((ch) >= ':' && (ch) <= '@') || \
+ ((ch) >= '[' && (ch) <= '`') || \
+ ((ch) >= '{' && (ch) <= '~'))
+
+static void stripCertificateTrailer(char *buffer, int buffer_len) {
+ int i;
+
+ // printf("->%s<-\n", buffer);
+
+ for(i=0; i<buffer_len; i++) {
+ // printf("%c [%d]\n", buffer[i], buffer[i]);
+
+ if((buffer[i] != '.')
+ && (buffer[i] != '-')
+ && (buffer[i] != '*')
+ && (!ndpi_isalpha(buffer[i]))
+ && (!ndpi_isdigit(buffer[i]))) {
+ buffer[i] = '\0';
+ buffer_len = i;
+ break;
+ }
+ }
+
+ if(i > 0) i--;
+
+ while(i > 0) {
+ if(!ndpi_isalpha(buffer[i])) {
+ buffer[i] = '\0';
+ buffer_len = i;
+ i--;
+ } else
+ break;
+ }
+
+ for(i=buffer_len; i>0; i--) {
+ if(buffer[i] == '.') break;
+ else if(ndpi_isdigit(buffer[i]))
+ buffer[i] = '\0', buffer_len = i;
+ }
+}
+
+/* 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;
+
+ /*
+ Nothing matched so far: let's decode the certificate with some heuristics
+ Patches courtesy of Denys Fedoryshchenko <nuclearcat@nuclearcat.com>
+ */
+ if(packet->payload[0] == 0x16 /* Handshake */) {
+ 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 */
+
+ memset(buffer, 0, buffer_len);
+
+ /* Truncate total len, search at least in incomplete packet */
+ if (total_len > packet->payload_packet_len)
+ total_len = packet->payload_packet_len;
+
+ /* At least "magic" 3 bytes, null for string end, otherwise no need to waste cpu cycles */
+ if(total_len > 4) {
+ int i;
+
+ if(handshake_protocol == 0x02 || handshake_protocol == 0xb /* Server Hello and Certificate message types are interesting for us */) {
+ u_int num_found = 0;
+
+ flow->l4.tcp.ssl_seen_server_cert = 1;
+
+ /* Check after handshake protocol header (5 bytes) and message header (4 bytes) */
+ for(i = 9; i < packet->payload_packet_len-3; i++) {
+ if(((packet->payload[i] == 0x04) && (packet->payload[i+1] == 0x03) && (packet->payload[i+2] == 0x0c))
+ || ((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x03))) {
+ u_int8_t server_len = packet->payload[i+3];
+
+ if(packet->payload[i] == 0x55) {
+ num_found++;
+
+ if(num_found != 2) continue;
+ }
+
+ if(server_len+i+3 < packet->payload_packet_len) {
+ char *server_name = (char*)&packet->payload[i+4];
+ u_int8_t begin = 0, len, j, num_dots;
+
+ while(begin < server_len) {
+ if(!ndpi_isprint(server_name[begin]))
+ begin++;
+ else
+ break;
+ }
+
+ // len = ndpi_min(server_len-begin, buffer_len-1);
+ len = buffer_len-1;
+ strncpy(buffer, &server_name[begin], len);
+ buffer[len] = '\0';
+
+ /* We now have to check if this looks like an IP address or host name */
+ for(j=0, num_dots = 0; j<len; j++) {
+ if(!ndpi_isprint((buffer[j]))) {
+ num_dots = 0; /* This is not what we look for */
+ break;
+ } else if(buffer[j] == '.') {
+ num_dots++;
+ if(num_dots >=2) break;
+ }
+ }
+
+ if(num_dots >= 2) {
+ stripCertificateTrailer(buffer, buffer_len);
+ snprintf(flow->protos.ssl.server_certificate,
+ sizeof(flow->protos.ssl.server_certificate), "%s", buffer);
+ return(1 /* Server Certificate */);
+ }
+ }
+ }
+ }
+ } else if(handshake_protocol == 0x01 /* Client Hello */) {
+ u_int offset, base_offset = 43;
+ u_int16_t session_id_len = packet->payload[base_offset];
+
+ 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;
+
+ flow->l4.tcp.ssl_seen_client_cert = 1;
+
+ if(offset < total_len) {
+ u_int16_t compression_len;
+ u_int16_t extensions_len;
+
+ compression_len = packet->payload[offset+1];
+ offset += compression_len + 3;
+
+ if(offset < total_len) {
+ extensions_len = packet->payload[offset];
+
+ if((extensions_len+offset) < total_len) {
+ u_int16_t extension_offset = 1; /* Move to the first extension */
+
+ while(extension_offset < extensions_len) {
+ u_int16_t extension_id, extension_len;
+
+ memcpy(&extension_id, &packet->payload[offset+extension_offset], 2);
+ extension_offset += 2;
+
+ memcpy(&extension_len, &packet->payload[offset+extension_offset], 2);
+ extension_offset += 2;
+
+ extension_id = ntohs(extension_id), extension_len = ntohs(extension_len);
+
+ if(extension_id == 0) {
+ u_int begin = 0,len;
+ 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;
+ }
+
+ len = (u_int)ndpi_min(extension_len-begin, buffer_len-1);
+ strncpy(buffer, &server_name[begin], len);
+ buffer[len] = '\0';
+ stripCertificateTrailer(buffer, buffer_len);
+
+ snprintf(flow->protos.ssl.client_certificate,
+ sizeof(flow->protos.ssl.client_certificate), "%s", buffer);
+
+ /* We're happy now */
+ return(2 /* Client Certificate */);
+ }
+
+ extension_offset += extension_len;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return(0); /* Not found */
+}
+
+int sslDetectProtocolFromCertificate(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(!packet->iph /* IPv4 */) return(-1);
+
+ if((packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
+ || (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL)) {
+ char certificate[64];
+ int rc;
+
+ certificate[0] = '\0';
+ rc = getSSLcertificate(ndpi_struct, flow, certificate, sizeof(certificate));
+ packet->ssl_certificate_num_checks++;
+
+ if(rc > 0) {
+ packet->ssl_certificate_detected++;
+#ifdef CERTIFICATE_DEBUG
+ printf("***** [SSL] %s\n", certificate);
+#endif
+
+ if(ndpi_match_string_subprotocol(ndpi_struct, flow, certificate, strlen(certificate)) != NDPI_PROTOCOL_UNKNOWN)
+ return(rc); /* Fix courtesy of Gianluca Costa <g.costa@xplico.org> */
+
+#ifdef NDPI_PROTOCOL_TOR
+ if(ndpi_is_ssl_tor(ndpi_struct, flow, certificate) != 0)
+ return(rc);
+#endif
+ }
+
+ if(((packet->ssl_certificate_num_checks >= 2)
+ && flow->l4.tcp.seen_syn
+ && flow->l4.tcp.seen_syn_ack
+ && flow->l4.tcp.seen_ack /* We have seen the 3-way handshake */)
+ || (flow->protos.ssl.server_certificate[0] != '\0')
+ || (flow->protos.ssl.client_certificate[0] != '\0')
+ )
+ ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL);
+ }
+
+ return(0);
+}
+
+static void ssl_mark_and_payload_search_for_other_protocols(struct
+ ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+#if defined(NDPI_PROTOCOL_MEEBO)|| defined(NDPI_PROTOCOL_TOR) || defined(NDPI_PROTOCOL_VPN_X) || defined(NDPI_PROTOCOL_UNENCRYPED_JABBER) || defined (NDPI_PROTOCOL_OSCAR) || defined (NDPI_PROTOCOL_ITUNES) || defined (NDPI_SERVICE_GMAIL)
+ struct ndpi_packet_struct *packet = &flow->packet;
+ // struct ndpi_id_struct *src=flow->src;
+ // struct ndpi_id_struct *dst=flow->dst;
+ u_int32_t a;
+ u_int32_t end;
+#if defined(NDPI_PROTOCOL_UNENCRYPED_JABBER)
+ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0)
+ goto check_for_ssl_payload;
+#endif
+#if defined(NDPI_PROTOCOL_OSCAR)
+ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_OSCAR) != 0)
+ goto check_for_ssl_payload;
+#endif
+ goto no_check_for_ssl_payload;
+
+ check_for_ssl_payload:
+ end = packet->payload_packet_len - 20;
+ for (a = 5; a < end; a++) {
+#ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER
+ if (packet->payload[a] == 't') {
+ if (memcmp(&packet->payload[a], "talk.google.com", 15) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "ssl jabber packet match\n");
+ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK
+ (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) {
+ ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER);
+ return;
+ }
+ }
+ }
+#endif
+#ifdef NDPI_PROTOCOL_OSCAR
+ if (packet->payload[a] == 'A' || packet->payload[a] == 'k' || packet->payload[a] == 'c'
+ || packet->payload[a] == 'h') {
+ if (((a + 19) < packet->payload_packet_len && memcmp(&packet->payload[a], "America Online Inc.", 19) == 0)
+ // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 )
+ // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0)
+ || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0)
+ || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "corehc@aol.net", 14) == 0)
+ || ((a + 41) < packet->payload_packet_len
+ && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0)
+ || ((a + 28) < packet->payload_packet_len
+ && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0)
+ || ((a + 32) < packet->payload_packet_len
+ && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n");
+
+ if (flow->dst != NULL && packet->payload_packet_len > 75) {
+ memcpy(flow->dst->oscar_ssl_session_id, &packet->payload[44], 32);
+ flow->dst->oscar_ssl_session_id[32] = '\0';
+ flow->dst->oscar_last_safe_access_time = packet->tick_timestamp;
+ }
+
+ ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR);
+ return;
+ }
+ }
+
+ if (packet->payload[a] == 'm' || packet->payload[a] == 's') {
+ if ((a + 21) < packet->payload_packet_len &&
+ (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0
+ || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n");
+ ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR);
+ return;
+ }
+ }
+#endif
+ }
+
+ no_check_for_ssl_payload:
+#endif
+ if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "found ssl connection.\n");
+ sslDetectProtocolFromCertificate(ndpi_struct, flow);
+
+ if(!packet->ssl_certificate_detected
+ && (!(flow->l4.tcp.ssl_seen_client_cert && flow->l4.tcp.ssl_seen_server_cert))) {
+ /* SSL without certificate (Skype, Ultrasurf?) */
+ ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL_NO_CERT);
+ } else
+ ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL);
+ }
+}
+
+
+static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+ //
+ // struct ndpi_id_struct *src=flow->src;
+ // struct ndpi_id_struct *dst=flow->dst;
+
+
+ if ((packet->payload_packet_len >= 5)
+ && (packet->payload[0] == 0x16)
+ && (packet->payload[1] == 0x03)
+ && ((packet->payload[2] == 0x00)
+ || (packet->payload[2] == 0x01)
+ || (packet->payload[2] == 0x02)
+ || (packet->payload[2] == 0x03)
+ )) {
+ u_int32_t temp;
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search sslv3\n");
+ // SSLv3 Record
+ if (packet->payload_packet_len >= 1300) {
+ return 1;
+ }
+ temp = ntohs(get_u_int16_t(packet->payload, 3)) + 5;
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp);
+ if (packet->payload_packet_len == temp
+ || (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) {
+ return 1;
+ }
+
+ if (packet->payload_packet_len < temp && temp < 5000 && packet->payload_packet_len > 9) {
+ /* the server hello may be split into small packets */
+ u_int32_t cert_start;
+
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
+ "maybe SSLv3 server hello split into smaller packets\n");
+
+ /* lets hope at least the server hello and the start of the certificate block are in the first packet */
+ cert_start = ntohs(get_u_int16_t(packet->payload, 7)) + 5 + 4;
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "suspected start of certificate: %u\n",
+ cert_start);
+
+ if (cert_start < packet->payload_packet_len && packet->payload[cert_start] == 0x0b) {
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
+ "found 0x0b at suspected start of certificate block\n");
+ return 2;
+ }
+ }
+
+ if ((packet->payload_packet_len > temp && packet->payload_packet_len > 100) && packet->payload_packet_len > 9) {
+ /* the server hello may be split into small packets and the certificate has its own SSL Record
+ * so temp contains only the length for the first ServerHello block */
+ u_int32_t cert_start;
+
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
+ "maybe SSLv3 server hello split into smaller packets but with seperate record for the certificate\n");
+
+ /* lets hope at least the server hello record and the start of the certificate record are in the first packet */
+ cert_start = ntohs(get_u_int16_t(packet->payload, 7)) + 5 + 5 + 4;
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "suspected start of certificate: %u\n",
+ cert_start);
+
+ if (cert_start < packet->payload_packet_len && packet->payload[cert_start] == 0x0b) {
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
+ "found 0x0b at suspected start of certificate block\n");
+ return 2;
+ }
+ }
+
+
+ if (packet->payload_packet_len >= temp + 5 && (packet->payload[temp] == 0x14 || packet->payload[temp] == 0x16)
+ && packet->payload[temp + 1] == 0x03) {
+ u_int32_t temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5;
+ if (temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) {
+ return 1;
+ }
+ temp += temp2;
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp);
+ if (packet->payload_packet_len == temp) {
+ return 1;
+ }
+ if (packet->payload_packet_len >= temp + 5 &&
+ packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) {
+ temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5;
+ if (temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) {
+ return 1;
+ }
+ temp += temp2;
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp);
+ if (packet->payload_packet_len == temp) {
+ return 1;
+ }
+ if (packet->payload_packet_len >= temp + 5 &&
+ packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) {
+ temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5;
+ if (temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) {
+ return 1;
+ }
+ temp += temp2;
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp);
+ if (temp == packet->payload_packet_len) {
+ return 1;
+ }
+ }
+
+ }
+
+
+ }
+
+ }
+ return 0;
+
+}
+
+void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=flow->src;
+ // struct ndpi_id_struct *dst=flow->dst;
+
+ u_int8_t ret;
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) {
+ if (flow->l4.tcp.ssl_stage == 3 && packet->payload_packet_len > 20 && flow->packet_counter < 5) {
+ /* this should only happen, when we detected SSL with a packet that had parts of the certificate in subsequent packets
+ * so go on checking for certificate patterns for a couple more packets
+ */
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
+ "ssl flow but check another packet for patterns\n");
+ ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) {
+ /* still ssl so check another packet */
+ return;
+ } else {
+ /* protocol has changed so we are done */
+ return;
+ }
+ }
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search ssl\n");
+
+ {
+ /* Check if this is whatsapp first (this proto runs over port 443) */
+ if((packet->payload_packet_len > 5)
+ && ((packet->payload[0] == 'W')
+ && (packet->payload[1] == 'A')
+ && (packet->payload[4] == 0)
+ && (packet->payload[2] <= 9)
+ && (packet->payload[3] <= 9))) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_SERVICE_WHATSAPP, NDPI_REAL_PROTOCOL);
+ return;
+ } else {
+ /* 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(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "first ssl packet\n");
+ // SSLv2 Record
+ if (packet->payload[2] == 0x01 && packet->payload[3] == 0x03
+ && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
+ && (packet->payload_packet_len - packet->payload[1] == 2)) {
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 len match\n");
+ flow->l4.tcp.ssl_stage = 1 + packet->packet_direction;
+ return;
+ }
+
+ if (packet->payload[0] == 0x16 && packet->payload[1] == 0x03
+ && (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02)
+ && (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) {
+ // SSLv3 Record
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 len match\n");
+ flow->l4.tcp.ssl_stage = 1 + packet->packet_direction;
+ return;
+ }
+ }
+
+ if (packet->payload_packet_len > 40 &&
+ flow->l4.tcp.ssl_stage == 1 + packet->packet_direction
+ && flow->packet_direction_counter[packet->packet_direction] < 5) {
+ return;
+ }
+
+ if (packet->payload_packet_len > 40 && flow->l4.tcp.ssl_stage == 2 - packet->packet_direction) {
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "second ssl packet\n");
+ // SSLv2 Record
+ if (packet->payload[2] == 0x01 && packet->payload[3] == 0x03
+ && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
+ && (packet->payload_packet_len - 2) >= packet->payload[1]) {
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 server len match\n");
+ ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
+ return;
+ }
+
+ ret = ndpi_search_sslv3_direction1(ndpi_struct, flow);
+ if (ret == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 server len match\n");
+ ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
+ return;
+ } else if (ret == 2) {
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
+ "sslv3 server len match with split packet -> check some more packets for SSL patterns\n");
+ ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) {
+ flow->l4.tcp.ssl_stage = 3;
+ }
+ return;
+ }
+
+ if (packet->payload_packet_len > 40 && flow->packet_direction_counter[packet->packet_direction] < 5) {
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "need next packet\n");
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "exclude ssl\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSL);
+ return;
+}
+#endif
diff --git a/src/lib/protocols/stealthnet.c b/src/lib/protocols/stealthnet.c
new file mode 100644
index 000000000..e8f1778e6
--- /dev/null
+++ b/src/lib/protocols/stealthnet.c
@@ -0,0 +1,58 @@
+/*
+ * stealthnet.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_STEALTHNET
+
+
+static void ndpi_int_stealthnet_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_STEALTHNET, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_stealthnet(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+// struct ndpi_id_struct *src = flow->src;
+// struct ndpi_id_struct *dst = flow->dst;
+
+
+ if (packet->payload_packet_len > 40
+ && memcmp(packet->payload, "LARS REGENSBURGER'S FILE SHARING PROTOCOL", 41) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_STEALTHNET, ndpi_struct, NDPI_LOG_DEBUG, "found stealthnet\n");
+ ndpi_int_stealthnet_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_STEALTHNET, ndpi_struct, NDPI_LOG_DEBUG, "exclude stealthnet.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_STEALTHNET);
+
+}
+#endif
diff --git a/src/lib/protocols/steam.c b/src/lib/protocols/steam.c
new file mode 100644
index 000000000..7911df85a
--- /dev/null
+++ b/src/lib/protocols/steam.c
@@ -0,0 +1,286 @@
+/*
+ * steam.c
+ *
+ * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
+ *
+ * The signature is mostly based on the Libprotoident library
+ * except the detection of HTTP Steam flows.
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_STEAM
+static void ndpi_int_steam_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_STEAM, NDPI_REAL_PROTOCOL);
+}
+
+static void ndpi_check_steam_http(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if (packet->user_agent_line.ptr != NULL
+ && packet->user_agent_line.len >= 23
+ && memcmp(packet->user_agent_line.ptr, "Valve/Steam HTTP Client", 23) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
+ ndpi_int_steam_add_connection(ndpi_struct, flow);
+ }
+}
+
+static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ if (flow->steam_stage == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n");
+
+ if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && match_first_bytes(packet->payload, "\x01\x00\x00\x00")) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->steam_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
+ return;
+ }
+
+ if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->steam_stage = packet->packet_direction + 3; // packet_direction 0: stage 3, packet_direction 1: stage 4
+ return;
+ }
+ } else if ((flow->steam_stage == 1) || (flow->steam_stage == 2)) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->steam_stage - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
+ ndpi_int_steam_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n");
+ flow->steam_stage = 0;
+ }
+ } else if ((flow->steam_stage == 3) || (flow->steam_stage == 4)) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->steam_stage - packet->packet_direction) == 3) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && match_first_bytes(packet->payload, "\x01\x00\x00\x00")) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
+ ndpi_int_steam_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n");
+ flow->steam_stage = 0;
+ }
+ }
+}
+
+static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "VS01")) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
+ ndpi_int_steam_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->steam_stage1 == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n");
+
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "\x31\xff\x30\x2e")) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->steam_stage1 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
+ return;
+ }
+
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->steam_stage1 = packet->packet_direction + 3; // packet_direction 0: stage 3, packet_direction 1: stage 4
+ return;
+ }
+
+ } else if ((flow->steam_stage1 == 1) || (flow->steam_stage1 == 2)) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage1);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->steam_stage1 - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
+ ndpi_int_steam_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n");
+ flow->steam_stage1 = 0;
+ }
+
+ } else if ((flow->steam_stage1 == 3) || (flow->steam_stage1 == 4)) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage1);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->steam_stage1 - packet->packet_direction) == 3) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len > 0) && match_first_bytes(packet->payload, "\x31\xff\x30\x2e")) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
+ ndpi_int_steam_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n");
+ flow->steam_stage1 = 0;
+ }
+
+ }
+}
+
+static void ndpi_check_steam_udp2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->steam_stage2 == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n");
+
+ if ((payload_len == 25) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->steam_stage2 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
+ }
+
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage2);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->steam_stage2 - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len == 0) || match_first_bytes(packet->payload, "\xff\xff\xff\xff")) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
+ ndpi_int_steam_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n");
+ flow->steam_stage2 = 0;
+ }
+
+ }
+}
+
+static void ndpi_check_steam_udp3(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+
+ /* Check if we so far detected the protocol in the request or not. */
+ if (flow->steam_stage3 == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n");
+
+ if ((payload_len == 4) && (packet->payload[0] == 0x39) && (packet->payload[1] == 0x18) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x00)) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n");
+
+ /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
+ flow->steam_stage3 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
+ }
+
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage3);
+
+ /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
+ if ((flow->steam_stage3 - packet->packet_direction) == 1) {
+ return;
+ }
+
+ /* This is a packet in another direction. Check if we find the proper response. */
+ if ((payload_len == 0) || ((payload_len == 8) && (packet->payload[0] == 0x3a) && (packet->payload[1] == 0x18) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x00))) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
+ ndpi_int_steam_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n");
+ flow->steam_stage3 = 0;
+ }
+
+ }
+}
+
+void ndpi_search_steam(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ /* Break after 20 packets. */
+ if (flow->packet_counter > 20) {
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Exclude STEAM.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_STEAM);
+ return;
+ }
+
+ /* skip marked or retransmitted packets */
+ if (packet->tcp_retransmission != 0) {
+ return;
+ }
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) {
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM detection...\n");
+ ndpi_check_steam_http(ndpi_struct, flow);
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) {
+ return;
+ }
+
+ ndpi_check_steam_tcp(ndpi_struct, flow);
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) {
+ return;
+ }
+
+ ndpi_check_steam_udp1(ndpi_struct, flow);
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) {
+ return;
+ }
+
+ ndpi_check_steam_udp2(ndpi_struct, flow);
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) {
+ return;
+ }
+
+ ndpi_check_steam_udp3(ndpi_struct, flow);
+}
+
+#endif
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
new file mode 100644
index 000000000..09ec4a050
--- /dev/null
+++ b/src/lib/protocols/stun.c
@@ -0,0 +1,188 @@
+/*
+ * stun.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_STUN
+
+
+static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_STUN, NDPI_REAL_PROTOCOL);
+}
+
+
+
+typedef enum {
+ NDPI_IS_STUN,
+ NDPI_IS_NOT_STUN
+} ndpi_int_stun_t;
+
+static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *ndpi_struct,
+ const u_int8_t * payload, const u_int16_t payload_length)
+{
+ u_int16_t a;
+
+
+ if((payload_length > 13)
+ && (strncmp((const char*)payload, (const char*)"RSP/", 4) == 0)
+ && (strncmp((const char*)&payload[7], (const char*)" STUN_", 6) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "Found stun.\n");
+ return NDPI_IS_STUN;
+ }
+
+ /*
+ * token list of message types and attribute types from
+ * http://wwwbs1.informatik.htw-dresden.de/svortrag/i02/Schoene/stun/stun.html
+ * the same list you can find in
+ * https://summersoft.fay.ar.us/repos/ethereal/branches/redhat-9/ethereal-0.10.3-1/ethereal-0.10.3/packet-stun.c
+ * token further message types and attributes from
+ * http://www.freeswitch.org/docs/group__stun1.html
+ * added further attributes observed
+ * message types: 0x0001, 0x0101, 0x0111, 0x0002, 0x0102, 0x0112, 0x0003, 0x0103, 0x0004, 0x0104, 0x0114, 0x0115
+ * attribute types: 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
+ * 0x000a, 0x000b, 0c000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0020,
+ * 0x0022, 0x0024, 0x8001, 0x8006, 0x8008, 0x8015, 0x8020, 0x8028, 0x802a, 0x8029, 0x8050, 0x8054, 0x8055
+ *
+ * 0x8003, 0x8004 used by facetime
+ */
+
+ if (payload_length >= 20 && ntohs(get_u_int16_t(payload, 2)) + 20 == payload_length &&
+ ((payload[0] == 0x00 && (payload[1] >= 0x01 && payload[1] <= 0x04)) ||
+ (payload[0] == 0x01 &&
+ ((payload[1] >= 0x01 && payload[1] <= 0x04) || (payload[1] >= 0x11 && payload[1] <= 0x15))))) {
+ u_int8_t mod;
+ u_int8_t old = 1;
+ u_int8_t padding = 0;
+ NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "len and type match.\n");
+
+ if (payload_length == 20) {
+ NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n");
+ return NDPI_IS_STUN;
+ }
+
+ a = 20;
+
+ while (a < payload_length) {
+
+ if (old && payload_length >= a + 4
+ &&
+ ((payload[a] == 0x00
+ && ((payload[a + 1] >= 0x01 && payload[a + 1] <= 0x16) || payload[a + 1] == 0x19
+ || payload[a + 1] == 0x20 || payload[a + 1] == 0x22 || payload[a + 1] == 0x24
+ || payload[a + 1] == 0x25))
+ || (payload[a] == 0x80
+ && (payload[a + 1] == 0x01 || payload[a + 1] == 0x03 || payload[a + 1] == 0x04
+ || payload[a + 1] == 0x06 || payload[a + 1] == 0x08 || payload[a + 1] == 0x15
+ || payload[a + 1] == 0x20 || payload[a + 1] == 0x22 || payload[a + 1] == 0x28
+ || payload[a + 1] == 0x2a || payload[a + 1] == 0x29 || payload[a + 1] == 0x50
+ || payload[a + 1] == 0x54 || payload[a + 1] == 0x55)))) {
+
+ NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "attribute match.\n");
+
+ a += ((payload[a + 2] << 8) + payload[a + 3] + 4);
+ mod = a % 4;
+ if (mod) {
+ padding = 4 - mod;
+ }
+ if (a == payload_length || (padding && (a + padding) == payload_length)) {
+ NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n");
+ return NDPI_IS_STUN;
+ }
+
+ } else if (payload_length >= a + padding + 4
+ &&
+ ((payload[a + padding] == 0x00
+ && ((payload[a + 1 + padding] >= 0x01 && payload[a + 1 + padding] <= 0x16)
+ || payload[a + 1 + padding] == 0x19 || payload[a + 1 + padding] == 0x20
+ || payload[a + 1 + padding] == 0x22 || payload[a + 1 + padding] == 0x24
+ || payload[a + 1 + padding] == 0x25))
+ || (payload[a + padding] == 0x80
+ && (payload[a + 1 + padding] == 0x01 || payload[a + 1 + padding] == 0x03
+ || payload[a + 1 + padding] == 0x04 || payload[a + 1 + padding] == 0x06
+ || payload[a + 1 + padding] == 0x08 || payload[a + 1 + padding] == 0x15
+ || payload[a + 1 + padding] == 0x20 || payload[a + 1 + padding] == 0x22
+ || payload[a + 1 + padding] == 0x28 || payload[a + 1 + padding] == 0x2a
+ || payload[a + 1 + padding] == 0x29 || payload[a + 1 + padding] == 0x50
+ || payload[a + 1 + padding] == 0x54 || payload[a + 1 + padding] == 0x55)))) {
+
+ NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "New STUN - attribute match.\n");
+
+ old = 0;
+ a += ((payload[a + 2 + padding] << 8) + payload[a + 3 + padding] + 4);
+ padding = 0;
+ mod = a % 4;
+ if (mod) {
+ a += 4 - mod;
+ }
+ if (a == payload_length) {
+ NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n");
+ return NDPI_IS_STUN;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ return NDPI_IS_NOT_STUN;
+}
+
+void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+ NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "search stun.\n");
+
+
+ if (packet->tcp) {
+
+ /* STUN may be encapsulated in TCP packets */
+
+ if (packet->payload_packet_len >= 2 + 20 &&
+ ntohs(get_u_int16_t(packet->payload, 0)) + 2 == packet->payload_packet_len) {
+
+ /* TODO there could be several STUN packets in a single TCP packet so maybe the detection could be
+ * improved by checking only the STUN packet of given length */
+
+ if (ndpi_int_check_stun(ndpi_struct, packet->payload + 2, packet->payload_packet_len - 2) ==
+ NDPI_IS_STUN) {
+ NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found TCP stun.\n");
+ ndpi_int_stun_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+ if (ndpi_int_check_stun(ndpi_struct, packet->payload, packet->payload_packet_len) == NDPI_IS_STUN) {
+ NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found UDP stun.\n");
+ ndpi_int_stun_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "exclude stun.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_STUN);
+}
+
+#endif
diff --git a/src/lib/protocols/syslog.c b/src/lib/protocols/syslog.c
new file mode 100644
index 000000000..b4732bfca
--- /dev/null
+++ b/src/lib/protocols/syslog.c
@@ -0,0 +1,130 @@
+/*
+ * syslog.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_SYSLOG
+
+static void ndpi_int_syslog_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SYSLOG, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_syslog(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ u_int8_t i;
+
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "search syslog\n");
+
+ if (packet->payload_packet_len > 20 && packet->payload_packet_len <= 1024 && packet->payload[0] == '<') {
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "checked len>20 and <1024 and first symbol=<.\n");
+ i = 1;
+
+ for (;;) {
+ if (packet->payload[i] < '0' || packet->payload[i] > '9' || i++ > 3) {
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG,
+ "read symbols while the symbol is a number.\n");
+ break;
+ }
+ }
+
+ if (packet->payload[i++] != '>') {
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "there is no > following the number.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SYSLOG);
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "a > following the number.\n");
+ }
+
+ if (packet->payload[i] == 0x20) {
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "a blank following the >: increment i.\n");
+ i++;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "no blank following the >: do nothing.\n");
+ }
+
+ /* check for "last message repeated" */
+ if (i + sizeof("last message") - 1 <= packet->payload_packet_len &&
+ memcmp(packet->payload + i, "last message", sizeof("last message") - 1) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "found syslog by 'last message' string.\n");
+
+ ndpi_int_syslog_add_connection(ndpi_struct, flow);
+
+ return;
+ } else if (i + sizeof("snort: ") - 1 <= packet->payload_packet_len &&
+ memcmp(packet->payload + i, "snort: ", sizeof("snort: ") - 1) == 0) {
+
+ /* snort events */
+
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "found syslog by 'snort: ' string.\n");
+
+ ndpi_int_syslog_add_connection(ndpi_struct, flow);
+
+ return;
+ }
+
+ if (memcmp(&packet->payload[i], "Jan", 3) != 0
+ && memcmp(&packet->payload[i], "Feb", 3) != 0
+ && memcmp(&packet->payload[i], "Mar", 3) != 0
+ && memcmp(&packet->payload[i], "Apr", 3) != 0
+ && memcmp(&packet->payload[i], "May", 3) != 0
+ && memcmp(&packet->payload[i], "Jun", 3) != 0
+ && memcmp(&packet->payload[i], "Jul", 3) != 0
+ && memcmp(&packet->payload[i], "Aug", 3) != 0
+ && memcmp(&packet->payload[i], "Sep", 3) != 0
+ && memcmp(&packet->payload[i], "Oct", 3) != 0
+ && memcmp(&packet->payload[i], "Nov", 3) != 0 && memcmp(&packet->payload[i], "Dec", 3) != 0) {
+
+
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG,
+ "no month-shortname following: syslog excluded.\n");
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SYSLOG);
+
+ return;
+
+ } else {
+
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG,
+ "a month-shortname following: syslog detected.\n");
+
+ ndpi_int_syslog_add_connection(ndpi_struct, flow);
+
+ return;
+ }
+ }
+ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "no syslog detected.\n");
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SYSLOG);
+}
+
+#endif
diff --git a/src/lib/protocols/tcp_udp.c b/src/lib/protocols/tcp_udp.c
new file mode 100644
index 000000000..da33e6e0e
--- /dev/null
+++ b/src/lib/protocols/tcp_udp.c
@@ -0,0 +1,78 @@
+/*
+ * tcp_or_udp.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+/* ndpi_main.c */
+extern u_int8_t ndpi_is_tor_flow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
+
+u_int ndpi_search_tcp_or_udp_raw(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int8_t protocol,
+ u_int32_t saddr, u_int32_t daddr, /* host endianess */
+ u_int16_t sport, u_int16_t dport) /* host endianess */
+{
+ u_int16_t rc;
+
+ if(protocol == IPPROTO_UDP) {
+ if((sport == dport) && (sport == 17500)) {
+ return(NDPI_PROTOCOL_DROPBOX);
+ }
+ }
+
+ if((rc = ndpi_host_ptree_match(ndpi_struct, saddr)) != NDPI_PROTOCOL_UNKNOWN) return(rc);
+
+ return(ndpi_host_ptree_match(ndpi_struct, daddr));
+}
+
+void ndpi_search_tcp_or_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ u_int16_t sport, dport;
+ u_int proto;
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(ndpi_is_tor_flow(ndpi_struct, flow)) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TOR, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ if(packet->udp) sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest);
+ else if(packet->tcp) sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
+ else sport = dport = 0;
+
+ if(packet->iph /* IPv4 Only: we need to support packet->iphv6 at some point */) {
+ proto = ndpi_search_tcp_or_udp_raw(ndpi_struct,
+ flow->packet.iph ? flow->packet.iph->protocol :
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ flow->packet.iphv6->nexthdr,
+#else
+ 0,
+#endif
+ ntohl(packet->iph->saddr),
+ ntohl(packet->iph->daddr),
+ sport, dport);
+
+ if(proto != NDPI_PROTOCOL_UNKNOWN)
+ ndpi_int_add_connection(ndpi_struct, flow, proto, NDPI_REAL_PROTOCOL);
+ }
+}
+
+
+
diff --git a/src/lib/protocols/tds.c b/src/lib/protocols/tds.c
new file mode 100644
index 000000000..af97316cd
--- /dev/null
+++ b/src/lib/protocols/tds.c
@@ -0,0 +1,91 @@
+/*
+ * tds.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_TDS
+
+static void ndpi_int_tds_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TDS, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_tds_tcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len > 8
+ && packet->payload_packet_len < 512
+ && packet->payload[1] < 0x02
+ && ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len && get_u_int16_t(packet->payload, 4) == 0x0000) {
+
+ if (flow->l4.tcp.tds_stage == 0) {
+ if (packet->payload[0] != 0x02 && packet->payload[0] != 0x07 && packet->payload[0] != 0x12) {
+ goto exclude_tds;
+ } else {
+ flow->l4.tcp.tds_stage = 1 + packet->packet_direction;
+ flow->l4.tcp.tds_login_version = packet->payload[0];
+ return;
+ }
+ } else if (flow->l4.tcp.tds_stage == 2 - packet->packet_direction) {
+ switch (flow->l4.tcp.tds_login_version) {
+ case 0x12:
+ if (packet->payload[0] == 0x04) {
+ flow->l4.tcp.tds_stage = 3 + packet->packet_direction;
+ return;
+ } else {
+ goto exclude_tds;
+ }
+ //TODO: add more cases for other versions
+ default:
+ goto exclude_tds;
+ }
+ } else if (flow->l4.tcp.tds_stage == 4 - packet->packet_direction) {
+ switch (flow->l4.tcp.tds_login_version) {
+ case 0x12:
+ if (packet->payload[0] == 0x12) {
+ NDPI_LOG(NDPI_PROTOCOL_TDS, ndpi_struct, NDPI_LOG_DEBUG, "TDS detected\n");
+ ndpi_int_tds_add_connection(ndpi_struct, flow);
+ return;
+ } else {
+ goto exclude_tds;
+ }
+ //TODO: add more cases for other versions
+ default:
+ goto exclude_tds;
+ }
+ }
+ }
+
+ exclude_tds:
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TDS);
+}
+
+#endif
diff --git a/src/lib/protocols/teamspeak.c b/src/lib/protocols/teamspeak.c
new file mode 100644
index 000000000..89ec12040
--- /dev/null
+++ b/src/lib/protocols/teamspeak.c
@@ -0,0 +1,65 @@
+/*
+ * viber.c
+ *
+ * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ *
+ * This module is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ndpi_api.h"
+
+
+#ifdef NDPI_PROTOCOL_TEAMSPEAK
+
+static void ndpi_int_teamspeak_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TEAMSPEAK, NDPI_REAL_PROTOCOL);
+}
+ u_int16_t tdport = 0, tsport = 0;
+ u_int16_t udport = 0, usport = 0;
+
+
+void ndpi_search_teamspeak(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+if (packet->udp != NULL) {
+ usport = ntohs(packet->udp->source), udport = ntohs(packet->udp->dest);
+ /* http://www.imfirewall.com/en/protocols/teamSpeak.htm */
+ if (((usport == 9987 || udport == 9987) || (usport == 8767 || udport == 8767)) && packet->payload_packet_len >= 20) {
+ NDPI_LOG(NDPI_PROTOCOL_TEAMSPEAK, ndpi_struct, NDPI_LOG_DEBUG, "found TEAMSPEAK udp.\n");
+ ndpi_int_teamspeak_add_connection(ndpi_struct, flow);
+ }
+}
+else if (packet->tcp != NULL) {
+ tsport = ntohs(packet->tcp->source), tdport = ntohs(packet->tcp->dest);
+ /* https://github.com/Youx/soliloque-server/wiki/Connection-packet */
+ if(packet->payload_packet_len >= 20) {
+ if (((memcmp(packet->payload, "\xf4\xbe\x03\x00", 4) == 0)) ||
+ ((memcmp(packet->payload, "\xf4\xbe\x02\x00", 4) == 0)) ||
+ ((memcmp(packet->payload, "\xf4\xbe\x01\x00", 4) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_TEAMSPEAK, ndpi_struct, NDPI_LOG_DEBUG, "found TEAMSPEAK tcp.\n");
+ ndpi_int_teamspeak_add_connection(ndpi_struct, flow);
+ } /* http://www.imfirewall.com/en/protocols/teamSpeak.htm */
+ } else if ((tsport == 14534 || tdport == 14534) || (tsport == 51234 || tdport == 51234)) {
+ NDPI_LOG(NDPI_PROTOCOL_TEAMSPEAK, ndpi_struct, NDPI_LOG_DEBUG, "found TEAMSPEAK.\n");
+ ndpi_int_teamspeak_add_connection(ndpi_struct, flow);
+ }
+ }
+ NDPI_LOG(NDPI_PROTOCOL_TEAMSPEAK, ndpi_struct, NDPI_LOG_DEBUG, "TEAMSPEAK excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TEAMSPEAK);
+ return;
+}
+#endif
diff --git a/src/lib/protocols/teamviewer.c b/src/lib/protocols/teamviewer.c
new file mode 100644
index 000000000..0fe0810c9
--- /dev/null
+++ b/src/lib/protocols/teamviewer.c
@@ -0,0 +1,100 @@
+/*
+ * teamviewer.c
+ *
+ * Copyright (C) 2012 by Gianluca Costa xplico.org
+ * Copyright (C) 2012-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_TEAMVIEWER
+
+static void ndpi_int_teamview_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TEAMVIEWER, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_TEAMVIEWER, ndpi_struct, NDPI_LOG_TRACE, "TEAMWIEWER Found.\n");
+}
+
+
+void ndpi_search_teamview(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ NDPI_LOG(NDPI_PROTOCOL_TEAMVIEWER, ndpi_struct, NDPI_LOG_TRACE, "TEAMWIEWER detection...\n");
+ /*
+ TeamViewer
+ 178.77.120.0/25
+
+ http://myip.ms/view/ip_owners/144885/Teamviewer_Gmbh.html
+ */
+ if(flow->packet.iph) {
+ u_int32_t src = ntohl(flow->packet.iph->saddr);
+ u_int32_t dst = ntohl(flow->packet.iph->daddr);
+
+ /* 95.211.37.195 - 95.211.37.203 */
+ if(((src >= 1607673283) && (src <= 1607673291))
+ || ((dst >= 1607673283) && (dst <= 1607673291))
+ || ((src & 0xFFFFFF80 /* 255.255.255.128 */) == 0xB24D7800 /* 178.77.120.0 */)
+ || ((dst & 0xFFFFFF80 /* 255.255.255.128 */) == 0xB24D7800 /* 178.77.120.0 */)
+ ) {
+ ndpi_int_teamview_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ if(packet->payload_packet_len == 0) return;
+
+ if (packet->udp != NULL) {
+ if (packet->payload_packet_len > 13) {
+ if (packet->payload[0] == 0x00 && packet->payload[11] == 0x17 && packet->payload[12] == 0x24) { /* byte 0 is a counter/seq number, and at the start is 0 */
+ flow->l4.udp.teamviewer_stage++;
+ if (flow->l4.udp.teamviewer_stage == 4 ||
+ packet->udp->dest == ntohs(5938) || packet->udp->source == ntohs(5938)) {
+ ndpi_int_teamview_add_connection(ndpi_struct, flow);
+ }
+ return;
+ }
+ }
+ }
+ else if(packet->tcp != NULL) {
+ if (packet->payload_packet_len > 2) {
+ if (packet->payload[0] == 0x17 && packet->payload[1] == 0x24) {
+ flow->l4.udp.teamviewer_stage++;
+ if (flow->l4.udp.teamviewer_stage == 4 ||
+ packet->tcp->dest == ntohs(5938) || packet->tcp->source == ntohs(5938)) {
+ ndpi_int_teamview_add_connection(ndpi_struct, flow);
+ }
+ return;
+ }
+ else if (flow->l4.udp.teamviewer_stage) {
+ if (packet->payload[0] == 0x11 && packet->payload[1] == 0x30) {
+ flow->l4.udp.teamviewer_stage++;
+ if (flow->l4.udp.teamviewer_stage == 4)
+ ndpi_int_teamview_add_connection(ndpi_struct, flow);
+ }
+ return;
+ }
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TEAMVIEWER);
+}
+#endif
diff --git a/src/lib/protocols/telegram.c b/src/lib/protocols/telegram.c
new file mode 100644
index 000000000..ba9397a92
--- /dev/null
+++ b/src/lib/protocols/telegram.c
@@ -0,0 +1,68 @@
+/*
+ * telegram.c
+ *
+ * Copyright (C) 2014 by Gianluca Costa xplico.org
+ * Copyright (C) 2012-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_TELEGRAM
+
+static void ndpi_int_telegram_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TELEGRAM, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_TELEGRAM, ndpi_struct, NDPI_LOG_TRACE, "TELEGRAM Found.\n");
+}
+
+
+void ndpi_search_telegram(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t dport /* , sport */;
+
+ NDPI_LOG(NDPI_PROTOCOL_TELEGRAM, ndpi_struct, NDPI_LOG_TRACE, "TELEGRAM detection...\n");
+
+ if (packet->payload_packet_len == 0)
+ return;
+ if (packet->tcp != NULL) {
+ if (packet->payload_packet_len > 56) {
+ dport = ntohs(packet->tcp->dest);
+ /* sport = ntohs(packet->tcp->source); */
+
+ if (packet->payload[0] == 0xef && (
+ dport == 443 || dport == 80 || dport == 25
+ )) {
+ if (packet->payload[1] == 0x7f) {
+ ndpi_int_telegram_add_connection(ndpi_struct, flow);
+ }
+ else if (packet->payload[1]*4 <= packet->payload_packet_len - 1) {
+ ndpi_int_telegram_add_connection(ndpi_struct, flow);
+ }
+ return;
+ }
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TELEGRAM);
+}
+#endif
diff --git a/src/lib/protocols/telnet.c b/src/lib/protocols/telnet.c
new file mode 100644
index 000000000..0954be111
--- /dev/null
+++ b/src/lib/protocols/telnet.c
@@ -0,0 +1,107 @@
+/*
+ * telnet.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_TELNET
+
+
+
+static void ndpi_int_telnet_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TELNET, NDPI_REAL_PROTOCOL);
+}
+
+
+#if !defined(WIN32)
+ static inline
+#else
+__forceinline static
+#endif
+ u_int8_t search_iac(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ u_int16_t a;
+
+ if (packet->payload_packet_len < 3) {
+ return 0;
+ }
+
+ if (!(packet->payload[0] == 0xff
+ && packet->payload[1] > 0xf9 && packet->payload[1] != 0xff && packet->payload[2] < 0x28)) {
+ return 0;
+ }
+
+ a = 3;
+
+ while (a < packet->payload_packet_len - 2) {
+ // commands start with a 0xff byte followed by a command byte >= 0xf0 and < 0xff
+ // command bytes 0xfb to 0xfe are followed by an option byte <= 0x28
+ if (!(packet->payload[a] != 0xff ||
+ (packet->payload[a] == 0xff && (packet->payload[a + 1] >= 0xf0) && (packet->payload[a + 1] <= 0xfa)) ||
+ (packet->payload[a] == 0xff && (packet->payload[a + 1] >= 0xfb) && (packet->payload[a + 1] != 0xff)
+ && (packet->payload[a + 2] <= 0x28)))) {
+ return 0;
+ }
+ a++;
+ }
+
+ return 1;
+}
+
+/* this detection also works asymmetrically */
+void ndpi_search_telnet_tcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+// struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_TELNET, ndpi_struct, NDPI_LOG_DEBUG, "search telnet.\n");
+
+ if (search_iac(ndpi_struct, flow) == 1) {
+
+ if (flow->l4.tcp.telnet_stage == 2) {
+ NDPI_LOG(NDPI_PROTOCOL_TELNET, ndpi_struct, NDPI_LOG_DEBUG, "telnet identified.\n");
+ ndpi_int_telnet_add_connection(ndpi_struct, flow);
+ return;
+ }
+ flow->l4.tcp.telnet_stage++;
+ NDPI_LOG(NDPI_PROTOCOL_TELNET, ndpi_struct, NDPI_LOG_DEBUG, "telnet stage %u.\n", flow->l4.tcp.telnet_stage);
+ return;
+ }
+
+ if ((flow->packet_counter < 12 && flow->l4.tcp.telnet_stage > 0) || flow->packet_counter < 6) {
+ return;
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_TELNET, ndpi_struct, NDPI_LOG_DEBUG, "telnet excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TELNET);
+ }
+ return;
+}
+
+#endif
diff --git a/src/lib/protocols/tftp.c b/src/lib/protocols/tftp.c
new file mode 100644
index 000000000..d5145445b
--- /dev/null
+++ b/src/lib/protocols/tftp.c
@@ -0,0 +1,70 @@
+/*
+ * tftp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_TFTP
+
+static void ndpi_int_tftp_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TFTP, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_tftp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+
+
+ NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "search TFTP.\n");
+
+
+
+ if (packet->payload_packet_len > 3 && flow->l4.udp.tftp_stage == 0
+ && ntohl(get_u_int32_t(packet->payload, 0)) == 0x00030001) {
+ NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "maybe tftp. need next packet.\n");
+ flow->l4.udp.tftp_stage = 1;
+ return;
+ }
+ if (packet->payload_packet_len > 3 && (flow->l4.udp.tftp_stage == 1)
+ && ntohl(get_u_int32_t(packet->payload, 0)) == 0x00040001) {
+
+ NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "found tftp.\n");
+ ndpi_int_tftp_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->payload_packet_len > 1
+ && ((packet->payload[0] == 0 && packet->payload[packet->payload_packet_len - 1] == 0)
+ || (packet->payload_packet_len == 4 && ntohl(get_u_int32_t(packet->payload, 0)) == 0x00040000))) {
+ NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "skip initial packet.\n");
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude TFTP.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TFTP);
+}
+#endif
diff --git a/src/lib/protocols/thunder.c b/src/lib/protocols/thunder.c
new file mode 100644
index 000000000..3784bb781
--- /dev/null
+++ b/src/lib/protocols/thunder.c
@@ -0,0 +1,211 @@
+/*
+ * thunder.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_THUNDER
+
+static void ndpi_int_thunder_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_THUNDER, protocol_type);
+
+ if (src != NULL) {
+ src->thunder_ts = packet->tick_timestamp;
+ }
+ if (dst != NULL) {
+ dst->thunder_ts = packet->tick_timestamp;
+ }
+}
+
+
+
+#if !defined(WIN32)
+ static inline
+#else
+__forceinline static
+#endif
+ void ndpi_int_search_thunder_udp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len > 8 && packet->payload[0] >= 0x30
+ && packet->payload[0] < 0x40 && packet->payload[1] == 0 && packet->payload[2] == 0 && packet->payload[3] == 0) {
+ if (flow->thunder_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, "THUNDER udp detected\n");
+ ndpi_int_thunder_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ flow->thunder_stage++;
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
+ "maybe thunder udp packet detected, stage increased to %u\n", flow->thunder_stage);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
+ "excluding thunder udp at stage %u\n", flow->thunder_stage);
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_THUNDER);
+}
+
+
+#if !defined(WIN32)
+ static inline
+#else
+__forceinline static
+#endif
+ void ndpi_int_search_thunder_tcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->payload_packet_len > 8 && packet->payload[0] >= 0x30
+ && packet->payload[0] < 0x40 && packet->payload[1] == 0 && packet->payload[2] == 0 && packet->payload[3] == 0) {
+ if (flow->thunder_stage == 3) {
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, "THUNDER tcp detected\n");
+ ndpi_int_thunder_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ flow->thunder_stage++;
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
+ "maybe thunder tcp packet detected, stage increased to %u\n", flow->thunder_stage);
+ return;
+ }
+
+ if (flow->thunder_stage == 0 && packet->payload_packet_len > 17
+ && memcmp(packet->payload, "POST / HTTP/1.1\r\n", 17) == 0) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
+ "maybe thunder http POST packet detected, parsed packet lines: %u, empty line set %u (at: %u)\n",
+ packet->parsed_lines, packet->empty_line_position_set, packet->empty_line_position);
+
+ if (packet->empty_line_position_set != 0 &&
+ packet->content_line.ptr != NULL &&
+ packet->content_line.len == 24 &&
+ memcmp(packet->content_line.ptr, "application/octet-stream",
+ 24) == 0 && packet->empty_line_position_set < (packet->payload_packet_len - 8)
+ && packet->payload[packet->empty_line_position + 2] >= 0x30
+ && packet->payload[packet->empty_line_position + 2] < 0x40
+ && packet->payload[packet->empty_line_position + 3] == 0x00
+ && packet->payload[packet->empty_line_position + 4] == 0x00
+ && packet->payload[packet->empty_line_position + 5] == 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
+ "maybe thunder http POST packet application does match\n");
+ ndpi_int_thunder_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
+ "excluding thunder tcp at stage %u\n", flow->thunder_stage);
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_THUNDER);
+}
+
+
+#if !defined(WIN32)
+ static inline
+#else
+__forceinline static
+#endif
+ void ndpi_int_search_thunder_http(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_THUNDER) {
+ if (src != NULL && ((u_int32_t)
+ (packet->tick_timestamp - src->thunder_ts) < ndpi_struct->thunder_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
+ "thunder : save src connection packet detected\n");
+ src->thunder_ts = packet->tick_timestamp;
+ } else if (dst != NULL && ((u_int32_t)
+ (packet->tick_timestamp - dst->thunder_ts) < ndpi_struct->thunder_timeout)) {
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
+ "thunder : save dst connection packet detected\n");
+ dst->thunder_ts = packet->tick_timestamp;
+ }
+ return;
+ }
+
+ if (packet->payload_packet_len > 5
+ && memcmp(packet->payload, "GET /", 5) == 0 && NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_THUNDER)) {
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, "HTTP packet detected.\n");
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if (packet->parsed_lines > 7
+ && packet->parsed_lines < 11
+ && packet->line[1].len > 10
+ && memcmp(packet->line[1].ptr, "Accept: */*", 11) == 0
+ && packet->line[2].len > 22
+ && memcmp(packet->line[2].ptr, "Cache-Control: no-cache",
+ 23) == 0 && packet->line[3].len > 16
+ && memcmp(packet->line[3].ptr, "Connection: close", 17) == 0
+ && packet->line[4].len > 6
+ && memcmp(packet->line[4].ptr, "Host: ", 6) == 0
+ && packet->line[5].len > 15
+ && memcmp(packet->line[5].ptr, "Pragma: no-cache", 16) == 0
+ && packet->user_agent_line.ptr != NULL
+ && packet->user_agent_line.len > 49
+ && memcmp(packet->user_agent_line.ptr,
+ "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)", 50) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
+ "Thunder HTTP download detected, adding flow.\n");
+ ndpi_int_thunder_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ }
+ }
+}
+
+void ndpi_search_thunder(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ //
+ //struct ndpi_id_struct *src = flow->src;
+ //struct ndpi_id_struct *dst = flow->dst;
+
+ if (packet->tcp != NULL) {
+ ndpi_int_search_thunder_http(ndpi_struct, flow);
+ ndpi_int_search_thunder_tcp(ndpi_struct, flow);
+ } else if (packet->udp != NULL) {
+ ndpi_int_search_thunder_udp(ndpi_struct, flow);
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/tor.c b/src/lib/protocols/tor.c
new file mode 100644
index 000000000..ead857726
--- /dev/null
+++ b/src/lib/protocols/tor.c
@@ -0,0 +1,109 @@
+/*
+ * tor.c
+ *
+ * Copyright (C) 2015 ntop.org
+ * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+
+#ifdef NDPI_PROTOCOL_TOR
+
+static void ndpi_int_tor_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TOR, NDPI_CORRELATED_PROTOCOL);
+}
+
+
+int ndpi_is_ssl_tor(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, char *certificate) {
+ int prev_num = 0, numbers_found = 0, num_found = 0, i;
+ char dummy[48], *dot, *name;
+
+ if((certificate == NULL)
+ || (strlen(certificate) < 6)
+ || strncmp(certificate, "www.", 4))
+ return(0);
+
+ // printf("***** [SSL] %s(): %s\n", __FUNCTION__, certificate);
+
+ snprintf(dummy, sizeof(dummy), "%s", certificate);
+
+ if((dot = strrchr(dummy, '.')) == NULL) return(0);
+ dot[0] = '\0';
+
+ if((dot = strrchr(dummy, '.')) == NULL) return(0);
+ name = &dot[1];
+
+ for(i = 0; name[i+1] != '\0'; i++) {
+ if((name[i] >= '0') && (name[i] <= '9')) {
+
+ if(prev_num != 1) {
+ numbers_found++;
+
+ if(numbers_found == 2) {
+ ndpi_int_tor_add_connection(ndpi_struct, flow);
+ return(1);
+ }
+ prev_num = 1;
+ }
+ } else
+ prev_num = 0;
+
+ if(ndpi_match_bigram(ndpi_struct, &ndpi_struct->impossible_bigrams_automa, &name[i])) {
+ ndpi_int_tor_add_connection(ndpi_struct, flow);
+ return(1);
+ }
+
+ if(ndpi_match_bigram(ndpi_struct, &ndpi_struct->bigrams_automa, &name[i])) {
+ num_found++;
+ }
+ }
+
+ if(num_found == 0) {
+ ndpi_int_tor_add_connection(ndpi_struct, flow);
+ return(1);
+ } else {
+#ifndef __KERNEL__
+#ifdef PENDANTIC_TOR_CHECK
+ if(gethostbyname(certificate) == NULL) {
+ ndpi_int_tor_add_connection(ndpi_struct, flow);
+ return(1);
+ }
+#endif
+#endif
+ }
+
+ return(0);
+}
+
+/* ******************************************* */
+
+void ndpi_search_tor(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t dport = 0, sport = 0;
+
+ NDPI_LOG(NDPI_PROTOCOL_TOR, ndpi_struct, NDPI_LOG_DEBUG, "search for TOR.\n");
+
+ if(packet->tcp != NULL) {
+ sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
+ NDPI_LOG(NDPI_PROTOCOL_TOR, ndpi_struct, NDPI_LOG_DEBUG, "calculating TOR over tcp.\n");
+
+ if ((((dport == 9001) || (sport == 9001)) || ((dport == 9030) || (sport == 9030)))
+ && ((packet->payload[0] == 0x17) || (packet->payload[0] == 0x16))
+ && (packet->payload[1] == 0x03)
+ && (packet->payload[2] == 0x01)
+ && (packet->payload[3] == 0x00)) {
+ NDPI_LOG(NDPI_PROTOCOL_TOR, ndpi_struct, NDPI_LOG_DEBUG, "found tor.\n");
+ ndpi_int_tor_add_connection(ndpi_struct, flow);
+ }
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_TOR, ndpi_struct, NDPI_LOG_DEBUG, "exclude TOR.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TOR);
+ }
+}
+#endif
diff --git a/src/lib/protocols/tvants.c b/src/lib/protocols/tvants.c
new file mode 100644
index 000000000..5021fadcd
--- /dev/null
+++ b/src/lib/protocols/tvants.c
@@ -0,0 +1,78 @@
+/*
+ * tvants.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_TVANTS
+
+static void ndpi_int_tvants_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TVANTS, NDPI_REAL_PROTOCOL);
+}
+
+
+
+
+void ndpi_search_tvants_udp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ NDPI_LOG(NDPI_PROTOCOL_TVANTS, ndpi_struct, NDPI_LOG_DEBUG, "search tvants. \n");
+
+ if (packet->udp != NULL && packet->payload_packet_len > 57
+ && packet->payload[0] == 0x04 && packet->payload[1] == 0x00
+ && (packet->payload[2] == 0x05 || packet->payload[2] == 0x06
+ || packet->payload[2] == 0x07) && packet->payload[3] == 0x00
+ && packet->payload_packet_len == (packet->payload[5] << 8) + packet->payload[4]
+ && packet->payload[6] == 0x00 && packet->payload[7] == 0x00
+ && (memcmp(&packet->payload[48], "TVANTS", 6) == 0
+ || memcmp(&packet->payload[49], "TVANTS", 6) == 0 || memcmp(&packet->payload[51], "TVANTS", 6) == 0)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_TVANTS, ndpi_struct, NDPI_LOG_DEBUG, "found tvants over udp. \n");
+ ndpi_int_tvants_add_connection(ndpi_struct, flow);
+
+ } else if (packet->tcp != NULL && packet->payload_packet_len > 15
+ && packet->payload[0] == 0x04 && packet->payload[1] == 0x00
+ && packet->payload[2] == 0x07 && packet->payload[3] == 0x00
+ && packet->payload_packet_len == (packet->payload[5] << 8) + packet->payload[4]
+ && packet->payload[6] == 0x00 && packet->payload[7] == 0x00
+ && memcmp(&packet->payload[8], "TVANTS", 6) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_TVANTS, ndpi_struct, NDPI_LOG_DEBUG, "found tvants over tcp. \n");
+ ndpi_int_tvants_add_connection(ndpi_struct, flow);
+
+ }
+ NDPI_LOG(NDPI_PROTOCOL_TVANTS, ndpi_struct, NDPI_LOG_DEBUG, "exclude tvants. \n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TVANTS);
+
+}
+#endif
diff --git a/src/lib/protocols/tvuplayer.c b/src/lib/protocols/tvuplayer.c
new file mode 100644
index 000000000..a81ea96b3
--- /dev/null
+++ b/src/lib/protocols/tvuplayer.c
@@ -0,0 +1,153 @@
+/*
+ * tvuplayer.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_TVUPLAYER
+
+
+static void ndpi_int_tvuplayer_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TVUPLAYER, protocol_type);
+}
+
+void ndpi_search_tvuplayer(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "search tvuplayer. \n");
+
+
+
+ if (packet->tcp != NULL) {
+ if ((packet->payload_packet_len == 36 || packet->payload_packet_len == 24)
+ && packet->payload[0] == 0x00
+ && ntohl(get_u_int32_t(packet->payload, 2)) == 0x31323334
+ && ntohl(get_u_int32_t(packet->payload, 6)) == 0x35363837 && packet->payload[10] == 0x01) {
+ NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer over tcp. \n");
+ ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+
+ if (packet->payload_packet_len >= 50) {
+
+ if (memcmp(packet->payload, "POST", 4) || memcmp(packet->payload, "GET", 3)) {
+ NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet);
+ if (packet->user_agent_line.ptr != NULL &&
+ packet->user_agent_line.len >= 8 && (memcmp(packet->user_agent_line.ptr, "MacTVUP", 7) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "Found user agent as MacTVUP.\n");
+ ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+ }
+
+ if (packet->udp != NULL) {
+
+ if (packet->payload_packet_len == 56 &&
+ packet->payload[0] == 0xff
+ && packet->payload[1] == 0xff && packet->payload[2] == 0x00
+ && packet->payload[3] == 0x01
+ && packet->payload[12] == 0x02 && packet->payload[13] == 0xff
+ && packet->payload[19] == 0x2c && ((packet->payload[26] == 0x05 && packet->payload[27] == 0x14)
+ || (packet->payload[26] == 0x14 && packet->payload[27] == 0x05))) {
+ NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type I. \n");
+ ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 82
+ && packet->payload[0] == 0x00 && packet->payload[2] == 0x00
+ && packet->payload[10] == 0x00 && packet->payload[11] == 0x00
+ && packet->payload[12] == 0x01 && packet->payload[13] == 0xff
+ && packet->payload[19] == 0x14 && packet->payload[32] == 0x03
+ && packet->payload[33] == 0xff && packet->payload[34] == 0x01
+ && packet->payload[39] == 0x32 && ((packet->payload[46] == 0x05 && packet->payload[47] == 0x14)
+ || (packet->payload[46] == 0x14 && packet->payload[47] == 0x05))) {
+ NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type II. \n");
+ ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 32
+ && packet->payload[0] == 0x00 && packet->payload[2] == 0x00
+ && (packet->payload[10] == 0x00 || packet->payload[10] == 0x65
+ || packet->payload[10] == 0x7e || packet->payload[10] == 0x49)
+ && (packet->payload[11] == 0x00 || packet->payload[11] == 0x57
+ || packet->payload[11] == 0x06 || packet->payload[11] == 0x22)
+ && packet->payload[12] == 0x01 && (packet->payload[13] == 0xff || packet->payload[13] == 0x01)
+ && packet->payload[19] == 0x14) {
+ NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type III. \n");
+ ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 84
+ && packet->payload[0] == 0x00 && packet->payload[2] == 0x00
+ && packet->payload[10] == 0x00 && packet->payload[11] == 0x00
+ && packet->payload[12] == 0x01 && packet->payload[13] == 0xff
+ && packet->payload[19] == 0x14 && packet->payload[32] == 0x03
+ && packet->payload[33] == 0xff && packet->payload[34] == 0x01 && packet->payload[39] == 0x34) {
+ NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type IV. \n");
+ ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 102
+ && packet->payload[0] == 0x00 && packet->payload[2] == 0x00
+ && packet->payload[10] == 0x00 && packet->payload[11] == 0x00
+ && packet->payload[12] == 0x01 && packet->payload[13] == 0xff
+ && packet->payload[19] == 0x14 && packet->payload[33] == 0xff && packet->payload[39] == 0x14) {
+ NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type V. \n");
+ ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len == 62 && packet->payload[0] == 0x00 && packet->payload[2] == 0x00
+ //&& packet->payload[10] == 0x00 && packet->payload[11] == 0x00
+ && packet->payload[12] == 0x03 && packet->payload[13] == 0xff
+ && packet->payload[19] == 0x32 && ((packet->payload[26] == 0x05 && packet->payload[27] == 0x14)
+ || (packet->payload[26] == 0x14 && packet->payload[27] == 0x05))) {
+ NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type VI. \n");
+ ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ // to check, if byte 26, 27, 33,39 match
+ if (packet->payload_packet_len == 60
+ && packet->payload[0] == 0x00 && packet->payload[2] == 0x00
+ && packet->payload[10] == 0x00 && packet->payload[11] == 0x00
+ && packet->payload[12] == 0x06 && packet->payload[13] == 0x00 && packet->payload[19] == 0x30) {
+ NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type VII. \n");
+ ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "exclude tvuplayer. \n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TVUPLAYER);
+
+}
+#endif
diff --git a/src/lib/protocols/twitter.c b/src/lib/protocols/twitter.c
new file mode 100644
index 000000000..db2f77a5e
--- /dev/null
+++ b/src/lib/protocols/twitter.c
@@ -0,0 +1,63 @@
+/*
+ * twitter.c
+ *
+ * Copyright (C) 2014 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_SERVICE_TWITTER
+
+static void ndpi_int_twitter_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_SERVICE_TWITTER, NDPI_REAL_PROTOCOL);
+}
+
+
+void ndpi_search_twitter(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+ /*
+ Twitter AS34702
+
+ http://bgp.he.net/AS13414
+ */
+ if(flow->packet.iph) {
+ // IPv4
+ u_int32_t src = ntohl(flow->packet.iph->saddr);
+ u_int32_t dst = ntohl(flow->packet.iph->daddr);
+
+ if(ndpi_ips_match(src, dst, 0xC0854C00, 22) /* 192.133.76.0/22 */
+ || ndpi_ips_match(src, dst, 0xC7109C00, 22) /* 199.16.156.0/22 */
+ || ndpi_ips_match(src, dst, 0xC73B9400, 22) /* 199.59.148.0/22 */
+ || ndpi_ips_match(src, dst, 0xC7603A00, 23) /* 199.96.58.0/23 */
+ || ndpi_ips_match(src, dst, 0xC7603E00, 23) /* 199.96.62.0/23 */
+ ) {
+ ndpi_int_twitter_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_SERVICE_TWITTER);
+}
+#endif
diff --git a/src/lib/protocols/usenet.c b/src/lib/protocols/usenet.c
new file mode 100644
index 000000000..07ed91678
--- /dev/null
+++ b/src/lib/protocols/usenet.c
@@ -0,0 +1,105 @@
+/*
+ * usenet.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_USENET
+
+
+static void ndpi_int_usenet_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_USENET, NDPI_REAL_PROTOCOL);
+}
+
+
+
+void ndpi_search_usenet_tcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: search usenet.\n");
+
+
+
+
+
+ NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: STAGE IS %u.\n", flow->l4.tcp.usenet_stage);
+
+
+ // check for the first server replay
+ /*
+ 200 Service available, posting allowed
+ 201 Service available, posting prohibited
+ */
+ if (flow->l4.tcp.usenet_stage == 0 && packet->payload_packet_len > 10
+ && ((memcmp(packet->payload, "200 ", 4) == 0)
+ || (memcmp(packet->payload, "201 ", 4) == 0))) {
+
+ NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: found 200 or 201.\n");
+ flow->l4.tcp.usenet_stage = 1 + packet->packet_direction;
+
+ NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: maybe hit.\n");
+ return;
+ }
+
+ /*
+ [C] AUTHINFO USER fred
+ [S] 381 Enter passphrase
+ [C] AUTHINFO PASS flintstone
+ [S] 281 Authentication accepted
+ */
+ // check for client username
+ if (flow->l4.tcp.usenet_stage == 2 - packet->packet_direction) {
+ if (packet->payload_packet_len > 20 && (memcmp(packet->payload, "AUTHINFO USER ", 14) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: username found\n");
+ flow->l4.tcp.usenet_stage = 3 + packet->packet_direction;
+
+ NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: found usenet.\n");
+ ndpi_int_usenet_add_connection(ndpi_struct, flow);
+ return;
+ } else if (packet->payload_packet_len == 13 && (memcmp(packet->payload, "MODE READER\r\n", 13) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG,
+ "USENET: no login necessary but we are a client.\n");
+
+ NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: found usenet.\n");
+ ndpi_int_usenet_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+
+
+ NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: exclude usenet.\n");
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_USENET);
+
+}
+
+#endif
diff --git a/src/lib/protocols/veohtv.c b/src/lib/protocols/veohtv.c
new file mode 100644
index 000000000..10f84c3fd
--- /dev/null
+++ b/src/lib/protocols/veohtv.c
@@ -0,0 +1,116 @@
+/*
+ * veohtv.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+
+#ifdef NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV
+
+static void ndpi_int_veohtv_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, protocol_type);
+}
+
+void ndpi_search_veohtv_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV)
+ return;
+
+ if (flow->l4.tcp.veoh_tv_stage == 1 || flow->l4.tcp.veoh_tv_stage == 2) {
+ if (packet->packet_direction != flow->setup_packet_direction &&
+ packet->payload_packet_len > NDPI_STATICSTRING_LEN("HTTP/1.1 20")
+ && memcmp(packet->payload, "HTTP/1.1 ", NDPI_STATICSTRING_LEN("HTTP/1.1 ")) == 0 &&
+ (packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '2' ||
+ packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '3' ||
+ packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '4' ||
+ packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '5')) {
+#ifdef NDPI_CONTENT_FLASH
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->detected_protocol_stack[0] == NDPI_CONTENT_FLASH &&
+ packet->server_line.ptr != NULL &&
+ packet->server_line.len > NDPI_STATICSTRING_LEN("Veoh-") &&
+ memcmp(packet->server_line.ptr, "Veoh-", NDPI_STATICSTRING_LEN("Veoh-")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n");
+ ndpi_int_veohtv_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+#endif
+ if (flow->l4.tcp.veoh_tv_stage == 2) {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask,
+ NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n");
+ ndpi_int_veohtv_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ } else if (flow->packet_direction_counter[(flow->setup_packet_direction == 1) ? 0 : 1] > 3) {
+ if (flow->l4.tcp.veoh_tv_stage == 2) {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask,
+ NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n");
+ ndpi_int_veohtv_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ } else {
+ if (flow->packet_counter > 10) {
+ if (flow->l4.tcp.veoh_tv_stage == 2) {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask,
+ NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n");
+ ndpi_int_veohtv_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ return;
+ }
+ } else if (packet->udp) {
+ /* UDP packets from Veoh Client Player
+ *
+ * packet starts with 16 byte random? value
+ * then a 4 byte mode value
+ * values between 21 and 26 has been seen
+ * then a 4 byte counter */
+
+ if (packet->payload_packet_len == 28 &&
+ get_u_int32_t(packet->payload, 16) == htonl(0x00000021) &&
+ get_u_int32_t(packet->payload, 20) == htonl(0x00000000) && get_u_int32_t(packet->payload, 24) == htonl(0x01040000)) {
+ NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "UDP VeohTV found.\n");
+ ndpi_int_veohtv_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV);
+}
+#endif
diff --git a/src/lib/protocols/vhua.c b/src/lib/protocols/vhua.c
new file mode 100644
index 000000000..027cc697c
--- /dev/null
+++ b/src/lib/protocols/vhua.c
@@ -0,0 +1,68 @@
+/*
+ * vhua.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * nDPI is free software: you can vhuatribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+/*
+ http://www.vhua.com
+
+ Skype-like Chinese phone protocol
+
+ */
+
+#ifdef NDPI_PROTOCOL_VHUA
+
+static void ndpi_int_vhua_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_VHUA, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_VHUA, ndpi_struct, NDPI_LOG_TRACE, "VHUA Found.\n");
+}
+
+
+static void ndpi_check_vhua(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+ u_char p0[] = { 0x05, 0x14, 0x3a, 0x05, 0x08, 0xf8, 0xa1, 0xb1, 0x03 };
+
+ if(payload_len == 0) return; /* Shouldn't happen */
+
+ /* Break after 3 packets. */
+ if((flow->packet_counter > 3)
+ || (packet->udp == NULL)
+ || (packet->payload_packet_len < sizeof(p0))) {
+ NDPI_LOG(NDPI_PROTOCOL_VHUA, ndpi_struct, NDPI_LOG_TRACE, "Exclude VHUA.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_VHUA);
+ } else if(memcmp(packet->payload, p0, sizeof(p0)) == 0) {
+ ndpi_int_vhua_add_connection(ndpi_struct, flow);
+ }
+}
+
+void ndpi_search_vhua(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_VHUA, ndpi_struct, NDPI_LOG_TRACE, "VHUA detection...\n");
+
+ /* skip marked packets */
+ if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_VHUA) {
+ ndpi_check_vhua(ndpi_struct, flow);
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/viber.c b/src/lib/protocols/viber.c
new file mode 100644
index 000000000..f53139e83
--- /dev/null
+++ b/src/lib/protocols/viber.c
@@ -0,0 +1,48 @@
+/*
+ * viber.c
+ *
+ * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ * Copyright (C) 2013 - 2014 ntop.org
+ *
+ * This module is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_VIBER
+
+void ndpi_search_viber(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_VIBER, ndpi_struct, NDPI_LOG_DEBUG, "search for VIBER.\n");
+
+ if(packet->udp != NULL) {
+ NDPI_LOG(NDPI_PROTOCOL_VIBER, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over udp.\n");
+
+ if((packet->payload_packet_len == 12 && packet->payload[2] == 0x03 && packet->payload[3] == 0x00)
+ || (packet->payload_packet_len == 20 && packet->payload[2] == 0x09 && packet->payload[3] == 0x00)
+ || ((packet->payload_packet_len < 135) && (packet->payload[0] == 0x11))) {
+ NDPI_LOG(NDPI_PROTOCOL_VIBER, ndpi_struct, NDPI_LOG_DEBUG, "found VIBER.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_VIBER, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_VIBER, ndpi_struct, NDPI_LOG_DEBUG, "exclude VIBER.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_VIBER);
+}
+
+#endif
diff --git a/src/lib/protocols/vmware.c b/src/lib/protocols/vmware.c
new file mode 100644
index 000000000..de21c521f
--- /dev/null
+++ b/src/lib/protocols/vmware.c
@@ -0,0 +1,45 @@
+/*
+ * vmware.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_VMWARE
+
+
+void ndpi_search_vmware(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ /* Check whether this is an VMWARE flow */
+ if((packet->payload_packet_len == 66)
+ && (ntohs(packet->udp->dest) == 902)
+ && ((packet->payload[0] & 0xFF) == 0xA4)) {
+ NDPI_LOG(NDPI_PROTOCOL_VMWARE, ndpi_struct, NDPI_LOG_DEBUG, "Found vmware.\n");
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_VMWARE, NDPI_REAL_PROTOCOL);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_VMWARE, ndpi_struct, NDPI_LOG_DEBUG, "exclude vmware.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_VMWARE);
+ }
+}
+
+
+#endif /* NDPI_PROTOCOL_VMWARE */
+
diff --git a/src/lib/protocols/vnc.c b/src/lib/protocols/vnc.c
new file mode 100644
index 000000000..afd467ea7
--- /dev/null
+++ b/src/lib/protocols/vnc.c
@@ -0,0 +1,67 @@
+/*
+ * vnc.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_VNC
+
+static void ndpi_int_vnc_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_VNC, NDPI_REAL_PROTOCOL);
+}
+
+/*
+ return 0 if nothing has been detected
+ return 1 if it is a http packet
+*/
+
+void ndpi_search_vnc_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ if (flow->l4.tcp.vnc_stage == 0) {
+ if (packet->payload_packet_len == 12
+ && memcmp(packet->payload, "RFB 003.00", 10) == 0 && packet->payload[11] == 0x0a) {
+ NDPI_LOG(NDPI_PROTOCOL_VNC, ndpi_struct, NDPI_LOG_DEBUG, "reached vnc stage one\n");
+ flow->l4.tcp.vnc_stage = 1 + packet->packet_direction;
+ return;
+ }
+ } else if (flow->l4.tcp.vnc_stage == 2 - packet->packet_direction) {
+ if (packet->payload_packet_len == 12
+ && memcmp(packet->payload, "RFB 003.00", 10) == 0 && packet->payload[11] == 0x0a) {
+ NDPI_LOG(NDPI_PROTOCOL_VNC, ndpi_struct, NDPI_LOG_DEBUG, "found vnc\n");
+ ndpi_int_vnc_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_VNC);
+
+}
+#endif
diff --git a/src/lib/protocols/warcraft3.c b/src/lib/protocols/warcraft3.c
new file mode 100644
index 000000000..7780dbf6e
--- /dev/null
+++ b/src/lib/protocols/warcraft3.c
@@ -0,0 +1,100 @@
+/*
+ * warcraft3.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+/* include files */
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_WARCRAFT3
+
+static void ndpi_int_warcraft3_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WARCRAFT3, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_warcraft3(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ u_int32_t l; /*
+ Leave it as u_int32_t because otherwise 'u_int16_t temp'
+ might overflood it and thus generate an infinite loop
+ */
+
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "search WARCRAFT3\n");
+
+
+ if (flow->packet_counter == 1 && packet->payload_packet_len == 1 && packet->payload[0] == 0x01) {
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "maybe warcraft3: packet_len == 1\n");
+ return;
+ } else if (packet->payload_packet_len >= 4 && (packet->payload[0] == 0xf7 || packet->payload[0] == 0xff)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "packet_payload begins with 0xf7 or 0xff\n");
+
+ l = packet->payload[2] + (packet->payload[3] << 8); // similar to ntohs
+
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "l = %u \n", l);
+
+ while (l <= (packet->payload_packet_len - 4)) {
+ if (packet->payload[l] == 0xf7) {
+ u_int16_t temp = (packet->payload[l + 2 + 1] << 8) + packet->payload[l + 2];
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "another f7 visited.\n");
+
+ if((temp <= 2) || (temp > 1500)) {
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "break\n");
+ break;
+ } else {
+ l += temp;
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "l = %u \n", l);
+ }
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "break\n");
+ break;
+ }
+ }
+
+ if (l == packet->payload_packet_len) {
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "maybe WARCRAFT3\n");
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "flow->packet_counter = %u \n",
+ flow->packet_counter);
+ if (flow->packet_counter > 2) {
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "detected WARCRAFT3\n");
+ ndpi_int_warcraft3_add_connection(ndpi_struct, flow);
+ return;
+ }
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "no warcraft3 detected.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WARCRAFT3);
+}
+
+#endif
diff --git a/src/lib/protocols/whoisdas.c b/src/lib/protocols/whoisdas.c
new file mode 100644
index 000000000..90fa387d7
--- /dev/null
+++ b/src/lib/protocols/whoisdas.c
@@ -0,0 +1,60 @@
+/*
+ * ssh.c
+ *
+ * Copyright (C) 2013 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_WHOIS_DAS
+
+void ndpi_search_whois_das(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
+
+ if ((packet->tcp != NULL)
+ && (
+ ((sport == 43) || (dport == 43))
+ ||
+ ((sport == 4343) || (dport == 4343))
+ )
+ ) {
+ if(packet->payload_packet_len > 0) {
+ u_int max_len = sizeof(flow->host_server_name)-1;
+ u_int i, j;
+
+ for(i=strlen((const char *)flow->host_server_name), j=0; (i<max_len) && (j<packet->payload_packet_len); i++, j++) {
+ if((packet->payload[j] == '\n') || (packet->payload[j] == '\r')) break;
+
+ flow->host_server_name[i] = packet->payload[j];
+ }
+
+ flow->host_server_name[i] = '\0';
+ flow->server_id = ((sport == 43) || (sport == 4343)) ? flow->src : flow->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_WHOIS_DAS, ndpi_struct, NDPI_LOG_DEBUG, "[WHOIS/DAS] %s\n", flow->host_server_name);
+ }
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WHOIS_DAS, NDPI_REAL_PROTOCOL);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_WHOIS_DAS, ndpi_struct, NDPI_LOG_TRACE, "WHOIS Excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WHOIS_DAS);
+ }
+}
+
+#endif
diff --git a/src/lib/protocols/winmx.c b/src/lib/protocols/winmx.c
new file mode 100644
index 000000000..d032150b7
--- /dev/null
+++ b/src/lib/protocols/winmx.c
@@ -0,0 +1,104 @@
+/*
+ * winmx.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+
+#ifdef NDPI_PROTOCOL_WINMX
+
+
+static void ndpi_int_winmx_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow);
+
+static void ndpi_int_winmx_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WINMX, NDPI_REAL_PROTOCOL);
+}
+
+
+void ndpi_search_winmx_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+
+ if (flow->l4.tcp.winmx_stage == 0) {
+ if (packet->payload_packet_len == 1 || (packet->payload_packet_len > 1 && packet->payload[0] == 0x31)) {
+ return;
+ }
+ /* did not see this pattern in any trace that we have */
+ if (((packet->payload_packet_len) == 4)
+ && (memcmp(packet->payload, "SEND", 4) == 0)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "maybe WinMX Send\n");
+ flow->l4.tcp.winmx_stage = 1;
+ return;
+ }
+
+ if (((packet->payload_packet_len) == 3)
+ && (memcmp(packet->payload, "GET", 3) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "found winmx by GET\n");
+ ndpi_int_winmx_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+
+ if (packet->payload_packet_len == 149 && packet->payload[0] == '8') {
+ NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "maybe WinMX\n");
+ if (get_u_int32_t(packet->payload, 17) == 0
+ && get_u_int32_t(packet->payload, 21) == 0
+ && get_u_int32_t(packet->payload, 25) == 0
+ && get_u_int16_t(packet->payload, 39) == 0 && get_u_int16_t(packet->payload, 135) == htons(0x7edf)
+ && get_u_int16_t(packet->payload, 147) == htons(0xf792)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG,
+ "found winmx by pattern in first packet\n");
+ ndpi_int_winmx_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ /* did not see this pattern in any trace that we have */
+ } else if (flow->l4.tcp.winmx_stage == 1) {
+ if (packet->payload_packet_len > 10 && packet->payload_packet_len < 1000) {
+ u_int16_t left = packet->payload_packet_len - 1;
+ while (left > 0) {
+ if (packet->payload[left] == ' ') {
+ NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "found winmx in second packet\n");
+ ndpi_int_winmx_add_connection(ndpi_struct, flow);
+ return;
+ } else if (packet->payload[left] < '0' || packet->payload[left] > '9') {
+ break;
+ }
+ left--;
+ }
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WINMX);
+}
+
+#endif
diff --git a/src/lib/protocols/world_of_kung_fu.c b/src/lib/protocols/world_of_kung_fu.c
new file mode 100644
index 000000000..da35c0aa0
--- /dev/null
+++ b/src/lib/protocols/world_of_kung_fu.c
@@ -0,0 +1,58 @@
+/*
+ * world_of_kung_fu.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+/* include files */
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_WORLD_OF_KUNG_FU
+
+static void ndpi_int_world_of_kung_fu_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WORLD_OF_KUNG_FU, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_world_of_kung_fu(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src=ndpi_struct->src;
+ // struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_WORLD_OF_KUNG_FU, ndpi_struct, NDPI_LOG_DEBUG, "search world_of_kung_fu.\n");
+
+ if ((packet->payload_packet_len == 16)
+ && ntohl(get_u_int32_t(packet->payload, 0)) == 0x0c000000 && ntohl(get_u_int32_t(packet->payload, 4)) == 0xd2000c00
+ && (packet->payload[9]
+ == 0x16) && ntohs(get_u_int16_t(packet->payload, 10)) == 0x0000 && ntohs(get_u_int16_t(packet->payload, 14)) == 0x0000) {
+ NDPI_LOG(NDPI_PROTOCOL_WORLD_OF_KUNG_FU, ndpi_struct, NDPI_LOG_DEBUG, "detected world_of_kung_fu.\n");
+ ndpi_int_world_of_kung_fu_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_WORLD_OF_KUNG_FU, ndpi_struct, NDPI_LOG_DEBUG, "exclude world_of_kung_fu.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WORLD_OF_KUNG_FU);
+}
+
+#endif
diff --git a/src/lib/protocols/world_of_warcraft.c b/src/lib/protocols/world_of_warcraft.c
new file mode 100644
index 000000000..02afc9d13
--- /dev/null
+++ b/src/lib/protocols/world_of_warcraft.c
@@ -0,0 +1,210 @@
+/*
+ * world_of_warcraft.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_WORLDOFWARCRAFT
+
+
+static void ndpi_int_worldofwarcraft_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WORLDOFWARCRAFT, protocol_type);
+}
+
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+u_int8_t ndpi_int_is_wow_port(const u_int16_t port)
+{
+ if (port == htons(3724) || port == htons(6112) || port == htons(6113) ||
+ port == htons(6114) || port == htons(4000) || port == htons(1119)) {
+ return 1;
+ }
+ return 0;
+}
+
+void ndpi_search_worldofwarcraft(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "Search World of Warcraft.\n");
+
+ if (packet->tcp != NULL) {
+ if ((packet->payload_packet_len > NDPI_STATICSTRING_LEN("POST /") &&
+ memcmp(packet->payload, "POST /", NDPI_STATICSTRING_LEN("POST /")) == 0) ||
+ (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /") &&
+ memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0)) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->user_agent_line.ptr != NULL &&
+ packet->user_agent_line.len == NDPI_STATICSTRING_LEN("Blizzard Web Client") &&
+ memcmp(packet->user_agent_line.ptr, "Blizzard Web Client",
+ NDPI_STATICSTRING_LEN("Blizzard Web Client")) == 0) {
+ ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG,
+ "World of Warcraft: Web Client found\n");
+ return;
+ }
+ }
+ if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /")
+ && memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->user_agent_line.ptr != NULL && packet->host_line.ptr != NULL
+ && packet->user_agent_line.len > NDPI_STATICSTRING_LEN("Blizzard Downloader")
+ && packet->host_line.len > NDPI_STATICSTRING_LEN("worldofwarcraft.com")
+ && memcmp(packet->user_agent_line.ptr, "Blizzard Downloader",
+ NDPI_STATICSTRING_LEN("Blizzard Downloader")) == 0
+ && memcmp(&packet->host_line.ptr[packet->host_line.len - NDPI_STATICSTRING_LEN("worldofwarcraft.com")],
+ "worldofwarcraft.com", NDPI_STATICSTRING_LEN("worldofwarcraft.com")) == 0) {
+ ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG,
+ "World of Warcraft: Web Client found\n");
+ return;
+ }
+ }
+ if (packet->payload_packet_len == 50 && memcmp(&packet->payload[2], "WORLD OF WARCRAFT CONNECTION",
+ NDPI_STATICSTRING_LEN("WORLD OF WARCRAFT CONNECTION")) == 0) {
+ ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "World of Warcraft: Login found\n");
+ return;
+ }
+ if (packet->tcp->dest == htons(3724) && packet->payload_packet_len < 70
+ && packet->payload_packet_len > 40 && (memcmp(&packet->payload[4], "WoW", 3) == 0
+ || memcmp(&packet->payload[5], "WoW", 3) == 0)) {
+ ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "World of Warcraft: Login found\n");
+ return;
+ }
+
+ if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_WORLDOFWARCRAFT) != 0) {
+ if (packet->tcp->source == htons(3724)
+ && packet->payload_packet_len == 8 && get_u_int32_t(packet->payload, 0) == htonl(0x0006ec01)) {
+ ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
+ NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n");
+ return;
+ }
+
+ }
+
+ /* for some well known WoW ports
+ check another pattern */
+ if (flow->l4.tcp.wow_stage == 0) {
+ if (ndpi_int_is_wow_port(packet->tcp->source) &&
+ packet->payload_packet_len >= 14 &&
+ ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2)) {
+ if (get_u_int32_t(packet->payload, 2) == htonl(0xec010100)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
+ NDPI_LOG_DEBUG, "probably World of Warcraft, waiting for final packet\n");
+ flow->l4.tcp.wow_stage = 2;
+ return;
+ } else if (packet->payload_packet_len == 41 &&
+ (get_u_int16_t(packet->payload, 2) == htons(0x0085) ||
+ get_u_int16_t(packet->payload, 2) == htons(0x0034) ||
+ get_u_int16_t(packet->payload, 2) == htons(0x1960))) {
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
+ NDPI_LOG_DEBUG, "maybe World of Warcraft, need next\n");
+ flow->l4.tcp.wow_stage = 1;
+ return;
+ }
+ }
+ }
+
+ if (flow->l4.tcp.wow_stage == 1) {
+ if (packet->payload_packet_len == 325 &&
+ ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2) &&
+ get_u_int16_t(packet->payload, 4) == 0 &&
+ (get_u_int16_t(packet->payload, packet->payload_packet_len - 3) == htons(0x2331) ||
+ get_u_int16_t(packet->payload, 67) == htons(0x2331)) &&
+ (memcmp
+ (&packet->payload[packet->payload_packet_len - 18],
+ "\x94\xec\xff\xfd\x67\x62\xd4\x67\xfb\xf9\xdd\xbd\xfd\x01\xc0\x8f\xf9\x81", 18) == 0
+ || memcmp(&packet->payload[packet->payload_packet_len - 30],
+ "\x94\xec\xff\xfd\x67\x62\xd4\x67\xfb\xf9\xdd\xbd\xfd\x01\xc0\x8f\xf9\x81", 18) == 0)) {
+ ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
+ NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n");
+ return;
+ }
+ if (packet->payload_packet_len > 32 &&
+ ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2)) {
+ if (get_u_int16_t(packet->payload, 4) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
+ NDPI_LOG_DEBUG, "probably World of Warcraft, waiting for final packet\n");
+ flow->l4.tcp.wow_stage = 2;
+ return;
+ } else if (get_u_int32_t(packet->payload, 2) == htonl(0x12050000)) {
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
+ NDPI_LOG_DEBUG, "probably World of Warcraft, waiting for final packet\n");
+ flow->l4.tcp.wow_stage = 2;
+ return;
+ }
+ }
+ }
+
+ if (flow->l4.tcp.wow_stage == 2) {
+ if (packet->payload_packet_len == 4) {
+ ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
+ NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n");
+ return;
+ } else if (packet->payload_packet_len > 4 && packet->payload_packet_len <= 16 && packet->payload[4] == 0x0c) {
+ ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
+ NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n");
+ return;
+ } else if (flow->packet_counter < 3) {
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "waiting for final packet\n");
+ return;
+ }
+ }
+ if (flow->l4.tcp.wow_stage == 0 && packet->tcp->dest == htons(1119)) {
+ /* special log in port for battle.net/world of warcraft */
+
+ if (packet->payload_packet_len >= 77 &&
+ get_u_int32_t(packet->payload, 0) == htonl(0x40000aed) && get_u_int32_t(packet->payload, 4) == htonl(0xea070aed)) {
+
+ ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
+ NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n");
+ return;
+ }
+ }
+ }
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WORLDOFWARCRAFT);
+}
+
+#endif
diff --git a/src/lib/protocols/xbox.c b/src/lib/protocols/xbox.c
new file mode 100644
index 000000000..6ee25f05f
--- /dev/null
+++ b/src/lib/protocols/xbox.c
@@ -0,0 +1,103 @@
+/*
+ * xbox.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_XBOX
+
+static void ndpi_int_xbox_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_XBOX, NDPI_REAL_PROTOCOL);
+}
+
+
+void ndpi_search_xbox(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ // struct ndpi_id_struct *src = flow->src;
+ // struct ndpi_id_struct *dst = flow->dst;
+
+ /*
+ * THIS IS TH XBOX UDP DETCTION ONLY !!!
+ * the xbox tcp detection is done by http code
+ */
+
+
+ /* this detection also works for asymmetric xbox udp traffic */
+ if (packet->udp != NULL) {
+
+ u_int16_t dport = ntohs(packet->udp->dest);
+ u_int16_t sport = ntohs(packet->udp->source);
+
+ NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "search xbox\n");
+
+ if (packet->payload_packet_len > 12 &&
+ get_u_int32_t(packet->payload, 0) == 0 && packet->payload[5] == 0x58 &&
+ memcmp(&packet->payload[7], "\x00\x00\x00", 3) == 0) {
+
+ if ((packet->payload[4] == 0x0c && packet->payload[6] == 0x76) ||
+ (packet->payload[4] == 0x02 && packet->payload[6] == 0x18) ||
+ (packet->payload[4] == 0x0b && packet->payload[6] == 0x80) ||
+ (packet->payload[4] == 0x03 && packet->payload[6] == 0x40) ||
+ (packet->payload[4] == 0x06 && packet->payload[6] == 0x4e)) {
+
+ ndpi_int_xbox_add_connection(ndpi_struct, flow);
+ NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "xbox udp connection detected\n");
+ return;
+ }
+ }
+ if ((dport == 3074 || sport == 3074)
+ && ((packet->payload_packet_len == 24 && packet->payload[0] == 0x00)
+ || (packet->payload_packet_len == 42 && packet->payload[0] == 0x4f && packet->payload[2] == 0x0a)
+ || (packet->payload_packet_len == 80 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x50bc
+ && packet->payload[2] == 0x45)
+ || (packet->payload_packet_len == 40 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xcf5f3202)
+ || (packet->payload_packet_len == 38 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xc1457f03)
+ || (packet->payload_packet_len == 28 && ntohl(get_u_int32_t(packet->payload, 0)) == 0x015f2c00))) {
+ if (flow->l4.udp.xbox_stage == 1) {
+ ndpi_int_xbox_add_connection(ndpi_struct, flow);
+ NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "xbox udp connection detected\n");
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "maybe xbox.\n");
+ flow->l4.udp.xbox_stage++;
+ return;
+ }
+
+ /* exclude here all non matched udp traffic, exclude here tcp only if http has been excluded, because xbox could use http */
+ if (packet->tcp == NULL
+#ifdef NDPI_PROTOCOL_HTTP
+ || NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP) != 0
+#endif
+ ) {
+ NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "xbox udp excluded.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_XBOX);
+ }
+ }
+ /* to not exclude tcp traffic here, done by http code... */
+}
+
+#endif
diff --git a/src/lib/protocols/xdmcp.c b/src/lib/protocols/xdmcp.c
new file mode 100644
index 000000000..dcbcfd231
--- /dev/null
+++ b/src/lib/protocols/xdmcp.c
@@ -0,0 +1,69 @@
+/*
+ * xdmcp.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_protocols.h"
+#ifdef NDPI_PROTOCOL_XDMCP
+
+
+static void ndpi_int_xdmcp_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_XDMCP, NDPI_REAL_PROTOCOL);
+}
+
+void ndpi_search_xdmcp(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+// struct ndpi_id_struct *src=ndpi_struct->src;
+// struct ndpi_id_struct *dst=ndpi_struct->dst;
+
+ NDPI_LOG(NDPI_PROTOCOL_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "search xdmcp.\n");
+
+ if (packet->tcp != NULL && (ntohs(packet->tcp->dest) >= 6000 && ntohs(packet->tcp->dest) <= 6005)
+ && packet->payload_packet_len == 48
+ && packet->payload[0] == 0x6c && packet->payload[1] == 0x00
+ && ntohs(get_u_int16_t(packet->payload, 6)) == 0x1200 && ntohs(get_u_int16_t(packet->payload, 8)) == 0x1000) {
+
+ NDPI_LOG(NDPI_PROTOCOL_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "found xdmcp over tcp.\n");
+ ndpi_int_xdmcp_add_connection(ndpi_struct, flow);
+ return;
+ }
+ if (packet->udp != NULL && ntohs(packet->udp->dest) == 177
+ && packet->payload_packet_len >= 6 && packet->payload_packet_len == 6 + ntohs(get_u_int16_t(packet->payload, 4))
+ && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0001 && ntohs(get_u_int16_t(packet->payload, 2)) == 0x0002) {
+
+ NDPI_LOG(NDPI_PROTOCOL_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "found xdmcp over udp.\n");
+ ndpi_int_xdmcp_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+
+ NDPI_LOG(NDPI_PROTOCOL_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "exclude xdmcp.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_XDMCP);
+}
+
+#endif
diff --git a/src/lib/protocols/yahoo.c b/src/lib/protocols/yahoo.c
new file mode 100644
index 000000000..c5d340bc1
--- /dev/null
+++ b/src/lib/protocols/yahoo.c
@@ -0,0 +1,434 @@
+/*
+ * yahoo.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_YAHOO
+
+
+struct ndpi_yahoo_header {
+ u_int8_t YMSG_str[4];
+ u_int16_t version;
+ u_int16_t nothing0;
+ u_int16_t len;
+ u_int16_t service;
+ u_int32_t status;
+ u_int32_t session_id;
+};
+
+/* This function checks the pattern '<Ymsg Command=' in line 8 of parsed lines or
+ * in the payload*/
+static u_int8_t ndpi_check_for_YmsgCommand(u_int16_t len, const u_int8_t * ptr)
+{
+ u_int16_t i;
+
+ for (i = 0; i < len - 12; i++) {
+ if (ptr[i] == 'Y') {
+ if (memcmp(&ptr[i + 1], "msg Command=", 12) == 0) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static void ndpi_int_yahoo_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_YAHOO, protocol_type);
+}
+
+
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+u_int8_t check_ymsg(const u_int8_t * payload, u_int16_t payload_packet_len)
+{
+
+ const struct ndpi_yahoo_header *yahoo = (struct ndpi_yahoo_header *) payload;
+
+ u_int16_t yahoo_len_parsed = 0;
+ do {
+ u_int16_t ylen = ntohs(yahoo->len);
+
+ yahoo_len_parsed += 20 + ylen; /* possible overflow here: 20 + ylen = 0x10000 --> 0 --> infinite loop */
+
+ if (ylen >= payload_packet_len || yahoo_len_parsed >= payload_packet_len)
+ break;
+
+ yahoo = (struct ndpi_yahoo_header *) (payload + yahoo_len_parsed);
+ }
+ while (memcmp(yahoo->YMSG_str, "YMSG", 4) == 0);
+
+ if (yahoo_len_parsed == payload_packet_len)
+ return 1;
+ return 0;
+}
+
+static void ndpi_search_yahoo_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ const struct ndpi_yahoo_header *yahoo = (struct ndpi_yahoo_header *) packet->payload;
+ if (packet->payload_packet_len == 0) {
+ return;
+ }
+
+ /* packet must be at least 20 bytes long */
+ if (packet->payload_packet_len >= 20
+ && memcmp(yahoo->YMSG_str, "YMSG", 4) == 0 && ((packet->payload_packet_len - 20) == ntohs(yahoo->len)
+ || check_ymsg(packet->payload, packet->payload_packet_len))) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO FOUND\n");
+ flow->yahoo_detection_finished = 2;
+ if (ntohs(yahoo->service) == 24 || ntohs(yahoo->service) == 152 || ntohs(yahoo->service) == 74) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO conference or chat invite found");
+ if (src != NULL) {
+ src->yahoo_conf_logged_in = 1;
+ }
+ if (dst != NULL) {
+ dst->yahoo_conf_logged_in = 1;
+ }
+ }
+ if (ntohs(yahoo->service) == 27 || ntohs(yahoo->service) == 155 || ntohs(yahoo->service) == 160) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO conference or chat logoff found");
+ if (src != NULL) {
+ src->yahoo_conf_logged_in = 0;
+ src->yahoo_voice_conf_logged_in = 0;
+ }
+ }
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ } else if (flow->yahoo_detection_finished == 2 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_YAHOO) {
+ return;
+ } else if (packet->payload_packet_len == 4 && memcmp(yahoo->YMSG_str, "YMSG", 4) == 0) {
+ flow->l4.tcp.yahoo_sip_comm = 1;
+ return;
+ } else if (flow->l4.tcp.yahoo_sip_comm && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN
+ && flow->packet_counter < 3) {
+ return;
+ }
+
+ /* now test for http login, at least 100 a bytes packet */
+ if (ndpi_struct->yahoo_detect_http_connections != 0 && packet->payload_packet_len > 100) {
+ if (memcmp(packet->payload, "POST /relay?token=", 18) == 0
+ || memcmp(packet->payload, "GET /relay?token=", 17) == 0
+ || memcmp(packet->payload, "GET /?token=", 12) == 0
+ || memcmp(packet->payload, "HEAD /relay?token=", 18) == 0) {
+ if ((src != NULL
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO)
+ != 0) || (dst != NULL
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO)
+ != 0)) {
+ /* this is mostly a file transfer */
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ if (memcmp(packet->payload, "POST ", 5) == 0) {
+ u_int16_t a;
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+
+ if ((packet->user_agent_line.len >= 21)
+ && (memcmp(packet->user_agent_line.ptr, "YahooMobileMessenger/", 21) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO(Mobile)");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+
+ if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_YAHOO)
+ && packet->parsed_lines > 5
+ && memcmp(&packet->payload[5], "/Messenger.", 11) == 0
+ && packet->line[1].len >= 17
+ && memcmp(packet->line[1].ptr, "Connection: Close",
+ 17) == 0 && packet->line[2].len >= 6
+ && memcmp(packet->line[2].ptr, "Host: ", 6) == 0
+ && packet->line[3].len >= 16
+ && memcmp(packet->line[3].ptr, "Content-Length: ",
+ 16) == 0 && packet->line[4].len >= 23
+ && memcmp(packet->line[4].ptr, "User-Agent: Mozilla/5.0",
+ 23) == 0 && packet->line[5].len >= 23
+ && memcmp(packet->line[5].ptr, "Cache-Control: no-cache", 23) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE,
+ "YAHOO HTTP POST P2P FILETRANSFER FOUND\n");
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+
+ if (packet->host_line.ptr != NULL && packet->host_line.len >= 26 &&
+ memcmp(packet->host_line.ptr, "filetransfer.msg.yahoo.com", 26) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO HTTP POST FILETRANSFER FOUND\n");
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ /* now check every line */
+ for (a = 0; a < packet->parsed_lines; a++) {
+ if (packet->line[a].len >= 4 && memcmp(packet->line[a].ptr, "YMSG", 4) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct,
+ NDPI_LOG_TRACE,
+ "YAHOO HTTP POST FOUND, line is: %.*s\n", packet->line[a].len, packet->line[a].ptr);
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ if (packet->parsed_lines > 8 && packet->line[8].len > 250 && packet->line[8].ptr != NULL) {
+ if (memcmp(packet->line[8].ptr, "<Session ", 9) == 0) {
+ if (ndpi_check_for_YmsgCommand(packet->line[8].len, packet->line[8].ptr)) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG,
+ "found HTTP Proxy Yahoo Chat <Ymsg Command= pattern \n");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+ }
+ if (memcmp(packet->payload, "GET /Messenger.", 15) == 0) {
+ if ((src != NULL
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO)
+ != 0) || (dst != NULL
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO)
+ != 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO HTTP GET /Messenger. match\n");
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+
+ if ((memcmp(packet->payload, "GET /", 5) == 0)) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if ((packet->user_agent_line.ptr != NULL
+ && packet->user_agent_line.len >= NDPI_STATICSTRING_LEN("YahooMobileMessenger/")
+ && memcmp(packet->user_agent_line.ptr, "YahooMobileMessenger/",
+ NDPI_STATICSTRING_LEN("YahooMobileMessenger/")) == 0)
+ || (packet->user_agent_line.len >= 15
+ && (memcmp(packet->user_agent_line.ptr, "Y!%20Messenger/", 15) == 0))) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO(Mobile)");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ if (packet->host_line.ptr != NULL && packet->host_line.len >= NDPI_STATICSTRING_LEN("msg.yahoo.com") &&
+ memcmp(&packet->host_line.ptr[packet->host_line.len - NDPI_STATICSTRING_LEN("msg.yahoo.com")],
+ "msg.yahoo.com", NDPI_STATICSTRING_LEN("msg.yahoo.com")) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+
+ }
+
+ }
+ /* found another http login command for yahoo, it is like OSCAR */
+ /* detect http connections */
+
+ if (packet->payload_packet_len > 50 && (memcmp(packet->payload, "content-length: ", 16) == 0)) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->parsed_lines > 2 && packet->line[1].len == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "first line is empty.\n");
+ if (packet->line[2].len > 13 && memcmp(packet->line[2].ptr, "<Ymsg Command=", 14) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO web chat found\n");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ }
+ }
+
+ if (packet->payload_packet_len > 38 && memcmp(packet->payload, "CONNECT scs.msg.yahoo.com:5050 HTTP/1.", 38) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO-HTTP FOUND\n");
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+
+ if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0)
+ || (dst != NULL
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0)) {
+ if (packet->payload_packet_len == 6 && memcmp(packet->payload, "YAHOO!", 6) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ /* asymmetric detection for SNDIMG not done yet.
+ * See ./Yahoo8.1-VideoCall-LAN.pcap and ./Yahoo-VideoCall-inPublicIP.pcap */
+
+
+ if (packet->payload_packet_len == 8
+ && (memcmp(packet->payload, "<SNDIMG>", 8) == 0 || memcmp(packet->payload, "<REQIMG>", 8) == 0
+ || memcmp(packet->payload, "<RVWCFG>", 8) == 0 || memcmp(packet->payload, "<RUPCFG>", 8) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE,
+ "YAHOO SNDIMG or REQIMG or RVWCFG or RUPCFG FOUND\n");
+ if (src != NULL) {
+ if (memcmp(packet->payload, "<SNDIMG>", 8) == 0) {
+ src->yahoo_video_lan_dir = 0;
+ } else {
+ src->yahoo_video_lan_dir = 1;
+ }
+ src->yahoo_video_lan_timer = packet->tick_timestamp;
+ }
+ if (dst != NULL) {
+ if (memcmp(packet->payload, "<SNDIMG>", 8) == 0) {
+ dst->yahoo_video_lan_dir = 0;
+ } else {
+ dst->yahoo_video_lan_dir = 1;
+ }
+ dst->yahoo_video_lan_timer = packet->tick_timestamp;
+
+ }
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO subtype VIDEO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ if (src != NULL && packet->tcp->dest == htons(5100)
+ && ((u_int32_t)
+ (packet->tick_timestamp - src->yahoo_video_lan_timer) < ndpi_struct->yahoo_lan_video_timeout)) {
+ if (src->yahoo_video_lan_dir == 1) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "IMG MARKED");
+ return;
+ }
+
+ }
+ if (dst != NULL && packet->tcp->dest == htons(5100)
+ && ((u_int32_t)
+ (packet->tick_timestamp - dst->yahoo_video_lan_timer) < ndpi_struct->yahoo_lan_video_timeout)) {
+ if (dst->yahoo_video_lan_dir == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "IMG MARKED");
+ return;
+ }
+
+ }
+ }
+
+ /* detect YAHOO over HTTP proxy */
+#ifdef NDPI_PROTOCOL_HTTP
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP)
+#endif
+ {
+
+ if (flow->l4.tcp.yahoo_http_proxy_stage == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG,
+ "YAHOO maybe HTTP proxy packet 1 => need next packet\n");
+ flow->l4.tcp.yahoo_http_proxy_stage = 1 + packet->packet_direction;
+ return;
+ }
+ if (flow->l4.tcp.yahoo_http_proxy_stage == 1 + packet->packet_direction) {
+ if ((packet->payload_packet_len > 250) && (memcmp(packet->payload, "<Session ", 9) == 0)) {
+ if (ndpi_check_for_YmsgCommand(packet->payload_packet_len, packet->payload)) {
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG,
+ "found HTTP Proxy Yahoo Chat <Ymsg Command= pattern \n");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG,
+ "YAHOO maybe HTTP proxy still initial direction => need next packet\n");
+ return;
+ }
+ if (flow->l4.tcp.yahoo_http_proxy_stage == 2 - packet->packet_direction) {
+
+ ndpi_parse_packet_line_info_any(ndpi_struct, flow);
+
+ if (packet->parsed_lines >= 9) {
+
+ if (packet->line[4].ptr != NULL && packet->line[4].len >= 9 &&
+ packet->line[8].ptr != NULL && packet->line[8].len >= 6 &&
+ memcmp(packet->line[4].ptr, "<Session ", 9) == 0 &&
+ memcmp(packet->line[8].ptr, "<Ymsg ", 6) == 0) {
+
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO over HTTP proxy");
+ ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ }
+ }
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_YAHOO);
+}
+
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+void ndpi_search_yahoo_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+
+
+
+ struct ndpi_id_struct *src = flow->src;
+ if (src == NULL || NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) == 0) {
+ goto excl_yahoo_udp;
+ }
+ excl_yahoo_udp:
+
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_YAHOO);
+}
+
+void ndpi_search_yahoo(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+
+ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "search yahoo\n");
+
+ if (packet->payload_packet_len > 0 && flow->yahoo_detection_finished == 0) {
+ if (packet->tcp != NULL && packet->tcp_retransmission == 0) {
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN
+#ifdef NDPI_PROTOCOL_HTTP
+ || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP
+#endif
+#ifdef NDPI_PROTOCOL_SSL
+ || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL
+#endif
+ ) {
+ ndpi_search_yahoo_tcp(ndpi_struct, flow);
+ }
+ } else if (packet->udp != NULL) {
+ ndpi_search_yahoo_udp(ndpi_struct, flow);
+ }
+ }
+ if (packet->payload_packet_len > 0 && flow->yahoo_detection_finished == 2) {
+ if (packet->tcp != NULL && packet->tcp_retransmission == 0) {
+ ndpi_search_yahoo_tcp(ndpi_struct, flow);
+ }
+ }
+}
+#endif
diff --git a/src/lib/protocols/zattoo.c b/src/lib/protocols/zattoo.c
new file mode 100644
index 000000000..f7de4a8e7
--- /dev/null
+++ b/src/lib/protocols/zattoo.c
@@ -0,0 +1,235 @@
+/*
+ * zattoo.c
+ *
+ * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_ZATTOO
+
+static void ndpi_int_zattoo_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ ndpi_protocol_type_t protocol_type)
+{
+
+ struct ndpi_packet_struct *packet = &flow->packet;
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_ZATTOO, protocol_type);
+
+ if (src != NULL) {
+ src->zattoo_ts = packet->tick_timestamp;
+ }
+ if (dst != NULL) {
+ dst->zattoo_ts = packet->tick_timestamp;
+ }
+}
+
+
+
+#if !defined(WIN32)
+static inline
+#else
+__forceinline static
+#endif
+u_int8_t ndpi_int_zattoo_user_agent_set(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ if (flow->packet.user_agent_line.ptr != NULL && flow->packet.user_agent_line.len == 111) {
+ if (memcmp(flow->packet.user_agent_line.ptr +
+ flow->packet.user_agent_line.len - 25, "Zattoo/4", sizeof("Zattoo/4") - 1) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "found zattoo useragent\n");
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void ndpi_search_zattoo(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+
+ struct ndpi_id_struct *src = flow->src;
+ struct ndpi_id_struct *dst = flow->dst;
+
+ u_int16_t i;
+
+ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_ZATTOO) {
+ if (src != NULL && ((u_int32_t)
+ (packet->tick_timestamp - src->zattoo_ts) < ndpi_struct->zattoo_connection_timeout)) {
+ src->zattoo_ts = packet->tick_timestamp;
+ }
+ if (dst != NULL && ((u_int32_t)
+ (packet->tick_timestamp - dst->zattoo_ts) < ndpi_struct->zattoo_connection_timeout)) {
+ dst->zattoo_ts = packet->tick_timestamp;
+ }
+ return;
+ }
+
+ if (packet->tcp != NULL) {
+ if (packet->payload_packet_len > 50 && memcmp(packet->payload, "GET /frontdoor/fd?brand=Zattoo&v=", 33) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct,
+ NDPI_LOG_DEBUG, "add connection over tcp with pattern GET /frontdoor/fd?brand=Zattoo&v=\n");
+ ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len > 50
+ && memcmp(packet->payload, "GET /ZattooAdRedirect/redirect.jsp?user=", 40) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct,
+ NDPI_LOG_DEBUG, "add connection over tcp with pattern GET /ZattooAdRedirect/redirect.jsp?user=\n");
+ ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ if (packet->payload_packet_len > 50
+ && (memcmp(packet->payload, "POST /channelserver/player/channel/update HTTP/1.1", 50) == 0
+ || memcmp(packet->payload, "GET /epg/query", 14) == 0)) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ for (i = 0; i < packet->parsed_lines; i++) {
+ if (packet->line[i].len >= 18 && (memcmp(packet->line[i].ptr, "User-Agent: Zattoo", 18) == 0)) {
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct,
+ NDPI_LOG_DEBUG,
+ "add connection over tcp with pattern POST /channelserver/player/channel/update HTTP/1.1\n");
+ ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ } else if (packet->payload_packet_len > 50
+ && (memcmp(packet->payload, "GET /", 5) == 0
+ || memcmp(packet->payload, "POST /", NDPI_STATICSTRING_LEN("POST /")) == 0)) {
+ /* TODO to avoid searching currently only a specific length and offset is used
+ * that might be changed later */
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (ndpi_int_zattoo_user_agent_set(ndpi_struct, flow)) {
+ ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ } else if (packet->payload_packet_len > 50 && memcmp(packet->payload, "POST http://", 12) == 0) {
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ // test for unique character of the zattoo header
+ if (packet->parsed_lines == 4 && packet->host_line.ptr != NULL) {
+ u_int32_t ip;
+ u_int16_t bytes_read = 0;
+
+ ip = ndpi_bytestream_to_ipv4(&packet->payload[12], packet->payload_packet_len, &bytes_read);
+
+ // and now test the firt 5 bytes of the payload for zattoo pattern
+ if (ip == packet->iph->daddr
+ && packet->empty_line_position_set != 0
+ && ((packet->payload_packet_len - packet->empty_line_position) > 10)
+ && packet->payload[packet->empty_line_position + 2] ==
+ 0x03
+ && packet->payload[packet->empty_line_position + 3] ==
+ 0x04
+ && packet->payload[packet->empty_line_position + 4] ==
+ 0x00
+ && packet->payload[packet->empty_line_position + 5] ==
+ 0x04
+ && packet->payload[packet->empty_line_position + 6] ==
+ 0x0a && packet->payload[packet->empty_line_position + 7] == 0x00) {
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct,
+ NDPI_LOG_DEBUG, "add connection over tcp with pattern POST http://\n");
+ ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ }
+ } else if (flow->zattoo_stage == 0) {
+
+ if (packet->payload_packet_len > 50
+ && packet->payload[0] == 0x03
+ && packet->payload[1] == 0x04
+ && packet->payload[2] == 0x00
+ && packet->payload[3] == 0x04 && packet->payload[4] == 0x0a && packet->payload[5] == 0x00) {
+ flow->zattoo_stage = 1 + packet->packet_direction;
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct,
+ NDPI_LOG_DEBUG, "need next packet, seen pattern 0x030400040a00\n");
+ return;
+ }
+ /* the following is is searching for flash, not for zattoo. cust1 wants to do so. */
+ } else if (flow->zattoo_stage == 2 - packet->packet_direction
+ && packet->payload_packet_len > 50 && packet->payload[0] == 0x03 && packet->payload[1] == 0x04) {
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over tcp with 0x0304.\n");
+ ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ } else if (flow->zattoo_stage == 1 + packet->packet_direction) {
+ if (packet->payload_packet_len > 500 && packet->payload[0] == 0x00 && packet->payload[1] == 0x00) {
+ flow->zattoo_stage = 3 + packet->packet_direction;
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct,
+ NDPI_LOG_DEBUG, "need next packet, seen pattern 0x0000\n");
+ return;
+ }
+ if (packet->payload_packet_len > 50
+ && packet->payload[0] == 0x03
+ && packet->payload[1] == 0x04
+ && packet->payload[2] == 0x00
+ && packet->payload[3] == 0x04 && packet->payload[4] == 0x0a && packet->payload[5] == 0x00) {
+ }
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG,
+ "need next packet, seen pattern 0x030400040a00\n");
+ return;
+ } else if (flow->zattoo_stage == 4 - packet->packet_direction
+ && packet->payload_packet_len > 50 && packet->payload[0] == 0x03 && packet->payload[1] == 0x04) {
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over tcp with 0x0304.\n");
+ ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ } else if (flow->zattoo_stage == 5 + packet->packet_direction && (packet->payload_packet_len == 125)) {
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "detected zattoo.\n");
+ ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ } else if (flow->zattoo_stage == 6 - packet->packet_direction && packet->payload_packet_len == 1412) {
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "found zattoo.\n");
+ ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG,
+ "ZATTOO: discarted the flow (TCP): packet_size: %u; Flowstage: %u\n",
+ packet->payload_packet_len, flow->zattoo_stage);
+
+ } else if (packet->udp != NULL) {
+
+ if (packet->payload_packet_len > 20 && (packet->udp->dest == htons(5003)
+ || packet->udp->source == htons(5003))
+ && (get_u_int16_t(packet->payload, 0) == htons(0x037a)
+ || get_u_int16_t(packet->payload, 0) == htons(0x0378)
+ || get_u_int16_t(packet->payload, 0) == htons(0x0305)
+ || get_u_int32_t(packet->payload, 0) == htonl(0x03040004)
+ || get_u_int32_t(packet->payload, 0) == htonl(0x03010005))) {
+ if (++flow->zattoo_stage == 2) {
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over udp.\n");
+ ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
+ return;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "need next packet udp.\n");
+ return;
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG,
+ "ZATTOO: discarded the flow (UDP): packet_size: %u; Flowstage: %u\n",
+ packet->payload_packet_len, flow->zattoo_stage);
+
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "exclude zattoo.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ZATTOO);
+}
+#endif
diff --git a/src/lib/protocols/zmq.c b/src/lib/protocols/zmq.c
new file mode 100644
index 000000000..12548a2ed
--- /dev/null
+++ b/src/lib/protocols/zmq.c
@@ -0,0 +1,100 @@
+/*
+ * zmq.c
+ *
+ * Copyright (C) 2011-15 - ntop.org
+ *
+ * nDPI is free software: you can zmqtribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_ZMQ
+
+static void ndpi_int_zmq_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_ZMQ, NDPI_REAL_PROTOCOL);
+ NDPI_LOG(NDPI_PROTOCOL_ZMQ, ndpi_struct, NDPI_LOG_TRACE, "ZMQ Found.\n");
+}
+
+
+static void ndpi_check_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+ u_char p0[] = { 0x00, 0x00, 0x00, 0x05, 0x01, 0x66, 0x6c, 0x6f, 0x77 };
+ u_char p1[] = { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f };
+ u_char p2[] = { 0x28, 0x66, 0x6c, 0x6f, 0x77, 0x00 };
+
+ if(payload_len == 0) return; /* Shouldn't happen */
+
+ /* Break after 17 packets. */
+ if(flow->packet_counter > 17) {
+ NDPI_LOG(NDPI_PROTOCOL_ZMQ, ndpi_struct, NDPI_LOG_TRACE, "Exclude ZMQ.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ZMQ);
+ return;
+ }
+
+ if(flow->l4.tcp.prev_zmq_pkt_len == 0) {
+ flow->l4.tcp.prev_zmq_pkt_len = ndpi_min(packet->payload_packet_len, 10);
+ memcpy(flow->l4.tcp.prev_zmq_pkt, packet->payload, flow->l4.tcp.prev_zmq_pkt_len);
+ return; /* Too early */
+ }
+
+ if(payload_len == 2) {
+ if(flow->l4.tcp.prev_zmq_pkt_len == 2) {
+ if((memcmp(packet->payload, "\01\01", 2) == 0)
+ && (memcmp(flow->l4.tcp.prev_zmq_pkt, "\01\02", 2) == 0)) {
+ ndpi_int_zmq_add_connection(ndpi_struct, flow);
+ return;
+ }
+ } else if(flow->l4.tcp.prev_zmq_pkt_len == 9) {
+ if((memcmp(packet->payload, "\00\00", 2) == 0)
+ && (memcmp(flow->l4.tcp.prev_zmq_pkt, p0, 9) == 0)) {
+ ndpi_int_zmq_add_connection(ndpi_struct, flow);
+ return;
+ }
+ } else if(flow->l4.tcp.prev_zmq_pkt_len == 10) {
+ if((memcmp(packet->payload, "\01\02", 2) == 0)
+ && (memcmp(flow->l4.tcp.prev_zmq_pkt, p1, 10) == 0)) {
+ ndpi_int_zmq_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ } else if(payload_len >= 10) {
+ if(flow->l4.tcp.prev_zmq_pkt_len == 10) {
+ if(((memcmp(packet->payload, p1, 10) == 0)
+ && (memcmp(flow->l4.tcp.prev_zmq_pkt, p1, 10) == 0))
+ || ((memcmp(&packet->payload[1], p2, sizeof(p2)) == 0)
+ && (memcmp(&flow->l4.tcp.prev_zmq_pkt[1], p2, sizeof(p2)) == 0))) {
+ ndpi_int_zmq_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+ }
+}
+
+void ndpi_search_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_ZMQ, ndpi_struct, NDPI_LOG_TRACE, "ZMQ detection...\n");
+
+ /* skip marked packets */
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_ZMQ) {
+ if (packet->tcp_retransmission == 0) {
+ ndpi_check_zmq(ndpi_struct, flow);
+ }
+ }
+}
+
+#endif
diff --git a/src/lib/third_party/include/actypes.h b/src/lib/third_party/include/actypes.h
new file mode 100644
index 000000000..1900ae9a0
--- /dev/null
+++ b/src/lib/third_party/include/actypes.h
@@ -0,0 +1,135 @@
+/*
+ * actypes.h: Includes basic data types of ahocorasick library
+ * This file is part of multifast.
+ *
+ Copyright 2010-2012 Kamiar Kanani <kamiar.kanani@gmail.com>
+
+ multifast is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ multifast is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with multifast. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _AC_TYPES_H_
+#define _AC_TYPES_H_
+
+/* AC_ALPHABET_t:
+ * defines the alphabet type.
+ * Actually defining AC_ALPHABET_t as a char will work, but sometimes we deal
+ * with streams of other (bigger) types e.g. integers, specific enum, objects.
+ * Although they consists of string of bytes (chars), but using their specific
+ * types for AC_ALPHABET_t will lead to a better performance. so instead of
+ * dealing with strings of chars, we assume dealing with strings of
+ * AC_ALPHABET_t and leave it optional for other developers to define their
+ * own alphabets.
+ **/
+typedef char AC_ALPHABET_t;
+
+/* AC_REP_t:
+ * Provides a more readable representative for a pattern.
+ * because patterns themselves are not always suitable for displaying
+ * (e.g. for hex patterns), we offer this type to improve intelligibility
+ * of output. furthermore, sometimes it is useful, for example while
+ * retrieving patterns from a database, to maintain their identifiers in the
+ * automata for further reference. we provisioned two possible types as a
+ * union for this purpose. you can add your desired type in it.
+ **/
+typedef union {
+ char * stringy; /* null-terminated string */
+ unsigned long number;
+} AC_REP_t;
+
+/* AC_PATTERN_t:
+ * This is the pattern type that must be fed into AC automata.
+ * the 'astring' field is not null-terminated, due to it can contain zero
+ * value bytes. the 'length' field determines the number of AC_ALPHABET_t it
+ * carries. the 'representative' field is described in AC_REP_t. despite
+ * 'astring', 'representative' can have duplicate values for different given
+ * AC_PATTERN_t. it is an optional field and you can just fill it with 0.
+ * CAUTION:
+ * Not always the 'astring' points to the correct position in memory.
+ * it is the responsibility of your program to maintain a permanent allocation
+ * for astring field of the added pattern to automata.
+ **/
+typedef struct
+{
+ AC_ALPHABET_t * astring; /* String of alphabets */
+ unsigned int length; /* Length of pattern */
+ AC_REP_t rep; /* Representative string (optional) */
+} AC_PATTERN_t;
+
+/* AC_TEXT_t:
+ * The input text type that is fed to ac_automata_search() to be searched.
+ * it is similar to AC_PATTERN_t. actually we could use AC_PATTERN_t as input
+ * text, but for the purpose of being more readable, we defined this new type.
+ **/
+typedef struct
+{
+ AC_ALPHABET_t * astring; /* String of alphabets */
+ unsigned int length; /* Length of string */
+} AC_TEXT_t;
+
+/* AC_MATCH_t:
+ * Provides the structure for reporting a match event.
+ * a match event occurs when the automata reaches a final node. any final
+ * node can match one or more pattern at a position in a text. the
+ * 'patterns' field holds these matched patterns. obviously these
+ * matched patterns have same end-position in the text. there is a relationship
+ * between matched patterns: the shorter one is a factor (tail) of the longer
+ * one. the 'position' maintains the end position of matched patterns. the
+ * start position of patterns could be found by knowing their 'length' in
+ * AC_PATTERN_t. e.g. suppose "recent" and "cent" are matched at
+ * position 40 in the text, then the start position of them are 34 and 36
+ * respectively. finally the field 'match_num' maintains the number of
+ * matched patterns.
+ **/
+typedef struct
+{
+ AC_PATTERN_t * patterns; /* Array of matched pattern */
+ long position; /* The end position of matching pattern(s) in the text */
+ unsigned int match_num; /* Number of matched patterns */
+} AC_MATCH_t;
+
+/* AC_ERROR_t:
+ * Error that may occur while adding a pattern to the automata.
+ * it is returned by ac_automata_add().
+ **/
+typedef enum
+ {
+ ACERR_SUCCESS = 0, /* No error occurred */
+ ACERR_DUPLICATE_PATTERN, /* Duplicate patterns */
+ ACERR_LONG_PATTERN, /* Pattern length is longer than AC_PATTRN_MAX_LENGTH */
+ ACERR_ZERO_PATTERN, /* Empty pattern (zero length) */
+ ACERR_AUTOMATA_CLOSED, /* Automata is closed. after calling
+ ac_automata_finalize() you can not add new patterns to the automata. */
+ } AC_ERROR_t;
+
+/* MATCH_CALBACK_t:
+ * This is the call-back function type that must be given to automata at
+ * initialization to report match occurrence to the caller.
+ * at a match event, the automata will reach you using this function and sends
+ * you a pointer to AC_MATCH_t. using that pointer you can handle
+ * matches. you can send parameters to the call-back function when you call
+ * ac_automata_search(). at call-back, the automata will sent you those
+ * parameters as the second parameter (void *) of MATCH_CALBACK_t. inside
+ * the call-back function you can cast it to whatever you want.
+ * If you return 0 from MATCH_CALBACK_t function to the automata, it will
+ * continue searching, otherwise it will return from ac_automata_search()
+ * to your calling function.
+ **/
+typedef int (*MATCH_CALBACK_f)(AC_MATCH_t *, void *);
+
+/* AC_PATTRN_MAX_LENGTH:
+ * Maximum acceptable pattern length in AC_PATTERN_t.length
+ **/
+#define AC_PATTRN_MAX_LENGTH 1024
+
+#endif
diff --git a/src/lib/third_party/include/ahocorasick.h b/src/lib/third_party/include/ahocorasick.h
new file mode 100644
index 000000000..ea92e4a1b
--- /dev/null
+++ b/src/lib/third_party/include/ahocorasick.h
@@ -0,0 +1,69 @@
+/*
+ * ahocorasick.h: the main ahocorasick header file.
+ * This file is part of multifast.
+ *
+ Copyright 2010-2012 Kamiar Kanani <kamiar.kanani@gmail.com>
+
+ multifast is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ multifast is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with multifast. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _AUTOMATA_H_
+#define _AUTOMATA_H_
+
+#include "node.h"
+
+typedef struct
+{
+ /* The root of the Aho-Corasick trie */
+ AC_NODE_t * root;
+
+ /* maintain all nodes pointers. it will be used to access or release
+ * all nodes. */
+ AC_NODE_t ** all_nodes;
+
+ unsigned int all_nodes_num; /* Number of all nodes in the automata */
+ unsigned int all_nodes_max; /* Current max allocated memory for *all_nodes */
+
+ AC_MATCH_t match; /* Any match is reported with this */
+ MATCH_CALBACK_f match_callback; /* Match call-back function */
+
+ /* this flag indicates that if automata is finalized by
+ * ac_automata_finalize() or not. 1 means finalized and 0
+ * means not finalized (is open). after finalizing automata you can not
+ * add pattern to automata anymore. */
+ unsigned short automata_open;
+
+ /* It is possible to feed a large input to the automata chunk by chunk to
+ * be searched using ac_automata_search(). in fact by default automata
+ * thinks that all chunks are related unless you do ac_automata_reset().
+ * followings are variables that keep track of searching state. */
+ AC_NODE_t * current_node; /* Pointer to current node while searching */
+ unsigned long base_position; /* Represents the position of current chunk
+ related to whole input text */
+
+ /* Statistic Variables */
+ unsigned long total_patterns; /* Total patterns in the automata */
+
+} AC_AUTOMATA_t;
+
+
+AC_AUTOMATA_t * ac_automata_init (MATCH_CALBACK_f mc);
+AC_ERROR_t ac_automata_add (AC_AUTOMATA_t * thiz, AC_PATTERN_t * str);
+void ac_automata_finalize (AC_AUTOMATA_t * thiz);
+int ac_automata_search (AC_AUTOMATA_t * thiz, AC_TEXT_t * str, void * param);
+void ac_automata_reset (AC_AUTOMATA_t * thiz);
+void ac_automata_release (AC_AUTOMATA_t * thiz);
+void ac_automata_display (AC_AUTOMATA_t * thiz, char repcast);
+
+#endif
diff --git a/src/lib/third_party/include/node.h b/src/lib/third_party/include/node.h
new file mode 100644
index 000000000..13cf2ff11
--- /dev/null
+++ b/src/lib/third_party/include/node.h
@@ -0,0 +1,66 @@
+/*
+ * node.h: automata node header file
+ * This file is part of multifast.
+ *
+ Copyright 2010-2012 Kamiar Kanani <kamiar.kanani@gmail.com>
+
+ multifast is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ multifast is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with multifast. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _NODE_H_
+#define _NODE_H_
+
+#include "actypes.h"
+
+/* Forward Declaration */
+struct edge;
+
+/* automata node */
+typedef struct ac_node
+{
+ int id; /* Node ID : for debugging purpose */
+ short int final; /* 0: no ; 1: yes, it is a final node */
+ struct ac_node * failure_node; /* The failure node of this node */
+ unsigned short depth; /* depth: distance between this node and the root */
+
+ /* Matched patterns */
+ AC_PATTERN_t * matched_patterns; /* Array of matched patterns */
+ unsigned short matched_patterns_num; /* Number of matched patterns at this node */
+ unsigned short matched_patterns_max; /* Max capacity of allocated memory for matched_patterns */
+
+ /* Outgoing Edges */
+ struct edge * outgoing; /* Array of outgoing edges */
+ unsigned short outgoing_degree; /* Number of outgoing edges */
+ unsigned short outgoing_max; /* Max capacity of allocated memory for outgoing */
+} AC_NODE_t;
+
+/* The Edge of the Node */
+struct edge
+{
+ AC_ALPHABET_t alpha; /* Edge alpha */
+ struct ac_node * next; /* Target of the edge */
+};
+
+
+AC_NODE_t * node_create (void);
+AC_NODE_t * node_create_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha);
+void node_register_matchstr (AC_NODE_t * thiz, AC_PATTERN_t * str);
+void node_register_outgoing (AC_NODE_t * thiz, AC_NODE_t * next, AC_ALPHABET_t alpha);
+AC_NODE_t * node_find_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha);
+AC_NODE_t * node_findbs_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha);
+void node_release (AC_NODE_t * thiz);
+void node_assign_id (AC_NODE_t * thiz);
+void node_sort_edges (AC_NODE_t * thiz);
+
+#endif
diff --git a/src/lib/third_party/include/patricia.h b/src/lib/third_party/include/patricia.h
new file mode 100644
index 000000000..be8476e85
--- /dev/null
+++ b/src/lib/third_party/include/patricia.h
@@ -0,0 +1,302 @@
+/*
+ * $Id: patricia.h,v 1.6 2005/12/07 20:53:01 dplonka Exp $
+ * Dave Plonka <plonka@doit.wisc.edu>
+ *
+ * This product includes software developed by the University of Michigan,
+ * Merit Network, Inc., and their contributors.
+ *
+ * This file had been called "radix.h" in the MRT sources.
+ *
+ * I renamed it to "patricia.h" since it's not an implementation of a general
+ * radix trie. Also, pulled in various requirements from "mrt.h" and added
+ * some other things it could be used as a standalone API.
+
+ https://github.com/deepfield/MRT/blob/master/COPYRIGHT
+
+ Copyright (c) 1999-2013
+
+ The Regents of the University of Michigan ("The Regents") and Merit
+ Network, Inc.
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef _PATRICIA_H
+#define _PATRICIA_H
+
+#define HAVE_IPV6
+
+/* typedef unsigned int u_int; */
+/* { from defs.h */
+#define prefix_touchar(prefix) ((u_char *)&(prefix)->add.sin)
+
+#ifdef __KERNEL__
+#define MAXLINE 512
+#else
+#define MAXLINE 1024
+#endif
+
+#define BIT_TEST(f, b) ((f) & (b))
+/* } */
+
+#define addroute make_and_lookup
+
+#ifndef __KERNEL__
+#include <sys/types.h> /* for u_* definitions (on FreeBSD 5) */
+#include <errno.h> /* for EAFNOSUPPORT */
+
+#ifndef EAFNOSUPPORT
+# defined EAFNOSUPPORT WSAEAFNOSUPPORT
+#else
+#ifndef WIN32
+# include <netinet/in.h> /* for struct in_addr */
+#endif
+#endif
+
+#ifndef WIN32
+#include <sys/socket.h> /* for AF_INET */
+#else
+#include <winsock2.h>
+#include <ws2tcpip.h> /* IPv6 */
+#endif
+
+#endif /* __KERNEL__ */
+
+/* { from mrt.h */
+
+typedef struct the_prefix4_t {
+ unsigned short family; /* AF_INET | AF_INET6 */
+ unsigned short bitlen; /* same as mask? */
+ int ref_count; /* reference count */
+ struct in_addr sin;
+} prefix4_t;
+
+typedef struct the_prefix_t {
+ unsigned short family; /* AF_INET | AF_INET6 */
+ unsigned short bitlen; /* same as mask? */
+ int ref_count; /* reference count */
+ union {
+ struct in_addr sin;
+#ifdef HAVE_IPV6
+ struct in6_addr sin6;
+#endif /* IPV6 */
+ } add;
+} prefix_t;
+
+/* } */
+
+/* pointer to usr data (ex. route flap info) */
+union patricia_node_value_t {
+ void *user_data;
+ u_int32_t user_value;
+};
+
+typedef struct _patricia_node_t {
+ u_int bit; /* flag if this node used */
+ prefix_t *prefix; /* who we are in patricia tree */
+ struct _patricia_node_t *l, *r; /* left and right children */
+ struct _patricia_node_t *parent;/* may be used */
+ void *data; /* pointer to data */
+ union patricia_node_value_t value;
+} patricia_node_t;
+
+typedef struct _patricia_tree_t {
+ patricia_node_t *head;
+ u_int maxbits; /* for IP, 32 bit addresses */
+ int num_active_node; /* for debug purpose */
+} patricia_tree_t;
+
+typedef void (*void_fn_t)(void *data);
+typedef void (*void_fn2_t)(prefix_t *prefix, void *data);
+
+/* renamed to ndpi_Patricia to avoid name conflicts */
+patricia_node_t *ndpi_patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix);
+patricia_node_t *ndpi_patricia_search_best (patricia_tree_t *patricia, prefix_t *prefix);
+patricia_node_t * ndpi_patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix,
+ int inclusive);
+patricia_node_t *ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix);
+void ndpi_patricia_remove (patricia_tree_t *patricia, patricia_node_t *node);
+patricia_tree_t *ndpi_New_Patricia (int maxbits);
+void ndpi_Clear_Patricia (patricia_tree_t *patricia, void_fn_t func);
+void ndpi_Destroy_Patricia (patricia_tree_t *patricia, void_fn_t func);
+void ndpi_patricia_process (patricia_tree_t *patricia, void_fn2_t func);
+
+#define PATRICIA_MAXBITS (sizeof(struct in6_addr) * 8)
+#define PATRICIA_NBIT(x) (0x80 >> ((x) & 0x7f))
+#define PATRICIA_NBYTE(x) ((x) >> 3)
+
+#define PATRICIA_DATA_GET(node, type) (type *)((node)->data)
+#define PATRICIA_DATA_SET(node, value) ((node)->data = (void *)(value))
+
+#define PATRICIA_WALK(Xhead, Xnode) \
+ do { \
+ patricia_node_t *Xstack[PATRICIA_MAXBITS+1]; \
+ patricia_node_t **Xsp = Xstack; \
+ patricia_node_t *Xrn = (Xhead); \
+ while ((Xnode = Xrn)) { \
+ if (Xnode->prefix)
+
+#define PATRICIA_WALK_ALL(Xhead, Xnode) \
+ do { \
+ patricia_node_t *Xstack[PATRICIA_MAXBITS+1]; \
+ patricia_node_t **Xsp = Xstack; \
+ patricia_node_t *Xrn = (Xhead); \
+ while ((Xnode = Xrn)) { \
+ if (1)
+
+#define PATRICIA_WALK_BREAK { \
+ if (Xsp != Xstack) { \
+ Xrn = *(--Xsp); \
+ } else { \
+ Xrn = (patricia_node_t *) 0; \
+ } \
+ continue; }
+
+#define PATRICIA_WALK_END \
+ if (Xrn->l) { \
+ if (Xrn->r) { \
+ *Xsp++ = Xrn->r; \
+ } \
+ Xrn = Xrn->l; \
+ } else if (Xrn->r) { \
+ Xrn = Xrn->r; \
+ } else if (Xsp != Xstack) { \
+ Xrn = *(--Xsp); \
+ } else { \
+ Xrn = (patricia_node_t *) 0; \
+ } \
+ } \
+ } while (0)
+
+#endif /* _PATRICIA_H */
+
+/*************************
+
+
+ [newtool.gif]
+
+MRT Credits
+
+ The Multi-Threaded Routing Toolkit
+ _________________________________________________________________
+
+ MRT was developed by [1]Merit Network, Inc., under National Science
+ Foundation grant NCR-9318902, "Experimentation with Routing Technology
+ to be Used for Inter-Domain Routing in the Internet."
+
+ Current MRT Staff
+
+ * [2]Craig Labovitz <labovit@merit.edu>
+ * [3]Makaki Hirabaru <masaki@merit.edu>
+ * [4]Farnam Jahanian <farnam@eecs.umich.edu>
+ * Susan Hares <skh@merit.edu>
+ * Susan R. Harris <srh@merit.edu>
+ * Nathan Binkert <binkertn@eecs.umich.edu>
+ * Gerald Winters <gerald@merit.edu>
+
+ Project Alumni
+
+ * [5]Marc Unangst <mju@merit.edu>
+ * John Scudder <jgs@ieng.com>
+
+ The BGP4+ extension was originally written by Francis Dupont
+ <Francis.Dupont@inria.fr>.
+
+ The public domain Struct C-library of linked list, hash table and
+ memory allocation routines was developed by Jonathan Dekock
+ <dekock@cadence.com>.
+
+ Susan Rebecca Harris <srh@merit.edu> provided help with the
+ documentation.
+ David Ward <dward@netstar.com> provided bug fixes and helpful
+ suggestions.
+ Some sections of code and architecture ideas were taken from the GateD
+ routing daemon.
+
+ The first port to Linux with IPv6 was done by Pedro Roque
+ <roque@di.fc.ul.pt>. Some interface routines to the Linux kernel were
+ originally written by him.
+
+ Alexey Kuznetsov made enhancements to 1.4.3a and fixed the Linux
+ kernel intarface. Linux's netlink interface was written, referring to
+ his code "iproute2".
+
+ We would also like to thank our other colleagues in Japan, Portugal,
+ the Netherlands, the UK, and the US for their many contributions to
+ the MRT development effort.
+ _________________________________________________________________
+
+ Cisco is a registered trademark of Cisco Systems Inc.
+ _________________________________________________________________
+
+ Merit Network 4251 Plymouth Road Suite C Ann Arbor, MI 48105-2785
+ 734-764-9430
+ info@merit.edu
+ _________________________________________________________________
+
+ © 1999 Merit Network, Inc.
+ [6]www@merit.edu
+
+References
+
+ 1. http://www.merit.edu/
+ 2. http://www.merit.edu/~labovit
+ 3. http://www.merit.edu/~masaki
+ 4. http://www.eecs.umich.edu/~farnam
+ 5. http://www.contrib.andrew.cmu.edu/~mju/
+ 6. mailto:www@merit.edu
+
+------------
+
+Copyright (c) 1997, 1998, 1999
+
+
+The Regents of the University of Michigan ("The Regents") and Merit Network,
+Inc. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1. Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+3. All advertising materials mentioning features or use of
+ this software must display the following acknowledgement:
+This product includes software developed by the University of Michigan, Merit
+Network, Inc., and their contributors.
+4. Neither the name of the University, Merit Network, nor the
+ names of their contributors may be used to endorse or
+ promote products derived from this software without
+ specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+************************ */
diff --git a/src/lib/third_party/include/sort.h b/src/lib/third_party/include/sort.h
new file mode 100644
index 000000000..ee7df8a10
--- /dev/null
+++ b/src/lib/third_party/include/sort.h
@@ -0,0 +1,6 @@
+/* This is a function ported from the Linux kernel lib/sort.c */
+
+void sort(void *base, size_t num, size_t len,
+ int (*cmp_func)(const void *, const void *),
+ void (*swap_func)(void *, void *, int size));
+
diff --git a/src/lib/third_party/src/ahocorasick.c b/src/lib/third_party/src/ahocorasick.c
new file mode 100644
index 000000000..54a97e776
--- /dev/null
+++ b/src/lib/third_party/src/ahocorasick.c
@@ -0,0 +1,391 @@
+/*
+ * ahocorasick.c: implementation of ahocorasick library's functions
+ * This file is part of multifast.
+ *
+ Copyright 2010-2012 Kamiar Kanani <kamiar.kanani@gmail.com>
+
+ multifast is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ multifast is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with multifast. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __KERNEL__
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#endif
+
+#include "ndpi_api.h"
+#include "ahocorasick.h"
+
+/* Allocation step for automata.all_nodes */
+#define REALLOC_CHUNK_ALLNODES 200
+
+/* Private function prototype */
+static void ac_automata_register_nodeptr
+(AC_AUTOMATA_t * thiz, AC_NODE_t * node);
+static void ac_automata_union_matchstrs
+(AC_NODE_t * node);
+static void ac_automata_set_failure
+(AC_AUTOMATA_t * thiz, AC_NODE_t * node, AC_ALPHABET_t * alphas);
+static void ac_automata_traverse_setfailure
+(AC_AUTOMATA_t * thiz, AC_NODE_t * node, AC_ALPHABET_t * alphas);
+
+
+/******************************************************************************
+ * FUNCTION: ac_automata_init
+ * Initialize automata; allocate memories and set initial values
+ * PARAMS:
+ * MATCH_CALBACK mc: call-back function
+ * the call-back function will be used to reach the caller on match occurrence
+ ******************************************************************************/
+AC_AUTOMATA_t * ac_automata_init (MATCH_CALBACK_f mc)
+{
+ AC_AUTOMATA_t * thiz = (AC_AUTOMATA_t *)ndpi_malloc(sizeof(AC_AUTOMATA_t));
+ memset (thiz, 0, sizeof(AC_AUTOMATA_t));
+ thiz->root = node_create ();
+ thiz->all_nodes_max = REALLOC_CHUNK_ALLNODES;
+ thiz->all_nodes = (AC_NODE_t **) ndpi_malloc (thiz->all_nodes_max*sizeof(AC_NODE_t *));
+ thiz->match_callback = mc;
+ ac_automata_register_nodeptr (thiz, thiz->root);
+ ac_automata_reset (thiz);
+ thiz->total_patterns = 0;
+ thiz->automata_open = 1;
+ return thiz;
+}
+
+/******************************************************************************
+ * FUNCTION: ac_automata_add
+ * Adds pattern to the automata.
+ * PARAMS:
+ * AC_AUTOMATA_t * thiz: the pointer to the automata
+ * AC_PATTERN_t * patt: the pointer to added pattern
+ * RETUERN VALUE: AC_ERROR_t
+ * the return value indicates the success or failure of adding action
+ ******************************************************************************/
+AC_ERROR_t ac_automata_add (AC_AUTOMATA_t * thiz, AC_PATTERN_t * patt)
+{
+ unsigned int i;
+ AC_NODE_t * n = thiz->root;
+ AC_NODE_t * next;
+ AC_ALPHABET_t alpha;
+
+ if(!thiz->automata_open)
+ return ACERR_AUTOMATA_CLOSED;
+
+ if (!patt->length)
+ return ACERR_ZERO_PATTERN;
+
+ if (patt->length > AC_PATTRN_MAX_LENGTH)
+ return ACERR_LONG_PATTERN;
+
+ for (i=0; i<patt->length; i++)
+ {
+ alpha = patt->astring[i];
+ if ((next = node_find_next(n, alpha)))
+ {
+ n = next;
+ continue;
+ }
+ else
+ {
+ next = node_create_next(n, alpha);
+ next->depth = n->depth + 1;
+ n = next;
+ ac_automata_register_nodeptr(thiz, n);
+ }
+ }
+
+ if(n->final)
+ return ACERR_DUPLICATE_PATTERN;
+
+ n->final = 1;
+ node_register_matchstr(n, patt);
+ thiz->total_patterns++;
+
+ return ACERR_SUCCESS;
+}
+
+/******************************************************************************
+ * FUNCTION: ac_automata_finalize
+ * Locate the failure node for all nodes and collect all matched pattern for
+ * every node. it also sorts outgoing edges of node, so binary search could be
+ * performed on them. after calling this function the automate literally will
+ * be finalized and you can not add new patterns to the automate.
+ * PARAMS:
+ * AC_AUTOMATA_t * thiz: the pointer to the automata
+ ******************************************************************************/
+void ac_automata_finalize (AC_AUTOMATA_t * thiz)
+{
+ unsigned int i;
+ AC_ALPHABET_t *alphas;
+ AC_NODE_t * node;
+
+ if((alphas = ndpi_malloc(AC_PATTRN_MAX_LENGTH)) != NULL) {
+ ac_automata_traverse_setfailure (thiz, thiz->root, alphas);
+
+ for (i=0; i < thiz->all_nodes_num; i++)
+ {
+ node = thiz->all_nodes[i];
+ ac_automata_union_matchstrs (node);
+ node_sort_edges (node);
+ }
+ thiz->automata_open = 0; /* do not accept patterns any more */
+ ndpi_free(alphas);
+ }
+}
+
+/******************************************************************************
+ * FUNCTION: ac_automata_search
+ * Search in the input text using the given automata. on match event it will
+ * call the call-back function. and the call-back function in turn after doing
+ * its job, will return an integer value to ac_automata_search(). 0 value means
+ * continue search, and non-0 value means stop search and return to the caller.
+ * PARAMS:
+ * AC_AUTOMATA_t * thiz: the pointer to the automata
+ * AC_TEXT_t * txt: the input text that must be searched
+ * void * param: this parameter will be send to call-back function. it is
+ * useful for sending parameter to call-back function from caller function.
+ * RETURN VALUE:
+ * -1: failed call; automata is not finalized
+ * 0: success; continue searching; call-back sent me a 0 value
+ * 1: success; stop searching; call-back sent me a non-0 value
+ ******************************************************************************/
+int ac_automata_search (AC_AUTOMATA_t * thiz, AC_TEXT_t * txt, void * param)
+{
+ unsigned long position;
+ AC_NODE_t *curr;
+ AC_NODE_t *next;
+
+ if(thiz->automata_open)
+ /* you must call ac_automata_locate_failure() first */
+ return -1;
+
+ position = 0;
+ curr = thiz->current_node;
+
+ /* This is the main search loop.
+ * it must be keep as lightweight as possible. */
+ while (position < txt->length)
+ {
+ if(!(next = node_findbs_next(curr, txt->astring[position])))
+ {
+ if(curr->failure_node /* we are not in the root node */)
+ curr = curr->failure_node;
+ else
+ position++;
+ }
+ else
+ {
+ curr = next;
+ position++;
+ }
+
+ if(curr->final && next)
+ /* We check 'next' to find out if we came here after a alphabet
+ * transition or due to a fail. in second case we should not report
+ * matching because it was reported in previous node */
+ {
+ thiz->match.position = position + thiz->base_position;
+ thiz->match.match_num = curr->matched_patterns_num;
+ thiz->match.patterns = curr->matched_patterns;
+ /* we found a match! do call-back */
+ if (thiz->match_callback(&thiz->match, param))
+ return 1;
+ }
+ }
+
+ /* save status variables */
+ thiz->current_node = curr;
+ thiz->base_position += position;
+ return 0;
+}
+
+/******************************************************************************
+ * FUNCTION: ac_automata_reset
+ * reset the automata and make it ready for doing new search on a new text.
+ * when you finished with the input text, you must reset automata state for
+ * new input, otherwise it will not work.
+ * PARAMS:
+ * AC_AUTOMATA_t * thiz: the pointer to the automata
+ ******************************************************************************/
+void ac_automata_reset (AC_AUTOMATA_t * thiz)
+{
+ thiz->current_node = thiz->root;
+ thiz->base_position = 0;
+}
+
+/******************************************************************************
+ * FUNCTION: ac_automata_release
+ * Release all allocated memories to the automata
+ * PARAMS:
+ * AC_AUTOMATA_t * thiz: the pointer to the automata
+ ******************************************************************************/
+void ac_automata_release (AC_AUTOMATA_t * thiz)
+{
+ unsigned int i;
+ AC_NODE_t * n;
+
+ for (i=0; i < thiz->all_nodes_num; i++)
+ {
+ n = thiz->all_nodes[i];
+ node_release(n);
+ }
+ ndpi_free(thiz->all_nodes);
+ ndpi_free(thiz);
+}
+
+#ifndef __KERNEL__
+/******************************************************************************
+ * FUNCTION: ac_automata_display
+ * Prints the automata to output in human readable form. it is useful for
+ * debugging purpose.
+ * PARAMS:
+ * AC_AUTOMATA_t * thiz: the pointer to the automata
+ * char repcast: 'n': print AC_REP_t as number, 's': print AC_REP_t as string
+ ******************************************************************************/
+void ac_automata_display (AC_AUTOMATA_t * thiz, char repcast)
+{
+ unsigned int i, j;
+ AC_NODE_t * n;
+ struct edge * e;
+ AC_PATTERN_t sid;
+
+ printf("---------------------------------\n");
+
+ for (i=0; i<thiz->all_nodes_num; i++)
+ {
+ n = thiz->all_nodes[i];
+ printf("NODE(%3d)/----fail----> NODE(%3d)\n",
+ n->id, (n->failure_node)?n->failure_node->id:1);
+ for (j=0; j<n->outgoing_degree; j++)
+ {
+ e = &n->outgoing[j];
+ printf(" |----(");
+ if(isgraph(e->alpha))
+ printf("%c)---", e->alpha);
+ else
+ printf("0x%x)", e->alpha);
+ printf("--> NODE(%3d)\n", e->next->id);
+ }
+ if (n->matched_patterns_num) {
+ printf("Accepted patterns: {");
+ for (j=0; j<n->matched_patterns_num; j++)
+ {
+ sid = n->matched_patterns[j];
+ if(j) printf(", ");
+ switch (repcast)
+ {
+ case 'n':
+ printf("%ld", sid.rep.number);
+ break;
+ case 's':
+ printf("%s", sid.rep.stringy);
+ break;
+ }
+ }
+ printf("}\n");
+ }
+ printf("---------------------------------\n");
+ }
+}
+#endif /* __KERNEL__ */
+
+/******************************************************************************
+ * FUNCTION: ac_automata_register_nodeptr
+ * Adds the node pointer to all_nodes.
+ ******************************************************************************/
+static void ac_automata_register_nodeptr (AC_AUTOMATA_t * thiz, AC_NODE_t * node)
+{
+ if(thiz->all_nodes_num >= thiz->all_nodes_max)
+ {
+ thiz->all_nodes = ndpi_realloc(thiz->all_nodes,
+ thiz->all_nodes_max*sizeof(AC_NODE_t *),
+ (REALLOC_CHUNK_ALLNODES+thiz->all_nodes_max)*sizeof(AC_NODE_t *)
+ );
+ thiz->all_nodes_max += REALLOC_CHUNK_ALLNODES;
+ }
+ thiz->all_nodes[thiz->all_nodes_num++] = node;
+}
+
+/******************************************************************************
+ * FUNCTION: ac_automata_union_matchstrs
+ * Collect accepted patterns of the node. the accepted patterns consist of the
+ * node's own accepted pattern plus accepted patterns of its failure node.
+ ******************************************************************************/
+static void ac_automata_union_matchstrs (AC_NODE_t * node)
+{
+ unsigned int i;
+ AC_NODE_t * m = node;
+
+ while ((m = m->failure_node))
+ {
+ for (i=0; i < m->matched_patterns_num; i++)
+ node_register_matchstr(node, &(m->matched_patterns[i]));
+
+ if (m->final)
+ node->final = 1;
+ }
+ // TODO : sort matched_patterns? is that necessary? I don't think so.
+}
+
+/******************************************************************************
+ * FUNCTION: ac_automata_set_failure
+ * find failure node for the given node.
+ ******************************************************************************/
+static void ac_automata_set_failure
+(AC_AUTOMATA_t * thiz, AC_NODE_t * node, AC_ALPHABET_t * alphas)
+{
+ unsigned int i, j;
+ AC_NODE_t * m;
+
+ for (i=1; i < node->depth; i++)
+ {
+ m = thiz->root;
+ for (j=i; j < node->depth && m; j++)
+ m = node_find_next (m, alphas[j]);
+ if (m)
+ {
+ node->failure_node = m;
+ break;
+ }
+ }
+ if (!node->failure_node)
+ node->failure_node = thiz->root;
+}
+
+/******************************************************************************
+ * FUNCTION: ac_automata_traverse_setfailure
+ * Traverse all automata nodes using DFS (Depth First Search), meanwhile it set
+ * the failure node for every node it passes through. this function must be
+ * called after adding last pattern to automata. i.e. after calling this you
+ * can not add further pattern to automata.
+ ******************************************************************************/
+static void ac_automata_traverse_setfailure
+(AC_AUTOMATA_t * thiz, AC_NODE_t * node, AC_ALPHABET_t * alphas)
+{
+ unsigned int i;
+ AC_NODE_t * next;
+
+ for (i=0; i < node->outgoing_degree; i++)
+ {
+ alphas[node->depth] = node->outgoing[i].alpha;
+ next = node->outgoing[i].next;
+
+ /* At every node look for its failure node */
+ ac_automata_set_failure (thiz, next, alphas);
+
+ /* Recursively call itself to traverse all nodes */
+ ac_automata_traverse_setfailure (thiz, next, alphas);
+ }
+}
diff --git a/src/lib/third_party/src/node.c b/src/lib/third_party/src/node.c
new file mode 100644
index 000000000..404fb24d4
--- /dev/null
+++ b/src/lib/third_party/src/node.c
@@ -0,0 +1,260 @@
+/*
+ * node.c: implementation of automata node
+ * This file is part of multifast.
+ *
+ Copyright 2010-2012 Kamiar Kanani <kamiar.kanani@gmail.com>
+
+ multifast is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ multifast is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with multifast. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __KERNEL__
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#endif
+
+#include "ndpi_api.h"
+
+#include "../include/node.h"
+#include "sort.h"
+
+/* reallocation step for AC_NODE_t.matched_patterns */
+#define REALLOC_CHUNK_MATCHSTR 8
+
+/* reallocation step for AC_NODE_t.outgoing array */
+#define REALLOC_CHUNK_OUTGOING 8
+/* TODO: For different depth of node, number of outgoing edges differs
+ considerably, It is efficient to use different chunk size for
+ different depths */
+
+/* Private function prototype */
+void node_init (AC_NODE_t * thiz);
+int node_edge_compare (const void * l, const void * r);
+int node_has_matchstr (AC_NODE_t * thiz, AC_PATTERN_t * newstr);
+
+
+/******************************************************************************
+ * FUNCTION: node_create
+ * Create the node
+ ******************************************************************************/
+AC_NODE_t * node_create(void)
+{
+ AC_NODE_t * thiz = (AC_NODE_t *) ndpi_malloc (sizeof(AC_NODE_t));
+ node_init(thiz);
+ node_assign_id(thiz);
+ return thiz;
+}
+
+/******************************************************************************
+ * FUNCTION: node_init
+ * Initialize node
+ ******************************************************************************/
+void node_init(AC_NODE_t * thiz)
+{
+ memset(thiz, 0, sizeof(AC_NODE_t));
+
+ thiz->outgoing_max = REALLOC_CHUNK_OUTGOING;
+ thiz->outgoing = (struct edge *) ndpi_malloc
+ (thiz->outgoing_max*sizeof(struct edge));
+
+ thiz->matched_patterns_max = REALLOC_CHUNK_MATCHSTR;
+ thiz->matched_patterns = (AC_PATTERN_t *) ndpi_malloc
+ (thiz->matched_patterns_max*sizeof(AC_PATTERN_t));
+}
+
+/******************************************************************************
+ * FUNCTION: node_release
+ * Release node
+ ******************************************************************************/
+void node_release(AC_NODE_t * thiz)
+{
+ ndpi_free(thiz->matched_patterns);
+ ndpi_free(thiz->outgoing);
+ ndpi_free(thiz);
+}
+
+/******************************************************************************
+ * FUNCTION: node_find_next
+ * Find out the next node for a given Alpha to move. this function is used in
+ * the pre-processing stage in which edge array is not sorted. so it uses
+ * linear search.
+ ******************************************************************************/
+AC_NODE_t * node_find_next(AC_NODE_t * thiz, AC_ALPHABET_t alpha)
+{
+ int i;
+
+ for (i=0; i < thiz->outgoing_degree; i++)
+ {
+ if(thiz->outgoing[i].alpha == alpha)
+ return (thiz->outgoing[i].next);
+ }
+ return NULL;
+}
+
+/******************************************************************************
+ * FUNCTION: node_findbs_next
+ * Find out the next node for a given Alpha. this function is used after the
+ * pre-processing stage in which we sort edges. so it uses Binary Search.
+ ******************************************************************************/
+AC_NODE_t * node_findbs_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha)
+{
+ int min, max, mid;
+ AC_ALPHABET_t amid;
+
+ min = 0;
+ max = thiz->outgoing_degree - 1;
+
+ while (min <= max)
+ {
+ mid = (min+max) >> 1;
+ amid = thiz->outgoing[mid].alpha;
+ if (alpha > amid)
+ min = mid + 1;
+ else if (alpha < amid)
+ max = mid - 1;
+ else
+ return (thiz->outgoing[mid].next);
+ }
+ return NULL;
+}
+
+/******************************************************************************
+ * FUNCTION: node_has_matchstr
+ * Determine if a final node contains a pattern in its accepted pattern list
+ * or not. return values: 1 = it has, 0 = it hasn't
+ ******************************************************************************/
+int node_has_matchstr (AC_NODE_t * thiz, AC_PATTERN_t * newstr)
+{
+ int i, j;
+ AC_PATTERN_t * str;
+
+ for (i=0; i < thiz->matched_patterns_num; i++)
+ {
+ str = &thiz->matched_patterns[i];
+
+ if (str->length != newstr->length)
+ continue;
+
+ for (j=0; j<(int)str->length; j++)
+ if(str->astring[j] != newstr->astring[j])
+ continue;
+
+ if (j == str->length)
+ return 1;
+ }
+ return 0;
+}
+
+/******************************************************************************
+ * FUNCTION: node_create_next
+ * Create the next node for the given alpha.
+ ******************************************************************************/
+AC_NODE_t * node_create_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha)
+{
+ AC_NODE_t * next;
+ next = node_find_next (thiz, alpha);
+ if (next)
+ /* The edge already exists */
+ return NULL;
+ /* Otherwise register new edge */
+ next = node_create ();
+ node_register_outgoing(thiz, next, alpha);
+
+ return next;
+}
+
+/******************************************************************************
+ * FUNCTION: node_register_matchstr
+ * Adds the pattern to the list of accepted pattern.
+ ******************************************************************************/
+void node_register_matchstr (AC_NODE_t * thiz, AC_PATTERN_t * str)
+{
+ /* Check if the new pattern already exists in the node list */
+ if (node_has_matchstr(thiz, str))
+ return;
+
+ /* Manage memory */
+ if (thiz->matched_patterns_num >= thiz->matched_patterns_max)
+ {
+ thiz->matched_patterns = (AC_PATTERN_t *) ndpi_realloc
+ (thiz->matched_patterns, thiz->matched_patterns_max*sizeof(AC_PATTERN_t),
+ (REALLOC_CHUNK_MATCHSTR+thiz->matched_patterns_max)*sizeof(AC_PATTERN_t));
+
+ thiz->matched_patterns_max += REALLOC_CHUNK_MATCHSTR;
+ }
+
+ thiz->matched_patterns[thiz->matched_patterns_num].astring = str->astring;
+ thiz->matched_patterns[thiz->matched_patterns_num].length = str->length;
+ thiz->matched_patterns[thiz->matched_patterns_num].rep = str->rep;
+ thiz->matched_patterns_num++;
+}
+
+/******************************************************************************
+ * FUNCTION: node_register_outgoing
+ * Establish an edge between two nodes
+ ******************************************************************************/
+void node_register_outgoing
+(AC_NODE_t * thiz, AC_NODE_t * next, AC_ALPHABET_t alpha)
+{
+ if(thiz->outgoing_degree >= thiz->outgoing_max)
+ {
+ thiz->outgoing = (struct edge *) ndpi_realloc
+ (thiz->outgoing, thiz->outgoing_max*sizeof(struct edge),
+ (REALLOC_CHUNK_OUTGOING+thiz->outgoing_max)*sizeof(struct edge));
+ thiz->outgoing_max += REALLOC_CHUNK_OUTGOING;
+ }
+
+ thiz->outgoing[thiz->outgoing_degree].alpha = alpha;
+ thiz->outgoing[thiz->outgoing_degree++].next = next;
+}
+
+/******************************************************************************
+ * FUNCTION: node_assign_id
+ * assign a unique ID to the node (used for debugging purpose).
+ ******************************************************************************/
+void node_assign_id (AC_NODE_t * thiz)
+{
+ static int unique_id = 1;
+ thiz->id = unique_id ++;
+}
+
+/******************************************************************************
+ * FUNCTION: node_edge_compare
+ * Comparison function for qsort. see man qsort.
+ ******************************************************************************/
+int node_edge_compare (const void * l, const void * r)
+{
+ /* According to man page:
+ * The comparison function must return an integer less than, equal to, or
+ * greater than zero if the first argument is considered to be
+ * respectively less than, equal to, or greater than the second. if two
+ * members compare as equal, their order in the sorted array is undefined.
+ *
+ * NOTE: Because edge alphabets are unique in every node we ignore
+ * equivalence case.
+ **/
+ if ( ((struct edge *)l)->alpha >= ((struct edge *)r)->alpha )
+ return 1;
+ else
+ return -1;
+}
+
+/******************************************************************************
+ * FUNCTION: node_sort_edges
+ * sorts edges alphabets.
+ ******************************************************************************/
+void node_sort_edges (AC_NODE_t * thiz)
+{
+ sort ((void *)thiz->outgoing, thiz->outgoing_degree, sizeof(struct edge), node_edge_compare, NULL);
+}
diff --git a/src/lib/third_party/src/patricia.c b/src/lib/third_party/src/patricia.c
new file mode 100644
index 000000000..b7b4c2010
--- /dev/null
+++ b/src/lib/third_party/src/patricia.c
@@ -0,0 +1,1076 @@
+/*
+ * $Id: patricia.c,v 1.7 2005/12/07 20:46:41 dplonka Exp $
+ * Dave Plonka <plonka@doit.wisc.edu>
+ *
+ * This product includes software developed by the University of Michigan,
+ * Merit Network, Inc., and their contributors.
+ *
+ * This file had been called "radix.c" in the MRT sources.
+ *
+ * I renamed it to "patricia.c" since it's not an implementation of a general
+ * radix trie. Also I pulled in various requirements from "prefix.c" and
+ * "demo.c" so that it could be used as a standalone API.
+
+
+ https://github.com/deepfield/MRT/blob/master/COPYRIGHT
+
+ Copyright (c) 1999-2013
+
+ The Regents of the University of Michigan ("The Regents") and Merit
+ Network, Inc.
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __KERNEL__
+#include <assert.h> /* assert */
+#include <ctype.h> /* isdigit */
+#include <errno.h> /* errno */
+#include <math.h> /* sin */
+#include <stddef.h> /* NULL */
+#include <stdio.h> /* sprintf, fprintf, stderr */
+#include <stdlib.h> /* free, atol, calloc */
+#include <string.h> /* memcpy, strchr, strlen */
+#include <sys/types.h> /* BSD: for inet_addr */
+#ifndef WIN32
+#include <sys/socket.h> /* BSD, Linux: for inet_addr */
+#include <netinet/in.h> /* BSD, Linux: for inet_addr */
+#include <arpa/inet.h> /* BSD, Linux, Solaris: for inet_addr */
+#endif
+#else
+#define assert(a) ;
+#endif /* __KERNEL__ */
+
+#include "patricia.h"
+
+#ifdef __KERNEL__
+
+long atol(const char *nptr) {
+ long l;
+ char *endp;
+
+ l = simple_strtol(nptr, &endp, 10);
+ return(l);
+}
+#endif
+
+// #define PATRICIA_DEBUG
+
+void ndpi_DeleteEntry(void *a) {
+ ndpi_free(a);
+}
+
+/* { from prefix.c */
+
+/* ndpi_prefix_tochar
+ * convert prefix information to bytes
+ */
+u_char *
+ndpi_prefix_tochar (prefix_t * prefix)
+{
+ if(prefix == NULL)
+ return (NULL);
+
+ return ((u_char *) & prefix->add.sin);
+}
+
+int ndpi_comp_with_mask (void *addr, void *dest, u_int mask) {
+ if( /* mask/8 == 0 || */ memcmp (addr, dest, mask / 8) == 0) {
+ int n = mask / 8;
+ int m = ((-1) << (8 - (mask % 8)));
+
+ if(mask % 8 == 0 || (((u_char *)addr)[n] & m) == (((u_char *)dest)[n] & m))
+ return (1);
+ }
+ return (0);
+}
+
+#if 0 /* this implementation does not support IPv6, using system inet_pton */
+#ifndef WIN32
+/* inet_pton substitute implementation
+ * Uses inet_addr to convert an IP address in dotted decimal notation into
+ * unsigned long and copies the result to dst.
+ * Only supports AF_INET. Follows standard error return conventions of
+ * inet_pton.
+ */
+int
+inet_pton (int af, const char *src, void *dst)
+{
+ u_long result;
+
+ if(af == AF_INET) {
+ result = inet_addr(src);
+ if(result == -1)
+ return 0;
+ else {
+ memcpy (dst, &result, sizeof(struct in_addr));
+ return 1;
+ }
+ }
+#ifdef NT
+#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+ else if(af == AF_INET6) {
+ struct in6_addr Address;
+ return (inet6_addr(src, &Address));
+ }
+#endif /* HAVE_IPV6 */
+#endif /* NT */
+#ifndef NT
+ else {
+ printf("NOT SUPP\n");
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+#endif /* NT */
+}
+#endif
+#endif
+
+/* this allows imcomplete prefix */
+int
+ndpi_my_inet_pton (int af, const char *src, void *dst)
+{
+ if(af == AF_INET) {
+ int i;
+ u_char xp[sizeof(struct in_addr)] = {0, 0, 0, 0};
+
+ for (i = 0; ; i++) {
+ int c, val;
+
+ c = *src++;
+ if(!isdigit (c))
+ return (-1);
+ val = 0;
+ do {
+ val = val * 10 + c - '0';
+ if(val > 255)
+ return (0);
+ c = *src++;
+ } while (c && isdigit (c));
+ xp[i] = val;
+ if(c == '\0')
+ break;
+ if(c != '.')
+ return (0);
+ if(i >= 3)
+ return (0);
+ }
+ memcpy (dst, xp, sizeof(struct in_addr));
+ return (1);
+#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+ } else if(af == AF_INET6) {
+ return (inet_pton (af, src, dst));
+#endif /* HAVE_IPV6 */
+ } else {
+#ifndef NT
+#ifndef __KERNEL__
+ errno = EAFNOSUPPORT;
+#endif
+#endif /* NT */
+ return -1;
+ }
+}
+
+#define PATRICIA_MAX_THREADS 16
+
+/*
+ * convert prefix information to ascii string with length
+ * thread safe and (almost) re-entrant implementation
+ */
+char *
+ndpi_ndpi_prefix_toa2x (prefix_t *prefix, char *buff, int with_len)
+{
+ if(prefix == NULL)
+ return ((char*)"(Null)");
+ assert (prefix->ref_count >= 0);
+ if(buff == NULL) {
+
+ struct buffer {
+ char buffs[PATRICIA_MAX_THREADS][48+5];
+ u_int i;
+ } *buffp;
+
+# if 0
+ THREAD_SPECIFIC_DATA (struct buffer, buffp, 1);
+# else
+ { /* for scope only */
+ static struct buffer local_buff;
+ buffp = &local_buff;
+ }
+# endif
+ if(buffp == NULL) {
+ /* XXX should we report an error? */
+ return (NULL);
+ }
+
+ buff = buffp->buffs[buffp->i++%PATRICIA_MAX_THREADS];
+ }
+ if(prefix->family == AF_INET) {
+ u_char *a;
+ assert (prefix->bitlen <= sizeof(struct in_addr) * 8);
+ a = prefix_touchar (prefix);
+ if(with_len) {
+ sprintf (buff, "%d.%d.%d.%d/%d", a[0], a[1], a[2], a[3],
+ prefix->bitlen);
+ }
+ else {
+ sprintf (buff, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
+ }
+ return (buff);
+ }
+#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+ else if(prefix->family == AF_INET6) {
+ char *r;
+ r = (char *) inet_ntop (AF_INET6, &prefix->add.sin6, buff, 48 /* a guess value */ );
+ if(r && with_len) {
+ assert (prefix->bitlen <= sizeof(struct in6_addr) * 8);
+ sprintf (buff + strlen (buff), "/%d", prefix->bitlen);
+ }
+ return (buff);
+ }
+#endif /* HAVE_IPV6 */
+ else
+ return (NULL);
+}
+
+/* ndpi_prefix_toa2
+ * convert prefix information to ascii string
+ */
+char *
+ndpi_prefix_toa2 (prefix_t *prefix, char *buff)
+{
+ return (ndpi_ndpi_prefix_toa2x (prefix, buff, 0));
+}
+
+/* ndpi_prefix_toa
+ */
+char *
+ndpi_prefix_toa (prefix_t * prefix)
+{
+ return (ndpi_prefix_toa2 (prefix, (char *) NULL));
+}
+
+prefix_t *
+ndpi_New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix)
+{
+ int dynamic_allocated = 0;
+ int default_bitlen = sizeof(struct in_addr) * 8;
+
+#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+ if(family == AF_INET6) {
+ default_bitlen = sizeof(struct in6_addr) * 8;
+ if(prefix == NULL) {
+ prefix = (prefix_t*)ndpi_calloc(1, sizeof (prefix_t));
+ dynamic_allocated++;
+ }
+ memcpy (&prefix->add.sin6, dest, sizeof(struct in6_addr));
+ }
+ else
+#endif /* HAVE_IPV6 */
+ if(family == AF_INET) {
+ if(prefix == NULL) {
+#ifndef NT
+ prefix = (prefix_t*)ndpi_calloc(1, sizeof (prefix4_t));
+#else
+ //for some reason, compiler is getting
+ //prefix4_t size incorrect on NT
+ prefix = ndpi_calloc(1, sizeof (prefix_t));
+#endif /* NT */
+
+ dynamic_allocated++;
+ }
+ memcpy (&prefix->add.sin, dest, sizeof(struct in_addr));
+ }
+ else {
+ return (NULL);
+ }
+
+ prefix->bitlen = (bitlen >= 0)? bitlen: default_bitlen;
+ prefix->family = family;
+ prefix->ref_count = 0;
+ if(dynamic_allocated) {
+ prefix->ref_count++;
+ }
+ /* fprintf(stderr, "[C %s, %d]\n", ndpi_prefix_toa (prefix), prefix->ref_count); */
+ return (prefix);
+}
+
+prefix_t *
+ndpi_New_Prefix (int family, void *dest, int bitlen)
+{
+ return (ndpi_New_Prefix2 (family, dest, bitlen, NULL));
+}
+
+/* ndpi_ascii2prefix
+ */
+prefix_t *
+ndpi_ascii2prefix (int family, char *string)
+{
+ long bitlen;
+ long maxbitlen = 0;
+ char *cp;
+ struct in_addr sin;
+#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+ struct in6_addr sin6;
+#endif /* HAVE_IPV6 */
+ char save[MAXLINE];
+
+ if(string == NULL)
+ return (NULL);
+
+ /* easy way to handle both families */
+ if(family == 0) {
+ family = AF_INET;
+#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+ if(strchr (string, ':')) family = AF_INET6;
+#endif /* HAVE_IPV6 */
+ }
+
+ if(family == AF_INET) {
+ maxbitlen = sizeof(struct in_addr) * 8;
+ }
+#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+ else if(family == AF_INET6) {
+ maxbitlen = sizeof(struct in6_addr) * 8;
+ }
+#endif /* HAVE_IPV6 */
+
+ if((cp = strchr (string, '/')) != NULL) {
+ bitlen = atol (cp + 1);
+ /* *cp = '\0'; */
+ /* copy the string to save. Avoid destroying the string */
+ assert (cp - string < MAXLINE);
+ memcpy (save, string, cp - string);
+ save[cp - string] = '\0';
+ string = save;
+ if((bitlen < 0) || (bitlen > maxbitlen))
+ bitlen = maxbitlen;
+ } else {
+ bitlen = maxbitlen;
+ }
+
+ if(family == AF_INET) {
+ if(ndpi_my_inet_pton (AF_INET, string, &sin) <= 0)
+ return (NULL);
+ return (ndpi_New_Prefix (AF_INET, &sin, bitlen));
+ }
+
+#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+ else if(family == AF_INET6) {
+ // Get rid of this with next IPv6 upgrade
+#if defined(NT) && !defined(HAVE_INET_NTOP)
+ inet6_addr(string, &sin6);
+ return (ndpi_New_Prefix (AF_INET6, &sin6, bitlen));
+#else
+ if(inet_pton (AF_INET6, string, &sin6) <= 0)
+ return (NULL);
+#endif /* NT */
+ return (ndpi_New_Prefix (AF_INET6, &sin6, bitlen));
+ }
+#endif /* HAVE_IPV6 */
+ else
+ return (NULL);
+}
+
+prefix_t *
+ndpi_Ref_Prefix (prefix_t * prefix)
+{
+ if(prefix == NULL)
+ return (NULL);
+ if(prefix->ref_count == 0) {
+ /* make a copy in case of a static prefix */
+ return (ndpi_New_Prefix2 (prefix->family, &prefix->add, prefix->bitlen, NULL));
+ }
+ prefix->ref_count++;
+ /* fprintf(stderr, "[A %s, %d]\n", ndpi_prefix_toa (prefix), prefix->ref_count); */
+ return (prefix);
+}
+
+void
+ndpi_Deref_Prefix (prefix_t * prefix)
+{
+ if(prefix == NULL)
+ return;
+ /* for secure programming, raise an assert. no static prefix can call this */
+ assert (prefix->ref_count > 0);
+
+ prefix->ref_count--;
+ assert (prefix->ref_count >= 0);
+ if(prefix->ref_count <= 0) {
+ ndpi_DeleteEntry (prefix);
+ return;
+ }
+}
+
+/* } */
+
+/* #define PATRICIA_DEBUG 1 */
+
+static int num_active_patricia = 0;
+
+/* these routines support continuous mask only */
+
+patricia_tree_t *
+ndpi_New_Patricia (int maxbits)
+{
+ patricia_tree_t *patricia = (patricia_tree_t*)ndpi_calloc(1, sizeof *patricia);
+
+ patricia->maxbits = maxbits;
+ patricia->head = NULL;
+ patricia->num_active_node = 0;
+ assert((u_int)maxbits <= PATRICIA_MAXBITS); /* XXX */
+ num_active_patricia++;
+ return (patricia);
+}
+
+
+/*
+ * if func is supplied, it will be called as func(node->data)
+ * before deleting the node
+ */
+
+void
+ndpi_Clear_Patricia (patricia_tree_t *patricia, void_fn_t func)
+{
+ assert (patricia);
+ if(patricia->head) {
+
+ patricia_node_t *Xstack[PATRICIA_MAXBITS+1];
+ patricia_node_t **Xsp = Xstack;
+ patricia_node_t *Xrn = patricia->head;
+
+ while (Xrn) {
+ patricia_node_t *l = Xrn->l;
+ patricia_node_t *r = Xrn->r;
+
+ if(Xrn->prefix) {
+ ndpi_Deref_Prefix (Xrn->prefix);
+ if(Xrn->data && func)
+ func (Xrn->data);
+ }
+ else {
+ assert (Xrn->data == NULL);
+ }
+ ndpi_DeleteEntry (Xrn);
+ patricia->num_active_node--;
+
+ if(l) {
+ if(r) {
+ *Xsp++ = r;
+ }
+ Xrn = l;
+ } else if(r) {
+ Xrn = r;
+ } else if(Xsp != Xstack) {
+ Xrn = *(--Xsp);
+ } else {
+ Xrn = NULL;
+ }
+ }
+ }
+ assert (patricia->num_active_node == 0);
+ /* ndpi_DeleteEntry (patricia); */
+}
+
+
+void
+ndpi_Destroy_Patricia (patricia_tree_t *patricia, void_fn_t func)
+{
+ ndpi_Clear_Patricia (patricia, func);
+ ndpi_DeleteEntry (patricia);
+ num_active_patricia--;
+}
+
+
+/*
+ * if func is supplied, it will be called as func(node->prefix, node->data)
+ */
+
+void
+ndpi_patricia_process (patricia_tree_t *patricia, void_fn2_t func)
+{
+ patricia_node_t *node;
+ assert (func);
+
+ PATRICIA_WALK (patricia->head, node) {
+ func (node->prefix, node->data);
+ } PATRICIA_WALK_END;
+}
+
+size_t
+ndpi_patricia_walk_inorder(patricia_node_t *node, void_fn2_t func)
+{
+ size_t n = 0;
+ assert(func);
+
+ if(node->l) {
+ n += ndpi_patricia_walk_inorder(node->l, func);
+ }
+
+ if(node->prefix) {
+ func(node->prefix, node->data);
+ n++;
+ }
+
+ if(node->r) {
+ n += ndpi_patricia_walk_inorder(node->r, func);
+ }
+
+ return n;
+}
+
+
+patricia_node_t *
+ndpi_patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix)
+{
+ patricia_node_t *node;
+ u_char *addr;
+ u_int bitlen;
+
+ assert (patricia);
+ assert (prefix);
+ assert (prefix->bitlen <= patricia->maxbits);
+
+ if(patricia->head == NULL)
+ return (NULL);
+
+ node = patricia->head;
+ addr = prefix_touchar (prefix);
+ bitlen = prefix->bitlen;
+
+ while (node->bit < bitlen) {
+
+ if(BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) {
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf (stderr, "patricia_search_exact: take right %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+ else
+ fprintf (stderr, "patricia_search_exact: take right at %u\n",
+ node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->r;
+ }
+ else {
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf (stderr, "patricia_search_exact: take left %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+ else
+ fprintf (stderr, "patricia_search_exact: take left at %u\n",
+ node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->l;
+ }
+
+ if(node == NULL)
+ return (NULL);
+ }
+
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf (stderr, "patricia_search_exact: stop at %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+ else
+ fprintf (stderr, "patricia_search_exact: stop at %u\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ if(node->bit > bitlen || node->prefix == NULL)
+ return (NULL);
+ assert (node->bit == bitlen);
+ assert (node->bit == node->prefix->bitlen);
+ if(ndpi_comp_with_mask (ndpi_prefix_tochar (node->prefix), ndpi_prefix_tochar (prefix),
+ bitlen)) {
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_search_exact: found %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ return (node);
+ }
+ return (NULL);
+}
+
+
+/* if inclusive != 0, "best" may be the given prefix itself */
+patricia_node_t *
+ndpi_patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inclusive)
+{
+ patricia_node_t *node;
+ patricia_node_t *stack[PATRICIA_MAXBITS + 1];
+ u_char *addr;
+ u_int bitlen;
+ int cnt = 0;
+
+ assert (patricia);
+ assert (prefix);
+ assert (prefix->bitlen <= patricia->maxbits);
+
+ if(patricia->head == NULL)
+ return (NULL);
+
+ node = patricia->head;
+ addr = prefix_touchar (prefix);
+ bitlen = prefix->bitlen;
+
+ while (node->bit < bitlen) {
+
+ if(node->prefix) {
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_search_best: push %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ stack[cnt++] = node;
+ }
+
+ if(BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) {
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf (stderr, "patricia_search_best: take right %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+ else
+ fprintf (stderr, "patricia_search_best: take right at %u\n",
+ node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->r;
+ }
+ else {
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf (stderr, "patricia_search_best: take left %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+ else
+ fprintf (stderr, "patricia_search_best: take left at %u\n",
+ node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->l;
+ }
+
+ if(node == NULL)
+ break;
+ }
+
+ if(inclusive && node && node->prefix)
+ stack[cnt++] = node;
+
+#ifdef PATRICIA_DEBUG
+ if(node == NULL)
+ fprintf (stderr, "patricia_search_best: stop at null\n");
+ else if(node->prefix)
+ fprintf (stderr, "patricia_search_best: stop at %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+ else
+ fprintf (stderr, "patricia_search_best: stop at %u\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+
+ if(cnt <= 0)
+ return (NULL);
+
+ while (--cnt >= 0) {
+ node = stack[cnt];
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_search_best: pop %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ if(ndpi_comp_with_mask (ndpi_prefix_tochar (node->prefix),
+ ndpi_prefix_tochar (prefix),
+ node->prefix->bitlen) && node->prefix->bitlen <= bitlen) {
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_search_best: found %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ return (node);
+ }
+ }
+ return (NULL);
+}
+
+
+patricia_node_t *
+ndpi_patricia_search_best (patricia_tree_t *patricia, prefix_t *prefix)
+{
+ return (ndpi_patricia_search_best2 (patricia, prefix, 1));
+}
+
+
+patricia_node_t *
+ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix)
+{
+ patricia_node_t *node, *new_node, *parent, *glue;
+ u_char *addr, *test_addr;
+ u_int bitlen, check_bit, differ_bit;
+ int i, j;
+
+ assert (patricia);
+ assert (prefix);
+ assert (prefix->bitlen <= patricia->maxbits);
+
+ if(patricia->head == NULL) {
+ node = (patricia_node_t*)ndpi_calloc(1, sizeof *node);
+ node->bit = prefix->bitlen;
+ node->prefix = ndpi_Ref_Prefix (prefix);
+ node->parent = NULL;
+ node->l = node->r = NULL;
+ node->data = NULL;
+ patricia->head = node;
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_lookup: new_node #0 %s/%d (head)\n",
+ ndpi_prefix_toa (prefix), prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ patricia->num_active_node++;
+ return (node);
+ }
+
+ addr = prefix_touchar (prefix);
+ bitlen = prefix->bitlen;
+ node = patricia->head;
+
+ while (node->bit < bitlen || node->prefix == NULL) {
+
+ if(node->bit < patricia->maxbits &&
+ BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) {
+ if(node->r == NULL)
+ break;
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf (stderr, "patricia_lookup: take right %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+ else
+ fprintf (stderr, "patricia_lookup: take right at %u\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->r;
+ }
+ else {
+ if(node->l == NULL)
+ break;
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf (stderr, "patricia_lookup: take left %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+ else
+ fprintf (stderr, "patricia_lookup: take left at %u\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->l;
+ }
+
+ assert (node);
+ }
+
+ assert (node->prefix);
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_lookup: stop at %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+
+ test_addr = prefix_touchar (node->prefix);
+ /* find the first bit different */
+ check_bit = (node->bit < bitlen)? node->bit: bitlen;
+ differ_bit = 0;
+ for (i = 0; (u_int)i*8 < check_bit; i++) {
+ int r;
+
+ if((r = (addr[i] ^ test_addr[i])) == 0) {
+ differ_bit = (i + 1) * 8;
+ continue;
+ }
+ /* I know the better way, but for now */
+ for (j = 0; j < 8; j++) {
+ if(BIT_TEST (r, (0x80 >> j)))
+ break;
+ }
+ /* must be found */
+ assert (j < 8);
+ differ_bit = i * 8 + j;
+ break;
+ }
+ if(differ_bit > check_bit)
+ differ_bit = check_bit;
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_lookup: differ_bit %d\n", differ_bit);
+#endif /* PATRICIA_DEBUG */
+
+ parent = node->parent;
+ while (parent && parent->bit >= differ_bit) {
+ node = parent;
+ parent = node->parent;
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf (stderr, "patricia_lookup: up to %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+ else
+ fprintf (stderr, "patricia_lookup: up to %u\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ }
+
+ if(differ_bit == bitlen && node->bit == bitlen) {
+ if(node->prefix) {
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_lookup: found %s/%d\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ return (node);
+ }
+ node->prefix = ndpi_Ref_Prefix (prefix);
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_lookup: new node #1 %s/%d (glue mod)\n",
+ ndpi_prefix_toa (prefix), prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ assert (node->data == NULL);
+ return (node);
+ }
+
+ new_node = (patricia_node_t*)ndpi_calloc(1, sizeof *new_node);
+ new_node->bit = prefix->bitlen;
+ new_node->prefix = ndpi_Ref_Prefix (prefix);
+ new_node->parent = NULL;
+ new_node->l = new_node->r = NULL;
+ new_node->data = NULL;
+ patricia->num_active_node++;
+
+ if(node->bit == differ_bit) {
+ new_node->parent = node;
+ if(node->bit < patricia->maxbits &&
+ BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) {
+ assert (node->r == NULL);
+ node->r = new_node;
+ }
+ else {
+ assert (node->l == NULL);
+ node->l = new_node;
+ }
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_lookup: new_node #2 %s/%d (child)\n",
+ ndpi_prefix_toa (prefix), prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ return (new_node);
+ }
+
+ if(bitlen == differ_bit) {
+ if(bitlen < patricia->maxbits &&
+ BIT_TEST (test_addr[bitlen >> 3], 0x80 >> (bitlen & 0x07))) {
+ new_node->r = node;
+ }
+ else {
+ new_node->l = node;
+ }
+ new_node->parent = node->parent;
+ if(node->parent == NULL) {
+ assert (patricia->head == node);
+ patricia->head = new_node;
+ }
+ else if(node->parent->r == node) {
+ node->parent->r = new_node;
+ }
+ else {
+ node->parent->l = new_node;
+ }
+ node->parent = new_node;
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_lookup: new_node #3 %s/%d (parent)\n",
+ ndpi_prefix_toa (prefix), prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ }
+ else {
+ glue = (patricia_node_t*)ndpi_calloc(1, sizeof *glue);
+ glue->bit = differ_bit;
+ glue->prefix = NULL;
+ glue->parent = node->parent;
+ glue->data = NULL;
+ patricia->num_active_node++;
+ if(differ_bit < patricia->maxbits &&
+ BIT_TEST (addr[differ_bit >> 3], 0x80 >> (differ_bit & 0x07))) {
+ glue->r = new_node;
+ glue->l = node;
+ }
+ else {
+ glue->r = node;
+ glue->l = new_node;
+ }
+ new_node->parent = glue;
+
+ if(node->parent == NULL) {
+ assert (patricia->head == node);
+ patricia->head = glue;
+ }
+ else if(node->parent->r == node) {
+ node->parent->r = glue;
+ }
+ else {
+ node->parent->l = glue;
+ }
+ node->parent = glue;
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_lookup: new_node #4 %s/%d (glue+node)\n",
+ ndpi_prefix_toa (prefix), prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ }
+ return (new_node);
+}
+
+
+void
+ndpi_patricia_remove (patricia_tree_t *patricia, patricia_node_t *node)
+{
+ patricia_node_t *parent, *child;
+
+ assert (patricia);
+ assert (node);
+
+ if(node->r && node->l) {
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_remove: #0 %s/%d (r & l)\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+
+ /* this might be a placeholder node -- have to check and make sure
+ * there is a prefix aossciated with it ! */
+ if(node->prefix != NULL)
+ ndpi_Deref_Prefix (node->prefix);
+ node->prefix = NULL;
+ /* Also I needed to clear data pointer -- masaki */
+ node->data = NULL;
+ return;
+ }
+
+ if(node->r == NULL && node->l == NULL) {
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_remove: #1 %s/%d (!r & !l)\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ parent = node->parent;
+ ndpi_Deref_Prefix (node->prefix);
+ ndpi_DeleteEntry (node);
+ patricia->num_active_node--;
+
+ if(parent == NULL) {
+ assert (patricia->head == node);
+ patricia->head = NULL;
+ return;
+ }
+
+ if(parent->r == node) {
+ parent->r = NULL;
+ child = parent->l;
+ }
+ else {
+ assert (parent->l == node);
+ parent->l = NULL;
+ child = parent->r;
+ }
+
+ if(parent->prefix)
+ return;
+
+ /* we need to remove parent too */
+
+ if(parent->parent == NULL) {
+ assert (patricia->head == parent);
+ patricia->head = child;
+ }
+ else if(parent->parent->r == parent) {
+ parent->parent->r = child;
+ }
+ else {
+ assert (parent->parent->l == parent);
+ parent->parent->l = child;
+ }
+ child->parent = parent->parent;
+ ndpi_DeleteEntry (parent);
+ patricia->num_active_node--;
+ return;
+ }
+
+#ifdef PATRICIA_DEBUG
+ fprintf (stderr, "patricia_remove: #2 %s/%d (r ^ l)\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ if(node->r) {
+ child = node->r;
+ }
+ else {
+ assert (node->l);
+ child = node->l;
+ }
+ parent = node->parent;
+ child->parent = parent;
+
+ ndpi_Deref_Prefix (node->prefix);
+ ndpi_DeleteEntry (node);
+ patricia->num_active_node--;
+
+ if(parent == NULL) {
+ assert (patricia->head == node);
+ patricia->head = child;
+ return;
+ }
+
+ if(parent->r == node) {
+ parent->r = child;
+ }
+ else {
+ assert (parent->l == node);
+ parent->l = child;
+ }
+}
+
+/* { from demo.c */
+#if 0
+
+patricia_node_t *
+ndpi_make_and_lookup (patricia_tree_t *tree, char *string)
+{
+ prefix_t *prefix;
+ patricia_node_t *node;
+
+ prefix = ndpi_ascii2prefix (AF_INET, string);
+ printf ("make_and_lookup: %s/%d\n", ndpi_prefix_toa (prefix), prefix->bitlen);
+ node = ndpi_patricia_lookup (tree, prefix);
+ ndpi_Deref_Prefix (prefix);
+ return (node);
+}
+
+patricia_node_t *
+ndpi_try_search_exact (patricia_tree_t *tree, char *string)
+{
+ prefix_t *prefix;
+ patricia_node_t *node;
+
+ prefix = ndpi_ascii2prefix (AF_INET, string);
+ printf ("try_search_exact: %s/%d\n", ndpi_prefix_toa (prefix), prefix->bitlen);
+ if((node = patricia_search_exact (tree, prefix)) == NULL) {
+ printf ("try_search_exact: not found\n");
+ }
+ else {
+ printf ("try_search_exact: %s/%d found\n",
+ ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
+ }
+ ndpi_Deref_Prefix (prefix);
+ return (node);
+}
+
+void
+ndpi_lookup_then_remove (patricia_tree_t *tree, char *string)
+{
+ patricia_node_t *node;
+
+ if((node = try_search_exact (tree, string)))
+ patricia_remove (tree, node);
+}
+#endif
+
+/* } */
diff --git a/src/lib/third_party/src/sort.c b/src/lib/third_party/src/sort.c
new file mode 100644
index 000000000..d6545e85a
--- /dev/null
+++ b/src/lib/third_party/src/sort.c
@@ -0,0 +1,130 @@
+/*
+ * A fast, small, non-recursive O(nlog n) sort for the Linux kernel
+ *
+ * Jan 23 2005 Matt Mackall <mpm@selenic.com>
+ */
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#ifdef WIN32
+#include <stdint.h>
+typedef uint32_t u_int32_t;
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#endif
+
+/* This is a function ported from the Linux kernel lib/sort.c */
+
+static void u_int32_t_swap(void *a, void *b, int size)
+{
+ u_int32_t t = *(u_int32_t *)a;
+ *(u_int32_t *)a = *(u_int32_t *)b;
+ *(u_int32_t *)b = t;
+}
+
+static void generic_swap(void *_a, void *_b, int size)
+{
+ char t;
+ char *a = (char*)_a;
+ char *b = (char*)_b;
+
+ do {
+ t = *a;
+ *a++ = *b;
+ *b++ = t;
+ } while (--size > 0);
+}
+
+/**
+ * sort - sort an array of elements
+ * @base: pointer to data to sort
+ * @num: number of elements
+ * @size: size of each element
+ * @cmp_func: pointer to comparison function
+ * @swap_func: pointer to swap function or NULL
+ *
+ * This function does a heapsort on the given array. You may provide a
+ * swap_func function optimized to your element type.
+ *
+ * Sorting time is O(n log n) both on average and worst-case. While
+ * qsort is about 20% faster on average, it suffers from exploitable
+ * O(n*n) worst-case behavior and extra memory requirements that make
+ * it less suitable for kernel use.
+ */
+
+void sort(void *_base, size_t num, size_t size,
+ int (*cmp_func)(const void *, const void *),
+ void (*swap_func)(void *, void *, int size))
+{
+ /* pre-scale counters for performance */
+ int i = (num/2 - 1) * size, n = num * size, c, r;
+ char *base = (char*)_base;
+
+ if (!swap_func)
+ swap_func = (size == 4 ? u_int32_t_swap : generic_swap);
+
+ /* heapify */
+ for ( ; i >= 0; i -= size) {
+ for (r = i; r * 2 + size < n; r = c) {
+ c = r * 2 + size;
+ if (c < n - size &&
+ cmp_func(base + c, base + c + size) < 0)
+ c += size;
+ if (cmp_func(base + r, base + c) >= 0)
+ break;
+ swap_func(base + r, base + c, size);
+ }
+ }
+
+ /* sort */
+ for (i = n - size; i > 0; i -= size) {
+ swap_func(base, base + i, size);
+ for (r = 0; r * 2 + size < i; r = c) {
+ c = r * 2 + size;
+ if (c < i - size &&
+ cmp_func(base + c, base + c + size) < 0)
+ c += size;
+ if (cmp_func(base + r, base + c) >= 0)
+ break;
+ swap_func(base + r, base + c, size);
+ }
+ }
+}
+
+
+#if 0
+/* a simple boot-time regression test */
+
+int cmpint(const void *a, const void *b)
+{
+ return *(int *)a - *(int *)b;
+}
+
+int main(int argc, char *argv[]) {
+ int *a, i, r = 1;
+
+ a = ndpi_malloc(1000 * sizeof(int));
+
+ printf("testing sort()\n");
+
+ for (i = 0; i < 1000; i++) {
+ r = (r * 725861) % 6599;
+ a[i] = r;
+ }
+
+ sort(a, 1000, sizeof(int), cmpint, NULL);
+
+ for (i = 0; i < 999; i++)
+ if (a[i] > a[i+1]) {
+ printf("sort() failed!\n");
+ break;
+ }
+
+ return 0;
+}
+
+#endif