From 2e5ceac844c32fb52f4f3042be5b872f8b0b4ff0 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Sun, 19 Apr 2015 07:25:59 +0200 Subject: Initial import from SVN --- COPYING | 165 + ChangeLog | 16 + INSTALL | 365 + Makefile.am | 8 + README.md | 59 +- README.protocols | 18 + autogen.sh | 7 + configure.ac | 84 + doc/nDPI_QuickStartGuide.pages | Bin 0 -> 157979 bytes doc/nDPI_QuickStartGuide.pdf | Bin 0 -> 146256 bytes example/Makefile.am | 12 + example/Win32/pcapExample.sln | 20 + example/Win32/pcapExample.suo | Bin 0 -> 306688 bytes example/Win32/pcapExample/pcapExample.cpp | 11 + example/Win32/pcapExample/pcapExample.vcxproj | 230 + .../Win32/pcapExample/pcapExample.vcxproj.filters | 462 ++ example/Win32/pcapExample/pcapExample.vcxproj.user | 3 + example/ndpiReader.c | 1788 +++++ example/protos.txt | 18 + lib | 1 + libndpi.pc.in | 10 + libndpi.sym | 27 + m4/ax_pthread.m4 | 332 + ndpi-netfilter/README | 4 + packages/homebrew/README | 11 + packages/homebrew/ndpi.rb | 23 + packages/ubuntu/Makefile | 42 + packages/ubuntu/Makefile.in | 42 + packages/ubuntu/configure | 2863 ++++++++ packages/ubuntu/configure.in | 32 + packages/ubuntu/debian/COPYRIGHT | 340 + packages/ubuntu/debian/README | 2 + packages/ubuntu/debian/changelog.in | 4 + packages/ubuntu/debian/compat | 1 + packages/ubuntu/debian/conffiles | 0 packages/ubuntu/debian/control.in | 28 + packages/ubuntu/debian/dirs | 1 + packages/ubuntu/debian/docs | 1 + packages/ubuntu/debian/files.in | 1 + packages/ubuntu/debian/postinst | 34 + packages/ubuntu/debian/postrm | 13 + packages/ubuntu/debian/preinst | 35 + packages/ubuntu/debian/prerm | 14 + packages/ubuntu/debian/rules | 59 + src/include/Makefile.am | 9 + src/include/linux_compat.h | 188 + src/include/ndpi_api.h | 242 + src/include/ndpi_define.h | 309 + src/include/ndpi_main.h | 156 + src/include/ndpi_protocol_ids.h | 244 + src/include/ndpi_protocols.h | 181 + src/include/ndpi_typedefs.h | 852 +++ src/include/ndpi_unix.h | 53 + src/include/ndpi_win32.h | 73 + src/lib/Makefile.am | 158 + src/lib/ndpi_content_match.c.inc | 7410 ++++++++++++++++++++ src/lib/ndpi_main.c | 5706 +++++++++++++++ src/lib/protocols/afp.c | 75 + src/lib/protocols/aimini.c | 283 + src/lib/protocols/applejuice.c | 57 + src/lib/protocols/armagetron.c | 102 + src/lib/protocols/attic/flash.c | 93 + src/lib/protocols/attic/ftp.c | 469 ++ src/lib/protocols/attic/manolito.c | 180 + src/lib/protocols/attic/popo.c | 86 + src/lib/protocols/attic/secondlife.c | 123 + src/lib/protocols/ayiya.c | 67 + src/lib/protocols/battlefield.c | 118 + src/lib/protocols/bgp.c | 57 + src/lib/protocols/bittorrent.c | 469 ++ src/lib/protocols/btlib.c | 509 ++ src/lib/protocols/btlib.h | 147 + src/lib/protocols/ciscovpn.c | 70 + src/lib/protocols/citrix.c | 93 + src/lib/protocols/collectd.c | 53 + src/lib/protocols/corba.c | 48 + src/lib/protocols/crossfire.c | 85 + src/lib/protocols/dcerpc.c | 54 + src/lib/protocols/dhcp.c | 60 + src/lib/protocols/dhcpv6.c | 60 + src/lib/protocols/directconnect.c | 474 ++ src/lib/protocols/directdownloadlink.c | 737 ++ src/lib/protocols/dns.c | 300 + src/lib/protocols/dofus.c | 149 + src/lib/protocols/dropbox.c | 77 + src/lib/protocols/edonkey.c | 211 + src/lib/protocols/fasttrack.c | 82 + src/lib/protocols/fiesta.c | 97 + src/lib/protocols/filetopia.c | 83 + src/lib/protocols/florensia.c | 122 + src/lib/protocols/ftp_control.c | 999 +++ src/lib/protocols/ftp_data.c | 275 + src/lib/protocols/gnutella.c | 375 + src/lib/protocols/gtp.c | 85 + src/lib/protocols/guildwars.c | 71 + src/lib/protocols/h323.c | 97 + src/lib/protocols/halflife2_and_mods.c | 65 + src/lib/protocols/http.c | 981 +++ src/lib/protocols/http_activesync.c | 54 + src/lib/protocols/iax.c | 94 + src/lib/protocols/icecast.c | 91 + src/lib/protocols/imesh.c | 294 + src/lib/protocols/ipp.c | 112 + src/lib/protocols/irc.c | 804 +++ src/lib/protocols/jabber.c | 311 + src/lib/protocols/kerberos.c | 82 + src/lib/protocols/kontiki.c | 65 + src/lib/protocols/ldap.c | 101 + src/lib/protocols/lotus_notes.c | 87 + src/lib/protocols/mail_imap.c | 293 + src/lib/protocols/mail_pop.c | 204 + src/lib/protocols/mail_smtp.c | 180 + src/lib/protocols/maplestory.c | 87 + src/lib/protocols/mdns.c | 146 + src/lib/protocols/meebo.c | 165 + src/lib/protocols/megaco.c | 49 + src/lib/protocols/mgcp.c | 102 + src/lib/protocols/mms.c | 80 + src/lib/protocols/msn.c | 563 ++ src/lib/protocols/mssql.c | 61 + src/lib/protocols/mysql.c | 70 + src/lib/protocols/netbios.c | 368 + src/lib/protocols/netflow.c | 93 + src/lib/protocols/nfs.c | 86 + src/lib/protocols/noe.c | 52 + src/lib/protocols/non_tcp_udp.c | 108 + src/lib/protocols/ntp.c | 68 + src/lib/protocols/openft.c | 56 + src/lib/protocols/openvpn.c | 69 + src/lib/protocols/oracle.c | 62 + src/lib/protocols/oscar.c | 273 + src/lib/protocols/pando.c | 157 + src/lib/protocols/pcanywhere.c | 55 + src/lib/protocols/postgres.c | 120 + src/lib/protocols/pplive.c | 220 + src/lib/protocols/ppstream.c | 105 + src/lib/protocols/pptp.c | 61 + src/lib/protocols/qq.c | 665 ++ src/lib/protocols/quake.c | 91 + src/lib/protocols/radius.c | 76 + src/lib/protocols/rdp.c | 56 + src/lib/protocols/redis.c | 92 + src/lib/protocols/rsync.c | 56 + src/lib/protocols/rtcp.c | 52 + src/lib/protocols/rtmp.c | 92 + src/lib/protocols/rtp.c | 325 + src/lib/protocols/rtsp.c | 120 + src/lib/protocols/sflow.c | 49 + src/lib/protocols/shoutcast.c | 107 + src/lib/protocols/sip.c | 200 + src/lib/protocols/skinny.c | 63 + src/lib/protocols/skype.c | 122 + src/lib/protocols/smb.c | 57 + src/lib/protocols/snmp.c | 126 + src/lib/protocols/socks4.c | 96 + src/lib/protocols/socks5.c | 92 + src/lib/protocols/socrates.c | 80 + src/lib/protocols/sopcast.c | 219 + src/lib/protocols/soulseek.c | 286 + src/lib/protocols/spotify.c | 128 + src/lib/protocols/ssdp.c | 70 + src/lib/protocols/ssh.c | 68 + src/lib/protocols/ssl.c | 637 ++ src/lib/protocols/stealthnet.c | 58 + src/lib/protocols/steam.c | 286 + src/lib/protocols/stun.c | 188 + src/lib/protocols/syslog.c | 130 + src/lib/protocols/tcp_udp.c | 78 + src/lib/protocols/tds.c | 91 + src/lib/protocols/teamspeak.c | 65 + src/lib/protocols/teamviewer.c | 100 + src/lib/protocols/telegram.c | 68 + src/lib/protocols/telnet.c | 107 + src/lib/protocols/tftp.c | 70 + src/lib/protocols/thunder.c | 211 + src/lib/protocols/tor.c | 109 + src/lib/protocols/tvants.c | 78 + src/lib/protocols/tvuplayer.c | 153 + src/lib/protocols/twitter.c | 63 + src/lib/protocols/usenet.c | 105 + src/lib/protocols/veohtv.c | 116 + src/lib/protocols/vhua.c | 68 + src/lib/protocols/viber.c | 48 + src/lib/protocols/vmware.c | 45 + src/lib/protocols/vnc.c | 67 + src/lib/protocols/warcraft3.c | 100 + src/lib/protocols/whoisdas.c | 60 + src/lib/protocols/winmx.c | 104 + src/lib/protocols/world_of_kung_fu.c | 58 + src/lib/protocols/world_of_warcraft.c | 210 + src/lib/protocols/xbox.c | 103 + src/lib/protocols/xdmcp.c | 69 + src/lib/protocols/yahoo.c | 434 ++ src/lib/protocols/zattoo.c | 235 + src/lib/protocols/zmq.c | 100 + src/lib/third_party/include/actypes.h | 135 + src/lib/third_party/include/ahocorasick.h | 69 + src/lib/third_party/include/node.h | 66 + src/lib/third_party/include/patricia.h | 302 + src/lib/third_party/include/sort.h | 6 + src/lib/third_party/src/ahocorasick.c | 391 ++ src/lib/third_party/src/node.c | 260 + src/lib/third_party/src/patricia.c | 1076 +++ src/lib/third_party/src/sort.c | 130 + 204 files changed, 47689 insertions(+), 1 deletion(-) create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 README.protocols create mode 100755 autogen.sh create mode 100644 configure.ac create mode 100644 doc/nDPI_QuickStartGuide.pages create mode 100644 doc/nDPI_QuickStartGuide.pdf create mode 100644 example/Makefile.am create mode 100644 example/Win32/pcapExample.sln create mode 100644 example/Win32/pcapExample.suo create mode 100644 example/Win32/pcapExample/pcapExample.cpp create mode 100644 example/Win32/pcapExample/pcapExample.vcxproj create mode 100644 example/Win32/pcapExample/pcapExample.vcxproj.filters create mode 100644 example/Win32/pcapExample/pcapExample.vcxproj.user create mode 100644 example/ndpiReader.c create mode 100644 example/protos.txt create mode 120000 lib create mode 100644 libndpi.pc.in create mode 100644 libndpi.sym create mode 100644 m4/ax_pthread.m4 create mode 100644 ndpi-netfilter/README create mode 100644 packages/homebrew/README create mode 100644 packages/homebrew/ndpi.rb create mode 100644 packages/ubuntu/Makefile create mode 100644 packages/ubuntu/Makefile.in create mode 100755 packages/ubuntu/configure create mode 100644 packages/ubuntu/configure.in create mode 100644 packages/ubuntu/debian/COPYRIGHT create mode 100644 packages/ubuntu/debian/README create mode 100644 packages/ubuntu/debian/changelog.in create mode 100644 packages/ubuntu/debian/compat create mode 100644 packages/ubuntu/debian/conffiles create mode 100644 packages/ubuntu/debian/control.in create mode 100644 packages/ubuntu/debian/dirs create mode 100644 packages/ubuntu/debian/docs create mode 100644 packages/ubuntu/debian/files.in create mode 100755 packages/ubuntu/debian/postinst create mode 100644 packages/ubuntu/debian/postrm create mode 100644 packages/ubuntu/debian/preinst create mode 100755 packages/ubuntu/debian/prerm create mode 100755 packages/ubuntu/debian/rules create mode 100644 src/include/Makefile.am create mode 100644 src/include/linux_compat.h create mode 100644 src/include/ndpi_api.h create mode 100644 src/include/ndpi_define.h create mode 100644 src/include/ndpi_main.h create mode 100644 src/include/ndpi_protocol_ids.h create mode 100644 src/include/ndpi_protocols.h create mode 100644 src/include/ndpi_typedefs.h create mode 100644 src/include/ndpi_unix.h create mode 100644 src/include/ndpi_win32.h create mode 100644 src/lib/Makefile.am create mode 100644 src/lib/ndpi_content_match.c.inc create mode 100644 src/lib/ndpi_main.c create mode 100644 src/lib/protocols/afp.c create mode 100644 src/lib/protocols/aimini.c create mode 100644 src/lib/protocols/applejuice.c create mode 100644 src/lib/protocols/armagetron.c create mode 100644 src/lib/protocols/attic/flash.c create mode 100644 src/lib/protocols/attic/ftp.c create mode 100644 src/lib/protocols/attic/manolito.c create mode 100644 src/lib/protocols/attic/popo.c create mode 100644 src/lib/protocols/attic/secondlife.c create mode 100644 src/lib/protocols/ayiya.c create mode 100644 src/lib/protocols/battlefield.c create mode 100644 src/lib/protocols/bgp.c create mode 100644 src/lib/protocols/bittorrent.c create mode 100644 src/lib/protocols/btlib.c create mode 100644 src/lib/protocols/btlib.h create mode 100644 src/lib/protocols/ciscovpn.c create mode 100644 src/lib/protocols/citrix.c create mode 100644 src/lib/protocols/collectd.c create mode 100644 src/lib/protocols/corba.c create mode 100644 src/lib/protocols/crossfire.c create mode 100644 src/lib/protocols/dcerpc.c create mode 100644 src/lib/protocols/dhcp.c create mode 100644 src/lib/protocols/dhcpv6.c create mode 100644 src/lib/protocols/directconnect.c create mode 100644 src/lib/protocols/directdownloadlink.c create mode 100644 src/lib/protocols/dns.c create mode 100644 src/lib/protocols/dofus.c create mode 100644 src/lib/protocols/dropbox.c create mode 100644 src/lib/protocols/edonkey.c create mode 100644 src/lib/protocols/fasttrack.c create mode 100644 src/lib/protocols/fiesta.c create mode 100644 src/lib/protocols/filetopia.c create mode 100644 src/lib/protocols/florensia.c create mode 100644 src/lib/protocols/ftp_control.c create mode 100644 src/lib/protocols/ftp_data.c create mode 100644 src/lib/protocols/gnutella.c create mode 100644 src/lib/protocols/gtp.c create mode 100644 src/lib/protocols/guildwars.c create mode 100644 src/lib/protocols/h323.c create mode 100644 src/lib/protocols/halflife2_and_mods.c create mode 100644 src/lib/protocols/http.c create mode 100644 src/lib/protocols/http_activesync.c create mode 100644 src/lib/protocols/iax.c create mode 100644 src/lib/protocols/icecast.c create mode 100644 src/lib/protocols/imesh.c create mode 100644 src/lib/protocols/ipp.c create mode 100644 src/lib/protocols/irc.c create mode 100644 src/lib/protocols/jabber.c create mode 100644 src/lib/protocols/kerberos.c create mode 100644 src/lib/protocols/kontiki.c create mode 100644 src/lib/protocols/ldap.c create mode 100644 src/lib/protocols/lotus_notes.c create mode 100644 src/lib/protocols/mail_imap.c create mode 100644 src/lib/protocols/mail_pop.c create mode 100644 src/lib/protocols/mail_smtp.c create mode 100644 src/lib/protocols/maplestory.c create mode 100644 src/lib/protocols/mdns.c create mode 100644 src/lib/protocols/meebo.c create mode 100644 src/lib/protocols/megaco.c create mode 100644 src/lib/protocols/mgcp.c create mode 100644 src/lib/protocols/mms.c create mode 100644 src/lib/protocols/msn.c create mode 100644 src/lib/protocols/mssql.c create mode 100644 src/lib/protocols/mysql.c create mode 100644 src/lib/protocols/netbios.c create mode 100644 src/lib/protocols/netflow.c create mode 100644 src/lib/protocols/nfs.c create mode 100644 src/lib/protocols/noe.c create mode 100644 src/lib/protocols/non_tcp_udp.c create mode 100644 src/lib/protocols/ntp.c create mode 100644 src/lib/protocols/openft.c create mode 100644 src/lib/protocols/openvpn.c create mode 100644 src/lib/protocols/oracle.c create mode 100644 src/lib/protocols/oscar.c create mode 100644 src/lib/protocols/pando.c create mode 100644 src/lib/protocols/pcanywhere.c create mode 100644 src/lib/protocols/postgres.c create mode 100644 src/lib/protocols/pplive.c create mode 100644 src/lib/protocols/ppstream.c create mode 100644 src/lib/protocols/pptp.c create mode 100644 src/lib/protocols/qq.c create mode 100644 src/lib/protocols/quake.c create mode 100644 src/lib/protocols/radius.c create mode 100644 src/lib/protocols/rdp.c create mode 100644 src/lib/protocols/redis.c create mode 100644 src/lib/protocols/rsync.c create mode 100644 src/lib/protocols/rtcp.c create mode 100644 src/lib/protocols/rtmp.c create mode 100644 src/lib/protocols/rtp.c create mode 100644 src/lib/protocols/rtsp.c create mode 100644 src/lib/protocols/sflow.c create mode 100644 src/lib/protocols/shoutcast.c create mode 100644 src/lib/protocols/sip.c create mode 100644 src/lib/protocols/skinny.c create mode 100644 src/lib/protocols/skype.c create mode 100644 src/lib/protocols/smb.c create mode 100644 src/lib/protocols/snmp.c create mode 100644 src/lib/protocols/socks4.c create mode 100644 src/lib/protocols/socks5.c create mode 100644 src/lib/protocols/socrates.c create mode 100644 src/lib/protocols/sopcast.c create mode 100644 src/lib/protocols/soulseek.c create mode 100644 src/lib/protocols/spotify.c create mode 100644 src/lib/protocols/ssdp.c create mode 100644 src/lib/protocols/ssh.c create mode 100644 src/lib/protocols/ssl.c create mode 100644 src/lib/protocols/stealthnet.c create mode 100644 src/lib/protocols/steam.c create mode 100644 src/lib/protocols/stun.c create mode 100644 src/lib/protocols/syslog.c create mode 100644 src/lib/protocols/tcp_udp.c create mode 100644 src/lib/protocols/tds.c create mode 100644 src/lib/protocols/teamspeak.c create mode 100644 src/lib/protocols/teamviewer.c create mode 100644 src/lib/protocols/telegram.c create mode 100644 src/lib/protocols/telnet.c create mode 100644 src/lib/protocols/tftp.c create mode 100644 src/lib/protocols/thunder.c create mode 100644 src/lib/protocols/tor.c create mode 100644 src/lib/protocols/tvants.c create mode 100644 src/lib/protocols/tvuplayer.c create mode 100644 src/lib/protocols/twitter.c create mode 100644 src/lib/protocols/usenet.c create mode 100644 src/lib/protocols/veohtv.c create mode 100644 src/lib/protocols/vhua.c create mode 100644 src/lib/protocols/viber.c create mode 100644 src/lib/protocols/vmware.c create mode 100644 src/lib/protocols/vnc.c create mode 100644 src/lib/protocols/warcraft3.c create mode 100644 src/lib/protocols/whoisdas.c create mode 100644 src/lib/protocols/winmx.c create mode 100644 src/lib/protocols/world_of_kung_fu.c create mode 100644 src/lib/protocols/world_of_warcraft.c create mode 100644 src/lib/protocols/xbox.c create mode 100644 src/lib/protocols/xdmcp.c create mode 100644 src/lib/protocols/yahoo.c create mode 100644 src/lib/protocols/zattoo.c create mode 100644 src/lib/protocols/zmq.c create mode 100644 src/lib/third_party/include/actypes.h create mode 100644 src/lib/third_party/include/ahocorasick.h create mode 100644 src/lib/third_party/include/node.h create mode 100644 src/lib/third_party/include/patricia.h create mode 100644 src/lib/third_party/include/sort.h create mode 100644 src/lib/third_party/src/ahocorasick.c create mode 100644 src/lib/third_party/src/node.c create mode 100644 src/lib/third_party/src/patricia.c create mode 100644 src/lib/third_party/src/sort.c diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..cca7fc278 --- /dev/null +++ b/COPYING @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..9bd7818c0 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,16 @@ +2014-03-21: +- improved support for eDonkey/eMule/Kademlia +- improved support for PPLive + +2014-03-20: +- code optimizations +- consistency improvements +- added support for new applications: Pando Media Booster +- improved support for Steam +- added support for new web services: Wikipedia, MSN, Amazon, eBay, CNN + +2014-03-19: +- added new protocols: FTP, code improvements + +2014-03-17: +- added new protocols: SOCKSv4, SOCKSv5, RTMP diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..7d1c323be --- /dev/null +++ b/INSTALL @@ -0,0 +1,365 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..80258e773 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,8 @@ +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = src/lib example + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libndpi.pc + +EXTRA_DIST = libndpi.sym autogen.sh diff --git a/README.md b/README.md index 4d0b1c616..d2bc89259 100644 --- a/README.md +++ b/README.md @@ -1 +1,58 @@ -# ndpi +This directory contains a modified version of OpenDPI which +includes ntop extensions. I have tried to push them into the +OpenDPI source tree but nobody in answering emails so I have +decided to create my own source tree + +========== + +In order to compile this library do + +# ./autogen.sh +# ./configure +# make + +Please note that the pre-requisites for compilation include: +- GNU tools (autogen, automake, autoconf, libtool) +- GNU C compiler (gcc) + +========== + +The entire procedure of adding new protocols in detail: + +1. Add new protocol together with its unique ID to: +src/include/ndpi_protocols_osdpi.h + +2. Create a new protocol in: +src/lib/protocols/ + +3. Variables to be kept for the duration of the entire flow (as state variables) needs to be placed in: +/include/ndpi_structs.h +in ndpi_flow_tcp_struct (for TCP only), ndpi_flow_udp_struct (for UDP only), or ndpi_flow_struct (for both). + +4. Add a new entry for the search function for the new protocol in: +src/include/ndpi_protocols.h + +5. Choose (do not change anything) a selection bitmask from: +src/include/ndpi_define.h + +6. Add a new entry in ndpi_set_protocol_detection_bitmask2 in: +src/lib/ndpi_main.c + +7. Set protocol default ports in ndpi_init_protocol_defaults in: +src/lib/ndpi_main.c + +8. Add the new protocol file to: +src/lib/Makefile.am + +9. ./autogen.sh +10. ./configure +11. make + +========== + +If you want to distribute a source tar file of nDPI do: + +# make dist + +-------------------------- +April 2015 - ntop \ No newline at end of file diff --git a/README.protocols b/README.protocols new file mode 100644 index 000000000..27d8c6408 --- /dev/null +++ b/README.protocols @@ -0,0 +1,18 @@ +Tor +--- + +Tor protocol can use SSL to hide itself. These are examples: + +TCP 37.128.208.46:9001 <-> 172.16.253.130:2078 [VLAN: 0][proto: 91/SSL][132 pkts/93834 bytes][SSL client: www.jwrpsthzrih.com] +TCP 172.16.253.130:2021 <-> 75.147.140.249:443 [VLAN: 0][proto: 91/SSL][28 pkts/8053 bytes][SSL client: www.5akw23dx.com] +TCP 172.16.253.130:2077 <-> 77.247.181.163:443 [VLAN: 0][proto: 91/SSL][136 pkts/94329 bytes][SSL client: www.fk4pprq42hsvl2wey.com] + +It can be detected by analyzing the SSL client certificate and checking the name that does not match to a real host in +addition of begin a bit weird. As doing DNS resolution is not a task for nDPI we let applications do and then recognize +SSL-tunnelled connections. + +See http://www.netresec.com/?page=Blog&month=2013-04&post=Detecting-TOR-Communication-in-Network-Traffic + +For this reason nDPI uses a heuristic, non-DNS based, approach to detect tor communications. If possible, apps +should validate the certificate using the DNS. This is not something nDPI can afford to do for performance +reasons diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 000000000..9853e65ef --- /dev/null +++ b/autogen.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +# +# 1.5.1 r8171 06/09/2014 +# +autoreconf -ivf +./configure diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000..b5079143f --- /dev/null +++ b/configure.ac @@ -0,0 +1,84 @@ +AC_INIT([libndpi], [1.5.2]) + +AC_CONFIG_MACRO_DIR([m4]) + +AM_INIT_AUTOMAKE([foreign subdir-objects]) + +LT_INIT + +AC_PROG_CC +AX_PTHREAD + +if test -d ".svn"; then : +SVN_RELEASE=`svn info . | grep "^Revision"|cut -d " " -f 2` +SVN_DATE=`svn info . | grep "^Last Changed Date"|cut -d " " -f 4-` +else +SVN_RELEASE="${PACKAGE_VERSION}" +SVN_DATE=`date` +fi + +AC_DEFINE_UNQUOTED(NDPI_SVN_RELEASE, "r${SVN_RELEASE}", [SVN Release]) +AC_DEFINE_UNQUOTED(NDPI_SVN_DATE, "${SVN_DATE}", [Last SVN change]) + +AC_CHECK_HEADERS([netinet/in.h stdint.h stdlib.h string.h unistd.h]) + +PCAP_HOME=$HOME/PF_RING/userland + +if test -d $PCAP_HOME; then : + echo -n "" +else + PCAP_HOME=`pwd`/../../PF_RING/userland +fi + +SHORT_MACHINE=`uname -m | cut -b1-3` +if test $SHORT_MACHINE = "arm"; then +LIBNUMA="" +else +LIBNUMA="-lnuma" +fi + +if test -f $PCAP_HOME/libpcap/libpcap.a; then : + echo "Using libpcap from $PCAP_HOME" + PCAP_INC="-I $PCAP_HOME/libpcap" + PCAP_LIB="$PCAP_HOME/libpcap/libpcap.a $PCAP_HOME/lib/libpfring.a $LIBNUMA" + + AC_CHECK_LIB([rt], [clock_gettime], [PCAP_LIB="$PCAP_LIB -lrt"]) + AC_CHECK_LIB([nl], [nl_handle_alloc], [PCAP_LIB="$PCAP_LIB -lnl"]) +else + AC_CHECK_LIB([pcap], [pcap_open_live], [PCAP_LIB="-lpcap"]) + + if test $ac_cv_lib_pcap_pcap_open_live = "no"; then : + echo "" + echo "ERROR: Missing libpcap(-dev) library required to compile the example application" + echo "ERROR: Please install it and try again" + exit + fi +fi + +if test -d /usr/local/include/json-c/; then : + CFLAGS="$CFLAGS -I/usr/local/include/json-c/" + LDFLAGS="$LDFLAGS -L/usr/local/lib -ljson-c" +else + CFLAGS="$CFLAGS $(pkg-config --cflags json-c)" + LDFLAGS="$LDFLAGS $(pkg-config --libs json-c)" +fi + +OLD_LIBS=$LIBS +LIBS="-L/opt/napatech3/lib $LIBS" +AC_CHECK_LIB([ntapi], + [NT_Init], + [PCAP_LIB="$PCAP_LIB -L/opt/napatech3/lib -lntapi"], + [], [] ) +LIBS=$OLD_LIBS + +AC_CHECK_LIB(json-c, json_object_new_object, AC_DEFINE_UNQUOTED(HAVE_JSON_C, 1, [The JSON-C library is present])) + +AC_CONFIG_FILES([Makefile src/lib/Makefile example/Makefile libndpi.pc]) +AC_CONFIG_HEADERS(config.h) +AC_SUBST(SVN_RELEASE) +AC_SUBST(SVN_DATE) +AC_SUBST(JSON_C_LIB) +AC_SUBST(PCAP_INC) +AC_SUBST(PCAP_LIB) + +AC_OUTPUT diff --git a/doc/nDPI_QuickStartGuide.pages b/doc/nDPI_QuickStartGuide.pages new file mode 100644 index 000000000..e2313a184 Binary files /dev/null and b/doc/nDPI_QuickStartGuide.pages differ diff --git a/doc/nDPI_QuickStartGuide.pdf b/doc/nDPI_QuickStartGuide.pdf new file mode 100644 index 000000000..f29be2a91 Binary files /dev/null and b/doc/nDPI_QuickStartGuide.pdf differ diff --git a/example/Makefile.am b/example/Makefile.am new file mode 100644 index 000000000..f98bae9ae --- /dev/null +++ b/example/Makefile.am @@ -0,0 +1,12 @@ +bin_PROGRAMS = ndpiReader + +AM_CPPFLAGS = -I$(top_srcdir)/src/include @PCAP_INC@ +AM_CFLAGS = @PTHREAD_CFLAGS@ + +LDADD = $(top_builddir)/src/lib/libndpi.la @JSON_C_LIB@ @PTHREAD_LIBS@ @PCAP_LIB@ +AM_LDFLAGS = -static + +ndpiReader_SOURCES = ndpiReader.c + +ndpiReader.o: ndpiReader.c + diff --git a/example/Win32/pcapExample.sln b/example/Win32/pcapExample.sln new file mode 100644 index 000000000..3c061ed01 --- /dev/null +++ b/example/Win32/pcapExample.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcapExample", "pcapExample\pcapExample.vcxproj", "{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}.Debug|Win32.ActiveCfg = Debug|Win32 + {F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}.Debug|Win32.Build.0 = Debug|Win32 + {F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}.Release|Win32.ActiveCfg = Release|Win32 + {F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/example/Win32/pcapExample.suo b/example/Win32/pcapExample.suo new file mode 100644 index 000000000..122e224b4 Binary files /dev/null and b/example/Win32/pcapExample.suo differ diff --git a/example/Win32/pcapExample/pcapExample.cpp b/example/Win32/pcapExample/pcapExample.cpp new file mode 100644 index 000000000..ad7655eea --- /dev/null +++ b/example/Win32/pcapExample/pcapExample.cpp @@ -0,0 +1,11 @@ +// pcapExample.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + + +int _tmain(int argc, _TCHAR* argv[]) +{ + return 0; +} + diff --git a/example/Win32/pcapExample/pcapExample.vcxproj b/example/Win32/pcapExample/pcapExample.vcxproj new file mode 100644 index 000000000..2b86797bd --- /dev/null +++ b/example/Win32/pcapExample/pcapExample.vcxproj @@ -0,0 +1,230 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {F6A2C0AE-2110-438A-87E4-7C1CFCE064C6} + Win32Proj + pcapExample + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + + + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + C:\ntop\nprobe\nprobe-win-32;C:\ntop\winpcap\Include;C:\ntop\dependencies\nDPI\src\lib\third_party\include;C:\ntop\dependencies\nDPI\src\include;%(AdditionalIncludeDirectories) + + + Console + true + Wsock32.lib;Ws2_32.lib;C:\ntop\winpcap\Lib\Packet.lib;C:\ntop\winpcap\Lib\wpcap.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/Win32/pcapExample/pcapExample.vcxproj.filters b/example/Win32/pcapExample/pcapExample.vcxproj.filters new file mode 100644 index 000000000..394d9dc7a --- /dev/null +++ b/example/Win32/pcapExample/pcapExample.vcxproj.filters @@ -0,0 +1,462 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/example/Win32/pcapExample/pcapExample.vcxproj.user b/example/Win32/pcapExample/pcapExample.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/example/Win32/pcapExample/pcapExample.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/example/ndpiReader.c b/example/ndpiReader.c new file mode 100644 index 000000000..41a4b42ed --- /dev/null +++ b/example/ndpiReader.c @@ -0,0 +1,1788 @@ +/* + * ndpiReader.c + * + * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2014 - Matteo Bogo (JSON support) + * + * 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 . + * + */ + +#ifdef linux +#define _GNU_SOURCE +#include +#endif +#include +#include +#ifdef WIN32 +#include /* winsock.h is included automatically */ +#include +#include +#include +#define getopt getopt____ +#else +#include +#include +#endif +#include +#include +#include +#include +#include +#include + +#include "../config.h" + +#ifdef HAVE_JSON_C +#include +#endif + +#include "ndpi_api.h" + +#include + +#define MAX_NUM_READER_THREADS 16 + +/** + * @brief Set main components necessary to the detection + * @details TODO + */ +static void setupDetection(u_int16_t thread_id); + +/** + * Client parameters + */ +static char *_pcap_file[MAX_NUM_READER_THREADS]; /**< Ingress pcap file/interafaces */ +static FILE *playlist_fp[MAX_NUM_READER_THREADS] = { NULL }; /**< Ingress playlist */ +static char *_bpf_filter = NULL; /**< bpf filter */ +static char *_protoFilePath = NULL; /**< Protocol file path */ +#ifdef HAVE_JSON_C +static char *_jsonFilePath = NULL; /**< JSON file path */ +#endif +#ifdef HAVE_JSON_C +static json_object *jArray_known_flows, *jArray_unknown_flows; +#endif +static u_int8_t live_capture = 0, full_http_dissection = 0; +static u_int8_t undetected_flows_deleted = 0; +/** + * User preferences + */ +static u_int8_t enable_protocol_guess = 1, verbose = 0, nDPI_traceLevel = 0, json_flag = 0; +static u_int16_t decode_tunnels = 0; +static u_int16_t num_loops = 1; +static u_int8_t shutdown_app = 0; +static u_int8_t num_threads = 1; +static u_int32_t current_ndpi_memory = 0, max_ndpi_memory = 0; +#ifdef linux +static int core_affinity[MAX_NUM_READER_THREADS]; +#endif + +static struct timeval pcap_start, pcap_end; + +/** + * Detection parameters + */ +static u_int32_t detection_tick_resolution = 1000; +static time_t capture_for = 0; +static time_t capture_until = 0; + +#define IDLE_SCAN_PERIOD 10 /* msec (use detection_tick_resolution = 1000) */ +#define MAX_IDLE_TIME 30000 +#define IDLE_SCAN_BUDGET 1024 + +#define NUM_ROOTS 512 + +static u_int32_t num_flows; + +struct thread_stats { + u_int32_t guessed_flow_protocols; + u_int64_t raw_packet_count; + u_int64_t ip_packet_count; + u_int64_t total_wire_bytes, total_ip_bytes, total_discarded_bytes; + u_int64_t protocol_counter[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; + u_int64_t protocol_counter_bytes[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; + u_int32_t protocol_flows[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; + u_int32_t ndpi_flow_count; + u_int64_t tcp_count, udp_count; + u_int64_t mpls_count, pppoe_count, vlan_count, fragmented_count; + u_int64_t packet_len[6]; + u_int16_t max_packet_len; +}; + +struct reader_thread { + struct ndpi_detection_module_struct *ndpi_struct; + void *ndpi_flows_root[NUM_ROOTS]; + char _pcap_error_buffer[PCAP_ERRBUF_SIZE]; + pcap_t *_pcap_handle; + u_int64_t last_time; + u_int64_t last_idle_scan_time; + u_int32_t idle_scan_idx; + u_int32_t num_idle_flows; + pthread_t pthread; + int _pcap_datalink_type; + + /* TODO Add barrier */ + struct thread_stats stats; + + struct ndpi_flow *idle_flows[IDLE_SCAN_BUDGET]; +}; + +static struct reader_thread ndpi_thread_info[MAX_NUM_READER_THREADS]; + +#define GTP_U_V1_PORT 2152 +#define MAX_NDPI_FLOWS 200000000 +/** + * @brief ID tracking + */ +typedef struct ndpi_id { + u_int8_t ip[4]; //< Ip address + struct ndpi_id_struct *ndpi_id; //< nDpi worker structure +} ndpi_id_t; + +static u_int32_t size_id_struct = 0; //< ID tracking structure size + +#ifndef ETH_P_IP +#define ETH_P_IP 0x0800 +#endif + +// flow tracking +typedef struct ndpi_flow { + u_int32_t lower_ip; + u_int32_t upper_ip; + u_int16_t lower_port; + u_int16_t upper_port; + u_int8_t detection_completed, protocol; + u_int16_t vlan_id; + struct ndpi_flow_struct *ndpi_flow; + char lower_name[32], upper_name[32]; + + u_int64_t last_seen; + + u_int64_t bytes; + u_int32_t packets; + + // result only, not used for flow identification + u_int32_t detected_protocol; + + char host_server_name[256]; + + struct { + char client_certificate[48], server_certificate[48]; + } ssl; + + void *src_id, *dst_id; +} ndpi_flow_t; + + +static u_int32_t size_flow_struct = 0; + +static void help(u_int long_help) { + printf("ndpiReader -i [-f ][-s ]\n" + " [-p ][-l [-d][-h][-t][-v ]\n" + " [-n ] [-j ]\n\n" + "Usage:\n" + " -i | Specify a pcap file/playlist to read packets from or a device for live capture (comma-separated list)\n" + " -f | Specify a BPF filter for filtering selected traffic\n" + " -s | Maximum capture duration in seconds (live traffic capture only)\n" + " -p .protos | Specify a protocol file (eg. protos.txt)\n" + " -l | Number of detection loops (test only)\n" + " -n | Number of threads. Default: number of interfaces in -i. Ignored with pcap files.\n" + " -j | Specify a file to write the content of packets in .json format\n" +#ifdef linux + " -g | Thread affinity mask (one core id per thread)\n" +#endif + " -d | Disable protocol guess and use only DPI\n" + " -t | Dissect GTP tunnels\n" + " -h | This help\n" + " -v <1|2> | Verbose 'unknown protocol' packet print. 1=verbose, 2=very verbose\n"); + + if(long_help) { + printf("\n\nSupported protocols:\n"); + num_threads = 1; + setupDetection(0); + ndpi_dump_protocols(ndpi_thread_info[0].ndpi_struct); + } + + exit(!long_help); +} + +/* ***************************************************** */ + +static void parseOptions(int argc, char **argv) { + char *__pcap_file = NULL, *bind_mask = NULL; + int thread_id, opt; +#ifdef linux + u_int num_cores = sysconf( _SC_NPROCESSORS_ONLN ); +#endif + + while ((opt = getopt(argc, argv, "df:g:i:hp:l:s:tv:V:n:j:")) != EOF) { + switch (opt) { + case 'd': + enable_protocol_guess = 0; + break; + + case 'i': + _pcap_file[0] = optarg; + break; + + case 'f': + _bpf_filter = optarg; + break; + + case 'g': + bind_mask = optarg; + break; + + case 'l': + num_loops = atoi(optarg); + break; + + case 'n': + num_threads = atoi(optarg); + break; + + case 'p': + _protoFilePath = optarg; + break; + + case 's': + capture_for = atoi(optarg); + capture_until = capture_for + time(NULL); + break; + + case 't': + decode_tunnels = 1; + break; + + case 'v': + verbose = atoi(optarg); + break; + + case 'V': + printf("%d\n",atoi(optarg) ); + nDPI_traceLevel = atoi(optarg); + break; + + case 'h': + help(1); + break; + + case 'j': +#ifndef HAVE_JSON_C + printf("WARNING: this copy of ndpiReader has been compiled without JSON-C: json export disabled\n"); +#else + _jsonFilePath = optarg; + json_flag = 1; +#endif + break; + + default: + help(0); + break; + } + } + + // check parameters + if(_pcap_file[0] == NULL || strcmp(_pcap_file[0], "") == 0) { + help(0); + } + + if(strchr(_pcap_file[0], ',')) { /* multiple ingress interfaces */ + num_threads = 0; /* setting number of threads = number of interfaces */ + __pcap_file = strtok(_pcap_file[0], ","); + while (__pcap_file != NULL && num_threads < MAX_NUM_READER_THREADS) { + _pcap_file[num_threads++] = __pcap_file; + __pcap_file = strtok(NULL, ","); + } + } else { + if(num_threads > MAX_NUM_READER_THREADS) num_threads = MAX_NUM_READER_THREADS; + for(thread_id = 1; thread_id < num_threads; thread_id++) + _pcap_file[thread_id] = _pcap_file[0]; + } + +#ifdef linux + for(thread_id = 0; thread_id < num_threads; thread_id++) + core_affinity[thread_id] = -1; + + if(num_cores > 1 && bind_mask != NULL) { + char *core_id = strtok(bind_mask, ":"); + thread_id = 0; + while (core_id != NULL && thread_id < num_threads) { + core_affinity[thread_id++] = atoi(core_id) % num_cores; + core_id = strtok(NULL, ":"); + } + } +#endif +} + +/* ***************************************************** */ + +static void debug_printf(u_int32_t protocol, void *id_struct, + ndpi_log_level_t log_level, + const char *format, ...) { + va_list va_ap; +#ifndef WIN32 + struct tm result; +#endif + + if(log_level <= nDPI_traceLevel) { + char buf[8192], out_buf[8192]; + char theDate[32]; + const char *extra_msg = ""; + time_t theTime = time(NULL); + + va_start (va_ap, format); + + if(log_level == NDPI_LOG_ERROR) + extra_msg = "ERROR: "; + else if(log_level == NDPI_LOG_TRACE) + extra_msg = "TRACE: "; + else + extra_msg = "DEBUG: "; + + memset(buf, 0, sizeof(buf)); + strftime(theDate, 32, "%d/%b/%Y %H:%M:%S", localtime_r(&theTime,&result) ); + vsnprintf(buf, sizeof(buf)-1, format, va_ap); + + snprintf(out_buf, sizeof(out_buf), "%s %s%s", theDate, extra_msg, buf); + printf("%s", out_buf); + fflush(stdout); + } + + va_end(va_ap); +} + +/* ***************************************************** */ + +static void *malloc_wrapper(unsigned long size) { + current_ndpi_memory += size; + + if(current_ndpi_memory > max_ndpi_memory) + max_ndpi_memory = current_ndpi_memory; + + return malloc(size); +} + +/* ***************************************************** */ + +static void free_wrapper(void *freeable) { + free(freeable); +} + +/* ***************************************************** */ + +static char* ipProto2Name(u_short proto_id) { + static char proto[8]; + + switch(proto_id) { + case IPPROTO_TCP: + return("TCP"); + break; + case IPPROTO_UDP: + return("UDP"); + break; + case IPPROTO_ICMP: + return("ICMP"); + break; + case 112: + return("VRRP"); + break; + case IPPROTO_IGMP: + return("IGMP"); + break; + } + + snprintf(proto, sizeof(proto), "%u", proto_id); + return(proto); +} + +/* ***************************************************** */ + +/* + * A faster replacement for inet_ntoa(). + */ +char* intoaV4(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 void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) { +#ifdef HAVE_JSON_C + json_object *jObj; +#endif + + if(!json_flag) { +#if 0 + printf("\t%s [VLAN: %u] %s:%u <-> %s:%u\n", + ipProto2Name(flow->protocol), flow->vlan_id, + flow->lower_name, ntohs(flow->lower_port), + flow->upper_name, ntohs(flow->upper_port)); + +#else + printf("\t%u", ++num_flows); + + printf("\t%s %s:%u <-> %s:%u ", + ipProto2Name(flow->protocol), + flow->lower_name, ntohs(flow->lower_port), + flow->upper_name, ntohs(flow->upper_port)); + + if(flow->vlan_id > 0) printf("[VLAN: %u]", flow->vlan_id); + + printf("[proto: %u/%s][%u pkts/%llu bytes]", + flow->detected_protocol, + ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol), + flow->packets, (long long unsigned int)flow->bytes); + + if(flow->host_server_name[0] != '\0') printf("[Host: %s]", flow->host_server_name); + if(flow->ssl.client_certificate[0] != '\0') printf("[SSL client: %s]", flow->ssl.client_certificate); + if(flow->ssl.server_certificate[0] != '\0') printf("[SSL server: %s]", flow->ssl.server_certificate); + + printf("\n"); +#endif + } else { +#ifdef HAVE_JSON_C + jObj = json_object_new_object(); + + json_object_object_add(jObj,"protocol",json_object_new_string(ipProto2Name(flow->protocol))); + json_object_object_add(jObj,"host_a.name",json_object_new_string(flow->lower_name)); + json_object_object_add(jObj,"host_a.port",json_object_new_int(ntohs(flow->lower_port))); + json_object_object_add(jObj,"host_b.name",json_object_new_string(flow->upper_name)); + json_object_object_add(jObj,"host_n.port",json_object_new_int(ntohs(flow->upper_port))); + json_object_object_add(jObj,"detected.protocol",json_object_new_int(flow->detected_protocol)); + json_object_object_add(jObj,"detected.protocol.name",json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol))); + json_object_object_add(jObj,"packets",json_object_new_int(flow->packets)); + json_object_object_add(jObj,"bytes",json_object_new_int(flow->bytes)); + + if(flow->host_server_name[0] != '\0') + json_object_object_add(jObj,"host.server.name",json_object_new_string(flow->host_server_name)); + + if((flow->ssl.client_certificate[0] != '\0') || (flow->ssl.server_certificate[0] != '\0')) { + json_object *sjObj = json_object_new_object(); + + if(flow->ssl.client_certificate[0] != '\0') + json_object_object_add(sjObj, "client", json_object_new_string(flow->ssl.client_certificate)); + + if(flow->ssl.server_certificate[0] != '\0') + json_object_object_add(sjObj, "server", json_object_new_string(flow->ssl.server_certificate)); + + json_object_object_add(jObj, "ssl", sjObj); + } + + //flow->protos.ssl.client_certificate, flow->protos.ssl.server_certificate); + if(json_flag == 1) + json_object_array_add(jArray_known_flows,jObj); + else if(json_flag == 2) + json_object_array_add(jArray_unknown_flows,jObj); +#endif + } +} + +/* ***************************************************** */ + +static void free_ndpi_flow(struct ndpi_flow *flow) { + if(flow->ndpi_flow) { ndpi_free_flow(flow->ndpi_flow); flow->ndpi_flow = NULL; } + if(flow->src_id) { ndpi_free(flow->src_id); flow->src_id = NULL; } + if(flow->dst_id) { ndpi_free(flow->dst_id); flow->dst_id = NULL; } +} + +/* ***************************************************** */ + +static void ndpi_flow_freer(void *node) { + struct ndpi_flow *flow = (struct ndpi_flow*)node; + + free_ndpi_flow(flow); + ndpi_free(flow); +} + +/* ***************************************************** */ + +static void node_print_unknown_proto_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { + struct ndpi_flow *flow = *(struct ndpi_flow**)node; + u_int16_t thread_id = *((u_int16_t*)user_data); + + if(flow->detected_protocol != 0 /* UNKNOWN */) return; + + if((which == ndpi_preorder) || (which == ndpi_leaf)) /* Avoid walking the same node multiple times */ + printFlow(thread_id, flow); +} + +/* ***************************************************** */ + +static void node_print_known_proto_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { + struct ndpi_flow *flow = *(struct ndpi_flow**)node; + u_int16_t thread_id = *((u_int16_t*)user_data); + + if(flow->detected_protocol == 0 /* UNKNOWN */) return; + + if((which == ndpi_preorder) || (which == ndpi_leaf)) /* Avoid walking the same node multiple times */ + printFlow(thread_id, flow); +} + +/* ***************************************************** */ + +static unsigned int node_guess_undetected_protocol(u_int16_t thread_id, + struct ndpi_flow *flow) { + flow->detected_protocol = ndpi_guess_undetected_protocol(ndpi_thread_info[thread_id].ndpi_struct, + flow->protocol, + ntohl(flow->lower_ip), + ntohs(flow->lower_port), + ntohl(flow->upper_ip), + ntohs(flow->upper_port)); + // printf("Guess state: %u\n", flow->detected_protocol); + if(flow->detected_protocol != 0) + ndpi_thread_info[thread_id].stats.guessed_flow_protocols++; + + return flow->detected_protocol; +} + +/* ***************************************************** */ + +static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { + struct ndpi_flow *flow = *(struct ndpi_flow **) node; + u_int16_t thread_id = *((u_int16_t *) user_data); + +#if 0 + printf("<%d>Walk on node %s (%p)\n", + depth, + which == preorder?"preorder": + which == postorder?"postorder": + which == endorder?"endorder": + which == leaf?"leaf": "unknown", + flow); +#endif + + if((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */ + if(enable_protocol_guess) { + if(flow->detected_protocol == 0 /* UNKNOWN */) { + node_guess_undetected_protocol(thread_id, flow); + // printFlow(thread_id, flow); + } + } + + ndpi_thread_info[thread_id].stats.protocol_counter[flow->detected_protocol] += flow->packets; + ndpi_thread_info[thread_id].stats.protocol_counter_bytes[flow->detected_protocol] += flow->bytes; + ndpi_thread_info[thread_id].stats.protocol_flows[flow->detected_protocol]++; + } +} + +/* ***************************************************** */ + +static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { + struct ndpi_flow *flow = *(struct ndpi_flow **) node; + u_int16_t thread_id = *((u_int16_t *) user_data); + + if(ndpi_thread_info[thread_id].num_idle_flows == IDLE_SCAN_BUDGET) /* TODO optimise with a budget-based walk */ + return; + + if((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */ + if(flow->last_seen + MAX_IDLE_TIME < ndpi_thread_info[thread_id].last_time) { + + /* update stats */ + node_proto_guess_walker(node, which, depth, user_data); + + if (flow->detected_protocol == 0 /* UNKNOWN */ && !undetected_flows_deleted) + undetected_flows_deleted = 1; + + free_ndpi_flow(flow); + ndpi_thread_info[thread_id].stats.ndpi_flow_count--; + + /* adding to a queue (we can't delete it from the tree inline ) */ + ndpi_thread_info[thread_id].idle_flows[ndpi_thread_info[thread_id].num_idle_flows++] = flow; + } + } +} + +/* ***************************************************** */ + +static int node_cmp(const void *a, const void *b) { + struct ndpi_flow *fa = (struct ndpi_flow*)a; + struct ndpi_flow *fb = (struct ndpi_flow*)b; + + if(fa->vlan_id < fb->vlan_id ) return(-1); else { if(fa->vlan_id > fb->vlan_id ) return(1); } + if(fa->lower_ip < fb->lower_ip ) return(-1); else { if(fa->lower_ip > fb->lower_ip ) return(1); } + if(fa->lower_port < fb->lower_port) return(-1); else { if(fa->lower_port > fb->lower_port) return(1); } + if(fa->upper_ip < fb->upper_ip ) return(-1); else { if(fa->upper_ip > fb->upper_ip ) return(1); } + if(fa->upper_port < fb->upper_port) return(-1); else { if(fa->upper_port > fb->upper_port) return(1); } + if(fa->protocol < fb->protocol ) return(-1); else { if(fa->protocol > fb->protocol ) return(1); } + + return(0); +} + +/* ***************************************************** */ + +static struct ndpi_flow *get_ndpi_flow(u_int16_t thread_id, + const u_int8_t version, + u_int16_t vlan_id, + const struct ndpi_iphdr *iph, + u_int16_t ip_offset, + u_int16_t ipsize, + u_int16_t l4_packet_len, + struct ndpi_id_struct **src, + struct ndpi_id_struct **dst, + u_int8_t *proto, + const struct ndpi_ip6_hdr *iph6) { + u_int32_t idx, l4_offset; + struct ndpi_tcphdr *tcph = NULL; + struct ndpi_udphdr *udph = NULL; + u_int32_t lower_ip; + u_int32_t upper_ip; + u_int16_t lower_port; + u_int16_t upper_port; + struct ndpi_flow flow; + void *ret; + u_int8_t *l3; + + /* + Note: to keep things simple (ndpiReader is just a demo app) + we handle IPv6 a-la-IPv4. + */ + if(version == 4) { + if(ipsize < 20) + return NULL; + + if((iph->ihl * 4) > ipsize || ipsize < ntohs(iph->tot_len) + || (iph->frag_off & htons(0x1FFF)) != 0) + return NULL; + + l4_offset = iph->ihl * 4; + l3 = (u_int8_t*)iph; + } else { + l4_offset = sizeof(struct ndpi_ip6_hdr); + l3 = (u_int8_t*)iph6; + } + + if(l4_packet_len < 64) + ndpi_thread_info[thread_id].stats.packet_len[0]++; + else if(l4_packet_len >= 64 && l4_packet_len < 128) + ndpi_thread_info[thread_id].stats.packet_len[1]++; + else if(l4_packet_len >= 128 && l4_packet_len < 256) + ndpi_thread_info[thread_id].stats.packet_len[2]++; + else if(l4_packet_len >= 256 && l4_packet_len < 1024) + ndpi_thread_info[thread_id].stats.packet_len[3]++; + else if(l4_packet_len >= 1024 && l4_packet_len < 1500) + ndpi_thread_info[thread_id].stats.packet_len[4]++; + else if(l4_packet_len >= 1500) + ndpi_thread_info[thread_id].stats.packet_len[5]++; + + if(l4_packet_len > ndpi_thread_info[thread_id].stats.max_packet_len) + ndpi_thread_info[thread_id].stats.max_packet_len = l4_packet_len; + + if(iph->saddr < iph->daddr) { + lower_ip = iph->saddr; + upper_ip = iph->daddr; + } else { + lower_ip = iph->daddr; + upper_ip = iph->saddr; + } + + *proto = iph->protocol; + + if(iph->protocol == 6 && l4_packet_len >= 20) { + ndpi_thread_info[thread_id].stats.tcp_count++; + + // tcp + tcph = (struct ndpi_tcphdr *) ((u_int8_t *) l3 + l4_offset); + if(iph->saddr < iph->daddr) { + lower_port = tcph->source; + upper_port = tcph->dest; + } else { + lower_port = tcph->dest; + upper_port = tcph->source; + + if(iph->saddr == iph->daddr) { + if(lower_port > upper_port) { + u_int16_t p = lower_port; + + lower_port = upper_port; + upper_port = p; + } + } + } + } else if(iph->protocol == 17 && l4_packet_len >= 8) { + // udp + ndpi_thread_info[thread_id].stats.udp_count++; + + udph = (struct ndpi_udphdr *) ((u_int8_t *) l3 + l4_offset); + if(iph->saddr < iph->daddr) { + lower_port = udph->source; + upper_port = udph->dest; + } else { + lower_port = udph->dest; + upper_port = udph->source; + } + } else { + // non tcp/udp protocols + lower_port = 0; + upper_port = 0; + } + + flow.protocol = iph->protocol, flow.vlan_id = vlan_id; + flow.lower_ip = lower_ip, flow.upper_ip = upper_ip; + flow.lower_port = lower_port, flow.upper_port = upper_port; + + if(0) + printf("[NDPI] [%u][%u:%u <-> %u:%u]\n", + iph->protocol, lower_ip, ntohs(lower_port), upper_ip, ntohs(upper_port)); + + idx = (vlan_id + lower_ip + upper_ip + iph->protocol + lower_port + upper_port) % NUM_ROOTS; + ret = ndpi_tfind(&flow, &ndpi_thread_info[thread_id].ndpi_flows_root[idx], node_cmp); + + if(ret == NULL) { + if(ndpi_thread_info[thread_id].stats.ndpi_flow_count == MAX_NDPI_FLOWS) { + printf("ERROR: maximum flow count (%u) has been exceeded\n", MAX_NDPI_FLOWS); + exit(-1); + } else { + struct ndpi_flow *newflow = (struct ndpi_flow*)malloc(sizeof(struct ndpi_flow)); + + if(newflow == NULL) { + printf("[NDPI] %s(1): not enough memory\n", __FUNCTION__); + return(NULL); + } + + memset(newflow, 0, sizeof(struct ndpi_flow)); + newflow->protocol = iph->protocol, newflow->vlan_id = vlan_id; + newflow->lower_ip = lower_ip, newflow->upper_ip = upper_ip; + newflow->lower_port = lower_port, newflow->upper_port = upper_port; + + if(version == 4) { + inet_ntop(AF_INET, &lower_ip, newflow->lower_name, sizeof(newflow->lower_name)); + inet_ntop(AF_INET, &upper_ip, newflow->upper_name, sizeof(newflow->upper_name)); + } else { + inet_ntop(AF_INET6, &iph6->ip6_src, newflow->lower_name, sizeof(newflow->lower_name)); + inet_ntop(AF_INET6, &iph6->ip6_dst, newflow->upper_name, sizeof(newflow->upper_name)); + } + + if((newflow->ndpi_flow = malloc_wrapper(size_flow_struct)) == NULL) { + printf("[NDPI] %s(2): not enough memory\n", __FUNCTION__); + return(NULL); + } else + memset(newflow->ndpi_flow, 0, size_flow_struct); + + if((newflow->src_id = malloc_wrapper(size_id_struct)) == NULL) { + printf("[NDPI] %s(3): not enough memory\n", __FUNCTION__); + return(NULL); + } else + memset(newflow->src_id, 0, size_id_struct); + + if((newflow->dst_id = malloc_wrapper(size_id_struct)) == NULL) { + printf("[NDPI] %s(4): not enough memory\n", __FUNCTION__); + return(NULL); + } else + memset(newflow->dst_id, 0, size_id_struct); + + ndpi_tsearch(newflow, &ndpi_thread_info[thread_id].ndpi_flows_root[idx], node_cmp); /* Add */ + ndpi_thread_info[thread_id].stats.ndpi_flow_count++; + + *src = newflow->src_id, *dst = newflow->dst_id; + + // printFlow(thread_id, newflow); + + return(newflow); + } + } else { + struct ndpi_flow *flow = *(struct ndpi_flow**)ret; + + if(flow->lower_ip == lower_ip && flow->upper_ip == upper_ip + && flow->lower_port == lower_port && flow->upper_port == upper_port) + *src = flow->src_id, *dst = flow->dst_id; + else + *src = flow->dst_id, *dst = flow->src_id; + + return flow; + } +} + +/* ***************************************************** */ + +static struct ndpi_flow *get_ndpi_flow6(u_int16_t thread_id, + u_int16_t vlan_id, + const struct ndpi_ip6_hdr *iph6, + u_int16_t ip_offset, + struct ndpi_id_struct **src, + struct ndpi_id_struct **dst, + u_int8_t *proto) { + struct ndpi_iphdr iph; + + memset(&iph, 0, sizeof(iph)); + iph.version = 4; + iph.saddr = iph6->ip6_src.__u6_addr.__u6_addr32[2] + iph6->ip6_src.__u6_addr.__u6_addr32[3]; + iph.daddr = iph6->ip6_dst.__u6_addr.__u6_addr32[2] + iph6->ip6_dst.__u6_addr.__u6_addr32[3]; + iph.protocol = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; + + if(iph.protocol == 0x3C /* IPv6 destination option */) { + u_int8_t *options = (u_int8_t*)iph6 + sizeof(const struct ndpi_ip6_hdr); + + iph.protocol = options[0]; + } + + return(get_ndpi_flow(thread_id, 6, vlan_id, &iph, ip_offset, + sizeof(struct ndpi_ip6_hdr), + ntohs(iph6->ip6_ctlun.ip6_un1.ip6_un1_plen), + src, dst, proto, iph6)); +} + +/* ***************************************************** */ + +static void setupDetection(u_int16_t thread_id) { + NDPI_PROTOCOL_BITMASK all; + + memset(&ndpi_thread_info[thread_id], 0, sizeof(ndpi_thread_info[thread_id])); + + // init global detection structure + ndpi_thread_info[thread_id].ndpi_struct = ndpi_init_detection_module(detection_tick_resolution, + malloc_wrapper, free_wrapper, debug_printf); + if(ndpi_thread_info[thread_id].ndpi_struct == NULL) { + printf("ERROR: global structure initialization failed\n"); + exit(-1); + } + + if(full_http_dissection) + ndpi_thread_info[thread_id].ndpi_struct->http_dissect_response = 1; + + // enable all protocols + NDPI_BITMASK_SET_ALL(all); + ndpi_set_protocol_detection_bitmask2(ndpi_thread_info[thread_id].ndpi_struct, &all); + + // allocate memory for id and flow tracking + size_id_struct = ndpi_detection_get_sizeof_ndpi_id_struct(); + size_flow_struct = ndpi_detection_get_sizeof_ndpi_flow_struct(); + + // clear memory for results + memset(ndpi_thread_info[thread_id].stats.protocol_counter, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_counter)); + memset(ndpi_thread_info[thread_id].stats.protocol_counter_bytes, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_counter_bytes)); + memset(ndpi_thread_info[thread_id].stats.protocol_flows, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_flows)); + + if(_protoFilePath != NULL) + ndpi_load_protocols_file(ndpi_thread_info[thread_id].ndpi_struct, _protoFilePath); +} + +/* ***************************************************** */ + +static void terminateDetection(u_int16_t thread_id) { + int i; + + for(i=0; ilen - ip_offset ; rawsize = header->len +static unsigned int packet_processing(u_int16_t thread_id, + const u_int64_t time, + u_int16_t vlan_id, + const struct ndpi_iphdr *iph, + struct ndpi_ip6_hdr *iph6, + u_int16_t ip_offset, + u_int16_t ipsize, u_int16_t rawsize) { + struct ndpi_id_struct *src, *dst; + struct ndpi_flow *flow; + struct ndpi_flow_struct *ndpi_flow = NULL; + u_int32_t protocol = 0; + u_int8_t proto; + + if(iph) + flow = get_ndpi_flow(thread_id, 4, vlan_id, iph, ip_offset, ipsize, + ntohs(iph->tot_len) - (iph->ihl * 4), + &src, &dst, &proto, NULL); + else + flow = get_ndpi_flow6(thread_id, vlan_id, iph6, ip_offset, &src, &dst, &proto); + + if(flow != NULL) { + ndpi_thread_info[thread_id].stats.ip_packet_count++; + ndpi_thread_info[thread_id].stats.total_wire_bytes += rawsize + 24 /* CRC etc */, ndpi_thread_info[thread_id].stats.total_ip_bytes += rawsize; + ndpi_flow = flow->ndpi_flow; + flow->packets++, flow->bytes += rawsize; + flow->last_seen = time; + } else { + return(0); + } + + if(flow->detection_completed) return(0); + + protocol = (const u_int32_t)ndpi_detection_process_packet(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow, + iph ? (uint8_t *)iph : (uint8_t *)iph6, + ipsize, time, src, dst); + + flow->detected_protocol = protocol; + + if((flow->detected_protocol != NDPI_PROTOCOL_UNKNOWN) + || ((proto == IPPROTO_UDP) && (flow->packets > 8)) + || ((proto == IPPROTO_TCP) && (flow->packets > 10))) { + flow->detection_completed = 1; + + snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name); + + if((proto == IPPROTO_TCP) && (flow->detected_protocol != NDPI_PROTOCOL_DNS)) { + snprintf(flow->ssl.client_certificate, sizeof(flow->ssl.client_certificate), "%s", flow->ndpi_flow->protos.ssl.client_certificate); + snprintf(flow->ssl.server_certificate, sizeof(flow->ssl.server_certificate), "%s", flow->ndpi_flow->protos.ssl.server_certificate); + } + + if(( + (flow->detected_protocol == NDPI_PROTOCOL_HTTP) + || (flow->detected_protocol == NDPI_SERVICE_FACEBOOK) + ) + && full_http_dissection) { + char *method; + + printf("[URL] %s\n", ndpi_get_http_url(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow)); + printf("[Content-Type] %s\n", ndpi_get_http_content_type(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow)); + + switch(ndpi_get_http_method(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow)) { + case HTTP_METHOD_OPTIONS: method = "HTTP_METHOD_OPTIONS"; break; + case HTTP_METHOD_GET: method = "HTTP_METHOD_GET"; break; + case HTTP_METHOD_HEAD: method = "HTTP_METHOD_HEAD"; break; + case HTTP_METHOD_POST: method = "HTTP_METHOD_POST"; break; + case HTTP_METHOD_PUT: method = "HTTP_METHOD_PUT"; break; + case HTTP_METHOD_DELETE: method = "HTTP_METHOD_DELETE"; break; + case HTTP_METHOD_TRACE: method = "HTTP_METHOD_TRACE"; break; + case HTTP_METHOD_CONNECT: method = "HTTP_METHOD_CONNECT"; break; + default: method = "HTTP_METHOD_UNKNOWN"; break; + } + + printf("[Method] %s\n", method); + } + + free_ndpi_flow(flow); + + if(verbose > 1) { + if(enable_protocol_guess) { + if(flow->detected_protocol == 0 /* UNKNOWN */) { + protocol = node_guess_undetected_protocol(thread_id, flow); + } + } + + printFlow(thread_id, flow); + } + } + +#if 0 + if(ndpi_flow->l4.tcp.host_server_name[0] != '\0') + printf("%s\n", ndpi_flow->l4.tcp.host_server_name); +#endif + + if(live_capture) { + if(ndpi_thread_info[thread_id].last_idle_scan_time + IDLE_SCAN_PERIOD < ndpi_thread_info[thread_id].last_time) { + /* scan for idle flows */ + ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[ndpi_thread_info[thread_id].idle_scan_idx], node_idle_scan_walker, &thread_id); + + /* remove idle flows (unfortunately we cannot do this inline) */ + while (ndpi_thread_info[thread_id].num_idle_flows > 0) + ndpi_tdelete(ndpi_thread_info[thread_id].idle_flows[--ndpi_thread_info[thread_id].num_idle_flows], + &ndpi_thread_info[thread_id].ndpi_flows_root[ndpi_thread_info[thread_id].idle_scan_idx], node_cmp); + + if(++ndpi_thread_info[thread_id].idle_scan_idx == NUM_ROOTS) ndpi_thread_info[thread_id].idle_scan_idx = 0; + ndpi_thread_info[thread_id].last_idle_scan_time = ndpi_thread_info[thread_id].last_time; + } + } + + return 0; +} + +/* ****************************************************** */ + +char* formatTraffic(float numBits, int bits, char *buf) { + char unit; + + if(bits) + unit = 'b'; + else + unit = 'B'; + + if(numBits < 1024) { + snprintf(buf, 32, "%lu %c", (unsigned long)numBits, unit); + } else if(numBits < 1048576) { + snprintf(buf, 32, "%.2f K%c", (float)(numBits)/1024, unit); + } else { + float tmpMBits = ((float)numBits)/1048576; + + if(tmpMBits < 1024) { + snprintf(buf, 32, "%.2f M%c", tmpMBits, unit); + } else { + tmpMBits /= 1024; + + if(tmpMBits < 1024) { + snprintf(buf, 32, "%.2f G%c", tmpMBits, unit); + } else { + snprintf(buf, 32, "%.2f T%c", (float)(tmpMBits)/1024, unit); + } + } + } + + return(buf); +} + +/* ***************************************************** */ + +char* formatPackets(float numPkts, char *buf) { + if(numPkts < 1000) { + snprintf(buf, 32, "%.2f", numPkts); + } else if(numPkts < 1000000) { + snprintf(buf, 32, "%.2f K", numPkts/1000); + } else { + numPkts /= 1000000; + snprintf(buf, 32, "%.2f M", numPkts); + } + + return(buf); +} + +/* ***************************************************** */ + +#ifdef HAVE_JSON_C +static void json_init() { + jArray_known_flows = json_object_new_array(); + jArray_unknown_flows = json_object_new_array(); +} +#endif + +/* ***************************************************** */ + +char* formatBytes(u_int32_t howMuch, char *buf, u_int buf_len) { + char unit = 'B'; + + if(howMuch < 1024) { + snprintf(buf, buf_len, "%lu %c", (unsigned long)howMuch, unit); + } else if(howMuch < 1048576) { + snprintf(buf, buf_len, "%.2f K%c", (float)(howMuch)/1024, unit); + } else { + float tmpGB = ((float)howMuch)/1048576; + + if(tmpGB < 1024) { + snprintf(buf, buf_len, "%.2f M%c", tmpGB, unit); + } else { + tmpGB /= 1024; + + snprintf(buf, buf_len, "%.2f G%c", tmpGB, unit); + } + } + + return(buf); +} + +/* ***************************************************** */ + +static void printResults(u_int64_t tot_usec) { + u_int32_t i; + u_int64_t total_flow_bytes = 0; + u_int avg_pkt_size = 0; + struct thread_stats cumulative_stats; + int thread_id; + char buf[32]; +#ifdef HAVE_JSON_C + FILE *json_fp; + json_object *jObj_main, *jObj_trafficStats, *jArray_detProto, *jObj; +#endif + long long unsigned int breed_stats[NUM_BREEDS] = { 0 }; + + memset(&cumulative_stats, 0, sizeof(cumulative_stats)); + + for(thread_id = 0; thread_id < num_threads; thread_id++) { + if(ndpi_thread_info[thread_id].stats.total_wire_bytes == 0) continue; + + for(i=0; i 1500: %-13lu\n", (unsigned long)cumulative_stats.packet_len[5]); + + if(tot_usec > 0) { + char buf[32], buf1[32]; + float t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)tot_usec; + float b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)tot_usec; + float traffic_duration; + if (live_capture) traffic_duration = tot_usec; + else traffic_duration = (pcap_end.tv_sec*1000000 + pcap_end.tv_usec) - (pcap_start.tv_sec*1000000 + pcap_start.tv_usec); + printf("\tnDPI throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); + t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)traffic_duration; + b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)traffic_duration; + printf("\tTraffic throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); + printf("\tTraffic duration: %.3f sec\n", traffic_duration/1000000); + } + + if(enable_protocol_guess) + printf("\tGuessed flow protos: %-13u\n", cumulative_stats.guessed_flow_protocols); + } else { +#ifdef HAVE_JSON_C + if((json_fp = fopen(_jsonFilePath,"w")) == NULL) { + printf("Error create .json file\n"); + json_flag = 0; + } else { + jObj_main = json_object_new_object(); + jObj_trafficStats = json_object_new_object(); + jArray_detProto = json_object_new_array(); + + json_object_object_add(jObj_trafficStats,"ethernet.bytes",json_object_new_int64(cumulative_stats.total_wire_bytes)); + json_object_object_add(jObj_trafficStats,"discarded.bytes",json_object_new_int64(cumulative_stats.total_discarded_bytes)); + json_object_object_add(jObj_trafficStats,"ip.packets",json_object_new_int64(cumulative_stats.ip_packet_count)); + json_object_object_add(jObj_trafficStats,"total.packets",json_object_new_int64(cumulative_stats.raw_packet_count)); + json_object_object_add(jObj_trafficStats,"ip.bytes",json_object_new_int64(cumulative_stats.total_ip_bytes)); + json_object_object_add(jObj_trafficStats,"avg.pkt.size",json_object_new_int(cumulative_stats.total_ip_bytes/cumulative_stats.raw_packet_count)); + json_object_object_add(jObj_trafficStats,"unique.flows",json_object_new_int(cumulative_stats.ndpi_flow_count)); + json_object_object_add(jObj_trafficStats,"tcp.pkts",json_object_new_int64(cumulative_stats.tcp_count)); + json_object_object_add(jObj_trafficStats,"udp.pkts",json_object_new_int64(cumulative_stats.udp_count)); + json_object_object_add(jObj_trafficStats,"vlan.pkts",json_object_new_int64(cumulative_stats.vlan_count)); + json_object_object_add(jObj_trafficStats,"mpls.pkts",json_object_new_int64(cumulative_stats.mpls_count)); + json_object_object_add(jObj_trafficStats,"pppoe.pkts",json_object_new_int64(cumulative_stats.pppoe_count)); + json_object_object_add(jObj_trafficStats,"fragmented.pkts",json_object_new_int64(cumulative_stats.fragmented_count)); + json_object_object_add(jObj_trafficStats,"max.pkt.size",json_object_new_int(cumulative_stats.max_packet_len)); + json_object_object_add(jObj_trafficStats,"pkt.len_min64",json_object_new_int64(cumulative_stats.packet_len[0])); + json_object_object_add(jObj_trafficStats,"pkt.len_64_128",json_object_new_int64(cumulative_stats.packet_len[1])); + json_object_object_add(jObj_trafficStats,"pkt.len_128_256",json_object_new_int64(cumulative_stats.packet_len[2])); + json_object_object_add(jObj_trafficStats,"pkt.len_256_1024",json_object_new_int64(cumulative_stats.packet_len[3])); + json_object_object_add(jObj_trafficStats,"pkt.len_1024_1500",json_object_new_int64(cumulative_stats.packet_len[4])); + json_object_object_add(jObj_trafficStats,"pkt.len_grt1500",json_object_new_int64(cumulative_stats.packet_len[5])); + json_object_object_add(jObj_trafficStats,"guessed.flow.protos",json_object_new_int(cumulative_stats.guessed_flow_protocols)); + + json_object_object_add(jObj_main,"traffic.statistics",jObj_trafficStats); + } +#endif + } + + if(!json_flag) printf("\n\nDetected protocols:\n"); + for(i = 0; i <= ndpi_get_num_supported_protocols(ndpi_thread_info[0].ndpi_struct); i++) { + ndpi_protocol_breed_t breed = ndpi_get_proto_breed(ndpi_thread_info[0].ndpi_struct, i); + + if(cumulative_stats.protocol_counter[i] > 0) { + breed_stats[breed] += (long long unsigned int)cumulative_stats.protocol_counter_bytes[i]; + + if(!json_flag) { + printf("\t%-20s packets: %-13llu bytes: %-13llu " + "flows: %-13u\n", + ndpi_get_proto_name(ndpi_thread_info[0].ndpi_struct, i), + (long long unsigned int)cumulative_stats.protocol_counter[i], + (long long unsigned int)cumulative_stats.protocol_counter_bytes[i], + cumulative_stats.protocol_flows[i]); + } else { +#ifdef HAVE_JSON_C + jObj = json_object_new_object(); + + json_object_object_add(jObj,"name",json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[0].ndpi_struct, i))); + json_object_object_add(jObj,"breed",json_object_new_string(ndpi_get_proto_breed_name(ndpi_thread_info[0].ndpi_struct, breed))); + json_object_object_add(jObj,"packets",json_object_new_int64(cumulative_stats.protocol_counter[i])); + json_object_object_add(jObj,"bytes",json_object_new_int64(cumulative_stats.protocol_counter_bytes[i])); + json_object_object_add(jObj,"flows",json_object_new_int(cumulative_stats.protocol_flows[i])); + + json_object_array_add(jArray_detProto,jObj); +#endif + } + + total_flow_bytes += cumulative_stats.protocol_counter_bytes[i]; + } + } + + if(!json_flag) { + printf("\n\nProtocol statistics:\n"); + + for(i=0; i < NUM_BREEDS; i++) { + if(breed_stats[i] > 0) { + printf("\t%-20s %13llu bytes\n", + ndpi_get_proto_breed_name(ndpi_thread_info[0].ndpi_struct, i), + breed_stats[i]); + } + } + } + + // printf("\n\nTotal Flow Traffic: %llu (diff: %llu)\n", total_flow_bytes, cumulative_stats.total_ip_bytes-total_flow_bytes); + + if(verbose) { + if(!json_flag) printf("\n"); + + num_flows = 0; + for(thread_id = 0; thread_id < num_threads; thread_id++) { + for(i=0; i 0) { + if(!json_flag) { + printf("\n\nUndetected flows:%s\n", undetected_flows_deleted ? " (expired flows are not listed below)" : ""); + } + + if(json_flag) + json_flag = 2; + break; + } + } + + num_flows = 0; + for(thread_id = 0; thread_id < num_threads; thread_id++) { + if(ndpi_thread_info[thread_id].stats.protocol_counter[0] > 0) { + for(i=0; i 0) { + if(!json_flag) printf("Capturing traffic up to %u seconds\n", (unsigned int)capture_for); + +#ifndef WIN32 + alarm(capture_for); + signal(SIGALRM, sigproc); +#endif + } +} + +/* ***************************************************** */ + +static void pcap_packet_callback(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { + const struct ndpi_ethhdr *ethernet; + struct ndpi_iphdr *iph; + struct ndpi_ip6_hdr *iph6; + u_int64_t time; + u_int16_t type, ip_offset, ip_len; + u_int16_t frag_off = 0, vlan_id = 0; + u_int8_t proto = 0, vlan_packet = 0; + u_int16_t thread_id = *((u_int16_t*)args); + + // printf("[ndpiReader] pcap_packet_callback : [%u.%u.%u.%u.%u -> %u.%u.%u.%u.%u]\n", ethernet->h_dest[1],ethernet->h_dest[2],ethernet->h_dest[3],ethernet->h_dest[4],ethernet->h_dest[5],ethernet->h_source[1],ethernet->h_source[2],ethernet->h_source[3],ethernet->h_source[4],ethernet->h_source[5]); + ndpi_thread_info[thread_id].stats.raw_packet_count++; + + if((capture_until != 0) && (header->ts.tv_sec >= capture_until)) { + if(ndpi_thread_info[thread_id]._pcap_handle != NULL) + pcap_breakloop(ndpi_thread_info[thread_id]._pcap_handle); + + return; + } + + if (!live_capture) { + if (!pcap_start.tv_sec) pcap_start.tv_sec = header->ts.tv_sec, pcap_start.tv_usec = header->ts.tv_usec; + pcap_end.tv_sec = header->ts.tv_sec, pcap_end.tv_usec = header->ts.tv_usec; + } + + time = ((uint64_t) header->ts.tv_sec) * detection_tick_resolution + + header->ts.tv_usec / (1000000 / detection_tick_resolution); + + if(ndpi_thread_info[thread_id].last_time > time) { /* safety check */ + // printf("\nWARNING: timestamp bug in the pcap file (ts delta: %llu, repairing)\n", ndpi_thread_info[thread_id].last_time - time); + time = ndpi_thread_info[thread_id].last_time; + } + ndpi_thread_info[thread_id].last_time = time; + + if(ndpi_thread_info[thread_id]._pcap_datalink_type == DLT_NULL) { + if(ntohl(*((u_int32_t*)packet)) == 2) + type = ETH_P_IP; + else + type = 0x86DD; /* IPv6 */ + + ip_offset = 4; + } else if(ndpi_thread_info[thread_id]._pcap_datalink_type == DLT_EN10MB) { + ethernet = (struct ndpi_ethhdr *) packet; + ip_offset = sizeof(struct ndpi_ethhdr); + type = ntohs(ethernet->h_proto); + } else if(ndpi_thread_info[thread_id]._pcap_datalink_type == 113 /* Linux Cooked Capture */) { + type = (packet[14] << 8) + packet[15]; + ip_offset = 16; + } else + return; + + while(1) { + if(type == 0x8100 /* VLAN */) { + vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF; + type = (packet[ip_offset+2] << 8) + packet[ip_offset+3]; + ip_offset += 4; + vlan_packet = 1; + } else if(type == 0x8847 /* MPLS */) { + u_int32_t label = ntohl(*((u_int32_t*)&packet[ip_offset])); + + ndpi_thread_info[thread_id].stats.mpls_count++; + type = 0x800, ip_offset += 4; + + while((label & 0x100) != 0x100) { + ip_offset += 4; + label = ntohl(*((u_int32_t*)&packet[ip_offset])); + } + } else if(type == 0x8864 /* PPPoE */) { + ndpi_thread_info[thread_id].stats.pppoe_count++; + type = 0x0800; + ip_offset += 8; + } else + break; + } + + ndpi_thread_info[thread_id].stats.vlan_count += vlan_packet; + + iph = (struct ndpi_iphdr *) &packet[ip_offset]; + + // just work on Ethernet packets that contain IP + if(type == ETH_P_IP && header->caplen >= ip_offset) { + frag_off = ntohs(iph->frag_off); + + proto = iph->protocol; + if(header->caplen < header->len) { + static u_int8_t cap_warning_used = 0; + + if(cap_warning_used == 0) { + if(!json_flag) printf("\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n"); + cap_warning_used = 1; + } + } + } + + if(iph->version == 4) { + ip_len = ((u_short)iph->ihl * 4); + iph6 = NULL; + + if((frag_off & 0x3FFF) != 0) { + static u_int8_t ipv4_frags_warning_used = 0; + + ndpi_thread_info[thread_id].stats.fragmented_count++; + if(ipv4_frags_warning_used == 0) { + if(!json_flag) printf("\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n"); + ipv4_frags_warning_used = 1; + } + + ndpi_thread_info[thread_id].stats.total_discarded_bytes += header->len; + return; + } + } else if(iph->version == 6) { + iph6 = (struct ndpi_ip6_hdr *)&packet[ip_offset]; + proto = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; + ip_len = sizeof(struct ndpi_ip6_hdr); + + if(proto == 0x3C /* IPv6 destination option */) { + u_int8_t *options = (u_int8_t*)&packet[ip_offset+ip_len]; + + proto = options[0]; + ip_len += 8 * (options[1] + 1); + } + + iph = NULL; + } else { + static u_int8_t ipv4_warning_used = 0; + + v4_warning: + if(ipv4_warning_used == 0) { + if(!json_flag) printf("\n\nWARNING: only IPv4/IPv6 packets are supported in this demo (nDPI supports both IPv4 and IPv6), all other packets will be discarded\n\n"); + ipv4_warning_used = 1; + } + + ndpi_thread_info[thread_id].stats.total_discarded_bytes += header->len; + return; + } + + if(decode_tunnels && (proto == IPPROTO_UDP)) { + struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len]; + u_int16_t sport = ntohs(udp->source), dport = ntohs(udp->dest); + + if((sport == GTP_U_V1_PORT) || (dport == GTP_U_V1_PORT)) { + /* Check if it's GTPv1 */ + u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr); + u_int8_t flags = packet[offset]; + u_int8_t message_type = packet[offset+1]; + + if((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) && (message_type == 0xFF /* T-PDU */)) { + ip_offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr)+8 /* GTPv1 header len */; + + if(flags & 0x04) ip_offset += 1; /* next_ext_header is present */ + if(flags & 0x02) ip_offset += 4; /* sequence_number is present (it also includes next_ext_header and pdu_number) */ + if(flags & 0x01) ip_offset += 1; /* pdu_number is present */ + + iph = (struct ndpi_iphdr *) &packet[ip_offset]; + + if(iph->version != 4) { + // printf("WARNING: not good (packet_id=%u)!\n", (unsigned int)ndpi_thread_info[thread_id].stats.raw_packet_count); + goto v4_warning; + } + } + } + } + + // process the packet + packet_processing(thread_id, time, vlan_id, iph, iph6, + ip_offset, header->len - ip_offset, header->len); +} + +/* ******************************************************************** */ + +static void runPcapLoop(u_int16_t thread_id) { + if((!shutdown_app) && (ndpi_thread_info[thread_id]._pcap_handle != NULL)) + pcap_loop(ndpi_thread_info[thread_id]._pcap_handle, -1, &pcap_packet_callback, (u_char*)&thread_id); +} + +/* ******************************************************************** */ + +void *processing_thread(void *_thread_id) { + long thread_id = (long) _thread_id; + +#ifdef linux + if(core_affinity[thread_id] >= 0) { + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(core_affinity[thread_id], &cpuset); + + if(pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset) != 0) + fprintf(stderr, "Error while binding thread %ld to core %d\n", thread_id, core_affinity[thread_id]); + else { + if(!json_flag) printf("Running thread %ld on core %d...\n", thread_id, core_affinity[thread_id]); + } + } else +#endif + if(!json_flag) printf("Running thread %ld...\n", thread_id); + + pcap_loop: + runPcapLoop(thread_id); + + if(playlist_fp[thread_id] != NULL) { /* playlist: read next file */ + char filename[256]; + + if(getNextPcapFileFromPlaylist(thread_id, filename, sizeof(filename)) == 0 && + (ndpi_thread_info[thread_id]._pcap_handle = pcap_open_offline(filename, ndpi_thread_info[thread_id]._pcap_error_buffer)) != NULL) { + configurePcapHandle(thread_id); + goto pcap_loop; + } + } + + return NULL; +} + +/* ******************************************************************** */ + +void test_lib() { + struct timeval begin, end; + u_int64_t tot_usec; + long thread_id; + +#ifdef HAVE_JSON_C + json_init(); +#endif + + for(thread_id = 0; thread_id < num_threads; thread_id++) { + setupDetection(thread_id); + openPcapFileOrDevice(thread_id); + } + + gettimeofday(&begin, NULL); + + /* Running processing threads */ + for(thread_id = 0; thread_id < num_threads; thread_id++) + pthread_create(&ndpi_thread_info[thread_id].pthread, NULL, processing_thread, (void *) thread_id); + + /* Waiting for completion */ + for(thread_id = 0; thread_id < num_threads; thread_id++) + pthread_join(ndpi_thread_info[thread_id].pthread, NULL); + + gettimeofday(&end, NULL); + tot_usec = end.tv_sec*1000000 + end.tv_usec - (begin.tv_sec*1000000 + begin.tv_usec); + + /* Printing cumulative results */ + printResults(tot_usec); + + for(thread_id = 0; thread_id < num_threads; thread_id++) { + closePcapFile(thread_id); + terminateDetection(thread_id); + } +} + +/* ***************************************************** */ + +int main(int argc, char **argv) { + int i; + + memset(ndpi_thread_info, 0, sizeof(ndpi_thread_info)); + memset(&pcap_start, 0, sizeof(pcap_start)); + memset(&pcap_end, 0, sizeof(pcap_end)); + + parseOptions(argc, argv); + + if(!json_flag) { + printf("\n-----------------------------------------------------------\n" + "* NOTE: This is demo app to show *some* nDPI features.\n" + "* In this demo we have implemented only some basic features\n" + "* just to show you what you can do with the library. Feel \n" + "* free to extend it and send us the patches for inclusion\n" + "------------------------------------------------------------\n\n"); + + printf("Using nDPI (%s) [%d thread(s)]\n", ndpi_revision(), num_threads); + } + + signal(SIGINT, sigproc); + + for(i=0; itv_sec = time(NULL); + tv->tv_usec = 0; + return(0); +} +#endif + +/* ***************************************************** */ + +int gettimeofday(struct timeval *tv, struct timezone *tz) { + FILETIME ft; + LARGE_INTEGER li; + __int64 t; + static int tzflag; + + if(tv) { + GetSystemTimeAsFileTime(&ft); + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + t = li.QuadPart; /* In 100-nanosecond intervals */ + t -= EPOCHFILETIME; /* Offset to the Epoch time */ + t /= 10; /* In microseconds */ + tv->tv_sec = (long)(t / 1000000); + tv->tv_usec = (long)(t % 1000000); + } + + if(tz) { + if(!tzflag) { + _tzset(); + tzflag++; + } + + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } + + return 0; +} +#endif /* WIN32 */ diff --git a/example/protos.txt b/example/protos.txt new file mode 100644 index 000000000..722399da9 --- /dev/null +++ b/example/protos.txt @@ -0,0 +1,18 @@ +# Format: +# :,:,.....@ + +tcp:81,tcp:8181@HTTP +udp:5061-5062@SIP +tcp:860,udp:860,tcp:3260,udp:3260@iSCSI +tcp:3000@ntop + +# Subprotocols +# Format: +# host:"",host:"",.....@ + +host:"googlesyndacation.com"@Google +host:"venere.com"@Venere +host:"kataweb.it",host:"repubblica.it"@Repubblica + + + diff --git a/lib b/lib new file mode 120000 index 000000000..d049b7c46 --- /dev/null +++ b/lib @@ -0,0 +1 @@ +src/lib/.libs \ No newline at end of file diff --git a/libndpi.pc.in b/libndpi.pc.in new file mode 100644 index 000000000..291429cc7 --- /dev/null +++ b/libndpi.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libndpi +Description: deep packet inspection library +Version: @VERSION@ +Libs: -L${libdir} -lndpi +Cflags: -I${includedir}/libndpi-@VERSION@ diff --git a/libndpi.sym b/libndpi.sym new file mode 100644 index 000000000..52307a2f4 --- /dev/null +++ b/libndpi.sym @@ -0,0 +1,27 @@ +ndpi_dump_protocols +ndpi_get_proto_name +ndpi_free +ndpi_guess_undetected_protocol +ndpi_tfind +ndpi_tsearch +ndpi_set_protocol_detection_bitmask2 +ndpi_detection_get_sizeof_ndpi_id_struct +ndpi_detection_get_sizeof_ndpi_flow_struct +ndpi_load_protocols_file +ndpi_tdestroy +ndpi_exit_detection_module +ndpi_detection_process_packet +ndpi_twalk +ndpi_tdelete +ndpi_revision +ndpi_init_detection_module +ndpi_get_num_supported_protocols +ndpi_set_proto_defaults +ndpi_get_protocol_id +ndpi_find_port_based_protocol +ndpi_get_http_method +ndpi_get_http_url +ndpi_get_http_content_type +ndpi_free_flow +ndpi_get_proto_breed +ndpi_get_proto_breed_name diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4 new file mode 100644 index 000000000..d383ad5c6 --- /dev/null +++ b/m4/ax_pthread.m4 @@ -0,0 +1,332 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program 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 General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 21 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case ${host_os} in + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +# Clang doesn't consider unrecognized options an error unless we specify +# -Werror. We throw in some extra Clang-specific options to ensure that +# this doesn't happen for GCC, which also accepts -Werror. + +AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags]) +save_CFLAGS="$CFLAGS" +ax_pthread_extra_flags="-Werror" +CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])], + [AC_MSG_RESULT([yes])], + [ax_pthread_extra_flags= + AC_MSG_RESULT([no])]) +CFLAGS="$save_CFLAGS" + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $attr; return attr /* ; */])], + [attr_name=$attr; break], + []) + done + AC_MSG_RESULT([$attr_name]) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case ${host_os} in + aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; + osf* | hpux*) flag="-D_REENTRANT";; + solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + # TODO: What about Clang on Solaris? + flag="-mt -D_REENTRANT" + fi + ;; + esac + AC_MSG_RESULT([$flag]) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != xyes; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AC_SUBST([PTHREAD_CC]) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/ndpi-netfilter/README b/ndpi-netfilter/README new file mode 100644 index 000000000..8cd573d61 --- /dev/null +++ b/ndpi-netfilter/README @@ -0,0 +1,4 @@ +This package is a GPL implementation of an iptables and netfilter module for +nDPI integration into the Linux kernel. + +https://github.com/ewildgoose/ndpi-netfilter diff --git a/packages/homebrew/README b/packages/homebrew/README new file mode 100644 index 000000000..c05b32fde --- /dev/null +++ b/packages/homebrew/README @@ -0,0 +1,11 @@ +=== HOMEBREW PACKAGE === + +NB: Work in progress + +- SUBMIT FORMULA +cp ndpi.rb /usr/local/Library/Formula/ + +- INSTALL FORMULA +#check the formula +brew audit ndpi +brew install -vd ndpi \ No newline at end of file diff --git a/packages/homebrew/ndpi.rb b/packages/homebrew/ndpi.rb new file mode 100644 index 000000000..ec06446a5 --- /dev/null +++ b/packages/homebrew/ndpi.rb @@ -0,0 +1,23 @@ +require "formula" + +class Ndpi < Formula + homepage "http://www.ntop.org/products/ndpi/" + url "https://downloads.sourceforge.net/project/ntop/nDPI/libndpi-1.5.1.tar.gz" + sha1 "0a6ed585545ab6611f3f0ac9efd9eb36bb5481dd" + + depends_on "autoconf" => :build + depends_on "automake" => :build + depends_on "pkg-config" => :build + depends_on "libtool" => :build + depends_on "json-c" + + def install + system "./configure","--prefix=#{prefix}" + system "make" + system "make", "install" + end + + test do + system "#{bin}/ndpiReader","-h" + end +end diff --git a/packages/ubuntu/Makefile b/packages/ubuntu/Makefile new file mode 100644 index 000000000..5f1684155 --- /dev/null +++ b/packages/ubuntu/Makefile @@ -0,0 +1,42 @@ +# +# Change it according to your setup +# +NDPI_HOME=$(PWD)/../.. +NDPI_BUILD=${NDPI_HOME}/packages/ubuntu + +all: clean ndpi + +ndpi: + \rm -rf ./usr ./debian/tmp ./debian/ndpi-dev + mkdir -p ./usr/local ./debian/ndpi-dev + mkdir -p ./usr/local/ndpi/lib ./usr/local/ndpi/bin ./ndpi-dev/usr/local/include/ndpi/ + cd ${NDPI_HOME}; ./autogen.sh; ./configure; make + cp $(NDPI_HOME)/lib/libndpi.a $(NDPI_HOME)/lib/libndpi.so* ./usr/local/ndpi/lib/ + cp $(NDPI_HOME)/example/ndpiReader ./usr/local/ndpi/bin/ + cp $(NDPI_HOME)/src/include/*.h ndpi-dev/usr/local/include/ndpi/ + -rm -fr ndpi-dev/usr/local/include/nprobe/ndpi/.svn ndpi-dev/usr/local/include/ndpi/Makefile* ndpi-dev/usr/local/include/ndpi/ndpi_win32.h* ndpi-dev/usr/local/include/ndpi/include + -find ./usr/local/lib -name "*.la" -exec /bin/rm {} ';' + @echo + @find . -name "*~" -exec /bin/rm {} ';' + dpkg-buildpackage -rfakeroot -d -us -uc + dpkg-sig --sign builder -k 7921DF34 ../ndpi*deb + @\rm -f ../ndpi*dsc ../ndpi*.gz ../ndpi*changes + @/bin/mv ../ndpi*deb . + @echo + @echo "Package built." + @/bin/ls ndpi*deb + @echo "-------------------------------" + -dpkg --contents ndpi*amd64.deb + @echo "-------------------------------" + @echo "-------------------------------" + -dpkg --contents ndpi*all.deb + @echo "-------------------------------" + +distclean: + echo "dummy distclean" + +install: + echo "dummy install" + +clean: + -rm -rf *~ *deb debian/tmp ./usr diff --git a/packages/ubuntu/Makefile.in b/packages/ubuntu/Makefile.in new file mode 100644 index 000000000..5f1684155 --- /dev/null +++ b/packages/ubuntu/Makefile.in @@ -0,0 +1,42 @@ +# +# Change it according to your setup +# +NDPI_HOME=$(PWD)/../.. +NDPI_BUILD=${NDPI_HOME}/packages/ubuntu + +all: clean ndpi + +ndpi: + \rm -rf ./usr ./debian/tmp ./debian/ndpi-dev + mkdir -p ./usr/local ./debian/ndpi-dev + mkdir -p ./usr/local/ndpi/lib ./usr/local/ndpi/bin ./ndpi-dev/usr/local/include/ndpi/ + cd ${NDPI_HOME}; ./autogen.sh; ./configure; make + cp $(NDPI_HOME)/lib/libndpi.a $(NDPI_HOME)/lib/libndpi.so* ./usr/local/ndpi/lib/ + cp $(NDPI_HOME)/example/ndpiReader ./usr/local/ndpi/bin/ + cp $(NDPI_HOME)/src/include/*.h ndpi-dev/usr/local/include/ndpi/ + -rm -fr ndpi-dev/usr/local/include/nprobe/ndpi/.svn ndpi-dev/usr/local/include/ndpi/Makefile* ndpi-dev/usr/local/include/ndpi/ndpi_win32.h* ndpi-dev/usr/local/include/ndpi/include + -find ./usr/local/lib -name "*.la" -exec /bin/rm {} ';' + @echo + @find . -name "*~" -exec /bin/rm {} ';' + dpkg-buildpackage -rfakeroot -d -us -uc + dpkg-sig --sign builder -k 7921DF34 ../ndpi*deb + @\rm -f ../ndpi*dsc ../ndpi*.gz ../ndpi*changes + @/bin/mv ../ndpi*deb . + @echo + @echo "Package built." + @/bin/ls ndpi*deb + @echo "-------------------------------" + -dpkg --contents ndpi*amd64.deb + @echo "-------------------------------" + @echo "-------------------------------" + -dpkg --contents ndpi*all.deb + @echo "-------------------------------" + +distclean: + echo "dummy distclean" + +install: + echo "dummy install" + +clean: + -rm -rf *~ *deb debian/tmp ./usr diff --git a/packages/ubuntu/configure b/packages/ubuntu/configure new file mode 100755 index 000000000..857a095ca --- /dev/null +++ b/packages/ubuntu/configure @@ -0,0 +1,2863 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for Makefile.in 1.0. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='Makefile.in' +PACKAGE_TARNAME='makefile-in' +PACKAGE_VERSION='1.0' +PACKAGE_STRING='Makefile.in 1.0' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_subst_vars='LTLIBOBJS +LIBOBJS +PFRING_SVN_RELEASE +SVN_RELEASE +KERNEL +DATE +EXTN +MACHINE +PFRING_VERS +NDPI_VERS +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +' + ac_precious_vars='build_alias +host_alias +target_alias' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures Makefile.in 1.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/makefile-in] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of Makefile.in 1.0:";; + esac + cat <<\_ACEOF + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +Makefile.in configure 1.0 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by Makefile.in $as_me 1.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +NDPI_VERS=`cat ../../config.h | grep -w VERSION | cut -d \" -f 2` +PFRING_VERS=`cat $HOME/PF_RING/kernel/linux/pf_ring.h | grep RING_VERSION | head -1 | cut -d '"' -f 2` +SVN_RELEASE=`svn info ../.. | grep "^Revision"|cut -d " " -f 2` +PFRING_SVN_RELEASE=`svn info $HOME/PF_RING | grep "^Revision"|cut -d " " -f 2` +MACHINE=`uname -m` + +if test $MACHINE = "x86_64"; then + EXTN="amd64" +else + EXTN="i386" +fi + +DATE=`date -R` +KERNEL=`uname -r` + + + + + + + + + + +ac_config_files="$ac_config_files Makefile" + +ac_config_files="$ac_config_files debian/changelog" + +ac_config_files="$ac_config_files debian/files" + +ac_config_files="$ac_config_files debian/control" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by Makefile.in $as_me 1.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +Makefile.in config.status 1.0 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "debian/changelog") CONFIG_FILES="$CONFIG_FILES debian/changelog" ;; + "debian/files") CONFIG_FILES="$CONFIG_FILES debian/files" ;; + "debian/control") CONFIG_FILES="$CONFIG_FILES debian/control" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/packages/ubuntu/configure.in b/packages/ubuntu/configure.in new file mode 100644 index 000000000..bf0608cf5 --- /dev/null +++ b/packages/ubuntu/configure.in @@ -0,0 +1,32 @@ +AC_INIT([Makefile.in], 1.0) + +NDPI_VERS=`cat ../../config.h | grep -w VERSION | cut -d \" -f 2` +PFRING_VERS=`cat $HOME/PF_RING/kernel/linux/pf_ring.h | grep RING_VERSION | head -1 | cut -d '"' -f 2` +SVN_RELEASE=`svn info ../.. | grep "^Revision"|cut -d " " -f 2` +PFRING_SVN_RELEASE=`svn info $HOME/PF_RING | grep "^Revision"|cut -d " " -f 2` +MACHINE=`uname -m` + +if test $MACHINE = "x86_64"; then + EXTN="amd64" +else + EXTN="i386" +fi + +DATE=`date -R` +KERNEL=`uname -r` + +AC_SUBST(NDPI_VERS) +AC_SUBST(PFRING_VERS) +AC_SUBST(MACHINE) +AC_SUBST(EXTN) +AC_SUBST(DATE) +AC_SUBST(KERNEL) +AC_SUBST(SVN_RELEASE) +AC_SUBST(PFRING_SVN_RELEASE) + +AC_CONFIG_FILES(Makefile) +AC_CONFIG_FILES(debian/changelog) +AC_CONFIG_FILES(debian/files) +AC_CONFIG_FILES(debian/control) + +AC_OUTPUT diff --git a/packages/ubuntu/debian/COPYRIGHT b/packages/ubuntu/debian/COPYRIGHT new file mode 100644 index 000000000..d60c31a97 --- /dev/null +++ b/packages/ubuntu/debian/COPYRIGHT @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/packages/ubuntu/debian/README b/packages/ubuntu/debian/README new file mode 100644 index 000000000..6563a5d36 --- /dev/null +++ b/packages/ubuntu/debian/README @@ -0,0 +1,2 @@ +This directory contains the files needed to build the package +named 'nprobe' for the Debian GNU/Linux distribution. diff --git a/packages/ubuntu/debian/changelog.in b/packages/ubuntu/debian/changelog.in new file mode 100644 index 000000000..15d86b02d --- /dev/null +++ b/packages/ubuntu/debian/changelog.in @@ -0,0 +1,4 @@ +ndpi (@NDPI_VERS@-@SVN_RELEASE@) stable; urgency=high + * Last packaged version + + -- Luca Deri @DATE@ diff --git a/packages/ubuntu/debian/compat b/packages/ubuntu/debian/compat new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/packages/ubuntu/debian/compat @@ -0,0 +1 @@ +1 diff --git a/packages/ubuntu/debian/conffiles b/packages/ubuntu/debian/conffiles new file mode 100644 index 000000000..e69de29bb diff --git a/packages/ubuntu/debian/control.in b/packages/ubuntu/debian/control.in new file mode 100644 index 000000000..56191e2eb --- /dev/null +++ b/packages/ubuntu/debian/control.in @@ -0,0 +1,28 @@ +Source: ndpi +Section: free +Priority: optional +Maintainer: Luca Deri +Standards-Version: @NDPI_VERSION@ +Build-Depends: +Build-Conflicts: + +Package: ndpi +Architecture: @EXTN@ +Depends: pfring (=@PFRING_VERS@-@PFRING_SVN_RELEASE@), libnuma +Recommends: +Suggests: +Pre-Depends: +Conflicts: +Provides: +Replaces: +Description: A network probe. + +Package: ndpi-dev +Section: libdevel +Architecture: all +Depends: ndpi (= ${binary:Version}), ${misc:Depends} +Conflicts: +Description: development library and header files for ndpi + Headers, static libraries, and documentation for the ndpi library + + diff --git a/packages/ubuntu/debian/dirs b/packages/ubuntu/debian/dirs new file mode 100644 index 000000000..c648ad7d0 --- /dev/null +++ b/packages/ubuntu/debian/dirs @@ -0,0 +1 @@ +usr/local/ndpi diff --git a/packages/ubuntu/debian/docs b/packages/ubuntu/debian/docs new file mode 100644 index 000000000..e845566c0 --- /dev/null +++ b/packages/ubuntu/debian/docs @@ -0,0 +1 @@ +README diff --git a/packages/ubuntu/debian/files.in b/packages/ubuntu/debian/files.in new file mode 100644 index 000000000..8f8691216 --- /dev/null +++ b/packages/ubuntu/debian/files.in @@ -0,0 +1 @@ +ndpi_@NDPI_VERS@_@EXTN@.deb free optional diff --git a/packages/ubuntu/debian/postinst b/packages/ubuntu/debian/postinst new file mode 100755 index 000000000..65bf04230 --- /dev/null +++ b/packages/ubuntu/debian/postinst @@ -0,0 +1,34 @@ +#!/bin/sh -e + +case "$1" in + configure) + # continue below + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + exit 0 + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +umask 022 + +# Update shared libs +echo "/usr/local/lib\n" > /etc/ld.so.conf.d/nprobe.conf +echo "Rebuilding ld cache..." +/sbin/ldconfig + +echo "Adding the nprobe startup script" +update-rc.d nprobe defaults 93 >/dev/null + +echo "Making the /etc/nprobe directory..." +mkdir -p /etc/nprobe/ + +echo "Making the /var/log/nprobe directory..." +mkdir -p /var/log/nprobe + +exit 0 diff --git a/packages/ubuntu/debian/postrm b/packages/ubuntu/debian/postrm new file mode 100644 index 000000000..8ea16af2d --- /dev/null +++ b/packages/ubuntu/debian/postrm @@ -0,0 +1,13 @@ +#!/bin/sh -e + +set -e + +#\/bin/rm /etc/ld.so.conf.d/nprobe.conf +/sbin/ldconfig + +# Not needed: upstart does it +if [ "$1" = "purge" ] ; then + update-rc.d nprobe remove >/dev/null +fi + +exit 0 diff --git a/packages/ubuntu/debian/preinst b/packages/ubuntu/debian/preinst new file mode 100644 index 000000000..cf9323e94 --- /dev/null +++ b/packages/ubuntu/debian/preinst @@ -0,0 +1,35 @@ +#! /bin/sh +# preinst script for nbox +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `install' +# * `install' +# * `upgrade' +# * `abort-upgrade' + +case "$1" in + install|upgrade) + if test -f /usr/local/sbin/nprobe; then + rm /usr/local/sbin/nprobe + fi + ;; + + abort-upgrade) + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + + + +exit 0 diff --git a/packages/ubuntu/debian/prerm b/packages/ubuntu/debian/prerm new file mode 100755 index 000000000..58af3b74c --- /dev/null +++ b/packages/ubuntu/debian/prerm @@ -0,0 +1,14 @@ +#!/bin/sh -e + +# Only shut the daemon down if we're really removing the package. If this is +# an upgrade, we will instead do a restart in the postinst... this keeps nprobe +# from being left shut down for a long time, which could pose problems. +case "$1" in +upgrade) + ;; +*) + /etc/init.d/nprobe stop + ;; +esac + +exit 0 \ No newline at end of file diff --git a/packages/ubuntu/debian/rules b/packages/ubuntu/debian/rules new file mode 100755 index 000000000..0000bdaf5 --- /dev/null +++ b/packages/ubuntu/debian/rules @@ -0,0 +1,59 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +# export DH_VERBOSE=1 + +# +# debian/compat +# We should use at least comparibily version 5 +# but this requires the whole building process +# to be remade and this is something we leave +# to when we will have more time +# http://www.tin.org/bin/man.cgi?section=7&topic=debhelper +# + +package=ndpi + +build: build-stamp +build-stamp: + dh_testdir + +clean: + dh_testdir + dh_testroot + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + dh_installinit + dh_installman +# install the files into debian/tmp. + cp -r ./usr/ ./debian/tmp + cp -r ./ndpi-dev/* ./debian/ndpi-dev/ + -find ./debian/tmp -name .svn -exec /bin/rm -rf {} ';' + -find ./debian/tmp -executable -type f |xargs strip + dh_link + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/src/include/Makefile.am b/src/include/Makefile.am new file mode 100644 index 000000000..71a507ae2 --- /dev/null +++ b/src/include/Makefile.am @@ -0,0 +1,9 @@ + +library_includedir=$(includedir)/libndpi-1.4/libndpi + +library_include_HEADERS = ndpi_api.h \ + ndpi_debug_functions.h \ + ndpi_define.h \ + ndpi_macros.h \ + ndpi_protocols_osdpi.h \ + ndpi_public_functions.h diff --git a/src/include/linux_compat.h b/src/include/linux_compat.h new file mode 100644 index 000000000..38601f180 --- /dev/null +++ b/src/include/linux_compat.h @@ -0,0 +1,188 @@ +/* + * linux_compat.h + * + * 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 . + * + */ + + +#ifndef __NDPI_LINUX_COMPAT_H__ +#define __NDPI_LINUX_COMPAT_H__ + +#include "ndpi_define.h" + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include + +#if _BYTE_ORDER == _LITTLE_ENDIAN +#ifndef __LITTLE_ENDIAN__ +#define __LITTLE_ENDIAN__ 1 +#endif +#else +#ifndef __BIG_ENDIAN__ +#define __BIG_ENDIAN__ 1 +#endif +#endif +#endif + +#pragma pack(push, 1) /* push current alignment to stack */ +#pragma pack(1) /* set alignment to 1 byte boundary */ + +#pragma pack(pop) /* restore original alignment from stack */ + +struct ndpi_ethhdr { + u_char h_dest[6]; /* destination eth addr */ + u_char h_source[6]; /* source ether addr */ + u_int16_t h_proto; /* packet type ID field */ +}; + +struct ndpi_80211q { + u_int16_t vlanId; + u_int16_t protoType; +}; + +struct ndpi_iphdr { +#if defined(__LITTLE_ENDIAN__) + u_int8_t ihl:4, version:4; +#elif defined(__BIG_ENDIAN__) + u_int8_t version:4, ihl:4; +#else +# error "Byte order must be defined" +#endif + u_int8_t tos; + u_int16_t tot_len; + u_int16_t id; + u_int16_t frag_off; + u_int8_t ttl; + u_int8_t protocol; + u_int16_t check; + u_int32_t saddr; + u_int32_t daddr; +}; + + +#ifdef WIN32 + +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int uint; +typedef unsigned long u_long; +typedef u_char u_int8_t; +typedef u_short u_int16_t; +typedef uint u_int32_t; + +#define _WS2TCPIP_H_ /* Avoid compilation problems */ +#define HAVE_SIN6_LEN + + +/* IPv6 address */ +/* Already defined in WS2tcpip.h */ +struct ndpi_win_in6_addr +{ + union + { + u_int8_t u6_addr8[16]; + u_int16_t u6_addr16[8]; + u_int32_t u6_addr32[4]; + } in6_u; +#ifdef s6_addr +#undef s6_addr +#endif + +#ifdef s6_addr16 +#undef s6_addr16 +#endif + +#ifdef s6_addr32 +#undef s6_addr32 +#endif + +#define s6_addr in6_u.u6_addr8 + // #define s6_addr16 in6_u.u6_addr16 + // #define s6_addr32 in6_u.u6_addr32 + +}; + +#define in6_addr win_in6_addr + +/* Generic extension header. */ +struct ndpi_ip6_ext +{ + u_int8_t ip6e_nxt; /* next header. */ + u_int8_t ip6e_len; /* length in units of 8 octets. */ +}; + +#define s6_addr16 __u6_addr.__u6_addr16 +#define s6_addr32 __u6_addr.__u6_addr32 +#else +#ifndef __KERNEL__ +#include +#endif +#endif + + + +struct ndpi_in6_addr { + union { + u_int8_t __u6_addr8[16]; + u_int16_t __u6_addr16[8]; + u_int32_t __u6_addr32[4]; + } __u6_addr; /* 128-bit IP6 address */ +}; + +struct ndpi_ip6_hdr { + union { + struct ndpi_ip6_hdrctl { + u_int32_t ip6_un1_flow; + u_int16_t ip6_un1_plen; + u_int8_t ip6_un1_nxt; + u_int8_t ip6_un1_hlim; + } ip6_un1; + u_int8_t ip6_un2_vfc; + } ip6_ctlun; + struct ndpi_in6_addr ip6_src; + struct ndpi_in6_addr ip6_dst; +}; + +struct ndpi_tcphdr { + u_int16_t source; + u_int16_t dest; + u_int32_t seq; + u_int32_t ack_seq; +#if defined(__LITTLE_ENDIAN__) + u_int16_t res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1; +#elif defined(__BIG_ENDIAN__) + u_int16_t doff:4, res1:4, cwr:1, ece:1, urg:1, ack:1, psh:1, rst:1, syn:1, fin:1; +#else +# error "Byte order must be defined" +#endif + u_int16_t window; + u_int16_t check; + u_int16_t urg_ptr; +}; + +struct ndpi_udphdr { + u_int16_t source; + u_int16_t dest; + u_int16_t len; + u_int16_t check; +}; + +#endif diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h new file mode 100644 index 000000000..2bfd345f9 --- /dev/null +++ b/src/include/ndpi_api.h @@ -0,0 +1,242 @@ +/* + * ndpi_api.h + * + * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2009-2011 by 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 . + * + */ + + +#ifndef __NDPI_PUBLIC_FUNCTIONS_H__ +#define __NDPI_PUBLIC_FUNCTIONS_H__ + +#include "ndpi_main.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * This function returns the size of the flow struct + * @return the size of the flow struct + */ + u_int32_t ndpi_detection_get_sizeof_ndpi_flow_struct(void); + + /** + * This function returns the size of the id struct + * @return the size of the id struct + */ + u_int32_t ndpi_detection_get_sizeof_ndpi_id_struct(void); + + + /* Public malloc/free */ + void* ndpi_malloc(unsigned long size); + void* ndpi_calloc(unsigned long count, unsigned long size); + void ndpi_free(void *ptr); + void *ndpi_realloc(void *ptr, size_t old_size, size_t new_size); + char *ndpi_strdup(const char *s); + /* + * 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); + + /** + * This function returns the nDPI protocol id for IP-based protocol detection + */ + u_int16_t ndpi_network_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, struct in_addr *pin); + + /** + * Same as ndpi_network_ptree_match + */ + u_int16_t ndpi_host_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t host); + + /** + * This function returns a new initialized detection module. + * @param ticks_per_second the timestamp resolution per second (like 1000 for millisecond resolution) + * @param ndpi_malloc function pointer to a memory allocator + * @param ndpi_debug_printf a function pointer to a debug output function, use NULL in productive envionments + * @return the initialized detection module + */ + 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); + + + /** + * This function frees the memory allocated in the specified flow + * @param flow to free + */ + void ndpi_free_flow(struct ndpi_flow_struct *flow); + + /** + * This function enables cache support in nDPI used for some protocol such as Skype + * @param cache host name + * @param cache port + */ + void ndpi_enable_cache(struct ndpi_detection_module_struct *ndpi_mod, char* host, u_int port); + + /** + * This function destroys the detection module + * @param ndpi_struct the to clearing detection module + * @param ndpi_free function pointer to a memory free function + */ + void + ndpi_exit_detection_module(struct ndpi_detection_module_struct + *ndpi_struct, void (*ndpi_free) (void *ptr)); + + /** + * This function sets the protocol bitmask2 + * @param ndpi_struct the detection module + * @param detection_bitmask the protocol bitmask + */ + void + ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *ndpi_struct, + const NDPI_PROTOCOL_BITMASK * detection_bitmask); + /** + * This function will processes one packet and returns the ID of the detected protocol. + * This is the main packet processing function. + * + * @param ndpi_struct the detection module + * @param flow void pointer to the connection state machine + * @param packet the packet as unsigned char pointer with the length of packetlen. the pointer must point to the Layer 3 (IP header) + * @param packetlen the length of the packet + * @param current_tick the current timestamp for the packet + * @param src void pointer to the source subscriber state machine + * @param dst void pointer to the destination subscriber state machine + * @return returns the detected ID of the protocol + */ + 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, + struct ndpi_id_struct *src, + struct ndpi_id_struct *dst); + +#define NDPI_DETECTION_ONLY_IPV4 ( 1 << 0 ) +#define NDPI_DETECTION_ONLY_IPV6 ( 1 << 1 ) + + /** + * query the pointer to the layer 4 packet + * + * @param l3 pointer to the layer 3 data + * @param l3_len length of the layer 3 data + * @param l4_return filled with the pointer the layer 4 data if return value == 0, undefined otherwise + * @param l4_len_return filled with the length of the layer 4 data if return value == 0, undefined otherwise + * @param l4_protocol_return filled with the protocol of the layer 4 data if return value == 0, undefined otherwise + * @param flags limit operation on ipv4 or ipv6 packets, possible values are NDPI_DETECTION_ONLY_IPV4 or NDPI_DETECTION_ONLY_IPV6; 0 means any + * @return 0 if correct layer 4 data could be found, != 0 otherwise + */ + 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); + /** + * returns the real protocol for the flow of the last packet given to the detection. + * if no real protocol could be found, the unknown protocol will be returned. + * + * @param ndpi_struct the detection module + * @return the protocol id of the last real protocol found in the protocol history of the flow + */ + u_int16_t ndpi_detection_get_real_protocol_of_flow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); + + /** + * returns true if the protocol history of the flow of the last packet given to the detection + * contains the given protocol. + * + * @param ndpi_struct the detection module + * @return 1 if protocol has been found, 0 otherwise + */ + 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); + unsigned int ndpi_find_port_based_protocol(struct ndpi_detection_module_struct *ndpi_struct, + u_int8_t proto, u_int32_t shost, u_int16_t sport, u_int32_t dhost, u_int16_t dport); + unsigned int ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_struct, + u_int8_t proto, u_int32_t shost, u_int16_t sport, u_int32_t dhost, u_int16_t dport); + 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); + 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); + int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_struct, + ndpi_automa *automa, char *bigram_to_match); + char* ndpi_get_proto_name(struct ndpi_detection_module_struct *mod, u_int16_t proto_id); + ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t proto); + char* ndpi_get_proto_breed_name(struct ndpi_detection_module_struct *ndpi_struct, ndpi_protocol_breed_t breed_id); + int ndpi_get_protocol_id(struct ndpi_detection_module_struct *ndpi_mod, char *proto); + void ndpi_dump_protocols(struct ndpi_detection_module_struct *mod); + int matchStringProtocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, + char *string_to_match, u_int string_to_match_len); + + int ndpi_load_protocols_file(struct ndpi_detection_module_struct *ndpi_mod, char* path); + u_int ndpi_get_num_supported_protocols(struct ndpi_detection_module_struct *ndpi_mod); + char* ndpi_revision(void); + void ndpi_set_automa(struct ndpi_detection_module_struct *ndpi_struct, void* automa); + +#define ADD_TO_DETECTION_BITMASK 1 +#define NO_ADD_TO_DETECTION_BITMASK 0 +#define SAVE_DETECTION_BITMASK_AS_UNKNOWN 1 +#define NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN 0 + + /** + * This function sets a single protocol bitmask + * @param label Protocol name + * @param ndpi_struct the detection module + * @param detection_bitmask the protocol bitmask + * @param idx the index of the callback_buffer + * @param func void function point of the protocol search + * @param ndpi_selection_bitmask the protocol selected bitmask + * @param b_save_bitmask_unknow set true if you want save the detection bitmask as unknow + * @param b_add_detection_bitmask set true if you want add the protocol bitmask to the detection bitmask + * NB: this function does not increment the index of the callback_buffer + */ + 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); + +#ifdef NDPI_PROTOCOL_HTTP + /* + API used to retrieve information for HTTP flows + */ + ndpi_http_method ndpi_get_http_method(struct ndpi_detection_module_struct *ndpi_mod, + struct ndpi_flow_struct *flow); + + char* ndpi_get_http_url(struct ndpi_detection_module_struct *ndpi_mod, + struct ndpi_flow_struct *flow); + + char* ndpi_get_http_content_type(struct ndpi_detection_module_struct *ndpi_mod, + struct ndpi_flow_struct *flow); +#endif + +#ifdef NDPI_PROTOCOL_TOR + int ndpi_is_ssl_tor(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, char *certificate); +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/include/ndpi_define.h b/src/include/ndpi_define.h new file mode 100644 index 000000000..365012adb --- /dev/null +++ b/src/include/ndpi_define.h @@ -0,0 +1,309 @@ +/* + * + * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2009-2011 by 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 . + * + */ + +#ifndef __NDPI_DEFINE_INCLUDE_FILE__ +#define __NDPI_DEFINE_INCLUDE_FILE__ + +/* + gcc -E -dM - < /dev/null |grep ENDIAN +*/ + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include +#endif + +#ifdef __OpenBSD__ +#include +#define __BYTE_ORDER BYTE_ORDER +#if BYTE_ORDER == LITTLE_ENDIAN +#define __LITTLE_ENDIAN__ +#else +#define __BIG_ENDIAN__ +#endif/* BYTE_ORDER */ +#endif/* __OPENBSD__ */ + +#if 0 +#ifndef NDPI_ENABLE_DEBUG_MESSAGES +#define NDPI_ENABLE_DEBUG_MESSAGES +#endif +#endif + +#ifdef WIN32 +#define __LITTLE_ENDIAN__ 1 +#endif + +#if !(defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__)) +#if defined(__mips__) +#undef __LITTLE_ENDIAN__ +#undef __LITTLE_ENDIAN +#define __BIG_ENDIAN__ +#endif + +/* Kernel modules */ +#if defined(__LITTLE_ENDIAN) +#define __LITTLE_ENDIAN__ +#endif +#if defined(__BIG_ENDIAN) +#define __BIG_ENDIAN__ +#endif +/* Everything else */ +#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)) +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define __LITTLE_ENDIAN__ +#else +#define __BIG_ENDIAN__ +#endif +#endif + +#endif + +#define NDPI_USE_ASYMMETRIC_DETECTION 0 +#define NDPI_SELECTION_BITMASK_PROTOCOL_SIZE u_int32_t + +#define NDPI_SELECTION_BITMASK_PROTOCOL_IP (1<<0) +#define NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP (1<<1) +#define NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP (1<<2) +#define NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP (1<<3) +#define NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD (1<<4) +#define NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION (1<<5) +#define NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 (1<<6) +#define NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6 (1<<7) +#define NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC (1<<8) +/* now combined detections */ + +/* v4 */ +#define NDPI_SELECTION_BITMASK_PROTOCOL_TCP (NDPI_SELECTION_BITMASK_PROTOCOL_IP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP) +#define NDPI_SELECTION_BITMASK_PROTOCOL_UDP (NDPI_SELECTION_BITMASK_PROTOCOL_IP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP) +#define NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP (NDPI_SELECTION_BITMASK_PROTOCOL_IP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP) + +/* v6 */ +#define NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP (NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V6_UDP (NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP_OR_UDP (NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP) + +/* v4 or v6 */ +#define NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP (NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP (NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP (NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP) + + +#define NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITH_PAYLOAD (NDPI_SELECTION_BITMASK_PROTOCOL_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP_WITH_PAYLOAD (NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD (NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) + +/* does it make sense to talk about udp with payload ??? have you ever seen empty udp packets ? */ +#define NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD (NDPI_SELECTION_BITMASK_PROTOCOL_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V6_UDP_WITH_PAYLOAD (NDPI_SELECTION_BITMASK_PROTOCOL_V6_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD (NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) + +#define NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD (NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP_OR_UDP_WITH_PAYLOAD (NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP_OR_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD (NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) + +#define NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION) + +#define NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP_OR_UDP_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP_OR_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION) + +#define NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) + +#define NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_V6_TCP_OR_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) +#define NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION (NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION | NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) + +/* safe src/dst protocol check macros... */ + +#define NDPI_SRC_HAS_PROTOCOL(src,protocol) ((src) != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK((src)->detected_protocol_bitmask,(protocol)) != 0) + +#define NDPI_DST_HAS_PROTOCOL(dst,protocol) ((dst) != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK((dst)->detected_protocol_bitmask,(protocol)) != 0) + +#define NDPI_SRC_OR_DST_HAS_PROTOCOL(src,dst,protocol) (NDPI_SRC_HAS_PROTOCOL(src,protocol) || NDPI_SRC_HAS_PROTOCOL(dst,protocol)) + +/** + * convenience macro to check for excluded protocol + * a protocol is excluded if the flow is known and either the protocol is not detected at all + * or the excluded bitmask contains the protocol + */ +#define NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct,flow,protocol) ((flow) != NULL && \ + ( NDPI_COMPARE_PROTOCOL_TO_BITMASK((ndpi_struct)->detection_bitmask, (protocol)) == 0 || \ + NDPI_COMPARE_PROTOCOL_TO_BITMASK((flow)->excluded_protocol_bitmask, (protocol)) != 0 ) ) + +/* misc definitions */ +#define NDPI_DEFAULT_MAX_TCP_RETRANSMISSION_WINDOW_SIZE 0x10000 + + +/* TODO: rebuild all memory areas to have a more aligned memory block here */ + +/* DEFINITION OF MAX LINE NUMBERS FOR line parse algorithm */ +#define NDPI_MAX_PARSE_LINES_PER_PACKET 64 + +#define MAX_PACKET_COUNTER 65000 +#define MAX_DEFAULT_PORTS 5 + +/********************** + * detection features * + **********************/ +#define NDPI_SELECT_DETECTION_WITH_REAL_PROTOCOL ( 1 << 0 ) + +#define NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT 600 +#define NDPI_IRC_CONNECTION_TIMEOUT 120 +#define NDPI_GNUTELLA_CONNECTION_TIMEOUT 60 +#define NDPI_BATTLEFIELD_CONNECTION_TIMEOUT 60 +#define NDPI_THUNDER_CONNECTION_TIMEOUT 30 +#define NDPI_RTSP_CONNECTION_TIMEOUT 5 +#define NDPI_TVANTS_CONNECTION_TIMEOUT 5 +#define NDPI_YAHOO_DETECT_HTTP_CONNECTIONS 1 +#define NDPI_YAHOO_LAN_VIDEO_TIMEOUT 30 +#define NDPI_ZATTOO_CONNECTION_TIMEOUT 120 +#define NDPI_ZATTOO_FLASH_TIMEOUT 5 +#define NDPI_JABBER_STUN_TIMEOUT 30 +#define NDPI_JABBER_FT_TIMEOUT 5 +#define NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT 600 + +#ifdef NDPI_ENABLE_DEBUG_MESSAGES + +#define NDPI_LOG(proto, mod, log_level, args...) \ + { \ + if(mod != NULL) { \ + mod->ndpi_debug_print_file=__FILE__; \ + mod->ndpi_debug_print_function=__FUNCTION__; \ + mod->ndpi_debug_print_line=__LINE__; \ + mod->ndpi_debug_printf(proto, mod, log_level, args); \ + } \ + } + +#else /* NDPI_ENABLE_DEBUG_MESSAGES */ + +#if defined(WIN32) +#define NDPI_LOG(...) {} +#else +#define NDPI_LOG(proto, mod, log_level, args...) {} +#endif + +#endif /* NDPI_ENABLE_DEBUG_MESSAGES */ + +/** + * macro for getting the string len of a static string + * + * use it instead of strlen to avoid runtime calculations + */ +#define NDPI_STATICSTRING_LEN( s ) ( sizeof( s ) - 1 ) + +/** macro to compare 2 IPv6 addresses with each other to identify the "smaller" IPv6 address */ +#define NDPI_COMPARE_IPV6_ADDRESS_STRUCTS(x,y) \ + ((((u_int64_t *)(x))[0]) < (((u_int64_t *)(y))[0]) || ( (((u_int64_t *)(x))[0]) == (((u_int64_t *)(y))[0]) && (((u_int64_t *)(x))[1]) < (((u_int64_t *)(y))[1])) ) + +#if !defined(__KERNEL__) && !defined(NDPI_IPTABLES_EXT) +#define NDPI_NUM_BITS 256 +#else +/* custom protocols not supported */ +#define NDPI_NUM_BITS 192 +#endif + +#define NDPI_BITS /* 32 */ (sizeof(ndpi_ndpi_mask) * 8 /* number of bits in a byte */) /* bits per mask */ +#define howmanybits(x, y) (((x)+((y)-1))/(y)) + + +#define NDPI_SET(p, n) ((p)->fds_bits[(n)/NDPI_BITS] |= (1 << (((u_int32_t)n) % NDPI_BITS))) +#define NDPI_CLR(p, n) ((p)->fds_bits[(n)/NDPI_BITS] &= ~(1 << (((u_int32_t)n) % NDPI_BITS))) +#define NDPI_ISSET(p, n) ((p)->fds_bits[(n)/NDPI_BITS] & (1 << (((u_int32_t)n) % NDPI_BITS))) +#define NDPI_ZERO(p) memset((char *)(p), 0, sizeof(*(p))) +#define NDPI_ONE(p) memset((char *)(p), 0xFF, sizeof(*(p))) + +#define NDPI_NUM_FDS_BITS howmanybits(NDPI_NUM_BITS, NDPI_BITS) + +#define NDPI_PROTOCOL_BITMASK ndpi_protocol_bitmask_struct_t + +#define NDPI_BITMASK_ADD(a,b) NDPI_SET(&a,b) +#define NDPI_BITMASK_DEL(a,b) NDPI_CLR(&a,b) +#define NDPI_BITMASK_RESET(a) NDPI_ZERO(&a) +#define NDPI_BITMASK_SET_ALL(a) NDPI_ONE(&a) +#define NDPI_BITMASK_SET(a, b) { memcpy(&a, &b, sizeof(NDPI_PROTOCOL_BITMASK)); } + +/* this is a very very tricky macro *g*, + * the compiler will remove all shifts here if the protocol is static... + */ +#define NDPI_ADD_PROTOCOL_TO_BITMASK(bmask,value) NDPI_SET(&bmask,value) +#define NDPI_DEL_PROTOCOL_FROM_BITMASK(bmask,value) NDPI_CLR(&bmask,value) +#define NDPI_COMPARE_PROTOCOL_TO_BITMASK(bmask,value) NDPI_ISSET(&bmask,value) + +#define NDPI_SAVE_AS_BITMASK(bmask,value) { NDPI_ZERO(&bmask) ; NDPI_ADD_PROTOCOL_TO_BITMASK(bmask, value); } + + +#define ndpi_min(a,b) ((a < b) ? a : b) +#define ndpi_max(a,b) ((a > b) ? a : b) + +#define NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct,flow,packet) \ + if (packet->packet_lines_parsed_complete != 1) { \ + ndpi_parse_packet_line_info(ndpi_struct,flow); \ + } \ + +#define NDPI_IPSEC_PROTOCOL_ESP 50 +#define NDPI_IPSEC_PROTOCOL_AH 51 +#define NDPI_GRE_PROTOCOL_TYPE 0x2F +#define NDPI_ICMP_PROTOCOL_TYPE 0x01 +#define NDPI_IGMP_PROTOCOL_TYPE 0x02 +#define NDPI_EGP_PROTOCOL_TYPE 0x08 +#define NDPI_OSPF_PROTOCOL_TYPE 0x59 +#define NDPI_SCTP_PROTOCOL_TYPE 132 +#define NDPI_IPIP_PROTOCOL_TYPE 0x04 +#define NDPI_ICMPV6_PROTOCOL_TYPE 0x3a + +/* the get_uXX will return raw network packet bytes !! */ +#define get_u_int8_t(X,O) (*(u_int8_t *)(((u_int8_t *)X) + O)) +#define get_u_int16_t(X,O) (*(u_int16_t *)(((u_int8_t *)X) + O)) +#define get_u_int32_t(X,O) (*(u_int32_t *)(((u_int8_t *)X) + O)) +#define get_u_int64_t(X,O) (*(u_int64_t *)(((u_int8_t *)X) + O)) + +/* new definitions to get little endian from network bytes */ +#define get_ul8(X,O) get_u_int8_t(X,O) + + +#if defined(__LITTLE_ENDIAN__) || defined(_LITTLE_ENDIAN) +#define get_l16(X,O) get_u_int16_t(X,O) +#define get_l32(X,O) get_u_int32_t(X,O) +#elif defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) +/* convert the bytes from big to little endian */ +#ifndef __KERNEL__ +# define get_l16(X,O) bswap_16(get_u_int16_t(X,O)) +# define get_l32(X,O) bswap_32(get_u_int32_t(X,O)) +#else +# define get_l16(X,O) __cpu_to_le16(get_u_int16_t(X,O)) +# define get_l32(X,O) __cpu_to_le32(get_u_int32_t(X,O)) +#endif + +#else + +#error "__BYTE_ORDER MUST BE DEFINED !" + +#endif /* __BYTE_ORDER */ + +/* define memory callback function */ +#define match_first_bytes(payload,st) (memcmp((payload),(st),(sizeof(st)-1))==0) + +#endif /* __NDPI_DEFINE_INCLUDE_FILE__ */ diff --git a/src/include/ndpi_main.h b/src/include/ndpi_main.h new file mode 100644 index 000000000..55db9235e --- /dev/null +++ b/src/include/ndpi_main.h @@ -0,0 +1,156 @@ +/* + * ndpi_main.h + * + * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2009-2011 by 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 . + * + */ + +#ifndef __NDPI_MAIN_INCLUDE_FILE__ +#define __NDPI_MAIN_INCLUDE_FILE__ + +#ifndef __KERNEL__ +#include +#include +#include +#include +#ifndef WIN32 +#include +#endif +#include +#include +#endif + + +#ifndef WIN32 +#ifndef __KERNEL__ +#include +#endif + +#if !defined __APPLE__ && !defined __FreeBSD__ && !defined __NetBSD__ && !defined __OpenBSD__ + +#ifndef __KERNEL__ +#include +#include +#else +#include +#include +#endif + +#endif + +/* default includes */ + +#ifndef __KERNEL__ +#include +#include +#endif +#endif + +#include "ndpi_win32.h" +#include "ndpi_unix.h" +#include "ndpi_define.h" +#include "ndpi_protocol_ids.h" +#include "ndpi_typedefs.h" +#include "ndpi_protocols.h" + + +void *ndpi_tdelete(const void * __restrict, void ** __restrict, + int (*)(const void *, const void *)); +void *ndpi_tfind(const void *, void *, int (*)(const void *, const void *)); +void *ndpi_tsearch(const void *, void**, int (*)(const void *, const void *)); +void ndpi_twalk(const void *, void (*)(const void *, ndpi_VISIT, int, void*), void *user_data); +void ndpi_tdestroy(void *vrootp, void (*freefct)(void *)); + +int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b); +int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a); +void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a); + +extern u_int8_t ndpi_net_match(u_int32_t ip_to_check, + u_int32_t net, + u_int32_t num_bits); + +extern u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst, + u_int32_t net, u_int32_t num_bits); + +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_int32_t ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); +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_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_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_int32_t ndpi_bytestream_to_ipv4(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + + +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); + + +/* function to parse a packet which has line based information into a line based structure + * this function will also set some well known line pointers like: + * - host, user agent, empty line,.... + */ +extern void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +extern void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +extern u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t counter); +extern 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); +extern 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); +extern void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod, + ndpi_protocol_breed_t protoBreed, u_int16_t protoId, + u_int16_t tcp_alias_protoId[2], u_int16_t udp_alias_protoId[2], + char *protoName, + ndpi_port_range *tcpDefPorts, ndpi_port_range *udpDefPorts); +extern void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet); +extern void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow); +extern int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip); +extern int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip); +extern void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip); +extern void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip); +extern char *ndpi_get_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const ndpi_ip_addr_t * ip); +extern char *ndpi_get_packet_src_ip_string(struct ndpi_detection_module_struct *ndpi_struct, + const struct ndpi_packet_struct *packet); +extern char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int id); +extern 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); +extern 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); + +extern u_int8_t ndpi_net_match(u_int32_t ip_to_check, + u_int32_t net, + u_int32_t num_bits); + +extern u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst, + u_int32_t net, u_int32_t num_bits); + +#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); +#endif + +#include "ndpi_api.h" + +#endif /* __NDPI_MAIN_INCLUDE_FILE__ */ diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h new file mode 100644 index 000000000..43e845117 --- /dev/null +++ b/src/include/ndpi_protocol_ids.h @@ -0,0 +1,244 @@ +/* + * ndpi_protocol_ids.h + * + * 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 . + * + */ + + +#ifndef __NDPI_API_INCLUDE_FILE__ + +#endif + +#ifndef __NDPI_PROTOCOLS_DEFAULT_H__ +#define __NDPI_PROTOCOLS_DEFAULT_H__ + +#define NDPI_DETECTION_SUPPORT_IPV6 +#define NDPI_PROTOCOL_HISTORY_SIZE 3 + +#define NDPI_PROTOCOL_UNKNOWN 0 + +#define NDPI_PROTOCOL_NO_MASTER_PROTO NDPI_PROTOCOL_UNKNOWN + +#define NDPI_PROTOCOL_IP_VRRP 73 +#define NDPI_PROTOCOL_IP_IPSEC 79 +#define NDPI_PROTOCOL_IP_GRE 80 +#define NDPI_PROTOCOL_IP_ICMP 81 +#define NDPI_PROTOCOL_IP_IGMP 82 +#define NDPI_PROTOCOL_IP_EGP 83 +#define NDPI_PROTOCOL_IP_SCTP 84 +#define NDPI_PROTOCOL_IP_OSPF 85 +#define NDPI_PROTOCOL_IP_IP_IN_IP 86 +#define NDPI_PROTOCOL_IP_ICMPV6 102 + +#define NDPI_PROTOCOL_HTTP 7 +#define NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV 60 +#define NDPI_PROTOCOL_SSL_NO_CERT 64 /* SSL without certificate (Skype, Ultrasurf?) - ntop.org */ +#define NDPI_PROTOCOL_SSL 91 +#define NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC 110 +#define NDPI_PROTOCOL_HTTP_CONNECT 130 +#define NDPI_PROTOCOL_HTTP_PROXY 131 +#define NDPI_PROTOCOL_SOCKS5 172 /* Tomasz Bujlow */ +#define NDPI_PROTOCOL_SOCKS4 173 /* Tomasz Bujlow */ + +#define NDPI_PROTOCOL_FTP_CONTROL 1 /* Tomasz Bujlow */ +#define NDPI_PROTOCOL_MAIL_POP 2 +#define NDPI_PROTOCOL_MAIL_SMTP 3 +#define NDPI_PROTOCOL_MAIL_IMAP 4 +#define NDPI_PROTOCOL_DNS 5 +#define NDPI_PROTOCOL_IPP 6 +#define NDPI_PROTOCOL_MDNS 8 +#define NDPI_PROTOCOL_NTP 9 +#define NDPI_PROTOCOL_NETBIOS 10 +#define NDPI_PROTOCOL_NFS 11 +#define NDPI_PROTOCOL_SSDP 12 +#define NDPI_PROTOCOL_BGP 13 +#define NDPI_PROTOCOL_SNMP 14 +#define NDPI_PROTOCOL_XDMCP 15 +#define NDPI_PROTOCOL_SMB 16 +#define NDPI_PROTOCOL_SYSLOG 17 +#define NDPI_PROTOCOL_DHCP 18 +#define NDPI_PROTOCOL_POSTGRES 19 +#define NDPI_PROTOCOL_MYSQL 20 +#define NDPI_PROTOCOL_TDS 21 +#define NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK 22 +#define NDPI_PROTOCOL_MAIL_POPS 23 +#define NDPI_PROTOCOL_APPLEJUICE 24 +#define NDPI_PROTOCOL_DIRECTCONNECT 25 +#define NDPI_PROTOCOL_SOCRATES 26 +#define NDPI_PROTOCOL_WINMX 27 +#define NDPI_PROTOCOL_VMWARE 28 +#define NDPI_PROTOCOL_MAIL_SMTPS 29 +#define NDPI_PROTOCOL_FILETOPIA 30 +#define NDPI_PROTOCOL_IMESH 31 +#define NDPI_PROTOCOL_KONTIKI 32 +#define NDPI_PROTOCOL_OPENFT 33 +#define NDPI_PROTOCOL_FASTTRACK 34 +#define NDPI_PROTOCOL_GNUTELLA 35 +#define NDPI_PROTOCOL_EDONKEY 36 /* Tomasz Bujlow */ +#define NDPI_PROTOCOL_BITTORRENT 37 +#define NDPI_PROTOCOL_EPP 38 +#define NDPI_PROTOCOL_XBOX 47 +#define NDPI_PROTOCOL_QQ 48 +#define NDPI_PROTOCOL_MOVE 49 +#define NDPI_PROTOCOL_RTSP 50 +#define NDPI_PROTOCOL_MAIL_IMAPS 51 +#define NDPI_PROTOCOL_ICECAST 52 +#define NDPI_PROTOCOL_PPLIVE 53 /* Tomasz Bujlow */ +#define NDPI_PROTOCOL_PPSTREAM 54 +#define NDPI_PROTOCOL_ZATTOO 55 +#define NDPI_PROTOCOL_SHOUTCAST 56 +#define NDPI_PROTOCOL_SOPCAST 57 +#define NDPI_PROTOCOL_TVANTS 58 +#define NDPI_PROTOCOL_TVUPLAYER 59 +#define NDPI_PROTOCOL_QQLIVE 61 +#define NDPI_PROTOCOL_THUNDER 62 +#define NDPI_PROTOCOL_SOULSEEK 63 +#define NDPI_PROTOCOL_IRC 65 +#define NDPI_PROTOCOL_AYIYA 66 +#define NDPI_PROTOCOL_UNENCRYPED_JABBER 67 +#define NDPI_PROTOCOL_MSN 68 +#define NDPI_PROTOCOL_OSCAR 69 +#define NDPI_PROTOCOL_YAHOO 70 +#define NDPI_PROTOCOL_BATTLEFIELD 71 +#define NDPI_PROTOCOL_QUAKE 72 +#define NDPI_PROTOCOL_STEAM 74 /* Tomasz Bujlow */ +#define NDPI_PROTOCOL_HALFLIFE2 75 +#define NDPI_PROTOCOL_WORLDOFWARCRAFT 76 +#define NDPI_PROTOCOL_TELNET 77 +#define NDPI_PROTOCOL_STUN 78 +#define NDPI_PROTOCOL_RTP 87 +#define NDPI_PROTOCOL_RDP 88 +#define NDPI_PROTOCOL_VNC 89 +#define NDPI_PROTOCOL_PCANYWHERE 90 +#define NDPI_PROTOCOL_SSH 92 +#define NDPI_PROTOCOL_USENET 93 +#define NDPI_PROTOCOL_MGCP 94 +#define NDPI_PROTOCOL_IAX 95 +#define NDPI_PROTOCOL_TFTP 96 +#define NDPI_PROTOCOL_AFP 97 +#define NDPI_PROTOCOL_STEALTHNET 98 +#define NDPI_PROTOCOL_AIMINI 99 +#define NDPI_PROTOCOL_SIP 100 +#define NDPI_PROTOCOL_TRUPHONE 101 +#define NDPI_PROTOCOL_DHCPV6 103 +#define NDPI_PROTOCOL_ARMAGETRON 104 +#define NDPI_PROTOCOL_CROSSFIRE 105 +#define NDPI_PROTOCOL_DOFUS 106 +#define NDPI_PROTOCOL_FIESTA 107 +#define NDPI_PROTOCOL_FLORENSIA 108 +#define NDPI_PROTOCOL_GUILDWARS 109 +#define NDPI_PROTOCOL_KERBEROS 111 +#define NDPI_PROTOCOL_LDAP 112 +#define NDPI_PROTOCOL_MAPLESTORY 113 +#define NDPI_PROTOCOL_MSSQL 114 +#define NDPI_PROTOCOL_PPTP 115 +#define NDPI_PROTOCOL_WARCRAFT3 116 +#define NDPI_PROTOCOL_WORLD_OF_KUNG_FU 117 +#define NDPI_PROTOCOL_MEEBO 118 +#define NDPI_PROTOCOL_DROPBOX 121 +#define NDPI_PROTOCOL_SKYPE 125 +#define NDPI_PROTOCOL_DCERPC 127 +#define NDPI_PROTOCOL_NETFLOW 128 +#define NDPI_PROTOCOL_SFLOW 129 +#define NDPI_PROTOCOL_CITRIX 132 +#define NDPI_PROTOCOL_SKYFILE_PREPAID 136 +#define NDPI_PROTOCOL_SKYFILE_RUDICS 137 +#define NDPI_PROTOCOL_SKYFILE_POSTPAID 138 +#define NDPI_PROTOCOL_CITRIX_ONLINE 139 +#define NDPI_PROTOCOL_WEBEX 141 +#define NDPI_PROTOCOL_VIBER 144 +#define NDPI_PROTOCOL_RADIUS 146 +#define NDPI_PROTOCOL_WINDOWS_UPDATE 147 /* Thierry Laurion */ +#define NDPI_PROTOCOL_TEAMVIEWER 148 /* xplico.org */ +#define NDPI_PROTOCOL_LOTUS_NOTES 150 +#define NDPI_PROTOCOL_SAP 151 +#define NDPI_PROTOCOL_GTP 152 +#define NDPI_PROTOCOL_UPNP 153 +#define NDPI_PROTOCOL_LLMNR 154 +#define NDPI_PROTOCOL_REMOTE_SCAN 155 +#define NDPI_PROTOCOL_SPOTIFY 156 +#define NDPI_PROTOCOL_H323 158 /* Remy Mudingay */ +#define NDPI_PROTOCOL_OPENVPN 159 /* Remy Mudingay */ +#define NDPI_PROTOCOL_NOE 160 /* Remy Mudingay */ +#define NDPI_PROTOCOL_CISCOVPN 161 /* Remy Mudingay */ +#define NDPI_PROTOCOL_TEAMSPEAK 162 /* Remy Mudingay */ +#define NDPI_PROTOCOL_TOR 163 /* Remy Mudingay */ +#define NDPI_PROTOCOL_SKINNY 164 /* Remy Mudingay */ +#define NDPI_PROTOCOL_RTCP 165 /* Remy Mudingay */ +#define NDPI_PROTOCOL_RSYNC 166 /* Remy Mudingay */ +#define NDPI_PROTOCOL_ORACLE 167 /* Remy Mudingay */ +#define NDPI_PROTOCOL_CORBA 168 /* Remy Mudingay */ +#define NDPI_PROTOCOL_UBUNTUONE 169 /* Remy Mudingay */ +#define NDPI_PROTOCOL_WHOIS_DAS 170 +#define NDPI_PROTOCOL_COLLECTD 171 +#define NDPI_PROTOCOL_RTMP 174 /* Tomasz Bujlow */ +#define NDPI_PROTOCOL_FTP_DATA 175 /* Tomasz Bujlow */ +#define NDPI_PROTOCOL_ZMQ 177 +#define NDPI_PROTOCOL_MEGACO 181 /* Gianluca Costa */ +#define NDPI_PROTOCOL_REDIS 182 +#define NDPI_PROTOCOL_PANDO 183 /* Tomasz Bujlow */ +#define NDPI_PROTOCOL_VHUA 184 +#define NDPI_PROTOCOL_TELEGRAM 185 /* Gianluca Costa */ + + +#define NDPI_CONTENT_AVI 39 +#define NDPI_CONTENT_FLASH 40 +#define NDPI_CONTENT_OGG 41 +#define NDPI_CONTENT_MPEG 42 +#define NDPI_CONTENT_QUICKTIME 43 +#define NDPI_CONTENT_REALMEDIA 44 +#define NDPI_CONTENT_WINDOWSMEDIA 45 +#define NDPI_CONTENT_MMS 46 +#define NDPI_CONTENT_WEBM 157 + +#define NDPI_SERVICE_FACEBOOK 119 +#define NDPI_SERVICE_TWITTER 120 +#define NDPI_SERVICE_GMAIL 122 +#define NDPI_SERVICE_GOOGLE_MAPS 123 +#define NDPI_SERVICE_YOUTUBE 124 +#define NDPI_SERVICE_VEVO 188 +#define NDPI_SERVICE_GOOGLE 126 +#define NDPI_SERVICE_NETFLIX 133 +#define NDPI_SERVICE_LASTFM 134 +#define NDPI_SERVICE_GROOVESHARK 135 +#define NDPI_SERVICE_APPLE 140 +#define NDPI_SERVICE_WHATSAPP 142 +#define NDPI_SERVICE_APPLE_ICLOUD 143 +#define NDPI_SERVICE_APPLE_ITUNES 145 +#define NDPI_SERVICE_TUENTI 149 +#define NDPI_SERVICE_WIKIPEDIA 176 /* Tomasz Bujlow */ +#define NDPI_SERVICE_MSN NDPI_PROTOCOL_MSN /* Tomasz Bujlow */ +#define NDPI_SERVICE_AMAZON 178 /* Tomasz Bujlow */ +#define NDPI_SERVICE_EBAY 179 /* Tomasz Bujlow */ +#define NDPI_SERVICE_CNN 180 /* Tomasz Bujlow */ +#define NDPI_SERVICE_DROPBOX NDPI_PROTOCOL_DROPBOX /* Tomasz Bujlow */ +#define NDPI_SERVICE_SKYPE NDPI_PROTOCOL_SKYPE /* Tomasz Bujlow */ +#define NDPI_SERVICE_VIBER NDPI_PROTOCOL_VIBER /* Tomasz Bujlow */ +#define NDPI_SERVICE_YAHOO NDPI_PROTOCOL_YAHOO /* Tomasz Bujlow */ +#define NDPI_SERVICE_FACEBOOK_CHAT 186 +#define NDPI_SERVICE_PANDORA 187 + +/* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE (NDPI_SERVICE_VEVO) */ +#define NDPI_LAST_IMPLEMENTED_PROTOCOL 188 + +#define NDPI_MAX_SUPPORTED_PROTOCOLS (NDPI_LAST_IMPLEMENTED_PROTOCOL + 1) +#define NDPI_MAX_NUM_CUSTOM_PROTOCOLS (NDPI_NUM_BITS-NDPI_LAST_IMPLEMENTED_PROTOCOL) +#endif diff --git a/src/include/ndpi_protocols.h b/src/include/ndpi_protocols.h new file mode 100644 index 000000000..5ab0da83a --- /dev/null +++ b/src/include/ndpi_protocols.h @@ -0,0 +1,181 @@ +/* + * ndpi_protocols.h + * + * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2009-2011 by 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 . + * + */ + + +#ifndef __NDPI_PROTOCOLS_INCLUDE_FILE__ +#define __NDPI_PROTOCOLS_INCLUDE_FILE__ + +#include "ndpi_main.h" + + +/* TCP/UDP protocols */ +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, + u_int16_t sport, u_int16_t dport); + +void ndpi_search_tcp_or_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); + +/* Applications and other protocols. */ +void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_bittorrent_init(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t size,u_int32_t timeout); +void ndpi_bittorrent_done(struct ndpi_detection_module_struct *ndpi_struct); +int ndpi_bittorrent_gc(struct hash_ip4p_table *ht,int key,time_t now); + +void ndpi_search_edonkey(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_fasttrack_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_winmx_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_directconnect(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_applejuice_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_i23v5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_socrates(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_soulseek_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_msn(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_yahoo(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_oscar(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_jabber_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_irc_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_sip(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_direct_download_link_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_mail_pop_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_http_subprotocol_conf(struct ndpi_detection_module_struct *ndpi_struct, char *attr, char *value, int protocol_id); +void ndpi_search_ftp_control(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_ftp_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_usenet_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_rtsp_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_filetopia_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_vmware(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_imesh_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_mms_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_icecast_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_shoutcast_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_veohtv_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_openft_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_tvants_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_sopcast(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_tvuplayer(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_ppstream(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_pplive(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_iax(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_mgcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_zattoo(struct ndpi_detection_module_struct*ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_qq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_feidian(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_ayiya(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_thunder(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_activesync(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_in_non_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_vnc_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_steam(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_halflife2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_xbox(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_smb_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_telnet_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_ntp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_nfs(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_rtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_ssdp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_worldofwarcraft(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_postgres_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_mysql_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_bgp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_quake(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_battlefield(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_secondlife(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_pcanywhere(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_rdp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_snmp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_kontiki(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_syslog(struct ndpi_detection_module_struct*ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_tds_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_netbios(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_mdns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_ipp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_ldap(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_warcraft3(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_xdmcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_mssql(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_pptp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_stealthnet(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_dhcpv6_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_meebo(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_afp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_aimini(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_florensia(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_maplestory(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_dofus(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_world_of_kung_fu(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_fiesta(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_crossfire_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_guildwars_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_armagetron_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_dropbox(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_skype(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_citrix(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_dcerpc(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_netflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_sflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_radius(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_wsus(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_teamview(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_lotus_notes(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_gtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_spotify(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_openvpn(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_noe(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_ciscovpn(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_viber(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_teamspeak(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_corba(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_collectd(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_oracle(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_rsync(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_rtcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_skinny(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_tor(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_whois_das(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_socks5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_socks4(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_rtmp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_pando(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_megaco(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_redis(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_twitter(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_vhua(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_telegram(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); + +#endif /* __NDPI_PROTOCOLS_INCLUDE_FILE__ */ diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h new file mode 100644 index 000000000..5bdd5a6e6 --- /dev/null +++ b/src/include/ndpi_typedefs.h @@ -0,0 +1,852 @@ +/* + * ndpi_typedefs.h + * + * 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 . + * + */ + +#ifndef __NDPI_TYPEDEFS_FILE__ +#define __NDPI_TYPEDEFS_FILE__ + +typedef enum { + NDPI_LOG_ERROR, + NDPI_LOG_TRACE, + NDPI_LOG_DEBUG +} ndpi_log_level_t; + +typedef void (*ndpi_debug_function_ptr) (u_int32_t protocol, + void *module_struct, ndpi_log_level_t log_level, + const char *format, ...); +#define BT_ANNOUNCE + +typedef enum { + ndpi_preorder, + ndpi_postorder, + ndpi_endorder, + ndpi_leaf +} ndpi_VISIT; + +typedef struct node_t { + char *key; + struct node_t *left, *right; +} ndpi_node; + +typedef u_int32_t ndpi_ndpi_mask; + +typedef struct ndpi_protocol_bitmask_struct { + ndpi_ndpi_mask fds_bits[NDPI_NUM_FDS_BITS]; +} ndpi_protocol_bitmask_struct_t; + +#ifdef NDPI_DETECTION_SUPPORT_IPV6 +struct ndpi_ip6_addr { + union { + u_int8_t u6_addr8[16]; + u_int16_t u6_addr16[8]; + u_int32_t u6_addr32[4]; + u_int64_t u6_addr64[2]; + } ndpi_v6_u; + +#define ndpi_v6_addr ndpi_v6_u.u6_addr8 +#define ndpi_v6_addr16 ndpi_v6_u.u6_addr16 +#define ndpi_v6_addr32 ndpi_v6_u.u6_addr32 +#define ndpi_v6_addr64 ndpi_v6_u.u6_addr64 +}; + +struct ndpi_ipv6hdr { + /* use userspace and kernelspace compatible compile parameters */ +#if defined(__LITTLE_ENDIAN__) + u_int8_t priority:4, version:4; +#elif defined(__BIG_ENDIAN__) + u_int8_t version:4, priority:4; +#else +# error "Byte order must be defined" +#endif + + u_int8_t flow_lbl[3]; + + u_int16_t payload_len; + u_int8_t nexthdr; + u_int8_t hop_limit; + + struct ndpi_ip6_addr saddr; + struct ndpi_ip6_addr daddr; +}; +#endif /* NDPI_DETECTION_SUPPORT_IPV6 */ + +typedef union { + u_int32_t ipv4; + u_int8_t ipv4_u_int8_t[4]; +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + struct ndpi_ip6_addr ipv6; +#endif +} ndpi_ip_addr_t; + + +#ifdef NDPI_PROTOCOL_BITTORRENT +#ifndef __KERNEL__ +typedef struct spinlock { + volatile int val; +} spinlock_t; +typedef struct atomic { + volatile int counter; +} atomic_t; + +#endif + +struct hash_ip4p_node { + struct hash_ip4p_node *next,*prev; + time_t lchg; + u_int16_t port,count:12,flag:4; + u_int32_t ip; + // + 12 bytes for ipv6 +}; + +struct hash_ip4p { + struct hash_ip4p_node *top; + spinlock_t lock; + size_t len; +}; + +struct hash_ip4p_table { + size_t size; + int ipv6; + spinlock_t lock; + atomic_t count; + struct hash_ip4p tbl[0]; +}; + +struct bt_announce { // 192 bytes + u_int32_t hash[5]; + u_int32_t ip[4]; + u_int32_t time; + u_int16_t port; + u_int8_t name_len, + name[192 - 4*10 - 2 - 1]; // 149 bytes +}; +#endif + +typedef enum { + HTTP_METHOD_UNKNOWN = 0, + HTTP_METHOD_OPTIONS, + HTTP_METHOD_GET, + HTTP_METHOD_HEAD, + HTTP_METHOD_POST, + HTTP_METHOD_PUT, + HTTP_METHOD_DELETE, + HTTP_METHOD_TRACE, + HTTP_METHOD_CONNECT +} ndpi_http_method; + +typedef struct ndpi_id_struct { + /* detected_protocol_bitmask: + * access this bitmask to find out whether an id has used skype or not + * if a flag is set here, it will not be resetted + * to compare this, use: + * if (NDPI_BITMASK_COMPARE(id->detected_protocol_bitmask, + * NDPI_PROTOCOL_BITMASK_XXX) != 0) + * { + * // protocol XXX detected on this id + * } + */ + NDPI_PROTOCOL_BITMASK detected_protocol_bitmask; +#ifdef NDPI_PROTOCOL_RTSP + ndpi_ip_addr_t rtsp_ip_address; +#endif +#ifdef NDPI_PROTOCOL_SIP +#ifdef NDPI_PROTOCOL_YAHOO + u_int32_t yahoo_video_lan_timer; +#endif +#endif +/* NDPI_PROTOCOL_IRC_MAXPORT % 2 must be 0 */ +#ifdef NDPI_PROTOCOL_IRC +#define NDPI_PROTOCOL_IRC_MAXPORT 8 + u_int16_t irc_port[NDPI_PROTOCOL_IRC_MAXPORT]; + u_int32_t last_time_port_used[NDPI_PROTOCOL_IRC_MAXPORT]; + u_int32_t irc_ts; +#endif +#ifdef NDPI_PROTOCOL_GNUTELLA + u_int32_t gnutella_ts; +#endif +#ifdef NDPI_PROTOCOL_BATTLEFIELD + u_int32_t battlefield_ts; +#endif +#ifdef NDPI_PROTOCOL_THUNDER + u_int32_t thunder_ts; +#endif +#ifdef NDPI_PROTOCOL_RTSP + u_int32_t rtsp_timer; +#endif +#ifdef NDPI_PROTOCOL_OSCAR + u_int32_t oscar_last_safe_access_time; +#endif +#ifdef NDPI_PROTOCOL_ZATTOO + u_int32_t zattoo_ts; +#endif +#ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER + u_int32_t jabber_stun_or_ft_ts; +#endif +#ifdef NDPI_PROTOCOL_DIRECTCONNECT + u_int32_t directconnect_last_safe_access_time; +#endif +#ifdef NDPI_PROTOCOL_SOULSEEK + u_int32_t soulseek_last_safe_access_time; +#endif +#ifdef NDPI_PROTOCOL_DIRECTCONNECT + u_int16_t detected_directconnect_port; + u_int16_t detected_directconnect_udp_port; + u_int16_t detected_directconnect_ssl_port; +#endif +#ifdef NDPI_PROTOCOL_BITTORRENT +#define NDPI_BT_PORTS 8 + u_int16_t bt_port_t[NDPI_BT_PORTS]; + u_int16_t bt_port_u[NDPI_BT_PORTS]; +#endif +#ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER +#define JABBER_MAX_STUN_PORTS 6 + u_int16_t jabber_voice_stun_port[JABBER_MAX_STUN_PORTS]; + u_int16_t jabber_file_transfer_port[2]; +#endif +#ifdef NDPI_PROTOCOL_GNUTELLA + u_int16_t detected_gnutella_port; +#endif +#ifdef NDPI_PROTOCOL_GNUTELLA + u_int16_t detected_gnutella_udp_port1; + u_int16_t detected_gnutella_udp_port2; +#endif +#ifdef NDPI_PROTOCOL_SOULSEEK + u_int16_t soulseek_listen_port; +#endif +#ifdef NDPI_PROTOCOL_IRC + u_int8_t irc_number_of_port; +#endif +#ifdef NDPI_PROTOCOL_OSCAR + u_int8_t oscar_ssl_session_id[33]; +#endif +#ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER + u_int8_t jabber_voice_stun_used_ports; +#endif +#ifdef NDPI_PROTOCOL_SIP +#ifdef NDPI_PROTOCOL_YAHOO + u_int32_t yahoo_video_lan_dir:1; +#endif +#endif +#ifdef NDPI_PROTOCOL_YAHOO + u_int32_t yahoo_conf_logged_in:1; + u_int32_t yahoo_voice_conf_logged_in:1; +#endif +#ifdef NDPI_PROTOCOL_RTSP + u_int32_t rtsp_ts_set:1; +#endif +} ndpi_id_struct; + +/* ************************************************** */ + +struct ndpi_flow_tcp_struct { +#ifdef NDPI_PROTOCOL_MAIL_SMTP + u_int16_t smtp_command_bitmask; +#endif +#ifdef NDPI_PROTOCOL_MAIL_POP + u_int16_t pop_command_bitmask; +#endif +#ifdef NDPI_PROTOCOL_QQ + u_int16_t qq_nxt_len; +#endif +#ifdef NDPI_PROTOCOL_TDS + u_int8_t tds_login_version; +#endif +#ifdef NDPI_PROTOCOL_IRC + u_int8_t irc_stage; + u_int8_t irc_port; +#endif +#ifdef NDPI_PROTOCOL_H323 + u_int8_t h323_valid_packets; +#endif +#ifdef NDPI_PROTOCOL_GNUTELLA + u_int8_t gnutella_msg_id[3]; +#endif +#ifdef NDPI_PROTOCOL_IRC + u_int32_t irc_3a_counter:3; + u_int32_t irc_stage2:5; + u_int32_t irc_direction:2; + u_int32_t irc_0x1000_full:1; +#endif +#ifdef NDPI_PROTOCOL_WINMX + u_int32_t winmx_stage:1; // 0-1 +#endif +#ifdef NDPI_PROTOCOL_SOULSEEK + u_int32_t soulseek_stage:2; +#endif +#ifdef NDPI_PROTOCOL_FILETOPIA + u_int32_t filetopia_stage:2; +#endif +#ifdef NDPI_PROTOCOL_TDS + u_int32_t tds_stage:3; +#endif +#ifdef NDPI_PROTOCOL_USENET + u_int32_t usenet_stage:2; +#endif +#ifdef NDPI_PROTOCOL_IMESH + u_int32_t imesh_stage:4; +#endif +#ifdef NDPI_PROTOCOL_HTTP + u_int32_t http_setup_dir:2; + u_int32_t http_stage:2; + u_int32_t http_empty_line_seen:1; + u_int32_t http_wait_for_retransmission:1; +#endif // NDPI_PROTOCOL_HTTP +#ifdef NDPI_PROTOCOL_GNUTELLA + u_int32_t gnutella_stage:2; //0-2 +#endif +#ifdef NDPI_CONTENT_MMS + u_int32_t mms_stage:2; +#endif +#ifdef NDPI_PROTOCOL_YAHOO + u_int32_t yahoo_sip_comm:1; + u_int32_t yahoo_http_proxy_stage:2; +#endif +#ifdef NDPI_PROTOCOL_MSN + u_int32_t msn_stage:3; + u_int32_t msn_ssl_ft:2; +#endif +#ifdef NDPI_PROTOCOL_SSH + u_int32_t ssh_stage:3; +#endif +#ifdef NDPI_PROTOCOL_VNC + u_int32_t vnc_stage:2; // 0 - 3 +#endif +#ifdef NDPI_PROTOCOL_TELNET + u_int32_t telnet_stage:2; // 0 - 2 +#endif +#ifdef NDPI_PROTOCOL_SSL + u_int8_t ssl_stage:2, ssl_seen_client_cert:1, ssl_seen_server_cert:1; // 0 - 5 +#endif +#ifdef NDPI_PROTOCOL_POSTGRES + u_int32_t postgres_stage:3; +#endif +#ifdef NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK + u_int32_t ddlink_server_direction:1; +#endif + u_int32_t seen_syn:1; + u_int32_t seen_syn_ack:1; + u_int32_t seen_ack:1; +#ifdef NDPI_PROTOCOL_ICECAST + u_int32_t icecast_stage:1; +#endif +#ifdef NDPI_PROTOCOL_DOFUS + u_int32_t dofus_stage:1; +#endif +#ifdef NDPI_PROTOCOL_FIESTA + u_int32_t fiesta_stage:2; +#endif +#ifdef NDPI_PROTOCOL_WORLDOFWARCRAFT + u_int32_t wow_stage:2; +#endif +#ifdef NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV + u_int32_t veoh_tv_stage:2; +#endif +#ifdef NDPI_PROTOCOL_SHOUTCAST + u_int32_t shoutcast_stage:2; +#endif +#ifdef NDPI_PROTOCOL_RTP + u_int32_t rtp_special_packets_seen:1; +#endif +#ifdef NDPI_PROTOCOL_MAIL_POP + u_int32_t mail_pop_stage:2; +#endif +#ifdef NDPI_PROTOCOL_MAIL_IMAP + u_int32_t mail_imap_stage:3; +#endif + +#ifdef NDPI_PROTOCOL_SKYPE + u_int8_t skype_packet_id; +#endif + +#ifdef NDPI_PROTOCOL_CITRIX + u_int8_t citrix_packet_id; +#endif + +#ifdef NDPI_PROTOCOL_LOTUS_NOTES + u_int8_t lotus_notes_packet_id; +#endif + +#ifdef NDPI_PROTOCOL_TEAMVIEWER + u_int8_t teamviewer_stage; +#endif + +#ifdef NDPI_PROTOCOL_ZMQ + u_int8_t prev_zmq_pkt_len; + u_char prev_zmq_pkt[10]; +#endif +} +#if !defined(WIN32) + __attribute__ ((__packed__)) +#endif + ; + +/* ************************************************** */ + +struct ndpi_flow_udp_struct { +#ifdef NDPI_PROTOCOL_BATTLEFIELD + u_int32_t battlefield_msg_id; +#endif +#ifdef NDPI_PROTOCOL_SNMP + u_int32_t snmp_msg_id; +#endif +#ifdef NDPI_PROTOCOL_BATTLEFIELD + u_int32_t battlefield_stage:3; +#endif +#ifdef NDPI_PROTOCOL_SNMP + u_int32_t snmp_stage:2; +#endif +#ifdef NDPI_PROTOCOL_PPSTREAM + u_int32_t ppstream_stage:3; // 0-7 +#endif +#ifdef NDPI_PROTOCOL_HALFLIFE2 + u_int32_t halflife2_stage:2; // 0 - 2 +#endif +#ifdef NDPI_PROTOCOL_TFTP + u_int32_t tftp_stage:1; +#endif +#ifdef NDPI_PROTOCOL_AIMINI + u_int32_t aimini_stage:5; +#endif +#ifdef NDPI_PROTOCOL_XBOX + u_int32_t xbox_stage:1; +#endif +#ifdef NDPI_PROTOCOL_WINDOWS_UPDATE + u_int32_t wsus_stage:1; +#endif +#ifdef NDPI_PROTOCOL_SKYPE + u_int8_t skype_packet_id; +#endif +#ifdef NDPI_PROTOCOL_TEAMVIEWER + u_int8_t teamviewer_stage; +#endif +} +#if !defined(WIN32) + __attribute__ ((__packed__)) +#endif + ; + +/* ************************************************** */ + +typedef struct ndpi_int_one_line_struct { + const u_int8_t *ptr; + u_int16_t len; +} ndpi_int_one_line_struct_t; + +typedef struct ndpi_packet_struct { + const struct ndpi_iphdr *iph; +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + const struct ndpi_ipv6hdr *iphv6; +#endif + const struct ndpi_tcphdr *tcp; + const struct ndpi_udphdr *udp; + const u_int8_t *generic_l4_ptr; /* is set only for non tcp-udp traffic */ + const u_int8_t *payload; + + u_int32_t tick_timestamp; + u_int64_t tick_timestamp_l; + + u_int16_t detected_protocol_stack[NDPI_PROTOCOL_HISTORY_SIZE]; + u_int8_t detected_subprotocol_stack[NDPI_PROTOCOL_HISTORY_SIZE]; + + /* this is for simple read-only access to the real protocol + * used for the main loop */ + u_int16_t real_protocol_read_only; + +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 +# if NDPI_PROTOCOL_HISTORY_SIZE > 5 +# error protocol stack size not supported +# endif + + struct { + u_int8_t entry_is_real_protocol:5; + u_int8_t current_stack_size_minus_one:3; + } +#if !defined(WIN32) + __attribute__ ((__packed__)) +#endif + protocol_stack_info; +#endif + + struct ndpi_int_one_line_struct line[NDPI_MAX_PARSE_LINES_PER_PACKET]; + struct ndpi_int_one_line_struct host_line; + struct ndpi_int_one_line_struct forwarded_line; + struct ndpi_int_one_line_struct referer_line; + struct ndpi_int_one_line_struct content_line; + struct ndpi_int_one_line_struct accept_line; + struct ndpi_int_one_line_struct user_agent_line; + struct ndpi_int_one_line_struct http_url_name; + struct ndpi_int_one_line_struct http_encoding; + struct ndpi_int_one_line_struct http_transfer_encoding; + struct ndpi_int_one_line_struct http_contentlen; + struct ndpi_int_one_line_struct http_cookie; + struct ndpi_int_one_line_struct http_origin; + struct ndpi_int_one_line_struct http_x_session_type; + struct ndpi_int_one_line_struct server_line; + struct ndpi_int_one_line_struct http_method; + struct ndpi_int_one_line_struct http_response; + + u_int16_t l3_packet_len; + u_int16_t l4_packet_len; + u_int16_t payload_packet_len; + u_int16_t actual_payload_len; + u_int16_t num_retried_bytes; + u_int16_t parsed_lines; + u_int16_t parsed_unix_lines; + u_int16_t empty_line_position; + u_int8_t tcp_retransmission; + u_int8_t l4_protocol; + + u_int8_t ssl_certificate_detected:4, ssl_certificate_num_checks:4; + u_int8_t packet_lines_parsed_complete:1, + packet_direction:1, + empty_line_position_set:1; +} ndpi_packet_struct_t; + +struct ndpi_detection_module_struct; +struct ndpi_flow_struct; + +typedef struct ndpi_call_function_struct { + NDPI_PROTOCOL_BITMASK detection_bitmask; + NDPI_PROTOCOL_BITMASK excluded_protocol_bitmask; + NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_bitmask; + void (*func) (struct ndpi_detection_module_struct *, struct ndpi_flow_struct *flow); + u_int8_t detection_feature; +} ndpi_call_function_struct_t; + +typedef struct ndpi_subprotocol_conf_struct { + void (*func) (struct ndpi_detection_module_struct *, char *attr, char *value, int protocol_id); +} ndpi_subprotocol_conf_struct_t; + + +typedef struct { + u_int16_t port_low, port_high; +} ndpi_port_range; + +typedef enum { + NDPI_PROTOCOL_SAFE = 0, /* Safe protocol with encryption */ + NDPI_PROTOCOL_ACCEPTABLE, /* Ok but not encrypted */ + NDPI_PROTOCOL_FUN, /* Pure fun protocol */ + NDPI_PROTOCOL_UNSAFE, /* Protocol with a safe version existing what should be used instead */ + NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, /* Be prepared to troubles */ + NDPI_PROTOCOL_UNRATED /* No idea */ +} ndpi_protocol_breed_t; + +#define NUM_BREEDS (NDPI_PROTOCOL_UNRATED+1) + +/* ntop extensions */ +typedef struct ndpi_proto_defaults { + char *protoName; + u_int16_t protoId, protoIdx; + u_int16_t master_tcp_protoId[2], master_udp_protoId[2]; /* The main protocols on which this sub-protocol sits on */ + ndpi_protocol_breed_t protoBreed; + void (*func) (struct ndpi_detection_module_struct *, struct ndpi_flow_struct *flow); +} ndpi_proto_defaults_t; + +typedef struct ndpi_default_ports_tree_node { + ndpi_proto_defaults_t *proto; + u_int16_t default_port; +} ndpi_default_ports_tree_node_t; + +typedef struct _ndpi_automa { + void *ac_automa; /* Real type is AC_AUTOMATA_t */ + u_int8_t ac_automa_finalized; +} ndpi_automa; + +typedef struct ndpi_detection_module_struct { + NDPI_PROTOCOL_BITMASK detection_bitmask; + NDPI_PROTOCOL_BITMASK generic_http_packet_bitmask; + + u_int32_t current_ts; + u_int32_t ticks_per_second; + +#ifdef NDPI_ENABLE_DEBUG_MESSAGES + void *user_data; +#endif + /* callback function buffer */ + struct ndpi_call_function_struct callback_buffer[NDPI_MAX_SUPPORTED_PROTOCOLS + 1]; + u_int32_t callback_buffer_size; + + struct ndpi_call_function_struct callback_buffer_tcp_no_payload[NDPI_MAX_SUPPORTED_PROTOCOLS + 1]; + u_int32_t callback_buffer_size_tcp_no_payload; + + struct ndpi_call_function_struct callback_buffer_tcp_payload[NDPI_MAX_SUPPORTED_PROTOCOLS + 1]; + u_int32_t callback_buffer_size_tcp_payload; + + struct ndpi_call_function_struct callback_buffer_udp[NDPI_MAX_SUPPORTED_PROTOCOLS + 1]; + u_int32_t callback_buffer_size_udp; + + struct ndpi_call_function_struct callback_buffer_non_tcp_udp[NDPI_MAX_SUPPORTED_PROTOCOLS + 1]; + u_int32_t callback_buffer_size_non_tcp_udp; + + ndpi_default_ports_tree_node_t *tcpRoot, *udpRoot; + +#ifdef NDPI_ENABLE_DEBUG_MESSAGES + /* debug callback, only set when debug is used */ + ndpi_debug_function_ptr ndpi_debug_printf; + const char *ndpi_debug_print_file; + const char *ndpi_debug_print_function; + u_int32_t ndpi_debug_print_line; +#endif + /* misc parameters */ + u_int32_t tcp_max_retransmission_window_size; + + u_int32_t directconnect_connection_ip_tick_timeout; + + /* subprotocol registration handler */ + struct ndpi_subprotocol_conf_struct subprotocol_conf[NDPI_MAX_SUPPORTED_PROTOCOLS + 1]; + + u_int ndpi_num_supported_protocols; + u_int ndpi_num_custom_protocols; + + /* HTTP/DNS/HTTPS host matching */ + ndpi_automa host_automa, content_automa, bigrams_automa, impossible_bigrams_automa; + + /* IP-based protocol detection */ + void *protocols_ptree; + + /* irc parameters */ + u_int32_t irc_timeout; + /* gnutella parameters */ + u_int32_t gnutella_timeout; + /* battlefield parameters */ + u_int32_t battlefield_timeout; + /* thunder parameters */ + u_int32_t thunder_timeout; + /* SoulSeek parameters */ + u_int32_t soulseek_connection_ip_tick_timeout; + /* rtsp parameters */ + u_int32_t rtsp_connection_timeout; + /* tvants parameters */ + u_int32_t tvants_connection_timeout; + u_int32_t orb_rstp_ts_timeout; + /* yahoo */ + // u_int32_t yahoo_http_filetransfer_timeout; + u_int8_t yahoo_detect_http_connections; + u_int32_t yahoo_lan_video_timeout; + u_int32_t zattoo_connection_timeout; + u_int32_t jabber_stun_timeout; + u_int32_t jabber_file_transfer_timeout; +#ifdef NDPI_ENABLE_DEBUG_MESSAGES +#define NDPI_IP_STRING_SIZE 40 + char ip_string[NDPI_IP_STRING_SIZE]; +#endif + u_int8_t ip_version_limit; + /* ********************* */ +#ifdef NDPI_PROTOCOL_BITTORRENT + struct hash_ip4p_table *bt_ht; +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + struct hash_ip4p_table *bt6_ht; +#endif +#ifdef BT_ANNOUNCE + struct bt_announce *bt_ann; + int bt_ann_len; +#endif +#endif + + ndpi_proto_defaults_t proto_defaults[NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS]; + + u_int8_t match_dns_host_names:1, http_dissect_response:1; + u_int8_t direction_detect_disable:1; /* disable internal detection of packet direction */ +} ndpi_detection_module_struct_t; + +typedef struct ndpi_flow_struct { + u_int16_t detected_protocol_stack[NDPI_PROTOCOL_HISTORY_SIZE]; +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 +# if NDPI_PROTOCOL_HISTORY_SIZE > 5 +# error protocol stack size not supported +# endif + + struct { + u_int8_t entry_is_real_protocol:5; + u_int8_t current_stack_size_minus_one:3; + } + +#if !defined(WIN32) + __attribute__ ((__packed__)) +#endif + protocol_stack_info; +#endif + + /* init parameter, internal used to set up timestamp,... */ + u_int16_t guessed_protocol_id; + + u_int8_t protocol_id_already_guessed:1; + u_int8_t no_cache_protocol:1; + u_int8_t init_finished:1; + u_int8_t setup_packet_direction:1; + u_int8_t packet_direction:1; /* if ndpi_struct->direction_detect_disable == 1 */ + /* tcp sequence number connection tracking */ + u_int32_t next_tcp_seq_nr[2]; + + /* the tcp / udp / other l4 value union + * this is used to reduce the number of bytes for tcp or udp protocol states + * */ + union { + struct ndpi_flow_tcp_struct tcp; + struct ndpi_flow_udp_struct udp; + } l4; + + struct ndpi_id_struct *server_id; /* + Pointer to src or dst + that identifies the + server of this connection + */ +#ifndef __KERNEL__ + u_char host_server_name[256]; /* HTTP host or DNS query */ +#else + u_char host_server_name[160]; +#endif + u_char detected_os[32]; /* Via HTTP User-Agent */ + u_char nat_ip[24]; /* Via HTTP X-Forwarded-For */ + + /* + This structure below will not not stay inside the protos + structure below as HTTP is used by many subprotocols + such as FaceBook, Google... so it is hard to know + when to use it or not. Thus we leave it outside for the + time being. + */ + struct { + ndpi_http_method method; + char *url, *content_type; + } http; + + union { + struct { + u_int8_t num_queries, num_answers, ret_code; + u_int8_t bad_packet /* the received packet looks bad */; + u_int16_t query_type, query_class, rsp_type; + } dns; + + struct { + char client_certificate[48], server_certificate[48]; + } ssl; + } protos; + /* ALL protocol specific 64 bit variables here */ + + /* protocols which have marked a connection as this connection cannot be protocol XXX, multiple u_int64_t */ + NDPI_PROTOCOL_BITMASK excluded_protocol_bitmask; + +#if 0 +#ifdef NDPI_PROTOCOL_RTP + u_int32_t rtp_ssid[2]; + u_int16_t rtp_seqnum[2]; /* current highest sequence number (only goes forwards, is not decreased by retransmissions) */ + /* tcp and udp */ + u_int8_t rtp_payload_type[2]; + u_int32_t rtp_stage1:2; //0-3 + u_int32_t rtp_stage2:2; +#endif +#endif + +#ifdef NDPI_PROTOCOL_REDIS + u_int8_t redis_s2d_first_char, redis_d2s_first_char; +#endif + + u_int16_t packet_counter; // can be 0-65000 + u_int16_t packet_direction_counter[2]; + u_int16_t byte_counter[2]; + +#ifdef NDPI_PROTOCOL_BITTORRENT + u_int8_t bittorrent_stage; // can be 0-255 +#endif +#ifdef NDPI_PROTOCOL_DIRECTCONNECT + u_int32_t directconnect_stage:2; // 0-1 +#endif +#ifdef NDPI_PROTOCOL_SIP +#ifdef NDPI_PROTOCOL_YAHOO + u_int32_t sip_yahoo_voice:1; +#endif +#endif +#ifdef NDPI_PROTOCOL_HTTP + u_int32_t http_detected:1; +#endif // NDPI_PROTOCOL_HTTP +#ifdef NDPI_PROTOCOL_RTSP + u_int32_t rtsprdt_stage:2; + u_int32_t rtsp_control_flow:1; +#endif + +#ifdef NDPI_PROTOCOL_YAHOO + u_int32_t yahoo_detection_finished:2; +#endif +#ifdef NDPI_PROTOCOL_ZATTOO + u_int32_t zattoo_stage:3; +#endif +#ifdef NDPI_PROTOCOL_QQ + u_int32_t qq_stage:3; +#endif +#ifdef NDPI_PROTOCOL_THUNDER + u_int32_t thunder_stage:2; // 0-3 +#endif +#ifdef NDPI_PROTOCOL_OSCAR + u_int32_t oscar_ssl_voice_stage:3; + u_int32_t oscar_video_voice:1; +#endif +#ifdef NDPI_PROTOCOL_FLORENSIA + u_int32_t florensia_stage:1; +#endif +#ifdef NDPI_PROTOCOL_SOCKS5 + u_int32_t socks5_stage:2; // 0-3 +#endif +#ifdef NDPI_PROTOCOL_SOCKS4 + u_int32_t socks4_stage:2; // 0-3 +#endif +#ifdef NDPI_PROTOCOL_EDONKEY + u_int32_t edonkey_stage:2; // 0-3 +#endif +#ifdef NDPI_PROTOCOL_FTP_CONTROL + u_int32_t ftp_control_stage:2; +#endif +#ifdef NDPI_PROTOCOL_FTP_DATA + u_int32_t ftp_data_stage:2; +#endif +#ifdef NDPI_PROTOCOL_RTMP + u_int32_t rtmp_stage:2; +#endif +#ifdef NDPI_PROTOCOL_PANDO + u_int32_t pando_stage:3; +#endif +#ifdef NDPI_PROTOCOL_STEAM + u_int32_t steam_stage:3; + u_int32_t steam_stage1:3; // 0 - 4 + u_int32_t steam_stage2:2; // 0 - 2 + u_int32_t steam_stage3:2; // 0 - 2 +#endif +#ifdef NDPI_PROTOCOL_PPLIVE + u_int32_t pplive_stage1:3; // 0-6 + u_int32_t pplive_stage2:2; // 0-2 + u_int32_t pplive_stage3:2; // 0-2 +#endif + + /* internal structures to save functions calls */ + struct ndpi_packet_struct packet; + struct ndpi_flow_struct *flow; + struct ndpi_id_struct *src; + struct ndpi_id_struct *dst; +} ndpi_flow_struct_t; + +typedef enum { + NDPI_REAL_PROTOCOL = 0, + NDPI_CORRELATED_PROTOCOL = 1 +} ndpi_protocol_type_t; + +#endif/* __NDPI_TYPEDEFS_FILE__ */ diff --git a/src/include/ndpi_unix.h b/src/include/ndpi_unix.h new file mode 100644 index 000000000..79de7b43c --- /dev/null +++ b/src/include/ndpi_unix.h @@ -0,0 +1,53 @@ +/* + * ndpi_unix.h + * + * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2009-2011 by 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 . + * + */ + +#ifndef __NDPI_UNIX_INCLUDE_FILE__ +#define __NDPI_UNIX_INCLUDE_FILE__ + +#include "linux_compat.h" + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include +#if defined(__NetBSD__) || defined(__OpenBSD__) +#include +#if defined(__OpenBSD__) +#include +#endif +#endif +#endif + +#ifndef WIN32 +#ifndef __KERNEL__ + +#include +#include +#include +#else +#include +#include +#include +#endif +#endif + +#endif /* __NDPI_UNIX_INCLUDE_FILE__ */ diff --git a/src/include/ndpi_win32.h b/src/include/ndpi_win32.h new file mode 100644 index 000000000..3b568beb9 --- /dev/null +++ b/src/include/ndpi_win32.h @@ -0,0 +1,73 @@ +/* + * ndpi_win32.h + * + * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2009-2011 by 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 . + * + */ + +#ifndef __NDPI_WIN32_INCLUDE_FILE__ +#define __NDPI_WIN32_INCLUDE_FILE__ + +#ifdef WIN32 +#include /* winsock.h is included automatically */ +#include +#include +#include /* getopt from: http://www.pwilson.net/sample.html. */ +#include /* for getpid() and the exec..() family */ + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif +#define snprintf _snprintf + +extern char* strsep(char **stringp, const char *delim); + +#define __attribute__(x) +#include +#ifndef __GNUC__ +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int uint; +typedef unsigned long u_long; +#endif +typedef u_char u_int8_t; +typedef u_short u_int16_t; +typedef unsigned int u_int32_t; +typedef unsigned __int64 u_int64_t; + + +#define pthread_t HANDLE +#define pthread_mutex_t HANDLE +#define pthread_rwlock_t pthread_mutex_t +#define pthread_rwlock_init pthread_mutex_init +#define pthread_rwlock_wrlock pthread_mutex_lock +#define pthread_rwlock_rdlock pthread_mutex_lock +#define pthread_rwlock_unlock pthread_mutex_unlock +#define pthread_rwlock_destroy pthread_mutex_destroy + +#define gmtime_r(a, b) gmtime(a) /* Already thread safe on windows */ + +extern unsigned long waitForNextEvent(unsigned long ulDelay /* ms */); + +#define sleep(a /* sec */) waitForNextEvent(1000*a /* ms */) + +#endif /* Win32 */ + +#endif /* __NDPI_WIN32_INCLUDE_FILE__ */ 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 . + * + */ + +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..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 . + * + */ + + +#ifndef __KERNEL__ +#include +#include +#endif + +#include "ahocorasick.h" +#include "ndpi_api.h" + + +#ifndef __KERNEL__ +#include "../../config.h" +#endif + +// #define DEBUG + +#ifdef __KERNEL__ +#include +#define printf printk +#else +#include +#ifndef WIN32 +#include +#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; jproto_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 */ + 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; indpi_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:"",host:"",.....@ */ + 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: + :,:,.....@ + + 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 */ + 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; (ihost_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. + * + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + + +/* 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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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://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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 + * + * 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 . + * + */ + +#ifndef NDPI_NO_STD_INC +#include +#include +#include +#include +#include + +typedef unsigned char u_int8_t; +typedef unsigned short int u_int16_t; +typedef unsigned long long int u_int64_t; + +#include +#include +#include +#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 + * + * 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 . + * + */ + +#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 + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 + * + * 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 . + * + */ + + +#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 . + * + */ + + + +/* 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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + + +/* 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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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; ihost_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 . + * + */ + + + +#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 . + * + */ + + +#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 + * + * 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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + + +/* 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 . + * + */ + + +#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 . + * + */ + + + +#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 + * + * 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 . + * + */ + + +#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 + * 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 . + * + */ + +#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, "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, "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, "!payload, "payload, "jabber", packet->payload_packet_len) == NULL)) + return 1; + + if(match_first_bytes(packet->payload, "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 . + * + */ + + +/* 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 . + * + */ + + +#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 . + * + */ + + + +/* 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 + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + +#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 . + * + */ + + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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, "payload, "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, "payload, "payload, "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, "payload_packet_len >= NDPI_STATICSTRING_LEN("payload, "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 . + * + */ + + + +/* 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 . + * + */ + + +#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 . + * + */ + + + +/* 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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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:///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 . + * + */ + + + +/* 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 . + * + */ + + +#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 . + * + */ + + +#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 */ + /* 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 . + * + */ + + +#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 . + * + */ + + +#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 + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 + * + */ + +#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 + * + * 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 . + * + */ + + +#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 . + * + */ + + +#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 + * + * 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 . + * + */ + +#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 . + * + */ + + +#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 . + * + */ + + +#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 + * + * 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 . + * + */ + +#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 . + * + */ + + +#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 . + * + */ + + + +/* 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 . + * + */ + + +#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 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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 + * + * 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 . + * + */ + + +#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 + * + */ + + +#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 + * + * 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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 */ + 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 + * + * 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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 + * + * 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 . + * + */ + + +#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 + * + * 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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 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 */ +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 + */ + 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=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 */ + +#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 . + * + */ + + +#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 + * + * 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 . + * + */ + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 + * + * 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 . + */ + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 + * 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 . + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + + +/* 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 . + * + */ + + +#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; (ipayload_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 . + * + */ + + +#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 . + * + */ + + + +/* 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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 . + * + */ + + +#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 '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, "line[8].len, packet->line[8].ptr)) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, + "found HTTP Proxy Yahoo Chat 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, "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, "", 8) == 0 || memcmp(packet->payload, "", 8) == 0 + || memcmp(packet->payload, "", 8) == 0 || memcmp(packet->payload, "", 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, "", 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, "", 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, "payload_packet_len, packet->payload)) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, + "found HTTP Proxy Yahoo Chat 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, "line[8].ptr, "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 . + * + */ + + +#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 . + * + */ + + +#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 + + 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 . +*/ + +#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 + + 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 . +*/ + +#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 + + 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 . +*/ + +#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 + * + * 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 /* for u_* definitions (on FreeBSD 5) */ +#include /* for EAFNOSUPPORT */ + +#ifndef EAFNOSUPPORT +# defined EAFNOSUPPORT WSAEAFNOSUPPORT +#else +#ifndef WIN32 +# include /* for struct in_addr */ +#endif +#endif + +#ifndef WIN32 +#include /* for AF_INET */ +#else +#include +#include /* 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 + * [3]Makaki Hirabaru + * [4]Farnam Jahanian + * Susan Hares + * Susan R. Harris + * Nathan Binkert + * Gerald Winters + + Project Alumni + + * [5]Marc Unangst + * John Scudder + + The BGP4+ extension was originally written by Francis Dupont + . + + The public domain Struct C-library of linked list, hash table and + memory allocation routines was developed by Jonathan Dekock + . + + Susan Rebecca Harris provided help with the + documentation. + David Ward 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 + . 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 + + 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 . +*/ + +#ifndef __KERNEL__ +#include +#include +#include +#include +#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; ilength; 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; iall_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; joutgoing_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; jmatched_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 + + 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 . +*/ + +#ifndef __KERNEL__ +#include +#include +#include +#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 + * + * 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 */ +#include /* isdigit */ +#include /* errno */ +#include /* sin */ +#include /* NULL */ +#include /* sprintf, fprintf, stderr */ +#include /* free, atol, calloc */ +#include /* memcpy, strchr, strlen */ +#include /* BSD: for inet_addr */ +#ifndef WIN32 +#include /* BSD, Linux: for inet_addr */ +#include /* BSD, Linux: for inet_addr */ +#include /* 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 + */ + +#ifdef __KERNEL__ +#include +#else +#ifdef WIN32 +#include +typedef uint32_t u_int32_t; +#endif + +#include +#include +#include +#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 -- cgit v1.2.3