diff options
204 files changed, 47689 insertions, 1 deletions
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. <http://fsf.org/> + 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 `<wchar.h>' 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 @@ -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 Binary files differnew file mode 100644 index 000000000..e2313a184 --- /dev/null +++ b/doc/nDPI_QuickStartGuide.pages diff --git a/doc/nDPI_QuickStartGuide.pdf b/doc/nDPI_QuickStartGuide.pdf Binary files differnew file mode 100644 index 000000000..f29be2a91 --- /dev/null +++ b/doc/nDPI_QuickStartGuide.pdf 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 Binary files differnew file mode 100644 index 000000000..122e224b4 --- /dev/null +++ b/example/Win32/pcapExample.suo 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 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>pcapExample</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>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)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>Wsock32.lib;Ws2_32.lib;C:\ntop\winpcap\Lib\Packet.lib;C:\ntop\winpcap\Lib\wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\..\nprobe\nprobe-win-32\getopt.c" />
+ <ClCompile Include="..\..\..\..\..\nprobe\nprobe-win-32\getopt1.c" />
+ <ClCompile Include="..\..\..\src\lib\ndpi_main.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\afp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\aimini.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\applejuice.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\armagetron.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\battlefield.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\bgp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\bittorrent.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\ciscovpn.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\citrix.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\corba.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\crossfire.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\dcerpc.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\dhcp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\dhcpv6.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\directconnect.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\directdownloadlink.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\dns.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\dofus.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\dropbox.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\edonkey.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\fasttrack.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\feidian.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\fiesta.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\filetopia.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\flash.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\florensia.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\ftp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\gadu_gadu.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\gnutella.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\gtp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\guildwars.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\h323.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\halflife2_and_mods.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\http.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\http_activesync.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\i23v5.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\iax.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\icecast.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\imesh.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\ipp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\irc.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\jabber.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\kerberos.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\kontiki.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\ldap.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\lotus_notes.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\mail_imap.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\mail_pop.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\mail_smtp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\maplestory.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\mdns.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\meebo.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\mgcp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\mms.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\msn.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\mssql.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\mysql.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\netbios.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\netflow.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\nfs.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\noe.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\non_tcp_udp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\ntp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\openft.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\openvpn.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\oracle.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\oscar.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\pando.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\pcanywhere.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\popo.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\postgres.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\pplive.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\ppstream.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\pptp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\qq.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\quake.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\radius.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\rdp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\rsync.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\rtcp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\rtp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\rtsp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\sflow.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\shoutcast.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\sip.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\skinny.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\skype.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\smb.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\snmp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\socrates.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\sopcast.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\soulseek.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\spotify.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\ssdp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\ssh.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\ssl.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\stealthnet.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\steam.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\stun.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\syslog.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\tcp_udp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\tds.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\teamspeak.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\teamviewer.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\telnet.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\tftp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\thunder.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\tor.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\tvants.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\tvuplayer.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\usenet.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\veohtv.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\viber.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\vmware.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\vnc.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\warcraft3.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\winmx.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\world_of_kung_fu.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\world_of_warcraft.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\xbox.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\xdmcp.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\yahoo.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\zattoo.c" />
+ <ClCompile Include="..\..\..\src\lib\third_party\src\ahocorasick.c" />
+ <ClCompile Include="..\..\..\src\lib\third_party\src\node.c" />
+ <ClCompile Include="..\..\..\src\lib\third_party\src\sort.c" />
+ <ClCompile Include="..\..\pcapReader.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\..\..\nprobe\nprobe-win-32\getopt.h" />
+ <ClInclude Include="..\..\..\src\include\linux_compat.h" />
+ <ClInclude Include="..\..\..\src\include\ndpi_api.h" />
+ <ClInclude Include="..\..\..\src\include\ndpi_debug_functions.h" />
+ <ClInclude Include="..\..\..\src\include\ndpi_define.h" />
+ <ClInclude Include="..\..\..\src\include\ndpi_macros.h" />
+ <ClInclude Include="..\..\..\src\include\ndpi_main.h" />
+ <ClInclude Include="..\..\..\src\include\ndpi_protocols.h" />
+ <ClInclude Include="..\..\..\src\include\ndpi_protocols_osdpi.h" />
+ <ClInclude Include="..\..\..\src\include\ndpi_protocol_history.h" />
+ <ClInclude Include="..\..\..\src\include\ndpi_public_functions.h" />
+ <ClInclude Include="..\..\..\src\include\ndpi_structs.h" />
+ <ClInclude Include="..\..\..\src\include\ndpi_utils.h" />
+ <ClInclude Include="..\..\..\src\lib\third_party\include\actypes.h" />
+ <ClInclude Include="..\..\..\src\lib\third_party\include\ahocorasick.h" />
+ <ClInclude Include="..\..\..\src\lib\third_party\include\node.h" />
+ <ClInclude Include="..\..\..\src\lib\third_party\include\sort.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ 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 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\pcapReader.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\ndpi_main.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\zattoo.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\afp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\aimini.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\applejuice.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\armagetron.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\battlefield.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\bgp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\bittorrent.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\ciscovpn.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\citrix.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\corba.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\crossfire.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\dcerpc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\dhcp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\dhcpv6.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\directconnect.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\directdownloadlink.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\dns.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\dofus.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\dropbox.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\edonkey.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\fasttrack.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\feidian.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\fiesta.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\filetopia.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\flash.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\florensia.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\ftp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\gadu_gadu.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\gnutella.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\gtp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\guildwars.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\h323.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\halflife2_and_mods.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\http.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\http_activesync.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\i23v5.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\iax.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\icecast.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\imesh.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\ipp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\irc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\jabber.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\kerberos.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\kontiki.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\ldap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\lotus_notes.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\mail_imap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\mail_pop.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\mail_smtp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\maplestory.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\mdns.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\meebo.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\mgcp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\mms.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\msn.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\mssql.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\mysql.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\netbios.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\netflow.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\nfs.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\noe.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\non_tcp_udp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\ntp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\openft.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\openvpn.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\oracle.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\oscar.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\pando.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\pcanywhere.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\popo.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\postgres.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\pplive.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\ppstream.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\pptp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\qq.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\quake.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\radius.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\rdp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\rsync.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\rtcp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\rtp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\rtsp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\sflow.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\shoutcast.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\sip.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\skinny.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\skype.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\smb.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\snmp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\socrates.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\sopcast.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\soulseek.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\spotify.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\ssdp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\ssh.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\ssl.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\stealthnet.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\steam.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\stun.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\syslog.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\tcp_udp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\tds.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\teamspeak.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\teamviewer.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\telnet.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\tftp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\thunder.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\tor.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\tvants.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\tvuplayer.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\usenet.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\veohtv.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\viber.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\vmware.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\vnc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\warcraft3.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\winmx.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\world_of_kung_fu.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\world_of_warcraft.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\xbox.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\xdmcp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\yahoo.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\third_party\src\ahocorasick.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\third_party\src\node.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\third_party\src\sort.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\..\nprobe\nprobe-win-32\getopt.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\..\nprobe\nprobe-win-32\getopt1.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\src\lib\third_party\include\actypes.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\lib\third_party\include\ahocorasick.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\lib\third_party\include\node.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\lib\third_party\include\sort.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\ndpi_api.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\ndpi_debug_functions.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\ndpi_define.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\ndpi_macros.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\ndpi_main.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\ndpi_protocol_history.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\ndpi_protocols.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\ndpi_protocols_osdpi.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\ndpi_public_functions.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\ndpi_structs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\ndpi_utils.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\include\linux_compat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\..\nprobe\nprobe-win-32\getopt.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
\ 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 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+</Project>
\ 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 <matteo.bogo@gmail.com> (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 <http://www.gnu.org/licenses/>. + * + */ + +#ifdef linux +#define _GNU_SOURCE +#include <sched.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#ifdef WIN32 +#include <winsock2.h> /* winsock.h is included automatically */ +#include <process.h> +#include <io.h> +#include <getopt.h> +#define getopt getopt____ +#else +#include <unistd.h> +#include <netinet/in.h> +#endif +#include <string.h> +#include <stdarg.h> +#include <search.h> +#include <pcap.h> +#include <signal.h> +#include <pthread.h> + +#include "../config.h" + +#ifdef HAVE_JSON_C +#include <json.h> +#endif + +#include "ndpi_api.h" + +#include <sys/socket.h> + +#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 <file|device> [-f <filter>][-s <duration>]\n" + " [-p <protos>][-l <loops>[-d][-h][-t][-v <level>]\n" + " [-n <threads>] [-j <file>]\n\n" + "Usage:\n" + " -i <file.pcap|device> | Specify a pcap file/playlist to read packets from or a device for live capture (comma-separated list)\n" + " -f <BPF filter> | Specify a BPF filter for filtering selected traffic\n" + " -s <duration> | Maximum capture duration in seconds (live traffic capture only)\n" + " -p <file>.protos | Specify a protocol file (eg. protos.txt)\n" + " -l <num loops> | Number of detection loops (test only)\n" + " -n <num threads> | Number of threads. Default: number of interfaces in -i. Ignored with pcap files.\n" + " -j <file.json> | Specify a file to write the content of packets in .json format\n" +#ifdef linux + " -g <id:id...> | 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; i<NUM_ROOTS; i++) { + ndpi_tdestroy(ndpi_thread_info[thread_id].ndpi_flows_root[i], ndpi_flow_freer); + ndpi_thread_info[thread_id].ndpi_flows_root[i] = NULL; + } + + ndpi_exit_detection_module(ndpi_thread_info[thread_id].ndpi_struct, free_wrapper); +} + +/* ***************************************************** */ + +// ipsize = header->len - 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<NUM_ROOTS; i++) + ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[i], node_proto_guess_walker, &thread_id); + + /* Stats aggregation */ + cumulative_stats.guessed_flow_protocols += ndpi_thread_info[thread_id].stats.guessed_flow_protocols; + cumulative_stats.raw_packet_count += ndpi_thread_info[thread_id].stats.raw_packet_count; + cumulative_stats.ip_packet_count += ndpi_thread_info[thread_id].stats.ip_packet_count; + cumulative_stats.total_wire_bytes += ndpi_thread_info[thread_id].stats.total_wire_bytes; + cumulative_stats.total_ip_bytes += ndpi_thread_info[thread_id].stats.total_ip_bytes; + cumulative_stats.total_discarded_bytes += ndpi_thread_info[thread_id].stats.total_discarded_bytes; + + for(i = 0; i < ndpi_get_num_supported_protocols(ndpi_thread_info[0].ndpi_struct); i++) { + cumulative_stats.protocol_counter[i] += ndpi_thread_info[thread_id].stats.protocol_counter[i]; + cumulative_stats.protocol_counter_bytes[i] += ndpi_thread_info[thread_id].stats.protocol_counter_bytes[i]; + cumulative_stats.protocol_flows[i] += ndpi_thread_info[thread_id].stats.protocol_flows[i]; + } + + cumulative_stats.ndpi_flow_count += ndpi_thread_info[thread_id].stats.ndpi_flow_count; + cumulative_stats.tcp_count += ndpi_thread_info[thread_id].stats.tcp_count; + cumulative_stats.udp_count += ndpi_thread_info[thread_id].stats.udp_count; + cumulative_stats.mpls_count += ndpi_thread_info[thread_id].stats.mpls_count; + cumulative_stats.pppoe_count += ndpi_thread_info[thread_id].stats.pppoe_count; + cumulative_stats.vlan_count += ndpi_thread_info[thread_id].stats.vlan_count; + cumulative_stats.fragmented_count += ndpi_thread_info[thread_id].stats.fragmented_count; + for(i = 0; i < 6; i++) + cumulative_stats.packet_len[i] += ndpi_thread_info[thread_id].stats.packet_len[i]; + cumulative_stats.max_packet_len += ndpi_thread_info[thread_id].stats.max_packet_len; + } + + printf("\nnDPI Memory statistics:\n"); + printf("\tnDPI Memory (once): %-13s\n", formatBytes(sizeof(struct ndpi_detection_module_struct), buf, sizeof(buf))); + printf("\tFlow Memory (per flow): %-13s\n", formatBytes(size_flow_struct, buf, sizeof(buf))); + printf("\tActual Memory: %-13s\n", formatBytes(current_ndpi_memory, buf, sizeof(buf))); + printf("\tPeak Memory: %-13s\n", formatBytes(max_ndpi_memory, buf, sizeof(buf))); + + if(!json_flag) { + printf("\nTraffic statistics:\n"); + printf("\tEthernet bytes: %-13llu (includes ethernet CRC/IFC/trailer)\n", + (long long unsigned int)cumulative_stats.total_wire_bytes); + printf("\tDiscarded bytes: %-13llu\n", + (long long unsigned int)cumulative_stats.total_discarded_bytes); + printf("\tIP packets: %-13llu of %llu packets total\n", + (long long unsigned int)cumulative_stats.ip_packet_count, + (long long unsigned int)cumulative_stats.raw_packet_count); + /* In order to prevent Floating point exception in case of no traffic*/ + if(cumulative_stats.total_ip_bytes && cumulative_stats.raw_packet_count) + avg_pkt_size = (unsigned int)(cumulative_stats.total_ip_bytes/cumulative_stats.raw_packet_count); + printf("\tIP bytes: %-13llu (avg pkt size %u bytes)\n", + (long long unsigned int)cumulative_stats.total_ip_bytes,avg_pkt_size); + printf("\tUnique flows: %-13u\n", cumulative_stats.ndpi_flow_count); + + printf("\tTCP Packets: %-13lu\n", (unsigned long)cumulative_stats.tcp_count); + printf("\tUDP Packets: %-13lu\n", (unsigned long)cumulative_stats.udp_count); + printf("\tVLAN Packets: %-13lu\n", (unsigned long)cumulative_stats.vlan_count); + printf("\tMPLS Packets: %-13lu\n", (unsigned long)cumulative_stats.mpls_count); + printf("\tPPPoE Packets: %-13lu\n", (unsigned long)cumulative_stats.pppoe_count); + printf("\tFragmented Packets: %-13lu\n", (unsigned long)cumulative_stats.fragmented_count); + printf("\tMax Packet size: %-13u\n", cumulative_stats.max_packet_len); + printf("\tPacket Len < 64: %-13lu\n", (unsigned long)cumulative_stats.packet_len[0]); + printf("\tPacket Len 64-128: %-13lu\n", (unsigned long)cumulative_stats.packet_len[1]); + printf("\tPacket Len 128-256: %-13lu\n", (unsigned long)cumulative_stats.packet_len[2]); + printf("\tPacket Len 256-1024: %-13lu\n", (unsigned long)cumulative_stats.packet_len[3]); + printf("\tPacket Len 1024-1500: %-13lu\n", (unsigned long)cumulative_stats.packet_len[4]); + printf("\tPacket Len > 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<NUM_ROOTS; i++) + ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[i], node_print_known_proto_walker, &thread_id); + } + + for(thread_id = 0; thread_id < num_threads; thread_id++) { + if(ndpi_thread_info[thread_id].stats.protocol_counter[0 /* 0 = Unknown */] > 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<NUM_ROOTS; i++) + ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[i], node_print_unknown_proto_walker, &thread_id); + } + } + } + + if(json_flag != 0) { +#ifdef HAVE_JSON_C + json_object_object_add(jObj_main,"detected.protos",jArray_detProto); + json_object_object_add(jObj_main,"known.flows",jArray_known_flows); + + if(json_object_array_length(jArray_unknown_flows) != 0) + json_object_object_add(jObj_main,"unknown.flows",jArray_unknown_flows); + + fprintf(json_fp,"%s\n",json_object_to_json_string(jObj_main)); + fclose(json_fp); +#endif + } +} + +/* ***************************************************** */ + +static void closePcapFile(u_int16_t thread_id) { + if(ndpi_thread_info[thread_id]._pcap_handle != NULL) { + pcap_close(ndpi_thread_info[thread_id]._pcap_handle); + } +} + +/* ***************************************************** */ + +static void breakPcapLoop(u_int16_t thread_id) { + if(ndpi_thread_info[thread_id]._pcap_handle != NULL) { + pcap_breakloop(ndpi_thread_info[thread_id]._pcap_handle); + } +} + +/* ***************************************************** */ + +// executed for each packet in the pcap file +void sigproc(int sig) { + static int called = 0; + int thread_id; + + if(called) return; else called = 1; + shutdown_app = 1; + + for(thread_id=0; thread_id<num_threads; thread_id++) + breakPcapLoop(thread_id); +} + +/* ***************************************************** */ + +static int getNextPcapFileFromPlaylist(u_int16_t thread_id, char filename[], u_int32_t filename_len) { + + if(playlist_fp[thread_id] == NULL) { + if((playlist_fp[thread_id] = fopen(_pcap_file[thread_id], "r")) == NULL) + return -1; + } + + next_line: + if(fgets(filename, filename_len, playlist_fp[thread_id])) { + int l = strlen(filename); + if(filename[0] == '\0' || filename[0] == '#') goto next_line; + if(filename[l-1] == '\n') filename[l-1] = '\0'; + return 0; + } else { + fclose(playlist_fp[thread_id]); + playlist_fp[thread_id] = NULL; + return -1; + } +} + +/* ***************************************************** */ + +static void configurePcapHandle(u_int16_t thread_id) { + ndpi_thread_info[thread_id]._pcap_datalink_type = pcap_datalink(ndpi_thread_info[thread_id]._pcap_handle); + + if(_bpf_filter != NULL) { + struct bpf_program fcode; + + if(pcap_compile(ndpi_thread_info[thread_id]._pcap_handle, &fcode, _bpf_filter, 1, 0xFFFFFF00) < 0) { + printf("pcap_compile error: '%s'\n", pcap_geterr(ndpi_thread_info[thread_id]._pcap_handle)); + } else { + if(pcap_setfilter(ndpi_thread_info[thread_id]._pcap_handle, &fcode) < 0) { + printf("pcap_setfilter error: '%s'\n", pcap_geterr(ndpi_thread_info[thread_id]._pcap_handle)); + } else + printf("Successfully set BPF filter to '%s'\n", _bpf_filter); + } + } +} + +/* ***************************************************** */ + +static void openPcapFileOrDevice(u_int16_t thread_id) { + u_int snaplen = 1536; + int promisc = 1; + char errbuf[PCAP_ERRBUF_SIZE]; + + /* trying to open a live interface */ + if((ndpi_thread_info[thread_id]._pcap_handle = pcap_open_live(_pcap_file[thread_id], snaplen, promisc, 500, errbuf)) == NULL) { + capture_for = capture_until = 0; + + live_capture = 0; + num_threads = 1; /* Open pcap files in single threads mode */ + + /* trying to open a pcap file */ + if((ndpi_thread_info[thread_id]._pcap_handle = pcap_open_offline(_pcap_file[thread_id], ndpi_thread_info[thread_id]._pcap_error_buffer)) == NULL) { + char filename[256]; + + /* trying to open a pcap playlist */ + 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) { + + printf("ERROR: could not open pcap file or playlist: %s\n", ndpi_thread_info[thread_id]._pcap_error_buffer); + exit(-1); + } else { + if(!json_flag) printf("Reading packets from playlist %s...\n", _pcap_file[thread_id]); + } + } else { + if(!json_flag) printf("Reading packets from pcap file %s...\n", _pcap_file[thread_id]); + } + } else { + live_capture = 1; + + if(!json_flag) printf("Capturing live traffic from device %s...\n", _pcap_file[thread_id]); + } + + configurePcapHandle(thread_id); + + if(capture_for > 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; i<num_loops; i++) + test_lib(); + + return 0; +} + +/* ****************************************************** */ + +#ifdef WIN32 +#ifndef __GNUC__ +#define EPOCHFILETIME (116444736000000000i64) +#else +#define EPOCHFILETIME (116444736000000000LL) +#endif + +struct timezone { + int tz_minuteswest; /* minutes W of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + +/* ***************************************************** */ + +#if 0 +int gettimeofday(struct timeval *tv, void *notUsed) { + tv->tv_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|udp>:<port>,<tcp|udp>:<port>,.....@<proto> + +tcp:81,tcp:8181@HTTP +udp:5061-5062@SIP +tcp:860,udp:860,tcp:3260,udp:3260@iSCSI +tcp:3000@ntop + +# Subprotocols +# Format: +# host:"<value>",host:"<value>",.....@<subproto> + +host:"googlesyndacation.com"@Google +host:"venere.com"@Venere +host:"kataweb.it",host:"repubblica.it"@Repubblica + + + @@ -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 <stevenj@alum.mit.edu> +# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG> +# +# 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 <http://www.gnu.org/licenses/>. +# +# 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 <pthread.h> + 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 <pthread.h>], + [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 <pthread.h>]], + [[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 </dev/null +exec 6>&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 2>/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 +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$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. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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. + + <signature of Ty Coon>, 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 <deri@ntop.org> @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 --- /dev/null +++ b/packages/ubuntu/debian/conffiles 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 <deri@ntop.org> +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: +# * <new-preinst> `install' +# * <new-preinst> `install' <old-version> +# * <new-preinst> `upgrade' <old-version> +# * <old-preinst> `abort-upgrade' <new-version> + +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 <http://www.gnu.org/licenses/>. + * + */ + + +#ifndef __NDPI_LINUX_COMPAT_H__ +#define __NDPI_LINUX_COMPAT_H__ + +#include "ndpi_define.h" + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include <machine/endian.h> + +#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 <arpa/inet.h> +#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 <http://www.gnu.org/licenses/>. + * + */ + + +#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 <http://www.gnu.org/licenses/>. + * + */ + +#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 <machine/endian.h> +#endif + +#ifdef __OpenBSD__ +#include <endian.h> +#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 <http://www.gnu.org/licenses/>. + * + */ + +#ifndef __NDPI_MAIN_INCLUDE_FILE__ +#define __NDPI_MAIN_INCLUDE_FILE__ + +#ifndef __KERNEL__ +#include <stdint.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#ifndef WIN32 +#include <pthread.h> +#endif +#include <ctype.h> +#include <time.h> +#endif + + +#ifndef WIN32 +#ifndef __KERNEL__ +#include <sys/time.h> +#endif + +#if !defined __APPLE__ && !defined __FreeBSD__ && !defined __NetBSD__ && !defined __OpenBSD__ + +#ifndef __KERNEL__ +#include <endian.h> +#include <byteswap.h> +#else +#include <asm/byteorder.h> +#include <linux/ctype.h> +#endif + +#endif + +/* default includes */ + +#ifndef __KERNEL__ +#include <sys/param.h> +#include <limits.h> +#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 <http://www.gnu.org/licenses/>. + * + */ + + +#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 <tomasz@skatnet.dk> */ +#define NDPI_PROTOCOL_SOCKS4 173 /* Tomasz Bujlow <tomasz@skatnet.dk> */ + +#define NDPI_PROTOCOL_FTP_CONTROL 1 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#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 <tomasz@skatnet.dk> */ +#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 <tomasz@skatnet.dk> */ +#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 <tomasz@skatnet.dk> */ +#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 <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_OPENVPN 159 /* Remy Mudingay <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_NOE 160 /* Remy Mudingay <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_CISCOVPN 161 /* Remy Mudingay <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_TEAMSPEAK 162 /* Remy Mudingay <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_TOR 163 /* Remy Mudingay <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_SKINNY 164 /* Remy Mudingay <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_RTCP 165 /* Remy Mudingay <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_RSYNC 166 /* Remy Mudingay <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_ORACLE 167 /* Remy Mudingay <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_CORBA 168 /* Remy Mudingay <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_UBUNTUONE 169 /* Remy Mudingay <mudingay@ill.fr> */ +#define NDPI_PROTOCOL_WHOIS_DAS 170 +#define NDPI_PROTOCOL_COLLECTD 171 +#define NDPI_PROTOCOL_RTMP 174 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_PROTOCOL_FTP_DATA 175 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_PROTOCOL_ZMQ 177 +#define NDPI_PROTOCOL_MEGACO 181 /* Gianluca Costa <g.costa@xplico.org> */ +#define NDPI_PROTOCOL_REDIS 182 +#define NDPI_PROTOCOL_PANDO 183 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_PROTOCOL_VHUA 184 +#define NDPI_PROTOCOL_TELEGRAM 185 /* Gianluca Costa <g.costa@xplico.org> */ + + +#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 <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_MSN NDPI_PROTOCOL_MSN /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_AMAZON 178 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_EBAY 179 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_CNN 180 /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_DROPBOX NDPI_PROTOCOL_DROPBOX /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_SKYPE NDPI_PROTOCOL_SKYPE /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_VIBER NDPI_PROTOCOL_VIBER /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#define NDPI_SERVICE_YAHOO NDPI_PROTOCOL_YAHOO /* Tomasz Bujlow <tomasz@skatnet.dk> */ +#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 <http://www.gnu.org/licenses/>. + * + */ + + +#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 <http://www.gnu.org/licenses/>. + * + */ + +#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 <http://www.gnu.org/licenses/>. + * + */ + +#ifndef __NDPI_UNIX_INCLUDE_FILE__ +#define __NDPI_UNIX_INCLUDE_FILE__ + +#include "linux_compat.h" + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include <netinet/in.h> +#if defined(__NetBSD__) || defined(__OpenBSD__) +#include <netinet/in_systm.h> +#if defined(__OpenBSD__) +#include <pthread.h> +#endif +#endif +#endif + +#ifndef WIN32 +#ifndef __KERNEL__ + +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> +#else +#include <linux/ip.h> +#include <linux/tcp.h> +#include <linux/udp.h> +#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 <http://www.gnu.org/licenses/>. + * + */ + +#ifndef __NDPI_WIN32_INCLUDE_FILE__ +#define __NDPI_WIN32_INCLUDE_FILE__ + +#ifdef WIN32 +#include <Winsock2.h> /* winsock.h is included automatically */ +#include <process.h> +#include <io.h> +#include <getopt.h> /* getopt from: http://www.pwilson.net/sample.html. */ +#include <process.h> /* 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 <stdint.h> +#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 <http://www.gnu.org/licenses/>. + * + */ + +typedef struct { + char *string_to_match, *proto_name; + int protocol_id; + ndpi_protocol_breed_t protocol_breed; +} ndpi_protocol_match; + +typedef struct { + u_int32_t network; + u_int8_t cidr; + u_int8_t value; +} ndpi_network; + +/* ****************************************************** */ + +static ndpi_network host_protocol_list[] = { + /* + Citrix GotoMeeting (AS16815, AS21866) + 216.115.208.0/20 + 216.219.112.0/20 + */ + { 0xD873D000 /* 216.115.208.0 */, 20, NDPI_PROTOCOL_CITRIX_ONLINE }, + { 0xD8DB7000 /* 216.219.112.0 */, 20, NDPI_PROTOCOL_CITRIX_ONLINE }, + + /* + Webex + 66.114.160.0/20 + */ + { 0x4272A000 /* 66.114.160.0 */, 20, NDPI_PROTOCOL_WEBEX }, + + /* + Viber + 54.171.62.0/24 + */ + { 0x36AB3E00 /* 54.171.62.0 */, 24, NDPI_PROTOCOL_VIBER }, + + /* + Apple (FaceTime, iMessage,...) + 17.0.0.0/8 + */ + { 0x11000000 /* 17.0.0.0 */, 8, NDPI_SERVICE_APPLE }, + + /* + Dropbox + 108.160.160.0/20 + 199.47.216.0/22 + */ + { 0x6CA0A000 /* 108.160.160.0 */, 20, NDPI_PROTOCOL_DROPBOX }, + { 0xC72FD800 /* 199.47.216.0 */, 22, NDPI_PROTOCOL_DROPBOX }, + { 0x6CA0A000 /* 108.160.160.0 */, 20, NDPI_PROTOCOL_DROPBOX }, + + /* + Skype + 157.56.0.0/14, 157.60.0.0/16, 157.54.0.0/15 + */ + { 0x9D380000 /* 157.56.0.0 */, 14, NDPI_PROTOCOL_SKYPE }, + { 0x9D3C0000 /* 157.60.0.0 */, 16, NDPI_PROTOCOL_SKYPE }, + { 0x9D360000 /* 157.54.0.0/ */, 15, NDPI_PROTOCOL_SKYPE }, + + /* + Google + 173.194.0.0/16 + */ + { 0xADC20000 /* 173.194.0.0 */, 16, NDPI_SERVICE_GOOGLE }, + + /* + Ubuntu One + 91.189.89.0/21 (255.255.248.0) + */ + { 0x5BBD5900 /* 91.189.89.0 */, 21, NDPI_PROTOCOL_UBUNTUONE}, + + /* + Telegram + route: 149.154.164.0/22 + descr: Telegram Messenger Amsterdam Network + origin: AS62041 + mnt-by: MNT-TELEGRAM + source: RIPE # Filtered + + route: 149.154.168.0/22 + descr: Telegram Messenger DC5 Network + origin: AS62014 + mnt-by: MNT-TELEGRAM + source: RIPE # Filtered + + http://myip.ms/view/web_hosting/363906/Telegram_Messenger_Network.html + */ + { 0x959AA400 /* 149.154.164.0/22 */, 22, NDPI_PROTOCOL_TELEGRAM}, + { 0x959AA800 /* 149.154.168.0/22 */, 22, NDPI_PROTOCOL_TELEGRAM}, + + /* Skype */ + { 0x17600000, 14, NDPI_PROTOCOL_SKYPE }, + { 0x17613000, 20, NDPI_PROTOCOL_SKYPE }, + { 0x17614000, 19, NDPI_PROTOCOL_SKYPE }, + { 0x17616000, 19, NDPI_PROTOCOL_SKYPE }, + { 0x17622000, 21, NDPI_PROTOCOL_SKYPE }, + { 0x17622800, 22, NDPI_PROTOCOL_SKYPE }, + { 0x17623800, 21, NDPI_PROTOCOL_SKYPE }, + { 0x17624000, 18, NDPI_PROTOCOL_SKYPE }, + { 0x17640000, 15, NDPI_PROTOCOL_SKYPE }, + { 0x17660000, 16, NDPI_PROTOCOL_SKYPE }, + { 0x17674000, 18, NDPI_PROTOCOL_SKYPE }, + { 0x17678000, 17, NDPI_PROTOCOL_SKYPE }, + { 0x40040000, 18, NDPI_PROTOCOL_SKYPE }, + { 0x41340000, 14, NDPI_PROTOCOL_SKYPE }, + { 0x4134A000, 19, NDPI_PROTOCOL_SKYPE }, + { 0x41362800, 24, NDPI_PROTOCOL_SKYPE }, + { 0x41364200, 23, NDPI_PROTOCOL_SKYPE }, + { 0x41364400, 24, NDPI_PROTOCOL_SKYPE }, + { 0x41365200, 24, NDPI_PROTOCOL_SKYPE }, + { 0x41365500, 24, NDPI_PROTOCOL_SKYPE }, + { 0x41365A00, 23, NDPI_PROTOCOL_SKYPE }, + { 0x41372C00, 24, NDPI_PROTOCOL_SKYPE }, + { 0x41377500, 24, NDPI_PROTOCOL_SKYPE }, + { 0x4137E600, 24, NDPI_PROTOCOL_SKYPE }, + { 0x4137E700, 24, NDPI_PROTOCOL_SKYPE }, + { 0x42779000, 20, NDPI_PROTOCOL_SKYPE }, + { 0x46250000, 17, NDPI_PROTOCOL_SKYPE }, + { 0x46258000, 18, NDPI_PROTOCOL_SKYPE }, + { 0x46259600, 23, NDPI_PROTOCOL_SKYPE }, + { 0x5EF54000, 18, NDPI_PROTOCOL_SKYPE }, + { 0x5EF54C00, 23, NDPI_PROTOCOL_SKYPE }, + { 0x5EF55200, 24, NDPI_PROTOCOL_SKYPE }, + { 0x68280000, 13, NDPI_PROTOCOL_SKYPE }, + { 0x68920000, 19, NDPI_PROTOCOL_SKYPE }, + { 0x68928000, 17, NDPI_PROTOCOL_SKYPE }, + { 0x68D00000, 13, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD1000, 20, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD1000, 21, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD1700, 24, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD4000, 18, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD4000, 21, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD4200, 24, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD4500, 24, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD4600, 24, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD4E00, 23, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD5000, 20, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD6000, 20, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD7000, 21, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD7800, 22, NDPI_PROTOCOL_SKYPE }, + { 0x6FDD7C00, 22, NDPI_PROTOCOL_SKYPE }, + { 0x83FD0100, 24, NDPI_PROTOCOL_SKYPE }, + { 0x83FD0500, 24, NDPI_PROTOCOL_SKYPE }, + { 0x83FD0600, 24, NDPI_PROTOCOL_SKYPE }, + { 0x83FD0800, 24, NDPI_PROTOCOL_SKYPE }, + { 0x83FD0C00, 22, NDPI_PROTOCOL_SKYPE }, + { 0x83FD1200, 24, NDPI_PROTOCOL_SKYPE }, + { 0x83FD1500, 24, NDPI_PROTOCOL_SKYPE }, + { 0x83FD1800, 21, NDPI_PROTOCOL_SKYPE }, + { 0x83FD2000, 20, NDPI_PROTOCOL_SKYPE }, + { 0x83FD2100, 24, NDPI_PROTOCOL_SKYPE }, + { 0x83FD2200, 24, NDPI_PROTOCOL_SKYPE }, + { 0x83FD3D00, 24, NDPI_PROTOCOL_SKYPE }, + { 0x83FD3E00, 23, NDPI_PROTOCOL_SKYPE }, + { 0x83FD8000, 17, NDPI_PROTOCOL_SKYPE }, + { 0x84F50000, 16, NDPI_PROTOCOL_SKYPE }, + { 0x84F59C00, 22, NDPI_PROTOCOL_SKYPE }, + { 0x84F5A000, 20, NDPI_PROTOCOL_SKYPE }, + { 0x86AA0000, 16, NDPI_PROTOCOL_SKYPE }, + { 0x86AA8000, 21, NDPI_PROTOCOL_SKYPE }, + { 0x86AA8800, 21, NDPI_PROTOCOL_SKYPE }, + { 0x86AAD900, 24, NDPI_PROTOCOL_SKYPE }, + { 0x89740000, 15, NDPI_PROTOCOL_SKYPE }, + { 0x89748000, 19, NDPI_PROTOCOL_SKYPE }, + { 0x8974A000, 20, NDPI_PROTOCOL_SKYPE }, + { 0x89870000, 16, NDPI_PROTOCOL_SKYPE }, + { 0x8A5B0000, 16, NDPI_PROTOCOL_SKYPE }, + { 0x8A5B0000, 20, NDPI_PROTOCOL_SKYPE }, + { 0x8A5B1000, 20, NDPI_PROTOCOL_SKYPE }, + { 0x8A5B2000, 20, NDPI_PROTOCOL_SKYPE }, + { 0x9D370000, 16, NDPI_PROTOCOL_SKYPE }, + { 0x9D380000, 16, NDPI_PROTOCOL_SKYPE }, + { 0x9D3C1700, 24, NDPI_PROTOCOL_SKYPE }, + { 0x9D3C1F00, 24, NDPI_PROTOCOL_SKYPE }, + { 0xA7DCF000, 22, NDPI_PROTOCOL_SKYPE }, + { 0xA83D0000, 16, NDPI_PROTOCOL_SKYPE }, + { 0xA83E0000, 15, NDPI_PROTOCOL_SKYPE }, + { 0xA83F8000, 17, NDPI_PROTOCOL_SKYPE }, + { 0xBFE80000, 13, NDPI_PROTOCOL_SKYPE }, + { 0xC030E100, 24, NDPI_PROTOCOL_SKYPE }, + { 0xC0549F00, 24, NDPI_PROTOCOL_SKYPE }, + { 0xC054A000, 23, NDPI_PROTOCOL_SKYPE }, + { 0xC0C59D00, 24, NDPI_PROTOCOL_SKYPE }, + { 0xC1954000, 19, NDPI_PROTOCOL_SKYPE }, + { 0xC1DD7100, 24, NDPI_PROTOCOL_SKYPE }, + { 0xC6310800, 24, NDPI_PROTOCOL_SKYPE }, + { 0xC6C88200, 24, NDPI_PROTOCOL_SKYPE }, + { 0xC6CEA400, 24, NDPI_PROTOCOL_SKYPE }, + { 0xC71E1000, 20, NDPI_PROTOCOL_SKYPE }, + { 0xC73C1C00, 24, NDPI_PROTOCOL_SKYPE }, + { 0xC74AD200, 24, NDPI_PROTOCOL_SKYPE }, + { 0xC7675A00, 23, NDPI_PROTOCOL_SKYPE }, + { 0xC7677A00, 24, NDPI_PROTOCOL_SKYPE }, + { 0xC7F23000, 21, NDPI_PROTOCOL_SKYPE }, + { 0xCA59E000, 21, NDPI_PROTOCOL_SKYPE }, + { 0xCC4F8700, 24, NDPI_PROTOCOL_SKYPE }, + { 0xCC4FB300, 24, NDPI_PROTOCOL_SKYPE }, + { 0xCC4FC300, 24, NDPI_PROTOCOL_SKYPE }, + { 0xCC4FC500, 24, NDPI_PROTOCOL_SKYPE }, + { 0xCC4FFC00, 24, NDPI_PROTOCOL_SKYPE }, + { 0xCC5F6000, 20, NDPI_PROTOCOL_SKYPE }, + { 0xCC988C00, 23, NDPI_PROTOCOL_SKYPE }, + { 0xCE8AA800, 21, NDPI_PROTOCOL_SKYPE }, + { 0xCEBFE000, 19, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E0000, 16, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E0000, 19, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E2000, 20, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E2900, 24, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E3000, 20, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E3A00, 24, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E3E00, 24, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E4000, 19, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E4800, 24, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E4D00, 24, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E6000, 19, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E6200, 24, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E8000, 17, NDPI_PROTOCOL_SKYPE }, + { 0xCF2E8000, 19, NDPI_PROTOCOL_SKYPE }, + { 0xCF2EE000, 20, NDPI_PROTOCOL_SKYPE }, + { 0xCF448000, 18, NDPI_PROTOCOL_SKYPE }, + { 0xCF52FA00, 23, NDPI_PROTOCOL_SKYPE }, + { 0xD0448800, 21, NDPI_PROTOCOL_SKYPE }, + { 0xD04C2D00, 24, NDPI_PROTOCOL_SKYPE }, + { 0xD04C2E00, 24, NDPI_PROTOCOL_SKYPE }, + { 0xD0540000, 24, NDPI_PROTOCOL_SKYPE }, + { 0xD0540100, 24, NDPI_PROTOCOL_SKYPE }, + { 0xD0540200, 24, NDPI_PROTOCOL_SKYPE }, + { 0xD0540300, 24, NDPI_PROTOCOL_SKYPE }, + { 0xD1017000, 23, NDPI_PROTOCOL_SKYPE }, + { 0xD1B98000, 22, NDPI_PROTOCOL_SKYPE }, + { 0xD1B9F000, 22, NDPI_PROTOCOL_SKYPE }, + { 0xD1F0C000, 19, NDPI_PROTOCOL_SKYPE }, + { 0xD5C78000, 18, NDPI_PROTOCOL_SKYPE }, + { 0xD820B400, 22, NDPI_PROTOCOL_SKYPE }, + { 0xD820F000, 22, NDPI_PROTOCOL_SKYPE }, + { 0xD820F200, 24, NDPI_PROTOCOL_SKYPE }, + { 0xD821F000, 22, NDPI_PROTOCOL_SKYPE }, + { 0xD4A10800, 24, NDPI_PROTOCOL_SKYPE }, + { 0x012A1231, 32, NDPI_PROTOCOL_TOR }, + { 0x01E69FA1, 32, NDPI_PROTOCOL_TOR }, + { 0x020DE985, 32, NDPI_PROTOCOL_TOR }, + { 0x021D88C5, 32, NDPI_PROTOCOL_TOR }, + { 0x0221585B, 32, NDPI_PROTOCOL_TOR }, + { 0x023E1975, 32, NDPI_PROTOCOL_TOR }, + { 0x0255D62F, 32, NDPI_PROTOCOL_TOR }, + { 0x025B6A07, 32, NDPI_PROTOCOL_TOR }, + { 0x025CB2FE, 32, NDPI_PROTOCOL_TOR }, + { 0x025DFEE6, 32, NDPI_PROTOCOL_TOR }, + { 0x025E83A7, 32, NDPI_PROTOCOL_TOR }, + { 0x02683058, 32, NDPI_PROTOCOL_TOR }, + { 0x026AEE77, 32, NDPI_PROTOCOL_TOR }, + { 0x026B16BA, 32, NDPI_PROTOCOL_TOR }, + { 0x028BD8A9, 32, NDPI_PROTOCOL_TOR }, + { 0x02D9E930, 32, NDPI_PROTOCOL_TOR }, + { 0x02E18D86, 32, NDPI_PROTOCOL_TOR }, + { 0x02E1E75C, 32, NDPI_PROTOCOL_TOR }, + { 0x02E688B0, 32, NDPI_PROTOCOL_TOR }, + { 0x02E6A4FE, 32, NDPI_PROTOCOL_TOR }, + { 0x02E7F51D, 32, NDPI_PROTOCOL_TOR }, + { 0x02EAEAFB, 32, NDPI_PROTOCOL_TOR }, + { 0x02EB2A85, 32, NDPI_PROTOCOL_TOR }, + { 0x02F04269, 32, NDPI_PROTOCOL_TOR }, + { 0x02F0667E, 32, NDPI_PROTOCOL_TOR }, + { 0x02F0DA7F, 32, NDPI_PROTOCOL_TOR }, + { 0x02F183CC, 32, NDPI_PROTOCOL_TOR }, + { 0x02F1A8DE, 32, NDPI_PROTOCOL_TOR }, + { 0x02F2F217, 32, NDPI_PROTOCOL_TOR }, + { 0x02F2FBEB, 32, NDPI_PROTOCOL_TOR }, + { 0x02F4CD37, 32, NDPI_PROTOCOL_TOR }, + { 0x02F779C1, 32, NDPI_PROTOCOL_TOR }, + { 0x0422C8FD, 32, NDPI_PROTOCOL_TOR }, + { 0x0422C8FD, 32, NDPI_PROTOCOL_TOR }, + { 0x0501547D, 32, NDPI_PROTOCOL_TOR }, + { 0x05021027, 32, NDPI_PROTOCOL_TOR }, + { 0x050902CC, 32, NDPI_PROTOCOL_TOR }, + { 0x050906A3, 32, NDPI_PROTOCOL_TOR }, + { 0x05091513, 32, NDPI_PROTOCOL_TOR }, + { 0x05091ADB, 32, NDPI_PROTOCOL_TOR }, + { 0x05091ADB, 32, NDPI_PROTOCOL_TOR }, + { 0x0509254B, 32, NDPI_PROTOCOL_TOR }, + { 0x05092771, 32, NDPI_PROTOCOL_TOR }, + { 0x05092B03, 32, NDPI_PROTOCOL_TOR }, + { 0x05092B50, 32, NDPI_PROTOCOL_TOR }, + { 0x05093176, 32, NDPI_PROTOCOL_TOR }, + { 0x05093394, 32, NDPI_PROTOCOL_TOR }, + { 0x050933AE, 32, NDPI_PROTOCOL_TOR }, + { 0x0509362C, 32, NDPI_PROTOCOL_TOR }, + { 0x05093B4E, 32, NDPI_PROTOCOL_TOR }, + { 0x0509437C, 32, NDPI_PROTOCOL_TOR }, + { 0x05094F06, 32, NDPI_PROTOCOL_TOR }, + { 0x05094F9A, 32, NDPI_PROTOCOL_TOR }, + { 0x0509501C, 32, NDPI_PROTOCOL_TOR }, + { 0x050953CC, 32, NDPI_PROTOCOL_TOR }, + { 0x05095812, 32, NDPI_PROTOCOL_TOR }, + { 0x050959BD, 32, NDPI_PROTOCOL_TOR }, + { 0x05096C4A, 32, NDPI_PROTOCOL_TOR }, + { 0x05096C56, 32, NDPI_PROTOCOL_TOR }, + { 0x05096E85, 32, NDPI_PROTOCOL_TOR }, + { 0x05096EEC, 32, NDPI_PROTOCOL_TOR }, + { 0x050975D4, 32, NDPI_PROTOCOL_TOR }, + { 0x05097B51, 32, NDPI_PROTOCOL_TOR }, + { 0x050981DA, 32, NDPI_PROTOCOL_TOR }, + { 0x05098A9B, 32, NDPI_PROTOCOL_TOR }, + { 0x05098CC3, 32, NDPI_PROTOCOL_TOR }, + { 0x050997F1, 32, NDPI_PROTOCOL_TOR }, + { 0x05099C11, 32, NDPI_PROTOCOL_TOR }, + { 0x05099E44, 32, NDPI_PROTOCOL_TOR }, + { 0x05099E4B, 32, NDPI_PROTOCOL_TOR }, + { 0x0509A92E, 32, NDPI_PROTOCOL_TOR }, + { 0x0509A92E, 32, NDPI_PROTOCOL_TOR }, + { 0x0509BF34, 32, NDPI_PROTOCOL_TOR }, + { 0x0509C38C, 32, NDPI_PROTOCOL_TOR }, + { 0x0509D4CE, 32, NDPI_PROTOCOL_TOR }, + { 0x0509D642, 32, NDPI_PROTOCOL_TOR }, + { 0x0509E35E, 32, NDPI_PROTOCOL_TOR }, + { 0x0509EAEE, 32, NDPI_PROTOCOL_TOR }, + { 0x050D3E81, 32, NDPI_PROTOCOL_TOR }, + { 0x050E066C, 32, NDPI_PROTOCOL_TOR }, + { 0x050E30B4, 32, NDPI_PROTOCOL_TOR }, + { 0x050E476B, 32, NDPI_PROTOCOL_TOR }, + { 0x050ECAE6, 32, NDPI_PROTOCOL_TOR }, + { 0x0513A267, 32, NDPI_PROTOCOL_TOR }, + { 0x0513B30A, 32, NDPI_PROTOCOL_TOR }, + { 0x0513EC45, 32, NDPI_PROTOCOL_TOR }, + { 0x0522B70F, 32, NDPI_PROTOCOL_TOR }, + { 0x0522B7CD, 32, NDPI_PROTOCOL_TOR }, + { 0x0522B7CF, 32, NDPI_PROTOCOL_TOR }, + { 0x05272D98, 32, NDPI_PROTOCOL_TOR }, + { 0x05273CF1, 32, NDPI_PROTOCOL_TOR }, + { 0x0527465F, 32, NDPI_PROTOCOL_TOR }, + { 0x05274C24, 32, NDPI_PROTOCOL_TOR }, + { 0x05274CB6, 32, NDPI_PROTOCOL_TOR }, + { 0x05274DD0, 32, NDPI_PROTOCOL_TOR }, + { 0x05274E65, 32, NDPI_PROTOCOL_TOR }, + { 0x05274FB5, 32, NDPI_PROTOCOL_TOR }, + { 0x0527501C, 32, NDPI_PROTOCOL_TOR }, + { 0x05275087, 32, NDPI_PROTOCOL_TOR }, + { 0x05275087, 32, NDPI_PROTOCOL_TOR }, + { 0x052752C0, 32, NDPI_PROTOCOL_TOR }, + { 0x052753D9, 32, NDPI_PROTOCOL_TOR }, + { 0x052754D9, 32, NDPI_PROTOCOL_TOR }, + { 0x052756CE, 32, NDPI_PROTOCOL_TOR }, + { 0x0527579C, 32, NDPI_PROTOCOL_TOR }, + { 0x05275808, 32, NDPI_PROTOCOL_TOR }, + { 0x05275813, 32, NDPI_PROTOCOL_TOR }, + { 0x05275836, 32, NDPI_PROTOCOL_TOR }, + { 0x0527597C, 32, NDPI_PROTOCOL_TOR }, + { 0x05277240, 32, NDPI_PROTOCOL_TOR }, + { 0x05277A42, 32, NDPI_PROTOCOL_TOR }, + { 0x05277A42, 32, NDPI_PROTOCOL_TOR }, + { 0x052A0AE5, 32, NDPI_PROTOCOL_TOR }, + { 0x052C634D, 32, NDPI_PROTOCOL_TOR }, + { 0x052C63A1, 32, NDPI_PROTOCOL_TOR }, + { 0x052C6B17, 32, NDPI_PROTOCOL_TOR }, + { 0x052D4824, 32, NDPI_PROTOCOL_TOR }, + { 0x052D4909, 32, NDPI_PROTOCOL_TOR }, + { 0x052D4D11, 32, NDPI_PROTOCOL_TOR }, + { 0x052D617F, 32, NDPI_PROTOCOL_TOR }, + { 0x052D626F, 32, NDPI_PROTOCOL_TOR }, + { 0x052D634B, 32, NDPI_PROTOCOL_TOR }, + { 0x052D688D, 32, NDPI_PROTOCOL_TOR }, + { 0x052D6CBD, 32, NDPI_PROTOCOL_TOR }, + { 0x0536FAC4, 32, NDPI_PROTOCOL_TOR }, + { 0x0538E13D, 32, NDPI_PROTOCOL_TOR }, + { 0x0538E4D0, 32, NDPI_PROTOCOL_TOR }, + { 0x053D223F, 32, NDPI_PROTOCOL_TOR }, + { 0x053D260B, 32, NDPI_PROTOCOL_TOR }, + { 0x053DA005, 32, NDPI_PROTOCOL_TOR }, + { 0x054F44A1, 32, NDPI_PROTOCOL_TOR }, + { 0x054F44A1, 32, NDPI_PROTOCOL_TOR }, + { 0x054F47C3, 32, NDPI_PROTOCOL_TOR }, + { 0x054F4E61, 32, NDPI_PROTOCOL_TOR }, + { 0x054F51C0, 32, NDPI_PROTOCOL_TOR }, + { 0x054F56A8, 32, NDPI_PROTOCOL_TOR }, + { 0x056476A6, 32, NDPI_PROTOCOL_TOR }, + { 0x056565E9, 32, NDPI_PROTOCOL_TOR }, + { 0x05656652, 32, NDPI_PROTOCOL_TOR }, + { 0x05656746, 32, NDPI_PROTOCOL_TOR }, + { 0x0567688C, 32, NDPI_PROTOCOL_TOR }, + { 0x0567E82F, 32, NDPI_PROTOCOL_TOR }, + { 0x05685A1D, 32, NDPI_PROTOCOL_TOR }, + { 0x05686A26, 32, NDPI_PROTOCOL_TOR }, + { 0x0581F54D, 32, NDPI_PROTOCOL_TOR }, + { 0x0581FAAD, 32, NDPI_PROTOCOL_TOR }, + { 0x058706AC, 32, NDPI_PROTOCOL_TOR }, + { 0x05873DD1, 32, NDPI_PROTOCOL_TOR }, + { 0x05873DDA, 32, NDPI_PROTOCOL_TOR }, + { 0x05875517, 32, NDPI_PROTOCOL_TOR }, + { 0x05878F54, 32, NDPI_PROTOCOL_TOR }, + { 0x0587917D, 32, NDPI_PROTOCOL_TOR }, + { 0x058794AB, 32, NDPI_PROTOCOL_TOR }, + { 0x058798B2, 32, NDPI_PROTOCOL_TOR }, + { 0x058798D0, 32, NDPI_PROTOCOL_TOR }, + { 0x05879ACF, 32, NDPI_PROTOCOL_TOR }, + { 0x05879B79, 32, NDPI_PROTOCOL_TOR }, + { 0x05879E65, 32, NDPI_PROTOCOL_TOR }, + { 0x05879F04, 32, NDPI_PROTOCOL_TOR }, + { 0x05879F6E, 32, NDPI_PROTOCOL_TOR }, + { 0x05879FCF, 32, NDPI_PROTOCOL_TOR }, + { 0x0587A046, 32, NDPI_PROTOCOL_TOR }, + { 0x0587A21C, 32, NDPI_PROTOCOL_TOR }, + { 0x0587A2D9, 32, NDPI_PROTOCOL_TOR }, + { 0x0587A393, 32, NDPI_PROTOCOL_TOR }, + { 0x0587A5E1, 32, NDPI_PROTOCOL_TOR }, + { 0x0587B1B7, 32, NDPI_PROTOCOL_TOR }, + { 0x0587B209, 32, NDPI_PROTOCOL_TOR }, + { 0x0587B5D5, 32, NDPI_PROTOCOL_TOR }, + { 0x0587B818, 32, NDPI_PROTOCOL_TOR }, + { 0x0587B991, 32, NDPI_PROTOCOL_TOR }, + { 0x0587BA49, 32, NDPI_PROTOCOL_TOR }, + { 0x0587BA9D, 32, NDPI_PROTOCOL_TOR }, + { 0x058B66B7, 32, NDPI_PROTOCOL_TOR }, + { 0x0591316A, 32, NDPI_PROTOCOL_TOR }, + { 0x05922138, 32, NDPI_PROTOCOL_TOR }, + { 0x05930EA4, 32, NDPI_PROTOCOL_TOR }, + { 0x0593158F, 32, NDPI_PROTOCOL_TOR }, + { 0x05937036, 32, NDPI_PROTOCOL_TOR }, + { 0x0595FA35, 32, NDPI_PROTOCOL_TOR }, + { 0x0595FAA4, 32, NDPI_PROTOCOL_TOR }, + { 0x0595FE6D, 32, NDPI_PROTOCOL_TOR }, + { 0x0595FE72, 32, NDPI_PROTOCOL_TOR }, + { 0x0596CC95, 32, NDPI_PROTOCOL_TOR }, + { 0x0596D5F4, 32, NDPI_PROTOCOL_TOR }, + { 0x0596DE9A, 32, NDPI_PROTOCOL_TOR }, + { 0x0596EF88, 32, NDPI_PROTOCOL_TOR }, + { 0x05A4F0C9, 32, NDPI_PROTOCOL_TOR }, + { 0x05A6DDC2, 32, NDPI_PROTOCOL_TOR }, + { 0x05A72D58, 32, NDPI_PROTOCOL_TOR }, + { 0x05A76C53, 32, NDPI_PROTOCOL_TOR }, + { 0x05A79195, 32, NDPI_PROTOCOL_TOR }, + { 0x05AC8CC1, 32, NDPI_PROTOCOL_TOR }, + { 0x05AF714C, 32, NDPI_PROTOCOL_TOR }, + { 0x05AFC17A, 32, NDPI_PROTOCOL_TOR }, + { 0x05AFC245, 32, NDPI_PROTOCOL_TOR }, + { 0x05B256DC, 32, NDPI_PROTOCOL_TOR }, + { 0x05BD82BB, 32, NDPI_PROTOCOL_TOR }, + { 0x05BD8738, 32, NDPI_PROTOCOL_TOR }, + { 0x05C4007B, 32, NDPI_PROTOCOL_TOR }, + { 0x05C40181, 32, NDPI_PROTOCOL_TOR }, + { 0x05C404D0, 32, NDPI_PROTOCOL_TOR }, + { 0x05C40A96, 32, NDPI_PROTOCOL_TOR }, + { 0x05C40BD0, 32, NDPI_PROTOCOL_TOR }, + { 0x05C40C4F, 32, NDPI_PROTOCOL_TOR }, + { 0x05C40C9C, 32, NDPI_PROTOCOL_TOR }, + { 0x05C40C9F, 32, NDPI_PROTOCOL_TOR }, + { 0x05C40D1A, 32, NDPI_PROTOCOL_TOR }, + { 0x05C40E33, 32, NDPI_PROTOCOL_TOR }, + { 0x05C40EEA, 32, NDPI_PROTOCOL_TOR }, + { 0x05C41405, 32, NDPI_PROTOCOL_TOR }, + { 0x05C41455, 32, NDPI_PROTOCOL_TOR }, + { 0x05C41AC6, 32, NDPI_PROTOCOL_TOR }, + { 0x05C44134, 32, NDPI_PROTOCOL_TOR }, + { 0x05C441E9, 32, NDPI_PROTOCOL_TOR }, + { 0x05C4426D, 32, NDPI_PROTOCOL_TOR }, + { 0x05C469E5, 32, NDPI_PROTOCOL_TOR }, + { 0x05C4C4A8, 32, NDPI_PROTOCOL_TOR }, + { 0x05C4E3A1, 32, NDPI_PROTOCOL_TOR }, + { 0x05C4E51D, 32, NDPI_PROTOCOL_TOR }, + { 0x05C78181, 32, NDPI_PROTOCOL_TOR }, + { 0x05C782BC, 32, NDPI_PROTOCOL_TOR }, + { 0x05C785C1, 32, NDPI_PROTOCOL_TOR }, + { 0x05C78E5D, 32, NDPI_PROTOCOL_TOR }, + { 0x05C78E7C, 32, NDPI_PROTOCOL_TOR }, + { 0x05C78EC3, 32, NDPI_PROTOCOL_TOR }, + { 0x05C78EE6, 32, NDPI_PROTOCOL_TOR }, + { 0x05C78EEC, 32, NDPI_PROTOCOL_TOR }, + { 0x05C7A208, 32, NDPI_PROTOCOL_TOR }, + { 0x05C7A51B, 32, NDPI_PROTOCOL_TOR }, + { 0x05C7A621, 32, NDPI_PROTOCOL_TOR }, + { 0x05C7A78A, 32, NDPI_PROTOCOL_TOR }, + { 0x05E4618A, 32, NDPI_PROTOCOL_TOR }, + { 0x05E4CC86, 32, NDPI_PROTOCOL_TOR }, + { 0x05F6674A, 32, NDPI_PROTOCOL_TOR }, + { 0x05F91F00, 32, NDPI_PROTOCOL_TOR }, + { 0x05F99676, 32, NDPI_PROTOCOL_TOR }, + { 0x05FE818A, 32, NDPI_PROTOCOL_TOR }, + { 0x05FF57A9, 32, NDPI_PROTOCOL_TOR }, + { 0x05FF57D5, 32, NDPI_PROTOCOL_TOR }, + { 0x081C576C, 32, NDPI_PROTOCOL_TOR }, + { 0x0C845D90, 32, NDPI_PROTOCOL_TOR }, + { 0x0E20584A, 32, NDPI_PROTOCOL_TOR }, + { 0x0EA2AFC9, 32, NDPI_PROTOCOL_TOR }, + { 0x0EC771B3, 32, NDPI_PROTOCOL_TOR }, + { 0x0ECAE0FB, 32, NDPI_PROTOCOL_TOR }, + { 0x0ECAE0FB, 32, NDPI_PROTOCOL_TOR }, + { 0x0F7EF324, 32, NDPI_PROTOCOL_TOR }, + { 0x12520388, 32, NDPI_PROTOCOL_TOR }, + { 0x125203C4, 32, NDPI_PROTOCOL_TOR }, + { 0x125203CD, 32, NDPI_PROTOCOL_TOR }, + { 0x127D01DE, 32, NDPI_PROTOCOL_TOR }, + { 0x12B5051C, 32, NDPI_PROTOCOL_TOR }, + { 0x12B50525, 32, NDPI_PROTOCOL_TOR }, + { 0x12BB0144, 32, NDPI_PROTOCOL_TOR }, + { 0x12BD4791, 32, NDPI_PROTOCOL_TOR }, + { 0x12E400BC, 32, NDPI_PROTOCOL_TOR }, + { 0x12EE0155, 32, NDPI_PROTOCOL_TOR }, + { 0x12EE0255, 32, NDPI_PROTOCOL_TOR }, + { 0x12EF008C, 32, NDPI_PROTOCOL_TOR }, + { 0x12EF009B, 32, NDPI_PROTOCOL_TOR }, + { 0x12F3001E, 32, NDPI_PROTOCOL_TOR }, + { 0x17159AC2, 32, NDPI_PROTOCOL_TOR }, + { 0x17162143, 32, NDPI_PROTOCOL_TOR }, + { 0x17198709, 32, NDPI_PROTOCOL_TOR }, + { 0x1750E204, 32, NDPI_PROTOCOL_TOR }, + { 0x1758E805, 32, NDPI_PROTOCOL_TOR }, + { 0x175B15E5, 32, NDPI_PROTOCOL_TOR }, + { 0x175B420B, 32, NDPI_PROTOCOL_TOR }, + { 0x175C1308, 32, NDPI_PROTOCOL_TOR }, + { 0x175C144D, 32, NDPI_PROTOCOL_TOR }, + { 0x175C154A, 32, NDPI_PROTOCOL_TOR }, + { 0x175C1A72, 32, NDPI_PROTOCOL_TOR }, + { 0x175CDC55, 32, NDPI_PROTOCOL_TOR }, + { 0x175E1BE3, 32, NDPI_PROTOCOL_TOR }, + { 0x175E2B4C, 32, NDPI_PROTOCOL_TOR }, + { 0x175E3FA2, 32, NDPI_PROTOCOL_TOR }, + { 0x175E6595, 32, NDPI_PROTOCOL_TOR }, + { 0x175ED723, 32, NDPI_PROTOCOL_TOR }, + { 0x175F092F, 32, NDPI_PROTOCOL_TOR }, + { 0x175F2687, 32, NDPI_PROTOCOL_TOR }, + { 0x175F26A0, 32, NDPI_PROTOCOL_TOR }, + { 0x175F27A1, 32, NDPI_PROTOCOL_TOR }, + { 0x175F2B1D, 32, NDPI_PROTOCOL_TOR }, + { 0x175F2B49, 32, NDPI_PROTOCOL_TOR }, + { 0x175F2B4B, 32, NDPI_PROTOCOL_TOR }, + { 0x175F2B4C, 32, NDPI_PROTOCOL_TOR }, + { 0x175F2B4D, 32, NDPI_PROTOCOL_TOR }, + { 0x175F2B52, 32, NDPI_PROTOCOL_TOR }, + { 0x175F6E41, 32, NDPI_PROTOCOL_TOR }, + { 0x175F6F50, 32, NDPI_PROTOCOL_TOR }, + { 0x175F70C0, 32, NDPI_PROTOCOL_TOR }, + { 0x1763514C, 32, NDPI_PROTOCOL_TOR }, + { 0x1766A02E, 32, NDPI_PROTOCOL_TOR }, + { 0x177A8D00, 32, NDPI_PROTOCOL_TOR }, + { 0x17E283AF, 32, NDPI_PROTOCOL_TOR }, + { 0x17E28484, 32, NDPI_PROTOCOL_TOR }, + { 0x17E94164, 32, NDPI_PROTOCOL_TOR }, + { 0x17E96B78, 32, NDPI_PROTOCOL_TOR }, + { 0x17EE11E5, 32, NDPI_PROTOCOL_TOR }, + { 0x17EEE636, 32, NDPI_PROTOCOL_TOR }, + { 0x17EF045E, 32, NDPI_PROTOCOL_TOR }, + { 0x17EF0590, 32, NDPI_PROTOCOL_TOR }, + { 0x17EF0A90, 32, NDPI_PROTOCOL_TOR }, + { 0x17EF1378, 32, NDPI_PROTOCOL_TOR }, + { 0x17EF1378, 32, NDPI_PROTOCOL_TOR }, + { 0x17EF1399, 32, NDPI_PROTOCOL_TOR }, + { 0x17EF1B1C, 32, NDPI_PROTOCOL_TOR }, + { 0x17EF1D41, 32, NDPI_PROTOCOL_TOR }, + { 0x17EF1D41, 32, NDPI_PROTOCOL_TOR }, + { 0x17EF1DE2, 32, NDPI_PROTOCOL_TOR }, + { 0x17EF7165, 32, NDPI_PROTOCOL_TOR }, + { 0x17FA079F, 32, NDPI_PROTOCOL_TOR }, + { 0x17FC36AA, 32, NDPI_PROTOCOL_TOR }, + { 0x17FE8026, 32, NDPI_PROTOCOL_TOR }, + { 0x17FEA584, 32, NDPI_PROTOCOL_TOR }, + { 0x17FEA5FA, 32, NDPI_PROTOCOL_TOR }, + { 0x17FEA6DE, 32, NDPI_PROTOCOL_TOR }, + { 0x17FEA7E7, 32, NDPI_PROTOCOL_TOR }, + { 0x17FFC32F, 32, NDPI_PROTOCOL_TOR }, + { 0x17FFCC6C, 32, NDPI_PROTOCOL_TOR }, + { 0x17FFF26D, 32, NDPI_PROTOCOL_TOR }, + { 0x18015D49, 32, NDPI_PROTOCOL_TOR }, + { 0x18041FF9, 32, NDPI_PROTOCOL_TOR }, + { 0x18048A52, 32, NDPI_PROTOCOL_TOR }, + { 0x18084CAE, 32, NDPI_PROTOCOL_TOR }, + { 0x180AEB3E, 32, NDPI_PROTOCOL_TOR }, + { 0x180CFAC8, 32, NDPI_PROTOCOL_TOR }, + { 0x180D9384, 32, NDPI_PROTOCOL_TOR }, + { 0x1810444C, 32, NDPI_PROTOCOL_TOR }, + { 0x1811131D, 32, NDPI_PROTOCOL_TOR }, + { 0x18140EAF, 32, NDPI_PROTOCOL_TOR }, + { 0x18153FC2, 32, NDPI_PROTOCOL_TOR }, + { 0x18157F86, 32, NDPI_PROTOCOL_TOR }, + { 0x18158EEB, 32, NDPI_PROTOCOL_TOR }, + { 0x1815BE96, 32, NDPI_PROTOCOL_TOR }, + { 0x1815EACE, 32, NDPI_PROTOCOL_TOR }, + { 0x18166B48, 32, NDPI_PROTOCOL_TOR }, + { 0x1816B6B0, 32, NDPI_PROTOCOL_TOR }, + { 0x18228E2D, 32, NDPI_PROTOCOL_TOR }, + { 0x1833357C, 32, NDPI_PROTOCOL_TOR }, + { 0x1834CE43, 32, NDPI_PROTOCOL_TOR }, + { 0x1834DF47, 32, NDPI_PROTOCOL_TOR }, + { 0x1834F2AC, 32, NDPI_PROTOCOL_TOR }, + { 0x183E84AB, 32, NDPI_PROTOCOL_TOR }, + { 0x183ECD0A, 32, NDPI_PROTOCOL_TOR }, + { 0x18405FB8, 32, NDPI_PROTOCOL_TOR }, + { 0x18446509, 32, NDPI_PROTOCOL_TOR }, + { 0x185AC5F6, 32, NDPI_PROTOCOL_TOR }, + { 0x18601285, 32, NDPI_PROTOCOL_TOR }, + { 0x186339F8, 32, NDPI_PROTOCOL_TOR }, + { 0x1868D868, 32, NDPI_PROTOCOL_TOR }, + { 0x186BDA67, 32, NDPI_PROTOCOL_TOR }, + { 0x187950A5, 32, NDPI_PROTOCOL_TOR }, + { 0x1880EB2A, 32, NDPI_PROTOCOL_TOR }, + { 0x18815804, 32, NDPI_PROTOCOL_TOR }, + { 0x188628E9, 32, NDPI_PROTOCOL_TOR }, + { 0x1886424B, 32, NDPI_PROTOCOL_TOR }, + { 0x1886A34A, 32, NDPI_PROTOCOL_TOR }, + { 0x1887456F, 32, NDPI_PROTOCOL_TOR }, + { 0x188CE8A3, 32, NDPI_PROTOCOL_TOR }, + { 0x18943BB9, 32, NDPI_PROTOCOL_TOR }, + { 0x18973BA8, 32, NDPI_PROTOCOL_TOR }, + { 0x189C1043, 32, NDPI_PROTOCOL_TOR }, + { 0x18A0A2C8, 32, NDPI_PROTOCOL_TOR }, + { 0x18A2F56C, 32, NDPI_PROTOCOL_TOR }, + { 0x18A57BA7, 32, NDPI_PROTOCOL_TOR }, + { 0x18A6420B, 32, NDPI_PROTOCOL_TOR }, + { 0x18AA2AAE, 32, NDPI_PROTOCOL_TOR }, + { 0x18B5AF66, 32, NDPI_PROTOCOL_TOR }, + { 0x18B93E50, 32, NDPI_PROTOCOL_TOR }, + { 0x18BB1408, 32, NDPI_PROTOCOL_TOR }, + { 0x18BE411A, 32, NDPI_PROTOCOL_TOR }, + { 0x18C05C02, 32, NDPI_PROTOCOL_TOR }, + { 0x18C1E947, 32, NDPI_PROTOCOL_TOR }, + { 0x18C4398A, 32, NDPI_PROTOCOL_TOR }, + { 0x18CB1026, 32, NDPI_PROTOCOL_TOR }, + { 0x18CBAD0C, 32, NDPI_PROTOCOL_TOR }, + { 0x18D48CD3, 32, NDPI_PROTOCOL_TOR }, + { 0x18D67228, 32, NDPI_PROTOCOL_TOR }, + { 0x18D921A8, 32, NDPI_PROTOCOL_TOR }, + { 0x18DCAE5D, 32, NDPI_PROTOCOL_TOR }, + { 0x18E94A6F, 32, NDPI_PROTOCOL_TOR }, + { 0x18EFCCC4, 32, NDPI_PROTOCOL_TOR }, + { 0x18FBC42B, 32, NDPI_PROTOCOL_TOR }, + { 0x18FC70B1, 32, NDPI_PROTOCOL_TOR }, + { 0x1B6D75D6, 32, NDPI_PROTOCOL_TOR }, + { 0x1B78549C, 32, NDPI_PROTOCOL_TOR }, + { 0x1B7C7C7A, 32, NDPI_PROTOCOL_TOR }, + { 0x1F036525, 32, NDPI_PROTOCOL_TOR }, + { 0x1F07B826, 32, NDPI_PROTOCOL_TOR }, + { 0x1F07B84C, 32, NDPI_PROTOCOL_TOR }, + { 0x1F07BADF, 32, NDPI_PROTOCOL_TOR }, + { 0x1F088004, 32, NDPI_PROTOCOL_TOR }, + { 0x1F0A4D53, 32, NDPI_PROTOCOL_TOR }, + { 0x1F0B41C6, 32, NDPI_PROTOCOL_TOR }, + { 0x1F0BF184, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1018A6, 32, NDPI_PROTOCOL_TOR }, + { 0x1F10AE02, 32, NDPI_PROTOCOL_TOR }, + { 0x1F11CDA0, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1269A3, 32, NDPI_PROTOCOL_TOR }, + { 0x1F12A967, 32, NDPI_PROTOCOL_TOR }, + { 0x1F12B428, 32, NDPI_PROTOCOL_TOR }, + { 0x1F12FBBE, 32, NDPI_PROTOCOL_TOR }, + { 0x1F13D492, 32, NDPI_PROTOCOL_TOR }, + { 0x1F17E469, 32, NDPI_PROTOCOL_TOR }, + { 0x1F180C17, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1979DC, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1E2413, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1E2E44, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1F4A40, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1F4A71, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1F4B54, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1F4BB5, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1F4CA9, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1F4DDE, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1F4E31, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1F4E8D, 32, NDPI_PROTOCOL_TOR }, + { 0x1F1F4F98, 32, NDPI_PROTOCOL_TOR }, + { 0x1F205448, 32, NDPI_PROTOCOL_TOR }, + { 0x1F21B915, 32, NDPI_PROTOCOL_TOR }, + { 0x1F22B6B1, 32, NDPI_PROTOCOL_TOR }, + { 0x1F2AA922, 32, NDPI_PROTOCOL_TOR }, + { 0x1F2CE29C, 32, NDPI_PROTOCOL_TOR }, + { 0x1F2D7B2D, 32, NDPI_PROTOCOL_TOR }, + { 0x1F30B0E8, 32, NDPI_PROTOCOL_TOR }, + { 0x1F326CF7, 32, NDPI_PROTOCOL_TOR }, + { 0x1F338AC8, 32, NDPI_PROTOCOL_TOR }, + { 0x1F81A64E, 32, NDPI_PROTOCOL_TOR }, + { 0x1F86556D, 32, NDPI_PROTOCOL_TOR }, + { 0x1FAC1FCF, 32, NDPI_PROTOCOL_TOR }, + { 0x1FB29AE6, 32, NDPI_PROTOCOL_TOR }, + { 0x1FB8C367, 32, NDPI_PROTOCOL_TOR }, + { 0x1FB8C370, 32, NDPI_PROTOCOL_TOR }, + { 0x1FB91BCB, 32, NDPI_PROTOCOL_TOR }, + { 0x1FC06934, 32, NDPI_PROTOCOL_TOR }, + { 0x1FC06C42, 32, NDPI_PROTOCOL_TOR }, + { 0x1FC0E4B9, 32, NDPI_PROTOCOL_TOR }, + { 0x1FC18B0E, 32, NDPI_PROTOCOL_TOR }, + { 0x1FC9B5F1, 32, NDPI_PROTOCOL_TOR }, + { 0x1FCC966A, 32, NDPI_PROTOCOL_TOR }, + { 0x1FCC968A, 32, NDPI_PROTOCOL_TOR }, + { 0x1FCC9866, 32, NDPI_PROTOCOL_TOR }, + { 0x1FCF8399, 32, NDPI_PROTOCOL_TOR }, + { 0x1FCFF1A8, 32, NDPI_PROTOCOL_TOR }, + { 0x1FD2636A, 32, NDPI_PROTOCOL_TOR }, + { 0x1FD263D2, 32, NDPI_PROTOCOL_TOR }, + { 0x1FD2694A, 32, NDPI_PROTOCOL_TOR }, + { 0x1FD269BA, 32, NDPI_PROTOCOL_TOR }, + { 0x1FD26E3A, 32, NDPI_PROTOCOL_TOR }, + { 0x1FD26E82, 32, NDPI_PROTOCOL_TOR }, + { 0x1FD27FBA, 32, NDPI_PROTOCOL_TOR }, + { 0x1FDC0580, 32, NDPI_PROTOCOL_TOR }, + { 0x1FDC0586, 32, NDPI_PROTOCOL_TOR }, + { 0x1FDC0599, 32, NDPI_PROTOCOL_TOR }, + { 0x1FDC05C8, 32, NDPI_PROTOCOL_TOR }, + { 0x1FDC073F, 32, NDPI_PROTOCOL_TOR }, + { 0x1FDC078F, 32, NDPI_PROTOCOL_TOR }, + { 0x1FDC07C9, 32, NDPI_PROTOCOL_TOR }, + { 0x1FDC2AC2, 32, NDPI_PROTOCOL_TOR }, + { 0x1FDC326D, 32, NDPI_PROTOCOL_TOR }, + { 0x20D7A24A, 32, NDPI_PROTOCOL_TOR }, + { 0x23007F34, 32, NDPI_PROTOCOL_TOR }, + { 0x23007F34, 32, NDPI_PROTOCOL_TOR }, + { 0x2437F025, 32, NDPI_PROTOCOL_TOR }, + { 0x2450B024, 32, NDPI_PROTOCOL_TOR }, + { 0x25007B98, 32, NDPI_PROTOCOL_TOR }, + { 0x25007BCF, 32, NDPI_PROTOCOL_TOR }, + { 0x2501C2B6, 32, NDPI_PROTOCOL_TOR }, + { 0x2501D288, 32, NDPI_PROTOCOL_TOR }, + { 0x2501D569, 32, NDPI_PROTOCOL_TOR }, + { 0x2501D799, 32, NDPI_PROTOCOL_TOR }, + { 0x25041A62, 32, NDPI_PROTOCOL_TOR }, + { 0x25041BED, 32, NDPI_PROTOCOL_TOR }, + { 0x2505A41C, 32, NDPI_PROTOCOL_TOR }, + { 0x250B231C, 32, NDPI_PROTOCOL_TOR }, + { 0x250B231C, 32, NDPI_PROTOCOL_TOR }, + { 0x250B480D, 32, NDPI_PROTOCOL_TOR }, + { 0x2511AD98, 32, NDPI_PROTOCOL_TOR }, + { 0x251816D1, 32, NDPI_PROTOCOL_TOR }, + { 0x2518F260, 32, NDPI_PROTOCOL_TOR }, + { 0x25223476, 32, NDPI_PROTOCOL_TOR }, + { 0x25223A38, 32, NDPI_PROTOCOL_TOR }, + { 0x252C2C0B, 32, NDPI_PROTOCOL_TOR }, + { 0x252EB809, 32, NDPI_PROTOCOL_TOR }, + { 0x25304046, 32, NDPI_PROTOCOL_TOR }, + { 0x2530417A, 32, NDPI_PROTOCOL_TOR }, + { 0x2530417A, 32, NDPI_PROTOCOL_TOR }, + { 0x253043AA, 32, NDPI_PROTOCOL_TOR }, + { 0x25304A4B, 32, NDPI_PROTOCOL_TOR }, + { 0x25304E9F, 32, NDPI_PROTOCOL_TOR }, + { 0x25305130, 32, NDPI_PROTOCOL_TOR }, + { 0x253056A0, 32, NDPI_PROTOCOL_TOR }, + { 0x25305A99, 32, NDPI_PROTOCOL_TOR }, + { 0x2530782F, 32, NDPI_PROTOCOL_TOR }, + { 0x253078C4, 32, NDPI_PROTOCOL_TOR }, + { 0x253110CB, 32, NDPI_PROTOCOL_TOR }, + { 0x253A70B2, 32, NDPI_PROTOCOL_TOR }, + { 0x253B0227, 32, NDPI_PROTOCOL_TOR }, + { 0x253B02BC, 32, NDPI_PROTOCOL_TOR }, + { 0x253B0EC9, 32, NDPI_PROTOCOL_TOR }, + { 0x253B1D49, 32, NDPI_PROTOCOL_TOR }, + { 0x253B24C6, 32, NDPI_PROTOCOL_TOR }, + { 0x253B2675, 32, NDPI_PROTOCOL_TOR }, + { 0x253B2E9F, 32, NDPI_PROTOCOL_TOR }, + { 0x253B2F1B, 32, NDPI_PROTOCOL_TOR }, + { 0x253B2F1B, 32, NDPI_PROTOCOL_TOR }, + { 0x253B4365, 32, NDPI_PROTOCOL_TOR }, + { 0x253B6052, 32, NDPI_PROTOCOL_TOR }, + { 0x253B60BF, 32, NDPI_PROTOCOL_TOR }, + { 0x253B63BF, 32, NDPI_PROTOCOL_TOR }, + { 0x253B640B, 32, NDPI_PROTOCOL_TOR }, + { 0x253B69D6, 32, NDPI_PROTOCOL_TOR }, + { 0x253B69E8, 32, NDPI_PROTOCOL_TOR }, + { 0x253B6FC0, 32, NDPI_PROTOCOL_TOR }, + { 0x253B704A, 32, NDPI_PROTOCOL_TOR }, + { 0x253B7493, 32, NDPI_PROTOCOL_TOR }, + { 0x253B7614, 32, NDPI_PROTOCOL_TOR }, + { 0x253B7662, 32, NDPI_PROTOCOL_TOR }, + { 0x253B76F6, 32, NDPI_PROTOCOL_TOR }, + { 0x253B794E, 32, NDPI_PROTOCOL_TOR }, + { 0x253B7B8E, 32, NDPI_PROTOCOL_TOR }, + { 0x253B7D1D, 32, NDPI_PROTOCOL_TOR }, + { 0x253B85D0, 32, NDPI_PROTOCOL_TOR }, + { 0x253B9010, 32, NDPI_PROTOCOL_TOR }, + { 0x253BA2DA, 32, NDPI_PROTOCOL_TOR }, + { 0x254BA34C, 32, NDPI_PROTOCOL_TOR }, + { 0x254CCFC4, 32, NDPI_PROTOCOL_TOR }, + { 0x256E0D88, 32, NDPI_PROTOCOL_TOR }, + { 0x256E3C0F, 32, NDPI_PROTOCOL_TOR }, + { 0x256EF1F9, 32, NDPI_PROTOCOL_TOR }, + { 0x25718DEE, 32, NDPI_PROTOCOL_TOR }, + { 0x2571B30C, 32, NDPI_PROTOCOL_TOR }, + { 0x25723407, 32, NDPI_PROTOCOL_TOR }, + { 0x25780229, 32, NDPI_PROTOCOL_TOR }, + { 0x25784275, 32, NDPI_PROTOCOL_TOR }, + { 0x2578A080, 32, NDPI_PROTOCOL_TOR }, + { 0x2578AC86, 32, NDPI_PROTOCOL_TOR }, + { 0x2578AC88, 32, NDPI_PROTOCOL_TOR }, + { 0x2578ACF2, 32, NDPI_PROTOCOL_TOR }, + { 0x257B700E, 32, NDPI_PROTOCOL_TOR }, + { 0x257B70FD, 32, NDPI_PROTOCOL_TOR }, + { 0x257B756F, 32, NDPI_PROTOCOL_TOR }, + { 0x257B924B, 32, NDPI_PROTOCOL_TOR }, + { 0x2582E385, 32, NDPI_PROTOCOL_TOR }, + { 0x2582E386, 32, NDPI_PROTOCOL_TOR }, + { 0x2585814C, 32, NDPI_PROTOCOL_TOR }, + { 0x25869E3E, 32, NDPI_PROTOCOL_TOR }, + { 0x258B03AB, 32, NDPI_PROTOCOL_TOR }, + { 0x258B03E7, 32, NDPI_PROTOCOL_TOR }, + { 0x258B0C33, 32, NDPI_PROTOCOL_TOR }, + { 0x258B0D4E, 32, NDPI_PROTOCOL_TOR }, + { 0x258B166E, 32, NDPI_PROTOCOL_TOR }, + { 0x258F094A, 32, NDPI_PROTOCOL_TOR }, + { 0x25904351, 32, NDPI_PROTOCOL_TOR }, + { 0x2591FF60, 32, NDPI_PROTOCOL_TOR }, + { 0x259267E1, 32, NDPI_PROTOCOL_TOR }, + { 0x25928712, 32, NDPI_PROTOCOL_TOR }, + { 0x25929590, 32, NDPI_PROTOCOL_TOR }, + { 0x25939A1B, 32, NDPI_PROTOCOL_TOR }, + { 0x2599010A, 32, NDPI_PROTOCOL_TOR }, + { 0x25993585, 32, NDPI_PROTOCOL_TOR }, + { 0x259DA955, 32, NDPI_PROTOCOL_TOR }, + { 0x259DC059, 32, NDPI_PROTOCOL_TOR }, + { 0x259DC2D2, 32, NDPI_PROTOCOL_TOR }, + { 0x259DC30D, 32, NDPI_PROTOCOL_TOR }, + { 0x259DC353, 32, NDPI_PROTOCOL_TOR }, + { 0x259DC38F, 32, NDPI_PROTOCOL_TOR }, + { 0x259DC3B2, 32, NDPI_PROTOCOL_TOR }, + { 0x259DC4DB, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB0012, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB007E, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB0255, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB02E5, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB02E6, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB0303, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB0408, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB04DB, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB052C, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB056D, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB074A, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB094F, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB115F, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB122B, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB122B, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB126D, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB12B4, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB143B, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB144F, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB151C, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB159D, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB15B4, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB1657, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB1683, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB17E8, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB17E8, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB1E4E, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB1F27, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB2693, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB27D2, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB33D2, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB3F72, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB4275, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB604E, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB611F, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB615F, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB62B9, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB638F, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB63C1, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB666C, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB66BA, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB675B, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB679C, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB692B, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB6941, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB6944, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB6B5B, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB6BD2, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB6BD2, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB6C50, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB6D13, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB6D3A, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB6D45, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB6E3F, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB6ED8, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB7224, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB728C, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB732F, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB7487, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB76EC, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB7C84, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB7CC6, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB7DCF, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB7DCF, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB7DE4, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB7E15, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB8244, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB82E2, 32, NDPI_PROTOCOL_TOR }, + { 0x25BB89E1, 32, NDPI_PROTOCOL_TOR }, + { 0x25BBB023, 32, NDPI_PROTOCOL_TOR }, + { 0x25BBB040, 32, NDPI_PROTOCOL_TOR }, + { 0x25BBB404, 32, NDPI_PROTOCOL_TOR }, + { 0x25BBB41C, 32, NDPI_PROTOCOL_TOR }, + { 0x25BBB441, 32, NDPI_PROTOCOL_TOR }, + { 0x25BBC635, 32, NDPI_PROTOCOL_TOR }, + { 0x25BBC69F, 32, NDPI_PROTOCOL_TOR }, + { 0x25BBEFBF, 32, NDPI_PROTOCOL_TOR }, + { 0x25BBF36D, 32, NDPI_PROTOCOL_TOR }, + { 0x25BBF428, 32, NDPI_PROTOCOL_TOR }, + { 0x25BBF6DD, 32, NDPI_PROTOCOL_TOR }, + { 0x25BC44E4, 32, NDPI_PROTOCOL_TOR }, + { 0x25BED50A, 32, NDPI_PROTOCOL_TOR }, + { 0x25BF8A2B, 32, NDPI_PROTOCOL_TOR }, + { 0x25C08768, 32, NDPI_PROTOCOL_TOR }, + { 0x25C2350B, 32, NDPI_PROTOCOL_TOR }, + { 0x25C3C530, 32, NDPI_PROTOCOL_TOR }, + { 0x25C86205, 32, NDPI_PROTOCOL_TOR }, + { 0x25C863FB, 32, NDPI_PROTOCOL_TOR }, + { 0x25C939D9, 32, NDPI_PROTOCOL_TOR }, + { 0x25C98337, 32, NDPI_PROTOCOL_TOR }, + { 0x25C9DF9D, 32, NDPI_PROTOCOL_TOR }, + { 0x25CCA01C, 32, NDPI_PROTOCOL_TOR }, + { 0x25CD0983, 32, NDPI_PROTOCOL_TOR }, + { 0x25CD0B95, 32, NDPI_PROTOCOL_TOR }, + { 0x25D13BC6, 32, NDPI_PROTOCOL_TOR }, + { 0x25D14A11, 32, NDPI_PROTOCOL_TOR }, + { 0x25D16FE5, 32, NDPI_PROTOCOL_TOR }, + { 0x25D3561F, 32, NDPI_PROTOCOL_TOR }, + { 0x25DC233D, 32, NDPI_PROTOCOL_TOR }, + { 0x25DDA125, 32, NDPI_PROTOCOL_TOR }, + { 0x25DDA137, 32, NDPI_PROTOCOL_TOR }, + { 0x25DDA2E2, 32, NDPI_PROTOCOL_TOR }, + { 0x25DDA2E2, 32, NDPI_PROTOCOL_TOR }, + { 0x25DDA5E5, 32, NDPI_PROTOCOL_TOR }, + { 0x25DDA5F6, 32, NDPI_PROTOCOL_TOR }, + { 0x25DDC114, 32, NDPI_PROTOCOL_TOR }, + { 0x25DDC5B7, 32, NDPI_PROTOCOL_TOR }, + { 0x25E48203, 32, NDPI_PROTOCOL_TOR }, + { 0x25E48424, 32, NDPI_PROTOCOL_TOR }, + { 0x25E60143, 32, NDPI_PROTOCOL_TOR }, + { 0x25EB30F7, 32, NDPI_PROTOCOL_TOR }, + { 0x25EB312E, 32, NDPI_PROTOCOL_TOR }, + { 0x25EB317C, 32, NDPI_PROTOCOL_TOR }, + { 0x25EB3443, 32, NDPI_PROTOCOL_TOR }, + { 0x25EB3753, 32, NDPI_PROTOCOL_TOR }, + { 0x25EB3C39, 32, NDPI_PROTOCOL_TOR }, + { 0x25EB3C3C, 32, NDPI_PROTOCOL_TOR }, + { 0x25EB3E07, 32, NDPI_PROTOCOL_TOR }, + { 0x25F71635, 32, NDPI_PROTOCOL_TOR }, + { 0x25F732A7, 32, NDPI_PROTOCOL_TOR }, + { 0x25F7348C, 32, NDPI_PROTOCOL_TOR }, + { 0x25F735A2, 32, NDPI_PROTOCOL_TOR }, + { 0x25FC0CBA, 32, NDPI_PROTOCOL_TOR }, + { 0x25FCBE85, 32, NDPI_PROTOCOL_TOR }, + { 0x264D16FB, 32, NDPI_PROTOCOL_TOR }, + { 0x266C0A8C, 32, NDPI_PROTOCOL_TOR }, + { 0x26825026, 32, NDPI_PROTOCOL_TOR }, + { 0x26825039, 32, NDPI_PROTOCOL_TOR }, + { 0x26E5001C, 32, NDPI_PROTOCOL_TOR }, + { 0x26E5001D, 32, NDPI_PROTOCOL_TOR }, + { 0x26E54621, 32, NDPI_PROTOCOL_TOR }, + { 0x26E54622, 32, NDPI_PROTOCOL_TOR }, + { 0x26E5462A, 32, NDPI_PROTOCOL_TOR }, + { 0x26E5462A, 32, NDPI_PROTOCOL_TOR }, + { 0x26E54633, 32, NDPI_PROTOCOL_TOR }, + { 0x26E54634, 32, NDPI_PROTOCOL_TOR }, + { 0x26E54635, 32, NDPI_PROTOCOL_TOR }, + { 0x26E54636, 32, NDPI_PROTOCOL_TOR }, + { 0x26E5463D, 32, NDPI_PROTOCOL_TOR }, + { 0x26E54F02, 32, NDPI_PROTOCOL_TOR }, + { 0x27775DC9, 32, NDPI_PROTOCOL_TOR }, + { 0x294885AE, 32, NDPI_PROTOCOL_TOR }, + { 0x294D88FA, 32, NDPI_PROTOCOL_TOR }, + { 0x2985828E, 32, NDPI_PROTOCOL_TOR }, + { 0x29B619B5, 32, NDPI_PROTOCOL_TOR }, + { 0x29D4257A, 32, NDPI_PROTOCOL_TOR }, + { 0x29D7F1EA, 32, NDPI_PROTOCOL_TOR }, + { 0x29DF358D, 32, NDPI_PROTOCOL_TOR }, + { 0x29F201F2, 32, NDPI_PROTOCOL_TOR }, + { 0x2A02EFEA, 32, NDPI_PROTOCOL_TOR }, + { 0x2A7010C4, 32, NDPI_PROTOCOL_TOR }, + { 0x2A701341, 32, NDPI_PROTOCOL_TOR }, + { 0x2A7013C9, 32, NDPI_PROTOCOL_TOR }, + { 0x2BFA082A, 32, NDPI_PROTOCOL_TOR }, + { 0x2BFA0842, 32, NDPI_PROTOCOL_TOR }, + { 0x2E04009C, 32, NDPI_PROTOCOL_TOR }, + { 0x2E0418A8, 32, NDPI_PROTOCOL_TOR }, + { 0x2E0419D6, 32, NDPI_PROTOCOL_TOR }, + { 0x2E0422F2, 32, NDPI_PROTOCOL_TOR }, + { 0x2E0427EB, 32, NDPI_PROTOCOL_TOR }, + { 0x2E0437B1, 32, NDPI_PROTOCOL_TOR }, + { 0x2E043C6A, 32, NDPI_PROTOCOL_TOR }, + { 0x2E0457AC, 32, NDPI_PROTOCOL_TOR }, + { 0x2E046723, 32, NDPI_PROTOCOL_TOR }, + { 0x2E046A12, 32, NDPI_PROTOCOL_TOR }, + { 0x2E046ACF, 32, NDPI_PROTOCOL_TOR }, + { 0x2E046F7C, 32, NDPI_PROTOCOL_TOR }, + { 0x2E0474B0, 32, NDPI_PROTOCOL_TOR }, + { 0x2E047AA2, 32, NDPI_PROTOCOL_TOR }, + { 0x2E047AAD, 32, NDPI_PROTOCOL_TOR }, + { 0x2E04AE34, 32, NDPI_PROTOCOL_TOR }, + { 0x2E04B777, 32, NDPI_PROTOCOL_TOR }, + { 0x2E04FDC2, 32, NDPI_PROTOCOL_TOR }, + { 0x2E051DC4, 32, NDPI_PROTOCOL_TOR }, + { 0x2E051E05, 32, NDPI_PROTOCOL_TOR }, + { 0x2E055F13, 32, NDPI_PROTOCOL_TOR }, + { 0x2E059971, 32, NDPI_PROTOCOL_TOR }, + { 0x2E09C314, 32, NDPI_PROTOCOL_TOR }, + { 0x2E0ACDFC, 32, NDPI_PROTOCOL_TOR }, + { 0x2E0EF5CE, 32, NDPI_PROTOCOL_TOR }, + { 0x2E10EA83, 32, NDPI_PROTOCOL_TOR }, + { 0x2E113FD6, 32, NDPI_PROTOCOL_TOR }, + { 0x2E138E1D, 32, NDPI_PROTOCOL_TOR }, + { 0x2E138E7E, 32, NDPI_PROTOCOL_TOR }, + { 0x2E14F675, 32, NDPI_PROTOCOL_TOR }, + { 0x2E167BDE, 32, NDPI_PROTOCOL_TOR }, + { 0x2E1746C3, 32, NDPI_PROTOCOL_TOR }, + { 0x2E17551F, 32, NDPI_PROTOCOL_TOR }, + { 0x2E1C449E, 32, NDPI_PROTOCOL_TOR }, + { 0x2E1C4581, 32, NDPI_PROTOCOL_TOR }, + { 0x2E1C6E81, 32, NDPI_PROTOCOL_TOR }, + { 0x2E1C6EF4, 32, NDPI_PROTOCOL_TOR }, + { 0x2E1CCAD6, 32, NDPI_PROTOCOL_TOR }, + { 0x2E1CCF78, 32, NDPI_PROTOCOL_TOR }, + { 0x2E20E8EE, 32, NDPI_PROTOCOL_TOR }, + { 0x2E20EABD, 32, NDPI_PROTOCOL_TOR }, + { 0x2E2423D5, 32, NDPI_PROTOCOL_TOR }, + { 0x2E24251B, 32, NDPI_PROTOCOL_TOR }, + { 0x2E2425B7, 32, NDPI_PROTOCOL_TOR }, + { 0x2E2425D6, 32, NDPI_PROTOCOL_TOR }, + { 0x2E24271A, 32, NDPI_PROTOCOL_TOR }, + { 0x2E2639C4, 32, NDPI_PROTOCOL_TOR }, + { 0x2E263E1E, 32, NDPI_PROTOCOL_TOR }, + { 0x2E263F07, 32, NDPI_PROTOCOL_TOR }, + { 0x2E26E9F2, 32, NDPI_PROTOCOL_TOR }, + { 0x2E26FA27, 32, NDPI_PROTOCOL_TOR }, + { 0x2E2779BC, 32, NDPI_PROTOCOL_TOR }, + { 0x2E298244, 32, NDPI_PROTOCOL_TOR }, + { 0x2E298454, 32, NDPI_PROTOCOL_TOR }, + { 0x2E2B325C, 32, NDPI_PROTOCOL_TOR }, + { 0x2E2D0F7B, 32, NDPI_PROTOCOL_TOR }, + { 0x2E2F133A, 32, NDPI_PROTOCOL_TOR }, + { 0x2E37146D, 32, NDPI_PROTOCOL_TOR }, + { 0x2E3B27B9, 32, NDPI_PROTOCOL_TOR }, + { 0x2E3B3A75, 32, NDPI_PROTOCOL_TOR }, + { 0x2E3B8EEC, 32, NDPI_PROTOCOL_TOR }, + { 0x2E3B9439, 32, NDPI_PROTOCOL_TOR }, + { 0x2E3B9998, 32, NDPI_PROTOCOL_TOR }, + { 0x2E3BB9D7, 32, NDPI_PROTOCOL_TOR }, + { 0x2E3BF04E, 32, NDPI_PROTOCOL_TOR }, + { 0x2E48594D, 32, NDPI_PROTOCOL_TOR }, + { 0x2E49F960, 32, NDPI_PROTOCOL_TOR }, + { 0x2E691148, 32, NDPI_PROTOCOL_TOR }, + { 0x2E6960BE, 32, NDPI_PROTOCOL_TOR }, + { 0x2E69AC56, 32, NDPI_PROTOCOL_TOR }, + { 0x2E69E8BC, 32, NDPI_PROTOCOL_TOR }, + { 0x2E6C27DB, 32, NDPI_PROTOCOL_TOR }, + { 0x2E76110C, 32, NDPI_PROTOCOL_TOR }, + { 0x2E762709, 32, NDPI_PROTOCOL_TOR }, + { 0x2E76A38F, 32, NDPI_PROTOCOL_TOR }, + { 0x2E76E5C9, 32, NDPI_PROTOCOL_TOR }, + { 0x2E7E47AA, 32, NDPI_PROTOCOL_TOR }, + { 0x2E7FC664, 32, NDPI_PROTOCOL_TOR }, + { 0x2E7FCB2F, 32, NDPI_PROTOCOL_TOR }, + { 0x2E7FD0F8, 32, NDPI_PROTOCOL_TOR }, + { 0x2E800457, 32, NDPI_PROTOCOL_TOR }, + { 0x2E802D63, 32, NDPI_PROTOCOL_TOR }, + { 0x2E802D76, 32, NDPI_PROTOCOL_TOR }, + { 0x2E80D52B, 32, NDPI_PROTOCOL_TOR }, + { 0x2E81138F, 32, NDPI_PROTOCOL_TOR }, + { 0x2E8115E6, 32, NDPI_PROTOCOL_TOR }, + { 0x2E817C16, 32, NDPI_PROTOCOL_TOR }, + { 0x2E84BCDD, 32, NDPI_PROTOCOL_TOR }, + { 0x2E92E027, 32, NDPI_PROTOCOL_TOR }, + { 0x2E95120A, 32, NDPI_PROTOCOL_TOR }, + { 0x2E97D0D5, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA25245, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA26191, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA340CA, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA341A0, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA3449C, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA34C20, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA34CFA, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA3DB56, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA5C560, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA5DDA6, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA5DDA6, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA5DFD6, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA5DFD9, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA5DFE3, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA5F08F, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA5F2A6, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA5F9E4, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA5FAEB, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA6A127, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA7F533, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA7F545, 32, NDPI_PROTOCOL_TOR }, + { 0x2EA7F5AC, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB5EEA4, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB61224, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB6126F, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB612F5, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB61303, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB61563, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB66ABE, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB6845A, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB6D01C, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB7D9F4, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB7DA8D, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB7DBC4, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB7DC84, 32, NDPI_PROTOCOL_TOR }, + { 0x2EB9E185, 32, NDPI_PROTOCOL_TOR }, + { 0x2EBB039C, 32, NDPI_PROTOCOL_TOR }, + { 0x2EBC0425, 32, NDPI_PROTOCOL_TOR }, + { 0x2EBC0A17, 32, NDPI_PROTOCOL_TOR }, + { 0x2EBC2510, 32, NDPI_PROTOCOL_TOR }, + { 0x2EBC2AB0, 32, NDPI_PROTOCOL_TOR }, + { 0x2EC29854, 32, NDPI_PROTOCOL_TOR }, + { 0x2ED80D2F, 32, NDPI_PROTOCOL_TOR }, + { 0x2EDF485B, 32, NDPI_PROTOCOL_TOR }, + { 0x2EDF4FDF, 32, NDPI_PROTOCOL_TOR }, + { 0x2EDF8DA7, 32, NDPI_PROTOCOL_TOR }, + { 0x2EDFCD19, 32, NDPI_PROTOCOL_TOR }, + { 0x2EDFF71E, 32, NDPI_PROTOCOL_TOR }, + { 0x2EE26D30, 32, NDPI_PROTOCOL_TOR }, + { 0x2EE26EB9, 32, NDPI_PROTOCOL_TOR }, + { 0x2EE360DA, 32, NDPI_PROTOCOL_TOR }, + { 0x2EE4045B, 32, NDPI_PROTOCOL_TOR }, + { 0x2EE4C713, 32, NDPI_PROTOCOL_TOR }, + { 0x2EE5EEAC, 32, NDPI_PROTOCOL_TOR }, + { 0x2EE90046, 32, NDPI_PROTOCOL_TOR }, + { 0x2EE9EDBB, 32, NDPI_PROTOCOL_TOR }, + { 0x2EEBE346, 32, NDPI_PROTOCOL_TOR }, + { 0x2EEC95E0, 32, NDPI_PROTOCOL_TOR }, + { 0x2EEF62AC, 32, NDPI_PROTOCOL_TOR }, + { 0x2EEF6472, 32, NDPI_PROTOCOL_TOR }, + { 0x2EEF6B4A, 32, NDPI_PROTOCOL_TOR }, + { 0x2EEF6CC2, 32, NDPI_PROTOCOL_TOR }, + { 0x2EEF75B4, 32, NDPI_PROTOCOL_TOR }, + { 0x2EF2623D, 32, NDPI_PROTOCOL_TOR }, + { 0x2EF48AFB, 32, NDPI_PROTOCOL_TOR }, + { 0x2EF5C841, 32, NDPI_PROTOCOL_TOR }, + { 0x2EF61484, 32, NDPI_PROTOCOL_TOR }, + { 0x2EF6220C, 32, NDPI_PROTOCOL_TOR }, + { 0x2EF623E5, 32, NDPI_PROTOCOL_TOR }, + { 0x2EF62E1B, 32, NDPI_PROTOCOL_TOR }, + { 0x2EF659A9, 32, NDPI_PROTOCOL_TOR }, + { 0x2EF66CAE, 32, NDPI_PROTOCOL_TOR }, + { 0x2EF66FCF, 32, NDPI_PROTOCOL_TOR }, + { 0x2EF9258F, 32, NDPI_PROTOCOL_TOR }, + { 0x2EFC1838, 32, NDPI_PROTOCOL_TOR }, + { 0x2EFC18F6, 32, NDPI_PROTOCOL_TOR }, + { 0x2EFC19F9, 32, NDPI_PROTOCOL_TOR }, + { 0x2EFC1A02, 32, NDPI_PROTOCOL_TOR }, + { 0x2EFC98C0, 32, NDPI_PROTOCOL_TOR }, + { 0x2EFE4BA8, 32, NDPI_PROTOCOL_TOR }, + { 0x2F376EBC, 32, NDPI_PROTOCOL_TOR }, + { 0x31CD342B, 32, NDPI_PROTOCOL_TOR }, + { 0x31D4A626, 32, NDPI_PROTOCOL_TOR }, + { 0x31D4ADDE, 32, NDPI_PROTOCOL_TOR }, + { 0x31D4C271, 32, NDPI_PROTOCOL_TOR }, + { 0x320163E9, 32, NDPI_PROTOCOL_TOR }, + { 0x32070872, 32, NDPI_PROTOCOL_TOR }, + { 0x32073D6A, 32, NDPI_PROTOCOL_TOR }, + { 0x3207A1DA, 32, NDPI_PROTOCOL_TOR }, + { 0x3207B03B, 32, NDPI_PROTOCOL_TOR }, + { 0x3207B03B, 32, NDPI_PROTOCOL_TOR }, + { 0x3207B03C, 32, NDPI_PROTOCOL_TOR }, + { 0x3207B03D, 32, NDPI_PROTOCOL_TOR }, + { 0x3207B03D, 32, NDPI_PROTOCOL_TOR }, + { 0x3207B03E, 32, NDPI_PROTOCOL_TOR }, + { 0x3207B83A, 32, NDPI_PROTOCOL_TOR }, + { 0x3207C27A, 32, NDPI_PROTOCOL_TOR }, + { 0x3207D2DA, 32, NDPI_PROTOCOL_TOR }, + { 0x3207F36B, 32, NDPI_PROTOCOL_TOR }, + { 0x3207F36B, 32, NDPI_PROTOCOL_TOR }, + { 0x32092FEE, 32, NDPI_PROTOCOL_TOR }, + { 0x321F4CC3, 32, NDPI_PROTOCOL_TOR }, + { 0x321FFF5E, 32, NDPI_PROTOCOL_TOR }, + { 0x322300F4, 32, NDPI_PROTOCOL_TOR }, + { 0x322554A1, 32, NDPI_PROTOCOL_TOR }, + { 0x322B0AF0, 32, NDPI_PROTOCOL_TOR }, + { 0x322B38B6, 32, NDPI_PROTOCOL_TOR }, + { 0x322EF39B, 32, NDPI_PROTOCOL_TOR }, + { 0x32354A02, 32, NDPI_PROTOCOL_TOR }, + { 0x32355AFB, 32, NDPI_PROTOCOL_TOR }, + { 0x323995CC, 32, NDPI_PROTOCOL_TOR }, + { 0x3245A0C6, 32, NDPI_PROTOCOL_TOR }, + { 0x3248C4CE, 32, NDPI_PROTOCOL_TOR }, + { 0x324C9FDA, 32, NDPI_PROTOCOL_TOR }, + { 0x324EC501, 32, NDPI_PROTOCOL_TOR }, + { 0x324F2036, 32, NDPI_PROTOCOL_TOR }, + { 0x32511947, 32, NDPI_PROTOCOL_TOR }, + { 0x32532059, 32, NDPI_PROTOCOL_TOR }, + { 0x32582849, 32, NDPI_PROTOCOL_TOR }, + { 0x3258C0F5, 32, NDPI_PROTOCOL_TOR }, + { 0x325A0246, 32, NDPI_PROTOCOL_TOR }, + { 0x325DF89A, 32, NDPI_PROTOCOL_TOR }, + { 0x325DF9E4, 32, NDPI_PROTOCOL_TOR }, + { 0x326F05DE, 32, NDPI_PROTOCOL_TOR }, + { 0x326FC86F, 32, NDPI_PROTOCOL_TOR }, + { 0x32710FAD, 32, NDPI_PROTOCOL_TOR }, + { 0x327375B9, 32, NDPI_PROTOCOL_TOR }, + { 0x32737A44, 32, NDPI_PROTOCOL_TOR }, + { 0x3273E93E, 32, NDPI_PROTOCOL_TOR }, + { 0x32740095, 32, NDPI_PROTOCOL_TOR }, + { 0x327403DF, 32, NDPI_PROTOCOL_TOR }, + { 0x3274048D, 32, NDPI_PROTOCOL_TOR }, + { 0x32740599, 32, NDPI_PROTOCOL_TOR }, + { 0x32740AF2, 32, NDPI_PROTOCOL_TOR }, + { 0x327415AC, 32, NDPI_PROTOCOL_TOR }, + { 0x32741D36, 32, NDPI_PROTOCOL_TOR }, + { 0x32741D36, 32, NDPI_PROTOCOL_TOR }, + { 0x327420D9, 32, NDPI_PROTOCOL_TOR }, + { 0x3274222C, 32, NDPI_PROTOCOL_TOR }, + { 0x32742806, 32, NDPI_PROTOCOL_TOR }, + { 0x32742AF5, 32, NDPI_PROTOCOL_TOR }, + { 0x32742E14, 32, NDPI_PROTOCOL_TOR }, + { 0x32742FAB, 32, NDPI_PROTOCOL_TOR }, + { 0x3274312E, 32, NDPI_PROTOCOL_TOR }, + { 0x3274320C, 32, NDPI_PROTOCOL_TOR }, + { 0x3274320C, 32, NDPI_PROTOCOL_TOR }, + { 0x32743687, 32, NDPI_PROTOCOL_TOR }, + { 0x32743830, 32, NDPI_PROTOCOL_TOR }, + { 0x327556D3, 32, NDPI_PROTOCOL_TOR }, + { 0x328293BF, 32, NDPI_PROTOCOL_TOR }, + { 0x328C5DDF, 32, NDPI_PROTOCOL_TOR }, + { 0x328F6411, 32, NDPI_PROTOCOL_TOR }, + { 0x3294BED5, 32, NDPI_PROTOCOL_TOR }, + { 0x3298F1C6, 32, NDPI_PROTOCOL_TOR }, + { 0x32A4685A, 32, NDPI_PROTOCOL_TOR }, + { 0x32A84435, 32, NDPI_PROTOCOL_TOR }, + { 0x32B12972, 32, NDPI_PROTOCOL_TOR }, + { 0x32B1AF1A, 32, NDPI_PROTOCOL_TOR }, + { 0x32B5B129, 32, NDPI_PROTOCOL_TOR }, + { 0x32C18F2A, 32, NDPI_PROTOCOL_TOR }, + { 0x32C701B2, 32, NDPI_PROTOCOL_TOR }, + { 0x32F11E91, 32, NDPI_PROTOCOL_TOR }, + { 0x32F57C83, 32, NDPI_PROTOCOL_TOR }, + { 0x32F74BCD, 32, NDPI_PROTOCOL_TOR }, + { 0x32F7C37C, 32, NDPI_PROTOCOL_TOR }, + { 0x32F90236, 32, NDPI_PROTOCOL_TOR }, + { 0x32FAC9FE, 32, NDPI_PROTOCOL_TOR }, + { 0x32FAD011, 32, NDPI_PROTOCOL_TOR }, + { 0x32FADAA1, 32, NDPI_PROTOCOL_TOR }, + { 0x32FF615D, 32, NDPI_PROTOCOL_TOR }, + { 0x340A7D8C, 32, NDPI_PROTOCOL_TOR }, + { 0x364023F4, 32, NDPI_PROTOCOL_TOR }, + { 0x3640E586, 32, NDPI_PROTOCOL_TOR }, + { 0x3641ACFE, 32, NDPI_PROTOCOL_TOR }, + { 0x3641CE17, 32, NDPI_PROTOCOL_TOR }, + { 0x3641CE2C, 32, NDPI_PROTOCOL_TOR }, + { 0x3641CE34, 32, NDPI_PROTOCOL_TOR }, + { 0x3641CE39, 32, NDPI_PROTOCOL_TOR }, + { 0x3641CE3C, 32, NDPI_PROTOCOL_TOR }, + { 0x3641CE43, 32, NDPI_PROTOCOL_TOR }, + { 0x3641CE4A, 32, NDPI_PROTOCOL_TOR }, + { 0x3641CE4F, 32, NDPI_PROTOCOL_TOR }, + { 0x3642A01A, 32, NDPI_PROTOCOL_TOR }, + { 0x3642ED8D, 32, NDPI_PROTOCOL_TOR }, + { 0x36431231, 32, NDPI_PROTOCOL_TOR }, + { 0x36441DAA, 32, NDPI_PROTOCOL_TOR }, + { 0x3645C64F, 32, NDPI_PROTOCOL_TOR }, + { 0x3649DA8A, 32, NDPI_PROTOCOL_TOR }, + { 0x364D068C, 32, NDPI_PROTOCOL_TOR }, + { 0x364D6EBC, 32, NDPI_PROTOCOL_TOR }, + { 0x364D7868, 32, NDPI_PROTOCOL_TOR }, + { 0x364D7DC1, 32, NDPI_PROTOCOL_TOR }, + { 0x364F7EC5, 32, NDPI_PROTOCOL_TOR }, + { 0x3652C35E, 32, NDPI_PROTOCOL_TOR }, + { 0x36542A9B, 32, NDPI_PROTOCOL_TOR }, + { 0x36546A29, 32, NDPI_PROTOCOL_TOR }, + { 0x36568324, 32, NDPI_PROTOCOL_TOR }, + { 0x36571DA1, 32, NDPI_PROTOCOL_TOR }, + { 0x36583B2D, 32, NDPI_PROTOCOL_TOR }, + { 0x36583F17, 32, NDPI_PROTOCOL_TOR }, + { 0x3658A5E5, 32, NDPI_PROTOCOL_TOR }, + { 0x365D2B6D, 32, NDPI_PROTOCOL_TOR }, + { 0x365E89A4, 32, NDPI_PROTOCOL_TOR }, + { 0x365E8BA7, 32, NDPI_PROTOCOL_TOR }, + { 0x365EF005, 32, NDPI_PROTOCOL_TOR }, + { 0x365EF097, 32, NDPI_PROTOCOL_TOR }, + { 0x365EF100, 32, NDPI_PROTOCOL_TOR }, + { 0x365EF1A2, 32, NDPI_PROTOCOL_TOR }, + { 0x365EF1A8, 32, NDPI_PROTOCOL_TOR }, + { 0x365EF1AB, 32, NDPI_PROTOCOL_TOR }, + { 0x365EF1B5, 32, NDPI_PROTOCOL_TOR }, + { 0x365EF1B8, 32, NDPI_PROTOCOL_TOR }, + { 0x3692143E, 32, NDPI_PROTOCOL_TOR }, + { 0x3692CB7D, 32, NDPI_PROTOCOL_TOR }, + { 0x36941FE1, 32, NDPI_PROTOCOL_TOR }, + { 0x36946DAA, 32, NDPI_PROTOCOL_TOR }, + { 0x36949610, 32, NDPI_PROTOCOL_TOR }, + { 0x3695F2AE, 32, NDPI_PROTOCOL_TOR }, + { 0x369A0E1A, 32, NDPI_PROTOCOL_TOR }, + { 0x36A49C46, 32, NDPI_PROTOCOL_TOR }, + { 0x36AB5EF9, 32, NDPI_PROTOCOL_TOR }, + { 0x36AD6890, 32, NDPI_PROTOCOL_TOR }, + { 0x36AF0DB5, 32, NDPI_PROTOCOL_TOR }, + { 0x36AF5145, 32, NDPI_PROTOCOL_TOR }, + { 0x36B9A3E2, 32, NDPI_PROTOCOL_TOR }, + { 0x36BB371D, 32, NDPI_PROTOCOL_TOR }, + { 0x36BBEF10, 32, NDPI_PROTOCOL_TOR }, + { 0x36BF1132, 32, NDPI_PROTOCOL_TOR }, + { 0x36BF7203, 32, NDPI_PROTOCOL_TOR }, + { 0x36BF80E4, 32, NDPI_PROTOCOL_TOR }, + { 0x36C25AB0, 32, NDPI_PROTOCOL_TOR }, + { 0x36D05F8F, 32, NDPI_PROTOCOL_TOR }, + { 0x36D5A676, 32, NDPI_PROTOCOL_TOR }, + { 0x36E035C2, 32, NDPI_PROTOCOL_TOR }, + { 0x36E44160, 32, NDPI_PROTOCOL_TOR }, + { 0x36E8A7C8, 32, NDPI_PROTOCOL_TOR }, + { 0x36EBF7DC, 32, NDPI_PROTOCOL_TOR }, + { 0x36EDB868, 32, NDPI_PROTOCOL_TOR }, + { 0x36FBC11C, 32, NDPI_PROTOCOL_TOR }, + { 0x36FBD0B4, 32, NDPI_PROTOCOL_TOR }, + { 0x36FC6132, 32, NDPI_PROTOCOL_TOR }, + { 0x3A0775BC, 32, NDPI_PROTOCOL_TOR }, + { 0x3A604E5D, 32, NDPI_PROTOCOL_TOR }, + { 0x3AB78278, 32, NDPI_PROTOCOL_TOR }, + { 0x3B656242, 32, NDPI_PROTOCOL_TOR }, + { 0x3BA79B3B, 32, NDPI_PROTOCOL_TOR }, + { 0x3BB14C69, 32, NDPI_PROTOCOL_TOR }, + { 0x3C230879, 32, NDPI_PROTOCOL_TOR }, + { 0x3CEA7764, 32, NDPI_PROTOCOL_TOR }, + { 0x3CF2B70F, 32, NDPI_PROTOCOL_TOR }, + { 0x3CF8A2B3, 32, NDPI_PROTOCOL_TOR }, + { 0x3D56E640, 32, NDPI_PROTOCOL_TOR }, + { 0x3D5A3C79, 32, NDPI_PROTOCOL_TOR }, + { 0x3DCD303F, 32, NDPI_PROTOCOL_TOR }, + { 0x3DDB7725, 32, NDPI_PROTOCOL_TOR }, + { 0x3DE6AE3B, 32, NDPI_PROTOCOL_TOR }, + { 0x3DE6C615, 32, NDPI_PROTOCOL_TOR }, + { 0x3E040D0D, 32, NDPI_PROTOCOL_TOR }, + { 0x3E1E7D29, 32, NDPI_PROTOCOL_TOR }, + { 0x3E2BAF76, 32, NDPI_PROTOCOL_TOR }, + { 0x3E2C7FB8, 32, NDPI_PROTOCOL_TOR }, + { 0x3E315C96, 32, NDPI_PROTOCOL_TOR }, + { 0x3E3F9D4E, 32, NDPI_PROTOCOL_TOR }, + { 0x3E3FEFD7, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4B8EA6, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4B8FA7, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4B9617, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4B9DC5, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4B9FF9, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4BB91A, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4BBB2A, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4BD198, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4BEBDE, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4BF147, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4BF17F, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4BF74A, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4BFB9D, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4BFDF7, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4C20B3, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4C2C95, 32, NDPI_PROTOCOL_TOR }, + { 0x3E4D554A, 32, NDPI_PROTOCOL_TOR }, + { 0x3E5C6F2D, 32, NDPI_PROTOCOL_TOR }, + { 0x3E6C249B, 32, NDPI_PROTOCOL_TOR }, + { 0x3E6C2530, 32, NDPI_PROTOCOL_TOR }, + { 0x3E6CAB4C, 32, NDPI_PROTOCOL_TOR }, + { 0x3E70C338, 32, NDPI_PROTOCOL_TOR }, + { 0x3E71DF9A, 32, NDPI_PROTOCOL_TOR }, + { 0x3E71FA27, 32, NDPI_PROTOCOL_TOR }, + { 0x3E71FAB4, 32, NDPI_PROTOCOL_TOR }, + { 0x3E7A36A1, 32, NDPI_PROTOCOL_TOR }, + { 0x3E8D24D5, 32, NDPI_PROTOCOL_TOR }, + { 0x3E8D251E, 32, NDPI_PROTOCOL_TOR }, + { 0x3E8D2574, 32, NDPI_PROTOCOL_TOR }, + { 0x3E8D2CCE, 32, NDPI_PROTOCOL_TOR }, + { 0x3E8D2E36, 32, NDPI_PROTOCOL_TOR }, + { 0x3E8D2EC1, 32, NDPI_PROTOCOL_TOR }, + { 0x3E8F7968, 32, NDPI_PROTOCOL_TOR }, + { 0x3E8F8DEE, 32, NDPI_PROTOCOL_TOR }, + { 0x3E8F91BE, 32, NDPI_PROTOCOL_TOR }, + { 0x3E8FDE16, 32, NDPI_PROTOCOL_TOR }, + { 0x3E92842F, 32, NDPI_PROTOCOL_TOR }, + { 0x3E93FB15, 32, NDPI_PROTOCOL_TOR }, + { 0x3E9502BC, 32, NDPI_PROTOCOL_TOR }, + { 0x3E950D39, 32, NDPI_PROTOCOL_TOR }, + { 0x3E982BCB, 32, NDPI_PROTOCOL_TOR }, + { 0x3EA803D4, 32, NDPI_PROTOCOL_TOR }, + { 0x3EB0EFE5, 32, NDPI_PROTOCOL_TOR }, + { 0x3EB287DB, 32, NDPI_PROTOCOL_TOR }, + { 0x3EB5EEBA, 32, NDPI_PROTOCOL_TOR }, + { 0x3EB63D99, 32, NDPI_PROTOCOL_TOR }, + { 0x3EC5289B, 32, NDPI_PROTOCOL_TOR }, + { 0x3ECA279D, 32, NDPI_PROTOCOL_TOR }, + { 0x3ECB0AE6, 32, NDPI_PROTOCOL_TOR }, + { 0x3ECC6EC6, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED22410, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED22552, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED24579, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED245EC, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED24A37, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED24A89, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED24A8F, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED24ABA, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED24AC9, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED24C60, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2522C, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED252A9, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED252B1, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED25404, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED25414, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED25C0B, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED25C0B, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED28438, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED28990, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED289E6, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED289E6, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2AA0A, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2AA1B, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2AA8F, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2AC5E, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2B6BC, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2B6EF, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2BCDA, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2BD22, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2C698, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2CC3D, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2CE19, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2CE19, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2CE35, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2D3ED, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2ECAE, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2ED55, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2EE32, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2F088, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2F3A7, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2F3B1, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED2FCAF, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED448F3, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED45233, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED454E5, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED45975, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED6063D, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED8D048, 32, NDPI_PROTOCOL_TOR }, + { 0x3ED97CFD, 32, NDPI_PROTOCOL_TOR }, + { 0x3EDA4B01, 32, NDPI_PROTOCOL_TOR }, + { 0x3EDB2E85, 32, NDPI_PROTOCOL_TOR }, + { 0x3EDBB62A, 32, NDPI_PROTOCOL_TOR }, + { 0x3EDC8781, 32, NDPI_PROTOCOL_TOR }, + { 0x3EDC88FD, 32, NDPI_PROTOCOL_TOR }, + { 0x3EDC9457, 32, NDPI_PROTOCOL_TOR }, + { 0x3EDC945E, 32, NDPI_PROTOCOL_TOR }, + { 0x3EDC9460, 32, NDPI_PROTOCOL_TOR }, + { 0x3EDC9461, 32, NDPI_PROTOCOL_TOR }, + { 0x3EDCB113, 32, NDPI_PROTOCOL_TOR }, + { 0x3EE1CA01, 32, NDPI_PROTOCOL_TOR }, + { 0x3EE2FA55, 32, NDPI_PROTOCOL_TOR }, + { 0x3EE47585, 32, NDPI_PROTOCOL_TOR }, + { 0x3EF1F052, 32, NDPI_PROTOCOL_TOR }, + { 0x3EFF6FC3, 32, NDPI_PROTOCOL_TOR }, + { 0x3F770D78, 32, NDPI_PROTOCOL_TOR }, + { 0x3F8EF878, 32, NDPI_PROTOCOL_TOR }, + { 0x3FE761E4, 32, NDPI_PROTOCOL_TOR }, + { 0x3FE7B589, 32, NDPI_PROTOCOL_TOR }, + { 0x3FF95AF8, 32, NDPI_PROTOCOL_TOR }, + { 0x400535AF, 32, NDPI_PROTOCOL_TOR }, + { 0x40167D28, 32, NDPI_PROTOCOL_TOR }, + { 0x4022A5ED, 32, NDPI_PROTOCOL_TOR }, + { 0x403AC85C, 32, NDPI_PROTOCOL_TOR }, + { 0x403EF9DE, 32, NDPI_PROTOCOL_TOR }, + { 0x404552A0, 32, NDPI_PROTOCOL_TOR }, + { 0x40478F7C, 32, NDPI_PROTOCOL_TOR }, + { 0x404A7772, 32, NDPI_PROTOCOL_TOR }, + { 0x404E969E, 32, NDPI_PROTOCOL_TOR }, + { 0x405713F4, 32, NDPI_PROTOCOL_TOR }, + { 0x405F3C4B, 32, NDPI_PROTOCOL_TOR }, + { 0x4071201D, 32, NDPI_PROTOCOL_TOR }, + { 0x40712CCE, 32, NDPI_PROTOCOL_TOR }, + { 0x407E2B54, 32, NDPI_PROTOCOL_TOR }, + { 0x40801EE8, 32, NDPI_PROTOCOL_TOR }, + { 0x4096D384, 32, NDPI_PROTOCOL_TOR }, + { 0x40ED332E, 32, NDPI_PROTOCOL_TOR }, + { 0x40FB0E11, 32, NDPI_PROTOCOL_TOR }, + { 0x4113B2B1, 32, NDPI_PROTOCOL_TOR }, + { 0x411DE8C4, 32, NDPI_PROTOCOL_TOR }, + { 0x4124628D, 32, NDPI_PROTOCOL_TOR }, + { 0x4132CB05, 32, NDPI_PROTOCOL_TOR }, + { 0x415E2693, 32, NDPI_PROTOCOL_TOR }, + { 0x416FBA42, 32, NDPI_PROTOCOL_TOR }, + { 0x41B57080, 32, NDPI_PROTOCOL_TOR }, + { 0x41B57159, 32, NDPI_PROTOCOL_TOR }, + { 0x41B57188, 32, NDPI_PROTOCOL_TOR }, + { 0x41B57BFE, 32, NDPI_PROTOCOL_TOR }, + { 0x41B57F76, 32, NDPI_PROTOCOL_TOR }, + { 0x41BF4B1E, 32, NDPI_PROTOCOL_TOR }, + { 0x4207CDA4, 32, NDPI_PROTOCOL_TOR }, + { 0x42088235, 32, NDPI_PROTOCOL_TOR }, + { 0x4208A63E, 32, NDPI_PROTOCOL_TOR }, + { 0x421F2F84, 32, NDPI_PROTOCOL_TOR }, + { 0x421FD0F6, 32, NDPI_PROTOCOL_TOR }, + { 0x422DF72A, 32, NDPI_PROTOCOL_TOR }, + { 0x424217DA, 32, NDPI_PROTOCOL_TOR }, + { 0x4244A7E8, 32, NDPI_PROTOCOL_TOR }, + { 0x42558348, 32, NDPI_PROTOCOL_TOR }, + { 0x426CCBC5, 32, NDPI_PROTOCOL_TOR }, + { 0x426D18CC, 32, NDPI_PROTOCOL_TOR }, + { 0x426F0210, 32, NDPI_PROTOCOL_TOR }, + { 0x426F0214, 32, NDPI_PROTOCOL_TOR }, + { 0x42746CB3, 32, NDPI_PROTOCOL_TOR }, + { 0x4275090A, 32, NDPI_PROTOCOL_TOR }, + { 0x4283C0D3, 32, NDPI_PROTOCOL_TOR }, + { 0x4289E293, 32, NDPI_PROTOCOL_TOR }, + { 0x4292C11F, 32, NDPI_PROTOCOL_TOR }, + { 0x4294745A, 32, NDPI_PROTOCOL_TOR }, + { 0x42AB5188, 32, NDPI_PROTOCOL_TOR }, + { 0x42ABB3C2, 32, NDPI_PROTOCOL_TOR }, + { 0x42AC0A43, 32, NDPI_PROTOCOL_TOR }, + { 0x42AC0CAE, 32, NDPI_PROTOCOL_TOR }, + { 0x42AC0CFE, 32, NDPI_PROTOCOL_TOR }, + { 0x42AC216A, 32, NDPI_PROTOCOL_TOR }, + { 0x42AC21DC, 32, NDPI_PROTOCOL_TOR }, + { 0x42AFD3F2, 32, NDPI_PROTOCOL_TOR }, + { 0x42AFD3F9, 32, NDPI_PROTOCOL_TOR }, + { 0x42AFD695, 32, NDPI_PROTOCOL_TOR }, + { 0x42AFD695, 32, NDPI_PROTOCOL_TOR }, + { 0x42AFD94E, 32, NDPI_PROTOCOL_TOR }, + { 0x42AFDC99, 32, NDPI_PROTOCOL_TOR }, + { 0x42AFDD18, 32, NDPI_PROTOCOL_TOR }, + { 0x42AFDF91, 32, NDPI_PROTOCOL_TOR }, + { 0x42B4C1DB, 32, NDPI_PROTOCOL_TOR }, + { 0x42C428FC, 32, NDPI_PROTOCOL_TOR }, + { 0x42DC03B3, 32, NDPI_PROTOCOL_TOR }, + { 0x42E421F8, 32, NDPI_PROTOCOL_TOR }, + { 0x42E42752, 32, NDPI_PROTOCOL_TOR }, + { 0x42E42772, 32, NDPI_PROTOCOL_TOR }, + { 0x42E42CCC, 32, NDPI_PROTOCOL_TOR }, + { 0x42E42FFE, 32, NDPI_PROTOCOL_TOR }, + { 0x42E436C3, 32, NDPI_PROTOCOL_TOR }, + { 0x42E43B18, 32, NDPI_PROTOCOL_TOR }, + { 0x42E43E5B, 32, NDPI_PROTOCOL_TOR }, + { 0x42F64BA7, 32, NDPI_PROTOCOL_TOR }, + { 0x42F8CC47, 32, NDPI_PROTOCOL_TOR }, + { 0x4300A951, 32, NDPI_PROTOCOL_TOR }, + { 0x4301F94A, 32, NDPI_PROTOCOL_TOR }, + { 0x43125C8D, 32, NDPI_PROTOCOL_TOR }, + { 0x43172B2E, 32, NDPI_PROTOCOL_TOR }, + { 0x4317B5ED, 32, NDPI_PROTOCOL_TOR }, + { 0x4355853B, 32, NDPI_PROTOCOL_TOR }, + { 0x43564FB9, 32, NDPI_PROTOCOL_TOR }, + { 0x4395F029, 32, NDPI_PROTOCOL_TOR }, + { 0x439EE2CA, 32, NDPI_PROTOCOL_TOR }, + { 0x43A58EE2, 32, NDPI_PROTOCOL_TOR }, + { 0x43A864B7, 32, NDPI_PROTOCOL_TOR }, + { 0x43A92D7F, 32, NDPI_PROTOCOL_TOR }, + { 0x43AD3984, 32, NDPI_PROTOCOL_TOR }, + { 0x43AD4C19, 32, NDPI_PROTOCOL_TOR }, + { 0x43B43F19, 32, NDPI_PROTOCOL_TOR }, + { 0x43B799D5, 32, NDPI_PROTOCOL_TOR }, + { 0x43CD598E, 32, NDPI_PROTOCOL_TOR }, + { 0x43CD704A, 32, NDPI_PROTOCOL_TOR }, + { 0x43D7FF8C, 32, NDPI_PROTOCOL_TOR }, + { 0x43DC16BF, 32, NDPI_PROTOCOL_TOR }, + { 0x43F43639, 32, NDPI_PROTOCOL_TOR }, + { 0x43F98A71, 32, NDPI_PROTOCOL_TOR }, + { 0x43FDF527, 32, NDPI_PROTOCOL_TOR }, + { 0x43FF09CB, 32, NDPI_PROTOCOL_TOR }, + { 0x440440C6, 32, NDPI_PROTOCOL_TOR }, + { 0x440859BD, 32, NDPI_PROTOCOL_TOR }, + { 0x44094F72, 32, NDPI_PROTOCOL_TOR }, + { 0x440FB66B, 32, NDPI_PROTOCOL_TOR }, + { 0x442300D4, 32, NDPI_PROTOCOL_TOR }, + { 0x44238420, 32, NDPI_PROTOCOL_TOR }, + { 0x44240EFA, 32, NDPI_PROTOCOL_TOR }, + { 0x44342124, 32, NDPI_PROTOCOL_TOR }, + { 0x4434AFBE, 32, NDPI_PROTOCOL_TOR }, + { 0x443A307C, 32, NDPI_PROTOCOL_TOR }, + { 0x4440A1EE, 32, NDPI_PROTOCOL_TOR }, + { 0x44416405, 32, NDPI_PROTOCOL_TOR }, + { 0x44429AD6, 32, NDPI_PROTOCOL_TOR }, + { 0x44432303, 32, NDPI_PROTOCOL_TOR }, + { 0x44472E8A, 32, NDPI_PROTOCOL_TOR }, + { 0x445011A0, 32, NDPI_PROTOCOL_TOR }, + { 0x44590067, 32, NDPI_PROTOCOL_TOR }, + { 0x4461BFC0, 32, NDPI_PROTOCOL_TOR }, + { 0x44669EA3, 32, NDPI_PROTOCOL_TOR }, + { 0x4468364B, 32, NDPI_PROTOCOL_TOR }, + { 0x44706295, 32, NDPI_PROTOCOL_TOR }, + { 0x4471943A, 32, NDPI_PROTOCOL_TOR }, + { 0x4494A2D8, 32, NDPI_PROTOCOL_TOR }, + { 0x449528B7, 32, NDPI_PROTOCOL_TOR }, + { 0x44B7A9A7, 32, NDPI_PROTOCOL_TOR }, + { 0x44BB40FC, 32, NDPI_PROTOCOL_TOR }, + { 0x44E003CC, 32, NDPI_PROTOCOL_TOR }, + { 0x44E003CC, 32, NDPI_PROTOCOL_TOR }, + { 0x44E4F314, 32, NDPI_PROTOCOL_TOR }, + { 0x44E7DBD4, 32, NDPI_PROTOCOL_TOR }, + { 0x44E9EBD9, 32, NDPI_PROTOCOL_TOR }, + { 0x450C569F, 32, NDPI_PROTOCOL_TOR }, + { 0x450D2623, 32, NDPI_PROTOCOL_TOR }, + { 0x451B5416, 32, NDPI_PROTOCOL_TOR }, + { 0x451C5230, 32, NDPI_PROTOCOL_TOR }, + { 0x451C5A69, 32, NDPI_PROTOCOL_TOR }, + { 0x452731C9, 32, NDPI_PROTOCOL_TOR }, + { 0x4532A549, 32, NDPI_PROTOCOL_TOR }, + { 0x453EA2B2, 32, NDPI_PROTOCOL_TOR }, + { 0x45402255, 32, NDPI_PROTOCOL_TOR }, + { 0x454027B4, 32, NDPI_PROTOCOL_TOR }, + { 0x454030A8, 32, NDPI_PROTOCOL_TOR }, + { 0x45403430, 32, NDPI_PROTOCOL_TOR }, + { 0x4543FC87, 32, NDPI_PROTOCOL_TOR }, + { 0x45596485, 32, NDPI_PROTOCOL_TOR }, + { 0x455A97E5, 32, NDPI_PROTOCOL_TOR }, + { 0x455D7F39, 32, NDPI_PROTOCOL_TOR }, + { 0x45722B5C, 32, NDPI_PROTOCOL_TOR }, + { 0x45733217, 32, NDPI_PROTOCOL_TOR }, + { 0x4573C28D, 32, NDPI_PROTOCOL_TOR }, + { 0x4588E954, 32, NDPI_PROTOCOL_TOR }, + { 0x458A00E2, 32, NDPI_PROTOCOL_TOR }, + { 0x458AB189, 32, NDPI_PROTOCOL_TOR }, + { 0x458D2BC5, 32, NDPI_PROTOCOL_TOR }, + { 0x45928DBA, 32, NDPI_PROTOCOL_TOR }, + { 0x45A26B05, 32, NDPI_PROTOCOL_TOR }, + { 0x45A28B09, 32, NDPI_PROTOCOL_TOR }, + { 0x45A323DE, 32, NDPI_PROTOCOL_TOR }, + { 0x45A3640C, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4C3F0, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4C4EE, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4C524, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4C620, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4C696, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4CD93, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4CEB0, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4CFEA, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4D108, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4D197, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4D312, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4D4B4, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4D6FA, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4D852, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4DD41, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4DD4E, 32, NDPI_PROTOCOL_TOR }, + { 0x45A4DD99, 32, NDPI_PROTOCOL_TOR }, + { 0x45AC94F2, 32, NDPI_PROTOCOL_TOR }, + { 0x45AC9C67, 32, NDPI_PROTOCOL_TOR }, + { 0x45ACE727, 32, NDPI_PROTOCOL_TOR }, + { 0x45B57E1B, 32, NDPI_PROTOCOL_TOR }, + { 0x45C38CAE, 32, NDPI_PROTOCOL_TOR }, + { 0x45C456D6, 32, NDPI_PROTOCOL_TOR }, + { 0x45C4AE92, 32, NDPI_PROTOCOL_TOR }, + { 0x45C5AF23, 32, NDPI_PROTOCOL_TOR }, + { 0x45C5AF24, 32, NDPI_PROTOCOL_TOR }, + { 0x45F5523E, 32, NDPI_PROTOCOL_TOR }, + { 0x460F3C1D, 32, NDPI_PROTOCOL_TOR }, + { 0x4618CF2E, 32, NDPI_PROTOCOL_TOR }, + { 0x462438C6, 32, NDPI_PROTOCOL_TOR }, + { 0x46261F79, 32, NDPI_PROTOCOL_TOR }, + { 0x462C2054, 32, NDPI_PROTOCOL_TOR }, + { 0x463D61E4, 32, NDPI_PROTOCOL_TOR }, + { 0x463D61E5, 32, NDPI_PROTOCOL_TOR }, + { 0x463FAA56, 32, NDPI_PROTOCOL_TOR }, + { 0x46551FF2, 32, NDPI_PROTOCOL_TOR }, + { 0x4663CC61, 32, NDPI_PROTOCOL_TOR }, + { 0x4670A038, 32, NDPI_PROTOCOL_TOR }, + { 0x4670A341, 32, NDPI_PROTOCOL_TOR }, + { 0x467176E8, 32, NDPI_PROTOCOL_TOR }, + { 0x46721018, 32, NDPI_PROTOCOL_TOR }, + { 0x46A22F33, 32, NDPI_PROTOCOL_TOR }, + { 0x46A2595A, 32, NDPI_PROTOCOL_TOR }, + { 0x46A56AAE, 32, NDPI_PROTOCOL_TOR }, + { 0x46A923AD, 32, NDPI_PROTOCOL_TOR }, + { 0x46B5013D, 32, NDPI_PROTOCOL_TOR }, + { 0x46BB9A33, 32, NDPI_PROTOCOL_TOR }, + { 0x46BED043, 32, NDPI_PROTOCOL_TOR }, + { 0x470EB6E8, 32, NDPI_PROTOCOL_TOR }, + { 0x47139515, 32, NDPI_PROTOCOL_TOR }, + { 0x4713954E, 32, NDPI_PROTOCOL_TOR }, + { 0x47139BBB, 32, NDPI_PROTOCOL_TOR }, + { 0x47139D7F, 32, NDPI_PROTOCOL_TOR }, + { 0x47139DD5, 32, NDPI_PROTOCOL_TOR }, + { 0x47236A50, 32, NDPI_PROTOCOL_TOR }, + { 0x4738B62B, 32, NDPI_PROTOCOL_TOR }, + { 0x474BC940, 32, NDPI_PROTOCOL_TOR }, + { 0x474F591F, 32, NDPI_PROTOCOL_TOR }, + { 0x474F9691, 32, NDPI_PROTOCOL_TOR }, + { 0x475ACDF8, 32, NDPI_PROTOCOL_TOR }, + { 0x475F28FC, 32, NDPI_PROTOCOL_TOR }, + { 0x47872D47, 32, NDPI_PROTOCOL_TOR }, + { 0x47A59723, 32, NDPI_PROTOCOL_TOR }, + { 0x47A79A15, 32, NDPI_PROTOCOL_TOR }, + { 0x47AE3E2D, 32, NDPI_PROTOCOL_TOR }, + { 0x47B1E232, 32, NDPI_PROTOCOL_TOR }, + { 0x47B76C25, 32, NDPI_PROTOCOL_TOR }, + { 0x47B8FBE9, 32, NDPI_PROTOCOL_TOR }, + { 0x47B9233B, 32, NDPI_PROTOCOL_TOR }, + { 0x47B9AB0D, 32, NDPI_PROTOCOL_TOR }, + { 0x47C3DB07, 32, NDPI_PROTOCOL_TOR }, + { 0x47C5EB05, 32, NDPI_PROTOCOL_TOR }, + { 0x47C5FE48, 32, NDPI_PROTOCOL_TOR }, + { 0x47C772A6, 32, NDPI_PROTOCOL_TOR }, + { 0x47CAB8E5, 32, NDPI_PROTOCOL_TOR }, + { 0x47CC7AF0, 32, NDPI_PROTOCOL_TOR }, + { 0x47D7CE97, 32, NDPI_PROTOCOL_TOR }, + { 0x47DBB265, 32, NDPI_PROTOCOL_TOR }, + { 0x47DE7EC5, 32, NDPI_PROTOCOL_TOR }, + { 0x47E0883A, 32, NDPI_PROTOCOL_TOR }, + { 0x47E6FD44, 32, NDPI_PROTOCOL_TOR }, + { 0x47E7BE7B, 32, NDPI_PROTOCOL_TOR }, + { 0x47EB4AB7, 32, NDPI_PROTOCOL_TOR }, + { 0x47F5506C, 32, NDPI_PROTOCOL_TOR }, + { 0x47FB9E4B, 32, NDPI_PROTOCOL_TOR }, + { 0x4800E332, 32, NDPI_PROTOCOL_TOR }, + { 0x480EB0AC, 32, NDPI_PROTOCOL_TOR }, + { 0x480EB1A4, 32, NDPI_PROTOCOL_TOR }, + { 0x480EB30A, 32, NDPI_PROTOCOL_TOR }, + { 0x480EB3A3, 32, NDPI_PROTOCOL_TOR }, + { 0x480EB552, 32, NDPI_PROTOCOL_TOR }, + { 0x480EB83D, 32, NDPI_PROTOCOL_TOR }, + { 0x480EBAE2, 32, NDPI_PROTOCOL_TOR }, + { 0x481AD093, 32, NDPI_PROTOCOL_TOR }, + { 0x481DA212, 32, NDPI_PROTOCOL_TOR }, + { 0x482E9BBA, 32, NDPI_PROTOCOL_TOR }, + { 0x48332350, 32, NDPI_PROTOCOL_TOR }, + { 0x48344B1B, 32, NDPI_PROTOCOL_TOR }, + { 0x48345B16, 32, NDPI_PROTOCOL_TOR }, + { 0x48345B1D, 32, NDPI_PROTOCOL_TOR }, + { 0x48345B1E, 32, NDPI_PROTOCOL_TOR }, + { 0x48358586, 32, NDPI_PROTOCOL_TOR }, + { 0x484200E9, 32, NDPI_PROTOCOL_TOR }, + { 0x4845E5D5, 32, NDPI_PROTOCOL_TOR }, + { 0x4845F863, 32, NDPI_PROTOCOL_TOR }, + { 0x484E8BB9, 32, NDPI_PROTOCOL_TOR }, + { 0x48531759, 32, NDPI_PROTOCOL_TOR }, + { 0x4859E93A, 32, NDPI_PROTOCOL_TOR }, + { 0x485DF597, 32, NDPI_PROTOCOL_TOR }, + { 0x488184C2, 32, NDPI_PROTOCOL_TOR }, + { 0x488313EC, 32, NDPI_PROTOCOL_TOR }, + { 0x48A0F076, 32, NDPI_PROTOCOL_TOR }, + { 0x48AEAC8D, 32, NDPI_PROTOCOL_TOR }, + { 0x48B13B6E, 32, NDPI_PROTOCOL_TOR }, + { 0x48C0D011, 32, NDPI_PROTOCOL_TOR }, + { 0x48C105B0, 32, NDPI_PROTOCOL_TOR }, + { 0x48C5C123, 32, NDPI_PROTOCOL_TOR }, + { 0x48D1B426, 32, NDPI_PROTOCOL_TOR }, + { 0x48D1DB9A, 32, NDPI_PROTOCOL_TOR }, + { 0x48D8ECC2, 32, NDPI_PROTOCOL_TOR }, + { 0x48DCAD6B, 32, NDPI_PROTOCOL_TOR }, + { 0x48DE8A0C, 32, NDPI_PROTOCOL_TOR }, + { 0x48E1295B, 32, NDPI_PROTOCOL_TOR }, + { 0x48EFE271, 32, NDPI_PROTOCOL_TOR }, + { 0x48F9B964, 32, NDPI_PROTOCOL_TOR }, + { 0x48FAD50D, 32, NDPI_PROTOCOL_TOR }, + { 0x48FD5C2C, 32, NDPI_PROTOCOL_TOR }, + { 0x49041E43, 32, NDPI_PROTOCOL_TOR }, + { 0x49043472, 32, NDPI_PROTOCOL_TOR }, + { 0x4906D179, 32, NDPI_PROTOCOL_TOR }, + { 0x4908B6E5, 32, NDPI_PROTOCOL_TOR }, + { 0x490B9E26, 32, NDPI_PROTOCOL_TOR }, + { 0x490F96AC, 32, NDPI_PROTOCOL_TOR }, + { 0x490FFEF1, 32, NDPI_PROTOCOL_TOR }, + { 0x49134ECD, 32, NDPI_PROTOCOL_TOR }, + { 0x491610C3, 32, NDPI_PROTOCOL_TOR }, + { 0x492574A8, 32, NDPI_PROTOCOL_TOR }, + { 0x4926F8B6, 32, NDPI_PROTOCOL_TOR }, + { 0x49274DA6, 32, NDPI_PROTOCOL_TOR }, + { 0x492C8639, 32, NDPI_PROTOCOL_TOR }, + { 0x492D254B, 32, NDPI_PROTOCOL_TOR }, + { 0x492FF6DF, 32, NDPI_PROTOCOL_TOR }, + { 0x49304E30, 32, NDPI_PROTOCOL_TOR }, + { 0x49308BE2, 32, NDPI_PROTOCOL_TOR }, + { 0x498400F7, 32, NDPI_PROTOCOL_TOR }, + { 0x4984FA0B, 32, NDPI_PROTOCOL_TOR }, + { 0x49A3EC5F, 32, NDPI_PROTOCOL_TOR }, + { 0x49A5F4EE, 32, NDPI_PROTOCOL_TOR }, + { 0x49A64EFD, 32, NDPI_PROTOCOL_TOR }, + { 0x49A69CAC, 32, NDPI_PROTOCOL_TOR }, + { 0x49AA0647, 32, NDPI_PROTOCOL_TOR }, + { 0x49AC98E6, 32, NDPI_PROTOCOL_TOR }, + { 0x49C08B3F, 32, NDPI_PROTOCOL_TOR }, + { 0x49C0E718, 32, NDPI_PROTOCOL_TOR }, + { 0x49C6A499, 32, NDPI_PROTOCOL_TOR }, + { 0x49C7CBB9, 32, NDPI_PROTOCOL_TOR }, + { 0x49CAE19F, 32, NDPI_PROTOCOL_TOR }, + { 0x49D03060, 32, NDPI_PROTOCOL_TOR }, + { 0x49D0409E, 32, NDPI_PROTOCOL_TOR }, + { 0x49D0A2E1, 32, NDPI_PROTOCOL_TOR }, + { 0x49D932BB, 32, NDPI_PROTOCOL_TOR }, + { 0x49DE0E0A, 32, NDPI_PROTOCOL_TOR }, + { 0x4A03A527, 32, NDPI_PROTOCOL_TOR }, + { 0x4A323644, 32, NDPI_PROTOCOL_TOR }, + { 0x4A3BA760, 32, NDPI_PROTOCOL_TOR }, + { 0x4A3BCC47, 32, NDPI_PROTOCOL_TOR }, + { 0x4A436379, 32, NDPI_PROTOCOL_TOR }, + { 0x4A47FA54, 32, NDPI_PROTOCOL_TOR }, + { 0x4A5203E0, 32, NDPI_PROTOCOL_TOR }, + { 0x4A536574, 32, NDPI_PROTOCOL_TOR }, + { 0x4A561813, 32, NDPI_PROTOCOL_TOR }, + { 0x4A5B1B8D, 32, NDPI_PROTOCOL_TOR }, + { 0x4A5B1B8E, 32, NDPI_PROTOCOL_TOR }, + { 0x4A5E43C4, 32, NDPI_PROTOCOL_TOR }, + { 0x4A5FBB69, 32, NDPI_PROTOCOL_TOR }, + { 0x4A60E7B2, 32, NDPI_PROTOCOL_TOR }, + { 0x4A621760, 32, NDPI_PROTOCOL_TOR }, + { 0x4A65C9F9, 32, NDPI_PROTOCOL_TOR }, + { 0x4A677F7F, 32, NDPI_PROTOCOL_TOR }, + { 0x4A6DF071, 32, NDPI_PROTOCOL_TOR }, + { 0x4A74BA78, 32, NDPI_PROTOCOL_TOR }, + { 0x4A79B693, 32, NDPI_PROTOCOL_TOR }, + { 0x4A7CAB14, 32, NDPI_PROTOCOL_TOR }, + { 0x4A8AA23A, 32, NDPI_PROTOCOL_TOR }, + { 0x4AB9DBC9, 32, NDPI_PROTOCOL_TOR }, + { 0x4AC09417, 32, NDPI_PROTOCOL_TOR }, + { 0x4AC14C45, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACEB5A4, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFE03F, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFE03F, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFE7BA, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFE7FA, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFE998, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFECC5, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFED2C, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFEDA7, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFEDA7, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFF207, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFF86E, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFF9A9, 32, NDPI_PROTOCOL_TOR }, + { 0x4ACFFB6D, 32, NDPI_PROTOCOL_TOR }, + { 0x4AD045C2, 32, NDPI_PROTOCOL_TOR }, + { 0x4AD04E82, 32, NDPI_PROTOCOL_TOR }, + { 0x4AD2C50C, 32, NDPI_PROTOCOL_TOR }, + { 0x4B013890, 32, NDPI_PROTOCOL_TOR }, + { 0x4B09754D, 32, NDPI_PROTOCOL_TOR }, + { 0x4B435766, 32, NDPI_PROTOCOL_TOR }, + { 0x4B451E4D, 32, NDPI_PROTOCOL_TOR }, + { 0x4B488B38, 32, NDPI_PROTOCOL_TOR }, + { 0x4B4F23FE, 32, NDPI_PROTOCOL_TOR }, + { 0x4B50A0EC, 32, NDPI_PROTOCOL_TOR }, + { 0x4B5169DB, 32, NDPI_PROTOCOL_TOR }, + { 0x4B52A04D, 32, NDPI_PROTOCOL_TOR }, + { 0x4B54A327, 32, NDPI_PROTOCOL_TOR }, + { 0x4B6189EA, 32, NDPI_PROTOCOL_TOR }, + { 0x4B642932, 32, NDPI_PROTOCOL_TOR }, + { 0x4B65602F, 32, NDPI_PROTOCOL_TOR }, + { 0x4B7650AB, 32, NDPI_PROTOCOL_TOR }, + { 0x4B76EED4, 32, NDPI_PROTOCOL_TOR }, + { 0x4B77E8C9, 32, NDPI_PROTOCOL_TOR }, + { 0x4B7F0F49, 32, NDPI_PROTOCOL_TOR }, + { 0x4B82033A, 32, NDPI_PROTOCOL_TOR }, + { 0x4B849247, 32, NDPI_PROTOCOL_TOR }, + { 0x4B8567ED, 32, NDPI_PROTOCOL_TOR }, + { 0x4B8FB432, 32, NDPI_PROTOCOL_TOR }, + { 0x4B91CDB1, 32, NDPI_PROTOCOL_TOR }, + { 0x4B965B14, 32, NDPI_PROTOCOL_TOR }, + { 0x4B965B15, 32, NDPI_PROTOCOL_TOR }, + { 0x4BA665D5, 32, NDPI_PROTOCOL_TOR }, + { 0x4BB117FE, 32, NDPI_PROTOCOL_TOR }, + { 0x4BB38B1A, 32, NDPI_PROTOCOL_TOR }, + { 0x4BB3AFC4, 32, NDPI_PROTOCOL_TOR }, + { 0x4BB66C77, 32, NDPI_PROTOCOL_TOR }, + { 0x4BB93208, 32, NDPI_PROTOCOL_TOR }, + { 0x4C0A8078, 32, NDPI_PROTOCOL_TOR }, + { 0x4C0CDB68, 32, NDPI_PROTOCOL_TOR }, + { 0x4C17D13D, 32, NDPI_PROTOCOL_TOR }, + { 0x4C1ACBF3, 32, NDPI_PROTOCOL_TOR }, + { 0x4C1CD1A5, 32, NDPI_PROTOCOL_TOR }, + { 0x4C1CEA17, 32, NDPI_PROTOCOL_TOR }, + { 0x4C400D9B, 32, NDPI_PROTOCOL_TOR }, + { 0x4C490364, 32, NDPI_PROTOCOL_TOR }, + { 0x4C4903AE, 32, NDPI_PROTOCOL_TOR }, + { 0x4C493996, 32, NDPI_PROTOCOL_TOR }, + { 0x4C4AB2F6, 32, NDPI_PROTOCOL_TOR }, + { 0x4C4ADB8A, 32, NDPI_PROTOCOL_TOR }, + { 0x4C4C08E8, 32, NDPI_PROTOCOL_TOR }, + { 0x4C4F2E66, 32, NDPI_PROTOCOL_TOR }, + { 0x4C55CFD4, 32, NDPI_PROTOCOL_TOR }, + { 0x4C5BCBA2, 32, NDPI_PROTOCOL_TOR }, + { 0x4C5BE269, 32, NDPI_PROTOCOL_TOR }, + { 0x4C5CE1D8, 32, NDPI_PROTOCOL_TOR }, + { 0x4C5DD733, 32, NDPI_PROTOCOL_TOR }, + { 0x4C63DE9C, 32, NDPI_PROTOCOL_TOR }, + { 0x4C66C7AA, 32, NDPI_PROTOCOL_TOR }, + { 0x4C6A2761, 32, NDPI_PROTOCOL_TOR }, + { 0x4C702F3C, 32, NDPI_PROTOCOL_TOR }, + { 0x4C7153C2, 32, NDPI_PROTOCOL_TOR }, + { 0x4C732D7C, 32, NDPI_PROTOCOL_TOR }, + { 0x4C73829B, 32, NDPI_PROTOCOL_TOR }, + { 0x4C778735, 32, NDPI_PROTOCOL_TOR }, + { 0x4C7A13E6, 32, NDPI_PROTOCOL_TOR }, + { 0x4C7BBBD2, 32, NDPI_PROTOCOL_TOR }, + { 0x4C7C660E, 32, NDPI_PROTOCOL_TOR }, + { 0x4C7CAF69, 32, NDPI_PROTOCOL_TOR }, + { 0x4C7E0D52, 32, NDPI_PROTOCOL_TOR }, + { 0x4CAA4864, 32, NDPI_PROTOCOL_TOR }, + { 0x4CAEFDD2, 32, NDPI_PROTOCOL_TOR }, + { 0x4CB28C0E, 32, NDPI_PROTOCOL_TOR }, + { 0x4CB9120F, 32, NDPI_PROTOCOL_TOR }, + { 0x4CBAB2BC, 32, NDPI_PROTOCOL_TOR }, + { 0x4CBC4252, 32, NDPI_PROTOCOL_TOR }, + { 0x4CBFD7D7, 32, NDPI_PROTOCOL_TOR }, + { 0x4CD11461, 32, NDPI_PROTOCOL_TOR }, + { 0x4CD90D94, 32, NDPI_PROTOCOL_TOR }, + { 0x4CD90D94, 32, NDPI_PROTOCOL_TOR }, + { 0x4CD995F0, 32, NDPI_PROTOCOL_TOR }, + { 0x4D00C9A3, 32, NDPI_PROTOCOL_TOR }, + { 0x4D01045C, 32, NDPI_PROTOCOL_TOR }, + { 0x4D04EB00, 32, NDPI_PROTOCOL_TOR }, + { 0x4D06EDF4, 32, NDPI_PROTOCOL_TOR }, + { 0x4D0A7CF0, 32, NDPI_PROTOCOL_TOR }, + { 0x4D0AAEE8, 32, NDPI_PROTOCOL_TOR }, + { 0x4D0AD0A5, 32, NDPI_PROTOCOL_TOR }, + { 0x4D0C1CB8, 32, NDPI_PROTOCOL_TOR }, + { 0x4D0C1CB8, 32, NDPI_PROTOCOL_TOR }, + { 0x4D0C65BB, 32, NDPI_PROTOCOL_TOR }, + { 0x4D0C84CC, 32, NDPI_PROTOCOL_TOR }, + { 0x4D0DB854, 32, NDPI_PROTOCOL_TOR }, + { 0x4D0DBCEF, 32, NDPI_PROTOCOL_TOR }, + { 0x4D142DA8, 32, NDPI_PROTOCOL_TOR }, + { 0x4D1430C4, 32, NDPI_PROTOCOL_TOR }, + { 0x4D145762, 32, NDPI_PROTOCOL_TOR }, + { 0x4D149215, 32, NDPI_PROTOCOL_TOR }, + { 0x4D149784, 32, NDPI_PROTOCOL_TOR }, + { 0x4D14C9D3, 32, NDPI_PROTOCOL_TOR }, + { 0x4D1505EA, 32, NDPI_PROTOCOL_TOR }, + { 0x4D15295E, 32, NDPI_PROTOCOL_TOR }, + { 0x4D154971, 32, NDPI_PROTOCOL_TOR }, + { 0x4D154D67, 32, NDPI_PROTOCOL_TOR }, + { 0x4D15D971, 32, NDPI_PROTOCOL_TOR }, + { 0x4D170724, 32, NDPI_PROTOCOL_TOR }, + { 0x4D170A99, 32, NDPI_PROTOCOL_TOR }, + { 0x4D171AE2, 32, NDPI_PROTOCOL_TOR }, + { 0x4D176F1E, 32, NDPI_PROTOCOL_TOR }, + { 0x4D250CBF, 32, NDPI_PROTOCOL_TOR }, + { 0x4D2588A5, 32, NDPI_PROTOCOL_TOR }, + { 0x4D25B87E, 32, NDPI_PROTOCOL_TOR }, + { 0x4D25DA91, 32, NDPI_PROTOCOL_TOR }, + { 0x4D25F08E, 32, NDPI_PROTOCOL_TOR }, + { 0x4D292F5B, 32, NDPI_PROTOCOL_TOR }, + { 0x4D2DFD87, 32, NDPI_PROTOCOL_TOR }, + { 0x4D2F7D6F, 32, NDPI_PROTOCOL_TOR }, + { 0x4D2FD16E, 32, NDPI_PROTOCOL_TOR }, + { 0x4D32EB4C, 32, NDPI_PROTOCOL_TOR }, + { 0x4D343FC5, 32, NDPI_PROTOCOL_TOR }, + { 0x4D3856DC, 32, NDPI_PROTOCOL_TOR }, + { 0x4D396860, 32, NDPI_PROTOCOL_TOR }, + { 0x4D3A033E, 32, NDPI_PROTOCOL_TOR }, + { 0x4D3AD4A9, 32, NDPI_PROTOCOL_TOR }, + { 0x4D40D46F, 32, NDPI_PROTOCOL_TOR }, + { 0x4D422DE3, 32, NDPI_PROTOCOL_TOR }, + { 0x4D422E18, 32, NDPI_PROTOCOL_TOR }, + { 0x4D44245D, 32, NDPI_PROTOCOL_TOR }, + { 0x4D463F8D, 32, NDPI_PROTOCOL_TOR }, + { 0x4D48932F, 32, NDPI_PROTOCOL_TOR }, + { 0x4D489696, 32, NDPI_PROTOCOL_TOR }, + { 0x4D4E77D3, 32, NDPI_PROTOCOL_TOR }, + { 0x4D51F029, 32, NDPI_PROTOCOL_TOR }, + { 0x4D56C546, 32, NDPI_PROTOCOL_TOR }, + { 0x4D56CC64, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6220E9, 32, NDPI_PROTOCOL_TOR }, + { 0x4D66D762, 32, NDPI_PROTOCOL_TOR }, + { 0x4D69D0D9, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6D8A2A, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6D8A2B, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6D8A2C, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6D8B1A, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6D8B1B, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6D8B1C, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6D8B57, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6D8D8A, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6D8D8B, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6D8D8C, 32, NDPI_PROTOCOL_TOR }, + { 0x4D6DB99C, 32, NDPI_PROTOCOL_TOR }, + { 0x4D765894, 32, NDPI_PROTOCOL_TOR }, + { 0x4D7B5606, 32, NDPI_PROTOCOL_TOR }, + { 0x4D834130, 32, NDPI_PROTOCOL_TOR }, + { 0x4D86A910, 32, NDPI_PROTOCOL_TOR }, + { 0x4D98FB30, 32, NDPI_PROTOCOL_TOR }, + { 0x4DAA0102, 32, NDPI_PROTOCOL_TOR }, + { 0x4DAE88F2, 32, NDPI_PROTOCOL_TOR }, + { 0x4DAEB4C5, 32, NDPI_PROTOCOL_TOR }, + { 0x4DAEF986, 32, NDPI_PROTOCOL_TOR }, + { 0x4DC5A34D, 32, NDPI_PROTOCOL_TOR }, + { 0x4DCBDD5B, 32, NDPI_PROTOCOL_TOR }, + { 0x4DCF4DB2, 32, NDPI_PROTOCOL_TOR }, + { 0x4DCF6FCE, 32, NDPI_PROTOCOL_TOR }, + { 0x4DDF4BCF, 32, NDPI_PROTOCOL_TOR }, + { 0x4DE4A752, 32, NDPI_PROTOCOL_TOR }, + { 0x4DE4AF4A, 32, NDPI_PROTOCOL_TOR }, + { 0x4DE9EE82, 32, NDPI_PROTOCOL_TOR }, + { 0x4DEA31CE, 32, NDPI_PROTOCOL_TOR }, + { 0x4DEA947A, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF30962, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF4FEE3, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF4FEE4, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF4FEE5, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF4FEE6, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF6D813, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF7B5A2, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF7B5A3, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF7B5A3, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF7B5A4, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF7B5A5, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF7B5A5, 32, NDPI_PROTOCOL_TOR }, + { 0x4DF7B5A6, 32, NDPI_PROTOCOL_TOR }, + { 0x4DFB6AF8, 32, NDPI_PROTOCOL_TOR }, + { 0x4DFEAE40, 32, NDPI_PROTOCOL_TOR }, + { 0x4E08A504, 32, NDPI_PROTOCOL_TOR }, + { 0x4E0D3D36, 32, NDPI_PROTOCOL_TOR }, + { 0x4E1506A1, 32, NDPI_PROTOCOL_TOR }, + { 0x4E18DA8A, 32, NDPI_PROTOCOL_TOR }, + { 0x4E1B6E57, 32, NDPI_PROTOCOL_TOR }, + { 0x4E1FA429, 32, NDPI_PROTOCOL_TOR }, + { 0x4E227847, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2917A2, 32, NDPI_PROTOCOL_TOR }, + { 0x4E29E9C0, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2A9D62, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2B689D, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2B752E, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2B8EB1, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2D136A, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E1188, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E2BDD, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E2DF2, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E337C, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E350B, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E3C1E, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E40F5, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E4229, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E50F7, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E512D, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E5F14, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E69F1, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E6A6F, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E6B0F, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E70DB, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E7B22, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E7BAC, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E943A, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E970B, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E9713, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2E989E, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2EA78D, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2EB0A9, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2EC54B, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2EDA0B, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2EDC82, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2EDD7D, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2EE185, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2EEFB7, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2EF724, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2EF729, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F0406, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F10A6, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F126E, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F1BF6, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F2323, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F273C, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F27BC, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F297D, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F2CBC, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F2CD4, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F31EB, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F325C, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F35B7, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F3DDE, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F405B, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F49B6, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F5462, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F5699, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F5D0C, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F5DC8, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F5F9C, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F8606, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F8B62, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F9199, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F94AE, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2F963D, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FA559, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FA844, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FABA6, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FACF4, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FAE9B, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FBAF3, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FBC04, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FBFDD, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FC5AC, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FD81C, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FDABE, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FDBA6, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FDE4A, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FE0DB, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FE208, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FE568, 32, NDPI_PROTOCOL_TOR }, + { 0x4E2FE56B, 32, NDPI_PROTOCOL_TOR }, + { 0x4E301266, 32, NDPI_PROTOCOL_TOR }, + { 0x4E30213F, 32, NDPI_PROTOCOL_TOR }, + { 0x4E30E5E7, 32, NDPI_PROTOCOL_TOR }, + { 0x4E314714, 32, NDPI_PROTOCOL_TOR }, + { 0x4E337866, 32, NDPI_PROTOCOL_TOR }, + { 0x4E339FA4, 32, NDPI_PROTOCOL_TOR }, + { 0x4E341CCA, 32, NDPI_PROTOCOL_TOR }, + { 0x4E344588, 32, NDPI_PROTOCOL_TOR }, + { 0x4E345BC2, 32, NDPI_PROTOCOL_TOR }, + { 0x4E34709C, 32, NDPI_PROTOCOL_TOR }, + { 0x4E3500BA, 32, NDPI_PROTOCOL_TOR }, + { 0x4E3543BB, 32, NDPI_PROTOCOL_TOR }, + { 0x4E3578C0, 32, NDPI_PROTOCOL_TOR }, + { 0x4E35D113, 32, NDPI_PROTOCOL_TOR }, + { 0x4E36B32D, 32, NDPI_PROTOCOL_TOR }, + { 0x4E36B849, 32, NDPI_PROTOCOL_TOR }, + { 0x4E37167F, 32, NDPI_PROTOCOL_TOR }, + { 0x4E371BD3, 32, NDPI_PROTOCOL_TOR }, + { 0x4E37EECD, 32, NDPI_PROTOCOL_TOR }, + { 0x4E382816, 32, NDPI_PROTOCOL_TOR }, + { 0x4E38837E, 32, NDPI_PROTOCOL_TOR }, + { 0x4E448EF1, 32, NDPI_PROTOCOL_TOR }, + { 0x4E455699, 32, NDPI_PROTOCOL_TOR }, + { 0x4E460AE6, 32, NDPI_PROTOCOL_TOR }, + { 0x4E559863, 32, NDPI_PROTOCOL_TOR }, + { 0x4E55C395, 32, NDPI_PROTOCOL_TOR }, + { 0x4E582ECD, 32, NDPI_PROTOCOL_TOR }, + { 0x4E5A0FE5, 32, NDPI_PROTOCOL_TOR }, + { 0x4E5A8252, 32, NDPI_PROTOCOL_TOR }, + { 0x4E5E71A9, 32, NDPI_PROTOCOL_TOR }, + { 0x4E5EC2DB, 32, NDPI_PROTOCOL_TOR }, + { 0x4E5EFD61, 32, NDPI_PROTOCOL_TOR }, + { 0x4E66CF73, 32, NDPI_PROTOCOL_TOR }, + { 0x4E6A9813, 32, NDPI_PROTOCOL_TOR }, + { 0x4E6BE9E5, 32, NDPI_PROTOCOL_TOR }, + { 0x4E6BED10, 32, NDPI_PROTOCOL_TOR }, + { 0x4E6BEFD5, 32, NDPI_PROTOCOL_TOR }, + { 0x4E6BFE79, 32, NDPI_PROTOCOL_TOR }, + { 0x4E6C3F2C, 32, NDPI_PROTOCOL_TOR }, + { 0x4E6C3F2E, 32, NDPI_PROTOCOL_TOR }, + { 0x4E6EA0B9, 32, NDPI_PROTOCOL_TOR }, + { 0x4E6F4E8C, 32, NDPI_PROTOCOL_TOR }, + { 0x4E6FEE6B, 32, NDPI_PROTOCOL_TOR }, + { 0x4E73B49D, 32, NDPI_PROTOCOL_TOR }, + { 0x4E787A3F, 32, NDPI_PROTOCOL_TOR }, + { 0x4E81891C, 32, NDPI_PROTOCOL_TOR }, + { 0x4E81A639, 32, NDPI_PROTOCOL_TOR }, + { 0x4E81B421, 32, NDPI_PROTOCOL_TOR }, + { 0x4E833886, 32, NDPI_PROTOCOL_TOR }, + { 0x4E8B7228, 32, NDPI_PROTOCOL_TOR }, + { 0x4E8D50EC, 32, NDPI_PROTOCOL_TOR }, + { 0x4E8E8EF6, 32, NDPI_PROTOCOL_TOR }, + { 0x4E8E918D, 32, NDPI_PROTOCOL_TOR }, + { 0x4E8EAF46, 32, NDPI_PROTOCOL_TOR }, + { 0x4E91349D, 32, NDPI_PROTOCOL_TOR }, + { 0x4E9BA97A, 32, NDPI_PROTOCOL_TOR }, + { 0x4E9C75EC, 32, NDPI_PROTOCOL_TOR }, + { 0x4E9C77C8, 32, NDPI_PROTOCOL_TOR }, + { 0x4E9DC871, 32, NDPI_PROTOCOL_TOR }, + { 0x4E9F3CC3, 32, NDPI_PROTOCOL_TOR }, + { 0x4EC0BD4C, 32, NDPI_PROTOCOL_TOR }, + { 0x4EC0F14B, 32, NDPI_PROTOCOL_TOR }, + { 0x4EC1067E, 32, NDPI_PROTOCOL_TOR }, + { 0x4EC128CD, 32, NDPI_PROTOCOL_TOR }, + { 0x4EC128FE, 32, NDPI_PROTOCOL_TOR }, + { 0x4EC14F78, 32, NDPI_PROTOCOL_TOR }, + { 0x4EC15603, 32, NDPI_PROTOCOL_TOR }, + { 0x4EC1674D, 32, NDPI_PROTOCOL_TOR }, + { 0x4EC1A442, 32, NDPI_PROTOCOL_TOR }, + { 0x4EC6B4CD, 32, NDPI_PROTOCOL_TOR }, + { 0x4ECD5081, 32, NDPI_PROTOCOL_TOR }, + { 0x4EDA527F, 32, NDPI_PROTOCOL_TOR }, + { 0x4EDD8C72, 32, NDPI_PROTOCOL_TOR }, + { 0x4EE030F7, 32, NDPI_PROTOCOL_TOR }, + { 0x4EE0F0C4, 32, NDPI_PROTOCOL_TOR }, + { 0x4EE2A060, 32, NDPI_PROTOCOL_TOR }, + { 0x4EE588B8, 32, NDPI_PROTOCOL_TOR }, + { 0x4EE96597, 32, NDPI_PROTOCOL_TOR }, + { 0x4EEC369E, 32, NDPI_PROTOCOL_TOR }, + { 0x4EEF7556, 32, NDPI_PROTOCOL_TOR }, + { 0x4EF7B665, 32, NDPI_PROTOCOL_TOR }, + { 0x4EF8D759, 32, NDPI_PROTOCOL_TOR }, + { 0x4F4771F0, 32, NDPI_PROTOCOL_TOR }, + { 0x4F501132, 32, NDPI_PROTOCOL_TOR }, + { 0x4F59660B, 32, NDPI_PROTOCOL_TOR }, + { 0x4F621F2A, 32, NDPI_PROTOCOL_TOR }, + { 0x4F660402, 32, NDPI_PROTOCOL_TOR }, + { 0x4F6D109F, 32, NDPI_PROTOCOL_TOR }, + { 0x4F6D94CB, 32, NDPI_PROTOCOL_TOR }, + { 0x4F6F13C2, 32, NDPI_PROTOCOL_TOR }, + { 0x4F6F51A0, 32, NDPI_PROTOCOL_TOR }, + { 0x4F6FDA32, 32, NDPI_PROTOCOL_TOR }, + { 0x4F700984, 32, NDPI_PROTOCOL_TOR }, + { 0x4F716914, 32, NDPI_PROTOCOL_TOR }, + { 0x4F780A62, 32, NDPI_PROTOCOL_TOR }, + { 0x4F78282D, 32, NDPI_PROTOCOL_TOR }, + { 0x4F7851B7, 32, NDPI_PROTOCOL_TOR }, + { 0x4F825F7B, 32, NDPI_PROTOCOL_TOR }, + { 0x4F861BFF, 32, NDPI_PROTOCOL_TOR }, + { 0x4F86EAC8, 32, NDPI_PROTOCOL_TOR }, + { 0x4F86EB05, 32, NDPI_PROTOCOL_TOR }, + { 0x4F86FF23, 32, NDPI_PROTOCOL_TOR }, + { 0x4F87465A, 32, NDPI_PROTOCOL_TOR }, + { 0x4F881D2B, 32, NDPI_PROTOCOL_TOR }, + { 0x4F882ABE, 32, NDPI_PROTOCOL_TOR }, + { 0x4F8BBDB9, 32, NDPI_PROTOCOL_TOR }, + { 0x4F8C27CA, 32, NDPI_PROTOCOL_TOR }, + { 0x4F8C2975, 32, NDPI_PROTOCOL_TOR }, + { 0x4F8C2976, 32, NDPI_PROTOCOL_TOR }, + { 0x4F8C4005, 32, NDPI_PROTOCOL_TOR }, + { 0x4F8E6A54, 32, NDPI_PROTOCOL_TOR }, + { 0x4F8FB36A, 32, NDPI_PROTOCOL_TOR }, + { 0x4F8FB572, 32, NDPI_PROTOCOL_TOR }, + { 0x4F8FBC46, 32, NDPI_PROTOCOL_TOR }, + { 0x4FA04C99, 32, NDPI_PROTOCOL_TOR }, + { 0x4FA0A26A, 32, NDPI_PROTOCOL_TOR }, + { 0x4FA438F1, 32, NDPI_PROTOCOL_TOR }, + { 0x4FA45FB4, 32, NDPI_PROTOCOL_TOR }, + { 0x4FA5B4F3, 32, NDPI_PROTOCOL_TOR }, + { 0x4FA5DFD1, 32, NDPI_PROTOCOL_TOR }, + { 0x4FAC1212, 32, NDPI_PROTOCOL_TOR }, + { 0x4FAC1CCD, 32, NDPI_PROTOCOL_TOR }, + { 0x4FACC120, 32, NDPI_PROTOCOL_TOR }, + { 0x4FACCC24, 32, NDPI_PROTOCOL_TOR }, + { 0x4FACF908, 32, NDPI_PROTOCOL_TOR }, + { 0x4FB73E97, 32, NDPI_PROTOCOL_TOR }, + { 0x4FBD0233, 32, NDPI_PROTOCOL_TOR }, + { 0x4FC17B35, 32, NDPI_PROTOCOL_TOR }, + { 0x4FC3BA9D, 32, NDPI_PROTOCOL_TOR }, + { 0x4FC5C597, 32, NDPI_PROTOCOL_TOR }, + { 0x4FC8C7B3, 32, NDPI_PROTOCOL_TOR }, + { 0x4FCA6B3A, 32, NDPI_PROTOCOL_TOR }, + { 0x4FCB519B, 32, NDPI_PROTOCOL_TOR }, + { 0x4FD446F9, 32, NDPI_PROTOCOL_TOR }, + { 0x4FD62F35, 32, NDPI_PROTOCOL_TOR }, + { 0x4FD6C9C2, 32, NDPI_PROTOCOL_TOR }, + { 0x4FD6E742, 32, NDPI_PROTOCOL_TOR }, + { 0x4FD7DEA0, 32, NDPI_PROTOCOL_TOR }, + { 0x4FDCC79F, 32, NDPI_PROTOCOL_TOR }, + { 0x4FE25CA4, 32, NDPI_PROTOCOL_TOR }, + { 0x4FE2CDCD, 32, NDPI_PROTOCOL_TOR }, + { 0x4FE2DAE6, 32, NDPI_PROTOCOL_TOR }, + { 0x4FE3BBBF, 32, NDPI_PROTOCOL_TOR }, + { 0x4FE478A5, 32, NDPI_PROTOCOL_TOR }, + { 0x4FE4EA15, 32, NDPI_PROTOCOL_TOR }, + { 0x4FE5C024, 32, NDPI_PROTOCOL_TOR }, + { 0x4FE755CF, 32, NDPI_PROTOCOL_TOR }, + { 0x4FEA50ED, 32, NDPI_PROTOCOL_TOR }, + { 0x4FEB63B5, 32, NDPI_PROTOCOL_TOR }, + { 0x4FEC5A62, 32, NDPI_PROTOCOL_TOR }, + { 0x4FECD8B0, 32, NDPI_PROTOCOL_TOR }, + { 0x4FF15810, 32, NDPI_PROTOCOL_TOR }, + { 0x4FF19FF7, 32, NDPI_PROTOCOL_TOR }, + { 0x4FF1D2DC, 32, NDPI_PROTOCOL_TOR }, + { 0x4FF1D690, 32, NDPI_PROTOCOL_TOR }, + { 0x4FF2515A, 32, NDPI_PROTOCOL_TOR }, + { 0x4FF35735, 32, NDPI_PROTOCOL_TOR }, + { 0x4FF5435F, 32, NDPI_PROTOCOL_TOR }, + { 0x4FF58FAB, 32, NDPI_PROTOCOL_TOR }, + { 0x4FF6CF32, 32, NDPI_PROTOCOL_TOR }, + { 0x4FF77321, 32, NDPI_PROTOCOL_TOR }, + { 0x4FF87986, 32, NDPI_PROTOCOL_TOR }, + { 0x4FFBF5CA, 32, NDPI_PROTOCOL_TOR }, + { 0x4FFF9947, 32, NDPI_PROTOCOL_TOR }, + { 0x50025741, 32, NDPI_PROTOCOL_TOR }, + { 0x5004F810, 32, NDPI_PROTOCOL_TOR }, + { 0x500593F5, 32, NDPI_PROTOCOL_TOR }, + { 0x500C5EB8, 32, NDPI_PROTOCOL_TOR }, + { 0x502A9965, 32, NDPI_PROTOCOL_TOR }, + { 0x502AA456, 32, NDPI_PROTOCOL_TOR }, + { 0x50390AA9, 32, NDPI_PROTOCOL_TOR }, + { 0x50393FB3, 32, NDPI_PROTOCOL_TOR }, + { 0x50397C3A, 32, NDPI_PROTOCOL_TOR }, + { 0x5042877B, 32, NDPI_PROTOCOL_TOR }, + { 0x5043AC13, 32, NDPI_PROTOCOL_TOR }, + { 0x504459B6, 32, NDPI_PROTOCOL_TOR }, + { 0x50445CF9, 32, NDPI_PROTOCOL_TOR }, + { 0x50478577, 32, NDPI_PROTOCOL_TOR }, + { 0x504786B5, 32, NDPI_PROTOCOL_TOR }, + { 0x5049D3D9, 32, NDPI_PROTOCOL_TOR }, + { 0x5049F28E, 32, NDPI_PROTOCOL_TOR }, + { 0x504EF251, 32, NDPI_PROTOCOL_TOR }, + { 0x504EF656, 32, NDPI_PROTOCOL_TOR }, + { 0x504F1707, 32, NDPI_PROTOCOL_TOR }, + { 0x5051111F, 32, NDPI_PROTOCOL_TOR }, + { 0x5051F378, 32, NDPI_PROTOCOL_TOR }, + { 0x5051F3E2, 32, NDPI_PROTOCOL_TOR }, + { 0x5051F3EB, 32, NDPI_PROTOCOL_TOR }, + { 0x5052D7D2, 32, NDPI_PROTOCOL_TOR }, + { 0x50555448, 32, NDPI_PROTOCOL_TOR }, + { 0x505554DE, 32, NDPI_PROTOCOL_TOR }, + { 0x505554F0, 32, NDPI_PROTOCOL_TOR }, + { 0x50565329, 32, NDPI_PROTOCOL_TOR }, + { 0x50565CB5, 32, NDPI_PROTOCOL_TOR }, + { 0x50565D80, 32, NDPI_PROTOCOL_TOR }, + { 0x5059C09E, 32, NDPI_PROTOCOL_TOR }, + { 0x505A2B81, 32, NDPI_PROTOCOL_TOR }, + { 0x505A2BDD, 32, NDPI_PROTOCOL_TOR }, + { 0x50631FF8, 32, NDPI_PROTOCOL_TOR }, + { 0x5063FE73, 32, NDPI_PROTOCOL_TOR }, + { 0x50642620, 32, NDPI_PROTOCOL_TOR }, + { 0x50642CDB, 32, NDPI_PROTOCOL_TOR }, + { 0x50642CFD, 32, NDPI_PROTOCOL_TOR }, + { 0x50642D9C, 32, NDPI_PROTOCOL_TOR }, + { 0x50648003, 32, NDPI_PROTOCOL_TOR }, + { 0x5064BD03, 32, NDPI_PROTOCOL_TOR }, + { 0x5064CC04, 32, NDPI_PROTOCOL_TOR }, + { 0x5064CE96, 32, NDPI_PROTOCOL_TOR }, + { 0x506573AA, 32, NDPI_PROTOCOL_TOR }, + { 0x506C8F13, 32, NDPI_PROTOCOL_TOR }, + { 0x506DA2EA, 32, NDPI_PROTOCOL_TOR }, + { 0x506DE134, 32, NDPI_PROTOCOL_TOR }, + { 0x506E2316, 32, NDPI_PROTOCOL_TOR }, + { 0x506E37C4, 32, NDPI_PROTOCOL_TOR }, + { 0x506FEC0F, 32, NDPI_PROTOCOL_TOR }, + { 0x50709921, 32, NDPI_PROTOCOL_TOR }, + { 0x5071010B, 32, NDPI_PROTOCOL_TOR }, + { 0x50743860, 32, NDPI_PROTOCOL_TOR }, + { 0x50764CC5, 32, NDPI_PROTOCOL_TOR }, + { 0x50807E83, 32, NDPI_PROTOCOL_TOR }, + { 0x50814072, 32, NDPI_PROTOCOL_TOR }, + { 0x50868F7F, 32, NDPI_PROTOCOL_TOR }, + { 0x5087E176, 32, NDPI_PROTOCOL_TOR }, + { 0x508874C1, 32, NDPI_PROTOCOL_TOR }, + { 0x50894240, 32, NDPI_PROTOCOL_TOR }, + { 0x508AEC03, 32, NDPI_PROTOCOL_TOR }, + { 0x508AEFF3, 32, NDPI_PROTOCOL_TOR }, + { 0x508B637B, 32, NDPI_PROTOCOL_TOR }, + { 0x508B727D, 32, NDPI_PROTOCOL_TOR }, + { 0x508C6003, 32, NDPI_PROTOCOL_TOR }, + { 0x508F6A3C, 32, NDPI_PROTOCOL_TOR }, + { 0x5093219D, 32, NDPI_PROTOCOL_TOR }, + { 0x509325F7, 32, NDPI_PROTOCOL_TOR }, + { 0x5098EF17, 32, NDPI_PROTOCOL_TOR }, + { 0x50990704, 32, NDPI_PROTOCOL_TOR }, + { 0x50A19C30, 32, NDPI_PROTOCOL_TOR }, + { 0x50A20720, 32, NDPI_PROTOCOL_TOR }, + { 0x50A32958, 32, NDPI_PROTOCOL_TOR }, + { 0x50A770EE, 32, NDPI_PROTOCOL_TOR }, + { 0x50AB1353, 32, NDPI_PROTOCOL_TOR }, + { 0x50AB285B, 32, NDPI_PROTOCOL_TOR }, + { 0x50C3B7F0, 32, NDPI_PROTOCOL_TOR }, + { 0x50CAAF5A, 32, NDPI_PROTOCOL_TOR }, + { 0x50CAEE20, 32, NDPI_PROTOCOL_TOR }, + { 0x50CB102E, 32, NDPI_PROTOCOL_TOR }, + { 0x50D4A2ED, 32, NDPI_PROTOCOL_TOR }, + { 0x50D87BFC, 32, NDPI_PROTOCOL_TOR }, + { 0x50DA9F57, 32, NDPI_PROTOCOL_TOR }, + { 0x50DAD94E, 32, NDPI_PROTOCOL_TOR }, + { 0x50DB0244, 32, NDPI_PROTOCOL_TOR }, + { 0x50DB8C29, 32, NDPI_PROTOCOL_TOR }, + { 0x50DC5274, 32, NDPI_PROTOCOL_TOR }, + { 0x50DCE66B, 32, NDPI_PROTOCOL_TOR }, + { 0x50DCF46B, 32, NDPI_PROTOCOL_TOR }, + { 0x50DFA940, 32, NDPI_PROTOCOL_TOR }, + { 0x50DFB670, 32, NDPI_PROTOCOL_TOR }, + { 0x50DFD0F6, 32, NDPI_PROTOCOL_TOR }, + { 0x50E500D2, 32, NDPI_PROTOCOL_TOR }, + { 0x50EDE24B, 32, NDPI_PROTOCOL_TOR }, + { 0x50EEE5A1, 32, NDPI_PROTOCOL_TOR }, + { 0x50F08096, 32, NDPI_PROTOCOL_TOR }, + { 0x50F080E9, 32, NDPI_PROTOCOL_TOR }, + { 0x50F086F6, 32, NDPI_PROTOCOL_TOR }, + { 0x50F08D97, 32, NDPI_PROTOCOL_TOR }, + { 0x50F1D942, 32, NDPI_PROTOCOL_TOR }, + { 0x50F1DA9A, 32, NDPI_PROTOCOL_TOR }, + { 0x50F1DCDD, 32, NDPI_PROTOCOL_TOR }, + { 0x50F1DE24, 32, NDPI_PROTOCOL_TOR }, + { 0x50F1DE62, 32, NDPI_PROTOCOL_TOR }, + { 0x50F4F39E, 32, NDPI_PROTOCOL_TOR }, + { 0x50F63BE9, 32, NDPI_PROTOCOL_TOR }, + { 0x50F8D083, 32, NDPI_PROTOCOL_TOR }, + { 0x50FEDB30, 32, NDPI_PROTOCOL_TOR }, + { 0x50FF0BD3, 32, NDPI_PROTOCOL_TOR }, + { 0x50FF0BE0, 32, NDPI_PROTOCOL_TOR }, + { 0x50FF0BED, 32, NDPI_PROTOCOL_TOR }, + { 0x5102C521, 32, NDPI_PROTOCOL_TOR }, + { 0x5102ECA5, 32, NDPI_PROTOCOL_TOR }, + { 0x5104655D, 32, NDPI_PROTOCOL_TOR }, + { 0x5104676A, 32, NDPI_PROTOCOL_TOR }, + { 0x51046810, 32, NDPI_PROTOCOL_TOR }, + { 0x51046852, 32, NDPI_PROTOCOL_TOR }, + { 0x510469C0, 32, NDPI_PROTOCOL_TOR }, + { 0x51046B24, 32, NDPI_PROTOCOL_TOR }, + { 0x51046B44, 32, NDPI_PROTOCOL_TOR }, + { 0x51046BBE, 32, NDPI_PROTOCOL_TOR }, + { 0x51046BE3, 32, NDPI_PROTOCOL_TOR }, + { 0x51046CC7, 32, NDPI_PROTOCOL_TOR }, + { 0x51046D2F, 32, NDPI_PROTOCOL_TOR }, + { 0x51046D7D, 32, NDPI_PROTOCOL_TOR }, + { 0x51046DD0, 32, NDPI_PROTOCOL_TOR }, + { 0x51046DFA, 32, NDPI_PROTOCOL_TOR }, + { 0x51046E5D, 32, NDPI_PROTOCOL_TOR }, + { 0x51046E95, 32, NDPI_PROTOCOL_TOR }, + { 0x51046F6B, 32, NDPI_PROTOCOL_TOR }, + { 0x51047930, 32, NDPI_PROTOCOL_TOR }, + { 0x510479B4, 32, NDPI_PROTOCOL_TOR }, + { 0x510479DE, 32, NDPI_PROTOCOL_TOR }, + { 0x510479E0, 32, NDPI_PROTOCOL_TOR }, + { 0x510479F3, 32, NDPI_PROTOCOL_TOR }, + { 0x51047D81, 32, NDPI_PROTOCOL_TOR }, + { 0x51047E79, 32, NDPI_PROTOCOL_TOR }, + { 0x51070777, 32, NDPI_PROTOCOL_TOR }, + { 0x51070865, 32, NDPI_PROTOCOL_TOR }, + { 0x51070A11, 32, NDPI_PROTOCOL_TOR }, + { 0x51070A1D, 32, NDPI_PROTOCOL_TOR }, + { 0x51070A1D, 32, NDPI_PROTOCOL_TOR }, + { 0x51070A44, 32, NDPI_PROTOCOL_TOR }, + { 0x51070AFB, 32, NDPI_PROTOCOL_TOR }, + { 0x51070B46, 32, NDPI_PROTOCOL_TOR }, + { 0x51070BFD, 32, NDPI_PROTOCOL_TOR }, + { 0x51070D54, 32, NDPI_PROTOCOL_TOR }, + { 0x51070D5A, 32, NDPI_PROTOCOL_TOR }, + { 0x51070DF8, 32, NDPI_PROTOCOL_TOR }, + { 0x51070EF6, 32, NDPI_PROTOCOL_TOR }, + { 0x5107103B, 32, NDPI_PROTOCOL_TOR }, + { 0x510A9F12, 32, NDPI_PROTOCOL_TOR }, + { 0x511115F6, 32, NDPI_PROTOCOL_TOR }, + { 0x5114849E, 32, NDPI_PROTOCOL_TOR }, + { 0x51148B91, 32, NDPI_PROTOCOL_TOR }, + { 0x5115F642, 32, NDPI_PROTOCOL_TOR }, + { 0x511932A6, 32, NDPI_PROTOCOL_TOR }, + { 0x511CC585, 32, NDPI_PROTOCOL_TOR }, + { 0x511E9858, 32, NDPI_PROTOCOL_TOR }, + { 0x511E9858, 32, NDPI_PROTOCOL_TOR }, + { 0x511F5A52, 32, NDPI_PROTOCOL_TOR }, + { 0x513842D5, 32, NDPI_PROTOCOL_TOR }, + { 0x5139852A, 32, NDPI_PROTOCOL_TOR }, + { 0x5139D087, 32, NDPI_PROTOCOL_TOR }, + { 0x514080DE, 32, NDPI_PROTOCOL_TOR }, + { 0x5140E6FD, 32, NDPI_PROTOCOL_TOR }, + { 0x51475D6A, 32, NDPI_PROTOCOL_TOR }, + { 0x51533A04, 32, NDPI_PROTOCOL_TOR }, + { 0x51544C43, 32, NDPI_PROTOCOL_TOR }, + { 0x51569E1B, 32, NDPI_PROTOCOL_TOR }, + { 0x515900C3, 32, NDPI_PROTOCOL_TOR }, + { 0x515900C4, 32, NDPI_PROTOCOL_TOR }, + { 0x515900C5, 32, NDPI_PROTOCOL_TOR }, + { 0x515900C6, 32, NDPI_PROTOCOL_TOR }, + { 0x515900C7, 32, NDPI_PROTOCOL_TOR }, + { 0x515900C8, 32, NDPI_PROTOCOL_TOR }, + { 0x515900C9, 32, NDPI_PROTOCOL_TOR }, + { 0x515900CA, 32, NDPI_PROTOCOL_TOR }, + { 0x515900CB, 32, NDPI_PROTOCOL_TOR }, + { 0x515900CC, 32, NDPI_PROTOCOL_TOR }, + { 0x51596058, 32, NDPI_PROTOCOL_TOR }, + { 0x51596059, 32, NDPI_PROTOCOL_TOR }, + { 0x51596535, 32, NDPI_PROTOCOL_TOR }, + { 0x515CACE7, 32, NDPI_PROTOCOL_TOR }, + { 0x515F0522, 32, NDPI_PROTOCOL_TOR }, + { 0x515F3444, 32, NDPI_PROTOCOL_TOR }, + { 0x5160DB54, 32, NDPI_PROTOCOL_TOR }, + { 0x5161B784, 32, NDPI_PROTOCOL_TOR }, + { 0x5163F715, 32, NDPI_PROTOCOL_TOR }, + { 0x51669B3F, 32, NDPI_PROTOCOL_TOR }, + { 0x5166F93D, 32, NDPI_PROTOCOL_TOR }, + { 0x516A0C3C, 32, NDPI_PROTOCOL_TOR }, + { 0x516B907F, 32, NDPI_PROTOCOL_TOR }, + { 0x516D69B6, 32, NDPI_PROTOCOL_TOR }, + { 0x51853556, 32, NDPI_PROTOCOL_TOR }, + { 0x518D6888, 32, NDPI_PROTOCOL_TOR }, + { 0x519840EA, 32, NDPI_PROTOCOL_TOR }, + { 0x519FC5DE, 32, NDPI_PROTOCOL_TOR }, + { 0x51A64037, 32, NDPI_PROTOCOL_TOR }, + { 0x51A98234, 32, NDPI_PROTOCOL_TOR }, + { 0x51A982D6, 32, NDPI_PROTOCOL_TOR }, + { 0x51A988CE, 32, NDPI_PROTOCOL_TOR }, + { 0x51A98D5C, 32, NDPI_PROTOCOL_TOR }, + { 0x51A98D5E, 32, NDPI_PROTOCOL_TOR }, + { 0x51A9957C, 32, NDPI_PROTOCOL_TOR }, + { 0x51A99864, 32, NDPI_PROTOCOL_TOR }, + { 0x51A999A7, 32, NDPI_PROTOCOL_TOR }, + { 0x51A99F52, 32, NDPI_PROTOCOL_TOR }, + { 0x51A9A86A, 32, NDPI_PROTOCOL_TOR }, + { 0x51A9AFA4, 32, NDPI_PROTOCOL_TOR }, + { 0x51A9B42B, 32, NDPI_PROTOCOL_TOR }, + { 0x51A9B92C, 32, NDPI_PROTOCOL_TOR }, + { 0x51A9D13A, 32, NDPI_PROTOCOL_TOR }, + { 0x51A9D20B, 32, NDPI_PROTOCOL_TOR }, + { 0x51A9D72F, 32, NDPI_PROTOCOL_TOR }, + { 0x51A9FFEB, 32, NDPI_PROTOCOL_TOR }, + { 0x51AA95F0, 32, NDPI_PROTOCOL_TOR }, + { 0x51AAD96B, 32, NDPI_PROTOCOL_TOR }, + { 0x51AAFFB8, 32, NDPI_PROTOCOL_TOR }, + { 0x51AC174F, 32, NDPI_PROTOCOL_TOR }, + { 0x51ADF051, 32, NDPI_PROTOCOL_TOR }, + { 0x51AEE712, 32, NDPI_PROTOCOL_TOR }, + { 0x51B0E436, 32, NDPI_PROTOCOL_TOR }, + { 0x51B73F2E, 32, NDPI_PROTOCOL_TOR }, + { 0x51B8EB2B, 32, NDPI_PROTOCOL_TOR }, + { 0x51BAF377, 32, NDPI_PROTOCOL_TOR }, + { 0x51BB1C09, 32, NDPI_PROTOCOL_TOR }, + { 0x51BBD20D, 32, NDPI_PROTOCOL_TOR }, + { 0x51BF7137, 32, NDPI_PROTOCOL_TOR }, + { 0x51C93CED, 32, NDPI_PROTOCOL_TOR }, + { 0x51CB9655, 32, NDPI_PROTOCOL_TOR }, + { 0x51CD17DA, 32, NDPI_PROTOCOL_TOR }, + { 0x51D91056, 32, NDPI_PROTOCOL_TOR }, + { 0x51D974C6, 32, NDPI_PROTOCOL_TOR }, + { 0x51D987C8, 32, NDPI_PROTOCOL_TOR }, + { 0x51D99D5A, 32, NDPI_PROTOCOL_TOR }, + { 0x51DA5B9A, 32, NDPI_PROTOCOL_TOR }, + { 0x51DA6D6A, 32, NDPI_PROTOCOL_TOR }, + { 0x51DA6DC3, 32, NDPI_PROTOCOL_TOR }, + { 0x51DAEBA2, 32, NDPI_PROTOCOL_TOR }, + { 0x51DB33CE, 32, NDPI_PROTOCOL_TOR }, + { 0x51DCA3CA, 32, NDPI_PROTOCOL_TOR }, + { 0x51DD555D, 32, NDPI_PROTOCOL_TOR }, + { 0x51DFD766, 32, NDPI_PROTOCOL_TOR }, + { 0x51E735A5, 32, NDPI_PROTOCOL_TOR }, + { 0x51E75573, 32, NDPI_PROTOCOL_TOR }, + { 0x51E7A4A1, 32, NDPI_PROTOCOL_TOR }, + { 0x51E7E226, 32, NDPI_PROTOCOL_TOR }, + { 0x51E9E3A1, 32, NDPI_PROTOCOL_TOR }, + { 0x51F285B4, 32, NDPI_PROTOCOL_TOR }, + { 0x51F6CAA9, 32, NDPI_PROTOCOL_TOR }, + { 0x51F777FC, 32, NDPI_PROTOCOL_TOR }, + { 0x52018046, 32, NDPI_PROTOCOL_TOR }, + { 0x5206BA74, 32, NDPI_PROTOCOL_TOR }, + { 0x5209EEF6, 32, NDPI_PROTOCOL_TOR }, + { 0x520CAF74, 32, NDPI_PROTOCOL_TOR }, + { 0x520DF0B2, 32, NDPI_PROTOCOL_TOR }, + { 0x5213FC52, 32, NDPI_PROTOCOL_TOR }, + { 0x52145714, 32, NDPI_PROTOCOL_TOR }, + { 0x52173C4E, 32, NDPI_PROTOCOL_TOR }, + { 0x5219BB97, 32, NDPI_PROTOCOL_TOR }, + { 0x521CC556, 32, NDPI_PROTOCOL_TOR }, + { 0x521E7362, 32, NDPI_PROTOCOL_TOR }, + { 0x521F29D7, 32, NDPI_PROTOCOL_TOR }, + { 0x52239D60, 32, NDPI_PROTOCOL_TOR }, + { 0x522BA860, 32, NDPI_PROTOCOL_TOR }, + { 0x522DB96B, 32, NDPI_PROTOCOL_TOR }, + { 0x522FE271, 32, NDPI_PROTOCOL_TOR }, + { 0x52303D0C, 32, NDPI_PROTOCOL_TOR }, + { 0x52343FD9, 32, NDPI_PROTOCOL_TOR }, + { 0x52424777, 32, NDPI_PROTOCOL_TOR }, + { 0x52449E7C, 32, NDPI_PROTOCOL_TOR }, + { 0x52450ECF, 32, NDPI_PROTOCOL_TOR }, + { 0x52453232, 32, NDPI_PROTOCOL_TOR }, + { 0x52462723, 32, NDPI_PROTOCOL_TOR }, + { 0x524805A4, 32, NDPI_PROTOCOL_TOR }, + { 0x52483D51, 32, NDPI_PROTOCOL_TOR }, + { 0x5248765A, 32, NDPI_PROTOCOL_TOR }, + { 0x52493309, 32, NDPI_PROTOCOL_TOR }, + { 0x5249DF9D, 32, NDPI_PROTOCOL_TOR }, + { 0x524A04F3, 32, NDPI_PROTOCOL_TOR }, + { 0x524C4802, 32, NDPI_PROTOCOL_TOR }, + { 0x52502163, 32, NDPI_PROTOCOL_TOR }, + { 0x525088B9, 32, NDPI_PROTOCOL_TOR }, + { 0x52532E63, 32, NDPI_PROTOCOL_TOR }, + { 0x525EF2DA, 32, NDPI_PROTOCOL_TOR }, + { 0x525EFBCB, 32, NDPI_PROTOCOL_TOR }, + { 0x525EFBCC, 32, NDPI_PROTOCOL_TOR }, + { 0x525EFBE3, 32, NDPI_PROTOCOL_TOR }, + { 0x525F42CB, 32, NDPI_PROTOCOL_TOR }, + { 0x525F6B33, 32, NDPI_PROTOCOL_TOR }, + { 0x525FEBF9, 32, NDPI_PROTOCOL_TOR }, + { 0x52624850, 32, NDPI_PROTOCOL_TOR }, + { 0x52668ED2, 32, NDPI_PROTOCOL_TOR }, + { 0x5270985F, 32, NDPI_PROTOCOL_TOR }, + { 0x52736339, 32, NDPI_PROTOCOL_TOR }, + { 0x52747803, 32, NDPI_PROTOCOL_TOR }, + { 0x52761386, 32, NDPI_PROTOCOL_TOR }, + { 0x5276F21E, 32, NDPI_PROTOCOL_TOR }, + { 0x5276F24F, 32, NDPI_PROTOCOL_TOR }, + { 0x527E663F, 32, NDPI_PROTOCOL_TOR }, + { 0x5280FFFC, 32, NDPI_PROTOCOL_TOR }, + { 0x52821A24, 32, NDPI_PROTOCOL_TOR }, + { 0x5282285C, 32, NDPI_PROTOCOL_TOR }, + { 0x52886403, 32, NDPI_PROTOCOL_TOR }, + { 0x528B5EFC, 32, NDPI_PROTOCOL_TOR }, + { 0x528B6271, 32, NDPI_PROTOCOL_TOR }, + { 0x52921BD1, 32, NDPI_PROTOCOL_TOR }, + { 0x529EEB26, 32, NDPI_PROTOCOL_TOR }, + { 0x52A1321E, 32, NDPI_PROTOCOL_TOR }, + { 0x52A13526, 32, NDPI_PROTOCOL_TOR }, + { 0x52A15B0D, 32, NDPI_PROTOCOL_TOR }, + { 0x52A16D47, 32, NDPI_PROTOCOL_TOR }, + { 0x52A1B614, 32, NDPI_PROTOCOL_TOR }, + { 0x52A1D257, 32, NDPI_PROTOCOL_TOR }, + { 0x52A1D4D1, 32, NDPI_PROTOCOL_TOR }, + { 0x52A1DF89, 32, NDPI_PROTOCOL_TOR }, + { 0x52A1EFB1, 32, NDPI_PROTOCOL_TOR }, + { 0x52A1FCA2, 32, NDPI_PROTOCOL_TOR }, + { 0x52A41BE4, 32, NDPI_PROTOCOL_TOR }, + { 0x52A50F97, 32, NDPI_PROTOCOL_TOR }, + { 0x52A58E4F, 32, NDPI_PROTOCOL_TOR }, + { 0x52A5C581, 32, NDPI_PROTOCOL_TOR }, + { 0x52A898B2, 32, NDPI_PROTOCOL_TOR }, + { 0x52A92496, 32, NDPI_PROTOCOL_TOR }, + { 0x52A99B48, 32, NDPI_PROTOCOL_TOR }, + { 0x52B1EEF0, 32, NDPI_PROTOCOL_TOR }, + { 0x52B419BA, 32, NDPI_PROTOCOL_TOR }, + { 0x52B583A0, 32, NDPI_PROTOCOL_TOR }, + { 0x52B6B40F, 32, NDPI_PROTOCOL_TOR }, + { 0x52B70EC3, 32, NDPI_PROTOCOL_TOR }, + { 0x52C0F11E, 32, NDPI_PROTOCOL_TOR }, + { 0x52C409DF, 32, NDPI_PROTOCOL_TOR }, + { 0x52C40E41, 32, NDPI_PROTOCOL_TOR }, + { 0x52C5D42F, 32, NDPI_PROTOCOL_TOR }, + { 0x52C79B59, 32, NDPI_PROTOCOL_TOR }, + { 0x52C7C0A7, 32, NDPI_PROTOCOL_TOR }, + { 0x52CBC340, 32, NDPI_PROTOCOL_TOR }, + { 0x52D300C9, 32, NDPI_PROTOCOL_TOR }, + { 0x52D3138F, 32, NDPI_PROTOCOL_TOR }, + { 0x52D3C9BC, 32, NDPI_PROTOCOL_TOR }, + { 0x52D3DF03, 32, NDPI_PROTOCOL_TOR }, + { 0x52D8FE03, 32, NDPI_PROTOCOL_TOR }, + { 0x52D91190, 32, NDPI_PROTOCOL_TOR }, + { 0x52DB0959, 32, NDPI_PROTOCOL_TOR }, + { 0x52DC5914, 32, NDPI_PROTOCOL_TOR }, + { 0x52DD64C9, 32, NDPI_PROTOCOL_TOR }, + { 0x52DD6500, 32, NDPI_PROTOCOL_TOR }, + { 0x52DD693D, 32, NDPI_PROTOCOL_TOR }, + { 0x52DF08FC, 32, NDPI_PROTOCOL_TOR }, + { 0x52DF0A44, 32, NDPI_PROTOCOL_TOR }, + { 0x52DF0B22, 32, NDPI_PROTOCOL_TOR }, + { 0x52DF179B, 32, NDPI_PROTOCOL_TOR }, + { 0x52E08A09, 32, NDPI_PROTOCOL_TOR }, + { 0x52E33F62, 32, NDPI_PROTOCOL_TOR }, + { 0x52E4FC14, 32, NDPI_PROTOCOL_TOR }, + { 0x52E53CF5, 32, NDPI_PROTOCOL_TOR }, + { 0x52E58A1F, 32, NDPI_PROTOCOL_TOR }, + { 0x52E97597, 32, NDPI_PROTOCOL_TOR }, + { 0x52EA8DC5, 32, NDPI_PROTOCOL_TOR }, + { 0x52EBD32A, 32, NDPI_PROTOCOL_TOR }, + { 0x52EC7EF6, 32, NDPI_PROTOCOL_TOR }, + { 0x52EC89EB, 32, NDPI_PROTOCOL_TOR }, + { 0x52EDD8E9, 32, NDPI_PROTOCOL_TOR }, + { 0x52EED0AD, 32, NDPI_PROTOCOL_TOR }, + { 0x52EF14AE, 32, NDPI_PROTOCOL_TOR }, + { 0x52F1EC57, 32, NDPI_PROTOCOL_TOR }, + { 0x52F298D3, 32, NDPI_PROTOCOL_TOR }, + { 0x52F313CC, 32, NDPI_PROTOCOL_TOR }, + { 0x52F34F09, 32, NDPI_PROTOCOL_TOR }, + { 0x52F4B127, 32, NDPI_PROTOCOL_TOR }, + { 0x52F5C791, 32, NDPI_PROTOCOL_TOR }, + { 0x52F76775, 32, NDPI_PROTOCOL_TOR }, + { 0x52FA311C, 32, NDPI_PROTOCOL_TOR }, + { 0x5306C520, 32, NDPI_PROTOCOL_TOR }, + { 0x5306EE3D, 32, NDPI_PROTOCOL_TOR }, + { 0x531BFBEF, 32, NDPI_PROTOCOL_TOR }, + { 0x53244725, 32, NDPI_PROTOCOL_TOR }, + { 0x532CE6B0, 32, NDPI_PROTOCOL_TOR }, + { 0x5335F24A, 32, NDPI_PROTOCOL_TOR }, + { 0x5338EA93, 32, NDPI_PROTOCOL_TOR }, + { 0x53451C51, 32, NDPI_PROTOCOL_TOR }, + { 0x534C9E3E, 32, NDPI_PROTOCOL_TOR }, + { 0x534E1005, 32, NDPI_PROTOCOL_TOR }, + { 0x535269F0, 32, NDPI_PROTOCOL_TOR }, + { 0x5352C0E6, 32, NDPI_PROTOCOL_TOR }, + { 0x5352F4DB, 32, NDPI_PROTOCOL_TOR }, + { 0x53530B96, 32, NDPI_PROTOCOL_TOR }, + { 0x535352B4, 32, NDPI_PROTOCOL_TOR }, + { 0x53542E39, 32, NDPI_PROTOCOL_TOR }, + { 0x53556653, 32, NDPI_PROTOCOL_TOR }, + { 0x5355D16B, 32, NDPI_PROTOCOL_TOR }, + { 0x5355FC5B, 32, NDPI_PROTOCOL_TOR }, + { 0x5357C9F9, 32, NDPI_PROTOCOL_TOR }, + { 0x53591FF9, 32, NDPI_PROTOCOL_TOR }, + { 0x535D3740, 32, NDPI_PROTOCOL_TOR }, + { 0x53638E4F, 32, NDPI_PROTOCOL_TOR }, + { 0x53650553, 32, NDPI_PROTOCOL_TOR }, + { 0x5365431F, 32, NDPI_PROTOCOL_TOR }, + { 0x537560B2, 32, NDPI_PROTOCOL_TOR }, + { 0x53809409, 32, NDPI_PROTOCOL_TOR }, + { 0x5380C8F4, 32, NDPI_PROTOCOL_TOR }, + { 0x5382722D, 32, NDPI_PROTOCOL_TOR }, + { 0x53857F91, 32, NDPI_PROTOCOL_TOR }, + { 0x5386DFC1, 32, NDPI_PROTOCOL_TOR }, + { 0x5387F0D5, 32, NDPI_PROTOCOL_TOR }, + { 0x538C0BFC, 32, NDPI_PROTOCOL_TOR }, + { 0x538FDBD4, 32, NDPI_PROTOCOL_TOR }, + { 0x5390693A, 32, NDPI_PROTOCOL_TOR }, + { 0x5391EDE0, 32, NDPI_PROTOCOL_TOR }, + { 0x5391F1E7, 32, NDPI_PROTOCOL_TOR }, + { 0x5391F3D7, 32, NDPI_PROTOCOL_TOR }, + { 0x539354E4, 32, NDPI_PROTOCOL_TOR }, + { 0x53957C88, 32, NDPI_PROTOCOL_TOR }, + { 0x53957C88, 32, NDPI_PROTOCOL_TOR }, + { 0x53957C89, 32, NDPI_PROTOCOL_TOR }, + { 0x53957C89, 32, NDPI_PROTOCOL_TOR }, + { 0x53957E1D, 32, NDPI_PROTOCOL_TOR }, + { 0x53957F8C, 32, NDPI_PROTOCOL_TOR }, + { 0x5395F9A5, 32, NDPI_PROTOCOL_TOR }, + { 0x5396023D, 32, NDPI_PROTOCOL_TOR }, + { 0x53961097, 32, NDPI_PROTOCOL_TOR }, + { 0x539610F4, 32, NDPI_PROTOCOL_TOR }, + { 0x53961184, 32, NDPI_PROTOCOL_TOR }, + { 0x5396527A, 32, NDPI_PROTOCOL_TOR }, + { 0x539C0058, 32, NDPI_PROTOCOL_TOR }, + { 0x53A05F63, 32, NDPI_PROTOCOL_TOR }, + { 0x53A19832, 32, NDPI_PROTOCOL_TOR }, + { 0x53A2026F, 32, NDPI_PROTOCOL_TOR }, + { 0x53A2BC64, 32, NDPI_PROTOCOL_TOR }, + { 0x53A2C060, 32, NDPI_PROTOCOL_TOR }, + { 0x53A2CD44, 32, NDPI_PROTOCOL_TOR }, + { 0x53A34DC3, 32, NDPI_PROTOCOL_TOR }, + { 0x53A3C9A8, 32, NDPI_PROTOCOL_TOR }, + { 0x53A59347, 32, NDPI_PROTOCOL_TOR }, + { 0x53A6EA5C, 32, NDPI_PROTOCOL_TOR }, + { 0x53A6EA6C, 32, NDPI_PROTOCOL_TOR }, + { 0x53A7B923, 32, NDPI_PROTOCOL_TOR }, + { 0x53A7B964, 32, NDPI_PROTOCOL_TOR }, + { 0x53A7E46B, 32, NDPI_PROTOCOL_TOR }, + { 0x53A8C8CC, 32, NDPI_PROTOCOL_TOR }, + { 0x53A91607, 32, NDPI_PROTOCOL_TOR }, + { 0x53A92DE7, 32, NDPI_PROTOCOL_TOR }, + { 0x53AB9437, 32, NDPI_PROTOCOL_TOR }, + { 0x53ABBE6A, 32, NDPI_PROTOCOL_TOR }, + { 0x53AEFA7D, 32, NDPI_PROTOCOL_TOR }, + { 0x53D19271, 32, NDPI_PROTOCOL_TOR }, + { 0x53D454DF, 32, NDPI_PROTOCOL_TOR }, + { 0x53D460B7, 32, NDPI_PROTOCOL_TOR }, + { 0x53D46270, 32, NDPI_PROTOCOL_TOR }, + { 0x53D46344, 32, NDPI_PROTOCOL_TOR }, + { 0x53D4637B, 32, NDPI_PROTOCOL_TOR }, + { 0x53D46612, 32, NDPI_PROTOCOL_TOR }, + { 0x53D4687C, 32, NDPI_PROTOCOL_TOR }, + { 0x53D46891, 32, NDPI_PROTOCOL_TOR }, + { 0x53D47185, 32, NDPI_PROTOCOL_TOR }, + { 0x53D47ED3, 32, NDPI_PROTOCOL_TOR }, + { 0x53D4A8BA, 32, NDPI_PROTOCOL_TOR }, + { 0x53D8F8E0, 32, NDPI_PROTOCOL_TOR }, + { 0x53DE8DEB, 32, NDPI_PROTOCOL_TOR }, + { 0x53E2EEA8, 32, NDPI_PROTOCOL_TOR }, + { 0x53E334A8, 32, NDPI_PROTOCOL_TOR }, + { 0x53E45D4C, 32, NDPI_PROTOCOL_TOR }, + { 0x53E71225, 32, NDPI_PROTOCOL_TOR }, + { 0x53E941D6, 32, NDPI_PROTOCOL_TOR }, + { 0x53E98714, 32, NDPI_PROTOCOL_TOR }, + { 0x53E9A8E7, 32, NDPI_PROTOCOL_TOR }, + { 0x53ECD04E, 32, NDPI_PROTOCOL_TOR }, + { 0x53ED1577, 32, NDPI_PROTOCOL_TOR }, + { 0x53F03D90, 32, NDPI_PROTOCOL_TOR }, + { 0x53F042A6, 32, NDPI_PROTOCOL_TOR }, + { 0x53F077B0, 32, NDPI_PROTOCOL_TOR }, + { 0x53F65317, 32, NDPI_PROTOCOL_TOR }, + { 0x53F6A4BB, 32, NDPI_PROTOCOL_TOR }, + { 0x53F6D985, 32, NDPI_PROTOCOL_TOR }, + { 0x53F74E5A, 32, NDPI_PROTOCOL_TOR }, + { 0x53F80E85, 32, NDPI_PROTOCOL_TOR }, + { 0x53F88441, 32, NDPI_PROTOCOL_TOR }, + { 0x53F8A214, 32, NDPI_PROTOCOL_TOR }, + { 0x53F8B2D6, 32, NDPI_PROTOCOL_TOR }, + { 0x53F946BE, 32, NDPI_PROTOCOL_TOR }, + { 0x53FA5511, 32, NDPI_PROTOCOL_TOR }, + { 0x53FB40E6, 32, NDPI_PROTOCOL_TOR }, + { 0x53FB515D, 32, NDPI_PROTOCOL_TOR }, + { 0x53FB5AA6, 32, NDPI_PROTOCOL_TOR }, + { 0x53FB864C, 32, NDPI_PROTOCOL_TOR }, + { 0x53FD36CE, 32, NDPI_PROTOCOL_TOR }, + { 0x53FDBBDA, 32, NDPI_PROTOCOL_TOR }, + { 0x53FE5430, 32, NDPI_PROTOCOL_TOR }, + { 0x53FF6645, 32, NDPI_PROTOCOL_TOR }, + { 0x53FFCBAC, 32, NDPI_PROTOCOL_TOR }, + { 0x540A6F0A, 32, NDPI_PROTOCOL_TOR }, + { 0x5413B234, 32, NDPI_PROTOCOL_TOR }, + { 0x5413B3E5, 32, NDPI_PROTOCOL_TOR }, + { 0x5413B450, 32, NDPI_PROTOCOL_TOR }, + { 0x54162AF6, 32, NDPI_PROTOCOL_TOR }, + { 0x54191CBA, 32, NDPI_PROTOCOL_TOR }, + { 0x541B5EF7, 32, NDPI_PROTOCOL_TOR }, + { 0x541EBB28, 32, NDPI_PROTOCOL_TOR }, + { 0x541FC855, 32, NDPI_PROTOCOL_TOR }, + { 0x54284D55, 32, NDPI_PROTOCOL_TOR }, + { 0x542862BB, 32, NDPI_PROTOCOL_TOR }, + { 0x54287046, 32, NDPI_PROTOCOL_TOR }, + { 0x542AA5A2, 32, NDPI_PROTOCOL_TOR }, + { 0x542D4C0A, 32, NDPI_PROTOCOL_TOR }, + { 0x542D4C0B, 32, NDPI_PROTOCOL_TOR }, + { 0x542D4C0C, 32, NDPI_PROTOCOL_TOR }, + { 0x542D4C0D, 32, NDPI_PROTOCOL_TOR }, + { 0x542E3EBA, 32, NDPI_PROTOCOL_TOR }, + { 0x54303AC3, 32, NDPI_PROTOCOL_TOR }, + { 0x54321453, 32, NDPI_PROTOCOL_TOR }, + { 0x54380652, 32, NDPI_PROTOCOL_TOR }, + { 0x54382C54, 32, NDPI_PROTOCOL_TOR }, + { 0x5439BD00, 32, NDPI_PROTOCOL_TOR }, + { 0x543BE658, 32, NDPI_PROTOCOL_TOR }, + { 0x543C046D, 32, NDPI_PROTOCOL_TOR }, + { 0x544815A3, 32, NDPI_PROTOCOL_TOR }, + { 0x5448B905, 32, NDPI_PROTOCOL_TOR }, + { 0x5448D5DD, 32, NDPI_PROTOCOL_TOR }, + { 0x5448DFC7, 32, NDPI_PROTOCOL_TOR }, + { 0x544980C3, 32, NDPI_PROTOCOL_TOR }, + { 0x544A0BDE, 32, NDPI_PROTOCOL_TOR }, + { 0x544A7D55, 32, NDPI_PROTOCOL_TOR }, + { 0x544AACE8, 32, NDPI_PROTOCOL_TOR }, + { 0x544B0C49, 32, NDPI_PROTOCOL_TOR }, + { 0x5454D02F, 32, NDPI_PROTOCOL_TOR }, + { 0x545C18D5, 32, NDPI_PROTOCOL_TOR }, + { 0x545C18D6, 32, NDPI_PROTOCOL_TOR }, + { 0x545C6C78, 32, NDPI_PROTOCOL_TOR }, + { 0x54674A57, 32, NDPI_PROTOCOL_TOR }, + { 0x5468A93B, 32, NDPI_PROTOCOL_TOR }, + { 0x5469DCFF, 32, NDPI_PROTOCOL_TOR }, + { 0x546A4A9E, 32, NDPI_PROTOCOL_TOR }, + { 0x546CCDB5, 32, NDPI_PROTOCOL_TOR }, + { 0x5470EE3A, 32, NDPI_PROTOCOL_TOR }, + { 0x5470EE3A, 32, NDPI_PROTOCOL_TOR }, + { 0x54711102, 32, NDPI_PROTOCOL_TOR }, + { 0x5471F5B1, 32, NDPI_PROTOCOL_TOR }, + { 0x5472F1DF, 32, NDPI_PROTOCOL_TOR }, + { 0x54732E95, 32, NDPI_PROTOCOL_TOR }, + { 0x5475164A, 32, NDPI_PROTOCOL_TOR }, + { 0x54767531, 32, NDPI_PROTOCOL_TOR }, + { 0x547688FC, 32, NDPI_PROTOCOL_TOR }, + { 0x54779B30, 32, NDPI_PROTOCOL_TOR }, + { 0x5477EDED, 32, NDPI_PROTOCOL_TOR }, + { 0x547BB3B6, 32, NDPI_PROTOCOL_TOR }, + { 0x547D73EA, 32, NDPI_PROTOCOL_TOR }, + { 0x5481A36E, 32, NDPI_PROTOCOL_TOR }, + { 0x5481DC92, 32, NDPI_PROTOCOL_TOR }, + { 0x548524F3, 32, NDPI_PROTOCOL_TOR }, + { 0x548A010A, 32, NDPI_PROTOCOL_TOR }, + { 0x5493E1C8, 32, NDPI_PROTOCOL_TOR }, + { 0x54947094, 32, NDPI_PROTOCOL_TOR }, + { 0x5499DCA5, 32, NDPI_PROTOCOL_TOR }, + { 0x549CFEEC, 32, NDPI_PROTOCOL_TOR }, + { 0x549FE146, 32, NDPI_PROTOCOL_TOR }, + { 0x549FEA53, 32, NDPI_PROTOCOL_TOR }, + { 0x549FEA53, 32, NDPI_PROTOCOL_TOR }, + { 0x54A202DA, 32, NDPI_PROTOCOL_TOR }, + { 0x54AD608B, 32, NDPI_PROTOCOL_TOR }, + { 0x54AEB5BD, 32, NDPI_PROTOCOL_TOR }, + { 0x54AFCF54, 32, NDPI_PROTOCOL_TOR }, + { 0x54AFF159, 32, NDPI_PROTOCOL_TOR }, + { 0x54B35824, 32, NDPI_PROTOCOL_TOR }, + { 0x54B46D3C, 32, NDPI_PROTOCOL_TOR }, + { 0x54B67B82, 32, NDPI_PROTOCOL_TOR }, + { 0x54B75D03, 32, NDPI_PROTOCOL_TOR }, + { 0x54B77113, 32, NDPI_PROTOCOL_TOR }, + { 0x54B771CE, 32, NDPI_PROTOCOL_TOR }, + { 0x54B7F756, 32, NDPI_PROTOCOL_TOR }, + { 0x54BA9896, 32, NDPI_PROTOCOL_TOR }, + { 0x54BAD4B7, 32, NDPI_PROTOCOL_TOR }, + { 0x54C14BF3, 32, NDPI_PROTOCOL_TOR }, + { 0x54C80821, 32, NDPI_PROTOCOL_TOR }, + { 0x54C808AF, 32, NDPI_PROTOCOL_TOR }, + { 0x54C808CF, 32, NDPI_PROTOCOL_TOR }, + { 0x54C80AD1, 32, NDPI_PROTOCOL_TOR }, + { 0x54C849EE, 32, NDPI_PROTOCOL_TOR }, + { 0x54C84DF3, 32, NDPI_PROTOCOL_TOR }, + { 0x54C852A3, 32, NDPI_PROTOCOL_TOR }, + { 0x54C853D6, 32, NDPI_PROTOCOL_TOR }, + { 0x54C90487, 32, NDPI_PROTOCOL_TOR }, + { 0x54C923CE, 32, NDPI_PROTOCOL_TOR }, + { 0x54CA3612, 32, NDPI_PROTOCOL_TOR }, + { 0x54D08C30, 32, NDPI_PROTOCOL_TOR }, + { 0x54D10F3F, 32, NDPI_PROTOCOL_TOR }, + { 0x54D14924, 32, NDPI_PROTOCOL_TOR }, + { 0x54D358E2, 32, NDPI_PROTOCOL_TOR }, + { 0x54D7D347, 32, NDPI_PROTOCOL_TOR }, + { 0x54DBAAE7, 32, NDPI_PROTOCOL_TOR }, + { 0x54DBC1BA, 32, NDPI_PROTOCOL_TOR }, + { 0x54E26D6D, 32, NDPI_PROTOCOL_TOR }, + { 0x54EA9B51, 32, NDPI_PROTOCOL_TOR }, + { 0x54EA9B51, 32, NDPI_PROTOCOL_TOR }, + { 0x54EA9B52, 32, NDPI_PROTOCOL_TOR }, + { 0x54EA9B52, 32, NDPI_PROTOCOL_TOR }, + { 0x54F270BE, 32, NDPI_PROTOCOL_TOR }, + { 0x54F41F34, 32, NDPI_PROTOCOL_TOR }, + { 0x54F520C3, 32, NDPI_PROTOCOL_TOR }, + { 0x54F52108, 32, NDPI_PROTOCOL_TOR }, + { 0x54F8529C, 32, NDPI_PROTOCOL_TOR }, + { 0x54F86B2C, 32, NDPI_PROTOCOL_TOR }, + { 0x54F8805F, 32, NDPI_PROTOCOL_TOR }, + { 0x54F9C0D5, 32, NDPI_PROTOCOL_TOR }, + { 0x54FA6A0D, 32, NDPI_PROTOCOL_TOR }, + { 0x54FB736F, 32, NDPI_PROTOCOL_TOR }, + { 0x54FB7CF4, 32, NDPI_PROTOCOL_TOR }, + { 0x550180C4, 32, NDPI_PROTOCOL_TOR }, + { 0x5502F728, 32, NDPI_PROTOCOL_TOR }, + { 0x55037656, 32, NDPI_PROTOCOL_TOR }, + { 0x5504E453, 32, NDPI_PROTOCOL_TOR }, + { 0x55082B53, 32, NDPI_PROTOCOL_TOR }, + { 0x550AC409, 32, NDPI_PROTOCOL_TOR }, + { 0x550AC40C, 32, NDPI_PROTOCOL_TOR }, + { 0x550AC6EC, 32, NDPI_PROTOCOL_TOR }, + { 0x550AC8E6, 32, NDPI_PROTOCOL_TOR }, + { 0x550AC92F, 32, NDPI_PROTOCOL_TOR }, + { 0x550ACA57, 32, NDPI_PROTOCOL_TOR }, + { 0x550ACB47, 32, NDPI_PROTOCOL_TOR }, + { 0x550ACBC5, 32, NDPI_PROTOCOL_TOR }, + { 0x550AD2C7, 32, NDPI_PROTOCOL_TOR }, + { 0x550AD335, 32, NDPI_PROTOCOL_TOR }, + { 0x550ADBA7, 32, NDPI_PROTOCOL_TOR }, + { 0x550AED68, 32, NDPI_PROTOCOL_TOR }, + { 0x550AF0FA, 32, NDPI_PROTOCOL_TOR }, + { 0x550EF020, 32, NDPI_PROTOCOL_TOR }, + { 0x550EF021, 32, NDPI_PROTOCOL_TOR }, + { 0x550EF022, 32, NDPI_PROTOCOL_TOR }, + { 0x550EF023, 32, NDPI_PROTOCOL_TOR }, + { 0x550EF0BC, 32, NDPI_PROTOCOL_TOR }, + { 0x550EF0BC, 32, NDPI_PROTOCOL_TOR }, + { 0x5511185F, 32, NDPI_PROTOCOL_TOR }, + { 0x551184F5, 32, NDPI_PROTOCOL_TOR }, + { 0x551184F6, 32, NDPI_PROTOCOL_TOR }, + { 0x55118DAE, 32, NDPI_PROTOCOL_TOR }, + { 0x551194E6, 32, NDPI_PROTOCOL_TOR }, + { 0x5511A451, 32, NDPI_PROTOCOL_TOR }, + { 0x5511B149, 32, NDPI_PROTOCOL_TOR }, + { 0x5511BE4D, 32, NDPI_PROTOCOL_TOR }, + { 0x5511BE4D, 32, NDPI_PROTOCOL_TOR }, + { 0x5511BE4F, 32, NDPI_PROTOCOL_TOR }, + { 0x5511BE4F, 32, NDPI_PROTOCOL_TOR }, + { 0x5511BE52, 32, NDPI_PROTOCOL_TOR }, + { 0x5511BE53, 32, NDPI_PROTOCOL_TOR }, + { 0x5511F893, 32, NDPI_PROTOCOL_TOR }, + { 0x551590E2, 32, NDPI_PROTOCOL_TOR }, + { 0x5516679A, 32, NDPI_PROTOCOL_TOR }, + { 0x5517911A, 32, NDPI_PROTOCOL_TOR }, + { 0x5517F393, 32, NDPI_PROTOCOL_TOR }, + { 0x5518D772, 32, NDPI_PROTOCOL_TOR }, + { 0x5518D773, 32, NDPI_PROTOCOL_TOR }, + { 0x5518D774, 32, NDPI_PROTOCOL_TOR }, + { 0x5518D775, 32, NDPI_PROTOCOL_TOR }, + { 0x5519090B, 32, NDPI_PROTOCOL_TOR }, + { 0x55192D93, 32, NDPI_PROTOCOL_TOR }, + { 0x55192F35, 32, NDPI_PROTOCOL_TOR }, + { 0x55192FB4, 32, NDPI_PROTOCOL_TOR }, + { 0x5519305B, 32, NDPI_PROTOCOL_TOR }, + { 0x55195F5B, 32, NDPI_PROTOCOL_TOR }, + { 0x55195F95, 32, NDPI_PROTOCOL_TOR }, + { 0x55196777, 32, NDPI_PROTOCOL_TOR }, + { 0x5519829A, 32, NDPI_PROTOCOL_TOR }, + { 0x55198A5D, 32, NDPI_PROTOCOL_TOR }, + { 0x551995BF, 32, NDPI_PROTOCOL_TOR }, + { 0x55199678, 32, NDPI_PROTOCOL_TOR }, + { 0x5519994F, 32, NDPI_PROTOCOL_TOR }, + { 0x5519C155, 32, NDPI_PROTOCOL_TOR }, + { 0x5519C444, 32, NDPI_PROTOCOL_TOR }, + { 0x5519CB2A, 32, NDPI_PROTOCOL_TOR }, + { 0x5519D0C9, 32, NDPI_PROTOCOL_TOR }, + { 0x5519D256, 32, NDPI_PROTOCOL_TOR }, + { 0x551EA9E1, 32, NDPI_PROTOCOL_TOR }, + { 0x551EF8C1, 32, NDPI_PROTOCOL_TOR }, + { 0x551FBA5D, 32, NDPI_PROTOCOL_TOR }, + { 0x551FBAD3, 32, NDPI_PROTOCOL_TOR }, + { 0x551FBAFD, 32, NDPI_PROTOCOL_TOR }, + { 0x55455D2E, 32, NDPI_PROTOCOL_TOR }, + { 0x55496286, 32, NDPI_PROTOCOL_TOR }, + { 0x55510502, 32, NDPI_PROTOCOL_TOR }, + { 0x55513A3B, 32, NDPI_PROTOCOL_TOR }, + { 0x55580BF3, 32, NDPI_PROTOCOL_TOR }, + { 0x55581C88, 32, NDPI_PROTOCOL_TOR }, + { 0x555D1259, 32, NDPI_PROTOCOL_TOR }, + { 0x555DCBB6, 32, NDPI_PROTOCOL_TOR }, + { 0x555DDACC, 32, NDPI_PROTOCOL_TOR }, + { 0x55719152, 32, NDPI_PROTOCOL_TOR }, + { 0x55728560, 32, NDPI_PROTOCOL_TOR }, + { 0x55775204, 32, NDPI_PROTOCOL_TOR }, + { 0x5577532C, 32, NDPI_PROTOCOL_TOR }, + { 0x5577538D, 32, NDPI_PROTOCOL_TOR }, + { 0x557FC146, 32, NDPI_PROTOCOL_TOR }, + { 0x558DC913, 32, NDPI_PROTOCOL_TOR }, + { 0x558F5F32, 32, NDPI_PROTOCOL_TOR }, + { 0x5596D244, 32, NDPI_PROTOCOL_TOR }, + { 0x559F71E4, 32, NDPI_PROTOCOL_TOR }, + { 0x559FD180, 32, NDPI_PROTOCOL_TOR }, + { 0x559FD19A, 32, NDPI_PROTOCOL_TOR }, + { 0x559FD2EF, 32, NDPI_PROTOCOL_TOR }, + { 0x559FD337, 32, NDPI_PROTOCOL_TOR }, + { 0x55A452E7, 32, NDPI_PROTOCOL_TOR }, + { 0x55A8FF49, 32, NDPI_PROTOCOL_TOR }, + { 0x55A8FFCA, 32, NDPI_PROTOCOL_TOR }, + { 0x55AB1623, 32, NDPI_PROTOCOL_TOR }, + { 0x55B0BCF4, 32, NDPI_PROTOCOL_TOR }, + { 0x55B0E108, 32, NDPI_PROTOCOL_TOR }, + { 0x55B1669A, 32, NDPI_PROTOCOL_TOR }, + { 0x55B2425E, 32, NDPI_PROTOCOL_TOR }, + { 0x55B2CDC4, 32, NDPI_PROTOCOL_TOR }, + { 0x55B2F435, 32, NDPI_PROTOCOL_TOR }, + { 0x55B35A3B, 32, NDPI_PROTOCOL_TOR }, + { 0x55B42652, 32, NDPI_PROTOCOL_TOR }, + { 0x55B4F715, 32, NDPI_PROTOCOL_TOR }, + { 0x55C35D4D, 32, NDPI_PROTOCOL_TOR }, + { 0x55C51E77, 32, NDPI_PROTOCOL_TOR }, + { 0x55C6B4EF, 32, NDPI_PROTOCOL_TOR }, + { 0x55CAE1D1, 32, NDPI_PROTOCOL_TOR }, + { 0x55CC0B35, 32, NDPI_PROTOCOL_TOR }, + { 0x55D2AB44, 32, NDPI_PROTOCOL_TOR }, + { 0x55D408E8, 32, NDPI_PROTOCOL_TOR }, + { 0x55D414C0, 32, NDPI_PROTOCOL_TOR }, + { 0x55D42B5E, 32, NDPI_PROTOCOL_TOR }, + { 0x55D45466, 32, NDPI_PROTOCOL_TOR }, + { 0x55D610D4, 32, NDPI_PROTOCOL_TOR }, + { 0x55D617BC, 32, NDPI_PROTOCOL_TOR }, + { 0x55D61DD5, 32, NDPI_PROTOCOL_TOR }, + { 0x55D62891, 32, NDPI_PROTOCOL_TOR }, + { 0x55D62CAC, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6349C, 32, NDPI_PROTOCOL_TOR }, + { 0x55D636FE, 32, NDPI_PROTOCOL_TOR }, + { 0x55D63E30, 32, NDPI_PROTOCOL_TOR }, + { 0x55D64469, 32, NDPI_PROTOCOL_TOR }, + { 0x55D646BC, 32, NDPI_PROTOCOL_TOR }, + { 0x55D64748, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6492C, 32, NDPI_PROTOCOL_TOR }, + { 0x55D650F9, 32, NDPI_PROTOCOL_TOR }, + { 0x55D665E9, 32, NDPI_PROTOCOL_TOR }, + { 0x55D66C81, 32, NDPI_PROTOCOL_TOR }, + { 0x55D673D6, 32, NDPI_PROTOCOL_TOR }, + { 0x55D67EF9, 32, NDPI_PROTOCOL_TOR }, + { 0x55D680C7, 32, NDPI_PROTOCOL_TOR }, + { 0x55D68211, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6909F, 32, NDPI_PROTOCOL_TOR }, + { 0x55D69242, 32, NDPI_PROTOCOL_TOR }, + { 0x55D692DD, 32, NDPI_PROTOCOL_TOR }, + { 0x55D69748, 32, NDPI_PROTOCOL_TOR }, + { 0x55D69C1C, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6C1EA, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6C3C6, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6CEDB, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6D38C, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6DC01, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6E066, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6E20F, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6ECCF, 32, NDPI_PROTOCOL_TOR }, + { 0x55D6F0DF, 32, NDPI_PROTOCOL_TOR }, + { 0x55D82298, 32, NDPI_PROTOCOL_TOR }, + { 0x55D84A33, 32, NDPI_PROTOCOL_TOR }, + { 0x55D85282, 32, NDPI_PROTOCOL_TOR }, + { 0x55D8EF08, 32, NDPI_PROTOCOL_TOR }, + { 0x55D96A51, 32, NDPI_PROTOCOL_TOR }, + { 0x55DA8B87, 32, NDPI_PROTOCOL_TOR }, + { 0x55DE7764, 32, NDPI_PROTOCOL_TOR }, + { 0x55E00DE3, 32, NDPI_PROTOCOL_TOR }, + { 0x55E23FF3, 32, NDPI_PROTOCOL_TOR }, + { 0x55E23FF3, 32, NDPI_PROTOCOL_TOR }, + { 0x55E272EC, 32, NDPI_PROTOCOL_TOR }, + { 0x55E3B85B, 32, NDPI_PROTOCOL_TOR }, + { 0x55E4C664, 32, NDPI_PROTOCOL_TOR }, + { 0x55E52799, 32, NDPI_PROTOCOL_TOR }, + { 0x55E56B0F, 32, NDPI_PROTOCOL_TOR }, + { 0x55E5DB15, 32, NDPI_PROTOCOL_TOR }, + { 0x55E6FB1B, 32, NDPI_PROTOCOL_TOR }, + { 0x55E9156D, 32, NDPI_PROTOCOL_TOR }, + { 0x55E92788, 32, NDPI_PROTOCOL_TOR }, + { 0x55E9EC02, 32, NDPI_PROTOCOL_TOR }, + { 0x55E9F05E, 32, NDPI_PROTOCOL_TOR }, + { 0x55EA0282, 32, NDPI_PROTOCOL_TOR }, + { 0x55F262DD, 32, NDPI_PROTOCOL_TOR }, + { 0x55F2F9AE, 32, NDPI_PROTOCOL_TOR }, + { 0x55F3CFC9, 32, NDPI_PROTOCOL_TOR }, + { 0x55F4D455, 32, NDPI_PROTOCOL_TOR }, + { 0x55F5023D, 32, NDPI_PROTOCOL_TOR }, + { 0x55FB5633, 32, NDPI_PROTOCOL_TOR }, + { 0x5600D6BA, 32, NDPI_PROTOCOL_TOR }, + { 0x56017832, 32, NDPI_PROTOCOL_TOR }, + { 0x5608E378, 32, NDPI_PROTOCOL_TOR }, + { 0x560DA7C3, 32, NDPI_PROTOCOL_TOR }, + { 0x56137EFA, 32, NDPI_PROTOCOL_TOR }, + { 0x5616F4E3, 32, NDPI_PROTOCOL_TOR }, + { 0x56187315, 32, NDPI_PROTOCOL_TOR }, + { 0x561BF297, 32, NDPI_PROTOCOL_TOR }, + { 0x562C1E07, 32, NDPI_PROTOCOL_TOR }, + { 0x5634AE44, 32, NDPI_PROTOCOL_TOR }, + { 0x5634AE44, 32, NDPI_PROTOCOL_TOR }, + { 0x56387108, 32, NDPI_PROTOCOL_TOR }, + { 0x5638E449, 32, NDPI_PROTOCOL_TOR }, + { 0x563A3DBE, 32, NDPI_PROTOCOL_TOR }, + { 0x563B1526, 32, NDPI_PROTOCOL_TOR }, + { 0x563B15A3, 32, NDPI_PROTOCOL_TOR }, + { 0x563B15FB, 32, NDPI_PROTOCOL_TOR }, + { 0x563B4616, 32, NDPI_PROTOCOL_TOR }, + { 0x563B7752, 32, NDPI_PROTOCOL_TOR }, + { 0x563B7753, 32, NDPI_PROTOCOL_TOR }, + { 0x563E75AB, 32, NDPI_PROTOCOL_TOR }, + { 0x5649B3AA, 32, NDPI_PROTOCOL_TOR }, + { 0x566187BA, 32, NDPI_PROTOCOL_TOR }, + { 0x56660386, 32, NDPI_PROTOCOL_TOR }, + { 0x56679157, 32, NDPI_PROTOCOL_TOR }, + { 0x5667972F, 32, NDPI_PROTOCOL_TOR }, + { 0x5667A17E, 32, NDPI_PROTOCOL_TOR }, + { 0x566A2A77, 32, NDPI_PROTOCOL_TOR }, + { 0x56791818, 32, NDPI_PROTOCOL_TOR }, + { 0x567B34BC, 32, NDPI_PROTOCOL_TOR }, + { 0x567EB91B, 32, NDPI_PROTOCOL_TOR }, + { 0x567FBE92, 32, NDPI_PROTOCOL_TOR }, + { 0x5681D4E1, 32, NDPI_PROTOCOL_TOR }, + { 0x5681D4E1, 32, NDPI_PROTOCOL_TOR }, + { 0x5697D436, 32, NDPI_PROTOCOL_TOR }, + { 0x569A0B2D, 32, NDPI_PROTOCOL_TOR }, + { 0x569BD0C5, 32, NDPI_PROTOCOL_TOR }, + { 0x569F0B08, 32, NDPI_PROTOCOL_TOR }, + { 0x56A1DCE0, 32, NDPI_PROTOCOL_TOR }, + { 0x56A2550C, 32, NDPI_PROTOCOL_TOR }, + { 0x56A27142, 32, NDPI_PROTOCOL_TOR }, + { 0x56AE29E4, 32, NDPI_PROTOCOL_TOR }, + { 0x56AF9CFB, 32, NDPI_PROTOCOL_TOR }, + { 0x56B00DD2, 32, NDPI_PROTOCOL_TOR }, + { 0x56B03E45, 32, NDPI_PROTOCOL_TOR }, + { 0x56B1719D, 32, NDPI_PROTOCOL_TOR }, + { 0x56B3ED06, 32, NDPI_PROTOCOL_TOR }, + { 0x56B43BD3, 32, NDPI_PROTOCOL_TOR }, + { 0x56B7FF53, 32, NDPI_PROTOCOL_TOR }, + { 0x56BABA50, 32, NDPI_PROTOCOL_TOR }, + { 0x56BDAAC7, 32, NDPI_PROTOCOL_TOR }, + { 0x56CDFD45, 32, NDPI_PROTOCOL_TOR }, + { 0x56D0805A, 32, NDPI_PROTOCOL_TOR }, + { 0x56D39F39, 32, NDPI_PROTOCOL_TOR }, + { 0x56D9692B, 32, NDPI_PROTOCOL_TOR }, + { 0x56EB2C1D, 32, NDPI_PROTOCOL_TOR }, + { 0x57214983, 32, NDPI_PROTOCOL_TOR }, + { 0x5740620E, 32, NDPI_PROTOCOL_TOR }, + { 0x5743BBE2, 32, NDPI_PROTOCOL_TOR }, + { 0x5743F359, 32, NDPI_PROTOCOL_TOR }, + { 0x574823EF, 32, NDPI_PROTOCOL_TOR }, + { 0x574849E7, 32, NDPI_PROTOCOL_TOR }, + { 0x574855D9, 32, NDPI_PROTOCOL_TOR }, + { 0x574855D9, 32, NDPI_PROTOCOL_TOR }, + { 0x5748EFBB, 32, NDPI_PROTOCOL_TOR }, + { 0x574933FE, 32, NDPI_PROTOCOL_TOR }, + { 0x574A4C6A, 32, NDPI_PROTOCOL_TOR }, + { 0x574E6298, 32, NDPI_PROTOCOL_TOR }, + { 0x574F4F5E, 32, NDPI_PROTOCOL_TOR }, + { 0x574FA117, 32, NDPI_PROTOCOL_TOR }, + { 0x574FBE6A, 32, NDPI_PROTOCOL_TOR }, + { 0x574FE6A9, 32, NDPI_PROTOCOL_TOR }, + { 0x57518B76, 32, NDPI_PROTOCOL_TOR }, + { 0x5751943D, 32, NDPI_PROTOCOL_TOR }, + { 0x575C404F, 32, NDPI_PROTOCOL_TOR }, + { 0x575C7E3B, 32, NDPI_PROTOCOL_TOR }, + { 0x57628430, 32, NDPI_PROTOCOL_TOR }, + { 0x57629FE7, 32, NDPI_PROTOCOL_TOR }, + { 0x5762B23D, 32, NDPI_PROTOCOL_TOR }, + { 0x5762B905, 32, NDPI_PROTOCOL_TOR }, + { 0x5762CE46, 32, NDPI_PROTOCOL_TOR }, + { 0x5762FADE, 32, NDPI_PROTOCOL_TOR }, + { 0x5762FAF4, 32, NDPI_PROTOCOL_TOR }, + { 0x57660FD8, 32, NDPI_PROTOCOL_TOR }, + { 0x576837CB, 32, NDPI_PROTOCOL_TOR }, + { 0x57686A90, 32, NDPI_PROTOCOL_TOR }, + { 0x57688562, 32, NDPI_PROTOCOL_TOR }, + { 0x576A0364, 32, NDPI_PROTOCOL_TOR }, + { 0x576A0E9F, 32, NDPI_PROTOCOL_TOR }, + { 0x576A10D6, 32, NDPI_PROTOCOL_TOR }, + { 0x576A1108, 32, NDPI_PROTOCOL_TOR }, + { 0x576A120D, 32, NDPI_PROTOCOL_TOR }, + { 0x576A14F6, 32, NDPI_PROTOCOL_TOR }, + { 0x576A154D, 32, NDPI_PROTOCOL_TOR }, + { 0x576A20BA, 32, NDPI_PROTOCOL_TOR }, + { 0x576A2567, 32, NDPI_PROTOCOL_TOR }, + { 0x576A2FBE, 32, NDPI_PROTOCOL_TOR }, + { 0x576A3528, 32, NDPI_PROTOCOL_TOR }, + { 0x576A3786, 32, NDPI_PROTOCOL_TOR }, + { 0x576A8C18, 32, NDPI_PROTOCOL_TOR }, + { 0x576A945A, 32, NDPI_PROTOCOL_TOR }, + { 0x576ABDEE, 32, NDPI_PROTOCOL_TOR }, + { 0x576ABF5F, 32, NDPI_PROTOCOL_TOR }, + { 0x576ABF9D, 32, NDPI_PROTOCOL_TOR }, + { 0x576AD0EC, 32, NDPI_PROTOCOL_TOR }, + { 0x576AF976, 32, NDPI_PROTOCOL_TOR }, + { 0x576AF9F8, 32, NDPI_PROTOCOL_TOR }, + { 0x57706F89, 32, NDPI_PROTOCOL_TOR }, + { 0x5772AA67, 32, NDPI_PROTOCOL_TOR }, + { 0x5775DB84, 32, NDPI_PROTOCOL_TOR }, + { 0x5775DB8C, 32, NDPI_PROTOCOL_TOR }, + { 0x57765454, 32, NDPI_PROTOCOL_TOR }, + { 0x577654B5, 32, NDPI_PROTOCOL_TOR }, + { 0x577654F6, 32, NDPI_PROTOCOL_TOR }, + { 0x577658DB, 32, NDPI_PROTOCOL_TOR }, + { 0x57765B8C, 32, NDPI_PROTOCOL_TOR }, + { 0x57765D7A, 32, NDPI_PROTOCOL_TOR }, + { 0x57765EE7, 32, NDPI_PROTOCOL_TOR }, + { 0x577670AD, 32, NDPI_PROTOCOL_TOR }, + { 0x57767286, 32, NDPI_PROTOCOL_TOR }, + { 0x577674E3, 32, NDPI_PROTOCOL_TOR }, + { 0x5776760C, 32, NDPI_PROTOCOL_TOR }, + { 0x5777BA76, 32, NDPI_PROTOCOL_TOR }, + { 0x5779348B, 32, NDPI_PROTOCOL_TOR }, + { 0x57793492, 32, NDPI_PROTOCOL_TOR }, + { 0x57793497, 32, NDPI_PROTOCOL_TOR }, + { 0x577FA5F4, 32, NDPI_PROTOCOL_TOR }, + { 0x578B21D9, 32, NDPI_PROTOCOL_TOR }, + { 0x5791BA0E, 32, NDPI_PROTOCOL_TOR }, + { 0x5792CEEC, 32, NDPI_PROTOCOL_TOR }, + { 0x57954623, 32, NDPI_PROTOCOL_TOR }, + { 0x57969A86, 32, NDPI_PROTOCOL_TOR }, + { 0x5796CE37, 32, NDPI_PROTOCOL_TOR }, + { 0x579737CB, 32, NDPI_PROTOCOL_TOR }, + { 0x5798EDA7, 32, NDPI_PROTOCOL_TOR }, + { 0x579B0B3B, 32, NDPI_PROTOCOL_TOR }, + { 0x579E1829, 32, NDPI_PROTOCOL_TOR }, + { 0x579E8E9E, 32, NDPI_PROTOCOL_TOR }, + { 0x579F41E5, 32, NDPI_PROTOCOL_TOR }, + { 0x579FA892, 32, NDPI_PROTOCOL_TOR }, + { 0x57A0D2C2, 32, NDPI_PROTOCOL_TOR }, + { 0x57A2CCAC, 32, NDPI_PROTOCOL_TOR }, + { 0x57A3F603, 32, NDPI_PROTOCOL_TOR }, + { 0x57A47E10, 32, NDPI_PROTOCOL_TOR }, + { 0x57A62B46, 32, NDPI_PROTOCOL_TOR }, + { 0x57A87901, 32, NDPI_PROTOCOL_TOR }, + { 0x57A97C46, 32, NDPI_PROTOCOL_TOR }, + { 0x57AC1458, 32, NDPI_PROTOCOL_TOR }, + { 0x57AE61DF, 32, NDPI_PROTOCOL_TOR }, + { 0x57AE69FB, 32, NDPI_PROTOCOL_TOR }, + { 0x57AEE582, 32, NDPI_PROTOCOL_TOR }, + { 0x57AEEF6C, 32, NDPI_PROTOCOL_TOR }, + { 0x57AEF49C, 32, NDPI_PROTOCOL_TOR }, + { 0x57B2A7F3, 32, NDPI_PROTOCOL_TOR }, + { 0x57B362F3, 32, NDPI_PROTOCOL_TOR }, + { 0x57B38736, 32, NDPI_PROTOCOL_TOR }, + { 0x57BA1D87, 32, NDPI_PROTOCOL_TOR }, + { 0x57BC52C0, 32, NDPI_PROTOCOL_TOR }, + { 0x57BC6D89, 32, NDPI_PROTOCOL_TOR }, + { 0x57BCC2CB, 32, NDPI_PROTOCOL_TOR }, + { 0x57BD56C4, 32, NDPI_PROTOCOL_TOR }, + { 0x57C1B3EE, 32, NDPI_PROTOCOL_TOR }, + { 0x57C1D00E, 32, NDPI_PROTOCOL_TOR }, + { 0x57C62255, 32, NDPI_PROTOCOL_TOR }, + { 0x57CBC2D4, 32, NDPI_PROTOCOL_TOR }, + { 0x57CFD9D4, 32, NDPI_PROTOCOL_TOR }, + { 0x57D430C9, 32, NDPI_PROTOCOL_TOR }, + { 0x57D8ABB3, 32, NDPI_PROTOCOL_TOR }, + { 0x57D93E0E, 32, NDPI_PROTOCOL_TOR }, + { 0x57DAA8EC, 32, NDPI_PROTOCOL_TOR }, + { 0x57E0D2F3, 32, NDPI_PROTOCOL_TOR }, + { 0x57E43BBD, 32, NDPI_PROTOCOL_TOR }, + { 0x57E611F5, 32, NDPI_PROTOCOL_TOR }, + { 0x57E6196D, 32, NDPI_PROTOCOL_TOR }, + { 0x57E619AC, 32, NDPI_PROTOCOL_TOR }, + { 0x57E6335F, 32, NDPI_PROTOCOL_TOR }, + { 0x57E64E6C, 32, NDPI_PROTOCOL_TOR }, + { 0x57E70AEB, 32, NDPI_PROTOCOL_TOR }, + { 0x57E77410, 32, NDPI_PROTOCOL_TOR }, + { 0x57EC1B9B, 32, NDPI_PROTOCOL_TOR }, + { 0x57ECC3B9, 32, NDPI_PROTOCOL_TOR }, + { 0x57ECC7A9, 32, NDPI_PROTOCOL_TOR }, + { 0x57ECD389, 32, NDPI_PROTOCOL_TOR }, + { 0x57EFA26E, 32, NDPI_PROTOCOL_TOR }, + { 0x57F38E21, 32, NDPI_PROTOCOL_TOR }, + { 0x57F4FFDA, 32, NDPI_PROTOCOL_TOR }, + { 0x57FB8C5D, 32, NDPI_PROTOCOL_TOR }, + { 0x57FE635F, 32, NDPI_PROTOCOL_TOR }, + { 0x580F9CD8, 32, NDPI_PROTOCOL_TOR }, + { 0x5811212D, 32, NDPI_PROTOCOL_TOR }, + { 0x58401AEB, 32, NDPI_PROTOCOL_TOR }, + { 0x58404EF4, 32, NDPI_PROTOCOL_TOR }, + { 0x5840805B, 32, NDPI_PROTOCOL_TOR }, + { 0x58412604, 32, NDPI_PROTOCOL_TOR }, + { 0x5841F49C, 32, NDPI_PROTOCOL_TOR }, + { 0x5843639C, 32, NDPI_PROTOCOL_TOR }, + { 0x58458580, 32, NDPI_PROTOCOL_TOR }, + { 0x584862F4, 32, NDPI_PROTOCOL_TOR }, + { 0x584931A8, 32, NDPI_PROTOCOL_TOR }, + { 0x58493380, 32, NDPI_PROTOCOL_TOR }, + { 0x584C5C8E, 32, NDPI_PROTOCOL_TOR }, + { 0x584D2F56, 32, NDPI_PROTOCOL_TOR }, + { 0x584DC1AC, 32, NDPI_PROTOCOL_TOR }, + { 0x584DCB92, 32, NDPI_PROTOCOL_TOR }, + { 0x584E47B6, 32, NDPI_PROTOCOL_TOR }, + { 0x5850B95D, 32, NDPI_PROTOCOL_TOR }, + { 0x5850D6BD, 32, NDPI_PROTOCOL_TOR }, + { 0x58526C1A, 32, NDPI_PROTOCOL_TOR }, + { 0x5856D7D5, 32, NDPI_PROTOCOL_TOR }, + { 0x58574E68, 32, NDPI_PROTOCOL_TOR }, + { 0x585BD594, 32, NDPI_PROTOCOL_TOR }, + { 0x58614DFF, 32, NDPI_PROTOCOL_TOR }, + { 0x58690051, 32, NDPI_PROTOCOL_TOR }, + { 0x58719D6B, 32, NDPI_PROTOCOL_TOR }, + { 0x58726D58, 32, NDPI_PROTOCOL_TOR }, + { 0x5872759B, 32, NDPI_PROTOCOL_TOR }, + { 0x5872E33E, 32, NDPI_PROTOCOL_TOR }, + { 0x587E6C2D, 32, NDPI_PROTOCOL_TOR }, + { 0x587F6026, 32, NDPI_PROTOCOL_TOR }, + { 0x588201AE, 32, NDPI_PROTOCOL_TOR }, + { 0x58823273, 32, NDPI_PROTOCOL_TOR }, + { 0x58864FB5, 32, NDPI_PROTOCOL_TOR }, + { 0x588678F8, 32, NDPI_PROTOCOL_TOR }, + { 0x58869115, 32, NDPI_PROTOCOL_TOR }, + { 0x58894FA1, 32, NDPI_PROTOCOL_TOR }, + { 0x58959A20, 32, NDPI_PROTOCOL_TOR }, + { 0x58982F2D, 32, NDPI_PROTOCOL_TOR }, + { 0x5898FFF5, 32, NDPI_PROTOCOL_TOR }, + { 0x58996247, 32, NDPI_PROTOCOL_TOR }, + { 0x5899A4FF, 32, NDPI_PROTOCOL_TOR }, + { 0x5899AB6B, 32, NDPI_PROTOCOL_TOR }, + { 0x5899B4A5, 32, NDPI_PROTOCOL_TOR }, + { 0x589F4697, 32, NDPI_PROTOCOL_TOR }, + { 0x589F53F4, 32, NDPI_PROTOCOL_TOR }, + { 0x58A3E58B, 32, NDPI_PROTOCOL_TOR }, + { 0x58A5F4A9, 32, NDPI_PROTOCOL_TOR }, + { 0x58A6C0B5, 32, NDPI_PROTOCOL_TOR }, + { 0x58A8F257, 32, NDPI_PROTOCOL_TOR }, + { 0x58B0042F, 32, NDPI_PROTOCOL_TOR }, + { 0x58B0B407, 32, NDPI_PROTOCOL_TOR }, + { 0x58B256CA, 32, NDPI_PROTOCOL_TOR }, + { 0x58B99B86, 32, NDPI_PROTOCOL_TOR }, + { 0x58B9E31D, 32, NDPI_PROTOCOL_TOR }, + { 0x58BA120C, 32, NDPI_PROTOCOL_TOR }, + { 0x58BB785A, 32, NDPI_PROTOCOL_TOR }, + { 0x58BBBAD8, 32, NDPI_PROTOCOL_TOR }, + { 0x58BBE53B, 32, NDPI_PROTOCOL_TOR }, + { 0x58BD8A61, 32, NDPI_PROTOCOL_TOR }, + { 0x58C3CF75, 32, NDPI_PROTOCOL_TOR }, + { 0x58C60910, 32, NDPI_PROTOCOL_TOR }, + { 0x58C61304, 32, NDPI_PROTOCOL_TOR }, + { 0x58C617B3, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6194C, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6195C, 32, NDPI_PROTOCOL_TOR }, + { 0x58C628A5, 32, NDPI_PROTOCOL_TOR }, + { 0x58C63352, 32, NDPI_PROTOCOL_TOR }, + { 0x58C63436, 32, NDPI_PROTOCOL_TOR }, + { 0x58C636D4, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6388C, 32, NDPI_PROTOCOL_TOR }, + { 0x58C64689, 32, NDPI_PROTOCOL_TOR }, + { 0x58C664E6, 32, NDPI_PROTOCOL_TOR }, + { 0x58C664E8, 32, NDPI_PROTOCOL_TOR }, + { 0x58C66D95, 32, NDPI_PROTOCOL_TOR }, + { 0x58C66DE5, 32, NDPI_PROTOCOL_TOR }, + { 0x58C66E98, 32, NDPI_PROTOCOL_TOR }, + { 0x58C66F77, 32, NDPI_PROTOCOL_TOR }, + { 0x58C67565, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6789B, 32, NDPI_PROTOCOL_TOR }, + { 0x58C67FE6, 32, NDPI_PROTOCOL_TOR }, + { 0x58C682D4, 32, NDPI_PROTOCOL_TOR }, + { 0x58C69A70, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6A363, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6A364, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6AF4C, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6C187, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6C259, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6C633, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6CFDE, 32, NDPI_PROTOCOL_TOR }, + { 0x58C6D6E9, 32, NDPI_PROTOCOL_TOR }, + { 0x58C8F312, 32, NDPI_PROTOCOL_TOR }, + { 0x58CC71BD, 32, NDPI_PROTOCOL_TOR }, + { 0x58D0CD8A, 32, NDPI_PROTOCOL_TOR }, + { 0x58D90267, 32, NDPI_PROTOCOL_TOR }, + { 0x58D92CAE, 32, NDPI_PROTOCOL_TOR }, + { 0x58D94FCA, 32, NDPI_PROTOCOL_TOR }, + { 0x58D98F35, 32, NDPI_PROTOCOL_TOR }, + { 0x58D9ABE1, 32, NDPI_PROTOCOL_TOR }, + { 0x58E44C31, 32, NDPI_PROTOCOL_TOR }, + { 0x59004F17, 32, NDPI_PROTOCOL_TOR }, + { 0x5900641C, 32, NDPI_PROTOCOL_TOR }, + { 0x5900878D, 32, NDPI_PROTOCOL_TOR }, + { 0x5900AD14, 32, NDPI_PROTOCOL_TOR }, + { 0x5900E463, 32, NDPI_PROTOCOL_TOR }, + { 0x5900E570, 32, NDPI_PROTOCOL_TOR }, + { 0x5900EA67, 32, NDPI_PROTOCOL_TOR }, + { 0x5900EC30, 32, NDPI_PROTOCOL_TOR }, + { 0x5900F2EF, 32, NDPI_PROTOCOL_TOR }, + { 0x5900F7A3, 32, NDPI_PROTOCOL_TOR }, + { 0x59039E31, 32, NDPI_PROTOCOL_TOR }, + { 0x590CF9FD, 32, NDPI_PROTOCOL_TOR }, + { 0x590D5330, 32, NDPI_PROTOCOL_TOR }, + { 0x590E57D6, 32, NDPI_PROTOCOL_TOR }, + { 0x590F649D, 32, NDPI_PROTOCOL_TOR }, + { 0x590F6BF1, 32, NDPI_PROTOCOL_TOR }, + { 0x590FC872, 32, NDPI_PROTOCOL_TOR }, + { 0x59108C47, 32, NDPI_PROTOCOL_TOR }, + { 0x5910B09E, 32, NDPI_PROTOCOL_TOR }, + { 0x59122A65, 32, NDPI_PROTOCOL_TOR }, + { 0x5912AC8B, 32, NDPI_PROTOCOL_TOR }, + { 0x5912AD29, 32, NDPI_PROTOCOL_TOR }, + { 0x5912AE45, 32, NDPI_PROTOCOL_TOR }, + { 0x5912AE56, 32, NDPI_PROTOCOL_TOR }, + { 0x5912BE6B, 32, NDPI_PROTOCOL_TOR }, + { 0x5916602F, 32, NDPI_PROTOCOL_TOR }, + { 0x5916613A, 32, NDPI_PROTOCOL_TOR }, + { 0x591661C1, 32, NDPI_PROTOCOL_TOR }, + { 0x591B0DD9, 32, NDPI_PROTOCOL_TOR }, + { 0x591B4114, 32, NDPI_PROTOCOL_TOR }, + { 0x591B5146, 32, NDPI_PROTOCOL_TOR }, + { 0x591F3905, 32, NDPI_PROTOCOL_TOR }, + { 0x5924EB42, 32, NDPI_PROTOCOL_TOR }, + { 0x59284795, 32, NDPI_PROTOCOL_TOR }, + { 0x592E64A2, 32, NDPI_PROTOCOL_TOR }, + { 0x592E6524, 32, NDPI_PROTOCOL_TOR }, + { 0x592E65B5, 32, NDPI_PROTOCOL_TOR }, + { 0x59410727, 32, NDPI_PROTOCOL_TOR }, + { 0x59412546, 32, NDPI_PROTOCOL_TOR }, + { 0x59438C76, 32, NDPI_PROTOCOL_TOR }, + { 0x59438C76, 32, NDPI_PROTOCOL_TOR }, + { 0x5943B32A, 32, NDPI_PROTOCOL_TOR }, + { 0x5943FE26, 32, NDPI_PROTOCOL_TOR }, + { 0x5944BDD0, 32, NDPI_PROTOCOL_TOR }, + { 0x594669E7, 32, NDPI_PROTOCOL_TOR }, + { 0x5949B1EC, 32, NDPI_PROTOCOL_TOR }, + { 0x5949D520, 32, NDPI_PROTOCOL_TOR }, + { 0x594A6CCE, 32, NDPI_PROTOCOL_TOR }, + { 0x594D88AE, 32, NDPI_PROTOCOL_TOR }, + { 0x5959FD25, 32, NDPI_PROTOCOL_TOR }, + { 0x5962E64C, 32, NDPI_PROTOCOL_TOR }, + { 0x59639B85, 32, NDPI_PROTOCOL_TOR }, + { 0x59669393, 32, NDPI_PROTOCOL_TOR }, + { 0x5967B502, 32, NDPI_PROTOCOL_TOR }, + { 0x5967B832, 32, NDPI_PROTOCOL_TOR }, + { 0x5969C582, 32, NDPI_PROTOCOL_TOR }, + { 0x596AF415, 32, NDPI_PROTOCOL_TOR }, + { 0x596C560B, 32, NDPI_PROTOCOL_TOR }, + { 0x596C58E3, 32, NDPI_PROTOCOL_TOR }, + { 0x596E9CF7, 32, NDPI_PROTOCOL_TOR }, + { 0x596F1444, 32, NDPI_PROTOCOL_TOR }, + { 0x5978777D, 32, NDPI_PROTOCOL_TOR }, + { 0x59829E95, 32, NDPI_PROTOCOL_TOR }, + { 0x59845CDA, 32, NDPI_PROTOCOL_TOR }, + { 0x5985A952, 32, NDPI_PROTOCOL_TOR }, + { 0x598619DA, 32, NDPI_PROTOCOL_TOR }, + { 0x59869680, 32, NDPI_PROTOCOL_TOR }, + { 0x59879056, 32, NDPI_PROTOCOL_TOR }, + { 0x598C623C, 32, NDPI_PROTOCOL_TOR }, + { 0x598E23D1, 32, NDPI_PROTOCOL_TOR }, + { 0x59910E6C, 32, NDPI_PROTOCOL_TOR }, + { 0x599B990F, 32, NDPI_PROTOCOL_TOR }, + { 0x599C3EBE, 32, NDPI_PROTOCOL_TOR }, + { 0x599C5DDC, 32, NDPI_PROTOCOL_TOR }, + { 0x599ED03F, 32, NDPI_PROTOCOL_TOR }, + { 0x599F568B, 32, NDPI_PROTOCOL_TOR }, + { 0x59A0DE85, 32, NDPI_PROTOCOL_TOR }, + { 0x59A257B4, 32, NDPI_PROTOCOL_TOR }, + { 0x59A3ABFA, 32, NDPI_PROTOCOL_TOR }, + { 0x59A3B9BA, 32, NDPI_PROTOCOL_TOR }, + { 0x59A3D14F, 32, NDPI_PROTOCOL_TOR }, + { 0x59A3D14F, 32, NDPI_PROTOCOL_TOR }, + { 0x59A3DD97, 32, NDPI_PROTOCOL_TOR }, + { 0x59A3DD97, 32, NDPI_PROTOCOL_TOR }, + { 0x59A3E00A, 32, NDPI_PROTOCOL_TOR }, + { 0x59A3E0A8, 32, NDPI_PROTOCOL_TOR }, + { 0x59A3E0BB, 32, NDPI_PROTOCOL_TOR }, + { 0x59A3E31C, 32, NDPI_PROTOCOL_TOR }, + { 0x59A6EAF6, 32, NDPI_PROTOCOL_TOR }, + { 0x59A9A5E9, 32, NDPI_PROTOCOL_TOR }, + { 0x59B08CBE, 32, NDPI_PROTOCOL_TOR }, + { 0x59B08D09, 32, NDPI_PROTOCOL_TOR }, + { 0x59B34E19, 32, NDPI_PROTOCOL_TOR }, + { 0x59B37F7C, 32, NDPI_PROTOCOL_TOR }, + { 0x59B3F11E, 32, NDPI_PROTOCOL_TOR }, + { 0x59B891D7, 32, NDPI_PROTOCOL_TOR }, + { 0x59BA8F86, 32, NDPI_PROTOCOL_TOR }, + { 0x59BB8ED0, 32, NDPI_PROTOCOL_TOR }, + { 0x59BC6DD2, 32, NDPI_PROTOCOL_TOR }, + { 0x59BFC7F5, 32, NDPI_PROTOCOL_TOR }, + { 0x59CF8537, 32, NDPI_PROTOCOL_TOR }, + { 0x59CF8799, 32, NDPI_PROTOCOL_TOR }, + { 0x59E31A37, 32, NDPI_PROTOCOL_TOR }, + { 0x59E7763D, 32, NDPI_PROTOCOL_TOR }, + { 0x59EA8D65, 32, NDPI_PROTOCOL_TOR }, + { 0x59EA9DFE, 32, NDPI_PROTOCOL_TOR }, + { 0x59EA9DFE, 32, NDPI_PROTOCOL_TOR }, + { 0x59EE455D, 32, NDPI_PROTOCOL_TOR }, + { 0x59EE4D04, 32, NDPI_PROTOCOL_TOR }, + { 0x59EE4E6C, 32, NDPI_PROTOCOL_TOR }, + { 0x59EEAC6C, 32, NDPI_PROTOCOL_TOR }, + { 0x59EFDAB4, 32, NDPI_PROTOCOL_TOR }, + { 0x59F8A679, 32, NDPI_PROTOCOL_TOR }, + { 0x59F8AC10, 32, NDPI_PROTOCOL_TOR }, + { 0x59F985A5, 32, NDPI_PROTOCOL_TOR }, + { 0x59FB968E, 32, NDPI_PROTOCOL_TOR }, + { 0x59FC0125, 32, NDPI_PROTOCOL_TOR }, + { 0x59FC028C, 32, NDPI_PROTOCOL_TOR }, + { 0x5A09C850, 32, NDPI_PROTOCOL_TOR }, + { 0x5A0A8BC7, 32, NDPI_PROTOCOL_TOR }, + { 0x5A0B5036, 32, NDPI_PROTOCOL_TOR }, + { 0x5A18B154, 32, NDPI_PROTOCOL_TOR }, + { 0x5A1B3C6B, 32, NDPI_PROTOCOL_TOR }, + { 0x5A1D82F0, 32, NDPI_PROTOCOL_TOR }, + { 0x5A1D9B54, 32, NDPI_PROTOCOL_TOR }, + { 0x5A20BA49, 32, NDPI_PROTOCOL_TOR }, + { 0x5A28F78E, 32, NDPI_PROTOCOL_TOR }, + { 0x5A3CABF0, 32, NDPI_PROTOCOL_TOR }, + { 0x5A3FA178, 32, NDPI_PROTOCOL_TOR }, + { 0x5A914577, 32, NDPI_PROTOCOL_TOR }, + { 0x5A921D38, 32, NDPI_PROTOCOL_TOR }, + { 0x5A92B569, 32, NDPI_PROTOCOL_TOR }, + { 0x5A951B7A, 32, NDPI_PROTOCOL_TOR }, + { 0x5A95517A, 32, NDPI_PROTOCOL_TOR }, + { 0x5A9B17DA, 32, NDPI_PROTOCOL_TOR }, + { 0x5AB0A48F, 32, NDPI_PROTOCOL_TOR }, + { 0x5AB50D30, 32, NDPI_PROTOCOL_TOR }, + { 0x5AB88EE0, 32, NDPI_PROTOCOL_TOR }, + { 0x5AB8A455, 32, NDPI_PROTOCOL_TOR }, + { 0x5AB8DE74, 32, NDPI_PROTOCOL_TOR }, + { 0x5AB8DE75, 32, NDPI_PROTOCOL_TOR }, + { 0x5AB8DE76, 32, NDPI_PROTOCOL_TOR }, + { 0x5AC04EC5, 32, NDPI_PROTOCOL_TOR }, + { 0x5ADB84FD, 32, NDPI_PROTOCOL_TOR }, + { 0x5AE14054, 32, NDPI_PROTOCOL_TOR }, + { 0x5AE150DB, 32, NDPI_PROTOCOL_TOR }, + { 0x5AE1558C, 32, NDPI_PROTOCOL_TOR }, + { 0x5AE2B287, 32, NDPI_PROTOCOL_TOR }, + { 0x5AE4CA9F, 32, NDPI_PROTOCOL_TOR }, + { 0x5AE7989F, 32, NDPI_PROTOCOL_TOR }, + { 0x5B025570, 32, NDPI_PROTOCOL_TOR }, + { 0x5B02F637, 32, NDPI_PROTOCOL_TOR }, + { 0x5B041823, 32, NDPI_PROTOCOL_TOR }, + { 0x5B05878B, 32, NDPI_PROTOCOL_TOR }, + { 0x5B06757C, 32, NDPI_PROTOCOL_TOR }, + { 0x5B09C013, 32, NDPI_PROTOCOL_TOR }, + { 0x5B0A081A, 32, NDPI_PROTOCOL_TOR }, + { 0x5B0A45D7, 32, NDPI_PROTOCOL_TOR }, + { 0x5B0A7B54, 32, NDPI_PROTOCOL_TOR }, + { 0x5B0CD9A9, 32, NDPI_PROTOCOL_TOR }, + { 0x5B0CEB4D, 32, NDPI_PROTOCOL_TOR }, + { 0x5B0D634C, 32, NDPI_PROTOCOL_TOR }, + { 0x5B0E755F, 32, NDPI_PROTOCOL_TOR }, + { 0x5B0F4794, 32, NDPI_PROTOCOL_TOR }, + { 0x5B120251, 32, NDPI_PROTOCOL_TOR }, + { 0x5B129DE3, 32, NDPI_PROTOCOL_TOR }, + { 0x5B152C3D, 32, NDPI_PROTOCOL_TOR }, + { 0x5B21CED5, 32, NDPI_PROTOCOL_TOR }, + { 0x5B225C74, 32, NDPI_PROTOCOL_TOR }, + { 0x5B25E831, 32, NDPI_PROTOCOL_TOR }, + { 0x5B265CAF, 32, NDPI_PROTOCOL_TOR }, + { 0x5B2C7D98, 32, NDPI_PROTOCOL_TOR }, + { 0x5B2DE1A9, 32, NDPI_PROTOCOL_TOR }, + { 0x5B3249DA, 32, NDPI_PROTOCOL_TOR }, + { 0x5B334FF1, 32, NDPI_PROTOCOL_TOR }, + { 0x5B336B45, 32, NDPI_PROTOCOL_TOR }, + { 0x5B33E422, 32, NDPI_PROTOCOL_TOR }, + { 0x5B33FBDE, 32, NDPI_PROTOCOL_TOR }, + { 0x5B343F6F, 32, NDPI_PROTOCOL_TOR }, + { 0x5B36DE01, 32, NDPI_PROTOCOL_TOR }, + { 0x5B3B5350, 32, NDPI_PROTOCOL_TOR }, + { 0x5B3D4574, 32, NDPI_PROTOCOL_TOR }, + { 0x5B3D52E4, 32, NDPI_PROTOCOL_TOR }, + { 0x5B3DF13E, 32, NDPI_PROTOCOL_TOR }, + { 0x5B3EE54E, 32, NDPI_PROTOCOL_TOR }, + { 0x5B406D9B, 32, NDPI_PROTOCOL_TOR }, + { 0x5B406F83, 32, NDPI_PROTOCOL_TOR }, + { 0x5B40EADB, 32, NDPI_PROTOCOL_TOR }, + { 0x5B41538E, 32, NDPI_PROTOCOL_TOR }, + { 0x5B4160F6, 32, NDPI_PROTOCOL_TOR }, + { 0x5B424E8B, 32, NDPI_PROTOCOL_TOR }, + { 0x5B4254DB, 32, NDPI_PROTOCOL_TOR }, + { 0x5B42CC01, 32, NDPI_PROTOCOL_TOR }, + { 0x5B434C46, 32, NDPI_PROTOCOL_TOR }, + { 0x5B4D127A, 32, NDPI_PROTOCOL_TOR }, + { 0x5B4F6E29, 32, NDPI_PROTOCOL_TOR }, + { 0x5B52ED7F, 32, NDPI_PROTOCOL_TOR }, + { 0x5B605C06, 32, NDPI_PROTOCOL_TOR }, + { 0x5B60BC9F, 32, NDPI_PROTOCOL_TOR }, + { 0x5B614084, 32, NDPI_PROTOCOL_TOR }, + { 0x5B6DF7AD, 32, NDPI_PROTOCOL_TOR }, + { 0x5B711952, 32, NDPI_PROTOCOL_TOR }, + { 0x5B77D141, 32, NDPI_PROTOCOL_TOR }, + { 0x5B77E5A1, 32, NDPI_PROTOCOL_TOR }, + { 0x5B790114, 32, NDPI_PROTOCOL_TOR }, + { 0x5B791043, 32, NDPI_PROTOCOL_TOR }, + { 0x5B7915E0, 32, NDPI_PROTOCOL_TOR }, + { 0x5B791C40, 32, NDPI_PROTOCOL_TOR }, + { 0x5B794CCC, 32, NDPI_PROTOCOL_TOR }, + { 0x5B794CCF, 32, NDPI_PROTOCOL_TOR }, + { 0x5B795210, 32, NDPI_PROTOCOL_TOR }, + { 0x5B795219, 32, NDPI_PROTOCOL_TOR }, + { 0x5B79545C, 32, NDPI_PROTOCOL_TOR }, + { 0x5B795582, 32, NDPI_PROTOCOL_TOR }, + { 0x5B7964C8, 32, NDPI_PROTOCOL_TOR }, + { 0x5B7968A8, 32, NDPI_PROTOCOL_TOR }, + { 0x5B796AB2, 32, NDPI_PROTOCOL_TOR }, + { 0x5B79734F, 32, NDPI_PROTOCOL_TOR }, + { 0x5B797422, 32, NDPI_PROTOCOL_TOR }, + { 0x5B799255, 32, NDPI_PROTOCOL_TOR }, + { 0x5B799275, 32, NDPI_PROTOCOL_TOR }, + { 0x5B799341, 32, NDPI_PROTOCOL_TOR }, + { 0x5B799FC4, 32, NDPI_PROTOCOL_TOR }, + { 0x5B79A5DF, 32, NDPI_PROTOCOL_TOR }, + { 0x5B79A698, 32, NDPI_PROTOCOL_TOR }, + { 0x5B79A921, 32, NDPI_PROTOCOL_TOR }, + { 0x5B79B857, 32, NDPI_PROTOCOL_TOR }, + { 0x5B79C584, 32, NDPI_PROTOCOL_TOR }, + { 0x5B79CF22, 32, NDPI_PROTOCOL_TOR }, + { 0x5B79E9F2, 32, NDPI_PROTOCOL_TOR }, + { 0x5B7A640D, 32, NDPI_PROTOCOL_TOR }, + { 0x5B7BC8A8, 32, NDPI_PROTOCOL_TOR }, + { 0x5B7BC8EB, 32, NDPI_PROTOCOL_TOR }, + { 0x5B7EFFCD, 32, NDPI_PROTOCOL_TOR }, + { 0x5B88A44D, 32, NDPI_PROTOCOL_TOR }, + { 0x5B8A448F, 32, NDPI_PROTOCOL_TOR }, + { 0x5B8A9B09, 32, NDPI_PROTOCOL_TOR }, + { 0x5B8C31D6, 32, NDPI_PROTOCOL_TOR }, + { 0x5B917635, 32, NDPI_PROTOCOL_TOR }, + { 0x5B927903, 32, NDPI_PROTOCOL_TOR }, + { 0x5B927A2D, 32, NDPI_PROTOCOL_TOR }, + { 0x5B95AD4F, 32, NDPI_PROTOCOL_TOR }, + { 0x5B9A9932, 32, NDPI_PROTOCOL_TOR }, + { 0x5B9BBD6B, 32, NDPI_PROTOCOL_TOR }, + { 0x5BB9C8DD, 32, NDPI_PROTOCOL_TOR }, + { 0x5BB9E123, 32, NDPI_PROTOCOL_TOR }, + { 0x5BBA2710, 32, NDPI_PROTOCOL_TOR }, + { 0x5BBC7D80, 32, NDPI_PROTOCOL_TOR }, + { 0x5BBDB576, 32, NDPI_PROTOCOL_TOR }, + { 0x5BBE754D, 32, NDPI_PROTOCOL_TOR }, + { 0x5BC2546A, 32, NDPI_PROTOCOL_TOR }, + { 0x5BC25A27, 32, NDPI_PROTOCOL_TOR }, + { 0x5BC25A67, 32, NDPI_PROTOCOL_TOR }, + { 0x5BC7C54C, 32, NDPI_PROTOCOL_TOR }, + { 0x5BC85544, 32, NDPI_PROTOCOL_TOR }, + { 0x5BCA2D9C, 32, NDPI_PROTOCOL_TOR }, + { 0x5BCBD4EE, 32, NDPI_PROTOCOL_TOR }, + { 0x5BCDAD52, 32, NDPI_PROTOCOL_TOR }, + { 0x5BCE8E46, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD05448, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD26A1B, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD33ED4, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD5082B, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD50854, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD50859, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD50874, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD508EB, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD508EB, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD508EC, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD6A8F0, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD6CB90, 32, NDPI_PROTOCOL_TOR }, + { 0x5BD6CBE9, 32, NDPI_PROTOCOL_TOR }, + { 0x5BDBED13, 32, NDPI_PROTOCOL_TOR }, + { 0x5BDBED6E, 32, NDPI_PROTOCOL_TOR }, + { 0x5BDBEDCF, 32, NDPI_PROTOCOL_TOR }, + { 0x5BDBEDDA, 32, NDPI_PROTOCOL_TOR }, + { 0x5BDBEDE5, 32, NDPI_PROTOCOL_TOR }, + { 0x5BDBEDF4, 32, NDPI_PROTOCOL_TOR }, + { 0x5BDBEEDD, 32, NDPI_PROTOCOL_TOR }, + { 0x5BDCA33E, 32, NDPI_PROTOCOL_TOR }, + { 0x5BDD6F07, 32, NDPI_PROTOCOL_TOR }, + { 0x5BDEDA85, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE09509, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE09521, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE0952D, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE09537, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE25911, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE434BA, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE49734, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE4B382, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE5141B, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE6CCC6, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE8D912, 32, NDPI_PROTOCOL_TOR }, + { 0x5BE97444, 32, NDPI_PROTOCOL_TOR }, + { 0x5BEA1630, 32, NDPI_PROTOCOL_TOR }, + { 0x5BEAE223, 32, NDPI_PROTOCOL_TOR }, + { 0x5BECEF87, 32, NDPI_PROTOCOL_TOR }, + { 0x5BECEF8C, 32, NDPI_PROTOCOL_TOR }, + { 0x5BED34AA, 32, NDPI_PROTOCOL_TOR }, + { 0x5BEDF43E, 32, NDPI_PROTOCOL_TOR }, + { 0x5BEDF73E, 32, NDPI_PROTOCOL_TOR }, + { 0x5BEE3C64, 32, NDPI_PROTOCOL_TOR }, + { 0x5BF0E5C3, 32, NDPI_PROTOCOL_TOR }, + { 0x5BFA7026, 32, NDPI_PROTOCOL_TOR }, + { 0x5BFA73B9, 32, NDPI_PROTOCOL_TOR }, + { 0x5BFAF20A, 32, NDPI_PROTOCOL_TOR }, + { 0x5BFAF267, 32, NDPI_PROTOCOL_TOR }, + { 0x5C002464, 32, NDPI_PROTOCOL_TOR }, + { 0x5C0124D4, 32, NDPI_PROTOCOL_TOR }, + { 0x5C01DCB8, 32, NDPI_PROTOCOL_TOR }, + { 0x5C07A833, 32, NDPI_PROTOCOL_TOR }, + { 0x5C0A3BD5, 32, NDPI_PROTOCOL_TOR }, + { 0x5C0EC83C, 32, NDPI_PROTOCOL_TOR }, + { 0x5C14074D, 32, NDPI_PROTOCOL_TOR }, + { 0x5C14CB4C, 32, NDPI_PROTOCOL_TOR }, + { 0x5C15F357, 32, NDPI_PROTOCOL_TOR }, + { 0x5C18851F, 32, NDPI_PROTOCOL_TOR }, + { 0x5C18851F, 32, NDPI_PROTOCOL_TOR }, + { 0x5C27F38B, 32, NDPI_PROTOCOL_TOR }, + { 0x5C27F62D, 32, NDPI_PROTOCOL_TOR }, + { 0x5C2869CC, 32, NDPI_PROTOCOL_TOR }, + { 0x5C32581A, 32, NDPI_PROTOCOL_TOR }, + { 0x5C34249B, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3C05EE, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3C05EE, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3F582D, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3F582F, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3F6E7C, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3FAB2D, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3FABCF, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3FAC96, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3FAE24, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3FAE46, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3FAE47, 32, NDPI_PROTOCOL_TOR }, + { 0x5C3FAF05, 32, NDPI_PROTOCOL_TOR }, + { 0x5C484CE3, 32, NDPI_PROTOCOL_TOR }, + { 0x5C487B89, 32, NDPI_PROTOCOL_TOR }, + { 0x5C48FF4A, 32, NDPI_PROTOCOL_TOR }, + { 0x5C4A357A, 32, NDPI_PROTOCOL_TOR }, + { 0x5C4AE372, 32, NDPI_PROTOCOL_TOR }, + { 0x5C4B0EC2, 32, NDPI_PROTOCOL_TOR }, + { 0x5C4C7C06, 32, NDPI_PROTOCOL_TOR }, + { 0x5C4CC040, 32, NDPI_PROTOCOL_TOR }, + { 0x5C4D2D74, 32, NDPI_PROTOCOL_TOR }, + { 0x5C4DB1FE, 32, NDPI_PROTOCOL_TOR }, + { 0x5C59AD55, 32, NDPI_PROTOCOL_TOR }, + { 0x5C5B7942, 32, NDPI_PROTOCOL_TOR }, + { 0x5C5B9C44, 32, NDPI_PROTOCOL_TOR }, + { 0x5C645773, 32, NDPI_PROTOCOL_TOR }, + { 0x5C647BD0, 32, NDPI_PROTOCOL_TOR }, + { 0x5C68349B, 32, NDPI_PROTOCOL_TOR }, + { 0x5C6893A0, 32, NDPI_PROTOCOL_TOR }, + { 0x5C6977C0, 32, NDPI_PROTOCOL_TOR }, + { 0x5C6AE25D, 32, NDPI_PROTOCOL_TOR }, + { 0x5C6C364C, 32, NDPI_PROTOCOL_TOR }, + { 0x5C6C7829, 32, NDPI_PROTOCOL_TOR }, + { 0x5C6D0707, 32, NDPI_PROTOCOL_TOR }, + { 0x5C6F8E21, 32, NDPI_PROTOCOL_TOR }, + { 0x5C81AF11, 32, NDPI_PROTOCOL_TOR }, + { 0x5C83BD03, 32, NDPI_PROTOCOL_TOR }, + { 0x5C89D859, 32, NDPI_PROTOCOL_TOR }, + { 0x5CC240C3, 32, NDPI_PROTOCOL_TOR }, + { 0x5CC328D6, 32, NDPI_PROTOCOL_TOR }, + { 0x5CC941B7, 32, NDPI_PROTOCOL_TOR }, + { 0x5CC94BCD, 32, NDPI_PROTOCOL_TOR }, + { 0x5CCA214F, 32, NDPI_PROTOCOL_TOR }, + { 0x5CCD15C1, 32, NDPI_PROTOCOL_TOR }, + { 0x5CD13085, 32, NDPI_PROTOCOL_TOR }, + { 0x5CD3AE6A, 32, NDPI_PROTOCOL_TOR }, + { 0x5CD6A588, 32, NDPI_PROTOCOL_TOR }, + { 0x5CD6ADD8, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE016C, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE0352, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE0466, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE04B2, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE0935, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE0946, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE1385, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE1482, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE1625, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE1671, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE19E1, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE1A24, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE1A51, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE1C5A, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE1C8F, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE1CF3, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE1D22, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE2211, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE2643, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE27B7, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE2DC7, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE45BC, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDE9993, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDEA236, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDEACE5, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDEB57B, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDEC022, 32, NDPI_PROTOCOL_TOR }, + { 0x5CDECC60, 32, NDPI_PROTOCOL_TOR }, + { 0x5CE09A94, 32, NDPI_PROTOCOL_TOR }, + { 0x5CE0A09F, 32, NDPI_PROTOCOL_TOR }, + { 0x5CE0B392, 32, NDPI_PROTOCOL_TOR }, + { 0x5CE10C0D, 32, NDPI_PROTOCOL_TOR }, + { 0x5CE169B5, 32, NDPI_PROTOCOL_TOR }, + { 0x5CE389A3, 32, NDPI_PROTOCOL_TOR }, + { 0x5CE4B19B, 32, NDPI_PROTOCOL_TOR }, + { 0x5CE52412, 32, NDPI_PROTOCOL_TOR }, + { 0x5CE59221, 32, NDPI_PROTOCOL_TOR }, + { 0x5CE68415, 32, NDPI_PROTOCOL_TOR }, + { 0x5CE86216, 32, NDPI_PROTOCOL_TOR }, + { 0x5CED16DA, 32, NDPI_PROTOCOL_TOR }, + { 0x5CF31ED0, 32, NDPI_PROTOCOL_TOR }, + { 0x5CF34569, 32, NDPI_PROTOCOL_TOR }, + { 0x5CF3BC10, 32, NDPI_PROTOCOL_TOR }, + { 0x5CF6147E, 32, NDPI_PROTOCOL_TOR }, + { 0x5CF733A9, 32, NDPI_PROTOCOL_TOR }, + { 0x5CF79DB0, 32, NDPI_PROTOCOL_TOR }, + { 0x5CF96241, 32, NDPI_PROTOCOL_TOR }, + { 0x5CF98F77, 32, NDPI_PROTOCOL_TOR }, + { 0x5CF9BCF6, 32, NDPI_PROTOCOL_TOR }, + { 0x5CFC2031, 32, NDPI_PROTOCOL_TOR }, + { 0x5CFE18CB, 32, NDPI_PROTOCOL_TOR }, + { 0x5CFE3951, 32, NDPI_PROTOCOL_TOR }, + { 0x5CFEB874, 32, NDPI_PROTOCOL_TOR }, + { 0x5CFFC311, 32, NDPI_PROTOCOL_TOR }, + { 0x5CFFCF59, 32, NDPI_PROTOCOL_TOR }, + { 0x5D134D18, 32, NDPI_PROTOCOL_TOR }, + { 0x5D1F9BAF, 32, NDPI_PROTOCOL_TOR }, + { 0x5D328CAA, 32, NDPI_PROTOCOL_TOR }, + { 0x5D48650E, 32, NDPI_PROTOCOL_TOR }, + { 0x5D515FF8, 32, NDPI_PROTOCOL_TOR }, + { 0x5D5A73BC, 32, NDPI_PROTOCOL_TOR }, + { 0x5D5B3291, 32, NDPI_PROTOCOL_TOR }, + { 0x5D5CCC06, 32, NDPI_PROTOCOL_TOR }, + { 0x5D5E922B, 32, NDPI_PROTOCOL_TOR }, + { 0x5D5FE37F, 32, NDPI_PROTOCOL_TOR }, + { 0x5D5FE3F5, 32, NDPI_PROTOCOL_TOR }, + { 0x5D5FE405, 32, NDPI_PROTOCOL_TOR }, + { 0x5D5FE433, 32, NDPI_PROTOCOL_TOR }, + { 0x5D5FE452, 32, NDPI_PROTOCOL_TOR }, + { 0x5D63058C, 32, NDPI_PROTOCOL_TOR }, + { 0x5D64A738, 32, NDPI_PROTOCOL_TOR }, + { 0x5D6797A7, 32, NDPI_PROTOCOL_TOR }, + { 0x5D688049, 32, NDPI_PROTOCOL_TOR }, + { 0x5D68A671, 32, NDPI_PROTOCOL_TOR }, + { 0x5D68D13D, 32, NDPI_PROTOCOL_TOR }, + { 0x5D68D19E, 32, NDPI_PROTOCOL_TOR }, + { 0x5D68D3A9, 32, NDPI_PROTOCOL_TOR }, + { 0x5D68D4FD, 32, NDPI_PROTOCOL_TOR }, + { 0x5D73569C, 32, NDPI_PROTOCOL_TOR }, + { 0x5D735EF3, 32, NDPI_PROTOCOL_TOR }, + { 0x5D735EF4, 32, NDPI_PROTOCOL_TOR }, + { 0x5D73F102, 32, NDPI_PROTOCOL_TOR }, + { 0x5D760C01, 32, NDPI_PROTOCOL_TOR }, + { 0x5D7C3305, 32, NDPI_PROTOCOL_TOR }, + { 0x5D7E65DF, 32, NDPI_PROTOCOL_TOR }, + { 0x5D804CF1, 32, NDPI_PROTOCOL_TOR }, + { 0x5D81945A, 32, NDPI_PROTOCOL_TOR }, + { 0x5D8456CA, 32, NDPI_PROTOCOL_TOR }, + { 0x5D84AC51, 32, NDPI_PROTOCOL_TOR }, + { 0x5D867771, 32, NDPI_PROTOCOL_TOR }, + { 0x5D8712F4, 32, NDPI_PROTOCOL_TOR }, + { 0x5D8BDD63, 32, NDPI_PROTOCOL_TOR }, + { 0x5D98C554, 32, NDPI_PROTOCOL_TOR }, + { 0x5D9C28A3, 32, NDPI_PROTOCOL_TOR }, + { 0x5D9C4AEF, 32, NDPI_PROTOCOL_TOR }, + { 0x5DA33850, 32, NDPI_PROTOCOL_TOR }, + { 0x5DA7F5B2, 32, NDPI_PROTOCOL_TOR }, + { 0x5DAE5A1E, 32, NDPI_PROTOCOL_TOR }, + { 0x5DAE5D15, 32, NDPI_PROTOCOL_TOR }, + { 0x5DAE5D3F, 32, NDPI_PROTOCOL_TOR }, + { 0x5DAF0C52, 32, NDPI_PROTOCOL_TOR }, + { 0x5DB49A5E, 32, NDPI_PROTOCOL_TOR }, + { 0x5DB49C54, 32, NDPI_PROTOCOL_TOR }, + { 0x5DB49C63, 32, NDPI_PROTOCOL_TOR }, + { 0x5DB49D28, 32, NDPI_PROTOCOL_TOR }, + { 0x5DB49D9A, 32, NDPI_PROTOCOL_TOR }, + { 0x5DB81566, 32, NDPI_PROTOCOL_TOR }, + { 0x5DB842E3, 32, NDPI_PROTOCOL_TOR }, + { 0x5DB9654C, 32, NDPI_PROTOCOL_TOR }, + { 0x5DB965AC, 32, NDPI_PROTOCOL_TOR }, + { 0x5DB96DBF, 32, NDPI_PROTOCOL_TOR }, + { 0x5DBAC8D5, 32, NDPI_PROTOCOL_TOR }, + { 0x5DBCA2EB, 32, NDPI_PROTOCOL_TOR }, + { 0x5DBF0D22, 32, NDPI_PROTOCOL_TOR }, + { 0x5DC06F39, 32, NDPI_PROTOCOL_TOR }, + { 0x5DC0AAC8, 32, NDPI_PROTOCOL_TOR }, + { 0x5DC0CA0C, 32, NDPI_PROTOCOL_TOR }, + { 0x5DC16D99, 32, NDPI_PROTOCOL_TOR }, + { 0x5DC2904C, 32, NDPI_PROTOCOL_TOR }, + { 0x5DC5E303, 32, NDPI_PROTOCOL_TOR }, + { 0x5DC5F098, 32, NDPI_PROTOCOL_TOR }, + { 0x5DC8C66B, 32, NDPI_PROTOCOL_TOR }, + { 0x5DCBFB93, 32, NDPI_PROTOCOL_TOR }, + { 0x5DCD0C3A, 32, NDPI_PROTOCOL_TOR }, + { 0x5DCF14E7, 32, NDPI_PROTOCOL_TOR }, + { 0x5DCF46AC, 32, NDPI_PROTOCOL_TOR }, + { 0x5DD3F085, 32, NDPI_PROTOCOL_TOR }, + { 0x5DD47CEB, 32, NDPI_PROTOCOL_TOR }, + { 0x5DD71649, 32, NDPI_PROTOCOL_TOR }, + { 0x5DD740AF, 32, NDPI_PROTOCOL_TOR }, + { 0x5DDA6C31, 32, NDPI_PROTOCOL_TOR }, + { 0x5DDB7692, 32, NDPI_PROTOCOL_TOR }, + { 0x5DDC0F3B, 32, NDPI_PROTOCOL_TOR }, + { 0x5DDC7449, 32, NDPI_PROTOCOL_TOR }, + { 0x5DDCD36F, 32, NDPI_PROTOCOL_TOR }, + { 0x5DDCEB0C, 32, NDPI_PROTOCOL_TOR }, + { 0x5DDF509D, 32, NDPI_PROTOCOL_TOR }, + { 0x5DDFCC89, 32, NDPI_PROTOCOL_TOR }, + { 0x5DE44D4E, 32, NDPI_PROTOCOL_TOR }, + { 0x5DE62635, 32, NDPI_PROTOCOL_TOR }, + { 0x5DE95360, 32, NDPI_PROTOCOL_TOR }, + { 0x5E05D57B, 32, NDPI_PROTOCOL_TOR }, + { 0x5E09C10C, 32, NDPI_PROTOCOL_TOR }, + { 0x5E104BE2, 32, NDPI_PROTOCOL_TOR }, + { 0x5E137BC2, 32, NDPI_PROTOCOL_TOR }, + { 0x5E160545, 32, NDPI_PROTOCOL_TOR }, + { 0x5E168F9E, 32, NDPI_PROTOCOL_TOR }, + { 0x5E16A01D, 32, NDPI_PROTOCOL_TOR }, + { 0x5E170291, 32, NDPI_PROTOCOL_TOR }, + { 0x5E1712A9, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17141C, 32, NDPI_PROTOCOL_TOR }, + { 0x5E1714BE, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17194E, 32, NDPI_PROTOCOL_TOR }, + { 0x5E171E35, 32, NDPI_PROTOCOL_TOR }, + { 0x5E172434, 32, NDPI_PROTOCOL_TOR }, + { 0x5E172599, 32, NDPI_PROTOCOL_TOR }, + { 0x5E1730BA, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17360C, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17381F, 32, NDPI_PROTOCOL_TOR }, + { 0x5E1746DE, 32, NDPI_PROTOCOL_TOR }, + { 0x5E175892, 32, NDPI_PROTOCOL_TOR }, + { 0x5E176919, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17A2E3, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17AB60, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17C221, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17C636, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17CCAF, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17D0BC, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17D2A3, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17ECBB, 32, NDPI_PROTOCOL_TOR }, + { 0x5E17FC1F, 32, NDPI_PROTOCOL_TOR }, + { 0x5E188C4A, 32, NDPI_PROTOCOL_TOR }, + { 0x5E22964B, 32, NDPI_PROTOCOL_TOR }, + { 0x5E29C2EE, 32, NDPI_PROTOCOL_TOR }, + { 0x5E2D3BF0, 32, NDPI_PROTOCOL_TOR }, + { 0x5E33CEA8, 32, NDPI_PROTOCOL_TOR }, + { 0x5E46889C, 32, NDPI_PROTOCOL_TOR }, + { 0x5E4BCF64, 32, NDPI_PROTOCOL_TOR }, + { 0x5E4F89B6, 32, NDPI_PROTOCOL_TOR }, + { 0x5E4FB906, 32, NDPI_PROTOCOL_TOR }, + { 0x5E6412A2, 32, NDPI_PROTOCOL_TOR }, + { 0x5E6635B1, 32, NDPI_PROTOCOL_TOR }, + { 0x5E663CAC, 32, NDPI_PROTOCOL_TOR }, + { 0x5E67AF55, 32, NDPI_PROTOCOL_TOR }, + { 0x5E716902, 32, NDPI_PROTOCOL_TOR }, + { 0x5E71E6DD, 32, NDPI_PROTOCOL_TOR }, + { 0x5E7CF603, 32, NDPI_PROTOCOL_TOR }, + { 0x5E7EB201, 32, NDPI_PROTOCOL_TOR }, + { 0x5E878697, 32, NDPI_PROTOCOL_TOR }, + { 0x5E88612A, 32, NDPI_PROTOCOL_TOR }, + { 0x5E8DACF0, 32, NDPI_PROTOCOL_TOR }, + { 0x5E8EF18A, 32, NDPI_PROTOCOL_TOR }, + { 0x5E8EF1F1, 32, NDPI_PROTOCOL_TOR }, + { 0x5E8EF21E, 32, NDPI_PROTOCOL_TOR }, + { 0x5E8EF5CE, 32, NDPI_PROTOCOL_TOR }, + { 0x5E8EF5E7, 32, NDPI_PROTOCOL_TOR }, + { 0x5E9B5D2D, 32, NDPI_PROTOCOL_TOR }, + { 0x5E9ED927, 32, NDPI_PROTOCOL_TOR }, + { 0x5E9FCE6E, 32, NDPI_PROTOCOL_TOR }, + { 0x5E9FDCF2, 32, NDPI_PROTOCOL_TOR }, + { 0x5EAE9EF4, 32, NDPI_PROTOCOL_TOR }, + { 0x5EB4D2CA, 32, NDPI_PROTOCOL_TOR }, + { 0x5EB4D8D9, 32, NDPI_PROTOCOL_TOR }, + { 0x5EB4E868, 32, NDPI_PROTOCOL_TOR }, + { 0x5EB51414, 32, NDPI_PROTOCOL_TOR }, + { 0x5EB95202, 32, NDPI_PROTOCOL_TOR }, + { 0x5EBC1C88, 32, NDPI_PROTOCOL_TOR }, + { 0x5EBC39EC, 32, NDPI_PROTOCOL_TOR }, + { 0x5EBEE03A, 32, NDPI_PROTOCOL_TOR }, + { 0x5EC6440D, 32, NDPI_PROTOCOL_TOR }, + { 0x5EC66247, 32, NDPI_PROTOCOL_TOR }, + { 0x5EC66411, 32, NDPI_PROTOCOL_TOR }, + { 0x5EC73365, 32, NDPI_PROTOCOL_TOR }, + { 0x5ED0E3DD, 32, NDPI_PROTOCOL_TOR }, + { 0x5ED2001C, 32, NDPI_PROTOCOL_TOR }, + { 0x5ED2BE2C, 32, NDPI_PROTOCOL_TOR }, + { 0x5ED3C0CA, 32, NDPI_PROTOCOL_TOR }, + { 0x5ED61659, 32, NDPI_PROTOCOL_TOR }, + { 0x5ED6179F, 32, NDPI_PROTOCOL_TOR }, + { 0x5ED9C67E, 32, NDPI_PROTOCOL_TOR }, + { 0x5ED9FE19, 32, NDPI_PROTOCOL_TOR }, + { 0x5EDA142C, 32, NDPI_PROTOCOL_TOR }, + { 0x5EDC49D6, 32, NDPI_PROTOCOL_TOR }, + { 0x5EDD6472, 32, NDPI_PROTOCOL_TOR }, + { 0x5EDD9651, 32, NDPI_PROTOCOL_TOR }, + { 0x5EE19A57, 32, NDPI_PROTOCOL_TOR }, + { 0x5EE4560B, 32, NDPI_PROTOCOL_TOR }, + { 0x5EE4DEC0, 32, NDPI_PROTOCOL_TOR }, + { 0x5EE6CB1F, 32, NDPI_PROTOCOL_TOR }, + { 0x5EE72228, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF23915, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF23926, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF239A4, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF239A9, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF239C4, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF239D4, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF23A46, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2C6A4, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2CC84, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2D178, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2D1F4, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2DE1B, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2DED7, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2F342, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2F3A2, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2F617, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2F618, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2FB70, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2FC29, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2FE51, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2FE51, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF2FEBF, 32, NDPI_PROTOCOL_TOR }, + { 0x5EF72982, 32, NDPI_PROTOCOL_TOR }, + { 0x5EFD0E62, 32, NDPI_PROTOCOL_TOR }, + { 0x5EFD4CD2, 32, NDPI_PROTOCOL_TOR }, + { 0x5EFE1877, 32, NDPI_PROTOCOL_TOR }, + { 0x5EFE30C2, 32, NDPI_PROTOCOL_TOR }, + { 0x5F122587, 32, NDPI_PROTOCOL_TOR }, + { 0x5F17F611, 32, NDPI_PROTOCOL_TOR }, + { 0x5F182884, 32, NDPI_PROTOCOL_TOR }, + { 0x5F1931B0, 32, NDPI_PROTOCOL_TOR }, + { 0x5F1BE179, 32, NDPI_PROTOCOL_TOR }, + { 0x5F1C5963, 32, NDPI_PROTOCOL_TOR }, + { 0x5F1EAD45, 32, NDPI_PROTOCOL_TOR }, + { 0x5F1F1B6C, 32, NDPI_PROTOCOL_TOR }, + { 0x5F1F2E02, 32, NDPI_PROTOCOL_TOR }, + { 0x5F25A84D, 32, NDPI_PROTOCOL_TOR }, + { 0x5F40CB0E, 32, NDPI_PROTOCOL_TOR }, + { 0x5F477EE6, 32, NDPI_PROTOCOL_TOR }, + { 0x5F480939, 32, NDPI_PROTOCOL_TOR }, + { 0x5F4892AD, 32, NDPI_PROTOCOL_TOR }, + { 0x5F491AE8, 32, NDPI_PROTOCOL_TOR }, + { 0x5F4931BA, 32, NDPI_PROTOCOL_TOR }, + { 0x5F49EB59, 32, NDPI_PROTOCOL_TOR }, + { 0x5F4D914B, 32, NDPI_PROTOCOL_TOR }, + { 0x5F4E3856, 32, NDPI_PROTOCOL_TOR }, + { 0x5F4F19B6, 32, NDPI_PROTOCOL_TOR }, + { 0x5F4F605F, 32, NDPI_PROTOCOL_TOR }, + { 0x5F4F89F8, 32, NDPI_PROTOCOL_TOR }, + { 0x5F500A2E, 32, NDPI_PROTOCOL_TOR }, + { 0x5F52F5EA, 32, NDPI_PROTOCOL_TOR }, + { 0x5F549049, 32, NDPI_PROTOCOL_TOR }, + { 0x5F5494AD, 32, NDPI_PROTOCOL_TOR }, + { 0x5F54C634, 32, NDPI_PROTOCOL_TOR }, + { 0x5F54C806, 32, NDPI_PROTOCOL_TOR }, + { 0x5F54D17E, 32, NDPI_PROTOCOL_TOR }, + { 0x5F550367, 32, NDPI_PROTOCOL_TOR }, + { 0x5F5503BF, 32, NDPI_PROTOCOL_TOR }, + { 0x5F5505D3, 32, NDPI_PROTOCOL_TOR }, + { 0x5F55075A, 32, NDPI_PROTOCOL_TOR }, + { 0x5F5508E2, 32, NDPI_PROTOCOL_TOR }, + { 0x5F550A47, 32, NDPI_PROTOCOL_TOR }, + { 0x5F550E4F, 32, NDPI_PROTOCOL_TOR }, + { 0x5F551449, 32, NDPI_PROTOCOL_TOR }, + { 0x5F55150E, 32, NDPI_PROTOCOL_TOR }, + { 0x5F5517BD, 32, NDPI_PROTOCOL_TOR }, + { 0x5F552522, 32, NDPI_PROTOCOL_TOR }, + { 0x5F55256F, 32, NDPI_PROTOCOL_TOR }, + { 0x5F552673, 32, NDPI_PROTOCOL_TOR }, + { 0x5F55271C, 32, NDPI_PROTOCOL_TOR }, + { 0x5F552A24, 32, NDPI_PROTOCOL_TOR }, + { 0x5F553605, 32, NDPI_PROTOCOL_TOR }, + { 0x5F553C17, 32, NDPI_PROTOCOL_TOR }, + { 0x5F594A54, 32, NDPI_PROTOCOL_TOR }, + { 0x5F599862, 32, NDPI_PROTOCOL_TOR }, + { 0x5F5A0C37, 32, NDPI_PROTOCOL_TOR }, + { 0x5F5B83B6, 32, NDPI_PROTOCOL_TOR }, + { 0x5F61A0CC, 32, NDPI_PROTOCOL_TOR }, + { 0x5F69A188, 32, NDPI_PROTOCOL_TOR }, + { 0x5F6A1BC6, 32, NDPI_PROTOCOL_TOR }, + { 0x5F6D7A90, 32, NDPI_PROTOCOL_TOR }, + { 0x5F7008D0, 32, NDPI_PROTOCOL_TOR }, + { 0x5F71E203, 32, NDPI_PROTOCOL_TOR }, + { 0x5F72385D, 32, NDPI_PROTOCOL_TOR }, + { 0x5F741FDB, 32, NDPI_PROTOCOL_TOR }, + { 0x5F76808A, 32, NDPI_PROTOCOL_TOR }, + { 0x5F802BA4, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8137AD, 32, NDPI_PROTOCOL_TOR }, + { 0x5F81CD53, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820959, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820959, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820979, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8209BE, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820A0F, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820B05, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820B0F, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820B2A, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820B2E, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820B93, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820BA2, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820BAA, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820BD6, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820C2F, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820C77, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820F60, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820F61, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820FFB, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820FFC, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820FFD, 32, NDPI_PROTOCOL_TOR }, + { 0x5F820FFE, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8387B3, 32, NDPI_PROTOCOL_TOR }, + { 0x5F83EA02, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8429AB, 32, NDPI_PROTOCOL_TOR }, + { 0x5F843460, 32, NDPI_PROTOCOL_TOR }, + { 0x5F851927, 32, NDPI_PROTOCOL_TOR }, + { 0x5F872D77, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8BE024, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8C2AB7, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8D5392, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8DE895, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8EA13F, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8EAD12, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8FACD4, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8FACD6, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8FACF4, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8FC191, 32, NDPI_PROTOCOL_TOR }, + { 0x5F8FE1C6, 32, NDPI_PROTOCOL_TOR }, + { 0x5F91E0D0, 32, NDPI_PROTOCOL_TOR }, + { 0x5F9A1849, 32, NDPI_PROTOCOL_TOR }, + { 0x5F9A58FC, 32, NDPI_PROTOCOL_TOR }, + { 0x5F9A6A86, 32, NDPI_PROTOCOL_TOR }, + { 0x5F9D0C83, 32, NDPI_PROTOCOL_TOR }, + { 0x5FA01056, 32, NDPI_PROTOCOL_TOR }, + { 0x5FA9BC67, 32, NDPI_PROTOCOL_TOR }, + { 0x5FAAB5D0, 32, NDPI_PROTOCOL_TOR }, + { 0x5FACEC76, 32, NDPI_PROTOCOL_TOR }, + { 0x5FAEE547, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD3079E, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD31B0A, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD349ED, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD3629F, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD38811, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD38A1B, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD3A923, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD3CD97, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD3D865, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD3DE93, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD3E1A7, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD3E408, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD3E59E, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD3E781, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD3F153, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD701B5, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72C66, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72C69, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72C6E, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72C6F, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72C7A, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72C91, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72CBA, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72CBB, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72CBD, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72CC2, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72CE8, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72CF9, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72D2F, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72D41, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72D44, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72D80, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72D8E, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72DBC, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72DC3, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72DC5, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72E24, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72E54, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72E5A, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72E67, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72E7B, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72E96, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72EF4, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72F75, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72F80, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72F8B, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72F96, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72FB1, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72FBB, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72FC7, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72FCE, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72FD8, 32, NDPI_PROTOCOL_TOR }, + { 0x5FD72FF2, 32, NDPI_PROTOCOL_TOR }, + { 0x5FDC69CA, 32, NDPI_PROTOCOL_TOR }, + { 0x5FDC822D, 32, NDPI_PROTOCOL_TOR }, + { 0x5FDE9C03, 32, NDPI_PROTOCOL_TOR }, + { 0x5FDE9C04, 32, NDPI_PROTOCOL_TOR }, + { 0x5FDEE336, 32, NDPI_PROTOCOL_TOR }, + { 0x5FDFD887, 32, NDPI_PROTOCOL_TOR }, + { 0x5FEEE099, 32, NDPI_PROTOCOL_TOR }, + { 0x5FEFE676, 32, NDPI_PROTOCOL_TOR }, + { 0x601390C6, 32, NDPI_PROTOCOL_TOR }, + { 0x601CBD5E, 32, NDPI_PROTOCOL_TOR }, + { 0x601F430F, 32, NDPI_PROTOCOL_TOR }, + { 0x60210687, 32, NDPI_PROTOCOL_TOR }, + { 0x60238283, 32, NDPI_PROTOCOL_TOR }, + { 0x60253C3F, 32, NDPI_PROTOCOL_TOR }, + { 0x6028292D, 32, NDPI_PROTOCOL_TOR }, + { 0x60290DA2, 32, NDPI_PROTOCOL_TOR }, + { 0x6029718C, 32, NDPI_PROTOCOL_TOR }, + { 0x602A211B, 32, NDPI_PROTOCOL_TOR }, + { 0x602CBD64, 32, NDPI_PROTOCOL_TOR }, + { 0x602CBD65, 32, NDPI_PROTOCOL_TOR }, + { 0x602CBD66, 32, NDPI_PROTOCOL_TOR }, + { 0x602F411A, 32, NDPI_PROTOCOL_TOR }, + { 0x602FE214, 32, NDPI_PROTOCOL_TOR }, + { 0x602FE215, 32, NDPI_PROTOCOL_TOR }, + { 0x602FE216, 32, NDPI_PROTOCOL_TOR }, + { 0x602FEC7E, 32, NDPI_PROTOCOL_TOR }, + { 0x60303837, 32, NDPI_PROTOCOL_TOR }, + { 0x60341169, 32, NDPI_PROTOCOL_TOR }, + { 0x60362A0F, 32, NDPI_PROTOCOL_TOR }, + { 0x607E6009, 32, NDPI_PROTOCOL_TOR }, + { 0x607E605A, 32, NDPI_PROTOCOL_TOR }, + { 0x607E6688, 32, NDPI_PROTOCOL_TOR }, + { 0x607E69DB, 32, NDPI_PROTOCOL_TOR }, + { 0x607E6E3C, 32, NDPI_PROTOCOL_TOR }, + { 0x607E6E3C, 32, NDPI_PROTOCOL_TOR }, + { 0x607E76E3, 32, NDPI_PROTOCOL_TOR }, + { 0x607E7AA6, 32, NDPI_PROTOCOL_TOR }, + { 0x607E7F58, 32, NDPI_PROTOCOL_TOR }, + { 0x60E26D05, 32, NDPI_PROTOCOL_TOR }, + { 0x60E29C48, 32, NDPI_PROTOCOL_TOR }, + { 0x60E53297, 32, NDPI_PROTOCOL_TOR }, + { 0x60E6398D, 32, NDPI_PROTOCOL_TOR }, + { 0x60E85742, 32, NDPI_PROTOCOL_TOR }, + { 0x60E932CF, 32, NDPI_PROTOCOL_TOR }, + { 0x60EE056F, 32, NDPI_PROTOCOL_TOR }, + { 0x60EE23B4, 32, NDPI_PROTOCOL_TOR }, + { 0x60F19A42, 32, NDPI_PROTOCOL_TOR }, + { 0x60FA5604, 32, NDPI_PROTOCOL_TOR }, + { 0x60FD4E6B, 32, NDPI_PROTOCOL_TOR }, + { 0x60FF47C9, 32, NDPI_PROTOCOL_TOR }, + { 0x6155B286, 32, NDPI_PROTOCOL_TOR }, + { 0x61570E0F, 32, NDPI_PROTOCOL_TOR }, + { 0x61573D40, 32, NDPI_PROTOCOL_TOR }, + { 0x615D1FB9, 32, NDPI_PROTOCOL_TOR }, + { 0x615F20B2, 32, NDPI_PROTOCOL_TOR }, + { 0x61664AC2, 32, NDPI_PROTOCOL_TOR }, + { 0x61664F0E, 32, NDPI_PROTOCOL_TOR }, + { 0x616B8418, 32, NDPI_PROTOCOL_TOR }, + { 0x616B867F, 32, NDPI_PROTOCOL_TOR }, + { 0x616B8A44, 32, NDPI_PROTOCOL_TOR }, + { 0x616B8B1C, 32, NDPI_PROTOCOL_TOR }, + { 0x616B8B6C, 32, NDPI_PROTOCOL_TOR }, + { 0x616B8E85, 32, NDPI_PROTOCOL_TOR }, + { 0x616B8EDA, 32, NDPI_PROTOCOL_TOR }, + { 0x616B8EEA, 32, NDPI_PROTOCOL_TOR }, + { 0x61761E24, 32, NDPI_PROTOCOL_TOR }, + { 0x62181813, 32, NDPI_PROTOCOL_TOR }, + { 0x62185496, 32, NDPI_PROTOCOL_TOR }, + { 0x621CA618, 32, NDPI_PROTOCOL_TOR }, + { 0x621CF5EC, 32, NDPI_PROTOCOL_TOR }, + { 0x6241C4D2, 32, NDPI_PROTOCOL_TOR }, + { 0x6245AA0A, 32, NDPI_PROTOCOL_TOR }, + { 0x626538B2, 32, NDPI_PROTOCOL_TOR }, + { 0x626D3882, 32, NDPI_PROTOCOL_TOR }, + { 0x626D7511, 32, NDPI_PROTOCOL_TOR }, + { 0x62726199, 32, NDPI_PROTOCOL_TOR }, + { 0x6274DF81, 32, NDPI_PROTOCOL_TOR }, + { 0x627C74C6, 32, NDPI_PROTOCOL_TOR }, + { 0x628E2F36, 32, NDPI_PROTOCOL_TOR }, + { 0x6296DFDD, 32, NDPI_PROTOCOL_TOR }, + { 0x629B1EED, 32, NDPI_PROTOCOL_TOR }, + { 0x629D1940, 32, NDPI_PROTOCOL_TOR }, + { 0x629D41CC, 32, NDPI_PROTOCOL_TOR }, + { 0x62B436C1, 32, NDPI_PROTOCOL_TOR }, + { 0x62B790F7, 32, NDPI_PROTOCOL_TOR }, + { 0x62C1C54A, 32, NDPI_PROTOCOL_TOR }, + { 0x62C774D0, 32, NDPI_PROTOCOL_TOR }, + { 0x62C925BF, 32, NDPI_PROTOCOL_TOR }, + { 0x62C99217, 32, NDPI_PROTOCOL_TOR }, + { 0x62CEB470, 32, NDPI_PROTOCOL_TOR }, + { 0x62CEB64E, 32, NDPI_PROTOCOL_TOR }, + { 0x62D2A4C6, 32, NDPI_PROTOCOL_TOR }, + { 0x62D6F355, 32, NDPI_PROTOCOL_TOR }, + { 0x62D8A86C, 32, NDPI_PROTOCOL_TOR }, + { 0x62D99D4C, 32, NDPI_PROTOCOL_TOR }, + { 0x62DA3282, 32, NDPI_PROTOCOL_TOR }, + { 0x62DA372F, 32, NDPI_PROTOCOL_TOR }, + { 0x62E0DAEE, 32, NDPI_PROTOCOL_TOR }, + { 0x62E7895E, 32, NDPI_PROTOCOL_TOR }, + { 0x62E818A7, 32, NDPI_PROTOCOL_TOR }, + { 0x62EC4BEC, 32, NDPI_PROTOCOL_TOR }, + { 0x62F5A7CC, 32, NDPI_PROTOCOL_TOR }, + { 0x62F62CE0, 32, NDPI_PROTOCOL_TOR }, + { 0x62F81DE9, 32, NDPI_PROTOCOL_TOR }, + { 0x62FC8D6B, 32, NDPI_PROTOCOL_TOR }, + { 0x62FFC9AB, 32, NDPI_PROTOCOL_TOR }, + { 0x630615BE, 32, NDPI_PROTOCOL_TOR }, + { 0x633F1919, 32, NDPI_PROTOCOL_TOR }, + { 0x635AD476, 32, NDPI_PROTOCOL_TOR }, + { 0x635F8924, 32, NDPI_PROTOCOL_TOR }, + { 0x6363E834, 32, NDPI_PROTOCOL_TOR }, + { 0x6366B2AD, 32, NDPI_PROTOCOL_TOR }, + { 0x63E1049C, 32, NDPI_PROTOCOL_TOR }, + { 0x63E4AB0B, 32, NDPI_PROTOCOL_TOR }, + { 0x63EA2BA0, 32, NDPI_PROTOCOL_TOR }, + { 0x6424B8E6, 32, NDPI_PROTOCOL_TOR }, + { 0x6425681C, 32, NDPI_PROTOCOL_TOR }, + { 0x65339B42, 32, NDPI_PROTOCOL_TOR }, + { 0x6562AEE2, 32, NDPI_PROTOCOL_TOR }, + { 0x65634096, 32, NDPI_PROTOCOL_TOR }, + { 0x658CD912, 32, NDPI_PROTOCOL_TOR }, + { 0x658EC26D, 32, NDPI_PROTOCOL_TOR }, + { 0x65B090B8, 32, NDPI_PROTOCOL_TOR }, + { 0x65BB0480, 32, NDPI_PROTOCOL_TOR }, + { 0x6706D5C6, 32, NDPI_PROTOCOL_TOR }, + { 0x670AC532, 32, NDPI_PROTOCOL_TOR }, + { 0x670AC764, 32, NDPI_PROTOCOL_TOR }, + { 0x67101A47, 32, NDPI_PROTOCOL_TOR }, + { 0x67193810, 32, NDPI_PROTOCOL_TOR }, + { 0x67298435, 32, NDPI_PROTOCOL_TOR }, + { 0x67F05B07, 32, NDPI_PROTOCOL_TOR }, + { 0x67FAB895, 32, NDPI_PROTOCOL_TOR }, + { 0x68091CA1, 32, NDPI_PROTOCOL_TOR }, + { 0x6820195D, 32, NDPI_PROTOCOL_TOR }, + { 0x68218AAE, 32, NDPI_PROTOCOL_TOR }, + { 0x6828018F, 32, NDPI_PROTOCOL_TOR }, + { 0x68288AA6, 32, NDPI_PROTOCOL_TOR }, + { 0x6829028B, 32, NDPI_PROTOCOL_TOR }, + { 0x68311642, 32, NDPI_PROTOCOL_TOR }, + { 0x68804E6B, 32, NDPI_PROTOCOL_TOR }, + { 0x68804E6B, 32, NDPI_PROTOCOL_TOR }, + { 0x68804E6C, 32, NDPI_PROTOCOL_TOR }, + { 0x68804E6C, 32, NDPI_PROTOCOL_TOR }, + { 0x6880AB3E, 32, NDPI_PROTOCOL_TOR }, + { 0x6880E1CB, 32, NDPI_PROTOCOL_TOR }, + { 0x68821999, 32, NDPI_PROTOCOL_TOR }, + { 0x68830974, 32, NDPI_PROTOCOL_TOR }, + { 0x68830C8B, 32, NDPI_PROTOCOL_TOR }, + { 0x68830EAF, 32, NDPI_PROTOCOL_TOR }, + { 0x68831377, 32, NDPI_PROTOCOL_TOR }, + { 0x68831C36, 32, NDPI_PROTOCOL_TOR }, + { 0x68831E06, 32, NDPI_PROTOCOL_TOR }, + { 0x688322AA, 32, NDPI_PROTOCOL_TOR }, + { 0x688322AC, 32, NDPI_PROTOCOL_TOR }, + { 0x68832D66, 32, NDPI_PROTOCOL_TOR }, + { 0x6883335D, 32, NDPI_PROTOCOL_TOR }, + { 0x6883378D, 32, NDPI_PROTOCOL_TOR }, + { 0x688337B8, 32, NDPI_PROTOCOL_TOR }, + { 0x6883387F, 32, NDPI_PROTOCOL_TOR }, + { 0x68833A42, 32, NDPI_PROTOCOL_TOR }, + { 0x68833F50, 32, NDPI_PROTOCOL_TOR }, + { 0x68833F8F, 32, NDPI_PROTOCOL_TOR }, + { 0x688341E1, 32, NDPI_PROTOCOL_TOR }, + { 0x688342C2, 32, NDPI_PROTOCOL_TOR }, + { 0x68834956, 32, NDPI_PROTOCOL_TOR }, + { 0x68834ACF, 32, NDPI_PROTOCOL_TOR }, + { 0x68835F18, 32, NDPI_PROTOCOL_TOR }, + { 0x68836C07, 32, NDPI_PROTOCOL_TOR }, + { 0x68836ED5, 32, NDPI_PROTOCOL_TOR }, + { 0x6883722B, 32, NDPI_PROTOCOL_TOR }, + { 0x68837248, 32, NDPI_PROTOCOL_TOR }, + { 0x688375E7, 32, NDPI_PROTOCOL_TOR }, + { 0x68837B10, 32, NDPI_PROTOCOL_TOR }, + { 0x68837D54, 32, NDPI_PROTOCOL_TOR }, + { 0x6883811E, 32, NDPI_PROTOCOL_TOR }, + { 0x68838182, 32, NDPI_PROTOCOL_TOR }, + { 0x6883862F, 32, NDPI_PROTOCOL_TOR }, + { 0x68839A74, 32, NDPI_PROTOCOL_TOR }, + { 0x6883A6F3, 32, NDPI_PROTOCOL_TOR }, + { 0x6883AC2E, 32, NDPI_PROTOCOL_TOR }, + { 0x6883B5AE, 32, NDPI_PROTOCOL_TOR }, + { 0x6883CC93, 32, NDPI_PROTOCOL_TOR }, + { 0x6883CE17, 32, NDPI_PROTOCOL_TOR }, + { 0x6883D523, 32, NDPI_PROTOCOL_TOR }, + { 0x6883E7F1, 32, NDPI_PROTOCOL_TOR }, + { 0x6883F0A8, 32, NDPI_PROTOCOL_TOR }, + { 0x6883F537, 32, NDPI_PROTOCOL_TOR }, + { 0x689C39C7, 32, NDPI_PROTOCOL_TOR }, + { 0x689C6F36, 32, NDPI_PROTOCOL_TOR }, + { 0x689CE01C, 32, NDPI_PROTOCOL_TOR }, + { 0x689CE053, 32, NDPI_PROTOCOL_TOR }, + { 0x689CEE74, 32, NDPI_PROTOCOL_TOR }, + { 0x689CFD47, 32, NDPI_PROTOCOL_TOR }, + { 0x68A2167C, 32, NDPI_PROTOCOL_TOR }, + { 0x68A762FD, 32, NDPI_PROTOCOL_TOR }, + { 0x68A76304, 32, NDPI_PROTOCOL_TOR }, + { 0x68A7630C, 32, NDPI_PROTOCOL_TOR }, + { 0x68A76458, 32, NDPI_PROTOCOL_TOR }, + { 0x68A764A8, 32, NDPI_PROTOCOL_TOR }, + { 0x68A766F4, 32, NDPI_PROTOCOL_TOR }, + { 0x68A76734, 32, NDPI_PROTOCOL_TOR }, + { 0x68A7695C, 32, NDPI_PROTOCOL_TOR }, + { 0x68A76A2D, 32, NDPI_PROTOCOL_TOR }, + { 0x68A76B8E, 32, NDPI_PROTOCOL_TOR }, + { 0x68A823A8, 32, NDPI_PROTOCOL_TOR }, + { 0x68AE61BA, 32, NDPI_PROTOCOL_TOR }, + { 0x68C81056, 32, NDPI_PROTOCOL_TOR }, + { 0x68C81056, 32, NDPI_PROTOCOL_TOR }, + { 0x68C812B6, 32, NDPI_PROTOCOL_TOR }, + { 0x68C812B6, 32, NDPI_PROTOCOL_TOR }, + { 0x68C8148E, 32, NDPI_PROTOCOL_TOR }, + { 0x68C81841, 32, NDPI_PROTOCOL_TOR }, + { 0x68CEC114, 32, NDPI_PROTOCOL_TOR }, + { 0x68CF802A, 32, NDPI_PROTOCOL_TOR }, + { 0x68CF846D, 32, NDPI_PROTOCOL_TOR }, + { 0x68CF84C9, 32, NDPI_PROTOCOL_TOR }, + { 0x68CF92C8, 32, NDPI_PROTOCOL_TOR }, + { 0x68CF940C, 32, NDPI_PROTOCOL_TOR }, + { 0x68DBB8A6, 32, NDPI_PROTOCOL_TOR }, + { 0x68DD4C83, 32, NDPI_PROTOCOL_TOR }, + { 0x68E0AF68, 32, NDPI_PROTOCOL_TOR }, + { 0x68E80163, 32, NDPI_PROTOCOL_TOR }, + { 0x68E80321, 32, NDPI_PROTOCOL_TOR }, + { 0x68E80323, 32, NDPI_PROTOCOL_TOR }, + { 0x68EADC47, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC0067, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC0658, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC084A, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC1197, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC191C, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC239C, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC26E7, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC27DB, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC2CD2, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC323E, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC3672, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC5353, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC5629, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC575A, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC5DE1, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC6452, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC6E0D, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC8E5D, 32, NDPI_PROTOCOL_TOR }, + { 0x68EC95F9, 32, NDPI_PROTOCOL_TOR }, + { 0x68ECAE0E, 32, NDPI_PROTOCOL_TOR }, + { 0x68ECB3DA, 32, NDPI_PROTOCOL_TOR }, + { 0x68ECB3F0, 32, NDPI_PROTOCOL_TOR }, + { 0x68ECB847, 32, NDPI_PROTOCOL_TOR }, + { 0x68ECD5C1, 32, NDPI_PROTOCOL_TOR }, + { 0x68ECE860, 32, NDPI_PROTOCOL_TOR }, + { 0x68ECFDEC, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED8054, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED8134, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED8134, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED814E, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED818E, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED818E, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED834B, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED834B, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED836B, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED8D6D, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED8DC1, 32, NDPI_PROTOCOL_TOR }, + { 0x68ED98C3, 32, NDPI_PROTOCOL_TOR }, + { 0x68F44B5B, 32, NDPI_PROTOCOL_TOR }, + { 0x68F4DFCC, 32, NDPI_PROTOCOL_TOR }, + { 0x68F5274A, 32, NDPI_PROTOCOL_TOR }, + { 0x68FBD208, 32, NDPI_PROTOCOL_TOR }, + { 0x699551A4, 32, NDPI_PROTOCOL_TOR }, + { 0x699AB5D4, 32, NDPI_PROTOCOL_TOR }, + { 0x69EDDE72, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB91C19, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB91C71, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB91C71, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB91CAA, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB91D5D, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB91EEE, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB91F81, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB91F81, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB92697, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB9273A, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB9273A, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB930D6, 32, NDPI_PROTOCOL_TOR }, + { 0x6AB930D6, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA109A, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA1228, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA12F2, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA1892, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA18FE, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA1C21, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA1D04, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA1D2A, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA1E34, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA7229, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA7541, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABA7541, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB23EC, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB24B7, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB259E, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB259E, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB26C6, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB2974, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB2B6E, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB2D9C, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB2F11, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB3444, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB37EF, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB5EFE, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB5EFE, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB60FA, 32, NDPI_PROTOCOL_TOR }, + { 0x6ABB6773, 32, NDPI_PROTOCOL_TOR }, + { 0x6B021E0D, 32, NDPI_PROTOCOL_TOR }, + { 0x6B060491, 32, NDPI_PROTOCOL_TOR }, + { 0x6B14B34B, 32, NDPI_PROTOCOL_TOR }, + { 0x6B812529, 32, NDPI_PROTOCOL_TOR }, + { 0x6B9614F1, 32, NDPI_PROTOCOL_TOR }, + { 0x6B961BC8, 32, NDPI_PROTOCOL_TOR }, + { 0x6B961F6B, 32, NDPI_PROTOCOL_TOR }, + { 0x6B962336, 32, NDPI_PROTOCOL_TOR }, + { 0x6B96268A, 32, NDPI_PROTOCOL_TOR }, + { 0x6B9635B2, 32, NDPI_PROTOCOL_TOR }, + { 0x6B96AA3A, 32, NDPI_PROTOCOL_TOR }, + { 0x6B988F3E, 32, NDPI_PROTOCOL_TOR }, + { 0x6B9B748F, 32, NDPI_PROTOCOL_TOR }, + { 0x6B9EFF15, 32, NDPI_PROTOCOL_TOR }, + { 0x6B9EFF15, 32, NDPI_PROTOCOL_TOR }, + { 0x6B9EFF16, 32, NDPI_PROTOCOL_TOR }, + { 0x6B9EFF16, 32, NDPI_PROTOCOL_TOR }, + { 0x6BA150C3, 32, NDPI_PROTOCOL_TOR }, + { 0x6BA151BB, 32, NDPI_PROTOCOL_TOR }, + { 0x6BA151D0, 32, NDPI_PROTOCOL_TOR }, + { 0x6BA154B9, 32, NDPI_PROTOCOL_TOR }, + { 0x6BA19E11, 32, NDPI_PROTOCOL_TOR }, + { 0x6BA1B357, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA2047, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA3234, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA330E, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA41C5, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA4E2A, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA4F93, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA5C89, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA5CED, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA5D0D, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA5D20, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA5D75, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA60EB, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA676F, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA6CDE, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA72CC, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA78D6, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA8F75, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA9607, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA9950, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAA9ED4, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAABC9B, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAAC021, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAAC442, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAACC21, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAAE84B, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAAF57F, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAAF6CC, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAAF721, 32, NDPI_PROTOCOL_TOR }, + { 0x6BAAFBB6, 32, NDPI_PROTOCOL_TOR }, + { 0x6BB5A60B, 32, NDPI_PROTOCOL_TOR }, + { 0x6BB5AE16, 32, NDPI_PROTOCOL_TOR }, + { 0x6BB613F9, 32, NDPI_PROTOCOL_TOR }, + { 0x6BB68374, 32, NDPI_PROTOCOL_TOR }, + { 0x6BB68388, 32, NDPI_PROTOCOL_TOR }, + { 0x6BB683CF, 32, NDPI_PROTOCOL_TOR }, + { 0x6BB683D3, 32, NDPI_PROTOCOL_TOR }, + { 0x6BBF2C9A, 32, NDPI_PROTOCOL_TOR }, + { 0x6BBF2ECC, 32, NDPI_PROTOCOL_TOR }, + { 0x6BBF3FB8, 32, NDPI_PROTOCOL_TOR }, + { 0x6BBF6245, 32, NDPI_PROTOCOL_TOR }, + { 0x6BBF6CCB, 32, NDPI_PROTOCOL_TOR }, + { 0x6BBF7EB8, 32, NDPI_PROTOCOL_TOR }, + { 0x6BC4142E, 32, NDPI_PROTOCOL_TOR }, + { 0x6BCB324B, 32, NDPI_PROTOCOL_TOR }, + { 0x6C009C8F, 32, NDPI_PROTOCOL_TOR }, + { 0x6C00C1EF, 32, NDPI_PROTOCOL_TOR }, + { 0x6C00CFF0, 32, NDPI_PROTOCOL_TOR }, + { 0x6C00DF0E, 32, NDPI_PROTOCOL_TOR }, + { 0x6C071024, 32, NDPI_PROTOCOL_TOR }, + { 0x6C0724B4, 32, NDPI_PROTOCOL_TOR }, + { 0x6C0CB2EB, 32, NDPI_PROTOCOL_TOR }, + { 0x6C0E531F, 32, NDPI_PROTOCOL_TOR }, + { 0x6C137138, 32, NDPI_PROTOCOL_TOR }, + { 0x6C1D6B46, 32, NDPI_PROTOCOL_TOR }, + { 0x6C1D75F5, 32, NDPI_PROTOCOL_TOR }, + { 0x6C1E388E, 32, NDPI_PROTOCOL_TOR }, + { 0x6C1E3970, 32, NDPI_PROTOCOL_TOR }, + { 0x6C1F2805, 32, NDPI_PROTOCOL_TOR }, + { 0x6C1FDC6E, 32, NDPI_PROTOCOL_TOR }, + { 0x6C203114, 32, NDPI_PROTOCOL_TOR }, + { 0x6C2D5D5E, 32, NDPI_PROTOCOL_TOR }, + { 0x6C309E93, 32, NDPI_PROTOCOL_TOR }, + { 0x6C32EBB6, 32, NDPI_PROTOCOL_TOR }, + { 0x6C33B8DC, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3504D1, 32, NDPI_PROTOCOL_TOR }, + { 0x6C35822A, 32, NDPI_PROTOCOL_TOR }, + { 0x6C36A4AF, 32, NDPI_PROTOCOL_TOR }, + { 0x6C38BD9D, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3A90E8, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3B02D0, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3B0BE1, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DA16F, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DA1E3, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DA457, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DA539, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DA646, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DA6C7, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DA7F0, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DA82C, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DB16E, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DB1C3, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DB22E, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DB233, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DB2D8, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DB3D8, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DB691, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DB6EC, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DB91A, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DB988, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DBCB4, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DC563, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DC6A6, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DC6CF, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DC7B0, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DC7CA, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DD0AB, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DD150, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DD27B, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DD35E, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DD466, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DF237, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DFB84, 32, NDPI_PROTOCOL_TOR }, + { 0x6C3DFCED, 32, NDPI_PROTOCOL_TOR }, + { 0x6C45A572, 32, NDPI_PROTOCOL_TOR }, + { 0x6C59AF93, 32, NDPI_PROTOCOL_TOR }, + { 0x6C6FAA05, 32, NDPI_PROTOCOL_TOR }, + { 0x6CA6A1BA, 32, NDPI_PROTOCOL_TOR }, + { 0x6CA6A89E, 32, NDPI_PROTOCOL_TOR }, + { 0x6CA6A8A7, 32, NDPI_PROTOCOL_TOR }, + { 0x6CA8033C, 32, NDPI_PROTOCOL_TOR }, + { 0x6CAA8A76, 32, NDPI_PROTOCOL_TOR }, + { 0x6CB49FFC, 32, NDPI_PROTOCOL_TOR }, + { 0x6CB9E23E, 32, NDPI_PROTOCOL_TOR }, + { 0x6CCC2E0E, 32, NDPI_PROTOCOL_TOR }, + { 0x6CD0E579, 32, NDPI_PROTOCOL_TOR }, + { 0x6CD20668, 32, NDPI_PROTOCOL_TOR }, + { 0x6CF0B68C, 32, NDPI_PROTOCOL_TOR }, + { 0x6CF72296, 32, NDPI_PROTOCOL_TOR }, + { 0x6CF7F4CC, 32, NDPI_PROTOCOL_TOR }, + { 0x6CF857F2, 32, NDPI_PROTOCOL_TOR }, + { 0x6D00AA2D, 32, NDPI_PROTOCOL_TOR }, + { 0x6D00DC98, 32, NDPI_PROTOCOL_TOR }, + { 0x6D163429, 32, NDPI_PROTOCOL_TOR }, + { 0x6D44AE3C, 32, NDPI_PROTOCOL_TOR }, + { 0x6D44BF85, 32, NDPI_PROTOCOL_TOR }, + { 0x6D454311, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4565A5, 32, NDPI_PROTOCOL_TOR }, + { 0x6D49345A, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4A0058, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4A9795, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4AC247, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4AC27C, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4AC3BE, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4AC865, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4ACC77, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4ACE0C, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4ACE15, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4BB84D, 32, NDPI_PROTOCOL_TOR }, + { 0x6D4BBD44, 32, NDPI_PROTOCOL_TOR }, + { 0x6D5A17DD, 32, NDPI_PROTOCOL_TOR }, + { 0x6D5AFAB0, 32, NDPI_PROTOCOL_TOR }, + { 0x6D5B68E8, 32, NDPI_PROTOCOL_TOR }, + { 0x6D5B6C94, 32, NDPI_PROTOCOL_TOR }, + { 0x6D5B7013, 32, NDPI_PROTOCOL_TOR }, + { 0x6D5B7DC3, 32, NDPI_PROTOCOL_TOR }, + { 0x6D5E6002, 32, NDPI_PROTOCOL_TOR }, + { 0x6D5FD279, 32, NDPI_PROTOCOL_TOR }, + { 0x6D5FD442, 32, NDPI_PROTOCOL_TOR }, + { 0x6D646686, 32, NDPI_PROTOCOL_TOR }, + { 0x6D64FC83, 32, NDPI_PROTOCOL_TOR }, + { 0x6D682CD1, 32, NDPI_PROTOCOL_TOR }, + { 0x6D696DA2, 32, NDPI_PROTOCOL_TOR }, + { 0x6D6A38E4, 32, NDPI_PROTOCOL_TOR }, + { 0x6D6B239A, 32, NDPI_PROTOCOL_TOR }, + { 0x6D6CDE14, 32, NDPI_PROTOCOL_TOR }, + { 0x6D6F9E13, 32, NDPI_PROTOCOL_TOR }, + { 0x6D78943C, 32, NDPI_PROTOCOL_TOR }, + { 0x6D78AD30, 32, NDPI_PROTOCOL_TOR }, + { 0x6D78B4F5, 32, NDPI_PROTOCOL_TOR }, + { 0x6D78B611, 32, NDPI_PROTOCOL_TOR }, + { 0x6D824D50, 32, NDPI_PROTOCOL_TOR }, + { 0x6D825345, 32, NDPI_PROTOCOL_TOR }, + { 0x6D984A8C, 32, NDPI_PROTOCOL_TOR }, + { 0x6D9BDAB1, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA1226E, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA3E9A9, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA3EA02, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA3EA04, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA3EA05, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA3EA07, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA3EA08, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA3EA09, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA3EBF6, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA3EBFC, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA4ECE7, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA78802, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA9001D, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA917CA, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA921A3, 32, NDPI_PROTOCOL_TOR }, + { 0x6DA92DE2, 32, NDPI_PROTOCOL_TOR }, + { 0x6DAD3BB4, 32, NDPI_PROTOCOL_TOR }, + { 0x6DB6971F, 32, NDPI_PROTOCOL_TOR }, + { 0x6DBD0643, 32, NDPI_PROTOCOL_TOR }, + { 0x6DBD834C, 32, NDPI_PROTOCOL_TOR }, + { 0x6DBD8F96, 32, NDPI_PROTOCOL_TOR }, + { 0x6DBDB40F, 32, NDPI_PROTOCOL_TOR }, + { 0x6DBE4755, 32, NDPI_PROTOCOL_TOR }, + { 0x6DBE6DE4, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC074AE, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC0CFE9, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC16B54, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC18057, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC2D95A, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC41236, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC50D36, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC53F2D, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC95A10, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC9830B, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC99A8D, 32, NDPI_PROTOCOL_TOR }, + { 0x6DC9C2DB, 32, NDPI_PROTOCOL_TOR }, + { 0x6DCB6C42, 32, NDPI_PROTOCOL_TOR }, + { 0x6DCEBA61, 32, NDPI_PROTOCOL_TOR }, + { 0x6DD412CD, 32, NDPI_PROTOCOL_TOR }, + { 0x6DD414AD, 32, NDPI_PROTOCOL_TOR }, + { 0x6DDA7515, 32, NDPI_PROTOCOL_TOR }, + { 0x6DE4963C, 32, NDPI_PROTOCOL_TOR }, + { 0x6DE6E02A, 32, NDPI_PROTOCOL_TOR }, + { 0x6DE6EC59, 32, NDPI_PROTOCOL_TOR }, + { 0x6DE6EC5F, 32, NDPI_PROTOCOL_TOR }, + { 0x6DE6ECAD, 32, NDPI_PROTOCOL_TOR }, + { 0x6DE97B2C, 32, NDPI_PROTOCOL_TOR }, + { 0x6DE97FE9, 32, NDPI_PROTOCOL_TOR }, + { 0x6DEB32A3, 32, NDPI_PROTOCOL_TOR }, + { 0x6DEC568A, 32, NDPI_PROTOCOL_TOR }, + { 0x6DEF301A, 32, NDPI_PROTOCOL_TOR }, + { 0x6DEF3098, 32, NDPI_PROTOCOL_TOR }, + { 0x6DEF30AE, 32, NDPI_PROTOCOL_TOR }, + { 0x6DEF3103, 32, NDPI_PROTOCOL_TOR }, + { 0x6DEF3C35, 32, NDPI_PROTOCOL_TOR }, + { 0x6DF150E7, 32, NDPI_PROTOCOL_TOR }, + { 0x6DF63848, 32, NDPI_PROTOCOL_TOR }, + { 0x6DFB8A1A, 32, NDPI_PROTOCOL_TOR }, + { 0x6DFF2ED7, 32, NDPI_PROTOCOL_TOR }, + { 0x6DFF69AD, 32, NDPI_PROTOCOL_TOR }, + { 0x6E42E657, 32, NDPI_PROTOCOL_TOR }, + { 0x6E42E657, 32, NDPI_PROTOCOL_TOR }, + { 0x6E5D17AA, 32, NDPI_PROTOCOL_TOR }, + { 0x6EAE2B88, 32, NDPI_PROTOCOL_TOR }, + { 0x6EAFF9CA, 32, NDPI_PROTOCOL_TOR }, + { 0x6F458D7B, 32, NDPI_PROTOCOL_TOR }, + { 0x6F45A280, 32, NDPI_PROTOCOL_TOR }, + { 0x6F59A849, 32, NDPI_PROTOCOL_TOR }, + { 0x6F677B5E, 32, NDPI_PROTOCOL_TOR }, + { 0x6F67ACCD, 32, NDPI_PROTOCOL_TOR }, + { 0x6F76B165, 32, NDPI_PROTOCOL_TOR }, + { 0x6FF8167F, 32, NDPI_PROTOCOL_TOR }, + { 0x70769CA3, 32, NDPI_PROTOCOL_TOR }, + { 0x7078955A, 32, NDPI_PROTOCOL_TOR }, + { 0x707899D7, 32, NDPI_PROTOCOL_TOR }, + { 0x70CDFABD, 32, NDPI_PROTOCOL_TOR }, + { 0x71A37584, 32, NDPI_PROTOCOL_TOR }, + { 0x7225CECB, 32, NDPI_PROTOCOL_TOR }, + { 0x724DE973, 32, NDPI_PROTOCOL_TOR }, + { 0x72860615, 32, NDPI_PROTOCOL_TOR }, + { 0x72BD691E, 32, NDPI_PROTOCOL_TOR }, + { 0x7342A640, 32, NDPI_PROTOCOL_TOR }, + { 0x7346F182, 32, NDPI_PROTOCOL_TOR }, + { 0x73BB4A5B, 32, NDPI_PROTOCOL_TOR }, + { 0x73BB9A6B, 32, NDPI_PROTOCOL_TOR }, + { 0x75124BEB, 32, NDPI_PROTOCOL_TOR }, + { 0x751263F9, 32, NDPI_PROTOCOL_TOR }, + { 0x760C8552, 32, NDPI_PROTOCOL_TOR }, + { 0x768D03A4, 32, NDPI_PROTOCOL_TOR }, + { 0x76AC0D55, 32, NDPI_PROTOCOL_TOR }, + { 0x76C1C25F, 32, NDPI_PROTOCOL_TOR }, + { 0x76D0C22A, 32, NDPI_PROTOCOL_TOR }, + { 0x76D0F817, 32, NDPI_PROTOCOL_TOR }, + { 0x76D3C1BE, 32, NDPI_PROTOCOL_TOR }, + { 0x76D3C2E6, 32, NDPI_PROTOCOL_TOR }, + { 0x77092F46, 32, NDPI_PROTOCOL_TOR }, + { 0x77EDA418, 32, NDPI_PROTOCOL_TOR }, + { 0x77F64734, 32, NDPI_PROTOCOL_TOR }, + { 0x781DD933, 32, NDPI_PROTOCOL_TOR }, + { 0x78339DD3, 32, NDPI_PROTOCOL_TOR }, + { 0x7839A32E, 32, NDPI_PROTOCOL_TOR }, + { 0x783B2AC8, 32, NDPI_PROTOCOL_TOR }, + { 0x783BA789, 32, NDPI_PROTOCOL_TOR }, + { 0x784AE0A4, 32, NDPI_PROTOCOL_TOR }, + { 0x7890BEA2, 32, NDPI_PROTOCOL_TOR }, + { 0x7936AF32, 32, NDPI_PROTOCOL_TOR }, + { 0x794953C0, 32, NDPI_PROTOCOL_TOR }, + { 0x7954959D, 32, NDPI_PROTOCOL_TOR }, + { 0x79623AD3, 32, NDPI_PROTOCOL_TOR }, + { 0x79628113, 32, NDPI_PROTOCOL_TOR }, + { 0x7963582E, 32, NDPI_PROTOCOL_TOR }, + { 0x7963B8C8, 32, NDPI_PROTOCOL_TOR }, + { 0x7972B51D, 32, NDPI_PROTOCOL_TOR }, + { 0x797AA193, 32, NDPI_PROTOCOL_TOR }, + { 0x79D1E5D4, 32, NDPI_PROTOCOL_TOR }, + { 0x79D34C57, 32, NDPI_PROTOCOL_TOR }, + { 0x79D3C2E6, 32, NDPI_PROTOCOL_TOR }, + { 0x7A744433, 32, NDPI_PROTOCOL_TOR }, + { 0x7B01A089, 32, NDPI_PROTOCOL_TOR }, + { 0x7B64357A, 32, NDPI_PROTOCOL_TOR }, + { 0x7B6CE046, 32, NDPI_PROTOCOL_TOR }, + { 0x7BDDB10E, 32, NDPI_PROTOCOL_TOR }, + { 0x7C0DAC95, 32, NDPI_PROTOCOL_TOR }, + { 0x7C18F2DD, 32, NDPI_PROTOCOL_TOR }, + { 0x7C67D84F, 32, NDPI_PROTOCOL_TOR }, + { 0x7C6DE896, 32, NDPI_PROTOCOL_TOR }, + { 0x7C951525, 32, NDPI_PROTOCOL_TOR }, + { 0x7CA9666D, 32, NDPI_PROTOCOL_TOR }, + { 0x7CA981CA, 32, NDPI_PROTOCOL_TOR }, + { 0x7CF8F9F5, 32, NDPI_PROTOCOL_TOR }, + { 0x7CF8F9F7, 32, NDPI_PROTOCOL_TOR }, + { 0x7CF8F9FA, 32, NDPI_PROTOCOL_TOR }, + { 0x7CF8F9FD, 32, NDPI_PROTOCOL_TOR }, + { 0x7D1E5578, 32, NDPI_PROTOCOL_TOR }, + { 0x7D352C26, 32, NDPI_PROTOCOL_TOR }, + { 0x7D83BD18, 32, NDPI_PROTOCOL_TOR }, + { 0x7D83BD2C, 32, NDPI_PROTOCOL_TOR }, + { 0x7DECCCB2, 32, NDPI_PROTOCOL_TOR }, + { 0x7DFF021E, 32, NDPI_PROTOCOL_TOR }, + { 0x7E08CD97, 32, NDPI_PROTOCOL_TOR }, + { 0x7E460792, 32, NDPI_PROTOCOL_TOR }, + { 0x7E57F79D, 32, NDPI_PROTOCOL_TOR }, + { 0x8006E06B, 32, NDPI_PROTOCOL_TOR }, + { 0x800CB13B, 32, NDPI_PROTOCOL_TOR }, + { 0x800CE238, 32, NDPI_PROTOCOL_TOR }, + { 0x800CE238, 32, NDPI_PROTOCOL_TOR }, + { 0x800CE252, 32, NDPI_PROTOCOL_TOR }, + { 0x800CE252, 32, NDPI_PROTOCOL_TOR }, + { 0x801F0022, 32, NDPI_PROTOCOL_TOR }, + { 0x801F0022, 32, NDPI_PROTOCOL_TOR }, + { 0x801F0027, 32, NDPI_PROTOCOL_TOR }, + { 0x80270844, 32, NDPI_PROTOCOL_TOR }, + { 0x80278E14, 32, NDPI_PROTOCOL_TOR }, + { 0x80278E15, 32, NDPI_PROTOCOL_TOR }, + { 0x80348069, 32, NDPI_PROTOCOL_TOR }, + { 0x8034A014, 32, NDPI_PROTOCOL_TOR }, + { 0x80392F1E, 32, NDPI_PROTOCOL_TOR }, + { 0x803B1279, 32, NDPI_PROTOCOL_TOR }, + { 0x804490CE, 32, NDPI_PROTOCOL_TOR }, + { 0x80473391, 32, NDPI_PROTOCOL_TOR }, + { 0x804910C0, 32, NDPI_PROTOCOL_TOR }, + { 0x804F35F4, 32, NDPI_PROTOCOL_TOR }, + { 0x804FBA39, 32, NDPI_PROTOCOL_TOR }, + { 0x80752B5C, 32, NDPI_PROTOCOL_TOR }, + { 0x80752B61, 32, NDPI_PROTOCOL_TOR }, + { 0x80752B61, 32, NDPI_PROTOCOL_TOR }, + { 0x807F2860, 32, NDPI_PROTOCOL_TOR }, + { 0x8082CC5B, 32, NDPI_PROTOCOL_TOR }, + { 0x8087BD74, 32, NDPI_PROTOCOL_TOR }, + { 0x80AD374E, 32, NDPI_PROTOCOL_TOR }, + { 0x80B1AA5A, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7227A, 32, NDPI_PROTOCOL_TOR }, + { 0x80C72305, 32, NDPI_PROTOCOL_TOR }, + { 0x80C723BF, 32, NDPI_PROTOCOL_TOR }, + { 0x80C729EE, 32, NDPI_PROTOCOL_TOR }, + { 0x80C72A6C, 32, NDPI_PROTOCOL_TOR }, + { 0x80C72C2E, 32, NDPI_PROTOCOL_TOR }, + { 0x80C72EDC, 32, NDPI_PROTOCOL_TOR }, + { 0x80C733D0, 32, NDPI_PROTOCOL_TOR }, + { 0x80C737CF, 32, NDPI_PROTOCOL_TOR }, + { 0x80C73947, 32, NDPI_PROTOCOL_TOR }, + { 0x80C73F21, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7404F, 32, NDPI_PROTOCOL_TOR }, + { 0x80C74471, 32, NDPI_PROTOCOL_TOR }, + { 0x80C748B6, 32, NDPI_PROTOCOL_TOR }, + { 0x80C74AE2, 32, NDPI_PROTOCOL_TOR }, + { 0x80C753BB, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7579B, 32, NDPI_PROTOCOL_TOR }, + { 0x80C75F79, 32, NDPI_PROTOCOL_TOR }, + { 0x80C75F7E, 32, NDPI_PROTOCOL_TOR }, + { 0x80C76AE6, 32, NDPI_PROTOCOL_TOR }, + { 0x80C77A68, 32, NDPI_PROTOCOL_TOR }, + { 0x80C77A76, 32, NDPI_PROTOCOL_TOR }, + { 0x80C77B13, 32, NDPI_PROTOCOL_TOR }, + { 0x80C782E3, 32, NDPI_PROTOCOL_TOR }, + { 0x80C78407, 32, NDPI_PROTOCOL_TOR }, + { 0x80C78548, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7859A, 32, NDPI_PROTOCOL_TOR }, + { 0x80C78BEC, 32, NDPI_PROTOCOL_TOR }, + { 0x80C79053, 32, NDPI_PROTOCOL_TOR }, + { 0x80C794F3, 32, NDPI_PROTOCOL_TOR }, + { 0x80C797C2, 32, NDPI_PROTOCOL_TOR }, + { 0x80C79A84, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7A56E, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7A5D4, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7A88E, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7AEF7, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7AF45, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7B364, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7B654, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7B73B, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7D4DC, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7D647, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7D9F3, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7E434, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7ECBE, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7F0C1, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7F24B, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7F4CE, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7FA9F, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7FCC5, 32, NDPI_PROTOCOL_TOR }, + { 0x80C7FD9C, 32, NDPI_PROTOCOL_TOR }, + { 0x80D002E9, 32, NDPI_PROTOCOL_TOR }, + { 0x80DF5C53, 32, NDPI_PROTOCOL_TOR }, + { 0x80E81239, 32, NDPI_PROTOCOL_TOR }, + { 0x80ED9D72, 32, NDPI_PROTOCOL_TOR }, + { 0x810A78C1, 32, NDPI_PROTOCOL_TOR }, + { 0x811583C0, 32, NDPI_PROTOCOL_TOR }, + { 0x81400893, 32, NDPI_PROTOCOL_TOR }, + { 0x817B0706, 32, NDPI_PROTOCOL_TOR }, + { 0x817B0706, 32, NDPI_PROTOCOL_TOR }, + { 0x817B0707, 32, NDPI_PROTOCOL_TOR }, + { 0x817B0707, 32, NDPI_PROTOCOL_TOR }, + { 0x817B0708, 32, NDPI_PROTOCOL_TOR }, + { 0x817B0708, 32, NDPI_PROTOCOL_TOR }, + { 0x817B0727, 32, NDPI_PROTOCOL_TOR }, + { 0x817B0727, 32, NDPI_PROTOCOL_TOR }, + { 0x817FFED5, 32, NDPI_PROTOCOL_TOR }, + { 0x818200B7, 32, NDPI_PROTOCOL_TOR }, + { 0x8185081F, 32, NDPI_PROTOCOL_TOR }, + { 0x81BB3621, 32, NDPI_PROTOCOL_TOR }, + { 0x81F1A1FA, 32, NDPI_PROTOCOL_TOR }, + { 0x81F480A9, 32, NDPI_PROTOCOL_TOR }, + { 0x820FBD2D, 32, NDPI_PROTOCOL_TOR }, + { 0x82192C69, 32, NDPI_PROTOCOL_TOR }, + { 0x823FAD7E, 32, NDPI_PROTOCOL_TOR }, + { 0x824B51FB, 32, NDPI_PROTOCOL_TOR }, + { 0x824BB225, 32, NDPI_PROTOCOL_TOR }, + { 0x827B031B, 32, NDPI_PROTOCOL_TOR }, + { 0x827E8EAB, 32, NDPI_PROTOCOL_TOR }, + { 0x8284B17E, 32, NDPI_PROTOCOL_TOR }, + { 0x82950E1F, 32, NDPI_PROTOCOL_TOR }, + { 0x8295C80C, 32, NDPI_PROTOCOL_TOR }, + { 0x8295CB6B, 32, NDPI_PROTOCOL_TOR }, + { 0x8295DC7D, 32, NDPI_PROTOCOL_TOR }, + { 0x82B417E6, 32, NDPI_PROTOCOL_TOR }, + { 0x82B43F96, 32, NDPI_PROTOCOL_TOR }, + { 0x82B84B76, 32, NDPI_PROTOCOL_TOR }, + { 0x82FD157B, 32, NDPI_PROTOCOL_TOR }, + { 0x82FF48A4, 32, NDPI_PROTOCOL_TOR }, + { 0x82FF49CA, 32, NDPI_PROTOCOL_TOR }, + { 0x82FF49CA, 32, NDPI_PROTOCOL_TOR }, + { 0x82FF8242, 32, NDPI_PROTOCOL_TOR }, + { 0x83488818, 32, NDPI_PROTOCOL_TOR }, + { 0x83488A0B, 32, NDPI_PROTOCOL_TOR }, + { 0x83AD8008, 32, NDPI_PROTOCOL_TOR }, + { 0x83BC180E, 32, NDPI_PROTOCOL_TOR }, + { 0x83BC28BC, 32, NDPI_PROTOCOL_TOR }, + { 0x83BC28BD, 32, NDPI_PROTOCOL_TOR }, + { 0x83BC28BD, 32, NDPI_PROTOCOL_TOR }, + { 0x83D79EED, 32, NDPI_PROTOCOL_TOR }, + { 0x83D7A8F2, 32, NDPI_PROTOCOL_TOR }, + { 0x83D7ACD6, 32, NDPI_PROTOCOL_TOR }, + { 0x83D7B062, 32, NDPI_PROTOCOL_TOR }, + { 0x84D83602, 32, NDPI_PROTOCOL_TOR }, + { 0x84E69651, 32, NDPI_PROTOCOL_TOR }, + { 0x84F81E0C, 32, NDPI_PROTOCOL_TOR }, + { 0x84FBE6E3, 32, NDPI_PROTOCOL_TOR }, + { 0x86001A20, 32, NDPI_PROTOCOL_TOR }, + { 0x86036F77, 32, NDPI_PROTOCOL_TOR }, + { 0x8603C987, 32, NDPI_PROTOCOL_TOR }, + { 0x8603EA32, 32, NDPI_PROTOCOL_TOR }, + { 0x86227D25, 32, NDPI_PROTOCOL_TOR }, + { 0x86227D44, 32, NDPI_PROTOCOL_TOR }, + { 0x862293AF, 32, NDPI_PROTOCOL_TOR }, + { 0x8622D0E9, 32, NDPI_PROTOCOL_TOR }, + { 0x8631E0BC, 32, NDPI_PROTOCOL_TOR }, + { 0x865B4E8F, 32, NDPI_PROTOCOL_TOR }, + { 0x865D88B1, 32, NDPI_PROTOCOL_TOR }, + { 0x86604111, 32, NDPI_PROTOCOL_TOR }, + { 0x866370A8, 32, NDPI_PROTOCOL_TOR }, + { 0x8666C865, 32, NDPI_PROTOCOL_TOR }, + { 0x866A03FE, 32, NDPI_PROTOCOL_TOR }, + { 0x867703A4, 32, NDPI_PROTOCOL_TOR }, + { 0x8679405D, 32, NDPI_PROTOCOL_TOR }, + { 0x8679436A, 32, NDPI_PROTOCOL_TOR }, + { 0x86A95CDB, 32, NDPI_PROTOCOL_TOR }, + { 0x86E2441D, 32, NDPI_PROTOCOL_TOR }, + { 0x86F993AE, 32, NDPI_PROTOCOL_TOR }, + { 0x86FFEF3D, 32, NDPI_PROTOCOL_TOR }, + { 0x88A8C999, 32, NDPI_PROTOCOL_TOR }, + { 0x88F307AF, 32, NDPI_PROTOCOL_TOR }, + { 0x88F30E86, 32, NDPI_PROTOCOL_TOR }, + { 0x88F3E072, 32, NDPI_PROTOCOL_TOR }, + { 0x88F3E072, 32, NDPI_PROTOCOL_TOR }, + { 0x898708E9, 32, NDPI_PROTOCOL_TOR }, + { 0x899306B0, 32, NDPI_PROTOCOL_TOR }, + { 0x89CD25DB, 32, NDPI_PROTOCOL_TOR }, + { 0x89CD7C23, 32, NDPI_PROTOCOL_TOR }, + { 0x89E0E221, 32, NDPI_PROTOCOL_TOR }, + { 0x89E23B7F, 32, NDPI_PROTOCOL_TOR }, + { 0x89E2952B, 32, NDPI_PROTOCOL_TOR }, + { 0x89F87A44, 32, NDPI_PROTOCOL_TOR }, + { 0x8A640AD1, 32, NDPI_PROTOCOL_TOR }, + { 0x8A6E2D26, 32, NDPI_PROTOCOL_TOR }, + { 0x8A807C37, 32, NDPI_PROTOCOL_TOR }, + { 0x8A80A9EC, 32, NDPI_PROTOCOL_TOR }, + { 0x8B0E0DEC, 32, NDPI_PROTOCOL_TOR }, + { 0x8B4E8DF7, 32, NDPI_PROTOCOL_TOR }, + { 0x8B5B466B, 32, NDPI_PROTOCOL_TOR }, + { 0x8C716E0B, 32, NDPI_PROTOCOL_TOR }, + { 0x8C795022, 32, NDPI_PROTOCOL_TOR }, + { 0x8C79502A, 32, NDPI_PROTOCOL_TOR }, + { 0x8CB4BEBF, 32, NDPI_PROTOCOL_TOR }, + { 0x8CBA4630, 32, NDPI_PROTOCOL_TOR }, + { 0x8CC0DA8B, 32, NDPI_PROTOCOL_TOR }, + { 0x8D0015F2, 32, NDPI_PROTOCOL_TOR }, + { 0x8D009B6D, 32, NDPI_PROTOCOL_TOR }, + { 0x8D00AF95, 32, NDPI_PROTOCOL_TOR }, + { 0x8D142144, 32, NDPI_PROTOCOL_TOR }, + { 0x8D142145, 32, NDPI_PROTOCOL_TOR }, + { 0x8D14214F, 32, NDPI_PROTOCOL_TOR }, + { 0x8D369FB8, 32, NDPI_PROTOCOL_TOR }, + { 0x8D466911, 32, NDPI_PROTOCOL_TOR }, + { 0x8D8A8A88, 32, NDPI_PROTOCOL_TOR }, + { 0x8D8A8DD0, 32, NDPI_PROTOCOL_TOR }, + { 0x8D8AC2E4, 32, NDPI_PROTOCOL_TOR }, + { 0x8DFFA58A, 32, NDPI_PROTOCOL_TOR }, + { 0x8DFFA77A, 32, NDPI_PROTOCOL_TOR }, + { 0x8DFFBDA1, 32, NDPI_PROTOCOL_TOR }, + { 0x8E0420C4, 32, NDPI_PROTOCOL_TOR }, + { 0x8E0433E4, 32, NDPI_PROTOCOL_TOR }, + { 0x8E04CF3B, 32, NDPI_PROTOCOL_TOR }, + { 0x8E04D0A7, 32, NDPI_PROTOCOL_TOR }, + { 0x8E04D519, 32, NDPI_PROTOCOL_TOR }, + { 0x8E04D571, 32, NDPI_PROTOCOL_TOR }, + { 0x8E04D726, 32, NDPI_PROTOCOL_TOR }, + { 0x8E04D757, 32, NDPI_PROTOCOL_TOR }, + { 0x8E36B0B2, 32, NDPI_PROTOCOL_TOR }, + { 0x8E69D044, 32, NDPI_PROTOCOL_TOR }, + { 0x8FB128C0, 32, NDPI_PROTOCOL_TOR }, + { 0x904C0626, 32, NDPI_PROTOCOL_TOR }, + { 0x904C063B, 32, NDPI_PROTOCOL_TOR }, + { 0x904C0849, 32, NDPI_PROTOCOL_TOR }, + { 0x904C0B64, 32, NDPI_PROTOCOL_TOR }, + { 0x904C0E91, 32, NDPI_PROTOCOL_TOR }, + { 0x904C1DD0, 32, NDPI_PROTOCOL_TOR }, + { 0x904C1EA7, 32, NDPI_PROTOCOL_TOR }, + { 0x904C25F2, 32, NDPI_PROTOCOL_TOR }, + { 0x904C27CA, 32, NDPI_PROTOCOL_TOR }, + { 0x904C2879, 32, NDPI_PROTOCOL_TOR }, + { 0x904C3225, 32, NDPI_PROTOCOL_TOR }, + { 0x904C357D, 32, NDPI_PROTOCOL_TOR }, + { 0x904C3635, 32, NDPI_PROTOCOL_TOR }, + { 0x904C4042, 32, NDPI_PROTOCOL_TOR }, + { 0x904C498C, 32, NDPI_PROTOCOL_TOR }, + { 0x904C5044, 32, NDPI_PROTOCOL_TOR }, + { 0x904C5B87, 32, NDPI_PROTOCOL_TOR }, + { 0x904C6007, 32, NDPI_PROTOCOL_TOR }, + { 0x904C6439, 32, NDPI_PROTOCOL_TOR }, + { 0x904C6E67, 32, NDPI_PROTOCOL_TOR }, + { 0x904C6E67, 32, NDPI_PROTOCOL_TOR }, + { 0x904C7055, 32, NDPI_PROTOCOL_TOR }, + { 0x904C7EB3, 32, NDPI_PROTOCOL_TOR }, + { 0x904C7FA5, 32, NDPI_PROTOCOL_TOR }, + { 0x904C8023, 32, NDPI_PROTOCOL_TOR }, + { 0x904C832A, 32, NDPI_PROTOCOL_TOR }, + { 0x904C95CB, 32, NDPI_PROTOCOL_TOR }, + { 0x904C9C65, 32, NDPI_PROTOCOL_TOR }, + { 0x904CA35D, 32, NDPI_PROTOCOL_TOR }, + { 0x904CB037, 32, NDPI_PROTOCOL_TOR }, + { 0x904CB6CA, 32, NDPI_PROTOCOL_TOR }, + { 0x904CC3E4, 32, NDPI_PROTOCOL_TOR }, + { 0x904CC728, 32, NDPI_PROTOCOL_TOR }, + { 0x904CCB75, 32, NDPI_PROTOCOL_TOR }, + { 0x904CF413, 32, NDPI_PROTOCOL_TOR }, + { 0x904CFD04, 32, NDPI_PROTOCOL_TOR }, + { 0x91DC000F, 32, NDPI_PROTOCOL_TOR }, + { 0x92002090, 32, NDPI_PROTOCOL_TOR }, + { 0x92002A3A, 32, NDPI_PROTOCOL_TOR }, + { 0x92002A6E, 32, NDPI_PROTOCOL_TOR }, + { 0x920048B4, 32, NDPI_PROTOCOL_TOR }, + { 0x920049B2, 32, NDPI_PROTOCOL_TOR }, + { 0x923434C7, 32, NDPI_PROTOCOL_TOR }, + { 0x9234419F, 32, NDPI_PROTOCOL_TOR }, + { 0x92344BB3, 32, NDPI_PROTOCOL_TOR }, + { 0x923490FC, 32, NDPI_PROTOCOL_TOR }, + { 0x92349273, 32, NDPI_PROTOCOL_TOR }, + { 0x925A1CB7, 32, NDPI_PROTOCOL_TOR }, + { 0x9273A850, 32, NDPI_PROTOCOL_TOR }, + { 0x92B915A6, 32, NDPI_PROTOCOL_TOR }, + { 0x92B983AF, 32, NDPI_PROTOCOL_TOR }, + { 0x92B983EF, 32, NDPI_PROTOCOL_TOR }, + { 0x92B988DF, 32, NDPI_PROTOCOL_TOR }, + { 0x92B98D39, 32, NDPI_PROTOCOL_TOR }, + { 0x92B98F90, 32, NDPI_PROTOCOL_TOR }, + { 0x92B996DB, 32, NDPI_PROTOCOL_TOR }, + { 0x92B99939, 32, NDPI_PROTOCOL_TOR }, + { 0x92B99FF1, 32, NDPI_PROTOCOL_TOR }, + { 0x92B9A2EB, 32, NDPI_PROTOCOL_TOR }, + { 0x92B9B440, 32, NDPI_PROTOCOL_TOR }, + { 0x92B9B70D, 32, NDPI_PROTOCOL_TOR }, + { 0x92B9B99A, 32, NDPI_PROTOCOL_TOR }, + { 0x92B9BDC5, 32, NDPI_PROTOCOL_TOR }, + { 0x92B9FB5A, 32, NDPI_PROTOCOL_TOR }, + { 0x92B9FDCA, 32, NDPI_PROTOCOL_TOR }, + { 0x92B9FDCA, 32, NDPI_PROTOCOL_TOR }, + { 0x92FF39E4, 32, NDPI_PROTOCOL_TOR }, + { 0x93459FC4, 32, NDPI_PROTOCOL_TOR }, + { 0x93660115, 32, NDPI_PROTOCOL_TOR }, + { 0x9366D8F2, 32, NDPI_PROTOCOL_TOR }, + { 0x93AFBB8F, 32, NDPI_PROTOCOL_TOR }, + { 0x93DEA58B, 32, NDPI_PROTOCOL_TOR }, + { 0x93E5081A, 32, NDPI_PROTOCOL_TOR }, + { 0x946429FB, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB1431, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB2832, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB2BE9, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB2D87, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB431B, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB4566, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB4D64, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB53C4, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB5884, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB71E6, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB7DD3, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB809C, 32, NDPI_PROTOCOL_TOR }, + { 0x94FB97BD, 32, NDPI_PROTOCOL_TOR }, + { 0x94FBBEE5, 32, NDPI_PROTOCOL_TOR }, + { 0x94FBCE86, 32, NDPI_PROTOCOL_TOR }, + { 0x94FBCF24, 32, NDPI_PROTOCOL_TOR }, + { 0x94FBD7E9, 32, NDPI_PROTOCOL_TOR }, + { 0x94FBD7F4, 32, NDPI_PROTOCOL_TOR }, + { 0x94FBE30E, 32, NDPI_PROTOCOL_TOR }, + { 0x94FBED4F, 32, NDPI_PROTOCOL_TOR }, + { 0x94FBF597, 32, NDPI_PROTOCOL_TOR }, + { 0x94FBFEE5, 32, NDPI_PROTOCOL_TOR }, + { 0x9509001B, 32, NDPI_PROTOCOL_TOR }, + { 0x9509003B, 32, NDPI_PROTOCOL_TOR }, + { 0x9509003C, 32, NDPI_PROTOCOL_TOR }, + { 0x951436DA, 32, NDPI_PROTOCOL_TOR }, + { 0x958405BD, 32, NDPI_PROTOCOL_TOR }, + { 0x959A9810, 32, NDPI_PROTOCOL_TOR }, + { 0x959A9879, 32, NDPI_PROTOCOL_TOR }, + { 0x959A9A92, 32, NDPI_PROTOCOL_TOR }, + { 0x959A9D50, 32, NDPI_PROTOCOL_TOR }, + { 0x959A9E7A, 32, NDPI_PROTOCOL_TOR }, + { 0x959A9EE4, 32, NDPI_PROTOCOL_TOR }, + { 0x959A9F57, 32, NDPI_PROTOCOL_TOR }, + { 0x959A9FAC, 32, NDPI_PROTOCOL_TOR }, + { 0x95ACC7F4, 32, NDPI_PROTOCOL_TOR }, + { 0x95D2AB45, 32, NDPI_PROTOCOL_TOR }, + { 0x95D2ADF7, 32, NDPI_PROTOCOL_TOR }, + { 0x95D2BAC6, 32, NDPI_PROTOCOL_TOR }, + { 0x95FF6DC9, 32, NDPI_PROTOCOL_TOR }, + { 0x96659DFA, 32, NDPI_PROTOCOL_TOR }, + { 0x968C0522, 32, NDPI_PROTOCOL_TOR }, + { 0x971B08A4, 32, NDPI_PROTOCOL_TOR }, + { 0x971DFD3F, 32, NDPI_PROTOCOL_TOR }, + { 0x971FA3B8, 32, NDPI_PROTOCOL_TOR }, + { 0x9741F79A, 32, NDPI_PROTOCOL_TOR }, + { 0x97507745, 32, NDPI_PROTOCOL_TOR }, + { 0x97507758, 32, NDPI_PROTOCOL_TOR }, + { 0x9750800C, 32, NDPI_PROTOCOL_TOR }, + { 0x9750A491, 32, NDPI_PROTOCOL_TOR }, + { 0x97E04B76, 32, NDPI_PROTOCOL_TOR }, + { 0x97E2D38D, 32, NDPI_PROTOCOL_TOR }, + { 0x97E5201B, 32, NDPI_PROTOCOL_TOR }, + { 0x97E65FF1, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC049E, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC0506, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC061B, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC0670, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC06C2, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC06C6, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC07B1, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC0B72, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC0E61, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC160C, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC171F, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC172C, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC1839, 32, NDPI_PROTOCOL_TOR }, + { 0x97EC18E4, 32, NDPI_PROTOCOL_TOR }, + { 0x97ECDA43, 32, NDPI_PROTOCOL_TOR }, + { 0x97ECDD2C, 32, NDPI_PROTOCOL_TOR }, + { 0x97ECDE1B, 32, NDPI_PROTOCOL_TOR }, + { 0x97ECDE1B, 32, NDPI_PROTOCOL_TOR }, + { 0x97ECDED9, 32, NDPI_PROTOCOL_TOR }, + { 0x97FC2A46, 32, NDPI_PROTOCOL_TOR }, + { 0x99782A89, 32, NDPI_PROTOCOL_TOR }, + { 0x997925A6, 32, NDPI_PROTOCOL_TOR }, + { 0x997938DD, 32, NDPI_PROTOCOL_TOR }, + { 0x99793A49, 32, NDPI_PROTOCOL_TOR }, + { 0x997FFB43, 32, NDPI_PROTOCOL_TOR }, + { 0x9A23AFE1, 32, NDPI_PROTOCOL_TOR }, + { 0x9A7F3C42, 32, NDPI_PROTOCOL_TOR }, + { 0x9A7F3D62, 32, NDPI_PROTOCOL_TOR }, + { 0x9A7F3D8D, 32, NDPI_PROTOCOL_TOR }, + { 0x9B5EA7C4, 32, NDPI_PROTOCOL_TOR }, + { 0x9BD2EF58, 32, NDPI_PROTOCOL_TOR }, + { 0x9C38FAE3, 32, NDPI_PROTOCOL_TOR }, + { 0x9D0757B8, 32, NDPI_PROTOCOL_TOR }, + { 0x9D07CA47, 32, NDPI_PROTOCOL_TOR }, + { 0x9D07D224, 32, NDPI_PROTOCOL_TOR }, + { 0x9D07DEE2, 32, NDPI_PROTOCOL_TOR }, + { 0x9D0EF604, 32, NDPI_PROTOCOL_TOR }, + { 0x9E3AA97E, 32, NDPI_PROTOCOL_TOR }, + { 0x9E554D57, 32, NDPI_PROTOCOL_TOR }, + { 0x9EB53326, 32, NDPI_PROTOCOL_TOR }, + { 0x9EB552B2, 32, NDPI_PROTOCOL_TOR }, + { 0x9EB560E3, 32, NDPI_PROTOCOL_TOR }, + { 0x9EDE8F19, 32, NDPI_PROTOCOL_TOR }, + { 0x9EFFD4B3, 32, NDPI_PROTOCOL_TOR }, + { 0x9EFFD729, 32, NDPI_PROTOCOL_TOR }, + { 0x9F94B55A, 32, NDPI_PROTOCOL_TOR }, + { 0xA0612F1E, 32, NDPI_PROTOCOL_TOR }, + { 0xA1357425, 32, NDPI_PROTOCOL_TOR }, + { 0xA1357898, 32, NDPI_PROTOCOL_TOR }, + { 0xA135A068, 32, NDPI_PROTOCOL_TOR }, + { 0xA2D3D985, 32, NDPI_PROTOCOL_TOR }, + { 0xA2D3E0E9, 32, NDPI_PROTOCOL_TOR }, + { 0xA2D813ED, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DA417E, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DA760C, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DAD084, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DAE92B, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DB02B1, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DC2FB8, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DC38BA, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DCD94C, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DCDA6D, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DCF1DF, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DDC939, 32, NDPI_PROTOCOL_TOR }, + { 0xA2DEA01D, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F307B4, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F317DD, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F320CA, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F323FB, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F32725, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F328A1, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F33089, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F33543, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F3354B, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F33EEF, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F348C6, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F3499C, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F35F80, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F364E1, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F3656E, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F367AE, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F371B6, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F37479, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F37734, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F377F6, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F37BDC, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F386E0, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F38B4E, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F38E6B, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F3969C, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F396E5, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F3971B, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F39C7A, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F3A25C, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F3F878, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F3FD76, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F418ED, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F419BA, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F419D6, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F41A09, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F41A9D, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F41D7C, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F422A9, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F52912, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F5D9D0, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F5DC86, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F5DC8C, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F74807, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F7481B, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F748C7, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F748C8, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F748C9, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F748D4, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F748D5, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F748D8, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F748D9, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F7494A, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F749CC, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F749CE, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F809ED, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F80B06, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F80BB0, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F88C65, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F88E67, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F88F29, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F8A033, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F8A053, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F8A090, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F8A097, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F8A1D5, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F8A3CA, 32, NDPI_PROTOCOL_TOR }, + { 0xA2F8A50E, 32, NDPI_PROTOCOL_TOR }, + { 0xA2FAE9C2, 32, NDPI_PROTOCOL_TOR }, + { 0xA2FAEA7D, 32, NDPI_PROTOCOL_TOR }, + { 0xA2FB463A, 32, NDPI_PROTOCOL_TOR }, + { 0xA2FB463A, 32, NDPI_PROTOCOL_TOR }, + { 0xA2FCCC3E, 32, NDPI_PROTOCOL_TOR }, + { 0xA2FCF079, 32, NDPI_PROTOCOL_TOR }, + { 0xA2FCF17B, 32, NDPI_PROTOCOL_TOR }, + { 0xA2FCF20D, 32, NDPI_PROTOCOL_TOR }, + { 0xA2FE4436, 32, NDPI_PROTOCOL_TOR }, + { 0xA40FA707, 32, NDPI_PROTOCOL_TOR }, + { 0xA4272AFE, 32, NDPI_PROTOCOL_TOR }, + { 0xA57B94C7, 32, NDPI_PROTOCOL_TOR }, + { 0xA5FEFF10, 32, NDPI_PROTOCOL_TOR }, + { 0xA5FEFF10, 32, NDPI_PROTOCOL_TOR }, + { 0xA6460F0E, 32, NDPI_PROTOCOL_TOR }, + { 0xA6465E6A, 32, NDPI_PROTOCOL_TOR }, + { 0xA646CF02, 32, NDPI_PROTOCOL_TOR }, + { 0xA646D4B5, 32, NDPI_PROTOCOL_TOR }, + { 0xA64E0721, 32, NDPI_PROTOCOL_TOR }, + { 0xA65215C8, 32, NDPI_PROTOCOL_TOR }, + { 0xA6540737, 32, NDPI_PROTOCOL_TOR }, + { 0xA6540794, 32, NDPI_PROTOCOL_TOR }, + { 0xA7397143, 32, NDPI_PROTOCOL_TOR }, + { 0xA7582348, 32, NDPI_PROTOCOL_TOR }, + { 0xA758283F, 32, NDPI_PROTOCOL_TOR }, + { 0xA7582898, 32, NDPI_PROTOCOL_TOR }, + { 0xA75828C8, 32, NDPI_PROTOCOL_TOR }, + { 0xA75829BB, 32, NDPI_PROTOCOL_TOR }, + { 0xA75829C2, 32, NDPI_PROTOCOL_TOR }, + { 0xA7582BF6, 32, NDPI_PROTOCOL_TOR }, + { 0xA7582C32, 32, NDPI_PROTOCOL_TOR }, + { 0xA7582C33, 32, NDPI_PROTOCOL_TOR }, + { 0xA7582C34, 32, NDPI_PROTOCOL_TOR }, + { 0xA7587066, 32, NDPI_PROTOCOL_TOR }, + { 0xA7587D43, 32, NDPI_PROTOCOL_TOR }, + { 0xA77202C0, 32, NDPI_PROTOCOL_TOR }, + { 0xA7720390, 32, NDPI_PROTOCOL_TOR }, + { 0xA77203A6, 32, NDPI_PROTOCOL_TOR }, + { 0xA772243E, 32, NDPI_PROTOCOL_TOR }, + { 0xA7722489, 32, NDPI_PROTOCOL_TOR }, + { 0xA77229D3, 32, NDPI_PROTOCOL_TOR }, + { 0xA77229D3, 32, NDPI_PROTOCOL_TOR }, + { 0xA77229D4, 32, NDPI_PROTOCOL_TOR }, + { 0xA77229D4, 32, NDPI_PROTOCOL_TOR }, + { 0xA772423D, 32, NDPI_PROTOCOL_TOR }, + { 0xA77243CC, 32, NDPI_PROTOCOL_TOR }, + { 0xA77243D4, 32, NDPI_PROTOCOL_TOR }, + { 0xA7724418, 32, NDPI_PROTOCOL_TOR }, + { 0xA7724726, 32, NDPI_PROTOCOL_TOR }, + { 0xA77247BD, 32, NDPI_PROTOCOL_TOR }, + { 0xA7726116, 32, NDPI_PROTOCOL_TOR }, + { 0xA772629A, 32, NDPI_PROTOCOL_TOR }, + { 0xA772712E, 32, NDPI_PROTOCOL_TOR }, + { 0xA7727130, 32, NDPI_PROTOCOL_TOR }, + { 0xA7727288, 32, NDPI_PROTOCOL_TOR }, + { 0xA77272D1, 32, NDPI_PROTOCOL_TOR }, + { 0xA7729864, 32, NDPI_PROTOCOL_TOR }, + { 0xA7A02CC2, 32, NDPI_PROTOCOL_TOR }, + { 0xA7A02CE2, 32, NDPI_PROTOCOL_TOR }, + { 0xA7A0A39A, 32, NDPI_PROTOCOL_TOR }, + { 0xA83ED9D8, 32, NDPI_PROTOCOL_TOR }, + { 0xA867C3FA, 32, NDPI_PROTOCOL_TOR }, + { 0xA896FB0F, 32, NDPI_PROTOCOL_TOR }, + { 0xA8EB91AF, 32, NDPI_PROTOCOL_TOR }, + { 0xA8EB9238, 32, NDPI_PROTOCOL_TOR }, + { 0xA8EB9239, 32, NDPI_PROTOCOL_TOR }, + { 0xA8EB935E, 32, NDPI_PROTOCOL_TOR }, + { 0xA8EB9361, 32, NDPI_PROTOCOL_TOR }, + { 0xA8EB9664, 32, NDPI_PROTOCOL_TOR }, + { 0xA8EB9A60, 32, NDPI_PROTOCOL_TOR }, + { 0xA8EB9CA2, 32, NDPI_PROTOCOL_TOR }, + { 0xA9E57D1B, 32, NDPI_PROTOCOL_TOR }, + { 0xA9E57D1B, 32, NDPI_PROTOCOL_TOR }, + { 0xAA4BA251, 32, NDPI_PROTOCOL_TOR }, + { 0xAA4BA257, 32, NDPI_PROTOCOL_TOR }, + { 0xAA4BA3B4, 32, NDPI_PROTOCOL_TOR }, + { 0xAB19C109, 32, NDPI_PROTOCOL_TOR }, + { 0xAB19C114, 32, NDPI_PROTOCOL_TOR }, + { 0xAB19C14D, 32, NDPI_PROTOCOL_TOR }, + { 0xAB19C14E, 32, NDPI_PROTOCOL_TOR }, + { 0xAB19C1EB, 32, NDPI_PROTOCOL_TOR }, + { 0xAB655D88, 32, NDPI_PROTOCOL_TOR }, + { 0xAC07A4C5, 32, NDPI_PROTOCOL_TOR }, + { 0xACF51678, 32, NDPI_PROTOCOL_TOR }, + { 0xACF520B9, 32, NDPI_PROTOCOL_TOR }, + { 0xACF520BA, 32, NDPI_PROTOCOL_TOR }, + { 0xACF521F9, 32, NDPI_PROTOCOL_TOR }, + { 0xACF52416, 32, NDPI_PROTOCOL_TOR }, + { 0xACF53C64, 32, NDPI_PROTOCOL_TOR }, + { 0xACF5DB85, 32, NDPI_PROTOCOL_TOR }, + { 0xACFE0D7C, 32, NDPI_PROTOCOL_TOR }, + { 0xAD08664C, 32, NDPI_PROTOCOL_TOR }, + { 0xAD0B116C, 32, NDPI_PROTOCOL_TOR }, + { 0xAD0D8D1C, 32, NDPI_PROTOCOL_TOR }, + { 0xAD10B454, 32, NDPI_PROTOCOL_TOR }, + { 0xAD12E604, 32, NDPI_PROTOCOL_TOR }, + { 0xAD16F0E2, 32, NDPI_PROTOCOL_TOR }, + { 0xAD172ADB, 32, NDPI_PROTOCOL_TOR }, + { 0xAD1C491B, 32, NDPI_PROTOCOL_TOR }, + { 0xAD2C23B2, 32, NDPI_PROTOCOL_TOR }, + { 0xAD2C3ACA, 32, NDPI_PROTOCOL_TOR }, + { 0xAD2DE436, 32, NDPI_PROTOCOL_TOR }, + { 0xAD304BF6, 32, NDPI_PROTOCOL_TOR }, + { 0xAD30B617, 32, NDPI_PROTOCOL_TOR }, + { 0xAD335037, 32, NDPI_PROTOCOL_TOR }, + { 0xAD33C620, 32, NDPI_PROTOCOL_TOR }, + { 0xAD36711E, 32, NDPI_PROTOCOL_TOR }, + { 0xAD40C757, 32, NDPI_PROTOCOL_TOR }, + { 0xAD427043, 32, NDPI_PROTOCOL_TOR }, + { 0xAD45B52A, 32, NDPI_PROTOCOL_TOR }, + { 0xAD469914, 32, NDPI_PROTOCOL_TOR }, + { 0xAD46DD71, 32, NDPI_PROTOCOL_TOR }, + { 0xAD4717F9, 32, NDPI_PROTOCOL_TOR }, + { 0xAD479C14, 32, NDPI_PROTOCOL_TOR }, + { 0xAD49717D, 32, NDPI_PROTOCOL_TOR }, + { 0xAD4CA387, 32, NDPI_PROTOCOL_TOR }, + { 0xAD5980AC, 32, NDPI_PROTOCOL_TOR }, + { 0xADA0B4BD, 32, NDPI_PROTOCOL_TOR }, + { 0xADA103A9, 32, NDPI_PROTOCOL_TOR }, + { 0xADA48BC3, 32, NDPI_PROTOCOL_TOR }, + { 0xADA4CEB5, 32, NDPI_PROTOCOL_TOR }, + { 0xADA4DBFA, 32, NDPI_PROTOCOL_TOR }, + { 0xADA5F099, 32, NDPI_PROTOCOL_TOR }, + { 0xADA71245, 32, NDPI_PROTOCOL_TOR }, + { 0xADC769FE, 32, NDPI_PROTOCOL_TOR }, + { 0xADD0C4D7, 32, NDPI_PROTOCOL_TOR }, + { 0xADD0FBB2, 32, NDPI_PROTOCOL_TOR }, + { 0xADD56C74, 32, NDPI_PROTOCOL_TOR }, + { 0xADD5719B, 32, NDPI_PROTOCOL_TOR }, + { 0xADE45AE0, 32, NDPI_PROTOCOL_TOR }, + { 0xADE45B5B, 32, NDPI_PROTOCOL_TOR }, + { 0xADE65550, 32, NDPI_PROTOCOL_TOR }, + { 0xADE68199, 32, NDPI_PROTOCOL_TOR }, + { 0xADE683CF, 32, NDPI_PROTOCOL_TOR }, + { 0xADE683CF, 32, NDPI_PROTOCOL_TOR }, + { 0xADE686EE, 32, NDPI_PROTOCOL_TOR }, + { 0xADE68ABF, 32, NDPI_PROTOCOL_TOR }, + { 0xADE68E82, 32, NDPI_PROTOCOL_TOR }, + { 0xADE694EC, 32, NDPI_PROTOCOL_TOR }, + { 0xADE69504, 32, NDPI_PROTOCOL_TOR }, + { 0xADE69A5A, 32, NDPI_PROTOCOL_TOR }, + { 0xADE69AB8, 32, NDPI_PROTOCOL_TOR }, + { 0xADECF938, 32, NDPI_PROTOCOL_TOR }, + { 0xADECFAD3, 32, NDPI_PROTOCOL_TOR }, + { 0xADECFF8E, 32, NDPI_PROTOCOL_TOR }, + { 0xADEF4FD2, 32, NDPI_PROTOCOL_TOR }, + { 0xADF279C7, 32, NDPI_PROTOCOL_TOR }, + { 0xADF66823, 32, NDPI_PROTOCOL_TOR }, + { 0xADF6FE86, 32, NDPI_PROTOCOL_TOR }, + { 0xADFED0A8, 32, NDPI_PROTOCOL_TOR }, + { 0xADFED842, 32, NDPI_PROTOCOL_TOR }, + { 0xADFED843, 32, NDPI_PROTOCOL_TOR }, + { 0xADFED844, 32, NDPI_PROTOCOL_TOR }, + { 0xADFED845, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFC24D, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFC41E, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFCD71, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFD1B5, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFD2CD, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFD3AF, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFDA6A, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFDCAB, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFDD60, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFE28E, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFE455, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFE459, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFE486, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFE8C0, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFE93C, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFED6B, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFED6B, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFEDA5, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFF217, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFF259, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFF574, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFF64E, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFF6A2, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFF7F7, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFF812, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFF869, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFF9DE, 32, NDPI_PROTOCOL_TOR }, + { 0xADFFFAF0, 32, NDPI_PROTOCOL_TOR }, + { 0xAE03A82A, 32, NDPI_PROTOCOL_TOR }, + { 0xAE064AC1, 32, NDPI_PROTOCOL_TOR }, + { 0xAE15F745, 32, NDPI_PROTOCOL_TOR }, + { 0xAE1D40A4, 32, NDPI_PROTOCOL_TOR }, + { 0xAE2DB58A, 32, NDPI_PROTOCOL_TOR }, + { 0xAE32F679, 32, NDPI_PROTOCOL_TOR }, + { 0xAE3E4833, 32, NDPI_PROTOCOL_TOR }, + { 0xAE3F713C, 32, NDPI_PROTOCOL_TOR }, + { 0xAE463C5C, 32, NDPI_PROTOCOL_TOR }, + { 0xAE475A25, 32, NDPI_PROTOCOL_TOR }, + { 0xAE5F6BA7, 32, NDPI_PROTOCOL_TOR }, + { 0xAE60D6AE, 32, NDPI_PROTOCOL_TOR }, + { 0xAE6208CA, 32, NDPI_PROTOCOL_TOR }, + { 0xAE6328BE, 32, NDPI_PROTOCOL_TOR }, + { 0xAE6C43BC, 32, NDPI_PROTOCOL_TOR }, + { 0xAE6D6112, 32, NDPI_PROTOCOL_TOR }, + { 0xAE7E102D, 32, NDPI_PROTOCOL_TOR }, + { 0xAE886956, 32, NDPI_PROTOCOL_TOR }, + { 0xAE8AC693, 32, NDPI_PROTOCOL_TOR }, + { 0xAE8FF3F7, 32, NDPI_PROTOCOL_TOR }, + { 0xAF648B8C, 32, NDPI_PROTOCOL_TOR }, + { 0xAF8741DE, 32, NDPI_PROTOCOL_TOR }, + { 0xB00901D3, 32, NDPI_PROTOCOL_TOR }, + { 0xB00904CE, 32, NDPI_PROTOCOL_TOR }, + { 0xB0090574, 32, NDPI_PROTOCOL_TOR }, + { 0xB0091051, 32, NDPI_PROTOCOL_TOR }, + { 0xB0091948, 32, NDPI_PROTOCOL_TOR }, + { 0xB00926C6, 32, NDPI_PROTOCOL_TOR }, + { 0xB0092E8D, 32, NDPI_PROTOCOL_TOR }, + { 0xB00932F0, 32, NDPI_PROTOCOL_TOR }, + { 0xB009368E, 32, NDPI_PROTOCOL_TOR }, + { 0xB0095425, 32, NDPI_PROTOCOL_TOR }, + { 0xB009558D, 32, NDPI_PROTOCOL_TOR }, + { 0xB0095AD7, 32, NDPI_PROTOCOL_TOR }, + { 0xB0096708, 32, NDPI_PROTOCOL_TOR }, + { 0xB0096714, 32, NDPI_PROTOCOL_TOR }, + { 0xB0096B68, 32, NDPI_PROTOCOL_TOR }, + { 0xB00977A7, 32, NDPI_PROTOCOL_TOR }, + { 0xB0097DD1, 32, NDPI_PROTOCOL_TOR }, + { 0xB0098BFC, 32, NDPI_PROTOCOL_TOR }, + { 0xB0098C6C, 32, NDPI_PROTOCOL_TOR }, + { 0xB0098FC8, 32, NDPI_PROTOCOL_TOR }, + { 0xB0098FD0, 32, NDPI_PROTOCOL_TOR }, + { 0xB00991C2, 32, NDPI_PROTOCOL_TOR }, + { 0xB0099344, 32, NDPI_PROTOCOL_TOR }, + { 0xB00994B0, 32, NDPI_PROTOCOL_TOR }, + { 0xB0099D4D, 32, NDPI_PROTOCOL_TOR }, + { 0xB009B42F, 32, NDPI_PROTOCOL_TOR }, + { 0xB009C0AB, 32, NDPI_PROTOCOL_TOR }, + { 0xB009ED02, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63C8, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63C8, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63C9, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63C9, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CA, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CA, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CB, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CB, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CC, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CC, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CD, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CD, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CE, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CE, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CF, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63CF, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63D0, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63D0, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63D1, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A63D1, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A6BB4, 32, NDPI_PROTOCOL_TOR }, + { 0xB00A74A9, 32, NDPI_PROTOCOL_TOR }, + { 0xB00AFA4F, 32, NDPI_PROTOCOL_TOR }, + { 0xB00AFDDB, 32, NDPI_PROTOCOL_TOR }, + { 0xB00AFE87, 32, NDPI_PROTOCOL_TOR }, + { 0xB00C1D0C, 32, NDPI_PROTOCOL_TOR }, + { 0xB00C6B1E, 32, NDPI_PROTOCOL_TOR }, + { 0xB00E717E, 32, NDPI_PROTOCOL_TOR }, + { 0xB00F49B5, 32, NDPI_PROTOCOL_TOR }, + { 0xB00FBBA1, 32, NDPI_PROTOCOL_TOR }, + { 0xB01C0978, 32, NDPI_PROTOCOL_TOR }, + { 0xB01C0B2A, 32, NDPI_PROTOCOL_TOR }, + { 0xB01C1F79, 32, NDPI_PROTOCOL_TOR }, + { 0xB01C305E, 32, NDPI_PROTOCOL_TOR }, + { 0xB01C36D5, 32, NDPI_PROTOCOL_TOR }, + { 0xB01F1C3F, 32, NDPI_PROTOCOL_TOR }, + { 0xB01F2395, 32, NDPI_PROTOCOL_TOR }, + { 0xB01F323D, 32, NDPI_PROTOCOL_TOR }, + { 0xB01F4255, 32, NDPI_PROTOCOL_TOR }, + { 0xB01F7158, 32, NDPI_PROTOCOL_TOR }, + { 0xB01F7494, 32, NDPI_PROTOCOL_TOR }, + { 0xB01F7827, 32, NDPI_PROTOCOL_TOR }, + { 0xB01F989F, 32, NDPI_PROTOCOL_TOR }, + { 0xB01F9CC7, 32, NDPI_PROTOCOL_TOR }, + { 0xB01FB509, 32, NDPI_PROTOCOL_TOR }, + { 0xB01FBF1A, 32, NDPI_PROTOCOL_TOR }, + { 0xB024237E, 32, NDPI_PROTOCOL_TOR }, + { 0xB0245D6B, 32, NDPI_PROTOCOL_TOR }, + { 0xB02496F6, 32, NDPI_PROTOCOL_TOR }, + { 0xB0249F29, 32, NDPI_PROTOCOL_TOR }, + { 0xB0268C0D, 32, NDPI_PROTOCOL_TOR }, + { 0xB03515A2, 32, NDPI_PROTOCOL_TOR }, + { 0xB0357FC2, 32, NDPI_PROTOCOL_TOR }, + { 0xB035E825, 32, NDPI_PROTOCOL_TOR }, + { 0xB038EC53, 32, NDPI_PROTOCOL_TOR }, + { 0xB038ECAD, 32, NDPI_PROTOCOL_TOR }, + { 0xB038ED5A, 32, NDPI_PROTOCOL_TOR }, + { 0xB038EDBF, 32, NDPI_PROTOCOL_TOR }, + { 0xB03A59BC, 32, NDPI_PROTOCOL_TOR }, + { 0xB03A60C7, 32, NDPI_PROTOCOL_TOR }, + { 0xB03A61C9, 32, NDPI_PROTOCOL_TOR }, + { 0xB03A6462, 32, NDPI_PROTOCOL_TOR }, + { 0xB03A6711, 32, NDPI_PROTOCOL_TOR }, + { 0xB03A6A59, 32, NDPI_PROTOCOL_TOR }, + { 0xB03A6AC0, 32, NDPI_PROTOCOL_TOR }, + { 0xB03A7317, 32, NDPI_PROTOCOL_TOR }, + { 0xB03A7816, 32, NDPI_PROTOCOL_TOR }, + { 0xB03A799F, 32, NDPI_PROTOCOL_TOR }, + { 0xB03A9FAF, 32, NDPI_PROTOCOL_TOR }, + { 0xB03D89DD, 32, NDPI_PROTOCOL_TOR }, + { 0xB043AC1E, 32, NDPI_PROTOCOL_TOR }, + { 0xB049E604, 32, NDPI_PROTOCOL_TOR }, + { 0xB04D1A58, 32, NDPI_PROTOCOL_TOR }, + { 0xB04D226A, 32, NDPI_PROTOCOL_TOR }, + { 0xB04D2746, 32, NDPI_PROTOCOL_TOR }, + { 0xB04D29B7, 32, NDPI_PROTOCOL_TOR }, + { 0xB05019F4, 32, NDPI_PROTOCOL_TOR }, + { 0xB063C782, 32, NDPI_PROTOCOL_TOR }, + { 0xB0678035, 32, NDPI_PROTOCOL_TOR }, + { 0xB06A3636, 32, NDPI_PROTOCOL_TOR }, + { 0xB06A6B2F, 32, NDPI_PROTOCOL_TOR }, + { 0xB06CA0F1, 32, NDPI_PROTOCOL_TOR }, + { 0xB06CA0F2, 32, NDPI_PROTOCOL_TOR }, + { 0xB06CA0FD, 32, NDPI_PROTOCOL_TOR }, + { 0xB072F82F, 32, NDPI_PROTOCOL_TOR }, + { 0xB0744531, 32, NDPI_PROTOCOL_TOR }, + { 0xB0746831, 32, NDPI_PROTOCOL_TOR }, + { 0xB075128D, 32, NDPI_PROTOCOL_TOR }, + { 0xB07B065E, 32, NDPI_PROTOCOL_TOR }, + { 0xB07B0665, 32, NDPI_PROTOCOL_TOR }, + { 0xB07B1C1F, 32, NDPI_PROTOCOL_TOR }, + { 0xB07B1C22, 32, NDPI_PROTOCOL_TOR }, + { 0xB07EF45B, 32, NDPI_PROTOCOL_TOR }, + { 0xB07EFC0B, 32, NDPI_PROTOCOL_TOR }, + { 0xB07EFC0C, 32, NDPI_PROTOCOL_TOR }, + { 0xB0BCDE53, 32, NDPI_PROTOCOL_TOR }, + { 0xB0BD2641, 32, NDPI_PROTOCOL_TOR }, + { 0xB0BD77B6, 32, NDPI_PROTOCOL_TOR }, + { 0xB0C17D30, 32, NDPI_PROTOCOL_TOR }, + { 0xB0C20E92, 32, NDPI_PROTOCOL_TOR }, + { 0xB0C62CC4, 32, NDPI_PROTOCOL_TOR }, + { 0xB0C65C86, 32, NDPI_PROTOCOL_TOR }, + { 0xB0C6642D, 32, NDPI_PROTOCOL_TOR }, + { 0xB0C67537, 32, NDPI_PROTOCOL_TOR }, + { 0xB0C7E07F, 32, NDPI_PROTOCOL_TOR }, + { 0xB0C7E590, 32, NDPI_PROTOCOL_TOR }, + { 0xB0D496A3, 32, NDPI_PROTOCOL_TOR }, + { 0xB0DD2E35, 32, NDPI_PROTOCOL_TOR }, + { 0xB0DECAC3, 32, NDPI_PROTOCOL_TOR }, + { 0xB0E2DAFF, 32, NDPI_PROTOCOL_TOR }, + { 0xB10648C6, 32, NDPI_PROTOCOL_TOR }, + { 0xB12F6D15, 32, NDPI_PROTOCOL_TOR }, + { 0xB15C1B98, 32, NDPI_PROTOCOL_TOR }, + { 0xB18D1209, 32, NDPI_PROTOCOL_TOR }, + { 0xB194ACC4, 32, NDPI_PROTOCOL_TOR }, + { 0xB1BC41E6, 32, NDPI_PROTOCOL_TOR }, + { 0xB1CD10C8, 32, NDPI_PROTOCOL_TOR }, + { 0xB2011DB1, 32, NDPI_PROTOCOL_TOR }, + { 0xB202DFF0, 32, NDPI_PROTOCOL_TOR }, + { 0xB202E307, 32, NDPI_PROTOCOL_TOR }, + { 0xB2031B59, 32, NDPI_PROTOCOL_TOR }, + { 0xB204CFB7, 32, NDPI_PROTOCOL_TOR }, + { 0xB2067327, 32, NDPI_PROTOCOL_TOR }, + { 0xB2070DE7, 32, NDPI_PROTOCOL_TOR }, + { 0xB20BA25E, 32, NDPI_PROTOCOL_TOR }, + { 0xB2102D5A, 32, NDPI_PROTOCOL_TOR }, + { 0xB210D038, 32, NDPI_PROTOCOL_TOR }, + { 0xB210D039, 32, NDPI_PROTOCOL_TOR }, + { 0xB211AA0B, 32, NDPI_PROTOCOL_TOR }, + { 0xB211AA13, 32, NDPI_PROTOCOL_TOR }, + { 0xB212106C, 32, NDPI_PROTOCOL_TOR }, + { 0xB21211CC, 32, NDPI_PROTOCOL_TOR }, + { 0xB21211EA, 32, NDPI_PROTOCOL_TOR }, + { 0xB21253D7, 32, NDPI_PROTOCOL_TOR }, + { 0xB2128308, 32, NDPI_PROTOCOL_TOR }, + { 0xB2143710, 32, NDPI_PROTOCOL_TOR }, + { 0xB2143712, 32, NDPI_PROTOCOL_TOR }, + { 0xB2151456, 32, NDPI_PROTOCOL_TOR }, + { 0xB2157245, 32, NDPI_PROTOCOL_TOR }, + { 0xB21572B9, 32, NDPI_PROTOCOL_TOR }, + { 0xB2182081, 32, NDPI_PROTOCOL_TOR }, + { 0xB218CF5C, 32, NDPI_PROTOCOL_TOR }, + { 0xB21944AC, 32, NDPI_PROTOCOL_TOR }, + { 0xB21968A9, 32, NDPI_PROTOCOL_TOR }, + { 0xB2198DE6, 32, NDPI_PROTOCOL_TOR }, + { 0xB21A57B7, 32, NDPI_PROTOCOL_TOR }, + { 0xB21A76A9, 32, NDPI_PROTOCOL_TOR }, + { 0xB21A8269, 32, NDPI_PROTOCOL_TOR }, + { 0xB21AB707, 32, NDPI_PROTOCOL_TOR }, + { 0xB21AC341, 32, NDPI_PROTOCOL_TOR }, + { 0xB21B383A, 32, NDPI_PROTOCOL_TOR }, + { 0xB21B78E5, 32, NDPI_PROTOCOL_TOR }, + { 0xB21B7ACB, 32, NDPI_PROTOCOL_TOR }, + { 0xB220225B, 32, NDPI_PROTOCOL_TOR }, + { 0xB2202C9D, 32, NDPI_PROTOCOL_TOR }, + { 0xB2203E91, 32, NDPI_PROTOCOL_TOR }, + { 0xB22064D7, 32, NDPI_PROTOCOL_TOR }, + { 0xB220784B, 32, NDPI_PROTOCOL_TOR }, + { 0xB2207A41, 32, NDPI_PROTOCOL_TOR }, + { 0xB2208FAF, 32, NDPI_PROTOCOL_TOR }, + { 0xB2208FAF, 32, NDPI_PROTOCOL_TOR }, + { 0xB220B560, 32, NDPI_PROTOCOL_TOR }, + { 0xB220B561, 32, NDPI_PROTOCOL_TOR }, + { 0xB220B562, 32, NDPI_PROTOCOL_TOR }, + { 0xB220B563, 32, NDPI_PROTOCOL_TOR }, + { 0xB220D861, 32, NDPI_PROTOCOL_TOR }, + { 0xB220D892, 32, NDPI_PROTOCOL_TOR }, + { 0xB220DBC5, 32, NDPI_PROTOCOL_TOR }, + { 0xB220DC0C, 32, NDPI_PROTOCOL_TOR }, + { 0xB220DC18, 32, NDPI_PROTOCOL_TOR }, + { 0xB220DD97, 32, NDPI_PROTOCOL_TOR }, + { 0xB220DDCF, 32, NDPI_PROTOCOL_TOR }, + { 0xB220DE15, 32, NDPI_PROTOCOL_TOR }, + { 0xB220EE9E, 32, NDPI_PROTOCOL_TOR }, + { 0xB2212397, 32, NDPI_PROTOCOL_TOR }, + { 0xB22170AB, 32, NDPI_PROTOCOL_TOR }, + { 0xB22EA34B, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E0999, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E0E7F, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E0E97, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E102A, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E12D7, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E1384, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E1A53, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E2520, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E27CA, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E2E07, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E3405, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E354B, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E36E3, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E38A3, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E3910, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E3A50, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E414D, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E4DB6, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E4E51, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E507C, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E5660, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E56CE, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E5A6F, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E5D24, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E5EF3, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E60A0, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E64C1, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E6892, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E6DA4, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E6E8D, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E6F30, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E7047, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E769A, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E83D8, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E9871, 32, NDPI_PROTOCOL_TOR }, + { 0xB23E9E9C, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EA3E3, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EA7B2, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EADCB, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EB2E4, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EB893, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EBA9B, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EBD4F, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EC4B1, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EC658, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EC6D5, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EC7E2, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EC927, 32, NDPI_PROTOCOL_TOR }, + { 0xB23ECC5B, 32, NDPI_PROTOCOL_TOR }, + { 0xB23ECC63, 32, NDPI_PROTOCOL_TOR }, + { 0xB23ED1FC, 32, NDPI_PROTOCOL_TOR }, + { 0xB23ED47B, 32, NDPI_PROTOCOL_TOR }, + { 0xB23ED986, 32, NDPI_PROTOCOL_TOR }, + { 0xB23ED9E9, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EDAA0, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EDE81, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EE525, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EE5D1, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EE707, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EEA99, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EEB68, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EEE78, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EF11E, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EF140, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EF877, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EFB08, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EFC52, 32, NDPI_PROTOCOL_TOR }, + { 0xB23EFCEA, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F00A1, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F1030, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F2E61, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F3D43, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F41B3, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F4AC4, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F4AF5, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F5E90, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F604F, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F6122, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F65C5, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F6E97, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F749D, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F91E2, 32, NDPI_PROTOCOL_TOR }, + { 0xB23F9A5D, 32, NDPI_PROTOCOL_TOR }, + { 0xB23FA2D4, 32, NDPI_PROTOCOL_TOR }, + { 0xB23FD133, 32, NDPI_PROTOCOL_TOR }, + { 0xB24021FC, 32, NDPI_PROTOCOL_TOR }, + { 0xB246D353, 32, NDPI_PROTOCOL_TOR }, + { 0xB248584D, 32, NDPI_PROTOCOL_TOR }, + { 0xB249D276, 32, NDPI_PROTOCOL_TOR }, + { 0xB249D2F0, 32, NDPI_PROTOCOL_TOR }, + { 0xB24A67E4, 32, NDPI_PROTOCOL_TOR }, + { 0xB24D627C, 32, NDPI_PROTOCOL_TOR }, + { 0xB24D7B29, 32, NDPI_PROTOCOL_TOR }, + { 0xB24ED425, 32, NDPI_PROTOCOL_TOR }, + { 0xB24EEAC3, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F8540, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F8623, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F86B7, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F86B7, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F86C4, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F88E6, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F8B11, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F8B2E, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F8D6C, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F8EE0, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F901C, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F901C, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F9D24, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F9D24, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F9F93, 32, NDPI_PROTOCOL_TOR }, + { 0xB24F9FE0, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FA039, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FA198, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FA1B1, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FA1ED, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FA1ED, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FA3A9, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FA515, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FA858, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FAAAD, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FAAB5, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FAAB5, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FB060, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FB072, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FB0B9, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FB5E6, 32, NDPI_PROTOCOL_TOR }, + { 0xB24FBCD4, 32, NDPI_PROTOCOL_TOR }, + { 0xB2520865, 32, NDPI_PROTOCOL_TOR }, + { 0xB2522270, 32, NDPI_PROTOCOL_TOR }, + { 0xB2522871, 32, NDPI_PROTOCOL_TOR }, + { 0xB2524269, 32, NDPI_PROTOCOL_TOR }, + { 0xB2534549, 32, NDPI_PROTOCOL_TOR }, + { 0xB2560A58, 32, NDPI_PROTOCOL_TOR }, + { 0xB281AD8F, 32, NDPI_PROTOCOL_TOR }, + { 0xB289B71D, 32, NDPI_PROTOCOL_TOR }, + { 0xB28C33AD, 32, NDPI_PROTOCOL_TOR }, + { 0xB28C33AD, 32, NDPI_PROTOCOL_TOR }, + { 0xB28C6812, 32, NDPI_PROTOCOL_TOR }, + { 0xB28CC54B, 32, NDPI_PROTOCOL_TOR }, + { 0xB28E0705, 32, NDPI_PROTOCOL_TOR }, + { 0xB2A23DD6, 32, NDPI_PROTOCOL_TOR }, + { 0xB2A242D4, 32, NDPI_PROTOCOL_TOR }, + { 0xB2A2C21E, 32, NDPI_PROTOCOL_TOR }, + { 0xB2A2C252, 32, NDPI_PROTOCOL_TOR }, + { 0xB2A2C2D2, 32, NDPI_PROTOCOL_TOR }, + { 0xB2A2C505, 32, NDPI_PROTOCOL_TOR }, + { 0xB2A746AA, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AA6FC2, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AF83C2, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AF8B8A, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AF8B8A, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AF8B8B, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AF8B8B, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AF8B8C, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AF8B8C, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AF8B8D, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AF8B8D, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AF8B8E, 32, NDPI_PROTOCOL_TOR }, + { 0xB2AF8B8E, 32, NDPI_PROTOCOL_TOR }, + { 0xB2BA743C, 32, NDPI_PROTOCOL_TOR }, + { 0xB2BED2D1, 32, NDPI_PROTOCOL_TOR }, + { 0xB2BFC29E, 32, NDPI_PROTOCOL_TOR }, + { 0xB2C0BBAF, 32, NDPI_PROTOCOL_TOR }, + { 0xB2C3EA94, 32, NDPI_PROTOCOL_TOR }, + { 0xB2C7EAC0, 32, NDPI_PROTOCOL_TOR }, + { 0xB2C861B6, 32, NDPI_PROTOCOL_TOR }, + { 0xB2C8CBEE, 32, NDPI_PROTOCOL_TOR }, + { 0xB2C8EE97, 32, NDPI_PROTOCOL_TOR }, + { 0xB2C92FF5, 32, NDPI_PROTOCOL_TOR }, + { 0xB2C98985, 32, NDPI_PROTOCOL_TOR }, + { 0xB2C9B19C, 32, NDPI_PROTOCOL_TOR }, + { 0xB2CA6B7B, 32, NDPI_PROTOCOL_TOR }, + { 0xB2CB9302, 32, NDPI_PROTOCOL_TOR }, + { 0xB2CB9A4F, 32, NDPI_PROTOCOL_TOR }, + { 0xB2CBBF12, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D13297, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D13363, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D134A2, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D3238A, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D808F5, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D83B33, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D85C75, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D9B820, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D9B943, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D9BB05, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D9BB06, 32, NDPI_PROTOCOL_TOR }, + { 0xB2D9BB27, 32, NDPI_PROTOCOL_TOR }, + { 0xB2DBF5D6, 32, NDPI_PROTOCOL_TOR }, + { 0xB2EEDF43, 32, NDPI_PROTOCOL_TOR }, + { 0xB2EEE084, 32, NDPI_PROTOCOL_TOR }, + { 0xB2EEE16C, 32, NDPI_PROTOCOL_TOR }, + { 0xB2EEE19E, 32, NDPI_PROTOCOL_TOR }, + { 0xB2EEE40C, 32, NDPI_PROTOCOL_TOR }, + { 0xB2EEED2C, 32, NDPI_PROTOCOL_TOR }, + { 0xB2EF3CAC, 32, NDPI_PROTOCOL_TOR }, + { 0xB2EFB113, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FAF3D9, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FD60A6, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE0615, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE08BB, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE0987, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE1486, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE1486, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE16E4, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE193E, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE19A5, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE1AF4, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE1C14, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE1E56, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE1FAD, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE1FD1, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE23E0, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE25C5, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE2805, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE2BF4, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE2C5B, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE2C5B, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE2C87, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE2C87, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE2CEA, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE2CEA, 32, NDPI_PROTOCOL_TOR }, + { 0xB2FE3765, 32, NDPI_PROTOCOL_TOR }, + { 0xB300C293, 32, NDPI_PROTOCOL_TOR }, + { 0xB32B8522, 32, NDPI_PROTOCOL_TOR }, + { 0xB36FE5E8, 32, NDPI_PROTOCOL_TOR }, + { 0xB3E8F4B7, 32, NDPI_PROTOCOL_TOR }, + { 0xB4DE4452, 32, NDPI_PROTOCOL_TOR }, + { 0xB529C599, 32, NDPI_PROTOCOL_TOR }, + { 0xB529DB75, 32, NDPI_PROTOCOL_TOR }, + { 0xB52E9531, 32, NDPI_PROTOCOL_TOR }, + { 0xB5A073AC, 32, NDPI_PROTOCOL_TOR }, + { 0xB6A70430, 32, NDPI_PROTOCOL_TOR }, + { 0xB7574B02, 32, NDPI_PROTOCOL_TOR }, + { 0xB75806AD, 32, NDPI_PROTOCOL_TOR }, + { 0xB8129B07, 32, NDPI_PROTOCOL_TOR }, + { 0xB812D6D9, 32, NDPI_PROTOCOL_TOR }, + { 0xB8230910, 32, NDPI_PROTOCOL_TOR }, + { 0xB827A1D3, 32, NDPI_PROTOCOL_TOR }, + { 0xB8486A34, 32, NDPI_PROTOCOL_TOR }, + { 0xB84E9433, 32, NDPI_PROTOCOL_TOR }, + { 0xB85EE222, 32, NDPI_PROTOCOL_TOR }, + { 0xB8645406, 32, NDPI_PROTOCOL_TOR }, + { 0xB869CB85, 32, NDPI_PROTOCOL_TOR }, + { 0xB869DC18, 32, NDPI_PROTOCOL_TOR }, + { 0xB869EB44, 32, NDPI_PROTOCOL_TOR }, + { 0xB86A6DF4, 32, NDPI_PROTOCOL_TOR }, + { 0xB86AD762, 32, NDPI_PROTOCOL_TOR }, + { 0xB8944B0F, 32, NDPI_PROTOCOL_TOR }, + { 0xB89BBBCD, 32, NDPI_PROTOCOL_TOR }, + { 0xB8A3447D, 32, NDPI_PROTOCOL_TOR }, + { 0xB8A48472, 32, NDPI_PROTOCOL_TOR }, + { 0xB8A4F401, 32, NDPI_PROTOCOL_TOR }, + { 0xB8A4F601, 32, NDPI_PROTOCOL_TOR }, + { 0xB8AA68F7, 32, NDPI_PROTOCOL_TOR }, + { 0xB8AF118B, 32, NDPI_PROTOCOL_TOR }, + { 0xB8AF2873, 32, NDPI_PROTOCOL_TOR }, + { 0xB8B07919, 32, NDPI_PROTOCOL_TOR }, + { 0xB8B705CB, 32, NDPI_PROTOCOL_TOR }, + { 0xB904E322, 32, NDPI_PROTOCOL_TOR }, + { 0xB9050983, 32, NDPI_PROTOCOL_TOR }, + { 0xB9053482, 32, NDPI_PROTOCOL_TOR }, + { 0xB905355D, 32, NDPI_PROTOCOL_TOR }, + { 0xB907944E, 32, NDPI_PROTOCOL_TOR }, + { 0xB908EC83, 32, NDPI_PROTOCOL_TOR }, + { 0xB908ED1B, 32, NDPI_PROTOCOL_TOR }, + { 0xB908EDD0, 32, NDPI_PROTOCOL_TOR }, + { 0xB908EE42, 32, NDPI_PROTOCOL_TOR }, + { 0xB908EE8B, 32, NDPI_PROTOCOL_TOR }, + { 0xB908EE8C, 32, NDPI_PROTOCOL_TOR }, + { 0xB90A1DF7, 32, NDPI_PROTOCOL_TOR }, + { 0xB90A4750, 32, NDPI_PROTOCOL_TOR }, + { 0xB90BA670, 32, NDPI_PROTOCOL_TOR }, + { 0xB90C0C85, 32, NDPI_PROTOCOL_TOR }, + { 0xB90C0E76, 32, NDPI_PROTOCOL_TOR }, + { 0xB90D259E, 32, NDPI_PROTOCOL_TOR }, + { 0xB90D2631, 32, NDPI_PROTOCOL_TOR }, + { 0xB90D2684, 32, NDPI_PROTOCOL_TOR }, + { 0xB90D26B9, 32, NDPI_PROTOCOL_TOR }, + { 0xB90D27C5, 32, NDPI_PROTOCOL_TOR }, + { 0xB90E1C6A, 32, NDPI_PROTOCOL_TOR }, + { 0xB90E1F3B, 32, NDPI_PROTOCOL_TOR }, + { 0xB90EB80D, 32, NDPI_PROTOCOL_TOR }, + { 0xB90EB9F0, 32, NDPI_PROTOCOL_TOR }, + { 0xB90FF47C, 32, NDPI_PROTOCOL_TOR }, + { 0xB9103C53, 32, NDPI_PROTOCOL_TOR }, + { 0xB9107C88, 32, NDPI_PROTOCOL_TOR }, + { 0xB910AC9B, 32, NDPI_PROTOCOL_TOR }, + { 0xB910AD54, 32, NDPI_PROTOCOL_TOR }, + { 0xB910AD56, 32, NDPI_PROTOCOL_TOR }, + { 0xB910C8B0, 32, NDPI_PROTOCOL_TOR }, + { 0xB910C91C, 32, NDPI_PROTOCOL_TOR }, + { 0xB911908A, 32, NDPI_PROTOCOL_TOR }, + { 0xB911B8E4, 32, NDPI_PROTOCOL_TOR }, + { 0xB9129404, 32, NDPI_PROTOCOL_TOR }, + { 0xB9135724, 32, NDPI_PROTOCOL_TOR }, + { 0xB9156432, 32, NDPI_PROTOCOL_TOR }, + { 0xB915671F, 32, NDPI_PROTOCOL_TOR }, + { 0xB915D8A6, 32, NDPI_PROTOCOL_TOR }, + { 0xB915D908, 32, NDPI_PROTOCOL_TOR }, + { 0xB9163F22, 32, NDPI_PROTOCOL_TOR }, + { 0xB918EBCD, 32, NDPI_PROTOCOL_TOR }, + { 0xB919D8ED, 32, NDPI_PROTOCOL_TOR }, + { 0xB91A7CB4, 32, NDPI_PROTOCOL_TOR }, + { 0xB91A9C1C, 32, NDPI_PROTOCOL_TOR }, + { 0xB91A9C1D, 32, NDPI_PROTOCOL_TOR }, + { 0xB91BAF18, 32, NDPI_PROTOCOL_TOR }, + { 0xB91F644B, 32, NDPI_PROTOCOL_TOR }, + { 0xB9222102, 32, NDPI_PROTOCOL_TOR }, + { 0xB9246491, 32, NDPI_PROTOCOL_TOR }, + { 0xB92592AC, 32, NDPI_PROTOCOL_TOR }, + { 0xB925E2C5, 32, NDPI_PROTOCOL_TOR }, + { 0xB9262FE0, 32, NDPI_PROTOCOL_TOR }, + { 0xB928870A, 32, NDPI_PROTOCOL_TOR }, + { 0xB92DC039, 32, NDPI_PROTOCOL_TOR }, + { 0xB92DC069, 32, NDPI_PROTOCOL_TOR }, + { 0xB92DC0BC, 32, NDPI_PROTOCOL_TOR }, + { 0xB92DC1F2, 32, NDPI_PROTOCOL_TOR }, + { 0xB9310ED3, 32, NDPI_PROTOCOL_TOR }, + { 0xB932BFFA, 32, NDPI_PROTOCOL_TOR }, + { 0xB932E9E0, 32, NDPI_PROTOCOL_TOR }, + { 0xB935A306, 32, NDPI_PROTOCOL_TOR }, + { 0xB936EE88, 32, NDPI_PROTOCOL_TOR }, + { 0xB9385426, 32, NDPI_PROTOCOL_TOR }, + { 0xB9395219, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D8932, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D8932, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D8949, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D8949, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D942E, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D9450, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D945D, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D9474, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D948D, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D948E, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D94B7, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D94BD, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D94C1, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D94E4, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D956D, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D9574, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D9576, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D9577, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D95B0, 32, NDPI_PROTOCOL_TOR }, + { 0xB93D95C1, 32, NDPI_PROTOCOL_TOR }, + { 0xB93FBC7C, 32, NDPI_PROTOCOL_TOR }, + { 0xB941C85D, 32, NDPI_PROTOCOL_TOR }, + { 0xB941CD12, 32, NDPI_PROTOCOL_TOR }, + { 0xB9453693, 32, NDPI_PROTOCOL_TOR }, + { 0xB9453744, 32, NDPI_PROTOCOL_TOR }, + { 0xB948B169, 32, NDPI_PROTOCOL_TOR }, + { 0xB948E86B, 32, NDPI_PROTOCOL_TOR }, + { 0xB948F791, 32, NDPI_PROTOCOL_TOR }, + { 0xB94B382C, 32, NDPI_PROTOCOL_TOR }, + { 0xB94B382C, 32, NDPI_PROTOCOL_TOR }, + { 0xB94B3874, 32, NDPI_PROTOCOL_TOR }, + { 0xB94B3874, 32, NDPI_PROTOCOL_TOR }, + { 0xB952C8E0, 32, NDPI_PROTOCOL_TOR }, + { 0xBA160C6E, 32, NDPI_PROTOCOL_TOR }, + { 0xBA1A4002, 32, NDPI_PROTOCOL_TOR }, + { 0xBA6B7BAE, 32, NDPI_PROTOCOL_TOR }, + { 0xBB3B6D26, 32, NDPI_PROTOCOL_TOR }, + { 0xBB3F6418, 32, NDPI_PROTOCOL_TOR }, + { 0xBB5F2203, 32, NDPI_PROTOCOL_TOR }, + { 0xBBD34A78, 32, NDPI_PROTOCOL_TOR }, + { 0xBBFEE732, 32, NDPI_PROTOCOL_TOR }, + { 0xBC0262D8, 32, NDPI_PROTOCOL_TOR }, + { 0xBC04F2B2, 32, NDPI_PROTOCOL_TOR }, + { 0xBC060D5B, 32, NDPI_PROTOCOL_TOR }, + { 0xBC06497F, 32, NDPI_PROTOCOL_TOR }, + { 0xBC18F4FF, 32, NDPI_PROTOCOL_TOR }, + { 0xBC208F85, 32, NDPI_PROTOCOL_TOR }, + { 0xBC20F2F4, 32, NDPI_PROTOCOL_TOR }, + { 0xBC28209A, 32, NDPI_PROTOCOL_TOR }, + { 0xBC2821D9, 32, NDPI_PROTOCOL_TOR }, + { 0xBC2825C8, 32, NDPI_PROTOCOL_TOR }, + { 0xBC2833E8, 32, NDPI_PROTOCOL_TOR }, + { 0xBC283512, 32, NDPI_PROTOCOL_TOR }, + { 0xBC283B50, 32, NDPI_PROTOCOL_TOR }, + { 0xBC283C8E, 32, NDPI_PROTOCOL_TOR }, + { 0xBC283CF2, 32, NDPI_PROTOCOL_TOR }, + { 0xBC284C73, 32, NDPI_PROTOCOL_TOR }, + { 0xBC286345, 32, NDPI_PROTOCOL_TOR }, + { 0xBC286BCD, 32, NDPI_PROTOCOL_TOR }, + { 0xBC2880F6, 32, NDPI_PROTOCOL_TOR }, + { 0xBC2899F2, 32, NDPI_PROTOCOL_TOR }, + { 0xBC28B34A, 32, NDPI_PROTOCOL_TOR }, + { 0xBC28CE05, 32, NDPI_PROTOCOL_TOR }, + { 0xBC28EBD7, 32, NDPI_PROTOCOL_TOR }, + { 0xBC28F839, 32, NDPI_PROTOCOL_TOR }, + { 0xBC2AFD0B, 32, NDPI_PROTOCOL_TOR }, + { 0xBC322E9A, 32, NDPI_PROTOCOL_TOR }, + { 0xBC3CC333, 32, NDPI_PROTOCOL_TOR }, + { 0xBC3E5662, 32, NDPI_PROTOCOL_TOR }, + { 0xBC499110, 32, NDPI_PROTOCOL_TOR }, + { 0xBC4DD834, 32, NDPI_PROTOCOL_TOR }, + { 0xBC4ED027, 32, NDPI_PROTOCOL_TOR }, + { 0xBC553281, 32, NDPI_PROTOCOL_TOR }, + { 0xBC57A8F9, 32, NDPI_PROTOCOL_TOR }, + { 0xBC5D117B, 32, NDPI_PROTOCOL_TOR }, + { 0xBC5DD54B, 32, NDPI_PROTOCOL_TOR }, + { 0xBC5FF78C, 32, NDPI_PROTOCOL_TOR }, + { 0xBC603CB8, 32, NDPI_PROTOCOL_TOR }, + { 0xBC607AC3, 32, NDPI_PROTOCOL_TOR }, + { 0xBC617F79, 32, NDPI_PROTOCOL_TOR }, + { 0xBC62D521, 32, NDPI_PROTOCOL_TOR }, + { 0xBC6450C9, 32, NDPI_PROTOCOL_TOR }, + { 0xBC67690F, 32, NDPI_PROTOCOL_TOR }, + { 0xBC676B47, 32, NDPI_PROTOCOL_TOR }, + { 0xBC6CD29D, 32, NDPI_PROTOCOL_TOR }, + { 0xBC6D5CC5, 32, NDPI_PROTOCOL_TOR }, + { 0xBC717278, 32, NDPI_PROTOCOL_TOR }, + { 0xBC728C79, 32, NDPI_PROTOCOL_TOR }, + { 0xBC769BEF, 32, NDPI_PROTOCOL_TOR }, + { 0xBC780C35, 32, NDPI_PROTOCOL_TOR }, + { 0xBC78EBA5, 32, NDPI_PROTOCOL_TOR }, + { 0xBC78EFF1, 32, NDPI_PROTOCOL_TOR }, + { 0xBC78FD27, 32, NDPI_PROTOCOL_TOR }, + { 0xBC7A05A1, 32, NDPI_PROTOCOL_TOR }, + { 0xBC7AD504, 32, NDPI_PROTOCOL_TOR }, + { 0xBC7B2F13, 32, NDPI_PROTOCOL_TOR }, + { 0xBC7C951D, 32, NDPI_PROTOCOL_TOR }, + { 0xBC7E5D51, 32, NDPI_PROTOCOL_TOR }, + { 0xBC7E5D5F, 32, NDPI_PROTOCOL_TOR }, + { 0xBC817CFA, 32, NDPI_PROTOCOL_TOR }, + { 0xBC860642, 32, NDPI_PROTOCOL_TOR }, + { 0xBC860C22, 32, NDPI_PROTOCOL_TOR }, + { 0xBC860CEC, 32, NDPI_PROTOCOL_TOR }, + { 0xBC864432, 32, NDPI_PROTOCOL_TOR }, + { 0xBC864BD3, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8653AB, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A01E5, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A01E5, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A0931, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A0931, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A09D0, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A09D0, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A110F, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A110F, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A5886, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A58A8, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A6574, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A6A8A, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A703C, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A70E2, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A7976, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A7DD1, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8A7DD1, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8D5359, 32, NDPI_PROTOCOL_TOR }, + { 0xBC8E70F6, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA5033F, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA5033F, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA519D2, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA51A0D, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA51A0D, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA53B2B, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA55E69, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA57B5F, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA57BF4, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA58822, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA58A8D, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA58AB5, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA58AB5, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA5919D, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA5A4A3, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA5A4A3, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA5C181, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA5C88A, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA5D59C, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA5E828, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA5EC12, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA5F1D8, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA609DA, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA60CD4, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA60DE6, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA61250, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA61286, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA6234D, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA624A3, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA625AD, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA625D7, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA62B21, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA62B3D, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA62BC8, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA62D23, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA62EAB, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA63064, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA630B1, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA63152, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA631B4, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA63271, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA63575, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA638B3, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA63C9E, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA63E18, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA73D86, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA745E0, 32, NDPI_PROTOCOL_TOR }, + { 0xBCA8225A, 32, NDPI_PROTOCOL_TOR }, + { 0xBCAE49D9, 32, NDPI_PROTOCOL_TOR }, + { 0xBCAE5D48, 32, NDPI_PROTOCOL_TOR }, + { 0xBCAEA791, 32, NDPI_PROTOCOL_TOR }, + { 0xBCAEB379, 32, NDPI_PROTOCOL_TOR }, + { 0xBCAED97F, 32, NDPI_PROTOCOL_TOR }, + { 0xBCB55D55, 32, NDPI_PROTOCOL_TOR }, + { 0xBCB7841D, 32, NDPI_PROTOCOL_TOR }, + { 0xBCBA10EC, 32, NDPI_PROTOCOL_TOR }, + { 0xBCC02309, 32, NDPI_PROTOCOL_TOR }, + { 0xBCC0A86E, 32, NDPI_PROTOCOL_TOR }, + { 0xBCC1632B, 32, NDPI_PROTOCOL_TOR }, + { 0xBCC1C8F8, 32, NDPI_PROTOCOL_TOR }, + { 0xBCC2C9AE, 32, NDPI_PROTOCOL_TOR }, + { 0xBCC30886, 32, NDPI_PROTOCOL_TOR }, + { 0xBCC348B3, 32, NDPI_PROTOCOL_TOR }, + { 0xBCC3D1FD, 32, NDPI_PROTOCOL_TOR }, + { 0xBCCAFCC1, 32, NDPI_PROTOCOL_TOR }, + { 0xBCD519EA, 32, NDPI_PROTOCOL_TOR }, + { 0xBCD58F17, 32, NDPI_PROTOCOL_TOR }, + { 0xBCD65D16, 32, NDPI_PROTOCOL_TOR }, + { 0xBCDF3258, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE23EAE, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE294A1, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2957C, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2AB6F, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2ACAA, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2BB8A, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2BD35, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2BE71, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2BF12, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2C030, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2C5E0, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2C7A0, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2C8D8, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2CEC8, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2D6B1, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2D98E, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2DC10, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2DCE2, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2DDF3, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2E196, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2E396, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2E839, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2FA52, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2FDB5, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE2FE59, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE3C986, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE3E068, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE4234B, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE43194, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE63CF6, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE65B87, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE6A6EB, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE6DFB2, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE8B717, 32, NDPI_PROTOCOL_TOR }, + { 0xBCE94947, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF17195, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF17251, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF18C77, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF18C86, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF18C94, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF18D13, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF18D15, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF18D87, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF18DAA, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF423AB, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF64BB2, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF6CC43, 32, NDPI_PROTOCOL_TOR }, + { 0xBCF764B8, 32, NDPI_PROTOCOL_TOR }, + { 0xBCFF1E24, 32, NDPI_PROTOCOL_TOR }, + { 0xBCFF70E0, 32, NDPI_PROTOCOL_TOR }, + { 0xBD446D80, 32, NDPI_PROTOCOL_TOR }, + { 0xBDD4A056, 32, NDPI_PROTOCOL_TOR }, + { 0xBDF2D9EF, 32, NDPI_PROTOCOL_TOR }, + { 0xBE03A993, 32, NDPI_PROTOCOL_TOR }, + { 0xBE589587, 32, NDPI_PROTOCOL_TOR }, + { 0xBE78E41E, 32, NDPI_PROTOCOL_TOR }, + { 0xBE7B2D60, 32, NDPI_PROTOCOL_TOR }, + { 0xBE7B2F74, 32, NDPI_PROTOCOL_TOR }, + { 0xBEBD7608, 32, NDPI_PROTOCOL_TOR }, + { 0xBEC0A60C, 32, NDPI_PROTOCOL_TOR }, + { 0xBEE25D6B, 32, NDPI_PROTOCOL_TOR }, + { 0xBF151340, 32, NDPI_PROTOCOL_TOR }, + { 0xBF6502EB, 32, NDPI_PROTOCOL_TOR }, + { 0xBF6598A6, 32, NDPI_PROTOCOL_TOR }, + { 0xBFEFD3DC, 32, NDPI_PROTOCOL_TOR }, + { 0xC0009D29, 32, NDPI_PROTOCOL_TOR }, + { 0xC0031CF2, 32, NDPI_PROTOCOL_TOR }, + { 0xC0031EDF, 32, NDPI_PROTOCOL_TOR }, + { 0xC0039416, 32, NDPI_PROTOCOL_TOR }, + { 0xC003941B, 32, NDPI_PROTOCOL_TOR }, + { 0xC00396AA, 32, NDPI_PROTOCOL_TOR }, + { 0xC0039DD4, 32, NDPI_PROTOCOL_TOR }, + { 0xC003A076, 32, NDPI_PROTOCOL_TOR }, + { 0xC003A4E3, 32, NDPI_PROTOCOL_TOR }, + { 0xC003ACEC, 32, NDPI_PROTOCOL_TOR }, + { 0xC003AD58, 32, NDPI_PROTOCOL_TOR }, + { 0xC003B1A7, 32, NDPI_PROTOCOL_TOR }, + { 0xC003B426, 32, NDPI_PROTOCOL_TOR }, + { 0xC003C9E2, 32, NDPI_PROTOCOL_TOR }, + { 0xC003C9F9, 32, NDPI_PROTOCOL_TOR }, + { 0xC003D27D, 32, NDPI_PROTOCOL_TOR }, + { 0xC00C211A, 32, NDPI_PROTOCOL_TOR }, + { 0xC00C211B, 32, NDPI_PROTOCOL_TOR }, + { 0xC01E202C, 32, NDPI_PROTOCOL_TOR }, + { 0xC0223B30, 32, NDPI_PROTOCOL_TOR }, + { 0xC0223F89, 32, NDPI_PROTOCOL_TOR }, + { 0xC022E022, 32, NDPI_PROTOCOL_TOR }, + { 0xC0264C03, 32, NDPI_PROTOCOL_TOR }, + { 0xC0266D90, 32, NDPI_PROTOCOL_TOR }, + { 0xC02A7410, 32, NDPI_PROTOCOL_TOR }, + { 0xC02A74A1, 32, NDPI_PROTOCOL_TOR }, + { 0xC02BF408, 32, NDPI_PROTOCOL_TOR }, + { 0xC02BF408, 32, NDPI_PROTOCOL_TOR }, + { 0xC02BF42A, 32, NDPI_PROTOCOL_TOR }, + { 0xC02BF42A, 32, NDPI_PROTOCOL_TOR }, + { 0xC02C1E28, 32, NDPI_PROTOCOL_TOR }, + { 0xC0405266, 32, NDPI_PROTOCOL_TOR }, + { 0xC043DE05, 32, NDPI_PROTOCOL_TOR }, + { 0xC045177C, 32, NDPI_PROTOCOL_TOR }, + { 0xC0455E39, 32, NDPI_PROTOCOL_TOR }, + { 0xC0479724, 32, NDPI_PROTOCOL_TOR }, + { 0xC047DAA0, 32, NDPI_PROTOCOL_TOR }, + { 0xC047F524, 32, NDPI_PROTOCOL_TOR }, + { 0xC047F589, 32, NDPI_PROTOCOL_TOR }, + { 0xC047F589, 32, NDPI_PROTOCOL_TOR }, + { 0xC047F5D7, 32, NDPI_PROTOCOL_TOR }, + { 0xC049EC12, 32, NDPI_PROTOCOL_TOR }, + { 0xC049EF53, 32, NDPI_PROTOCOL_TOR }, + { 0xC051842E, 32, NDPI_PROTOCOL_TOR }, + { 0xC051DC5B, 32, NDPI_PROTOCOL_TOR }, + { 0xC051DDA2, 32, NDPI_PROTOCOL_TOR }, + { 0xC051F91F, 32, NDPI_PROTOCOL_TOR }, + { 0xC0571C1C, 32, NDPI_PROTOCOL_TOR }, + { 0xC0571C52, 32, NDPI_PROTOCOL_TOR }, + { 0xC057E0BD, 32, NDPI_PROTOCOL_TOR }, + { 0xC05BEBE6, 32, NDPI_PROTOCOL_TOR }, + { 0xC05F1A3A, 32, NDPI_PROTOCOL_TOR }, + { 0xC05F1B8F, 32, NDPI_PROTOCOL_TOR }, + { 0xC05F2889, 32, NDPI_PROTOCOL_TOR }, + { 0xC05F2CA9, 32, NDPI_PROTOCOL_TOR }, + { 0xC0630289, 32, NDPI_PROTOCOL_TOR }, + { 0xC0630289, 32, NDPI_PROTOCOL_TOR }, + { 0xC0630620, 32, NDPI_PROTOCOL_TOR }, + { 0xC0630852, 32, NDPI_PROTOCOL_TOR }, + { 0xC0630B30, 32, NDPI_PROTOCOL_TOR }, + { 0xC0630F7A, 32, NDPI_PROTOCOL_TOR }, + { 0xC0630FDC, 32, NDPI_PROTOCOL_TOR }, + { 0xC063259C, 32, NDPI_PROTOCOL_TOR }, + { 0xC0632B71, 32, NDPI_PROTOCOL_TOR }, + { 0xC0632B9C, 32, NDPI_PROTOCOL_TOR }, + { 0xC0632BCE, 32, NDPI_PROTOCOL_TOR }, + { 0xC063681B, 32, NDPI_PROTOCOL_TOR }, + { 0xC063914E, 32, NDPI_PROTOCOL_TOR }, + { 0xC0639A18, 32, NDPI_PROTOCOL_TOR }, + { 0xC0639A4B, 32, NDPI_PROTOCOL_TOR }, + { 0xC0639A50, 32, NDPI_PROTOCOL_TOR }, + { 0xC0639AEA, 32, NDPI_PROTOCOL_TOR }, + { 0xC063A866, 32, NDPI_PROTOCOL_TOR }, + { 0xC063A93D, 32, NDPI_PROTOCOL_TOR }, + { 0xC063BA5E, 32, NDPI_PROTOCOL_TOR }, + { 0xC063C1C1, 32, NDPI_PROTOCOL_TOR }, + { 0xC063D48B, 32, NDPI_PROTOCOL_TOR }, + { 0xC063D497, 32, NDPI_PROTOCOL_TOR }, + { 0xC063F665, 32, NDPI_PROTOCOL_TOR }, + { 0xC063F7EA, 32, NDPI_PROTOCOL_TOR }, + { 0xC063FA8F, 32, NDPI_PROTOCOL_TOR }, + { 0xC07247DE, 32, NDPI_PROTOCOL_TOR }, + { 0xC0794208, 32, NDPI_PROTOCOL_TOR }, + { 0xC079AA4B, 32, NDPI_PROTOCOL_TOR }, + { 0xC07CFA53, 32, NDPI_PROTOCOL_TOR }, + { 0xC087A8FB, 32, NDPI_PROTOCOL_TOR }, + { 0xC0965E31, 32, NDPI_PROTOCOL_TOR }, + { 0xC0979A8E, 32, NDPI_PROTOCOL_TOR }, + { 0xC0999AF4, 32, NDPI_PROTOCOL_TOR }, + { 0xC09B506F, 32, NDPI_PROTOCOL_TOR }, + { 0xC09B5365, 32, NDPI_PROTOCOL_TOR }, + { 0xC09B5736, 32, NDPI_PROTOCOL_TOR }, + { 0xC09B5874, 32, NDPI_PROTOCOL_TOR }, + { 0xC09B5D65, 32, NDPI_PROTOCOL_TOR }, + { 0xC09B5F7A, 32, NDPI_PROTOCOL_TOR }, + { 0xC09B5F7A, 32, NDPI_PROTOCOL_TOR }, + { 0xC09B5FDE, 32, NDPI_PROTOCOL_TOR }, + { 0xC09DC04F, 32, NDPI_PROTOCOL_TOR }, + { 0xC09DEFF3, 32, NDPI_PROTOCOL_TOR }, + { 0xC09DFD7D, 32, NDPI_PROTOCOL_TOR }, + { 0xC0A0C16E, 32, NDPI_PROTOCOL_TOR }, + { 0xC0A264D5, 32, NDPI_PROTOCOL_TOR }, + { 0xC0A2650F, 32, NDPI_PROTOCOL_TOR }, + { 0xC0A3E033, 32, NDPI_PROTOCOL_TOR }, + { 0xC0AB3D72, 32, NDPI_PROTOCOL_TOR }, + { 0xC0B82075, 32, NDPI_PROTOCOL_TOR }, + { 0xC0B8502A, 32, NDPI_PROTOCOL_TOR }, + { 0xC0B85175, 32, NDPI_PROTOCOL_TOR }, + { 0xC0B851A0, 32, NDPI_PROTOCOL_TOR }, + { 0xC0B85280, 32, NDPI_PROTOCOL_TOR }, + { 0xC0B8555C, 32, NDPI_PROTOCOL_TOR }, + { 0xC0B858CF, 32, NDPI_PROTOCOL_TOR }, + { 0xC0B85E6F, 32, NDPI_PROTOCOL_TOR }, + { 0xC0BB6A92, 32, NDPI_PROTOCOL_TOR }, + { 0xC0C8EC20, 32, NDPI_PROTOCOL_TOR }, + { 0xC0D28AA3, 32, NDPI_PROTOCOL_TOR }, + { 0xC0D28AAB, 32, NDPI_PROTOCOL_TOR }, + { 0xC0D2C7B1, 32, NDPI_PROTOCOL_TOR }, + { 0xC0D2CC27, 32, NDPI_PROTOCOL_TOR }, + { 0xC0D2CEBD, 32, NDPI_PROTOCOL_TOR }, + { 0xC0D2E780, 32, NDPI_PROTOCOL_TOR }, + { 0xC0D2F0D9, 32, NDPI_PROTOCOL_TOR }, + { 0xC0E28C77, 32, NDPI_PROTOCOL_TOR }, + { 0xC0E38B12, 32, NDPI_PROTOCOL_TOR }, + { 0xC0E38F11, 32, NDPI_PROTOCOL_TOR }, + { 0xC0E3E71B, 32, NDPI_PROTOCOL_TOR }, + { 0xC0EB4E13, 32, NDPI_PROTOCOL_TOR }, + { 0xC0EB4EDB, 32, NDPI_PROTOCOL_TOR }, + { 0xC0EDD411, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F158B5, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F183E9, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1863E, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F192D5, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F19438, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1B238, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1B41B, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1B4A3, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1B57A, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1C4B2, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1C66A, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1C7D0, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1CAD6, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1CEAB, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1D063, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1D265, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1D878, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1E9CB, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1E9F2, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F1FC3F, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F37E51, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F9380B, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F93EB7, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F93F97, 32, NDPI_PROTOCOL_TOR }, + { 0xC0F93F9C, 32, NDPI_PROTOCOL_TOR }, + { 0xC0FC828E, 32, NDPI_PROTOCOL_TOR }, + { 0xC0FEA81A, 32, NDPI_PROTOCOL_TOR }, + { 0xC101C19C, 32, NDPI_PROTOCOL_TOR }, + { 0xC106DE6E, 32, NDPI_PROTOCOL_TOR }, + { 0xC107B1DF, 32, NDPI_PROTOCOL_TOR }, + { 0xC10B722B, 32, NDPI_PROTOCOL_TOR }, + { 0xC10B722D, 32, NDPI_PROTOCOL_TOR }, + { 0xC10B722E, 32, NDPI_PROTOCOL_TOR }, + { 0xC10B722F, 32, NDPI_PROTOCOL_TOR }, + { 0xC10B8978, 32, NDPI_PROTOCOL_TOR }, + { 0xC10BA4F3, 32, NDPI_PROTOCOL_TOR }, + { 0xC10BA6C2, 32, NDPI_PROTOCOL_TOR }, + { 0xC10BA6C2, 32, NDPI_PROTOCOL_TOR }, + { 0xC10C4907, 32, NDPI_PROTOCOL_TOR }, + { 0xC10D6125, 32, NDPI_PROTOCOL_TOR }, + { 0xC10E9FCC, 32, NDPI_PROTOCOL_TOR }, + { 0xC117F4F4, 32, NDPI_PROTOCOL_TOR }, + { 0xC118D194, 32, NDPI_PROTOCOL_TOR }, + { 0xC118D27E, 32, NDPI_PROTOCOL_TOR }, + { 0xC119019D, 32, NDPI_PROTOCOL_TOR }, + { 0xC11CE446, 32, NDPI_PROTOCOL_TOR }, + { 0xC121D817, 32, NDPI_PROTOCOL_TOR }, + { 0xC1220201, 32, NDPI_PROTOCOL_TOR }, + { 0xC1233435, 32, NDPI_PROTOCOL_TOR }, + { 0xC12598C7, 32, NDPI_PROTOCOL_TOR }, + { 0xC12598F1, 32, NDPI_PROTOCOL_TOR }, + { 0xC1530139, 32, NDPI_PROTOCOL_TOR }, + { 0xC15A0C56, 32, NDPI_PROTOCOL_TOR }, + { 0xC15A0C57, 32, NDPI_PROTOCOL_TOR }, + { 0xC15A0C58, 32, NDPI_PROTOCOL_TOR }, + { 0xC15A0C59, 32, NDPI_PROTOCOL_TOR }, + { 0xC15A0C5A, 32, NDPI_PROTOCOL_TOR }, + { 0xC15FE4E8, 32, NDPI_PROTOCOL_TOR }, + { 0xC15FF2D5, 32, NDPI_PROTOCOL_TOR }, + { 0xC168DC23, 32, NDPI_PROTOCOL_TOR }, + { 0xC168DC36, 32, NDPI_PROTOCOL_TOR }, + { 0xC1698632, 32, NDPI_PROTOCOL_TOR }, + { 0xC169869C, 32, NDPI_PROTOCOL_TOR }, + { 0xC16B131E, 32, NDPI_PROTOCOL_TOR }, + { 0xC16B5538, 32, NDPI_PROTOCOL_TOR }, + { 0xC16B5539, 32, NDPI_PROTOCOL_TOR }, + { 0xC16B553D, 32, NDPI_PROTOCOL_TOR }, + { 0xC16B553E, 32, NDPI_PROTOCOL_TOR }, + { 0xC16E9D97, 32, NDPI_PROTOCOL_TOR }, + { 0xC16F1A16, 32, NDPI_PROTOCOL_TOR }, + { 0xC16F8D6E, 32, NDPI_PROTOCOL_TOR }, + { 0xC188CC75, 32, NDPI_PROTOCOL_TOR }, + { 0xC189ADD9, 32, NDPI_PROTOCOL_TOR }, + { 0xC18A7603, 32, NDPI_PROTOCOL_TOR }, + { 0xC18A7608, 32, NDPI_PROTOCOL_TOR }, + { 0xC18AD865, 32, NDPI_PROTOCOL_TOR }, + { 0xC1960E3E, 32, NDPI_PROTOCOL_TOR }, + { 0xC196791A, 32, NDPI_PROTOCOL_TOR }, + { 0xC1967942, 32, NDPI_PROTOCOL_TOR }, + { 0xC19A0D98, 32, NDPI_PROTOCOL_TOR }, + { 0xC19D73FA, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A3DC8F, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A48535, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A4D955, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A744, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A745, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A746, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A747, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A748, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A749, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A74A, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A74B, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A74C, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A74D, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A74E, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A74F, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A750, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A751, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A752, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A753, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A754, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A755, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A756, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A757, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A758, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A759, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A75A, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A75B, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A75C, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A75D, 32, NDPI_PROTOCOL_TOR }, + { 0xC1A6A75E, 32, NDPI_PROTOCOL_TOR }, + { 0xC1AE0614, 32, NDPI_PROTOCOL_TOR }, + { 0xC1B69035, 32, NDPI_PROTOCOL_TOR }, + { 0xC1B763D5, 32, NDPI_PROTOCOL_TOR }, + { 0xC1BEA835, 32, NDPI_PROTOCOL_TOR }, + { 0xC1CB312E, 32, NDPI_PROTOCOL_TOR }, + { 0xC1DB24CF, 32, NDPI_PROTOCOL_TOR }, + { 0xC1E0A32B, 32, NDPI_PROTOCOL_TOR }, + { 0xC1F66F3E, 32, NDPI_PROTOCOL_TOR }, + { 0xC20EB3B8, 32, NDPI_PROTOCOL_TOR }, + { 0xC2173CFA, 32, NDPI_PROTOCOL_TOR }, + { 0xC230DA31, 32, NDPI_PROTOCOL_TOR }, + { 0xC2601297, 32, NDPI_PROTOCOL_TOR }, + { 0xC2680064, 32, NDPI_PROTOCOL_TOR }, + { 0xC26DCED4, 32, NDPI_PROTOCOL_TOR }, + { 0xC276346F, 32, NDPI_PROTOCOL_TOR }, + { 0xC276D253, 32, NDPI_PROTOCOL_TOR }, + { 0xC27EC6E4, 32, NDPI_PROTOCOL_TOR }, + { 0xC296A84F, 32, NDPI_PROTOCOL_TOR }, + { 0xC296A85F, 32, NDPI_PROTOCOL_TOR }, + { 0xC296A86C, 32, NDPI_PROTOCOL_TOR }, + { 0xC2A6A031, 32, NDPI_PROTOCOL_TOR }, + { 0xC313AE72, 32, NDPI_PROTOCOL_TOR }, + { 0xC313AE73, 32, NDPI_PROTOCOL_TOR }, + { 0xC31DA8CE, 32, NDPI_PROTOCOL_TOR }, + { 0xC3236D3D, 32, NDPI_PROTOCOL_TOR }, + { 0xC325BE55, 32, NDPI_PROTOCOL_TOR }, + { 0xC328B523, 32, NDPI_PROTOCOL_TOR }, + { 0xC32EB925, 32, NDPI_PROTOCOL_TOR }, + { 0xC3409582, 32, NDPI_PROTOCOL_TOR }, + { 0xC3474454, 32, NDPI_PROTOCOL_TOR }, + { 0xC3527C6F, 32, NDPI_PROTOCOL_TOR }, + { 0xC358543B, 32, NDPI_PROTOCOL_TOR }, + { 0xC35BED96, 32, NDPI_PROTOCOL_TOR }, + { 0xC36E061F, 32, NDPI_PROTOCOL_TOR }, + { 0xC36E09E8, 32, NDPI_PROTOCOL_TOR }, + { 0xC38AF902, 32, NDPI_PROTOCOL_TOR }, + { 0xC38CFE59, 32, NDPI_PROTOCOL_TOR }, + { 0xC3947CC7, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A057B, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A05CD, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A0937, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A0A9B, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A0C42, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A0D0A, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A0D60, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A0E28, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A0F75, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A2A65, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A40D6, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A411D, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A43E5, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A4682, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A4B54, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A4BA5, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A4DC8, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A4E71, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A4E73, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A516C, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A516E, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A51E3, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A51F5, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A5258, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A533C, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A57E7, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A5B8B, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A610A, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6111, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A611B, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A61A0, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6775, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6886, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6935, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6939, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6B56, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6B97, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6C4E, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6D1E, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6D34, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6D9D, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6DCB, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6DDD, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A6E4C, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A7095, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A72B9, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A742B, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A74E8, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A75A3, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A76AC, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A7763, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A79C6, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A79EA, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A7BDE, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A7E2B, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A7EA5, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A7FF6, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A803A, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A8097, 32, NDPI_PROTOCOL_TOR }, + { 0xC39A8879, 32, NDPI_PROTOCOL_TOR }, + { 0xC39AA671, 32, NDPI_PROTOCOL_TOR }, + { 0xC39AA671, 32, NDPI_PROTOCOL_TOR }, + { 0xC39AAF14, 32, NDPI_PROTOCOL_TOR }, + { 0xC39AB416, 32, NDPI_PROTOCOL_TOR }, + { 0xC39AD7F0, 32, NDPI_PROTOCOL_TOR }, + { 0xC39ADDED, 32, NDPI_PROTOCOL_TOR }, + { 0xC39AE205, 32, NDPI_PROTOCOL_TOR }, + { 0xC39AE93A, 32, NDPI_PROTOCOL_TOR }, + { 0xC39AF076, 32, NDPI_PROTOCOL_TOR }, + { 0xC39AFB5E, 32, NDPI_PROTOCOL_TOR }, + { 0xC39FA2C2, 32, NDPI_PROTOCOL_TOR }, + { 0xC3A6C926, 32, NDPI_PROTOCOL_TOR }, + { 0xC3A97DE2, 32, NDPI_PROTOCOL_TOR }, + { 0xC3A9C4BC, 32, NDPI_PROTOCOL_TOR }, + { 0xC3A9CF36, 32, NDPI_PROTOCOL_TOR }, + { 0xC3A9D8BF, 32, NDPI_PROTOCOL_TOR }, + { 0xC3B2B57B, 32, NDPI_PROTOCOL_TOR }, + { 0xC3B40BC4, 32, NDPI_PROTOCOL_TOR }, + { 0xC3BFE9DD, 32, NDPI_PROTOCOL_TOR }, + { 0xC3C6F2C2, 32, NDPI_PROTOCOL_TOR }, + { 0xC3CAD33B, 32, NDPI_PROTOCOL_TOR }, + { 0xC3D21DED, 32, NDPI_PROTOCOL_TOR }, + { 0xC3E1D31A, 32, NDPI_PROTOCOL_TOR }, + { 0xC3E42DB0, 32, NDPI_PROTOCOL_TOR }, + { 0xC3E44B83, 32, NDPI_PROTOCOL_TOR }, + { 0xC3E6A853, 32, NDPI_PROTOCOL_TOR }, + { 0xC3EA9856, 32, NDPI_PROTOCOL_TOR }, + { 0xC3F25002, 32, NDPI_PROTOCOL_TOR }, + { 0xC3FAA3B1, 32, NDPI_PROTOCOL_TOR }, + { 0xC3FBFCE2, 32, NDPI_PROTOCOL_TOR }, + { 0xC4252C59, 32, NDPI_PROTOCOL_TOR }, + { 0xC55752E7, 32, NDPI_PROTOCOL_TOR }, + { 0xC5E7DDD3, 32, NDPI_PROTOCOL_TOR }, + { 0xC60C50BB, 32, NDPI_PROTOCOL_TOR }, + { 0xC60C5B69, 32, NDPI_PROTOCOL_TOR }, + { 0xC60C68D0, 32, NDPI_PROTOCOL_TOR }, + { 0xC60F4FC5, 32, NDPI_PROTOCOL_TOR }, + { 0xC61799A1, 32, NDPI_PROTOCOL_TOR }, + { 0xC617B141, 32, NDPI_PROTOCOL_TOR }, + { 0xC617BB9E, 32, NDPI_PROTOCOL_TOR }, + { 0xC617F7CC, 32, NDPI_PROTOCOL_TOR }, + { 0xC61B447E, 32, NDPI_PROTOCOL_TOR }, + { 0xC61B562B, 32, NDPI_PROTOCOL_TOR }, + { 0xC61B562D, 32, NDPI_PROTOCOL_TOR }, + { 0xC61B6D24, 32, NDPI_PROTOCOL_TOR }, + { 0xC6257224, 32, NDPI_PROTOCOL_TOR }, + { 0xC62E8E4A, 32, NDPI_PROTOCOL_TOR }, + { 0xC62E9933, 32, NDPI_PROTOCOL_TOR }, + { 0xC6329148, 32, NDPI_PROTOCOL_TOR }, + { 0xC63291CF, 32, NDPI_PROTOCOL_TOR }, + { 0xC6329228, 32, NDPI_PROTOCOL_TOR }, + { 0xC63292FC, 32, NDPI_PROTOCOL_TOR }, + { 0xC63293EF, 32, NDPI_PROTOCOL_TOR }, + { 0xC632957F, 32, NDPI_PROTOCOL_TOR }, + { 0xC63295A0, 32, NDPI_PROTOCOL_TOR }, + { 0xC632970A, 32, NDPI_PROTOCOL_TOR }, + { 0xC6329766, 32, NDPI_PROTOCOL_TOR }, + { 0xC6329811, 32, NDPI_PROTOCOL_TOR }, + { 0xC6329C4E, 32, NDPI_PROTOCOL_TOR }, + { 0xC632B758, 32, NDPI_PROTOCOL_TOR }, + { 0xC632BF5F, 32, NDPI_PROTOCOL_TOR }, + { 0xC632E716, 32, NDPI_PROTOCOL_TOR }, + { 0xC63482DA, 32, NDPI_PROTOCOL_TOR }, + { 0xC634A041, 32, NDPI_PROTOCOL_TOR }, + { 0xC634A090, 32, NDPI_PROTOCOL_TOR }, + { 0xC634C827, 32, NDPI_PROTOCOL_TOR }, + { 0xC634F4ED, 32, NDPI_PROTOCOL_TOR }, + { 0xC634F7A0, 32, NDPI_PROTOCOL_TOR }, + { 0xC634F7A2, 32, NDPI_PROTOCOL_TOR }, + { 0xC634F7F7, 32, NDPI_PROTOCOL_TOR }, + { 0xC634F7FA, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A601C, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A6079, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A66EA, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A6793, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A6793, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A6AF5, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A6AF5, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A6B34, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A6B34, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A6B35, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A6D52, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A73D2, 32, NDPI_PROTOCOL_TOR }, + { 0xC63A7FC9, 32, NDPI_PROTOCOL_TOR }, + { 0xC6475142, 32, NDPI_PROTOCOL_TOR }, + { 0xC648E7E9, 32, NDPI_PROTOCOL_TOR }, + { 0xC6493247, 32, NDPI_PROTOCOL_TOR }, + { 0xC64A38BF, 32, NDPI_PROTOCOL_TOR }, + { 0xC64A3A10, 32, NDPI_PROTOCOL_TOR }, +{ 0xC64A3ACE, 32, NDPI_PROTOCOL_TOR }, +{ 0xC64A3C1A, 32, NDPI_PROTOCOL_TOR }, +{ 0xC64A3E6B, 32, NDPI_PROTOCOL_TOR }, +{ 0xC654A10C, 32, NDPI_PROTOCOL_TOR }, +{ 0xC654F0E5, 32, NDPI_PROTOCOL_TOR }, +{ 0xC654F96A, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6609B03, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6623103, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6623495, 32, NDPI_PROTOCOL_TOR }, +{ 0xC662358D, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6649014, 32, NDPI_PROTOCOL_TOR }, +{ 0xC664904B, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6649470, 32, NDPI_PROTOCOL_TOR }, +{ 0xC664947B, 32, NDPI_PROTOCOL_TOR }, +{ 0xC664959F, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6649B36, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6649BC2, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6697D25, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6697DB2, 32, NDPI_PROTOCOL_TOR }, +{ 0xC669D0A4, 32, NDPI_PROTOCOL_TOR }, +{ 0xC669DF92, 32, NDPI_PROTOCOL_TOR }, +{ 0xC68F88ED, 32, NDPI_PROTOCOL_TOR }, +{ 0xC693141D, 32, NDPI_PROTOCOL_TOR }, +{ 0xC693174D, 32, NDPI_PROTOCOL_TOR }, +{ 0xC69451A7, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6A7895C, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6A78F95, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6B49609, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6C74845, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6C76BDC, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6C77079, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6C77231, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6C775A4, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6C77A11, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6CD713B, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6D36392, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6D37ABF, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6D37B5C, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6D37CD6, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6D37DF2, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6D37E53, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6F464C8, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6F46963, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6F53294, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6F53C28, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6F53C93, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6F53CC2, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6F53E68, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6F53FE4, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6FC9957, 32, NDPI_PROTOCOL_TOR }, +{ 0xC6FC996B, 32, NDPI_PROTOCOL_TOR }, +{ 0xC710BF3A, 32, NDPI_PROTOCOL_TOR }, +{ 0xC71355FC, 32, NDPI_PROTOCOL_TOR }, +{ 0xC713D5B0, 32, NDPI_PROTOCOL_TOR }, +{ 0xC726567A, 32, NDPI_PROTOCOL_TOR }, +{ 0xC73A530A, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7579AFF, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7737387, 32, NDPI_PROTOCOL_TOR }, +{ 0xC773CDF1, 32, NDPI_PROTOCOL_TOR }, +{ 0xC773CDF2, 32, NDPI_PROTOCOL_TOR }, +{ 0xC773CDF3, 32, NDPI_PROTOCOL_TOR }, +{ 0xC773CDF5, 32, NDPI_PROTOCOL_TOR }, +{ 0xC773CDF8, 32, NDPI_PROTOCOL_TOR }, +{ 0xC77FE240, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7A78088, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7A7A1C3, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7A7C679, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7BC649A, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7BCC235, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7C173D1, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7C1FD31, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7C3C116, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7C3F83C, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7C3F890, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7C3F9D4, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7CA151D, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7FEEE2C, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7FEEE34, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7FEEE34, 32, NDPI_PROTOCOL_TOR }, +{ 0xC7FFDF58, 32, NDPI_PROTOCOL_TOR }, +{ 0xC811D20C, 32, NDPI_PROTOCOL_TOR }, +{ 0xC8628B17, 32, NDPI_PROTOCOL_TOR }, +{ 0xC86CEC4B, 32, NDPI_PROTOCOL_TOR }, +{ 0xC8B55A41, 32, NDPI_PROTOCOL_TOR }, +{ 0xC8DFD4D2, 32, NDPI_PROTOCOL_TOR }, +{ 0xC906897F, 32, NDPI_PROTOCOL_TOR }, +{ 0xC91BEB7F, 32, NDPI_PROTOCOL_TOR }, +{ 0xC9AA12B7, 32, NDPI_PROTOCOL_TOR }, +{ 0xC9D46CB8, 32, NDPI_PROTOCOL_TOR }, +{ 0xC9DA72A2, 32, NDPI_PROTOCOL_TOR }, +{ 0xCA07F408, 32, NDPI_PROTOCOL_TOR }, +{ 0xCA3C4220, 32, NDPI_PROTOCOL_TOR }, +{ 0xCA4A2C0F, 32, NDPI_PROTOCOL_TOR }, +{ 0xCA536AB3, 32, NDPI_PROTOCOL_TOR }, +{ 0xCA55E922, 32, NDPI_PROTOCOL_TOR }, +{ 0xCAAB9C54, 32, NDPI_PROTOCOL_TOR }, +{ 0xCAAC1039, 32, NDPI_PROTOCOL_TOR }, +{ 0xCB56CAA7, 32, NDPI_PROTOCOL_TOR }, +{ 0xCB56CD2E, 32, NDPI_PROTOCOL_TOR }, +{ 0xCB6DE90F, 32, NDPI_PROTOCOL_TOR }, +{ 0xCB71AC95, 32, NDPI_PROTOCOL_TOR }, +{ 0xCB71AC98, 32, NDPI_PROTOCOL_TOR }, +{ 0xCB71AC9A, 32, NDPI_PROTOCOL_TOR }, +{ 0xCB7B3001, 32, NDPI_PROTOCOL_TOR }, +{ 0xCB7E7B52, 32, NDPI_PROTOCOL_TOR }, +{ 0xCB8A63DA, 32, NDPI_PROTOCOL_TOR }, +{ 0xCB98C302, 32, NDPI_PROTOCOL_TOR }, +{ 0xCB99CEA6, 32, NDPI_PROTOCOL_TOR }, +{ 0xCBA16711, 32, NDPI_PROTOCOL_TOR }, +{ 0xCBB2850B, 32, NDPI_PROTOCOL_TOR }, +{ 0xCBCEEDC5, 32, NDPI_PROTOCOL_TOR }, +{ 0xCBD9AD92, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC089C8E, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC093747, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC0B3283, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC1025F4, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC11382A, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC11382A, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC1B382D, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC1B382D, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC1B3ACA, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC2D1E7A, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC2D1E7D, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC2DB6E2, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC534638, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC55BF1E, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC59C10A, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC7C5382, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC7C5382, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC7C5386, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC7C5386, 32, NDPI_PROTOCOL_TOR }, +{ 0xCC91512D, 32, NDPI_PROTOCOL_TOR }, +{ 0xCCC21D04, 32, NDPI_PROTOCOL_TOR }, +{ 0xCCF67A48, 32, NDPI_PROTOCOL_TOR }, +{ 0xCDA85485, 32, NDPI_PROTOCOL_TOR }, +{ 0xCDB973EA, 32, NDPI_PROTOCOL_TOR }, +{ 0xCDB97A98, 32, NDPI_PROTOCOL_TOR }, +{ 0xCE2876E5, 32, NDPI_PROTOCOL_TOR }, +{ 0xCE374A00, 32, NDPI_PROTOCOL_TOR }, +{ 0xCE374A01, 32, NDPI_PROTOCOL_TOR }, +{ 0xCE48C698, 32, NDPI_PROTOCOL_TOR }, +{ 0xCEAE7054, 32, NDPI_PROTOCOL_TOR }, +{ 0xCEBE9906, 32, NDPI_PROTOCOL_TOR }, +{ 0xCF268613, 32, NDPI_PROTOCOL_TOR }, +{ 0xCF6CDABA, 32, NDPI_PROTOCOL_TOR }, +{ 0xCF9E0F72, 32, NDPI_PROTOCOL_TOR }, +{ 0xCFACD159, 32, NDPI_PROTOCOL_TOR }, +{ 0xCFBD72D7, 32, NDPI_PROTOCOL_TOR }, +{ 0xCFC046FA, 32, NDPI_PROTOCOL_TOR }, +{ 0xCFC9DFC3, 32, NDPI_PROTOCOL_TOR }, +{ 0xCFC9DFC4, 32, NDPI_PROTOCOL_TOR }, +{ 0xCFC9DFC5, 32, NDPI_PROTOCOL_TOR }, +{ 0xCFE54199, 32, NDPI_PROTOCOL_TOR }, +{ 0xCFF44B8E, 32, NDPI_PROTOCOL_TOR }, +{ 0xCFF4526D, 32, NDPI_PROTOCOL_TOR }, +{ 0xCFF4526D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD041B5BD, 32, NDPI_PROTOCOL_TOR }, +{ 0xD0421E1B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD049CCE4, 32, NDPI_PROTOCOL_TOR }, +{ 0xD04FD17C, 32, NDPI_PROTOCOL_TOR }, +{ 0xD04FD34D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD0509A27, 32, NDPI_PROTOCOL_TOR }, +{ 0xD0526625, 32, NDPI_PROTOCOL_TOR }, +{ 0xD053DF22, 32, NDPI_PROTOCOL_TOR }, +{ 0xD053DFE5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD0549BCD, 32, NDPI_PROTOCOL_TOR }, +{ 0xD0549BF3, 32, NDPI_PROTOCOL_TOR }, +{ 0xD0549BF7, 32, NDPI_PROTOCOL_TOR }, +{ 0xD056FB58, 32, NDPI_PROTOCOL_TOR }, +{ 0xD05B798E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD065161A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD06F2350, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1063507, 32, NDPI_PROTOCOL_TOR }, +{ 0xD106441D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD10685EE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD111BF75, 32, NDPI_PROTOCOL_TOR }, +{ 0xD12C72B2, 32, NDPI_PROTOCOL_TOR }, +{ 0xD133A319, 32, NDPI_PROTOCOL_TOR }, +{ 0xD133BFBE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1709F3C, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC25, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC25, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC26, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC26, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC27, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC27, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC28, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC28, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC29, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC29, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC2A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD177BC2A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD17BA242, 32, NDPI_PROTOCOL_TOR }, +{ 0xD17E47E9, 32, NDPI_PROTOCOL_TOR }, +{ 0xD17E4854, 32, NDPI_PROTOCOL_TOR }, +{ 0xD17E6907, 32, NDPI_PROTOCOL_TOR }, +{ 0xD18D23E8, 32, NDPI_PROTOCOL_TOR }, +{ 0xD18D242A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD18D2ECC, 32, NDPI_PROTOCOL_TOR }, +{ 0xD18D328A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD18D34EF, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1942E81, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1942E82, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1942E82, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1945576, 32, NDPI_PROTOCOL_TOR }, +{ 0xD19F8A13, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1A221CF, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1B5E383, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1D01A29, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1D04F05, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1D2D215, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1DE08C4, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1DE1EF1, 32, NDPI_PROTOCOL_TOR }, +{ 0xD1FA02FE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD217021E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD23625E2, 32, NDPI_PROTOCOL_TOR }, +{ 0xD2A6194E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD2C33DFC, 32, NDPI_PROTOCOL_TOR }, +{ 0xD2D37ACC, 32, NDPI_PROTOCOL_TOR }, +{ 0xD2FBD989, 32, NDPI_PROTOCOL_TOR }, +{ 0xD31AF36D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD31C8EEF, 32, NDPI_PROTOCOL_TOR }, +{ 0xD31FC4F8, 32, NDPI_PROTOCOL_TOR }, +{ 0xD3CA291F, 32, NDPI_PROTOCOL_TOR }, +{ 0xD407C247, 32, NDPI_PROTOCOL_TOR }, +{ 0xD407DC06, 32, NDPI_PROTOCOL_TOR }, +{ 0xD40A5604, 32, NDPI_PROTOCOL_TOR }, +{ 0xD40CCB27, 32, NDPI_PROTOCOL_TOR }, +{ 0xD41010B8, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4106821, 32, NDPI_PROTOCOL_TOR }, +{ 0xD411664D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD41824CD, 32, NDPI_PROTOCOL_TOR }, +{ 0xD41890BC, 32, NDPI_PROTOCOL_TOR }, +{ 0xD421F581, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE209, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE3AC, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE3AC, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE445, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE459, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE5D1, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE5D1, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE745, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE784, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE80D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE8F6, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FE97E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FEA54, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FEB57, 32, NDPI_PROTOCOL_TOR }, +{ 0xD42FECDB, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4305435, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4339C5A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4339C8F, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4339C9E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4339C9E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4339F4E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4339F72, 32, NDPI_PROTOCOL_TOR }, +{ 0xD438D698, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4402044, 32, NDPI_PROTOCOL_TOR }, +{ 0xD447EECB, 32, NDPI_PROTOCOL_TOR }, +{ 0xD447F805, 32, NDPI_PROTOCOL_TOR }, +{ 0xD447F945, 32, NDPI_PROTOCOL_TOR }, +{ 0xD447F945, 32, NDPI_PROTOCOL_TOR }, +{ 0xD447F981, 32, NDPI_PROTOCOL_TOR }, +{ 0xD447FC6D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD447FC74, 32, NDPI_PROTOCOL_TOR }, +{ 0xD447FDE2, 32, NDPI_PROTOCOL_TOR }, +{ 0xD44AFEF3, 32, NDPI_PROTOCOL_TOR }, +{ 0xD44DE210, 32, NDPI_PROTOCOL_TOR }, +{ 0xD44DE2F5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4532F5B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD45394CD, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4539A21, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4539A21, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4539E05, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4539E14, 32, NDPI_PROTOCOL_TOR }, +{ 0xD453A298, 32, NDPI_PROTOCOL_TOR }, +{ 0xD453A7AF, 32, NDPI_PROTOCOL_TOR }, +{ 0xD453AAFC, 32, NDPI_PROTOCOL_TOR }, +{ 0xD453B07A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD453B07D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD453BECB, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4554F44, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4554F47, 32, NDPI_PROTOCOL_TOR }, +{ 0xD45CDB0F, 32, NDPI_PROTOCOL_TOR }, +{ 0xD467903A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD46A09CE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD46B9591, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4722F34, 32, NDPI_PROTOCOL_TOR }, +{ 0xD472303A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4726D21, 32, NDPI_PROTOCOL_TOR }, +{ 0xD472FA12, 32, NDPI_PROTOCOL_TOR }, +{ 0xD472FE5B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4758F4A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD475B46B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4763E03, 32, NDPI_PROTOCOL_TOR }, +{ 0xD47CB453, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4810454, 32, NDPI_PROTOCOL_TOR }, +{ 0xD48110B6, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4811AF6, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4812A09, 32, NDPI_PROTOCOL_TOR }, +{ 0xD48132F6, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4813431, 32, NDPI_PROTOCOL_TOR }, +{ 0xD495D15B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD49F5B16, 32, NDPI_PROTOCOL_TOR }, +{ 0xD49F70C4, 32, NDPI_PROTOCOL_TOR }, +{ 0xD49F8F53, 32, NDPI_PROTOCOL_TOR }, +{ 0xD49FB1C6, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4A4EF79, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4B733DE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4BA59A2, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4BBC8AA, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4C04A64, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4C04A65, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4C63318, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4C6C924, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4C6E391, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4E054E3, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4E059FD, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4E326F7, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4E38BC3, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4E3F876, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4E81D65, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4FAA0B2, 32, NDPI_PROTOCOL_TOR }, +{ 0xD4FAA0BB, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5095DAE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD52C58EA, 32, NDPI_PROTOCOL_TOR }, +{ 0xD52F2397, 32, NDPI_PROTOCOL_TOR }, +{ 0xD52F4B43, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5317328, 32, NDPI_PROTOCOL_TOR }, +{ 0xD53D957D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD53D957E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD540E2E6, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5430E91, 32, NDPI_PROTOCOL_TOR }, +{ 0xD54951D2, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5497087, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5582A31, 32, NDPI_PROTOCOL_TOR }, +{ 0xD55F1536, 32, NDPI_PROTOCOL_TOR }, +{ 0xD55F153B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD56B4D04, 32, NDPI_PROTOCOL_TOR }, +{ 0xD56C6947, 32, NDPI_PROTOCOL_TOR }, +{ 0xD56C69FD, 32, NDPI_PROTOCOL_TOR }, +{ 0xD56CD7EE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD56FF097, 32, NDPI_PROTOCOL_TOR }, +{ 0xD57086D3, 32, NDPI_PROTOCOL_TOR }, +{ 0xD570C73F, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5713D6A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5717790, 32, NDPI_PROTOCOL_TOR }, +{ 0xD571D5BE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5724869, 32, NDPI_PROTOCOL_TOR }, +{ 0xD57293E0, 32, NDPI_PROTOCOL_TOR }, +{ 0xD572966F, 32, NDPI_PROTOCOL_TOR }, +{ 0xD572E864, 32, NDPI_PROTOCOL_TOR }, +{ 0xD57F85A7, 32, NDPI_PROTOCOL_TOR }, +{ 0xD57F921B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD585639C, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5856D29, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5856DA5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5857B97, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58845ED, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5884715, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5884B2A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5885261, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5885674, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58857F5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5885A9B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5885CA9, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58A653C, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58A66D1, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58A6E58, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58A71E8, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58D8818, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58D8D93, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58D95E3, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58D9EED, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58E2E79, 32, NDPI_PROTOCOL_TOR }, +{ 0xD58F7A02, 32, NDPI_PROTOCOL_TOR }, +{ 0xD59B0490, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5A3482F, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5A348A2, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5A54610, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5A54F22, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5A54FF3, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5A55106, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5A5551E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5A55546, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5A555F9, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5AFD83B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5B39EF1, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5B73821, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5B7388C, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5B9E355, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5BA07E8, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5BB54BE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5BB6FFE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5BC77C9, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5C489E3, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5C5167C, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5C52469, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5D0BCCB, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5D3FC58, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5DE7461, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5E3FAF5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5EFC519, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5EFD329, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5EFD414, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5EFD6AF, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5EFD8DE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5EFD912, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5EFDA14, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5EFDA93, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5EFF9DB, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5F05E3A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5F06C19, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5F53D3D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5FBBB37, 32, NDPI_PROTOCOL_TOR }, +{ 0xD5FBC7AE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD80CC652, 32, NDPI_PROTOCOL_TOR }, +{ 0xD80CC653, 32, NDPI_PROTOCOL_TOR }, +{ 0xD80F0122, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8116382, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8116390, 32, NDPI_PROTOCOL_TOR }, +{ 0xD811654F, 32, NDPI_PROTOCOL_TOR }, +{ 0xD81169CB, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8116EE7, 32, NDPI_PROTOCOL_TOR }, +{ 0xD818AEF5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8425592, 32, NDPI_PROTOCOL_TOR }, +{ 0xD873031A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD873063A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD892E107, 32, NDPI_PROTOCOL_TOR }, +{ 0xD89A71F4, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8A13759, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8BAC1C9, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8BD9264, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8BD9575, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8BD9666, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8BD9718, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8C3851B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8DA860C, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8DAD8C2, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8DD24F4, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8E6E69C, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8E6E6F7, 32, NDPI_PROTOCOL_TOR }, +{ 0xD8F455D3, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90833AD, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90B39E2, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90B7727, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90CC7BE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90CC7D1, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90CCB2E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90CCC59, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90CCC68, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90CCC93, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90CD075, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90D4A29, 32, NDPI_PROTOCOL_TOR }, +{ 0xD90DC505, 32, NDPI_PROTOCOL_TOR }, +{ 0xD910B514, 32, NDPI_PROTOCOL_TOR }, +{ 0xD910B614, 32, NDPI_PROTOCOL_TOR }, +{ 0xD91318D8, 32, NDPI_PROTOCOL_TOR }, +{ 0xD91318E9, 32, NDPI_PROTOCOL_TOR }, +{ 0xD917011B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD91A1259, 32, NDPI_PROTOCOL_TOR }, +{ 0xD91BB67D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD92287E1, 32, NDPI_PROTOCOL_TOR }, +{ 0xD92287E7, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9251373, 32, NDPI_PROTOCOL_TOR }, +{ 0xD92855C2, 32, NDPI_PROTOCOL_TOR }, +{ 0xD928FEB1, 32, NDPI_PROTOCOL_TOR }, +{ 0xD943154D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD945FE58, 32, NDPI_PROTOCOL_TOR }, +{ 0xD946BD91, 32, NDPI_PROTOCOL_TOR }, +{ 0xD946BF0D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD948141E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD94FB23C, 32, NDPI_PROTOCOL_TOR }, +{ 0xD94FB532, 32, NDPI_PROTOCOL_TOR }, +{ 0xD94FB538, 32, NDPI_PROTOCOL_TOR }, +{ 0xD94FB65F, 32, NDPI_PROTOCOL_TOR }, +{ 0xD94FBE19, 32, NDPI_PROTOCOL_TOR }, +{ 0xD954FBD5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD95597B5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD95EEEF5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD970833A, 32, NDPI_PROTOCOL_TOR }, +{ 0xD97293F5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD972DA12, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9730A85, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9730A86, 32, NDPI_PROTOCOL_TOR }, +{ 0xD97729D5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD97BFEEE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD98090A0, 32, NDPI_PROTOCOL_TOR }, +{ 0xD991C735, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9924B24, 32, NDPI_PROTOCOL_TOR }, +{ 0xD99454B4, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9A0122D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9A013EC, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9A05C43, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9A07E32, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9A083B0, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9A276FE, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9AACD71, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9ACB392, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9ACBE13, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9ACBE13, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9ACFFE5, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9AD4A5B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9BCEA09, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9BDC5F4, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9BF49C3, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9BF6813, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9BFF274, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9C3AA91, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9C504DC, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9C553A2, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9C556AD, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9C55B91, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9C55B91, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9C55BA4, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9C5B52D, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9D075D3, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9D11257, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9D27158, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9D28C5F, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9D2A52B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9D39FA1, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9E40B41, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9E46874, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9E76B72, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9E94FC8, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9E94FC8, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9EA6B0B, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9F595B7, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9F63320, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9F76904, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9F7DE9C, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9F7E61F, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9F9203E, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9FBD765, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9FD96F6, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9FD9F48, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9FE3DAC, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9FE47CC, 32, NDPI_PROTOCOL_TOR }, +{ 0xD9FEB60F, 32, NDPI_PROTOCOL_TOR }, +{ 0xDAA1200E, 32, NDPI_PROTOCOL_TOR }, +{ 0xDAE7EBDB, 32, NDPI_PROTOCOL_TOR }, +{ 0xDAE868DC, 32, NDPI_PROTOCOL_TOR }, +{ 0xDAE868DD, 32, NDPI_PROTOCOL_TOR }, +{ 0xDAFAF536, 32, NDPI_PROTOCOL_TOR }, +{ 0xDB4F067A, 32, NDPI_PROTOCOL_TOR }, +{ 0xDB59C4CA, 32, NDPI_PROTOCOL_TOR }, +{ 0xDB6DCB40, 32, NDPI_PROTOCOL_TOR }, +{ 0xDB75CE2E, 32, NDPI_PROTOCOL_TOR }, +{ 0xDB791014, 32, NDPI_PROTOCOL_TOR }, +{ 0xDBA189F3, 32, NDPI_PROTOCOL_TOR }, +{ 0xDBA4C22E, 32, NDPI_PROTOCOL_TOR }, +{ 0xDBAD0E54, 32, NDPI_PROTOCOL_TOR }, +{ 0xDC39428E, 32, NDPI_PROTOCOL_TOR }, +{ 0xDC87FE3F, 32, NDPI_PROTOCOL_TOR }, +{ 0xDC898752, 32, NDPI_PROTOCOL_TOR }, +{ 0xDC9387F3, 32, NDPI_PROTOCOL_TOR }, +{ 0xDC9DC3F3, 32, NDPI_PROTOCOL_TOR }, +{ 0xDCE97BAC, 32, NDPI_PROTOCOL_TOR }, +{ 0xDCE9AF0E, 32, NDPI_PROTOCOL_TOR }, +{ 0xDCFD1CE1, 32, NDPI_PROTOCOL_TOR }, +{ 0xDCFF85C3, 32, NDPI_PROTOCOL_TOR }, +{ 0xDD7132CB, 32, NDPI_PROTOCOL_TOR }, +{ 0xDD9E95C5, 32, NDPI_PROTOCOL_TOR }, +{ 0xDE047C92, 32, NDPI_PROTOCOL_TOR }, +{ 0xDE0C7C9A, 32, NDPI_PROTOCOL_TOR }, +{ 0xDE7294F8, 32, NDPI_PROTOCOL_TOR }, +{ 0xDEEB761A, 32, NDPI_PROTOCOL_TOR }, +{ 0xDF1273E5, 32, NDPI_PROTOCOL_TOR }, +{ 0xDF85F4CA, 32, NDPI_PROTOCOL_TOR }, +{ 0xDFE57B41, 32, NDPI_PROTOCOL_TOR }, +{ 0x0, 0, 0 } +}; + +/* ****************************************************** */ + +/* + Host-based match + + HTTP: Server: field + HTTPS: Server certificate name + */ + +ndpi_protocol_match host_match[] = { + { "amazon.", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, + { "amazon.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, + { "images-amazon.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, + { "amazonaws.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, + { "amazon-adsystem.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, + { ".apple.com", "Apple", NDPI_SERVICE_APPLE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".mzstatic.com", "Apple", NDPI_SERVICE_APPLE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".icloud.com", "AppleiCloud", NDPI_SERVICE_APPLE_ICLOUD, NDPI_PROTOCOL_ACCEPTABLE }, + { "itunes.apple.com", "AppleiTunes", NDPI_SERVICE_APPLE_ITUNES, NDPI_PROTOCOL_FUN }, + { ".cnn.c", "CNN", NDPI_SERVICE_CNN, NDPI_PROTOCOL_FUN }, + { ".cnn.net", "CNN", NDPI_SERVICE_CNN, NDPI_PROTOCOL_FUN }, + { ".dropbox.com", "DropBox", NDPI_SERVICE_DROPBOX, NDPI_PROTOCOL_SAFE }, + { ".ebay.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, + { ".ebaystatic.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, + { ".ebaydesc.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, + { ".ebayrtm.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, + { ".facebook.com", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, + { ".fbcdn.net", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, + { "fbcdn-", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, /* fbcdn-video-a-akamaihd.net */ + { ".gstatic.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".googlesyndication.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".googletagservices.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".2mdn.net", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".doubleclick.net", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, /* Ads */ + { "googleads.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { "google-analytics.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { "googleusercontent.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { "googleadservices.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { "googleapis.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { "ggpht.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { "maps.google.", "GoogleMaps", NDPI_SERVICE_GOOGLE_MAPS, NDPI_PROTOCOL_ACCEPTABLE }, + { "maps.gstatic.com", "GoogleMaps", NDPI_SERVICE_GOOGLE_MAPS, NDPI_PROTOCOL_ACCEPTABLE }, + { ".gmail.", "GMail", NDPI_SERVICE_GMAIL, NDPI_PROTOCOL_SAFE }, + { "mail.google.", "GMail", NDPI_SERVICE_GMAIL, NDPI_PROTOCOL_SAFE }, + { ".grooveshark.com", "GrooveShark", NDPI_SERVICE_GROOVESHARK, NDPI_PROTOCOL_FUN }, + { ".last.fm", "LastFM", NDPI_SERVICE_LASTFM, NDPI_PROTOCOL_FUN }, + { "msn.com", "MSN", NDPI_SERVICE_MSN, NDPI_PROTOCOL_FUN }, + { "netflix.com", "NetFlix", NDPI_SERVICE_NETFLIX, NDPI_PROTOCOL_FUN }, + { "nflxext.com", "NetFlix", NDPI_SERVICE_NETFLIX, NDPI_PROTOCOL_FUN }, + { "nflximg.com", "NetFlix", NDPI_SERVICE_NETFLIX, NDPI_PROTOCOL_FUN }, + { "nflximg.net", "NetFlix", NDPI_SERVICE_NETFLIX, NDPI_PROTOCOL_FUN }, + + { ".skype.", "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".skypeassets.", "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".skypedata.", "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".skypeecs-", /* no final . */ "Skype", NDPI_SERVICE_SKYPE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".tuenti.com", "Tuenti", NDPI_SERVICE_TUENTI, NDPI_PROTOCOL_ACCEPTABLE }, + { ".twttr.com", "Twitter", NDPI_SERVICE_TWITTER, NDPI_PROTOCOL_ACCEPTABLE }, + { "twitter.", "Twitter", NDPI_SERVICE_TWITTER, NDPI_PROTOCOL_ACCEPTABLE }, + { "twimg.com", "Twitter", NDPI_SERVICE_TWITTER, NDPI_PROTOCOL_ACCEPTABLE }, + { ".viber.com", "Viber", NDPI_SERVICE_VIBER, NDPI_PROTOCOL_ACCEPTABLE }, + { "wikipedia.", "Wikipedia", NDPI_SERVICE_WIKIPEDIA, NDPI_PROTOCOL_ACCEPTABLE }, + { "wikimedia.", "Wikipedia", NDPI_SERVICE_WIKIPEDIA, NDPI_PROTOCOL_ACCEPTABLE }, + { "mediawiki.", "Wikipedia", NDPI_SERVICE_WIKIPEDIA, NDPI_PROTOCOL_ACCEPTABLE }, + { "wikimediafoundation.", "Wikipedia", NDPI_SERVICE_WIKIPEDIA, NDPI_PROTOCOL_ACCEPTABLE }, + { ".whatsapp.net", "WhatsApp", NDPI_SERVICE_WHATSAPP, NDPI_PROTOCOL_ACCEPTABLE }, + { ".yahoo.", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE }, + { "yimg.com", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE }, + { "yahooapis.", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE }, + { "youtube.", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, + { ".googlevideo.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, + { ".ytimg.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, + { "youtube-nocookie.", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, + { ".vevo.com", "Vevo", NDPI_SERVICE_VEVO, NDPI_PROTOCOL_FUN }, + { ".google.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { ".spotify.", "Spotify", NDPI_PROTOCOL_SPOTIFY, NDPI_PROTOCOL_FUN }, + { ".pandora.com", "Pandora", NDPI_SERVICE_PANDORA, NDPI_PROTOCOL_FUN }, + { ".torproject.org", "Tor", NDPI_PROTOCOL_TOR, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS }, + { NULL, 0 } +}; + + +/* + Mime-type content match match +*/ +ndpi_protocol_match content_match[] = { + { "audio/mpeg", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN }, + { "audio/x-mpeg", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN }, + { "audio/mpeg3", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN }, + { "audio/mp4a", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN }, + { "video/mpeg", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN }, + { "video/nsv", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN }, + { "misc/ultravox", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN }, + { "audio/ogg", NULL, NDPI_CONTENT_OGG, NDPI_PROTOCOL_FUN }, + { "video/ogg", NULL, NDPI_CONTENT_OGG, NDPI_PROTOCOL_FUN }, + { "application/ogg", NULL, NDPI_CONTENT_OGG, NDPI_PROTOCOL_FUN }, + { "video/flv", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN }, + { "video/x-flv", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN }, + { "application/x-fcs", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN }, + { "application/x-shockwave-flash", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_ACCEPTABLE }, + { "video/flash", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN }, + { "application/flv", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN }, + { "flv-application/octet-stream", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN }, + { "application/futuresplash", NULL, NDPI_CONTENT_FLASH, NDPI_PROTOCOL_FUN }, + { "video/quicktime", NULL, NDPI_CONTENT_QUICKTIME, NDPI_PROTOCOL_FUN }, + { "video/mp4", NULL, NDPI_CONTENT_QUICKTIME, NDPI_PROTOCOL_FUN }, + { "video/x-m4v", NULL, NDPI_CONTENT_QUICKTIME, NDPI_PROTOCOL_FUN }, + { "audio/x-pn-realaudio", NULL, NDPI_CONTENT_REALMEDIA, NDPI_PROTOCOL_FUN }, + { "application/vnd.rn-realmedia", NULL, NDPI_CONTENT_REALMEDIA, NDPI_PROTOCOL_FUN }, + { "video/x-ms-", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN }, + { "asf", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN }, + { "asx", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN }, + { "video/x-msvideo", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN }, + { "audio/x-wav", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN }, + { "application/vnd.ms.wms-hdr.asfv1", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN }, + { "NSPlayer/", NULL, NDPI_CONTENT_WINDOWSMEDIA, NDPI_PROTOCOL_FUN }, + { "application/x-mms-framed", NULL, NDPI_CONTENT_MMS, NDPI_PROTOCOL_FUN }, + { "Xbox Live Client/", NULL, NDPI_PROTOCOL_XBOX, NDPI_PROTOCOL_FUN }, + { "Windows-Update-Agent", NULL, NDPI_PROTOCOL_WINDOWS_UPDATE, NDPI_PROTOCOL_FUN }, + { "audio/webm", NULL, NDPI_CONTENT_WEBM, NDPI_PROTOCOL_FUN }, + { "video/webm", NULL, NDPI_CONTENT_WEBM, NDPI_PROTOCOL_FUN }, + { "application/x-rtsp-tunnelled", NULL, NDPI_PROTOCOL_RTSP, NDPI_PROTOCOL_FUN }, + { NULL, 0 } +}; + +/* ****************************************************** */ + +/* + Tor + The tor protocol uses SSL to contact peers so it could be exchanged with + standard SSL. However the host names such as + + - www.fgd2iwya7vinfutj5wq5we.com + - www.qbtxzhetq4s2f.com + - www.fgd2iwya7vinfutj5wq5we.net + + In essence www.<name>.com|net + + To do things properly we should check if host name in the certificate + exists or if the IP address of the SSL peer resolves to a name. Unfortunately + for performance reasons we can't afford to do a DNS lookup in nDPI (however apps + can do it if possible) and thus we have created a heuristic algorithm that tries + to check the host name (in the SSL certificate) to see if it looks like a + random name or a real name. We cannot use a dictionary (how can the kernel read a file?) + and this we use bigrams distribution to decide if the string looks like a + word or just random chars. + + http://www3.nd.edu/~busiforc/handouts/cryptography/Letter%20Frequencies.html +*/ + +static const char *ndpi_en_bigrams[] = { + "aa", "ba", "ca", "da", "ea", "fa", "ga", "ha", "ia", "ja", "ka", "la", "ma", "na", "oa", "pa", "qa", + "ra", "sa", "ta", "ua", "va", "wa", "xa", "ya", "za", "ab", "bb", "db", "eb", "fb", "gb", "hb", "ib", + "kb", "lb", "mb", "nb", "ob", "pb", "rb", "sb", "tb", "ub", "wb", "yb", "ac", "bc", "cc", "dc", "ec", + "fc", "gc", "hc", "ic", "kc", "lc", "mc", "nc", "oc", "pc", "rc", "sc", "tc", "uc", "wc", "xc", "yc", + "ad", "bd", "cd", "dd", "ed", "fd", "gd", "hd", "id", "kd", "ld", "md", "nd", "od", "pd", "rd", "sd", + "td", "ud", "wd", "xd", "yd", "zd", "ae", "be", "ce", "de", "ee", "fe", "ge", "he", "ie", "je", "ke", + "le", "me", "ne", "oe", "pe", "re", "se", "te", "ue", "ve", "we", "xe", "ye", "ze", "af", "bf", "df", + "ef", "ff", "gf", "hf", "if", "kf", "lf", "mf", "nf", "of", "pf", "rf", "sf", "tf", "uf", "wf", "xf", + "yf", "zf", "ag", "bg", "dg", "eg", "fg", "gg", "hg", "ig", "kg", "lg", "ng", "og", "pg", "rg", "sg", + "tg", "ug", "wg", "yg", "ah", "bh", "ch", "dh", "eh", "fh", "gh", "hh", "ih", "kh", "lh", "mh", "nh", + "oh", "ph", "rh", "sh", "th", "uh", "wh", "xh", "yh", "ai", "bi", "ci", "di", "ei", "fi", "gi", "hi", + "ii", "ji", "ki", "li", "mi", "ni", "oi", "pi", "qi", "ri", "si", "ti", "ui", "vi", "wi", "xi", "yi", + "zi", "aj", "bj", "dj", "ej", "fj", "gj", "hj", "ij", "jj", "kj", "lj", "nj", "oj", "pj", "rj", "sj", + "tj", "uj", "wj", "yj", "ak", "ck", "dk", "ek", "gk", "ik", "kk", "lk", "mk", "nk", "ok", "pk", "rk", + "sk", "tk", "uk", "wk", "yk", "zk", "al", "bl", "cl", "dl", "el", "fl", "gl", "hl", "il", "kl", "ll", + "ml", "nl", "ol", "pl", "rl", "sl", "tl", "ul", "vl", "wl", "xl", "yl", "zl", "am", "bm", "cm", "dm", + "em", "fm", "gm", "hm", "im", "km", "lm", "mm", "nm", "om", "pm", "rm", "sm", "tm", "um", "wm", "xm", + "ym", "zm", "an", "bn", "cn", "dn", "en", "fn", "gn", "hn", "in", "kn", "ln", "mn", "nn", "on", "pn", + "rn", "sn", "tn", "un", "wn", "xn", "yn", "ao", "bo", "co", "do", "eo", "fo", "go", "ho", "io", "jo", + "ko", "lo", "mo", "no", "oo", "po", "ro", "so", "to", "uo", "vo", "wo", "xo", "yo", "zo", "ap", "bp", + "dp", "ep", "fp", "gp", "hp", "ip", "kp", "lp", "mp", "np", "op", "pp", "rp", "sp", "tp", "up", "wp", + "xp", "yp", "zp", "aq", "cq", "dq", "eq", "hq", "iq", "nq", "oq", "qq", "rq", "sq", "uq", "xq", "ar", + "br", "cr", "dr", "er", "fr", "gr", "hr", "ir", "kr", "lr", "mr", "nr", "or", "pr", "rr", "sr", "tr", + "ur", "vr", "wr", "xr", "yr", "as", "bs", "cs", "ds", "es", "fs", "gs", "hs", "is", "ks", "ls", "ms", + "ns", "os", "ps", "rs", "ss", "ts", "us", "vs", "ws", "xs", "ys", "at", "bt", "ct", "dt", "et", "ft", + "gt", "ht", "it", "kt", "lt", "mt", "nt", "ot", "pt", "rt", "st", "tt", "ut", "wt", "xt", "yt", "zt", + "au", "bu", "cu", "du", "eu", "fu", "gu", "hu", "iu", "ju", "ku", "lu", "mu", "nu", "ou", "pu", "qu", + "ru", "su", "tu", "uu", "vu", "wu", "xu", "yu", "zu", "av", "bv", "dv", "ev", "iv", "lv", "mv", "nv", + "ov", "rv", "sv", "tv", "uv", "vv", "zv", "aw", "bw", "dw", "ew", "fw", "gw", "hw", "iw", "kw", "lw", + "mw", "nw", "ow", "pw", "rw", "sw", "tw", "uw", "ww", "xw", "yw", "zw", "ax", "ex", "ix", "nx", "ox", + "rx", "ux", "xx", "yx", "ay", "by", "cy", "dy", "ey", "fy", "gy", "hy", "ky", "ly", "my", "ny", "oy", + "py", "ry", "sy", "ty", "uy", "vy", "wy", "xy", "yy", "zy", "az", "bz", "cz", "dz", "ez", "gz", "iz", + "lz", "nz", "oz", "pz", "rz", "tz", "uz", "zz", NULL }; + +static const char *ndpi_en_impossible_bigrams[] = { + "bk", "bq", "bx", "cb", "cf", "cg", "cj", "cp", "cv", "cw", "cx", "dx", "fk", "fq", "fv", "fx", "ee", + "fz", "gq", "gv", "gx", "hh", "hk", "hv", "hx", "hz", "iy", "jb", "jc", "jd", "jf", "jg", "jh", "jk", + "jl", "jm", "jn", "jp", "jq", "jr", "js", "jt", "jv", "jw", "jx", "jy", "jz", "kg", "kq", "kv", "kx", + "kz", "lq", "lx", "mg", "mj", "mq", "mx", "mz", "pq", "pv", "px", "qb", "qc", "qd", "qe", "qf", "ii", + "qg", "qh", "qj", "qk", "ql", "qm", "qn", "qo", "qp", "qr", "qs", "qt", "qv", "qw", "qx", "qy", "uu", + "qz", "sx", "sz", "tq", "tx", "vb", "vc", "vd", "vf", "vg", "vh", "vj", "vk", "vm", "vn", "vp", "bw", + "vq", "vt", "vw", "vx", "vz", "wq", "wv", "wx", "wz", "xb", "xg", "xj", "xk", "xv", "xz", "xw", "yd", "yp", + "yj", "yq", "yv", "yz", "yw", "zb", "zc", "zg", "zh", "zj", "zn", "zq", "zr", "zs", "zx", "wh", "wk", + "wb", "zk", "kp", "zk", "xy", + NULL }; diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c new file mode 100644 index 000000000..22892c474 --- /dev/null +++ b/src/lib/ndpi_main.c @@ -0,0 +1,5706 @@ +/* + * ndpi_main.c + * + * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2009-11 - ipoque GmbH + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#ifndef __KERNEL__ +#include <stdlib.h> +#include <errno.h> +#endif + +#include "ahocorasick.h" +#include "ndpi_api.h" + + +#ifndef __KERNEL__ +#include "../../config.h" +#endif + +// #define DEBUG + +#ifdef __KERNEL__ +#include <linux/version.h> +#define printf printk +#else +#include <time.h> +#ifndef WIN32 +#include <unistd.h> +#endif +#endif + +#include "ndpi_content_match.c.inc" +#include "third_party/include/patricia.h" +#include "third_party/src/patricia.c" + +#ifdef WIN32 +/* http://social.msdn.microsoft.com/Forums/uk/vcgeneral/thread/963aac07-da1a-4612-be4a-faac3f1d65ca */ +#ifndef strtok_r +#define strtok_r(a,b,c) strtok(a,b) +#endif +#endif + +#ifdef __KERNEL__ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) +static inline char _tolower(const char c) +{ + return c | 0x20; +} + +static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res) +{ + unsigned long long acc; + int ok; + + if(base == 0) { + if(s[0] == '0') { + if(_tolower(s[1]) == 'x' && isxdigit(s[2])) + base = 16; + else + base = 8; + } else + base = 10; + } + if(base == 16 && s[0] == '0' && _tolower(s[1]) == 'x') + s += 2; + + acc = 0; + ok = 0; + while (*s) { + unsigned int val; + + if('0' <= *s && *s <= '9') + val = *s - '0'; + else if('a' <= _tolower(*s) && _tolower(*s) <= 'f') + val = _tolower(*s) - 'a' + 10; + else if(*s == '\n') { + if(*(s + 1) == '\0') + break; + else + return -EINVAL; + } else + return -EINVAL; + + if(val >= base) + return -EINVAL; + if(acc > div_u64(ULLONG_MAX - val, base)) + return -ERANGE; + acc = acc * base + val; + ok = 1; + + s++; + } + if(!ok) + return -EINVAL; + *res = acc; + return 0; +} + +int kstrtoull(const char *s, unsigned int base, unsigned long long *res) +{ + if(s[0] == '+') + s++; + return _kstrtoull(s, base, res); +} +int kstrtoll(const char *s, unsigned int base, long long *res) +{ + unsigned long long tmp; + int rv; + + if(s[0] == '-') { + rv = _kstrtoull(s + 1, base, &tmp); + if(rv < 0) + return rv; + if((long long)(-tmp) >= 0) + return -ERANGE; + *res = -tmp; + } else { + rv = kstrtoull(s, base, &tmp); + if(rv < 0) + return rv; + if((long long)tmp < 0) + return -ERANGE; + *res = tmp; + } + return 0; +} +int kstrtoint(const char *s, unsigned int base, int *res) +{ + long long tmp; + int rv; + + rv = kstrtoll(s, base, &tmp); + if(rv < 0) + return rv; + if(tmp != (long long)(int)tmp) + return -ERANGE; + *res = tmp; + return 0; +} +#endif + +int atoi(const char *str) { + int rc; + + if(kstrtoint(str, 0, &rc) == 0 /* Success */) + return(rc); + else + return(0); +} +#endif + +/* ftp://ftp.cc.uoc.gr/mirrors/OpenBSD/src/lib/libc/stdlib/tsearch.c */ +/* find or insert datum into search tree */ +void * +ndpi_tsearch(const void *vkey, void **vrootp, + int (*compar)(const void *, const void *)) +{ + ndpi_node *q; + char *key = (char *)vkey; + ndpi_node **rootp = (ndpi_node **)vrootp; + + if(rootp == (ndpi_node **)0) + return ((void *)0); + while (*rootp != (ndpi_node *)0) { /* Knuth's T1: */ + int r; + + if((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */ + return ((void *)*rootp); /* we found it! */ + rootp = (r < 0) ? + &(*rootp)->left : /* T3: follow left branch */ + &(*rootp)->right; /* T4: follow right branch */ + } + q = (ndpi_node *) ndpi_malloc(sizeof(ndpi_node)); /* T5: key not found */ + if(q != (ndpi_node *)0) { /* make new node */ + *rootp = q; /* link new node to old */ + q->key = key; /* initialize new node */ + q->left = q->right = (ndpi_node *)0; + } + return ((void *)q); +} + +/* delete node with given key */ +void * +ndpi_tdelete(const void *vkey, void **vrootp, + int (*compar)(const void *, const void *)) +{ + ndpi_node **rootp = (ndpi_node **)vrootp; + char *key = (char *)vkey; + ndpi_node *p = (ndpi_node *)1; + ndpi_node *q; + ndpi_node *r; + int cmp; + + if(rootp == (ndpi_node **)0 || *rootp == (ndpi_node *)0) + return ((ndpi_node *)0); + while ((cmp = (*compar)(key, (*rootp)->key)) != 0) { + p = *rootp; + rootp = (cmp < 0) ? + &(*rootp)->left : /* follow left branch */ + &(*rootp)->right; /* follow right branch */ + if(*rootp == (ndpi_node *)0) + return ((void *)0); /* key not found */ + } + r = (*rootp)->right; /* D1: */ + if((q = (*rootp)->left) == (ndpi_node *)0) /* Left (ndpi_node *)0? */ + q = r; + else if(r != (ndpi_node *)0) { /* Right link is null? */ + if(r->left == (ndpi_node *)0) { /* D2: Find successor */ + r->left = q; + q = r; + } else { /* D3: Find (ndpi_node *)0 link */ + for (q = r->left; q->left != (ndpi_node *)0; q = r->left) + r = q; + r->left = q->right; + q->left = (*rootp)->left; + q->right = (*rootp)->right; + } + } + ndpi_free((ndpi_node *) *rootp); /* D4: Free node */ + *rootp = q; /* link parent to new node */ + return(p); +} + +/* Walk the nodes of a tree */ +static void +ndpi_trecurse(ndpi_node *root, void (*action)(const void *, ndpi_VISIT, int, void*), int level, void *user_data) +{ + if(root->left == (ndpi_node *)0 && root->right == (ndpi_node *)0) + (*action)(root, ndpi_leaf, level, user_data); + else { + (*action)(root, ndpi_preorder, level, user_data); + if(root->left != (ndpi_node *)0) + ndpi_trecurse(root->left, action, level + 1, user_data); + (*action)(root, ndpi_postorder, level, user_data); + if(root->right != (ndpi_node *)0) + ndpi_trecurse(root->right, action, level + 1, user_data); + (*action)(root, ndpi_endorder, level, user_data); + } +} + +/* Walk the nodes of a tree */ +void +ndpi_twalk(const void *vroot, void (*action)(const void *, ndpi_VISIT, int, void *), void *user_data) +{ + ndpi_node *root = (ndpi_node *)vroot; + + if(root != (ndpi_node *)0 && action != (void (*)(const void *, ndpi_VISIT, int, void*))0) + ndpi_trecurse(root, action, 0, user_data); +} + +/* find a node, or return 0 */ +void * +ndpi_tfind(const void *vkey, void *vrootp, + int (*compar)(const void *, const void *)) +{ + char *key = (char *)vkey; + ndpi_node **rootp = (ndpi_node **)vrootp; + + if(rootp == (ndpi_node **)0) + return ((ndpi_node *)0); + while (*rootp != (ndpi_node *)0) { /* T1: */ + int r; + if((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */ + return (*rootp); /* key found */ + rootp = (r < 0) ? + &(*rootp)->left : /* T3: follow left branch */ + &(*rootp)->right; /* T4: follow right branch */ + } + return (ndpi_node *)0; +} + +/* ****************************************** */ + +/* Walk the nodes of a tree */ +static void ndpi_tdestroy_recurse(ndpi_node* root, void (*free_action)(void *)) { + if(root->left != NULL) + ndpi_tdestroy_recurse(root->left, free_action); + if(root->right != NULL) + ndpi_tdestroy_recurse(root->right, free_action); + + (*free_action) ((void *) root->key); + ndpi_free(root); +} + +void ndpi_tdestroy(void *vrootp, void (*freefct)(void *)) { + ndpi_node *root = (ndpi_node *) vrootp; + + if(root != NULL) + ndpi_tdestroy_recurse(root, freefct); +} + +/* ****************************************** */ + +u_int8_t ndpi_net_match(u_int32_t ip_to_check, + u_int32_t net, + u_int32_t num_bits) { + u_int32_t mask = 0; + + mask = ~(~mask >> num_bits); + + return(((ip_to_check & mask) == (net & mask)) ? 1 : 0); +} + +u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst, + u_int32_t net, u_int32_t num_bits) { + return(ndpi_net_match(src, net, num_bits) || ndpi_net_match(dst, net, num_bits)); +} + +/* ****************************************** */ + +static void *(*_ndpi_malloc)(unsigned long size); +static void (*_ndpi_free)(void *ptr); + +/* ****************************************** */ + +#ifdef WIN32 +/* http://opensource.apple.com/source/Libc/Libc-186/string.subproj/strcasecmp.c */ + +/* + * This array is designed for mapping upper and lower case letter + * together for a case independent comparison. The mappings are + * based upon ascii character sequences. + */ +static const u_char charmap[] = { + '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', + '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', + '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', + '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', + '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', + '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', + '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', + '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', + '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', + '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', + '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', + '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', + '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', + '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', + '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', + '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', + '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', + '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', + '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307', + '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317', + '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', + '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', + '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', + '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', + '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', + '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', +}; + +int +strcasecmp(s1, s2) + const char *s1, *s2; +{ + register const u_char *cm = charmap, + *us1 = (const u_char *)s1, + *us2 = (const u_char *)s2; + + while (cm[*us1] == cm[*us2++]) + if(*us1++ == '\0') + return (0); + return (cm[*us1] - cm[*--us2]); +} + +int +strncasecmp(s1, s2, n) + const char *s1, *s2; + register size_t n; +{ + if(n != 0) { + register const u_char *cm = charmap, + *us1 = (const u_char *)s1, + *us2 = (const u_char *)s2; + + do { + if(cm[*us1] != cm[*us2++]) + return (cm[*us1] - cm[*--us2]); + if(*us1++ == '\0') + break; + } while (--n != 0); + } + return (0); +} + +#endif + +/* ****************************************** */ + +/* Forward */ +static void addDefaultPort(ndpi_port_range *range, + ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root); +static int removeDefaultPort(ndpi_port_range *range, + ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root); + +/* ****************************************** */ + +void* ndpi_malloc(unsigned long size) { return(_ndpi_malloc(size)); } + +/* ****************************************** */ + +void* ndpi_calloc(unsigned long count, unsigned long size) { + unsigned long len = count*size; + void *p = ndpi_malloc(len); + + if(p) + memset(p, 0, len); + + return(p); +} + +/* ****************************************** */ + +void ndpi_free(void *ptr) { _ndpi_free(ptr); } + +/* ****************************************** */ + +void *ndpi_realloc(void *ptr, size_t old_size, size_t new_size) { + void *ret = ndpi_malloc(new_size); + + if(!ret) + return(ret); + else { + memcpy(ret, ptr, old_size); + ndpi_free(ptr); + return(ret); + } +} +/* ****************************************** */ + +char *ndpi_strdup(const char *s) { + int len = strlen(s); + char *m = ndpi_malloc(len+1); + + if(m) { + memcpy(m, s, len); + m[len] = '\0'; + } + + return(m); +} + +/* ****************************************** */ + +u_int32_t ndpi_detection_get_sizeof_ndpi_flow_struct(void) +{ + return sizeof(struct ndpi_flow_struct); +} + +/* ****************************************** */ + +u_int32_t ndpi_detection_get_sizeof_ndpi_id_struct(void) +{ + return sizeof(struct ndpi_id_struct); +} + +/* ******************************************************************** */ + +char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int id) { + return((id >= ndpi_mod->ndpi_num_supported_protocols) ? NULL : ndpi_mod->proto_defaults[id].protoName); +} + +/* ******************************************************************** */ + +ndpi_port_range* ndpi_build_default_ports_range(ndpi_port_range *ports, + u_int16_t portA_low, u_int16_t portA_high, + u_int16_t portB_low, u_int16_t portB_high, + u_int16_t portC_low, u_int16_t portC_high, + u_int16_t portD_low, u_int16_t portD_high, + u_int16_t portE_low, u_int16_t portE_high) { + int i = 0; + + ports[i].port_low = portA_low, ports[i].port_high = portA_high; i++; + ports[i].port_low = portB_low, ports[i].port_high = portB_high; i++; + ports[i].port_low = portC_low, ports[i].port_high = portC_high; i++; + ports[i].port_low = portD_low, ports[i].port_high = portD_high; i++; + ports[i].port_low = portE_low, ports[i].port_high = portE_high; i++; + + return(ports); +} + +/* ******************************************************************** */ + +ndpi_port_range* ndpi_build_default_ports(ndpi_port_range *ports, + u_int16_t portA, + u_int16_t portB, + u_int16_t portC, + u_int16_t portD, + u_int16_t portE) { + int i = 0; + + ports[i].port_low = portA, ports[i].port_high = portA; i++; + ports[i].port_low = portB, ports[i].port_high = portB; i++; + ports[i].port_low = portC, ports[i].port_high = portC; i++; + ports[i].port_low = portD, ports[i].port_high = portD; i++; + ports[i].port_low = portE, ports[i].port_high = portE; i++; + + return(ports); +} + +/* ******************************************************************** */ + +void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod, + ndpi_protocol_breed_t breed, u_int16_t protoId, + u_int16_t tcp_master_protoId[2], u_int16_t udp_master_protoId[2], + char *protoName, + ndpi_port_range *tcpDefPorts, ndpi_port_range *udpDefPorts) { + char *name = ndpi_strdup(protoName); + int j; + + if(protoId >= NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS) { + printf("[NDPI] %s(protoId=%d): INTERNAL ERROR\n", __FUNCTION__, protoId); + ndpi_free(name); + return; + } + + ndpi_mod->proto_defaults[protoId].protoName = name, + ndpi_mod->proto_defaults[protoId].protoId = protoId, + ndpi_mod->proto_defaults[protoId].protoBreed = breed; + + memcpy(&ndpi_mod->proto_defaults[protoId].master_tcp_protoId, tcp_master_protoId, 2*sizeof(u_int16_t)); + memcpy(&ndpi_mod->proto_defaults[protoId].master_udp_protoId, udp_master_protoId, 2*sizeof(u_int16_t)); + + for(j=0; j<MAX_DEFAULT_PORTS; j++) { + if(udpDefPorts[j].port_low != 0) addDefaultPort(&udpDefPorts[j], &ndpi_mod->proto_defaults[protoId], &ndpi_mod->udpRoot); + if(tcpDefPorts[j].port_low != 0) addDefaultPort(&tcpDefPorts[j], &ndpi_mod->proto_defaults[protoId], &ndpi_mod->tcpRoot); + } + +#if 0 + printf("%s(%d, %s, %p) [%s]\n", + __FUNCTION__, + protoId, + ndpi_mod->proto_defaults[protoId].protoName, + ndpi_mod, + ndpi_mod->proto_defaults[1].protoName); +#endif +} + +/* ******************************************************************** */ + +static int ndpi_default_ports_tree_node_t_cmp(const void *a, const void *b) { + ndpi_default_ports_tree_node_t *fa = (ndpi_default_ports_tree_node_t*)a; + ndpi_default_ports_tree_node_t *fb = (ndpi_default_ports_tree_node_t*)b; + + //printf("[NDPI] %s(%d, %d)\n", __FUNCTION__, fa->default_port, fb->default_port); + + return((fa->default_port == fb->default_port) ? 0 : ((fa->default_port < fb->default_port) ? -1 : 1)); +} + +/* ******************************************************************** */ + +void ndpi_default_ports_tree_node_t_walker(const void *node, const ndpi_VISIT which, const int depth) { + ndpi_default_ports_tree_node_t *f = *(ndpi_default_ports_tree_node_t **)node; + + + printf("<%d>Walk on node %s (%u)\n", + depth, + which == ndpi_preorder?"ndpi_preorder": + which == ndpi_postorder?"ndpi_postorder": + which == ndpi_endorder?"ndpi_endorder": + which == ndpi_leaf?"ndpi_leaf": "unknown", + f->default_port); +} + +/* ******************************************************************** */ + +static void addDefaultPort(ndpi_port_range *range, + ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root) { + ndpi_default_ports_tree_node_t *ret; + u_int16_t port; + + // printf("[NDPI] %s(%d)\n", __FUNCTION__, port); + + for(port=range->port_low; port<=range->port_high; port++) { + ndpi_default_ports_tree_node_t *node = (ndpi_default_ports_tree_node_t*)ndpi_malloc(sizeof(ndpi_default_ports_tree_node_t)); + + if(!node) { + printf("[NDPI] %s(): not enough memory\n", __FUNCTION__); + break; + } + + node->proto = def, node->default_port = port; + ret = *(ndpi_default_ports_tree_node_t**)ndpi_tsearch(node, (void*)root, ndpi_default_ports_tree_node_t_cmp); /* Add it to the tree */ + + if(ret != node) { + printf("[NDPI] %s(): found duplicate for port %u: overwriting it with new value\n", __FUNCTION__, port); + + ret->proto = def; + ndpi_free(node); + } + } +} + +/* ****************************************************** */ + +/* + NOTE + + This function must be called with a semaphore set, this in order to avoid + changing the datastrutures while using them +*/ +static int removeDefaultPort(ndpi_port_range *range, + ndpi_proto_defaults_t *def, + ndpi_default_ports_tree_node_t **root) { + ndpi_default_ports_tree_node_t node; + ndpi_default_ports_tree_node_t *ret; + u_int16_t port; + + for(port=range->port_low; port<=range->port_high; port++) { + node.proto = def, node.default_port = port; + ret = *(ndpi_default_ports_tree_node_t**)ndpi_tdelete(&node, (void*)root, + ndpi_default_ports_tree_node_t_cmp); /* Add it to the tree */ + + if(ret != NULL) { + ndpi_free((ndpi_default_ports_tree_node_t*)ret); + return(0); + } + } + + return(-1); +} + +/* ****************************************************** */ + +static int ndpi_string_to_automa(struct ndpi_detection_module_struct *ndpi_struct, + ndpi_automa *automa, + char *value, int protocol_id, + ndpi_protocol_breed_t breed) { + AC_PATTERN_t ac_pattern; + + if(protocol_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) { + printf("[NDPI] %s(protoId=%d): INTERNAL ERROR\n", __FUNCTION__, protocol_id); + return(-1); + } + + if(automa->ac_automa == NULL) return(-2); + ac_pattern.astring = value; + ac_pattern.rep.number = protocol_id; + ac_pattern.length = strlen(ac_pattern.astring); + ac_automata_add(((AC_AUTOMATA_t*)automa->ac_automa), &ac_pattern); + + return(0); +} + +/* ****************************************************** */ + +static int ndpi_add_host_url_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, + char *value, int protocol_id, + ndpi_protocol_breed_t breed) { + return(ndpi_string_to_automa(ndpi_struct, &ndpi_struct->host_automa, + value, protocol_id, breed)); +} + +/* ****************************************************** */ + +int ndpi_add_content_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, + char *value, int protocol_id, + ndpi_protocol_breed_t breed) { + return(ndpi_string_to_automa(ndpi_struct, &ndpi_struct->content_automa, value, protocol_id, breed)); +} + +/* ****************************************************** */ + +/* + NOTE + + This function must be called with a semaphore set, this in order to avoid + changing the datastrutures while using them +*/ +static int ndpi_remove_host_url_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, + char *value, int protocol_id) { + + printf("[NDPI] Missing implementation of %s()\n", __FUNCTION__); + return(-1); +} + +/* ******************************************************************** */ + +static void init_string_based_protocols(struct ndpi_detection_module_struct *ndpi_mod) { + int i; + + for(i=0; host_match[i].string_to_match != NULL; i++) { + ndpi_add_host_url_subprotocol(ndpi_mod, host_match[i].string_to_match, + host_match[i].protocol_id, host_match[i].protocol_breed); + + if(ndpi_mod->proto_defaults[host_match[i].protocol_id].protoName == NULL) { + ndpi_mod->proto_defaults[host_match[i].protocol_id].protoName = ndpi_strdup(host_match[i].proto_name); + ndpi_mod->proto_defaults[host_match[i].protocol_id].protoId = host_match[i].protocol_id; + ndpi_mod->proto_defaults[host_match[i].protocol_id].protoBreed = host_match[i].protocol_breed; + } + } + + for(i=0; content_match[i].string_to_match != NULL; i++) + ndpi_add_content_subprotocol(ndpi_mod, content_match[i].string_to_match, + content_match[i].protocol_id, + content_match[i].protocol_breed); + + for(i=0; ndpi_en_bigrams[i] != NULL; i++) + ndpi_string_to_automa(ndpi_mod, &ndpi_mod->bigrams_automa, + (char*)ndpi_en_bigrams[i], + 1, NDPI_PROTOCOL_UNRATED); + + for(i=0; ndpi_en_impossible_bigrams[i] != NULL; i++) + ndpi_string_to_automa(ndpi_mod, &ndpi_mod->impossible_bigrams_automa, + (char*)ndpi_en_impossible_bigrams[i], + 1, NDPI_PROTOCOL_UNRATED); +} + +/* ******************************************************************** */ + +/* This function is used to map protocol name and default ports and it MUST + be updated whenever a new protocol is added to NDPI. + + Do NOT add web services (NDPI_SERVICE_xxx) here. +*/ +static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndpi_mod) { + int i; + ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS]; + u_int16_t no_master[2] = { NDPI_PROTOCOL_NO_MASTER_PROTO, NDPI_PROTOCOL_NO_MASTER_PROTO }, + custom_master[2], custom_master1[2]; + + /* Reset all settings */ + memset(ndpi_mod->proto_defaults, 0, sizeof(ndpi_mod->proto_defaults)); + + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNRATED, NDPI_PROTOCOL_UNKNOWN, + no_master, + no_master, "Unknown", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_FTP_CONTROL, + no_master, + no_master, "FTP_CONTROL", + ndpi_build_default_ports(ports_a, 21, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_FTP_DATA, + no_master, + no_master, "FTP_DATA", + ndpi_build_default_ports(ports_a, 20, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_MAIL_POP, + no_master, + no_master, "POP3", + ndpi_build_default_ports(ports_a, 110, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MAIL_POPS, + no_master, + no_master, "POPS", + ndpi_build_default_ports(ports_a, 995, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_MAIL_SMTP, + no_master, + no_master, "SMTP", + ndpi_build_default_ports(ports_a, 25, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MAIL_SMTPS, + no_master, + no_master, "SMTPS", + ndpi_build_default_ports(ports_a, 465, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_MAIL_IMAP, + no_master, + no_master, "IMAP", + ndpi_build_default_ports(ports_a, 143, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MAIL_IMAPS, + no_master, + no_master, "IMAPS", + ndpi_build_default_ports(ports_a, 993, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DNS, + no_master, + no_master, "DNS", + ndpi_build_default_ports(ports_a, 53, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 53, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IPP, + no_master, + no_master, "IPP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP, + no_master, + no_master, "HTTP", + ndpi_build_default_ports(ports_a, 80, 0 /* ntop */, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MDNS, + no_master, + no_master, "MDNS", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 5353, 5354, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NTP, + no_master, + no_master, "NTP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 123, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NETBIOS, + no_master, + no_master, "NetBIOS", + ndpi_build_default_ports(ports_a, 139, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 137, 138, 139, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NFS, + no_master, + no_master, "NFS", + ndpi_build_default_ports(ports_a, 2049, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 2049, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SSDP, + no_master, + no_master, "SSDP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_BGP, + no_master, + no_master, "BGP", + ndpi_build_default_ports(ports_a, 2605, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SNMP, + no_master, + no_master, "SNMP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 161, 162, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_XDMCP, + no_master, + no_master, "XDMCP", + ndpi_build_default_ports(ports_a, 177, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 177, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SMB, + no_master, + no_master, "SMB", + ndpi_build_default_ports(ports_a, 445, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SYSLOG, + no_master, + no_master, "Syslog", + ndpi_build_default_ports(ports_a, 514, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 514, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DHCP, + no_master, + no_master, "DHCP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 67, 68, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_POSTGRES, + no_master, + no_master, "PostgreSQL", + ndpi_build_default_ports(ports_a, 5432, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MYSQL, + no_master, + no_master, "MySQL", + ndpi_build_default_ports(ports_a, 3306, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNRATED, NDPI_PROTOCOL_TDS, + no_master, + no_master, "TDS", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, + no_master, + no_master, "Direct_Download_Link", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_APPLEJUICE, + no_master, + no_master, "AppleJuice", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_DIRECTCONNECT, + no_master, + no_master, "DirectConnect", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_SOCRATES, + no_master, + no_master, "Socrates", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_WINMX, + no_master, + no_master, "WinMX", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VMWARE, + no_master, + no_master, "VMware", + ndpi_build_default_ports(ports_a, 903, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 902, 903, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_FILETOPIA, + no_master, + no_master, "Filetopia", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_IMESH, + no_master, + no_master, "iMESH", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_KONTIKI, + no_master, + no_master, "Kontiki", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_OPENFT, + no_master, + no_master, "OpenFT", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_FASTTRACK, + no_master, + no_master, "FastTrack", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_GNUTELLA, + no_master, + no_master, "Gnutella", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_EDONKEY, + no_master, + no_master, "eDonkey", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_BITTORRENT, + no_master, + no_master, "BitTorrent", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_EPP, + no_master, + no_master, "EPP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_AVI, + no_master, + no_master, "AVI", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_CONTENT_FLASH, + no_master, + no_master, "Flash", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_OGG, + no_master, + no_master, "OggVorbis", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_MPEG, + no_master, + no_master, "MPEG", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_QUICKTIME, + no_master, + no_master, "QuickTime", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_REALMEDIA, + no_master, + no_master, "RealMedia", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_CONTENT_WINDOWSMEDIA, + no_master, + no_master, "WindowsMedia", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_CONTENT_MMS, + no_master, + no_master, "MMS", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_XBOX, + no_master, + no_master, "Xbox", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_QQ, + no_master, + no_master, "QQ", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_MOVE, + no_master, + no_master, "Move", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_RTSP, + no_master, + no_master, "RTSP", + ndpi_build_default_ports(ports_a, 554, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 554, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_ICECAST, + no_master, + no_master, "IceCast", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_PPLIVE, + no_master, + no_master, "PPLive", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_PPSTREAM, + no_master, + no_master, "PPStream", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_ZATTOO, + no_master, + no_master, "Zattoo", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SHOUTCAST, + no_master, + no_master, "ShoutCast", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SOPCAST, + no_master, + no_master, "Sopcast", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_TVANTS, + no_master, + no_master, "Tvants", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_TVUPLAYER, + no_master, + no_master, "TVUplayer", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, + no_master, + no_master, "HTTP_APPLICATION_VEOHTV", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_QQLIVE, + no_master, + no_master, "QQLive", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_THUNDER, + no_master, + no_master, "Thunder", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SOULSEEK, + no_master, + no_master, "Soulseek", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + + custom_master[0] = NDPI_PROTOCOL_SSL, custom_master[1] = NDPI_PROTOCOL_UNKNOWN; + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SSL_NO_CERT, + custom_master, no_master, "SSL_No_Cert", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IRC, + no_master, + no_master, "IRC", + ndpi_build_default_ports(ports_a, 194, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 194, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AYIYA, + no_master, + no_master, "Ayiya", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 5072, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_UNENCRYPED_JABBER, + no_master, + no_master, "Unencryped_Jabber", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MSN, + no_master, + no_master, "MSN", + ndpi_build_default_ports(ports_a, 1863, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_OSCAR, + no_master, + no_master, "Oscar", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_YAHOO, + no_master, + no_master, "Yahoo", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_BATTLEFIELD, + no_master, + no_master, "BattleField", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_QUAKE, + no_master, + no_master, "Quake", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_VRRP, + no_master, + no_master, "VRRP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_STEAM, + no_master, + no_master, "Steam", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_HALFLIFE2, + no_master, + no_master, "HalfLife2", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_WORLDOFWARCRAFT, + no_master, + no_master, "WorldOfWarcraft", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_TELNET, + no_master, + no_master, "Telnet", + ndpi_build_default_ports(ports_a, 23, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + + custom_master[0] = NDPI_PROTOCOL_SIP, custom_master[1] = NDPI_PROTOCOL_H323; + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_STUN, + no_master, custom_master, "STUN", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_IP_IPSEC, + no_master, + no_master, "IPsec", + ndpi_build_default_ports(ports_a, 500, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 500, 4500, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_GRE, + no_master, + no_master, "GRE", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_ICMP, + no_master, + no_master, "ICMP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_IGMP, + no_master, + no_master, "IGMP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_EGP, + no_master, + no_master, "EGP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_SCTP, + no_master, + no_master, "SCTP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_OSPF, + no_master, + no_master, "OSPF", + ndpi_build_default_ports(ports_a, 2604, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_IP_IN_IP, + no_master, + no_master, "IP_in_IP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTP, + no_master, + no_master, "RTP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RDP, + no_master, + no_master, "RDP", + ndpi_build_default_ports(ports_a, 3389, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VNC, + no_master, + no_master, "VNC", + ndpi_build_default_ports(ports_a, 5900, 5901, 5800, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_PCANYWHERE, + no_master, + no_master, "PcAnywhere", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + + custom_master[0] = NDPI_PROTOCOL_SSL_NO_CERT, custom_master[1] = NDPI_PROTOCOL_UNKNOWN; + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_SSL, + no_master, custom_master, "SSL", + ndpi_build_default_ports(ports_a, 443, 3001 /* ntop */, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SSH, + no_master, + no_master, "SSH", + ndpi_build_default_ports(ports_a, 22, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_USENET, + no_master, + no_master, "Usenet", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MGCP, + no_master, + no_master, "MGCP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IAX, + no_master, + no_master, "IAX", + ndpi_build_default_ports(ports_a, 4569, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 4569, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TFTP, + no_master, + no_master, "TFTP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AFP, + no_master, + no_master, "AFP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_STEALTHNET, + no_master, + no_master, "Stealthnet", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_AIMINI, + no_master, + no_master, "Aimini", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SIP, + no_master, + no_master, + "SIP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 5060, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TRUPHONE, + no_master, + no_master, "TruPhone", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_ICMPV6, + no_master, + no_master, "ICMPV6", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DHCPV6, + no_master, + no_master, "DHCPV6", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_ARMAGETRON, + no_master, + no_master, "Armagetron", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_CROSSFIRE, + no_master, + no_master, "Crossfire", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_DOFUS, + no_master, + no_master, "Dofus", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_UNRATED, NDPI_PROTOCOL_FIESTA, + no_master, + no_master, "Fiesta", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_FLORENSIA, + no_master, + no_master, "Florensia", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_GUILDWARS, + no_master, + no_master, "Guildwars", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC, + no_master, + no_master, "HTTP_Application_ActiveSync", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_KERBEROS, + no_master, + no_master, "Kerberos", + ndpi_build_default_ports(ports_a, 88, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 88, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_LDAP, + no_master, + no_master, "LDAP", + ndpi_build_default_ports(ports_a, 389, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 389, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_MAPLESTORY, + no_master, + no_master, "MapleStory", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MSSQL, + no_master, + no_master, "MsSQL", + ndpi_build_default_ports(ports_a, 1433, 1434, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_PPTP, + no_master, + no_master, "PPTP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_WARCRAFT3, + no_master, + no_master, "Warcraft3", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_WORLD_OF_KUNG_FU, + no_master, + no_master, "WorldOfKungFu", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MEEBO, + no_master, + no_master, "Meebo", /* Remove */ + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DROPBOX, + no_master, + no_master, "DropBox", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 17500, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKYPE, + no_master, + no_master, "Skype", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DCERPC, + no_master, + no_master, "DCE_RPC", + ndpi_build_default_ports(ports_a, 135, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NETFLOW, + no_master, + no_master, "NetFlow", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 2055, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SFLOW, + no_master, + no_master, "sFlow", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 6343, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP_CONNECT, + no_master, + no_master, "HTTP_Connect", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP_PROXY, + no_master, + no_master, "HTTP_Proxy", + ndpi_build_default_ports(ports_a, 8080, 3128, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CITRIX, + no_master, + no_master, "Citrix", + ndpi_build_default_ports(ports_a, 1494, 2598, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKYFILE_PREPAID, + no_master, + no_master, "SkyFile_PrePaid", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKYFILE_RUDICS, + no_master, + no_master, "SkyFile_Rudics", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKYFILE_POSTPAID, + no_master, + no_master, "SkyFile_PostPaid", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CITRIX_ONLINE, + no_master, + no_master, "Citrix_Online", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WEBEX, + no_master, + no_master, "Webex", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RADIUS, + no_master, + no_master, "Radius", + ndpi_build_default_ports(ports_a, 1812, 1813, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 1812, 1813, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WINDOWS_UPDATE, + no_master, + no_master, "WindowsUpdate", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TEAMVIEWER, + no_master, + no_master, "TeamViewer", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_LOTUS_NOTES, + no_master, + no_master, "LotusNotes", + ndpi_build_default_ports(ports_a, 1352, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SAP, + no_master, + no_master, "SAP", + ndpi_build_default_ports(ports_a, 3201, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); /* Missing dissector: port based only */ + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_GTP, + no_master, + no_master, "GTP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 2152, 2123, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_UPNP, + no_master, + no_master, "UPnP", + ndpi_build_default_ports(ports_a, 1780, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 1900, 0, 0, 0, 0) /* UDP */); /* Missing dissector: port based only */ + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TELEGRAM, + no_master, + no_master, "Telegram", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + + custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN; + custom_master1[0] = NDPI_PROTOCOL_DNS, custom_master1[1] = NDPI_PROTOCOL_UNKNOWN; + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, + NDPI_SERVICE_GOOGLE, + custom_master, custom_master1, + "Google", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + + custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN; + custom_master1[0] = NDPI_PROTOCOL_DNS, custom_master1[1] = NDPI_PROTOCOL_UNKNOWN; + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, + NDPI_SERVICE_APPLE, + custom_master, custom_master1, + "Apple", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + + custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN; + custom_master1[0] = NDPI_PROTOCOL_DNS, custom_master1[1] = NDPI_PROTOCOL_UNKNOWN; + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, + NDPI_SERVICE_APPLE_ICLOUD, + custom_master, custom_master1, + "AppleiCloud", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + + custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN; + custom_master1[0] = NDPI_PROTOCOL_DNS, custom_master1[1] = NDPI_PROTOCOL_UNKNOWN; + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, + NDPI_SERVICE_APPLE_ITUNES, + custom_master, custom_master1, + "AppleiTunes", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + + /* http://en.wikipedia.org/wiki/Link-local_Multicast_Name_Resolution */ + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_LLMNR, + no_master, + no_master, "LLMNR", + ndpi_build_default_ports(ports_a, 5355, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 5355, 0, 0, 0, 0) /* UDP */); /* Missing dissector: port based only */ + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_REMOTE_SCAN, + no_master, + no_master, "RemoteScan", + ndpi_build_default_ports(ports_a, 6077, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 6078, 0, 0, 0, 0) /* UDP */); /* Missing dissector: port based only */ + + custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN; + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SPOTIFY, + custom_master, no_master, "Spotify", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 57621, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_CONTENT_WEBM, + no_master, + no_master, "WebM", /* Courtesy of Shreeram Ramamoorthy Swaminathan <shreeram <shreeram1985@yahoo.co.in> */ + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_H323, + no_master, + no_master, + "H323", + ndpi_build_default_ports(ports_a, 1719, 1720, 3478, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 1719, 1720, 3478, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_OPENVPN, + no_master, + no_master, "OpenVPN", + ndpi_build_default_ports(ports_a, 1194, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 1194, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NOE, + no_master, + no_master, "NOE", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_CISCOVPN, + no_master, + no_master, "CiscoVPN", + ndpi_build_default_ports(ports_a, 10000, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 10000, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TEAMSPEAK, + no_master, + no_master, "TeamSpeak", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_TOR, + no_master, + no_master, "TOR", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKINNY, + no_master, + no_master, "CiscoSkinny", + ndpi_build_default_ports(ports_a, 2000, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTCP, + no_master, + no_master, "RTCP", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RSYNC, + no_master, + no_master, "RSYNC", + ndpi_build_default_ports(ports_a, 873, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ORACLE, + no_master, + no_master, "Oracle", + ndpi_build_default_ports(ports_a, 1521, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CORBA, + no_master, + no_master, "Corba", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_UBUNTUONE, + no_master, + no_master, "UbuntuONE", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHOIS_DAS, + no_master, + no_master, "Whois-DAS", + ndpi_build_default_ports(ports_a, 43, 4343, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_COLLECTD, + no_master, + no_master, "Collectd", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 25826, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOCKS5, + no_master, + no_master, "SOCKS5", + ndpi_build_default_ports(ports_a, 1080, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 1080, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOCKS4, + no_master, + no_master, "SOCKS4", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTMP, + no_master, + no_master, "RTMP", + ndpi_build_default_ports(ports_a, 1935, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_PANDO, + no_master, + no_master, "Pando_Media_Booster", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VIBER, + no_master, + no_master, "Viber", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MEGACO, + no_master, + no_master, "Megaco", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 2944 , 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_REDIS, + no_master, + no_master, "Redis", + ndpi_build_default_ports(ports_a, 6379, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ZMQ, + no_master, + no_master, "ZeroMQ", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_SERVICE_TWITTER, + no_master, + no_master, "Twitter", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_VHUA, + no_master, + no_master, "VHUA", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 58267, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_SERVICE_FACEBOOK, + no_master, + no_master, "Facebook", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_SERVICE_FACEBOOK_CHAT, + no_master, + no_master, "FacebookChat", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_SERVICE_PANDORA, + no_master, + no_master, "Pandora", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + + init_string_based_protocols(ndpi_mod); + + for(i=0; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++) { + if(ndpi_mod->proto_defaults[i].protoName == NULL) { + printf("[NDPI] %s(missing protoId=%d) INTERNAL ERROR: not all protocols have been initialized\n", __FUNCTION__, i); + } + } +} + +/* ****************************************************** */ + +static int ac_match_handler(AC_MATCH_t *m, void *param) { + int *matching_protocol_id = (int*)param; + + /* Stopping to the first match. We might consider searching + * for the more specific match, paying more cpu cycles. */ + *matching_protocol_id = m->patterns[0].rep.number; + + return 1; /* 0 to continue searching, !0 to stop */ +} + +/* ******************************************************************** */ + +#ifdef NDPI_PROTOCOL_TOR + +static int fill_prefix_v4(prefix_t *p, struct in_addr *a, int b, int mb) { + do { + if(b < 0 || b > mb) + return(-1); + + memcpy(&p->add.sin, a, (mb+7)/8); + p->family = AF_INET; + p->bitlen = b; + p->ref_count = 0; + } while (0); + + return(0); +} + +/* ******************************************* */ + +u_int16_t ndpi_network_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, struct in_addr *pin) { + prefix_t prefix; + patricia_node_t *node; + + fill_prefix_v4(&prefix, pin, 32, ((patricia_tree_t*)ndpi_struct->protocols_ptree)->maxbits); + node = ndpi_patricia_search_best(ndpi_struct->protocols_ptree, &prefix); + + return(node ? node->value.user_value : NDPI_PROTOCOL_UNKNOWN); +} + +/* ******************************************* */ + +u_int16_t ndpi_host_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t host) { + struct in_addr pin; + + pin.s_addr = host; + + return(ndpi_network_ptree_match(ndpi_struct, &pin)); +} + +/* ******************************************* */ + +static u_int8_t tor_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, struct in_addr *pin) { + return((ndpi_network_ptree_match(ndpi_struct, pin) == NDPI_PROTOCOL_TOR) ? 1 : 0); +} + +/* ******************************************* */ + +u_int8_t ndpi_is_tor_flow(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + if(packet->tcp != NULL) { + if(flow->packet.iph) { + if(tor_ptree_match(ndpi_struct, (struct in_addr *)&packet->iph->saddr) + || tor_ptree_match(ndpi_struct, (struct in_addr *)&packet->iph->daddr)) { + return(1); + } + } + } + + return(0); +} + +/* ******************************************* */ + +static patricia_node_t* add_to_ptree(patricia_tree_t *tree, int family, + void *addr, int bits) { + prefix_t prefix; + patricia_node_t *node; + + fill_prefix_v4(&prefix, (struct in_addr*)addr, bits, tree->maxbits); + + node = ndpi_patricia_lookup(tree, &prefix); + + return(node); +} +/* ******************************************* */ + +static void ndpi_init_ptree_ipv4(struct ndpi_detection_module_struct *ndpi_str, + void *ptree, ndpi_network host_list[]) { + int i; + + for(i=0; host_list[i].network != 0x0; i++) { + struct in_addr pin; + patricia_node_t *node; + + pin.s_addr = host_list[i].network; + if((node = add_to_ptree(ptree, AF_INET, &pin, host_list[i].cidr /* bits */)) != NULL) + node->value.user_value = host_list[i].value; + } +} +#endif + +/* ******************************************************************** */ + +struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_per_second, + void* (*__ndpi_malloc)(unsigned long size), + void (*__ndpi_free)(void *ptr), + ndpi_debug_function_ptr ndpi_debug_printf) +{ + struct ndpi_detection_module_struct *ndpi_str; + + _ndpi_malloc = __ndpi_malloc; + _ndpi_free = __ndpi_free; + + ndpi_str = ndpi_malloc(sizeof(struct ndpi_detection_module_struct)); + + if(ndpi_str == NULL) { + ndpi_debug_printf(0, NULL, NDPI_LOG_DEBUG, "ndpi_init_detection_module initial malloc failed\n"); + return NULL; + } + memset(ndpi_str, 0, sizeof(struct ndpi_detection_module_struct)); + + if((ndpi_str->protocols_ptree = ndpi_New_Patricia(32 /* IPv4 */)) != NULL) + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, host_protocol_list); + + NDPI_BITMASK_RESET(ndpi_str->detection_bitmask); +#ifdef NDPI_ENABLE_DEBUG_MESSAGES + ndpi_str->ndpi_debug_printf = ndpi_debug_printf; + ndpi_str->user_data = NULL; +#endif + + ndpi_str->match_dns_host_names = 1; /* + Set it to 0 to increase library speed avoid + matching host names + */ + ndpi_str->ticks_per_second = ticks_per_second; + ndpi_str->tcp_max_retransmission_window_size = NDPI_DEFAULT_MAX_TCP_RETRANSMISSION_WINDOW_SIZE; + ndpi_str->directconnect_connection_ip_tick_timeout = + NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT * ticks_per_second; + + ndpi_str->rtsp_connection_timeout = NDPI_RTSP_CONNECTION_TIMEOUT * ticks_per_second; + ndpi_str->tvants_connection_timeout = NDPI_TVANTS_CONNECTION_TIMEOUT * ticks_per_second; + ndpi_str->irc_timeout = NDPI_IRC_CONNECTION_TIMEOUT * ticks_per_second; + ndpi_str->gnutella_timeout = NDPI_GNUTELLA_CONNECTION_TIMEOUT * ticks_per_second; + + ndpi_str->battlefield_timeout = NDPI_BATTLEFIELD_CONNECTION_TIMEOUT * ticks_per_second; + + ndpi_str->thunder_timeout = NDPI_THUNDER_CONNECTION_TIMEOUT * ticks_per_second; + ndpi_str->yahoo_detect_http_connections = NDPI_YAHOO_DETECT_HTTP_CONNECTIONS; + + ndpi_str->yahoo_lan_video_timeout = NDPI_YAHOO_LAN_VIDEO_TIMEOUT * ticks_per_second; + ndpi_str->zattoo_connection_timeout = NDPI_ZATTOO_CONNECTION_TIMEOUT * ticks_per_second; + ndpi_str->jabber_stun_timeout = NDPI_JABBER_STUN_TIMEOUT * ticks_per_second; + ndpi_str->jabber_file_transfer_timeout = NDPI_JABBER_FT_TIMEOUT * ticks_per_second; + ndpi_str->soulseek_connection_ip_tick_timeout = NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT * ticks_per_second; + + ndpi_str->ndpi_num_supported_protocols = NDPI_MAX_SUPPORTED_PROTOCOLS; + ndpi_str->ndpi_num_custom_protocols = 0; + + ndpi_str->host_automa.ac_automa = ac_automata_init(ac_match_handler); + ndpi_str->content_automa.ac_automa = ac_automata_init(ac_match_handler); + ndpi_str->bigrams_automa.ac_automa = ac_automata_init(ac_match_handler); + ndpi_str->impossible_bigrams_automa.ac_automa = ac_automata_init(ac_match_handler); + + ndpi_init_protocol_defaults(ndpi_str); + return ndpi_str; +} + +/* *********************************************** */ + +static void free_ptree_data(void *data) { ; } + +/* ****************************************************** */ + +void ndpi_exit_detection_module(struct ndpi_detection_module_struct + *ndpi_struct, void (*ndpi_free) (void *ptr)) { + if(ndpi_struct != NULL) { + int i; + + for(i=0; i<(int)ndpi_struct->ndpi_num_supported_protocols; i++) { + if(ndpi_struct->proto_defaults[i].protoName) + ndpi_free(ndpi_struct->proto_defaults[i].protoName); + } + + if(ndpi_struct->protocols_ptree) + ndpi_Destroy_Patricia((patricia_tree_t*)ndpi_struct->protocols_ptree, free_ptree_data); + + ndpi_tdestroy(ndpi_struct->udpRoot, ndpi_free); + ndpi_tdestroy(ndpi_struct->tcpRoot, ndpi_free); + + if(ndpi_struct->host_automa.ac_automa != NULL) + ac_automata_release((AC_AUTOMATA_t*)ndpi_struct->host_automa.ac_automa); + + if(ndpi_struct->content_automa.ac_automa != NULL) + ac_automata_release((AC_AUTOMATA_t*)ndpi_struct->content_automa.ac_automa); + + if(ndpi_struct->bigrams_automa.ac_automa != NULL) + ac_automata_release((AC_AUTOMATA_t*)ndpi_struct->bigrams_automa.ac_automa); + + if(ndpi_struct->impossible_bigrams_automa.ac_automa != NULL) + ac_automata_release((AC_AUTOMATA_t*)ndpi_struct->impossible_bigrams_automa.ac_automa); + + ndpi_free(ndpi_struct); + } +} + +/* ****************************************************** */ + +int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_struct, + u_int16_t protocol_id, + u_int16_t** tcp_master_proto, + u_int16_t** udp_master_proto) { + if(protocol_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) { + *tcp_master_proto = *udp_master_proto = NDPI_PROTOCOL_UNKNOWN; + return(-1); + } + + *tcp_master_proto = ndpi_struct->proto_defaults[protocol_id].master_tcp_protoId, + *udp_master_proto = ndpi_struct->proto_defaults[protocol_id].master_udp_protoId; + + return(0); +} + +/* ****************************************************** */ + +u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct, + u_int8_t proto, u_int16_t sport, u_int16_t dport) { + const void *ret; + ndpi_default_ports_tree_node_t node; + + if(sport && dport) { + node.default_port = sport; + ret = ndpi_tfind(&node, + (proto == IPPROTO_TCP) ? (void*)&ndpi_struct->tcpRoot : (void*)&ndpi_struct->udpRoot, + ndpi_default_ports_tree_node_t_cmp); + + if(ret == NULL) { + node.default_port = dport; + ret = ndpi_tfind(&node, + (proto == IPPROTO_TCP) ? (void*)&ndpi_struct->tcpRoot : (void*)&ndpi_struct->udpRoot, + ndpi_default_ports_tree_node_t_cmp); + } + + if(ret != NULL) { + ndpi_default_ports_tree_node_t *found = *(ndpi_default_ports_tree_node_t**)ret; + + return(found->proto->protoId); + } + } else { + /* No TCP/UDP */ + + switch(proto) { + case NDPI_IPSEC_PROTOCOL_ESP: + case NDPI_IPSEC_PROTOCOL_AH: + return(NDPI_PROTOCOL_IP_IPSEC); + break; + case NDPI_GRE_PROTOCOL_TYPE: + return(NDPI_PROTOCOL_IP_GRE); + break; + case NDPI_ICMP_PROTOCOL_TYPE: + return(NDPI_PROTOCOL_IP_ICMP); + break; + case NDPI_IGMP_PROTOCOL_TYPE: + return(NDPI_PROTOCOL_IP_IGMP); + break; + case NDPI_EGP_PROTOCOL_TYPE: + return(NDPI_PROTOCOL_IP_EGP); + break; + case NDPI_SCTP_PROTOCOL_TYPE: + return(NDPI_PROTOCOL_IP_SCTP); + break; + case NDPI_OSPF_PROTOCOL_TYPE: + return(NDPI_PROTOCOL_IP_OSPF); + break; + case NDPI_IPIP_PROTOCOL_TYPE: + return(NDPI_PROTOCOL_IP_IP_IN_IP); + break; + case NDPI_ICMPV6_PROTOCOL_TYPE: + return(NDPI_PROTOCOL_IP_ICMPV6); + break; + case 112: + return(NDPI_PROTOCOL_IP_VRRP); + break; + } + } + + return(NDPI_PROTOCOL_UNKNOWN); +} + +/* ******************************************************************** */ + +#if 0 +#ifndef __KERNEL__ +static int add_proto_default_port(u_int16_t **ports, u_int16_t new_port, + ndpi_proto_defaults_t *def, + ndpi_default_ports_tree_node_t *root) { + u_int num_ports, i; + + if(*ports == NULL) { + ndpi_port_range range = { new_port, new_port }; + + addDefaultPort(&range, def, &root); + return(0); + } + + for(num_ports=0; (*ports)[num_ports] != 0; num_ports++) + ; + + if(num_ports >= MAX_DEFAULT_PORTS) { + printf("Too many ports defined: ignored port %d\n", new_port); + return(-1); + } else { + u_int16_t *new_ports = (u_int16_t*)ndpi_malloc(num_ports+1); + ndpi_port_range range; + + if(new_ports == NULL) { + printf("Not enough memory\n"); + return(-2); + } + + for(i=0; i<num_ports; i++) + new_ports[i] = (*ports)[i]; + + new_ports[i++] = new_port; + new_ports[i++] = 0; + + ndpi_free(*ports); + *ports = new_ports; + + range.port_low = range.port_high = new_port; + addDefaultPort(&range, def, &root); + return(0); + } +} +#endif +#endif + +/* ******************************************************************** */ + +u_int ndpi_get_num_supported_protocols(struct ndpi_detection_module_struct *ndpi_mod) { + return(ndpi_mod->ndpi_num_supported_protocols); +} + +/* ******************************************************************** */ + +int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_mod, char* rule, u_int8_t do_add) { + char *at, *proto, *elem; + ndpi_proto_defaults_t *def; + int subprotocol_id, i; + + at = strrchr(rule, '@'); + if(at == NULL) { + printf("Invalid rule '%s'\n", rule); + return(-1); + } else + at[0] = 0, proto = &at[1]; + + for(i=0, def = NULL; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++) { + if(strcasecmp(ndpi_mod->proto_defaults[i].protoName, proto) == 0) { + def = &ndpi_mod->proto_defaults[i]; + subprotocol_id = i; + break; + } + } + + if(def == NULL) { + if(!do_add) { + /* We need to remove a rule */ + printf("Unable to find protocol '%s': skipping rule '%s'\n", proto, rule); + return(-3); + } else { + ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS]; + u_int16_t no_master[2] = { NDPI_PROTOCOL_NO_MASTER_PROTO, NDPI_PROTOCOL_NO_MASTER_PROTO }; + + if(ndpi_mod->ndpi_num_custom_protocols >= (NDPI_MAX_NUM_CUSTOM_PROTOCOLS-1)) { + printf("Too many protocols defined (%u): skipping protocol %s\n", + ndpi_mod->ndpi_num_custom_protocols, proto); + return(-2); + } + + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, + ndpi_mod->ndpi_num_supported_protocols, + no_master, + no_master, + ndpi_strdup(proto), + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + def = &ndpi_mod->proto_defaults[ndpi_mod->ndpi_num_supported_protocols]; + subprotocol_id = ndpi_mod->ndpi_num_supported_protocols; + ndpi_mod->ndpi_num_supported_protocols++, ndpi_mod->ndpi_num_custom_protocols++; + } + } + + while((elem = strsep(&rule, ",")) != NULL) { + char *attr = elem, *value = NULL; + ndpi_port_range range; + int is_tcp = 0, is_udp = 0; + + if(strncmp(attr, "tcp:", 4) == 0) + is_tcp = 1, value = &attr[4]; + else if(strncmp(attr, "udp:", 4) == 0) + is_udp = 1, value = &attr[4]; + else if(strncmp(attr, "host:", 5) == 0) { + /* host:"<value>",host:"<value>",.....@<subproto> */ + value = &attr[5]; + if(value[0] == '"') value++; /* remove leading " */ + if(value[strlen(value)-1] == '"') value[strlen(value)-1] = '\0'; /* remove trailing " */ + } + + if(is_tcp || is_udp) { + if(sscanf(value, "%u-%u", (unsigned int *)&range.port_low, (unsigned int *)&range.port_high) != 2) + range.port_low = range.port_high = atoi(&elem[4]); + if(do_add) + addDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot); + else + removeDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot); + } else { + if(do_add) + ndpi_add_host_url_subprotocol(ndpi_mod, value, subprotocol_id, NDPI_PROTOCOL_ACCEPTABLE); + else + ndpi_remove_host_url_subprotocol(ndpi_mod, value, subprotocol_id); + } + } + + return(0); +} + +/* ******************************************************************** */ + +/* + Format: + <tcp|udp>:<port>,<tcp|udp>:<port>,.....@<proto> + + Example: + tcp:80,tcp:3128@HTTP + udp:139@NETBIOS + +*/ +int ndpi_load_protocols_file(struct ndpi_detection_module_struct *ndpi_mod, char* path) { +#ifdef __KERNEL__ + return(0); +#else + FILE *fd = fopen(path, "r"); + int i; + + if(fd == NULL) { + printf("Unable to open file %s [%s]", path, strerror(errno)); + return(-1); + } + + while(fd) { + char buffer[512], *line; + + if(!(line = fgets(buffer, sizeof(buffer), fd))) + break; + + if(((i = strlen(line)) <= 1) || (line[0] == '#')) + continue; + else + line[i-1] = '\0'; + + ndpi_handle_rule(ndpi_mod, line, 1); + } + + fclose(fd); + +#if 0 + printf("\nTCP:\n"); + ndpi_twalk(ndpi_mod->tcpRoot, ndpi_default_ports_tree_node_t_walker, NULL); + printf("\nUDP:\n"); + ndpi_twalk(ndpi_mod->udpRoot, ndpi_default_ports_tree_node_t_walker, NULL); +#endif +#endif + + return(0); +} + +/* ntop */ +void ndpi_set_bitmask_protocol_detection( char * label, + struct ndpi_detection_module_struct *ndpi_struct, + const NDPI_PROTOCOL_BITMASK * detection_bitmask, + const u_int32_t idx, + u_int16_t ndpi_protocol_id, + void (*func) (struct ndpi_detection_module_struct *, struct ndpi_flow_struct *flow), + const NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_bitmask, + u_int8_t b_save_bitmask_unknow, + u_int8_t b_add_detection_bitmask) +{ + /* + Compare specify protocol bitmask with main detection bitmask + */ + if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(*detection_bitmask, ndpi_protocol_id) != 0) { + // #ifdef DEBUG + NDPI_LOG(0, ndpi_struct, NDPI_LOG_DEBUG,"[NDPI] ndpi_set_bitmask_protocol_detection: %s : [callback_buffer] idx= %u, [proto_defaults] protocol_id=%u\n", label, idx, ndpi_protocol_id); + // #endif + /* + Set funcition and index protocol within proto_default strcuture for port protocol detection + and callback_buffer function for DPI protocol detection + */ + ndpi_struct->proto_defaults[ndpi_protocol_id].protoIdx = idx; + + ndpi_struct->proto_defaults[ndpi_protocol_id].func = + ndpi_struct->callback_buffer[idx].func = func; + /* + Set ndpi_selection_bitmask for protocol + */ + ndpi_struct->callback_buffer[idx].ndpi_selection_bitmask = ndpi_selection_bitmask; + + /* + Reset protocol detection bitmask via NDPI_PROTOCOL_UNKNOWN and than add specify protocol bitmast to callback + buffer. + */ + if (b_save_bitmask_unknow) NDPI_SAVE_AS_BITMASK(ndpi_struct->callback_buffer[idx].detection_bitmask, NDPI_PROTOCOL_UNKNOWN); + if (b_add_detection_bitmask) NDPI_ADD_PROTOCOL_TO_BITMASK(ndpi_struct->callback_buffer[idx].detection_bitmask, ndpi_protocol_id); + + NDPI_SAVE_AS_BITMASK(ndpi_struct->callback_buffer[idx].excluded_protocol_bitmask, ndpi_protocol_id); + } +} + +/* ******************************************************************** */ + +void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *ndpi_struct, + const NDPI_PROTOCOL_BITMASK * dbm) +{ + NDPI_PROTOCOL_BITMASK detection_bitmask_local; + NDPI_PROTOCOL_BITMASK *detection_bitmask = &detection_bitmask_local; + u_int32_t a = 0; + + NDPI_BITMASK_SET(detection_bitmask_local, *dbm); + NDPI_BITMASK_SET(ndpi_struct->detection_bitmask, *dbm); + + /* set this here to zero to be interrupt safe */ + ndpi_struct->callback_buffer_size = 0; + + +#ifdef NDPI_PROTOCOL_HTTP + ndpi_set_bitmask_protocol_detection("HTTP",ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_HTTP, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + ndpi_set_bitmask_protocol_detection("HTTP_PROXY", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_HTTP_PROXY, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + +#ifdef NDPI_CONTENT_MPEG + ndpi_set_bitmask_protocol_detection("MPEG", ndpi_struct, detection_bitmask, a++, + NDPI_CONTENT_MPEG, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_CONTENT_FLASH + ndpi_set_bitmask_protocol_detection("FLASH", ndpi_struct, detection_bitmask, a++, + NDPI_CONTENT_FLASH, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_CONTENT_QUICKTIME + ndpi_set_bitmask_protocol_detection("QUICKTIME", ndpi_struct, detection_bitmask, a++, + NDPI_CONTENT_QUICKTIME, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_CONTENT_REALMEDIA + ndpi_set_bitmask_protocol_detection("REALMEDIA", ndpi_struct, detection_bitmask, a++, + NDPI_CONTENT_REALMEDIA, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_CONTENT_WINDOWSMEDIA + ndpi_set_bitmask_protocol_detection("WINDOWSMEDIA", ndpi_struct, detection_bitmask, a++, + NDPI_CONTENT_WINDOWSMEDIA, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_CONTENT_MMS + ndpi_set_bitmask_protocol_detection("MMS", ndpi_struct, detection_bitmask, a++, + NDPI_CONTENT_MMS, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_XBOX + ndpi_set_bitmask_protocol_detection("XBOX", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_XBOX, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_WINDOWS_UPDATE + ndpi_set_bitmask_protocol_detection("WINDOWS_UPDATE", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_WINDOWS_UPDATE, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_QQ + ndpi_set_bitmask_protocol_detection("QQ", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_QQ, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_CONTENT_AVI + ndpi_set_bitmask_protocol_detection("AVI", ndpi_struct, detection_bitmask, a++, + NDPI_CONTENT_AVI, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_CONTENT_OGG + ndpi_set_bitmask_protocol_detection("OGG", ndpi_struct, detection_bitmask, a++, + NDPI_CONTENT_OGG, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_MOVE + ndpi_set_bitmask_protocol_detection("MOVE", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_MOVE, + ndpi_search_http_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + /*Update excluded protocol bitmask*/ + NDPI_BITMASK_SET(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, + ndpi_struct->callback_buffer[a].detection_bitmask); + + /*Delete protocol from exluded protocol bitmask*/ + NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, + NDPI_PROTOCOL_UNKNOWN); + + NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, + NDPI_PROTOCOL_QQ); + +#ifdef NDPI_CONTENT_FLASH + NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, + NDPI_CONTENT_FLASH); +#endif + + NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, + NDPI_CONTENT_MMS); + // #ifdef NDPI_PROTOCOL_RTSP + // NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, + // NDPI_PROTOCOL_RTSP); + // #endif + NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask, + NDPI_PROTOCOL_XBOX); + + NDPI_BITMASK_SET(ndpi_struct->generic_http_packet_bitmask, + ndpi_struct->callback_buffer[a].detection_bitmask); + + NDPI_DEL_PROTOCOL_FROM_BITMASK(ndpi_struct->generic_http_packet_bitmask, NDPI_PROTOCOL_UNKNOWN); + + /* Update callback_buffer index */ + a++; +#endif + + +#ifdef NDPI_PROTOCOL_SSL + ndpi_set_bitmask_protocol_detection("SSL", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_SSL, + ndpi_search_ssl_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + + +#ifdef NDPI_PROTOCOL_STUN + ndpi_set_bitmask_protocol_detection("STUN", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_STUN, + ndpi_search_stun, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_RTP + ndpi_set_bitmask_protocol_detection("RTP", ndpi_struct, detection_bitmask,a, + NDPI_PROTOCOL_RTP, + ndpi_search_rtp, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + /* consider also real protocol for detection select in main loop */ + ndpi_struct->callback_buffer[a].detection_feature = NDPI_SELECT_DETECTION_WITH_REAL_PROTOCOL; + /* Update callback_buffer index */ + a++; +#endif + +#ifdef NDPI_PROTOCOL_RTSP + ndpi_set_bitmask_protocol_detection("RTSP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_RTSP, + ndpi_search_rtsp_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_RDP + ndpi_set_bitmask_protocol_detection("RDP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_RDP, + ndpi_search_rdp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_SIP + ndpi_set_bitmask_protocol_detection("SIP", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_SIP, + ndpi_search_sip, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,/* Fix courtesy of Miguel Quesada <mquesadab@gmail.com> */ + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_BITTORRENT + ndpi_set_bitmask_protocol_detection("BITTORRENT", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_BITTORRENT, + ndpi_search_bittorrent, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_EDONKEY + ndpi_set_bitmask_protocol_detection("EDONKEY", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_EDONKEY, + ndpi_search_edonkey, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_FASTTRACK + ndpi_set_bitmask_protocol_detection("FASTTRACK", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_FASTTRACK, + ndpi_search_fasttrack_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_GNUTELLA + ndpi_set_bitmask_protocol_detection("GNUTELLA", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_GNUTELLA, + ndpi_search_gnutella, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_WINMX + ndpi_set_bitmask_protocol_detection("WINMX", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_WINMX, + ndpi_search_winmx_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_DIRECTCONNECT + ndpi_set_bitmask_protocol_detection("DIRECTCONNECT", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_DIRECTCONNECT, + ndpi_search_directconnect, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_MSN + + NDPI_BITMASK_RESET(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask); + + ndpi_set_bitmask_protocol_detection("MSN", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_MSN, + ndpi_search_msn, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_YAHOO + ndpi_set_bitmask_protocol_detection("YAHOO", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_YAHOO, + ndpi_search_yahoo, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_OSCAR + ndpi_set_bitmask_protocol_detection("OSCAR", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_OSCAR, + ndpi_search_oscar, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_APPLEJUICE + ndpi_set_bitmask_protocol_detection("APPLEJUICE", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_APPLEJUICE, + ndpi_search_applejuice_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_SOULSEEK + ndpi_set_bitmask_protocol_detection("SOULSEEK", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_SOULSEEK, + ndpi_search_soulseek_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_IRC + ndpi_set_bitmask_protocol_detection("IRC", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_IRC, + ndpi_search_irc_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER + ndpi_set_bitmask_protocol_detection("UNENCRYPED_JABBER", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_UNENCRYPED_JABBER, + ndpi_search_jabber_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_MAIL_POP + ndpi_set_bitmask_protocol_detection("MAIL_POP", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_MAIL_POP, + ndpi_search_mail_pop_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_MAIL_IMAP + ndpi_set_bitmask_protocol_detection("MAIL_IMAP", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_MAIL_IMAP, + ndpi_search_mail_imap_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_MAIL_SMTP + ndpi_set_bitmask_protocol_detection("MAIL_SMTP", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_MAIL_SMTP, + ndpi_search_mail_smtp_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_USENET + ndpi_set_bitmask_protocol_detection("USENET", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_USENET, + ndpi_search_usenet_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_DNS + ndpi_set_bitmask_protocol_detection("DNS", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_DNS, + ndpi_search_dns, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_FILETOPIA + ndpi_set_bitmask_protocol_detection("FILETOPIA", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_FILETOPIA, + ndpi_search_filetopia_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_VMWARE + ndpi_set_bitmask_protocol_detection("VMWARE", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_VMWARE, + ndpi_search_vmware, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_IMESH + ndpi_set_bitmask_protocol_detection("IMESH", ndpi_struct, detection_bitmask,a++, + NDPI_PROTOCOL_IMESH, + ndpi_search_imesh_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_CONTENT_MMS + ndpi_set_bitmask_protocol_detection("NDPI_CONTENT_MMS", ndpi_struct, detection_bitmask,a++, + NDPI_CONTENT_MMS, + ndpi_search_mms_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#if defined(NDPI_PROTOCOL_IP_IPSEC) || defined(NDPI_PROTOCOL_IP_GRE) || defined(NDPI_PROTOCOL_IP_ICMP) || defined(NDPI_PROTOCOL_IP_IGMP) || defined(NDPI_PROTOCOL_IP_EGP) || defined(NDPI_PROTOCOL_IP_SCTP) || defined(NDPI_PROTOCOL_IP_OSPF) || defined(NDPI_PROTOCOL_IP_IP_IN_IP) || defined(NDPI_PROTOCOL_IP_ICMPV6) + + /* always add non tcp/udp if one protocol is compiled in */ + NDPI_SAVE_AS_BITMASK(ndpi_struct->callback_buffer[a].detection_bitmask, NDPI_PROTOCOL_UNKNOWN); + + ndpi_set_bitmask_protocol_detection("IP_IPSEC", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_IP_IPSEC, + ndpi_search_in_non_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + ndpi_set_bitmask_protocol_detection("IP_GRE", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_IP_GRE, + ndpi_search_in_non_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + ndpi_set_bitmask_protocol_detection("IP_ICMP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_IP_ICMP, + ndpi_search_in_non_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + ndpi_set_bitmask_protocol_detection("IP_IGMP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_IP_IGMP, + ndpi_search_in_non_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + ndpi_set_bitmask_protocol_detection("IP_EGP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_IP_EGP, + ndpi_search_in_non_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + ndpi_set_bitmask_protocol_detection("IP_SCTP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_IP_SCTP, + ndpi_search_in_non_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + ndpi_set_bitmask_protocol_detection("IP_OSPF", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_IP_OSPF, + ndpi_search_in_non_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + ndpi_set_bitmask_protocol_detection("IP_IP_IN_IP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_IP_IP_IN_IP, + ndpi_search_in_non_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + ndpi_set_bitmask_protocol_detection("IP_ICMPV6", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_IP_ICMPV6, + ndpi_search_in_non_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6, + NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + // NDPI_BITMASK_RESET(ndpi_struct->callback_buffer[a].excluded_protocol_bitmask); +#endif + + +#ifdef NDPI_PROTOCOL_TVANTS + ndpi_set_bitmask_protocol_detection("TVANTS", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_TVANTS, + ndpi_search_tvants_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_SOPCAST + ndpi_set_bitmask_protocol_detection("SOPCAST", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SOPCAST, + ndpi_search_sopcast, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_TVUPLAYER + ndpi_set_bitmask_protocol_detection("TVUPLAYER", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_TVUPLAYER, + ndpi_search_tvuplayer, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_PPSTREAM + ndpi_set_bitmask_protocol_detection("PPSTREAM", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_PPSTREAM, + ndpi_search_ppstream, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_PPLIVE + ndpi_set_bitmask_protocol_detection("PPLIVE", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_PPLIVE, + ndpi_search_pplive, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_IAX + ndpi_set_bitmask_protocol_detection("IAX", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_IAX, + ndpi_search_iax, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_MGCP + ndpi_set_bitmask_protocol_detection("MGCP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_MGCP, + ndpi_search_mgcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_ZATTOO + ndpi_set_bitmask_protocol_detection("ZATTOO", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_ZATTOO, + ndpi_search_zattoo, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_QQ + ndpi_set_bitmask_protocol_detection("QQ", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_QQ, + ndpi_search_qq, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_SSH + ndpi_set_bitmask_protocol_detection("SSH", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SSH, + ndpi_search_ssh_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_AYIYA + ndpi_set_bitmask_protocol_detection("AYIYA", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_AYIYA, + ndpi_search_ayiya, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_THUNDER + ndpi_set_bitmask_protocol_detection("THUNDER", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_THUNDER, + ndpi_search_thunder, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_VNC + ndpi_set_bitmask_protocol_detection("VNC", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_VNC, + ndpi_search_vnc_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_TEAMVIEWER + ndpi_set_bitmask_protocol_detection("TEAMVIEWER", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_TEAMVIEWER, + ndpi_search_teamview, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_DHCP + ndpi_set_bitmask_protocol_detection("DHCP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_DHCP, + ndpi_search_dhcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_SOCRATES + ndpi_set_bitmask_protocol_detection("SOCRATES", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SOCRATES, + ndpi_search_socrates, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_STEAM + ndpi_set_bitmask_protocol_detection("STEAM", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_STEAM, + ndpi_search_steam, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_HALFLIFE2 + ndpi_set_bitmask_protocol_detection("HALFLIFE2", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_HALFLIFE2, + ndpi_search_halflife2, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_XBOX + ndpi_set_bitmask_protocol_detection("XBOX", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_XBOX, + ndpi_search_xbox, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC + ndpi_set_bitmask_protocol_detection("HTTP_APPLICATION_ACTIVESYNC", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC, + ndpi_search_activesync, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_SMB + ndpi_set_bitmask_protocol_detection("SMB", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SMB, + ndpi_search_smb_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_TELNET + ndpi_set_bitmask_protocol_detection("TELNET", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_TELNET, + ndpi_search_telnet_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_NTP + ndpi_set_bitmask_protocol_detection("NTP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_NTP, + ndpi_search_ntp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_NFS + ndpi_set_bitmask_protocol_detection("NFS", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_NFS, + ndpi_search_nfs, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_SSDP + ndpi_set_bitmask_protocol_detection("SSDP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SSDP, + ndpi_search_ssdp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_WORLDOFWARCRAFT + ndpi_set_bitmask_protocol_detection("WORLDOFWARCRAFT", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_WORLDOFWARCRAFT, + ndpi_search_worldofwarcraft, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_POSTGRES + ndpi_set_bitmask_protocol_detection("POSTGRES", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_POSTGRES, + ndpi_search_postgres_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_MYSQL + ndpi_set_bitmask_protocol_detection("MYSQL", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_MYSQL, + ndpi_search_mysql_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_BGP + ndpi_set_bitmask_protocol_detection("BGP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_BGP, + ndpi_search_bgp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_QUAKE + ndpi_set_bitmask_protocol_detection("QUAKE", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_QUAKE, + ndpi_search_quake, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_BATTLEFIELD + ndpi_set_bitmask_protocol_detection("BATTLEFIELD", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_BATTLEFIELD, + ndpi_search_battlefield, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_PCANYWHERE + ndpi_set_bitmask_protocol_detection("PCANYWHERE", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_PCANYWHERE, + ndpi_search_pcanywhere, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_SNMP + ndpi_set_bitmask_protocol_detection("SNMP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SNMP, + ndpi_search_snmp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_KONTIKI + ndpi_set_bitmask_protocol_detection("KONTIKI", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_KONTIKI, + ndpi_search_kontiki, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_ICECAST + ndpi_set_bitmask_protocol_detection("ICECAST", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_ICECAST, + ndpi_search_icecast_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_SHOUTCAST + ndpi_set_bitmask_protocol_detection("SHOUTCAST", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SHOUTCAST, + ndpi_search_shoutcast_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV + ndpi_set_bitmask_protocol_detection("HTTP_APPLICATION_VEOHTV", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, + ndpi_search_veohtv_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_KERBEROS + ndpi_set_bitmask_protocol_detection("KERBEROS", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_KERBEROS, + ndpi_search_kerberos, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_OPENFT + ndpi_set_bitmask_protocol_detection("OPENFT", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_OPENFT, + ndpi_search_openft_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_SYSLOG + ndpi_set_bitmask_protocol_detection("SYSLOG", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SYSLOG, + ndpi_search_syslog, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_TDS + ndpi_set_bitmask_protocol_detection("TDS", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_TDS, + ndpi_search_tds_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK + ndpi_set_bitmask_protocol_detection("DIRECT_DOWNLOAD_LINK", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, + ndpi_search_direct_download_link_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_NETBIOS + ndpi_set_bitmask_protocol_detection("NETBIOS", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_NETBIOS, + ndpi_search_netbios, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_MDNS + ndpi_set_bitmask_protocol_detection("MDNS", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_MDNS, + ndpi_search_mdns, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_IPP + ndpi_set_bitmask_protocol_detection("IPP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_IPP, + ndpi_search_ipp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_LDAP + ndpi_set_bitmask_protocol_detection("LDAP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_LDAP, + ndpi_search_ldap, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_WARCRAFT3 + ndpi_set_bitmask_protocol_detection("WARCRAFT3", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_WARCRAFT3, + ndpi_search_warcraft3, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_XDMCP + ndpi_set_bitmask_protocol_detection("XDMCP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_XDMCP, + ndpi_search_xdmcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_TFTP + ndpi_set_bitmask_protocol_detection("TFTP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_TFTP, + ndpi_search_tftp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_MSSQL + ndpi_set_bitmask_protocol_detection("MSSQL", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_MSSQL, + ndpi_search_mssql, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_PPTP + ndpi_set_bitmask_protocol_detection("PPTP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_PPTP, + ndpi_search_pptp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_STEALTHNET + ndpi_set_bitmask_protocol_detection("STEALTHNET", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_STEALTHNET, + ndpi_search_stealthnet, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_DHCPV6 + ndpi_set_bitmask_protocol_detection("DHCPV6", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_DHCPV6, + ndpi_search_dhcpv6_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_MEEBO + ndpi_set_bitmask_protocol_detection("Meebo", ndpi_struct, detection_bitmask, a, + NDPI_PROTOCOL_MEEBO, + ndpi_search_meebo, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + /* Add protocol bitmask dependencies to detected bitmask*/ +#ifdef NDPI_CONTENT_FLASH + NDPI_ADD_PROTOCOL_TO_BITMASK(ndpi_struct->callback_buffer[a].detection_bitmask, NDPI_CONTENT_FLASH); +#endif + a++; +#endif + +#ifdef NDPI_PROTOCOL_AFP + ndpi_set_bitmask_protocol_detection("AFP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_AFP, + ndpi_search_afp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_AIMINI + ndpi_set_bitmask_protocol_detection("AIMINI", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_AIMINI, + ndpi_search_aimini, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_FLORENSIA + ndpi_set_bitmask_protocol_detection("FLORENSIA", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_FLORENSIA, + ndpi_search_florensia, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_MAPLESTORY + ndpi_set_bitmask_protocol_detection("MAPLESTORY", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_MAPLESTORY, + ndpi_search_maplestory, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_DOFUS + ndpi_set_bitmask_protocol_detection("DOFUS", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_DOFUS, + ndpi_search_dofus, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_WORLD_OF_KUNG_FU + ndpi_set_bitmask_protocol_detection("WORLD_OF_KUNG_FU", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_WORLD_OF_KUNG_FU, + ndpi_search_world_of_kung_fu, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_FIESTA + ndpi_set_bitmask_protocol_detection("FIESTA", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_FIESTA, + ndpi_search_fiesta, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_CROSSFIRE + ndpi_set_bitmask_protocol_detection("CROSSFIRE", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_CROSSFIRE, + ndpi_search_crossfire_tcp_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_GUILDWARS + ndpi_set_bitmask_protocol_detection("GUILDWARS", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_GUILDWARS, + ndpi_search_guildwars_tcp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif +#ifdef NDPI_PROTOCOL_ARMAGETRON + ndpi_set_bitmask_protocol_detection("ARMAGETRON", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_ARMAGETRON, + ndpi_search_armagetron_udp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_DROPBOX + ndpi_set_bitmask_protocol_detection("DROPBOX", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_DROPBOX, + ndpi_search_dropbox, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_SPOTIFY + ndpi_set_bitmask_protocol_detection("SPOTIFY", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SPOTIFY, + ndpi_search_spotify, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_SKYPE + ndpi_set_bitmask_protocol_detection("SKYPE", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SKYPE, + ndpi_search_skype, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_RADIUS + ndpi_set_bitmask_protocol_detection("RADIUS", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_RADIUS, + ndpi_search_radius, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_CITRIX + ndpi_set_bitmask_protocol_detection("CITRIX", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_CITRIX, + ndpi_search_citrix, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_LOTUS_NOTES + ndpi_set_bitmask_protocol_detection("LOTUS_NOTES", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_LOTUS_NOTES, + ndpi_search_lotus_notes, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_GTP + ndpi_set_bitmask_protocol_detection("GTP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_GTP, + ndpi_search_gtp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_DCERPC + ndpi_set_bitmask_protocol_detection("DCERPC", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_DCERPC, + ndpi_search_dcerpc, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_NETFLOW + ndpi_set_bitmask_protocol_detection("NETFLOW", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_NETFLOW, + ndpi_search_netflow, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_SFLOW + ndpi_set_bitmask_protocol_detection("SFLOW", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SFLOW, + ndpi_search_sflow, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_H323 + ndpi_set_bitmask_protocol_detection("H323", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_H323, + ndpi_search_h323, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_OPENVPN + ndpi_set_bitmask_protocol_detection("OPENVPN", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_OPENVPN, + ndpi_search_openvpn, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_NOE + ndpi_set_bitmask_protocol_detection("NOE", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_NOE, + ndpi_search_noe, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_CISCOVPN + ndpi_set_bitmask_protocol_detection("CISCOVPN", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_CISCOVPN, + ndpi_search_ciscovpn, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_TEAMSPEAK + ndpi_set_bitmask_protocol_detection("TEAMSPEAK", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_TEAMSPEAK, + ndpi_search_teamspeak, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_VIBER + ndpi_set_bitmask_protocol_detection("VIBER", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_VIBER, + ndpi_search_viber, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_TOR + ndpi_set_bitmask_protocol_detection("TOR", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_TOR, + ndpi_search_tor, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_SKINNY + ndpi_set_bitmask_protocol_detection("SKINNY", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_SKINNY, + ndpi_search_skinny, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_RTCP + ndpi_set_bitmask_protocol_detection("RTCP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_RTCP, + ndpi_search_rtcp, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_RSYNC + ndpi_set_bitmask_protocol_detection("RSYNC", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_RSYNC, + ndpi_search_rsync, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_WHOIS_DAS + ndpi_set_bitmask_protocol_detection("WHOIS_DAS", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_WHOIS_DAS, + ndpi_search_whois_das, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_ORACLE + ndpi_set_bitmask_protocol_detection("ORACLE", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_ORACLE, + ndpi_search_oracle, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_CORBA + ndpi_set_bitmask_protocol_detection("CORBA", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_CORBA, + ndpi_search_corba, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_RTMP + ndpi_set_bitmask_protocol_detection("RTMP", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_RTMP, + ndpi_search_rtmp, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_FTP_CONTROL + ndpi_set_bitmask_protocol_detection("FTP_CONTROL", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_FTP_CONTROL, + ndpi_search_ftp_control, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_FTP_DATA + ndpi_set_bitmask_protocol_detection("FTP_DATA", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_FTP_DATA, + ndpi_search_ftp_data, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_PANDO + ndpi_set_bitmask_protocol_detection("PANDO", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_PANDO, + ndpi_search_pando, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_MEGACO + ndpi_set_bitmask_protocol_detection("MEGACO", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_MEGACO, + ndpi_search_megaco, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_REDIS + ndpi_set_bitmask_protocol_detection("REDIS", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_REDIS, + ndpi_search_redis, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_VHUA + ndpi_set_bitmask_protocol_detection("VHUA", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_VHUA, + ndpi_search_vhua, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_ZMQ + ndpi_set_bitmask_protocol_detection("ZMQ", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_ZMQ, + ndpi_search_zmq, /* TODO: add UDP support */ + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + + +#ifdef NDPI_SERVICE_TWITTER + ndpi_set_bitmask_protocol_detection("TWITTER", ndpi_struct, detection_bitmask, a++, + NDPI_SERVICE_TWITTER, + ndpi_search_twitter, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + +#ifdef NDPI_PROTOCOL_TELEGRAM + ndpi_set_bitmask_protocol_detection("TELEGRAM", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_TELEGRAM, + ndpi_search_telegram, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + + ndpi_struct->callback_buffer_size = a; + + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, + "callback_buffer_size is %u\n", ndpi_struct->callback_buffer_size); + + /* now build the specific buffer for tcp, udp and non_tcp_udp */ + ndpi_struct->callback_buffer_size_tcp_payload = 0; + ndpi_struct->callback_buffer_size_tcp_no_payload = 0; + for (a = 0; a < ndpi_struct->callback_buffer_size; a++) { + if((ndpi_struct->callback_buffer[a].ndpi_selection_bitmask + & (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | + NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP | + NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC)) != 0) { + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, + "callback_buffer_tcp_payload, adding buffer %u as entry %u\n", a, + ndpi_struct->callback_buffer_size_tcp_payload); + + memcpy(&ndpi_struct->callback_buffer_tcp_payload[ndpi_struct->callback_buffer_size_tcp_payload], + &ndpi_struct->callback_buffer[a], sizeof(struct ndpi_call_function_struct)); + ndpi_struct->callback_buffer_size_tcp_payload++; + + if((ndpi_struct-> + callback_buffer[a].ndpi_selection_bitmask & NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) == 0) { + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, + "\tcallback_buffer_tcp_no_payload, additional adding buffer %u to no_payload process\n", a); + + memcpy(&ndpi_struct->callback_buffer_tcp_no_payload + [ndpi_struct->callback_buffer_size_tcp_no_payload], &ndpi_struct->callback_buffer[a], + sizeof(struct ndpi_call_function_struct)); + ndpi_struct->callback_buffer_size_tcp_no_payload++; + } + } + } + + ndpi_struct->callback_buffer_size_udp = 0; + for (a = 0; a < ndpi_struct->callback_buffer_size; a++) { + if((ndpi_struct->callback_buffer[a].ndpi_selection_bitmask & (NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP | + NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP | + NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC)) + != 0) { + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, + "callback_buffer_size_udp: adding buffer : %u as entry %u\n", a, ndpi_struct->callback_buffer_size_udp); + + memcpy(&ndpi_struct->callback_buffer_udp[ndpi_struct->callback_buffer_size_udp], + &ndpi_struct->callback_buffer[a], sizeof(struct ndpi_call_function_struct)); + ndpi_struct->callback_buffer_size_udp++; + } + } + + ndpi_struct->callback_buffer_size_non_tcp_udp = 0; + for (a = 0; a < ndpi_struct->callback_buffer_size; a++) { + if((ndpi_struct->callback_buffer[a].ndpi_selection_bitmask & (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | + NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP | + NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP)) + == 0 + || (ndpi_struct-> + callback_buffer[a].ndpi_selection_bitmask & NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC) != 0) { + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, + "callback_buffer_non_tcp_udp: adding buffer : %u as entry %u\n", a, ndpi_struct->callback_buffer_size_non_tcp_udp); + + memcpy(&ndpi_struct->callback_buffer_non_tcp_udp[ndpi_struct->callback_buffer_size_non_tcp_udp], + &ndpi_struct->callback_buffer[a], sizeof(struct ndpi_call_function_struct)); + ndpi_struct->callback_buffer_size_non_tcp_udp++; + } + } +} + +#ifdef NDPI_DETECTION_SUPPORT_IPV6 +/* handle extension headers in IPv6 packets + * arguments: + * l4ptr: pointer to the byte following the initial IPv6 header + * l4len: the length of the IPv6 packet excluding the IPv6 header + * nxt_hdr: next header value from the IPv6 header + * result: + * l4ptr: pointer to the start of the actual packet payload + * l4len: length of the actual payload + * nxt_hdr: protocol of the actual payload + * returns 0 upon success and 1 upon failure + */ +static int ndpi_handle_ipv6_extension_headers(struct ndpi_detection_module_struct *ndpi_struct, + const u_int8_t ** l4ptr, u_int16_t * l4len, u_int8_t * nxt_hdr) +{ + while ((*nxt_hdr == 0 || *nxt_hdr == 43 || *nxt_hdr == 44 || *nxt_hdr == 60 || *nxt_hdr == 135 || *nxt_hdr == 59)) { + u_int16_t ehdr_len; + + // no next header + if(*nxt_hdr == 59) { + return 1; + } + // fragment extension header has fixed size of 8 bytes and the first byte is the next header type + if(*nxt_hdr == 44) { + if(*l4len < 8) { + return 1; + } + *nxt_hdr = (*l4ptr)[0]; + *l4len -= 8; + (*l4ptr) += 8; + continue; + } + // the other extension headers have one byte for the next header type + // and one byte for the extension header length in 8 byte steps minus the first 8 bytes + ehdr_len = (*l4ptr)[1]; + ehdr_len *= 8; + ehdr_len += 8; + + if(*l4len < ehdr_len) { + return 1; + } + *nxt_hdr = (*l4ptr)[0]; + *l4len -= ehdr_len; + (*l4ptr) += ehdr_len; + } + return 0; +} +#endif /* NDPI_DETECTION_SUPPORT_IPV6 */ + + +static u_int8_t ndpi_iph_is_valid_and_not_fragmented(const struct ndpi_iphdr *iph, const u_int16_t ipsize) +{ + //#ifdef REQUIRE_FULL_PACKETS + if(ipsize < iph->ihl * 4 || + ipsize < ntohs(iph->tot_len) || ntohs(iph->tot_len) < iph->ihl * 4 || (iph->frag_off & htons(0x1FFF)) != 0) { + return 0; + } + //#endif + + return 1; +} + +static u_int8_t ndpi_detection_get_l4_internal(struct ndpi_detection_module_struct *ndpi_struct, + const u_int8_t * l3, u_int16_t l3_len, const u_int8_t ** l4_return, u_int16_t * l4_len_return, + u_int8_t * l4_protocol_return, u_int32_t flags) +{ + const struct ndpi_iphdr *iph = NULL; +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + const struct ndpi_ipv6hdr *iph_v6 = NULL; +#endif + u_int16_t l4len = 0; + const u_int8_t *l4ptr = NULL; + u_int8_t l4protocol = 0; + + if(l3 == NULL || l3_len < sizeof(struct ndpi_iphdr)) + return 1; + + iph = (const struct ndpi_iphdr *) l3; + + if(iph->version == 4 && iph->ihl >= 5) { + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv4 header\n"); + } +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + else if(iph->version == 6 && l3_len >= sizeof(struct ndpi_ipv6hdr)) { + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv6 header\n"); + iph_v6 = (const struct ndpi_ipv6hdr *) iph; + iph = NULL; + } +#endif + else { + return 1; + } + + if((flags & NDPI_DETECTION_ONLY_IPV6) && iph != NULL) { + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv4 header found but excluded by flag\n"); + return 1; + } +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + else if((flags & NDPI_DETECTION_ONLY_IPV4) && iph_v6 != NULL) { + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv6 header found but excluded by flag\n"); + return 1; + } +#endif + + if(iph != NULL && ndpi_iph_is_valid_and_not_fragmented(iph, l3_len)) { + u_int16_t len = ntohs(iph->tot_len); + u_int16_t hlen = (iph->ihl * 4); + + l4ptr = (((const u_int8_t *) iph) + iph->ihl * 4); + + if(len == 0) len = l3_len; + + l4len = (len > hlen) ? (len - hlen) : 0; + l4protocol = iph->protocol; + } +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + else if(iph_v6 != NULL && (l3_len - sizeof(struct ndpi_ipv6hdr)) >= ntohs(iph_v6->payload_len)) { + l4ptr = (((const u_int8_t *) iph_v6) + sizeof(struct ndpi_ipv6hdr)); + l4len = ntohs(iph_v6->payload_len); + l4protocol = iph_v6->nexthdr; + + // we need to handle IPv6 extension headers if present + if(ndpi_handle_ipv6_extension_headers(ndpi_struct, &l4ptr, &l4len, &l4protocol) != 0) { + return 1; + } + + } +#endif + else { + return 1; + } + + if(l4_return != NULL) { + *l4_return = l4ptr; + } + + if(l4_len_return != NULL) { + *l4_len_return = l4len; + } + + if(l4_protocol_return != NULL) { + *l4_protocol_return = l4protocol; + } + + return 0; +} + +#if !defined(WIN32) +#define ATTRIBUTE_ALWAYS_INLINE static inline +#else +__forceinline static +#endif +void ndpi_apply_flow_protocol_to_packet(struct ndpi_flow_struct *flow, + struct ndpi_packet_struct *packet) +{ + memcpy(&packet->detected_protocol_stack[0], + &flow->detected_protocol_stack[0], sizeof(packet->detected_protocol_stack)); +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 + memcpy(&packet->protocol_stack_info, &flow->protocol_stack_info, sizeof(packet->protocol_stack_info)); +#endif +} + +static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + unsigned short packetlen) +{ + const struct ndpi_iphdr *decaps_iph = NULL; + u_int16_t l3len; + u_int16_t l4len; + const u_int8_t *l4ptr; + u_int8_t l4protocol; + u_int8_t l4_result; + + /* reset payload_packet_len, will be set if ipv4 tcp or udp */ + flow->packet.payload_packet_len = 0; + flow->packet.l4_packet_len = 0; + flow->packet.l3_packet_len = packetlen; + + flow->packet.tcp = NULL; + flow->packet.udp = NULL; + flow->packet.generic_l4_ptr = NULL; +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + flow->packet.iphv6 = NULL; +#endif /* NDPI_DETECTION_SUPPORT_IPV6 */ + + if(flow) { + ndpi_apply_flow_protocol_to_packet(flow, &flow->packet); + } else { + ndpi_int_reset_packet_protocol(&flow->packet); + } + + l3len = flow->packet.l3_packet_len; + +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + if(flow->packet.iph != NULL) { +#endif /* NDPI_DETECTION_SUPPORT_IPV6 */ + + decaps_iph =flow->packet.iph; + +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + } +#endif /* NDPI_DETECTION_SUPPORT_IPV6 */ + + if(decaps_iph->version == 4 && decaps_iph->ihl >= 5) { + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv4 header\n"); + } +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + else if(decaps_iph->version == 6 && l3len >= sizeof(struct ndpi_ipv6hdr) && + (ndpi_struct->ip_version_limit & NDPI_DETECTION_ONLY_IPV4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "ipv6 header\n"); + flow->packet.iphv6 = (struct ndpi_ipv6hdr *)flow->packet.iph; + flow->packet.iph = NULL; + } +#endif + else { + flow->packet.iph = NULL; + return 1; + } + + + /* needed: + * - unfragmented packets + * - ip header <= packet len + * - ip total length >= packet len + */ + + + l4ptr = NULL; + l4len = 0; + l4protocol = 0; + + l4_result = + ndpi_detection_get_l4_internal(ndpi_struct, (const u_int8_t *) decaps_iph, l3len, &l4ptr, &l4len, &l4protocol, 0); + + if(l4_result != 0) { + return 1; + } + + flow->packet.l4_protocol = l4protocol; + flow->packet.l4_packet_len = l4len; + + /* tcp / udp detection */ + if(l4protocol == 6 /* TCP */ &&flow->packet.l4_packet_len >= 20 /* min size of tcp */ ) { + /* tcp */ + flow->packet.tcp = (struct ndpi_tcphdr *) l4ptr; + + if(flow->packet.l4_packet_len >=flow->packet.tcp->doff * 4) { + flow->packet.payload_packet_len = + flow->packet.l4_packet_len -flow->packet.tcp->doff * 4; + flow->packet.actual_payload_len =flow->packet.payload_packet_len; + flow->packet.payload = ((u_int8_t *)flow->packet.tcp) + (flow->packet.tcp->doff * 4); + + /* check for new tcp syn packets, here + * idea: reset detection state if a connection is unknown + */ + if(flow && flow->packet.tcp->syn != 0 + && flow->packet.tcp->ack == 0 + && flow->init_finished != 0 + && flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { + + memset(flow, 0, sizeof(*(flow))); + + + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, + NDPI_LOG_DEBUG, + "%s:%u: tcp syn packet for unknown protocol, reset detection state\n", __FUNCTION__, __LINE__); + + } + } else { + /* tcp header not complete */ + flow->packet.tcp = NULL; + } + } else if(l4protocol == 17 /* udp */ &&flow->packet.l4_packet_len >= 8 /* size of udp */ ) { + flow->packet.udp = (struct ndpi_udphdr *) l4ptr; + flow->packet.payload_packet_len =flow->packet.l4_packet_len - 8; + flow->packet.payload = ((u_int8_t *)flow->packet.udp) + 8; + } else { + flow->packet.generic_l4_ptr = l4ptr; + } + return 0; +} + + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + /* const for gcc code optimisation and cleaner code */ + struct ndpi_packet_struct *packet = &flow->packet; + const struct ndpi_iphdr *iph = packet->iph; +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + const struct ndpi_ipv6hdr *iphv6 = packet->iphv6; +#endif + const struct ndpi_tcphdr *tcph = packet->tcp; + const struct ndpi_udphdr *udph = flow->packet.udp; + + //struct ndpi_unique_flow_struct unique_flow; + //uint8_t new_connection; + + u_int8_t proxy_enabled = 0; + + packet->tcp_retransmission = 0, packet->packet_direction = 0; + + if(ndpi_struct->direction_detect_disable) { + packet->packet_direction = flow->packet_direction; + } else { + if(iph != NULL && iph->saddr < iph->daddr) + packet->packet_direction = 1; + +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + if(iphv6 != NULL && NDPI_COMPARE_IPV6_ADDRESS_STRUCTS(&iphv6->saddr, &iphv6->daddr) != 0) + packet->packet_direction = 1; +#endif + } + + packet->packet_lines_parsed_complete = 0; + if(flow == NULL) + return; + + if(flow->init_finished == 0) { + flow->init_finished = 1; + flow->setup_packet_direction = packet->packet_direction; + } + + if(tcph != NULL) { + /* reset retried bytes here before setting it */ + packet->num_retried_bytes = 0; + + if(!ndpi_struct->direction_detect_disable) + packet->packet_direction = (tcph->source < tcph->dest) ? 1 : 0; + + if(tcph->syn != 0 && tcph->ack == 0 && flow->l4.tcp.seen_syn == 0 && flow->l4.tcp.seen_syn_ack == 0 + && flow->l4.tcp.seen_ack == 0) { + flow->l4.tcp.seen_syn = 1; + } + if(tcph->syn != 0 && tcph->ack != 0 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 0 + && flow->l4.tcp.seen_ack == 0) { + flow->l4.tcp.seen_syn_ack = 1; + } + if(tcph->syn == 0 && tcph->ack == 1 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 1 + && flow->l4.tcp.seen_ack == 0) { + flow->l4.tcp.seen_ack = 1; + } + if((flow->next_tcp_seq_nr[0] == 0 && flow->next_tcp_seq_nr[1] == 0) + || (proxy_enabled && (flow->next_tcp_seq_nr[0] == 0 || flow->next_tcp_seq_nr[1] == 0))) { + /* initalize tcp sequence counters */ + /* the ack flag needs to be set to get valid sequence numbers from the other + * direction. Usually it will catch the second packet syn+ack but it works + * also for asymmetric traffic where it will use the first data packet + * + * if the syn flag is set add one to the sequence number, + * otherwise use the payload length. + */ + if(tcph->ack != 0) { + flow->next_tcp_seq_nr[flow->packet.packet_direction] = + ntohl(tcph->seq) + (tcph->syn ? 1 : packet->payload_packet_len); + if(!proxy_enabled) { + flow->next_tcp_seq_nr[1 -flow->packet.packet_direction] = ntohl(tcph->ack_seq); + } + } + } else if(packet->payload_packet_len > 0) { + /* check tcp sequence counters */ + if(((u_int32_t) + (ntohl(tcph->seq) - + flow->next_tcp_seq_nr[packet->packet_direction])) > + ndpi_struct->tcp_max_retransmission_window_size) { + + packet->tcp_retransmission = 1; + + + /*CHECK IF PARTIAL RETRY IS HAPPENENING */ + if((flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq) < packet->payload_packet_len)) { + /* num_retried_bytes actual_payload_len hold info about the partial retry + analyzer which require this info can make use of this info + Other analyzer can use packet->payload_packet_len */ + packet->num_retried_bytes = (u_int16_t)(flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq)); + packet->actual_payload_len = packet->payload_packet_len - packet->num_retried_bytes; + flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len; + } + } + /*normal path + actual_payload_len is initialized to payload_packet_len during tcp header parsing itself. + It will be changed only in case of retransmission */ + else { + + + packet->num_retried_bytes = 0; + flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len; + } + + + } + + if(tcph->rst) { + flow->next_tcp_seq_nr[0] = 0; + flow->next_tcp_seq_nr[1] = 0; + } + } else if(udph != NULL) { + if(!ndpi_struct->direction_detect_disable) + packet->packet_direction = (udph->source < udph->dest) ? 1 : 0; + } + + if(flow->packet_counter < MAX_PACKET_COUNTER && packet->payload_packet_len) { + flow->packet_counter++; + } + + if(flow->packet_direction_counter[packet->packet_direction] < MAX_PACKET_COUNTER && packet->payload_packet_len) { + flow->packet_direction_counter[packet->packet_direction]++; + } + + if(flow->byte_counter[packet->packet_direction] + packet->payload_packet_len > + flow->byte_counter[packet->packet_direction]) { + flow->byte_counter[packet->packet_direction] += packet->payload_packet_len; + } +} + +void check_ndpi_other_flow_func(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) { + void *func = NULL; + u_int32_t a; + u_int16_t proto_index = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoIdx; + int16_t proto_id = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoId; + NDPI_PROTOCOL_BITMASK detection_bitmask; + + NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]); + + if((proto_id != NDPI_PROTOCOL_UNKNOWN) + && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask, + ndpi_struct->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 + && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer[proto_index].detection_bitmask, + detection_bitmask) != 0 + && (ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask + & *ndpi_selection_packet) == ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask) { + if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) + && (ndpi_struct->proto_defaults[flow->guessed_protocol_id].func != NULL)) + ndpi_struct->proto_defaults[flow->guessed_protocol_id].func(ndpi_struct, flow), + func = ndpi_struct->proto_defaults[flow->guessed_protocol_id].func; + } + + for (a = 0; a < ndpi_struct->callback_buffer_size_non_tcp_udp; a++) { + if((func != ndpi_struct->callback_buffer_non_tcp_udp[a].func) + && (ndpi_struct->callback_buffer_non_tcp_udp[a].ndpi_selection_bitmask & *ndpi_selection_packet) == + ndpi_struct->callback_buffer_non_tcp_udp[a].ndpi_selection_bitmask + && (flow == NULL + || + NDPI_BITMASK_COMPARE + (flow->excluded_protocol_bitmask, + ndpi_struct->callback_buffer_non_tcp_udp[a].excluded_protocol_bitmask) == 0) + && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer_non_tcp_udp[a].detection_bitmask, + detection_bitmask) != 0) { + + if(ndpi_struct->callback_buffer_non_tcp_udp[a].func != NULL) + ndpi_struct->callback_buffer_non_tcp_udp[a].func(ndpi_struct, flow); + + if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) + break; /* Stop after detecting the first protocol */ + } + } +} + + +void check_ndpi_udp_flow_func(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) { + void *func = NULL; + u_int32_t a; + u_int16_t proto_index = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoIdx; + int16_t proto_id = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoId; + NDPI_PROTOCOL_BITMASK detection_bitmask; + + NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]); + + if((proto_id != NDPI_PROTOCOL_UNKNOWN) + && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask, + ndpi_struct->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 + && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer[proto_index].detection_bitmask, + detection_bitmask) != 0 + && (ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask + & *ndpi_selection_packet) == ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask) { + if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) + && (ndpi_struct->proto_defaults[flow->guessed_protocol_id].func != NULL)) + ndpi_struct->proto_defaults[flow->guessed_protocol_id].func(ndpi_struct, flow), + func = ndpi_struct->proto_defaults[flow->guessed_protocol_id].func; + } + + for (a = 0; a < ndpi_struct->callback_buffer_size_udp; a++) { + if((func != ndpi_struct->callback_buffer_tcp_payload[a].func) + && (ndpi_struct->callback_buffer_udp[a].ndpi_selection_bitmask & *ndpi_selection_packet) == + ndpi_struct->callback_buffer_udp[a].ndpi_selection_bitmask + && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask, + ndpi_struct->callback_buffer_udp[a].excluded_protocol_bitmask) == 0 + && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer_udp[a].detection_bitmask, + detection_bitmask) != 0) { + ndpi_struct->callback_buffer_udp[a].func(ndpi_struct, flow); + // NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, "[UDP,CALL] dissector of protocol as callback_buffer idx = %d\n",a); + if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) + break; /* Stop after detecting the first protocol */ + } else + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, + "[UDP,SKIP] dissector of protocol as callback_buffer idx = %d\n",a); + } +} + + +void check_ndpi_tcp_flow_func(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) { + void *func = NULL; + u_int32_t a; + u_int16_t proto_index = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoIdx; + int16_t proto_id = ndpi_struct->proto_defaults[flow->guessed_protocol_id].protoId; + NDPI_PROTOCOL_BITMASK detection_bitmask; + + NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]); + + if(flow->packet.payload_packet_len != 0) { + if((proto_id != NDPI_PROTOCOL_UNKNOWN) + && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask, + ndpi_struct->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 + && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer[proto_index].detection_bitmask, + detection_bitmask) != 0 + && (ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask + & *ndpi_selection_packet) == ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask) { + if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) + && (ndpi_struct->proto_defaults[flow->guessed_protocol_id].func != NULL)) + ndpi_struct->proto_defaults[flow->guessed_protocol_id].func(ndpi_struct, flow), + func = ndpi_struct->proto_defaults[flow->guessed_protocol_id].func; + } + + if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { + for (a = 0; a < ndpi_struct->callback_buffer_size_tcp_payload; a++) { + if((func != ndpi_struct->callback_buffer_tcp_payload[a].func) + && (ndpi_struct->callback_buffer_tcp_payload[a].ndpi_selection_bitmask + & *ndpi_selection_packet) == ndpi_struct->callback_buffer_tcp_payload[a].ndpi_selection_bitmask + && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask, + ndpi_struct->callback_buffer_tcp_payload[a].excluded_protocol_bitmask) == 0 + && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer_tcp_payload[a].detection_bitmask, + detection_bitmask) != 0) { + ndpi_struct->callback_buffer_tcp_payload[a].func(ndpi_struct, flow); + + if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) + break; /* Stop after detecting the first protocol */ + } + } + } + } else { + /* no payload */ + if((proto_id != NDPI_PROTOCOL_UNKNOWN) + && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask, + ndpi_struct->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 + && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer[proto_index].detection_bitmask, + detection_bitmask) != 0 + && (ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask + & *ndpi_selection_packet) == ndpi_struct->callback_buffer[proto_index].ndpi_selection_bitmask) { + if((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) + && (ndpi_struct->proto_defaults[flow->guessed_protocol_id].func != NULL) + && ((ndpi_struct->callback_buffer[flow->guessed_protocol_id].ndpi_selection_bitmask & NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) == 0)) + ndpi_struct->proto_defaults[flow->guessed_protocol_id].func(ndpi_struct, flow), + func = ndpi_struct->proto_defaults[flow->guessed_protocol_id].func; + } + + for (a = 0; a < ndpi_struct->callback_buffer_size_tcp_no_payload; a++) { + if((func != ndpi_struct->callback_buffer_tcp_payload[a].func) + && (ndpi_struct->callback_buffer_tcp_no_payload[a].ndpi_selection_bitmask & *ndpi_selection_packet) == + ndpi_struct->callback_buffer_tcp_no_payload[a].ndpi_selection_bitmask + && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask, + ndpi_struct-> + callback_buffer_tcp_no_payload[a].excluded_protocol_bitmask) == 0 + && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer_tcp_no_payload[a].detection_bitmask, + detection_bitmask) != 0) { + ndpi_struct->callback_buffer_tcp_no_payload[a].func(ndpi_struct, flow); + + if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) + break; /* Stop after detecting the first protocol */ + } + } + } +} + +void check_ndpi_flow_func(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) { + if(flow->packet.tcp != NULL) + check_ndpi_tcp_flow_func(ndpi_struct, flow, ndpi_selection_packet); + else if(flow->packet.udp != NULL) + check_ndpi_udp_flow_func(ndpi_struct, flow, ndpi_selection_packet); + else + check_ndpi_other_flow_func(ndpi_struct, flow, ndpi_selection_packet); +} + +unsigned int ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + const unsigned char *packet, + const unsigned short packetlen, + const u_int64_t current_tick_l, + struct ndpi_id_struct *src, + struct ndpi_id_struct *dst) +{ + NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet; + u_int32_t a; + + if(flow == NULL) + return NDPI_PROTOCOL_UNKNOWN; + + if(flow->server_id == NULL) flow->server_id = dst; /* Default */ + if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN && !flow->no_cache_protocol) + return(flow->detected_protocol_stack[0]); /* Stop after detecting the first protocol */ + + /* need at least 20 bytes for ip header */ + if(packetlen < 20) { + /* reset protocol which is normally done in init_packet_header */ + ndpi_int_reset_packet_protocol(&flow->packet); + + return NDPI_PROTOCOL_UNKNOWN; + } + + flow->packet.tick_timestamp_l = current_tick_l; +#ifdef __KERNEL__ + { + u_int64_t d = current_tick_l; + do_div(d,1000); + flow->packet.tick_timestamp = d; + } +#else + flow->packet.tick_timestamp = current_tick_l/1000; +#endif + + /* parse packet */ + flow->packet.iph = (struct ndpi_iphdr *) packet; + /* we are interested in ipv4 packet */ + + if(ndpi_init_packet_header(ndpi_struct, flow, packetlen) != 0) + return NDPI_PROTOCOL_UNKNOWN; + + /* detect traffic for tcp or udp only */ + + flow->src = src, flow->dst = dst; + + ndpi_connection_tracking(ndpi_struct, flow); + + /* build ndpi_selction packet bitmask */ + ndpi_selection_packet = NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC; + if(flow->packet.iph != NULL) { + ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IP | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6; + } + if(flow->packet.tcp != NULL) { + ndpi_selection_packet |= + (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP); + } + if(flow->packet.udp != NULL) { + ndpi_selection_packet |= + (NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP); + } + if(flow->packet.payload_packet_len != 0) { + ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD; + } + + if(flow->packet.tcp_retransmission == 0) { + ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION; + } +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + if(flow->packet.iphv6 != NULL) { + ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6; + } +#endif /* NDPI_DETECTION_SUPPORT_IPV6 */ + + if((!flow->protocol_id_already_guessed) + && ( +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + flow->packet.iphv6 || +#endif + flow->packet.iph)) { + u_int16_t sport, dport; + u_int8_t protocol; + u_int32_t saddr, daddr; + +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + if(flow->packet.iphv6 != NULL) { + protocol = flow->packet.iphv6->nexthdr, saddr = 0, daddr = 0; + } else +#endif + { + protocol = flow->packet.iph->protocol; + saddr = ntohl(flow->packet.iph->saddr); + daddr = ntohl(flow->packet.iph->daddr); + } + + if(flow->packet.udp) sport = ntohs(flow->packet.udp->source), dport = ntohs(flow->packet.udp->dest); + else if(flow->packet.tcp) sport = ntohs(flow->packet.tcp->source), dport = ntohs(flow->packet.tcp->dest); + else sport = dport = 0; + + flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol, + sport, dport); + flow->protocol_id_already_guessed = 1; + } + + a = flow->detected_protocol_stack[0]; + if(a != NDPI_PROTOCOL_UNKNOWN && flow->no_cache_protocol) { + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_TRACE, "PROCESS KNOWN PROTOCOL\n"); + ndpi_struct->proto_defaults[a].func(ndpi_struct, flow); + return a; + } + + check_ndpi_flow_func(ndpi_struct, flow, &ndpi_selection_packet); + + a = flow->packet.detected_protocol_stack[0]; + if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, a) == 0) + a = NDPI_PROTOCOL_UNKNOWN; + + if(a != NDPI_PROTOCOL_UNKNOWN) { + int i; + + for(i=0; (i<sizeof(flow->host_server_name)) && (flow->host_server_name[i] != '\0'); i++) + flow->host_server_name[i] = tolower(flow->host_server_name[i]); + + flow->host_server_name[i] ='\0'; + } + + return a; +} + + +u_int32_t ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read) +{ + u_int32_t val; + val = 0; + // cancel if eof, ' ' or line end chars are reached + while (*str >= '0' && *str <= '9' && max_chars_to_read > 0) { + val *= 10; + val += *str - '0'; + str++; + max_chars_to_read = max_chars_to_read - 1; + *bytes_read = *bytes_read + 1; + } + return (val); +} + +u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read) +{ + u_int32_t val; + val = 0; + if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') { + return ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read); + } else { + /*use base 16 system */ + str += 2; + max_chars_to_read -= 2; + *bytes_read = *bytes_read + 2; + while (max_chars_to_read > 0) { + + if(*str >= '0' && *str <= '9') { + val *= 16; + val += *str - '0'; + } else if(*str >= 'a' && *str <= 'f') { + val *= 16; + val += *str + 10 - 'a'; + } else if(*str >= 'A' && *str <= 'F') { + val *= 16; + val += *str + 10 - 'A'; + } else { + break; + } + str++; + max_chars_to_read = max_chars_to_read - 1; + *bytes_read = *bytes_read + 1; + } + } + return (val); +} + + +u_int64_t ndpi_bytestream_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read) +{ + u_int64_t val; + val = 0; + // cancel if eof, ' ' or line end chars are reached + while (max_chars_to_read > 0 && *str >= '0' && *str <= '9') { + val *= 10; + val += *str - '0'; + str++; + max_chars_to_read = max_chars_to_read - 1; + *bytes_read = *bytes_read + 1; + } + return (val); +} + +u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read) +{ + u_int64_t val; + val = 0; + if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') { + return ndpi_bytestream_to_number64(str, max_chars_to_read, bytes_read); + } else { + /*use base 16 system */ + str += 2; + max_chars_to_read -= 2; + *bytes_read = *bytes_read + 2; + while (max_chars_to_read > 0) { + + if(*str >= '0' && *str <= '9') { + val *= 16; + val += *str - '0'; + } else if(*str >= 'a' && *str <= 'f') { + val *= 16; + val += *str + 10 - 'a'; + } else if(*str >= 'A' && *str <= 'F') { + val *= 16; + val += *str + 10 - 'A'; + } else { + break; + } + str++; + max_chars_to_read = max_chars_to_read - 1; + *bytes_read = *bytes_read + 1; + } + } + return (val); +} + + +u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read) +{ + u_int32_t val; + u_int16_t read = 0; + u_int16_t oldread; + u_int32_t c; + /* ip address must be X.X.X.X with each X between 0 and 255 */ + oldread = read; + c = ndpi_bytestream_to_number(str, max_chars_to_read, &read); + if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.') + return 0; + read++; + val = c << 24; + oldread = read; + c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read); + if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.') + return 0; + read++; + val = val + (c << 16); + oldread = read; + c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read); + if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.') + return 0; + read++; + val = val + (c << 8); + oldread = read; + c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read); + if(c > 255 || oldread == read || max_chars_to_read == read) + return 0; + val = val + c; + + *bytes_read = *bytes_read + read; + + return htonl(val); +} + +/* internal function for every detection to parse one packet and to increase the info buffer */ +void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + u_int32_t a; + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t end = packet->payload_packet_len - 1; + if(packet->packet_lines_parsed_complete != 0) + return; + + packet->packet_lines_parsed_complete = 1; + packet->parsed_lines = 0; + + packet->empty_line_position_set = 0; + + packet->host_line.ptr = NULL; + packet->host_line.len = 0; + packet->referer_line.ptr = NULL; + packet->referer_line.len = 0; + packet->content_line.ptr = NULL; + packet->content_line.len = 0; + packet->accept_line.ptr = NULL; + packet->accept_line.len = 0; + packet->user_agent_line.ptr = NULL; + packet->user_agent_line.len = 0; + packet->http_url_name.ptr = NULL; + packet->http_url_name.len = 0; + packet->http_encoding.ptr = NULL; + packet->http_encoding.len = 0; + packet->http_transfer_encoding.ptr = NULL; + packet->http_transfer_encoding.len = 0; + packet->http_contentlen.ptr = NULL; + packet->http_contentlen.len = 0; + packet->http_cookie.ptr = NULL; + packet->http_cookie.len = 0; + packet->http_origin.len = 0; + packet->http_origin.ptr = NULL; + packet->http_x_session_type.ptr = NULL; + packet->http_x_session_type.len = 0; + packet->server_line.ptr = NULL; + packet->server_line.len = 0; + packet->http_method.ptr = NULL; + packet->http_method.len = 0; + packet->http_response.ptr = NULL; + packet->http_response.len = 0; + + if((packet->payload_packet_len == 0) + || (packet->payload == NULL)) + return; + + packet->line[packet->parsed_lines].ptr = packet->payload; + packet->line[packet->parsed_lines].len = 0; + + for (a = 0; a < end; a++) { + if(get_u_int16_t(packet->payload, a) == ntohs(0x0d0a)) { + packet->line[packet->parsed_lines].len = (u_int16_t)(((unsigned long) &packet->payload[a]) - ((unsigned long) packet->line[packet->parsed_lines].ptr)); + + if(packet->parsed_lines == 0 && packet->line[0].len >= NDPI_STATICSTRING_LEN("HTTP/1.1 200 ") && + memcmp(packet->line[0].ptr, "HTTP/1.", NDPI_STATICSTRING_LEN("HTTP/1.")) == 0 && + packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] > '0' && + packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] < '6') { + packet->http_response.ptr = &packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.1 ")]; + packet->http_response.len = packet->line[0].len - NDPI_STATICSTRING_LEN("HTTP/1.1 "); + NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, + "ndpi_parse_packet_line_info: HTTP response parsed: \"%.*s\"\n", + packet->http_response.len, packet->http_response.ptr); + } + if(packet->line[packet->parsed_lines].len > NDPI_STATICSTRING_LEN("Server:") + 1 + && memcmp(packet->line[packet->parsed_lines].ptr, "Server:", NDPI_STATICSTRING_LEN("Server:")) == 0) { + // some stupid clients omit a space and place the servername directly after the colon + if(packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")] == ' ') { + packet->server_line.ptr = + &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:") + 1]; + packet->server_line.len = + packet->line[packet->parsed_lines].len - (NDPI_STATICSTRING_LEN("Server:") + 1); + } else { + packet->server_line.ptr = &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")]; + packet->server_line.len = packet->line[packet->parsed_lines].len - NDPI_STATICSTRING_LEN("Server:"); + } + } + + if(packet->line[packet->parsed_lines].len > 6 + && memcmp(packet->line[packet->parsed_lines].ptr, "Host:", 5) == 0) { + // some stupid clients omit a space and place the hostname directly after the colon + if(packet->line[packet->parsed_lines].ptr[5] == ' ') { + packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[6]; + packet->host_line.len = packet->line[packet->parsed_lines].len - 6; + } else { + packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[5]; + packet->host_line.len = packet->line[packet->parsed_lines].len - 5; + } + } + + if(packet->line[packet->parsed_lines].len > 17 + && memcmp(packet->line[packet->parsed_lines].ptr, "X-Forwarded-For:", 16) == 0) { + // some stupid clients omit a space and place the hostname directly after the colon + if(packet->line[packet->parsed_lines].ptr[16] == ' ') { + packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[17]; + packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 17; + } else { + packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[16]; + packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 16; + } + } + + if(packet->line[packet->parsed_lines].len > 14 + && + (memcmp + (packet->line[packet->parsed_lines].ptr, "Content-Type: ", + 14) == 0 || memcmp(packet->line[packet->parsed_lines].ptr, "Content-type: ", 14) == 0)) { + packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[14]; + packet->content_line.len = packet->line[packet->parsed_lines].len - 14; + } + + if(packet->line[packet->parsed_lines].len > 13 + && memcmp(packet->line[packet->parsed_lines].ptr, "Content-type:", 13) == 0) { + packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[13]; + packet->content_line.len = packet->line[packet->parsed_lines].len - 13; + } + + if(packet->line[packet->parsed_lines].len > 8 + && memcmp(packet->line[packet->parsed_lines].ptr, "Accept: ", 8) == 0) { + packet->accept_line.ptr = &packet->line[packet->parsed_lines].ptr[8]; + packet->accept_line.len = packet->line[packet->parsed_lines].len - 8; + } + + if(packet->line[packet->parsed_lines].len > 9 + && memcmp(packet->line[packet->parsed_lines].ptr, "Referer: ", 9) == 0) { + packet->referer_line.ptr = &packet->line[packet->parsed_lines].ptr[9]; + packet->referer_line.len = packet->line[packet->parsed_lines].len - 9; + } + + if(packet->line[packet->parsed_lines].len > 12 + && (memcmp(packet->line[packet->parsed_lines].ptr, "User-Agent: ", 12) == 0 || + memcmp(packet->line[packet->parsed_lines].ptr, "User-agent: ", 12) == 0)) { + packet->user_agent_line.ptr = &packet->line[packet->parsed_lines].ptr[12]; + packet->user_agent_line.len = packet->line[packet->parsed_lines].len - 12; + } + + if(packet->line[packet->parsed_lines].len > 18 + && memcmp(packet->line[packet->parsed_lines].ptr, "Content-Encoding: ", 18) == 0) { + packet->http_encoding.ptr = &packet->line[packet->parsed_lines].ptr[18]; + packet->http_encoding.len = packet->line[packet->parsed_lines].len - 18; + } + + if(packet->line[packet->parsed_lines].len > 19 + && memcmp(packet->line[packet->parsed_lines].ptr, "Transfer-Encoding: ", 19) == 0) { + packet->http_transfer_encoding.ptr = &packet->line[packet->parsed_lines].ptr[19]; + packet->http_transfer_encoding.len = packet->line[packet->parsed_lines].len - 19; + } + if(packet->line[packet->parsed_lines].len > 16 + && ((memcmp(packet->line[packet->parsed_lines].ptr, "Content-Length: ", 16) == 0) + || (memcmp(packet->line[packet->parsed_lines].ptr, "content-length: ", 16) == 0))) { + packet->http_contentlen.ptr = &packet->line[packet->parsed_lines].ptr[16]; + packet->http_contentlen.len = packet->line[packet->parsed_lines].len - 16; + } + if(packet->line[packet->parsed_lines].len > 8 + && memcmp(packet->line[packet->parsed_lines].ptr, "Cookie: ", 8) == 0) { + packet->http_cookie.ptr = &packet->line[packet->parsed_lines].ptr[8]; + packet->http_cookie.len = packet->line[packet->parsed_lines].len - 8; + } + if(packet->line[packet->parsed_lines].len > 8 + && memcmp(packet->line[packet->parsed_lines].ptr, "Origin: ", 8) == 0) { + packet->http_origin.ptr = &packet->line[packet->parsed_lines].ptr[8]; + packet->http_origin.len = packet->line[packet->parsed_lines].len - 8; + } + if(packet->line[packet->parsed_lines].len > 16 + && memcmp(packet->line[packet->parsed_lines].ptr, "X-Session-Type: ", 16) == 0) { + packet->http_x_session_type.ptr = &packet->line[packet->parsed_lines].ptr[16]; + packet->http_x_session_type.len = packet->line[packet->parsed_lines].len - 16; + } + + + if(packet->line[packet->parsed_lines].len == 0) { + packet->empty_line_position = a; + packet->empty_line_position_set = 1; + } + + if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1)) { + return; + } + + packet->parsed_lines++; + packet->line[packet->parsed_lines].ptr = &packet->payload[a + 2]; + packet->line[packet->parsed_lines].len = 0; + + if((a + 2) >= packet->payload_packet_len) { + + return; + } + a++; + } + } + + if(packet->parsed_lines >= 1) { + packet->line[packet->parsed_lines].len + = (u_int16_t)(((unsigned long) &packet->payload[packet->payload_packet_len]) - + ((unsigned long) packet->line[packet->parsed_lines].ptr)); + packet->parsed_lines++; + } +} + +void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t a; + u_int16_t end = packet->payload_packet_len; + if(packet->packet_lines_parsed_complete != 0) + return; + + + + packet->packet_lines_parsed_complete = 1; + packet->parsed_lines = 0; + + if(packet->payload_packet_len == 0) + return; + + packet->line[packet->parsed_lines].ptr = packet->payload; + packet->line[packet->parsed_lines].len = 0; + + for (a = 0; a < end; a++) { + if(packet->payload[a] == 0x0a) { + packet->line[packet->parsed_lines].len = (u_int16_t)( + ((unsigned long) &packet->payload[a]) - + ((unsigned long) packet->line[packet->parsed_lines].ptr)); + if(a > 0 && packet->payload[a-1] == 0x0d) + packet->line[packet->parsed_lines].len--; + + if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1)) { + break; + } + + packet->parsed_lines++; + packet->line[packet->parsed_lines].ptr = &packet->payload[a + 1]; + packet->line[packet->parsed_lines].len = 0; + + if((a + 1) >= packet->payload_packet_len) { + break; + } + //a++; + } + } +} + + +u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, u_int16_t counter) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "called ndpi_check_for_email_address\n"); + + if(packet->payload_packet_len > counter && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') + || (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') + || (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') + || packet->payload[counter] == '-' || packet->payload[counter] == '_')) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "first letter\n"); + counter++; + while (packet->payload_packet_len > counter + && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') + || (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') + || (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') + || packet->payload[counter] == '-' || packet->payload[counter] == '_' + || packet->payload[counter] == '.')) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "further letter\n"); + counter++; + if(packet->payload_packet_len > counter && packet->payload[counter] == '@') { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "@\n"); + counter++; + while (packet->payload_packet_len > counter + && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') + || (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') + || (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') + || packet->payload[counter] == '-' || packet->payload[counter] == '_')) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "letter\n"); + counter++; + if(packet->payload_packet_len > counter && packet->payload[counter] == '.') { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, ".\n"); + counter++; + if(packet->payload_packet_len > counter + 1 + && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') + && (packet->payload[counter + 1] >= 'a' && packet->payload[counter + 1] <= 'z'))) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "two letters\n"); + counter += 2; + if(packet->payload_packet_len > counter + && (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "whitespace1\n"); + return counter; + } else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a' + && packet->payload[counter] <= 'z') { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "one letter\n"); + counter++; + if(packet->payload_packet_len > counter + && (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "whitespace2\n"); + return counter; + } else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a' + && packet->payload[counter] <= 'z') { + counter++; + if(packet->payload_packet_len > counter + && (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "whitespace3\n"); + return counter; + } else { + return 0; + } + } else { + return 0; + } + } else { + return 0; + } + } else { + return 0; + } + } + } + return 0; + } + } + } + return 0; +} + +#ifdef NDPI_ENABLE_DEBUG_MESSAGES +void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct + *ndpi_struct, const char **file, const char **func, u_int32_t * line) +{ + *file = ""; + *func = ""; + + if(ndpi_struct->ndpi_debug_print_file != NULL) + *file = ndpi_struct->ndpi_debug_print_file; + + if(ndpi_struct->ndpi_debug_print_function != NULL) + *func = ndpi_struct->ndpi_debug_print_function; + + *line = ndpi_struct->ndpi_debug_print_line; +} +#endif +u_int8_t ndpi_detection_get_l4(const u_int8_t * l3, u_int16_t l3_len, const u_int8_t ** l4_return, u_int16_t * l4_len_return, + u_int8_t * l4_protocol_return, u_int32_t flags) +{ + return ndpi_detection_get_l4_internal(NULL, l3, l3_len, l4_return, l4_len_return, l4_protocol_return, flags); +} + +void ndpi_int_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type) +{ + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + ndpi_int_change_protocol(ndpi_struct, flow, detected_protocol, protocol_type); + + if(src != NULL) { + NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, detected_protocol); + } + if(dst != NULL) { + NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, detected_protocol); + } +} + +void ndpi_int_change_flow_protocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type) +{ +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 + u_int8_t a; + u_int8_t stack_size; + u_int8_t new_is_real = 0; + u_int16_t preserve_bitmask; +#endif + + if(!flow) + return; + +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 + stack_size = flow->protocol_stack_info.current_stack_size_minus_one + 1; + + /* here are the rules for stack manipulations: + * 1.if the new protocol is a real protocol, insert it at the position + * of the top-most real protocol or below the last non-unknown correlated + * protocol. + * 2.if the new protocol is not real, put it on top of stack but if there is + * a real protocol in the stack, make sure at least one real protocol remains + * in the stack + */ + + if(protocol_type == NDPI_CORRELATED_PROTOCOL) { + u_int16_t saved_real_protocol = NDPI_PROTOCOL_UNKNOWN; + + if(stack_size == NDPI_PROTOCOL_HISTORY_SIZE) { + /* check whether we will lost real protocol information due to shifting */ + u_int16_t real_protocol = flow->protocol_stack_info.entry_is_real_protocol; + + for (a = 0; a < stack_size; a++) { + if(real_protocol & 1) + break; + real_protocol >>= 1; + } + + if(a == (stack_size - 1)) { + /* oh, only one real protocol at the end, store it and insert it later */ + saved_real_protocol = flow->detected_protocol_stack[stack_size - 1]; + } + } else { + flow->protocol_stack_info.current_stack_size_minus_one++; + stack_size++; + } + + /* now shift and insert */ + for (a = stack_size - 1; a > 0; a--) { + flow->detected_protocol_stack[a] = flow->detected_protocol_stack[a - 1]; + } + + flow->protocol_stack_info.entry_is_real_protocol <<= 1; + + /* now set the new protocol */ + + flow->detected_protocol_stack[0] = detected_protocol; + + /* restore real protocol */ + if(saved_real_protocol != NDPI_PROTOCOL_UNKNOWN) { + flow->detected_protocol_stack[stack_size - 1] = saved_real_protocol; + flow->protocol_stack_info.entry_is_real_protocol |= 1 << (stack_size - 1); + } + /* done */ + } else { + u_int8_t insert_at = 0; + + if(!(flow->protocol_stack_info.entry_is_real_protocol & 1)) { + u_int16_t real_protocol = flow->protocol_stack_info.entry_is_real_protocol; + + for (a = 0; a < stack_size; a++) { + if(real_protocol & 1) + break; + real_protocol >>= 1; + } + + insert_at = a; + } + + if(insert_at >= stack_size) { + /* no real protocol found, insert it at the bottom */ + + insert_at = stack_size - 1; + } + + if(stack_size < NDPI_PROTOCOL_HISTORY_SIZE) { + flow->protocol_stack_info.current_stack_size_minus_one++; + stack_size++; + } + + /* first shift all stacks */ + for (a = stack_size - 1; a > insert_at; a--) { + flow->detected_protocol_stack[a] = flow->detected_protocol_stack[a - 1]; + } + + preserve_bitmask = (1 << insert_at) - 1; + + new_is_real = (flow->protocol_stack_info.entry_is_real_protocol & (~preserve_bitmask)) << 1; + new_is_real |= flow->protocol_stack_info.entry_is_real_protocol & preserve_bitmask; + + flow->protocol_stack_info.entry_is_real_protocol = new_is_real; + + /* now set the new protocol */ + + flow->detected_protocol_stack[insert_at] = detected_protocol; + + /* and finally update the additional stack information */ + + flow->protocol_stack_info.entry_is_real_protocol |= 1 << insert_at; + } +#else + flow->detected_protocol_stack[0] = detected_protocol; + flow->detected_subprotocol_stack[0] = detected_subprotocol; +#endif +} + +void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type) +{ + struct ndpi_packet_struct *packet = &flow->packet; + /* NOTE: everything below is identically to change_flow_protocol + * except flow->packet If you want to change something here, + * don't! Change it for the flow function and apply it here + * as well */ +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 + u_int8_t a; + u_int8_t stack_size; + u_int16_t new_is_real = 0; + u_int16_t preserve_bitmask; +#endif + + if(!packet) + return; + +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 + stack_size = packet->protocol_stack_info.current_stack_size_minus_one + 1; + + /* here are the rules for stack manipulations: + * 1.if the new protocol is a real protocol, insert it at the position + * of the top-most real protocol or below the last non-unknown correlated + * protocol. + * 2.if the new protocol is not real, put it on top of stack but if there is + * a real protocol in the stack, make sure at least one real protocol remains + * in the stack + */ + + if(protocol_type == NDPI_CORRELATED_PROTOCOL) { + u_int16_t saved_real_protocol = NDPI_PROTOCOL_UNKNOWN; + + if(stack_size == NDPI_PROTOCOL_HISTORY_SIZE) { + /* check whether we will lost real protocol information due to shifting */ + u_int16_t real_protocol = packet->protocol_stack_info.entry_is_real_protocol; + + for (a = 0; a < stack_size; a++) { + if(real_protocol & 1) + break; + real_protocol >>= 1; + } + + if(a == (stack_size - 1)) { + /* oh, only one real protocol at the end, store it and insert it later */ + saved_real_protocol = packet->detected_protocol_stack[stack_size - 1]; + } + } else { + packet->protocol_stack_info.current_stack_size_minus_one++; + stack_size++; + } + + /* now shift and insert */ + for (a = stack_size - 1; a > 0; a--) { + packet->detected_protocol_stack[a] = packet->detected_protocol_stack[a - 1]; + } + + packet->protocol_stack_info.entry_is_real_protocol <<= 1; + + /* now set the new protocol */ + + packet->detected_protocol_stack[0] = detected_protocol; + + /* restore real protocol */ + if(saved_real_protocol != NDPI_PROTOCOL_UNKNOWN) { + packet->detected_protocol_stack[stack_size - 1] = saved_real_protocol; + packet->protocol_stack_info.entry_is_real_protocol |= 1 << (stack_size - 1); + } + /* done */ + } else { + u_int8_t insert_at = 0; + + if(!(packet->protocol_stack_info.entry_is_real_protocol & 1)) { + u_int16_t real_protocol = packet->protocol_stack_info.entry_is_real_protocol; + + for (a = 0; a < stack_size; a++) { + if(real_protocol & 1) + break; + real_protocol >>= 1; + } + + insert_at = a; + } + + if(insert_at >= stack_size) { + /* no real protocol found, insert it at the first unknown protocol */ + + insert_at = stack_size - 1; + } + + if(stack_size < NDPI_PROTOCOL_HISTORY_SIZE) { + packet->protocol_stack_info.current_stack_size_minus_one++; + stack_size++; + } + + /* first shift all stacks */ + for (a = stack_size - 1; a > insert_at; a--) { + packet->detected_protocol_stack[a] = packet->detected_protocol_stack[a - 1]; + } + + preserve_bitmask = (1 << insert_at) - 1; + + new_is_real = (packet->protocol_stack_info.entry_is_real_protocol & (~preserve_bitmask)) << 1; + new_is_real |= packet->protocol_stack_info.entry_is_real_protocol & preserve_bitmask; + + packet->protocol_stack_info.entry_is_real_protocol = (u_int8_t)new_is_real; + + /* now set the new protocol */ + + packet->detected_protocol_stack[insert_at] = detected_protocol; + + /* and finally update the additional stack information */ + + packet->protocol_stack_info.entry_is_real_protocol |= 1 << insert_at; + } +#else + packet->detected_protocol_stack[0] = detected_protocol; + packet->detected_subprotocol_stack[0] = detected_subprotocol; +#endif +} + + +/* + * this function returns the real protocol of the flow. Actually it + * accesses the packet stack since this is what leaves the library but + * it could also use the flow stack. + */ +u_int16_t ndpi_detection_get_real_protocol_of_flow(struct ndpi_detection_module_struct * ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 + u_int8_t a; + u_int8_t stack_size; + u_int16_t real_protocol; +#endif + + if(!packet) + return NDPI_PROTOCOL_UNKNOWN; + +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 + stack_size = packet->protocol_stack_info.current_stack_size_minus_one + 1; + real_protocol = packet->protocol_stack_info.entry_is_real_protocol; + + for (a = 0; a < stack_size; a++) { + if(real_protocol & 1) + return packet->detected_protocol_stack[a]; + real_protocol >>= 1; + } + + return NDPI_PROTOCOL_UNKNOWN; +#else + return packet->detected_protocol_stack[0]; +#endif +} + +/* + * this function checks whether a protocol can be found in the + * history. Actually it accesses the packet stack since this is what + * leaves the library but it could also use the flow stack. + */ +u_int8_t ndpi_detection_flow_protocol_history_contains_protocol(struct ndpi_detection_module_struct * ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t protocol_id) +{ + u_int8_t a; + u_int8_t stack_size; + struct ndpi_packet_struct *packet = &flow->packet; + + if(!packet) + return 0; + +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 + stack_size = packet->protocol_stack_info.current_stack_size_minus_one + 1; +#else + stack_size = 1; +#endif + + for (a = 0; a < stack_size; a++) { + if(packet->detected_protocol_stack[a] == protocol_id) + return 1; + } + + return 0; +} + +/* generic function for setting a protocol for a flow + * + * what it does is: + * 1.call ndpi_int_change_protocol + * 2.set protocol in detected bitmask for src and dst + */ +void ndpi_int_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type); + +/* generic function for changing the flow protocol + * + * what it does is: + * 1.update the flow protocol stack with the new protocol + */ +void ndpi_int_change_flow_protocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type); + +/* generic function for changing the packetprotocol + * + * what it does is: + * 1.update the packet protocol stack with the new protocol + */ +void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t detected_protocol, ndpi_protocol_type_t protocol_type); + +/* generic function for changing the protocol + * + * what it does is: + * 1.update the flow protocol stack with the new protocol + * 2.update the packet protocol stack with the new protocol + */ +void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t detected_protocol, + ndpi_protocol_type_t protocol_type) +{ + ndpi_int_change_flow_protocol(ndpi_struct, flow, detected_protocol, protocol_type); + ndpi_int_change_packet_protocol(ndpi_struct, flow, detected_protocol, protocol_type); +} + + +/* turns a packet back to unknown */ +void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet) { + packet->detected_protocol_stack[0] = NDPI_PROTOCOL_UNKNOWN; + +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 + packet->protocol_stack_info.current_stack_size_minus_one = 0; + packet->protocol_stack_info.entry_is_real_protocol = 0; +#endif +} + +void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow) +{ + if(flow) { + flow->detected_protocol_stack[0] = NDPI_PROTOCOL_UNKNOWN; + +#if NDPI_PROTOCOL_HISTORY_SIZE > 1 + flow->protocol_stack_info.current_stack_size_minus_one = 0; + flow->protocol_stack_info.entry_is_real_protocol = 0; +#endif + } +} + +void NDPI_PROTOCOL_IP_clear(ndpi_ip_addr_t * ip) +{ + memset(ip, 0, sizeof(ndpi_ip_addr_t)); +} + +/* NTOP */ +int NDPI_PROTOCOL_IP_is_set(const ndpi_ip_addr_t * ip) +{ + return memcmp(ip, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(ndpi_ip_addr_t)) != 0; +} + +/* check if the source ip address in packet and ip are equal */ +/* NTOP */ +int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip) +{ +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + if(packet->iphv6 != NULL) { + if(packet->iphv6->saddr.ndpi_v6_u.u6_addr64[0] == ip->ipv6.ndpi_v6_u.u6_addr64[0] && + packet->iphv6->saddr.ndpi_v6_u.u6_addr64[1] == ip->ipv6.ndpi_v6_u.u6_addr64[1]) { + + return 1; + } else { + return 0; + } + } +#endif + if(packet->iph->saddr == ip->ipv4) { + return 1; + } + return 0; +} + +/* check if the destination ip address in packet and ip are equal */ +int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip) +{ +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + if(packet->iphv6 != NULL) { + if(packet->iphv6->daddr.ndpi_v6_u.u6_addr64[0] == ip->ipv6.ndpi_v6_u.u6_addr64[0] && + packet->iphv6->daddr.ndpi_v6_u.u6_addr64[1] == ip->ipv6.ndpi_v6_u.u6_addr64[1]) { + return 1; + } else { + return 0; + } + } +#endif + if(packet->iph->daddr == ip->ipv4) { + return 1; + } + return 0; +} + +/* get the source ip address from packet and put it into ip */ +/* NTOP */ +void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip) +{ + NDPI_PROTOCOL_IP_clear(ip); +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + if(packet->iphv6 != NULL) { + ip->ipv6.ndpi_v6_u.u6_addr64[0] = packet->iphv6->saddr.ndpi_v6_u.u6_addr64[0]; + ip->ipv6.ndpi_v6_u.u6_addr64[1] = packet->iphv6->saddr.ndpi_v6_u.u6_addr64[1]; + } else +#endif + ip->ipv4 = packet->iph->saddr; +} + +/* get the destination ip address from packet and put it into ip */ +/* NTOP */ +void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip) +{ + NDPI_PROTOCOL_IP_clear(ip); +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + if(packet->iphv6 != NULL) { + ip->ipv6.ndpi_v6_u.u6_addr64[0] = packet->iphv6->daddr.ndpi_v6_u.u6_addr64[0]; + ip->ipv6.ndpi_v6_u.u6_addr64[1] = packet->iphv6->daddr.ndpi_v6_u.u6_addr64[1]; + } else +#endif + ip->ipv4 = packet->iph->daddr; +} + +#ifdef NDPI_ENABLE_DEBUG_MESSAGES +/* get the string representation of ip + * returns a pointer to a static string + * only valid until the next call of this function */ +char *ndpi_get_ip_string(struct ndpi_detection_module_struct *ndpi_struct, + const ndpi_ip_addr_t * ip) +{ + const u_int8_t *a = (const u_int8_t *) &ip->ipv4; + +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + if(ip->ipv6.ndpi_v6_u.u6_addr32[1] != 0 || ip->ipv6.ndpi_v6_u.u6_addr64[1] != 0) { + const u_int16_t *b = ip->ipv6.ndpi_v6_u.u6_addr16; + snprintf(ndpi_struct->ip_string, 32, "%x:%x:%x:%x:%x:%x:%x:%x", + ntohs(b[0]), ntohs(b[1]), ntohs(b[2]), ntohs(b[3]), + ntohs(b[4]), ntohs(b[5]), ntohs(b[6]), ntohs(b[7])); + return ndpi_struct->ip_string; + } +#endif + snprintf(ndpi_struct->ip_string, 32, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]); + return ndpi_struct->ip_string; + +} + + +/* get the string representation of the source ip address from packet */ +char *ndpi_get_packet_src_ip_string(struct ndpi_detection_module_struct *ndpi_struct, + const struct ndpi_packet_struct *packet) +{ + ndpi_ip_addr_t ip; + ndpi_packet_src_ip_get(packet, &ip); + return ndpi_get_ip_string(ndpi_struct, &ip); +} + +/* get the string representation of the destination ip address from packet */ +char *ndpi_get_packet_dst_ip_string(struct ndpi_detection_module_struct *ndpi_struct, + const struct ndpi_packet_struct *packet) +{ + ndpi_ip_addr_t ip; + ndpi_packet_dst_ip_get(packet, &ip); + return ndpi_get_ip_string(ndpi_struct, &ip); +} +#endif /* NDPI_ENABLE_DEBUG_MESSAGES */ + +/* ****************************************************** */ + +u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read) +{ + u_int16_t val = ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read); + return ntohs(val); +} + +/* ****************************************************** */ + +#if 0 +#ifndef __KERNEL__ +static u_int is_port(u_int16_t sport, u_int16_t dport, u_int16_t match_port) { + return(((match_port == sport) || (match_port == dport)) ? 1 : 0); +} +#endif +#endif + +/* ****************************************************** */ + +unsigned int ndpi_find_port_based_protocol(struct ndpi_detection_module_struct *ndpi_struct /* NOTUSED */, + u_int8_t proto, + u_int32_t shost, u_int16_t sport, + u_int32_t dhost, u_int16_t dport) { + /* Skyfile (host 193.252.234.246 or host 10.10.102.80) */ + if((shost == 0xC1FCEAF6) || (dhost == 0xC1FCEAF6) + || (shost == 0x0A0A6650) || (dhost == 0x0A0A6650)) { + if((sport == 4708) || (dport == 4708)) return(NDPI_PROTOCOL_SKYFILE_PREPAID); + else if((sport == 4709) || (dport == 4709)) return(NDPI_PROTOCOL_SKYFILE_RUDICS); + else if((sport == 4710) || (dport == 4710)) return(NDPI_PROTOCOL_SKYFILE_POSTPAID); + } + + return(NDPI_PROTOCOL_UNKNOWN); +} + +/* ****************************************************** */ + +unsigned int ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_struct, + u_int8_t proto, + u_int32_t shost /* host byte order */, u_int16_t sport, + u_int32_t dhost /* host byte order */, u_int16_t dport) { + unsigned int rc; + struct in_addr addr; + + if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) { + rc = ndpi_search_tcp_or_udp_raw(ndpi_struct, proto, shost, dhost, sport, dport); + if(rc != NDPI_PROTOCOL_UNKNOWN) return(rc); + + rc = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport); + if(rc != NDPI_PROTOCOL_UNKNOWN) { + if(rc == NDPI_PROTOCOL_SSL) + goto check_guessed_skype; + else + return(rc); + } + + rc = ndpi_find_port_based_protocol(ndpi_struct, proto, shost, sport, dhost, dport); + if(rc != NDPI_PROTOCOL_UNKNOWN) return(rc); + + check_guessed_skype: + addr.s_addr = shost; + if(ndpi_network_ptree_match(ndpi_struct, &addr) == NDPI_PROTOCOL_SKYPE) return(NDPI_PROTOCOL_SKYPE); + + addr.s_addr = dhost; + if(ndpi_network_ptree_match(ndpi_struct, &addr) == NDPI_PROTOCOL_SKYPE) return(NDPI_PROTOCOL_SKYPE); + + return(rc); + } else { + return(ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport)); + } +} + +/* ****************************************************** */ + +char* ndpi_get_proto_name(struct ndpi_detection_module_struct *ndpi_mod, u_int16_t proto_id) { + if((proto_id >= ndpi_mod->ndpi_num_supported_protocols) + || ((proto_id < (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) + && (ndpi_mod->proto_defaults[proto_id].protoName == NULL))) + proto_id = NDPI_PROTOCOL_UNKNOWN; + + return(ndpi_mod->proto_defaults[proto_id].protoName); +} + +/* ****************************************************** */ + +ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *ndpi_mod, + u_int16_t proto_id) { + if((proto_id >= ndpi_mod->ndpi_num_supported_protocols) + || ((proto_id < (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) + && (ndpi_mod->proto_defaults[proto_id].protoName == NULL))) + proto_id = NDPI_PROTOCOL_UNKNOWN; + + return(ndpi_mod->proto_defaults[proto_id].protoBreed); +} + +/* ****************************************************** */ + +char* ndpi_get_proto_breed_name(struct ndpi_detection_module_struct *ndpi_mod, + ndpi_protocol_breed_t breed_id) { + switch(breed_id) { + case NDPI_PROTOCOL_SAFE: + return("Safe"); + break; + case NDPI_PROTOCOL_ACCEPTABLE: + return("Acceptable"); + break; + case NDPI_PROTOCOL_FUN: + return("Fun"); + break; + case NDPI_PROTOCOL_UNSAFE: + return("Unsafe"); + break; + case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS: + return("Dangerous"); + break; + + case NDPI_PROTOCOL_UNRATED: + default: + return("Unrated"); + break; + } +} + +/* ****************************************************** */ + +int ndpi_get_protocol_id(struct ndpi_detection_module_struct *ndpi_mod, char *proto) { + int i; + + for(i=0; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++) + if(strcasecmp(proto, ndpi_mod->proto_defaults[i].protoName) == 0) + return(i); + + return(-1); +} + +/* ****************************************************** */ + +void ndpi_dump_protocols(struct ndpi_detection_module_struct *ndpi_mod) { + int i; + + for(i=0; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++) + printf("[%3d] %s\n", i, ndpi_mod->proto_defaults[i].protoName); +} + +/* ****************************************************** */ + +/* + * Find the first occurrence of find in s, where the search is limited to the + * first slen characters of s. + */ +char* ndpi_strnstr(const char *s, const char *find, size_t slen) { + char c, sc; + size_t len; + + if((c = *find++) != '\0') { + len = strlen(find); + do { + do { + if(slen-- < 1 || (sc = *s++) == '\0') + return (NULL); + } while (sc != c); + if(len > slen) + return (NULL); + } while (strncmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} + +/* ****************************************************** */ + +static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, + ndpi_automa *automa, + struct ndpi_flow_struct *flow, + char *string_to_match, u_int string_to_match_len) { + int matching_protocol_id; + struct ndpi_packet_struct *packet = &flow->packet; + AC_TEXT_t ac_input_text; + + if((automa->ac_automa == NULL) || (string_to_match_len== 0)) return(NDPI_PROTOCOL_UNKNOWN); + + if(!automa->ac_automa_finalized) { + ac_automata_finalize((AC_AUTOMATA_t*)automa->ac_automa); + automa->ac_automa_finalized = 1; + } + + matching_protocol_id = NDPI_PROTOCOL_UNKNOWN; + + ac_input_text.astring = string_to_match, ac_input_text.length = string_to_match_len; + ac_automata_search (((AC_AUTOMATA_t*)automa->ac_automa), &ac_input_text, (void*)&matching_protocol_id); + + ac_automata_reset(((AC_AUTOMATA_t*)automa->ac_automa)); + +#ifdef DEBUG + { + char m[256]; + int len = ndpi_min(sizeof(m), string_to_match_len); + + strncpy(m, string_to_match, len); + m[len] = '\0'; + + printf("[NDPI] ndpi_match_string_subprotocol(%s): %s\n", m, ndpi_struct->proto_defaults[matching_protocol_id].protoName); + } +#endif + + if(matching_protocol_id != NDPI_PROTOCOL_UNKNOWN) { + packet->detected_protocol_stack[0] = matching_protocol_id; + + if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) + flow->detected_protocol_stack[0] = packet->detected_protocol_stack[0]; + + return(packet->detected_protocol_stack[0]); + } + +#ifdef DEBUG + string_to_match[string_to_match_len] = '\0'; + printf("[NTOP] Unable to find a match for '%s'\n", string_to_match); +#endif + + return(NDPI_PROTOCOL_UNKNOWN); +} + +/* ****************************************************** */ + +int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + char *string_to_match, u_int string_to_match_len) { + return(ndpi_automa_match_string_subprotocol(ndpi_struct, &ndpi_struct->host_automa, + flow, string_to_match, string_to_match_len)); +} + +/* ****************************************************** */ + +int ndpi_match_content_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + char *string_to_match, u_int string_to_match_len) { + return(ndpi_automa_match_string_subprotocol(ndpi_struct, &ndpi_struct->content_automa, + flow, string_to_match, string_to_match_len)); +} + +/* ****************************************************** */ + +int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_struct, + ndpi_automa *automa, char *bigram_to_match) { + AC_TEXT_t ac_input_text; + int ret = 0; + + if((automa->ac_automa == NULL) || (bigram_to_match == NULL)) + return(ret); + + if(!automa->ac_automa_finalized) { + ac_automata_finalize((AC_AUTOMATA_t*)automa->ac_automa); + automa->ac_automa_finalized = 1; + } + + ac_input_text.astring = bigram_to_match, ac_input_text.length = 2; + ac_automata_search(((AC_AUTOMATA_t*)automa->ac_automa), &ac_input_text, (void*)&ret); + ac_automata_reset(((AC_AUTOMATA_t*)automa->ac_automa)); + + return(ret); +} + +/* ****************************************************** */ + +void ndpi_free_flow(struct ndpi_flow_struct *flow) { + if(flow) { + if(flow->http.url) ndpi_free(flow->http.url); + if(flow->http.content_type) ndpi_free(flow->http.content_type); + ndpi_free(flow); + } +} + +/* ****************************************************** */ + +#ifndef __KERNEL__ +char* ndpi_revision() { + return(NDPI_SVN_RELEASE); +} +#endif + +/* ****************************************************** */ + +#ifdef WIN32 + +/* + int pthread_mutex_init(pthread_mutex_t *mutex, void *unused) { + unused = NULL; + *mutex = CreateMutex(NULL, FALSE, NULL); + return *mutex == NULL ? -1 : 0; + } + + int pthread_mutex_destroy(pthread_mutex_t *mutex) { + return CloseHandle(*mutex) == 0 ? -1 : 0; + } + + int pthread_mutex_lock(pthread_mutex_t *mutex) { + return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1; + } + + int pthread_mutex_unlock(pthread_mutex_t *mutex) { + return ReleaseMutex(*mutex) == 0 ? -1 : 0; + } +*/ +/* http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/port/gettimeofday.c;h=75a91993b74414c0a1c13a2a09ce739cb8aa8a08;hb=HEAD */ +int gettimeofday(struct timeval * tp, struct timezone * tzp) { + /* FILETIME of Jan 1 1970 00:00:00. */ + const unsigned __int64 epoch = (__int64)(116444736000000000); + + FILETIME file_time; + SYSTEMTIME system_time; + ULARGE_INTEGER ularge; + + GetSystemTime(&system_time); + SystemTimeToFileTime(&system_time, &file_time); + ularge.LowPart = file_time.dwLowDateTime; + ularge.HighPart = file_time.dwHighDateTime; + + tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L); + tp->tv_usec = (long) (system_time.wMilliseconds * 1000); + + return 0; +} +#endif + +int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b) { + int i; + + for(i=0; i<NDPI_NUM_FDS_BITS; i++) { + if(a.fds_bits[i] & b.fds_bits[i]) + return(1); + } + + return(0); +} + +int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a) { + int i; + + for(i=0; i<NDPI_NUM_FDS_BITS; i++) + if(a.fds_bits[i] != 0) + return(0); + + return(1); +} + +void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a) { + int i; + + for(i=0; i<NDPI_NUM_FDS_BITS; i++) + printf("[%d=%u]", i, a.fds_bits[i]); + + printf("\n"); +} + + +#ifdef WIN32 +/* http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/strsep.c */ + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char* strsep(char **stringp, const char *delim) { + char *s; + const char *spanp; + int c, sc; + char *tok; + + if((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if((sc = *spanp++) == c) { + if(c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} +#endif + + diff --git a/src/lib/protocols/afp.c b/src/lib/protocols/afp.c new file mode 100644 index 000000000..b400f53c5 --- /dev/null +++ b/src/lib/protocols/afp.c @@ -0,0 +1,75 @@ +/* + * afp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_AFP + +static void ndpi_int_afp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_AFP, NDPI_REAL_PROTOCOL); +} + + +void ndpi_search_afp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // struct ndpi_id_struct *src = flow->src; +// struct ndpi_id_struct *dst = flow->dst; + + + /* + * this will detect the OpenSession command of the Data Stream Interface (DSI) protocol + * which is exclusively used by the Apple Filing Protocol (AFP) on TCP/IP networks + */ + if (packet->payload_packet_len >= 22 && get_u_int16_t(packet->payload, 0) == htons(0x0004) && + get_u_int16_t(packet->payload, 2) == htons(0x0001) && get_u_int32_t(packet->payload, 4) == 0 && + get_u_int32_t(packet->payload, 8) == htonl(packet->payload_packet_len - 16) && + get_u_int32_t(packet->payload, 12) == 0 && get_u_int16_t(packet->payload, 16) == htons(0x0104)) { + + NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP: DSI OpenSession detected.\n"); + ndpi_int_afp_add_connection(ndpi_struct, flow); + return; + } + + /* + * detection of GetStatus command of DSI protocl + */ + if (packet->payload_packet_len >= 18 && get_u_int16_t(packet->payload, 0) == htons(0x0003) && + get_u_int16_t(packet->payload, 2) == htons(0x0001) && get_u_int32_t(packet->payload, 4) == 0 && + get_u_int32_t(packet->payload, 8) == htonl(packet->payload_packet_len - 16) && + get_u_int32_t(packet->payload, 12) == 0 && get_u_int16_t(packet->payload, 16) == htons(0x0f00)) { + + NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP: DSI GetStatus detected.\n"); + ndpi_int_afp_add_connection(ndpi_struct, flow); + return; + } + + + NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_AFP); +} + +#endif diff --git a/src/lib/protocols/aimini.c b/src/lib/protocols/aimini.c new file mode 100644 index 000000000..165ee2fc4 --- /dev/null +++ b/src/lib/protocols/aimini.c @@ -0,0 +1,283 @@ +/* + * aimini.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_AIMINI + + +static void ndpi_int_aimini_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, + ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_AIMINI, protocol_type); +} + + +static u_int8_t is_special_aimini_host(struct ndpi_int_one_line_struct host_line) +{ + if (host_line.ptr != NULL && host_line.len >= NDPI_STATICSTRING_LEN("X.X.X.X.aimini.net")) { + if ((get_u_int32_t(host_line.ptr, 0) & htonl(0x00ff00ff)) == htonl(0x002e002e) && + (get_u_int32_t(host_line.ptr, 4) & htonl(0x00ff00ff)) == htonl(0x002e002e) && + memcmp(&host_line.ptr[8], "aimini.net", NDPI_STATICSTRING_LEN("aimini.net")) == 0) { + return 1; + } + } + return 0; +} + +void ndpi_search_aimini(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "search aimini.\n"); + + if (packet->udp != NULL) { + if (flow->l4.udp.aimini_stage == 0) { + if (packet->payload_packet_len == 64 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010b) { + flow->l4.udp.aimini_stage = 1; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 1.\n"); + return; + } + if (packet->payload_packet_len == 136 + && (ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9 || ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165)) { + flow->l4.udp.aimini_stage = 4; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 4.\n"); + return; + } + if (packet->payload_packet_len == 88 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101) { + flow->l4.udp.aimini_stage = 7; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 7.\n"); + return; + } + if (packet->payload_packet_len == 104 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102) { + flow->l4.udp.aimini_stage = 10; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 10.\n"); + return; + } + if (packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca) { + flow->l4.udp.aimini_stage = 13; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 13.\n"); + return; + } + if (packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c) { + flow->l4.udp.aimini_stage = 16; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 16.\n"); + return; + } + } + /* first packet chronology: (len, value): (64, 0x010b), (>100, 0x0115), (16, 0x010c || 64, 0x010b || 88, 0x0115), + * (16, 0x010c || 64, 0x010b || >100, 0x0115) + */ + if (flow->l4.udp.aimini_stage == 1 && packet->payload_packet_len > 100 + && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0115) { + flow->l4.udp.aimini_stage = 2; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 2.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 2 && + ((packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 0) == htons(0x010c)) || + (packet->payload_packet_len == 64 && get_u_int16_t(packet->payload, 0) == htons(0x010b)) || + (packet->payload_packet_len == 88 && get_u_int16_t(packet->payload, 0) == ntohs(0x0115)))) { + flow->l4.udp.aimini_stage = 3; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 3.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 3 + && ((packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c) + || (packet->payload_packet_len == 64 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010b) + || (packet->payload_packet_len > 100 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0115))) { + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "found aimini (64, 0x010b), (>300, 0x0115), " + "(16, 0x010c || 64, 0x010b), (16, 0x010c || 64, 0x010b || >100, 0x0115).\n"); + ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + /* second packet chronology: (len, value): (136, 0x01c9), (136, 0x01c9),(136, 0x01c9),(136, 0x01c9 || 32, 0x01ca) */ + + if (flow->l4.udp.aimini_stage == 4 && packet->payload_packet_len == 136 + && (ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9 || ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165)) { + flow->l4.udp.aimini_stage = 5; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 5.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 5 && (packet->payload_packet_len == 136 + && (ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9 + || ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165))) { + flow->l4.udp.aimini_stage = 6; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 6.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 6 && ((packet->payload_packet_len == 136 + && ((ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165) + || ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9)) + || (packet->payload_packet_len == 32 + && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca))) { + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, + "found aimini (136, 0x01c9), (136, 0x01c9)," "(136, 0x01c9),(136, 0x01c9 || 32, 0x01ca).\n"); + ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + /* third packet chronology: (len, value): (88, 0x0101), (88, 0x0101),(88, 0x0101),(88, 0x0101) */ + + if (flow->l4.udp.aimini_stage == 7 && packet->payload_packet_len == 88 + && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101) { + flow->l4.udp.aimini_stage = 8; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 8.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 8 + && (packet->payload_packet_len == 88 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101)) { + flow->l4.udp.aimini_stage = 9; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 9.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 9 + && (packet->payload_packet_len == 88 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101)) { + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, + "found aimini (88, 0x0101), (88, 0x0101)," "(88, 0x0101),(88, 0x0101).\n"); + ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + /* fourth packet chronology: (len, value): (104, 0x0102), (104, 0x0102), (104, 0x0102), (104, 0x0102) */ + + if (flow->l4.udp.aimini_stage == 10 && packet->payload_packet_len == 104 + && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102) { + flow->l4.udp.aimini_stage = 11; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 11.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 11 + && (packet->payload_packet_len == 104 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102)) { + flow->l4.udp.aimini_stage = 12; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 12.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 12 + && ((packet->payload_packet_len == 104 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102) + || (packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca))) { + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, + "found aimini (104, 0x0102), (104, 0x0102), " "(104, 0x0102), (104, 0x0102).\n"); + ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + /* fifth packet chronology (len, value): (32,0x01ca), (32,0x01ca), (32,0x01ca), ((136, 0x0166) || (32,0x01ca)) */ + + if (flow->l4.udp.aimini_stage == 13 && packet->payload_packet_len == 32 + && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca) { + flow->l4.udp.aimini_stage = 14; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 14.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 14 + && ((packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca) + || (packet->payload_packet_len == 136 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0166))) { + flow->l4.udp.aimini_stage = 15; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 15.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 15 + && ((packet->payload_packet_len == 136 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0166) + || (packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca))) { + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, + "found aimini (32,0x01ca), (32,0x01ca), (32,0x01ca), ((136, 0x0166)||(32,0x01ca)).\n"); + ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + /* sixth packet chronology (len, value): (16, 0x010c), (16, 0x010c), (16, 0x010c), (16, 0x010c) */ + + if (flow->l4.udp.aimini_stage == 16 && packet->payload_packet_len == 16 + && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c) { + flow->l4.udp.aimini_stage = 17; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 17.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 17 + && (packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c)) { + flow->l4.udp.aimini_stage = 18; + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 18.\n"); + return; + } + if (flow->l4.udp.aimini_stage == 18 + && (packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c)) { + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, + "found aimini (16, 0x010c), (16, 0x010c), (16, 0x010c), (16, 0x010c).\n"); + ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } else if (packet->tcp != NULL) { + if ((packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /player/") && + (memcmp(packet->payload, "GET /player/", NDPI_STATICSTRING_LEN("GET /player/")) == 0)) || + (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /play/?fid=") && + (memcmp(packet->payload, "GET /play/?fid=", NDPI_STATICSTRING_LEN("GET /play/?fid=")) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "HTTP packet detected.\n"); + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->host_line.ptr != NULL && packet->host_line.len > 11 + && (memcmp(&packet->host_line.ptr[packet->host_line.len - 11], ".aimini.net", 11) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "AIMINI HTTP traffic detected.\n"); + ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + if (packet->payload_packet_len > 100) { + if (memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0) { + if (memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /")], "play/", + NDPI_STATICSTRING_LEN("play/")) == 0 || + memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /")], "download/", + NDPI_STATICSTRING_LEN("download/")) == 0) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (is_special_aimini_host(packet->host_line) == 1) { + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, + "AIMINI HTTP traffic detected.\n"); + ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } else if (memcmp(packet->payload, "POST /", NDPI_STATICSTRING_LEN("POST /")) == 0) { + if (memcmp(&packet->payload[NDPI_STATICSTRING_LEN("POST /")], "upload/", + NDPI_STATICSTRING_LEN("upload/")) == 0) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (is_special_aimini_host(packet->host_line) == 1) { + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, + "AIMINI HTTP traffic detected.\n"); + ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + } + } + + NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "exclude aimini.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_AIMINI); + +} +#endif diff --git a/src/lib/protocols/applejuice.c b/src/lib/protocols/applejuice.c new file mode 100644 index 000000000..d989d571b --- /dev/null +++ b/src/lib/protocols/applejuice.c @@ -0,0 +1,57 @@ +/* + * applejuice.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_APPLEJUICE + + +static void ndpi_int_applejuice_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_APPLEJUICE, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_applejuice_tcp(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_APPLEJUICE, ndpi_struct, NDPI_LOG_DEBUG, "search applejuice.\n"); + + if ((packet->payload_packet_len > 7) && (packet->payload[6] == 0x0d) + && (packet->payload[7] == 0x0a) + && (memcmp(packet->payload, "ajprot", 6) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_APPLEJUICE, ndpi_struct, NDPI_LOG_DEBUG, "detected applejuice.\n"); + ndpi_int_applejuice_add_connection(ndpi_struct, flow); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_APPLEJUICE, ndpi_struct, NDPI_LOG_DEBUG, "exclude applejuice.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_APPLEJUICE); +} + +#endif diff --git a/src/lib/protocols/armagetron.c b/src/lib/protocols/armagetron.c new file mode 100644 index 000000000..6c5064fda --- /dev/null +++ b/src/lib/protocols/armagetron.c @@ -0,0 +1,102 @@ +/* + * armagetron.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +/* include files */ +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_ARMAGETRON + + +static void ndpi_int_armagetron_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_ARMAGETRON, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_armagetron_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "search armagetron.\n"); + + + if (packet->payload_packet_len > 10) { + /* login request */ + if (get_u_int32_t(packet->payload, 0) == htonl(0x000b0000)) { + const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4)); + if (dataLength == 0 || dataLength * 2 + 8 != packet->payload_packet_len) + goto exclude; + if (get_u_int16_t(packet->payload, 6) == htons(0x0008) + && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) { + NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "detected armagetron.\n"); + ndpi_int_armagetron_add_connection(ndpi_struct, flow); + return; + } + } + /* sync_msg */ + if (packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 0) == htons(0x001c) + && get_u_int16_t(packet->payload, 2) != 0) { + const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4)); + if (dataLength != 4) + goto exclude; + if (get_u_int32_t(packet->payload, 6) == htonl(0x00000500) && get_u_int32_t(packet->payload, 6 + 4) == htonl(0x00010000) + && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) { + NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "detected armagetron.\n"); + ndpi_int_armagetron_add_connection(ndpi_struct, flow); + return; + } + } + + /* net_sync combination */ + if (packet->payload_packet_len > 50 && get_u_int16_t(packet->payload, 0) == htons(0x0018) + && get_u_int16_t(packet->payload, 2) != 0) { + u_int16_t val; + const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4)); + if (dataLength == 0 || dataLength * 2 + 8 > packet->payload_packet_len) + goto exclude; + val = get_u_int16_t(packet->payload, 6 + 2); + if (val == get_u_int16_t(packet->payload, 6 + 6)) { + val = ntohs(get_u_int16_t(packet->payload, 6 + 8)); + if ((6 + 10 + val + 4) < packet->payload_packet_len + && (get_u_int32_t(packet->payload, 6 + 10 + val) == htonl(0x00010000) + || get_u_int32_t(packet->payload, 6 + 10 + val) == htonl(0x00000001)) + && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) { + NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "detected armagetron.\n"); + ndpi_int_armagetron_add_connection(ndpi_struct, flow); + return; + } + } + } + } + + exclude: + NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "exclude armagetron.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ARMAGETRON); +} + +#endif diff --git a/src/lib/protocols/attic/flash.c b/src/lib/protocols/attic/flash.c new file mode 100644 index 000000000..e6b89a185 --- /dev/null +++ b/src/lib/protocols/attic/flash.c @@ -0,0 +1,93 @@ +/* + * flash.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_FLASH + +static void ndpi_int_flash_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FLASH, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_flash(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (flow->l4.tcp.flash_stage == 0 && packet->payload_packet_len > 0 + && (packet->payload[0] == 0x03 || packet->payload[0] == 0x06)) { + flow->l4.tcp.flash_bytes = packet->payload_packet_len; + if (packet->tcp->psh == 0) { + NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG, "FLASH pass 1: \n"); + flow->l4.tcp.flash_stage = packet->packet_direction + 1; + + NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG, + "FLASH pass 1: flash_stage: %u, flash_bytes: %u\n", flow->l4.tcp.flash_stage, + flow->l4.tcp.flash_bytes); + return; + } else if (packet->tcp->psh != 0 && flow->l4.tcp.flash_bytes == 1537) { + NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG, + "FLASH hit: flash_stage: %u, flash_bytes: %u\n", flow->l4.tcp.flash_stage, + flow->l4.tcp.flash_bytes); + flow->l4.tcp.flash_stage = 3; + ndpi_int_flash_add_connection(ndpi_struct, flow); + return; + } + } else if (flow->l4.tcp.flash_stage == 1 + packet->packet_direction) { + flow->l4.tcp.flash_bytes += packet->payload_packet_len; + if (packet->tcp->psh != 0 && flow->l4.tcp.flash_bytes == 1537) { + NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG, + "FLASH hit: flash_stage: %u, flash_bytes: %u\n", flow->l4.tcp.flash_stage, + flow->l4.tcp.flash_bytes); + flow->l4.tcp.flash_stage = 3; + ndpi_int_flash_add_connection(ndpi_struct, flow); + return; + } else if (packet->tcp->psh == 0 && flow->l4.tcp.flash_bytes < 1537) { + NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG, + "FLASH pass 2: flash_stage: %u, flash_bytes: %u\n", flow->l4.tcp.flash_stage, + flow->l4.tcp.flash_bytes); + return; + } + } + + NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG, + "FLASH might be excluded: flash_stage: %u, flash_bytes: %u, packet_direction: %u\n", + flow->l4.tcp.flash_stage, flow->l4.tcp.flash_bytes, packet->packet_direction); + +#ifdef NDPI_PROTOCOL_HTTP + if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP) != 0) { +#endif /* NDPI_PROTOCOL_HTTP */ + NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG, "FLASH: exclude\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FLASH); +#ifdef NDPI_PROTOCOL_HTTP + } else { + NDPI_LOG(NDPI_PROTOCOL_FLASH, ndpi_struct, NDPI_LOG_DEBUG, "FLASH avoid early exclude from http\n"); + } +#endif /* NDPI_PROTOCOL_HTTP */ + +} +#endif diff --git a/src/lib/protocols/attic/ftp.c b/src/lib/protocols/attic/ftp.c new file mode 100644 index 000000000..f48f3e946 --- /dev/null +++ b/src/lib/protocols/attic/ftp.c @@ -0,0 +1,469 @@ +/* + * ftp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#include "ndpi_utils.h" + +#ifdef NDPI_PROTOCOL_FTP + + +static void ndpi_int_ftp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FTP, NDPI_REAL_PROTOCOL); +} + +/** + * checks for possible FTP command + * not all valid commands are tested, it just need to be 3 or 4 characters followed by a space if the + * packet is longer + * + * this functions is not used to accept, just to not reject + */ +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +u_int8_t ndpi_int_check_possible_ftp_command(const struct ndpi_packet_struct *packet) +{ + if (packet->payload_packet_len < 3) + return 0; + + if ((packet->payload[0] < 'a' || packet->payload[0] > 'z') && + (packet->payload[0] < 'A' || packet->payload[0] > 'Z')) + return 0; + if ((packet->payload[1] < 'a' || packet->payload[1] > 'z') && + (packet->payload[1] < 'A' || packet->payload[1] > 'Z')) + return 0; + if ((packet->payload[2] < 'a' || packet->payload[2] > 'z') && + (packet->payload[2] < 'A' || packet->payload[2] > 'Z')) + return 0; + + if (packet->payload_packet_len > 3) { + if ((packet->payload[3] < 'a' || packet->payload[3] > 'z') && + (packet->payload[3] < 'A' || packet->payload[3] > 'Z') && packet->payload[3] != ' ') + return 0; + + if (packet->payload_packet_len > 4) { + if (packet->payload[3] != ' ' && packet->payload[4] != ' ') + return 0; + } + } + + return 1; +} + +/** + * ftp replies are are 3-digit number followed by space or hyphen + */ +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +u_int8_t ndpi_int_check_possible_ftp_reply(const struct ndpi_packet_struct *packet) +{ + if (packet->payload_packet_len < 5) + return 0; + + if (packet->payload[3] != ' ' && packet->payload[3] != '-') + return 0; + + if (packet->payload[0] < '0' || packet->payload[0] > '9') + return 0; + if (packet->payload[1] < '0' || packet->payload[1] > '9') + return 0; + if (packet->payload[2] < '0' || packet->payload[2] > '9') + return 0; + + return 1; +} + +/** + * check for continuation replies + * there is no real indication whether it is a continuation message, we just + * require that there are at least 5 ascii characters + */ +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +u_int8_t ndpi_int_check_possible_ftp_continuation_reply(const struct ndpi_packet_struct *packet) +{ + u_int16_t i; + + if (packet->payload_packet_len < 5) + return 0; + + for (i = 0; i < 5; i++) { + if (packet->payload[i] < ' ' || packet->payload[i] > 127) + return 0; + } + + return 1; +} + +/* + * these are the commands we tracking and expecting to see + */ +enum { + FTP_USER_CMD = 1 << 0, + FTP_FEAT_CMD = 1 << 1, + FTP_COMMANDS = ((1 << 2) - 1), + FTP_220_CODE = 1 << 2, + FTP_331_CODE = 1 << 3, + FTP_211_CODE = 1 << 4, + FTP_CODES = ((1 << 5) - 1 - FTP_COMMANDS) +}; + +/* + return 0 if nothing has been detected + return 1 if a pop packet +*/ + +static u_int8_t search_ftp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + + u_int8_t current_ftp_code = 0; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + + /* initiate client direction flag */ + if (flow->packet_counter == 1) { + if (flow->l4.tcp.seen_syn) { + flow->l4.tcp.ftp_client_direction = flow->setup_packet_direction; + } else { + /* no syn flag seen so guess */ + if (packet->payload_packet_len > 0) { + if (packet->payload[0] >= '0' && packet->payload[0] <= '9') { + /* maybe server side */ + flow->l4.tcp.ftp_client_direction = 1 - packet->packet_direction; + } else { + flow->l4.tcp.ftp_client_direction = packet->packet_direction; + } + } + } + } + + if (packet->packet_direction == flow->l4.tcp.ftp_client_direction) { + if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("USER ") && + (memcmp(packet->payload, "USER ", NDPI_STATICSTRING_LEN("USER ")) == 0 || + memcmp(packet->payload, "user ", NDPI_STATICSTRING_LEN("user ")) == 0)) { + + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP: found USER command\n"); + flow->l4.tcp.ftp_codes_seen |= FTP_USER_CMD; + current_ftp_code = FTP_USER_CMD; + } else if (packet->payload_packet_len >= NDPI_STATICSTRING_LEN("FEAT") && + (memcmp(packet->payload, "FEAT", NDPI_STATICSTRING_LEN("FEAT")) == 0 || + memcmp(packet->payload, "feat", NDPI_STATICSTRING_LEN("feat")) == 0)) { + + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP: found FEAT command\n"); + flow->l4.tcp.ftp_codes_seen |= FTP_FEAT_CMD; + current_ftp_code = FTP_FEAT_CMD; + } else if (!ndpi_int_check_possible_ftp_command(packet)) { + return 0; + } + } else { + if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("220 ") && + (memcmp(packet->payload, "220 ", NDPI_STATICSTRING_LEN("220 ")) == 0 || + memcmp(packet->payload, "220-", NDPI_STATICSTRING_LEN("220-")) == 0)) { + + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP: found 220 reply code\n"); + flow->l4.tcp.ftp_codes_seen |= FTP_220_CODE; + current_ftp_code = FTP_220_CODE; + } else if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("331 ") && + (memcmp(packet->payload, "331 ", NDPI_STATICSTRING_LEN("331 ")) == 0 || + memcmp(packet->payload, "331-", NDPI_STATICSTRING_LEN("331-")) == 0)) { + + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP: found 331 reply code\n"); + flow->l4.tcp.ftp_codes_seen |= FTP_331_CODE; + current_ftp_code = FTP_331_CODE; + } else if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("211 ") && + (memcmp(packet->payload, "211 ", NDPI_STATICSTRING_LEN("211 ")) == 0 || + memcmp(packet->payload, "211-", NDPI_STATICSTRING_LEN("211-")) == 0)) { + + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP: found 211reply code\n"); + flow->l4.tcp.ftp_codes_seen |= FTP_211_CODE; + current_ftp_code = FTP_211_CODE; + } else if (!ndpi_int_check_possible_ftp_reply(packet)) { + if ((flow->l4.tcp.ftp_codes_seen & FTP_CODES) == 0 || + (!ndpi_int_check_possible_ftp_continuation_reply(packet))) { + return 0; + } + } + } + + if ((flow->l4.tcp.ftp_codes_seen & FTP_COMMANDS) != 0 && (flow->l4.tcp.ftp_codes_seen & FTP_CODES) != 0) { + + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP detected\n"); + ndpi_int_ftp_add_connection(ndpi_struct, flow); + return 1; + } + + /* if no valid code has been seen for the first packets reject */ + if (flow->l4.tcp.ftp_codes_seen == 0 && flow->packet_counter > 3) + return 0; + + /* otherwise wait more packets, wait more for traffic on known ftp port */ + if ((packet->packet_direction == flow->setup_packet_direction && packet->tcp && packet->tcp->dest == htons(21)) || + (packet->packet_direction != flow->setup_packet_direction && packet->tcp && packet->tcp->source == htons(21))) { + /* flow to known ftp port */ + + /* wait much longer if this was a 220 code, initial messages might be long */ + if (current_ftp_code == FTP_220_CODE) { + if (flow->packet_counter > 40) + return 0; + } else { + if (flow->packet_counter > 20) + return 0; + } + } else { + /* wait much longer if this was a 220 code, initial messages might be long */ + if (current_ftp_code == FTP_220_CODE) { + if (flow->packet_counter > 20) + return 0; + } else { + if (flow->packet_counter > 10) + return 0; + } + } + + return 2; +} + + +static void search_passive_ftp_mode(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *dst = flow->dst; + struct ndpi_id_struct *src = flow->src; + u_int16_t plen; + u_int8_t i; + u_int32_t ftp_ip; + + + // TODO check if normal passive mode also needs adaption for ipv6 + if (packet->payload_packet_len > 3 && ndpi_mem_cmp(packet->payload, "227 ", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP passive mode initial string\n"); + + plen = 4; //=4 for "227 " + while (1) { + if (plen >= packet->payload_packet_len) { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, + "plen >= packet->payload_packet_len, return\n"); + return; + } + if (packet->payload[plen] == '(') { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "found (. break.\n"); + break; + } + /* if (!isalnum(packet->payload[plen])) { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "no alpha numeric symbol --> break.\n"); + return; + }*/ + plen++; + } + plen++; + + if (plen >= packet->payload_packet_len) + return; + + + ftp_ip = 0; + for (i = 0; i < 4; i++) { + u_int16_t oldplen = plen; + ftp_ip = + (ftp_ip << 8) + + ndpi_bytestream_to_number(&packet->payload[plen], packet->payload_packet_len - plen, &plen); + if (oldplen == plen || plen >= packet->payload_packet_len) { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP passive mode %u value parse failed\n", + i); + return; + } + if (packet->payload[plen] != ',') { + + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, + "FTP passive mode %u value parse failed, char ',' is missing\n", i); + return; + } + plen++; + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, + "FTP passive mode %u value parsed, ip is now: %u\n", i, ftp_ip); + + } + if (dst != NULL) { + dst->ftp_ip.ipv4 = htonl(ftp_ip); + dst->ftp_timer = packet->tick_timestamp; + dst->ftp_timer_set = 1; + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to dst"); + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP PASSIVE MODE FOUND: use Server %s\n", + ndpi_get_ip_string(ndpi_struct, &dst->ftp_ip)); + } + if (src != NULL) { + src->ftp_ip.ipv4 = packet->iph->daddr; + src->ftp_timer = packet->tick_timestamp; + src->ftp_timer_set = 1; + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to src"); + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP PASSIVE MODE FOUND: use Server %s\n", + ndpi_get_ip_string(ndpi_struct, &src->ftp_ip)); + } + return; + } + + if (packet->payload_packet_len > 34 && ndpi_mem_cmp(packet->payload, "229 Entering Extended Passive Mode", 34) == 0) { + if (dst != NULL) { + ndpi_packet_src_ip_get(packet, &dst->ftp_ip); + dst->ftp_timer = packet->tick_timestamp; + dst->ftp_timer_set = 1; + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to dst"); + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, + "FTP Extended PASSIVE MODE FOUND: use Server %s\n", ndpi_get_ip_string(ndpi_struct, &dst->ftp_ip)); + } + if (src != NULL) { + ndpi_packet_dst_ip_get(packet, &src->ftp_ip); + src->ftp_timer = packet->tick_timestamp; + src->ftp_timer_set = 1; + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to src"); + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, + "FTP Extended PASSIVE MODE FOUND: use Server %s\n", ndpi_get_ip_string(ndpi_struct, &src->ftp_ip)); + } + return; + } +} + + +static void search_active_ftp_mode(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + if (packet->payload_packet_len > 5 + && (ndpi_mem_cmp(packet->payload, "PORT ", 5) == 0 || ndpi_mem_cmp(packet->payload, "EPRT ", 5) == 0)) { + + //src->local_ftp_data_port = htons(data_port_number); + if (src != NULL) { + ndpi_packet_dst_ip_get(packet, &src->ftp_ip); + src->ftp_timer = packet->tick_timestamp; + src->ftp_timer_set = 1; + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP ACTIVE MODE FOUND, command is %.*s\n", 4, + packet->payload); + } + if (dst != NULL) { + ndpi_packet_src_ip_get(packet, &dst->ftp_ip); + dst->ftp_timer = packet->tick_timestamp; + dst->ftp_timer_set = 1; + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP ACTIVE MODE FOUND, command is %.*s\n", 4, + packet->payload); + } + } + return; +} + + +void ndpi_search_ftp_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + + + if (src != NULL && ndpi_packet_dst_ip_eql(packet, &src->ftp_ip) + && packet->tcp->syn != 0 && packet->tcp->ack == 0 + && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, + NDPI_PROTOCOL_FTP) != 0 && src->ftp_timer_set != 0) { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "possible ftp data, src!= 0.\n"); + + if (((u_int32_t) + (packet->tick_timestamp - src->ftp_timer)) >= ndpi_struct->ftp_connection_timeout) { + src->ftp_timer_set = 0; + } else if (ntohs(packet->tcp->dest) > 1024 + && (ntohs(packet->tcp->source) > 1024 || ntohs(packet->tcp->source) == 20)) { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "detected FTP data stream.\n"); + ndpi_int_ftp_add_connection(ndpi_struct, flow); + return; + } + } + + if (dst != NULL && ndpi_packet_src_ip_eql(packet, &dst->ftp_ip) + && packet->tcp->syn != 0 && packet->tcp->ack == 0 + && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, + NDPI_PROTOCOL_FTP) != 0 && dst->ftp_timer_set != 0) { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "possible ftp data; dst!= 0.\n"); + + if (((u_int32_t) + (packet->tick_timestamp - dst->ftp_timer)) >= ndpi_struct->ftp_connection_timeout) { + dst->ftp_timer_set = 0; + + } else if (ntohs(packet->tcp->dest) > 1024 + && (ntohs(packet->tcp->source) > 1024 || ntohs(packet->tcp->source) == 20)) { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "detected FTP data stream.\n"); + ndpi_int_ftp_add_connection(ndpi_struct, flow); + return; + } + } + // ftp data asymmetrically + + + /* skip packets without payload */ + if (packet->payload_packet_len == 0) { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, + "FTP test skip because of data connection or zero byte packet_payload.\n"); + return; + } + /* skip excluded connections */ + + // we test for FTP connection and search for passive mode + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_FTP) { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, + "detected ftp command mode. going to test data mode.\n"); + search_passive_ftp_mode(ndpi_struct, flow); + + search_active_ftp_mode(ndpi_struct, flow); + return; + } + + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && search_ftp(ndpi_struct, flow) != 0) { + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "unknown. need next packet.\n"); + + return; + } + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FTP); + NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude ftp.\n"); + +} + +#endif diff --git a/src/lib/protocols/attic/manolito.c b/src/lib/protocols/attic/manolito.c new file mode 100644 index 000000000..f4ffba0cc --- /dev/null +++ b/src/lib/protocols/attic/manolito.c @@ -0,0 +1,180 @@ +/* + * manolito.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_MANOLITO + +static void ndpi_int_manolito_add_connection(struct + ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MANOLITO, NDPI_REAL_PROTOCOL); + + + if (src != NULL) { + if (packet->udp != NULL) { + src->manolito_last_pkt_arrival_time = packet->tick_timestamp; + } + } + if (dst != NULL) { + if (packet->udp != NULL) { + dst->manolito_last_pkt_arrival_time = packet->tick_timestamp; + } + } +} + +/* + return 0 if nothing has been detected + return 1 if it is a megaupload packet +*/ +u_int8_t search_manolito_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +u_int8_t search_manolito_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src = flow->src; + // struct ndpi_id_struct *dst = flow->dst; + + NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO TCP DETECTION\n"); + + if (flow->l4.tcp.manolito_stage == 0 && packet->payload_packet_len > 6) { + if (memcmp(packet->payload, "SIZ ", 4) != 0) + goto end_manolito_nothing_found; + + flow->l4.tcp.manolito_stage = 1 + packet->packet_direction; + NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO Stage 1.\n"); + goto end_manolito_maybe_hit; + + } else if ((flow->l4.tcp.manolito_stage == 2 - packet->packet_direction) + && packet->payload_packet_len > 4) { + if (memcmp(packet->payload, "STR ", 4) != 0) + goto end_manolito_nothing_found; + NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO Stage 2.\n"); + flow->l4.tcp.manolito_stage = 3 + packet->packet_direction; + goto end_manolito_maybe_hit; + + } else if ((flow->l4.tcp.manolito_stage == 4 - packet->packet_direction) && packet->payload_packet_len > 5) { + if (memcmp(packet->payload, "MD5 ", 4) != 0) + goto end_manolito_nothing_found; + NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO Stage 3.\n"); + flow->l4.tcp.manolito_stage = 5 + packet->packet_direction; + goto end_manolito_maybe_hit; + + } else if ((flow->l4.tcp.manolito_stage == 6 - packet->packet_direction) && packet->payload_packet_len == 4) { + + if (memcmp(packet->payload, "GO!!", 4) != 0) + goto end_manolito_nothing_found; + NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO Stage 4.\n"); + goto end_manolito_found; + } + //NDPI_LOG(NDPI_PROTOCOL_MANOLITO,ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO FLOW STAGE %d\n", flow->l4.tcp.manolito_stage); + goto end_manolito_nothing_found; + + end_manolito_found: + NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO FOUND\n"); + ndpi_int_manolito_add_connection(ndpi_struct, flow); + return 1; + + end_manolito_maybe_hit: + NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO maybe hit.\n"); + return 2; + + end_manolito_nothing_found: + NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO NOTHING FOUND\n"); + return 0; +} + +void ndpi_search_manolito_tcp_udp(struct + ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + + if (packet->tcp != NULL) { + if (search_manolito_tcp(ndpi_struct, flow) != 0) + return; + } else if (packet->udp != NULL) { + if (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_MANOLITO) { + if (src != NULL) { + src->manolito_last_pkt_arrival_time = packet->tick_timestamp; + } + if (dst != NULL) { + dst->manolito_last_pkt_arrival_time = packet->tick_timestamp; + } + return; + } else if (packet->udp->source == htons(41170) + || packet->udp->dest == htons(41170)) { + if (src != NULL && src->manolito_last_pkt_arrival_time != 0 + && (packet->tick_timestamp - src->manolito_last_pkt_arrival_time < + ndpi_struct->manolito_subscriber_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO: UDP detected \n"); + ndpi_int_manolito_add_connection(ndpi_struct, flow); + return; + } else if (src != NULL + && (packet->tick_timestamp - src->manolito_last_pkt_arrival_time) >= + ndpi_struct->manolito_subscriber_timeout) { + src->manolito_last_pkt_arrival_time = 0; + } + + if (dst != NULL && dst->manolito_last_pkt_arrival_time != 0 + && (packet->tick_timestamp - dst->manolito_last_pkt_arrival_time < + ndpi_struct->manolito_subscriber_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO: UDP detected \n"); + ndpi_int_manolito_add_connection(ndpi_struct, flow); + return; + } else if (dst != NULL + && (packet->tick_timestamp - dst->manolito_last_pkt_arrival_time) >= + ndpi_struct->manolito_subscriber_timeout) { + dst->manolito_last_pkt_arrival_time = 0; + } + + if ((packet->payload_packet_len == 20 && htons(0x3d4b) == get_u_int16_t(packet->payload, 0) + && packet->payload[2] == 0xd9 && htons(0xedbb) == get_u_int16_t(packet->payload, 16)) + || (packet->payload_packet_len == 25 && htons(0x3e4a) == get_u_int16_t(packet->payload, 0) + && htons(0x092f) == get_u_int16_t(packet->payload, 20) && packet->payload[22] == 0x20) + || (packet->payload_packet_len == 20 && !get_u_int16_t(packet->payload, 2) && !get_u_int32_t(packet->payload, 8) + && !get_u_int16_t(packet->payload, 18) && get_u_int16_t(packet->payload, 0)) + ) { //20B pkt is For PING + NDPI_LOG(NDPI_PROTOCOL_MANOLITO, ndpi_struct, NDPI_LOG_DEBUG, "MANOLITO: UDP detected \n"); + ndpi_int_manolito_add_connection(ndpi_struct, flow); + return; + } else if (flow->packet_counter < 7) { + return; + } + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MANOLITO); +} +#endif diff --git a/src/lib/protocols/attic/popo.c b/src/lib/protocols/attic/popo.c new file mode 100644 index 000000000..b5c45ea2b --- /dev/null +++ b/src/lib/protocols/attic/popo.c @@ -0,0 +1,86 @@ +/* + * popo.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_POPO + +static void ndpi_int_popo_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_POPO, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_popo_tcp_udp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + if (packet->tcp != NULL) { + if ((packet->payload_packet_len == 20) + && get_u_int32_t(packet->payload, 0) == htonl(0x0c000000) + && get_u_int32_t(packet->payload, 4) == htonl(0x01010000) + && get_u_int32_t(packet->payload, 8) == htonl(0x06000000) + && get_u_int32_t(packet->payload, 12) == 0 && get_u_int32_t(packet->payload, 16) == 0) { + NDPI_LOG(NDPI_PROTOCOL_POPO, ndpi_struct, NDPI_LOG_DEBUG, "POPO detected\n"); + ndpi_int_popo_add_connection(ndpi_struct, flow); + return; + } + + if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_POPO) != 0) { +#define NDPI_POPO_IP_SUBNET_START ( (220 << 24) + (181 << 16) + (28 << 8) + 220) +#define NDPI_POPO_IP_SUBNET_END ( (220 << 24) + (181 << 16) + (28 << 8) + 238) + + /* may match the first payload ip packet only ... */ + + if (ntohl(packet->iph->daddr) >= NDPI_POPO_IP_SUBNET_START + && ntohl(packet->iph->daddr) <= NDPI_POPO_IP_SUBNET_END) { + NDPI_LOG(NDPI_PROTOCOL_POPO, ndpi_struct, NDPI_LOG_DEBUG, "POPO ip subnet detected\n"); + ndpi_int_popo_add_connection(ndpi_struct, flow); + return; + } + } + } + + if (packet->payload_packet_len > 13 && packet->payload_packet_len == get_l32(packet->payload, 0) + && !get_l16(packet->payload, 12)) { + register u_int16_t ii; + for (ii = 14; ii < 50 && ii < packet->payload_packet_len - 8; ++ii) { + if (packet->payload[ii] == '@') + if (!memcmp(&packet->payload[ii + 1], "163.com", 7) + || (ii <= packet->payload_packet_len - 13 && !memcmp(&packet->payload[ii + 1], "popo.163.com", 12))) { + NDPI_LOG(NDPI_PROTOCOL_POPO, ndpi_struct, NDPI_LOG_DEBUG, "POPO detected.\n"); + ndpi_int_popo_add_connection(ndpi_struct, flow); + return; + } + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_POPO); +} + +#endif diff --git a/src/lib/protocols/attic/secondlife.c b/src/lib/protocols/attic/secondlife.c new file mode 100644 index 000000000..1d43231e0 --- /dev/null +++ b/src/lib/protocols/attic/secondlife.c @@ -0,0 +1,123 @@ +/* + * secondlife.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_utils.h" +#ifdef NDPI_PROTOCOL_SECONDLIFE + +static void ndpi_int_secondlife_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SECONDLIFE, protocol_type); +} + +void ndpi_search_secondlife(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + // if ((ntohs(packet->udp->dest) == 12035 || ntohs(packet->udp->dest) == 12036 || (ntohs(packet->udp->dest) >= 13000 && ntohs(packet->udp->dest) <= 13050)) //port + // && packet->payload_packet_len > 6 // min length with no extra header, high frequency and 1 byte message body + // && get_u_int8_t(packet->payload, 0) == 0x40 // reliable packet + // && ntohl(get_u_int32_t(packet->payload, 1)) == 0x00000001 // sequence number equals 1 + // //ntohl (get_u_int32_t (packet->payload, 5)) == 0x00FFFF00 // no extra header, low frequency message - can't use, message may have higher frequency + // ) { + // NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life detected.\n"); + // ndpi_int_secondlife_add_connection(ndpi_struct, flow); + // return; + // } + + if (packet->tcp != NULL) { + if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /") + && memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life HTTP 'GET /'' found.\n"); + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->user_agent_line.ptr != NULL + && packet->user_agent_line.len > + NDPI_STATICSTRING_LEN + ("Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/532.4 (KHTML, like Gecko) SecondLife/") + && memcmp(&packet->user_agent_line.ptr[NDPI_STATICSTRING_LEN + ("Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/532.4 (KHTML, like Gecko) ")], + "SecondLife/", NDPI_STATICSTRING_LEN("SecondLife/")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, + "Second Life TCP HTTP User Agent detected.\n"); + ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + if (packet->host_line.ptr != NULL && packet->host_line.len > NDPI_STATICSTRING_LEN(".agni.lindenlab.com:")) { + u_int8_t x; + for (x = 2; x < 6; x++) { + if (packet->host_line.ptr[packet->host_line.len - (1 + x)] == ':') { + if ((1 + x + NDPI_STATICSTRING_LEN(".agni.lindenlab.com")) < packet->host_line.len + && memcmp(&packet->host_line.ptr[packet->host_line.len - + (1 + x + NDPI_STATICSTRING_LEN(".agni.lindenlab.com"))], + ".agni.lindenlab.com", NDPI_STATICSTRING_LEN(".agni.lindenlab.com")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, + "Second Life TCP HTTP Host detected.\n"); + ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + break; + } + } + } + } + } + if (packet->udp != NULL) { + if (packet->payload_packet_len == 46 + && memcmp(packet->payload, "\x40\x00\x00\x00\x01\x00\xff\xff\x00\x03", 10) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life 0xffff0003 detected.\n"); + ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 54 + && memcmp(packet->payload, "\x40\x00\x00\x00\x01\x00\xff\xff\x00\x52", 10) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life 0xffff0052 detected.\n"); + ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 58 + && memcmp(packet->payload, "\x40\x00\x00\x00\x01\x00\xff\xff\x00\xa9", 10) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life 0xffff00a9 detected.\n"); + ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len > 54 && memcmp(packet->payload, "\x40\x00\x00\x00\x01\x00\x08", 7) == 0 && + get_u_int32_t(packet->payload, packet->payload_packet_len - 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life 0x08 detected.\n"); + ndpi_int_secondlife_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + + + NDPI_LOG(NDPI_PROTOCOL_SECONDLIFE, ndpi_struct, NDPI_LOG_DEBUG, "Second Life excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SECONDLIFE); +} + +#endif diff --git a/src/lib/protocols/ayiya.c b/src/lib/protocols/ayiya.c new file mode 100644 index 000000000..c4d1a26ad --- /dev/null +++ b/src/lib/protocols/ayiya.c @@ -0,0 +1,67 @@ +/* + * ayiya.c + * + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/* + http://en.wikipedia.org/wiki/Anything_In_Anything + http://tools.ietf.org/html/rfc4891 +*/ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_AYIYA + +struct ayiya { + u_int8_t flags[3]; + u_int8_t next_header; + u_int32_t epoch; + u_int8_t identity[16]; + u_int8_t signature[20]; +}; + +void ndpi_search_ayiya(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if(packet->udp && (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)) { + /* Ayiya is udp based, port 5072 */ + if ((packet->udp->source == htons(5072) || packet->udp->dest == htons(5072)) + /* check for ayiya new packet */ + && (packet->payload_packet_len > 44) + ) { + /* FINISH */ + struct ayiya *a = (struct ayiya*)packet->payload; + u_int32_t epoch = ntohl(a->epoch), now; + u_int32_t fireyears = 86400 * 365 * 5; + + now = flow->packet.tick_timestamp; + + if((epoch >= (now - fireyears)) && (epoch <= (now+86400 /* 1 day */))) + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_AYIYA, NDPI_REAL_PROTOCOL); + + return; + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_AYIYA); + } +} +#endif diff --git a/src/lib/protocols/battlefield.c b/src/lib/protocols/battlefield.c new file mode 100644 index 000000000..374dcb61b --- /dev/null +++ b/src/lib/protocols/battlefield.c @@ -0,0 +1,118 @@ +/* + * battlefield.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_BATTLEFIELD + + +static void ndpi_int_battlefield_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_BATTLEFIELD, NDPI_REAL_PROTOCOL); + + if (src != NULL) { + src->battlefield_ts = packet->tick_timestamp; + } + if (dst != NULL) { + dst->battlefield_ts = packet->tick_timestamp; + } +} + +void ndpi_search_battlefield(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_BATTLEFIELD) { + if (src != NULL && ((u_int32_t) + (packet->tick_timestamp - src->battlefield_ts) < ndpi_struct->battlefield_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct, NDPI_LOG_DEBUG, + "battlefield : save src connection packet detected\n"); + src->battlefield_ts = packet->tick_timestamp; + } else if (dst != NULL && ((u_int32_t) + (packet->tick_timestamp - dst->battlefield_ts) < ndpi_struct->battlefield_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct, NDPI_LOG_DEBUG, + "battlefield : save dst connection packet detected\n"); + dst->battlefield_ts = packet->tick_timestamp; + } + return; + } + + if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_BATTLEFIELD)) { + if (flow->l4.udp.battlefield_stage == 0 || flow->l4.udp.battlefield_stage == 1 + packet->packet_direction) { + if (packet->payload_packet_len > 8 && get_u_int16_t(packet->payload, 0) == htons(0xfefd)) { + flow->l4.udp.battlefield_msg_id = get_u_int32_t(packet->payload, 2); + flow->l4.udp.battlefield_stage = 1 + packet->packet_direction; + return; + } + } else if (flow->l4.udp.battlefield_stage == 2 - packet->packet_direction) { + if (packet->payload_packet_len > 8 && get_u_int32_t(packet->payload, 0) == flow->l4.udp.battlefield_msg_id) { + NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct, + NDPI_LOG_DEBUG, "Battlefield message and reply detected.\n"); + ndpi_int_battlefield_add_connection(ndpi_struct, flow); + return; + } + } + } + + if (flow->l4.udp.battlefield_stage == 0) { + if (packet->payload_packet_len == 46 && packet->payload[2] == 0 && packet->payload[4] == 0 + && get_u_int32_t(packet->payload, 7) == htonl(0x98001100)) { + flow->l4.udp.battlefield_stage = 3 + packet->packet_direction; + return; + } + } else if (flow->l4.udp.battlefield_stage == 4 - packet->packet_direction) { + if (packet->payload_packet_len == 7 + && (packet->payload[0] == 0x02 || packet->payload[packet->payload_packet_len - 1] == 0xe0)) { + NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct, NDPI_LOG_DEBUG, + "Battlefield message and reply detected.\n"); + ndpi_int_battlefield_add_connection(ndpi_struct, flow); + return; + } + } + + if (packet->payload_packet_len == 18 && memcmp(&packet->payload[5], "battlefield2\x00", 13) == 0) { + NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct, NDPI_LOG_DEBUG, "Battlefield 2 hello packet detected.\n"); + ndpi_int_battlefield_add_connection(ndpi_struct, flow); + return; + } else if (packet->payload_packet_len > 10 && + (memcmp(packet->payload, "\x11\x20\x00\x01\x00\x00\x50\xb9\x10\x11", 10) == 0 + || memcmp(packet->payload, "\x11\x20\x00\x01\x00\x00\x30\xb9\x10\x11", 10) == 0 + || memcmp(packet->payload, "\x11\x20\x00\x01\x00\x00\xa0\x98\x00\x11", 10) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_BATTLEFIELD, ndpi_struct, NDPI_LOG_DEBUG, "Battlefield safe pattern detected.\n"); + ndpi_int_battlefield_add_connection(ndpi_struct, flow); + return; + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BATTLEFIELD); + return; +} + +#endif diff --git a/src/lib/protocols/bgp.c b/src/lib/protocols/bgp.c new file mode 100644 index 000000000..8d4f00ab4 --- /dev/null +++ b/src/lib/protocols/bgp.c @@ -0,0 +1,57 @@ +/* + * bgp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_BGP + + +static void ndpi_int_bgp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_BGP, NDPI_REAL_PROTOCOL); +} + +/* this detection also works asymmetrically */ +void ndpi_search_bgp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len > 18 && + get_u_int64_t(packet->payload, 0) == 0xffffffffffffffffULL && + get_u_int64_t(packet->payload, 8) == 0xffffffffffffffffULL && + ntohs(get_u_int16_t(packet->payload, 16)) <= packet->payload_packet_len && + (packet->tcp->dest == htons(179) || packet->tcp->source == htons(179)) + && packet->payload[18] < 5) { + NDPI_LOG(NDPI_PROTOCOL_BGP, ndpi_struct, NDPI_LOG_DEBUG, "BGP detected.\n"); + ndpi_int_bgp_add_connection(ndpi_struct, flow); + return; + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BGP); +} + +#endif diff --git a/src/lib/protocols/bittorrent.c b/src/lib/protocols/bittorrent.c new file mode 100644 index 000000000..4be42548f --- /dev/null +++ b/src/lib/protocols/bittorrent.c @@ -0,0 +1,469 @@ +/* + * bittorrent.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_BITTORRENT +#define NDPI_PROTOCOL_UNSAFE_DETECTION 0 +#define NDPI_PROTOCOL_SAFE_DETECTION 1 + +#define NDPI_PROTOCOL_PLAIN_DETECTION 0 +#define NDPI_PROTOCOL_WEBSEED_DETECTION 2 +static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, + const u_int8_t save_detection, const u_int8_t encrypted_connection, + ndpi_protocol_type_t protocol_type) +{ + ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BITTORRENT, protocol_type); +} + +static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src = flow->src; + // struct ndpi_id_struct *dst = flow->dst; + + u_int16_t a = 0; + + if (packet->payload_packet_len == 1 && packet->payload[0] == 0x13) { + /* reset stage back to 0 so we will see the next packet here too */ + flow->bittorrent_stage = 0; + return 0; + } + if (flow->packet_counter == 2 && packet->payload_packet_len > 20) { + + if (memcmp(&packet->payload[0], "BitTorrent protocol", 19) == 0) { + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, + ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, + NDPI_REAL_PROTOCOL); + return 1; + } + } + + + if (packet->payload_packet_len > 20) { + /* test for match 0x13+"BitTorrent protocol" */ + if (packet->payload[0] == 0x13) { + if (memcmp(&packet->payload[1], "BitTorrent protocol", 19) == 0) { + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, + ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, + NDPI_REAL_PROTOCOL); + return 1; + } + } + } + + if (packet->payload_packet_len > 23 && memcmp(packet->payload, "GET /webseed?info_hash=", 23) == 0) { + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, + NDPI_LOG_TRACE, "BT: plain webseed BitTorrent protocol detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION, + NDPI_CORRELATED_PROTOCOL); + return 1; + } + /* seen Azureus as server for webseed, possibly other servers existing, to implement */ + /* is Server: hypertracker Bittorrent? */ + /* no asymmetric detection possible for answer of pattern "GET /data?fid=". */ + if (packet->payload_packet_len > 60 + && memcmp(packet->payload, "GET /data?fid=", 14) == 0 && memcmp(&packet->payload[54], "&size=", 6) == 0) { + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, + NDPI_LOG_TRACE, "BT: plain Bitcomet persistent seed protocol detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION, + NDPI_CORRELATED_PROTOCOL); + return 1; + } + + + if (packet->payload_packet_len > 90 && (memcmp(packet->payload, "GET ", 4) == 0 + || memcmp(packet->payload, "POST ", 5) == 0)) { + const u_int8_t *ptr = &packet->payload[4]; + u_int16_t len = packet->payload_packet_len - 4; + a = 0; + + + /* parse complete get packet here into line structure elements */ + ndpi_parse_packet_line_info(ndpi_struct, flow); + /* answer to this pattern is HTTP....Server: hypertracker */ + if (packet->user_agent_line.ptr != NULL + && ((packet->user_agent_line.len > 8 && memcmp(packet->user_agent_line.ptr, "Azureus ", 8) == 0) + || (packet->user_agent_line.len >= 10 && memcmp(packet->user_agent_line.ptr, "BitTorrent", 10) == 0) + || (packet->user_agent_line.len >= 11 && memcmp(packet->user_agent_line.ptr, "BTWebClient", 11) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, + NDPI_LOG_TRACE, "Azureus /Bittorrent user agent line detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION, + NDPI_CORRELATED_PROTOCOL); + return 1; + } + + if (packet->user_agent_line.ptr != NULL + && (packet->user_agent_line.len >= 9 && memcmp(packet->user_agent_line.ptr, "Shareaza ", 9) == 0) + && (packet->parsed_lines > 8 && packet->line[8].ptr != 0 + && packet->line[8].len >= 9 && memcmp(packet->line[8].ptr, "X-Queue: ", 9) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, + NDPI_LOG_TRACE, "Bittorrent Shareaza detected.\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION, + NDPI_CORRELATED_PROTOCOL); + return 1; + } + + /* this is a self built client, not possible to catch asymmetrically */ + if ((packet->parsed_lines == 10 || (packet->parsed_lines == 11 && packet->line[11].len == 0)) + && packet->user_agent_line.ptr != NULL + && packet->user_agent_line.len > 12 + && memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 ", + 12) == 0 + && packet->host_line.ptr != NULL + && packet->host_line.len >= 7 + && packet->line[2].ptr != NULL + && packet->line[2].len > 14 + && memcmp(packet->line[2].ptr, "Keep-Alive: 300", 15) == 0 + && packet->line[3].ptr != NULL + && packet->line[3].len > 21 + && memcmp(packet->line[3].ptr, "Connection: Keep-alive", 22) == 0 + && packet->line[4].ptr != NULL + && packet->line[4].len > 10 + && (memcmp(packet->line[4].ptr, "Accpet: */*", 11) == 0 + || memcmp(packet->line[4].ptr, "Accept: */*", 11) == 0) + + && packet->line[5].ptr != NULL + && packet->line[5].len > 12 + && memcmp(packet->line[5].ptr, "Range: bytes=", 13) == 0 + && packet->line[7].ptr != NULL + && packet->line[7].len > 15 + && memcmp(packet->line[7].ptr, "Pragma: no-cache", 16) == 0 + && packet->line[8].ptr != NULL + && packet->line[8].len > 22 && memcmp(packet->line[8].ptr, "Cache-Control: no-cache", 23) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "Bitcomet LTS detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, + NDPI_CORRELATED_PROTOCOL); + return 1; + + } + + /* FlashGet pattern */ + if (packet->parsed_lines == 8 + && packet->user_agent_line.ptr != NULL + && packet->user_agent_line.len > (sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) + && memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 (compatible; MSIE 6.0;", + sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) == 0 + && packet->host_line.ptr != NULL + && packet->host_line.len >= 7 + && packet->line[2].ptr != NULL + && packet->line[2].len == 11 + && memcmp(packet->line[2].ptr, "Accept: */*", 11) == 0 + && packet->line[3].ptr != NULL && packet->line[3].len >= (sizeof("Referer: ") - 1) + && memcmp(packet->line[3].ptr, "Referer: ", sizeof("Referer: ") - 1) == 0 + && packet->line[5].ptr != NULL + && packet->line[5].len > 13 + && memcmp(packet->line[5].ptr, "Range: bytes=", 13) == 0 + && packet->line[6].ptr != NULL + && packet->line[6].len > 21 && memcmp(packet->line[6].ptr, "Connection: Keep-Alive", 22) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "FlashGet detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, + NDPI_CORRELATED_PROTOCOL); + return 1; + + } + if (packet->parsed_lines == 7 + && packet->user_agent_line.ptr != NULL + && packet->user_agent_line.len > (sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) + && memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 (compatible; MSIE 6.0;", + sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) == 0 + && packet->host_line.ptr != NULL + && packet->host_line.len >= 7 + && packet->line[2].ptr != NULL + && packet->line[2].len == 11 + && memcmp(packet->line[2].ptr, "Accept: */*", 11) == 0 + && packet->line[3].ptr != NULL && packet->line[3].len >= (sizeof("Referer: ") - 1) + && memcmp(packet->line[3].ptr, "Referer: ", sizeof("Referer: ") - 1) == 0 + && packet->line[5].ptr != NULL + && packet->line[5].len > 21 && memcmp(packet->line[5].ptr, "Connection: Keep-Alive", 22) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "FlashGet detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, + NDPI_CORRELATED_PROTOCOL); + return 1; + + } + + /* answer to this pattern is not possible to implement asymmetrically */ + while (1) { + if (len < 50 || ptr[0] == 0x0d) { + goto ndpi_end_bt_tracker_check; + } + if (memcmp(ptr, "info_hash=", 10) == 0) { + break; + } + len--; + ptr++; + } + + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, + NDPI_LOG_TRACE, " BT stat: tracker info hash found\n"); + + /* len is > 50, so save operation here */ + len -= 10; + ptr += 10; + + /* parse bt hash */ + for (a = 0; a < 20; a++) { + if (len < 3) { + goto ndpi_end_bt_tracker_check; + } + if (*ptr == '%') { + u_int8_t x1 = 0xFF; + u_int8_t x2 = 0xFF; + + + if (ptr[1] >= '0' && ptr[1] <= '9') { + x1 = ptr[1] - '0'; + } + if (ptr[1] >= 'a' && ptr[1] <= 'f') { + x1 = 10 + ptr[1] - 'a'; + } + if (ptr[1] >= 'A' && ptr[1] <= 'F') { + x1 = 10 + ptr[1] - 'A'; + } + + if (ptr[2] >= '0' && ptr[2] <= '9') { + x2 = ptr[2] - '0'; + } + if (ptr[2] >= 'a' && ptr[2] <= 'f') { + x2 = 10 + ptr[2] - 'a'; + } + if (ptr[2] >= 'A' && ptr[2] <= 'F') { + x2 = 10 + ptr[2] - 'A'; + } + + if (x1 == 0xFF || x2 == 0xFF) { + goto ndpi_end_bt_tracker_check; + } + ptr += 3; + len -= 3; + } else if (*ptr >= 32 && *ptr < 127) { + ptr++; + len--; + } else { + goto ndpi_end_bt_tracker_check; + } + } + + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, + NDPI_LOG_TRACE, " BT stat: tracker info hash parsed\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, + NDPI_CORRELATED_PROTOCOL); + return 1; + } + + ndpi_end_bt_tracker_check: + + if (packet->payload_packet_len == 80) { + /* Warez 80 Bytes Packet + * +----------------+---------------+-----------------+-----------------+ + * |20 BytesPattern | 32 Bytes Value| 12 BytesPattern | 16 Bytes Data | + * +----------------+---------------+-----------------+-----------------+ + * 20 BytesPattern : 4c 00 00 00 ff ff ff ff 57 00 00 00 00 00 00 00 20 00 00 00 + * 12 BytesPattern : 28 23 00 00 01 00 00 00 10 00 00 00 + * */ + static const char pattern_20_bytes[20] = { 0x4c, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0x57, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00 + }; + static const char pattern_12_bytes[12] = { 0x28, 0x23, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00 + }; + + /* did not see this pattern anywhere */ + if ((memcmp(&packet->payload[0], pattern_20_bytes, 20) == 0) + && (memcmp(&packet->payload[52], pattern_12_bytes, 12) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, + NDPI_LOG_TRACE, "BT: Warez - Plain BitTorrent protocol detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, + NDPI_REAL_PROTOCOL); + return 1; + } + } + + else if (packet->payload_packet_len > 50) { + if (memcmp(packet->payload, "GET", 3) == 0) { + + ndpi_parse_packet_line_info(ndpi_struct, flow); + /* haven't fount this pattern anywhere */ + if (packet->host_line.ptr != NULL + && packet->host_line.len >= 9 && memcmp(packet->host_line.ptr, "ip2p.com:", 9) == 0) { + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, + ndpi_struct, NDPI_LOG_TRACE, + "BT: Warez - Plain BitTorrent protocol detected due to Host: ip2p.com: pattern\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION, + NDPI_CORRELATED_PROTOCOL); + return 1; + } + } + } + return 0; +} + + +/*Search for BitTorrent commands*/ +static void ndpi_int_search_bittorrent_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + + if (packet->payload_packet_len == 0) { + return; + } + + if (flow->bittorrent_stage == 0 && packet->payload_packet_len != 0) { + /* exclude stage 0 detection from next run */ + flow->bittorrent_stage = 1; + if (ndpi_int_search_bittorrent_tcp_zero(ndpi_struct, flow) != 0) { + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_DEBUG, + "stage 0 has detected something, returning\n"); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_DEBUG, + "stage 0 has no direct detection, fall through\n"); + } + return; +} + +void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + /* This is broadcast */ + if(packet->iph + && ((packet->iph->saddr == 0xFFFFFFFF) || (packet->iph->daddr == 0xFFFFFFFF))) + return; + + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_BITTORRENT) { + /* check for tcp retransmission here */ + + if ((packet->tcp != NULL) + && (packet->tcp_retransmission == 0 || packet->num_retried_bytes)) { + ndpi_int_search_bittorrent_tcp(ndpi_struct, flow); + } + else if(packet->udp != NULL) { + if((ntohs(packet->udp->source) < 1024) + || (ntohs(packet->udp->dest) < 1024) /* High ports only */) + return; + + /* + Check for uTP http://www.bittorrent.org/beps/bep_0029.html + + wireshark/epan/dissectors/packet-bt-utp.c + */ + + if(packet->payload_packet_len >= 23 /* min header size */) { + /* Check if this is protocol v0 */ + u_int8_t v0_extension = packet->payload[17]; + u_int8_t v0_flags = packet->payload[18]; + + /* Check if this is protocol v1 */ + u_int8_t v1_version = packet->payload[0]; + u_int8_t v1_extension = packet->payload[1]; + u_int32_t v1_window_size = *((u_int32_t*)&packet->payload[12]); + + if((packet->payload[0]== 0x60) + && (packet->payload[1]== 0x0) + && (packet->payload[2]== 0x0) + && (packet->payload[3]== 0x0) + && (packet->payload[4]== 0x0)) { + /* Heuristic */ + goto bittorrent_found; + } else if(((v1_version & 0x0f) == 1) + && ((v1_version >> 4) < 5 /* ST_NUM_STATES */) + && (v1_extension < 3 /* EXT_NUM_EXT */) + && (v1_window_size < 32768 /* 32k */) + ) { + goto bittorrent_found; + } else if((v0_flags < 6 /* ST_NUM_STATES */) + && (v0_extension < 3 /* EXT_NUM_EXT */)) { + u_int32_t ts = ntohl(*((u_int32_t*)&(packet->payload[4]))); + u_int32_t now; + +#ifndef __KERNEL__ + now = (u_int32_t)time(NULL); +#else + struct timespec t; + + getnstimeofday(&t); + now = t.tv_sec; +#endif + + if((ts < (now+86400)) && (ts > (now-86400))) { + goto bittorrent_found; + } + } + } + + flow->bittorrent_stage++; + + if(flow->bittorrent_stage < 10) { + if(packet->payload_packet_len > 19 /* min size */) { + if(ndpi_strnstr((const char *)packet->payload, ":target20:", packet->payload_packet_len) + || ndpi_strnstr((const char *)packet->payload, ":find_node1:", packet->payload_packet_len) + || ndpi_strnstr((const char *)packet->payload, "d1:ad2:id20:", packet->payload_packet_len) + || ndpi_strnstr((const char *)packet->payload, ":info_hash20:", packet->payload_packet_len) + || ndpi_strnstr((const char *)packet->payload, ":filter64", packet->payload_packet_len) + || ndpi_strnstr((const char *)packet->payload, "d1:rd2:id20:", packet->payload_packet_len) + || ndpi_strnstr((const char *)packet->payload, "BitTorrent protocol", packet->payload_packet_len) + ) { + bittorrent_found: + NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, + ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n"); + ndpi_add_connection_as_bittorrent(ndpi_struct, flow, + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, + NDPI_REAL_PROTOCOL); + return; + } + } + + return; + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BITTORRENT); + } + } +} +#endif diff --git a/src/lib/protocols/btlib.c b/src/lib/protocols/btlib.c new file mode 100644 index 000000000..6442c7db7 --- /dev/null +++ b/src/lib/protocols/btlib.c @@ -0,0 +1,509 @@ +/* + * btlib.c + * + * Copyright (C) 2011-15 - ntop.org + * Contributed by Vitaly Lavrov <vel21ripn@gmail.com> + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef NDPI_NO_STD_INC +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <strings.h> + +typedef unsigned char u_int8_t; +typedef unsigned short int u_int16_t; +typedef unsigned long long int u_int64_t; + +#include <stdint.h> +#include <stdlib.h> +#include <arpa/inet.h> +#endif + +typedef signed long long int i_int64_t; + +#include "btlib.h" + +#ifndef __KERNEL__ + +int bt_parse_debug = 0; + +static char *printXb(char *s,const u_int8_t *b,int l) { + int i; + for(i=0; i < l; i++) + snprintf(&s[i*2],41,"%02x",b[i]); + return s; +} + +static char *print20b(char *s,const u_int8_t *b) { + snprintf(s,41,"%08x%08x%08x%08x%08x", + htonl(*(u_int32_t*)b), + htonl(*(u_int32_t*)(b+4)), + htonl(*(u_int32_t*)(b+8)), + htonl(*(u_int32_t*)(b+12)), + htonl(*(u_int32_t*)(b+16))); + return s; +} + +static char *print_id_ip_p(char *s, const struct bt_nodes_data *b) { + u_int8_t *p = (void*)b; + print20b(s,b->id); + snprintf(s+40,39," %d.%d.%d.%d:%u", + p[20], p[21], p[22], p[23], htons(b->port)); + return s; +} + +static char *print_ip_p(char *s, const struct bt_ipv4p *b,int np) { + const u_int8_t *p = (const void*)b; + snprintf(s,39,!np ? "%d.%d.%d.%d:%u":"%d.%d.%d.%d", + p[0], p[1], p[2], p[3], htons(b->port)); + return s; +} + +static char *print_ip6_p(char *s, const struct bt_ipv6p *b,int np) { + u_int16_t *p = (void*)b; + snprintf(s,79,!np ? "%x:%x:%x:%x:%x:%x:%x:%x.%u":"%x:%x:%x:%x:%x:%x:%x:%x", + htons(p[0]), htons(p[1]), htons(p[2]), htons(p[3]), + htons(p[4]), htons(p[5]), htons(p[6]), htons(p[7]), + htons(b->port)); + return s; +} + +static char *print_id_ip6_p(char *s,const struct bt_nodes6_data *b) { + return print_ip6_p(s,(struct bt_ipv6p *)&b->ip,0); +} + + +void dump_bt_proto_struct(struct bt_parse_protocol *p) { + char b20h[128]; + int i; + + if(p->y_e && p->e_msg) { + printf("Error %s/%u\n", p->e_msg, p->e_len); + } + if(p->y_q) { + printf("Query "); + if(p->q_ping) printf("ping\n"); + if(p->q_g_peers) printf("get_peers\n"); + if(p->q_f_node) printf("find_node\n"); + if(p->q_a_peer) printf("announce_peer\n"); + } + if(p->y_r) + printf("Reply\n"); + + if(p->t) printf("\tt\t%llx\n",p->t); + if(p->v) printf("\tv\t%llx\n",p->v); + if(p->ip) printf("\tIP\t%s\n",print_ip_p(b20h,p->ip,0)); + + if(p->a.port) printf("\tport\t%d\n",htons(p->a.port)); + if(p->a.id) printf("\tID\t%s\n",print20b(b20h,p->a.id)); + if(p->a.target) printf("\ttarget\t%s\n",print20b(b20h,p->a.target)); + if(p->a.token) printf("\ttoken\t%s\n",printXb(b20h,p->a.token,p->a.t_len)); + if(p->a.info_hash) printf("\ti_hash\t%s\n",print20b(b20h,p->a.info_hash)); + if(p->a.name && p->a.name_len) printf("\tname\t%.*s\n",p->a.name_len,p->a.name); + + if(p->r.ip) printf("\tip\t%s\n",print_ip_p(b20h,p->r.ip,1)); + if(p->r.port) printf("\tport\t%d\n",htons(p->r.port)); + if(p->r.id) printf("\tID\t%s\n",print20b(b20h,p->r.id)); + if(p->r.token) printf("\ttoken\t%s\n",printXb(b20h,p->r.token,p->r.t_len)); + if(p->r.name && p->r.name_len) printf("\tname\t%.*s\n",p->r.name_len,p->r.name); + if(p->r.values && p->r.nv) { + struct bt_ipv4p2 *n = (struct bt_ipv4p2 *)p->r.values; + for(i=0;i < p->r.nv; i++,n++) { + printf("\tvalues\t%s\n", print_ip_p(b20h,&n->d,0)); + } + } + if(p->r.values6 && p->r.nv6) { + struct bt_ipv6p2 *n = (struct bt_ipv6p2 *)p->r.values6; + for(i=0;i < p->r.nv6; i++,n++) { + printf("\tvalues6\t%s\n", print_ip6_p(b20h,&n->d,0)); + } + } + if(p->r.nodes && p->r.nn) { + for(i=0;i < p->r.nn; i++) { + printf("\tnodes\t%s\n",print_id_ip_p(b20h,p->r.nodes+i)); + } + } + if(p->r.nodes6 && p->r.nn6) { + for(i=0;i < p->r.nn6; i++) { + printf("\tnodes6\t%s\n",print_id_ip6_p(b20h,p->r.nodes6+i)); + } + } + + if(p->peers && p->n_peers) { + for(i=0;i < p->n_peers; i++) { + printf("\tpeers\t%s\n",print_ip_p(b20h,p->peers+i,0)); + } + } + + if(p->interval) printf("\tinterval\t%d\n",p->interval); + if(p->min_interval) printf("\tmin interval\t%d\n",p->min_interval); +} + +static void _print_safe_str(char *msg,char *k,const u_int8_t *s,size_t l) { + static const char *th="0123456789abcdef?"; + char *buf = (char*)ndpi_malloc((size_t)(l*3+2)); + + int sl = l; + if(buf) { + char *b = buf; + for(;l > 0; s++,l--) { + if(*s < ' ' || *s >= 127) { + *b++ = '%'; + *b++ = th[(*s >> 4)&0xf]; + *b++ = th[(*s)&0xf]; + } else *b++ = *s; + } + *b = 0; + + printf("%s %s %s len %d\n",msg,k,buf ? buf:"",sl); + + ndpi_free(buf); + } +} + +static void print_safe_str(char *msg,bt_parse_data_cb_t *cbd) { + _print_safe_str(msg,cbd->buf,cbd->v.s.s,cbd->v.s.l); +} +#define DEBUG_TRACE(cmd) { if(bt_parse_debug) cmd; } +#else +#define DEBUG_TRACE(cmd,args...) +#endif /* __KERNEL */ + +#define STREQ(a,b) !strcmp(a,b) + + +void cb_data(bt_parse_data_cb_t *cbd,int *ret) { + struct bt_parse_protocol *p = &(cbd->p); + const u_int8_t *s; + const char *ss; + + if(cbd->t == 0) return; + + if(cbd->t == 1) { + + DEBUG_TRACE(printf("%s %lld\n",cbd->buf,cbd->v.i)); + + if(STREQ(cbd->buf,"a.port")) { + p->a.port = (u_int16_t)(cbd->v.i & 0xffff); + return; + } + if( + STREQ(cbd->buf,"a.implied_port") || + STREQ(cbd->buf,"a.noseed") || + STREQ(cbd->buf,"a.scrape") || + STREQ(cbd->buf,"a.seed") || + STREQ(cbd->buf,"a.vote") + ) { + return; + } + if(STREQ(cbd->buf,"r.port") || STREQ(cbd->buf,"r.p")) { + p->r.port = (u_int16_t)(cbd->v.i & 0xffff); + return; + } + if(STREQ(cbd->buf,"interval")) { + p->interval = (u_int16_t)(cbd->v.i & 0x7fffffff); + p->h_int = 1; + return; + } + if(STREQ(cbd->buf,"min interval")) { + p->min_interval = (u_int16_t)(cbd->v.i & 0x7fffffff); + p->h_mint = 1; + return; + } + DEBUG_TRACE(printf("UNKNOWN %s %lld\n",cbd->buf,cbd->v.i)); + return; + } + if(cbd->t != 2) { + DEBUG_TRACE(printf("BUG! t=%d %s\n",cbd->t,cbd->buf)); + return; + } + DEBUG_TRACE(print_safe_str("",cbd)); + + s = cbd->v.s.s; + ss = (char *)s; + + if(STREQ(cbd->buf,"a.id")) { + p->a.id = s; + return; + } + if(STREQ(cbd->buf,"a.info_hash")) { + p->a.info_hash = s; + return; + } + if(STREQ(cbd->buf,"a.target")) { + p->a.target = s; + return; + } + if(STREQ(cbd->buf,"a.token")) { + p->a.token = s; + p->a.t_len = cbd->v.s.l; + return; + } + if(STREQ(cbd->buf,"a.name")) { + p->a.name = s; + p->a.name_len = cbd->v.s.l; + return; + } + if(STREQ(cbd->buf,"a.want")) { + return; + } + + if(STREQ(cbd->buf,"r.id")) { + p->r.id = s; + return; + } + if(STREQ(cbd->buf,"r.ip")) { + if(cbd->v.s.l != 4) { + DEBUG_TRACE(printf("BUG! r.ip with port\n")); + return; + } + p->r.ip = (struct bt_ipv4p *)s; + return; + } + if(STREQ(cbd->buf,"r.token")) { + p->r.token = s; + p->r.t_len = cbd->v.s.l; + return; + } + if(STREQ(cbd->buf,"r.values")) { + if(cbd->v.s.l == 18) { + if(!p->r.values6) { + p->r.values6 = s; + p->r.nv6 = 1; + } else { + if(s != p->r.values6+(p->r.nv6*21)) { + // DEBUG_TRACE(printf("BUG! r.values6 not in list! %08x %08x \n", p->r.values+(p->r.nv6*21),s)); + return; + } + p->r.nv6++; + } + return; + } + if(cbd->v.s.l == 6) { + if(!p->r.values) { + p->r.values = s; + p->r.nv = 1; + } else { + if(s != p->r.values+(p->r.nv*8)) { + // DEBUG_TRACE(printf("BUG! r.values not in list! %u \n",s-p->r.values+(p->r.nv*8))); + return; + } + p->r.nv++; + } + return; + } + return; + } + + if(STREQ(cbd->buf,"r.name") || STREQ(cbd->buf,"r.n")) { + p->r.name = s; + p->r.name_len = cbd->v.s.l; + return; + } + if(STREQ(cbd->buf,"r.nodes")) { + if(cbd->v.s.l % 26) { + // DEBUG_TRACE(printf("BUG! r.nodes length %d not %% 26\n",cbd->v.s.l)); + return; + } + p->r.nodes = (struct bt_nodes_data *)s; + p->r.nn = cbd->v.s.l / 26; + return; + } + if(STREQ(cbd->buf,"r.nodes6")) { + if(cbd->v.s.l % 38) { + // DEBUG_TRACE(printf("BUG! r.nodes length %d not %% 38\n",cbd->v.s.l)); + return; + } + p->r.nodes6 = (struct bt_nodes6_data *)s; + p->r.nn6 = cbd->v.s.l / 38; + return; + } + + if(cbd->buf[0] == 'y' && !cbd->buf[1]) { + if(cbd->v.s.l != 1) return; + if(*ss == 'q') { p->y_q = 1; return; } + if(*ss == 'r') { p->y_r = 1; return; } + if(*ss == 'e') { p->y_e = 1; return; } + return; + } + if(cbd->buf[0] == 'q' && !cbd->buf[1]) { + if(!strncmp(ss,"announce_peer",13)) { + p->q_a_peer = 1; + return; + } + if(!strncmp(ss,"find_node",9)) { + p->q_f_node = 1; + return; + } + if(!strncmp(ss,"get_peers",9)) { + p->q_g_peers = 1; + return; + } + if(!strncmp(ss,"ping",4)) { + p->q_ping = 1; + return; + } + if(!strncmp(ss,"vote",4)) { + return; + } + } + if(STREQ(cbd->buf,"ip")) { + if(cbd->v.s.l != 6) { + // DEBUG_TRACE(printf("BUG! r.ip w/o port\n")); + } + p->ip = (struct bt_ipv4p *)s; + p->h_ip = 1; + return; + } + if(STREQ(cbd->buf,"peers")) { + if(cbd->v.s.l % 6) return; + p->peers = (struct bt_ipv4p *)s; + p->n_peers = cbd->v.s.l / 6; + return; + } + if((*cbd->buf == 't' || *cbd->buf == 'v') && !cbd->buf[1]) { + u_int64_t d = *(u_int64_t*)s; + switch(cbd->v.s.l) { + case 2: + d &= 0xffffllu; d = htons(d); break; + case 4: + d &= 0xffffffffllu; d = htonl(d); break; + case 6: + d &= 0xffffffffffffllu; d = (htonl(d & 0xffffffff) << 16) | + (htons(d >> 32) & 0xffff); + break; + case 8: d = ((u_int64_t)htonl(d & 0xffffffff) << 32) | + htonl(d >> 32); + break; + default: d = 0; + } + if(*cbd->buf == 'v') cbd->p.v = d; + else cbd->p.t = d; + return; + } + + if(cbd->buf[0] == 'e' && !cbd->buf[0]) { + p->e_msg = s; + p->e_len = cbd->v.s.l; + return; + } + // DEBUG_TRACE(print_safe_str("UKNOWN",cbd)); +} + + +const u_int8_t *bt_decode(const u_int8_t *b, size_t *l, int *ret, bt_parse_data_cb_t *cbd) { + + unsigned int n=0,neg=0; + i_int64_t d = 0; + register u_int8_t c; + + if(*l == 0) return NULL; + if(cbd->level > BDEC_MAXDEPT) goto bad_data; + c = *b++; (*l)--; + if(c == 'i') { // integer + while(*l) { + c = *b++; (*l)--; + n++; + if(c == '-') { + if(n != 1) goto bad_data; + n--; + neg=1; + continue; + } + if(c >= '0' && c <= '9') { + if(c == '0' && n > 1 && !d && *b != 'e') goto bad_data; + d *= 10; + d += c-'0'; + continue; + } + if(c != 'e') goto bad_data; + break; + } + if(neg) d=-d; + cbd->t = 1; + cbd->v.i = neg ? -d:d; + return b; + } + if(c >= '1' && c <= '9') { //string + d=c-'0'; + while(*l) { + c = *b++; (*l)--; + n++; + if(c >= '0' && c <= '9') { + if(c == '0' && n > 1 && d == 0) goto bad_data; + d *= 10; + d += c-'0'; + continue; + } + if(c != ':') goto bad_data; + break; + } + if(d > *l) goto bad_data; + cbd->t = 2; + cbd->v.s.s = b; + cbd->v.s.l = d; + b += d; + *l -= d; + return b; + } + if(c == 'l') { + cbd->level++; + do { + b = bt_decode(b,l,ret,cbd); + if(*ret < 0 || *l == 0) goto bad_data; + cb_data(cbd,ret); + if(*ret < 0) goto bad_data; + cbd->t = 0; + } while (*b != 'e' && *l != 0); + b++; (*l)--; + cbd->level--; + return b; + } + if(c == 'd') { + cbd->level++; + do { + char *ls = cbd->buf + strlen(cbd->buf); + int l1 = ls != cbd->buf ? 1:0; + if(!(*b >= '1' && *b <= '9')) goto bad_data; + b = bt_decode(b,l,ret,cbd); + if(*ret < 0 || *l == 0) goto bad_data; + if(ls+cbd->v.s.l+l1 < &cbd->buf[sizeof(cbd->buf)-1]) { + if(l1) ls[0]='.'; + strncpy(ls+l1,(char *)cbd->v.s.s,cbd->v.s.l); + ls[cbd->v.s.l+l1]=0; + } + b = bt_decode(b,l,ret,cbd); + if(*ret < 0 || *l == 0) goto bad_data; + cb_data(cbd,ret); + if(*ret < 0) goto bad_data; + cbd->t = 0; + *ls = 0; + } while (*b != 'e' && l != 0); + + b++; (*l)--; + cbd->level--; + return b; + } + bad_data: + *ret=-1; + return b; +} diff --git a/src/lib/protocols/btlib.h b/src/lib/protocols/btlib.h new file mode 100644 index 000000000..cc2928155 --- /dev/null +++ b/src/lib/protocols/btlib.h @@ -0,0 +1,147 @@ +/* + * btlib.h + * + * Copyright (C) 2011-15 - ntop.org + * Contributed by Vitaly Lavrov <vel21ripn@gmail.com> + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#define BDEC_MAXDEPT 8 + + +typedef struct b_elem_s { + const u_int8_t *s; + size_t l; +} b_elem_s_t; + +struct __attribute__ ((__packed__)) bt_nodes_data { + u_int8_t id[20] ; + u_int32_t ip; + u_int16_t port; +}; + +struct __attribute__ ((__packed__)) bt_ipv4p { + u_int32_t ip; + u_int16_t port; +}; + +struct __attribute__ ((__packed__)) bt_ipv4p2 { + struct bt_ipv4p d; + u_int8_t pad[2]; +}; + +struct __attribute__ ((__packed__)) bt_nodes6_data { + u_int8_t id[20] ; + u_int32_t ip[4]; + u_int16_t port; +}; + +struct __attribute__ ((__packed__)) bt_ipv6p { + u_int32_t ip[4]; + u_int16_t port; +}; + +struct __attribute__ ((__packed__)) bt_ipv6p2 { + struct bt_ipv6p d; + u_int8_t pad[3]; +}; + +/* + + a.id S r.id S + a.info_hash S r.ip ipv4 + a.name S r.nodes x(id,ipv4,port) + -a.noseed 0|1 r.n S name of file + a.port N r.p port + -a.scrape 0|1 r.token S + -a.seed 0|1 r.values x(ipv4,port) + a.target S + a.token S -a.vote N + -a.want n4|n6 + + q announce_peer q find_node + q get_peers q ping + -q vote + + ip ipv4+port interval N + min interval N peers x(ipv4,port) + t 2/4/8b v 4/6b + + e S y e y r y q + + */ + +struct bt_parse_protocol { + u_int16_t y_e:1, y_r:1, y_q:1, + q_a_peer:1,q_f_node:1, + q_g_peers:1,q_ping:1, + h_int:1,h_mint:1,h_ip:1; + struct { + const u_int8_t *id, // 20 + *info_hash, // 20 + *target, // 20 + *token, // 20|8 + *name; // varlen + u_int16_t name_len; + u_int16_t port; + u_int16_t t_len; + } a; + struct { + const u_int8_t *id, // 20 + *token, // 20|8 + *values, // (6+2)*x + *values6, // (18_3)*x + *name; // varlen + struct bt_ipv4p *ip; + struct bt_nodes_data *nodes; + struct bt_nodes6_data *nodes6; + u_int16_t name_len; + u_int16_t nn; // nodes num + u_int16_t nv; // valuse num + u_int16_t nn6; // nodes6 num + u_int16_t nv6; // valuse6 num + u_int16_t port; + u_int16_t t_len; + } r; + int interval,min_interval; + struct bt_ipv4p *peers; + int n_peers; + struct bt_ipv4p *ip; + const u_int8_t *e_msg; + u_int16_t e_len; + u_int64_t t,v; +}; + +typedef struct bt_parse_data_cb { + struct bt_parse_protocol p; + char buf[64]; + int level; + int t; + union { + i_int64_t i; + b_elem_s_t s; + } v; +} bt_parse_data_cb_t; + +#ifndef __KERNEL__ +extern int bt_parse_debug; +void dump_bt_proto_struct(struct bt_parse_protocol *p); +#endif +const u_int8_t *bt_decode(const u_int8_t *b, size_t *l, int *ret, bt_parse_data_cb_t *cbd); + diff --git a/src/lib/protocols/ciscovpn.c b/src/lib/protocols/ciscovpn.c new file mode 100644 index 000000000..9245a6aaa --- /dev/null +++ b/src/lib/protocols/ciscovpn.c @@ -0,0 +1,70 @@ +/* + * ciscovpn.c + * Copyright (C) 2013 by Remy Mudingay <mudingay@ill.fr> + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_CISCOVPN + +static void ndpi_int_ciscovpn_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CISCOVPN, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_ciscovpn(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t udport = 0, usport = 0; + u_int16_t tdport = 0, tsport = 0; + + + NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "search CISCOVPN.\n"); + + if(packet->tcp != NULL) { + tsport = ntohs(packet->tcp->source), tdport = ntohs(packet->tcp->dest); + NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "calculated CISCOVPN over tcp ports.\n"); + } + if(packet->udp != NULL) { + usport = ntohs(packet->udp->source), udport = ntohs(packet->udp->dest); + NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "calculated CISCOVPN over udp ports.\n"); + } + + if((tdport == 10000 && tsport == 10000) || + ((tsport == 443 || tdport == 443) && + (packet->payload[0] == 0x17 && + packet->payload[1] == 0x01 && + packet->payload[2] == 0x00 && + packet->payload[3] == 0x00) + ) + ) + + { + /* This is a good query 17010000*/ + NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "found CISCOVPN.\n"); + ndpi_int_ciscovpn_add_connection(ndpi_struct, flow); + } + else if( + ( + (usport == 10000 && udport == 10000) + && + (packet->payload[0] == 0xfe && + packet->payload[1] == 0x57 && + packet->payload[2] == 0x7e && + packet->payload[3] == 0x2b) + ) + ) + { + + + /* This is a good query fe577e2b */ + NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "found CISCOVPN.\n"); + ndpi_int_ciscovpn_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_CISCOVPN, ndpi_struct, NDPI_LOG_DEBUG, "exclude CISCOVPN.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CISCOVPN); + } + +} +#endif diff --git a/src/lib/protocols/citrix.c b/src/lib/protocols/citrix.c new file mode 100644 index 000000000..1cae9f9e5 --- /dev/null +++ b/src/lib/protocols/citrix.c @@ -0,0 +1,93 @@ +/* + * citrix.c + * + * Copyright (C) 2012-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_CITRIX + +/* ************************************ */ + +static void ndpi_check_citrix(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + +#if 0 + printf("[len=%u][%02X %02X %02X %02X]\n", payload_len, + packet->payload[0] & 0xFF, + packet->payload[1] & 0xFF, + packet->payload[2] & 0xFF, + packet->payload[3] & 0xFF); +#endif + + if(packet->tcp != NULL) { + flow->l4.tcp.citrix_packet_id++; + + if((flow->l4.tcp.citrix_packet_id == 3) + /* We have seen the 3-way handshake */ + && flow->l4.tcp.seen_syn + && flow->l4.tcp.seen_syn_ack + && flow->l4.tcp.seen_ack) { + if(payload_len == 6) { + char citrix_header[] = { 0x07, 0x07, 0x49, 0x43, 0x41, 0x00 }; + + if(memcmp(packet->payload, citrix_header, sizeof(citrix_header)) == 0) { + NDPI_LOG(NDPI_PROTOCOL_CITRIX, ndpi_struct, NDPI_LOG_DEBUG, "Found citrix.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CITRIX, NDPI_REAL_PROTOCOL); + } + + return; + } else if(payload_len > 4) { + char citrix_header[] = { 0x1a, 0x43, 0x47, 0x50, 0x2f, 0x30, 0x31 }; + + if((memcmp(packet->payload, citrix_header, sizeof(citrix_header)) == 0) + || (ndpi_strnstr((const char *)packet->payload, "Citrix.TcpProxyService", payload_len) != NULL)) { + NDPI_LOG(NDPI_PROTOCOL_CITRIX, ndpi_struct, NDPI_LOG_DEBUG, "Found citrix.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CITRIX, NDPI_REAL_PROTOCOL); + } + + return; + } + + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CITRIX); + } else if(flow->l4.tcp.citrix_packet_id > 3) + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CITRIX); + + return; + } +} + +void ndpi_search_citrix(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_CITRIX, ndpi_struct, NDPI_LOG_DEBUG, "citrix detection...\n"); + + /* skip marked packets */ + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_CITRIX) + ndpi_check_citrix(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/collectd.c b/src/lib/protocols/collectd.c new file mode 100644 index 000000000..eee805d5c --- /dev/null +++ b/src/lib/protocols/collectd.c @@ -0,0 +1,53 @@ +/* + * collectd.c + * + * Copyright (C) 2014 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_COLLECTD + +void ndpi_search_collectd(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int len = 0; + + NDPI_LOG(NDPI_PROTOCOL_COLLECTD, ndpi_struct, NDPI_LOG_DEBUG, "search collectd.\n"); + + if (packet->udp == NULL) return; + + + while(len < packet->payload_packet_len) { + // u_int16_t elem_type = ntohs(*((u_int16_t*)&packet->payload[len])); + u_int16_t elem_len = ntohs(*((u_int16_t*)&packet->payload[len+2])); + + if (elem_len == 0) break; + + len += elem_len; + } + + if(len == packet->payload_packet_len) { + NDPI_LOG(NDPI_PROTOCOL_COLLECTD, ndpi_struct, NDPI_LOG_DEBUG, "found COLLECTD.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_COLLECTD, NDPI_REAL_PROTOCOL); + } else { + NDPI_LOG(NDPI_PROTOCOL_COLLECTD, ndpi_struct, NDPI_LOG_DEBUG, "exclude COLLECTD.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_COLLECTD); + } +} +#endif diff --git a/src/lib/protocols/corba.c b/src/lib/protocols/corba.c new file mode 100644 index 000000000..050d1035d --- /dev/null +++ b/src/lib/protocols/corba.c @@ -0,0 +1,48 @@ +/* + * corba.c + * + * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * + * This module is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This module is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License. + * If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_CORBA +static void ndpi_int_corba_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CORBA, NDPI_CORRELATED_PROTOCOL); +} +void ndpi_search_corba(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_CORBA, ndpi_struct, NDPI_LOG_DEBUG, "search for CORBA.\n"); + if(packet->tcp != NULL) { + NDPI_LOG(NDPI_PROTOCOL_CORBA, ndpi_struct, NDPI_LOG_DEBUG, "calculating CORBA over tcp.\n"); + /* Corba General Inter-ORB Protocol -> GIOP */ + if ((packet->payload_packet_len >= 24 && packet->payload_packet_len <= 144) && + memcmp(packet->payload, "GIOP", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_CORBA, ndpi_struct, NDPI_LOG_DEBUG, "found corba.\n"); + ndpi_int_corba_add_connection(ndpi_struct, flow); + } + } else { + NDPI_LOG(NDPI_PROTOCOL_CORBA, ndpi_struct, NDPI_LOG_DEBUG, "exclude CORBA.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CORBA); + } +} +#endif diff --git a/src/lib/protocols/crossfire.c b/src/lib/protocols/crossfire.c new file mode 100644 index 000000000..cb5b3520f --- /dev/null +++ b/src/lib/protocols/crossfire.c @@ -0,0 +1,85 @@ +/* + * crossfire.c + * + * Copyright (C) 2012-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +/* include files */ +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_CROSSFIRE + + +static void ndpi_int_crossfire_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type) +{ + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CROSSFIRE, protocol_type); +} + +void ndpi_search_crossfire_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_CROSSFIRE, ndpi_struct, NDPI_LOG_DEBUG, "search crossfire.\n"); + + + if (packet->udp != 0) { + if (packet->payload_packet_len == 25 && get_u_int32_t(packet->payload, 0) == ntohl(0xc7d91999) + && get_u_int16_t(packet->payload, 4) == ntohs(0x0200) + && get_u_int16_t(packet->payload, 22) == ntohs(0x7d00) + ) { + NDPI_LOG(NDPI_PROTOCOL_CROSSFIRE, ndpi_struct, NDPI_LOG_DEBUG, "Crossfire: found udp packet.\n"); + ndpi_int_crossfire_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + } else if (packet->tcp != 0) { + + if (packet->payload_packet_len > 4 && memcmp(packet->payload, "GET /", 5) == 0) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->parsed_lines == 8 + && (packet->line[0].ptr != NULL && packet->line[0].len >= 30 + && (memcmp(&packet->payload[5], "notice/login_big", 16) == 0 + || memcmp(&packet->payload[5], "notice/login_small", 18) == 0)) + && memcmp(&packet->payload[packet->line[0].len - 19], "/index.asp HTTP/1.", 18) == 0 + && (packet->host_line.ptr != NULL && packet->host_line.len >= 13 + && (memcmp(packet->host_line.ptr, "crossfire", 9) == 0 + || memcmp(packet->host_line.ptr, "www.crossfire", 13) == 0)) + ) { + NDPI_LOG(NDPI_PROTOCOL_CROSSFIRE, ndpi_struct, NDPI_LOG_DEBUG, "Crossfire: found HTTP request.\n"); + ndpi_int_crossfire_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + + } + + NDPI_LOG(NDPI_PROTOCOL_CROSSFIRE, ndpi_struct, NDPI_LOG_DEBUG, "exclude crossfire.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CROSSFIRE); +} + + + +#endif diff --git a/src/lib/protocols/dcerpc.c b/src/lib/protocols/dcerpc.c new file mode 100644 index 000000000..5879aec6d --- /dev/null +++ b/src/lib/protocols/dcerpc.c @@ -0,0 +1,54 @@ +/* + * dcerpc.c + * + * Copyright (C) 2011-13 by ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_DCERPC + +static void ndpi_int_dcerpc_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DCERPC, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_dcerpc(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + if((packet->tcp != NULL) + && (packet->payload_packet_len > 64) + && ((ntohs(packet->tcp->source) == 135) || (ntohs(packet->tcp->dest) == 135)) + && (packet->payload[0] == 0x05) /* version 5 */ + && (packet->payload[2] < 16) /* Packet type */ + ) { + NDPI_LOG(NDPI_PROTOCOL_DCERPC, ndpi_struct, NDPI_LOG_DEBUG, "DCERPC match\n"); + ndpi_int_dcerpc_add_connection(ndpi_struct, flow); + return; + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DCERPC); +} + +#endif diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c new file mode 100644 index 000000000..b623a6a15 --- /dev/null +++ b/src/lib/protocols/dhcp.c @@ -0,0 +1,60 @@ +/* + * dhcp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_DHCP + +static void ndpi_int_dhcp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DHCP, NDPI_REAL_PROTOCOL); +} + + +void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + /* this detection also works for asymmetric dhcp traffic */ + + /*check standard DHCP 0.0.0.0:68 -> 255.255.255.255:67 */ + if (packet->payload_packet_len >= 244 && (packet->udp->source == htons(67) + || packet->udp->source == htons(68)) + && (packet->udp->dest == htons(67) || packet->udp->dest == htons(68)) + && get_u_int32_t(packet->payload, 236) == htonl(0x63825363) + && get_u_int16_t(packet->payload, 240) == htons(0x3501)) { + + NDPI_LOG(NDPI_PROTOCOL_DHCP, ndpi_struct, NDPI_LOG_DEBUG, "DHCP request\n"); + + ndpi_int_dhcp_add_connection(ndpi_struct, flow); + return; + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DHCP); +} +#endif diff --git a/src/lib/protocols/dhcpv6.c b/src/lib/protocols/dhcpv6.c new file mode 100644 index 000000000..b0c23c9c9 --- /dev/null +++ b/src/lib/protocols/dhcpv6.c @@ -0,0 +1,60 @@ +/* + * dhcpv6.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +/* include files */ + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_DHCPV6 + +static void ndpi_int_dhcpv6_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DHCPV6, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_dhcpv6_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len >= 4 && + (packet->udp->source == htons(546) || packet->udp->source == htons(547)) && + (packet->udp->dest == htons(546) || packet->udp->dest == htons(547)) && + packet->payload[0] >= 1 && packet->payload[0] <= 13) { + + NDPI_LOG(NDPI_PROTOCOL_DHCPV6, ndpi_struct, NDPI_LOG_DEBUG, "DHCPv6 detected.\n"); + ndpi_int_dhcpv6_add_connection(ndpi_struct, flow); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_DHCPV6, ndpi_struct, NDPI_LOG_DEBUG, "DHCPv6 excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DHCPV6); +} + +#endif diff --git a/src/lib/protocols/directconnect.c b/src/lib/protocols/directconnect.c new file mode 100644 index 000000000..624f57e58 --- /dev/null +++ b/src/lib/protocols/directconnect.c @@ -0,0 +1,474 @@ +/* + * directconnect.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_DIRECTCONNECT + +//#define NDPI_DEBUG_DIRECTCONNECT +//#define NDPI_DIRECTCONNECT_PORT_DEBUG +//#define NDPI_DEBUG_DIRECTCONNECT_CONN + + +#define DIRECT_CONNECT_TYPE_HUB 0 +#define DIRECT_CONNECT_TYPE_PEER 1 +#define DIRECT_CONNECT_ADC_PEER 2 + +static u_int32_t skip_unknown_headers(const u_int8_t * payload, u_int32_t payload_len, u_int32_t pos) +{ + u_int32_t i = pos; + while (i < payload_len && payload[i] != 0x0a) + i++; + + i++; + return i; + +} + +static u_int16_t parse_binf_message(struct ndpi_detection_module_struct + *ndpi_struct, const u_int8_t * payload, int payload_len) +{ + u_int32_t i = 4; + u_int16_t bytes_read = 0; + u_int16_t ssl_port = 0; + while (i < payload_len) { + i = skip_unknown_headers(payload, payload_len, i); + if ((i + 30) < payload_len) { + if (memcmp(&payload[i], "DCTM", 4) == 0) { + if (memcmp(&payload[i + 15], "ADCS", 4) == 0) { + ssl_port = ntohs_ndpi_bytestream_to_number(&payload[i + 25], 5, &bytes_read); + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "directconnect ssl port parsed %d", ssl_port); + + } + } + } else { + break; + } + + } + return ssl_port; +} + +static void ndpi_int_directconnect_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + const u_int8_t connection_type) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL); + + if (src != NULL) { + src->directconnect_last_safe_access_time = packet->tick_timestamp; + if (connection_type == DIRECT_CONNECT_TYPE_PEER) { + if (packet->tcp != NULL + && flow->setup_packet_direction != packet->packet_direction && src->detected_directconnect_port == 0) { + src->detected_directconnect_port = packet->tcp->source; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "directconnect tcp PORT %u for src\n", ntohs(src->detected_directconnect_port)); + } + if (packet->udp != NULL && src->detected_directconnect_udp_port == 0) { + src->detected_directconnect_udp_port = packet->udp->source; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "directconnect udp PORT %u for src\n", ntohs(src->detected_directconnect_port)); + + } + } + + } + if (dst != NULL) { + dst->directconnect_last_safe_access_time = packet->tick_timestamp; + if (connection_type == DIRECT_CONNECT_TYPE_PEER) { + if (packet->tcp != NULL + && flow->setup_packet_direction == packet->packet_direction && dst->detected_directconnect_port == 0) { + /* DST PORT MARKING CAN LEAD TO PORT MISSDETECTIONS + * seen at large customer http servers, where someone has send faked DC tcp packets + * to the server + */ + + /* + dst->detected_directconnect_port = packet->tcp->dest; + NDPI_LOG (NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "directconnect tcp PORT %u for dst\n", + ntohs (dst->detected_directconnect_port)); + */ + } + } + } +} + +static void ndpi_search_directconnect_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + if (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_DIRECTCONNECT) { + if (packet->payload_packet_len >= 40 && memcmp(&packet->payload[0], "BINF", 4) == 0) { + u_int16_t ssl_port = 0; + ssl_port = parse_binf_message(ndpi_struct, &packet->payload[4], packet->payload_packet_len - 4); + if (dst != NULL && ssl_port) { + dst->detected_directconnect_ssl_port = ssl_port; + } + if (src != NULL && ssl_port) { + src->detected_directconnect_ssl_port = ssl_port; + } + + + } + if ((packet->payload_packet_len >= 38 && packet->payload_packet_len <= 42) + && memcmp(&packet->payload[0], "DCTM", 4) == 0 && memcmp(&packet->payload[15], "ADCS", 4) == 0) { + u_int16_t bytes_read = 0; + if (dst != NULL) { + dst->detected_directconnect_ssl_port = + ntohs_ndpi_bytestream_to_number(&packet->payload[25], 5, &bytes_read); + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "directconnect ssl port parsed %d", ntohs(dst->detected_directconnect_ssl_port)); + } + if (src != NULL) { + src->detected_directconnect_ssl_port = + ntohs_ndpi_bytestream_to_number(&packet->payload[25], 5, &bytes_read); + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "directconnect ssl port parsed %d", ntohs(src->detected_directconnect_ssl_port)); + } + + + } + return; + + } + if (src != NULL) { + if (src->detected_directconnect_port == packet->tcp->source) { + if ((u_int32_t) + (packet->tick_timestamp - + src->directconnect_last_safe_access_time) < ndpi_struct->directconnect_connection_ip_tick_timeout) { + ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL); + src->directconnect_last_safe_access_time = packet->tick_timestamp; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "marking using dc port\n %d", ntohs(src->detected_directconnect_port)); + return; + } else { + src->detected_directconnect_port = 0; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "resetting src port due to timeout"); + return; + } + } + if (src->detected_directconnect_ssl_port == packet->tcp->dest) { + if ((u_int32_t) + (packet->tick_timestamp - + src->directconnect_last_safe_access_time) < ndpi_struct->directconnect_connection_ip_tick_timeout) { + ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL); + src->directconnect_last_safe_access_time = packet->tick_timestamp; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "marking using dc port\n %d", ntohs(src->detected_directconnect_ssl_port)); + return; + } else { + src->detected_directconnect_ssl_port = 0; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "resetting src port due to timeout"); + return; + } + } + + } + + if (dst != NULL) { + if (dst->detected_directconnect_port == packet->tcp->dest) { + if ((u_int32_t) + (packet->tick_timestamp - + dst->directconnect_last_safe_access_time) < ndpi_struct->directconnect_connection_ip_tick_timeout) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL); + dst->directconnect_last_safe_access_time = packet->tick_timestamp; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "marking using dc port\n %d", ntohs(dst->detected_directconnect_port)); + return; + } else { + dst->detected_directconnect_port = 0; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "resetting dst port due to timeout"); + return; + } + } + if (dst->detected_directconnect_ssl_port == packet->tcp->dest) { + if ((u_int32_t) + (packet->tick_timestamp - + dst->directconnect_last_safe_access_time) < ndpi_struct->directconnect_connection_ip_tick_timeout) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL); + dst->directconnect_last_safe_access_time = packet->tick_timestamp; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "marking using dc port\n %d", ntohs(dst->detected_directconnect_ssl_port)); + + return; + } else { + dst->detected_directconnect_ssl_port = 0; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "resetting dst port due to timeout"); + return; + } + } + + } + + if (flow->directconnect_stage == 0) { + + if (packet->payload_packet_len > 6) { + if (packet->payload[0] == '$' + && packet->payload[packet->payload_packet_len - 1] == '|' + && (memcmp(&packet->payload[1], "Lock ", 5) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "maybe first dc connect to hub detected\n"); + flow->directconnect_stage = 1; + return; + } + if (packet->payload_packet_len > 7 + && packet->payload[0] == '$' + && packet->payload[packet->payload_packet_len - 1] == '|' + && (memcmp(&packet->payload[1], "MyNick ", 7) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "maybe first dc connect between peers detected\n"); + flow->directconnect_stage = 2; + return; + } + + } + if (packet->payload_packet_len >= 11) { + /* did not see this pattern in any trace */ + if (memcmp(&packet->payload[0], "HSUP ADBAS0", 11) == 0 + || memcmp(&packet->payload[0], "HSUP ADBASE", 11) == 0) { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "found directconnect HSUP ADBAS0 E\n"); + ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_HUB); + return; + /* did not see this pattern in any trace */ + } else if (memcmp(&packet->payload[0], "CSUP ADBAS0", 11) == 0 || + memcmp(&packet->payload[0], "CSUP ADBASE", 11) == 0) { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "found directconnect CSUP ADBAS0 E\n"); + ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_ADC_PEER); + return; + + } + + } + + } else if (flow->directconnect_stage == 1) { + if (packet->payload_packet_len >= 11) { + /* did not see this pattern in any trace */ + if (memcmp(&packet->payload[0], "HSUP ADBAS0", 11) == 0 + || memcmp(&packet->payload[0], "HSUP ADBASE", 11) == 0) { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "found directconnect HSUP ADBAS E in second packet\n"); + ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_HUB); + + return; + /* did not see this pattern in any trace */ + } else if (memcmp(&packet->payload[0], "CSUP ADBAS0", 11) == 0 || + memcmp(&packet->payload[0], "CSUP ADBASE", 11) == 0) { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "found directconnect HSUP ADBAS0 E in second packet\n"); + ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_ADC_PEER); + + + return; + + } + } + /* get client hello answer or server message */ + if (packet->payload_packet_len > 6) { + if ((packet->payload[0] == '$' || packet->payload[0] == '<') + && packet->payload[packet->payload_packet_len - 1] == '|') { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, NDPI_LOG_DEBUG, "second dc detected\n"); + ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_HUB); + + return; + } else { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, NDPI_LOG_DEBUG, "second dc not detected\n"); + } + + } + } else if (flow->directconnect_stage == 2) { + /* get client hello answer or server message */ + if (packet->payload_packet_len > 6) { + if (packet->payload[0] == '$' && packet->payload[packet->payload_packet_len - 1] == '|') { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "second dc between peers detected\n"); + + + ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_PEER); + + return; + } else { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "second dc between peers not detected\n"); + } + } + + } + + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DIRECTCONNECT); + +} + +static void ndpi_search_directconnect_udp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + int pos, count = 0; + + + if (dst != NULL && dst->detected_directconnect_udp_port == packet->udp->dest) { + if ((u_int32_t) + (packet->tick_timestamp - + dst->directconnect_last_safe_access_time) < ndpi_struct->directconnect_connection_ip_tick_timeout) { + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_REAL_PROTOCOL); + dst->directconnect_last_safe_access_time = packet->tick_timestamp; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "marking using dc udp port\n %d", ntohs(dst->detected_directconnect_udp_port)); + return; + } else { + dst->detected_directconnect_udp_port = 0; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "resetting dst udp port due to timeout"); + return; + } + } + + if (packet->payload_packet_len > 58) { + if (src != NULL + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_DIRECTCONNECT)) { + if (packet->payload[0] == '$' + && packet->payload[packet->payload_packet_len - 1] == '|' + && memcmp(&packet->payload[1], "SR ", 3) == 0) { + pos = packet->payload_packet_len - 2; + if (packet->payload[pos] == ')') { + while (pos > 0 && packet->payload[pos] != '(' && count < 21) { + pos--; + count++; + } + if (packet->payload[pos] == '(') { + pos = pos - 44; + if (pos > 2 && memcmp(&packet->payload[pos], "TTH:", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, NDPI_LOG_DEBUG, "dc udp detected\n"); + ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_PEER); + return; + } + } + } + flow->directconnect_stage++; + + if (flow->directconnect_stage < 3) { + + + return; + } + + } + + } + if (dst != NULL + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_DIRECTCONNECT)) { + if (packet->payload[0] == '$' + && packet->payload[packet->payload_packet_len - 1] == '|' + && memcmp(&packet->payload[1], "SR ", 3) == 0) { + pos = packet->payload_packet_len - 2; + if (packet->payload[pos] == ')') { + while (pos > 0 && packet->payload[pos] != '(' && count < 21) { + pos--; + count++; + } + if (packet->payload[pos] == '(') { + pos = pos - 44; + if (pos > 2 && memcmp(&packet->payload[pos], "TTH:", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, NDPI_LOG_DEBUG, "dc udp detected\n"); + ndpi_int_directconnect_add_connection(ndpi_struct, flow, DIRECT_CONNECT_TYPE_PEER); + return; + } + } + } + flow->directconnect_stage++; + if (flow->directconnect_stage < 3) + return; + + } + } + + } + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, NDPI_LOG_DEBUG, + "excluded at stage %d \n", flow->directconnect_stage); + + + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DIRECTCONNECT); + + +} + +void ndpi_search_directconnect(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_DIRECTCONNECT) { + if (src != NULL && ((u_int32_t) + (packet->tick_timestamp - + src->directconnect_last_safe_access_time) < + ndpi_struct->directconnect_connection_ip_tick_timeout)) { + src->directconnect_last_safe_access_time = packet->tick_timestamp; + + } else if (dst != NULL && ((u_int32_t) + (packet->tick_timestamp - + dst->directconnect_last_safe_access_time) < + ndpi_struct->directconnect_connection_ip_tick_timeout)) { + dst->directconnect_last_safe_access_time = packet->tick_timestamp; + } else { + packet->detected_protocol_stack[0] = NDPI_PROTOCOL_UNKNOWN; + NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, + NDPI_LOG_DEBUG, "directconnect: skipping as unknown due to timeout\n"); + } + return; + } + + if (packet->tcp != NULL) { + ndpi_search_directconnect_tcp(ndpi_struct, flow); + } else if (packet->udp != NULL) { + ndpi_search_directconnect_udp(ndpi_struct, flow); + } +} + +#endif diff --git a/src/lib/protocols/directdownloadlink.c b/src/lib/protocols/directdownloadlink.c new file mode 100644 index 000000000..5c8de52c0 --- /dev/null +++ b/src/lib/protocols/directdownloadlink.c @@ -0,0 +1,737 @@ +/* + * directdownloadlink.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-14svn - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK + + +#ifdef NDPI_DEBUG_DIRECT_DOWNLOAD_LINK +//#define NDPI_DEBUG_DIRECT_DOWNLOAD_LINK_NOTHING_FOUND +//#define NDPI_DEBUG_DIRECT_DOWNLOAD_LINK_PACKET_TOO_SMALL +#define NDPI_DEBUG_DIRECT_DOWNLOAD_LINK_IP +#endif + +static void ndpi_int_direct_download_link_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, NDPI_CORRELATED_PROTOCOL); + + flow->l4.tcp.ddlink_server_direction = packet->packet_direction; +} + + + +/* + return 0 if nothing has been detected + return 1 if it is a megaupload packet +*/ +u_int8_t search_ddl_domains(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + u_int16_t filename_start = 0; + u_int8_t i = 1; + u_int16_t host_line_len_without_port; + + if (packet->payload_packet_len < 100) { + NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: Packet too small.\n"); + goto end_ddl_nothing_found; + } + + + + if (memcmp(packet->payload, "POST ", 5) == 0) { + filename_start = 5; // POST + NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: POST FOUND\n"); + } else if (memcmp(packet->payload, "GET ", 4) == 0) { + filename_start = 4; // GET + NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: GET FOUND\n"); + } else { + goto end_ddl_nothing_found; + } + // parse packet + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if (packet->host_line.ptr == NULL) { + NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: NO HOST FOUND\n"); + goto end_ddl_nothing_found; + } + + NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: Host: found\n"); + + if (packet->line[0].len < 9 + filename_start + || memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) != 0) { + NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, + NDPI_LOG_DEBUG, "DDL: PACKET NOT HTTP CONFORM.\nXXX%.*sXXX\n", + 8, &packet->line[0].ptr[packet->line[0].len - 9]); + goto end_ddl_nothing_found; + } + // BEGIN OF AUTOMATED CODE GENERATION + // first see if we have ':port' at the end of the line + host_line_len_without_port = packet->host_line.len; + if (host_line_len_without_port >= i && packet->host_line.ptr[host_line_len_without_port - i] >= '0' + && packet->host_line.ptr[packet->host_line.len - i] <= '9') { + i = 2; + while (host_line_len_without_port >= i && packet->host_line.ptr[host_line_len_without_port - i] >= '0' + && packet->host_line.ptr[host_line_len_without_port - i] <= '9') { + NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: number found\n"); + i++; + } + if (host_line_len_without_port >= i && packet->host_line.ptr[host_line_len_without_port - i] == ':') { + NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: ':' found\n"); + host_line_len_without_port = host_line_len_without_port - i; + } + } + // then start automated code generation + + if (host_line_len_without_port >= 0 + 4 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 4], ".com", 4) == 0) { + if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'd') { + if (host_line_len_without_port >= 5 + 6 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 6], "4share", 6) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 6 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 6 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 8 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 8], "fileclou", 8) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 5 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 5], "uploa", 5) == 0) { + if (host_line_len_without_port >= 10 + 6 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 6], "files-", 6) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 10 - 6 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 10 - 6 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 10 + 4 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 4], "mega", 4) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 10 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 5], "rapid", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 10 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 5], "turbo", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'o') { + if (host_line_len_without_port >= 5 + 6 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 6], "badong", 6) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 6 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 6 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 5], "fileh", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'g') { + if (host_line_len_without_port >= 5 + 2 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 2], "in", 2) == 0) { + if (host_line_len_without_port >= 7 + 4 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 7 - 4], "shar", 4) == 0) { + if (host_line_len_without_port >= 11 + 4 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 11 - 4], "best", 4) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 11 - 4 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 11 - 4 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 11 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 11 - 5], "quick", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 11 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 11 - 5 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 7 + 6 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 7 - 6], "upload", 6) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 7 - 6 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 7 - 6 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 5 + 7 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 7], "sharebi", 7) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 4 + 8 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 8], "bigfilez", 8) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 4 - 8 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 4 - 8 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'e') { + if (host_line_len_without_port >= 5 + 3 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 3], "fil", 3) == 0) { + if (host_line_len_without_port >= 8 + 2 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 2], "mo", 2) == 0) { + if (host_line_len_without_port >= 10 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 5], "china", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 8 + 2 + 1 + && (packet->host_line.ptr[host_line_len_without_port - 8 - 2 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 8 - 2 - 1] == '.')) { + goto end_ddl_found; + } + } + if (host_line_len_without_port >= 8 + 3 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 3], "hot", 3) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 8 - 3 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 8 - 3 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 8 + 6 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 6], "keepmy", 6) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 8 - 6 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 8 - 6 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 8 + 1 + && packet->host_line.ptr[host_line_len_without_port - 8 - 1] == 'e') { + if (host_line_len_without_port >= 9 + 3 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 3], "sav", 3) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 9 - 3 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 9 - 3 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 9 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 5], "sendm", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 9 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 9 - 5 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 8 + 8 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 8], "sharebig", 8) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 8 - 8 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 8 - 8 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 8 + 3 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 3], "up-", 3) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 8 - 3 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 8 - 3 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 5 + 1 && packet->host_line.ptr[host_line_len_without_port - 5 - 1] == 'r') { + if (host_line_len_without_port >= 6 + 3 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 6 - 3], "sha", 3) == 0) { + if (host_line_len_without_port >= 9 + 1 + && packet->host_line.ptr[host_line_len_without_port - 9 - 1] == '-') { + if (host_line_len_without_port >= 10 + 4 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 4], "easy", + 4) == 0 && (packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == + '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 10 + 4 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 4], "fast", + 4) == 0 && (packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == + '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 10 + 4 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 4], "live", + 4) == 0 && (packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 10 - 4 - 1] == + '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 9 + 4 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 4], "ftp2", 4) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 9 + 4 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 4], "gige", 4) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 9 + 4 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 4], "mega", 4) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 9 - 4 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 9 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 9 - 5], "rapid", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 9 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 9 - 5 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 6 + 7 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 6 - 7], "mediafi", 7) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 6 - 7 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 6 - 7 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 5 + 7 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 7], "gigasiz", 7) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 8 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 8], "sendspac", 8) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 7 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 7], "sharebe", 7) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 11 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 11], "sharebigfli", 11) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 11 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 11 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 8 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 8], "fileserv", 8) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 's') { + if (host_line_len_without_port >= 5 + 1 && packet->host_line.ptr[host_line_len_without_port - 5 - 1] == 'e') { + if (host_line_len_without_port >= 6 + 10 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 6 - 10], "depositfil", + 10) == 0 && (packet->host_line.ptr[host_line_len_without_port - 6 - 10 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 6 - 10 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 6 + 8 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 6 - 8], "megashar", 8) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 6 - 8 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 6 - 8 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 5 + 10 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 10], "fileupyour", 10) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 4 + 11 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 11], "filefactory", 11) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 4 - 11 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 4 - 11 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 't') { + if (host_line_len_without_port >= 5 + 8 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 8], "filefron", 8) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 10 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 10], "uploadingi", 10) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 11 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 11], "yourfilehos", 11) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 11 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 11 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'r') { + if (host_line_len_without_port >= 5 + 8 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 8], "mytempdi", 8) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 8 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 10 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 10], "uploadpowe", 10) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 10 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 4 + 9 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 9], "mega.1280", 9) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 4 + 9 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 9], "filesonic", 9) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 0 + 4 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 4], ".net", 4) == 0) { + if (host_line_len_without_port >= 4 + 7 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 7], "badongo", 7) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'd') { + if (host_line_len_without_port >= 5 + 3 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 3], "loa", 3) == 0) { + if (host_line_len_without_port >= 8 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 5], "fast-", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 8 + 2 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 2], "up", 2) == 0) { + if (host_line_len_without_port >= 10 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 5], "file-", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 10 - 5 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 10 + 6 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 6], "simple", + 6) == 0 && (packet->host_line.ptr[host_line_len_without_port - 10 - 6 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 10 - 6 - 1] == + '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 10 + 3 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 10 - 3], "wii", 3) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 10 - 3 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 10 - 3 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 5 + 7 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 7], "filesen", 7) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 7 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 4 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 5], "filer", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 4 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 4 - 5 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 4 + 9 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 9], "livedepot", 9) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 4 - 9 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 4 + 1 && packet->host_line.ptr[host_line_len_without_port - 4 - 1] == 'e') { + if (host_line_len_without_port >= 5 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 5], "mofil", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 17 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 17], "odsiebie.najlepsz", + 17) == 0 && (packet->host_line.ptr[host_line_len_without_port - 5 - 17 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 17 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 5 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 5 - 5], "zshar", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 5 - 5 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 0 + 1 && packet->host_line.ptr[host_line_len_without_port - 0 - 1] == 'u') { + if (host_line_len_without_port >= 1 + 6 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 6], "data.h", 6) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 1 - 6 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 1 - 6 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 1 + 2 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 2], ".r", 2) == 0) { + if (host_line_len_without_port >= 3 + 10 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 10], "filearchiv", 10) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 3 - 10 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 3 - 10 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 3 + 8 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 8], "filepost", 8) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 3 - 8 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 3 - 8 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 3 + 7 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 7], "ifolder", 7) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 3 - 7 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 3 - 7 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 0 + 11 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 11], "filehost.tv", 11) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 0 - 11 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 0 - 11 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 0 + 3 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 3], ".to", 3) == 0) { + if (host_line_len_without_port >= 3 + 1 && packet->host_line.ptr[host_line_len_without_port - 3 - 1] == 'e') { + if (host_line_len_without_port >= 4 + 7 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 7], "filesaf", 7) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 4 + 8 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 8], "sharebas", 8) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 4 - 8 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 4 - 8 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 3 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 5], "files", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 3 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 3 - 5 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 3 + 1 && packet->host_line.ptr[host_line_len_without_port - 3 - 1] == 'd') { + if (host_line_len_without_port >= 4 + 3 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 3], "loa", 3) == 0) { + if (host_line_len_without_port >= 7 + 7 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 7 - 7], "file-up", 7) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 7 - 7 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 7 - 7 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 4 + 3 + 1 + && (packet->host_line.ptr[host_line_len_without_port - 4 - 3 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 4 - 3 - 1] == '.')) { + goto end_ddl_found; + } + } + if (host_line_len_without_port >= 4 + 7 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 4 - 7], "uploade", 7) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 4 - 7 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 0 + 1 && packet->host_line.ptr[host_line_len_without_port - 0 - 1] == 'z') { + if (host_line_len_without_port >= 1 + 14 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 14], "leteckaposta.c", 14) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 1 - 14 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 1 - 14 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 1 + 12 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 12], "yourfiles.bi", 12) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 1 - 12 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 1 - 12 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 0 + 1 && packet->host_line.ptr[host_line_len_without_port - 0 - 1] == 'n') { + if (host_line_len_without_port >= 1 + 9 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 9], "netload.i", 9) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 1 - 9 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 1 - 9 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 1 + 2 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 1 - 2], ".v", 2) == 0) { + if (host_line_len_without_port >= 3 + 7 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 7], "4shared", 7) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 3 - 7 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 3 - 7 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 3 + 9 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 9], "megashare", 9) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 3 - 9 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 3 - 9 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 0 + 3 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 3], ".de", 3) == 0) { + if (host_line_len_without_port >= 3 + 5 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 5], "share", 5) == 0) { + if (host_line_len_without_port >= 8 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 5], "rapid", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == '.')) { + goto end_ddl_found; + } + if (host_line_len_without_port >= 8 + 5 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 8 - 5], "ultra", 5) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 8 - 5 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 3 + 15 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 3 - 15], "uploadyourfiles", 15) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 3 - 15 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 3 - 15 - 1] == '.')) { + goto end_ddl_found; + } + goto end_ddl_nothing_found; + } + if (host_line_len_without_port >= 0 + 14 + 1 + && memcmp((void *) &packet->host_line.ptr[host_line_len_without_port - 0 - 14], "speedshare.org", 14) == 0 + && (packet->host_line.ptr[host_line_len_without_port - 0 - 14 - 1] == ' ' + || packet->host_line.ptr[host_line_len_without_port - 0 - 14 - 1] == '.')) { + goto end_ddl_found; + } + // END OF AUTOMATED CODE GENERATION + + /* This is the hard way. We do this in order to find the download of services when other + domains are involved. This is not significant if ddl is blocked. --> then the link can not be started because + the ads are not viewed. But when ddl is only limited then the download is the important part. + */ + + end_ddl_nothing_found: + NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, + "Nothing Found\n"); + return 0; + + end_ddl_found: + NDPI_LOG(NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, ndpi_struct, NDPI_LOG_DEBUG, "DDL: DIRECT DOWNLOAD LINK FOUND\n"); + ndpi_int_direct_download_link_add_connection(ndpi_struct, flow); + return 1; +} + + +void ndpi_search_direct_download_link_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; +#if 0 + if (ndpi_struct->direct_download_link_counter_callback != NULL) { + if (packet->detected_protocol == NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK) { + /* skip packets not requests from the client to the server */ + if (packet->packet_direction == flow->l4.tcp.ddlink_server_direction) { + search_ddl_domains(ndpi_struct, flow); // do the detection again in order to get the URL in keep alive streams + } else { + // just count the packet + ndpi_struct->direct_download_link_counter_callback(flow->hash_id_number, packet->l3_packet_len); + } + } + return; + } +#endif + // do not detect again if it is already ddl + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK) { + if (search_ddl_domains(ndpi_struct, flow) != 0) { + return; + } + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK); + } + +} +#endif diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c new file mode 100644 index 000000000..071039340 --- /dev/null +++ b/src/lib/protocols/dns.c @@ -0,0 +1,300 @@ +/* + * dns.c + * + * Copyright (C) 2012-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_DNS + +static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) { + if(payload[i] == 0x00) + return(1); + else if(payload[i] == 0xC0) + return(2); + else { + u_int8_t len = payload[i]; + u_int8_t off = len + 1; + + if(off == 0) /* Bad packet */ + return(0); + else + return(off + getNameLength(i+off, payload, payloadLen)); + } +} + +/* *********************************************** */ + +static char* ndpi_intoa_v4(unsigned int addr, char* buf, u_short bufLen) { + char *cp, *retStr; + uint byte; + int n; + + cp = &buf[bufLen]; + *--cp = '\0'; + + n = 4; + do { + byte = addr & 0xff; + *--cp = byte % 10 + '0'; + byte /= 10; + if(byte > 0) { + *--cp = byte % 10 + '0'; + byte /= 10; + if(byte > 0) + *--cp = byte + '0'; + } + *--cp = '.'; + addr >>= 8; + } while (--n > 0); + + /* Convert the string to lowercase */ + retStr = (char*)(cp+1); + + return(retStr); +} + +/* *********************************************** */ + +static u_int16_t get16(int *i, const u_int8_t *payload) { + u_int16_t v = *(u_int16_t*)&payload[*i]; + + (*i) += 2; + + return(ntohs(v)); +} + +/* *********************************************** */ + +struct dns_packet_header { + u_int16_t transaction_id, flags, num_queries, answer_rrs, authority_rrs, additional_rrs; +} __attribute__((packed)); + +void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t dport = 0, sport = 0; + +#define NDPI_MAX_DNS_REQUESTS 16 + + NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "search DNS.\n"); + + if (packet->udp != NULL) { + sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); + NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over UDP.\n"); + } else if(packet->tcp != NULL) { + sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); + NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over tcp.\n"); + } + + if(((dport == 53) || (sport == 53) || (dport == 5355)) + && (packet->payload_packet_len > sizeof(struct dns_packet_header))) { + int i = packet->tcp ? 2 : 0; + struct dns_packet_header header, *dns = (struct dns_packet_header*)&packet->payload[i]; + u_int8_t is_query, ret_code, is_dns = 0; + u_int32_t a_record[NDPI_MAX_DNS_REQUESTS] = { 0 }, query_offset, num_a_records = 0; + + header.flags = ntohs(dns->flags); + header.transaction_id = ntohs(dns->transaction_id); + header.num_queries = ntohs(dns->num_queries); + header.answer_rrs = ntohs(dns->answer_rrs); + header.authority_rrs = ntohs(dns->authority_rrs); + header.additional_rrs = ntohs(dns->additional_rrs); + is_query = (header.flags & 0x8000) ? 0 : 1; + ret_code = is_query ? 0 : (header.flags & 0x0F); + i += sizeof(struct dns_packet_header); + query_offset = i; + + if(is_query) { + /* DNS Request */ + if((header.num_queries > 0) && (header.num_queries <= NDPI_MAX_DNS_REQUESTS) + && (((header.flags & 0x2800) == 0x2800 /* Dynamic DNS Update */) + || ((header.answer_rrs == 0) && (header.authority_rrs == 0)))) { + /* This is a good query */ + is_dns = 1; + + if(header.num_queries > 0) { + while(i < packet->payload_packet_len) { + if(packet->payload[i] == '\0') { + i++; + flow->protos.dns.query_type = get16(&i, packet->payload); + break; + } else + i++; + } + } + } + } else { + /* DNS Reply */ + + flow->server_id = flow->dst; + + if((header.num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */ + && (((header.answer_rrs > 0) && (header.answer_rrs <= NDPI_MAX_DNS_REQUESTS)) + || ((header.authority_rrs > 0) && (header.authority_rrs <= NDPI_MAX_DNS_REQUESTS)) + || ((header.additional_rrs > 0) && (header.additional_rrs <= NDPI_MAX_DNS_REQUESTS))) + ) { + /* This is a good reply */ + is_dns = 1; + + i++; + + if(packet->payload[i] != '\0') { + while((i < packet->payload_packet_len) + && (packet->payload[i] != '\0')) { + i++; + } + + i++; + } + + i += 4; + + if(header.answer_rrs > 0) { + u_int16_t rsp_type /*, rsp_class */; + u_int16_t num; + + for(num = 0; num < header.answer_rrs; num++) { + u_int16_t data_len; + + if((i+6) >= packet->payload_packet_len) { + break; + } + + if((data_len = getNameLength(i, packet->payload, packet->payload_packet_len)) == 0) { + break; + } else + i += data_len; + + rsp_type = get16(&i, packet->payload); + // rsp_class = get16(&i, packet->payload); + + i += 4; + data_len = get16(&i, packet->payload); + + if((data_len <= 1) || (data_len > (packet->payload_packet_len-i))) { + break; + } + + flow->protos.dns.rsp_type = rsp_type; + + if(rsp_type == 1 /* A */) { + if(data_len == 4) { + u_int32_t v = ntohl(*((u_int32_t*)&packet->payload[i])); + + if(num_a_records < (NDPI_MAX_DNS_REQUESTS-1)) + a_record[num_a_records++] = v; + else + break; /* One record is enough */ + } + } + + if(data_len == 0) { + break; + } + + i += data_len; + } /* for */ + } + } + + if((header.num_queries <= NDPI_MAX_DNS_REQUESTS) + && ((header.answer_rrs == 0) + || (header.authority_rrs == 0) + || (header.additional_rrs == 0)) + && (ret_code != 0 /* 0 == OK */) + ) { + /* This is a good reply */ + is_dns = 1; + } + } + + if(is_dns) { + int j = 0; + + flow->protos.dns.num_queries = (u_int8_t)header.num_queries, + flow->protos.dns.num_answers = (u_int8_t)(header.answer_rrs+header.authority_rrs+header.additional_rrs), + flow->protos.dns.ret_code = ret_code; + + i = query_offset+1; + + while((i < packet->payload_packet_len) + && (j < (sizeof(flow->host_server_name)-1)) + && (packet->payload[i] != '\0')) { + flow->host_server_name[j] = tolower(packet->payload[i]); + if(flow->host_server_name[j] < ' ') + flow->host_server_name[j] = '.'; + j++, i++; + } + + if(a_record != 0) { + char a_buf[32]; + int i; + + for(i=0; i<num_a_records; i++) { + j += snprintf((char*)&flow->host_server_name[j], sizeof(flow->host_server_name)-1-j, "%s%s", + (i == 0) ? "@" : ";", + ndpi_intoa_v4(a_record[i], a_buf, sizeof(a_buf))); + } + } + + flow->host_server_name[j] = '\0'; + + if(j > 0) { +#ifdef DEBUG + printf("==> %s\n", flow->host_server_name); +#endif + + if(ndpi_struct->match_dns_host_names) + ndpi_match_string_subprotocol(ndpi_struct, flow, + (char *)flow->host_server_name, + strlen((const char*)flow->host_server_name)); + } + + i++; + + memcpy(&flow->protos.dns.query_type, &packet->payload[i], 2); + flow->protos.dns.query_type = ntohs(flow->protos.dns.query_type), i += 2; + + memcpy(&flow->protos.dns.query_class, &packet->payload[i], 2); + flow->protos.dns.query_class = ntohs(flow->protos.dns.query_class), i += 2; + +#ifdef DEBUG + printf("%s [type=%04X][class=%04X]\n", flow->host_server_name, flow->protos.dns.query_type, flow->protos.dns.query_class); +#endif + + if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { + /* + Do not set the protocol with DNS if ndpi_match_string_subprotocol() has + matched a subprotocol + */ + NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n"); + ndpi_int_add_connection(ndpi_struct, flow, (dport == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_REAL_PROTOCOL); + } + } else { + flow->protos.dns.bad_packet = 1; + NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS); + } + } +} +#endif diff --git a/src/lib/protocols/dofus.c b/src/lib/protocols/dofus.c new file mode 100644 index 000000000..43d9c9f73 --- /dev/null +++ b/src/lib/protocols/dofus.c @@ -0,0 +1,149 @@ +/* + * dofus.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_DOFUS + +static void ndpi_dofus_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DOFUS, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_dofus(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + + /* Dofus v 1.x.x */ + if (packet->payload_packet_len == 13 && get_u_int16_t(packet->payload, 1) == ntohs(0x0508) + && get_u_int16_t(packet->payload, 5) == ntohs(0x04a0) + && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == ntohs(0x0194)) { + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n"); + ndpi_dofus_add_connection(ndpi_struct, flow); + return; + } + if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len == 3 && memcmp(packet->payload, "HG", 2) == 0 + && packet->payload[packet->payload_packet_len - 1] == 0) { + flow->l4.tcp.dofus_stage = 1; + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n"); + return; + } + if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len == 35 && memcmp(packet->payload, "HC", 2) == 0 + && packet->payload[packet->payload_packet_len - 1] == 0) { + flow->l4.tcp.dofus_stage = 1; + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n"); + return; + } + if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len > 2 && packet->payload[0] == 'A' + && (packet->payload[1] == 'x' || packet->payload[1] == 'X') + && packet->payload[packet->payload_packet_len - 1] == 0) { + flow->l4.tcp.dofus_stage = 1; + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n"); + return; + } + if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len == 12 && memcmp(packet->payload, "Af", 2) == 0 + && packet->payload[packet->payload_packet_len - 1] == 0) { + flow->l4.tcp.dofus_stage = 1; + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n"); + return; + } + if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len > 2 && memcmp(packet->payload, "Ad", 2) + && packet->payload[packet->payload_packet_len - 1] == 0) { + flow->l4.tcp.dofus_stage = 1; + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n"); + return; + } + if (packet->payload_packet_len == 11 && memcmp(packet->payload, "AT", 2) == 0 && packet->payload[10] == 0x00) { + if (flow->l4.tcp.dofus_stage == 1) { + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n"); + ndpi_dofus_add_connection(ndpi_struct, flow); + return; + } + } + if (flow->l4.tcp.dofus_stage == 1 && packet->payload_packet_len == 5 + && packet->payload[0] == 'A' && packet->payload[4] == 0x00 && (packet->payload[1] == 'T' + || packet->payload[1] == 'k')) { + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus asym.\n"); + ndpi_dofus_add_connection(ndpi_struct, flow); + return; + } + /* end Dofus 1.x.x */ + + + /* Dofus 2.0 */ + if ((packet->payload_packet_len == 11 || packet->payload_packet_len == 13 || packet->payload_packet_len == 49) + && get_u_int32_t(packet->payload, 0) == ntohl(0x00050800) + && get_u_int16_t(packet->payload, 4) == ntohs(0x0005) + && get_u_int16_t(packet->payload, 8) == ntohs(0x0005) + && packet->payload[10] == 0x18) { + if (packet->payload_packet_len == 13 + && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) != ntohs(0x0194)) { + goto exclude; + } + if (packet->payload_packet_len == 49 && ntohs(get_u_int16_t(packet->payload, 15)) + 17 != packet->payload_packet_len) { + goto exclude; + } + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n"); + ndpi_dofus_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len >= 41 && get_u_int16_t(packet->payload, 0) == ntohs(0x01b9) && packet->payload[2] == 0x26) { + u_int16_t len, len2; + len = ntohs(get_u_int16_t(packet->payload, 3)); + if ((len + 5 + 2) > packet->payload_packet_len) + goto exclude; + len2 = ntohs(get_u_int16_t(packet->payload, 5 + len)); + if (5 + len + 2 + len2 == packet->payload_packet_len) { + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n"); + ndpi_dofus_add_connection(ndpi_struct, flow); + return; + } + } + if (packet->payload_packet_len == 56 + && memcmp(packet->payload, "\x00\x11\x35\x02\x03\x00\x93\x96\x01\x00", 10) == 0) { + u_int16_t len, len2; + len = ntohs(get_u_int16_t(packet->payload, 10)); + if ((len + 12 + 2) > packet->payload_packet_len) + goto exclude; + len2 = ntohs(get_u_int16_t(packet->payload, 12 + len)); + if ((12 + len + 2 + len2 + 1) > packet->payload_packet_len) + goto exclude; + if (12 + len + 2 + len2 + 1 == packet->payload_packet_len && packet->payload[12 + len + 2 + len2] == 0x01) { + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n"); + ndpi_dofus_add_connection(ndpi_struct, flow); + return; + } + } + exclude: + NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "exclude dofus.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DOFUS); +} + +#endif diff --git a/src/lib/protocols/dropbox.c b/src/lib/protocols/dropbox.c new file mode 100644 index 000000000..e4ef2e0ce --- /dev/null +++ b/src/lib/protocols/dropbox.c @@ -0,0 +1,77 @@ +/* + * dropbox.c + * + * Copyright (C) 2011-13 by ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_DROPBOX +static void ndpi_int_dropbox_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int8_t due_to_correlation) +{ + ndpi_int_add_connection(ndpi_struct, flow, + NDPI_PROTOCOL_DROPBOX, + due_to_correlation ? NDPI_CORRELATED_PROTOCOL : NDPI_REAL_PROTOCOL); +} + + +static void ndpi_check_dropbox(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // const u_int8_t *packet_payload = packet->payload; + u_int32_t payload_len = packet->payload_packet_len; + + if(packet->udp != NULL) { + u_int16_t dropbox_port = htons(17500); + + if((packet->udp->source == dropbox_port) + && (packet->udp->dest == dropbox_port)) { + if(payload_len > 2) { + if(strncmp((const char *)packet->payload, "{\"", 2) == 0) { + NDPI_LOG(NDPI_PROTOCOL_DROPBOX, ndpi_struct, NDPI_LOG_DEBUG, "Found dropbox.\n"); + ndpi_int_dropbox_add_connection(ndpi_struct, flow, 0); + return; + } + } + } + } + + NDPI_LOG(NDPI_PROTOCOL_DROPBOX, ndpi_struct, NDPI_LOG_DEBUG, "exclude dropbox.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DROPBOX); +} + +void ndpi_search_dropbox(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_DROPBOX, ndpi_struct, NDPI_LOG_DEBUG, "dropbox detection...\n"); + + /* skip marked packets */ + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_DROPBOX) { + if (packet->tcp_retransmission == 0) { + ndpi_check_dropbox(ndpi_struct, flow); + } + } +} + +#endif diff --git a/src/lib/protocols/edonkey.c b/src/lib/protocols/edonkey.c new file mode 100644 index 000000000..d452c7348 --- /dev/null +++ b/src/lib/protocols/edonkey.c @@ -0,0 +1,211 @@ +/* + * edonkey.c + * + * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> + * + * The signature is based on the Libprotoident library. + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_EDONKEY +static void ndpi_int_edonkey_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_EDONKEY, NDPI_REAL_PROTOCOL); +} + +static int ndpi_edonkey_payload_check(const u_int8_t *data, u_int32_t len) { + + if ((len >= 4) && (data[0] == 0xe3) && (data[2] == 0x00) && (data[3] == 0x00)) + return 1; + + if ((len >= 4) && (data[0] == 0xc5) && (data[2] == 0x00) && (data[3] == 0x00)) + return 1; + + if ((len >= 2) && (data[0] == 0xe5) && (data[1] == 0x43)) + return 1; + + if ((len >= 4) && (data[0] == 0xe5) && (data[1] == 0x08) && (data[2] == 0x78) && (data[3] == 0xda)) + return 1; + + if ((len >= 4) && (data[0] == 0xe5) && (data[1] == 0x28) && (data[2] == 0x78) && (data[3] == 0xda)) + return 1; + + if ((len >= 2) && (data[0] == 0xc5) && (data[1] == 0x90)) + return 1; + + if ((len >= 2) && (data[0] == 0xc5) && (data[1] == 0x91)) + return 1; + + if ((len == 2) && (data[0] == 0xc5) && (data[1] == 0x92)) + return 1; + + if ((len == 2) && (data[0] == 0xc5) && (data[1] == 0x93)) + return 1; + + if ((len >= 38 && len <= 70) && (data[0] == 0xc5) && (data[1] == 0x94)) + return 1; + + if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x9a)) + return 1; + + if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x9b)) + return 1; + + if ((len == 6) && (data[0] == 0xe3) && (data[1] == 0x96)) + return 1; + + if ((len <= 34 && ((len - 2) % 4 == 0)) && (data[0] == 0xe3) && (data[1] == 0x97)) + return 1; + + if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x92)) + return 1; + + if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x94)) + return 1; + + if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x98)) + return 1; + + if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x99)) + return 1; + + if ((len == 6) && (data[0] == 0xe3) && (data[1] == 0xa2)) + return 1; + + if ((len >= 2) && (data[0] == 0xe3) && (data[1] == 0xa3)) + return 1; + + if ((len == 27) && (data[0] == 0xe4) && (data[1] == 0x00)) + return 1; + + if ((len == 529) && (data[0] == 0xe4) && (data[1] == 0x08)) + return 1; + + if ((len == 18) && (data[0] == 0xe4) && (data[1] == 0x01) && (data[2] == 0x00) && (data[3] == 0x00)) + return 1; + + if ((len == 523) && (data[0] == 0xe4) && (data[1] == 0x09)) + return 1; + + if ((len == 35) && (data[0] == 0xe4) && (data[1] == 0x21)) + return 1; + + if ((len == 19) && (data[0] == 0xe4) && (data[1] == 0x4b)) + return 1; + + if ((len >= 2) && (data[0] == 0xe4) && (data[1] == 0x11)) + return 1; + + if ((len == 22 || len == 38 || len == 28) && (data[0] == 0xe4) && (data[1] == 0x19)) + return 1; + + if ((len == 35) && (data[0] == 0xe4) && (data[1] == 0x20)) + return 1; + + if ((len == 27) && (data[0] == 0xe4) && (data[1] == 0x18)) + return 1; + + if ((len == 27) && (data[0] == 0xe4) && (data[1] == 0x10)) + return 1; + + if ((len == 6) && (data[0] == 0xe4) && (data[1] == 0x58)) + return 1; + + if ((len == 4) && (data[0] == 0xe4) && (data[1] == 0x50)) + return 1; + + if ((len == 36) && (data[0] == 0xe4) && (data[1] == 0x52)) + return 1; + + if ((len == 48) && (data[0] == 0xe4) && (data[1] == 0x40)) + return 1; + + if ((len == 225) && (data[0] == 0xe4) && (data[1] == 0x43)) + return 1; + + if ((len == 19) && (data[0] == 0xe4) && (data[1] == 0x48)) + return 1; + + if ((len == 119 || len == 69 || len == 294) && (data[0] == 0xe4) && (data[1] == 0x29)) + return 1; + + if ((len == 119 || len == 69 || len == 294 || len == 44 || len == 269) && (data[0] == 0xe4) && (data[1] == 0x28)) + return 1; + + return 0; +} + +static void ndpi_check_edonkey(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Break after 20 packets. */ + if (flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "Exclude EDONKEY.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_EDONKEY); + return; + } + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->edonkey_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "EDONKEY stage 0: \n"); + + if (ndpi_edonkey_payload_check(packet->payload, payload_len)) { + NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "Possible EDONKEY request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->edonkey_stage = packet->packet_direction + 1; + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "EDONKEY stage %u: \n", flow->edonkey_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->edonkey_stage - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len == 0) || (ndpi_edonkey_payload_check(packet->payload, payload_len))) { + NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "Found EDONKEY.\n"); + ndpi_int_edonkey_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to EDONKEY, resetting the stage to 0...\n"); + flow->edonkey_stage = 0; + } + + } +} + +void ndpi_search_edonkey(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "EDONKEY detection...\n"); + + /* skip marked packets */ + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_EDONKEY) { + if (packet->tcp_retransmission == 0) { + ndpi_check_edonkey(ndpi_struct, flow); + } + } +} + +#endif diff --git a/src/lib/protocols/fasttrack.c b/src/lib/protocols/fasttrack.c new file mode 100644 index 000000000..0e0ff1988 --- /dev/null +++ b/src/lib/protocols/fasttrack.c @@ -0,0 +1,82 @@ +/* + * fasttrack.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_FASTTRACK + + + +static void ndpi_int_fasttrack_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FASTTRACK, NDPI_CORRELATED_PROTOCOL); +} + + +void ndpi_search_fasttrack_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len > 6 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) { + NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "detected 0d0a at the end of the packet.\n"); + + if (memcmp(packet->payload, "GIVE ", 5) == 0 && packet->payload_packet_len >= 8) { + u_int16_t i; + for (i = 5; i < (packet->payload_packet_len - 2); i++) { + // make shure that the argument to GIVE is numeric + if (!(packet->payload[i] >= '0' && packet->payload[i] <= '9')) { + goto exclude_fasttrack; + } + } + + NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "FASTTRACK GIVE DETECTED\n"); + ndpi_int_fasttrack_add_connection(ndpi_struct, flow); + return; + } + + if (packet->payload_packet_len > 50 && memcmp(packet->payload, "GET /", 5) == 0) { + u_int8_t a = 0; + NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "detected GET /. \n"); + ndpi_parse_packet_line_info(ndpi_struct, flow); + for (a = 0; a < packet->parsed_lines; a++) { + if ((packet->line[a].len > 17 && memcmp(packet->line[a].ptr, "X-Kazaa-Username: ", 18) == 0) + || (packet->line[a].len > 23 && memcmp(packet->line[a].ptr, "User-Agent: PeerEnabler/", 24) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, + "detected X-Kazaa-Username: || User-Agent: PeerEnabler/\n"); + ndpi_int_fasttrack_add_connection(ndpi_struct, flow); + return; + } + } + } + } + + exclude_fasttrack: + NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "fasttrack/kazaa excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FASTTRACK); +} +#endif diff --git a/src/lib/protocols/fiesta.c b/src/lib/protocols/fiesta.c new file mode 100644 index 000000000..2b09ac9f7 --- /dev/null +++ b/src/lib/protocols/fiesta.c @@ -0,0 +1,97 @@ +/* + * fiesta.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +/* include files */ +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_FIESTA + + +static void ndpi_int_fiesta_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FIESTA, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_fiesta(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "search fiesta.\n"); + + if (flow->l4.tcp.fiesta_stage == 0 && packet->payload_packet_len == 5 + && get_u_int16_t(packet->payload, 0) == ntohs(0x0407) + && (packet->payload[2] == 0x08) + && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01)) { + + NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "maybe fiesta symmetric, first packet.\n"); + flow->l4.tcp.fiesta_stage = 1 + packet->packet_direction; + goto maybe_fiesta; + } + if (flow->l4.tcp.fiesta_stage == (2 - packet->packet_direction) + && ((packet->payload_packet_len > 1 && packet->payload_packet_len - 1 == packet->payload[0]) + || (packet->payload_packet_len > 3 && packet->payload[0] == 0 + && get_l16(packet->payload, 1) == packet->payload_packet_len - 3))) { + NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "Maybe fiesta.\n"); + goto maybe_fiesta; + } + if (flow->l4.tcp.fiesta_stage == (1 + packet->packet_direction)) { + if (packet->payload_packet_len == 4 && get_u_int32_t(packet->payload, 0) == htonl(0x03050c01)) { + goto add_fiesta; + } + if (packet->payload_packet_len == 5 && get_u_int32_t(packet->payload, 0) == htonl(0x04030c01) + && packet->payload[4] == 0) { + goto add_fiesta; + } + if (packet->payload_packet_len == 6 && get_u_int32_t(packet->payload, 0) == htonl(0x050e080b)) { + goto add_fiesta; + } + if (packet->payload_packet_len == 100 && packet->payload[0] == 0x63 && packet->payload[61] == 0x52 + && packet->payload[81] == 0x5a && get_u_int16_t(packet->payload, 1) == htons(0x3810) + && get_u_int16_t(packet->payload, 62) == htons(0x6f75)) { + goto add_fiesta; + } + if (packet->payload_packet_len > 3 && packet->payload_packet_len - 1 == packet->payload[0] + && get_u_int16_t(packet->payload, 1) == htons(0x140c)) { + goto add_fiesta; + } + } + + NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "exclude fiesta.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FIESTA); + return; + + maybe_fiesta: + NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "Stage is set to %d.\n", flow->l4.tcp.fiesta_stage); + return; + + add_fiesta: + NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "detected fiesta.\n"); + ndpi_int_fiesta_add_connection(ndpi_struct, flow); + return; +} +#endif diff --git a/src/lib/protocols/filetopia.c b/src/lib/protocols/filetopia.c new file mode 100644 index 000000000..d9ba1e820 --- /dev/null +++ b/src/lib/protocols/filetopia.c @@ -0,0 +1,83 @@ +/* + * filetopia.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_FILETOPIA + + +static void ndpi_int_filetopia_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FILETOPIA, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_filetopia_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (flow->l4.tcp.filetopia_stage == 0) { + if (packet->payload_packet_len >= 50 && packet->payload_packet_len <= 70 + && packet->payload[0] == 0x03 && packet->payload[1] == 0x9a + && packet->payload[3] == 0x22 && packet->payload[packet->payload_packet_len - 1] == 0x2b) { + NDPI_LOG(NDPI_PROTOCOL_FILETOPIA, ndpi_struct, NDPI_LOG_DEBUG, "Filetopia stage 1 detected\n"); + flow->l4.tcp.filetopia_stage = 1; + return; + } + + } else if (flow->l4.tcp.filetopia_stage == 1) { + if (packet->payload_packet_len >= 100 && packet->payload[0] == 0x03 + && packet->payload[1] == 0x9a && (packet->payload[3] == 0x22 || packet->payload[3] == 0x23)) { + + int i; + for (i = 0; i < 10; i++) { // check 10 bytes for valid ASCII printable characters + if (!(packet->payload[5 + i] >= 0x20 && packet->payload[5 + i] <= 0x7e)) { + goto end_filetopia_nothing_found; + } + } + + NDPI_LOG(NDPI_PROTOCOL_FILETOPIA, ndpi_struct, NDPI_LOG_DEBUG, "Filetopia stage 2 detected\n"); + flow->l4.tcp.filetopia_stage = 2; + return; + } + + + } else if (flow->l4.tcp.filetopia_stage == 2) { + if (packet->payload_packet_len >= 4 && packet->payload_packet_len <= 100 + && packet->payload[0] == 0x03 && packet->payload[1] == 0x9a + && (packet->payload[3] == 0x22 || packet->payload[3] == 0x23)) { + NDPI_LOG(NDPI_PROTOCOL_FILETOPIA, ndpi_struct, NDPI_LOG_DEBUG, "Filetopia detected\n"); + ndpi_int_filetopia_add_connection(ndpi_struct, flow); + return; + } + + } + + end_filetopia_nothing_found: + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FILETOPIA); +} + +#endif diff --git a/src/lib/protocols/florensia.c b/src/lib/protocols/florensia.c new file mode 100644 index 000000000..7f253cb6f --- /dev/null +++ b/src/lib/protocols/florensia.c @@ -0,0 +1,122 @@ +/* + * florensia.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_FLORENSIA + + +static void ndpi_florensia_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FLORENSIA, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_florensia(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "search florensia.\n"); + + if (packet->tcp != NULL) { + if (packet->payload_packet_len == 5 && get_l16(packet->payload, 0) == packet->payload_packet_len + && packet->payload[2] == 0x65 && packet->payload[4] == 0xff) { + if (flow->florensia_stage == 1) { + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "found florensia.\n"); + ndpi_florensia_add_connection(ndpi_struct, flow); + return; + } + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia -> stage is set to 1.\n"); + flow->florensia_stage = 1; + return; + } + if (packet->payload_packet_len > 8 && get_l16(packet->payload, 0) == packet->payload_packet_len + && get_u_int16_t(packet->payload, 2) == htons(0x0201) && get_u_int32_t(packet->payload, 4) == htonl(0xFFFFFFFF)) { + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia -> stage is set to 1.\n"); + flow->florensia_stage = 1; + return; + } + if (packet->payload_packet_len == 406 && get_l16(packet->payload, 0) == packet->payload_packet_len + && packet->payload[2] == 0x63) { + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia -> stage is set to 1.\n"); + flow->florensia_stage = 1; + return; + } + if (packet->payload_packet_len == 12 && get_l16(packet->payload, 0) == packet->payload_packet_len + && get_u_int16_t(packet->payload, 2) == htons(0x0301)) { + if (flow->florensia_stage == 1) { + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "found florensia.\n"); + ndpi_florensia_add_connection(ndpi_struct, flow); + return; + } + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia -> stage is set to 1.\n"); + flow->florensia_stage = 1; + return; + } + + if (flow->florensia_stage == 1) { + if (packet->payload_packet_len == 8 && get_l16(packet->payload, 0) == packet->payload_packet_len + && get_u_int16_t(packet->payload, 2) == htons(0x0302) && get_u_int32_t(packet->payload, 4) == htonl(0xFFFFFFFF)) { + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "found florensia asymmetrically.\n"); + ndpi_florensia_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len == 24 && get_l16(packet->payload, 0) == packet->payload_packet_len + && get_u_int16_t(packet->payload, 2) == htons(0x0202) + && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) == htonl(0xFFFFFFFF)) { + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "found florensia.\n"); + ndpi_florensia_add_connection(ndpi_struct, flow); + return; + } + if (flow->packet_counter < 10 && get_l16(packet->payload, 0) == packet->payload_packet_len) { + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia.\n"); + return; + } + } + } + + if (packet->udp != NULL) { + if (flow->florensia_stage == 0 && packet->payload_packet_len == 6 + && get_u_int16_t(packet->payload, 0) == ntohs(0x0503) && get_u_int32_t(packet->payload, 2) == htonl(0xFFFF0000)) { + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "maybe florensia -> stage is set to 1.\n"); + flow->florensia_stage = 1; + return; + } + if (flow->florensia_stage == 1 && packet->payload_packet_len == 8 + && get_u_int16_t(packet->payload, 0) == ntohs(0x0500) && get_u_int16_t(packet->payload, 4) == htons(0x4191)) { + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "found florensia.\n"); + ndpi_florensia_add_connection(ndpi_struct, flow); + return; + } + } + + NDPI_LOG(NDPI_PROTOCOL_FLORENSIA, ndpi_struct, NDPI_LOG_DEBUG, "exclude florensia.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FLORENSIA); +} + +#endif diff --git a/src/lib/protocols/ftp_control.c b/src/lib/protocols/ftp_control.c new file mode 100644 index 000000000..a757902dc --- /dev/null +++ b/src/lib/protocols/ftp_control.c @@ -0,0 +1,999 @@ +/* + * ftp_control.c + * + * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_FTP_CONTROL + +static void ndpi_int_ftp_control_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FTP_CONTROL, NDPI_REAL_PROTOCOL); +} + +static int ndpi_ftp_control_check_request(const u_int8_t *payload) { + + if (match_first_bytes(payload, "ABOR")) { + return 1; + } + + if (match_first_bytes(payload, "ACCT")) { + return 1; + } + + if (match_first_bytes(payload, "ADAT")) { + return 1; + } + + if (match_first_bytes(payload, "ALLO")) { + return 1; + } + + if (match_first_bytes(payload, "APPE")) { + return 1; + } + + if (match_first_bytes(payload, "AUTH")) { + return 1; + } + if (match_first_bytes(payload, "CCC")) { + return 1; + } + + if (match_first_bytes(payload, "CDUP")) { + return 1; + } + + if (match_first_bytes(payload, "CONF")) { + return 1; + } + + if (match_first_bytes(payload, "CWD")) { + return 1; + } + + if (match_first_bytes(payload, "DELE")) { + return 1; + } + + if (match_first_bytes(payload, "ENC")) { + return 1; + } + + if (match_first_bytes(payload, "EPRT")) { + return 1; + } + + if (match_first_bytes(payload, "EPSV")) { + return 1; + } + + if (match_first_bytes(payload, "FEAT")) { + return 1; + } + + if (match_first_bytes(payload, "HELP")) { + return 1; + } + + if (match_first_bytes(payload, "LANG")) { + return 1; + } + + if (match_first_bytes(payload, "LIST")) { + return 1; + } + + if (match_first_bytes(payload, "LPRT")) { + return 1; + } + + if (match_first_bytes(payload, "LPSV")) { + return 1; + } + + if (match_first_bytes(payload, "MDTM")) { + return 1; + } + + if (match_first_bytes(payload, "MIC")) { + return 1; + } + + if (match_first_bytes(payload, "MKD")) { + return 1; + } + + if (match_first_bytes(payload, "MLSD")) { + return 1; + } + + if (match_first_bytes(payload, "MLST")) { + return 1; + } + + if (match_first_bytes(payload, "MODE")) { + return 1; + } + + if (match_first_bytes(payload, "NLST")) { + return 1; + } + + if (match_first_bytes(payload, "NOOP")) { + return 1; + } + + if (match_first_bytes(payload, "OPTS")) { + return 1; + } + + if (match_first_bytes(payload, "PASS")) { + return 1; + } + + if (match_first_bytes(payload, "PASV")) { + return 1; + } + + if (match_first_bytes(payload, "PBSZ")) { + return 1; + } + + if (match_first_bytes(payload, "PORT")) { + return 1; + } + + if (match_first_bytes(payload, "PROT")) { + return 1; + } + + if (match_first_bytes(payload, "PWD")) { + return 1; + } + + if (match_first_bytes(payload, "QUIT")) { + return 1; + } + + if (match_first_bytes(payload, "REIN")) { + return 1; + } + + if (match_first_bytes(payload, "REST")) { + return 1; + } + + if (match_first_bytes(payload, "RETR")) { + return 1; + } + + if (match_first_bytes(payload, "RMD")) { + return 1; + } + + if (match_first_bytes(payload, "RNFR")) { + return 1; + } + + if (match_first_bytes(payload, "RNTO")) { + return 1; + } + + if (match_first_bytes(payload, "SITE")) { + return 1; + } + + if (match_first_bytes(payload, "SIZE")) { + return 1; + } + + if (match_first_bytes(payload, "SMNT")) { + return 1; + } + + if (match_first_bytes(payload, "STAT")) { + return 1; + } + + if (match_first_bytes(payload, "STOR")) { + return 1; + } + + if (match_first_bytes(payload, "STOU")) { + return 1; + } + + if (match_first_bytes(payload, "STRU")) { + return 1; + } + + if (match_first_bytes(payload, "SYST")) { + return 1; + } + + if (match_first_bytes(payload, "TYPE")) { + return 1; + } + + if (match_first_bytes(payload, "USER")) { + return 1; + } + + if (match_first_bytes(payload, "XCUP")) { + return 1; + } + + if (match_first_bytes(payload, "XMKD")) { + return 1; + } + + if (match_first_bytes(payload, "XPWD")) { + return 1; + } + + if (match_first_bytes(payload, "XRCP")) { + return 1; + } + + if (match_first_bytes(payload, "XRMD")) { + return 1; + } + + if (match_first_bytes(payload, "XRSQ")) { + return 1; + } + + if (match_first_bytes(payload, "XSEM")) { + return 1; + } + + if (match_first_bytes(payload, "XSEN")) { + return 1; + } + + if (match_first_bytes(payload, "HOST")) { + return 1; + } + + if (match_first_bytes(payload, "abor")) { + return 1; + } + + if (match_first_bytes(payload, "acct")) { + return 1; + } + + if (match_first_bytes(payload, "adat")) { + return 1; + } + + if (match_first_bytes(payload, "allo")) { + return 1; + } + + if (match_first_bytes(payload, "appe")) { + return 1; + } + + if (match_first_bytes(payload, "auth")) { + return 1; + } + + if (match_first_bytes(payload, "ccc")) { + return 1; + } + + if (match_first_bytes(payload, "cdup")) { + return 1; + } + + if (match_first_bytes(payload, "conf")) { + return 1; + } + + if (match_first_bytes(payload, "cwd")) { + return 1; + } + + if (match_first_bytes(payload, "dele")) { + return 1; + } + + if (match_first_bytes(payload, "enc")) { + return 1; + } + + if (match_first_bytes(payload, "eprt")) { + return 1; + } + + if (match_first_bytes(payload, "epsv")) { + return 1; + } + + if (match_first_bytes(payload, "feat")) { + return 1; + } + + if (match_first_bytes(payload, "help")) { + return 1; + } + + if (match_first_bytes(payload, "lang")) { + return 1; + } + + if (match_first_bytes(payload, "list")) { + return 1; + } + + if (match_first_bytes(payload, "lprt")) { + return 1; + } + + if (match_first_bytes(payload, "lpsv")) { + return 1; + } + + if (match_first_bytes(payload, "mdtm")) { + return 1; + } + + if (match_first_bytes(payload, "mic")) { + return 1; + } + + if (match_first_bytes(payload, "mkd")) { + return 1; + } + + if (match_first_bytes(payload, "mlsd")) { + return 1; + } + + if (match_first_bytes(payload, "mlst")) { + return 1; + } + + if (match_first_bytes(payload, "mode")) { + return 1; + } + + if (match_first_bytes(payload, "nlst")) { + return 1; + } + + if (match_first_bytes(payload, "noop")) { + return 1; + } + + if (match_first_bytes(payload, "opts")) { + return 1; + } + + if (match_first_bytes(payload, "pass")) { + return 1; + } + + if (match_first_bytes(payload, "pasv")) { + return 1; + } + + if (match_first_bytes(payload, "pbsz")) { + return 1; + } + + if (match_first_bytes(payload, "port")) { + return 1; + } + + if (match_first_bytes(payload, "prot")) { + return 1; + } + + if (match_first_bytes(payload, "pwd")) { + return 1; + } + + if (match_first_bytes(payload, "quit")) { + return 1; + } + + if (match_first_bytes(payload, "rein")) { + return 1; + } + + if (match_first_bytes(payload, "rest")) { + return 1; + } + + if (match_first_bytes(payload, "retr")) { + return 1; + } + + if (match_first_bytes(payload, "rmd")) { + return 1; + } + + if (match_first_bytes(payload, "rnfr")) { + return 1; + } + + if (match_first_bytes(payload, "rnto")) { + return 1; + } + + if (match_first_bytes(payload, "site")) { + return 1; + } + + if (match_first_bytes(payload, "size")) { + return 1; + } + + if (match_first_bytes(payload, "smnt")) { + return 1; + } + + if (match_first_bytes(payload, "stat")) { + return 1; + } + + if (match_first_bytes(payload, "stor")) { + return 1; + } + + if (match_first_bytes(payload, "stou")) { + return 1; + } + + if (match_first_bytes(payload, "stru")) { + return 1; + } + + if (match_first_bytes(payload, "syst")) { + return 1; + } + + if (match_first_bytes(payload, "type")) { + return 1; + } + + if (match_first_bytes(payload, "user")) { + return 1; + } + + if (match_first_bytes(payload, "xcup")) { + return 1; + } + + if (match_first_bytes(payload, "xmkd")) { + return 1; + } + + if (match_first_bytes(payload, "xpwd")) { + return 1; + } + + if (match_first_bytes(payload, "xrcp")) { + return 1; + } + + if (match_first_bytes(payload, "xrmd")) { + return 1; + } + + if (match_first_bytes(payload, "xrsq")) { + return 1; + } + + if (match_first_bytes(payload, "xsem")) { + return 1; + } + + if (match_first_bytes(payload, "xsen")) { + return 1; + } + + if (match_first_bytes(payload, "host")) { + return 1; + } + + return 0; +} + +static int ndpi_ftp_control_check_response(const u_int8_t *payload) { + + if (match_first_bytes(payload, "110-")) { + return 1; + } + + if (match_first_bytes(payload, "120-")) { + return 1; + } + + if (match_first_bytes(payload, "125-")) { + return 1; + } + + if (match_first_bytes(payload, "150-")) { + return 1; + } + + if (match_first_bytes(payload, "202-")) { + return 1; + } + + if (match_first_bytes(payload, "211-")) { + return 1; + } + + if (match_first_bytes(payload, "212-")) { + return 1; + } + + if (match_first_bytes(payload, "213-")) { + return 1; + } + + if (match_first_bytes(payload, "214-")) { + return 1; + } + + if (match_first_bytes(payload, "215-")) { + return 1; + } + + if (match_first_bytes(payload, "220-")) { + return 1; + } + + if (match_first_bytes(payload, "221-")) { + return 1; + } + + if (match_first_bytes(payload, "225-")) { + return 1; + } + + if (match_first_bytes(payload, "226-")) { + return 1; + } + + if (match_first_bytes(payload, "227-")) { + return 1; + } + + if (match_first_bytes(payload, "228-")) { + return 1; + } + + if (match_first_bytes(payload, "229-")) { + return 1; + } + + if (match_first_bytes(payload, "230-")) { + return 1; + } + + if (match_first_bytes(payload, "231-")) { + return 1; + } + + if (match_first_bytes(payload, "232-")) { + return 1; + } + + if (match_first_bytes(payload, "250-")) { + return 1; + } + + if (match_first_bytes(payload, "257-")) { + return 1; + } + + if (match_first_bytes(payload, "331-")) { + return 1; + } + + if (match_first_bytes(payload, "332-")) { + return 1; + } + + if (match_first_bytes(payload, "350-")) { + return 1; + } + + if (match_first_bytes(payload, "421-")) { + return 1; + } + + if (match_first_bytes(payload, "425-")) { + return 1; + } + + if (match_first_bytes(payload, "426-")) { + return 1; + } + + if (match_first_bytes(payload, "430-")) { + return 1; + } + + if (match_first_bytes(payload, "434-")) { + return 1; + } + + if (match_first_bytes(payload, "450-")) { + return 1; + } + + if (match_first_bytes(payload, "451-")) { + return 1; + } + + if (match_first_bytes(payload, "452-")) { + return 1; + } + + if (match_first_bytes(payload, "501-")) { + return 1; + } + + if (match_first_bytes(payload, "502-")) { + return 1; + } + + if (match_first_bytes(payload, "503-")) { + return 1; + } + + if (match_first_bytes(payload, "504-")) { + return 1; + } + + if (match_first_bytes(payload, "530-")) { + return 1; + } + + if (match_first_bytes(payload, "532-")) { + return 1; + } + + if (match_first_bytes(payload, "550-")) { + return 1; + } + + if (match_first_bytes(payload, "551-")) { + return 1; + } + + if (match_first_bytes(payload, "552-")) { + return 1; + } + + if (match_first_bytes(payload, "553-")) { + return 1; + } + + if (match_first_bytes(payload, "631-")) { + return 1; + } + + if (match_first_bytes(payload, "632-")) { + return 1; + } + + if (match_first_bytes(payload, "633-")) { + return 1; + } + + if (match_first_bytes(payload, "10054-")) { + return 1; + } + + if (match_first_bytes(payload, "10060-")) { + return 1; + } + + if (match_first_bytes(payload, "10061-")) { + return 1; + } + + if (match_first_bytes(payload, "10066-")) { + return 1; + } + + if (match_first_bytes(payload, "10068-")) { + return 1; + } + + if (match_first_bytes(payload, "110 ")) { + return 1; + } + + if (match_first_bytes(payload, "120 ")) { + return 1; + } + + if (match_first_bytes(payload, "125 ")) { + return 1; + } + + if (match_first_bytes(payload, "150 ")) { + return 1; + } + + if (match_first_bytes(payload, "202 ")) { + return 1; + } + + if (match_first_bytes(payload, "211 ")) { + return 1; + } + + if (match_first_bytes(payload, "212 ")) { + return 1; + } + + if (match_first_bytes(payload, "213 ")) { + return 1; + } + + if (match_first_bytes(payload, "214 ")) { + return 1; + } + + if (match_first_bytes(payload, "215 ")) { + return 1; + } + + if (match_first_bytes(payload, "220 ")) { + return 1; + } + + if (match_first_bytes(payload, "221 ")) { + return 1; + } + + if (match_first_bytes(payload, "225 ")) { + return 1; + } + + if (match_first_bytes(payload, "226 ")) { + return 1; + } + + if (match_first_bytes(payload, "227 ")) { + return 1; + } + + if (match_first_bytes(payload, "228 ")) { + return 1; + } + + if (match_first_bytes(payload, "229 ")) { + return 1; + } + + if (match_first_bytes(payload, "230 ")) { + return 1; + } + + if (match_first_bytes(payload, "231 ")) { + return 1; + } + + if (match_first_bytes(payload, "232 ")) { + return 1; + } + + if (match_first_bytes(payload, "250 ")) { + return 1; + } + + if (match_first_bytes(payload, "257 ")) { + return 1; + } + + if (match_first_bytes(payload, "331 ")) { + return 1; + } + + if (match_first_bytes(payload, "332 ")) { + return 1; + } + + if (match_first_bytes(payload, "350 ")) { + return 1; + } + + if (match_first_bytes(payload, "421 ")) { + return 1; + } + + if (match_first_bytes(payload, "425 ")) { + return 1; + } + + if (match_first_bytes(payload, "426 ")) { + return 1; + } + + if (match_first_bytes(payload, "430 ")) { + return 1; + } + + if (match_first_bytes(payload, "434 ")) { + return 1; + } + + if (match_first_bytes(payload, "450 ")) { + return 1; + } + + if (match_first_bytes(payload, "451 ")) { + return 1; + } + + if (match_first_bytes(payload, "452 ")) { + return 1; + } + + if (match_first_bytes(payload, "501 ")) { + return 1; + } + + if (match_first_bytes(payload, "502 ")) { + return 1; + } + + if (match_first_bytes(payload, "503 ")) { + return 1; + } + + if (match_first_bytes(payload, "504 ")) { + return 1; + } + + if (match_first_bytes(payload, "530 ")) { + return 1; + } + + if (match_first_bytes(payload, "532 ")) { + return 1; + } + if (match_first_bytes(payload, "550 ")) { + return 1; + } + + if (match_first_bytes(payload, "551 ")) { + return 1; + } + + if (match_first_bytes(payload, "552 ")) { + return 1; + } + + if (match_first_bytes(payload, "553 ")) { + return 1; + } + + if (match_first_bytes(payload, "631 ")) { + return 1; + } + + if (match_first_bytes(payload, "632 ")) { + return 1; + } + + if (match_first_bytes(payload, "633 ")) { + return 1; + } + + if (match_first_bytes(payload, "10054 ")) { + return 1; + } + + if (match_first_bytes(payload, "10060 ")) { + return 1; + } + + if (match_first_bytes(payload, "10061 ")) { + return 1; + } + + if (match_first_bytes(payload, "10066 ")) { + return 1; + } + + if (match_first_bytes(payload, "10068 ")) { + return 1; + } + + return 0; +} + +static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Exclude SMTP, which uses similar commands. */ + if (packet->tcp->dest == htons(25) || packet->tcp->source == htons(25)) { + NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Exclude FTP_CONTROL.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FTP_CONTROL); + return; + } + + /* Break after 20 packets. */ + if (flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Exclude FTP_CONTROL.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FTP_CONTROL); + return; + } + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->ftp_control_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "FTP_CONTROL stage 0: \n"); + + if ((payload_len > 0) && ndpi_ftp_control_check_request(packet->payload)) { + NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Possible FTP_CONTROL request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->ftp_control_stage = packet->packet_direction + 1; + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "FTP_CONTROL stage %u: \n", flow->ftp_control_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->ftp_control_stage - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len > 0) && ndpi_ftp_control_check_response(packet->payload)) { + NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Found FTP_CONTROL.\n"); + ndpi_int_ftp_control_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to FTP_CONTROL, resetting the stage to 0...\n"); + flow->ftp_control_stage = 0; + } + + } +} + +void ndpi_search_ftp_control(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "FTP_CONTROL detection...\n"); + + /* skip marked packets */ + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_FTP_CONTROL) { + if (packet->tcp_retransmission == 0) { + ndpi_check_ftp_control(ndpi_struct, flow); + } + } +} + +#endif diff --git a/src/lib/protocols/ftp_data.c b/src/lib/protocols/ftp_data.c new file mode 100644 index 000000000..2bb77e1ec --- /dev/null +++ b/src/lib/protocols/ftp_data.c @@ -0,0 +1,275 @@ +/* + * ftp_data.c + * + * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> + * Copyright (C) 2014 - ntop.org + * + * The signature is based on the Libprotoident library. + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_FTP_DATA +static void ndpi_int_ftp_data_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FTP_DATA, NDPI_REAL_PROTOCOL); +} + +static int ndpi_match_ftp_data_port(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + if(packet->tcp->dest == htons(20) || packet->tcp->source == htons(20)) { + return 1; + } + + return 0; + +} + +static int ndpi_match_ftp_data_directory(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + if((payload_len >= 4) + && ((packet->payload[0] == '-') || (packet->payload[0] == 'd')) + && ((packet->payload[1] == '-') || (packet->payload[1] == 'r')) + && ((packet->payload[2] == '-') || (packet->payload[2] == 'w')) + && ((packet->payload[3] == '-') || (packet->payload[3] == 'x'))) { + + return 1; + } + + return 0; + +} + +static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + /* A FTP packet is pretty long so 256 is a bit consrvative but it should be OK */ + if(packet->payload_packet_len < 256) + return 0; + + /* RIFF is a meta-format for storing AVI and WAV files */ + if(match_first_bytes(packet->payload, "RIFF")) + return 1; + + /* MZ is a .exe file */ + if((packet->payload[0] == 'M') && (packet->payload[1] == 'Z') && (packet->payload[3] == 0x00)) + return 1; + + /* Ogg files */ + if(match_first_bytes(packet->payload, "OggS")) + return 1; + + /* ZIP files */ + if((packet->payload[0] == 'P') && (packet->payload[1] == 'K') && (packet->payload[2] == 0x03) && (packet->payload[3] == 0x04)) + return 1; + + /* MPEG files */ + if((packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x01) && (packet->payload[3] == 0xba)) + return 1; + + /* RAR files */ + if(match_first_bytes(packet->payload, "Rar!")) + return 1; + + /* EBML */ + if((packet->payload[0] == 0x1a) && (packet->payload[1] == 0x45) && (packet->payload[2] == 0xdf) && (packet->payload[3] == 0xa3)) + return 1; + + /* JPG */ + if((packet->payload[0] == 0xff) && (packet->payload[1] ==0xd8)) + return 1; + + /* GIF */ + if(match_first_bytes(packet->payload, "GIF8")) + return 1; + + /* PHP scripts */ + if((packet->payload[0] == 0x3c) && (packet->payload[1] == 0x3f) && (packet->payload[2] == 0x70) && (packet->payload[3] == 0x68)) + return 1; + + /* Unix scripts */ + if((packet->payload[0] == 0x23) && (packet->payload[1] == 0x21) && (packet->payload[2] == 0x2f) && (packet->payload[3] == 0x62)) + return 1; + + /* PDFs */ + if(match_first_bytes(packet->payload, "%PDF")) + return 1; + + /* PNG */ + if((packet->payload[0] == 0x89) && (packet->payload[1] == 'P') && (packet->payload[2] == 'N') && (packet->payload[3] == 'G')) + return 1; + + /* HTML */ + if(match_first_bytes(packet->payload, "<htm")) + return 1; + if((packet->payload[0] == 0x0a) && (packet->payload[1] == '<') && (packet->payload[2] == '!') && (packet->payload[3] == 'D')) + return 1; + + /* 7zip */ + if((packet->payload[0] == 0x37) && (packet->payload[1] == 0x7a) && (packet->payload[2] == 0xbc) && (packet->payload[3] == 0xaf)) + return 1; + + /* gzip */ + if((packet->payload[0] == 0x1f) && (packet->payload[1] == 0x8b) && (packet->payload[2] == 0x08)) + return 1; + + /* XML */ + if(match_first_bytes(packet->payload, "<!DO")) + return 1; + + /* FLAC */ + if(match_first_bytes(packet->payload, "fLaC")) + return 1; + + /* MP3 */ + if((packet->payload[0] == 'I') && (packet->payload[1] == 'D') && (packet->payload[2] == '3') && (packet->payload[3] == 0x03)) + return 1; + if(match_first_bytes(packet->payload, "\xff\xfb\x90\xc0")) + return 1; + + /* RPM */ + if((packet->payload[0] == 0xed) && (packet->payload[1] == 0xab) && (packet->payload[2] == 0xee) && (packet->payload[3] == 0xdb)) + return 1; + + /* Wz Patch */ + if(match_first_bytes(packet->payload, "WzPa")) + return 1; + + /* Flash Video */ + if((packet->payload[0] == 'F') && (packet->payload[1] == 'L') && (packet->payload[2] == 'V') && (packet->payload[3] == 0x01)) + return 1; + + /* .BKF (Microsoft Tape Format) */ + if(match_first_bytes(packet->payload, "TAPE")) + return 1; + + /* MS Office Doc file - this is unpleasantly geeky */ + if((packet->payload[0] == 0xd0) && (packet->payload[1] == 0xcf) && (packet->payload[2] == 0x11) && (packet->payload[3] == 0xe0)) + return 1; + + /* ASP */ + if((packet->payload[0] == 0x3c) && (packet->payload[1] == 0x25) && (packet->payload[2] == 0x40) && (packet->payload[3] == 0x20)) + return 1; + + /* WMS file */ + if((packet->payload[0] == 0x3c) && (packet->payload[1] == 0x21) && (packet->payload[2] == 0x2d) && (packet->payload[3] == 0x2d)) + return 1; + + /* ar archive, typically .deb files */ + if(match_first_bytes(packet->payload, "!<ar")) + return 1; + + /* Raw XML (skip jabber-like traffic as this is not FTP but unencrypted jabber) */ + if((match_first_bytes(packet->payload, "<?xm")) + && (ndpi_strnstr((const char *)packet->payload, "jabber", packet->payload_packet_len) == NULL)) + return 1; + + if(match_first_bytes(packet->payload, "<iq ")) + return 1; + + /* SPF */ + if(match_first_bytes(packet->payload, "SPFI")) + return 1; + + /* ABIF - Applied Biosystems */ + if(match_first_bytes(packet->payload, "ABIF")) + return 1; + + /* bzip2 - other digits are also possible instead of 9 */ + if((packet->payload[0] == 'B') && (packet->payload[1] == 'Z') && (packet->payload[2] == 'h') && (packet->payload[3] == '9')) + return 1; + + /* Some other types of files */ + + if((packet->payload[0] == '<') && (packet->payload[1] == 'c') && (packet->payload[2] == 'f')) + return 1; + if((packet->payload[0] == '<') && (packet->payload[1] == 'C') && (packet->payload[2] == 'F')) + return 1; + if(match_first_bytes(packet->payload, ".tem")) + return 1; + if(match_first_bytes(packet->payload, ".ite")) + return 1; + if(match_first_bytes(packet->payload, ".lef")) + return 1; + + return 0; +} + +static void ndpi_check_ftp_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Check if we so far detected the protocol in the request or not. */ + if(flow->ftp_data_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "FTP_DATA stage 0: \n"); + + if((payload_len > 0) && (ndpi_match_file_header(ndpi_struct, flow) || ndpi_match_ftp_data_directory(ndpi_struct, flow) || ndpi_match_ftp_data_port(ndpi_struct, flow))) { + NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "Possible FTP_DATA request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->ftp_data_stage = packet->packet_direction + 1; + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "FTP_DATA stage %u: \n", flow->ftp_data_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if((flow->ftp_data_stage - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if(payload_len == 0) { + NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "Found FTP_DATA.\n"); + ndpi_int_ftp_data_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to FTP_DATA, resetting the stage to 0...\n"); + flow->ftp_data_stage = 0; + } + + } +} + +void ndpi_search_ftp_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + /* Break after 20 packets. */ + if(flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "Exclude FTP_DATA.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FTP_DATA); + return; + } + + /* skip marked or retransmitted packets */ + if(packet->tcp_retransmission != 0) { + return; + } + + if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_FTP_DATA) { + return; + } + + NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "FTP_DATA detection...\n"); + ndpi_check_ftp_data(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/gnutella.c b/src/lib/protocols/gnutella.c new file mode 100644 index 000000000..022df6e3d --- /dev/null +++ b/src/lib/protocols/gnutella.c @@ -0,0 +1,375 @@ +/* + * gnutella.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +/* include files */ + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_GNUTELLA + +static void ndpi_int_gnutella_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + ndpi_protocol_type_t protocol_type) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_GNUTELLA, protocol_type); + + if (src != NULL) { + src->gnutella_ts = packet->tick_timestamp; + if (packet->udp != NULL) { + if (!src->detected_gnutella_udp_port1) { + src->detected_gnutella_udp_port1 = (packet->udp->source); + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, + NDPI_LOG_DEBUG, "GNUTELLA UDP PORT1 DETECTED as %u\n", + src->detected_gnutella_udp_port1); + + } else if ((ntohs(packet->udp->source) != src->detected_gnutella_udp_port1) + && !src->detected_gnutella_udp_port2) { + src->detected_gnutella_udp_port2 = (packet->udp->source); + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, + NDPI_LOG_DEBUG, "GNUTELLA UDP PORT2 DETECTED as %u\n", + src->detected_gnutella_udp_port2); + + } + } + } + if (dst != NULL) { + dst->gnutella_ts = packet->tick_timestamp; + } +} + +void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + u_int16_t c; + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_GNUTELLA) { + if (src != NULL && ((u_int32_t) + (packet->tick_timestamp - src->gnutella_ts) < ndpi_struct->gnutella_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, + NDPI_LOG_DEBUG, "gnutella : save src connection packet detected\n"); + src->gnutella_ts = packet->tick_timestamp; + } else if (dst != NULL && ((u_int32_t) + (packet->tick_timestamp - dst->gnutella_ts) < ndpi_struct->gnutella_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, + NDPI_LOG_DEBUG, "gnutella : save dst connection packet detected\n"); + dst->gnutella_ts = packet->tick_timestamp; + } + if (src != NULL && (packet->tick_timestamp - src->gnutella_ts) > ndpi_struct->gnutella_timeout) { + src->detected_gnutella_udp_port1 = 0; + src->detected_gnutella_udp_port2 = 0; + } + if (dst != NULL && (packet->tick_timestamp - dst->gnutella_ts) > ndpi_struct->gnutella_timeout) { + dst->detected_gnutella_udp_port1 = 0; + dst->detected_gnutella_udp_port2 = 0; + } + + return; + } + + /* skip packets without payload */ + if (packet->payload_packet_len < 2) { + return; + } + if (packet->tcp != NULL) { + /* this case works asymmetrically */ + if (packet->payload_packet_len > 10 && memcmp(packet->payload, "GNUTELLA/", 9) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "GNUTELLA DETECTED\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + /* this case works asymmetrically */ + if (packet->payload_packet_len > 17 && memcmp(packet->payload, "GNUTELLA CONNECT/", 17) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "GNUTELLA DETECTED\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0) + || (memcmp(packet->payload, "GET /uri-res/", 13) == 0) + )) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + for (c = 0; c < packet->parsed_lines; c++) { + if ((packet->line[c].len > 19 && memcmp(packet->line[c].ptr, "User-Agent: Gnutella", 20) == 0) + || (packet->line[c].len > 10 && memcmp(packet->line[c].ptr, "X-Gnutella-", 11) == 0) + || (packet->line[c].len > 7 && memcmp(packet->line[c].ptr, "X-Queue:", 8) == 0) + || (packet->line[c].len > 36 && memcmp(packet->line[c].ptr, + "Content-Type: application/x-gnutella-", 37) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "DETECTED GNUTELLA GET.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET / HTTP", 9) == 0))) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if ((packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > 15 + && memcmp(packet->user_agent_line.ptr, "BearShare Lite ", 15) == 0) + || (packet->accept_line.ptr != NULL && packet->accept_line.len > 24 + && memcmp(packet->accept_line.ptr, "application n/x-gnutella", 24) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "DETECTED GNUTELLA GET.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + } + + } + /* haven't found this pattern in any trace. */ + if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0) + || (memcmp(packet->payload, "GET /uri-res/", 13) == 0))) { + c = 8; + while (c < (packet->payload_packet_len - 9)) { + if (packet->payload[c] == '?') + break; + c++; + } + + if (c < (packet->payload_packet_len - 9) && memcmp(&packet->payload[c], "urn:sha1:", 9) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, + "detected GET /get/ or GET /uri-res/.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + } + + } + + /* answer to this packet is HTTP/1.1 ..... Content-Type: application/x-gnutella-packets, + * it is searched in the upper paragraph. */ + if (packet->payload_packet_len > 30 && memcmp(packet->payload, "HEAD /gnutella/push-proxy?", 26) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected HEAD /gnutella/push-proxy?\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + /* haven't found any trace with this pattern */ + if (packet->payload_packet_len == 46 + && memcmp(packet->payload, "\x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a", 10) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, + "detected \x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + /* haven't found any trace with this pattern */ + if (packet->payload_packet_len > 250 && memcmp(packet->payload, "GET /gnutella/", 14) == 0) + //PATTERN IS :: GET /gnutella/tigertree/v3?urn:tree:tiger/: + { + const u_int16_t end = packet->payload_packet_len - 3; + + c = 13; + while (c < end) { + if ((memcmp(&packet->payload[14], "tigertree/", 10) == 0) + || (end - c > 18 && memcmp(&packet->payload[c], "\r\nUser-Agent: Foxy", 18) == 0) + || (end - c > 44 + && memcmp(&packet->payload[c], + "\r\nAccept: application/tigertree-breadthfirst", + 44) == 0) || (end - c > 10 && memcmp(&packet->payload[c], "\r\nX-Queue:", 10) == 0) + || (end - c > 13 && memcmp(&packet->payload[c], "\r\nX-Features:", 13) == 0)) { + + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, + ndpi_struct, NDPI_LOG_TRACE, "FOXY :: GNUTELLA GET 2 DETECTED\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + + c++; + } + } + /* haven't found any trace with this pattern */ + if (packet->payload_packet_len > 1 && packet->payload[packet->payload_packet_len - 1] == 0x0a + && packet->payload[packet->payload_packet_len - 2] == 0x0a) { + if (packet->payload_packet_len > 3 && memcmp(packet->payload, "GIV", 3) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "MORPHEUS GIV DETECTED\n"); + /* Not Excludeing the flow now.. We shall Check the next Packet too for Gnutella Patterns */ + return; + } + } + /* might be super tricky new ssl gnutella transmission, but the certificate is strange... */ + if (packet->payload_packet_len == 46 && get_u_int32_t(packet->payload, 0) == htonl(0x802c0103) && + get_u_int32_t(packet->payload, 4) == htonl(0x01000300) && get_u_int32_t(packet->payload, 8) == htonl(0x00002000) && + get_u_int16_t(packet->payload, 12) == htons(0x0034)) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected gnutella len == 46.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 49 && + memcmp(packet->payload, "\x80\x2f\x01\x03\x01\x00\x06\x00\x00\x00\x20\x00\x00\x34\x00\x00\xff\x4d\x6c", + 19) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected gnutella len == 49.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 89 && memcmp(&packet->payload[43], "\x20\x4d\x6c", 3) == 0 && + memcmp(packet->payload, "\x16\x03\x01\x00\x54\x01\x00\x00\x50\x03\x01\x4d\x6c", 13) == 0 && + memcmp(&packet->payload[76], "\x00\x02\x00\x34\x01\x00\x00\x05", 8) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, + "detected gnutella asymmetrically len == 388.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } else if (packet->payload_packet_len == 82) { + if (get_u_int32_t(packet->payload, 0) == htonl(0x16030100) + && get_u_int32_t(packet->payload, 4) == htonl(0x4d010000) + && get_u_int16_t(packet->payload, 8) == htons(0x4903) + && get_u_int16_t(packet->payload, 76) == htons(0x0002) + && get_u_int32_t(packet->payload, 78) == htonl(0x00340100)) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected len == 82.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + } else if (packet->udp != NULL) { + if (src != NULL && (packet->udp->source == src->detected_gnutella_udp_port1 || + packet->udp->source == src->detected_gnutella_udp_port2) && + (packet->tick_timestamp - src->gnutella_ts) < ndpi_struct->gnutella_timeout) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "port based detection\n\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + } + /* observations: + * all the following patterns send out many packets which are the only ones of their flows, + * often on the very beginning of the traces, or flows with many packets in one direction only. + * but then suddenly, one gets an answer as you can see in netpeker-gnutella-rpc.pcap packet 11483. + * Maybe gnutella tries to send out keys? + */ + if (packet->payload_packet_len == 23 && packet->payload[15] == 0x00 + && packet->payload[16] == 0x41 && packet->payload[17] == 0x01 + && packet->payload[18] == 0x00 && packet->payload[19] == 0x00 + && packet->payload[20] == 0x00 && packet->payload[21] == 0x00 && packet->payload[22] == 0x00) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, + "detected gnutella udp, len = 23.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + + return; + } + if (packet->payload_packet_len == 35 && packet->payload[25] == 0x49 + && packet->payload[26] == 0x50 && packet->payload[27] == 0x40 + && packet->payload[28] == 0x83 && packet->payload[29] == 0x53 + && packet->payload[30] == 0x43 && packet->payload[31] == 0x50 && packet->payload[32] == 0x41) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, + "detected gnutella udp, len = 35.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 32 + && (memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00\x4c\x49\x4d\x45", 11) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, + "detected gnutella udp, len = 32.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 34 && (memcmp(&packet->payload[25], "SCP@", 4) == 0) + && (memcmp(&packet->payload[30], "DNA@", 4) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, + "detected gnutella udp, len = 34.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if ((packet->payload_packet_len == 73 || packet->payload_packet_len == 96) + && memcmp(&packet->payload[32], "urn:sha1:", 9) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, + "detected gnutella udp, len = 73,96.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + if (memcmp(packet->payload, "GND", 3) == 0) { + if ((packet->payload_packet_len == 8 && (memcmp(&packet->payload[6], "\x01\x00", 2) == 0)) + || (packet->payload_packet_len == 11 && (memcmp(&packet->payload[6], "\x01\x01\x08\x50\x49", 5) + == 0)) || (packet->payload_packet_len == 17 + && + (memcmp + (&packet->payload[6], "\x01\x01\x4c\x05\x50", + 5) == 0)) + || (packet->payload_packet_len == 28 + && (memcmp(&packet->payload[6], "\x01\x01\x54\x0f\x51\x4b\x52\x50\x06\x52", 10) == 0)) + || (packet->payload_packet_len == 41 + && (memcmp(&packet->payload[6], "\x01\x01\x5c\x1b\x50\x55\x53\x48\x48\x10", 10) == 0)) + || (packet->payload_packet_len > 200 && packet->payload_packet_len < 300 && packet->payload[3] == 0x03) + || (packet->payload_packet_len > 300 && (packet->payload[3] == 0x01 || packet->payload[3] == 0x03))) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, + "detected gnutella udp, GND.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + + if ((packet->payload_packet_len == 32) + && memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00", 7) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, + "detected gnutella udp, len = 32 ii.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if ((packet->payload_packet_len == 23) + && memcmp(&packet->payload[16], "\x00\x01\x00\x00\x00\x00\x00", 7) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, + "detected gnutella udp, len = 23 ii.\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + //neonet detection follows + + /* haven't found any trace with this pattern */ + if (packet->tcp != NULL && ntohs(packet->tcp->source) >= 1024 && ntohs(packet->tcp->dest) >= 1024) { + if (flow->l4.tcp.gnutella_stage == 0) { + if (flow->packet_counter == 1 + && (packet->payload_packet_len == 11 + || packet->payload_packet_len == 33 || packet->payload_packet_len == 37)) { + flow->l4.tcp.gnutella_msg_id[0] = packet->payload[4]; + flow->l4.tcp.gnutella_msg_id[1] = packet->payload[6]; + flow->l4.tcp.gnutella_msg_id[2] = packet->payload[8]; + flow->l4.tcp.gnutella_stage = 1 + packet->packet_direction; + return; + } + } else if (flow->l4.tcp.gnutella_stage == 1 + packet->packet_direction) { + if (flow->packet_counter == 2 && (packet->payload_packet_len == 33 || packet->payload_packet_len == 22) + && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0] + && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2] + && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4] + && NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_GNUTELLA)) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, + NDPI_LOG_TRACE, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } else if (flow->l4.tcp.gnutella_stage == 2 - packet->packet_direction) { + if (flow->packet_counter == 2 && (packet->payload_packet_len == 10 || packet->payload_packet_len == 75) + && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0] + && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2] + && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4] + && NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_GNUTELLA)) { + NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, + NDPI_LOG_TRACE, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n"); + ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GNUTELLA); +} +#endif diff --git a/src/lib/protocols/gtp.c b/src/lib/protocols/gtp.c new file mode 100644 index 000000000..b9aee7a97 --- /dev/null +++ b/src/lib/protocols/gtp.c @@ -0,0 +1,85 @@ +/* + * gtp.c + * + * Copyright (C) 2011-15 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_GTP + +struct gtp_header_generic { + u_int8_t flags, message_type; + u_int16_t message_len; + u_int32_t teid; +}; + +static void ndpi_check_gtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // const u_int8_t *packet_payload = packet->payload; + u_int32_t payload_len = packet->payload_packet_len; + +#if 0 + printf("[len=%u][%02X %02X %02X %02X]\n", payload_len, + packet->payload[0] & 0xFF, + packet->payload[1] & 0xFF, + packet->payload[2] & 0xFF, + packet->payload[3] & 0xFF); +#endif + + if((packet->udp != NULL) && (payload_len > sizeof(struct gtp_header_generic))) { + u_int32_t gtp_u = ntohs(2152); + u_int32_t gtp_c = ntohs(2123); + u_int32_t gtp_v0 = ntohs(3386); + + if((packet->udp->source == gtp_u) || (packet->udp->dest == gtp_u) + || (packet->udp->source == gtp_c) || (packet->udp->dest == gtp_c) + || (packet->udp->source == gtp_v0) || (packet->udp->dest == gtp_v0) + ) { + struct gtp_header_generic *gtp = (struct gtp_header_generic*)packet->payload; + u_int8_t gtp_version = (gtp->flags & 0xE0) >> 5; + + if((gtp_version == 0) || (gtp_version == 1) || (gtp_version == 2)) { + u_int16_t message_len = ntohs(gtp->message_len); + + if(message_len <= (payload_len-sizeof(struct gtp_header_generic))) { + NDPI_LOG(NDPI_PROTOCOL_GTP, ndpi_struct, NDPI_LOG_DEBUG, "Found gtp.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_GTP, NDPI_REAL_PROTOCOL); + return; + } + } + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GTP); + return; +} + +void ndpi_search_gtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_GTP, ndpi_struct, NDPI_LOG_DEBUG, "gtp detection...\n"); + + /* skip marked packets */ + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_GTP) + ndpi_check_gtp(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/guildwars.c b/src/lib/protocols/guildwars.c new file mode 100644 index 000000000..b5dda0cdf --- /dev/null +++ b/src/lib/protocols/guildwars.c @@ -0,0 +1,71 @@ +/* + * guildwars.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +/* include files */ +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_GUILDWARS + + +static void ndpi_int_guildwars_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_GUILDWARS, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_guildwars_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "search guildwars.\n"); + + if (packet->payload_packet_len == 64 && get_u_int16_t(packet->payload, 1) == ntohs(0x050c) + && memcmp(&packet->payload[50], "@2&P", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 29.350: found.\n"); + ndpi_int_guildwars_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 1) == ntohs(0x040c) + && get_u_int16_t(packet->payload, 4) == ntohs(0xa672) + && packet->payload[8] == 0x01 && packet->payload[12] == 0x04) { + NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 29.350: found.\n"); + ndpi_int_guildwars_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len == 21 && get_u_int16_t(packet->payload, 0) == ntohs(0x0100) + && get_u_int32_t(packet->payload, 5) == ntohl(0xf1001000) + && packet->payload[9] == 0x01) { + NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 216.107.245.50: found.\n"); + ndpi_int_guildwars_add_connection(ndpi_struct, flow); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "exclude guildwars.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GUILDWARS); +} + +#endif diff --git a/src/lib/protocols/h323.c b/src/lib/protocols/h323.c new file mode 100644 index 000000000..9d2fac8c8 --- /dev/null +++ b/src/lib/protocols/h323.c @@ -0,0 +1,97 @@ +/* + * h323.c + * + * Copyright (C) 2015 ntop.org + * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_H323 + +struct tpkt { + u_int8_t version, reserved; + u_int16_t len; +}; + +void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t dport = 0, sport = 0; + + NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "search H323.\n"); + + if(packet->tcp != NULL) { + NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over tcp.\n"); + + /* H323 */ + if((packet->payload[0] == 0x03) + && (packet->payload[1] == 0x00) + && (packet->payload[2] == 0x00)) { + struct tpkt *t = (struct tpkt*)packet->payload; + u_int16_t len = ntohs(t->len); + + if(packet->payload_packet_len == len) { + /* + We need to check if this packet is in reality + a RDP (Remote Desktop) packet encapsulated on TPTK + */ + + if(packet->payload[4] == (packet->payload_packet_len - sizeof(struct tpkt) - 1)) { + /* ISO 8073/X.224 */ + if((packet->payload[5] == 0xE0 /* CC Connect Request */) + || (packet->payload[5] == 0xD0 /* CC Connect Confirm */)) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RDP, NDPI_REAL_PROTOCOL); + return; + } + } + + flow->l4.tcp.h323_valid_packets++; + + if(flow->l4.tcp.h323_valid_packets >= 2) { + NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_REAL_PROTOCOL); + } + } else { + /* This is not H.323 */ + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_H323); + } + } + } else if(packet->udp != NULL) { + sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); + NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over udp.\n"); + + if(packet->payload[0] == 0x80 && packet->payload[1] == 0x08 && (packet->payload[2] == 0xe7 || packet->payload[2] == 0x26) && + packet->payload[4] == 0x00 && packet->payload[5] == 0x00) + { + NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_REAL_PROTOCOL); + return; + } + /* H323 */ + if(sport == 1719 || dport == 1719) + { + if(packet->payload[0] == 0x16 && packet->payload[1] == 0x80 && packet->payload[4] == 0x06 && packet->payload[5] == 0x00) + { + NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_REAL_PROTOCOL); + return; + } + else if(packet->payload_packet_len >= 20 || packet->payload_packet_len <= 117) + { + NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_REAL_PROTOCOL); + return; + } + else + { + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_H323); + return; + } + } + } + +} +#endif diff --git a/src/lib/protocols/halflife2_and_mods.c b/src/lib/protocols/halflife2_and_mods.c new file mode 100644 index 000000000..2644950c9 --- /dev/null +++ b/src/lib/protocols/halflife2_and_mods.c @@ -0,0 +1,65 @@ +/* + * halflife2_and_mods.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_HALFLIFE2 + + +static void ndpi_int_halflife2_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HALFLIFE2, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_halflife2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (flow->l4.udp.halflife2_stage == 0) { + if (packet->payload_packet_len >= 20 + && get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF + && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) == htonl(0x30303000)) { + flow->l4.udp.halflife2_stage = 1 + packet->packet_direction; + NDPI_LOG(NDPI_PROTOCOL_HALFLIFE2, ndpi_struct, NDPI_LOG_DEBUG, + "halflife2 client req detected, waiting for server reply\n"); + return; + } + } else if (flow->l4.udp.halflife2_stage == 2 - packet->packet_direction) { + if (packet->payload_packet_len >= 20 + && get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF + && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) == htonl(0x30303000)) { + ndpi_int_halflife2_add_connection(ndpi_struct, flow); + NDPI_LOG(NDPI_PROTOCOL_HALFLIFE2, ndpi_struct, NDPI_LOG_DEBUG, "halflife2 server reply detected\n"); + return; + } + } + + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HALFLIFE2); +} + +#endif diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c new file mode 100644 index 000000000..3c4cfe128 --- /dev/null +++ b/src/lib/protocols/http.c @@ -0,0 +1,981 @@ +/* + * http.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_HTTP + +static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int32_t protocol) { + + if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { + /* This is HTTP and it is not a sub protocol (e.g. skype or dropbox) */ + + ndpi_search_tcp_or_udp(ndpi_struct, flow); + + /* If no custom protocol has been detected */ + if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { + if(protocol != NDPI_PROTOCOL_HTTP) { + ndpi_search_tcp_or_udp(ndpi_struct, flow); + ndpi_int_add_connection(ndpi_struct, flow, protocol, NDPI_CORRELATED_PROTOCOL); + } else { + ndpi_int_reset_protocol(flow); + ndpi_int_add_connection(ndpi_struct, flow, protocol, NDPI_REAL_PROTOCOL); + } + } + + flow->http_detected = 1; + } + +} + +#ifdef NDPI_CONTENT_FLASH +static void flash_check_http_payload(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + const u_int8_t *pos; + + if(packet->empty_line_position_set == 0 || (packet->empty_line_position + 10) > (packet->payload_packet_len)) + return; + + pos = &packet->payload[packet->empty_line_position] + 2; + + + if(memcmp(pos, "FLV", 3) == 0 && pos[3] == 0x01 && (pos[4] == 0x01 || pos[4] == 0x04 || pos[4] == 0x05) + && pos[5] == 0x00 && pos[6] == 0x00 && pos[7] == 0x00 && pos[8] == 0x09) { + + NDPI_LOG(NDPI_CONTENT_FLASH, ndpi_struct, NDPI_LOG_DEBUG, "Flash content in http detected\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_FLASH); + } +} +#endif + +#ifdef NDPI_CONTENT_AVI +static void avi_check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + NDPI_LOG(NDPI_CONTENT_AVI, ndpi_struct, NDPI_LOG_DEBUG, "called avi_check_http_payload: %u %u %u\n", + packet->empty_line_position_set, flow->l4.tcp.http_empty_line_seen, packet->empty_line_position); + + if(packet->empty_line_position_set == 0 && flow->l4.tcp.http_empty_line_seen == 0) + return; + + if(packet->empty_line_position_set != 0 && ((packet->empty_line_position + 20) > (packet->payload_packet_len)) + && flow->l4.tcp.http_empty_line_seen == 0) { + flow->l4.tcp.http_empty_line_seen = 1; + return; + } + + if(flow->l4.tcp.http_empty_line_seen == 1) { + if(packet->payload_packet_len > 20 && memcmp(packet->payload, "RIFF", 4) == 0 + && memcmp(packet->payload + 8, "AVI LIST", 8) == 0) { + NDPI_LOG(NDPI_CONTENT_AVI, ndpi_struct, NDPI_LOG_DEBUG, "Avi content in http detected\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_AVI); + } + flow->l4.tcp.http_empty_line_seen = 0; + return; + } + + if(packet->empty_line_position_set != 0) { + // check for avi header + // for reference see http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/avirifffilereference.asp + u_int32_t p = packet->empty_line_position + 2; + + NDPI_LOG(NDPI_CONTENT_AVI, ndpi_struct, NDPI_LOG_DEBUG, "p = %u\n", p); + + if((p + 16) <= packet->payload_packet_len && memcmp(&packet->payload[p], "RIFF", 4) == 0 + && memcmp(&packet->payload[p + 8], "AVI LIST", 8) == 0) { + NDPI_LOG(NDPI_CONTENT_AVI, ndpi_struct, NDPI_LOG_DEBUG, "Avi content in http detected\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_AVI); + } + } +} +#endif + +#ifdef NDPI_PROTOCOL_TEAMVIEWER +static void teamviewer_check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + const u_int8_t *pos; + + NDPI_LOG(NDPI_PROTOCOL_TEAMVIEWER, ndpi_struct, NDPI_LOG_DEBUG, "called teamviewer_check_http_payload: %u %u %u\n", + packet->empty_line_position_set, flow->l4.tcp.http_empty_line_seen, packet->empty_line_position); + + if(packet->empty_line_position_set == 0 || (packet->empty_line_position + 5) > (packet->payload_packet_len)) + return; + + pos = &packet->payload[packet->empty_line_position] + 2; + + if(pos[0] == 0x17 && pos[1] == 0x24) { + NDPI_LOG(NDPI_PROTOCOL_TEAMVIEWER, ndpi_struct, NDPI_LOG_DEBUG, "TeamViewer content in http detected\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TEAMVIEWER); + } +} +#endif + + +#ifdef NDPI_PROTOCOL_RTSP +static void rtsp_parse_packet_acceptline(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if(packet->accept_line.len >= 28 && memcmp(packet->accept_line.ptr, "application/x-rtsp-tunnelled", 28) == 0) { + NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "RTSP accept line detected\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTSP); + } +} +#endif + +static void setHttpUserAgent(struct ndpi_flow_struct *flow, char *ua) { + if(!strcmp(ua, "Windows NT 5.0")) ua = "Windows 2000"; + else if(!strcmp(ua, "Windows NT 5.1")) ua = "Windows XP"; + else if(!strcmp(ua, "Windows NT 5.2")) ua = "Windows Server 2003"; + else if(!strcmp(ua, "Windows NT 6.0")) ua = "Windows Vista"; + // else if(!strcmp(ua, "Windows NT 7.0")) ua = "Windows 7"; + else if(!strcmp(ua, "Windows NT 6.1")) ua = "Windows 7"; + else if(!strcmp(ua, "Windows NT 6.2")) ua = "Windows 8"; + else if(!strcmp(ua, "Windows NT 6.3")) ua = "Windows 8.1"; + + //printf("==> %s\n", ua); + snprintf((char*)flow->detected_os, sizeof(flow->detected_os), "%s", ua); +} + +static void parseHttpSubprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + // int i = 0; + struct ndpi_packet_struct *packet = &flow->packet; + + if(packet->iph /* IPv4 only */) { + /* + Twitter Inc. TWITTER-NETWORK (NET-199-59-148-0-1) 199.59.148.0 - 199.59.151.255 + 199.59.148.0/22 + */ + if(((ntohl(packet->iph->saddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC73B9400 /* 199.59.148.0 */) + || ((ntohl(packet->iph->daddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC73B9400 /* 199.59.148.0 */)) { + packet->detected_protocol_stack[0] = NDPI_SERVICE_TWITTER; + return; + } + + /* + CIDR: 69.53.224.0/19 + OriginAS: AS2906 + NetName: NETFLIX-INC + */ + if(((ntohl(packet->iph->saddr) & 0xFFFFE000 /* 255.255.224.0 */) == 0x4535E000 /* 69.53.224.0 */) + || ((ntohl(packet->iph->daddr) & 0xFFFFE000 /* 255.255.224.0 */) == 0x4535E000 /* 69.53.224.0 */)) { + packet->detected_protocol_stack[0] = NDPI_SERVICE_NETFLIX; + return; + } + } + + if((flow->l4.tcp.http_stage == 0) + || (flow->http.url && flow->http_detected)) { + /* Try matching subprotocols */ + // ndpi_match_string_subprotocol(ndpi_struct, flow, (char*)packet->host_line.ptr, packet->host_line.len); + + if(ndpi_struct->http_dissect_response) { + if(flow->http.url && flow->http_detected) + ndpi_match_string_subprotocol(ndpi_struct, flow, (char *)&flow->http.url[7], strlen((const char *)&flow->http.url[7])); + } else + ndpi_match_string_subprotocol(ndpi_struct, flow, (char *)flow->host_server_name, strlen((const char *)flow->host_server_name)); + } +} + +/* + NOTE + + ndpi_parse_packet_line_info @ ndpi_main.c + is the code that parses the packet +*/ +static void check_content_type_and_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { +#ifdef NDPI_CONTENT_MPEG + struct ndpi_packet_struct *packet = &flow->packet; +#endif +#ifdef NDPI_CONTENT_AVI +#endif + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + u_int8_t a; + + if(ndpi_struct->http_dissect_response) { + if((flow->http.url == NULL) + && (packet->http_url_name.len > 0) + && (packet->host_line.len > 0)) { + int len = packet->http_url_name.len + packet->host_line.len + 7 + 1; /* "http://" */ + + flow->http.url = ndpi_malloc(len); + if(flow->http.url) { + strncpy(flow->http.url, "http://", 7); + strncpy(&flow->http.url[7], (char*)packet->host_line.ptr, packet->host_line.len); + strncpy(&flow->http.url[7+packet->host_line.len], (char*)packet->http_url_name.ptr, + packet->http_url_name.len); + flow->http.url[len-1] = '\0'; + } + + if(flow->packet.http_method.len < 3) + flow->http.method = HTTP_METHOD_UNKNOWN; + else { + switch(flow->packet.http_method.ptr[0]) { + case 'O': flow->http.method = HTTP_METHOD_OPTIONS; break; + case 'G': flow->http.method = HTTP_METHOD_GET; break; + case 'H': flow->http.method = HTTP_METHOD_HEAD; break; + + case 'P': + switch(flow->packet.http_method.ptr[1]) { + case 'O': flow->http.method = HTTP_METHOD_POST; break; + case 'U': flow->http.method = HTTP_METHOD_PUT; break; + } + break; + + case 'D': flow->http.method = HTTP_METHOD_DELETE; break; + case 'T': flow->http.method = HTTP_METHOD_TRACE; break; + case 'C': flow->http.method = HTTP_METHOD_CONNECT; break; + default: + flow->http.method = HTTP_METHOD_UNKNOWN; + break; + } + } + } + + if((flow->http.content_type == NULL) && (packet->content_line.len > 0)) { + int len = packet->content_line.len + 1; + + flow->http.content_type = ndpi_malloc(len); + if(flow->http.content_type) { + strncpy(flow->http.content_type, (char*)packet->content_line.ptr, + packet->content_line.len); + flow->http.content_type[packet->content_line.len] = '\0'; + } + } + } + + if(packet->user_agent_line.ptr != NULL && packet->user_agent_line.len != 0) { + /* Format: + Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) .... + */ + if(packet->user_agent_line.len > 7) { + char ua[256]; + u_int mlen = ndpi_min(packet->user_agent_line.len, sizeof(ua)-1); + + strncpy(ua, (const char *)packet->user_agent_line.ptr, mlen); + ua[mlen] = '\0'; + + if(strncmp(ua, "Mozilla", 7) == 0) { + char *parent = strchr(ua, '('); + + if(parent) { + char *token, *end; + + parent++; + end = strchr(parent, ')'); + if(end) end[0] = '\0'; + + token = strsep(&parent, ";"); + if(token) { + if((strcmp(token, "X11") == 0) + || (strcmp(token, "compatible") == 0) + || (strcmp(token, "Linux") == 0) + || (strcmp(token, "Macintosh") == 0) + ) { + token = strsep(&parent, ";"); + if(token && (token[0] == ' ')) token++; /* Skip space */ + + if(token + && ((strcmp(token, "U") == 0) + || (strncmp(token, "MSIE", 4) == 0))) { + token = strsep(&parent, ";"); + if(token && (token[0] == ' ')) token++; /* Skip space */ + + if(token && (strncmp(token, "Update", 6) == 0)) { + token = strsep(&parent, ";"); + + if(token && (token[0] == ' ')) token++; /* Skip space */ + + if(token && (strncmp(token, "AOL", 3) == 0)) { + token = strsep(&parent, ";"); + + if(token && (token[0] == ' ')) token++; /* Skip space */ + } + } + } + } + + if(token) + setHttpUserAgent(flow, token); + } + } + } + } + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "User Agent Type Line found %.*s\n", + packet->user_agent_line.len, packet->user_agent_line.ptr); + + if((!ndpi_struct->http_dissect_response) || flow->http_detected) + ndpi_match_content_subprotocol(ndpi_struct, flow, + (char*)packet->user_agent_line.ptr, + packet->user_agent_line.len); + } + + /* check for host line */ + if(packet->host_line.ptr != NULL) { + u_int len; + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HOST Line found %.*s\n", + packet->host_line.len, packet->host_line.ptr); + + if((!ndpi_struct->http_dissect_response) || flow->http_detected) + ndpi_match_content_subprotocol(ndpi_struct, flow, + (char*)packet->host_line.ptr, + packet->host_line.len); + + /* Copy result for nDPI apps */ + len = ndpi_min(packet->host_line.len, sizeof(flow->host_server_name)-1); + strncpy((char*)flow->host_server_name, (char*)packet->host_line.ptr, len); + flow->host_server_name[len] = '\0', flow->server_id = flow->dst; + + len = ndpi_min(packet->forwarded_line.len, sizeof(flow->nat_ip)-1); + strncpy((char*)flow->nat_ip, (char*)packet->forwarded_line.ptr, len); + flow->nat_ip[len] = '\0'; + + if(!ndpi_struct->http_dissect_response) + parseHttpSubprotocol(ndpi_struct, flow); + + if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) + && ((!ndpi_struct->http_dissect_response) || flow->http_detected)) + ndpi_match_string_subprotocol(ndpi_struct, flow, + (char *)flow->host_server_name, + strlen((const char *)flow->host_server_name)); + + if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) + && ((!ndpi_struct->http_dissect_response) || flow->http_detected) + && (packet->http_origin.len > 0)) + ndpi_match_string_subprotocol(ndpi_struct, flow, + (char *)packet->http_origin.ptr, + packet->http_origin.len); + + if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) { + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_HTTP) { + ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0]); + return; /* We have identified a sub-protocol so we're done */ + } + } + } + + if(ndpi_struct->http_dissect_response && flow->http_detected) + parseHttpSubprotocol(ndpi_struct, flow); + + /* check for accept line */ + if(packet->accept_line.ptr != NULL) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Accept Line found %.*s\n", + packet->accept_line.len, packet->accept_line.ptr); +#ifdef NDPI_PROTOCOL_RTSP + if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_RTSP) != 0) { + rtsp_parse_packet_acceptline(ndpi_struct, flow); + } +#endif + } + + /* search for line startin with "Icy-MetaData" */ +#ifdef NDPI_CONTENT_MPEG + for (a = 0; a < packet->parsed_lines; a++) { + if(packet->line[a].len > 11 && memcmp(packet->line[a].ptr, "Icy-MetaData", 12) == 0) { + NDPI_LOG(NDPI_CONTENT_MPEG, ndpi_struct, NDPI_LOG_DEBUG, "MPEG: Icy-MetaData found.\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_CONTENT_MPEG); + return; + } + } +#ifdef NDPI_CONTENT_AVI +#endif +#endif + + if(packet->content_line.ptr != NULL && packet->content_line.len != 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Content Type Line found %.*s\n", + packet->content_line.len, packet->content_line.ptr); + + if((!ndpi_struct->http_dissect_response) || flow->http_detected) + ndpi_match_content_subprotocol(ndpi_struct, flow, (char*)packet->content_line.ptr, packet->content_line.len); + } + + /* check user agent here too */ +} + +static void check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "called check_http_payload.\n"); + +#ifdef NDPI_CONTENT_FLASH + if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_CONTENT_FLASH) != 0) + flash_check_http_payload(ndpi_struct, flow); +#endif +#ifdef NDPI_CONTENT_AVI + if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_CONTENT_AVI) != 0) + avi_check_http_payload(ndpi_struct, flow); +#endif +#ifdef NDPI_PROTOCOL_TEAMVIEWER + teamviewer_check_http_payload(ndpi_struct, flow); +#endif + +} + +/** + * this functions checks whether the packet begins with a valid http request + * @param ndpi_struct + * @returnvalue 0 if no valid request has been found + * @returnvalue >0 indicates start of filename but not necessarily in packet limit + */ +static u_int16_t http_request_url_offset(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "====>>>> HTTP: %c%c%c%c [len: %u]\n", + packet->payload[0], packet->payload[1], packet->payload[2], packet->payload[3], + packet->payload_packet_len); + + /* FIRST PAYLOAD PACKET FROM CLIENT */ + /* check if the packet starts with POST or GET */ + if(packet->payload_packet_len >= 4 && memcmp(packet->payload, "GET ", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: GET FOUND\n"); + return 4; + } else if(packet->payload_packet_len >= 5 && memcmp(packet->payload, "POST ", 5) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: POST FOUND\n"); + return 5; + } else if(packet->payload_packet_len >= 8 && memcmp(packet->payload, "OPTIONS ", 8) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: OPTIONS FOUND\n"); + return 8; + } else if(packet->payload_packet_len >= 5 && memcmp(packet->payload, "HEAD ", 5) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: HEAD FOUND\n"); + return 5; + } else if(packet->payload_packet_len >= 4 && memcmp(packet->payload, "PUT ", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: PUT FOUND\n"); + return 4; + } else if(packet->payload_packet_len >= 7 && memcmp(packet->payload, "DELETE ", 7) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: DELETE FOUND\n"); + return 7; + } else if(packet->payload_packet_len >= 8 && memcmp(packet->payload, "CONNECT ", 8) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: CONNECT FOUND\n"); + return 8; + } else if(packet->payload_packet_len >= 9 && memcmp(packet->payload, "PROPFIND ", 9) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: PROFIND FOUND\n"); + return 9; + } else if(packet->payload_packet_len >= 7 && memcmp(packet->payload, "REPORT ", 7) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: REPORT FOUND\n"); + return 7; + } + + return 0; +} + +static void http_bitmask_exclude(struct ndpi_flow_struct *flow) +{ + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP); +#ifdef NDPI_PROTOCOL_WINDOWS_UPDATE + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WINDOWS_UPDATE); +#endif +#ifdef NDPI_CONTENT_MPEG + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_MPEG); +#endif +#ifdef NDPI_CONTENT_QUICKTIME + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_QUICKTIME); +#endif +#ifdef NDPI_CONTENT_WINDOWSMEDIA + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_WINDOWSMEDIA); +#endif +#ifdef NDPI_CONTENT_REALMEDIA + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_REALMEDIA); +#endif +#ifdef NDPI_CONTENT_AVI + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_AVI); +#endif +#ifdef NDPI_CONTENT_OGG + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_OGG); +#endif +#ifdef NDPI_PROTOCOL_MOVE + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MOVE); +#endif +#ifdef NDPI_PROTOCOL_XBOX + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_XBOX); +#endif +} + +void _org_ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + u_int16_t filename_start; + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "search http\n"); + + /* set client-server_direction */ + if(flow->l4.tcp.http_setup_dir == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "initializes http to stage: 1 \n"); + flow->l4.tcp.http_setup_dir = 1 + packet->packet_direction; + } + + if(NDPI_COMPARE_PROTOCOL_TO_BITMASK + (ndpi_struct->generic_http_packet_bitmask, packet->detected_protocol_stack[0]) != 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "protocol might be detected earlier as http jump to payload type detection\n"); + goto http_parse_detection; + } + + if(flow->l4.tcp.http_setup_dir == 1 + packet->packet_direction) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "http stage: 1\n"); + + if(flow->l4.tcp.http_wait_for_retransmission) { + if(!packet->tcp_retransmission) { + if(flow->packet_counter <= 5) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "still waiting for retransmission\n"); + return; + } else { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "retransmission not found, exclude\n"); + http_bitmask_exclude(flow); + return; + } + } + } + + if(flow->l4.tcp.http_stage == 0) { + filename_start = http_request_url_offset(ndpi_struct, flow); + if(filename_start == 0) { + if(packet->payload_packet_len >= 7 && memcmp(packet->payload, "HTTP/1.", 7) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP response found (truncated flow ?)\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "filename not found, exclude\n"); + http_bitmask_exclude(flow); + return; + } + // parse packet + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if(packet->parsed_lines <= 1) { + /* parse one more packet .. */ + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "just one line, search next packet\n"); + + packet->http_method.ptr = packet->line[0].ptr; + packet->http_method.len = filename_start - 1; + flow->l4.tcp.http_stage = 1; + return; + } + // parsed_lines > 1 here + if(packet->line[0].len >= (9 + filename_start) + && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { + u_int16_t proto_id; + + packet->http_url_name.ptr = &packet->payload[filename_start]; + packet->http_url_name.len = packet->line[0].len - (filename_start + 9); + + packet->http_method.ptr = packet->line[0].ptr; + packet->http_method.len = filename_start - 1; + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "http structure detected, adding\n"); + + if(filename_start == 8 && (memcmp(packet->payload, "CONNECT ", 8) == 0)) /* nathan@getoffmalawn.com */ + proto_id = NDPI_PROTOCOL_HTTP_CONNECT; + else { + if((packet->http_url_name.len > 7) && (!strncmp((const char*)packet->http_url_name.ptr, "http://", 7))) + proto_id = NDPI_PROTOCOL_HTTP_PROXY; + else { + proto_id = NDPI_PROTOCOL_HTTP; + } + } + + ndpi_int_http_add_connection(ndpi_struct, flow, proto_id); + check_content_type_and_change_protocol(ndpi_struct, flow); + /* HTTP found, look for host... */ + if(packet->host_line.ptr != NULL) { + /* aaahh, skip this direction and wait for a server reply here */ + flow->l4.tcp.http_stage = 2; + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP START HOST found\n"); + return; + } + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP START HOST found\n"); + + /* host not found, check in next packet after */ + flow->l4.tcp.http_stage = 1; + return; + } + } else if(flow->l4.tcp.http_stage == 1) { + /* SECOND PAYLOAD TRAFFIC FROM CLIENT, FIRST PACKET MIGHT HAVE BEEN HTTP... */ + /* UNKNOWN TRAFFIC, HERE FOR HTTP again.. */ + // parse packet + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if(packet->parsed_lines <= 1) { + /* wait some packets in case request is split over more than 2 packets */ + if(flow->packet_counter < 5) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "line still not finished, search next packet\n"); + return; + } else { + /* stop parsing here */ + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "HTTP: PACKET DOES NOT HAVE A LINE STRUCTURE\n"); + http_bitmask_exclude(flow); + return; + } + } + // http://www.slideshare.net/DSPIP/rtsp-analysis-wireshark + if(packet->line[0].len >= 9 && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + check_content_type_and_change_protocol(ndpi_struct, flow); + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "HTTP START HTTP found in 2. packet, check host here...\n"); + /* HTTP found, look for host... */ + flow->l4.tcp.http_stage = 2; + + return; + } + } + } else { + /* We have received a response for a previously identified partial HTTP request */ + + if((packet->parsed_lines == 1) && (packet->packet_direction == 1 /* server -> client */)) { + /* + In apache if you do "GET /\n\n" the response comes without any header so we can assume that + this can be the case + */ + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + return; + } + + } + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: REQUEST NOT HTTP CONFORM\n"); + http_bitmask_exclude(flow); + return; + + http_parse_detection: + if(flow->l4.tcp.http_setup_dir == 1 + packet->packet_direction) { + /* we have something like http here, so check for host and content type if possible */ + if(flow->l4.tcp.http_stage == 0 || flow->l4.tcp.http_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP RUN MAYBE NEXT GET/POST...\n"); + // parse packet + ndpi_parse_packet_line_info(ndpi_struct, flow); + /* check for url here */ + filename_start = http_request_url_offset(ndpi_struct, flow); + if(filename_start != 0 && packet->parsed_lines > 1 && packet->line[0].len >= (9 + filename_start) + && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { + packet->http_url_name.ptr = &packet->payload[filename_start]; + packet->http_url_name.len = packet->line[0].len - (filename_start + 9); + + packet->http_method.ptr = packet->line[0].ptr; + packet->http_method.len = filename_start - 1; + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "next http action, " + "resetting to http and search for other protocols later.\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + } + check_content_type_and_change_protocol(ndpi_struct, flow); + /* HTTP found, look for host... */ + if(packet->host_line.ptr != NULL) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "HTTP RUN MAYBE NEXT HOST found, skipping all packets from this direction\n"); + /* aaahh, skip this direction and wait for a server reply here */ + flow->l4.tcp.http_stage = 2; + return; + } + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "HTTP RUN MAYBE NEXT HOST NOT found, scanning one more packet from this direction\n"); + flow->l4.tcp.http_stage = 1; + } else if(flow->l4.tcp.http_stage == 1) { + // parse packet and maybe find a packet info with host ptr,... + ndpi_parse_packet_line_info(ndpi_struct, flow); + check_content_type_and_change_protocol(ndpi_struct, flow); + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP RUN second packet scanned\n"); + /* HTTP found, look for host... */ + flow->l4.tcp.http_stage = 2; + } + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "HTTP skipping client packets after second packet\n"); + return; + } + /* server response */ + if(flow->l4.tcp.http_stage > 0) { + /* first packet from server direction, might have a content line */ + ndpi_parse_packet_line_info(ndpi_struct, flow); + check_content_type_and_change_protocol(ndpi_struct, flow); + + if(packet->empty_line_position_set != 0 || flow->l4.tcp.http_empty_line_seen == 1) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "empty line. check_http_payload.\n"); + check_http_payload(ndpi_struct, flow); + } + + if(flow->l4.tcp.http_stage == 2) { + flow->l4.tcp.http_stage = 3; + } else { + flow->l4.tcp.http_stage = 0; + } + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "HTTP response first or second packet scanned,new stage is: %u\n", flow->l4.tcp.http_stage); + return; + } else { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP response next packet skipped\n"); + } +} + +/*************************************************************************************************/ + +static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t filename_start; + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->l4.tcp.http_stage == 0) { + flow->http_detected = 0; + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP stage %d: \n", + flow->l4.tcp.http_stage); + + filename_start = http_request_url_offset(ndpi_struct, flow); + + + if (filename_start == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "Filename HTTP not found, we look for possible truncate flow...\n"); + if (packet->payload_packet_len >= 7 && memcmp(packet->payload, "HTTP/1.", 7) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "HTTP response found (truncated flow ?)\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + check_content_type_and_change_protocol(ndpi_struct, flow); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Exclude HTTP\n"); + http_bitmask_exclude(flow); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "Filename HTTP found: %d, we look for line info..\n", filename_start); + + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if (packet->parsed_lines <= 1) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "Found just one line, we will look further for the next packet...\n"); + + packet->http_method.ptr = packet->line[0].ptr; + packet->http_method.len = filename_start - 1; + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 + return; + } + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "Found more than one line, we look further for the next packet...\n"); + + if(packet->line[0].len >= (9 + filename_start) + && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { + + packet->http_url_name.ptr = &packet->payload[filename_start]; + packet->http_url_name.len = packet->line[0].len - (filename_start + 9); + + packet->http_method.ptr = packet->line[0].ptr; + packet->http_method.len = filename_start - 1; + + if((packet->http_url_name.len > 7) + && (!strncmp((const char*) packet->http_url_name.ptr, "http://", 7))) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP_PROXY Found.\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_PROXY); + check_content_type_and_change_protocol(ndpi_struct, flow); + } + + if(filename_start == 8 && (memcmp(packet->payload, "CONNECT ", 8) == 0)) /* nathan@getoffmalawn.com */ + { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP_CONNECT Found.\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_CONNECT); + check_content_type_and_change_protocol(ndpi_struct, flow); + } + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "HTTP START Found, we will look for sub-protocols (content and host)...\n"); + + check_content_type_and_change_protocol(ndpi_struct, flow); + + if(packet->host_line.ptr != NULL) { + /* + nDPI is pretty scrupoulous about HTTP so it waits until the + HTTP response is received just to check that it conforms + with the HTTP specs. However this might be a waste of time as + in 99.99% of the cases is like that. + */ + + if(!ndpi_struct->http_dissect_response) { + if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) /* No subprotocol found */ + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + } else { + flow->http_detected = 1; + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "HTTP START Found, we will look further for the response...\n"); + flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 + } + + return; + } + } + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: REQUEST NOT HTTP CONFORM\n"); + http_bitmask_exclude(flow); + } else if ((flow->l4.tcp.http_stage == 1) || (flow->l4.tcp.http_stage == 2)) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP stage %u: \n", + flow->l4.tcp.http_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, if http is detected do nothing now and return, + * otherwise check the second packet for the http request . */ + if ((flow->l4.tcp.http_stage - packet->packet_direction) == 1) { + + if (flow->http_detected) + return; + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + " SECOND PAYLOAD TRAFFIC FROM CLIENT, FIRST PACKET MIGHT HAVE BEEN HTTP...UNKNOWN TRAFFIC, HERE FOR HTTP again.. \n"); + + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if (packet->parsed_lines <= 1) { + /* wait some packets in case request is split over more than 2 packets */ + if (flow->packet_counter < 5) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "line still not finished, search next packet\n"); + return; + } else { + /* stop parsing here */ + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "HTTP: PACKET DOES NOT HAVE A LINE STRUCTURE\n"); + http_bitmask_exclude(flow); + return; + } + } + // http://www.slideshare.net/DSPIP/rtsp-analysis-wireshark + if (packet->line[0].len >= 9 + && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Found HTTP.\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + check_content_type_and_change_protocol(ndpi_struct, flow); + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, + "HTTP START Found in 2. packet, we will look further for the response....\n"); + flow->http_detected = 1; + } + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + /* We have received a response for a previously identified partial HTTP request */ + + if ((packet->parsed_lines == 1) && (packet->packet_direction == 1 /* server -> client */)) { + /* + In apache if you do "GET /\n\n" the response comes without any header so we can assume that + this can be the case + */ + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Found HTTP. (apache)\n"); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + check_content_type_and_change_protocol(ndpi_struct, flow); + return; + } + + /* If we already detected the http request, we can add the connection and then check for the sub-protocol*/ + if (flow->http_detected) + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + + /* Parse packet line and we look for the subprotocols */ + ndpi_parse_packet_line_info(ndpi_struct, flow); + check_content_type_and_change_protocol(ndpi_struct, flow); + + if (packet->empty_line_position_set != 0 || flow->l4.tcp.http_empty_line_seen == 1) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "empty line. check_http_payload.\n"); + check_http_payload(ndpi_struct, flow); + } + + flow->l4.tcp.http_stage = 0; + return; + } + +} + +void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + /* Break after 20 packets. */ + if (flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Exclude HTTP.\n"); + http_bitmask_exclude(flow); + return; + } + + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) { + return; + } + + NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP detection...\n"); + ndpi_check_http_tcp(ndpi_struct, flow); +} + +/* ********************************* */ + +ndpi_http_method ndpi_get_http_method(struct ndpi_detection_module_struct *ndpi_mod, + struct ndpi_flow_struct *flow) { + if(!flow) + return(HTTP_METHOD_UNKNOWN); + else + return(flow->http.method); +} + +/* ********************************* */ + +char* ndpi_get_http_url(struct ndpi_detection_module_struct *ndpi_mod, + struct ndpi_flow_struct *flow) { + if((!flow) || (!flow->http.url)) + return(""); + else + return(flow->http.url); +} + +/* ********************************* */ + +char* ndpi_get_http_content_type(struct ndpi_detection_module_struct *ndpi_mod, + struct ndpi_flow_struct *flow) { + if((!flow) || (!flow->http.content_type)) + return(""); + else + return(flow->http.content_type); +} + +#endif diff --git a/src/lib/protocols/http_activesync.c b/src/lib/protocols/http_activesync.c new file mode 100644 index 000000000..fd115ced6 --- /dev/null +++ b/src/lib/protocols/http_activesync.c @@ -0,0 +1,54 @@ +/* + * http_activesync.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC +static void ndpi_int_activesync_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC, NDPI_CORRELATED_PROTOCOL); +} + +void ndpi_search_activesync(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if (packet->tcp != NULL) { + + if (packet->payload_packet_len > 150 + && ((memcmp(packet->payload, "OPTIONS /Microsoft-Server-ActiveSync?", 37) == 0) + || (memcmp(packet->payload, "POST /Microsoft-Server-ActiveSync?", 34) == 0))) { + ndpi_int_activesync_add_connection(ndpi_struct, flow); + NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC, ndpi_struct, NDPI_LOG_DEBUG, + " flow marked as ActiveSync \n"); + return; + } + } + + NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC, ndpi_struct, NDPI_LOG_DEBUG, "exclude activesync\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC); + +} +#endif diff --git a/src/lib/protocols/iax.c b/src/lib/protocols/iax.c new file mode 100644 index 000000000..d7a01b51c --- /dev/null +++ b/src/lib/protocols/iax.c @@ -0,0 +1,94 @@ +/* + * iax.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_IAX + +#define NDPI_IAX_MAX_INFORMATION_ELEMENTS 15 + +static void ndpi_int_iax_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_IAX, NDPI_REAL_PROTOCOL); +} + +static void ndpi_search_setup_iax(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int8_t i; + u_int16_t packet_len; + + if ( /* 1. iax is udp based, port 4569 */ + (packet->udp->source == htons(4569) || packet->udp->dest == htons(4569)) + /* check for iax new packet */ + && packet->payload_packet_len >= 12 + /* check for dst call id == 0, do not check for highest bit (packet retransmission) */ + // && (ntohs(get_u_int16_t(packet->payload, 2)) & 0x7FFF) == 0 + /* check full IAX packet */ + && (packet->payload[0] & 0x80) != 0 + /* outbound seq == 0 */ + && packet->payload[8] == 0 + /* inbound seq == 0 || 1 */ + && (packet->payload[9] == 0 || packet->payload[9] == 0x01) + /* */ + && packet->payload[10] == 0x06 + /* IAX type: 0-15 */ + && packet->payload[11] <= 15) { + + if (packet->payload_packet_len == 12) { + NDPI_LOG(NDPI_PROTOCOL_IAX, ndpi_struct, NDPI_LOG_DEBUG, "found IAX.\n"); + ndpi_int_iax_add_connection(ndpi_struct, flow); + return; + } + packet_len = 12; + for (i = 0; i < NDPI_IAX_MAX_INFORMATION_ELEMENTS; i++) { + packet_len = packet_len + 2 + packet->payload[packet_len + 1]; + if (packet_len == packet->payload_packet_len) { + NDPI_LOG(NDPI_PROTOCOL_IAX, ndpi_struct, NDPI_LOG_DEBUG, "found IAX.\n"); + ndpi_int_iax_add_connection(ndpi_struct, flow); + return; + } + if (packet_len > packet->payload_packet_len) { + break; + } + } + + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IAX); + +} + +void ndpi_search_iax(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // struct ndpi_flow_struct *flow=ndpi_struct->flow; + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + if(packet->udp + && (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)) + ndpi_search_setup_iax(ndpi_struct, flow); +} +#endif diff --git a/src/lib/protocols/icecast.c b/src/lib/protocols/icecast.c new file mode 100644 index 000000000..49c6f5fc5 --- /dev/null +++ b/src/lib/protocols/icecast.c @@ -0,0 +1,91 @@ +/* + * icecast.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_ICECAST + +static void ndpi_int_icecast_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_ICECAST, NDPI_CORRELATED_PROTOCOL); +} + +void ndpi_search_icecast_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int8_t i; + + NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "search icecast.\n"); + + if ((packet->payload_packet_len < 500 && + packet->payload_packet_len >= 7 && memcmp(packet->payload, "SOURCE ", 7) == 0) + || flow->l4.tcp.icecast_stage) { + ndpi_parse_packet_line_info_any(ndpi_struct, flow); + NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast lines=%d\n", packet->parsed_lines); + for (i = 0; i < packet->parsed_lines; i++) { + if (packet->line[i].ptr != NULL && packet->line[i].len > 4 + && memcmp(packet->line[i].ptr, "ice-", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast detected.\n"); + ndpi_int_icecast_add_connection(ndpi_struct, flow); + return; + } + } + + if (packet->parsed_lines < 1 && !flow->l4.tcp.icecast_stage) { + flow->l4.tcp.icecast_stage = 1; + return; + } + } +#ifdef NDPI_PROTOCOL_HTTP + if (NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct, flow, NDPI_PROTOCOL_HTTP)) { + goto icecast_exclude; + } +#endif + + if (packet->packet_direction == flow->setup_packet_direction && flow->packet_counter < 10) { + return; + } + + if (packet->packet_direction != flow->setup_packet_direction) { + /* server answer, now test Server for Icecast */ + + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if (packet->server_line.ptr != NULL && packet->server_line.len > NDPI_STATICSTRING_LEN("Icecast") && + memcmp(packet->server_line.ptr, "Icecast", NDPI_STATICSTRING_LEN("Icecast")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast detected.\n"); + /* TODO maybe store the previous protocol type as subtype? + * e.g. ogg or mpeg + */ + ndpi_int_icecast_add_connection(ndpi_struct, flow); + return; + } + } + + icecast_exclude: + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ICECAST); + NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast excluded.\n"); +} +#endif diff --git a/src/lib/protocols/imesh.c b/src/lib/protocols/imesh.c new file mode 100644 index 000000000..1e2238fca --- /dev/null +++ b/src/lib/protocols/imesh.c @@ -0,0 +1,294 @@ +/* + * imesh.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_IMESH + + +static void ndpi_int_imesh_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_IMESH, protocol_type); +} + + +void ndpi_search_imesh_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if (packet->udp != NULL) { + + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "UDP FOUND\n"); + + // this is the login packet + if (packet->payload_packet_len == 28 && (get_u_int32_t(packet->payload, 0)) == htonl(0x02000000) && + get_u_int32_t(packet->payload, 24) == 0 && + (packet->udp->dest == htons(1864) || packet->udp->source == htons(1864))) { + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh Login detected\n"); + ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 36) { + if (get_u_int32_t(packet->payload, 0) == htonl(0x02000000) && packet->payload[4] != 0 && + packet->payload[5] == 0 && get_u_int16_t(packet->payload, 6) == htons(0x0083) && + get_u_int32_t(packet->payload, 24) == htonl(0x40000000) && + (packet->payload[packet->payload_packet_len - 1] == packet->payload[packet->payload_packet_len - 5] || + packet->payload[packet->payload_packet_len - 1] - 1 == packet->payload[packet->payload_packet_len - 5] + || packet->payload[packet->payload_packet_len - 1] == + packet->payload[packet->payload_packet_len - 5] - 1)) { + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh detected\n"); + ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (get_u_int16_t(packet->payload, 0) == htons(0x0200) && get_u_int16_t(packet->payload, 2) != 0 && + get_u_int32_t(packet->payload, 4) == htonl(0x02000083) && get_u_int32_t(packet->payload, 24) == htonl(0x40000000) && + (packet->payload[packet->payload_packet_len - 1] == packet->payload[packet->payload_packet_len - 5] || + packet->payload[packet->payload_packet_len - 1] - 1 == packet->payload[packet->payload_packet_len - 5] + || packet->payload[packet->payload_packet_len - 1] == + packet->payload[packet->payload_packet_len - 5] - 1)) { + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh detected\n"); + ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + if (packet->payload_packet_len == 24 && get_u_int16_t(packet->payload, 0) == htons(0x0200) + && get_u_int16_t(packet->payload, 2) != 0 && get_u_int32_t(packet->payload, 4) == htonl(0x03000084) && + (packet->payload[packet->payload_packet_len - 1] == packet->payload[packet->payload_packet_len - 5] || + packet->payload[packet->payload_packet_len - 1] - 1 == packet->payload[packet->payload_packet_len - 5] || + packet->payload[packet->payload_packet_len - 1] == packet->payload[packet->payload_packet_len - 5] - 1)) { + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh detected\n"); + ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 32 && get_u_int32_t(packet->payload, 0) == htonl(0x02000000) && + get_u_int16_t(packet->payload, 21) == 0 && get_u_int16_t(packet->payload, 26) == htons(0x0100)) { + if (get_u_int32_t(packet->payload, 4) == htonl(0x00000081) && packet->payload[11] == packet->payload[15] && + get_l16(packet->payload, 24) == htons(packet->udp->source)) { + /* packet->payload[28] = source address */ + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh detected\n"); + ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (get_u_int32_t(packet->payload, 4) == htonl(0x01000082)) { + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh detected\n"); + ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh UDP packetlen: %d\n", + packet->payload_packet_len); + + } + + if (packet->tcp != NULL) { + if (packet->payload_packet_len == 64 && get_u_int32_t(packet->payload, 0) == htonl(0x40000000) && + get_u_int32_t(packet->payload, 4) == 0 && get_u_int32_t(packet->payload, 8) == htonl(0x0000fcff) && + get_u_int32_t(packet->payload, 12) == htonl(0x04800100) && get_u_int32_t(packet->payload, 45) == htonl(0xff020000) && + get_u_int16_t(packet->payload, 49) == htons(0x001a)) { + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "found imesh.\n"); + ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 95 && get_u_int32_t(packet->payload, 0) == htonl(0x5f000000) && + get_u_int16_t(packet->payload, 4) == 0 && get_u_int16_t(packet->payload, 7) == htons(0x0004) && + get_u_int32_t(packet->payload, 20) == 0 && get_u_int32_t(packet->payload, 28) == htonl(0xc8000400) && + packet->payload[9] == 0x80 && get_u_int32_t(packet->payload, 10) == get_u_int32_t(packet->payload, 24)) { + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "found imesh.\n"); + ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 28 && get_u_int32_t(packet->payload, 0) == htonl(0x1c000000) && + get_u_int16_t(packet->payload, 10) == htons(0xfcff) && get_u_int32_t(packet->payload, 12) == htonl(0x07801800) && + (get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == htons(0x1900) || + get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == htons(0x1a00))) { + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "found imesh.\n"); + ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "TCP FOUND :: Payload %u\n", + packet->payload_packet_len); + + if (packet->actual_payload_len == 0) { + return; + } + if ((packet->actual_payload_len == 8 || packet->payload_packet_len == 10) /* PATTERN:: 04 00 00 00 00 00 00 00 [00 00] */ + &&get_u_int32_t(packet->payload, 0) == htonl(0x04000000) + && get_u_int32_t(packet->payload, 4) == 0) { + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if (packet->actual_payload_len == 10 /* PATTERN:: ?? ?? 04|00 00 64|00 00 */ + && (packet->payload[2] == 0x04 || packet->payload[2] == 0x00) + && packet->payload[3] == 0x00 && (packet->payload[4] == 0x00 || packet->payload[4] == 0x64) + && packet->payload[5] == 0x00 + && (packet->payload[2] != packet->payload[4]) /* We do not want that the packet is ?? ?? 00 00 00 00 */ + ) { + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if (packet->actual_payload_len == 2 && packet->payload[0] == 0x06 && packet->payload[1] == 0x00) { + flow->l4.tcp.imesh_stage++; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if (packet->actual_payload_len == 10 /* PATTERN:: 06 00 04|00 00 01|00 00 01|00 00 ?? 00 */ + && packet->payload[0] == 0x06 + && packet->payload[1] == 0x00 && (packet->payload[2] == 0x04 || packet->payload[2] == 0x00) + && packet->payload[3] == 0x00 && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01) + && packet->payload[5] == 0x00 && (packet->payload[6] == 0x01 || packet->payload[6] == 0x00) + && packet->payload[7] == 0x00 && packet->payload[9] == 0x00 + && (packet->payload[2] || packet->payload[4] || packet->payload[6]) /* We do not want that the packet is all 06 00 00 ... */ + ) { + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if (packet->actual_payload_len == 24 && packet->payload[0] == 0x06 // PATTERN :: 06 00 12 00 00 00 34 00 00 + && packet->payload[1] == 0x00 + && packet->payload[2] == 0x12 + && packet->payload[3] == 0x00 + && packet->payload[4] == 0x00 + && packet->payload[5] == 0x00 + && packet->payload[6] == 0x34 && packet->payload[7] == 0x00 && packet->payload[8] == 0x00) { + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if (packet->actual_payload_len == 8 /* PATTERN:: 06|00 00 02 00 00 00 33 00 */ + && (packet->payload[0] == 0x06 || packet->payload[0] == 0x00) + && packet->payload[1] == 0x00 + && packet->payload[2] == 0x02 + && packet->payload[3] == 0x00 + && packet->payload[4] == 0x00 + && packet->payload[5] == 0x00 && packet->payload[6] == 0x33 && packet->payload[7] == 0x00) { + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if (packet->payload_packet_len == 6 /* PATTERN:: 02 00 00 00 33 00 */ + && packet->payload[0] == 0x02 + && packet->payload[1] == 0x00 + && packet->payload[2] == 0x00 + && packet->payload[3] == 0x00 && packet->payload[4] == 0x33 && packet->payload[5] == 0x00) { + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if (packet->actual_payload_len == 12 && packet->payload[0] == 0x06 // PATTERN : 06 00 06 00 00 00 64 00 + && packet->payload[1] == 0x00 + && packet->payload[2] == 0x06 + && packet->payload[3] == 0x00 + && packet->payload[4] == 0x00 + && packet->payload[5] == 0x00 && packet->payload[6] == 0x64 && packet->payload[7] == 0x00) { + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if (packet->actual_payload_len == 10 /* PATTERN:: 06 00 04|01 00 00 00 01|00 00 ?? 00 */ + && packet->payload[0] == 0x06 + && packet->payload[1] == 0x00 && (packet->payload[2] == 0x04 || packet->payload[2] == 0x01) + && packet->payload[3] == 0x00 + && packet->payload[4] == 0x00 + && packet->payload[5] == 0x00 && (packet->payload[6] == 0x01 || packet->payload[6] == 0x00) + && packet->payload[7] == 0x00 + /* && packet->payload[8]==0x00 */ + && packet->payload[9] == 0x00) { + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if ((packet->actual_payload_len == 64 || packet->actual_payload_len == 52 /* PATTERN:: [len] 00 00 00 00 */ + || packet->actual_payload_len == 95) + && get_u_int16_t(packet->payload, 0) == (packet->actual_payload_len) + && packet->payload[1] == 0x00 && packet->payload[2] == 0x00 + && packet->payload[3] == 0x00 && packet->payload[4] == 0x00) { + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if (packet->actual_payload_len == 6 && packet->payload[0] == 0x06 // PATTERN : 06 00 04|6c 00|01 00 00 + && packet->payload[1] == 0x00 && (packet->payload[2] == 0x04 || packet->payload[2] == 0x6c) + && (packet->payload[3] == 0x00 || packet->payload[3] == 0x01) + && packet->payload[4] == 0x00 && packet->payload[5] == 0x00) { + + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if (packet->actual_payload_len == 6 /* PATTERN:: [len] ?? ee 00 00 00 */ + && get_u_int16_t(packet->payload, 0) == (packet->actual_payload_len) + && packet->payload[2] == 0xee + && packet->payload[3] == 0x00 && packet->payload[4] == 0x00 && packet->payload[5] == 0x00) { + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } else if (packet->actual_payload_len == 10 /* PATTERN:: 06 00 00 00 00 00 00 00 */ + && packet->payload[0] == 0x06 + && packet->payload[1] == 0x00 + && packet->payload[2] == 0x00 + && packet->payload[3] == 0x00 + && packet->payload[4] == 0x00 + && packet->payload[5] == 0x00 && packet->payload[6] == 0x00 && packet->payload[7] == 0x00) { + flow->l4.tcp.imesh_stage += 2; + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, + "IMESH FOUND :: Payload %u\n", packet->actual_payload_len); + } + + + /* http login */ + if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("POST /registration") && + memcmp(packet->payload, "POST /registration", NDPI_STATICSTRING_LEN("POST /registration")) == 0) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->parsed_lines > 6 && + packet->host_line.ptr != NULL && + packet->host_line.len == NDPI_STATICSTRING_LEN("login.bearshare.com") && + packet->line[1].ptr != NULL && + packet->line[1].len == NDPI_STATICSTRING_LEN("Authorization: Basic Og==") && + packet->line[4].ptr != NULL && + packet->line[4].len == NDPI_STATICSTRING_LEN("Accept-Encoding: identity") && + memcmp(packet->line[1].ptr, "Authorization: Basic Og==", + NDPI_STATICSTRING_LEN("Authorization: Basic Og==")) == 0 && + memcmp(packet->host_line.ptr, "login.bearshare.com", + NDPI_STATICSTRING_LEN("login.bearshare.com")) == 0 && + memcmp(packet->line[4].ptr, "Accept-Encoding: identity", + NDPI_STATICSTRING_LEN("Accept-Encoding: identity")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh Login detected\n"); + ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + /*give one packet tolerance for detection */ + if((flow->l4.tcp.imesh_stage >= 4) + && (flow->l4.tcp.seen_syn && flow->l4.tcp.seen_syn_ack && flow->l4.tcp.seen_ack) /* We have seen the 3-way handshake */) + { + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "found imesh.\n"); + ndpi_int_imesh_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + + if ((flow->packet_counter < 5) || packet->actual_payload_len == 0) { + return; + } + //imesh_not_found_end: + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IMESH); + NDPI_LOG(NDPI_PROTOCOL_IMESH, ndpi_struct, NDPI_LOG_DEBUG, "iMesh excluded at stage %d\n", + packet->tcp != NULL ? flow->l4.tcp.imesh_stage : 0); + +} +#endif diff --git a/src/lib/protocols/ipp.c b/src/lib/protocols/ipp.c new file mode 100644 index 000000000..72a75bc2a --- /dev/null +++ b/src/lib/protocols/ipp.c @@ -0,0 +1,112 @@ +/* + * ipp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_IPP + +static void ndpi_int_ipp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_IPP, protocol_type); +} + +void ndpi_search_ipp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + u_int8_t i; + + NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "search ipp\n"); + if (packet->payload_packet_len > 20) { + + NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, + "searching for a payload with a pattern like 'number(1to8)blanknumber(1to3)ipp://.\n"); + /* this pattern means that there is a printer saying that his state is idle, + * means that he is not printing anything at the moment */ + i = 0; + + if (packet->payload[i] < '0' || packet->payload[i] > '9') { + NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "payload does not begin with a number.\n"); + goto search_for_next_pattern; + } + + for (;;) { + i++; + if (!((packet->payload[i] >= '0' && packet->payload[i] <= '9') || + (packet->payload[i] >= 'a' && packet->payload[i] <= 'f') || + (packet->payload[i] >= 'A' && packet->payload[i] <= 'F')) || i > 8) { + NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, + "read symbols while the symbol is a number.\n"); + break; + } + } + + if (packet->payload[i++] != ' ') { + NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "there is no blank following the number.\n"); + goto search_for_next_pattern; + } + + if (packet->payload[i] < '0' || packet->payload[i] > '9') { + NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "no number following the blank.\n"); + goto search_for_next_pattern; + } + + for (;;) { + i++; + if (packet->payload[i] < '0' || packet->payload[i] > '9' || i > 12) { + NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, + "read symbols while the symbol is a number.\n"); + break; + } + } + + if (memcmp(&packet->payload[i], " ipp://", 7) != 0) { + NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "the string ' ipp://' does not follow.\n"); + goto search_for_next_pattern; + } + + NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "found ipp\n"); + ndpi_int_ipp_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + search_for_next_pattern: + + if (packet->payload_packet_len > 3 && memcmp(packet->payload, "POST", 4) == 0) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->content_line.ptr != NULL && packet->content_line.len > 14 + && memcmp(packet->content_line.ptr, "application/ipp", 15) == 0) { + NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "found ipp via POST ... application/ipp.\n"); + ndpi_int_ipp_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "no ipp detected.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IPP); +} + +#endif diff --git a/src/lib/protocols/irc.c b/src/lib/protocols/irc.c new file mode 100644 index 000000000..1947c3ac9 --- /dev/null +++ b/src/lib/protocols/irc.c @@ -0,0 +1,804 @@ +/* + * irc.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_IRC +#define NDPI_IRC_FIND_LESS(time_err,less) {int t1 = 0; \ + u_int32_t timestamp = time_err[0]; \ + for(t1=0;t1 < NDPI_PROTOCOL_IRC_MAXPORT;t1++) { \ + if(timestamp > time_err[t1]) { \ + timestamp = time_err[t1]; \ + less = t1;}}} + +static void ndpi_int_irc_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_IRC, NDPI_REAL_PROTOCOL); +} + + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +u_int8_t ndpi_is_duplicate(struct ndpi_id_struct *id_t, u_int16_t port) +{ + int index = 0; + while (index < id_t->irc_number_of_port) { + if (port == id_t->irc_port[index]) + return 1; + index++; + } + return 0; +} + +static u_int8_t ndpi_check_for_NOTICE_or_PRIVMSG(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + // + u_int16_t i; + u_int8_t number_of_lines_to_be_searched_for = 0; + for (i = 0; i < packet->payload_packet_len - 7; i++) { + if (packet->payload[i] == 'N' || packet->payload[i] == 'P') { + if (memcmp(&packet->payload[i + 1], "OTICE ", 6) == 0 || memcmp(&packet->payload[i + 1], "RIVMSG ", 7) == 0) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "found NOTICE or PRIVMSG\n"); + return 1; + } + } + if (packet->payload[i] == 0x0a) { + number_of_lines_to_be_searched_for++; + if (number_of_lines_to_be_searched_for == 2) { + return 0; + } + } + } + return 0; + +} + +static u_int8_t ndpi_check_for_Nickname(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t i, packetl = packet->payload_packet_len; + + if (packetl < 4) { + return 0; + } + + for (i = 0; i < (packetl - 4); i++) { + if (packet->payload[i] == 'N' || packet->payload[i] == 'n') { + if ((((packetl - (i + 1)) >= 4) && memcmp(&packet->payload[i + 1], "ick=", 4) == 0) + || (((packetl - (i + 1)) >= 8) && (memcmp(&packet->payload[i + 1], "ickname=", 8) == 0)) + || (((packetl - (i + 1)) >= 8) && (memcmp(&packet->payload[i + 1], "ickName=", 8) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "found HTTP IRC Nickname pattern\n"); + return 1; + } + } + } + return 0; +} + +static u_int8_t ndpi_check_for_cmd(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t i; + + if (packet->payload_packet_len < 4) { + return 0; + } + + for (i = 0; i < packet->payload_packet_len - 4; i++) { + if (packet->payload[i] == 'c') { + if (memcmp(&packet->payload[i + 1], "md=", 3) == 0) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "found HTTP IRC cmd pattern \n"); + return 1; + } + } + } + return 0; +} + +static u_int8_t ndpi_check_for_IRC_traces(const u_int8_t * ptr, u_int16_t len) +{ + u_int16_t i; + + if (len < 4) { + return 0; + } + + for (i = 0; i < len - 4; i++) { + if (ptr[i] == 'i') { + if (memcmp(&ptr[i + 1], "rc.", 3) == 0) { + return 1; + } + } + } + return 0; +} + + +u_int8_t ndpi_search_irc_ssl_detect_ninty_percent_but_very_fast(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + + + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, + "called ndpi_search_irc_ssl_detect_ninty_percent_but_very_fast\n"); + + /* case 1: len 1460, len 1460, len 1176 several times in one direction, than len = 4, 4096, 8192 in the other direction */ + if (packet->payload_packet_len == 1460 + && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0) || (flow->l4.tcp.irc_stage2 == 3 + && flow->l4.tcp.irc_direction == + 1 + packet->packet_direction))) { + flow->l4.tcp.irc_stage2 = 1; + flow->l4.tcp.irc_direction = 1 + packet->packet_direction; + return 1; + } + if (packet->payload_packet_len == 1460 && flow->l4.tcp.irc_stage2 == 1 + && flow->l4.tcp.irc_direction == 1 + packet->packet_direction) { + flow->l4.tcp.irc_stage2 = 2; + return 1; + } + if (packet->payload_packet_len == 1176 && flow->l4.tcp.irc_stage2 == 2 + && flow->l4.tcp.irc_direction == 1 + packet->packet_direction) { + flow->l4.tcp.irc_stage2 = 3; + flow->l4.tcp.irc_0x1000_full = 1; + return 1; + } + if (packet->payload_packet_len == 4 && (flow->l4.tcp.irc_stage2 == 3 || flow->l4.tcp.irc_0x1000_full == 1) + && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 0x1000 + || ntohs(get_u_int16_t(packet->payload, 2)) == + 0x2000)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1460,1460,1176,<-4096||8192"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return 1; + } + /* case 2: len 1448, len 1448, len 1200 several times in one direction, than len = 4, 4096, 8192 in the other direction */ + if (packet->payload_packet_len == 1448 + && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0) || (flow->l4.tcp.irc_stage2 == 6 + && flow->l4.tcp.irc_direction == + 1 + packet->packet_direction))) { + flow->l4.tcp.irc_stage2 = 4; + flow->l4.tcp.irc_direction = 1 + packet->packet_direction; + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "len = 1448 first\n"); + return 1; + } + if (packet->payload_packet_len == 1448 && flow->l4.tcp.irc_stage2 == 4 + && flow->l4.tcp.irc_direction == 1 + packet->packet_direction) { + flow->l4.tcp.irc_stage2 = 5; + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "len = 1448 second \n"); + return 1; + } + if (packet->payload_packet_len == 1200 && flow->l4.tcp.irc_stage2 == 5 + && flow->l4.tcp.irc_direction == 1 + packet->packet_direction) { + flow->l4.tcp.irc_stage2 = 6; + flow->l4.tcp.irc_0x1000_full = 1; + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "len = 1200 \n"); + return 1; + } + if (packet->payload_packet_len == 4 && (flow->l4.tcp.irc_stage2 == 6 || flow->l4.tcp.irc_0x1000_full == 1) + && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 0x1000 + || ntohs(get_u_int16_t(packet->payload, 2)) == + 0x2000)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1448,1448,1200,<-4096||8192"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return 1; + } + /* case 3: several packets with len 1380, 1200, 1024, 1448, 1248, + * than one packet in the other direction with the len or two times the len. */ + if (packet->payload_packet_len == 1380 && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0) + || (flow->l4.tcp.irc_stage2 == 7 + && flow->l4.tcp.irc_direction == 1 + packet->packet_direction))) { + flow->l4.tcp.irc_stage2 = 7; + flow->l4.tcp.irc_direction = 1 + packet->packet_direction; + return 1; + } + if (packet->payload_packet_len == 4 && flow->l4.tcp.irc_stage2 == 7 + && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 1380 + || ntohs(get_u_int16_t(packet->payload, 2)) == + 2760)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1380,<-1380||2760"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return 1; + } + if (packet->payload_packet_len == 1200 && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0) + || (flow->l4.tcp.irc_stage2 == 8 + && flow->l4.tcp.irc_direction == 1 + packet->packet_direction))) { + flow->l4.tcp.irc_stage2 = 8; + flow->l4.tcp.irc_direction = 1 + packet->packet_direction; + return 1; + } + if (packet->payload_packet_len == 4 && flow->l4.tcp.irc_stage2 == 8 + && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 1200 + || ntohs(get_u_int16_t(packet->payload, 2)) == + 2400)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1200,<-1200||2400"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return 1; + } + if (packet->payload_packet_len == 1024 && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0) + || (flow->l4.tcp.irc_stage2 == 9 + && flow->l4.tcp.irc_direction == 1 + packet->packet_direction))) { + flow->l4.tcp.irc_stage2 = 9; + flow->l4.tcp.irc_direction = 1 + packet->packet_direction; + return 1; + } + if (packet->payload_packet_len == 4 && (flow->l4.tcp.irc_stage2 == 9 || flow->l4.tcp.irc_stage2 == 15) + && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 1024 + || ntohs(get_u_int16_t(packet->payload, 2)) == + 2048)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1024,<-1024||2048"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return 1; + } + if (packet->payload_packet_len == 1248 && ((flow->l4.tcp.irc_stage2 == 0 && flow->l4.tcp.irc_direction == 0) + || (flow->l4.tcp.irc_stage2 == 10 + && flow->l4.tcp.irc_direction == 1 + packet->packet_direction))) { + flow->l4.tcp.irc_stage2 = 10; + flow->l4.tcp.irc_direction = 1 + packet->packet_direction; + return 1; + } + if (packet->payload_packet_len == 4 && flow->l4.tcp.irc_stage2 == 10 + && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 1248 + || ntohs(get_u_int16_t(packet->payload, 2)) == + 2496)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1248,<-1248||2496"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return 1; + } + if (packet->payload_packet_len == 1448 + && (flow->l4.tcp.irc_stage2 == 5 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) { + flow->l4.tcp.irc_stage2 = 11; + return 1; + } + if (packet->payload_packet_len == 4 + && (flow->l4.tcp.irc_stage2 == 4 || flow->l4.tcp.irc_stage2 == 5 || flow->l4.tcp.irc_stage2 == 11 + || flow->l4.tcp.irc_stage2 == 13) + && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && (ntohs(get_u_int16_t(packet->payload, 2)) == 1448 + || ntohs(get_u_int16_t(packet->payload, 2)) == + 2896)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1448,<-1448||2896"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return 1; + } + /* case 4 : five packets with len = 1448, one with len 952, than one packet from other direction len = 8192 */ + if (packet->payload_packet_len == 1448 + && (flow->l4.tcp.irc_stage2 == 11 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) { + flow->l4.tcp.irc_stage2 = 12; + return 1; + } + if (packet->payload_packet_len == 1448 + && (flow->l4.tcp.irc_stage2 == 12 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) { + flow->l4.tcp.irc_stage2 = 13; + return 1; + } + if (packet->payload_packet_len == 952 + && (flow->l4.tcp.irc_stage2 == 13 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) { + flow->l4.tcp.irc_stage2 = 14; + return 1; + } + if (packet->payload_packet_len == 4 + && flow->l4.tcp.irc_stage2 == 14 + && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && ntohs(get_u_int16_t(packet->payload, 2)) == 8192) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "IRC SSL detected: ->1448,1448,1448,1448,1448,952,<-8192"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return 1; + } + /* case 5: len 1024, len 1448, len 1448, len 1200, len 1448, len 600 */ + if (packet->payload_packet_len == 1448 + && (flow->l4.tcp.irc_stage2 == 9 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) { + flow->l4.tcp.irc_stage2 = 15; + return 1; + } + if (packet->payload_packet_len == 1448 + && (flow->l4.tcp.irc_stage2 == 15 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) { + flow->l4.tcp.irc_stage2 = 16; + return 1; + } + if (packet->payload_packet_len == 1200 + && (flow->l4.tcp.irc_stage2 == 16 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) { + flow->l4.tcp.irc_stage2 = 17; + return 1; + } + if (packet->payload_packet_len == 1448 + && (flow->l4.tcp.irc_stage2 == 17 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) { + flow->l4.tcp.irc_stage2 = 18; + return 1; + } + if (packet->payload_packet_len == 600 + && (flow->l4.tcp.irc_stage2 == 18 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) { + flow->l4.tcp.irc_stage2 = 19; + return 1; + } + if (packet->payload_packet_len == 4 + && flow->l4.tcp.irc_stage2 == 19 + && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && ntohs(get_u_int16_t(packet->payload, 2)) == 7168) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "IRC SSL detected: ->1024,1448,1448,1200,1448,600,<-7168"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return 1; + } + /* -> 1024, 1380, -> 2404 */ + if (packet->payload_packet_len == 1380 + && (flow->l4.tcp.irc_stage2 == 9 && flow->l4.tcp.irc_direction == 1 + packet->packet_direction)) { + flow->l4.tcp.irc_stage2 = 20; + return 1; + } + if (packet->payload_packet_len == 4 + && flow->l4.tcp.irc_stage2 == 20 + && flow->l4.tcp.irc_direction == 2 - packet->packet_direction && ntohs(get_u_int16_t(packet->payload, 2)) == 2404) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected: ->1024,1380 <-2404"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return 1; + + } + return 0; +} + + +void ndpi_search_irc_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + int less; + u_int16_t c = 0; + u_int16_t c1 = 0; + u_int16_t port = 0; + u_int16_t sport = 0; + u_int16_t dport = 0; + u_int16_t counter = 0; + u_int16_t i = 0; + u_int16_t j = 0; + u_int16_t k = 0; + u_int16_t h; + u_int16_t http_content_ptr_len = 0; + u_int8_t space = 0; + + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "irc : search irc\n"); + if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && flow->packet_counter > 70) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "exclude irc, packet_counter > 70\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IRC); + return; + } + if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && flow->packet_counter > 30 && + flow->l4.tcp.irc_stage2 == 0) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "packet_counter > 30, exclude irc.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IRC); + return; + } + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_IRC) { + if (src != NULL && ((u_int32_t) + (packet->tick_timestamp - src->irc_ts) < ndpi_struct->irc_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "irc : save src connection packet detected\n"); + src->irc_ts = packet->tick_timestamp; + } else if (dst != NULL && ((u_int32_t) + (packet->tick_timestamp - dst->irc_ts) < ndpi_struct->irc_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "irc : save dst connection packet detected\n"); + dst->irc_ts = packet->tick_timestamp; + } + } + + if (((dst != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_IRC) + && ((u_int32_t) + (packet->tick_timestamp - dst->irc_ts)) < + ndpi_struct->irc_timeout)) || (src != NULL + && + NDPI_COMPARE_PROTOCOL_TO_BITMASK + (src->detected_protocol_bitmask, NDPI_PROTOCOL_IRC) + && ((u_int32_t) + (packet->tick_timestamp - src->irc_ts)) < ndpi_struct->irc_timeout)) { + if (packet->tcp != NULL) { + sport = packet->tcp->source; + dport = packet->tcp->dest; + } + if (dst != NULL) { + for (counter = 0; counter < dst->irc_number_of_port; counter++) { + if (dst->irc_port[counter] == sport || dst->irc_port[counter] == dport) { + dst->last_time_port_used[counter] = packet->tick_timestamp; + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "dest port matched with the DCC port and the flow is marked as IRC"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return; + } + } + } + if (src != NULL) { + for (counter = 0; counter < src->irc_number_of_port; counter++) { + if (src->irc_port[counter] == sport || src->irc_port[counter] == dport) { + src->last_time_port_used[counter] = packet->tick_timestamp; + ndpi_int_irc_add_connection(ndpi_struct, flow); + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "Source port matched with the DCC port and the flow is marked as IRC"); + return; + } + } + } + } + + + + if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC + && flow->packet_counter == 2 && (packet->payload_packet_len > 400 && packet->payload_packet_len < 1381)) { + for (c1 = 50; c1 < packet->payload_packet_len - 23; c1++) { + if (packet->payload[c1] == 'i' || packet->payload[c1] == 'd') { + if ((memcmp(&packet->payload[c1], "irc.hackthissite.org0", 21) + == 0) + || (memcmp(&packet->payload[c1], "irc.gamepad.ca1", 15) == 0) + || (memcmp(&packet->payload[c1], "dungeon.axenet.org0", 19) + == 0) + || (memcmp(&packet->payload[c1], "dazed.nuggethaus.net", 20) + == 0) + || (memcmp(&packet->payload[c1], "irc.indymedia.org", 17) + == 0) + || (memcmp(&packet->payload[c1], "irc.cccp-project.net", 20) + == 0) + || (memcmp(&packet->payload[c1], "dirc.followell.net0", 19) + == 0) + || (memcmp(&packet->payload[c1], "irc.discostars.de1", 18) + == 0) + || (memcmp(&packet->payload[c1], "irc.rizon.net", 13) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "IRC SSL detected with :- irc.hackthissite.org0 | irc.gamepad.ca1 | dungeon.axenet.org0 " + "| dazed.nuggethaus.net | irc.indymedia.org | irc.discostars.de1 "); + ndpi_int_irc_add_connection(ndpi_struct, flow); + break; + } + } + } + } + if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && + ndpi_search_irc_ssl_detect_ninty_percent_but_very_fast(ndpi_struct, flow) != 0) { + return; + } + + if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && flow->packet_counter < 20 + && packet->payload_packet_len >= 8) { + if (get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x0a + || (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0a00)) { + if (memcmp(packet->payload, ":", 1) == 0) { + if (packet->payload[packet->payload_packet_len - 2] != 0x0d + && packet->payload[packet->payload_packet_len - 1] == 0x0a) { + ndpi_parse_packet_line_info_any(ndpi_struct, flow); + } else if (packet->payload[packet->payload_packet_len - 2] == 0x0d) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + } else { + flow->l4.tcp.irc_3a_counter++; + } + for (i = 0; i < packet->parsed_lines; i++) { + if (packet->line[i].ptr[0] == ':') { + flow->l4.tcp.irc_3a_counter++; + if (flow->l4.tcp.irc_3a_counter == 7) { /* ':' == 0x3a */ + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "0x3a. seven times. found irc."); + ndpi_int_irc_add_connection(ndpi_struct, flow); + goto detected_irc; + } + } + } + if (flow->l4.tcp.irc_3a_counter == 7) { /* ':' == 0x3a */ + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "0x3a. seven times. found irc."); + ndpi_int_irc_add_connection(ndpi_struct, flow); + goto detected_irc; + } + } + if ((memcmp(packet->payload, "USER ", 5) == 0) + || (memcmp(packet->payload, "NICK ", 5) == 0) + || (memcmp(packet->payload, "PASS ", 5) == 0) + || (memcmp(packet->payload, ":", 1) == 0 && ndpi_check_for_NOTICE_or_PRIVMSG(ndpi_struct, flow) != 0) + || (memcmp(packet->payload, "PONG ", 5) == 0) + || (memcmp(packet->payload, "PING ", 5) == 0) + || (memcmp(packet->payload, "JOIN ", 5) == 0) + || (memcmp(packet->payload, "NOTICE ", 7) == 0) + || (memcmp(packet->payload, "PRIVMSG ", 8) == 0) + || (memcmp(packet->payload, "VERSION ", 8) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "USER, NICK, PASS, NOTICE, PRIVMSG one time"); + if (flow->l4.tcp.irc_stage == 2) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "found irc"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + flow->l4.tcp.irc_stage = 3; + } + if (flow->l4.tcp.irc_stage == 1) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "second time, stage=2"); + flow->l4.tcp.irc_stage = 2; + } + if (flow->l4.tcp.irc_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "first time, stage=1"); + flow->l4.tcp.irc_stage = 1; + } + /* irc packets can have either windows line breaks (0d0a) or unix line breaks (0a) */ + if (packet->payload[packet->payload_packet_len - 2] == 0x0d + && packet->payload[packet->payload_packet_len - 1] == 0x0a) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->parsed_lines > 1) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "packet contains more than one line"); + for (c = 1; c < packet->parsed_lines; c++) { + if (packet->line[c].len > 4 && (memcmp(packet->line[c].ptr, "NICK ", 5) == 0 + || memcmp(packet->line[c].ptr, "USER ", 5) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, + NDPI_LOG_TRACE, "two icq signal words in the same packet"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + flow->l4.tcp.irc_stage = 3; + return; + } + } + } + + } else if (packet->payload[packet->payload_packet_len - 1] == 0x0a) { + ndpi_parse_packet_line_info_any(ndpi_struct, flow); + if (packet->parsed_lines > 1) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "packet contains more than one line"); + for (c = 1; c < packet->parsed_lines; c++) { + if (packet->line[c].len > 4 && (memcmp(packet->line[c].ptr, "NICK ", 5) == 0 + || memcmp(packet->line[c].ptr, "USER ", + 5) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "two icq signal words in the same packet"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + flow->l4.tcp.irc_stage = 3; + return; + } + } + } + } + } + } + } + + /** + * Trying to primarily detect the HTTP Web based IRC chat patterns based on the HTTP headers + * during the User login time.When the HTTP data gets posted using the POST method ,patterns + * will be searched in the HTTP content. + */ + if ((flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC) && (flow->l4.tcp.irc_stage == 0) + && (packet->payload_packet_len > 5)) { + //HTTP POST Method being employed + if (memcmp(packet->payload, "POST ", 5) == 0) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->parsed_lines) { + u_int16_t http_header_len = (packet->line[packet->parsed_lines - 1].ptr - packet->payload) + 2; + if (packet->payload_packet_len > http_header_len) { + http_content_ptr_len = packet->payload_packet_len - http_header_len; + } + if ((ndpi_check_for_IRC_traces(packet->line[0].ptr, packet->line[0].len)) + || ((packet->http_url_name.ptr) + && (ndpi_check_for_IRC_traces(packet->http_url_name.ptr, packet->http_url_name.len))) + || ((packet->referer_line.ptr) + && (ndpi_check_for_IRC_traces(packet->referer_line.ptr, packet->referer_line.len)))) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "IRC detected from the Http URL/ Referer header "); + flow->l4.tcp.irc_stage = 1; + // HTTP POST Request body is not in the same packet. + if (!http_content_ptr_len) { + return; + } + } + } + } + } + + if ((flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC) && (flow->l4.tcp.irc_stage == 1)) { + if ((((packet->payload_packet_len - http_content_ptr_len) > 10) + && (memcmp(packet->payload + http_content_ptr_len, "interface=", 10) == 0) + && (ndpi_check_for_Nickname(ndpi_struct, flow) != 0)) + || (((packet->payload_packet_len - http_content_ptr_len) > 5) + && (memcmp(packet->payload + http_content_ptr_len, "item=", 5) == 0) + && (ndpi_check_for_cmd(ndpi_struct, flow) != 0))) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC Nickname, cmd, one time"); + ndpi_int_irc_add_connection(ndpi_struct, flow); + return; + } + } + + detected_irc: + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "detected_irc:"); + + if (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_IRC) { + /* maybe this can be deleted at the end */ + + if (packet->payload[packet->payload_packet_len - 2] != 0x0d + && packet->payload[packet->payload_packet_len - 1] == 0x0a) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, + "ndpi_parse_packet_line_info_any(ndpi_struct, flow);"); + ndpi_parse_packet_line_info_any(ndpi_struct, flow); + } else if (packet->payload[packet->payload_packet_len - 2] == 0x0d) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + } else { + return; + } + for (i = 0; i < packet->parsed_lines; i++) { + if (packet->line[i].len > 6 && memcmp(packet->line[i].ptr, "NOTICE ", 7) == 0) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "NOTICE"); + for (j = 7; j < packet->line[i].len - 8; j++) { + if (packet->line[i].ptr[j] == ':') { + if (memcmp(&packet->line[i].ptr[j + 1], "DCC SEND ", 9) == 0 + || memcmp(&packet->line[i].ptr[j + 1], "DCC CHAT ", 9) == 0) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "found NOTICE and DCC CHAT or DCC SEND."); + } + } + } + } + if (packet->payload_packet_len > 0 && packet->payload[0] == 0x3a /* 0x3a = ':' */ ) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "3a"); + for (j = 1; j < packet->line[i].len - 9; j++) { + if (packet->line[i].ptr[j] == ' ') { + j++; + if (packet->line[i].ptr[j] == 'P') { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "P"); + j++; + if (memcmp(&packet->line[i].ptr[j], "RIVMSG ", 7) == 0) + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "RIVMSG"); + h = j + 7; + goto read_privmsg; + } + } + } + } + if (packet->line[i].len > 7 && (memcmp(packet->line[i].ptr, "PRIVMSG ", 8) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "PRIVMSG "); + h = 7; + read_privmsg: + for (j = h; j < packet->line[i].len - 9; j++) { + if (packet->line[i].ptr[j] == ':') { + if (memcmp(&packet->line[i].ptr[j + 1], "xdcc ", 5) == 0) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "xdcc should match."); + } + j += 2; + if (memcmp(&packet->line[i].ptr[j], "DCC ", 4) == 0) { + j += 4; + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "found DCC."); + if (memcmp(&packet->line[i].ptr[j], "SEND ", 5) == 0 + || (memcmp(&packet->line[i].ptr[j], "CHAT", 4) == 0) + || (memcmp(&packet->line[i].ptr[j], "chat", 4) == 0) + || (memcmp(&packet->line[i].ptr[j], "sslchat", 7) == 0) + || (memcmp(&packet->line[i].ptr[j], "TSEND", 5) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "found CHAT,chat,sslchat,TSEND."); + j += 4; + + while (packet->line[i].len > j && + ((packet->line[i].ptr[j] >= 'a' && packet->line[i].ptr[j] <= 'z') + || (packet->line[i].ptr[j] >= 'A' && packet->line[i].ptr[j] <= 'Z') + || (packet->line[i].ptr[j] >= '0' && packet->line[i].ptr[j] <= '9') + || (packet->line[i].ptr[j] >= ' ') + || (packet->line[i].ptr[j] >= '.') + || (packet->line[i].ptr[j] >= '-'))) { + + if (packet->line[i].ptr[j] == ' ') { + space++; + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "space %u.", space); + } + if (space == 3) { + j++; + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "read port."); + if (src != NULL) { + k = j; + port = + ntohs_ndpi_bytestream_to_number + (&packet->line[i].ptr[j], packet->payload_packet_len - j, &j); + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "port %u.", + port); + j = k; + // hier jetzt überlegen, wie die ports abgespeichert werden sollen + if (src->irc_number_of_port < NDPI_PROTOCOL_IRC_MAXPORT) + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, + "src->irc_number_of_port < NDPI_PROTOCOL_IRC_MAXPORT."); + if (src->irc_number_of_port < NDPI_PROTOCOL_IRC_MAXPORT && port != 0) { + if (!ndpi_is_duplicate(src, port)) { + src->irc_port[src->irc_number_of_port] + = port; + src->irc_number_of_port++; + NDPI_LOG + (NDPI_PROTOCOL_IRC, + ndpi_struct, + NDPI_LOG_DEBUG, "found port=%d", + ntohs(get_u_int16_t(src->irc_port, 0))); + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, + "jjeeeeeeeeeeeeeeeeeeeeeeeee"); + } + src->irc_ts = packet->tick_timestamp; + } else if (port != 0 && src->irc_number_of_port == NDPI_PROTOCOL_IRC_MAXPORT) { + if (!ndpi_is_duplicate(src, port)) { + less = 0; + NDPI_IRC_FIND_LESS(src->last_time_port_used, less); + src->irc_port[less] = port; + NDPI_LOG + (NDPI_PROTOCOL_IRC, + ndpi_struct, + NDPI_LOG_DEBUG, "found port=%d", + ntohs(get_u_int16_t(src->irc_port, 0))); + } + src->irc_ts = packet->tick_timestamp; + } + if (dst == NULL) { + break; + } + } + if (dst != NULL) { + port = ntohs_ndpi_bytestream_to_number + (&packet->line[i].ptr[j], packet->payload_packet_len - j, &j); + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "port %u.", + port); + // hier das gleiche wie oben. + /* hier werden NDPI_PROTOCOL_IRC_MAXPORT ports pro irc flows mitgespeichert. könnte man denn nicht ein- + * fach an die dst oder src einen flag setzten, dass dieser port für eine bestimmte + * zeit ein irc-port bleibt? + */ + if (dst->irc_number_of_port < NDPI_PROTOCOL_IRC_MAXPORT && port != 0) { + if (!ndpi_is_duplicate(dst, port)) { + dst->irc_port[dst->irc_number_of_port] + = port; + dst->irc_number_of_port++; + NDPI_LOG + (NDPI_PROTOCOL_IRC, + ndpi_struct, + NDPI_LOG_DEBUG, "found port=%d", + ntohs(get_u_int16_t(dst->irc_port, 0))); + NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, + "juuuuuuuuuuuuuuuu"); + } + dst->irc_ts = packet->tick_timestamp; + } else if (port != 0 && dst->irc_number_of_port == NDPI_PROTOCOL_IRC_MAXPORT) { + if (!ndpi_is_duplicate(dst, port)) { + less = 0; + NDPI_IRC_FIND_LESS(dst->last_time_port_used, less); + dst->irc_port[less] = port; + + NDPI_LOG + (NDPI_PROTOCOL_IRC, + ndpi_struct, + NDPI_LOG_DEBUG, "found port=%d", + ntohs(get_u_int16_t(dst->irc_port, 0))); + } + dst->irc_ts = packet->tick_timestamp; + } + + break; + } + } + + + j++; + } + + } + } + } + } + + } + } + } +} + +#endif diff --git a/src/lib/protocols/jabber.c b/src/lib/protocols/jabber.c new file mode 100644 index 000000000..7b78febb1 --- /dev/null +++ b/src/lib/protocols/jabber.c @@ -0,0 +1,311 @@ +/* + * jabber.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER +struct jabber_string { + char *string; + u_int ndpi_protocol; +}; + +static struct jabber_string jabber_strings[] = { +#ifdef NDPI_PROTOCOL_TRUPHONE + { "='im.truphone.com'", NDPI_PROTOCOL_TRUPHONE }, + { "=\"im.truphone.com\"", NDPI_PROTOCOL_TRUPHONE }, +#endif + +#ifdef NDPI_SERVICE_FACEBOOK_CHAT + { "to='chat.facebook.com'", NDPI_SERVICE_FACEBOOK_CHAT }, +#endif + { NULL, 0 } +}; + +static void ndpi_int_jabber_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int32_t protocol, ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, protocol, protocol_type); +} + +static void check_content_type_and_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, u_int16_t x) +{ + struct ndpi_packet_struct *packet = &flow->packet; + int i, left = packet->payload_packet_len-x; + + if(left <= 0) return; + + for(i=0; jabber_strings[i].string != NULL; i++) { + if(ndpi_strnstr((const char*)&packet->payload[x], jabber_strings[i].string, left) != NULL) { + ndpi_int_jabber_add_connection(ndpi_struct, flow, jabber_strings[i].ndpi_protocol, NDPI_CORRELATED_PROTOCOL); + return; + } + } +} + +void ndpi_search_jabber_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + u_int16_t x; + + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_TRACE, "JABBER detection....\n"); + + /* search for jabber file transfer */ + /* this part is working asymmetrically */ + if (packet->tcp != NULL && packet->tcp->syn != 0 && packet->payload_packet_len == 0) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "check jabber syn\n"); + if (src != NULL && src->jabber_file_transfer_port[0] != 0) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, + "src jabber ft port set, ports are: %u, %u\n", ntohs(src->jabber_file_transfer_port[0]), + ntohs(src->jabber_file_transfer_port[1])); + if (((u_int32_t) + (packet->tick_timestamp - src->jabber_stun_or_ft_ts)) >= ndpi_struct->jabber_file_transfer_timeout) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, + NDPI_LOG_DEBUG, "JABBER src stun timeout %u %u\n", src->jabber_stun_or_ft_ts, + packet->tick_timestamp); + src->jabber_file_transfer_port[0] = 0; + src->jabber_file_transfer_port[1] = 0; + } else if (src->jabber_file_transfer_port[0] == packet->tcp->dest + || src->jabber_file_transfer_port[0] == packet->tcp->source + || src->jabber_file_transfer_port[1] == packet->tcp->dest + || src->jabber_file_transfer_port[1] == packet->tcp->source) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, + "found jabber file transfer.\n"); + + ndpi_int_jabber_add_connection(ndpi_struct, flow, + NDPI_PROTOCOL_UNENCRYPED_JABBER, NDPI_CORRELATED_PROTOCOL); + } + } + if (dst != NULL && dst->jabber_file_transfer_port[0] != 0) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, + "dst jabber ft port set, ports are: %u, %u\n", ntohs(dst->jabber_file_transfer_port[0]), + ntohs(dst->jabber_file_transfer_port[1])); + if (((u_int32_t) + (packet->tick_timestamp - dst->jabber_stun_or_ft_ts)) >= ndpi_struct->jabber_file_transfer_timeout) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, + NDPI_LOG_DEBUG, "JABBER dst stun timeout %u %u\n", dst->jabber_stun_or_ft_ts, + packet->tick_timestamp); + dst->jabber_file_transfer_port[0] = 0; + dst->jabber_file_transfer_port[1] = 0; + } else if (dst->jabber_file_transfer_port[0] == packet->tcp->dest + || dst->jabber_file_transfer_port[0] == packet->tcp->source + || dst->jabber_file_transfer_port[1] == packet->tcp->dest + || dst->jabber_file_transfer_port[1] == packet->tcp->source) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, + "found jabber file transfer.\n"); + + ndpi_int_jabber_add_connection(ndpi_struct, flow, + NDPI_PROTOCOL_UNENCRYPED_JABBER, NDPI_CORRELATED_PROTOCOL); + } + } + return; + } + + if (packet->tcp != 0 && packet->payload_packet_len == 0) { + return; + } + + + /* this part parses a packet and searches for port=. it works asymmetrically. */ + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNENCRYPED_JABBER) { + u_int16_t lastlen; + u_int16_t j_port = 0; + /* check for google jabber voip connections ... */ + /* need big packet */ + if (packet->payload_packet_len < 100) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "packet too small, return.\n"); + return; + } + /* need message to or type for file-transfer */ + if (memcmp(packet->payload, "<iq from=\"", 8) == 0 || memcmp(packet->payload, "<iq from=\'", 8) == 0) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER <iq from=\".\n"); + lastlen = packet->payload_packet_len - 11; + for (x = 10; x < lastlen; x++) { + if (packet->payload[x] == 'p') { + if (memcmp(&packet->payload[x], "port=", 5) == 0) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "port=\n"); + if (src != NULL) { + src->jabber_stun_or_ft_ts = packet->tick_timestamp; + } + + if (dst != NULL) { + dst->jabber_stun_or_ft_ts = packet->tick_timestamp; + } + x += 6; + j_port = ntohs_ndpi_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x); + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, + NDPI_LOG_DEBUG, "JABBER port : %u\n", ntohs(j_port)); + if (src != NULL) { + if (src->jabber_file_transfer_port[0] == 0 || src->jabber_file_transfer_port[0] == j_port) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, + NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[0] = j_port = %u;\n", + ntohs(j_port)); + src->jabber_file_transfer_port[0] = j_port; + } else { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, + NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[1] = j_port = %u;\n", + ntohs(j_port)); + src->jabber_file_transfer_port[1] = j_port; + } + } + if (dst != NULL) { + if (dst->jabber_file_transfer_port[0] == 0 || dst->jabber_file_transfer_port[0] == j_port) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, + NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[0] = j_port = %u;\n", + ntohs(j_port)); + dst->jabber_file_transfer_port[0] = j_port; + } else { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, + NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[1] = j_port = %u;\n", + ntohs(j_port)); + dst->jabber_file_transfer_port[1] = j_port; + } + } + } + + + } + } + + } else if (memcmp(packet->payload, "<iq to=\"", 8) == 0 || memcmp(packet->payload, "<iq to=\'", 8) == 0 + || memcmp(packet->payload, "<iq type=", 9) == 0) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER <iq to=\"/type=\"\n"); + lastlen = packet->payload_packet_len - 21; + for (x = 8; x < lastlen; x++) { + /* invalid character */ + if (packet->payload[x] < 32 || packet->payload[x] > 127) { + return; + } + if (packet->payload[x] == '@') { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER @\n"); + break; + } + } + if (x >= lastlen) { + return; + } + + lastlen = packet->payload_packet_len - 10; + for (; x < lastlen; x++) { + if (packet->payload[x] == 'p') { + if (memcmp(&packet->payload[x], "port=", 5) == 0) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "port=\n"); + if (src != NULL) { + src->jabber_stun_or_ft_ts = packet->tick_timestamp; + } + + if (dst != NULL) { + dst->jabber_stun_or_ft_ts = packet->tick_timestamp; + } + + x += 6; + j_port = ntohs_ndpi_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x); + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, + NDPI_LOG_DEBUG, "JABBER port : %u\n", ntohs(j_port)); + + if (src != NULL && src->jabber_voice_stun_used_ports < JABBER_MAX_STUN_PORTS - 1) { + if (packet->payload[5] == 'o') { + src->jabber_voice_stun_port[src->jabber_voice_stun_used_ports++] + = j_port; + } else { + if (src->jabber_file_transfer_port[0] == 0 + || src->jabber_file_transfer_port[0] == j_port) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, + "src->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port)); + src->jabber_file_transfer_port[0] = j_port; + } else { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, + NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[1] = j_port = %u;\n", + ntohs(j_port)); + src->jabber_file_transfer_port[1] = j_port; + } + } + } + + if (dst != NULL && dst->jabber_voice_stun_used_ports < JABBER_MAX_STUN_PORTS - 1) { + if (packet->payload[5] == 'o') { + dst->jabber_voice_stun_port[dst->jabber_voice_stun_used_ports++] + = j_port; + } else { + if (dst->jabber_file_transfer_port[0] == 0 + || dst->jabber_file_transfer_port[0] == j_port) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, + "dst->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port)); + dst->jabber_file_transfer_port[0] = j_port; + } else { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, + NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[1] = j_port = %u;\n", + ntohs(j_port)); + dst->jabber_file_transfer_port[1] = j_port; + } + } + } + return; + } + } + } + } + return; + } + + + /* search for jabber here */ + /* this part is working asymmetrically */ + if ((packet->payload_packet_len > 13 && memcmp(packet->payload, "<?xml version=", 14) == 0) + || (packet->payload_packet_len >= NDPI_STATICSTRING_LEN("<stream:stream ") + && memcmp(packet->payload, "<stream:stream ", NDPI_STATICSTRING_LEN("<stream:stream ")) == 0)) { + int start = packet->payload_packet_len-13; + + if(ndpi_strnstr((const char *)&packet->payload[13], "xmlns:stream='http://etherx.jabber.org/streams'", start) + || ndpi_strnstr((const char *)&packet->payload[13], "xmlns:stream=\"http://etherx.jabber.org/streams\"", start)) { + + /* Protocol family */ + ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER, NDPI_REAL_PROTOCOL); + + /* search for subprotocols */ + check_content_type_and_change_protocol(ndpi_struct, flow, 13); + return; + } + } + + if (flow->packet_counter < 3) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, + NDPI_LOG_DEBUG, "packet_counter: %u\n", flow->packet_counter); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_TRACE, "JABBER Excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER); + +#ifdef NDPI_PROTOCOL_TRUPHONE + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TRUPHONE); +#endif +} + +#endif diff --git a/src/lib/protocols/kerberos.c b/src/lib/protocols/kerberos.c new file mode 100644 index 000000000..b04265fc5 --- /dev/null +++ b/src/lib/protocols/kerberos.c @@ -0,0 +1,82 @@ +/* + * kerberos.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +/* include files */ + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_KERBEROS + +static void ndpi_int_kerberos_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_KERBEROS, NDPI_REAL_PROTOCOL); +} + + +void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + + /* I have observed 0a,0c,0d,0e at packet->payload[19/21], maybe there are other possibilities */ + if (packet->payload_packet_len >= 4 && ntohl(get_u_int32_t(packet->payload, 0)) == packet->payload_packet_len - 4) { + if (packet->payload_packet_len > 19 && + packet->payload[14] == 0x05 && + (packet->payload[19] == 0x0a || + packet->payload[19] == 0x0c || packet->payload[19] == 0x0d || packet->payload[19] == 0x0e)) { + NDPI_LOG(NDPI_PROTOCOL_KERBEROS, ndpi_struct, NDPI_LOG_DEBUG, "found KERBEROS\n"); + ndpi_int_kerberos_add_connection(ndpi_struct, flow); + return; + + } + if (packet->payload_packet_len > 21 && + packet->payload[16] == 0x05 && + (packet->payload[21] == 0x0a || + packet->payload[21] == 0x0c || packet->payload[21] == 0x0d || packet->payload[21] == 0x0e)) { + NDPI_LOG(NDPI_PROTOCOL_KERBEROS, ndpi_struct, NDPI_LOG_DEBUG, "found KERBEROS\n"); + ndpi_int_kerberos_add_connection(ndpi_struct, flow); + return; + + } + + + + } + + + + + + + + + NDPI_LOG(NDPI_PROTOCOL_KERBEROS, ndpi_struct, NDPI_LOG_DEBUG, "no KERBEROS detected.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_KERBEROS); +} + +#endif diff --git a/src/lib/protocols/kontiki.c b/src/lib/protocols/kontiki.c new file mode 100644 index 000000000..72ba1acab --- /dev/null +++ b/src/lib/protocols/kontiki.c @@ -0,0 +1,65 @@ +/* + * kontiki.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_KONTIKI + +static void ndpi_int_kontiki_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_KONTIKI, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_kontiki(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + + if (packet->payload_packet_len == 4 && (get_u_int32_t(packet->payload, 0) == htonl(0x02010100))) { + NDPI_LOG(NDPI_PROTOCOL_KONTIKI, ndpi_struct, NDPI_LOG_DEBUG, "Kontiki UDP detected.\n"); + ndpi_int_kontiki_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len > 0 && packet->payload[0] == 0x02) { + + if (packet->payload_packet_len == 20 && (get_u_int32_t(packet->payload, 16) == htonl(0x02040100))) { + NDPI_LOG(NDPI_PROTOCOL_KONTIKI, ndpi_struct, NDPI_LOG_DEBUG, "Kontiki UDP detected.\n"); + ndpi_int_kontiki_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len == 16 && (get_u_int32_t(packet->payload, 12) == htonl(0x000004e4))) { + NDPI_LOG(NDPI_PROTOCOL_KONTIKI, ndpi_struct, NDPI_LOG_DEBUG, "Kontiki UDP detected.\n"); + ndpi_int_kontiki_add_connection(ndpi_struct, flow); + return; + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_KONTIKI); +} + +#endif diff --git a/src/lib/protocols/ldap.c b/src/lib/protocols/ldap.c new file mode 100644 index 000000000..44313156e --- /dev/null +++ b/src/lib/protocols/ldap.c @@ -0,0 +1,101 @@ +/* + * ldap.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +/* include files */ + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_LDAP + +static void ndpi_int_ldap_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_LDAP, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_ldap(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + +// u_int16_t dport; + + + + NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "search ldap\n"); + + + if (packet->payload_packet_len >= 14 && packet->payload[0] == 0x30) { + + // simple type + if (packet->payload[1] == 0x0c && packet->payload_packet_len == 14 && + packet->payload[packet->payload_packet_len - 1] == 0x00 && packet->payload[2] == 0x02) { + + if (packet->payload[3] == 0x01 && + (packet->payload[5] == 0x60 || packet->payload[5] == 0x61) && packet->payload[6] == 0x07) { + NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "found ldap simple type 1\n"); + ndpi_int_ldap_add_connection(ndpi_struct, flow); + return; + } + + if (packet->payload[3] == 0x02 && + (packet->payload[6] == 0x60 || packet->payload[6] == 0x61) && packet->payload[7] == 0x07) { + NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "found ldap simple type 2\n"); + ndpi_int_ldap_add_connection(ndpi_struct, flow); + return; + } + } + // normal type + if (packet->payload[1] == 0x84 && packet->payload_packet_len >= 0x84 && + packet->payload[2] == 0x00 && packet->payload[3] == 0x00 && packet->payload[6] == 0x02) { + + if (packet->payload[7] == 0x01 && + (packet->payload[9] == 0x60 || packet->payload[9] == 0x61 || packet->payload[9] == 0x63 || + packet->payload[9] == 0x64) && packet->payload[10] == 0x84) { + + NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "found ldap type 1\n"); + ndpi_int_ldap_add_connection(ndpi_struct, flow); + return; + } + + if (packet->payload[7] == 0x02 && + (packet->payload[10] == 0x60 || packet->payload[10] == 0x61 || packet->payload[10] == 0x63 || + packet->payload[10] == 0x64) && packet->payload[11] == 0x84) { + + NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "found ldap type 2\n"); + ndpi_int_ldap_add_connection(ndpi_struct, flow); + return; + } + } + } + + + NDPI_LOG(NDPI_PROTOCOL_LDAP, ndpi_struct, NDPI_LOG_DEBUG, "ldap excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_LDAP); +} + +#endif diff --git a/src/lib/protocols/lotus_notes.c b/src/lib/protocols/lotus_notes.c new file mode 100644 index 000000000..6294bce20 --- /dev/null +++ b/src/lib/protocols/lotus_notes.c @@ -0,0 +1,87 @@ +/* + * lotus_notes.c + * + * Copyright (C) 2012-15 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_LOTUS_NOTES + +/* ************************************ */ + +static void ndpi_check_lotus_notes(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // const u_int8_t *packet_payload = packet->payload; + u_int32_t payload_len = packet->payload_packet_len; + + if(packet->tcp != NULL) { + flow->l4.tcp.lotus_notes_packet_id++; + +#if 0 + printf("[lotus_notes_packet_id: %u][len=%u][%02X %02X %02X %02X %02X %02X %02X %02X]\n", + flow->l4.tcp.lotus_notes_packet_id, payload_len, + packet->payload[6] & 0xFF, + packet->payload[7] & 0xFF, + packet->payload[8] & 0xFF, + packet->payload[9] & 0xFF, + packet->payload[10] & 0xFF, + packet->payload[11] & 0xFF, + packet->payload[12] & 0xFF, + packet->payload[13] & 0xFF + ); +#endif + + if((flow->l4.tcp.lotus_notes_packet_id == 1) + /* We have seen the 3-way handshake */ + && flow->l4.tcp.seen_syn + && flow->l4.tcp.seen_syn_ack + && flow->l4.tcp.seen_ack) { + if(payload_len > 16) { + char lotus_notes_header[] = { 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0x02, 0x0F }; + + if(memcmp(&packet->payload[6], lotus_notes_header, sizeof(lotus_notes_header)) == 0) { + NDPI_LOG(NDPI_PROTOCOL_LOTUS_NOTES, ndpi_struct, NDPI_LOG_DEBUG, "Found lotus_notes.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_LOTUS_NOTES, NDPI_REAL_PROTOCOL); + } + + return; + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_LOTUS_NOTES); + } else if(flow->l4.tcp.lotus_notes_packet_id > 3) + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_LOTUS_NOTES); + + return; + } +} + +void ndpi_search_lotus_notes(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_LOTUS_NOTES, ndpi_struct, NDPI_LOG_DEBUG, "lotus_notes detection...\n"); + + /* skip marked packets */ + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_LOTUS_NOTES) + ndpi_check_lotus_notes(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/mail_imap.c b/src/lib/protocols/mail_imap.c new file mode 100644 index 000000000..11a02a8f5 --- /dev/null +++ b/src/lib/protocols/mail_imap.c @@ -0,0 +1,293 @@ +/* + * mail_imap.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_MAIL_IMAP + +static void ndpi_int_mail_imap_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_IMAP, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t i = 0; + u_int16_t space_pos = 0; + u_int16_t command_start = 0; + u_int8_t saw_command = 0; + /* const u_int8_t *command = 0; */ + + NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "search IMAP.\n"); + + if (packet->payload_packet_len >= 4 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) { + // the DONE command appears without a tag + if (packet->payload_packet_len == 6 && ((packet->payload[0] == 'D' || packet->payload[0] == 'd') + && (packet->payload[1] == 'O' || packet->payload[1] == 'o') + && (packet->payload[2] == 'N' || packet->payload[2] == 'n') + && (packet->payload[3] == 'E' || packet->payload[3] == 'e'))) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } else { + + if (flow->l4.tcp.mail_imap_stage < 4) { + // search for the first space character (end of the tag) + while (i < 20 && i < packet->payload_packet_len) { + if (i > 0 && packet->payload[i] == ' ') { + space_pos = i; + break; + } + if (!((packet->payload[i] >= 'a' && packet->payload[i] <= 'z') || + (packet->payload[i] >= 'A' && packet->payload[i] <= 'Z') || + (packet->payload[i] >= '0' && packet->payload[i] <= '9') || packet->payload[i] == '*')) { + goto imap_excluded; + } + i++; + } + if (space_pos == 0 || space_pos == (packet->payload_packet_len - 1)) { + goto imap_excluded; + } + // now walk over a possible mail number to the next space + i++; + if (i < packet->payload_packet_len && (packet->payload[i] >= '0' && packet->payload[i] <= '9')) { + while (i < 20 && i < packet->payload_packet_len) { + if (i > 0 && packet->payload[i] == ' ') { + space_pos = i; + break; + } + if (!(packet->payload[i] >= '0' && packet->payload[i] <= '9')) { + goto imap_excluded; + } + i++; + } + if (space_pos == 0 || space_pos == (packet->payload_packet_len - 1)) { + goto imap_excluded; + } + } + command_start = space_pos + 1; + /* command = &(packet->payload[command_start]); */ + } else { + command_start = 0; + /* command = &(packet->payload[command_start]); */ + } + + if ((command_start + 3) < packet->payload_packet_len) { + if ((packet->payload[command_start] == 'O' || packet->payload[command_start] == 'o') + && (packet->payload[command_start + 1] == 'K' || packet->payload[command_start + 1] == 'k') + && packet->payload[command_start + 2] == ' ') { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } else if ((packet->payload[command_start] == 'U' || packet->payload[command_start] == 'u') + && (packet->payload[command_start + 1] == 'I' || packet->payload[command_start + 1] == 'i') + && (packet->payload[command_start + 2] == 'D' || packet->payload[command_start + 2] == 'd')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } + } + if ((command_start + 10) < packet->payload_packet_len) { + if ((packet->payload[command_start] == 'C' || packet->payload[command_start] == 'c') + && (packet->payload[command_start + 1] == 'A' || packet->payload[command_start + 1] == 'a') + && (packet->payload[command_start + 2] == 'P' || packet->payload[command_start + 2] == 'p') + && (packet->payload[command_start + 3] == 'A' || packet->payload[command_start + 3] == 'a') + && (packet->payload[command_start + 4] == 'B' || packet->payload[command_start + 4] == 'b') + && (packet->payload[command_start + 5] == 'I' || packet->payload[command_start + 5] == 'i') + && (packet->payload[command_start + 6] == 'L' || packet->payload[command_start + 6] == 'l') + && (packet->payload[command_start + 7] == 'I' || packet->payload[command_start + 7] == 'i') + && (packet->payload[command_start + 8] == 'T' || packet->payload[command_start + 8] == 't') + && (packet->payload[command_start + 9] == 'Y' || packet->payload[command_start + 9] == 'y')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } + } + if ((command_start + 8) < packet->payload_packet_len) { + if ((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's') + && (packet->payload[command_start + 1] == 'T' || packet->payload[command_start + 1] == 't') + && (packet->payload[command_start + 2] == 'A' || packet->payload[command_start + 2] == 'a') + && (packet->payload[command_start + 3] == 'R' || packet->payload[command_start + 3] == 'r') + && (packet->payload[command_start + 4] == 'T' || packet->payload[command_start + 4] == 't') + && (packet->payload[command_start + 5] == 'T' || packet->payload[command_start + 5] == 't') + && (packet->payload[command_start + 6] == 'L' || packet->payload[command_start + 6] == 'l') + && (packet->payload[command_start + 7] == 'S' || packet->payload[command_start + 7] == 's')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } + } + if ((command_start + 5) < packet->payload_packet_len) { + if ((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l') + && (packet->payload[command_start + 1] == 'O' || packet->payload[command_start + 1] == 'o') + && (packet->payload[command_start + 2] == 'G' || packet->payload[command_start + 2] == 'g') + && (packet->payload[command_start + 3] == 'I' || packet->payload[command_start + 3] == 'i') + && (packet->payload[command_start + 4] == 'N' || packet->payload[command_start + 4] == 'n')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } else if ((packet->payload[command_start] == 'F' || packet->payload[command_start] == 'f') + && (packet->payload[command_start + 1] == 'E' || packet->payload[command_start + 1] == 'e') + && (packet->payload[command_start + 2] == 'T' || packet->payload[command_start + 2] == 't') + && (packet->payload[command_start + 3] == 'C' || packet->payload[command_start + 3] == 'c') + && (packet->payload[command_start + 4] == 'H' || packet->payload[command_start + 4] == 'h')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } else if ((packet->payload[command_start] == 'F' || packet->payload[command_start] == 'f') + && (packet->payload[command_start + 1] == 'L' || packet->payload[command_start + 1] == 'l') + && (packet->payload[command_start + 2] == 'A' || packet->payload[command_start + 2] == 'a') + && (packet->payload[command_start + 3] == 'G' || packet->payload[command_start + 3] == 'g') + && (packet->payload[command_start + 4] == 'S' || packet->payload[command_start + 4] == 's')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } else if ((packet->payload[command_start] == 'C' || packet->payload[command_start] == 'c') + && (packet->payload[command_start + 1] == 'H' || packet->payload[command_start + 1] == 'h') + && (packet->payload[command_start + 2] == 'E' || packet->payload[command_start + 2] == 'e') + && (packet->payload[command_start + 3] == 'C' || packet->payload[command_start + 3] == 'c') + && (packet->payload[command_start + 4] == 'K' || packet->payload[command_start + 4] == 'k')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } else if ((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's') + && (packet->payload[command_start + 1] == 'T' || packet->payload[command_start + 1] == 't') + && (packet->payload[command_start + 2] == 'O' || packet->payload[command_start + 2] == 'o') + && (packet->payload[command_start + 3] == 'R' || packet->payload[command_start + 3] == 'r') + && (packet->payload[command_start + 4] == 'E' || packet->payload[command_start + 4] == 'e')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } + } + if ((command_start + 12) < packet->payload_packet_len) { + if ((packet->payload[command_start] == 'A' || packet->payload[command_start] == 'a') + && (packet->payload[command_start + 1] == 'U' || packet->payload[command_start + 1] == 'u') + && (packet->payload[command_start + 2] == 'T' || packet->payload[command_start + 2] == 't') + && (packet->payload[command_start + 3] == 'H' || packet->payload[command_start + 3] == 'h') + && (packet->payload[command_start + 4] == 'E' || packet->payload[command_start + 4] == 'e') + && (packet->payload[command_start + 5] == 'N' || packet->payload[command_start + 5] == 'n') + && (packet->payload[command_start + 6] == 'T' || packet->payload[command_start + 6] == 't') + && (packet->payload[command_start + 7] == 'I' || packet->payload[command_start + 7] == 'i') + && (packet->payload[command_start + 8] == 'C' || packet->payload[command_start + 8] == 'c') + && (packet->payload[command_start + 9] == 'A' || packet->payload[command_start + 9] == 'a') + && (packet->payload[command_start + 10] == 'T' || packet->payload[command_start + 10] == 't') + && (packet->payload[command_start + 11] == 'E' || packet->payload[command_start + 11] == 'e')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } + } + if ((command_start + 9) < packet->payload_packet_len) { + if ((packet->payload[command_start] == 'N' || packet->payload[command_start] == 'n') + && (packet->payload[command_start + 1] == 'A' || packet->payload[command_start + 1] == 'a') + && (packet->payload[command_start + 2] == 'M' || packet->payload[command_start + 2] == 'm') + && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e') + && (packet->payload[command_start + 4] == 'S' || packet->payload[command_start + 4] == 's') + && (packet->payload[command_start + 5] == 'P' || packet->payload[command_start + 5] == 'p') + && (packet->payload[command_start + 6] == 'A' || packet->payload[command_start + 6] == 'a') + && (packet->payload[command_start + 7] == 'C' || packet->payload[command_start + 7] == 'c') + && (packet->payload[command_start + 8] == 'E' || packet->payload[command_start + 8] == 'e')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } + } + if ((command_start + 4) < packet->payload_packet_len) { + if ((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l') + && (packet->payload[command_start + 1] == 'S' || packet->payload[command_start + 1] == 's') + && (packet->payload[command_start + 2] == 'U' || packet->payload[command_start + 2] == 'u') + && (packet->payload[command_start + 3] == 'B' || packet->payload[command_start + 3] == 'b')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } else if ((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l') + && (packet->payload[command_start + 1] == 'I' || packet->payload[command_start + 1] == 'i') + && (packet->payload[command_start + 2] == 'S' || packet->payload[command_start + 2] == 's') + && (packet->payload[command_start + 3] == 'T' || packet->payload[command_start + 3] == 't')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } else if ((packet->payload[command_start] == 'N' || packet->payload[command_start] == 'n') + && (packet->payload[command_start + 1] == 'O' || packet->payload[command_start + 1] == 'o') + && (packet->payload[command_start + 2] == 'O' || packet->payload[command_start + 2] == 'o') + && (packet->payload[command_start + 3] == 'P' || packet->payload[command_start + 3] == 'p')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } else if ((packet->payload[command_start] == 'I' || packet->payload[command_start] == 'i') + && (packet->payload[command_start + 1] == 'D' || packet->payload[command_start + 1] == 'd') + && (packet->payload[command_start + 2] == 'L' || packet->payload[command_start + 2] == 'l') + && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } + } + if ((command_start + 6) < packet->payload_packet_len) { + if ((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's') + && (packet->payload[command_start + 1] == 'E' || packet->payload[command_start + 1] == 'e') + && (packet->payload[command_start + 2] == 'L' || packet->payload[command_start + 2] == 'l') + && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e') + && (packet->payload[command_start + 4] == 'C' || packet->payload[command_start + 4] == 'c') + && (packet->payload[command_start + 5] == 'T' || packet->payload[command_start + 5] == 't')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } else if ((packet->payload[command_start] == 'E' || packet->payload[command_start] == 'e') + && (packet->payload[command_start + 1] == 'X' || packet->payload[command_start + 1] == 'x') + && (packet->payload[command_start + 2] == 'I' || packet->payload[command_start + 2] == 'i') + && (packet->payload[command_start + 3] == 'S' || packet->payload[command_start + 3] == 's') + && (packet->payload[command_start + 4] == 'T' || packet->payload[command_start + 4] == 't') + && (packet->payload[command_start + 5] == 'S' || packet->payload[command_start + 5] == 's')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } else if ((packet->payload[command_start] == 'A' || packet->payload[command_start] == 'a') + && (packet->payload[command_start + 1] == 'P' || packet->payload[command_start + 1] == 'p') + && (packet->payload[command_start + 2] == 'P' || packet->payload[command_start + 2] == 'p') + && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e') + && (packet->payload[command_start + 4] == 'N' || packet->payload[command_start + 4] == 'n') + && (packet->payload[command_start + 5] == 'D' || packet->payload[command_start + 5] == 'd')) { + flow->l4.tcp.mail_imap_stage += 1; + saw_command = 1; + } + } + + } + + if (saw_command == 1) { + if (flow->l4.tcp.mail_imap_stage == 3 || flow->l4.tcp.mail_imap_stage == 5) { + NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "mail imap identified\n"); + ndpi_int_mail_imap_add_connection(ndpi_struct, flow); + return; + } + } + } + + if (packet->payload_packet_len > 1 && packet->payload[packet->payload_packet_len - 1] == ' ') { + NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, + "maybe a split imap command -> need next packet and imap_stage is set to 4.\n"); + flow->l4.tcp.mail_imap_stage = 4; + return; + } + + imap_excluded: + + // skip over possible authentication hashes etc. that cannot be identified as imap commands or responses + // if the packet count is low enough and at least one command or response was seen before + if ((packet->payload_packet_len >= 2 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) + && flow->packet_counter < 6 && flow->l4.tcp.mail_imap_stage >= 1) { + NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, + "no imap command or response but packet count < 6 and imap stage >= 1 -> skip\n"); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "exclude IMAP.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAIL_IMAP); +} +#endif diff --git a/src/lib/protocols/mail_pop.c b/src/lib/protocols/mail_pop.c new file mode 100644 index 000000000..522d4948e --- /dev/null +++ b/src/lib/protocols/mail_pop.c @@ -0,0 +1,204 @@ +/* + * mail_pop.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_MAIL_POP + +#define POP_BIT_AUTH 0x0001 +#define POP_BIT_APOP 0x0002 +#define POP_BIT_USER 0x0004 +#define POP_BIT_PASS 0x0008 +#define POP_BIT_CAPA 0x0010 +#define POP_BIT_LIST 0x0020 +#define POP_BIT_STAT 0x0040 +#define POP_BIT_UIDL 0x0080 +#define POP_BIT_RETR 0x0100 +#define POP_BIT_DELE 0x0200 +#define POP_BIT_STLS 0x0400 + + +static void ndpi_int_mail_pop_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_POP, NDPI_REAL_PROTOCOL); +} + + +static int ndpi_int_mail_pop_check_for_client_commands(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len > 4) { + if ((packet->payload[0] == 'A' || packet->payload[0] == 'a') + && (packet->payload[1] == 'U' || packet->payload[1] == 'u') + && (packet->payload[2] == 'T' || packet->payload[2] == 't') + && (packet->payload[3] == 'H' || packet->payload[3] == 'h')) { + flow->l4.tcp.pop_command_bitmask |= POP_BIT_AUTH; + return 1; + } else if ((packet->payload[0] == 'A' || packet->payload[0] == 'a') + && (packet->payload[1] == 'P' || packet->payload[1] == 'p') + && (packet->payload[2] == 'O' || packet->payload[2] == 'o') + && (packet->payload[3] == 'P' || packet->payload[3] == 'p')) { + flow->l4.tcp.pop_command_bitmask |= POP_BIT_APOP; + return 1; + } else if ((packet->payload[0] == 'U' || packet->payload[0] == 'u') + && (packet->payload[1] == 'S' || packet->payload[1] == 's') + && (packet->payload[2] == 'E' || packet->payload[2] == 'e') + && (packet->payload[3] == 'R' || packet->payload[3] == 'r')) { + flow->l4.tcp.pop_command_bitmask |= POP_BIT_USER; + return 1; + } else if ((packet->payload[0] == 'P' || packet->payload[0] == 'p') + && (packet->payload[1] == 'A' || packet->payload[1] == 'a') + && (packet->payload[2] == 'S' || packet->payload[2] == 's') + && (packet->payload[3] == 'S' || packet->payload[3] == 's')) { + flow->l4.tcp.pop_command_bitmask |= POP_BIT_PASS; + return 1; + } else if ((packet->payload[0] == 'C' || packet->payload[0] == 'c') + && (packet->payload[1] == 'A' || packet->payload[1] == 'a') + && (packet->payload[2] == 'P' || packet->payload[2] == 'p') + && (packet->payload[3] == 'A' || packet->payload[3] == 'a')) { + flow->l4.tcp.pop_command_bitmask |= POP_BIT_CAPA; + return 1; + } else if ((packet->payload[0] == 'L' || packet->payload[0] == 'l') + && (packet->payload[1] == 'I' || packet->payload[1] == 'i') + && (packet->payload[2] == 'S' || packet->payload[2] == 's') + && (packet->payload[3] == 'T' || packet->payload[3] == 't')) { + flow->l4.tcp.pop_command_bitmask |= POP_BIT_LIST; + return 1; + } else if ((packet->payload[0] == 'S' || packet->payload[0] == 's') + && (packet->payload[1] == 'T' || packet->payload[1] == 't') + && (packet->payload[2] == 'A' || packet->payload[2] == 'a') + && (packet->payload[3] == 'T' || packet->payload[3] == 't')) { + flow->l4.tcp.pop_command_bitmask |= POP_BIT_STAT; + return 1; + } else if ((packet->payload[0] == 'U' || packet->payload[0] == 'u') + && (packet->payload[1] == 'I' || packet->payload[1] == 'i') + && (packet->payload[2] == 'D' || packet->payload[2] == 'd') + && (packet->payload[3] == 'L' || packet->payload[3] == 'l')) { + flow->l4.tcp.pop_command_bitmask |= POP_BIT_UIDL; + return 1; + } else if ((packet->payload[0] == 'R' || packet->payload[0] == 'r') + && (packet->payload[1] == 'E' || packet->payload[1] == 'e') + && (packet->payload[2] == 'T' || packet->payload[2] == 't') + && (packet->payload[3] == 'R' || packet->payload[3] == 'r')) { + flow->l4.tcp.pop_command_bitmask |= POP_BIT_RETR; + return 1; + } else if ((packet->payload[0] == 'D' || packet->payload[0] == 'd') + && (packet->payload[1] == 'E' || packet->payload[1] == 'e') + && (packet->payload[2] == 'L' || packet->payload[2] == 'l') + && (packet->payload[3] == 'E' || packet->payload[3] == 'e')) { + flow->l4.tcp.pop_command_bitmask |= POP_BIT_DELE; + return 1; + } else if ((packet->payload[0] == 'S' || packet->payload[0] == 's') + && (packet->payload[1] == 'T' || packet->payload[1] == 't') + && (packet->payload[2] == 'L' || packet->payload[2] == 'l') + && (packet->payload[3] == 'S' || packet->payload[3] == 's')) { + flow->l4.tcp.pop_command_bitmask |= POP_BIT_STLS; + return 1; + } + } + return 0; +} + + + +void ndpi_search_mail_pop_tcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + u_int8_t a = 0; + u_int8_t bit_count = 0; + + NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG, "search mail_pop\n"); + + + + if ((packet->payload_packet_len > 3 + && (packet->payload[0] == '+' && (packet->payload[1] == 'O' || packet->payload[1] == 'o') + && (packet->payload[2] == 'K' || packet->payload[2] == 'k'))) + || (packet->payload_packet_len > 4 + && (packet->payload[0] == '-' && (packet->payload[1] == 'E' || packet->payload[1] == 'e') + && (packet->payload[2] == 'R' || packet->payload[2] == 'r') + && (packet->payload[3] == 'R' || packet->payload[3] == 'r')))) { + // +OK or -ERR seen + flow->l4.tcp.mail_pop_stage += 1; + } else if (!ndpi_int_mail_pop_check_for_client_commands(ndpi_struct, flow)) { + goto maybe_split_pop; + } + + if (packet->payload_packet_len > 2 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) { + + // count the bits set in the bitmask + if (flow->l4.tcp.pop_command_bitmask != 0) { + for (a = 0; a < 16; a++) { + bit_count += (flow->l4.tcp.pop_command_bitmask >> a) & 0x01; + } + } + + NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG, + "mail_pop +OK/-ERR responses: %u, unique commands: %u\n", flow->l4.tcp.mail_pop_stage, bit_count); + + if ((bit_count + flow->l4.tcp.mail_pop_stage) >= 3) { + if (flow->l4.tcp.mail_pop_stage > 0) { + NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG, "mail_pop identified\n"); + ndpi_int_mail_pop_add_connection(ndpi_struct, flow); + return; + } else { + return; + } + } else { + return; + } + + } else { + // first part of a split packet + NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG, + "mail_pop command without line ending -> skip\n"); + return; + } + + + maybe_split_pop: + + if (((packet->payload_packet_len > 2 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) + || flow->l4.tcp.pop_command_bitmask != 0 || flow->l4.tcp.mail_pop_stage != 0) && flow->packet_counter < 12) { + // maybe part of a split pop packet + NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG, + "maybe part of split mail_pop packet -> skip\n"); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG, "exclude mail_pop\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAIL_POP); +} +#endif diff --git a/src/lib/protocols/mail_smtp.c b/src/lib/protocols/mail_smtp.c new file mode 100644 index 000000000..e6ee4b1c8 --- /dev/null +++ b/src/lib/protocols/mail_smtp.c @@ -0,0 +1,180 @@ +/* + * mail_smtp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_MAIL_SMTP + +#define SMTP_BIT_220 0x01 +#define SMTP_BIT_250 0x02 +#define SMTP_BIT_235 0x04 +#define SMTP_BIT_334 0x08 +#define SMTP_BIT_354 0x10 +#define SMTP_BIT_HELO_EHLO 0x20 +#define SMTP_BIT_MAIL 0x40 +#define SMTP_BIT_RCPT 0x80 +#define SMTP_BIT_AUTH 0x100 +#define SMTP_BIT_STARTTLS 0x200 +#define SMTP_BIT_DATA 0x400 +#define SMTP_BIT_NOOP 0x800 +#define SMTP_BIT_RSET 0x1000 +#define SMTP_BIT_TlRM 0x2000 + +static void ndpi_int_mail_smtp_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_SMTP, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + + NDPI_LOG(NDPI_PROTOCOL_MAIL_SMTP, ndpi_struct, NDPI_LOG_DEBUG, "search mail_smtp.\n"); + + + if (packet->payload_packet_len > 2 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) { + u_int8_t a; + u_int8_t bit_count = 0; + + NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow,packet); + for (a = 0; a < packet->parsed_lines; a++) { + + // expected server responses + if (packet->line[a].len >= 3) { + if (memcmp(packet->line[a].ptr, "220", 3) == 0) { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_220; + } else if (memcmp(packet->line[a].ptr, "250", 3) == 0) { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_250; + } else if (memcmp(packet->line[a].ptr, "235", 3) == 0) { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_235; + } else if (memcmp(packet->line[a].ptr, "334", 3) == 0) { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_334; + } else if (memcmp(packet->line[a].ptr, "354", 3) == 0) { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_354; + } + } + // expected client requests + if (packet->line[a].len >= 5) { + if ((((packet->line[a].ptr[0] == 'H' || packet->line[a].ptr[0] == 'h') + && (packet->line[a].ptr[1] == 'E' || packet->line[a].ptr[1] == 'e')) + || ((packet->line[a].ptr[0] == 'E' || packet->line[a].ptr[0] == 'e') + && (packet->line[a].ptr[1] == 'H' || packet->line[a].ptr[1] == 'h'))) + && (packet->line[a].ptr[2] == 'L' || packet->line[a].ptr[2] == 'l') + && (packet->line[a].ptr[3] == 'O' || packet->line[a].ptr[3] == 'o') + && packet->line[a].ptr[4] == ' ') { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_HELO_EHLO; + } else if ((packet->line[a].ptr[0] == 'M' || packet->line[a].ptr[0] == 'm') + && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a') + && (packet->line[a].ptr[2] == 'I' || packet->line[a].ptr[2] == 'i') + && (packet->line[a].ptr[3] == 'L' || packet->line[a].ptr[3] == 'l') + && packet->line[a].ptr[4] == ' ') { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_MAIL; + } else if ((packet->line[a].ptr[0] == 'R' || packet->line[a].ptr[0] == 'r') + && (packet->line[a].ptr[1] == 'C' || packet->line[a].ptr[1] == 'c') + && (packet->line[a].ptr[2] == 'P' || packet->line[a].ptr[2] == 'p') + && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't') + && packet->line[a].ptr[4] == ' ') { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_RCPT; + } else if ((packet->line[a].ptr[0] == 'A' || packet->line[a].ptr[0] == 'a') + && (packet->line[a].ptr[1] == 'U' || packet->line[a].ptr[1] == 'u') + && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't') + && (packet->line[a].ptr[3] == 'H' || packet->line[a].ptr[3] == 'h') + && packet->line[a].ptr[4] == ' ') { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_AUTH; + } + } + + if (packet->line[a].len >= 8) { + if ((packet->line[a].ptr[0] == 'S' || packet->line[a].ptr[0] == 's') + && (packet->line[a].ptr[1] == 'T' || packet->line[a].ptr[1] == 't') + && (packet->line[a].ptr[2] == 'A' || packet->line[a].ptr[2] == 'a') + && (packet->line[a].ptr[3] == 'R' || packet->line[a].ptr[3] == 'r') + && (packet->line[a].ptr[4] == 'T' || packet->line[a].ptr[0] == 't') + && (packet->line[a].ptr[5] == 'T' || packet->line[a].ptr[1] == 't') + && (packet->line[a].ptr[6] == 'L' || packet->line[a].ptr[2] == 'l') + && (packet->line[a].ptr[7] == 'S' || packet->line[a].ptr[3] == 's')) { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_STARTTLS; + } + } + + if (packet->line[a].len >= 4) { + if ((packet->line[a].ptr[0] == 'D' || packet->line[a].ptr[0] == 'd') + && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a') + && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't') + && (packet->line[a].ptr[3] == 'A' || packet->line[a].ptr[3] == 'a')) { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_DATA; + } else if ((packet->line[a].ptr[0] == 'N' || packet->line[a].ptr[0] == 'n') + && (packet->line[a].ptr[1] == 'O' || packet->line[a].ptr[1] == 'o') + && (packet->line[a].ptr[2] == 'O' || packet->line[a].ptr[2] == 'o') + && (packet->line[a].ptr[3] == 'P' || packet->line[a].ptr[3] == 'p')) { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_NOOP; + } else if ((packet->line[a].ptr[0] == 'R' || packet->line[a].ptr[0] == 'r') + && (packet->line[a].ptr[1] == 'S' || packet->line[a].ptr[1] == 's') + && (packet->line[a].ptr[2] == 'E' || packet->line[a].ptr[2] == 'e') + && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't')) { + flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_RSET; + } + } + + } + + // now count the bits set in the bitmask + if (flow->l4.tcp.smtp_command_bitmask != 0) { + for (a = 0; a < 16; a++) { + bit_count += (flow->l4.tcp.smtp_command_bitmask >> a) & 0x01; + } + } + NDPI_LOG(NDPI_PROTOCOL_MAIL_SMTP, ndpi_struct, NDPI_LOG_DEBUG, "seen smtp commands and responses: %u.\n", + bit_count); + + if (bit_count >= 3) { + NDPI_LOG(NDPI_PROTOCOL_MAIL_SMTP, ndpi_struct, NDPI_LOG_DEBUG, "mail smtp identified\n"); + ndpi_int_mail_smtp_add_connection(ndpi_struct, flow); + return; + } + if (bit_count >= 1 && flow->packet_counter < 12) { + return; + } + } + /* when the first or second packets are split into two packets, those packets are ignored. */ + if (flow->packet_counter <= 4 && + packet->payload_packet_len >= 4 && + (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a + || memcmp(packet->payload, "220", 3) == 0 || memcmp(packet->payload, "EHLO", 4) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_MAIL_SMTP, ndpi_struct, NDPI_LOG_DEBUG, "maybe SMTP, need next packet.\n"); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_MAIL_SMTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude smtp\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAIL_SMTP); + +} +#endif diff --git a/src/lib/protocols/maplestory.c b/src/lib/protocols/maplestory.c new file mode 100644 index 000000000..e9d89d1da --- /dev/null +++ b/src/lib/protocols/maplestory.c @@ -0,0 +1,87 @@ +/* + * maplestory.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_MAPLESTORY + +static void ndpi_int_maplestory_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, + ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAPLESTORY, protocol_type); +} + + +void ndpi_search_maplestory(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + + + if (packet->payload_packet_len == 16 + && (ntohl(get_u_int32_t(packet->payload, 0)) == 0x0e003a00 || ntohl(get_u_int32_t(packet->payload, 0)) == 0x0e003b00 + || ntohl(get_u_int32_t(packet->payload, 0)) == 0x0e004200) + && ntohs(get_u_int16_t(packet->payload, 4)) == 0x0100 && (packet->payload[6] == 0x32 || packet->payload[6] == 0x33)) { + NDPI_LOG(NDPI_PROTOCOL_MAPLESTORY, ndpi_struct, NDPI_LOG_DEBUG, "found maplestory.\n"); + ndpi_int_maplestory_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /maple") + && memcmp(packet->payload, "GET /maple", NDPI_STATICSTRING_LEN("GET /maple")) == 0) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + /* Maplestory update */ + if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /maple/patch") + && packet->payload[NDPI_STATICSTRING_LEN("GET /maple")] == '/') { + if (packet->user_agent_line.ptr != NULL && packet->host_line.ptr != NULL + && packet->user_agent_line.len == NDPI_STATICSTRING_LEN("Patcher") + && packet->host_line.len > NDPI_STATICSTRING_LEN("patch.") + && memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /maple/")], "patch", + NDPI_STATICSTRING_LEN("patch")) == 0 + && memcmp(packet->user_agent_line.ptr, "Patcher", NDPI_STATICSTRING_LEN("Patcher")) == 0 + && memcmp(packet->host_line.ptr, "patch.", NDPI_STATICSTRING_LEN("patch.")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MAPLESTORY, ndpi_struct, NDPI_LOG_DEBUG, "found maplestory update.\n"); + ndpi_int_maplestory_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } else if (packet->user_agent_line.ptr != NULL && packet->user_agent_line.len == NDPI_STATICSTRING_LEN("AspINet") + && memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /maple")], "story/", + NDPI_STATICSTRING_LEN("story/")) == 0 + && memcmp(packet->user_agent_line.ptr, "AspINet", NDPI_STATICSTRING_LEN("AspINet")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MAPLESTORY, ndpi_struct, NDPI_LOG_DEBUG, "found maplestory update.\n"); + ndpi_int_maplestory_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + + NDPI_LOG(NDPI_PROTOCOL_MAPLESTORY, ndpi_struct, NDPI_LOG_DEBUG, "exclude maplestory.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAPLESTORY); + +} +#endif diff --git a/src/lib/protocols/mdns.c b/src/lib/protocols/mdns.c new file mode 100644 index 000000000..9b9b72582 --- /dev/null +++ b/src/lib/protocols/mdns.c @@ -0,0 +1,146 @@ +/* + * mdns.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_MDNS + +#define NDPI_MAX_MDNS_REQUESTS 128 + +/* +This module should detect MDNS +*/ + +static void ndpi_int_mdns_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MDNS, NDPI_REAL_PROTOCOL); +} + +static int ndpi_int_check_mdns_payload(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if ((packet->payload[2] & 0x80) == 0 && + ntohs(get_u_int16_t(packet->payload, 4)) <= NDPI_MAX_MDNS_REQUESTS && + ntohs(get_u_int16_t(packet->payload, 6)) <= NDPI_MAX_MDNS_REQUESTS) { + + NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, NDPI_LOG_DEBUG, "found MDNS with question query.\n"); + + return 1; + } else if ((packet->payload[2] & 0x80) != 0 && + ntohs(get_u_int16_t(packet->payload, 4)) == 0 && + ntohs(get_u_int16_t(packet->payload, 6)) <= NDPI_MAX_MDNS_REQUESTS && + ntohs(get_u_int16_t(packet->payload, 6)) != 0) { + NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, NDPI_LOG_DEBUG, "found MDNS with answer query.\n"); + + return 1; + } + + return 0; +} + +void ndpi_search_mdns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + u_int16_t dport; +// const u_int16_t sport=ntohs(packet->udp->source); + + /* check if UDP and */ + if (packet->udp != NULL) { + /*read destination port */ + dport = ntohs(packet->udp->dest); + + NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, NDPI_LOG_DEBUG, "MDNS udp start \n"); + + + + /*check standard MDNS to port 5353 */ + /*took this information from http://www.it-administrator.de/lexikon/multicast-dns.html */ + + if (dport == 5353 && packet->payload_packet_len >= 12) { + + NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, NDPI_LOG_DEBUG, "found MDNS with destination port 5353\n"); + + /* MDNS header is similar to dns header */ + /* dns header + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + | ID | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + |QR| Opcode |AA|TC|RD|RA| Z | RCODE | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + | QDCOUNT | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + | ANCOUNT | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + | NSCOUNT | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + | ARCOUNT | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * + * dns query check: query: QR set, ancount = 0, nscount = 0, QDCOUNT < MAX_MDNS, ARCOUNT < MAX_MDNS + * + */ + + /* mdns protocol must have destination address 224.0.0.251 */ + /* took this information from http://www.it-administrator.de/lexikon/multicast-dns.html */ + + if (packet->iph != NULL && ntohl(packet->iph->daddr) == 0xe00000fb) { + + NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, + NDPI_LOG_DEBUG, "found MDNS with destination address 224.0.0.251 (=0xe00000fb)\n"); + + if (ndpi_int_check_mdns_payload(ndpi_struct, flow) == 1) { + ndpi_int_mdns_add_connection(ndpi_struct, flow); + return; + } + } +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + if (packet->iphv6 != NULL) { + const u_int32_t *daddr = packet->iphv6->daddr.ndpi_v6_u.u6_addr32; + if (daddr[0] == htonl(0xff020000) && daddr[1] == 0 && daddr[2] == 0 && daddr[3] == htonl(0xfb)) { + + NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, + NDPI_LOG_DEBUG, "found MDNS with destination address ff02::fb\n"); + + if (ndpi_int_check_mdns_payload(ndpi_struct, flow) == 1) { + ndpi_int_mdns_add_connection(ndpi_struct, flow); + return; + } + } + } +#endif + + } + } + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MDNS); +} +#endif diff --git a/src/lib/protocols/meebo.c b/src/lib/protocols/meebo.c new file mode 100644 index 000000000..a54cb311e --- /dev/null +++ b/src/lib/protocols/meebo.c @@ -0,0 +1,165 @@ +/* + * meebo.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_MEEBO + +static void ndpi_int_meebo_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MEEBO, NDPI_CORRELATED_PROTOCOL); +} + + + + +void ndpi_search_meebo(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "search meebo.\n"); + + /* catch audio/video flows which are flash (rtmp) */ + if ( +#ifdef NDPI_CONTENT_FLASH + packet->detected_protocol_stack[0] == NDPI_CONTENT_FLASH +#else + (packet->tcp->source == htons(1935) || packet->tcp->dest == htons(1935)) +#endif + ) { + + /* TODO: once we have an amf decoder we can more directly access the rtmp fields + * if so, we may also exclude earlier */ + if (packet->payload_packet_len > 900) { + if (memcmp(packet->payload + 116, "tokbox/", NDPI_STATICSTRING_LEN("tokbox/")) == 0 || + memcmp(packet->payload + 316, "tokbox/", NDPI_STATICSTRING_LEN("tokbox/")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "found meebo/tokbox flash flow.\n"); + ndpi_int_meebo_add_connection(ndpi_struct, flow); + return; + } + } + + if (flow->packet_counter < 16 && flow->packet_direction_counter[flow->setup_packet_direction] < 6) { + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "need next packet.\n"); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "exclude meebo.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MEEBO); + return; + } + + if (( +#ifdef NDPI_PROTOCOL_HTTP + packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || +#endif + ((packet->payload_packet_len > 3 && memcmp(packet->payload, "GET ", 4) == 0) + || (packet->payload_packet_len > 4 && memcmp(packet->payload, "POST ", 5) == 0)) + ) && flow->packet_counter == 1) { + u_int8_t host_or_referer_match = 0; + + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->host_line.ptr != NULL + && packet->host_line.len >= 9 + && memcmp(&packet->host_line.ptr[packet->host_line.len - 9], "meebo.com", 9) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found Meebo host\n"); + host_or_referer_match = 1; + } else if (packet->host_line.ptr != NULL + && packet->host_line.len >= 10 + && memcmp(&packet->host_line.ptr[packet->host_line.len - 10], "tokbox.com", 10) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found tokbox host\n"); + /* set it to 2 to avoid having plain tokbox traffic detected as meebo */ + host_or_referer_match = 2; + } else if (packet->host_line.ptr != NULL && packet->host_line.len >= NDPI_STATICSTRING_LEN("74.114.28.110") + && memcmp(&packet->host_line.ptr[packet->host_line.len - NDPI_STATICSTRING_LEN("74.114.28.110")], + "74.114.28.110", NDPI_STATICSTRING_LEN("74.114.28.110")) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found meebo IP\n"); + host_or_referer_match = 1; + } else if (packet->referer_line.ptr != NULL && + packet->referer_line.len >= NDPI_STATICSTRING_LEN("http://www.meebo.com/") && + memcmp(packet->referer_line.ptr, "http://www.meebo.com/", + NDPI_STATICSTRING_LEN("http://www.meebo.com/")) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found meebo referer\n"); + host_or_referer_match = 1; + } else if (packet->referer_line.ptr != NULL && + packet->referer_line.len >= NDPI_STATICSTRING_LEN("http://mee.tokbox.com/") && + memcmp(packet->referer_line.ptr, "http://mee.tokbox.com/", + NDPI_STATICSTRING_LEN("http://mee.tokbox.com/")) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found tokbox referer\n"); + host_or_referer_match = 1; + } else if (packet->referer_line.ptr != NULL && + packet->referer_line.len >= NDPI_STATICSTRING_LEN("http://74.114.28.110/") && + memcmp(packet->referer_line.ptr, "http://74.114.28.110/", + NDPI_STATICSTRING_LEN("http://74.114.28.110/")) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found meebo IP referer\n"); + host_or_referer_match = 1; + } + + if (host_or_referer_match) { + if (host_or_referer_match == 1) { + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, + "Found Meebo traffic based on host/referer\n"); + ndpi_int_meebo_add_connection(ndpi_struct, flow); + return; + } + } + } + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_MEEBO) { + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, + "in case that ssl meebo has been detected return.\n"); + return; + } + + if (flow->packet_counter < 5 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSL) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "ssl not yet excluded. need next packet.\n"); + return; + } +#ifdef NDPI_CONTENT_FLASH + if (flow->packet_counter < 5 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && + !NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct, flow, NDPI_CONTENT_FLASH)) { + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "flash not yet excluded. need next packet.\n"); + return; + } +#endif + + NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "exclude meebo.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MEEBO); +} +#endif diff --git a/src/lib/protocols/megaco.c b/src/lib/protocols/megaco.c new file mode 100644 index 000000000..ca8d26380 --- /dev/null +++ b/src/lib/protocols/megaco.c @@ -0,0 +1,49 @@ +/* + * megaco.c + * + * Copyright (C) 2014 by Gianluca Costa http://www.capanalysis.net + * Copyright (C) 2012-15 - ntop.org + * + * This module is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This module is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License. + * If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_MEGACO + +void ndpi_search_megaco(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_MEGACO, ndpi_struct, NDPI_LOG_DEBUG, "search for MEGACO.\n"); + + if(packet->udp != NULL) { + if((packet->payload_packet_len > 4 && packet->payload[0] == '!' && packet->payload[1] == '/' && + packet->payload[2] == '1' && packet->payload[3] == ' ' && packet->payload[4] == '[') + || (packet->payload_packet_len > 9 && packet->payload[0] == 'M' && packet->payload[1] == 'E' && + packet->payload[2] == 'G' && packet->payload[3] == 'A' && packet->payload[4] == 'C' && + packet->payload[5] == 'O' && packet->payload[6] == '/' && + packet->payload[7] == '1' && packet->payload[8] == ' ' && packet->payload[9] == '[')) { + NDPI_LOG(NDPI_PROTOCOL_MEGACO, ndpi_struct, NDPI_LOG_DEBUG, "found MEGACO.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MEGACO, NDPI_REAL_PROTOCOL); + return; + } + } + + NDPI_LOG(NDPI_PROTOCOL_MEGACO, ndpi_struct, NDPI_LOG_DEBUG, "exclude MEGACO.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MEGACO); +} + +#endif diff --git a/src/lib/protocols/mgcp.c b/src/lib/protocols/mgcp.c new file mode 100644 index 000000000..c749f007b --- /dev/null +++ b/src/lib/protocols/mgcp.c @@ -0,0 +1,102 @@ +/* + * mgcp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_MGCP + +static void ndpi_int_mgcp_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MGCP, NDPI_REAL_PROTOCOL); +} + + + +#if !defined(WIN32) + static inline +#else +__forceinline static +#endif + void ndpi_search_mgcp_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + /* information about MGCP taken from http://en.wikipedia.org/wiki/MGCP */ + + u_int16_t pos = 4; + + if (packet->payload_packet_len < 8) { + goto mgcp_excluded; + } + + /* packet must end with 0x0d0a or with 0x0a */ + if (packet->payload[packet->payload_packet_len - 1] != 0x0a + && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) != htons(0x0d0a)) { + goto mgcp_excluded; + } + + + + if (packet->payload[0] != 'A' && packet->payload[0] != 'C' && packet->payload[0] != 'D' && + packet->payload[0] != 'E' && packet->payload[0] != 'M' && packet->payload[0] != 'N' && + packet->payload[0] != 'R') { + goto mgcp_excluded; + } + if (memcmp(packet->payload, "AUEP ", 5) != 0 && memcmp(packet->payload, "AUCX ", 5) != 0 && + memcmp(packet->payload, "CRCX ", 5) != 0 && memcmp(packet->payload, "DLCX ", 5) != 0 && + memcmp(packet->payload, "EPCF ", 5) != 0 && memcmp(packet->payload, "MDCX ", 5) != 0 && + memcmp(packet->payload, "NTFY ", 5) != 0 && memcmp(packet->payload, "RQNT ", 5) != 0 && + memcmp(packet->payload, "RSIP ", 5) != 0) { + goto mgcp_excluded; + } + // now search for string "MGCP " in the rest of the message + while ((pos + 5) < packet->payload_packet_len) { + if (memcmp(&packet->payload[pos], "MGCP ", 5) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MGCP, ndpi_struct, NDPI_LOG_DEBUG, "MGCP match.\n"); + ndpi_int_mgcp_add_connection(ndpi_struct, flow); + return; + } + pos++; + } + + mgcp_excluded: + NDPI_LOG(NDPI_PROTOCOL_MGCP, ndpi_struct, NDPI_LOG_DEBUG, "exclude MGCP.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MGCP); +} + + +void ndpi_search_mgcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + ndpi_search_mgcp_connection(ndpi_struct, flow); + +} +#endif diff --git a/src/lib/protocols/mms.c b/src/lib/protocols/mms.c new file mode 100644 index 000000000..00f2cb764 --- /dev/null +++ b/src/lib/protocols/mms.c @@ -0,0 +1,80 @@ +/* + * mms.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_CONTENT_MMS + + +static void ndpi_int_mms_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_CONTENT_MMS, NDPI_REAL_PROTOCOL); +} + + +void ndpi_search_mms_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + + /* search MSMMS packets */ + if (packet->payload_packet_len >= 20) { + if (flow->l4.tcp.mms_stage == 0 && packet->payload[4] == 0xce + && packet->payload[5] == 0xfa && packet->payload[6] == 0x0b + && packet->payload[7] == 0xb0 && packet->payload[12] == 0x4d + && packet->payload[13] == 0x4d && packet->payload[14] == 0x53 && packet->payload[15] == 0x20) { + NDPI_LOG(NDPI_CONTENT_MMS, ndpi_struct, NDPI_LOG_DEBUG, "MMS: MSMMS Request found \n"); + flow->l4.tcp.mms_stage = 1 + packet->packet_direction; + return; + } + + if (flow->l4.tcp.mms_stage == 2 - packet->packet_direction + && packet->payload[4] == 0xce && packet->payload[5] == 0xfa + && packet->payload[6] == 0x0b && packet->payload[7] == 0xb0 + && packet->payload[12] == 0x4d && packet->payload[13] == 0x4d + && packet->payload[14] == 0x53 && packet->payload[15] == 0x20) { + NDPI_LOG(NDPI_CONTENT_MMS, ndpi_struct, NDPI_LOG_DEBUG, "MMS: MSMMS Response found \n"); + ndpi_int_mms_add_connection(ndpi_struct, flow); + return; + } + } +#ifdef NDPI_PROTOCOL_HTTP + if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP) != 0) { +#endif /* NDPI_PROTOCOL_HTTP */ + NDPI_LOG(NDPI_CONTENT_MMS, ndpi_struct, NDPI_LOG_DEBUG, "MMS: exclude\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_CONTENT_MMS); + +#ifdef NDPI_PROTOCOL_HTTP + } else { + NDPI_LOG(NDPI_CONTENT_MMS, ndpi_struct, NDPI_LOG_DEBUG, "MMS avoid early exclude from http\n"); + } +#endif /* NDPI_PROTOCOL_HTTP */ + +} +#endif diff --git a/src/lib/protocols/msn.c b/src/lib/protocols/msn.c new file mode 100644 index 000000000..a34367071 --- /dev/null +++ b/src/lib/protocols/msn.c @@ -0,0 +1,563 @@ +/* + * msn.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_MSN + +#define MAX_PACKETS_FOR_MSN 100 +static void ndpi_int_msn_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, + ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MSN, protocol_type); +} + +static u_int8_t ndpi_int_find_xmsn(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if (packet->parsed_lines > 3) { + u_int16_t i; + for (i = 2; i < packet->parsed_lines; i++) { + if (packet->line[i].ptr != NULL && packet->line[i].len > NDPI_STATICSTRING_LEN("X-MSN") && + memcmp(packet->line[i].ptr, "X-MSN", NDPI_STATICSTRING_LEN("X-MSN")) == 0) { + return 1; + } + } + } + return 0; +} + + +static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + u_int16_t plen; + u_int16_t status = 0; + + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN tcp detection...\n"); +#ifdef NDPI_PROTOCOL_SSL + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "msn ssl ft test\n"); + if (flow->packet_counter < 10) { + } + + if (flow->packet_counter == 7 && packet->payload_packet_len > 300) { + if (memcmp(packet->payload + 24, "MSNSLP", 6) == 0 + || (get_u_int32_t(packet->payload, 0) == htonl(0x30000000) && get_u_int32_t(packet->payload, 4) == 0x00000000)) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "detected MSN File Transfer, ifdef ssl.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + if (flow->packet_counter >= 5 && flow->packet_counter <= 10 && (get_u_int32_t(packet->payload, 0) == htonl(0x18000000) + && get_u_int32_t(packet->payload, 4) == 0x00000000)) { + flow->l4.tcp.msn_ssl_ft++; + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "increased msn ft ssl stage to: %u at packet nr: %u\n", flow->l4.tcp.msn_ssl_ft, + flow->packet_counter); + if (flow->l4.tcp.msn_ssl_ft == 2) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "detected MSN File Transfer, ifdef ssl 2.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + } + return; + } + } +#endif + + + + /* we detect the initial connection only ! */ + /* match: "VER " ..... "CVR" x 0x0d 0x0a + * len should be small, lets say less than 100 bytes + * x is now "0", but can be increased + */ + /* now we have a look at the first packet only. */ + if (flow->packet_counter == 1 +#ifdef NDPI_PROTOCOL_SSL + || ((packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) && flow->packet_counter <= 3) +#endif + ) { + + /* this part is working asymmetrically */ + if (packet->payload_packet_len > 32 && (packet->payload[0] == 0x02 || packet->payload[0] == 0x00) + && (ntohl(get_u_int32_t(packet->payload, 8)) == 0x2112a442 || ntohl(get_u_int32_t(packet->payload, 4)) == 0x2112a442) + && ((ntohl(get_u_int32_t(packet->payload, 24)) == 0x000f0004 && ntohl(get_u_int32_t(packet->payload, 28)) == 0x72c64bc6) + || (ntohl(get_u_int32_t(packet->payload, 20)) == 0x000f0004 + && ntohl(get_u_int32_t(packet->payload, 24)) == 0x72c64bc6))) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "found MSN in packets that also contain voice.messenger.live.com.\n"); + + /* TODO this is an alternative pattern for video detection */ + /* if (packet->payload_packet_len > 100 && + get_u_int16_t(packet->payload, 86) == htons(0x05dc)) { */ + if (packet->payload_packet_len > 101 && packet->payload[101] == 0x02) { + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + } else { + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + } + + return; + } + + /* this case works asymmetrically */ + if (packet->payload_packet_len > 10 && packet->payload_packet_len < 100) { + if (get_u_int8_t(packet->payload, packet->payload_packet_len - 2) == 0x0d + && get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x0a) { + /* The MSNP string is used in XBOX clients. */ + if (memcmp(packet->payload, "VER ", 4) == 0) { + + if (memcmp(&packet->payload[packet->payload_packet_len - 6], "CVR", + 3) == 0 || memcmp(&packet->payload[packet->payload_packet_len - 8], "MSNP", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "found MSN by pattern VER...CVR/MSNP ODOA.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (memcmp(&packet->payload[4], "MSNFT", 5) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "found MSN FT by pattern VER MSNFT...0d0a.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + } + } + + if ( +#ifdef NDPI_PROTOCOL_HTTP + packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || +#endif + memcmp(packet->payload, "GET ", NDPI_STATICSTRING_LEN("GET ")) == 0 || + memcmp(packet->payload, "POST ", NDPI_STATICSTRING_LEN("POST ")) == 0) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->user_agent_line.ptr != NULL && + packet->user_agent_line.len > NDPI_STATICSTRING_LEN("Messenger/") && + memcmp(packet->user_agent_line.ptr, "Messenger/", NDPI_STATICSTRING_LEN("Messenger/")) == 0) { + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } +#ifdef NDPI_PROTOCOL_HTTP + /* we have to examine two http packets */ + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP) { + } +#endif + /* not seen this pattern in any trace */ + /* now test for http login, at least 100 a bytes packet */ + if (packet->payload_packet_len > 100) { + if ( +#ifdef NDPI_PROTOCOL_HTTP + packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || +#endif + memcmp(packet->payload, "POST http://", 12) == 0) { + /* scan packet if not already done... */ + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if (packet->content_line.ptr != NULL && + ((packet->content_line.len == NDPI_STATICSTRING_LEN("application/x-msn-messenger") && + memcmp(packet->content_line.ptr, "application/x-msn-messenger", + NDPI_STATICSTRING_LEN("application/x-msn-messenger")) == 0) || + (packet->content_line.len >= NDPI_STATICSTRING_LEN("text/x-msnmsgr") && + memcmp(packet->content_line.ptr, "text/x-msnmsgr", + NDPI_STATICSTRING_LEN("text/x-msnmsgr")) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "found MSN by pattern POST http:// .... application/x-msn-messenger.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + + /* now test for http login that uses a gateway, at least 400 a bytes packet */ + /* for this case the asymmetric detection is asym (1) */ + if (packet->payload_packet_len > 400) { + if (( +#ifdef NDPI_PROTOCOL_HTTP + packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || +#endif + (memcmp(packet->payload, "POST ", 5) == 0))) { + u_int16_t c; + if (memcmp(&packet->payload[5], "http://", 7) == 0) { + /* + * We are searching for a paten "POST http://gateway.messenger.hotmail.com/gateway/gateway.dll" or + * "POST http://<some ip addres here like 172.0.0.0>/gateway/gateway.dll" + * POST http:// is 12 byte so we are searching for 13 to 70 byte for this paten. + */ + for (c = 13; c < 50; c++) { + if (memcmp(&packet->payload[c], "/", 1) == 0) { + if (memcmp(&packet->payload[c], "/gateway/gateway.dll", 20) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "found pattern http://.../gateway/gateway.ddl.\n"); + status = 1; + break; + } + } + } + } else if ((memcmp(&packet->payload[5], "/gateway/gateway.dll", 20) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "found pattern http://.../gateway/gateway.ddl.\n"); + status = 1; + } + } + if (status) { + u_int16_t a; + + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if (packet->content_line.ptr != NULL + && + ((packet->content_line.len == 23 + && memcmp(packet->content_line.ptr, "text/xml; charset=utf-8", 23) == 0) + || + (packet->content_line.len == 24 + && memcmp(packet->content_line.ptr, "text/html; charset=utf-8", 24) == 0) + || + (packet->content_line.len == 33 + && memcmp(packet->content_line.ptr, "application/x-www-form-urlencoded", 33) == 0) + )) { + if ((src != NULL + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) + != 0) || (dst != NULL + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, + NDPI_PROTOCOL_MSN) + != 0)) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "found MSN with pattern text/xml; charset=utf-8.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + for (a = 0; a < packet->parsed_lines; a++) { + if (packet->line[a].len >= 4 && + (memcmp(packet->line[a].ptr, "CVR ", 4) == 0 + || memcmp(packet->line[a].ptr, "VER ", + 4) == 0 || memcmp(packet->line[a].ptr, "ANS ", 4) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "found MSN with pattern text/sml; charset0utf-8.\n"); + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, + NDPI_LOG_TRACE, "MSN xml CVS / VER / ANS found\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + } + } + /* asym (1) ; possibly occurs in symmetric cases also. */ + if (flow->packet_counter <= 10 && + (flow->packet_direction_counter[0] <= 2 || flow->packet_direction_counter[1] <= 2) + && packet->payload_packet_len > 100) { + /* not necessary to check the length, because this has been done : >400. */ + if ( +#ifdef NDPI_PROTOCOL_HTTP + packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || +#endif + (memcmp(packet->payload, "HTTP/1.0 200 OK", 15) == 0) || + (memcmp(packet->payload, "HTTP/1.1 200 OK", 15) == 0) + ) { + + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if (packet->content_line.ptr != NULL && + ((packet->content_line.len == NDPI_STATICSTRING_LEN("application/x-msn-messenger") && + memcmp(packet->content_line.ptr, "application/x-msn-messenger", + NDPI_STATICSTRING_LEN("application/x-msn-messenger")) == 0) || + (packet->content_line.len >= NDPI_STATICSTRING_LEN("text/x-msnmsgr") && + memcmp(packet->content_line.ptr, "text/x-msnmsgr", + NDPI_STATICSTRING_LEN("text/x-msnmsgr")) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "HTTP/1.0 200 OK .... application/x-msn-messenger.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + if (ndpi_int_find_xmsn(ndpi_struct, flow) == 1) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "HTTP/1.0 200 OK .... X-MSN.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + + + /* did not find any trace with this pattern !!!!! */ + /* now block proxy connection */ + if (packet->payload_packet_len >= 42) { + if (memcmp(packet->payload, "CONNECT messenger.hotmail.com:1863 HTTP/1.", 42) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "found MSN with pattern CONNECT messenger.hotmail.com:1863 HTTP/1..\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + + if (packet->payload_packet_len >= 18) { + + if (memcmp(packet->payload, "USR ", 4) == 0 || memcmp(packet->payload, "ANS ", 4) == 0) { + /* now we must see a number */ + const u_int16_t endlen = packet->payload_packet_len - 12; + plen = 4; + while (1) { + if (packet->payload[plen] == ' ') { + break; + } + if (packet->payload[plen] < '0' || packet->payload[plen] > '9') { + goto ndpi_msn_exclude; + } + plen++; + if (plen >= endlen) { + goto ndpi_msn_exclude; + } + } + + while (plen < endlen) { + if (ndpi_check_for_email_address(ndpi_struct, flow, plen) != 0) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found mail address\n"); + break; + } + if (packet->payload_packet_len > plen + 1 + && (packet->payload[plen] < 20 || packet->payload[plen] > 128)) { + goto ndpi_msn_exclude; + } + plen++; + if (plen >= endlen) { + goto ndpi_msn_exclude; + } + + } + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "found MSN with pattern USR/ANS ...mail_address.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + } + + /* finished examining the first packet only. */ + + + /* asym (1) ; possibly occurs in symmetric cases also. */ + if (flow->packet_counter <= 10 && + (flow->packet_direction_counter[0] <= 2 || flow->packet_direction_counter[1] <= 2) && + packet->payload_packet_len > 100) { + /* not necessary to check the length, because this has been done : >400. */ + if ( +#ifdef NDPI_PROTOCOL_HTTP + packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || +#endif + (memcmp(packet->payload, "HTTP/1.0 200 OK", 15) == 0) || + (memcmp(packet->payload, "HTTP/1.1 200 OK", 15) == 0) + ) { + + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if (packet->content_line.ptr != NULL && + ((packet->content_line.len == NDPI_STATICSTRING_LEN("application/x-msn-messenger") && + memcmp(packet->content_line.ptr, "application/x-msn-messenger", + NDPI_STATICSTRING_LEN("application/x-msn-messenger")) == 0) || + (packet->content_line.len >= NDPI_STATICSTRING_LEN("text/x-msnmsgr") && + memcmp(packet->content_line.ptr, "text/x-msnmsgr", NDPI_STATICSTRING_LEN("text/x-msnmsgr")) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, + "HTTP/1.0 200 OK .... application/x-msn-messenger.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + if (ndpi_int_find_xmsn(ndpi_struct, flow) == 1) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "HTTP/1.0 200 OK .... X-MSN.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + + + + + /* finished examining the secone packet only */ + /* direct user connection (file transfer,...) */ + + if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) != 0) + || (dst != NULL + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) != 0)) { + if (flow->packet_counter == 1 && + packet->payload_packet_len > 12 && memcmp(packet->payload, "recipientid=", 12) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "detected file transfer.\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + + /* MSN File Transfer of MSN 8.1 and 8.5 + * first packet with length 4 and pattern 0x04000000 + * second packet (in the same direction), with length 56 and pattern 0x00000000 from payload[16] + * third packet (in the opposite direction to 1 & 2), with length 4 and pattern 0x30000000 + */ + if (flow->l4.tcp.msn_stage == 0) { + /* asymmetric detection to this pattern is asym (2) */ + if ((packet->payload_packet_len == 4 || packet->payload_packet_len == 8) + && get_u_int32_t(packet->payload, 0) == htonl(0x04000000)) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "maybe first TCP MSN detected\n"); + + if (packet->payload_packet_len == 8 && get_u_int32_t(packet->payload, 4) == htonl(0x666f6f00)) { + flow->l4.tcp.msn_stage = 5 + packet->packet_direction; + return; + } + + flow->l4.tcp.msn_stage = 1 + packet->packet_direction; + return; + } + /* asymmetric detection to this pattern is asym (2) */ + } else if (flow->l4.tcp.msn_stage == 1 + packet->packet_direction) { + if (packet->payload_packet_len > 10 && get_u_int32_t(packet->payload, 0) == htonl(0x666f6f00)) { + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 1\n"); + return; + } + /* did not see this pattern in any trace */ + if (packet->payload_packet_len == 56 && get_u_int32_t(packet->payload, 16) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "maybe Second TCP MSN detected\n"); + flow->l4.tcp.msn_stage = 3 + packet->packet_direction; + return; + } + + + } else if (flow->l4.tcp.msn_stage == 2 - packet->packet_direction + && packet->payload_packet_len == 4 && get_u_int32_t(packet->payload, 0) == htonl(0x30000000)) { + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 2\n"); + return; + } else if ((flow->l4.tcp.msn_stage == 3 + packet->packet_direction) + || (flow->l4.tcp.msn_stage == 4 - packet->packet_direction)) { + if (packet->payload_packet_len == 4 && get_u_int32_t(packet->payload, 0) == htonl(0x30000000)) { + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 2\n"); + return; + } + } else if (flow->l4.tcp.msn_stage == 6 - packet->packet_direction) { + if ((packet->payload_packet_len == 4) && + (get_u_int32_t(packet->payload, 0) == htonl(0x10000000) || get_u_int32_t(packet->payload, 0) == htonl(0x30000000))) { + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 3\n"); + return; + } + } else if (flow->l4.tcp.msn_stage == 5 + packet->packet_direction) { + if ((packet->payload_packet_len == 20) && get_u_int32_t(packet->payload, 0) == htonl(0x10000000)) { + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 3\n"); + return; + } + } + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "msn 7.\n"); + if (flow->packet_counter <= MAX_PACKETS_FOR_MSN) { + if (packet->tcp->source == htons(443) + || packet->tcp->dest == htons(443)) { + if (packet->payload_packet_len > 300) { + if (memcmp(&packet->payload[40], "INVITE MSNMSGR", 14) == 0 + || memcmp(&packet->payload[56], "INVITE MSNMSGR", 14) == 0 + || memcmp(&packet->payload[172], "INVITE MSNMSGR", 14) == 0) { + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 3\n"); + return; + } + } + return; + } + /* For no + n port 443 flows exclude flow bitmask after first packet itself */ + } + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN tcp excluded.\n"); + ndpi_msn_exclude: + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSN); +} + + + +static void ndpi_search_udp_msn_misc(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + + /* do we have an msn login ? */ + if ((src == NULL || NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) == 0) + && (dst == NULL + || NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) == 0)) { + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSN); + return; + } + + /* asymmetric ft detection works */ + if (packet->payload_packet_len == 20 + && get_u_int32_t(packet->payload, 4) == 0 && packet->payload[9] == 0 + && get_u_int16_t(packet->payload, 10) == htons(0x0100)) { + NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "msn udp misc data connection detected\n"); + ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + } + + /* asymmetric detection working. */ + return; + //} +} + + +void ndpi_search_msn(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + /* this if request should always be true */ + if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSN) == 0) { + /* we deal with tcp now */ + if (packet->tcp != NULL) { + /* msn can use http or ssl for connection. That's why every http, ssl and ukn packet must enter in the msn detection */ + /* the detection can swich out the http or the ssl detection. In this case we need not check those protocols */ + // need to do the ceck when protocol == http too (POST /gateway ...) + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN +#if defined(NDPI_PROTOCOL_HTTP) + || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP +#endif +#if defined(NDPI_PROTOCOL_SSL) + || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL +#endif +#if defined(NDPI_PROTOCOL_STUN) + || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN +#endif + ) { + ndpi_search_msn_tcp(ndpi_struct, flow); + } + } else if (packet->udp != NULL) { + ndpi_search_udp_msn_misc(ndpi_struct, flow); + } + } +} + +#endif diff --git a/src/lib/protocols/mssql.c b/src/lib/protocols/mssql.c new file mode 100644 index 000000000..15f2ab210 --- /dev/null +++ b/src/lib/protocols/mssql.c @@ -0,0 +1,61 @@ +/* + * mssql.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +/* include files */ + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_MSSQL + +static void ndpi_int_mssql_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MSSQL, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_mssql(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + + + NDPI_LOG(NDPI_PROTOCOL_MSSQL, ndpi_struct, NDPI_LOG_DEBUG, "search mssql.\n"); + + + if (packet->payload_packet_len > 51 && ntohs(get_u_int32_t(packet->payload, 0)) == 0x1201 + && ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len + && ntohl(get_u_int32_t(packet->payload, 4)) == 0x00000100 && memcmp(&packet->payload[41], "sqlexpress", 10) == 0) { + NDPI_LOG(NDPI_PROTOCOL_MSSQL, ndpi_struct, NDPI_LOG_DEBUG, "found mssql.\n"); + ndpi_int_mssql_add_connection(ndpi_struct, flow); + return; + } + + + NDPI_LOG(NDPI_PROTOCOL_MSSQL, ndpi_struct, NDPI_LOG_DEBUG, "exclude mssql.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSSQL); +} +#endif diff --git a/src/lib/protocols/mysql.c b/src/lib/protocols/mysql.c new file mode 100644 index 000000000..107b1888e --- /dev/null +++ b/src/lib/protocols/mysql.c @@ -0,0 +1,70 @@ +/* + * mysql.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_MYSQL + +static void ndpi_int_mysql_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MYSQL, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_mysql_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len > 37 //min length + && get_u_int16_t(packet->payload, 0) == packet->payload_packet_len - 4 //first 3 bytes are length + && get_u_int8_t(packet->payload, 2) == 0x00 //3rd byte of packet length + && get_u_int8_t(packet->payload, 3) == 0x00 //packet sequence number is 0 for startup packet + && get_u_int8_t(packet->payload, 5) > 0x30 //server version > 0 + && get_u_int8_t(packet->payload, 5) < 0x37 //server version < 7 + && get_u_int8_t(packet->payload, 6) == 0x2e //dot + ) { + u_int32_t a; + for (a = 7; a + 31 < packet->payload_packet_len; a++) { + if (packet->payload[a] == 0x00) { + if (get_u_int8_t(packet->payload, a + 13) == 0x00 //filler byte + && get_u_int64_t(packet->payload, a + 19) == 0x0ULL //13 more + && get_u_int32_t(packet->payload, a + 27) == 0x0 //filler bytes + && get_u_int8_t(packet->payload, a + 31) == 0x0) { + NDPI_LOG(NDPI_PROTOCOL_MYSQL, ndpi_struct, NDPI_LOG_DEBUG, "MySQL detected.\n"); + ndpi_int_mysql_add_connection(ndpi_struct, flow); + return; + } + break; + } + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MYSQL); + +} + +#endif diff --git a/src/lib/protocols/netbios.c b/src/lib/protocols/netbios.c new file mode 100644 index 000000000..41f13b0f6 --- /dev/null +++ b/src/lib/protocols/netbios.c @@ -0,0 +1,368 @@ +/* + * netbios.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_NETBIOS + +/* The function below has been inherited by tcpdump */ +static int netbios_name_interpret(char *in, char *out, u_int out_len) { + int ret, len; + char *b; + + len = (*in++)/2; + b = out; + *out=0; + + if(len > (out_len-1) || len < 1) + return(-1); + + while (len--) { + if(in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { + *out = 0; + return(-1); + } + + *out = ((in[0]-'A')<<4) + (in[1]-'A'); + in += 2; + out++; + } + ret = *(--out); + *out = 0; + + /* Courtesy of Roberto F. De Luca <deluca@tandar.cnea.gov.ar> */ + /* Trim trailing whitespace from the returned string */ + for(out--; out>=b && *out==' '; out--) *out = '\0'; + + return(ret); +} + + +static void ndpi_int_netbios_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NETBIOS, NDPI_REAL_PROTOCOL); +} + + +void ndpi_search_netbios(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + + u_int16_t dport; + + if (packet->udp != NULL) { + dport = ntohs(packet->udp->dest); + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, "netbios udp start\n"); + + /*check standard NETBIOS over udp to port 137 */ + if ((dport == 137 || 0) && packet->payload_packet_len >= 50) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, "found netbios port 137 and payload_packet_len 50\n"); + + if (ntohs(get_u_int16_t(packet->payload, 2)) == 0 && + ntohs(get_u_int16_t(packet->payload, 4)) == 1 && + ntohs(get_u_int16_t(packet->payload, 6)) == 0 && + ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, "found netbios with questions = 1 and answers = 0, authority = 0 \n"); + + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload[2] == 0x80 && + ntohs(get_u_int16_t(packet->payload, 4)) == 1 && + ntohs(get_u_int16_t(packet->payload, 6)) == 0 && + ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 1) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, "found netbios with questions = 1 and answers, authority, additional = 0 \n"); + + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + if (ntohs(get_u_int16_t(packet->payload, 2)) == 0x4000 && + ntohs(get_u_int16_t(packet->payload, 4)) == 1 && + ntohs(get_u_int16_t(packet->payload, 6)) == 0 && + ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 1) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, "found netbios with questions = 1 and answers = 0, authority = 0 \n"); + + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + if (ntohs(get_u_int16_t(packet->payload, 2)) == 0x8400 && + ntohs(get_u_int16_t(packet->payload, 4)) == 0 && + ntohs(get_u_int16_t(packet->payload, 6)) == 1 && + ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, + "found netbios with flag 8400 questions = 0 and answers = 1, authority, additional = 0 \n"); + + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + if (ntohs(get_u_int16_t(packet->payload, 2)) == 0x8500 && + ntohs(get_u_int16_t(packet->payload, 4)) == 0 && + ntohs(get_u_int16_t(packet->payload, 6)) == 1 && + ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, + "found netbios with flag 8500 questions = 0 and answers = 1, authority, additional = 0 \n"); + + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + if (ntohs(get_u_int16_t(packet->payload, 2)) == 0x2910 && + ntohs(get_u_int16_t(packet->payload, 4)) == 1 && + ntohs(get_u_int16_t(packet->payload, 6)) == 0 && + ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 1) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, + "found netbios with flag 2910, questions = 1 and answers, authority=0, additional = 1 \n"); + + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + if (ntohs(get_u_int16_t(packet->payload, 2)) == 0xAD86 && + ntohs(get_u_int16_t(packet->payload, 4)) == 0 && + ntohs(get_u_int16_t(packet->payload, 6)) == 1 && + ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, + "found netbios with flag ad86 questions = 0 and answers = 1, authority, additional = 0 \n"); + + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + if (ntohs(get_u_int16_t(packet->payload, 2)) == 0x0110 && + ntohs(get_u_int16_t(packet->payload, 4)) == 1 && + ntohs(get_u_int16_t(packet->payload, 6)) == 0 && + ntohs(get_u_int16_t(packet->payload, 8)) == 0 && ntohs(get_u_int16_t(packet->payload, 10)) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, + "found netbios with flag 0110 questions = 1 and answers = 0, authority, additional = 0 \n"); + + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + + if ((ntohs(get_u_int16_t(packet->payload, 2)) & 0xf800) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, "possible netbios name query request\n"); + + if (get_u_int16_t(packet->payload, 4) == htons(1) && + get_u_int16_t(packet->payload, 6) == 0 && + get_u_int16_t(packet->payload, 8) == 0 && get_u_int16_t(packet->payload, 10) == 0) { + + /* name is encoded as described in rfc883 */ + u_int8_t name_length = packet->payload[12]; + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "possible netbios name query request, one question\n"); + + if (packet->payload_packet_len == 12 + 1 + name_length + 1 + 2 + 2) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "possible netbios name query request, length matches\n"); + + /* null terminated? */ + if (packet->payload[12 + name_length + 1] == 0 && + get_u_int16_t(packet->payload, 12 + name_length + 2) == htons(0x0020) && + get_u_int16_t(packet->payload, 12 + name_length + 4) == htons(0x0001)) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "found netbios name query request\n"); + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + } + } + } else if ((ntohs(get_u_int16_t(packet->payload, 2)) & 0xf800) == 0x8000) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "possible netbios name query response\n"); + + if (get_u_int16_t(packet->payload, 4) == 0 && + get_u_int16_t(packet->payload, 6) == htons(1) && + get_u_int16_t(packet->payload, 8) == 0 && get_u_int16_t(packet->payload, 10) == 0) { + + /* name is encoded as described in rfc883 */ + u_int8_t name_length = packet->payload[12]; + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "possible netbios positive name query response, one answer\n"); + + if (packet->payload_packet_len >= 12 + 1 + name_length + 1 + 2 + 2) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "possible netbios name query response, length matches\n"); + + /* null terminated? */ + if (packet->payload[12 + name_length + 1] == 0 && + get_u_int16_t(packet->payload, 12 + name_length + 2) == htons(0x0020) && + get_u_int16_t(packet->payload, 12 + name_length + 4) == htons(0x0001)) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "found netbios name query response\n"); + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + } + } else if (get_u_int16_t(packet->payload, 4) == 0 && + get_u_int16_t(packet->payload, 6) == 0 && + get_u_int16_t(packet->payload, 8) == 0 && get_u_int16_t(packet->payload, 10) == 0) { + + /* name is encoded as described in rfc883 */ + u_int8_t name_length = packet->payload[12]; + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "possible netbios negative name query response, one answer\n"); + + if (packet->payload_packet_len >= 12 + 1 + name_length + 1 + 2 + 2) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "possible netbios name query response, length matches\n"); + + /* null terminated? */ + if (packet->payload[12 + name_length + 1] == 0 && + get_u_int16_t(packet->payload, 12 + name_length + 2) == htons(0x000A) && + get_u_int16_t(packet->payload, 12 + name_length + 4) == htons(0x0001)) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "found netbios name query response\n"); + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + } + } else if (get_u_int16_t(packet->payload, 4) == 0 && + get_u_int16_t(packet->payload, 6) == 0 && + get_u_int16_t(packet->payload, 8) == htons(1) && get_u_int16_t(packet->payload, 10) == htons(1)) { + + /* name is encoded as described in rfc883 */ + u_int8_t name_length = packet->payload[12]; + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "possible netbios redirect name query response, one answer\n"); + + if (packet->payload_packet_len >= 12 + 1 + name_length + 1 + 2 + 2) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "possible netbios name query response, length matches\n"); + + /* null terminated? */ + if (packet->payload[12 + name_length + 1] == 0 && + get_u_int16_t(packet->payload, 12 + name_length + 2) == htons(0x0002) && + get_u_int16_t(packet->payload, 12 + name_length + 4) == htons(0x0001)) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, + "found netbios name query response\n"); + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + } + } + } + /* TODO: extend according to rfc1002 */ + } + + /*check standard NETBIOS over udp to port 138 */ + + /*netbios header token from http://www.protocolbase.net/protocols/protocol_NBDGM.php */ + + if ((dport == 138) && + packet->payload_packet_len >= 14 && + ntohs(get_u_int16_t(packet->payload, 10)) == packet->payload_packet_len - 14) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, "found netbios port 138 and payload length >= 112 \n"); + + if (packet->payload[0] >= 0x11 && packet->payload[0] <= 0x16) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, "found netbios with MSG-type 0x11,0x12,0x13,0x14,0x15 or 0x16\n"); + + if (ntohl(get_u_int32_t(packet->payload, 4)) == ntohl(packet->iph->saddr)) { + char name[32]; + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, "found netbios with checked ip-address.\n"); + + if(netbios_name_interpret((char*)&packet->payload[14], name, sizeof(name)) > 0) + snprintf((char*)flow->host_server_name, sizeof(flow->host_server_name), "%s", name); + + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + } + } + } + + if (packet->tcp != NULL) { + dport = ntohs(packet->tcp->dest); + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, "netbios tcp start\n"); + + /* destination port must be 139 */ + if (dport == 139) { + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, "found netbios with destination port 139\n"); + + /* payload_packet_len must be 72 */ + if (packet->payload_packet_len == 72) { + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, "found netbios with payload_packen_len = 72. \n"); + + if (packet->payload[0] == 0x81 && packet->payload[1] == 0 && ntohs(get_u_int16_t(packet->payload, 2)) == 68) { + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, + NDPI_LOG_DEBUG, + "found netbios with session request = 81, flags=0 and length od following bytes = 68. \n"); + + ndpi_int_netbios_add_connection(ndpi_struct, flow); + return; + } + } + } + + } + + NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, "exclude netbios\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NETBIOS); + +} +#endif diff --git a/src/lib/protocols/netflow.c b/src/lib/protocols/netflow.c new file mode 100644 index 000000000..ccf275a8b --- /dev/null +++ b/src/lib/protocols/netflow.c @@ -0,0 +1,93 @@ +/* + * netflow.c + * + * Copyright (C) 2011-15 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_NETFLOW + +#ifndef __KERNEL__ +#ifdef WIN32 +extern int gettimeofday(struct timeval * tp, struct timezone * tzp); +#endif +#define do_gettimeofday(a) gettimeofday(a, NULL) +#endif + +static void ndpi_check_netflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // const u_int8_t *packet_payload = packet->payload; + u_int32_t payload_len = packet->payload_packet_len; + time_t now; + struct timeval now_tv; + + if((packet->udp != NULL) && (payload_len >= 24)) { + u_int16_t version = (packet->payload[0] << 8) + packet->payload[1], uptime_offset; + u_int32_t when, *_when; + u_int16_t n = (packet->payload[2] << 8) + packet->payload[3]; + + switch(version) { + case 1: + case 5: + case 7: + case 9: + { + u_int16_t num_flows = n; + + if((num_flows == 0) || (num_flows > 30)) + return; + } + uptime_offset = 8; + break; + case 10: /* IPFIX */ + { + u_int16_t ipfix_len = n; + + if(ipfix_len != payload_len) + return; + } + uptime_offset = 4; + break; + default: + return; + } + + _when = (u_int32_t*)&packet->payload[uptime_offset]; /* Sysuptime */ + when = ntohl(*_when); + + do_gettimeofday(&now_tv); + now = now_tv.tv_sec; + + if(((version == 1) && (when == 0)) + || ((when >= 946684800 /* 1/1/2000 */) && (when <= now))) { + NDPI_LOG(NDPI_PROTOCOL_NETFLOW, ndpi_struct, NDPI_LOG_DEBUG, "Found netflow.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NETFLOW, NDPI_REAL_PROTOCOL); + return; + } + } +} + +void ndpi_search_netflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + NDPI_LOG(NDPI_PROTOCOL_NETFLOW, ndpi_struct, NDPI_LOG_DEBUG, "netflow detection...\n"); + ndpi_check_netflow(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/nfs.c b/src/lib/protocols/nfs.c new file mode 100644 index 000000000..0a3fde84b --- /dev/null +++ b/src/lib/protocols/nfs.c @@ -0,0 +1,86 @@ +/* + * nfs.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_NFS + +static void ndpi_int_nfs_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NFS, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_nfs(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + u_int8_t offset = 0; + if (packet->tcp != NULL) + offset = 4; + + if (packet->payload_packet_len < (40 + offset)) + goto exclude_nfs; + + NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS user match stage 1\n"); + + + if (offset != 0 && get_u_int32_t(packet->payload, 0) != htonl(0x80000000 + packet->payload_packet_len - 4)) + goto exclude_nfs; + + NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS user match stage 2\n"); + + if (get_u_int32_t(packet->payload, 4 + offset) != 0) + goto exclude_nfs; + + NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS user match stage 3\n"); + + if (get_u_int32_t(packet->payload, 8 + offset) != htonl(0x02)) + goto exclude_nfs; + + NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS match stage 3\n"); + + if (get_u_int32_t(packet->payload, 12 + offset) != htonl(0x000186a5) + && get_u_int32_t(packet->payload, 12 + offset) != htonl(0x000186a3) + && get_u_int32_t(packet->payload, 12 + offset) != htonl(0x000186a0)) + goto exclude_nfs; + + NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS match stage 4\n"); + + if (ntohl(get_u_int32_t(packet->payload, 16 + offset)) > 4) + goto exclude_nfs; + + NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS match\n"); + + ndpi_int_nfs_add_connection(ndpi_struct, flow); + return; + + exclude_nfs: + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NFS); +} + +#endif diff --git a/src/lib/protocols/noe.c b/src/lib/protocols/noe.c new file mode 100644 index 000000000..218201b9a --- /dev/null +++ b/src/lib/protocols/noe.c @@ -0,0 +1,52 @@ +/* + * noe.c (Alcatel new office environment) + * + * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * + */ + + +#include "ndpi_api.h" + + +#ifdef NDPI_PROTOCOL_NOE +static void ndpi_int_noe_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NOE, NDPI_CORRELATED_PROTOCOL); +} + +void ndpi_search_noe(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "search for NOE.\n"); + + if(packet->udp != NULL) { + NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over udp.\n"); + + if (packet->payload_packet_len == 1 && ( packet->payload[0] == 0x05 || packet->payload[0] == 0x04 )) { + NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "found noe.\n"); + ndpi_int_noe_add_connection(ndpi_struct, flow); + return; + } else if((packet->payload_packet_len == 5 || packet->payload_packet_len == 12) && + (packet->payload[0] == 0x07 ) && + (packet->payload[1] == 0x00 ) && + (packet->payload[2] != 0x00 ) && + (packet->payload[3] == 0x00 )) { + NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "found noe.\n"); + ndpi_int_noe_add_connection(ndpi_struct, flow); + } else if((packet->payload_packet_len >= 25) && + (packet->payload[0] == 0x00 && + packet->payload[1] == 0x06 && + packet->payload[2] == 0x62 && + packet->payload[3] == 0x6c)) { + NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "found noe.\n"); + ndpi_int_noe_add_connection(ndpi_struct, flow); + } + } else { + NDPI_LOG(NDPI_PROTOCOL_NOE, ndpi_struct, NDPI_LOG_DEBUG, "exclude NOE.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NOE); + } +} +#endif diff --git a/src/lib/protocols/non_tcp_udp.c b/src/lib/protocols/non_tcp_udp.c new file mode 100644 index 000000000..bb48b88a2 --- /dev/null +++ b/src/lib/protocols/non_tcp_udp.c @@ -0,0 +1,108 @@ +/* + * non_tcp_udp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#if defined(NDPI_PROTOCOL_IP_IPSEC) || defined(NDPI_PROTOCOL_IP_GRE) || defined(NDPI_PROTOCOL_IP_ICMP) || defined(NDPI_PROTOCOL_IP_IGMP) || defined(NDPI_PROTOCOL_IP_EGP) || defined(NDPI_PROTOCOL_IP_SCTP) || defined(NDPI_PROTOCOL_IP_OSPF) || defined(NDPI_PROTOCOL_IP_IP_IN_IP) + +#define set_protocol_and_bmask(nprot) \ + { \ + if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask,nprot) != 0) \ + { \ + ndpi_int_add_connection(ndpi_struct, flow, \ + nprot, \ + NDPI_REAL_PROTOCOL); \ + } \ + } + + +void ndpi_search_in_non_tcp_udp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if (packet->iph == NULL) { +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + if (packet->iphv6 == NULL) +#endif + return; + } + + switch (packet->l4_protocol) { +#ifdef NDPI_PROTOCOL_IP_IPSEC + case NDPI_IPSEC_PROTOCOL_ESP: + case NDPI_IPSEC_PROTOCOL_AH: + set_protocol_and_bmask(NDPI_PROTOCOL_IP_IPSEC); + break; +#endif /* NDPI_PROTOCOL_IP_IPSEC */ +#ifdef NDPI_PROTOCOL_IP_GRE + case NDPI_GRE_PROTOCOL_TYPE: + set_protocol_and_bmask(NDPI_PROTOCOL_IP_GRE); + break; +#endif /* NDPI_PROTOCOL_IP_GRE */ +#ifdef NDPI_PROTOCOL_IP_ICMP + case NDPI_ICMP_PROTOCOL_TYPE: + set_protocol_and_bmask(NDPI_PROTOCOL_IP_ICMP); + break; +#endif /* NDPI_PROTOCOL_IP_ICMP */ +#ifdef NDPI_PROTOCOL_IP_IGMP + case NDPI_IGMP_PROTOCOL_TYPE: + set_protocol_and_bmask(NDPI_PROTOCOL_IP_IGMP); + break; +#endif /* NDPI_PROTOCOL_IP_IGMP */ +#ifdef NDPI_PROTOCOL_IP_EGP + case NDPI_EGP_PROTOCOL_TYPE: + set_protocol_and_bmask(NDPI_PROTOCOL_IP_EGP); + break; +#endif /* NDPI_PROTOCOL_IP_EGP */ +#ifdef NDPI_PROTOCOL_IP_SCTP + case NDPI_SCTP_PROTOCOL_TYPE: + set_protocol_and_bmask(NDPI_PROTOCOL_IP_SCTP); + break; +#endif /* NDPI_PROTOCOL_IP_SCTP */ +#ifdef NDPI_PROTOCOL_IP_OSPF + case NDPI_OSPF_PROTOCOL_TYPE: + set_protocol_and_bmask(NDPI_PROTOCOL_IP_OSPF); + break; +#endif /* NDPI_PROTOCOL_IP_OSPF */ +#ifdef NDPI_PROTOCOL_IP_IP_IN_IP + case NDPI_IPIP_PROTOCOL_TYPE: + set_protocol_and_bmask(NDPI_PROTOCOL_IP_IP_IN_IP); + break; +#endif /* NDPI_PROTOCOL_IP_IP_IN_IP */ +#ifdef NDPI_PROTOCOL_IP_ICMPV6 + case NDPI_ICMPV6_PROTOCOL_TYPE: + set_protocol_and_bmask(NDPI_PROTOCOL_IP_ICMPV6); + break; +#endif /* NDPI_PROTOCOL_IP_ICMPV6 */ +#ifdef NDPI_PROTOCOL_IP_VRRP + case 112: + set_protocol_and_bmask(NDPI_PROTOCOL_IP_VRRP); + break; +#endif /* NDPI_PROTOCOL_IP_VRRP */ + } +} + +#endif diff --git a/src/lib/protocols/ntp.c b/src/lib/protocols/ntp.c new file mode 100644 index 000000000..7d19968c5 --- /dev/null +++ b/src/lib/protocols/ntp.c @@ -0,0 +1,68 @@ +/* + * ntp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_NTP + +static void ndpi_int_ntp_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NTP, NDPI_REAL_PROTOCOL); +} + +/* detection also works asymmetrically */ + +void ndpi_search_ntp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (!(packet->udp->dest == htons(123) || packet->udp->source == htons(123))) + goto exclude_ntp; + + NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP port detected\n"); + + if (packet->payload_packet_len != 48) + goto exclude_ntp; + + NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP length detected\n"); + + + if ((((packet->payload[0] & 0x38) >> 3) <= 4)) { + NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "detected NTP."); + ndpi_int_ntp_add_connection(ndpi_struct, flow); + return; + } + + + + exclude_ntp: + NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NTP); +} + +#endif diff --git a/src/lib/protocols/openft.c b/src/lib/protocols/openft.c new file mode 100644 index 000000000..6f4e94bc5 --- /dev/null +++ b/src/lib/protocols/openft.c @@ -0,0 +1,56 @@ +/* + * openft.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_OPENFT + +static void ndpi_int_openft_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OPENFT, NDPI_CORRELATED_PROTOCOL); +} + +void ndpi_search_openft_tcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len > 5 && memcmp(packet->payload, "GET /", 5) == 0) { + NDPI_LOG(NDPI_PROTOCOL_OPENFT, ndpi_struct, NDPI_LOG_DEBUG, "HTTP packet detected.\n"); + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->parsed_lines >= 2 + && packet->line[1].len > 13 && memcmp(packet->line[1].ptr, "X-OpenftAlias:", 14) == 0) { + NDPI_LOG(NDPI_PROTOCOL_OPENFT, ndpi_struct, NDPI_LOG_DEBUG, "OpenFT detected.\n"); + ndpi_int_openft_add_connection(ndpi_struct, flow); + return; + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OPENFT); +} +#endif diff --git a/src/lib/protocols/openvpn.c b/src/lib/protocols/openvpn.c new file mode 100644 index 000000000..df13356ff --- /dev/null +++ b/src/lib/protocols/openvpn.c @@ -0,0 +1,69 @@ +/* + * h323.c + * + * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * + */ + +#include "ndpi_api.h" + + +#ifdef NDPI_PROTOCOL_OPENVPN + +void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct, + struct ndpi_flow_struct* flow) { + struct ndpi_packet_struct* packet = &flow->packet; + u_int16_t dport = 0, sport = 0; + + if (packet->udp != NULL) { + + sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); + + if ((packet->payload_packet_len >= 25) && (sport == 443 || dport == 443) && + (packet->payload[0] == 0x17 && packet->payload[1] == 0x01 && + packet->payload[2] == 0x00 && packet->payload[3] == 0x00)) { + NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, + "found openvpn udp 443.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, + NDPI_REAL_PROTOCOL); + return; + } + + if ( ( (packet->payload_packet_len > 40) || + (packet->payload_packet_len <= 14) ) && // hard-reset + (sport == 1194 || dport == 1194) && + (packet->payload[0] == 0x30 || packet->payload[0] == 0x31 || + packet->payload[0] == 0x32 || packet->payload[0] == 0x33 || + packet->payload[0] == 0x34 || packet->payload[0] == 0x35 || + packet->payload[0] == 0x36 || packet->payload[0] == 0x37 || + packet->payload[0] == 0x38 || packet->payload[0] == 0x39)) { + NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, + "found openvpn broadcast udp STD.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, + NDPI_REAL_PROTOCOL); + return; + } + + } + + if (packet->tcp != NULL) { + + sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); + + if ((packet->payload_packet_len >= 40) && + (sport == 1194 || dport == 1194) && + ((packet->payload[0] == 0x00) && (packet->payload[1] == 0x2a) && + (packet->payload[2] == 0x38))) { + NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, + "found openvpn broadcast udp STD.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, + NDPI_REAL_PROTOCOL); + return; + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, + NDPI_PROTOCOL_OPENVPN); +} + +#endif diff --git a/src/lib/protocols/oracle.c b/src/lib/protocols/oracle.c new file mode 100644 index 000000000..e6df77930 --- /dev/null +++ b/src/lib/protocols/oracle.c @@ -0,0 +1,62 @@ +/* + * oracle.c + * + * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * + * This module is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This module is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License. + * If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + + +#ifdef NDPI_PROTOCOL_ORACLE +static void ndpi_int_oracle_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_ORACLE, NDPI_CORRELATED_PROTOCOL); +} + +void ndpi_search_oracle(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t dport = 0, sport = 0; + + NDPI_LOG(NDPI_PROTOCOL_ORACLE, ndpi_struct, NDPI_LOG_DEBUG, "search for ORACLE.\n"); + + if(packet->tcp != NULL) { + sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); + NDPI_LOG(NDPI_PROTOCOL_ORACLE, ndpi_struct, NDPI_LOG_DEBUG, "calculating ORACLE over tcp.\n"); + /* Oracle Database 9g,10g,11g */ + if ((dport == 1521 || sport == 1521) + && (((packet->payload[0] == 0x07) && (packet->payload[1] == 0xff) && (packet->payload[2] == 0x00)) + || ((packet->payload_packet_len >= 232) && ((packet->payload[0] == 0x00) || (packet->payload[0] == 0x01)) + && (packet->payload[1] != 0x00) + && (packet->payload[2] == 0x00) + && (packet->payload[3] == 0x00)))) { + NDPI_LOG(NDPI_PROTOCOL_ORACLE, ndpi_struct, NDPI_LOG_DEBUG, "found oracle.\n"); + ndpi_int_oracle_add_connection(ndpi_struct, flow); + } else if (packet->payload_packet_len == 213 && packet->payload[0] == 0x00 && + packet->payload[1] == 0xd5 && packet->payload[2] == 0x00 && + packet->payload[3] == 0x00 ) { + NDPI_LOG(NDPI_PROTOCOL_ORACLE, ndpi_struct, NDPI_LOG_DEBUG, "found oracle.\n"); + ndpi_int_oracle_add_connection(ndpi_struct, flow); + } + } else { + NDPI_LOG(NDPI_PROTOCOL_ORACLE, ndpi_struct, NDPI_LOG_DEBUG, "exclude ORACLE.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ORACLE); + } +} +#endif diff --git a/src/lib/protocols/oscar.c b/src/lib/protocols/oscar.c new file mode 100644 index 000000000..c9ec58eba --- /dev/null +++ b/src/lib/protocols/oscar.c @@ -0,0 +1,273 @@ +/* + * oscar.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + + +#ifdef NDPI_PROTOCOL_OSCAR + +static void ndpi_int_oscar_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR, protocol_type); + + if (src != NULL) { + src->oscar_last_safe_access_time = packet->tick_timestamp; + } + if (dst != NULL) { + dst->oscar_last_safe_access_time = packet->tick_timestamp; + } +} + +static void ndpi_search_oscar_tcp_connect(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + if (packet->payload_packet_len >= 10 && packet->payload[0] == 0x2a) { + + /* if is a oscar connection, 10 bytes long */ + + /* OSCAR Connection :: Connection detected at initial packets only + * +----+----+------+------+---------------+ + * |0x2a|Code|SeqNum|PktLen|ProtcolVersion | + * +----+----+------+------+---------------+ + * Code 1 Byte : 0x01 Oscar Connection + * SeqNum and PktLen are 2 Bytes each and ProtcolVersion: 0x00000001 + * */ + if (get_u_int8_t(packet->payload, 1) == 0x01 && get_u_int16_t(packet->payload, 4) == htons(packet->payload_packet_len - 6) + && get_u_int32_t(packet->payload, 6) == htonl(0x0000000001)) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Connection FOUND \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + /* OSCAR IM + * +----+----+------+------+----------+-----------+ + * |0x2a|Code|SeqNum|PktLen|FNACfamily|FNACsubtype| + * +----+----+------+------+----------+-----------+ + * Code 1 Byte : 0x02 SNAC Header Code; + * SeqNum and PktLen are 2 Bytes each + * FNACfamily 2 Byte : 0x0004 IM Messaging + * FNACEsubtype 2 Byte : 0x0006 IM Outgoing Message, 0x000c IM Message Acknowledgment + * */ + if (packet->payload[1] == 0x02 + && ntohs(get_u_int16_t(packet->payload, 4)) >= + packet->payload_packet_len - 6 && get_u_int16_t(packet->payload, 6) == htons(0x0004) + && (get_u_int16_t(packet->payload, 8) == htons(0x0006) + || get_u_int16_t(packet->payload, 8) == htons(0x000c))) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR IM Detected \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + + + /* detect http connections */ + if (packet->payload_packet_len >= 18) { + if ((packet->payload[0] == 'P') && (memcmp(packet->payload, "POST /photo/upload", 18) == 0)) { + NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet); + if (packet->host_line.len >= 18 && packet->host_line.ptr != NULL) { + if (memcmp(packet->host_line.ptr, "lifestream.aol.com", 18) == 0) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, + "OSCAR over HTTP found, POST method\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + } + if (packet->payload_packet_len > 40) { + if ((packet->payload[0] == 'G') && (memcmp(packet->payload, "GET /", 5) == 0)) { + if ((memcmp(&packet->payload[5], "aim/fetchEvents?aimsid=", 23) == 0) || + (memcmp(&packet->payload[5], "aim/startSession?", 17) == 0) || + (memcmp(&packet->payload[5], "aim/gromit/aim_express", 22) == 0) || + (memcmp(&packet->payload[5], "b/ss/aolwpaim", 13) == 0) || + (memcmp(&packet->payload[5], "hss/storage/aimtmpshare", 23) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR over HTTP found, GET /aim/\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + + if ((memcmp(&packet->payload[5], "aim", 3) == 0) || (memcmp(&packet->payload[5], "im", 2) == 0)) { + NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet); + if (packet->user_agent_line.len > 15 && packet->user_agent_line.ptr != NULL && + ((memcmp(packet->user_agent_line.ptr, "mobileAIM/", 10) == 0) || + (memcmp(packet->user_agent_line.ptr, "ICQ/", 4) == 0) || + (memcmp(packet->user_agent_line.ptr, "mobileICQ/", 10) == 0) || + (memcmp(packet->user_agent_line.ptr, "AIM%20Free/", NDPI_STATICSTRING_LEN("AIM%20Free/")) == 0) || + (memcmp(packet->user_agent_line.ptr, "AIM/", 4) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR over HTTP found\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet); + if (packet->referer_line.ptr != NULL && packet->referer_line.len >= 22) { + + if (memcmp(&packet->referer_line.ptr[packet->referer_line.len - NDPI_STATICSTRING_LEN("WidgetMain.swf")], + "WidgetMain.swf", NDPI_STATICSTRING_LEN("WidgetMain.swf")) == 0) { + u_int16_t i; + for (i = 0; i < (packet->referer_line.len - 22); i++) { + if (packet->referer_line.ptr[i] == 'a') { + if (memcmp(&packet->referer_line.ptr[i + 1], "im/gromit/aim_express", 21) == 0) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, + "OSCAR over HTTP found : aim/gromit/aim_express\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + } + } + } + if (memcmp(packet->payload, "CONNECT ", 8) == 0) { + if (memcmp(packet->payload, "CONNECT login.icq.com:443 HTTP/1.", 33) == 0) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR ICQ-HTTP FOUND\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + if (memcmp(packet->payload, "CONNECT login.oscar.aol.com:5190 HTTP/1.", 40) == 0) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR AIM-HTTP FOUND\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + + } + } + + if (packet->payload_packet_len > 43 + && memcmp(packet->payload, "GET http://http.proxy.icq.com/hello HTTP/1.", 43) == 0) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR ICQ-HTTP PROXY FOUND\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + + if (packet->payload_packet_len > 46 + && memcmp(packet->payload, "GET http://aimhttp.oscar.aol.com/hello HTTP/1.", 46) == 0) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR AIM-HTTP PROXY FOUND\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + + if (packet->payload_packet_len > 5 && get_u_int32_t(packet->payload, 0) == htonl(0x05010003)) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "Maybe OSCAR Picturetransfer\n"); + return; + } + + if (packet->payload_packet_len == 10 && get_u_int32_t(packet->payload, 0) == htonl(0x05000001) && + get_u_int32_t(packet->payload, 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "Maybe OSCAR Picturetransfer\n"); + return; + } + + if (packet->payload_packet_len >= 70 && + memcmp(&packet->payload[packet->payload_packet_len - 26], + "\x67\x00\x65\x00\x74\x00\x43\x00\x61\x00\x74\x00\x61\x00\x6c\x00\x6f\x00\x67", 19) == 0) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_OSCAR) != 0) { + + if (flow->packet_counter == 1 + && + ((packet->payload_packet_len == 9 + && memcmp(packet->payload, "\x00\x09\x00\x00\x83\x01\xc0\x00\x00", 9) == 0) + || (packet->payload_packet_len == 13 + && (memcmp(packet->payload, "\x00\x0d\x00\x87\x01\xc0", 6) == 0 + || memcmp(packet->payload, "\x00\x0d\x00\x87\x01\xc1", 6) == 0)))) { + flow->oscar_video_voice = 1; + } + if (flow->oscar_video_voice && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len + && packet->payload[2] == 0x00 && packet->payload[3] == 0x00) { + } + + if (packet->payload_packet_len >= 70 && ntohs(get_u_int16_t(packet->payload, 4)) == packet->payload_packet_len) { + if (memcmp(packet->payload, "OFT", 3) == 0 && + ((packet->payload[3] == '3' && ((memcmp(&packet->payload[4], "\x01\x00\x01\x01", 4) == 0) + || (memcmp(&packet->payload[6], "\x01\x01\x00", 3) == 0))) + || (packet->payload[3] == '2' && ((memcmp(&packet->payload[6], "\x01\x01", 2) + == 0) + )))) { + // FILE TRANSFER PATTERN:: OFT3 or OFT2 + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR FILE TRANSFER\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + if (memcmp(packet->payload, "ODC2", 4) == 0 && memcmp(&packet->payload[6], "\x00\x01\x00\x06", 4) == 0) { + //PICTURE TRANSFER PATTERN EXMAPLE:: + //4f 44 43 32 00 4c 00 01 00 06 00 00 00 00 00 00 ODC2.L.......... + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + if (packet->payload_packet_len > 40 && (memcmp(&packet->payload[2], "\x04\x4a\x00", 3) == 0) + && (memcmp(&packet->payload[6], "\x00\x00", 2) == 0) + && packet->payload[packet->payload_packet_len - 15] == 'F' + && packet->payload[packet->payload_packet_len - 12] == 'L' + && (memcmp(&packet->payload[packet->payload_packet_len - 6], "DEST", 4) == 0) + && (memcmp(&packet->payload[packet->payload_packet_len - 2], "\x00\x00", 2) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + if (ntohs(packet->tcp->dest) == 443 || ntohs(packet->tcp->source) == 443) { + flow->oscar_ssl_voice_stage = 1; + } + return; + + } + } + if (flow->packet_counter < 3 && packet->payload_packet_len > 11 && (memcmp(packet->payload, "\x00\x37\x04\x4a", 4) + || memcmp(packet->payload, "\x00\x0a\x04\x4a", + 4))) { + return; + } + + + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_OSCAR) { + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OSCAR); + return; + } +} + +void ndpi_search_oscar(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + if (packet->tcp != NULL) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR :: TCP\n"); + ndpi_search_oscar_tcp_connect(ndpi_struct, flow); + } +} +#endif diff --git a/src/lib/protocols/pando.c b/src/lib/protocols/pando.c new file mode 100644 index 000000000..c409982de --- /dev/null +++ b/src/lib/protocols/pando.c @@ -0,0 +1,157 @@ +/* + * pando.c + * + * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> + * + * The signature is based on the Libprotoident library. + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_PANDO +static void ndpi_int_pando_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PANDO, NDPI_REAL_PROTOCOL); +} + +static void ndpi_check_pando_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + if ((payload_len > 0) && match_first_bytes(packet->payload, "\x0ePan")) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n"); + ndpi_int_pando_add_connection(ndpi_struct, flow); + } +} + +static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->pando_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "PANDO stage 0: \n"); + + if ((payload_len >= 4) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x09)) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->pando_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 + return; + } + + if ((payload_len > 0) && match_first_bytes(packet->payload, "UDPA")) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->pando_stage = packet->packet_direction + 3; // packet_direction 0: stage 3, packet_direction 1: stage 4 + return; + } + + if ((payload_len > 0) && (match_first_bytes(packet->payload, "UDPR") || match_first_bytes(packet->payload, "UDPE"))) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->pando_stage = packet->packet_direction + 5; // packet_direction 0: stage 5, packet_direction 1: stage 6 + return; + } + + } else if ((flow->pando_stage == 1) || (flow->pando_stage == 2)) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "PANDO stage %u: \n", flow->pando_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->pando_stage - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len == 0) || ((payload_len >= 4) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x09))) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n"); + ndpi_int_pando_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PANDO, resetting the stage to 0...\n"); + flow->pando_stage = 0; + } + + } else if ((flow->pando_stage == 3) || (flow->pando_stage == 4)) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "PANDO stage %u: \n", flow->pando_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->pando_stage - packet->packet_direction) == 3) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len == 0) || match_first_bytes(packet->payload, "UDPR") || match_first_bytes(packet->payload, "UDPE")) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n"); + ndpi_int_pando_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PANDO, resetting the stage to 0...\n"); + flow->pando_stage = 0; + } + + } else if ((flow->pando_stage == 5) || (flow->pando_stage == 6)) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "PANDO stage %u: \n", flow->pando_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->pando_stage - packet->packet_direction) == 5) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len > 0) && match_first_bytes(packet->payload, "UDPA")) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n"); + ndpi_int_pando_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PANDO, resetting the stage to 0...\n"); + flow->pando_stage = 0; + } + } +} + +void ndpi_search_pando(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + /* Break after 20 packets. */ + if (flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_TRACE, "PANDO excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PANDO); + return; + } + + /* skip marked or retransmitted packets */ + if (packet->tcp_retransmission != 0) { + return; + } + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_PANDO) { + return; + } + + NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_TRACE, "PANDO detection...\n"); + ndpi_check_pando_tcp(ndpi_struct, flow); + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_PANDO) { + return; + } + + ndpi_check_pando_udp(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/pcanywhere.c b/src/lib/protocols/pcanywhere.c new file mode 100644 index 000000000..a86785cd2 --- /dev/null +++ b/src/lib/protocols/pcanywhere.c @@ -0,0 +1,55 @@ +/* + * pcanywhere.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_PCANYWHERE + +static void ndpi_int_pcanywhere_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PCANYWHERE, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_pcanywhere(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->udp != NULL && packet->udp->dest == htons(5632) + && packet->payload_packet_len == 2 + && (memcmp(packet->payload, "NQ", 2) == 0 || memcmp(packet->payload, "ST", 2) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_PCANYWHERE, ndpi_struct, NDPI_LOG_DEBUG, + "PC Anywhere name or status query detected.\n"); + ndpi_int_pcanywhere_add_connection(ndpi_struct, flow); + return; + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PCANYWHERE); +} + +#endif diff --git a/src/lib/protocols/postgres.c b/src/lib/protocols/postgres.c new file mode 100644 index 000000000..bd078d8cd --- /dev/null +++ b/src/lib/protocols/postgres.c @@ -0,0 +1,120 @@ +/* + * postgres.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_POSTGRES + + +static void ndpi_int_postgres_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_POSTGRES, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_postgres_tcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + u_int16_t size; + + if (flow->l4.tcp.postgres_stage == 0) { + //SSL + if (packet->payload_packet_len > 7 && + packet->payload[4] == 0x04 && + packet->payload[5] == 0xd2 && + packet->payload[6] == 0x16 && + packet->payload[7] == 0x2f && ntohl(get_u_int32_t(packet->payload, 0)) == packet->payload_packet_len) { + flow->l4.tcp.postgres_stage = 1 + packet->packet_direction; + return; + } + //no SSL + if (packet->payload_packet_len > 7 && + //protocol version number - to be updated + ntohl(get_u_int32_t(packet->payload, 4)) < 0x00040000 && + ntohl(get_u_int32_t(packet->payload, 0)) == packet->payload_packet_len) { + flow->l4.tcp.postgres_stage = 3 + packet->packet_direction; + return; + } + } else { + if (flow->l4.tcp.postgres_stage == 2 - packet->packet_direction) { + //SSL accepted + if (packet->payload_packet_len == 1 && packet->payload[0] == 'S') { + NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "PostgreSQL detected, SSL accepted.\n"); + ndpi_int_postgres_add_connection(ndpi_struct, flow); + return; + } + //SSL denied + if (packet->payload_packet_len == 1 && packet->payload[0] == 'N') { + NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "PostgreSQL detected, SSL denied.\n"); + ndpi_int_postgres_add_connection(ndpi_struct, flow); + return; + } + } + //no SSL + if (flow->l4.tcp.postgres_stage == 4 - packet->packet_direction) + if (packet->payload_packet_len > 8 && + ntohl(get_u_int32_t(packet->payload, 5)) < 10 && + ntohl(get_u_int32_t(packet->payload, 1)) == packet->payload_packet_len - 1 && packet->payload[0] == 0x52) { + NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "PostgreSQL detected, no SSL.\n"); + ndpi_int_postgres_add_connection(ndpi_struct, flow); + return; + } + if (flow->l4.tcp.postgres_stage == 6 + && ntohl(get_u_int32_t(packet->payload, 1)) == packet->payload_packet_len - 1 && packet->payload[0] == 'p') { + NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "found postgres asymmetrically.\n"); + ndpi_int_postgres_add_connection(ndpi_struct, flow); + return; + } + if (flow->l4.tcp.postgres_stage == 5 && packet->payload[0] == 'R') { + if (ntohl(get_u_int32_t(packet->payload, 1)) == packet->payload_packet_len - 1) { + NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "found postgres asymmetrically.\n"); + ndpi_int_postgres_add_connection(ndpi_struct, flow); + return; + } + size = (u_int16_t)ntohl(get_u_int32_t(packet->payload, 1)) + 1; + if (packet->payload[size - 1] == 'S') { + if ((size + get_u_int32_t(packet->payload, (size + 1))) == packet->payload_packet_len) { + NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "found postgres asymmetrically.\n"); + ndpi_int_postgres_add_connection(ndpi_struct, flow); + return; + } + } + size += get_u_int32_t(packet->payload, (size + 1)) + 1; + if (packet->payload[size - 1] == 'S') { + NDPI_LOG(NDPI_PROTOCOL_POSTGRES, ndpi_struct, NDPI_LOG_DEBUG, "found postgres asymmetrically.\n"); + ndpi_int_postgres_add_connection(ndpi_struct, flow); + return; + } + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_POSTGRES); +} + +#endif diff --git a/src/lib/protocols/pplive.c b/src/lib/protocols/pplive.c new file mode 100644 index 000000000..1cd880503 --- /dev/null +++ b/src/lib/protocols/pplive.c @@ -0,0 +1,220 @@ +/* + * pplive.c + * + * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> + * + * The signature is mostly based on the Libprotoident library + * except the detection of HTTP Steam flows. + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_PPLIVE +static void ndpi_int_pplive_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PPLIVE, NDPI_REAL_PROTOCOL); +} + +static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->pplive_stage1 == 0) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n"); + + if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->pplive_stage1 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 + return; + } + + if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x42\x01")) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->pplive_stage1 = packet->packet_direction + 3; // packet_direction 0: stage 3, packet_direction 1: stage 4 + return; + } + + if ((payload_len > 0) && match_first_bytes(packet->payload, "\x1c\x1c\x32\x01")) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->pplive_stage1 = packet->packet_direction + 5; // packet_direction 0: stage 5, packet_direction 1: stage 6 + return; + } + + } else if ((flow->pplive_stage1 == 1) || (flow->pplive_stage1 == 2)) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage %u: \n", flow->pplive_stage1); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->pplive_stage1 - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len > 0) && (match_first_bytes(packet->payload, "\xe9\x03\x42\x01") || match_first_bytes(packet->payload, "\xe9\x03\x41\x01"))) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n"); + ndpi_int_pplive_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PPLIVE, resetting the stage to 0...\n"); + flow->pplive_stage1 = 0; + } + + } else if ((flow->pplive_stage1 == 3) || (flow->pplive_stage1 == 4)) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage %u: \n", flow->pplive_stage1); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->pplive_stage1 - packet->packet_direction) == 3) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n"); + ndpi_int_pplive_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PPLIVE, resetting the stage to 0...\n"); + flow->pplive_stage1 = 0; + } + } else if ((flow->pplive_stage1 == 5) || (flow->pplive_stage1 == 6)) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage %u: \n", flow->pplive_stage1); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->pplive_stage1 - packet->packet_direction) == 5) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len > 0) && match_first_bytes(packet->payload, "\x1c\x1c\x32\x01")) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n"); + ndpi_int_pplive_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PPLIVE, resetting the stage to 0...\n"); + flow->pplive_stage1 = 0; + } + } + +} + +static void ndpi_check_pplive_udp2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->pplive_stage2 == 0) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n"); + + if ((payload_len == 57) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->pplive_stage2 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage %u: \n", flow->pplive_stage2); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->pplive_stage2 - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if (payload_len == 0) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n"); + ndpi_int_pplive_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PPLIVE, resetting the stage to 0...\n"); + flow->pplive_stage2 = 0; + } + + } +} + +static void ndpi_check_pplive_udp3(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->pplive_stage3 == 0) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n"); + + if ((payload_len == 94) && (packet->udp->dest == htons(5041) || packet->udp->source == htons(5041) || packet->udp->dest == htons(8303) || packet->udp->source == htons(8303))) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->pplive_stage3 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 + return; + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage %u: \n", flow->pplive_stage3); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->pplive_stage3 - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len == 0) || (payload_len == 49) ||(payload_len == 94)) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n"); + ndpi_int_pplive_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to PPLIVE, resetting the stage to 0...\n"); + flow->pplive_stage3 = 0; + } + } + +} + +void ndpi_search_pplive(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + /* Break after 20 packets. */ + if (flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Exclude PPLIVE.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PPLIVE); + return; + } + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_PPLIVE) { + return; + } + + NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE detection...\n"); + ndpi_check_pplive_udp1(ndpi_struct, flow); + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_PPLIVE) { + return; + } + + ndpi_check_pplive_udp2(ndpi_struct, flow); + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_PPLIVE) { + return; + } + + ndpi_check_pplive_udp3(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/ppstream.c b/src/lib/protocols/ppstream.c new file mode 100644 index 000000000..06c3c4045 --- /dev/null +++ b/src/lib/protocols/ppstream.c @@ -0,0 +1,105 @@ +/* + * ppstream.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_PPSTREAM + +static void ndpi_int_ppstream_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PPSTREAM, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_ppstream(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + + + /* check TCP Connections -> Videodata */ + if (packet->tcp != NULL) { + if (packet->payload_packet_len >= 60 && get_u_int32_t(packet->payload, 52) == 0 + && memcmp(packet->payload, "PSProtocol\x0", 11) == 0) { + NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, "found ppstream over tcp.\n"); + ndpi_int_ppstream_add_connection(ndpi_struct, flow); + return; + } + } + + if (packet->udp != NULL) { + if (packet->payload_packet_len > 2 && packet->payload[2] == 0x43 + && ((packet->payload_packet_len - 4 == get_l16(packet->payload, 0)) + || (packet->payload_packet_len == get_l16(packet->payload, 0)) + || (packet->payload_packet_len >= 6 && packet->payload_packet_len - 6 == get_l16(packet->payload, 0)))) { + flow->l4.udp.ppstream_stage++; + if (flow->l4.udp.ppstream_stage == 5) { + NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, + "found ppstream over udp pattern len, 43.\n"); + ndpi_int_ppstream_add_connection(ndpi_struct, flow); + return; + } + return; + } + + if (flow->l4.udp.ppstream_stage == 0 + && packet->payload_packet_len > 4 && ((packet->payload_packet_len - 4 == get_l16(packet->payload, 0)) + || (packet->payload_packet_len == get_l16(packet->payload, 0)) + || (packet->payload_packet_len >= 6 + && packet->payload_packet_len - 6 == get_l16(packet->payload, + 0)))) { + + if (packet->payload[2] == 0x00 && packet->payload[3] == 0x00 && packet->payload[4] == 0x03) { + flow->l4.udp.ppstream_stage = 7; + NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, "need next packet I.\n"); + return; + } + } + + if (flow->l4.udp.ppstream_stage == 7 + && packet->payload_packet_len > 4 && packet->payload[3] == 0x00 + && ((packet->payload_packet_len - 4 == get_l16(packet->payload, 0)) + || (packet->payload_packet_len == get_l16(packet->payload, 0)) + || (packet->payload_packet_len >= 6 && packet->payload_packet_len - 6 == get_l16(packet->payload, 0))) + && (packet->payload[2] == 0x00 && packet->payload[4] == 0x03)) { + NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, + "found ppstream over udp with pattern Vb.\n"); + ndpi_int_ppstream_add_connection(ndpi_struct, flow); + return; + } + + + + + } + + NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, "exclude ppstream.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PPSTREAM); +} +#endif diff --git a/src/lib/protocols/pptp.c b/src/lib/protocols/pptp.c new file mode 100644 index 000000000..c5ad6c8b9 --- /dev/null +++ b/src/lib/protocols/pptp.c @@ -0,0 +1,61 @@ +/* + * pptp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +/* include files */ + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_PPTP + +static void ndpi_int_pptp_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PPTP, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_pptp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len >= 10 && get_u_int16_t(packet->payload, 0) == htons(packet->payload_packet_len) + && get_u_int16_t(packet->payload, 2) == htons(0x0001) /* message type: control message */ + &&get_u_int32_t(packet->payload, 4) == htonl(0x1a2b3c4d) /* cookie: correct */ + &&(get_u_int16_t(packet->payload, 8) == htons(0x0001) /* control type: start-control-connection-request */ + )) { + + NDPI_LOG(NDPI_PROTOCOL_PPTP, ndpi_struct, NDPI_LOG_DEBUG, "found pptp.\n"); + ndpi_int_pptp_add_connection(ndpi_struct, flow); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_PPTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude pptp.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PPTP); +} +#endif diff --git a/src/lib/protocols/qq.c b/src/lib/protocols/qq.c new file mode 100644 index 000000000..17c5268d9 --- /dev/null +++ b/src/lib/protocols/qq.c @@ -0,0 +1,665 @@ +/* + * qq.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_QQ + +static void ndpi_int_qq_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_QQ, protocol_type); +} + + +/* + * a qq client packet looks like this: + * + * TCP packets starts with 16 bit length, then the normal packets follows + * + * 0 1 byte packet tag (usually 0x02) + * 1 2 byte client tag (client version) + * 3 2 byte command + * 5 2 byte sequence number + * 7 4 byte userid + * 11 x bytes data + * LAST 1 byte packet tail (usually 0x03) + * + * a qq server packet looks like this: + * + * TCP packets starts with 16 bit length, then the normal packets follows + * + * 0 1 byte packet tag (usually 0x02) + * 1 2 byte source tag (client version, might also be a server id) + * 3 2 byte command (usually reply to client request, so same command id) + * 5 2 byte sequence number + * LAST 1 byte packet tail (usually 0x03) + * + * NOTE: there are other qq versions which uses different packet types! + */ + +/* + * these are some currently known client ids (or server ids) + * new ids might be added here if the traffic is really QQ + */ +static const u_int16_t ndpi_valid_qq_versions[] = { + 0x0100, 0x05a5, 0x062e, 0x06d5, 0x072e, 0x0801, 0x087d, 0x08d2, 0x0961, + 0x0a1d, 0x0b07, 0x0b2f, 0x0b35, 0x0b37, 0x0c0b, 0x0c0d, 0x0c21, 0x0c49, + 0x0d05, 0x0d51, 0x0d55, 0x0d61, 0x0e1b, 0x0e35, 0x0f15, 0x0f4b, 0x0f5f, + 0x1105, 0x111b, 0x111d, 0x1131, 0x113f, 0x115b, 0x1203, 0x1205, 0x120b, + 0x1251, 0x1412, 0x1441, 0x1501, 0x1549, 0x163a, 0x1801, 0x180d, 0x1c27, + 0x1e0d +}; + +/** + * this functions checks whether the packet is a valid qq packet + * it can handle tcp and udp packets + */ + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +u_int8_t ndpi_is_valid_qq_packet(const struct ndpi_packet_struct *packet) +{ + u_int8_t real_start = 0; + u_int16_t command; + u_int8_t ids, found = 0; + u_int16_t version_id; + + if (packet->payload_packet_len < 9) + return 0; + + /* for tcp the length is prefixed */ + if (packet->tcp) { + if (ntohs(get_u_int16_t(packet->payload, 0)) != packet->payload_packet_len) { + return 0; + } + real_start = 2; + } + + /* packet usually starts with 0x02 */ + if (packet->payload[real_start] != 0x02) { + return 0; + } + + /* packet usually ends with 0x03 */ + if (packet->payload[packet->payload_packet_len - 1] != 0x03) { + return 0; + } + + version_id = ntohs(get_u_int16_t(packet->payload, real_start + 1)); + + if (version_id == 0) { + return 0; + } + + /* check for known version id */ + for (ids = 0; ids < sizeof(ndpi_valid_qq_versions) / sizeof(ndpi_valid_qq_versions[0]); ids++) { + if (version_id == ndpi_valid_qq_versions[ids]) { + found = 1; + break; + } + } + + if (!found) + return 0; + + command = ntohs(get_u_int16_t(packet->payload, real_start + 3)); + + /* these are some known commands, not all need to be checked + since many are used with already established connections */ + + switch (command) { + case 0x0091: /* get server */ + case 0x00ba: /* login token */ + case 0x00dd: /* password verify */ + case 0x00e5: + case 0x00a4: + case 0x0030: + case 0x001d: + case 0x0001: + case 0x0062: + case 0x0002: + case 0x0022: + case 0x0029: + break; + default: + return 0; + break; + } + + return 1; +} + +/* + * some file transfer packets look like this + * + * 0 1 byte packet tag (usually 0x04) + * 1 2 byte client tag (client version) + * 3 2 byte length (this is speculative) + * LAST 1 byte packet tail (usually 0x03) + * + */ +/** + * this functions checks whether the packet is a valid qq file transfer packet + * it can handle tcp and udp packets + */ + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +u_int8_t ndpi_is_valid_qq_ft_packet(const struct ndpi_packet_struct *packet) +{ + u_int8_t ids, found = 0; + u_int16_t version_id; + + if (packet->payload_packet_len < 9) + return 0; + + /* file transfer packets may start with 0x00 (control), 0x03 (data), 0x04 (agent) */ + + if (packet->payload[0] != 0x04 && packet->payload[0] != 0x03 && packet->payload[0] != 0x00) { + return 0; + } + + version_id = ntohs(get_u_int16_t(packet->payload, 1)); + + if (version_id == 0) { + return 0; + } + + /* check for known version id */ + for (ids = 0; ids < sizeof(ndpi_valid_qq_versions) / sizeof(ndpi_valid_qq_versions[0]); ids++) { + if (version_id == ndpi_valid_qq_versions[ids]) { + found = 1; + break; + } + } + + if (!found) + return 0; + + if (packet->payload[0] == 0x04) { + + if (ntohs(get_u_int16_t(packet->payload, 3)) != packet->payload_packet_len) { + return 0; + } + + /* packet usually ends with 0x03 */ + if (packet->payload[packet->payload_packet_len - 1] != 0x03) { + return 0; + } + } else if (packet->payload[0] == 0x03) { + /* TODO currently not detected */ + return 0; + } else if (packet->payload[0] == 0x00) { + + /* packet length check, there might be other lengths */ + if (packet->payload_packet_len != 84) { + return 0; + } + + /* packet usually ends with 0x0c ? */ + if (packet->payload[packet->payload_packet_len - 1] != 0x0c) { + return 0; + } + } + return 1; +} + +static void ndpi_search_qq_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + static const u_int16_t p8000_patt_02[12] = // maybe version numbers + { 0x1549, 0x1801, 0x180d, 0x0961, 0x01501, 0x0e35, 0x113f, 0x0b37, 0x1131, 0x163a, 0x1e0d }; + u_int16_t no_of_patterns = 11, index = 0; + + + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "search qq udp.\n"); + + + if (flow->qq_stage <= 3) { + if ((packet->payload_packet_len == 27 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0300 + && packet->payload[2] == 0x01) + || (packet->payload_packet_len == 84 && ((ntohs(get_u_int16_t(packet->payload, 0)) == 0x000e + && packet->payload[2] == 0x35) + || (ntohs(get_u_int16_t(packet->payload, 0)) == 0x0015 + && packet->payload[2] == 0x01) + || (ntohs(get_u_int16_t(packet->payload, 0)) == 0x000b + && packet->payload[2] == 0x37) + || (ntohs(get_u_int16_t(packet->payload, 0)) == 0x0015 + && packet->payload[2] == 0x49))) + || (packet->payload_packet_len > 10 + && ((get_u_int16_t(packet->payload, 0) == htons(0x000b) && packet->payload[2] == 0x37) + || (get_u_int32_t(packet->payload, 0) == htonl(0x04163a00) + && packet->payload[packet->payload_packet_len - 1] == 0x03 + && packet->payload[4] == packet->payload_packet_len)))) { + /* + if (flow->qq_stage == 3 && flow->detected_protocol == NDPI_PROTOCOL_QQ) { + if (flow->packet_direction_counter[0] > 0 && flow->packet_direction_counter[1] > 0) { + flow->protocol_subtype = NDPI_PROTOCOL_QQ_SUBTYPE_AUDIO; + return; + } else if (flow->packet_counter < 10) { + return; + } + } */ + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, + "found qq udp pattern 030001 or 000e35 four times.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + if (packet->payload_packet_len > 2 && (packet->payload[0] == 0x02 || packet->payload[0] == 0x04)) { + u_int16_t pat = ntohs(get_u_int16_t(packet->payload, 1)); + for (index = 0; index < no_of_patterns; index++) { + if (pat == p8000_patt_02[index] && packet->payload[packet->payload_packet_len - 1] == 0x03) { + flow->qq_stage++; + // maybe we can test here packet->payload[4] == packet->payload_packet_len + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, + "found qq udp pattern 02 ... 03 four times.\n"); + /* + if (packet->payload[0] == 0x04) { + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } */ + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + } + } + if (packet->payload_packet_len == 84 && (packet->payload[0] == 0 || packet->payload[0] == 0x03)) { + u_int16_t pat = ntohs(get_u_int16_t(packet->payload, 1)); + for (index = 0; index < no_of_patterns; index++) { + if (pat == p8000_patt_02[index]) { + flow->qq_stage++; + /* + if (flow->qq_stage == 3 && flow->packet_direction_counter[0] > 0 && + flow->packet_direction_counter[1] > 0) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern four times.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } else */ if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern four times.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + } + } + if (packet->payload_packet_len > 2 && packet->payload[0] == 0x04 + && ((ntohs(get_u_int16_t(packet->payload, 1)) == 0x1549 + || ntohs(get_u_int16_t(packet->payload, 1)) == 0x1801 || ntohs(get_u_int16_t(packet->payload, 1)) == 0x0961) + || + (packet->payload_packet_len > 16 + && (ntohs(get_u_int16_t(packet->payload, 1)) == 0x180d || ntohs(get_u_int16_t(packet->payload, 1)) == 0x096d) + && ntohl(get_u_int32_t(packet->payload, 12)) == 0x28000000 + && ntohs(get_u_int16_t(packet->payload, 3)) == packet->payload_packet_len)) + && packet->payload[packet->payload_packet_len - 1] == 0x03) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, + "found qq udp pattern 04 1159 ... 03 four times.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + if (packet->payload_packet_len > 2 && (packet->payload[0] == 0x06 || packet->payload[0] == 0x02) + && ntohs(get_u_int16_t(packet->payload, 1)) == 0x0100 + && (packet->payload[packet->payload_packet_len - 1] == 0x00 + || packet->payload[packet->payload_packet_len - 1] == 0x03)) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, + "found qq udp pattern 02/06 0100 ... 03/00 four times.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + + if (packet->payload_packet_len > 2 && (packet->payload[0] == 0x02) + && ntohs(get_u_int16_t(packet->payload, 1)) == 0x1131 && packet->payload[packet->payload_packet_len - 1] == 0x03) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, + "found qq udp pattern 02 1131 ... 03 four times.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + + if (packet->payload_packet_len > 5 && get_u_int16_t(packet->payload, 0) == htons(0x0203) && + ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len && + get_u_int16_t(packet->payload, 4) == htons(0x0b0b)) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, + "found qq udp pattern 0203[packet_length_0b0b] three times.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + + if (packet->udp->dest == htons(9000) || packet->udp->source == htons(9000)) { + if (packet->payload_packet_len > 3 + && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0202 + && ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, + "found qq udp pattern 02 02 <length> four times.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + + } + } + + if (ndpi_is_valid_qq_packet(packet)) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over udp.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq packet stage %d\n", flow->qq_stage); + return; + } + + if (ndpi_is_valid_qq_ft_packet(packet)) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq ft over udp.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + + if (flow->qq_stage && flow->packet_counter <= 5) { + return; + } + + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "QQ excluded\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QQ); +} + + + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +void ndpi_search_qq_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + + + u_int16_t i = 0; + // u_int16_t a = 0; + + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "search qq tcp.\n"); + + if (packet->payload_packet_len == 39 && get_u_int32_t(packet->payload, 0) == htonl(0x27000000) && + get_u_int16_t(packet->payload, 4) == htons(0x0014) && get_u_int32_t(packet->payload, 11) != 0 && + get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == htons(0x0000)) { + if (flow->qq_stage == 4) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp - maybe ft/audio/video.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + flow->qq_stage = 4; + return; + } + + if ((packet->payload_packet_len > 4 && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len + && get_u_int16_t(packet->payload, 2) == htons(0x0212) && packet->payload[4] == 0x0b) + || (packet->payload_packet_len > 6 && packet->payload[0] == 0x02 + && packet->payload[packet->payload_packet_len - 1] == 0x03 + && ntohs(get_u_int16_t(packet->payload, 1)) == packet->payload_packet_len + && (get_u_int16_t(packet->payload, 3) == htons(0x0605) || get_u_int16_t(packet->payload, 3) == htons(0x0608)) + && packet->payload[5] == 0x00) + || (packet->payload_packet_len > 9 && get_u_int32_t(packet->payload, 0) == htonl(0x04154900) + && get_l16(packet->payload, 4) == packet->payload_packet_len + && packet->payload[packet->payload_packet_len - 1] == 0x03) + || (packet->payload_packet_len > 9 && get_u_int32_t(packet->payload, 0) == htonl(0x040e3500) + && get_l16(packet->payload, 4) == packet->payload_packet_len + && packet->payload[9] == 0x33 && packet->payload[packet->payload_packet_len - 1] == 0x03) + || (packet->payload_packet_len > 9 && get_u_int32_t(packet->payload, 0) == htonl(0x040e0215) + && get_l16(packet->payload, 4) == packet->payload_packet_len + && packet->payload[9] == 0x33 && packet->payload[packet->payload_packet_len - 1] == 0x03) + || (packet->payload_packet_len > 6 && get_u_int32_t(packet->payload, 2) == htonl(0x020d5500) + && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len + && packet->payload[packet->payload_packet_len - 1] == 0x03) + || (packet->payload_packet_len > 6 && get_u_int16_t(packet->payload, 0) == htons(0x0418) + && packet->payload[2] == 0x01 + && ntohs(get_u_int16_t(packet->payload, 3)) == packet->payload_packet_len + && packet->payload[packet->payload_packet_len - 1] == 0x03) + || (packet->payload_packet_len > 6 && get_u_int16_t(packet->payload, 0) == htons(0x0411) + && packet->payload[2] == 0x31 + && ntohs(get_u_int16_t(packet->payload, 3)) == packet->payload_packet_len + && packet->payload[packet->payload_packet_len - 1] == 0x03) + || (packet->payload_packet_len > 6 && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len + && get_u_int16_t(packet->payload, 2) == htons(0x0211) && packet->payload[4] == 0x31 + && packet->payload[packet->payload_packet_len - 1] == 0x03) + || (packet->payload_packet_len > 6 && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len + && get_u_int16_t(packet->payload, 2) == htons(0x0218) && packet->payload[4] == 0x01 + && packet->payload[packet->payload_packet_len - 1] == 0x03) + || (packet->payload_packet_len > 10 && get_u_int32_t(packet->payload, 0) == htonl(0x04163a00) + && packet->payload[packet->payload_packet_len - 1] == 0x03 + && packet->payload[4] == packet->payload_packet_len) + ) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + + if (ndpi_is_valid_qq_packet(packet)) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + + if (ndpi_is_valid_qq_ft_packet(packet)) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq ft over tcp.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + + if (packet->payload_packet_len == 2) { + flow->l4.tcp.qq_nxt_len = ntohs(get_u_int16_t(packet->payload, 0)); + return; + } + if (packet->payload_packet_len > 5 && (((flow->l4.tcp.qq_nxt_len == packet->payload_packet_len + 2) + && packet->payload[0] == 0x02 + && packet->payload[packet->payload_packet_len - 1] == 0x03 + && get_u_int16_t(packet->payload, 1) == htons(0x0f5f)) + || (ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len + && packet->payload[2] == 0x02 + && packet->payload[packet->payload_packet_len - 1] == 0x03 + && get_u_int16_t(packet->payload, 3) == htons(0x0f5f)))) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern 02 ... 03 four times.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + + } + if (packet->payload_packet_len > 2 && packet->payload[0] == 0x04 && ((get_u_int16_t(packet->payload, 1) == htons(0x1549) + || get_u_int16_t(packet->payload, + 1) == htons(0x1801) + || get_u_int16_t(packet->payload, + 1) == htons(0x0961)) + || (packet->payload_packet_len > 16 + && (get_u_int16_t(packet->payload, 1) == + htons(0x180d) + || get_u_int16_t(packet->payload, + 1) == htons(0x096d)) + && get_u_int32_t(packet->payload, + 12) == htonl(0x28000000) + && ntohs(get_u_int16_t(packet->payload, 3)) == + packet->payload_packet_len)) + && packet->payload[packet->payload_packet_len - 1] == 0x03) { + flow->qq_stage++; + if (flow->qq_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, + "found qq udp pattern 04 1159 ... 03 four times.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + return; + } + + + + if (packet->payload_packet_len > 100 + && ((memcmp(packet->payload, "GET", 3) == 0) || (memcmp(packet->payload, "POST", 4) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found GET or POST.\n"); + if (memcmp(packet->payload, "GET /qqfile/qq", 14) == 0) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp GET /qqfile/qq.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if (packet->user_agent_line.ptr != NULL + && (packet->user_agent_line.len > 7 && memcmp(packet->user_agent_line.ptr, "QQClient", 8) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp GET...QQClient\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + for (i = 0; i < packet->parsed_lines; i++) { + if (packet->line[i].len > 3 && memcmp(packet->line[i].ptr, "QQ: ", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp GET...QQ: \n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + if (packet->host_line.ptr != NULL) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "host line ptr\n"); + if (packet->host_line.len > 11 && memcmp(&packet->host_line.ptr[0], "www.qq.co.za", 12) == 0) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over tcp Host: www.qq.co.za\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + if (flow->qq_stage == 0 && packet->payload_packet_len == 82 + && get_u_int32_t(packet->payload, 0) == htonl(0x0000004e) && get_u_int32_t(packet->payload, 4) == htonl(0x01010000)) { + for (i = 8; i < 82; i++) { + if (packet->payload[i] != 0x00) { + break; + } + if (i == 81) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq Mail.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + } + if (flow->qq_stage == 0 && packet->payload_packet_len == 182 && get_u_int32_t(packet->payload, 0) == htonl(0x000000b2) + && get_u_int32_t(packet->payload, 4) == htonl(0x01020000) + && get_u_int32_t(packet->payload, 8) == htonl(0x04015151) && get_u_int32_t(packet->payload, 12) == htonl(0x4d61696c)) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq Mail.\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 204 && flow->qq_stage == 0 && get_u_int32_t(packet->payload, 200) == htonl(0xfbffffff)) { + for (i = 0; i < 200; i++) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "i = %u\n", i); + if (packet->payload[i] != 0) { + break; + } + if (i == 199) { + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq chat or file transfer\n"); + ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + } +#ifdef NDPI_PROTOCOL_HTTP + if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP) != 0) { +#endif /* NDPI_PROTOCOL_HTTP */ + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QQ); + NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "QQ tcp excluded; len %u\n", + packet->payload_packet_len); + +#ifdef NDPI_PROTOCOL_HTTP + } +#endif /* NDPI_PROTOCOL_HTTP */ + +} + + +void ndpi_search_qq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if (packet->udp != NULL && flow->detected_protocol_stack[0] != NDPI_PROTOCOL_QQ) + ndpi_search_qq_udp(ndpi_struct, flow); + + if (packet->tcp != NULL && flow->detected_protocol_stack[0] != NDPI_PROTOCOL_QQ) + ndpi_search_qq_tcp(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/quake.c b/src/lib/protocols/quake.c new file mode 100644 index 000000000..18a027970 --- /dev/null +++ b/src/lib/protocols/quake.c @@ -0,0 +1,91 @@ +/* + * quake.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_QUAKE + +static void ndpi_int_quake_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_QUAKE, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_quake(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if ((packet->payload_packet_len == 14 + && get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "getInfo", 7) == 0) + || (packet->payload_packet_len == 17 + && get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "challenge", 9) == 0) + || (packet->payload_packet_len > 20 + && packet->payload_packet_len < 30 + && get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "getServers", 10) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake IV detected.\n"); + ndpi_int_quake_add_connection(ndpi_struct, flow); + return; + } + + /* Quake III/Quake Live */ + if (packet->payload_packet_len == 15 && get_u_int32_t(packet->payload, 0) == 0xffffffff + && memcmp(&packet->payload[4], "getinfo", NDPI_STATICSTRING_LEN("getinfo")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n"); + ndpi_int_quake_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len == 16 && get_u_int32_t(packet->payload, 0) == 0xffffffff + && memcmp(&packet->payload[4], "getchallenge", NDPI_STATICSTRING_LEN("getchallenge")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n"); + ndpi_int_quake_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len > 20 && packet->payload_packet_len < 30 + && get_u_int32_t(packet->payload, 0) == 0xffffffff + && memcmp(&packet->payload[4], "getservers", NDPI_STATICSTRING_LEN("getservers")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n"); + ndpi_int_quake_add_connection(ndpi_struct, flow); + return; + } + + + + /* ports for startup packet: + Quake I 26000 (starts with 0x8000) + Quake II 27910 + Quake III 27960 (increases with each player) + Quake IV 27650 + Quake World 27500 + Quake Wars ????? + */ + + NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUAKE); +} + +#endif diff --git a/src/lib/protocols/radius.c b/src/lib/protocols/radius.c new file mode 100644 index 000000000..0b7698a94 --- /dev/null +++ b/src/lib/protocols/radius.c @@ -0,0 +1,76 @@ +/* + * radius.c + * + * Copyright (C) 2012-15 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_RADIUS + +struct radius_header { + u_int8_t code; + u_int8_t packet_id; + u_int16_t len; +}; + +static void ndpi_check_radius(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // const u_int8_t *packet_payload = packet->payload; + u_int32_t payload_len = packet->payload_packet_len; + +#if 0 + printf("[len=%u][%02X %02X %02X %02X]\n", payload_len, + packet->payload[0] & 0xFF, + packet->payload[1] & 0xFF, + packet->payload[2] & 0xFF, + packet->payload[3] & 0xFF); +#endif + + if(packet->udp != NULL) { + struct radius_header *h = (struct radius_header*)packet->payload; + u_int len = ntohs(h->len); + + if((payload_len > sizeof(struct radius_header)) + && (h->code > 0) + && (h->code <= 5) + && (len == payload_len)) { + NDPI_LOG(NDPI_PROTOCOL_RADIUS, ndpi_struct, NDPI_LOG_DEBUG, "Found radius.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RADIUS, NDPI_REAL_PROTOCOL); + + return; + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RADIUS); + return; + } +} + +void ndpi_search_radius(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_RADIUS, ndpi_struct, NDPI_LOG_DEBUG, "radius detection...\n"); + + /* skip marked packets */ + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_RADIUS) + ndpi_check_radius(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/rdp.c b/src/lib/protocols/rdp.c new file mode 100644 index 000000000..02bbb86e5 --- /dev/null +++ b/src/lib/protocols/rdp.c @@ -0,0 +1,56 @@ +/* + * rdp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_RDP + +static void ndpi_int_rdp_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RDP, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_rdp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len > 10 + && get_u_int8_t(packet->payload, 0) > 0 + && get_u_int8_t(packet->payload, 0) < 4 && get_u_int16_t(packet->payload, 2) == ntohs(packet->payload_packet_len) + && get_u_int8_t(packet->payload, 4) == packet->payload_packet_len - 5 + && get_u_int8_t(packet->payload, 5) == 0xe0 + && get_u_int16_t(packet->payload, 6) == 0 && get_u_int16_t(packet->payload, 8) == 0 && get_u_int8_t(packet->payload, 10) == 0) { + NDPI_LOG(NDPI_PROTOCOL_RDP, ndpi_struct, NDPI_LOG_DEBUG, "RDP detected.\n"); + ndpi_int_rdp_add_connection(ndpi_struct, flow); + return; + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RDP); +} + +#endif diff --git a/src/lib/protocols/redis.c b/src/lib/protocols/redis.c new file mode 100644 index 000000000..a47778b48 --- /dev/null +++ b/src/lib/protocols/redis.c @@ -0,0 +1,92 @@ +/* + * redis.c + * + * Copyright (C) 2011-15 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_REDIS + +static void ndpi_int_redis_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_REDIS, NDPI_REAL_PROTOCOL); +} + + +static void ndpi_check_redis(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + if(payload_len == 0) return; /* Shouldn't happen */ + + /* Break after 20 packets. */ + if(flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_REDIS, ndpi_struct, NDPI_LOG_DEBUG, "Exclude Redis.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_REDIS); + return; + } + + if(packet->packet_direction == 0) + flow->redis_s2d_first_char = packet->payload[0]; + else + flow->redis_d2s_first_char = packet->payload[0]; + + if((flow->redis_s2d_first_char != '\0') && (flow->redis_d2s_first_char != '\0')) { + /* + *1 + $4 + PING + +PONG + *3 + $3 + SET + $19 + dns.cache.127.0.0.1 + $9 + localhost + +OK + */ + + if(((flow->redis_s2d_first_char == '*') + && ((flow->redis_d2s_first_char == '+') || (flow->redis_d2s_first_char == ':'))) + || ((flow->redis_d2s_first_char == '*') + && ((flow->redis_s2d_first_char == '+') || (flow->redis_s2d_first_char == ':')))) { + NDPI_LOG(NDPI_PROTOCOL_REDIS, ndpi_struct, NDPI_LOG_DEBUG, "Found Redis.\n"); + ndpi_int_redis_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_REDIS, ndpi_struct, NDPI_LOG_DEBUG, "Exclude Redis.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_REDIS); + } + } else + return; /* Too early */ +} + +void ndpi_search_redis(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_REDIS, ndpi_struct, NDPI_LOG_DEBUG, "Redis detection...\n"); + + /* skip marked packets */ + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_REDIS) { + if (packet->tcp_retransmission == 0) { + ndpi_check_redis(ndpi_struct, flow); + } + } +} + +#endif diff --git a/src/lib/protocols/rsync.c b/src/lib/protocols/rsync.c new file mode 100644 index 000000000..7caa09e0a --- /dev/null +++ b/src/lib/protocols/rsync.c @@ -0,0 +1,56 @@ +/* + * rsync.c + * + * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * + * This module is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This module is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License. + * If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + + +#ifdef NDPI_PROTOCOL_RSYNC +static void ndpi_int_rsync_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RSYNC, NDPI_CORRELATED_PROTOCOL); +} + +void ndpi_search_rsync(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_RSYNC, ndpi_struct, NDPI_LOG_DEBUG, "search for RSYNC.\n"); + + if(packet->tcp != NULL) { + NDPI_LOG(NDPI_PROTOCOL_RSYNC, ndpi_struct, NDPI_LOG_DEBUG, "calculating RSYNC over tcp.\n"); + /* + * Should match: memcmp(packet->payload, "@RSYN NCD: 28", 14) == 0) + */ + if (packet->payload_packet_len == 12 && packet->payload[0] == 0x40 && + packet->payload[1] == 0x52 && packet->payload[2] == 0x53 && + packet->payload[3] == 0x59 && packet->payload[4] == 0x4e && + packet->payload[5] == 0x43 && packet->payload[6] == 0x44 && + packet->payload[7] == 0x3a ) { + NDPI_LOG(NDPI_PROTOCOL_RSYNC, ndpi_struct, NDPI_LOG_DEBUG, "found rsync.\n"); + ndpi_int_rsync_add_connection(ndpi_struct, flow); + } + } else { + NDPI_LOG(NDPI_PROTOCOL_RSYNC, ndpi_struct, NDPI_LOG_DEBUG, "exclude RSYNC.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RSYNC); + } +} +#endif diff --git a/src/lib/protocols/rtcp.c b/src/lib/protocols/rtcp.c new file mode 100644 index 000000000..02875648a --- /dev/null +++ b/src/lib/protocols/rtcp.c @@ -0,0 +1,52 @@ +/* + * rtcp.c (RTP Control Protocol) + * + * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_RTCP +static void ndpi_int_rtcp_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTCP, NDPI_CORRELATED_PROTOCOL); +} + +void ndpi_search_rtcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t dport = 0, sport = 0; + + NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "search for RTCP.\n"); + + if(packet->tcp != NULL) { + sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); + NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over tcp.\n"); + + if(packet->payload_packet_len > 13 && (sport == 554 || dport == 554) && + packet->payload[0] == 0x00 && packet->payload[1] == 0x00 && + packet->payload[2] == 0x01 && packet->payload[3] == 0x01 && + packet->payload[4] == 0x08 && packet->payload[5] == 0x0a && + packet->payload[6] == 0x00 && packet->payload[7] == 0x01) { + NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "found rtcp.\n"); + ndpi_int_rtcp_add_connection(ndpi_struct, flow); + } + } else if(packet->udp != NULL) { + sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); + NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over udp.\n"); + if(((packet->payload_packet_len >= 28 || packet->payload_packet_len <= 1200) && + ((packet->payload[0] == 0x80) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9)) && (packet->payload[2] == 0x00))) + || (((packet->payload[0] == 0x81) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9)) + && (packet->payload[2] == 0x00)))) { + NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "found rtcp.\n"); + ndpi_int_rtcp_add_connection(ndpi_struct, flow); + } + } else { + NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "exclude RTCP.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTCP); + } +} +#endif diff --git a/src/lib/protocols/rtmp.c b/src/lib/protocols/rtmp.c new file mode 100644 index 000000000..6ebb5ebf2 --- /dev/null +++ b/src/lib/protocols/rtmp.c @@ -0,0 +1,92 @@ +/* + * rtmp.c + * + * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> + * + * The signature is based on the Libprotoident library. + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_RTMP +static void ndpi_int_rtmp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTMP, NDPI_REAL_PROTOCOL); +} + +static void ndpi_check_rtmp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Break after 20 packets. */ + if (flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "Exclude RTMP.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTMP); + return; + } + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->rtmp_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "RTMP stage 0: \n"); + + if ((payload_len >= 4) && ((packet->payload[0] == 0x03) || (packet->payload[0] == 0x06))) { + NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "Possible RTMP request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->rtmp_stage = packet->packet_direction + 1; + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "RTMP stage %u: \n", flow->rtmp_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->rtmp_stage - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len >= 4) && ((packet->payload[0] == 0x03) || (packet->payload[0] == 0x06) || (packet->payload[0] == 0x08) || (packet->payload[0] == 0x09) || (packet->payload[0] == 0x0a))) { + NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "Found RTMP.\n"); + ndpi_int_rtmp_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to RTMP, resetting the stage to 0...\n"); + flow->rtmp_stage = 0; + } + + } +} + +void ndpi_search_rtmp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_RTMP, ndpi_struct, NDPI_LOG_DEBUG, "RTMP detection...\n"); + + /* skip marked packets */ + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_RTMP) { + if (packet->tcp_retransmission == 0) { + ndpi_check_rtmp(ndpi_struct, flow); + } + } +} + +#endif diff --git a/src/lib/protocols/rtp.c b/src/lib/protocols/rtp.c new file mode 100644 index 000000000..1e1a82a8b --- /dev/null +++ b/src/lib/protocols/rtp.c @@ -0,0 +1,325 @@ +/* + * rtp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_RTP + + +static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + const u_int8_t * payload, const u_int16_t payload_len) +{ + //struct ndpi_packet_struct *packet = &flow->packet; + u_int8_t payload_type = payload[1] & 0x7F; + u_int32_t *ssid = (u_int32_t*)&payload[8]; + + /* Check whether this is an RTP flow */ + if((payload_len >= 12) + && ((payload[0] & 0xFF) == 0x80) /* RTP magic byte[1] */ + && ((payload_type < 72) || (payload_type > 76)) + && (payload_type < 128 /* http://anonsvn.wireshark.org/wireshark/trunk/epan/dissectors/packet-rtp.c */) + && (*ssid != 0) + ) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "Found rtp.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTP, NDPI_REAL_PROTOCOL); + } else { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP); + } +} + +void ndpi_search_rtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if((packet->udp != NULL) + && (ntohs(packet->udp->source) > 1023) + && (ntohs(packet->udp->dest) > 1023)) + ndpi_rtp_search(ndpi_struct, flow, packet->payload, packet->payload_packet_len); +} + +#if 0 +/* Original (messy) OpenDPI code */ + +#define RTP_MAX_OUT_OF_ORDER 11 + +static void ndpi_int_rtp_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTP, NDPI_REAL_PROTOCOL); +} + +/* + * maintenance of current highest sequence number, cycle count, packet counter + * adapted from RFC3550 Appendix A.1 + * + * In their formulation, it is not possible to represent "no packets sent yet". This is fixed here by defining + * baseseq to be the sequence number of the first packet minus 1 (in other words, the sequence number of the + * zeroth packet). + * + * Note: As described in the RFC, the number of packets received includes retransmitted packets. + * This means the "packets lost" count (seq_num-isn+1)-received can become negative. + * + * include_current_packet should be + * 1, if the current packet should count towards the total, or + * 0, if it it regarded as belonging to the previous reporting interval + */ + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +void init_seq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, + u_int8_t direction, u_int16_t seq, u_int8_t include_current_packet) +{ + flow->rtp_seqnum[direction] = seq; + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "rtp_seqnum[%u] = %u\n", direction, seq); +} + +/* returns difference between old and new highest sequence number */ + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +u_int16_t update_seq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, + u_int8_t direction, u_int16_t seq) +{ + u_int16_t delta = seq - flow->rtp_seqnum[direction]; + + + if (delta < RTP_MAX_OUT_OF_ORDER) { /* in order, with permissible gap */ + flow->rtp_seqnum[direction] = seq; + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "rtp_seqnum[%u] = %u (increased by %u)\n", + direction, seq, delta); + return delta; + } else { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "retransmission (dir %u, seqnum %u)\n", + direction, seq); + return 0; + } +} + +static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + const u_int8_t * payload, const u_int16_t payload_len) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + u_int8_t stage; + u_int16_t seqnum = ntohs(get_u_int16_t(payload, 2)); + + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "search rtp.\n"); + + if (payload_len == 4 && get_u_int32_t(packet->payload, 0) == 0 && flow->packet_counter < 8) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "need next packet, maybe ClearSea out calls.\n"); + return; + } + + if (payload_len == 5 && memcmp(payload, "hello", 5) == 0) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, + "need next packet, initial hello packet of SIP out calls.\n"); + return; + } + + if (payload_len == 1 && payload[0] == 0) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, + "need next packet, payload_packet_len == 1 && payload[0] == 0.\n"); + return; + } + + if (payload_len == 3 && memcmp(payload, "png", 3) == 0) { + /* weird packet found in Ninja GlobalIP trace */ + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "skipping packet with len = 3 and png payload.\n"); + return; + } + + if (payload_len < 12) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "minimal packet size for rtp packets: 12.\n"); + goto exclude_rtp; + } + + if (payload_len == 12 && get_u_int32_t(payload, 0) == 0 && get_u_int32_t(payload, 4) == 0 && get_u_int32_t(payload, 8) == 0) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "skipping packet with len = 12 and only 0-bytes.\n"); + return; + } + + if ((payload[0] & 0xc0) == 0xc0 || (payload[0] & 0xc0) == 0x40 || (payload[0] & 0xc0) == 0x00) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "version = 3 || 1 || 0, maybe first rtp packet.\n"); + return; + } + + if ((payload[0] & 0xc0) != 0x80) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, + NDPI_LOG_DEBUG, "rtp version must be 2, first two bits of a packets must be 10.\n"); + goto exclude_rtp; + } + + /* rtp_payload_type are the last seven bits of the second byte */ + if (flow->rtp_payload_type[packet->packet_direction] != (payload[1] & 0x7F)) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "payload_type has changed, reset stages.\n"); + packet->packet_direction == 0 ? (flow->rtp_stage1 = 0) : (flow->rtp_stage2 = 0); + } + /* first bit of first byte is not part of payload_type */ + flow->rtp_payload_type[packet->packet_direction] = payload[1] & 0x7F; + + stage = (packet->packet_direction == 0 ? flow->rtp_stage1 : flow->rtp_stage2); + + if (stage > 0) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, + NDPI_LOG_DEBUG, "stage = %u.\n", packet->packet_direction == 0 ? flow->rtp_stage1 : flow->rtp_stage2); + if (flow->rtp_ssid[packet->packet_direction] != get_u_int32_t(payload, 8)) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "ssid has changed, goto exclude rtp.\n"); + goto exclude_rtp; + } + + if (seqnum == flow->rtp_seqnum[packet->packet_direction]) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "maybe \"retransmission\", need next packet.\n"); + return; + } else if ((u_int16_t) (seqnum - flow->rtp_seqnum[packet->packet_direction]) < RTP_MAX_OUT_OF_ORDER) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, + "new packet has larger sequence number (within valid range)\n"); + update_seq(ndpi_struct, flow, packet->packet_direction, seqnum); + } else if ((u_int16_t) (flow->rtp_seqnum[packet->packet_direction] - seqnum) < RTP_MAX_OUT_OF_ORDER) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, + "new packet has smaller sequence number (within valid range)\n"); + init_seq(ndpi_struct, flow, packet->packet_direction, seqnum, 1); + } else { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, + "sequence number diff is too big, goto exclude rtp.\n"); + goto exclude_rtp; + } + } else { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, + NDPI_LOG_DEBUG, "rtp_ssid[%u] = %u.\n", packet->packet_direction, + flow->rtp_ssid[packet->packet_direction]); + flow->rtp_ssid[packet->packet_direction] = get_u_int32_t(payload, 8); + if (flow->packet_counter < 3) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "packet_counter < 3, need next packet.\n"); + } + init_seq(ndpi_struct, flow, packet->packet_direction, seqnum, 1); + } + if (seqnum <= 3) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, + NDPI_LOG_DEBUG, "sequence_number = %u, too small, need next packet, return.\n", seqnum); + return; + } + + if (stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "add connection I.\n"); + ndpi_int_rtp_add_connection(ndpi_struct, flow); + } else { + packet->packet_direction == 0 ? flow->rtp_stage1++ : flow->rtp_stage2++; + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "stage[%u]++; need next packet.\n", + packet->packet_direction); + } + return; + + exclude_rtp: +#ifdef NDPI_PROTOCOL_STUN + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN + || packet->real_protocol_read_only == NDPI_PROTOCOL_STUN) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "STUN: is detected, need next packet.\n"); + return; + } +#endif /* NDPI_PROTOCOL_STUN */ + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP); +} + + +void ndpi_search_rtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + if (packet->udp) { + ndpi_rtp_search(ndpi_struct, flow, packet->payload, packet->payload_packet_len); + } else if (packet->tcp) { + + /* skip special packets seen at yahoo traces */ + if (packet->payload_packet_len >= 20 && ntohs(get_u_int16_t(packet->payload, 2)) + 20 == packet->payload_packet_len && + packet->payload[0] == 0x90 && packet->payload[1] >= 0x01 && packet->payload[1] <= 0x07) { + if (flow->packet_counter == 2) + flow->l4.tcp.rtp_special_packets_seen = 1; + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, + "skipping STUN-like, special yahoo packets with payload[0] == 0x90.\n"); + return; + } +#ifdef NDPI_PROTOCOL_STUN + /* TODO the rtp detection sometimes doesn't exclude rtp + * so for TCP flows only run the detection if STUN has been + * detected (or RTP is already detected) + * If flows will be seen which start directly with RTP + * we can remove this restriction + */ + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN + || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_RTP) { + + /* RTP may be encapsulated in TCP packets */ + + if (packet->payload_packet_len >= 2 && ntohs(get_u_int16_t(packet->payload, 0)) + 2 == packet->payload_packet_len) { + + /* TODO there could be several RTP packets in a single TCP packet so maybe the detection could be + * improved by checking only the RTP packet of given length */ + + ndpi_rtp_search(ndpi_struct, flow, packet->payload + 2, packet->payload_packet_len - 2); + + return; + } + } + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && flow->l4.tcp.rtp_special_packets_seen == 1) { + + if (packet->payload_packet_len >= 4 && ntohl(get_u_int32_t(packet->payload, 0)) + 4 == packet->payload_packet_len) { + + /* TODO there could be several RTP packets in a single TCP packet so maybe the detection could be + * improved by checking only the RTP packet of given length */ + + ndpi_rtp_search(ndpi_struct, flow, packet->payload + 4, packet->payload_packet_len - 4); + + return; + } + } + + if (NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct, flow, NDPI_PROTOCOL_STUN)) { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP); + } else { + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "STUN not yet excluded, need next packet.\n"); + } +#else + NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP); +#endif + } +} +#endif + +#endif /* NDPI_PROTOCOL_RTP */ + diff --git a/src/lib/protocols/rtsp.c b/src/lib/protocols/rtsp.c new file mode 100644 index 000000000..2614f0c6f --- /dev/null +++ b/src/lib/protocols/rtsp.c @@ -0,0 +1,120 @@ +/* + * rtsp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_RTSP +#ifndef NDPI_PROTOCOL_RTP +#error RTSP requires RTP detection to work correctly +#endif +#ifndef NDPI_PROTOCOL_RTSP +#error RTSP requires RTSP detection to work correctly +#endif +#ifndef NDPI_PROTOCOL_RDP +#error RTSP requires RDP detection to work correctly +#endif + +static void ndpi_int_rtsp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTSP, protocol_type); +} + +/* this function searches for a rtsp-"handshake" over tcp or udp. */ +void ndpi_search_rtsp_tcp_udp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_TRACE, "RTSP detection...\n"); + + if (flow->rtsprdt_stage == 0 +#ifdef NDPI_PROTOCOL_RTCP + && !(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_RTCP) +#endif + ) { + flow->rtsprdt_stage = 1 + packet->packet_direction; + NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "maybe handshake 1; need next packet, return.\n"); + return; + } + + if (flow->packet_counter < 3 && flow->rtsprdt_stage == 1 + packet->packet_direction) { + + NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "maybe handshake 2; need next packet.\n"); + return; + } + + if (packet->payload_packet_len > 20 && flow->rtsprdt_stage == 2 - packet->packet_direction) { + char buf[32] = { 0 }; + u_int len = packet->payload_packet_len; + + if(len >= (sizeof(buf)-1)) len = sizeof(buf)-1; + strncpy(buf, (const char*)packet->payload, len); + + // RTSP Server Message + if((memcmp(packet->payload, "RTSP/1.0 ", 9) == 0) + || (strstr(buf, "rtsp://") != NULL)) { + NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_TRACE, "found RTSP/1.0 .\n"); + if (dst != NULL) { + NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_TRACE, "found dst.\n"); + ndpi_packet_src_ip_get(packet, &dst->rtsp_ip_address); + dst->rtsp_timer = packet->tick_timestamp; + dst->rtsp_ts_set = 1; + } + if (src != NULL) { + NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_TRACE, "found src.\n"); + ndpi_packet_dst_ip_get(packet, &src->rtsp_ip_address); + src->rtsp_timer = packet->tick_timestamp; + src->rtsp_ts_set = 1; + } + NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_TRACE, "RTSP detected.\n"); + flow->rtsp_control_flow = 1; + ndpi_int_rtsp_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + if (packet->udp != NULL && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN + && ((NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP) == 0) +#ifdef NDPI_PROTOCOL_RTCP + || (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTCP) == 0) +#endif + )) { + NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, + "maybe RTSP RTP, RTSP RTCP, RDT; need next packet.\n"); + return; + } + + + NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "didn't find handshake, exclude.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTSP); + return; +} + + +#endif diff --git a/src/lib/protocols/sflow.c b/src/lib/protocols/sflow.c new file mode 100644 index 000000000..980867634 --- /dev/null +++ b/src/lib/protocols/sflow.c @@ -0,0 +1,49 @@ +/* + * sflow.c + * + * Copyright (C) 2011-15 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_SFLOW + +static void ndpi_check_sflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // const u_int8_t *packet_payload = packet->payload; + u_int32_t payload_len = packet->payload_packet_len; + + if((packet->udp != NULL) + && (payload_len >= 24) + /* Version */ + && (packet->payload[0] == 0) && (packet->payload[1] == 0) && (packet->payload[2] == 0) + && ((packet->payload[3] == 2) || (packet->payload[3] == 5))) { + NDPI_LOG(NDPI_PROTOCOL_SFLOW, ndpi_struct, NDPI_LOG_DEBUG, "Found sflow.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SFLOW, NDPI_REAL_PROTOCOL); + return; + } +} + +void ndpi_search_sflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + NDPI_LOG(NDPI_PROTOCOL_SFLOW, ndpi_struct, NDPI_LOG_DEBUG, "sflow detection...\n"); + ndpi_check_sflow(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/shoutcast.c b/src/lib/protocols/shoutcast.c new file mode 100644 index 000000000..f700db330 --- /dev/null +++ b/src/lib/protocols/shoutcast.c @@ -0,0 +1,107 @@ +/* + * shoutcast.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_SHOUTCAST + +static void ndpi_int_shoutcast_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SHOUTCAST, NDPI_CORRELATED_PROTOCOL); +} + +void ndpi_search_shoutcast_tcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "search shoutcast.\n"); + + if (flow->packet_counter == 1) { +/* this case in paul_upload_oddcast_002.pcap */ + if (packet->payload_packet_len >= 6 + && packet->payload_packet_len < 80 && memcmp(packet->payload, "123456", 6) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 1, \"123456\".\n"); + return; + } + if (flow->packet_counter < 3 +#ifdef NDPI_PROTOCOL_HTTP + && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP +#endif + ) { + NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, + "http detected, need next packet for shoutcast detection.\n"); + if (packet->payload_packet_len > 4 + && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) != htonl(0x0d0a0d0a)) { + NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "segmented packet found.\n"); + flow->l4.tcp.shoutcast_stage = 1 + packet->packet_direction; + } + return; + } + + + /* else + goto exclude_shoutcast; */ + + } + /* evtl. für asym detection noch User-Agent:Winamp dazunehmen. */ + if (packet->payload_packet_len > 11 && memcmp(packet->payload, "ICY 200 OK\x0d\x0a", 12) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "found shoutcast by ICY 200 OK.\n"); + ndpi_int_shoutcast_add_connection(ndpi_struct, flow); + return; + } + if (flow->l4.tcp.shoutcast_stage == 1 + packet->packet_direction + && flow->packet_direction_counter[packet->packet_direction] < 5) { + return; + } + + if (flow->packet_counter == 2) { + if (packet->payload_packet_len == 2 && memcmp(packet->payload, "\x0d\x0a", 2) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 1 continuation.\n"); + return; + } else if (packet->payload_packet_len > 3 && memcmp(&packet->payload[0], "OK2", 3) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 2, OK2 found.\n"); + return; + } else + goto exclude_shoutcast; + } else if (flow->packet_counter == 3 || flow->packet_counter == 4) { + if (packet->payload_packet_len > 3 && memcmp(&packet->payload[0], "OK2", 3) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 2, OK2 found.\n"); + return; + } else if (packet->payload_packet_len > 4 && memcmp(&packet->payload[0], "icy-", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast detected.\n"); + ndpi_int_shoutcast_add_connection(ndpi_struct, flow); + return; + } else + goto exclude_shoutcast; + } + + exclude_shoutcast: + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SHOUTCAST); + NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast excluded.\n"); +} +#endif diff --git a/src/lib/protocols/sip.c b/src/lib/protocols/sip.c new file mode 100644 index 000000000..201d2b23f --- /dev/null +++ b/src/lib/protocols/sip.c @@ -0,0 +1,200 @@ +/* + * sip.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_SIP +static void ndpi_int_sip_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int8_t due_to_correlation) +{ + + ndpi_int_add_connection(ndpi_struct, flow, + NDPI_PROTOCOL_SIP, + due_to_correlation ? NDPI_CORRELATED_PROTOCOL : NDPI_REAL_PROTOCOL); +} + + + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +void ndpi_search_sip_handshake(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + const u_int8_t *packet_payload = packet->payload; + u_int32_t payload_len = packet->payload_packet_len; + + + if (payload_len > 4) { + /* search for STUN Turn ChannelData Prefix */ + u_int16_t message_len = ntohs(get_u_int16_t(packet->payload, 2)); + if (payload_len - 4 == message_len) { + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found STUN TURN ChannelData prefix.\n"); + payload_len -= 4; + packet_payload += 4; + } + } +#ifndef NDPI_PROTOCOL_YAHOO + if (payload_len >= 14 && packet_payload[payload_len - 2] == 0x0d && packet_payload[payload_len - 1] == 0x0a) +#endif +#ifdef NDPI_PROTOCOL_YAHOO + if (payload_len >= 14) +#endif + { + + if ((memcmp(packet_payload, "NOTIFY ", 7) == 0 || memcmp(packet_payload, "notify ", 7) == 0) + && (memcmp(&packet_payload[7], "SIP:", 4) == 0 || memcmp(&packet_payload[7], "sip:", 4) == 0)) { + + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip NOTIFY.\n"); + ndpi_int_sip_add_connection(ndpi_struct, flow, 0); + return; + } + + if ((memcmp(packet_payload, "REGISTER ", 9) == 0 || memcmp(packet_payload, "register ", 9) == 0) + && (memcmp(&packet_payload[9], "SIP:", 4) == 0 || memcmp(&packet_payload[9], "sip:", 4) == 0)) { + + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip REGISTER.\n"); + ndpi_int_sip_add_connection(ndpi_struct, flow, 0); + return; + } + + if ((memcmp(packet_payload, "INVITE ", 7) == 0 || memcmp(packet_payload, "invite ", 7) == 0) + && (memcmp(&packet_payload[7], "SIP:", 4) == 0 || memcmp(&packet_payload[7], "sip:", 4) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip INVITE.\n"); + ndpi_int_sip_add_connection(ndpi_struct, flow, 0); + return; + } + + /* seen this in second direction on the third position, + * maybe it could be deleted, if somebody sees it in the first direction, + * please delete this comment. + */ + + /* + if (memcmp(packet_payload, "SIP/2.0 200 OK", 14) == 0 || memcmp(packet_payload, "sip/2.0 200 OK", 14) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip SIP/2.0 0K.\n"); + ndpi_int_sip_add_connection(ndpi_struct, flow, 0); + return; + } + */ + if (memcmp(packet_payload, "SIP/2.0 ", 8) == 0 || memcmp(packet_payload, "sip/2.0 ", 8) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip SIP/2.0 *.\n"); + ndpi_int_sip_add_connection(ndpi_struct, flow, 0); + return; + } + + if ((memcmp(packet_payload, "BYE ", 4) == 0 || memcmp(packet_payload, "bye ", 4) == 0) + && (memcmp(&packet_payload[4], "SIP:", 4) == 0 || memcmp(&packet_payload[4], "sip:", 4) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip BYE.\n"); + ndpi_int_sip_add_connection(ndpi_struct, flow, 0); + return; + } + + if ((memcmp(packet_payload, "ACK ", 4) == 0 || memcmp(packet_payload, "ack ", 4) == 0) + && (memcmp(&packet_payload[4], "SIP:", 4) == 0 || memcmp(&packet_payload[4], "sip:", 4) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip ACK.\n"); + ndpi_int_sip_add_connection(ndpi_struct, flow, 0); + return; + } + + if ((memcmp(packet_payload, "CANCEL ", 7) == 0 || memcmp(packet_payload, "cancel ", 7) == 0) + && (memcmp(&packet_payload[4], "SIP:", 7) == 0 || memcmp(&packet_payload[4], "sip:", 7) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip CANCEL.\n"); + ndpi_int_sip_add_connection(ndpi_struct, flow, 0); + return; + } + + /* Courtesy of Miguel Quesada <mquesadab@gmail.com> */ + if ((memcmp(packet_payload, "OPTIONS ", 8) == 0 + || memcmp(packet_payload, "options ", 8) == 0) + && (memcmp(&packet_payload[8], "SIP:", 4) == 0 + || memcmp(&packet_payload[8], "sip:", 4) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip OPTIONS.\n"); + ndpi_int_sip_add_connection(ndpi_struct, flow, 0); + return; + } + } + + /* add bitmask for tcp only, some stupid udp programs + * send a very few (< 10 ) packets before invite (mostly a 0x0a0x0d, but just search the first 3 payload_packets here */ + if (packet->udp != NULL && flow->packet_counter < 20) { + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "need next packet.\n"); + return; + } +#ifdef NDPI_PROTOCOL_STUN + /* for STUN flows we need some more packets */ + if (packet->udp != NULL && flow->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN && flow->packet_counter < 40) { + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "need next STUN packet.\n"); + return; + } +#endif + + if (payload_len == 4 && get_u_int32_t(packet_payload, 0) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "maybe sip. need next packet.\n"); + return; + } +#ifdef NDPI_PROTOCOL_YAHOO + if (payload_len > 30 && packet_payload[0] == 0x90 + && packet_payload[3] == payload_len - 20 && get_u_int32_t(packet_payload, 4) == 0 + && get_u_int32_t(packet_payload, 8) == 0) { + flow->sip_yahoo_voice = 1; + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "maybe sip yahoo. need next packet.\n"); + } + if (flow->sip_yahoo_voice && flow->packet_counter < 10) { + return; + } +#endif + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "exclude sip.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SIP); + return; + + +} + +void ndpi_search_sip(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // struct ndpi_flow_struct *flow = ndpi_struct->flow; + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "sip detection...\n"); + + /* skip marked packets */ + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SIP) { + if (packet->tcp_retransmission == 0) { + ndpi_search_sip_handshake(ndpi_struct, flow); + } + } +} + +#endif diff --git a/src/lib/protocols/skinny.c b/src/lib/protocols/skinny.c new file mode 100644 index 000000000..5e35f11f5 --- /dev/null +++ b/src/lib/protocols/skinny.c @@ -0,0 +1,63 @@ +/* + * skinny.c + * + * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * + * This module is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This module is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License. + * If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + + +#ifdef NDPI_PROTOCOL_SKINNY +static void ndpi_int_skinny_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKINNY, NDPI_CORRELATED_PROTOCOL); +} + +void ndpi_search_skinny(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t dport = 0, sport = 0; + const char pattern_9_bytes[9] = { 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + const char pattern_8_bytes[8] = { 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + const char keypadmsg_8_bytes[8] = { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + const char selectmsg_8_bytes[8] = { 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + NDPI_LOG(NDPI_PROTOCOL_SKINNY, ndpi_struct, NDPI_LOG_DEBUG, "search for SKINNY.\n"); + + if(packet->tcp != NULL) { + sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); + NDPI_LOG(NDPI_PROTOCOL_SKINNY, ndpi_struct, NDPI_LOG_DEBUG, "calculating SKINNY over tcp.\n"); + if (dport == 2000 && ((packet->payload_packet_len == 24 && + memcmp(&packet->payload[0], keypadmsg_8_bytes, 8) == 0) + || ((packet->payload_packet_len == 64) && memcmp(&packet->payload[0], pattern_8_bytes, 8) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_SKINNY, ndpi_struct, NDPI_LOG_DEBUG, "found skinny.\n"); + ndpi_int_skinny_add_connection(ndpi_struct, flow); + } else if (sport == 2000 && ((packet->payload_packet_len == 28 && + memcmp(&packet->payload[0], selectmsg_8_bytes, 8) == 0 ) || + (packet->payload_packet_len == 44 && + memcmp(&packet->payload[0], pattern_9_bytes, 9) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_SKINNY, ndpi_struct, NDPI_LOG_DEBUG, "found skinny.\n"); + ndpi_int_skinny_add_connection(ndpi_struct, flow); + } + } else { + NDPI_LOG(NDPI_PROTOCOL_SKINNY, ndpi_struct, NDPI_LOG_DEBUG, "exclude SKINNY.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SKINNY); + } +} +#endif diff --git a/src/lib/protocols/skype.c b/src/lib/protocols/skype.c new file mode 100644 index 000000000..8d2a3a72b --- /dev/null +++ b/src/lib/protocols/skype.c @@ -0,0 +1,122 @@ +/* + * skype.c + * + * Copyright (C) 2011-15 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_SKYPE + + +static u_int8_t is_skype_host(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t host) { + struct in_addr pin; + + pin.s_addr = host; + + return((ndpi_network_ptree_match(ndpi_struct, &pin) == NDPI_PROTOCOL_SKYPE) ? 1 : 0); +} + +u_int8_t is_skype_flow(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + if(packet->iph) { + /* + Skype connections are identified by some SSL-like communications + without SSL certificate being exchanged + */ + if(is_skype_host(ndpi_struct, ntohl(packet->iph->saddr)) + || is_skype_host(ndpi_struct, ntohl(packet->iph->daddr))) { + return(1); + } + } + + return(0); +} + +static void ndpi_check_skype(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // const u_int8_t *packet_payload = packet->payload; + u_int32_t payload_len = packet->payload_packet_len; + + /* + Skype AS8220 + 212.161.8.0/24 + */ + if(is_skype_flow(ndpi_struct, flow)) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE, NDPI_REAL_PROTOCOL); + return; + } + + if(packet->udp != NULL) { + flow->l4.udp.skype_packet_id++; + + if(flow->l4.udp.skype_packet_id < 5) { + /* skype-to-skype */ + if(((payload_len == 3) && ((packet->payload[2] & 0x0F)== 0x0d)) + || ((payload_len >= 16) + && (packet->payload[0] != 0x30) /* Avoid invalid SNMP detection */ + && (packet->payload[2] == 0x02))) { + NDPI_LOG(NDPI_PROTOCOL_SKYPE, ndpi_struct, NDPI_LOG_DEBUG, "Found skype.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE, NDPI_REAL_PROTOCOL); + } + + return; + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SKYPE); + return; + } else if(packet->tcp != NULL) { + flow->l4.tcp.skype_packet_id++; + + if(flow->l4.tcp.skype_packet_id < 3) { + ; /* Too early */ + } else if((flow->l4.tcp.skype_packet_id == 3) + /* We have seen the 3-way handshake */ + && flow->l4.tcp.seen_syn + && flow->l4.tcp.seen_syn_ack + && flow->l4.tcp.seen_ack) { + if((payload_len == 8) || (payload_len == 3)) { + //printf("[SKYPE] %u/%u\n", ntohs(packet->tcp->source), ntohs(packet->tcp->dest)); + + NDPI_LOG(NDPI_PROTOCOL_SKYPE, ndpi_struct, NDPI_LOG_DEBUG, "Found skype.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE, NDPI_REAL_PROTOCOL); + } + + /* printf("[SKYPE] [id: %u][len: %d]\n", flow->l4.tcp.skype_packet_id, payload_len); */ + } else + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SKYPE); + + return; + } +} + +void ndpi_search_skype(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_SKYPE, ndpi_struct, NDPI_LOG_DEBUG, "skype detection...\n"); + + /* skip marked packets */ + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SKYPE) + ndpi_check_skype(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/smb.c b/src/lib/protocols/smb.c new file mode 100644 index 000000000..031572ead --- /dev/null +++ b/src/lib/protocols/smb.c @@ -0,0 +1,57 @@ +/* + * smb.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_SMB + +static void ndpi_int_smb_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SMB, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_smb_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if(packet && packet->tcp) { + NDPI_LOG(NDPI_PROTOCOL_SMB, ndpi_struct, NDPI_LOG_DEBUG, "search SMB.\n"); + + if (packet->tcp->dest == htons(445) + && packet->payload_packet_len > (32 + 4 + 4) + && (packet->payload_packet_len - 4) == ntohl(get_u_int32_t(packet->payload, 0)) + && get_u_int32_t(packet->payload, 4) == htonl(0xff534d42)) { + NDPI_LOG(NDPI_PROTOCOL_SMB, ndpi_struct, NDPI_LOG_DEBUG, "found SMB.\n"); + ndpi_int_smb_add_connection(ndpi_struct, flow); + return; + + } + } + + NDPI_LOG(NDPI_PROTOCOL_SMB, ndpi_struct, NDPI_LOG_DEBUG, "exclude SMB.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SMB); +} + +#endif diff --git a/src/lib/protocols/snmp.c b/src/lib/protocols/snmp.c new file mode 100644 index 000000000..2ddf21229 --- /dev/null +++ b/src/lib/protocols/snmp.c @@ -0,0 +1,126 @@ +/* + * snmp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_SNMP + +static void ndpi_int_snmp_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SNMP, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_snmp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len > 32 && packet->payload[0] == 0x30) { + int offset; + switch (packet->payload[1]) { + case 0x81: + offset = 3; + break; + case 0x82: + offset = 4; + break; + default: + if (packet->payload[1] > 0x82) { + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded, second byte is > 0x82\n"); + goto excl; + } + offset = 2; + } + + if (get_u_int16_t(packet->payload, offset) != htons(0x0201)) { + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded, 0x0201 pattern not found\n"); + goto excl; + } + + if (packet->payload[offset + 2] >= 0x04) { + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded, version > 3\n"); + goto excl; + } + + if (flow->l4.udp.snmp_stage == 0) { + if (packet->udp->dest == htons(161) || packet->udp->dest == htons(162)) { + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP detected due to port.\n"); + ndpi_int_snmp_add_connection(ndpi_struct, flow); + return; + } + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP stage 0.\n"); + if (packet->payload[offset + 2] == 3) { + flow->l4.udp.snmp_msg_id = ntohs(get_u_int32_t(packet->payload, offset + 8)); + } else if (packet->payload[offset + 2] == 0) { + flow->l4.udp.snmp_msg_id = get_u_int8_t(packet->payload, offset + 15); + } else { + flow->l4.udp.snmp_msg_id = ntohs(get_u_int16_t(packet->payload, offset + 15)); + } + flow->l4.udp.snmp_stage = 1 + packet->packet_direction; + return; + } else if (flow->l4.udp.snmp_stage == 1 + packet->packet_direction) { + if (packet->payload[offset + 2] == 0) { + if (flow->l4.udp.snmp_msg_id != get_u_int8_t(packet->payload, offset + 15) - 1) { + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, + "SNMP v1 excluded, message ID doesn't match\n"); + goto excl; + } + } + } else if (flow->l4.udp.snmp_stage == 2 - packet->packet_direction) { + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP stage 1-2.\n"); + if (packet->payload[offset + 2] == 3) { + if (flow->l4.udp.snmp_msg_id != ntohs(get_u_int32_t(packet->payload, offset + 8))) { + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, + "SNMP v3 excluded, message ID doesn't match\n"); + goto excl; + } + } else if (packet->payload[offset + 2] == 0) { + if (flow->l4.udp.snmp_msg_id != get_u_int8_t(packet->payload, offset + 15)) { + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, + "SNMP v1 excluded, message ID doesn't match\n"); + goto excl; + } + } else { + if (flow->l4.udp.snmp_msg_id != ntohs(get_u_int16_t(packet->payload, offset + 15))) { + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, + "SNMP v2 excluded, message ID doesn't match\n"); + goto excl; + } + } + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP detected.\n"); + ndpi_int_snmp_add_connection(ndpi_struct, flow); + return; + } + } else { + NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded.\n"); + } + excl: + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SNMP); + +} + +#endif diff --git a/src/lib/protocols/socks4.c b/src/lib/protocols/socks4.c new file mode 100644 index 000000000..e89f7050c --- /dev/null +++ b/src/lib/protocols/socks4.c @@ -0,0 +1,96 @@ +/* + * socks4.c + * + * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> + * + * The signature is based on the Libprotoident library. + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_SOCKS4 +static void ndpi_int_socks4_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SOCKS4, NDPI_REAL_PROTOCOL); +} + +static void ndpi_check_socks4(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Break after 20 packets. */ + if (flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "Exclude SOCKS4.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOCKS4); + return; + } + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->socks4_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS4 stage 0: \n"); + + /*Octets 3 and 4 contain the port number, port 80 and 25 for now. */ + if ((payload_len == 9) && + (((packet->payload[0] == 0x04) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x50)) + || + ((packet->payload[0] == 0x04) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x19)))) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "Possible SOCKS4 request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->socks4_stage = packet->packet_direction + 1; + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS4 stage %u: \n", flow->socks4_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->socks4_stage - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if (payload_len == 0) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "Found SOCKS4.\n"); + ndpi_int_socks4_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to SOCKS4, resetting the stage to 0...\n"); + flow->socks4_stage = 0; + } + + } +} + +void ndpi_search_socks4(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_SOCKS4, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS4 detection...\n"); + + /* skip marked packets */ + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SOCKS4) { + if (packet->tcp_retransmission == 0) { + ndpi_check_socks4(ndpi_struct, flow); + } + } +} + +#endif diff --git a/src/lib/protocols/socks5.c b/src/lib/protocols/socks5.c new file mode 100644 index 000000000..7aa4c90a1 --- /dev/null +++ b/src/lib/protocols/socks5.c @@ -0,0 +1,92 @@ +/* + * socks5.c + * + * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> + * + * The signature is based on the Libprotoident library. + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_SOCKS5 +static void ndpi_int_socks5_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SOCKS5, NDPI_REAL_PROTOCOL); +} + +static void ndpi_check_socks5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Break after 20 packets. */ + if (flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "Exclude SOCKS5.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOCKS5); + return; + } + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->socks5_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS5 stage 0: \n"); + + if ((payload_len == 3) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00)) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "Possible SOCKS5 request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->socks5_stage = packet->packet_direction + 1; + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS5 stage %u: \n", flow->socks5_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->socks5_stage - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len == 0) || ((payload_len == 2) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x00))) { + NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "Found SOCKS5.\n"); + ndpi_int_socks5_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to SOCKS5, resetting the stage to 0...\n"); + flow->socks5_stage = 0; + } + + } +} + +void ndpi_search_socks5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_SOCKS5, ndpi_struct, NDPI_LOG_DEBUG, "SOCKS5 detection...\n"); + + /* skip marked packets */ + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SOCKS5) { + if (packet->tcp_retransmission == 0) { + ndpi_check_socks5(ndpi_struct, flow); + } + } +} + +#endif diff --git a/src/lib/protocols/socrates.c b/src/lib/protocols/socrates.c new file mode 100644 index 000000000..c433580fc --- /dev/null +++ b/src/lib/protocols/socrates.c @@ -0,0 +1,80 @@ +/* + * socrates.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_SOCRATES + + +static void ndpi_socrates_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SOCRATES, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_socrates(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + + + NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "search socrates.\n"); + if (packet->udp != NULL) { + if (packet->payload_packet_len > 9 && packet->payload[0] == 0xfe + && packet->payload[packet->payload_packet_len - 1] == 0x05) { + NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "found fe.\n"); + + NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "len match.\n"); + if (memcmp(&packet->payload[2], "socrates", 8) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "found socrates udp.\n"); + ndpi_socrates_add_connection(ndpi_struct, flow); + } + + } + } else if (packet->tcp != NULL) { + if (packet->payload_packet_len > 13 && packet->payload[0] == 0xfe + && packet->payload[packet->payload_packet_len - 1] == 0x05) { + NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "found fe.\n"); + if (packet->payload_packet_len == ntohl(get_u_int32_t(packet->payload, 2))) { + NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "len match.\n"); + if (memcmp(&packet->payload[6], "socrates", 8) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "found socrates tcp.\n"); + ndpi_socrates_add_connection(ndpi_struct, flow); + } + } + } + } + + + + + NDPI_LOG(NDPI_PROTOCOL_SOCRATES, ndpi_struct, NDPI_LOG_DEBUG, "exclude socrates.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOCRATES); +} + +#endif diff --git a/src/lib/protocols/sopcast.c b/src/lib/protocols/sopcast.c new file mode 100644 index 000000000..363caba42 --- /dev/null +++ b/src/lib/protocols/sopcast.c @@ -0,0 +1,219 @@ +/* + * sopcast.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_SOPCAST + + +static void ndpi_int_sopcast_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SOPCAST, NDPI_REAL_PROTOCOL); +} + +/** + * this function checks for sopcast tcp pattern + * + * NOTE: if you add more patterns please keep the number of if levels + * low, it is already complex enough + */ + +#if !defined(WIN32) + static inline +#else +__forceinline static +#endif + u_int8_t ndpi_int_is_sopcast_tcp(const u_int8_t * payload, const u_int16_t payload_len) +{ + if (payload_len != 54) + return 0; + + if (payload[2] != payload[3] - 4 && payload[2] != payload[3] + 4) + return 0; + + if (payload[2] != payload[4] - 1 && payload[2] != payload[4] + 1) + return 0; + + if (payload[25] != payload[25 + 16 - 1] + 1 && payload[25] != payload[25 + 16 - 1] - 1) { + + if (payload[3] != payload[25] && + payload[3] != payload[25] - 4 && payload[3] != payload[25] + 4 && payload[3] != payload[25] - 21) { + return 0; + } + } + + if (payload[4] != payload[28] || + payload[28] != payload[30] || + payload[30] != payload[31] || + get_u_int16_t(payload, 30) != get_u_int16_t(payload, 32) || get_u_int16_t(payload, 32) != get_u_int16_t(payload, 34)) { + + if ((payload[2] != payload[5] - 1 && payload[2] != payload[5] + 1) || + payload[2] != payload[25] || + payload[4] != payload[28] || + payload[4] != payload[31] || + payload[4] != payload[32] || + payload[4] != payload[33] || + payload[4] != payload[34] || + payload[4] != payload[35] || payload[4] != payload[30] || payload[2] != payload[36]) { + return 0; + } + } + + if (payload[42] != payload[53]) + return 0; + + if (payload[45] != payload[46] + 1 && payload[45] != payload[46] - 1) + return 0; + + if (payload[45] != payload[49] || payload[46] != payload[50] || payload[47] != payload[51]) + return 0; + + return 1; +} + +static void ndpi_search_sopcast_tcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + + if (flow->packet_counter == 1 && packet->payload_packet_len == 54 && get_u_int16_t(packet->payload, 0) == ntohs(0x0036)) { + if (ndpi_int_is_sopcast_tcp(packet->payload, packet->payload_packet_len)) { + NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast TCP \n"); + ndpi_int_sopcast_add_connection(ndpi_struct, flow); + return; + } + } + + NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "exclude sopcast TCP. \n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOPCAST); + + +} + +static void ndpi_search_sopcast_udp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "search sopcast. \n"); + + + if (packet->payload_packet_len == 52 && packet->payload[0] == 0xff + && packet->payload[1] == 0xff && packet->payload[2] == 0x01 + && packet->payload[8] == 0x02 && packet->payload[9] == 0xff + && packet->payload[10] == 0x00 && packet->payload[11] == 0x2c + && packet->payload[12] == 0x00 && packet->payload[13] == 0x00 && packet->payload[14] == 0x00) { + NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if I. \n"); + ndpi_int_sopcast_add_connection(ndpi_struct, flow); + return; + } + if ((packet->payload_packet_len == 80 || packet->payload_packet_len == 28 || packet->payload_packet_len == 94) + && packet->payload[0] == 0x00 && (packet->payload[2] == 0x02 || packet->payload[2] == 0x01) + && packet->payload[8] == 0x01 && packet->payload[9] == 0xff + && packet->payload[10] == 0x00 && packet->payload[11] == 0x14 + && packet->payload[12] == 0x00 && packet->payload[13] == 0x00) { + NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if II. \n"); + ndpi_int_sopcast_add_connection(ndpi_struct, flow); + return; + } + /* this case has been seen once. Please revome this comment, if you see it another time */ + if (packet->payload_packet_len == 60 && packet->payload[0] == 0x00 + && packet->payload[2] == 0x01 + && packet->payload[8] == 0x03 && packet->payload[9] == 0xff + && packet->payload[10] == 0x00 && packet->payload[11] == 0x34 + && packet->payload[12] == 0x00 && packet->payload[13] == 0x00 && packet->payload[14] == 0x00) { + NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if III. \n"); + ndpi_int_sopcast_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len == 42 && packet->payload[0] == 0x00 + && packet->payload[1] == 0x02 && packet->payload[2] == 0x01 + && packet->payload[3] == 0x07 && packet->payload[4] == 0x03 + && packet->payload[8] == 0x06 + && packet->payload[9] == 0x01 && packet->payload[10] == 0x00 + && packet->payload[11] == 0x22 && packet->payload[12] == 0x00 && packet->payload[13] == 0x00) { + NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if IV. \n"); + ndpi_int_sopcast_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len == 28 && packet->payload[0] == 0x00 + && packet->payload[1] == 0x0c && packet->payload[2] == 0x01 + && packet->payload[3] == 0x07 && packet->payload[4] == 0x00 + && packet->payload[8] == 0x01 + && packet->payload[9] == 0x01 && packet->payload[10] == 0x00 + && packet->payload[11] == 0x14 && packet->payload[12] == 0x00 && packet->payload[13] == 0x00) { + NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if V. \n"); + ndpi_int_sopcast_add_connection(ndpi_struct, flow); + return; + } + /* this case has been seen once. Please revome this comment, if you see it another time */ + if (packet->payload_packet_len == 286 && packet->payload[0] == 0x00 + && packet->payload[1] == 0x02 && packet->payload[2] == 0x01 + && packet->payload[3] == 0x07 && packet->payload[4] == 0x03 + && packet->payload[8] == 0x06 + && packet->payload[9] == 0x01 && packet->payload[10] == 0x01 + && packet->payload[11] == 0x16 && packet->payload[12] == 0x00 && packet->payload[13] == 0x00) { + NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if VI. \n"); + ndpi_int_sopcast_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len == 76 && packet->payload[0] == 0xff + && packet->payload[1] == 0xff && packet->payload[2] == 0x01 + && packet->payload[8] == 0x0c && packet->payload[9] == 0xff + && packet->payload[10] == 0x00 && packet->payload[11] == 0x44 + && packet->payload[16] == 0x01 && packet->payload[15] == 0x01 + && packet->payload[12] == 0x00 && packet->payload[13] == 0x00 && packet->payload[14] == 0x00) { + NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast with if VII. \n"); + ndpi_int_sopcast_add_connection(ndpi_struct, flow); + return; + } + + /* Attention please: no asymmetric detection necessary. This detection works asymmetrically as well. */ + + NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "exclude sopcast. \n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOPCAST); + + + +} + +void ndpi_search_sopcast(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if (packet->udp != NULL) + ndpi_search_sopcast_udp(ndpi_struct, flow); + if (packet->tcp != NULL) + ndpi_search_sopcast_tcp(ndpi_struct, flow); + +} +#endif diff --git a/src/lib/protocols/soulseek.c b/src/lib/protocols/soulseek.c new file mode 100644 index 000000000..061acfa51 --- /dev/null +++ b/src/lib/protocols/soulseek.c @@ -0,0 +1,286 @@ +/* + * soulseek.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_SOULSEEK + +static void ndpi_int_soulseek_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SOULSEEK, NDPI_REAL_PROTOCOL); + + if (src != NULL) { + src->soulseek_last_safe_access_time = packet->tick_timestamp; + } + if (dst != NULL) { + dst->soulseek_last_safe_access_time = packet->tick_timestamp; + } + + return; +} + +void ndpi_search_soulseek_tcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "Soulseek: search soulseec tcp \n"); + + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SOULSEEK) { + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "packet marked as Soulseek\n"); + if (src != NULL) + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, + " SRC bitmask: %u, packet tick %llu , last safe access timestamp: %llu\n", + NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_SOULSEEK) + != 0 ? 1 : 0, (u_int64_t) packet->tick_timestamp, (u_int64_t) src->soulseek_last_safe_access_time); + if (dst != NULL) + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, + " DST bitmask: %u, packet tick %llu , last safe ts: %llu\n", + NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_SOULSEEK) + != 0 ? 1 : 0, (u_int64_t) packet->tick_timestamp, (u_int64_t) dst->soulseek_last_safe_access_time); + + if (packet->payload_packet_len == 431) { + if (dst != NULL) { + dst->soulseek_last_safe_access_time = packet->tick_timestamp; + } + return; + } + if (packet->payload_packet_len == 12 && get_l32(packet->payload, 4) == 0x02) { + if (src != NULL) { + src->soulseek_last_safe_access_time = packet->tick_timestamp; + if (packet->tcp != NULL && src->soulseek_listen_port == 0) { + src->soulseek_listen_port = get_l32(packet->payload, 8); + return; + } + } + } + + if (src != NULL && ((u_int32_t) + (packet->tick_timestamp - + src->soulseek_last_safe_access_time) < + ndpi_struct->soulseek_connection_ip_tick_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, + "Soulseek: SRC update last safe access time and SKIP_FOR_TIME \n"); + src->soulseek_last_safe_access_time = packet->tick_timestamp; + } + + if (dst != NULL && ((u_int32_t) + (packet->tick_timestamp - + dst->soulseek_last_safe_access_time) < + ndpi_struct->soulseek_connection_ip_tick_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, + "Soulseek: DST update last safe access time and SKIP_FOR_TIME \n"); + dst->soulseek_last_safe_access_time = packet->tick_timestamp; + } + } + + + if (dst != NULL && dst->soulseek_listen_port != 0 && dst->soulseek_listen_port == ntohs(packet->tcp->dest) + && ((u_int32_t) + (packet->tick_timestamp - dst->soulseek_last_safe_access_time) < + ndpi_struct->soulseek_connection_ip_tick_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, + "Soulseek: Plain detection on Port : %u packet_tick_timestamp: %u soulseeek_last_safe_access_time: %u soulseek_connection_ip_ticktimeout: %u\n", + dst->soulseek_listen_port, packet->tick_timestamp, + dst->soulseek_last_safe_access_time, ndpi_struct->soulseek_connection_ip_tick_timeout); + ndpi_int_soulseek_add_connection(ndpi_struct, flow); + return; + } + + if (flow->l4.tcp.soulseek_stage == 0) { + + u_int32_t index = 0; + + if (packet->payload_packet_len >= 12 && packet->payload_packet_len < 300 && get_l32(packet->payload, 4) == 1) { + while (!get_u_int16_t(packet->payload, index + 2) + && (index + get_l32(packet->payload, index)) < packet->payload_packet_len - 4) { + if (get_l32(packet->payload, index) < 8) /*Minimum soulsek login msg is 8B */ + break; + + if (index + get_l32(packet->payload, index) + 4 <= index) { + /* avoid overflow */ + break; + } + + index += get_l32(packet->payload, index) + 4; + } + if (index + get_l32(packet->payload, index) == + packet->payload_packet_len - 4 && !get_u_int16_t(packet->payload, 10)) { + /*This structure seems to be soulseek proto */ + index = get_l32(packet->payload, 8) + 12; // end of "user name" + if ((index + 4) <= packet->payload_packet_len && !get_u_int16_t(packet->payload, index + 2)) // for passwd len + { + index += get_l32(packet->payload, index) + 4; //end of "Passwd" + if ((index + 4 + 4) <= packet->payload_packet_len && !get_u_int16_t(packet->payload, index + 6)) // to read version,hashlen + { + index += get_l32(packet->payload, index + 4) + 8; // enf of "hash value" + if (index == get_l32(packet->payload, 0)) { + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, + ndpi_struct, NDPI_LOG_DEBUG, "Soulseek Login Detected\n"); + ndpi_int_soulseek_add_connection(ndpi_struct, flow); + return; + } + } + } + } + } + if (packet->payload_packet_len > 8 + && packet->payload_packet_len < 200 && get_l32(packet->payload, 0) == packet->payload_packet_len - 4) { + //Server Messages: + const u_int32_t msgcode = get_l32(packet->payload, 4); + + if (msgcode == 0x7d) { + flow->l4.tcp.soulseek_stage = 1 + packet->packet_direction; + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "Soulseek Messages Search\n"); + return; + } else if (msgcode == 0x02 && packet->payload_packet_len == 12) { + const u_int32_t soulseek_listen_port = get_l32(packet->payload, 8); + + if (src != NULL) { + src->soulseek_last_safe_access_time = packet->tick_timestamp; + + if (packet->tcp != NULL && src->soulseek_listen_port == 0) { + src->soulseek_listen_port = soulseek_listen_port; + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, + NDPI_LOG_DEBUG, "\n Listen Port Saved : %u", src->soulseek_listen_port); + ndpi_int_soulseek_add_connection(ndpi_struct, flow); + return; + } + } + + } + //Peer Messages : Peer Init Message Detection + if (get_l32(packet->payload, 0) == packet->payload_packet_len - 4) { + const u_int32_t typelen = get_l32(packet->payload, packet->payload_packet_len - 9); + const u_int8_t type = packet->payload[packet->payload_packet_len - 5]; + const u_int32_t namelen = get_l32(packet->payload, 5); + if (packet->payload[4] == 0x01 && typelen == 1 + && namelen <= packet->payload_packet_len + && (4 + 1 + 4 + namelen + 4 + 1 + 4) == + packet->payload_packet_len && (type == 'F' || type == 'P' || type == 'D')) { + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected\n"); + ndpi_int_soulseek_add_connection(ndpi_struct, flow); + return; + } + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "1\n"); + } + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "3\n"); + //Peer Message : Pierce Firewall + if (packet->payload_packet_len == 9 && get_l32(packet->payload, 0) == 5 + && packet->payload[4] <= 0x10 && get_u_int32_t(packet->payload, 5) != 0x00000000) { + flow->l4.tcp.soulseek_stage = 1 + packet->packet_direction; + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_TRACE, "Soulseek Size 9 Pierce Firewall\n"); + return; + } + + } + + if (packet->payload_packet_len > 25 && packet->payload[4] == 0x01 && !get_u_int16_t(packet->payload, 7) + && !get_u_int16_t(packet->payload, 2)) { + const u_int32_t usrlen = get_l32(packet->payload, 5); + + if (usrlen <= packet->payload_packet_len - 4 + 1 + 4 + 4 + 1 + 4) { + const u_int32_t typelen = get_l32(packet->payload, 4 + 1 + 4 + usrlen); + const u_int8_t type = packet->payload[4 + 1 + 4 + usrlen + 4]; + if (typelen == 1 && (type == 'F' || type == 'P' || type == 'D')) { + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, + NDPI_LOG_DEBUG, "soulseek detected Pattern command(D|P|F).\n"); + ndpi_int_soulseek_add_connection(ndpi_struct, flow); + return; + } + } + } + + } else if (flow->l4.tcp.soulseek_stage == 2 - packet->packet_direction) { + if (packet->payload_packet_len > 8) { + if ((packet->payload[0] || packet->payload[1]) && get_l32(packet->payload, 4) == 9) { + /* 9 is search result */ + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected Second Pkt\n"); + ndpi_int_soulseek_add_connection(ndpi_struct, flow); + return; + } + if (get_l32(packet->payload, 0) == packet->payload_packet_len - 4) { + const u_int32_t msgcode = get_l32(packet->payload, 4); + if (msgcode == 0x03 && packet->payload_packet_len >= 12) //Server Message : Get Peer Address + { + const u_int32_t usrlen = get_l32(packet->payload, 8); + if (usrlen <= packet->payload_packet_len && 4 + 4 + 4 + usrlen == packet->payload_packet_len) { + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, + NDPI_LOG_DEBUG, "Soulseek Request Get Peer Address Detected\n"); + ndpi_int_soulseek_add_connection(ndpi_struct, flow); + return; + } + } + } + } + + if (packet->payload_packet_len == 8 && get_l32(packet->payload, 4) == 0x00000004) { + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected\n"); + ndpi_int_soulseek_add_connection(ndpi_struct, flow); + return; + } + + if (packet->payload_packet_len == 4 + && get_u_int16_t(packet->payload, 2) == 0x00 && get_u_int16_t(packet->payload, 0) != 0x00) { + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected\n"); + ndpi_int_soulseek_add_connection(ndpi_struct, flow); + return; + } else if (packet->payload_packet_len == 4) { + flow->l4.tcp.soulseek_stage = 3; + return; + } + } else if (flow->l4.tcp.soulseek_stage == 1 + packet->packet_direction) { + if (packet->payload_packet_len > 8) { + if (packet->payload[4] == 0x03 && get_l32(packet->payload, 5) == 0x00000031) { + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, + NDPI_LOG_DEBUG, "soulseek detected Second Pkt with SIGNATURE :: 0x0331000000 \n"); + ndpi_int_soulseek_add_connection(ndpi_struct, flow); + return; + } + } + } + if (flow->l4.tcp.soulseek_stage == 3 && packet->payload_packet_len == 8 && !get_u_int32_t(packet->payload, 4)) { + + NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected bcz of 8B pkt\n"); + ndpi_int_soulseek_add_connection(ndpi_struct, flow); + return; + } + if (flow->l4.tcp.soulseek_stage && flow->packet_counter < 11) { + } else { + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOULSEEK); + } +} + +#endif diff --git a/src/lib/protocols/spotify.c b/src/lib/protocols/spotify.c new file mode 100644 index 000000000..43ed5ec92 --- /dev/null +++ b/src/lib/protocols/spotify.c @@ -0,0 +1,128 @@ +/* + * spotify.c + * + * Copyright (C) 2011-13 by ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_SPOTIFY +static void ndpi_int_spotify_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int8_t due_to_correlation) +{ + ndpi_int_add_connection(ndpi_struct, flow, + NDPI_PROTOCOL_SPOTIFY, + due_to_correlation ? NDPI_CORRELATED_PROTOCOL : NDPI_REAL_PROTOCOL); +} + + +static void ndpi_check_spotify(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // const u_int8_t *packet_payload = packet->payload; + u_int32_t payload_len = packet->payload_packet_len; + + if(packet->udp != NULL) { + u_int16_t spotify_port = htons(57621); + + if((packet->udp->source == spotify_port) + && (packet->udp->dest == spotify_port)) { + if(payload_len > 2) { + if(memcmp(packet->payload, "SpotUdp", 7) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SPOTIFY, ndpi_struct, NDPI_LOG_DEBUG, "Found spotify udp dissector.\n"); + ndpi_int_spotify_add_connection(ndpi_struct, flow, 0); + return; + } + } + } + } else if(packet->tcp != NULL) { + + if(packet->payload[0] == 0x00 && packet->payload[1] == 0x04 && + packet->payload[2] == 0x00 && packet->payload[3] == 0x00&& + packet->payload[6] == 0x52 && packet->payload[7] == 0x0e && + packet->payload[8] == 0x50 ) { + NDPI_LOG(NDPI_PROTOCOL_SPOTIFY, ndpi_struct, NDPI_LOG_DEBUG, "Found spotify tcp dissector.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SPOTIFY, NDPI_REAL_PROTOCOL); + } + + + if(packet->iph /* IPv4 Only: we need to support packet->iphv6 at some point */) { + /* if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) */ { + /* + Spotify + + 78.31.8.0 - 78.31.15.255 (78.31.8.0/22) + AS29017 + + 193.235.232.0 - 193.235.235.255 (193.235.232.0/22) + AS29017 + + 194.132.196.0 - 194.132.199.255 (194.132.198.147/22) + AS43650 + + 194.132.176.0 - 194.132.179.255 (194.132.176.0/22) + AS43650 + + 194.132.162.0 - 194.132.163.255 (194.132.162.0/24) + AS43650 + */ + + //printf("%08X - %08X\n", ntohl(packet->iph->saddr), ntohl(packet->iph->daddr)); + if(((ntohl(packet->iph->saddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0x4E1F0800 /* 78.31.8.0 */) + || ((ntohl(packet->iph->daddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0x4E1F0800 /* 78.31.8.0 */) + /* **** */ + || ((ntohl(packet->iph->saddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC1EBE800 /* 193.235.232.0 */) + || ((ntohl(packet->iph->daddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC1EBE800 /* 193.235.232.0 */) + /* **** */ + || ((ntohl(packet->iph->saddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC284C400 /* 194.132.196.0 */) + || ((ntohl(packet->iph->daddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC284C400 /* 194.132.196.0 */) + /* **** */ + || ((ntohl(packet->iph->saddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC284A200 /* 194.132.162.0 */) + || ((ntohl(packet->iph->daddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC284A200 /* 194.132.162.0 */) + ) { + NDPI_LOG(NDPI_PROTOCOL_SPOTIFY, ndpi_struct, NDPI_LOG_DEBUG, "Found spotify via ip range.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SPOTIFY, NDPI_REAL_PROTOCOL); + return; + } + } + } + } + + NDPI_LOG(NDPI_PROTOCOL_SPOTIFY, ndpi_struct, NDPI_LOG_DEBUG, "exclude spotify.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SPOTIFY); +} + +void ndpi_search_spotify(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_SPOTIFY, ndpi_struct, NDPI_LOG_DEBUG, "spotify detection...\n"); + + /* skip marked packets */ + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SPOTIFY) { + if (packet->tcp_retransmission == 0) { + ndpi_check_spotify(ndpi_struct, flow); + } + } +} + +#endif diff --git a/src/lib/protocols/ssdp.c b/src/lib/protocols/ssdp.c new file mode 100644 index 000000000..83ce102d4 --- /dev/null +++ b/src/lib/protocols/ssdp.c @@ -0,0 +1,70 @@ +/* + * ssdp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_SSDP + + +static void ndpi_int_ssdp_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSDP, NDPI_REAL_PROTOCOL); +} + +/* this detection also works asymmetrically */ +void ndpi_search_ssdp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_SSDP, ndpi_struct, NDPI_LOG_DEBUG, "search ssdp.\n"); + if (packet->udp != NULL) { + + if (packet->payload_packet_len > 100) { + if ((memcmp(packet->payload, "M-SEARCH * HTTP/1.1", 19) == 0) + || memcmp(packet->payload, "NOTIFY * HTTP/1.1", 17) == 0) { + + + NDPI_LOG(NDPI_PROTOCOL_SSDP, ndpi_struct, NDPI_LOG_DEBUG, "found ssdp.\n"); + ndpi_int_ssdp_add_connection(ndpi_struct, flow); + return; + } + +#define SSDP_HTTP "HTTP/1.1 200 OK\r\n" + if(memcmp(packet->payload, SSDP_HTTP, strlen(SSDP_HTTP)) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SSDP, ndpi_struct, NDPI_LOG_DEBUG, "found ssdp.\n"); + ndpi_int_ssdp_add_connection(ndpi_struct, flow); + return; + } + } + } + + NDPI_LOG(NDPI_PROTOCOL_SSDP, ndpi_struct, NDPI_LOG_DEBUG, "ssdp excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSDP); +} + +#endif diff --git a/src/lib/protocols/ssh.c b/src/lib/protocols/ssh.c new file mode 100644 index 000000000..f659294a2 --- /dev/null +++ b/src/lib/protocols/ssh.c @@ -0,0 +1,68 @@ +/* + * ssh.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_SSH + +static void ndpi_int_ssh_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSH, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + + + if (flow->l4.tcp.ssh_stage == 0) { + if (packet->payload_packet_len > 7 && packet->payload_packet_len < 100 + && memcmp(packet->payload, "SSH-", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SSH, ndpi_struct, NDPI_LOG_DEBUG, "ssh stage 0 passed\n"); + flow->l4.tcp.ssh_stage = 1 + packet->packet_direction; + return; + } + } else if (flow->l4.tcp.ssh_stage == (2 - packet->packet_direction)) { + if (packet->payload_packet_len > 7 && packet->payload_packet_len < 100 + && memcmp(packet->payload, "SSH-", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_SSH, ndpi_struct, NDPI_LOG_DEBUG, "found ssh\n"); + ndpi_int_ssh_add_connection(ndpi_struct, flow); + return; + + } + + + } + + NDPI_LOG(NDPI_PROTOCOL_SSH, ndpi_struct, NDPI_LOG_DEBUG, "excluding ssh at stage %d\n", flow->l4.tcp.ssh_stage); + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSH); +} + +#endif diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c new file mode 100644 index 000000000..c61c039c1 --- /dev/null +++ b/src/lib/protocols/ssl.c @@ -0,0 +1,637 @@ +/* + * ssl.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +// #define CERTIFICATE_DEBUG 1 + +#ifdef NDPI_PROTOCOL_SSL + +#define NDPI_MAX_SSL_REQUEST_SIZE 10000 + +/* Skype.c */ +extern u_int8_t is_skype_flow(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow); + +static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, u_int32_t protocol) +{ + if((protocol != NDPI_PROTOCOL_SSL) + && (protocol != NDPI_PROTOCOL_SSL_NO_CERT)) { + ndpi_int_add_connection(ndpi_struct, flow, protocol, NDPI_CORRELATED_PROTOCOL); + } else { + struct ndpi_packet_struct *packet = &flow->packet; + + if((flow->protos.ssl.client_certificate[0] != '\0') + || (flow->protos.ssl.server_certificate[0] != '\0') + || (flow->host_server_name[0] != '\0')) + protocol = NDPI_PROTOCOL_SSL; + else + protocol = NDPI_PROTOCOL_SSL_NO_CERT; + + if(packet->tcp != NULL) { + switch(protocol) { + case NDPI_PROTOCOL_SSL: + case NDPI_PROTOCOL_SSL_NO_CERT: + { + /* + In case of SSL there are probably sub-protocols + such as IMAPS that can be otherwise detected + */ + u_int16_t sport = ntohs(packet->tcp->source); + u_int16_t dport = ntohs(packet->tcp->dest); + + if((sport == 465) || (dport == 465)) protocol = NDPI_PROTOCOL_MAIL_SMTPS; + else if((sport == 993) || (dport == 993)) protocol = NDPI_PROTOCOL_MAIL_IMAPS; + else if((sport == 995) || (dport == 995)) protocol = NDPI_PROTOCOL_MAIL_POPS; + } + break; + } + + if((protocol == NDPI_PROTOCOL_SSL_NO_CERT) + && is_skype_flow(ndpi_struct, flow)) { + protocol = NDPI_PROTOCOL_SKYPE; + } + } + + ndpi_int_add_connection(ndpi_struct, flow, protocol, NDPI_REAL_PROTOCOL); + } +} + +/* Can't call libc functions from kernel space, define some stub instead */ + +#define ndpi_isalpha(ch) (((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z')) +#define ndpi_isdigit(ch) ((ch) >= '0' && (ch) <= '9') +#define ndpi_isspace(ch) (((ch) >= '\t' && (ch) <= '\r') || ((ch) == ' ')) +#define ndpi_isprint(ch) ((ch) >= 0x20 && (ch) <= 0x7e) +#define ndpi_ispunct(ch) (((ch) >= '!' && (ch) <= '/') || \ + ((ch) >= ':' && (ch) <= '@') || \ + ((ch) >= '[' && (ch) <= '`') || \ + ((ch) >= '{' && (ch) <= '~')) + +static void stripCertificateTrailer(char *buffer, int buffer_len) { + int i; + + // printf("->%s<-\n", buffer); + + for(i=0; i<buffer_len; i++) { + // printf("%c [%d]\n", buffer[i], buffer[i]); + + if((buffer[i] != '.') + && (buffer[i] != '-') + && (buffer[i] != '*') + && (!ndpi_isalpha(buffer[i])) + && (!ndpi_isdigit(buffer[i]))) { + buffer[i] = '\0'; + buffer_len = i; + break; + } + } + + if(i > 0) i--; + + while(i > 0) { + if(!ndpi_isalpha(buffer[i])) { + buffer[i] = '\0'; + buffer_len = i; + i--; + } else + break; + } + + for(i=buffer_len; i>0; i--) { + if(buffer[i] == '.') break; + else if(ndpi_isdigit(buffer[i])) + buffer[i] = '\0', buffer_len = i; + } +} + +/* Code fixes courtesy of Alexsandro Brahm <alex@digistar.com.br> */ +int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + char *buffer, int buffer_len) { + struct ndpi_packet_struct *packet = &flow->packet; + + /* + Nothing matched so far: let's decode the certificate with some heuristics + Patches courtesy of Denys Fedoryshchenko <nuclearcat@nuclearcat.com> + */ + if(packet->payload[0] == 0x16 /* Handshake */) { + u_int16_t total_len = (packet->payload[3] << 8) + packet->payload[4] + 5 /* SSL Header */; + u_int8_t handshake_protocol = packet->payload[5]; /* handshake protocol a bit misleading, it is message type according TLS specs */ + + memset(buffer, 0, buffer_len); + + /* Truncate total len, search at least in incomplete packet */ + if (total_len > packet->payload_packet_len) + total_len = packet->payload_packet_len; + + /* At least "magic" 3 bytes, null for string end, otherwise no need to waste cpu cycles */ + if(total_len > 4) { + int i; + + if(handshake_protocol == 0x02 || handshake_protocol == 0xb /* Server Hello and Certificate message types are interesting for us */) { + u_int num_found = 0; + + flow->l4.tcp.ssl_seen_server_cert = 1; + + /* Check after handshake protocol header (5 bytes) and message header (4 bytes) */ + for(i = 9; i < packet->payload_packet_len-3; i++) { + if(((packet->payload[i] == 0x04) && (packet->payload[i+1] == 0x03) && (packet->payload[i+2] == 0x0c)) + || ((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x03))) { + u_int8_t server_len = packet->payload[i+3]; + + if(packet->payload[i] == 0x55) { + num_found++; + + if(num_found != 2) continue; + } + + if(server_len+i+3 < packet->payload_packet_len) { + char *server_name = (char*)&packet->payload[i+4]; + u_int8_t begin = 0, len, j, num_dots; + + while(begin < server_len) { + if(!ndpi_isprint(server_name[begin])) + begin++; + else + break; + } + + // len = ndpi_min(server_len-begin, buffer_len-1); + len = buffer_len-1; + strncpy(buffer, &server_name[begin], len); + buffer[len] = '\0'; + + /* We now have to check if this looks like an IP address or host name */ + for(j=0, num_dots = 0; j<len; j++) { + if(!ndpi_isprint((buffer[j]))) { + num_dots = 0; /* This is not what we look for */ + break; + } else if(buffer[j] == '.') { + num_dots++; + if(num_dots >=2) break; + } + } + + if(num_dots >= 2) { + stripCertificateTrailer(buffer, buffer_len); + snprintf(flow->protos.ssl.server_certificate, + sizeof(flow->protos.ssl.server_certificate), "%s", buffer); + return(1 /* Server Certificate */); + } + } + } + } + } else if(handshake_protocol == 0x01 /* Client Hello */) { + u_int offset, base_offset = 43; + u_int16_t session_id_len = packet->payload[base_offset]; + + if((session_id_len+base_offset+2) <= total_len) { + u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8); + offset = base_offset + session_id_len + cypher_len + 2; + + flow->l4.tcp.ssl_seen_client_cert = 1; + + if(offset < total_len) { + u_int16_t compression_len; + u_int16_t extensions_len; + + compression_len = packet->payload[offset+1]; + offset += compression_len + 3; + + if(offset < total_len) { + extensions_len = packet->payload[offset]; + + if((extensions_len+offset) < total_len) { + u_int16_t extension_offset = 1; /* Move to the first extension */ + + while(extension_offset < extensions_len) { + u_int16_t extension_id, extension_len; + + memcpy(&extension_id, &packet->payload[offset+extension_offset], 2); + extension_offset += 2; + + memcpy(&extension_len, &packet->payload[offset+extension_offset], 2); + extension_offset += 2; + + extension_id = ntohs(extension_id), extension_len = ntohs(extension_len); + + if(extension_id == 0) { + u_int begin = 0,len; + char *server_name = (char*)&packet->payload[offset+extension_offset]; + + while(begin < extension_len) { + if((!ndpi_isprint(server_name[begin])) + || ndpi_ispunct(server_name[begin]) + || ndpi_isspace(server_name[begin])) + begin++; + else + break; + } + + len = (u_int)ndpi_min(extension_len-begin, buffer_len-1); + strncpy(buffer, &server_name[begin], len); + buffer[len] = '\0'; + stripCertificateTrailer(buffer, buffer_len); + + snprintf(flow->protos.ssl.client_certificate, + sizeof(flow->protos.ssl.client_certificate), "%s", buffer); + + /* We're happy now */ + return(2 /* Client Certificate */); + } + + extension_offset += extension_len; + } + } + } + } + } + } + } + } + + return(0); /* Not found */ +} + +int sslDetectProtocolFromCertificate(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + if(!packet->iph /* IPv4 */) return(-1); + + if((packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) + || (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL)) { + char certificate[64]; + int rc; + + certificate[0] = '\0'; + rc = getSSLcertificate(ndpi_struct, flow, certificate, sizeof(certificate)); + packet->ssl_certificate_num_checks++; + + if(rc > 0) { + packet->ssl_certificate_detected++; +#ifdef CERTIFICATE_DEBUG + printf("***** [SSL] %s\n", certificate); +#endif + + if(ndpi_match_string_subprotocol(ndpi_struct, flow, certificate, strlen(certificate)) != NDPI_PROTOCOL_UNKNOWN) + return(rc); /* Fix courtesy of Gianluca Costa <g.costa@xplico.org> */ + +#ifdef NDPI_PROTOCOL_TOR + if(ndpi_is_ssl_tor(ndpi_struct, flow, certificate) != 0) + return(rc); +#endif + } + + if(((packet->ssl_certificate_num_checks >= 2) + && flow->l4.tcp.seen_syn + && flow->l4.tcp.seen_syn_ack + && flow->l4.tcp.seen_ack /* We have seen the 3-way handshake */) + || (flow->protos.ssl.server_certificate[0] != '\0') + || (flow->protos.ssl.client_certificate[0] != '\0') + ) + ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL); + } + + return(0); +} + +static void ssl_mark_and_payload_search_for_other_protocols(struct + ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ +#if defined(NDPI_PROTOCOL_MEEBO)|| defined(NDPI_PROTOCOL_TOR) || defined(NDPI_PROTOCOL_VPN_X) || defined(NDPI_PROTOCOL_UNENCRYPED_JABBER) || defined (NDPI_PROTOCOL_OSCAR) || defined (NDPI_PROTOCOL_ITUNES) || defined (NDPI_SERVICE_GMAIL) + struct ndpi_packet_struct *packet = &flow->packet; + // struct ndpi_id_struct *src=flow->src; + // struct ndpi_id_struct *dst=flow->dst; + u_int32_t a; + u_int32_t end; +#if defined(NDPI_PROTOCOL_UNENCRYPED_JABBER) + if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) + goto check_for_ssl_payload; +#endif +#if defined(NDPI_PROTOCOL_OSCAR) + if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_OSCAR) != 0) + goto check_for_ssl_payload; +#endif + goto no_check_for_ssl_payload; + + check_for_ssl_payload: + end = packet->payload_packet_len - 20; + for (a = 5; a < end; a++) { +#ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER + if (packet->payload[a] == 't') { + if (memcmp(&packet->payload[a], "talk.google.com", 15) == 0) { + NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "ssl jabber packet match\n"); + if (NDPI_COMPARE_PROTOCOL_TO_BITMASK + (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) { + ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER); + return; + } + } + } +#endif +#ifdef NDPI_PROTOCOL_OSCAR + if (packet->payload[a] == 'A' || packet->payload[a] == 'k' || packet->payload[a] == 'c' + || packet->payload[a] == 'h') { + if (((a + 19) < packet->payload_packet_len && memcmp(&packet->payload[a], "America Online Inc.", 19) == 0) + // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 ) + // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0) + || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0) + || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "corehc@aol.net", 14) == 0) + || ((a + 41) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0) + || ((a + 28) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0) + || ((a + 32) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); + + if (flow->dst != NULL && packet->payload_packet_len > 75) { + memcpy(flow->dst->oscar_ssl_session_id, &packet->payload[44], 32); + flow->dst->oscar_ssl_session_id[32] = '\0'; + flow->dst->oscar_last_safe_access_time = packet->tick_timestamp; + } + + ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR); + return; + } + } + + if (packet->payload[a] == 'm' || packet->payload[a] == 's') { + if ((a + 21) < packet->payload_packet_len && + (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0 + || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); + ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR); + return; + } + } +#endif + } + + no_check_for_ssl_payload: +#endif + if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "found ssl connection.\n"); + sslDetectProtocolFromCertificate(ndpi_struct, flow); + + if(!packet->ssl_certificate_detected + && (!(flow->l4.tcp.ssl_seen_client_cert && flow->l4.tcp.ssl_seen_server_cert))) { + /* SSL without certificate (Skype, Ultrasurf?) */ + ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL_NO_CERT); + } else + ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL); + } +} + + +static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + + struct ndpi_packet_struct *packet = &flow->packet; + // + // struct ndpi_id_struct *src=flow->src; + // struct ndpi_id_struct *dst=flow->dst; + + + if ((packet->payload_packet_len >= 5) + && (packet->payload[0] == 0x16) + && (packet->payload[1] == 0x03) + && ((packet->payload[2] == 0x00) + || (packet->payload[2] == 0x01) + || (packet->payload[2] == 0x02) + || (packet->payload[2] == 0x03) + )) { + u_int32_t temp; + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search sslv3\n"); + // SSLv3 Record + if (packet->payload_packet_len >= 1300) { + return 1; + } + temp = ntohs(get_u_int16_t(packet->payload, 3)) + 5; + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp); + if (packet->payload_packet_len == temp + || (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) { + return 1; + } + + if (packet->payload_packet_len < temp && temp < 5000 && packet->payload_packet_len > 9) { + /* the server hello may be split into small packets */ + u_int32_t cert_start; + + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, + "maybe SSLv3 server hello split into smaller packets\n"); + + /* lets hope at least the server hello and the start of the certificate block are in the first packet */ + cert_start = ntohs(get_u_int16_t(packet->payload, 7)) + 5 + 4; + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "suspected start of certificate: %u\n", + cert_start); + + if (cert_start < packet->payload_packet_len && packet->payload[cert_start] == 0x0b) { + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, + "found 0x0b at suspected start of certificate block\n"); + return 2; + } + } + + if ((packet->payload_packet_len > temp && packet->payload_packet_len > 100) && packet->payload_packet_len > 9) { + /* the server hello may be split into small packets and the certificate has its own SSL Record + * so temp contains only the length for the first ServerHello block */ + u_int32_t cert_start; + + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, + "maybe SSLv3 server hello split into smaller packets but with seperate record for the certificate\n"); + + /* lets hope at least the server hello record and the start of the certificate record are in the first packet */ + cert_start = ntohs(get_u_int16_t(packet->payload, 7)) + 5 + 5 + 4; + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "suspected start of certificate: %u\n", + cert_start); + + if (cert_start < packet->payload_packet_len && packet->payload[cert_start] == 0x0b) { + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, + "found 0x0b at suspected start of certificate block\n"); + return 2; + } + } + + + if (packet->payload_packet_len >= temp + 5 && (packet->payload[temp] == 0x14 || packet->payload[temp] == 0x16) + && packet->payload[temp + 1] == 0x03) { + u_int32_t temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; + if (temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { + return 1; + } + temp += temp2; + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp); + if (packet->payload_packet_len == temp) { + return 1; + } + if (packet->payload_packet_len >= temp + 5 && + packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { + temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; + if (temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { + return 1; + } + temp += temp2; + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp); + if (packet->payload_packet_len == temp) { + return 1; + } + if (packet->payload_packet_len >= temp + 5 && + packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { + temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; + if (temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { + return 1; + } + temp += temp2; + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp); + if (temp == packet->payload_packet_len) { + return 1; + } + } + + } + + + } + + } + return 0; + +} + +void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=flow->src; + // struct ndpi_id_struct *dst=flow->dst; + + u_int8_t ret; + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) { + if (flow->l4.tcp.ssl_stage == 3 && packet->payload_packet_len > 20 && flow->packet_counter < 5) { + /* this should only happen, when we detected SSL with a packet that had parts of the certificate in subsequent packets + * so go on checking for certificate patterns for a couple more packets + */ + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, + "ssl flow but check another packet for patterns\n"); + ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow); + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) { + /* still ssl so check another packet */ + return; + } else { + /* protocol has changed so we are done */ + return; + } + } + return; + } + + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search ssl\n"); + + { + /* Check if this is whatsapp first (this proto runs over port 443) */ + if((packet->payload_packet_len > 5) + && ((packet->payload[0] == 'W') + && (packet->payload[1] == 'A') + && (packet->payload[4] == 0) + && (packet->payload[2] <= 9) + && (packet->payload[3] <= 9))) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_SERVICE_WHATSAPP, NDPI_REAL_PROTOCOL); + return; + } else { + /* No whatsapp, let's try SSL */ + if(sslDetectProtocolFromCertificate(ndpi_struct, flow) > 0) + return; + } + } + + if (packet->payload_packet_len > 40 && flow->l4.tcp.ssl_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "first ssl packet\n"); + // SSLv2 Record + if (packet->payload[2] == 0x01 && packet->payload[3] == 0x03 + && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) + && (packet->payload_packet_len - packet->payload[1] == 2)) { + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 len match\n"); + flow->l4.tcp.ssl_stage = 1 + packet->packet_direction; + return; + } + + if (packet->payload[0] == 0x16 && packet->payload[1] == 0x03 + && (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02) + && (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) { + // SSLv3 Record + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 len match\n"); + flow->l4.tcp.ssl_stage = 1 + packet->packet_direction; + return; + } + } + + if (packet->payload_packet_len > 40 && + flow->l4.tcp.ssl_stage == 1 + packet->packet_direction + && flow->packet_direction_counter[packet->packet_direction] < 5) { + return; + } + + if (packet->payload_packet_len > 40 && flow->l4.tcp.ssl_stage == 2 - packet->packet_direction) { + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "second ssl packet\n"); + // SSLv2 Record + if (packet->payload[2] == 0x01 && packet->payload[3] == 0x03 + && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) + && (packet->payload_packet_len - 2) >= packet->payload[1]) { + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 server len match\n"); + ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow); + return; + } + + ret = ndpi_search_sslv3_direction1(ndpi_struct, flow); + if (ret == 1) { + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 server len match\n"); + ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow); + return; + } else if (ret == 2) { + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, + "sslv3 server len match with split packet -> check some more packets for SSL patterns\n"); + ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow); + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) { + flow->l4.tcp.ssl_stage = 3; + } + return; + } + + if (packet->payload_packet_len > 40 && flow->packet_direction_counter[packet->packet_direction] < 5) { + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "need next packet\n"); + return; + } + } + + NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "exclude ssl\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSL); + return; +} +#endif diff --git a/src/lib/protocols/stealthnet.c b/src/lib/protocols/stealthnet.c new file mode 100644 index 000000000..e8f1778e6 --- /dev/null +++ b/src/lib/protocols/stealthnet.c @@ -0,0 +1,58 @@ +/* + * stealthnet.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_STEALTHNET + + +static void ndpi_int_stealthnet_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_STEALTHNET, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_stealthnet(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + +// struct ndpi_id_struct *src = flow->src; +// struct ndpi_id_struct *dst = flow->dst; + + + if (packet->payload_packet_len > 40 + && memcmp(packet->payload, "LARS REGENSBURGER'S FILE SHARING PROTOCOL", 41) == 0) { + NDPI_LOG(NDPI_PROTOCOL_STEALTHNET, ndpi_struct, NDPI_LOG_DEBUG, "found stealthnet\n"); + ndpi_int_stealthnet_add_connection(ndpi_struct, flow); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_STEALTHNET, ndpi_struct, NDPI_LOG_DEBUG, "exclude stealthnet.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_STEALTHNET); + +} +#endif diff --git a/src/lib/protocols/steam.c b/src/lib/protocols/steam.c new file mode 100644 index 000000000..7911df85a --- /dev/null +++ b/src/lib/protocols/steam.c @@ -0,0 +1,286 @@ +/* + * steam.c + * + * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> + * + * The signature is mostly based on the Libprotoident library + * except the detection of HTTP Steam flows. + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_STEAM +static void ndpi_int_steam_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_STEAM, NDPI_REAL_PROTOCOL); +} + +static void ndpi_check_steam_http(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + if (packet->user_agent_line.ptr != NULL + && packet->user_agent_line.len >= 23 + && memcmp(packet->user_agent_line.ptr, "Valve/Steam HTTP Client", 23) == 0) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); + ndpi_int_steam_add_connection(ndpi_struct, flow); + } +} + +static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + if (flow->steam_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n"); + + if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && match_first_bytes(packet->payload, "\x01\x00\x00\x00")) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->steam_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 + return; + } + + if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->steam_stage = packet->packet_direction + 3; // packet_direction 0: stage 3, packet_direction 1: stage 4 + return; + } + } else if ((flow->steam_stage == 1) || (flow->steam_stage == 2)) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->steam_stage - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); + ndpi_int_steam_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n"); + flow->steam_stage = 0; + } + } else if ((flow->steam_stage == 3) || (flow->steam_stage == 4)) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->steam_stage - packet->packet_direction) == 3) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && match_first_bytes(packet->payload, "\x01\x00\x00\x00")) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); + ndpi_int_steam_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n"); + flow->steam_stage = 0; + } + } +} + +static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + if ((payload_len > 0) && match_first_bytes(packet->payload, "VS01")) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); + ndpi_int_steam_add_connection(ndpi_struct, flow); + return; + } + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->steam_stage1 == 0) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n"); + + if ((payload_len > 0) && match_first_bytes(packet->payload, "\x31\xff\x30\x2e")) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->steam_stage1 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 + return; + } + + if ((payload_len > 0) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->steam_stage1 = packet->packet_direction + 3; // packet_direction 0: stage 3, packet_direction 1: stage 4 + return; + } + + } else if ((flow->steam_stage1 == 1) || (flow->steam_stage1 == 2)) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage1); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->steam_stage1 - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len > 0) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); + ndpi_int_steam_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n"); + flow->steam_stage1 = 0; + } + + } else if ((flow->steam_stage1 == 3) || (flow->steam_stage1 == 4)) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage1); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->steam_stage1 - packet->packet_direction) == 3) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len > 0) && match_first_bytes(packet->payload, "\x31\xff\x30\x2e")) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); + ndpi_int_steam_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n"); + flow->steam_stage1 = 0; + } + + } +} + +static void ndpi_check_steam_udp2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->steam_stage2 == 0) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n"); + + if ((payload_len == 25) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->steam_stage2 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage2); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->steam_stage2 - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len == 0) || match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); + ndpi_int_steam_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n"); + flow->steam_stage2 = 0; + } + + } +} + +static void ndpi_check_steam_udp3(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + + /* Check if we so far detected the protocol in the request or not. */ + if (flow->steam_stage3 == 0) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n"); + + if ((payload_len == 4) && (packet->payload[0] == 0x39) && (packet->payload[1] == 0x18) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x00)) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n"); + + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ + flow->steam_stage3 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 + } + + } else { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage %u: \n", flow->steam_stage3); + + /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ + if ((flow->steam_stage3 - packet->packet_direction) == 1) { + return; + } + + /* This is a packet in another direction. Check if we find the proper response. */ + if ((payload_len == 0) || ((payload_len == 8) && (packet->payload[0] == 0x3a) && (packet->payload[1] == 0x18) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x00))) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); + ndpi_int_steam_add_connection(ndpi_struct, flow); + } else { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "The reply did not seem to belong to STEAM, resetting the stage to 0...\n"); + flow->steam_stage3 = 0; + } + + } +} + +void ndpi_search_steam(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + /* Break after 20 packets. */ + if (flow->packet_counter > 20) { + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Exclude STEAM.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_STEAM); + return; + } + + /* skip marked or retransmitted packets */ + if (packet->tcp_retransmission != 0) { + return; + } + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) { + return; + } + + NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM detection...\n"); + ndpi_check_steam_http(ndpi_struct, flow); + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) { + return; + } + + ndpi_check_steam_tcp(ndpi_struct, flow); + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) { + return; + } + + ndpi_check_steam_udp1(ndpi_struct, flow); + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) { + return; + } + + ndpi_check_steam_udp2(ndpi_struct, flow); + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) { + return; + } + + ndpi_check_steam_udp3(ndpi_struct, flow); +} + +#endif diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c new file mode 100644 index 000000000..09ec4a050 --- /dev/null +++ b/src/lib/protocols/stun.c @@ -0,0 +1,188 @@ +/* + * stun.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_STUN + + +static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_STUN, NDPI_REAL_PROTOCOL); +} + + + +typedef enum { + NDPI_IS_STUN, + NDPI_IS_NOT_STUN +} ndpi_int_stun_t; + +static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *ndpi_struct, + const u_int8_t * payload, const u_int16_t payload_length) +{ + u_int16_t a; + + + if((payload_length > 13) + && (strncmp((const char*)payload, (const char*)"RSP/", 4) == 0) + && (strncmp((const char*)&payload[7], (const char*)" STUN_", 6) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "Found stun.\n"); + return NDPI_IS_STUN; + } + + /* + * token list of message types and attribute types from + * http://wwwbs1.informatik.htw-dresden.de/svortrag/i02/Schoene/stun/stun.html + * the same list you can find in + * https://summersoft.fay.ar.us/repos/ethereal/branches/redhat-9/ethereal-0.10.3-1/ethereal-0.10.3/packet-stun.c + * token further message types and attributes from + * http://www.freeswitch.org/docs/group__stun1.html + * added further attributes observed + * message types: 0x0001, 0x0101, 0x0111, 0x0002, 0x0102, 0x0112, 0x0003, 0x0103, 0x0004, 0x0104, 0x0114, 0x0115 + * attribute types: 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + * 0x000a, 0x000b, 0c000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0020, + * 0x0022, 0x0024, 0x8001, 0x8006, 0x8008, 0x8015, 0x8020, 0x8028, 0x802a, 0x8029, 0x8050, 0x8054, 0x8055 + * + * 0x8003, 0x8004 used by facetime + */ + + if (payload_length >= 20 && ntohs(get_u_int16_t(payload, 2)) + 20 == payload_length && + ((payload[0] == 0x00 && (payload[1] >= 0x01 && payload[1] <= 0x04)) || + (payload[0] == 0x01 && + ((payload[1] >= 0x01 && payload[1] <= 0x04) || (payload[1] >= 0x11 && payload[1] <= 0x15))))) { + u_int8_t mod; + u_int8_t old = 1; + u_int8_t padding = 0; + NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "len and type match.\n"); + + if (payload_length == 20) { + NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n"); + return NDPI_IS_STUN; + } + + a = 20; + + while (a < payload_length) { + + if (old && payload_length >= a + 4 + && + ((payload[a] == 0x00 + && ((payload[a + 1] >= 0x01 && payload[a + 1] <= 0x16) || payload[a + 1] == 0x19 + || payload[a + 1] == 0x20 || payload[a + 1] == 0x22 || payload[a + 1] == 0x24 + || payload[a + 1] == 0x25)) + || (payload[a] == 0x80 + && (payload[a + 1] == 0x01 || payload[a + 1] == 0x03 || payload[a + 1] == 0x04 + || payload[a + 1] == 0x06 || payload[a + 1] == 0x08 || payload[a + 1] == 0x15 + || payload[a + 1] == 0x20 || payload[a + 1] == 0x22 || payload[a + 1] == 0x28 + || payload[a + 1] == 0x2a || payload[a + 1] == 0x29 || payload[a + 1] == 0x50 + || payload[a + 1] == 0x54 || payload[a + 1] == 0x55)))) { + + NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "attribute match.\n"); + + a += ((payload[a + 2] << 8) + payload[a + 3] + 4); + mod = a % 4; + if (mod) { + padding = 4 - mod; + } + if (a == payload_length || (padding && (a + padding) == payload_length)) { + NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n"); + return NDPI_IS_STUN; + } + + } else if (payload_length >= a + padding + 4 + && + ((payload[a + padding] == 0x00 + && ((payload[a + 1 + padding] >= 0x01 && payload[a + 1 + padding] <= 0x16) + || payload[a + 1 + padding] == 0x19 || payload[a + 1 + padding] == 0x20 + || payload[a + 1 + padding] == 0x22 || payload[a + 1 + padding] == 0x24 + || payload[a + 1 + padding] == 0x25)) + || (payload[a + padding] == 0x80 + && (payload[a + 1 + padding] == 0x01 || payload[a + 1 + padding] == 0x03 + || payload[a + 1 + padding] == 0x04 || payload[a + 1 + padding] == 0x06 + || payload[a + 1 + padding] == 0x08 || payload[a + 1 + padding] == 0x15 + || payload[a + 1 + padding] == 0x20 || payload[a + 1 + padding] == 0x22 + || payload[a + 1 + padding] == 0x28 || payload[a + 1 + padding] == 0x2a + || payload[a + 1 + padding] == 0x29 || payload[a + 1 + padding] == 0x50 + || payload[a + 1 + padding] == 0x54 || payload[a + 1 + padding] == 0x55)))) { + + NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "New STUN - attribute match.\n"); + + old = 0; + a += ((payload[a + 2 + padding] << 8) + payload[a + 3 + padding] + 4); + padding = 0; + mod = a % 4; + if (mod) { + a += 4 - mod; + } + if (a == payload_length) { + NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n"); + return NDPI_IS_STUN; + } + } else { + break; + } + } + } + + return NDPI_IS_NOT_STUN; +} + +void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "search stun.\n"); + + + if (packet->tcp) { + + /* STUN may be encapsulated in TCP packets */ + + if (packet->payload_packet_len >= 2 + 20 && + ntohs(get_u_int16_t(packet->payload, 0)) + 2 == packet->payload_packet_len) { + + /* TODO there could be several STUN packets in a single TCP packet so maybe the detection could be + * improved by checking only the STUN packet of given length */ + + if (ndpi_int_check_stun(ndpi_struct, packet->payload + 2, packet->payload_packet_len - 2) == + NDPI_IS_STUN) { + NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found TCP stun.\n"); + ndpi_int_stun_add_connection(ndpi_struct, flow); + return; + } + } + } + if (ndpi_int_check_stun(ndpi_struct, packet->payload, packet->payload_packet_len) == NDPI_IS_STUN) { + NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found UDP stun.\n"); + ndpi_int_stun_add_connection(ndpi_struct, flow); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "exclude stun.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_STUN); +} + +#endif diff --git a/src/lib/protocols/syslog.c b/src/lib/protocols/syslog.c new file mode 100644 index 000000000..b4732bfca --- /dev/null +++ b/src/lib/protocols/syslog.c @@ -0,0 +1,130 @@ +/* + * syslog.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_SYSLOG + +static void ndpi_int_syslog_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SYSLOG, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_syslog(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + u_int8_t i; + + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "search syslog\n"); + + if (packet->payload_packet_len > 20 && packet->payload_packet_len <= 1024 && packet->payload[0] == '<') { + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "checked len>20 and <1024 and first symbol=<.\n"); + i = 1; + + for (;;) { + if (packet->payload[i] < '0' || packet->payload[i] > '9' || i++ > 3) { + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, + "read symbols while the symbol is a number.\n"); + break; + } + } + + if (packet->payload[i++] != '>') { + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "there is no > following the number.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SYSLOG); + return; + } else { + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "a > following the number.\n"); + } + + if (packet->payload[i] == 0x20) { + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "a blank following the >: increment i.\n"); + i++; + } else { + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "no blank following the >: do nothing.\n"); + } + + /* check for "last message repeated" */ + if (i + sizeof("last message") - 1 <= packet->payload_packet_len && + memcmp(packet->payload + i, "last message", sizeof("last message") - 1) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "found syslog by 'last message' string.\n"); + + ndpi_int_syslog_add_connection(ndpi_struct, flow); + + return; + } else if (i + sizeof("snort: ") - 1 <= packet->payload_packet_len && + memcmp(packet->payload + i, "snort: ", sizeof("snort: ") - 1) == 0) { + + /* snort events */ + + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "found syslog by 'snort: ' string.\n"); + + ndpi_int_syslog_add_connection(ndpi_struct, flow); + + return; + } + + if (memcmp(&packet->payload[i], "Jan", 3) != 0 + && memcmp(&packet->payload[i], "Feb", 3) != 0 + && memcmp(&packet->payload[i], "Mar", 3) != 0 + && memcmp(&packet->payload[i], "Apr", 3) != 0 + && memcmp(&packet->payload[i], "May", 3) != 0 + && memcmp(&packet->payload[i], "Jun", 3) != 0 + && memcmp(&packet->payload[i], "Jul", 3) != 0 + && memcmp(&packet->payload[i], "Aug", 3) != 0 + && memcmp(&packet->payload[i], "Sep", 3) != 0 + && memcmp(&packet->payload[i], "Oct", 3) != 0 + && memcmp(&packet->payload[i], "Nov", 3) != 0 && memcmp(&packet->payload[i], "Dec", 3) != 0) { + + + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, + "no month-shortname following: syslog excluded.\n"); + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SYSLOG); + + return; + + } else { + + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, + "a month-shortname following: syslog detected.\n"); + + ndpi_int_syslog_add_connection(ndpi_struct, flow); + + return; + } + } + NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "no syslog detected.\n"); + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SYSLOG); +} + +#endif diff --git a/src/lib/protocols/tcp_udp.c b/src/lib/protocols/tcp_udp.c new file mode 100644 index 000000000..da33e6e0e --- /dev/null +++ b/src/lib/protocols/tcp_udp.c @@ -0,0 +1,78 @@ +/* + * tcp_or_udp.c + * + * Copyright (C) 2011-15 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +/* ndpi_main.c */ +extern u_int8_t ndpi_is_tor_flow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); + +u_int ndpi_search_tcp_or_udp_raw(struct ndpi_detection_module_struct *ndpi_struct, + u_int8_t protocol, + u_int32_t saddr, u_int32_t daddr, /* host endianess */ + u_int16_t sport, u_int16_t dport) /* host endianess */ +{ + u_int16_t rc; + + if(protocol == IPPROTO_UDP) { + if((sport == dport) && (sport == 17500)) { + return(NDPI_PROTOCOL_DROPBOX); + } + } + + if((rc = ndpi_host_ptree_match(ndpi_struct, saddr)) != NDPI_PROTOCOL_UNKNOWN) return(rc); + + return(ndpi_host_ptree_match(ndpi_struct, daddr)); +} + +void ndpi_search_tcp_or_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + u_int16_t sport, dport; + u_int proto; + struct ndpi_packet_struct *packet = &flow->packet; + + if(ndpi_is_tor_flow(ndpi_struct, flow)) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TOR, NDPI_REAL_PROTOCOL); + return; + } + + if(packet->udp) sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); + else if(packet->tcp) sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); + else sport = dport = 0; + + if(packet->iph /* IPv4 Only: we need to support packet->iphv6 at some point */) { + proto = ndpi_search_tcp_or_udp_raw(ndpi_struct, + flow->packet.iph ? flow->packet.iph->protocol : +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + flow->packet.iphv6->nexthdr, +#else + 0, +#endif + ntohl(packet->iph->saddr), + ntohl(packet->iph->daddr), + sport, dport); + + if(proto != NDPI_PROTOCOL_UNKNOWN) + ndpi_int_add_connection(ndpi_struct, flow, proto, NDPI_REAL_PROTOCOL); + } +} + + + diff --git a/src/lib/protocols/tds.c b/src/lib/protocols/tds.c new file mode 100644 index 000000000..af97316cd --- /dev/null +++ b/src/lib/protocols/tds.c @@ -0,0 +1,91 @@ +/* + * tds.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_TDS + +static void ndpi_int_tds_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TDS, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_tds_tcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len > 8 + && packet->payload_packet_len < 512 + && packet->payload[1] < 0x02 + && ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len && get_u_int16_t(packet->payload, 4) == 0x0000) { + + if (flow->l4.tcp.tds_stage == 0) { + if (packet->payload[0] != 0x02 && packet->payload[0] != 0x07 && packet->payload[0] != 0x12) { + goto exclude_tds; + } else { + flow->l4.tcp.tds_stage = 1 + packet->packet_direction; + flow->l4.tcp.tds_login_version = packet->payload[0]; + return; + } + } else if (flow->l4.tcp.tds_stage == 2 - packet->packet_direction) { + switch (flow->l4.tcp.tds_login_version) { + case 0x12: + if (packet->payload[0] == 0x04) { + flow->l4.tcp.tds_stage = 3 + packet->packet_direction; + return; + } else { + goto exclude_tds; + } + //TODO: add more cases for other versions + default: + goto exclude_tds; + } + } else if (flow->l4.tcp.tds_stage == 4 - packet->packet_direction) { + switch (flow->l4.tcp.tds_login_version) { + case 0x12: + if (packet->payload[0] == 0x12) { + NDPI_LOG(NDPI_PROTOCOL_TDS, ndpi_struct, NDPI_LOG_DEBUG, "TDS detected\n"); + ndpi_int_tds_add_connection(ndpi_struct, flow); + return; + } else { + goto exclude_tds; + } + //TODO: add more cases for other versions + default: + goto exclude_tds; + } + } + } + + exclude_tds: + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TDS); +} + +#endif diff --git a/src/lib/protocols/teamspeak.c b/src/lib/protocols/teamspeak.c new file mode 100644 index 000000000..89ec12040 --- /dev/null +++ b/src/lib/protocols/teamspeak.c @@ -0,0 +1,65 @@ +/* + * viber.c + * + * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * + * This module is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This module is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License. + * If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ndpi_api.h" + + +#ifdef NDPI_PROTOCOL_TEAMSPEAK + +static void ndpi_int_teamspeak_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TEAMSPEAK, NDPI_REAL_PROTOCOL); +} + u_int16_t tdport = 0, tsport = 0; + u_int16_t udport = 0, usport = 0; + + +void ndpi_search_teamspeak(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +if (packet->udp != NULL) { + usport = ntohs(packet->udp->source), udport = ntohs(packet->udp->dest); + /* http://www.imfirewall.com/en/protocols/teamSpeak.htm */ + if (((usport == 9987 || udport == 9987) || (usport == 8767 || udport == 8767)) && packet->payload_packet_len >= 20) { + NDPI_LOG(NDPI_PROTOCOL_TEAMSPEAK, ndpi_struct, NDPI_LOG_DEBUG, "found TEAMSPEAK udp.\n"); + ndpi_int_teamspeak_add_connection(ndpi_struct, flow); + } +} +else if (packet->tcp != NULL) { + tsport = ntohs(packet->tcp->source), tdport = ntohs(packet->tcp->dest); + /* https://github.com/Youx/soliloque-server/wiki/Connection-packet */ + if(packet->payload_packet_len >= 20) { + if (((memcmp(packet->payload, "\xf4\xbe\x03\x00", 4) == 0)) || + ((memcmp(packet->payload, "\xf4\xbe\x02\x00", 4) == 0)) || + ((memcmp(packet->payload, "\xf4\xbe\x01\x00", 4) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_TEAMSPEAK, ndpi_struct, NDPI_LOG_DEBUG, "found TEAMSPEAK tcp.\n"); + ndpi_int_teamspeak_add_connection(ndpi_struct, flow); + } /* http://www.imfirewall.com/en/protocols/teamSpeak.htm */ + } else if ((tsport == 14534 || tdport == 14534) || (tsport == 51234 || tdport == 51234)) { + NDPI_LOG(NDPI_PROTOCOL_TEAMSPEAK, ndpi_struct, NDPI_LOG_DEBUG, "found TEAMSPEAK.\n"); + ndpi_int_teamspeak_add_connection(ndpi_struct, flow); + } + } + NDPI_LOG(NDPI_PROTOCOL_TEAMSPEAK, ndpi_struct, NDPI_LOG_DEBUG, "TEAMSPEAK excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TEAMSPEAK); + return; +} +#endif diff --git a/src/lib/protocols/teamviewer.c b/src/lib/protocols/teamviewer.c new file mode 100644 index 000000000..0fe0810c9 --- /dev/null +++ b/src/lib/protocols/teamviewer.c @@ -0,0 +1,100 @@ +/* + * teamviewer.c + * + * Copyright (C) 2012 by Gianluca Costa xplico.org + * Copyright (C) 2012-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_TEAMVIEWER + +static void ndpi_int_teamview_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TEAMVIEWER, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_TEAMVIEWER, ndpi_struct, NDPI_LOG_TRACE, "TEAMWIEWER Found.\n"); +} + + +void ndpi_search_teamview(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + NDPI_LOG(NDPI_PROTOCOL_TEAMVIEWER, ndpi_struct, NDPI_LOG_TRACE, "TEAMWIEWER detection...\n"); + /* + TeamViewer + 178.77.120.0/25 + + http://myip.ms/view/ip_owners/144885/Teamviewer_Gmbh.html + */ + if(flow->packet.iph) { + u_int32_t src = ntohl(flow->packet.iph->saddr); + u_int32_t dst = ntohl(flow->packet.iph->daddr); + + /* 95.211.37.195 - 95.211.37.203 */ + if(((src >= 1607673283) && (src <= 1607673291)) + || ((dst >= 1607673283) && (dst <= 1607673291)) + || ((src & 0xFFFFFF80 /* 255.255.255.128 */) == 0xB24D7800 /* 178.77.120.0 */) + || ((dst & 0xFFFFFF80 /* 255.255.255.128 */) == 0xB24D7800 /* 178.77.120.0 */) + ) { + ndpi_int_teamview_add_connection(ndpi_struct, flow); + return; + } + } + + if(packet->payload_packet_len == 0) return; + + if (packet->udp != NULL) { + if (packet->payload_packet_len > 13) { + if (packet->payload[0] == 0x00 && packet->payload[11] == 0x17 && packet->payload[12] == 0x24) { /* byte 0 is a counter/seq number, and at the start is 0 */ + flow->l4.udp.teamviewer_stage++; + if (flow->l4.udp.teamviewer_stage == 4 || + packet->udp->dest == ntohs(5938) || packet->udp->source == ntohs(5938)) { + ndpi_int_teamview_add_connection(ndpi_struct, flow); + } + return; + } + } + } + else if(packet->tcp != NULL) { + if (packet->payload_packet_len > 2) { + if (packet->payload[0] == 0x17 && packet->payload[1] == 0x24) { + flow->l4.udp.teamviewer_stage++; + if (flow->l4.udp.teamviewer_stage == 4 || + packet->tcp->dest == ntohs(5938) || packet->tcp->source == ntohs(5938)) { + ndpi_int_teamview_add_connection(ndpi_struct, flow); + } + return; + } + else if (flow->l4.udp.teamviewer_stage) { + if (packet->payload[0] == 0x11 && packet->payload[1] == 0x30) { + flow->l4.udp.teamviewer_stage++; + if (flow->l4.udp.teamviewer_stage == 4) + ndpi_int_teamview_add_connection(ndpi_struct, flow); + } + return; + } + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TEAMVIEWER); +} +#endif diff --git a/src/lib/protocols/telegram.c b/src/lib/protocols/telegram.c new file mode 100644 index 000000000..ba9397a92 --- /dev/null +++ b/src/lib/protocols/telegram.c @@ -0,0 +1,68 @@ +/* + * telegram.c + * + * Copyright (C) 2014 by Gianluca Costa xplico.org + * Copyright (C) 2012-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_TELEGRAM + +static void ndpi_int_telegram_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TELEGRAM, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_TELEGRAM, ndpi_struct, NDPI_LOG_TRACE, "TELEGRAM Found.\n"); +} + + +void ndpi_search_telegram(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t dport /* , sport */; + + NDPI_LOG(NDPI_PROTOCOL_TELEGRAM, ndpi_struct, NDPI_LOG_TRACE, "TELEGRAM detection...\n"); + + if (packet->payload_packet_len == 0) + return; + if (packet->tcp != NULL) { + if (packet->payload_packet_len > 56) { + dport = ntohs(packet->tcp->dest); + /* sport = ntohs(packet->tcp->source); */ + + if (packet->payload[0] == 0xef && ( + dport == 443 || dport == 80 || dport == 25 + )) { + if (packet->payload[1] == 0x7f) { + ndpi_int_telegram_add_connection(ndpi_struct, flow); + } + else if (packet->payload[1]*4 <= packet->payload_packet_len - 1) { + ndpi_int_telegram_add_connection(ndpi_struct, flow); + } + return; + } + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TELEGRAM); +} +#endif diff --git a/src/lib/protocols/telnet.c b/src/lib/protocols/telnet.c new file mode 100644 index 000000000..0954be111 --- /dev/null +++ b/src/lib/protocols/telnet.c @@ -0,0 +1,107 @@ +/* + * telnet.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_TELNET + + + +static void ndpi_int_telnet_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TELNET, NDPI_REAL_PROTOCOL); +} + + +#if !defined(WIN32) + static inline +#else +__forceinline static +#endif + u_int8_t search_iac(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + u_int16_t a; + + if (packet->payload_packet_len < 3) { + return 0; + } + + if (!(packet->payload[0] == 0xff + && packet->payload[1] > 0xf9 && packet->payload[1] != 0xff && packet->payload[2] < 0x28)) { + return 0; + } + + a = 3; + + while (a < packet->payload_packet_len - 2) { + // commands start with a 0xff byte followed by a command byte >= 0xf0 and < 0xff + // command bytes 0xfb to 0xfe are followed by an option byte <= 0x28 + if (!(packet->payload[a] != 0xff || + (packet->payload[a] == 0xff && (packet->payload[a + 1] >= 0xf0) && (packet->payload[a + 1] <= 0xfa)) || + (packet->payload[a] == 0xff && (packet->payload[a + 1] >= 0xfb) && (packet->payload[a + 1] != 0xff) + && (packet->payload[a + 2] <= 0x28)))) { + return 0; + } + a++; + } + + return 1; +} + +/* this detection also works asymmetrically */ +void ndpi_search_telnet_tcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ +// struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_TELNET, ndpi_struct, NDPI_LOG_DEBUG, "search telnet.\n"); + + if (search_iac(ndpi_struct, flow) == 1) { + + if (flow->l4.tcp.telnet_stage == 2) { + NDPI_LOG(NDPI_PROTOCOL_TELNET, ndpi_struct, NDPI_LOG_DEBUG, "telnet identified.\n"); + ndpi_int_telnet_add_connection(ndpi_struct, flow); + return; + } + flow->l4.tcp.telnet_stage++; + NDPI_LOG(NDPI_PROTOCOL_TELNET, ndpi_struct, NDPI_LOG_DEBUG, "telnet stage %u.\n", flow->l4.tcp.telnet_stage); + return; + } + + if ((flow->packet_counter < 12 && flow->l4.tcp.telnet_stage > 0) || flow->packet_counter < 6) { + return; + } else { + NDPI_LOG(NDPI_PROTOCOL_TELNET, ndpi_struct, NDPI_LOG_DEBUG, "telnet excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TELNET); + } + return; +} + +#endif diff --git a/src/lib/protocols/tftp.c b/src/lib/protocols/tftp.c new file mode 100644 index 000000000..d5145445b --- /dev/null +++ b/src/lib/protocols/tftp.c @@ -0,0 +1,70 @@ +/* + * tftp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_TFTP + +static void ndpi_int_tftp_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TFTP, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_tftp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + + + NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "search TFTP.\n"); + + + + if (packet->payload_packet_len > 3 && flow->l4.udp.tftp_stage == 0 + && ntohl(get_u_int32_t(packet->payload, 0)) == 0x00030001) { + NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "maybe tftp. need next packet.\n"); + flow->l4.udp.tftp_stage = 1; + return; + } + if (packet->payload_packet_len > 3 && (flow->l4.udp.tftp_stage == 1) + && ntohl(get_u_int32_t(packet->payload, 0)) == 0x00040001) { + + NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "found tftp.\n"); + ndpi_int_tftp_add_connection(ndpi_struct, flow); + return; + } + if (packet->payload_packet_len > 1 + && ((packet->payload[0] == 0 && packet->payload[packet->payload_packet_len - 1] == 0) + || (packet->payload_packet_len == 4 && ntohl(get_u_int32_t(packet->payload, 0)) == 0x00040000))) { + NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "skip initial packet.\n"); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude TFTP.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TFTP); +} +#endif diff --git a/src/lib/protocols/thunder.c b/src/lib/protocols/thunder.c new file mode 100644 index 000000000..3784bb781 --- /dev/null +++ b/src/lib/protocols/thunder.c @@ -0,0 +1,211 @@ +/* + * thunder.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_THUNDER + +static void ndpi_int_thunder_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type) +{ + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_THUNDER, protocol_type); + + if (src != NULL) { + src->thunder_ts = packet->tick_timestamp; + } + if (dst != NULL) { + dst->thunder_ts = packet->tick_timestamp; + } +} + + + +#if !defined(WIN32) + static inline +#else +__forceinline static +#endif + void ndpi_int_search_thunder_udp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len > 8 && packet->payload[0] >= 0x30 + && packet->payload[0] < 0x40 && packet->payload[1] == 0 && packet->payload[2] == 0 && packet->payload[3] == 0) { + if (flow->thunder_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, "THUNDER udp detected\n"); + ndpi_int_thunder_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + flow->thunder_stage++; + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, + "maybe thunder udp packet detected, stage increased to %u\n", flow->thunder_stage); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, + "excluding thunder udp at stage %u\n", flow->thunder_stage); + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_THUNDER); +} + + +#if !defined(WIN32) + static inline +#else +__forceinline static +#endif + void ndpi_int_search_thunder_tcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->payload_packet_len > 8 && packet->payload[0] >= 0x30 + && packet->payload[0] < 0x40 && packet->payload[1] == 0 && packet->payload[2] == 0 && packet->payload[3] == 0) { + if (flow->thunder_stage == 3) { + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, "THUNDER tcp detected\n"); + ndpi_int_thunder_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + flow->thunder_stage++; + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, + "maybe thunder tcp packet detected, stage increased to %u\n", flow->thunder_stage); + return; + } + + if (flow->thunder_stage == 0 && packet->payload_packet_len > 17 + && memcmp(packet->payload, "POST / HTTP/1.1\r\n", 17) == 0) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, + "maybe thunder http POST packet detected, parsed packet lines: %u, empty line set %u (at: %u)\n", + packet->parsed_lines, packet->empty_line_position_set, packet->empty_line_position); + + if (packet->empty_line_position_set != 0 && + packet->content_line.ptr != NULL && + packet->content_line.len == 24 && + memcmp(packet->content_line.ptr, "application/octet-stream", + 24) == 0 && packet->empty_line_position_set < (packet->payload_packet_len - 8) + && packet->payload[packet->empty_line_position + 2] >= 0x30 + && packet->payload[packet->empty_line_position + 2] < 0x40 + && packet->payload[packet->empty_line_position + 3] == 0x00 + && packet->payload[packet->empty_line_position + 4] == 0x00 + && packet->payload[packet->empty_line_position + 5] == 0x00) { + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, + "maybe thunder http POST packet application does match\n"); + ndpi_int_thunder_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, + "excluding thunder tcp at stage %u\n", flow->thunder_stage); + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_THUNDER); +} + + +#if !defined(WIN32) + static inline +#else +__forceinline static +#endif + void ndpi_int_search_thunder_http(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_THUNDER) { + if (src != NULL && ((u_int32_t) + (packet->tick_timestamp - src->thunder_ts) < ndpi_struct->thunder_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, + "thunder : save src connection packet detected\n"); + src->thunder_ts = packet->tick_timestamp; + } else if (dst != NULL && ((u_int32_t) + (packet->tick_timestamp - dst->thunder_ts) < ndpi_struct->thunder_timeout)) { + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, + "thunder : save dst connection packet detected\n"); + dst->thunder_ts = packet->tick_timestamp; + } + return; + } + + if (packet->payload_packet_len > 5 + && memcmp(packet->payload, "GET /", 5) == 0 && NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_THUNDER)) { + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, "HTTP packet detected.\n"); + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if (packet->parsed_lines > 7 + && packet->parsed_lines < 11 + && packet->line[1].len > 10 + && memcmp(packet->line[1].ptr, "Accept: */*", 11) == 0 + && packet->line[2].len > 22 + && memcmp(packet->line[2].ptr, "Cache-Control: no-cache", + 23) == 0 && packet->line[3].len > 16 + && memcmp(packet->line[3].ptr, "Connection: close", 17) == 0 + && packet->line[4].len > 6 + && memcmp(packet->line[4].ptr, "Host: ", 6) == 0 + && packet->line[5].len > 15 + && memcmp(packet->line[5].ptr, "Pragma: no-cache", 16) == 0 + && packet->user_agent_line.ptr != NULL + && packet->user_agent_line.len > 49 + && memcmp(packet->user_agent_line.ptr, + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)", 50) == 0) { + NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, + "Thunder HTTP download detected, adding flow.\n"); + ndpi_int_thunder_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + } + } +} + +void ndpi_search_thunder(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + // + //struct ndpi_id_struct *src = flow->src; + //struct ndpi_id_struct *dst = flow->dst; + + if (packet->tcp != NULL) { + ndpi_int_search_thunder_http(ndpi_struct, flow); + ndpi_int_search_thunder_tcp(ndpi_struct, flow); + } else if (packet->udp != NULL) { + ndpi_int_search_thunder_udp(ndpi_struct, flow); + } +} + +#endif diff --git a/src/lib/protocols/tor.c b/src/lib/protocols/tor.c new file mode 100644 index 000000000..ead857726 --- /dev/null +++ b/src/lib/protocols/tor.c @@ -0,0 +1,109 @@ +/* + * tor.c + * + * Copyright (C) 2015 ntop.org + * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * + */ + + +#include "ndpi_api.h" + + +#ifdef NDPI_PROTOCOL_TOR + +static void ndpi_int_tor_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TOR, NDPI_CORRELATED_PROTOCOL); +} + + +int ndpi_is_ssl_tor(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, char *certificate) { + int prev_num = 0, numbers_found = 0, num_found = 0, i; + char dummy[48], *dot, *name; + + if((certificate == NULL) + || (strlen(certificate) < 6) + || strncmp(certificate, "www.", 4)) + return(0); + + // printf("***** [SSL] %s(): %s\n", __FUNCTION__, certificate); + + snprintf(dummy, sizeof(dummy), "%s", certificate); + + if((dot = strrchr(dummy, '.')) == NULL) return(0); + dot[0] = '\0'; + + if((dot = strrchr(dummy, '.')) == NULL) return(0); + name = &dot[1]; + + for(i = 0; name[i+1] != '\0'; i++) { + if((name[i] >= '0') && (name[i] <= '9')) { + + if(prev_num != 1) { + numbers_found++; + + if(numbers_found == 2) { + ndpi_int_tor_add_connection(ndpi_struct, flow); + return(1); + } + prev_num = 1; + } + } else + prev_num = 0; + + if(ndpi_match_bigram(ndpi_struct, &ndpi_struct->impossible_bigrams_automa, &name[i])) { + ndpi_int_tor_add_connection(ndpi_struct, flow); + return(1); + } + + if(ndpi_match_bigram(ndpi_struct, &ndpi_struct->bigrams_automa, &name[i])) { + num_found++; + } + } + + if(num_found == 0) { + ndpi_int_tor_add_connection(ndpi_struct, flow); + return(1); + } else { +#ifndef __KERNEL__ +#ifdef PENDANTIC_TOR_CHECK + if(gethostbyname(certificate) == NULL) { + ndpi_int_tor_add_connection(ndpi_struct, flow); + return(1); + } +#endif +#endif + } + + return(0); +} + +/* ******************************************* */ + +void ndpi_search_tor(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t dport = 0, sport = 0; + + NDPI_LOG(NDPI_PROTOCOL_TOR, ndpi_struct, NDPI_LOG_DEBUG, "search for TOR.\n"); + + if(packet->tcp != NULL) { + sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); + NDPI_LOG(NDPI_PROTOCOL_TOR, ndpi_struct, NDPI_LOG_DEBUG, "calculating TOR over tcp.\n"); + + if ((((dport == 9001) || (sport == 9001)) || ((dport == 9030) || (sport == 9030))) + && ((packet->payload[0] == 0x17) || (packet->payload[0] == 0x16)) + && (packet->payload[1] == 0x03) + && (packet->payload[2] == 0x01) + && (packet->payload[3] == 0x00)) { + NDPI_LOG(NDPI_PROTOCOL_TOR, ndpi_struct, NDPI_LOG_DEBUG, "found tor.\n"); + ndpi_int_tor_add_connection(ndpi_struct, flow); + } + } else { + NDPI_LOG(NDPI_PROTOCOL_TOR, ndpi_struct, NDPI_LOG_DEBUG, "exclude TOR.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TOR); + } +} +#endif diff --git a/src/lib/protocols/tvants.c b/src/lib/protocols/tvants.c new file mode 100644 index 000000000..5021fadcd --- /dev/null +++ b/src/lib/protocols/tvants.c @@ -0,0 +1,78 @@ +/* + * tvants.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_TVANTS + +static void ndpi_int_tvants_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TVANTS, NDPI_REAL_PROTOCOL); +} + + + + +void ndpi_search_tvants_udp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + + NDPI_LOG(NDPI_PROTOCOL_TVANTS, ndpi_struct, NDPI_LOG_DEBUG, "search tvants. \n"); + + if (packet->udp != NULL && packet->payload_packet_len > 57 + && packet->payload[0] == 0x04 && packet->payload[1] == 0x00 + && (packet->payload[2] == 0x05 || packet->payload[2] == 0x06 + || packet->payload[2] == 0x07) && packet->payload[3] == 0x00 + && packet->payload_packet_len == (packet->payload[5] << 8) + packet->payload[4] + && packet->payload[6] == 0x00 && packet->payload[7] == 0x00 + && (memcmp(&packet->payload[48], "TVANTS", 6) == 0 + || memcmp(&packet->payload[49], "TVANTS", 6) == 0 || memcmp(&packet->payload[51], "TVANTS", 6) == 0)) { + + NDPI_LOG(NDPI_PROTOCOL_TVANTS, ndpi_struct, NDPI_LOG_DEBUG, "found tvants over udp. \n"); + ndpi_int_tvants_add_connection(ndpi_struct, flow); + + } else if (packet->tcp != NULL && packet->payload_packet_len > 15 + && packet->payload[0] == 0x04 && packet->payload[1] == 0x00 + && packet->payload[2] == 0x07 && packet->payload[3] == 0x00 + && packet->payload_packet_len == (packet->payload[5] << 8) + packet->payload[4] + && packet->payload[6] == 0x00 && packet->payload[7] == 0x00 + && memcmp(&packet->payload[8], "TVANTS", 6) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_TVANTS, ndpi_struct, NDPI_LOG_DEBUG, "found tvants over tcp. \n"); + ndpi_int_tvants_add_connection(ndpi_struct, flow); + + } + NDPI_LOG(NDPI_PROTOCOL_TVANTS, ndpi_struct, NDPI_LOG_DEBUG, "exclude tvants. \n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TVANTS); + +} +#endif diff --git a/src/lib/protocols/tvuplayer.c b/src/lib/protocols/tvuplayer.c new file mode 100644 index 000000000..a81ea96b3 --- /dev/null +++ b/src/lib/protocols/tvuplayer.c @@ -0,0 +1,153 @@ +/* + * tvuplayer.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_TVUPLAYER + + +static void ndpi_int_tvuplayer_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TVUPLAYER, protocol_type); +} + +void ndpi_search_tvuplayer(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "search tvuplayer. \n"); + + + + if (packet->tcp != NULL) { + if ((packet->payload_packet_len == 36 || packet->payload_packet_len == 24) + && packet->payload[0] == 0x00 + && ntohl(get_u_int32_t(packet->payload, 2)) == 0x31323334 + && ntohl(get_u_int32_t(packet->payload, 6)) == 0x35363837 && packet->payload[10] == 0x01) { + NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer over tcp. \n"); + ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + + if (packet->payload_packet_len >= 50) { + + if (memcmp(packet->payload, "POST", 4) || memcmp(packet->payload, "GET", 3)) { + NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet); + if (packet->user_agent_line.ptr != NULL && + packet->user_agent_line.len >= 8 && (memcmp(packet->user_agent_line.ptr, "MacTVUP", 7) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "Found user agent as MacTVUP.\n"); + ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + } + + if (packet->udp != NULL) { + + if (packet->payload_packet_len == 56 && + packet->payload[0] == 0xff + && packet->payload[1] == 0xff && packet->payload[2] == 0x00 + && packet->payload[3] == 0x01 + && packet->payload[12] == 0x02 && packet->payload[13] == 0xff + && packet->payload[19] == 0x2c && ((packet->payload[26] == 0x05 && packet->payload[27] == 0x14) + || (packet->payload[26] == 0x14 && packet->payload[27] == 0x05))) { + NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type I. \n"); + ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 82 + && packet->payload[0] == 0x00 && packet->payload[2] == 0x00 + && packet->payload[10] == 0x00 && packet->payload[11] == 0x00 + && packet->payload[12] == 0x01 && packet->payload[13] == 0xff + && packet->payload[19] == 0x14 && packet->payload[32] == 0x03 + && packet->payload[33] == 0xff && packet->payload[34] == 0x01 + && packet->payload[39] == 0x32 && ((packet->payload[46] == 0x05 && packet->payload[47] == 0x14) + || (packet->payload[46] == 0x14 && packet->payload[47] == 0x05))) { + NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type II. \n"); + ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 32 + && packet->payload[0] == 0x00 && packet->payload[2] == 0x00 + && (packet->payload[10] == 0x00 || packet->payload[10] == 0x65 + || packet->payload[10] == 0x7e || packet->payload[10] == 0x49) + && (packet->payload[11] == 0x00 || packet->payload[11] == 0x57 + || packet->payload[11] == 0x06 || packet->payload[11] == 0x22) + && packet->payload[12] == 0x01 && (packet->payload[13] == 0xff || packet->payload[13] == 0x01) + && packet->payload[19] == 0x14) { + NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type III. \n"); + ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 84 + && packet->payload[0] == 0x00 && packet->payload[2] == 0x00 + && packet->payload[10] == 0x00 && packet->payload[11] == 0x00 + && packet->payload[12] == 0x01 && packet->payload[13] == 0xff + && packet->payload[19] == 0x14 && packet->payload[32] == 0x03 + && packet->payload[33] == 0xff && packet->payload[34] == 0x01 && packet->payload[39] == 0x34) { + NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type IV. \n"); + ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 102 + && packet->payload[0] == 0x00 && packet->payload[2] == 0x00 + && packet->payload[10] == 0x00 && packet->payload[11] == 0x00 + && packet->payload[12] == 0x01 && packet->payload[13] == 0xff + && packet->payload[19] == 0x14 && packet->payload[33] == 0xff && packet->payload[39] == 0x14) { + NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type V. \n"); + ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (packet->payload_packet_len == 62 && packet->payload[0] == 0x00 && packet->payload[2] == 0x00 + //&& packet->payload[10] == 0x00 && packet->payload[11] == 0x00 + && packet->payload[12] == 0x03 && packet->payload[13] == 0xff + && packet->payload[19] == 0x32 && ((packet->payload[26] == 0x05 && packet->payload[27] == 0x14) + || (packet->payload[26] == 0x14 && packet->payload[27] == 0x05))) { + NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type VI. \n"); + ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + // to check, if byte 26, 27, 33,39 match + if (packet->payload_packet_len == 60 + && packet->payload[0] == 0x00 && packet->payload[2] == 0x00 + && packet->payload[10] == 0x00 && packet->payload[11] == 0x00 + && packet->payload[12] == 0x06 && packet->payload[13] == 0x00 && packet->payload[19] == 0x30) { + NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "found tvuplayer pattern type VII. \n"); + ndpi_int_tvuplayer_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + + NDPI_LOG(NDPI_PROTOCOL_TVUPLAYER, ndpi_struct, NDPI_LOG_DEBUG, "exclude tvuplayer. \n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TVUPLAYER); + +} +#endif diff --git a/src/lib/protocols/twitter.c b/src/lib/protocols/twitter.c new file mode 100644 index 000000000..db2f77a5e --- /dev/null +++ b/src/lib/protocols/twitter.c @@ -0,0 +1,63 @@ +/* + * twitter.c + * + * Copyright (C) 2014 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_SERVICE_TWITTER + +static void ndpi_int_twitter_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_SERVICE_TWITTER, NDPI_REAL_PROTOCOL); +} + + +void ndpi_search_twitter(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + /* + Twitter AS34702 + + http://bgp.he.net/AS13414 + */ + if(flow->packet.iph) { + // IPv4 + u_int32_t src = ntohl(flow->packet.iph->saddr); + u_int32_t dst = ntohl(flow->packet.iph->daddr); + + if(ndpi_ips_match(src, dst, 0xC0854C00, 22) /* 192.133.76.0/22 */ + || ndpi_ips_match(src, dst, 0xC7109C00, 22) /* 199.16.156.0/22 */ + || ndpi_ips_match(src, dst, 0xC73B9400, 22) /* 199.59.148.0/22 */ + || ndpi_ips_match(src, dst, 0xC7603A00, 23) /* 199.96.58.0/23 */ + || ndpi_ips_match(src, dst, 0xC7603E00, 23) /* 199.96.62.0/23 */ + ) { + ndpi_int_twitter_add_connection(ndpi_struct, flow); + return; + } + + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_SERVICE_TWITTER); +} +#endif diff --git a/src/lib/protocols/usenet.c b/src/lib/protocols/usenet.c new file mode 100644 index 000000000..07ed91678 --- /dev/null +++ b/src/lib/protocols/usenet.c @@ -0,0 +1,105 @@ +/* + * usenet.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_USENET + + +static void ndpi_int_usenet_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_USENET, NDPI_REAL_PROTOCOL); +} + + + +void ndpi_search_usenet_tcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: search usenet.\n"); + + + + + + NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: STAGE IS %u.\n", flow->l4.tcp.usenet_stage); + + + // check for the first server replay + /* + 200 Service available, posting allowed + 201 Service available, posting prohibited + */ + if (flow->l4.tcp.usenet_stage == 0 && packet->payload_packet_len > 10 + && ((memcmp(packet->payload, "200 ", 4) == 0) + || (memcmp(packet->payload, "201 ", 4) == 0))) { + + NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: found 200 or 201.\n"); + flow->l4.tcp.usenet_stage = 1 + packet->packet_direction; + + NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: maybe hit.\n"); + return; + } + + /* + [C] AUTHINFO USER fred + [S] 381 Enter passphrase + [C] AUTHINFO PASS flintstone + [S] 281 Authentication accepted + */ + // check for client username + if (flow->l4.tcp.usenet_stage == 2 - packet->packet_direction) { + if (packet->payload_packet_len > 20 && (memcmp(packet->payload, "AUTHINFO USER ", 14) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: username found\n"); + flow->l4.tcp.usenet_stage = 3 + packet->packet_direction; + + NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: found usenet.\n"); + ndpi_int_usenet_add_connection(ndpi_struct, flow); + return; + } else if (packet->payload_packet_len == 13 && (memcmp(packet->payload, "MODE READER\r\n", 13) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, + "USENET: no login necessary but we are a client.\n"); + + NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: found usenet.\n"); + ndpi_int_usenet_add_connection(ndpi_struct, flow); + return; + } + } + + + + NDPI_LOG(NDPI_PROTOCOL_USENET, ndpi_struct, NDPI_LOG_DEBUG, "USENET: exclude usenet.\n"); + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_USENET); + +} + +#endif diff --git a/src/lib/protocols/veohtv.c b/src/lib/protocols/veohtv.c new file mode 100644 index 000000000..10f84c3fd --- /dev/null +++ b/src/lib/protocols/veohtv.c @@ -0,0 +1,116 @@ +/* + * veohtv.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + + +#ifdef NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV + +static void ndpi_int_veohtv_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, protocol_type); +} + +void ndpi_search_veohtv_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV) + return; + + if (flow->l4.tcp.veoh_tv_stage == 1 || flow->l4.tcp.veoh_tv_stage == 2) { + if (packet->packet_direction != flow->setup_packet_direction && + packet->payload_packet_len > NDPI_STATICSTRING_LEN("HTTP/1.1 20") + && memcmp(packet->payload, "HTTP/1.1 ", NDPI_STATICSTRING_LEN("HTTP/1.1 ")) == 0 && + (packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '2' || + packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '3' || + packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '4' || + packet->payload[NDPI_STATICSTRING_LEN("HTTP/1.1 ")] == '5')) { +#ifdef NDPI_CONTENT_FLASH + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->detected_protocol_stack[0] == NDPI_CONTENT_FLASH && + packet->server_line.ptr != NULL && + packet->server_line.len > NDPI_STATICSTRING_LEN("Veoh-") && + memcmp(packet->server_line.ptr, "Veoh-", NDPI_STATICSTRING_LEN("Veoh-")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n"); + ndpi_int_veohtv_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } +#endif + if (flow->l4.tcp.veoh_tv_stage == 2) { + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, + NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV); + return; + } + NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n"); + ndpi_int_veohtv_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } else if (flow->packet_direction_counter[(flow->setup_packet_direction == 1) ? 0 : 1] > 3) { + if (flow->l4.tcp.veoh_tv_stage == 2) { + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, + NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV); + return; + } + NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n"); + ndpi_int_veohtv_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } else { + if (flow->packet_counter > 10) { + if (flow->l4.tcp.veoh_tv_stage == 2) { + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, + NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV); + return; + } + NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "VeohTV detected.\n"); + ndpi_int_veohtv_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + return; + } + } else if (packet->udp) { + /* UDP packets from Veoh Client Player + * + * packet starts with 16 byte random? value + * then a 4 byte mode value + * values between 21 and 26 has been seen + * then a 4 byte counter */ + + if (packet->payload_packet_len == 28 && + get_u_int32_t(packet->payload, 16) == htonl(0x00000021) && + get_u_int32_t(packet->payload, 20) == htonl(0x00000000) && get_u_int32_t(packet->payload, 24) == htonl(0x01040000)) { + NDPI_LOG(NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, ndpi_struct, NDPI_LOG_DEBUG, "UDP VeohTV found.\n"); + ndpi_int_veohtv_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV); +} +#endif diff --git a/src/lib/protocols/vhua.c b/src/lib/protocols/vhua.c new file mode 100644 index 000000000..027cc697c --- /dev/null +++ b/src/lib/protocols/vhua.c @@ -0,0 +1,68 @@ +/* + * vhua.c + * + * Copyright (C) 2011-15 - ntop.org + * + * nDPI is free software: you can vhuatribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +/* + http://www.vhua.com + + Skype-like Chinese phone protocol + + */ + +#ifdef NDPI_PROTOCOL_VHUA + +static void ndpi_int_vhua_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_VHUA, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_VHUA, ndpi_struct, NDPI_LOG_TRACE, "VHUA Found.\n"); +} + + +static void ndpi_check_vhua(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + u_char p0[] = { 0x05, 0x14, 0x3a, 0x05, 0x08, 0xf8, 0xa1, 0xb1, 0x03 }; + + if(payload_len == 0) return; /* Shouldn't happen */ + + /* Break after 3 packets. */ + if((flow->packet_counter > 3) + || (packet->udp == NULL) + || (packet->payload_packet_len < sizeof(p0))) { + NDPI_LOG(NDPI_PROTOCOL_VHUA, ndpi_struct, NDPI_LOG_TRACE, "Exclude VHUA.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_VHUA); + } else if(memcmp(packet->payload, p0, sizeof(p0)) == 0) { + ndpi_int_vhua_add_connection(ndpi_struct, flow); + } +} + +void ndpi_search_vhua(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_VHUA, ndpi_struct, NDPI_LOG_TRACE, "VHUA detection...\n"); + + /* skip marked packets */ + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_VHUA) { + ndpi_check_vhua(ndpi_struct, flow); + } +} + +#endif diff --git a/src/lib/protocols/viber.c b/src/lib/protocols/viber.c new file mode 100644 index 000000000..f53139e83 --- /dev/null +++ b/src/lib/protocols/viber.c @@ -0,0 +1,48 @@ +/* + * viber.c + * + * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * Copyright (C) 2013 - 2014 ntop.org + * + * This module is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This module is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License. + * If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_VIBER + +void ndpi_search_viber(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_VIBER, ndpi_struct, NDPI_LOG_DEBUG, "search for VIBER.\n"); + + if(packet->udp != NULL) { + NDPI_LOG(NDPI_PROTOCOL_VIBER, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over udp.\n"); + + if((packet->payload_packet_len == 12 && packet->payload[2] == 0x03 && packet->payload[3] == 0x00) + || (packet->payload_packet_len == 20 && packet->payload[2] == 0x09 && packet->payload[3] == 0x00) + || ((packet->payload_packet_len < 135) && (packet->payload[0] == 0x11))) { + NDPI_LOG(NDPI_PROTOCOL_VIBER, ndpi_struct, NDPI_LOG_DEBUG, "found VIBER.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_VIBER, NDPI_REAL_PROTOCOL); + return; + } + } + + NDPI_LOG(NDPI_PROTOCOL_VIBER, ndpi_struct, NDPI_LOG_DEBUG, "exclude VIBER.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_VIBER); +} + +#endif diff --git a/src/lib/protocols/vmware.c b/src/lib/protocols/vmware.c new file mode 100644 index 000000000..de21c521f --- /dev/null +++ b/src/lib/protocols/vmware.c @@ -0,0 +1,45 @@ +/* + * vmware.c + * + * Copyright (C) 2011-15 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_VMWARE + + +void ndpi_search_vmware(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + /* Check whether this is an VMWARE flow */ + if((packet->payload_packet_len == 66) + && (ntohs(packet->udp->dest) == 902) + && ((packet->payload[0] & 0xFF) == 0xA4)) { + NDPI_LOG(NDPI_PROTOCOL_VMWARE, ndpi_struct, NDPI_LOG_DEBUG, "Found vmware.\n"); + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_VMWARE, NDPI_REAL_PROTOCOL); + } else { + NDPI_LOG(NDPI_PROTOCOL_VMWARE, ndpi_struct, NDPI_LOG_DEBUG, "exclude vmware.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_VMWARE); + } +} + + +#endif /* NDPI_PROTOCOL_VMWARE */ + diff --git a/src/lib/protocols/vnc.c b/src/lib/protocols/vnc.c new file mode 100644 index 000000000..afd467ea7 --- /dev/null +++ b/src/lib/protocols/vnc.c @@ -0,0 +1,67 @@ +/* + * vnc.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_VNC + +static void ndpi_int_vnc_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_VNC, NDPI_REAL_PROTOCOL); +} + +/* + return 0 if nothing has been detected + return 1 if it is a http packet +*/ + +void ndpi_search_vnc_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + + if (flow->l4.tcp.vnc_stage == 0) { + if (packet->payload_packet_len == 12 + && memcmp(packet->payload, "RFB 003.00", 10) == 0 && packet->payload[11] == 0x0a) { + NDPI_LOG(NDPI_PROTOCOL_VNC, ndpi_struct, NDPI_LOG_DEBUG, "reached vnc stage one\n"); + flow->l4.tcp.vnc_stage = 1 + packet->packet_direction; + return; + } + } else if (flow->l4.tcp.vnc_stage == 2 - packet->packet_direction) { + if (packet->payload_packet_len == 12 + && memcmp(packet->payload, "RFB 003.00", 10) == 0 && packet->payload[11] == 0x0a) { + NDPI_LOG(NDPI_PROTOCOL_VNC, ndpi_struct, NDPI_LOG_DEBUG, "found vnc\n"); + ndpi_int_vnc_add_connection(ndpi_struct, flow); + return; + } + } + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_VNC); + +} +#endif diff --git a/src/lib/protocols/warcraft3.c b/src/lib/protocols/warcraft3.c new file mode 100644 index 000000000..7780dbf6e --- /dev/null +++ b/src/lib/protocols/warcraft3.c @@ -0,0 +1,100 @@ +/* + * warcraft3.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +/* include files */ + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_WARCRAFT3 + +static void ndpi_int_warcraft3_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WARCRAFT3, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_warcraft3(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + u_int32_t l; /* + Leave it as u_int32_t because otherwise 'u_int16_t temp' + might overflood it and thus generate an infinite loop + */ + + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "search WARCRAFT3\n"); + + + if (flow->packet_counter == 1 && packet->payload_packet_len == 1 && packet->payload[0] == 0x01) { + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "maybe warcraft3: packet_len == 1\n"); + return; + } else if (packet->payload_packet_len >= 4 && (packet->payload[0] == 0xf7 || packet->payload[0] == 0xff)) { + + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "packet_payload begins with 0xf7 or 0xff\n"); + + l = packet->payload[2] + (packet->payload[3] << 8); // similar to ntohs + + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "l = %u \n", l); + + while (l <= (packet->payload_packet_len - 4)) { + if (packet->payload[l] == 0xf7) { + u_int16_t temp = (packet->payload[l + 2 + 1] << 8) + packet->payload[l + 2]; + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "another f7 visited.\n"); + + if((temp <= 2) || (temp > 1500)) { + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "break\n"); + break; + } else { + l += temp; + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "l = %u \n", l); + } + } else { + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "break\n"); + break; + } + } + + if (l == packet->payload_packet_len) { + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "maybe WARCRAFT3\n"); + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "flow->packet_counter = %u \n", + flow->packet_counter); + if (flow->packet_counter > 2) { + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "detected WARCRAFT3\n"); + ndpi_int_warcraft3_add_connection(ndpi_struct, flow); + return; + } + return; + } + } + + NDPI_LOG(NDPI_PROTOCOL_WARCRAFT3, ndpi_struct, NDPI_LOG_DEBUG, "no warcraft3 detected.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WARCRAFT3); +} + +#endif diff --git a/src/lib/protocols/whoisdas.c b/src/lib/protocols/whoisdas.c new file mode 100644 index 000000000..90fa387d7 --- /dev/null +++ b/src/lib/protocols/whoisdas.c @@ -0,0 +1,60 @@ +/* + * ssh.c + * + * Copyright (C) 2013 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_WHOIS_DAS + +void ndpi_search_whois_das(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); + + if ((packet->tcp != NULL) + && ( + ((sport == 43) || (dport == 43)) + || + ((sport == 4343) || (dport == 4343)) + ) + ) { + if(packet->payload_packet_len > 0) { + u_int max_len = sizeof(flow->host_server_name)-1; + u_int i, j; + + for(i=strlen((const char *)flow->host_server_name), j=0; (i<max_len) && (j<packet->payload_packet_len); i++, j++) { + if((packet->payload[j] == '\n') || (packet->payload[j] == '\r')) break; + + flow->host_server_name[i] = packet->payload[j]; + } + + flow->host_server_name[i] = '\0'; + flow->server_id = ((sport == 43) || (sport == 4343)) ? flow->src : flow->dst; + + NDPI_LOG(NDPI_PROTOCOL_WHOIS_DAS, ndpi_struct, NDPI_LOG_DEBUG, "[WHOIS/DAS] %s\n", flow->host_server_name); + } + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WHOIS_DAS, NDPI_REAL_PROTOCOL); + } else { + NDPI_LOG(NDPI_PROTOCOL_WHOIS_DAS, ndpi_struct, NDPI_LOG_TRACE, "WHOIS Excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WHOIS_DAS); + } +} + +#endif diff --git a/src/lib/protocols/winmx.c b/src/lib/protocols/winmx.c new file mode 100644 index 000000000..d032150b7 --- /dev/null +++ b/src/lib/protocols/winmx.c @@ -0,0 +1,104 @@ +/* + * winmx.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" + +#ifdef NDPI_PROTOCOL_WINMX + + +static void ndpi_int_winmx_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow); + +static void ndpi_int_winmx_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WINMX, NDPI_REAL_PROTOCOL); +} + + +void ndpi_search_winmx_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + + if (flow->l4.tcp.winmx_stage == 0) { + if (packet->payload_packet_len == 1 || (packet->payload_packet_len > 1 && packet->payload[0] == 0x31)) { + return; + } + /* did not see this pattern in any trace that we have */ + if (((packet->payload_packet_len) == 4) + && (memcmp(packet->payload, "SEND", 4) == 0)) { + + NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "maybe WinMX Send\n"); + flow->l4.tcp.winmx_stage = 1; + return; + } + + if (((packet->payload_packet_len) == 3) + && (memcmp(packet->payload, "GET", 3) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "found winmx by GET\n"); + ndpi_int_winmx_add_connection(ndpi_struct, flow); + return; + } + + + if (packet->payload_packet_len == 149 && packet->payload[0] == '8') { + NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "maybe WinMX\n"); + if (get_u_int32_t(packet->payload, 17) == 0 + && get_u_int32_t(packet->payload, 21) == 0 + && get_u_int32_t(packet->payload, 25) == 0 + && get_u_int16_t(packet->payload, 39) == 0 && get_u_int16_t(packet->payload, 135) == htons(0x7edf) + && get_u_int16_t(packet->payload, 147) == htons(0xf792)) { + + NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, + "found winmx by pattern in first packet\n"); + ndpi_int_winmx_add_connection(ndpi_struct, flow); + return; + } + } + /* did not see this pattern in any trace that we have */ + } else if (flow->l4.tcp.winmx_stage == 1) { + if (packet->payload_packet_len > 10 && packet->payload_packet_len < 1000) { + u_int16_t left = packet->payload_packet_len - 1; + while (left > 0) { + if (packet->payload[left] == ' ') { + NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "found winmx in second packet\n"); + ndpi_int_winmx_add_connection(ndpi_struct, flow); + return; + } else if (packet->payload[left] < '0' || packet->payload[left] > '9') { + break; + } + left--; + } + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WINMX); +} + +#endif diff --git a/src/lib/protocols/world_of_kung_fu.c b/src/lib/protocols/world_of_kung_fu.c new file mode 100644 index 000000000..da35c0aa0 --- /dev/null +++ b/src/lib/protocols/world_of_kung_fu.c @@ -0,0 +1,58 @@ +/* + * world_of_kung_fu.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + + +/* include files */ +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_WORLD_OF_KUNG_FU + +static void ndpi_int_world_of_kung_fu_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WORLD_OF_KUNG_FU, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_world_of_kung_fu(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src=ndpi_struct->src; + // struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_WORLD_OF_KUNG_FU, ndpi_struct, NDPI_LOG_DEBUG, "search world_of_kung_fu.\n"); + + if ((packet->payload_packet_len == 16) + && ntohl(get_u_int32_t(packet->payload, 0)) == 0x0c000000 && ntohl(get_u_int32_t(packet->payload, 4)) == 0xd2000c00 + && (packet->payload[9] + == 0x16) && ntohs(get_u_int16_t(packet->payload, 10)) == 0x0000 && ntohs(get_u_int16_t(packet->payload, 14)) == 0x0000) { + NDPI_LOG(NDPI_PROTOCOL_WORLD_OF_KUNG_FU, ndpi_struct, NDPI_LOG_DEBUG, "detected world_of_kung_fu.\n"); + ndpi_int_world_of_kung_fu_add_connection(ndpi_struct, flow); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_WORLD_OF_KUNG_FU, ndpi_struct, NDPI_LOG_DEBUG, "exclude world_of_kung_fu.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WORLD_OF_KUNG_FU); +} + +#endif diff --git a/src/lib/protocols/world_of_warcraft.c b/src/lib/protocols/world_of_warcraft.c new file mode 100644 index 000000000..02afc9d13 --- /dev/null +++ b/src/lib/protocols/world_of_warcraft.c @@ -0,0 +1,210 @@ +/* + * world_of_warcraft.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_WORLDOFWARCRAFT + + +static void ndpi_int_worldofwarcraft_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WORLDOFWARCRAFT, protocol_type); +} + + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +u_int8_t ndpi_int_is_wow_port(const u_int16_t port) +{ + if (port == htons(3724) || port == htons(6112) || port == htons(6113) || + port == htons(6114) || port == htons(4000) || port == htons(1119)) { + return 1; + } + return 0; +} + +void ndpi_search_worldofwarcraft(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "Search World of Warcraft.\n"); + + if (packet->tcp != NULL) { + if ((packet->payload_packet_len > NDPI_STATICSTRING_LEN("POST /") && + memcmp(packet->payload, "POST /", NDPI_STATICSTRING_LEN("POST /")) == 0) || + (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /") && + memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0)) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->user_agent_line.ptr != NULL && + packet->user_agent_line.len == NDPI_STATICSTRING_LEN("Blizzard Web Client") && + memcmp(packet->user_agent_line.ptr, "Blizzard Web Client", + NDPI_STATICSTRING_LEN("Blizzard Web Client")) == 0) { + ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, + "World of Warcraft: Web Client found\n"); + return; + } + } + if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /") + && memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->user_agent_line.ptr != NULL && packet->host_line.ptr != NULL + && packet->user_agent_line.len > NDPI_STATICSTRING_LEN("Blizzard Downloader") + && packet->host_line.len > NDPI_STATICSTRING_LEN("worldofwarcraft.com") + && memcmp(packet->user_agent_line.ptr, "Blizzard Downloader", + NDPI_STATICSTRING_LEN("Blizzard Downloader")) == 0 + && memcmp(&packet->host_line.ptr[packet->host_line.len - NDPI_STATICSTRING_LEN("worldofwarcraft.com")], + "worldofwarcraft.com", NDPI_STATICSTRING_LEN("worldofwarcraft.com")) == 0) { + ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, + "World of Warcraft: Web Client found\n"); + return; + } + } + if (packet->payload_packet_len == 50 && memcmp(&packet->payload[2], "WORLD OF WARCRAFT CONNECTION", + NDPI_STATICSTRING_LEN("WORLD OF WARCRAFT CONNECTION")) == 0) { + ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "World of Warcraft: Login found\n"); + return; + } + if (packet->tcp->dest == htons(3724) && packet->payload_packet_len < 70 + && packet->payload_packet_len > 40 && (memcmp(&packet->payload[4], "WoW", 3) == 0 + || memcmp(&packet->payload[5], "WoW", 3) == 0)) { + ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "World of Warcraft: Login found\n"); + return; + } + + if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_WORLDOFWARCRAFT) != 0) { + if (packet->tcp->source == htons(3724) + && packet->payload_packet_len == 8 && get_u_int32_t(packet->payload, 0) == htonl(0x0006ec01)) { + ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, + NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n"); + return; + } + + } + + /* for some well known WoW ports + check another pattern */ + if (flow->l4.tcp.wow_stage == 0) { + if (ndpi_int_is_wow_port(packet->tcp->source) && + packet->payload_packet_len >= 14 && + ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2)) { + if (get_u_int32_t(packet->payload, 2) == htonl(0xec010100)) { + + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, + NDPI_LOG_DEBUG, "probably World of Warcraft, waiting for final packet\n"); + flow->l4.tcp.wow_stage = 2; + return; + } else if (packet->payload_packet_len == 41 && + (get_u_int16_t(packet->payload, 2) == htons(0x0085) || + get_u_int16_t(packet->payload, 2) == htons(0x0034) || + get_u_int16_t(packet->payload, 2) == htons(0x1960))) { + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, + NDPI_LOG_DEBUG, "maybe World of Warcraft, need next\n"); + flow->l4.tcp.wow_stage = 1; + return; + } + } + } + + if (flow->l4.tcp.wow_stage == 1) { + if (packet->payload_packet_len == 325 && + ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2) && + get_u_int16_t(packet->payload, 4) == 0 && + (get_u_int16_t(packet->payload, packet->payload_packet_len - 3) == htons(0x2331) || + get_u_int16_t(packet->payload, 67) == htons(0x2331)) && + (memcmp + (&packet->payload[packet->payload_packet_len - 18], + "\x94\xec\xff\xfd\x67\x62\xd4\x67\xfb\xf9\xdd\xbd\xfd\x01\xc0\x8f\xf9\x81", 18) == 0 + || memcmp(&packet->payload[packet->payload_packet_len - 30], + "\x94\xec\xff\xfd\x67\x62\xd4\x67\xfb\xf9\xdd\xbd\xfd\x01\xc0\x8f\xf9\x81", 18) == 0)) { + ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, + NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n"); + return; + } + if (packet->payload_packet_len > 32 && + ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2)) { + if (get_u_int16_t(packet->payload, 4) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, + NDPI_LOG_DEBUG, "probably World of Warcraft, waiting for final packet\n"); + flow->l4.tcp.wow_stage = 2; + return; + } else if (get_u_int32_t(packet->payload, 2) == htonl(0x12050000)) { + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, + NDPI_LOG_DEBUG, "probably World of Warcraft, waiting for final packet\n"); + flow->l4.tcp.wow_stage = 2; + return; + } + } + } + + if (flow->l4.tcp.wow_stage == 2) { + if (packet->payload_packet_len == 4) { + ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, + NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n"); + return; + } else if (packet->payload_packet_len > 4 && packet->payload_packet_len <= 16 && packet->payload[4] == 0x0c) { + ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, + NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n"); + return; + } else if (flow->packet_counter < 3) { + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "waiting for final packet\n"); + return; + } + } + if (flow->l4.tcp.wow_stage == 0 && packet->tcp->dest == htons(1119)) { + /* special log in port for battle.net/world of warcraft */ + + if (packet->payload_packet_len >= 77 && + get_u_int32_t(packet->payload, 0) == htonl(0x40000aed) && get_u_int32_t(packet->payload, 4) == htonl(0xea070aed)) { + + ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, + NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n"); + return; + } + } + } + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WORLDOFWARCRAFT); +} + +#endif diff --git a/src/lib/protocols/xbox.c b/src/lib/protocols/xbox.c new file mode 100644 index 000000000..6ee25f05f --- /dev/null +++ b/src/lib/protocols/xbox.c @@ -0,0 +1,103 @@ +/* + * xbox.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_XBOX + +static void ndpi_int_xbox_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_XBOX, NDPI_REAL_PROTOCOL); +} + + +void ndpi_search_xbox(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + // struct ndpi_id_struct *src = flow->src; + // struct ndpi_id_struct *dst = flow->dst; + + /* + * THIS IS TH XBOX UDP DETCTION ONLY !!! + * the xbox tcp detection is done by http code + */ + + + /* this detection also works for asymmetric xbox udp traffic */ + if (packet->udp != NULL) { + + u_int16_t dport = ntohs(packet->udp->dest); + u_int16_t sport = ntohs(packet->udp->source); + + NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "search xbox\n"); + + if (packet->payload_packet_len > 12 && + get_u_int32_t(packet->payload, 0) == 0 && packet->payload[5] == 0x58 && + memcmp(&packet->payload[7], "\x00\x00\x00", 3) == 0) { + + if ((packet->payload[4] == 0x0c && packet->payload[6] == 0x76) || + (packet->payload[4] == 0x02 && packet->payload[6] == 0x18) || + (packet->payload[4] == 0x0b && packet->payload[6] == 0x80) || + (packet->payload[4] == 0x03 && packet->payload[6] == 0x40) || + (packet->payload[4] == 0x06 && packet->payload[6] == 0x4e)) { + + ndpi_int_xbox_add_connection(ndpi_struct, flow); + NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "xbox udp connection detected\n"); + return; + } + } + if ((dport == 3074 || sport == 3074) + && ((packet->payload_packet_len == 24 && packet->payload[0] == 0x00) + || (packet->payload_packet_len == 42 && packet->payload[0] == 0x4f && packet->payload[2] == 0x0a) + || (packet->payload_packet_len == 80 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x50bc + && packet->payload[2] == 0x45) + || (packet->payload_packet_len == 40 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xcf5f3202) + || (packet->payload_packet_len == 38 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xc1457f03) + || (packet->payload_packet_len == 28 && ntohl(get_u_int32_t(packet->payload, 0)) == 0x015f2c00))) { + if (flow->l4.udp.xbox_stage == 1) { + ndpi_int_xbox_add_connection(ndpi_struct, flow); + NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "xbox udp connection detected\n"); + return; + } + NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "maybe xbox.\n"); + flow->l4.udp.xbox_stage++; + return; + } + + /* exclude here all non matched udp traffic, exclude here tcp only if http has been excluded, because xbox could use http */ + if (packet->tcp == NULL +#ifdef NDPI_PROTOCOL_HTTP + || NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP) != 0 +#endif + ) { + NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "xbox udp excluded.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_XBOX); + } + } + /* to not exclude tcp traffic here, done by http code... */ +} + +#endif diff --git a/src/lib/protocols/xdmcp.c b/src/lib/protocols/xdmcp.c new file mode 100644 index 000000000..dcbcfd231 --- /dev/null +++ b/src/lib/protocols/xdmcp.c @@ -0,0 +1,69 @@ +/* + * xdmcp.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_protocols.h" +#ifdef NDPI_PROTOCOL_XDMCP + + +static void ndpi_int_xdmcp_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_XDMCP, NDPI_REAL_PROTOCOL); +} + +void ndpi_search_xdmcp(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + +// struct ndpi_id_struct *src=ndpi_struct->src; +// struct ndpi_id_struct *dst=ndpi_struct->dst; + + NDPI_LOG(NDPI_PROTOCOL_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "search xdmcp.\n"); + + if (packet->tcp != NULL && (ntohs(packet->tcp->dest) >= 6000 && ntohs(packet->tcp->dest) <= 6005) + && packet->payload_packet_len == 48 + && packet->payload[0] == 0x6c && packet->payload[1] == 0x00 + && ntohs(get_u_int16_t(packet->payload, 6)) == 0x1200 && ntohs(get_u_int16_t(packet->payload, 8)) == 0x1000) { + + NDPI_LOG(NDPI_PROTOCOL_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "found xdmcp over tcp.\n"); + ndpi_int_xdmcp_add_connection(ndpi_struct, flow); + return; + } + if (packet->udp != NULL && ntohs(packet->udp->dest) == 177 + && packet->payload_packet_len >= 6 && packet->payload_packet_len == 6 + ntohs(get_u_int16_t(packet->payload, 4)) + && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0001 && ntohs(get_u_int16_t(packet->payload, 2)) == 0x0002) { + + NDPI_LOG(NDPI_PROTOCOL_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "found xdmcp over udp.\n"); + ndpi_int_xdmcp_add_connection(ndpi_struct, flow); + return; + } + + + NDPI_LOG(NDPI_PROTOCOL_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "exclude xdmcp.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_XDMCP); +} + +#endif diff --git a/src/lib/protocols/yahoo.c b/src/lib/protocols/yahoo.c new file mode 100644 index 000000000..c5d340bc1 --- /dev/null +++ b/src/lib/protocols/yahoo.c @@ -0,0 +1,434 @@ +/* + * yahoo.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_YAHOO + + +struct ndpi_yahoo_header { + u_int8_t YMSG_str[4]; + u_int16_t version; + u_int16_t nothing0; + u_int16_t len; + u_int16_t service; + u_int32_t status; + u_int32_t session_id; +}; + +/* This function checks the pattern '<Ymsg Command=' in line 8 of parsed lines or + * in the payload*/ +static u_int8_t ndpi_check_for_YmsgCommand(u_int16_t len, const u_int8_t * ptr) +{ + u_int16_t i; + + for (i = 0; i < len - 12; i++) { + if (ptr[i] == 'Y') { + if (memcmp(&ptr[i + 1], "msg Command=", 12) == 0) { + return 1; + } + } + } + return 0; +} + +static void ndpi_int_yahoo_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, ndpi_protocol_type_t protocol_type) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_YAHOO, protocol_type); +} + + + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +u_int8_t check_ymsg(const u_int8_t * payload, u_int16_t payload_packet_len) +{ + + const struct ndpi_yahoo_header *yahoo = (struct ndpi_yahoo_header *) payload; + + u_int16_t yahoo_len_parsed = 0; + do { + u_int16_t ylen = ntohs(yahoo->len); + + yahoo_len_parsed += 20 + ylen; /* possible overflow here: 20 + ylen = 0x10000 --> 0 --> infinite loop */ + + if (ylen >= payload_packet_len || yahoo_len_parsed >= payload_packet_len) + break; + + yahoo = (struct ndpi_yahoo_header *) (payload + yahoo_len_parsed); + } + while (memcmp(yahoo->YMSG_str, "YMSG", 4) == 0); + + if (yahoo_len_parsed == payload_packet_len) + return 1; + return 0; +} + +static void ndpi_search_yahoo_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + const struct ndpi_yahoo_header *yahoo = (struct ndpi_yahoo_header *) packet->payload; + if (packet->payload_packet_len == 0) { + return; + } + + /* packet must be at least 20 bytes long */ + if (packet->payload_packet_len >= 20 + && memcmp(yahoo->YMSG_str, "YMSG", 4) == 0 && ((packet->payload_packet_len - 20) == ntohs(yahoo->len) + || check_ymsg(packet->payload, packet->payload_packet_len))) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO FOUND\n"); + flow->yahoo_detection_finished = 2; + if (ntohs(yahoo->service) == 24 || ntohs(yahoo->service) == 152 || ntohs(yahoo->service) == 74) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO conference or chat invite found"); + if (src != NULL) { + src->yahoo_conf_logged_in = 1; + } + if (dst != NULL) { + dst->yahoo_conf_logged_in = 1; + } + } + if (ntohs(yahoo->service) == 27 || ntohs(yahoo->service) == 155 || ntohs(yahoo->service) == 160) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO conference or chat logoff found"); + if (src != NULL) { + src->yahoo_conf_logged_in = 0; + src->yahoo_voice_conf_logged_in = 0; + } + } + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } else if (flow->yahoo_detection_finished == 2 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_YAHOO) { + return; + } else if (packet->payload_packet_len == 4 && memcmp(yahoo->YMSG_str, "YMSG", 4) == 0) { + flow->l4.tcp.yahoo_sip_comm = 1; + return; + } else if (flow->l4.tcp.yahoo_sip_comm && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN + && flow->packet_counter < 3) { + return; + } + + /* now test for http login, at least 100 a bytes packet */ + if (ndpi_struct->yahoo_detect_http_connections != 0 && packet->payload_packet_len > 100) { + if (memcmp(packet->payload, "POST /relay?token=", 18) == 0 + || memcmp(packet->payload, "GET /relay?token=", 17) == 0 + || memcmp(packet->payload, "GET /?token=", 12) == 0 + || memcmp(packet->payload, "HEAD /relay?token=", 18) == 0) { + if ((src != NULL + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) + != 0) || (dst != NULL + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) + != 0)) { + /* this is mostly a file transfer */ + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + if (memcmp(packet->payload, "POST ", 5) == 0) { + u_int16_t a; + ndpi_parse_packet_line_info(ndpi_struct, flow); + + if ((packet->user_agent_line.len >= 21) + && (memcmp(packet->user_agent_line.ptr, "YahooMobileMessenger/", 21) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO(Mobile)"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + + if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_YAHOO) + && packet->parsed_lines > 5 + && memcmp(&packet->payload[5], "/Messenger.", 11) == 0 + && packet->line[1].len >= 17 + && memcmp(packet->line[1].ptr, "Connection: Close", + 17) == 0 && packet->line[2].len >= 6 + && memcmp(packet->line[2].ptr, "Host: ", 6) == 0 + && packet->line[3].len >= 16 + && memcmp(packet->line[3].ptr, "Content-Length: ", + 16) == 0 && packet->line[4].len >= 23 + && memcmp(packet->line[4].ptr, "User-Agent: Mozilla/5.0", + 23) == 0 && packet->line[5].len >= 23 + && memcmp(packet->line[5].ptr, "Cache-Control: no-cache", 23) == 0) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, + "YAHOO HTTP POST P2P FILETRANSFER FOUND\n"); + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + + if (packet->host_line.ptr != NULL && packet->host_line.len >= 26 && + memcmp(packet->host_line.ptr, "filetransfer.msg.yahoo.com", 26) == 0) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO HTTP POST FILETRANSFER FOUND\n"); + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + /* now check every line */ + for (a = 0; a < packet->parsed_lines; a++) { + if (packet->line[a].len >= 4 && memcmp(packet->line[a].ptr, "YMSG", 4) == 0) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, + NDPI_LOG_TRACE, + "YAHOO HTTP POST FOUND, line is: %.*s\n", packet->line[a].len, packet->line[a].ptr); + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + if (packet->parsed_lines > 8 && packet->line[8].len > 250 && packet->line[8].ptr != NULL) { + if (memcmp(packet->line[8].ptr, "<Session ", 9) == 0) { + if (ndpi_check_for_YmsgCommand(packet->line[8].len, packet->line[8].ptr)) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, + "found HTTP Proxy Yahoo Chat <Ymsg Command= pattern \n"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + } + if (memcmp(packet->payload, "GET /Messenger.", 15) == 0) { + if ((src != NULL + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) + != 0) || (dst != NULL + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) + != 0)) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO HTTP GET /Messenger. match\n"); + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + + if ((memcmp(packet->payload, "GET /", 5) == 0)) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if ((packet->user_agent_line.ptr != NULL + && packet->user_agent_line.len >= NDPI_STATICSTRING_LEN("YahooMobileMessenger/") + && memcmp(packet->user_agent_line.ptr, "YahooMobileMessenger/", + NDPI_STATICSTRING_LEN("YahooMobileMessenger/")) == 0) + || (packet->user_agent_line.len >= 15 + && (memcmp(packet->user_agent_line.ptr, "Y!%20Messenger/", 15) == 0))) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO(Mobile)"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + if (packet->host_line.ptr != NULL && packet->host_line.len >= NDPI_STATICSTRING_LEN("msg.yahoo.com") && + memcmp(&packet->host_line.ptr[packet->host_line.len - NDPI_STATICSTRING_LEN("msg.yahoo.com")], + "msg.yahoo.com", NDPI_STATICSTRING_LEN("msg.yahoo.com")) == 0) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + + } + + } + /* found another http login command for yahoo, it is like OSCAR */ + /* detect http connections */ + + if (packet->payload_packet_len > 50 && (memcmp(packet->payload, "content-length: ", 16) == 0)) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (packet->parsed_lines > 2 && packet->line[1].len == 0) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "first line is empty.\n"); + if (packet->line[2].len > 13 && memcmp(packet->line[2].ptr, "<Ymsg Command=", 14) == 0) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO web chat found\n"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + } + } + + if (packet->payload_packet_len > 38 && memcmp(packet->payload, "CONNECT scs.msg.yahoo.com:5050 HTTP/1.", 38) == 0) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO-HTTP FOUND\n"); + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + + if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0) + || (dst != NULL + && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0)) { + if (packet->payload_packet_len == 6 && memcmp(packet->payload, "YAHOO!", 6) == 0) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + /* asymmetric detection for SNDIMG not done yet. + * See ./Yahoo8.1-VideoCall-LAN.pcap and ./Yahoo-VideoCall-inPublicIP.pcap */ + + + if (packet->payload_packet_len == 8 + && (memcmp(packet->payload, "<SNDIMG>", 8) == 0 || memcmp(packet->payload, "<REQIMG>", 8) == 0 + || memcmp(packet->payload, "<RVWCFG>", 8) == 0 || memcmp(packet->payload, "<RUPCFG>", 8) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, + "YAHOO SNDIMG or REQIMG or RVWCFG or RUPCFG FOUND\n"); + if (src != NULL) { + if (memcmp(packet->payload, "<SNDIMG>", 8) == 0) { + src->yahoo_video_lan_dir = 0; + } else { + src->yahoo_video_lan_dir = 1; + } + src->yahoo_video_lan_timer = packet->tick_timestamp; + } + if (dst != NULL) { + if (memcmp(packet->payload, "<SNDIMG>", 8) == 0) { + dst->yahoo_video_lan_dir = 0; + } else { + dst->yahoo_video_lan_dir = 1; + } + dst->yahoo_video_lan_timer = packet->tick_timestamp; + + } + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO subtype VIDEO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + if (src != NULL && packet->tcp->dest == htons(5100) + && ((u_int32_t) + (packet->tick_timestamp - src->yahoo_video_lan_timer) < ndpi_struct->yahoo_lan_video_timeout)) { + if (src->yahoo_video_lan_dir == 1) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "IMG MARKED"); + return; + } + + } + if (dst != NULL && packet->tcp->dest == htons(5100) + && ((u_int32_t) + (packet->tick_timestamp - dst->yahoo_video_lan_timer) < ndpi_struct->yahoo_lan_video_timeout)) { + if (dst->yahoo_video_lan_dir == 0) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "IMG MARKED"); + return; + } + + } + } + + /* detect YAHOO over HTTP proxy */ +#ifdef NDPI_PROTOCOL_HTTP + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP) +#endif + { + + if (flow->l4.tcp.yahoo_http_proxy_stage == 0) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, + "YAHOO maybe HTTP proxy packet 1 => need next packet\n"); + flow->l4.tcp.yahoo_http_proxy_stage = 1 + packet->packet_direction; + return; + } + if (flow->l4.tcp.yahoo_http_proxy_stage == 1 + packet->packet_direction) { + if ((packet->payload_packet_len > 250) && (memcmp(packet->payload, "<Session ", 9) == 0)) { + if (ndpi_check_for_YmsgCommand(packet->payload_packet_len, packet->payload)) { + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, + "found HTTP Proxy Yahoo Chat <Ymsg Command= pattern \n"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, + "YAHOO maybe HTTP proxy still initial direction => need next packet\n"); + return; + } + if (flow->l4.tcp.yahoo_http_proxy_stage == 2 - packet->packet_direction) { + + ndpi_parse_packet_line_info_any(ndpi_struct, flow); + + if (packet->parsed_lines >= 9) { + + if (packet->line[4].ptr != NULL && packet->line[4].len >= 9 && + packet->line[8].ptr != NULL && packet->line[8].len >= 6 && + memcmp(packet->line[4].ptr, "<Session ", 9) == 0 && + memcmp(packet->line[8].ptr, "<Ymsg ", 6) == 0) { + + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO over HTTP proxy"); + ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } + } + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_YAHOO); +} + + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +void ndpi_search_yahoo_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + + + + struct ndpi_id_struct *src = flow->src; + if (src == NULL || NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) == 0) { + goto excl_yahoo_udp; + } + excl_yahoo_udp: + + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_YAHOO); +} + +void ndpi_search_yahoo(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + + NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "search yahoo\n"); + + if (packet->payload_packet_len > 0 && flow->yahoo_detection_finished == 0) { + if (packet->tcp != NULL && packet->tcp_retransmission == 0) { + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN +#ifdef NDPI_PROTOCOL_HTTP + || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP +#endif +#ifdef NDPI_PROTOCOL_SSL + || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL +#endif + ) { + ndpi_search_yahoo_tcp(ndpi_struct, flow); + } + } else if (packet->udp != NULL) { + ndpi_search_yahoo_udp(ndpi_struct, flow); + } + } + if (packet->payload_packet_len > 0 && flow->yahoo_detection_finished == 2) { + if (packet->tcp != NULL && packet->tcp_retransmission == 0) { + ndpi_search_yahoo_tcp(ndpi_struct, flow); + } + } +} +#endif diff --git a/src/lib/protocols/zattoo.c b/src/lib/protocols/zattoo.c new file mode 100644 index 000000000..f7de4a8e7 --- /dev/null +++ b/src/lib/protocols/zattoo.c @@ -0,0 +1,235 @@ +/* + * zattoo.c + * + * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-15 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_ZATTOO + +static void ndpi_int_zattoo_add_connection(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + ndpi_protocol_type_t protocol_type) +{ + + struct ndpi_packet_struct *packet = &flow->packet; + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_ZATTOO, protocol_type); + + if (src != NULL) { + src->zattoo_ts = packet->tick_timestamp; + } + if (dst != NULL) { + dst->zattoo_ts = packet->tick_timestamp; + } +} + + + +#if !defined(WIN32) +static inline +#else +__forceinline static +#endif +u_int8_t ndpi_int_zattoo_user_agent_set(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + if (flow->packet.user_agent_line.ptr != NULL && flow->packet.user_agent_line.len == 111) { + if (memcmp(flow->packet.user_agent_line.ptr + + flow->packet.user_agent_line.len - 25, "Zattoo/4", sizeof("Zattoo/4") - 1) == 0) { + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "found zattoo useragent\n"); + return 1; + } + } + return 0; +} + +void ndpi_search_zattoo(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + + struct ndpi_id_struct *src = flow->src; + struct ndpi_id_struct *dst = flow->dst; + + u_int16_t i; + + if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_ZATTOO) { + if (src != NULL && ((u_int32_t) + (packet->tick_timestamp - src->zattoo_ts) < ndpi_struct->zattoo_connection_timeout)) { + src->zattoo_ts = packet->tick_timestamp; + } + if (dst != NULL && ((u_int32_t) + (packet->tick_timestamp - dst->zattoo_ts) < ndpi_struct->zattoo_connection_timeout)) { + dst->zattoo_ts = packet->tick_timestamp; + } + return; + } + + if (packet->tcp != NULL) { + if (packet->payload_packet_len > 50 && memcmp(packet->payload, "GET /frontdoor/fd?brand=Zattoo&v=", 33) == 0) { + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, + NDPI_LOG_DEBUG, "add connection over tcp with pattern GET /frontdoor/fd?brand=Zattoo&v=\n"); + ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + if (packet->payload_packet_len > 50 + && memcmp(packet->payload, "GET /ZattooAdRedirect/redirect.jsp?user=", 40) == 0) { + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, + NDPI_LOG_DEBUG, "add connection over tcp with pattern GET /ZattooAdRedirect/redirect.jsp?user=\n"); + ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + if (packet->payload_packet_len > 50 + && (memcmp(packet->payload, "POST /channelserver/player/channel/update HTTP/1.1", 50) == 0 + || memcmp(packet->payload, "GET /epg/query", 14) == 0)) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + for (i = 0; i < packet->parsed_lines; i++) { + if (packet->line[i].len >= 18 && (memcmp(packet->line[i].ptr, "User-Agent: Zattoo", 18) == 0)) { + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, + NDPI_LOG_DEBUG, + "add connection over tcp with pattern POST /channelserver/player/channel/update HTTP/1.1\n"); + ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } else if (packet->payload_packet_len > 50 + && (memcmp(packet->payload, "GET /", 5) == 0 + || memcmp(packet->payload, "POST /", NDPI_STATICSTRING_LEN("POST /")) == 0)) { + /* TODO to avoid searching currently only a specific length and offset is used + * that might be changed later */ + ndpi_parse_packet_line_info(ndpi_struct, flow); + if (ndpi_int_zattoo_user_agent_set(ndpi_struct, flow)) { + ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } else if (packet->payload_packet_len > 50 && memcmp(packet->payload, "POST http://", 12) == 0) { + ndpi_parse_packet_line_info(ndpi_struct, flow); + // test for unique character of the zattoo header + if (packet->parsed_lines == 4 && packet->host_line.ptr != NULL) { + u_int32_t ip; + u_int16_t bytes_read = 0; + + ip = ndpi_bytestream_to_ipv4(&packet->payload[12], packet->payload_packet_len, &bytes_read); + + // and now test the firt 5 bytes of the payload for zattoo pattern + if (ip == packet->iph->daddr + && packet->empty_line_position_set != 0 + && ((packet->payload_packet_len - packet->empty_line_position) > 10) + && packet->payload[packet->empty_line_position + 2] == + 0x03 + && packet->payload[packet->empty_line_position + 3] == + 0x04 + && packet->payload[packet->empty_line_position + 4] == + 0x00 + && packet->payload[packet->empty_line_position + 5] == + 0x04 + && packet->payload[packet->empty_line_position + 6] == + 0x0a && packet->payload[packet->empty_line_position + 7] == 0x00) { + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, + NDPI_LOG_DEBUG, "add connection over tcp with pattern POST http://\n"); + ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + } + } else if (flow->zattoo_stage == 0) { + + if (packet->payload_packet_len > 50 + && packet->payload[0] == 0x03 + && packet->payload[1] == 0x04 + && packet->payload[2] == 0x00 + && packet->payload[3] == 0x04 && packet->payload[4] == 0x0a && packet->payload[5] == 0x00) { + flow->zattoo_stage = 1 + packet->packet_direction; + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, + NDPI_LOG_DEBUG, "need next packet, seen pattern 0x030400040a00\n"); + return; + } + /* the following is is searching for flash, not for zattoo. cust1 wants to do so. */ + } else if (flow->zattoo_stage == 2 - packet->packet_direction + && packet->payload_packet_len > 50 && packet->payload[0] == 0x03 && packet->payload[1] == 0x04) { + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over tcp with 0x0304.\n"); + ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } else if (flow->zattoo_stage == 1 + packet->packet_direction) { + if (packet->payload_packet_len > 500 && packet->payload[0] == 0x00 && packet->payload[1] == 0x00) { + flow->zattoo_stage = 3 + packet->packet_direction; + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, + NDPI_LOG_DEBUG, "need next packet, seen pattern 0x0000\n"); + return; + } + if (packet->payload_packet_len > 50 + && packet->payload[0] == 0x03 + && packet->payload[1] == 0x04 + && packet->payload[2] == 0x00 + && packet->payload[3] == 0x04 && packet->payload[4] == 0x0a && packet->payload[5] == 0x00) { + } + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, + "need next packet, seen pattern 0x030400040a00\n"); + return; + } else if (flow->zattoo_stage == 4 - packet->packet_direction + && packet->payload_packet_len > 50 && packet->payload[0] == 0x03 && packet->payload[1] == 0x04) { + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over tcp with 0x0304.\n"); + ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } else if (flow->zattoo_stage == 5 + packet->packet_direction && (packet->payload_packet_len == 125)) { + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "detected zattoo.\n"); + ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } else if (flow->zattoo_stage == 6 - packet->packet_direction && packet->payload_packet_len == 1412) { + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "found zattoo.\n"); + ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); + return; + } + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, + "ZATTOO: discarted the flow (TCP): packet_size: %u; Flowstage: %u\n", + packet->payload_packet_len, flow->zattoo_stage); + + } else if (packet->udp != NULL) { + + if (packet->payload_packet_len > 20 && (packet->udp->dest == htons(5003) + || packet->udp->source == htons(5003)) + && (get_u_int16_t(packet->payload, 0) == htons(0x037a) + || get_u_int16_t(packet->payload, 0) == htons(0x0378) + || get_u_int16_t(packet->payload, 0) == htons(0x0305) + || get_u_int32_t(packet->payload, 0) == htonl(0x03040004) + || get_u_int32_t(packet->payload, 0) == htonl(0x03010005))) { + if (++flow->zattoo_stage == 2) { + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over udp.\n"); + ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); + return; + } + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "need next packet udp.\n"); + return; + } + + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, + "ZATTOO: discarded the flow (UDP): packet_size: %u; Flowstage: %u\n", + packet->payload_packet_len, flow->zattoo_stage); + + } + + NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "exclude zattoo.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ZATTOO); +} +#endif diff --git a/src/lib/protocols/zmq.c b/src/lib/protocols/zmq.c new file mode 100644 index 000000000..12548a2ed --- /dev/null +++ b/src/lib/protocols/zmq.c @@ -0,0 +1,100 @@ +/* + * zmq.c + * + * Copyright (C) 2011-15 - ntop.org + * + * nDPI is free software: you can zmqtribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_ZMQ + +static void ndpi_int_zmq_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_ZMQ, NDPI_REAL_PROTOCOL); + NDPI_LOG(NDPI_PROTOCOL_ZMQ, ndpi_struct, NDPI_LOG_TRACE, "ZMQ Found.\n"); +} + + +static void ndpi_check_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + u_char p0[] = { 0x00, 0x00, 0x00, 0x05, 0x01, 0x66, 0x6c, 0x6f, 0x77 }; + u_char p1[] = { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f }; + u_char p2[] = { 0x28, 0x66, 0x6c, 0x6f, 0x77, 0x00 }; + + if(payload_len == 0) return; /* Shouldn't happen */ + + /* Break after 17 packets. */ + if(flow->packet_counter > 17) { + NDPI_LOG(NDPI_PROTOCOL_ZMQ, ndpi_struct, NDPI_LOG_TRACE, "Exclude ZMQ.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ZMQ); + return; + } + + if(flow->l4.tcp.prev_zmq_pkt_len == 0) { + flow->l4.tcp.prev_zmq_pkt_len = ndpi_min(packet->payload_packet_len, 10); + memcpy(flow->l4.tcp.prev_zmq_pkt, packet->payload, flow->l4.tcp.prev_zmq_pkt_len); + return; /* Too early */ + } + + if(payload_len == 2) { + if(flow->l4.tcp.prev_zmq_pkt_len == 2) { + if((memcmp(packet->payload, "\01\01", 2) == 0) + && (memcmp(flow->l4.tcp.prev_zmq_pkt, "\01\02", 2) == 0)) { + ndpi_int_zmq_add_connection(ndpi_struct, flow); + return; + } + } else if(flow->l4.tcp.prev_zmq_pkt_len == 9) { + if((memcmp(packet->payload, "\00\00", 2) == 0) + && (memcmp(flow->l4.tcp.prev_zmq_pkt, p0, 9) == 0)) { + ndpi_int_zmq_add_connection(ndpi_struct, flow); + return; + } + } else if(flow->l4.tcp.prev_zmq_pkt_len == 10) { + if((memcmp(packet->payload, "\01\02", 2) == 0) + && (memcmp(flow->l4.tcp.prev_zmq_pkt, p1, 10) == 0)) { + ndpi_int_zmq_add_connection(ndpi_struct, flow); + return; + } + } + } else if(payload_len >= 10) { + if(flow->l4.tcp.prev_zmq_pkt_len == 10) { + if(((memcmp(packet->payload, p1, 10) == 0) + && (memcmp(flow->l4.tcp.prev_zmq_pkt, p1, 10) == 0)) + || ((memcmp(&packet->payload[1], p2, sizeof(p2)) == 0) + && (memcmp(&flow->l4.tcp.prev_zmq_pkt[1], p2, sizeof(p2)) == 0))) { + ndpi_int_zmq_add_connection(ndpi_struct, flow); + return; + } + } + } +} + +void ndpi_search_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_ZMQ, ndpi_struct, NDPI_LOG_TRACE, "ZMQ detection...\n"); + + /* skip marked packets */ + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_ZMQ) { + if (packet->tcp_retransmission == 0) { + ndpi_check_zmq(ndpi_struct, flow); + } + } +} + +#endif diff --git a/src/lib/third_party/include/actypes.h b/src/lib/third_party/include/actypes.h new file mode 100644 index 000000000..1900ae9a0 --- /dev/null +++ b/src/lib/third_party/include/actypes.h @@ -0,0 +1,135 @@ +/* + * actypes.h: Includes basic data types of ahocorasick library + * This file is part of multifast. + * + Copyright 2010-2012 Kamiar Kanani <kamiar.kanani@gmail.com> + + multifast is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + multifast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with multifast. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _AC_TYPES_H_ +#define _AC_TYPES_H_ + +/* AC_ALPHABET_t: + * defines the alphabet type. + * Actually defining AC_ALPHABET_t as a char will work, but sometimes we deal + * with streams of other (bigger) types e.g. integers, specific enum, objects. + * Although they consists of string of bytes (chars), but using their specific + * types for AC_ALPHABET_t will lead to a better performance. so instead of + * dealing with strings of chars, we assume dealing with strings of + * AC_ALPHABET_t and leave it optional for other developers to define their + * own alphabets. + **/ +typedef char AC_ALPHABET_t; + +/* AC_REP_t: + * Provides a more readable representative for a pattern. + * because patterns themselves are not always suitable for displaying + * (e.g. for hex patterns), we offer this type to improve intelligibility + * of output. furthermore, sometimes it is useful, for example while + * retrieving patterns from a database, to maintain their identifiers in the + * automata for further reference. we provisioned two possible types as a + * union for this purpose. you can add your desired type in it. + **/ +typedef union { + char * stringy; /* null-terminated string */ + unsigned long number; +} AC_REP_t; + +/* AC_PATTERN_t: + * This is the pattern type that must be fed into AC automata. + * the 'astring' field is not null-terminated, due to it can contain zero + * value bytes. the 'length' field determines the number of AC_ALPHABET_t it + * carries. the 'representative' field is described in AC_REP_t. despite + * 'astring', 'representative' can have duplicate values for different given + * AC_PATTERN_t. it is an optional field and you can just fill it with 0. + * CAUTION: + * Not always the 'astring' points to the correct position in memory. + * it is the responsibility of your program to maintain a permanent allocation + * for astring field of the added pattern to automata. + **/ +typedef struct +{ + AC_ALPHABET_t * astring; /* String of alphabets */ + unsigned int length; /* Length of pattern */ + AC_REP_t rep; /* Representative string (optional) */ +} AC_PATTERN_t; + +/* AC_TEXT_t: + * The input text type that is fed to ac_automata_search() to be searched. + * it is similar to AC_PATTERN_t. actually we could use AC_PATTERN_t as input + * text, but for the purpose of being more readable, we defined this new type. + **/ +typedef struct +{ + AC_ALPHABET_t * astring; /* String of alphabets */ + unsigned int length; /* Length of string */ +} AC_TEXT_t; + +/* AC_MATCH_t: + * Provides the structure for reporting a match event. + * a match event occurs when the automata reaches a final node. any final + * node can match one or more pattern at a position in a text. the + * 'patterns' field holds these matched patterns. obviously these + * matched patterns have same end-position in the text. there is a relationship + * between matched patterns: the shorter one is a factor (tail) of the longer + * one. the 'position' maintains the end position of matched patterns. the + * start position of patterns could be found by knowing their 'length' in + * AC_PATTERN_t. e.g. suppose "recent" and "cent" are matched at + * position 40 in the text, then the start position of them are 34 and 36 + * respectively. finally the field 'match_num' maintains the number of + * matched patterns. + **/ +typedef struct +{ + AC_PATTERN_t * patterns; /* Array of matched pattern */ + long position; /* The end position of matching pattern(s) in the text */ + unsigned int match_num; /* Number of matched patterns */ +} AC_MATCH_t; + +/* AC_ERROR_t: + * Error that may occur while adding a pattern to the automata. + * it is returned by ac_automata_add(). + **/ +typedef enum + { + ACERR_SUCCESS = 0, /* No error occurred */ + ACERR_DUPLICATE_PATTERN, /* Duplicate patterns */ + ACERR_LONG_PATTERN, /* Pattern length is longer than AC_PATTRN_MAX_LENGTH */ + ACERR_ZERO_PATTERN, /* Empty pattern (zero length) */ + ACERR_AUTOMATA_CLOSED, /* Automata is closed. after calling + ac_automata_finalize() you can not add new patterns to the automata. */ + } AC_ERROR_t; + +/* MATCH_CALBACK_t: + * This is the call-back function type that must be given to automata at + * initialization to report match occurrence to the caller. + * at a match event, the automata will reach you using this function and sends + * you a pointer to AC_MATCH_t. using that pointer you can handle + * matches. you can send parameters to the call-back function when you call + * ac_automata_search(). at call-back, the automata will sent you those + * parameters as the second parameter (void *) of MATCH_CALBACK_t. inside + * the call-back function you can cast it to whatever you want. + * If you return 0 from MATCH_CALBACK_t function to the automata, it will + * continue searching, otherwise it will return from ac_automata_search() + * to your calling function. + **/ +typedef int (*MATCH_CALBACK_f)(AC_MATCH_t *, void *); + +/* AC_PATTRN_MAX_LENGTH: + * Maximum acceptable pattern length in AC_PATTERN_t.length + **/ +#define AC_PATTRN_MAX_LENGTH 1024 + +#endif diff --git a/src/lib/third_party/include/ahocorasick.h b/src/lib/third_party/include/ahocorasick.h new file mode 100644 index 000000000..ea92e4a1b --- /dev/null +++ b/src/lib/third_party/include/ahocorasick.h @@ -0,0 +1,69 @@ +/* + * ahocorasick.h: the main ahocorasick header file. + * This file is part of multifast. + * + Copyright 2010-2012 Kamiar Kanani <kamiar.kanani@gmail.com> + + multifast is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + multifast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with multifast. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _AUTOMATA_H_ +#define _AUTOMATA_H_ + +#include "node.h" + +typedef struct +{ + /* The root of the Aho-Corasick trie */ + AC_NODE_t * root; + + /* maintain all nodes pointers. it will be used to access or release + * all nodes. */ + AC_NODE_t ** all_nodes; + + unsigned int all_nodes_num; /* Number of all nodes in the automata */ + unsigned int all_nodes_max; /* Current max allocated memory for *all_nodes */ + + AC_MATCH_t match; /* Any match is reported with this */ + MATCH_CALBACK_f match_callback; /* Match call-back function */ + + /* this flag indicates that if automata is finalized by + * ac_automata_finalize() or not. 1 means finalized and 0 + * means not finalized (is open). after finalizing automata you can not + * add pattern to automata anymore. */ + unsigned short automata_open; + + /* It is possible to feed a large input to the automata chunk by chunk to + * be searched using ac_automata_search(). in fact by default automata + * thinks that all chunks are related unless you do ac_automata_reset(). + * followings are variables that keep track of searching state. */ + AC_NODE_t * current_node; /* Pointer to current node while searching */ + unsigned long base_position; /* Represents the position of current chunk + related to whole input text */ + + /* Statistic Variables */ + unsigned long total_patterns; /* Total patterns in the automata */ + +} AC_AUTOMATA_t; + + +AC_AUTOMATA_t * ac_automata_init (MATCH_CALBACK_f mc); +AC_ERROR_t ac_automata_add (AC_AUTOMATA_t * thiz, AC_PATTERN_t * str); +void ac_automata_finalize (AC_AUTOMATA_t * thiz); +int ac_automata_search (AC_AUTOMATA_t * thiz, AC_TEXT_t * str, void * param); +void ac_automata_reset (AC_AUTOMATA_t * thiz); +void ac_automata_release (AC_AUTOMATA_t * thiz); +void ac_automata_display (AC_AUTOMATA_t * thiz, char repcast); + +#endif diff --git a/src/lib/third_party/include/node.h b/src/lib/third_party/include/node.h new file mode 100644 index 000000000..13cf2ff11 --- /dev/null +++ b/src/lib/third_party/include/node.h @@ -0,0 +1,66 @@ +/* + * node.h: automata node header file + * This file is part of multifast. + * + Copyright 2010-2012 Kamiar Kanani <kamiar.kanani@gmail.com> + + multifast is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + multifast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with multifast. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _NODE_H_ +#define _NODE_H_ + +#include "actypes.h" + +/* Forward Declaration */ +struct edge; + +/* automata node */ +typedef struct ac_node +{ + int id; /* Node ID : for debugging purpose */ + short int final; /* 0: no ; 1: yes, it is a final node */ + struct ac_node * failure_node; /* The failure node of this node */ + unsigned short depth; /* depth: distance between this node and the root */ + + /* Matched patterns */ + AC_PATTERN_t * matched_patterns; /* Array of matched patterns */ + unsigned short matched_patterns_num; /* Number of matched patterns at this node */ + unsigned short matched_patterns_max; /* Max capacity of allocated memory for matched_patterns */ + + /* Outgoing Edges */ + struct edge * outgoing; /* Array of outgoing edges */ + unsigned short outgoing_degree; /* Number of outgoing edges */ + unsigned short outgoing_max; /* Max capacity of allocated memory for outgoing */ +} AC_NODE_t; + +/* The Edge of the Node */ +struct edge +{ + AC_ALPHABET_t alpha; /* Edge alpha */ + struct ac_node * next; /* Target of the edge */ +}; + + +AC_NODE_t * node_create (void); +AC_NODE_t * node_create_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha); +void node_register_matchstr (AC_NODE_t * thiz, AC_PATTERN_t * str); +void node_register_outgoing (AC_NODE_t * thiz, AC_NODE_t * next, AC_ALPHABET_t alpha); +AC_NODE_t * node_find_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha); +AC_NODE_t * node_findbs_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha); +void node_release (AC_NODE_t * thiz); +void node_assign_id (AC_NODE_t * thiz); +void node_sort_edges (AC_NODE_t * thiz); + +#endif diff --git a/src/lib/third_party/include/patricia.h b/src/lib/third_party/include/patricia.h new file mode 100644 index 000000000..be8476e85 --- /dev/null +++ b/src/lib/third_party/include/patricia.h @@ -0,0 +1,302 @@ +/* + * $Id: patricia.h,v 1.6 2005/12/07 20:53:01 dplonka Exp $ + * Dave Plonka <plonka@doit.wisc.edu> + * + * This product includes software developed by the University of Michigan, + * Merit Network, Inc., and their contributors. + * + * This file had been called "radix.h" in the MRT sources. + * + * I renamed it to "patricia.h" since it's not an implementation of a general + * radix trie. Also, pulled in various requirements from "mrt.h" and added + * some other things it could be used as a standalone API. + + https://github.com/deepfield/MRT/blob/master/COPYRIGHT + + Copyright (c) 1999-2013 + + The Regents of the University of Michigan ("The Regents") and Merit + Network, Inc. + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _PATRICIA_H +#define _PATRICIA_H + +#define HAVE_IPV6 + +/* typedef unsigned int u_int; */ +/* { from defs.h */ +#define prefix_touchar(prefix) ((u_char *)&(prefix)->add.sin) + +#ifdef __KERNEL__ +#define MAXLINE 512 +#else +#define MAXLINE 1024 +#endif + +#define BIT_TEST(f, b) ((f) & (b)) +/* } */ + +#define addroute make_and_lookup + +#ifndef __KERNEL__ +#include <sys/types.h> /* for u_* definitions (on FreeBSD 5) */ +#include <errno.h> /* for EAFNOSUPPORT */ + +#ifndef EAFNOSUPPORT +# defined EAFNOSUPPORT WSAEAFNOSUPPORT +#else +#ifndef WIN32 +# include <netinet/in.h> /* for struct in_addr */ +#endif +#endif + +#ifndef WIN32 +#include <sys/socket.h> /* for AF_INET */ +#else +#include <winsock2.h> +#include <ws2tcpip.h> /* IPv6 */ +#endif + +#endif /* __KERNEL__ */ + +/* { from mrt.h */ + +typedef struct the_prefix4_t { + unsigned short family; /* AF_INET | AF_INET6 */ + unsigned short bitlen; /* same as mask? */ + int ref_count; /* reference count */ + struct in_addr sin; +} prefix4_t; + +typedef struct the_prefix_t { + unsigned short family; /* AF_INET | AF_INET6 */ + unsigned short bitlen; /* same as mask? */ + int ref_count; /* reference count */ + union { + struct in_addr sin; +#ifdef HAVE_IPV6 + struct in6_addr sin6; +#endif /* IPV6 */ + } add; +} prefix_t; + +/* } */ + +/* pointer to usr data (ex. route flap info) */ +union patricia_node_value_t { + void *user_data; + u_int32_t user_value; +}; + +typedef struct _patricia_node_t { + u_int bit; /* flag if this node used */ + prefix_t *prefix; /* who we are in patricia tree */ + struct _patricia_node_t *l, *r; /* left and right children */ + struct _patricia_node_t *parent;/* may be used */ + void *data; /* pointer to data */ + union patricia_node_value_t value; +} patricia_node_t; + +typedef struct _patricia_tree_t { + patricia_node_t *head; + u_int maxbits; /* for IP, 32 bit addresses */ + int num_active_node; /* for debug purpose */ +} patricia_tree_t; + +typedef void (*void_fn_t)(void *data); +typedef void (*void_fn2_t)(prefix_t *prefix, void *data); + +/* renamed to ndpi_Patricia to avoid name conflicts */ +patricia_node_t *ndpi_patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix); +patricia_node_t *ndpi_patricia_search_best (patricia_tree_t *patricia, prefix_t *prefix); +patricia_node_t * ndpi_patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, + int inclusive); +patricia_node_t *ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix); +void ndpi_patricia_remove (patricia_tree_t *patricia, patricia_node_t *node); +patricia_tree_t *ndpi_New_Patricia (int maxbits); +void ndpi_Clear_Patricia (patricia_tree_t *patricia, void_fn_t func); +void ndpi_Destroy_Patricia (patricia_tree_t *patricia, void_fn_t func); +void ndpi_patricia_process (patricia_tree_t *patricia, void_fn2_t func); + +#define PATRICIA_MAXBITS (sizeof(struct in6_addr) * 8) +#define PATRICIA_NBIT(x) (0x80 >> ((x) & 0x7f)) +#define PATRICIA_NBYTE(x) ((x) >> 3) + +#define PATRICIA_DATA_GET(node, type) (type *)((node)->data) +#define PATRICIA_DATA_SET(node, value) ((node)->data = (void *)(value)) + +#define PATRICIA_WALK(Xhead, Xnode) \ + do { \ + patricia_node_t *Xstack[PATRICIA_MAXBITS+1]; \ + patricia_node_t **Xsp = Xstack; \ + patricia_node_t *Xrn = (Xhead); \ + while ((Xnode = Xrn)) { \ + if (Xnode->prefix) + +#define PATRICIA_WALK_ALL(Xhead, Xnode) \ + do { \ + patricia_node_t *Xstack[PATRICIA_MAXBITS+1]; \ + patricia_node_t **Xsp = Xstack; \ + patricia_node_t *Xrn = (Xhead); \ + while ((Xnode = Xrn)) { \ + if (1) + +#define PATRICIA_WALK_BREAK { \ + if (Xsp != Xstack) { \ + Xrn = *(--Xsp); \ + } else { \ + Xrn = (patricia_node_t *) 0; \ + } \ + continue; } + +#define PATRICIA_WALK_END \ + if (Xrn->l) { \ + if (Xrn->r) { \ + *Xsp++ = Xrn->r; \ + } \ + Xrn = Xrn->l; \ + } else if (Xrn->r) { \ + Xrn = Xrn->r; \ + } else if (Xsp != Xstack) { \ + Xrn = *(--Xsp); \ + } else { \ + Xrn = (patricia_node_t *) 0; \ + } \ + } \ + } while (0) + +#endif /* _PATRICIA_H */ + +/************************* + + + [newtool.gif] + +MRT Credits + + The Multi-Threaded Routing Toolkit + _________________________________________________________________ + + MRT was developed by [1]Merit Network, Inc., under National Science + Foundation grant NCR-9318902, "Experimentation with Routing Technology + to be Used for Inter-Domain Routing in the Internet." + + Current MRT Staff + + * [2]Craig Labovitz <labovit@merit.edu> + * [3]Makaki Hirabaru <masaki@merit.edu> + * [4]Farnam Jahanian <farnam@eecs.umich.edu> + * Susan Hares <skh@merit.edu> + * Susan R. Harris <srh@merit.edu> + * Nathan Binkert <binkertn@eecs.umich.edu> + * Gerald Winters <gerald@merit.edu> + + Project Alumni + + * [5]Marc Unangst <mju@merit.edu> + * John Scudder <jgs@ieng.com> + + The BGP4+ extension was originally written by Francis Dupont + <Francis.Dupont@inria.fr>. + + The public domain Struct C-library of linked list, hash table and + memory allocation routines was developed by Jonathan Dekock + <dekock@cadence.com>. + + Susan Rebecca Harris <srh@merit.edu> provided help with the + documentation. + David Ward <dward@netstar.com> provided bug fixes and helpful + suggestions. + Some sections of code and architecture ideas were taken from the GateD + routing daemon. + + The first port to Linux with IPv6 was done by Pedro Roque + <roque@di.fc.ul.pt>. Some interface routines to the Linux kernel were + originally written by him. + + Alexey Kuznetsov made enhancements to 1.4.3a and fixed the Linux + kernel intarface. Linux's netlink interface was written, referring to + his code "iproute2". + + We would also like to thank our other colleagues in Japan, Portugal, + the Netherlands, the UK, and the US for their many contributions to + the MRT development effort. + _________________________________________________________________ + + Cisco is a registered trademark of Cisco Systems Inc. + _________________________________________________________________ + + Merit Network 4251 Plymouth Road Suite C Ann Arbor, MI 48105-2785 + 734-764-9430 + info@merit.edu + _________________________________________________________________ + + © 1999 Merit Network, Inc. + [6]www@merit.edu + +References + + 1. http://www.merit.edu/ + 2. http://www.merit.edu/~labovit + 3. http://www.merit.edu/~masaki + 4. http://www.eecs.umich.edu/~farnam + 5. http://www.contrib.andrew.cmu.edu/~mju/ + 6. mailto:www@merit.edu + +------------ + +Copyright (c) 1997, 1998, 1999 + + +The Regents of the University of Michigan ("The Regents") and Merit Network, +Inc. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. +2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. +3. All advertising materials mentioning features or use of + this software must display the following acknowledgement: +This product includes software developed by the University of Michigan, Merit +Network, Inc., and their contributors. +4. Neither the name of the University, Merit Network, nor the + names of their contributors may be used to endorse or + promote products derived from this software without + specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +************************ */ diff --git a/src/lib/third_party/include/sort.h b/src/lib/third_party/include/sort.h new file mode 100644 index 000000000..ee7df8a10 --- /dev/null +++ b/src/lib/third_party/include/sort.h @@ -0,0 +1,6 @@ +/* This is a function ported from the Linux kernel lib/sort.c */ + +void sort(void *base, size_t num, size_t len, + int (*cmp_func)(const void *, const void *), + void (*swap_func)(void *, void *, int size)); + diff --git a/src/lib/third_party/src/ahocorasick.c b/src/lib/third_party/src/ahocorasick.c new file mode 100644 index 000000000..54a97e776 --- /dev/null +++ b/src/lib/third_party/src/ahocorasick.c @@ -0,0 +1,391 @@ +/* + * ahocorasick.c: implementation of ahocorasick library's functions + * This file is part of multifast. + * + Copyright 2010-2012 Kamiar Kanani <kamiar.kanani@gmail.com> + + multifast is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + multifast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with multifast. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __KERNEL__ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#endif + +#include "ndpi_api.h" +#include "ahocorasick.h" + +/* Allocation step for automata.all_nodes */ +#define REALLOC_CHUNK_ALLNODES 200 + +/* Private function prototype */ +static void ac_automata_register_nodeptr +(AC_AUTOMATA_t * thiz, AC_NODE_t * node); +static void ac_automata_union_matchstrs +(AC_NODE_t * node); +static void ac_automata_set_failure +(AC_AUTOMATA_t * thiz, AC_NODE_t * node, AC_ALPHABET_t * alphas); +static void ac_automata_traverse_setfailure +(AC_AUTOMATA_t * thiz, AC_NODE_t * node, AC_ALPHABET_t * alphas); + + +/****************************************************************************** + * FUNCTION: ac_automata_init + * Initialize automata; allocate memories and set initial values + * PARAMS: + * MATCH_CALBACK mc: call-back function + * the call-back function will be used to reach the caller on match occurrence + ******************************************************************************/ +AC_AUTOMATA_t * ac_automata_init (MATCH_CALBACK_f mc) +{ + AC_AUTOMATA_t * thiz = (AC_AUTOMATA_t *)ndpi_malloc(sizeof(AC_AUTOMATA_t)); + memset (thiz, 0, sizeof(AC_AUTOMATA_t)); + thiz->root = node_create (); + thiz->all_nodes_max = REALLOC_CHUNK_ALLNODES; + thiz->all_nodes = (AC_NODE_t **) ndpi_malloc (thiz->all_nodes_max*sizeof(AC_NODE_t *)); + thiz->match_callback = mc; + ac_automata_register_nodeptr (thiz, thiz->root); + ac_automata_reset (thiz); + thiz->total_patterns = 0; + thiz->automata_open = 1; + return thiz; +} + +/****************************************************************************** + * FUNCTION: ac_automata_add + * Adds pattern to the automata. + * PARAMS: + * AC_AUTOMATA_t * thiz: the pointer to the automata + * AC_PATTERN_t * patt: the pointer to added pattern + * RETUERN VALUE: AC_ERROR_t + * the return value indicates the success or failure of adding action + ******************************************************************************/ +AC_ERROR_t ac_automata_add (AC_AUTOMATA_t * thiz, AC_PATTERN_t * patt) +{ + unsigned int i; + AC_NODE_t * n = thiz->root; + AC_NODE_t * next; + AC_ALPHABET_t alpha; + + if(!thiz->automata_open) + return ACERR_AUTOMATA_CLOSED; + + if (!patt->length) + return ACERR_ZERO_PATTERN; + + if (patt->length > AC_PATTRN_MAX_LENGTH) + return ACERR_LONG_PATTERN; + + for (i=0; i<patt->length; i++) + { + alpha = patt->astring[i]; + if ((next = node_find_next(n, alpha))) + { + n = next; + continue; + } + else + { + next = node_create_next(n, alpha); + next->depth = n->depth + 1; + n = next; + ac_automata_register_nodeptr(thiz, n); + } + } + + if(n->final) + return ACERR_DUPLICATE_PATTERN; + + n->final = 1; + node_register_matchstr(n, patt); + thiz->total_patterns++; + + return ACERR_SUCCESS; +} + +/****************************************************************************** + * FUNCTION: ac_automata_finalize + * Locate the failure node for all nodes and collect all matched pattern for + * every node. it also sorts outgoing edges of node, so binary search could be + * performed on them. after calling this function the automate literally will + * be finalized and you can not add new patterns to the automate. + * PARAMS: + * AC_AUTOMATA_t * thiz: the pointer to the automata + ******************************************************************************/ +void ac_automata_finalize (AC_AUTOMATA_t * thiz) +{ + unsigned int i; + AC_ALPHABET_t *alphas; + AC_NODE_t * node; + + if((alphas = ndpi_malloc(AC_PATTRN_MAX_LENGTH)) != NULL) { + ac_automata_traverse_setfailure (thiz, thiz->root, alphas); + + for (i=0; i < thiz->all_nodes_num; i++) + { + node = thiz->all_nodes[i]; + ac_automata_union_matchstrs (node); + node_sort_edges (node); + } + thiz->automata_open = 0; /* do not accept patterns any more */ + ndpi_free(alphas); + } +} + +/****************************************************************************** + * FUNCTION: ac_automata_search + * Search in the input text using the given automata. on match event it will + * call the call-back function. and the call-back function in turn after doing + * its job, will return an integer value to ac_automata_search(). 0 value means + * continue search, and non-0 value means stop search and return to the caller. + * PARAMS: + * AC_AUTOMATA_t * thiz: the pointer to the automata + * AC_TEXT_t * txt: the input text that must be searched + * void * param: this parameter will be send to call-back function. it is + * useful for sending parameter to call-back function from caller function. + * RETURN VALUE: + * -1: failed call; automata is not finalized + * 0: success; continue searching; call-back sent me a 0 value + * 1: success; stop searching; call-back sent me a non-0 value + ******************************************************************************/ +int ac_automata_search (AC_AUTOMATA_t * thiz, AC_TEXT_t * txt, void * param) +{ + unsigned long position; + AC_NODE_t *curr; + AC_NODE_t *next; + + if(thiz->automata_open) + /* you must call ac_automata_locate_failure() first */ + return -1; + + position = 0; + curr = thiz->current_node; + + /* This is the main search loop. + * it must be keep as lightweight as possible. */ + while (position < txt->length) + { + if(!(next = node_findbs_next(curr, txt->astring[position]))) + { + if(curr->failure_node /* we are not in the root node */) + curr = curr->failure_node; + else + position++; + } + else + { + curr = next; + position++; + } + + if(curr->final && next) + /* We check 'next' to find out if we came here after a alphabet + * transition or due to a fail. in second case we should not report + * matching because it was reported in previous node */ + { + thiz->match.position = position + thiz->base_position; + thiz->match.match_num = curr->matched_patterns_num; + thiz->match.patterns = curr->matched_patterns; + /* we found a match! do call-back */ + if (thiz->match_callback(&thiz->match, param)) + return 1; + } + } + + /* save status variables */ + thiz->current_node = curr; + thiz->base_position += position; + return 0; +} + +/****************************************************************************** + * FUNCTION: ac_automata_reset + * reset the automata and make it ready for doing new search on a new text. + * when you finished with the input text, you must reset automata state for + * new input, otherwise it will not work. + * PARAMS: + * AC_AUTOMATA_t * thiz: the pointer to the automata + ******************************************************************************/ +void ac_automata_reset (AC_AUTOMATA_t * thiz) +{ + thiz->current_node = thiz->root; + thiz->base_position = 0; +} + +/****************************************************************************** + * FUNCTION: ac_automata_release + * Release all allocated memories to the automata + * PARAMS: + * AC_AUTOMATA_t * thiz: the pointer to the automata + ******************************************************************************/ +void ac_automata_release (AC_AUTOMATA_t * thiz) +{ + unsigned int i; + AC_NODE_t * n; + + for (i=0; i < thiz->all_nodes_num; i++) + { + n = thiz->all_nodes[i]; + node_release(n); + } + ndpi_free(thiz->all_nodes); + ndpi_free(thiz); +} + +#ifndef __KERNEL__ +/****************************************************************************** + * FUNCTION: ac_automata_display + * Prints the automata to output in human readable form. it is useful for + * debugging purpose. + * PARAMS: + * AC_AUTOMATA_t * thiz: the pointer to the automata + * char repcast: 'n': print AC_REP_t as number, 's': print AC_REP_t as string + ******************************************************************************/ +void ac_automata_display (AC_AUTOMATA_t * thiz, char repcast) +{ + unsigned int i, j; + AC_NODE_t * n; + struct edge * e; + AC_PATTERN_t sid; + + printf("---------------------------------\n"); + + for (i=0; i<thiz->all_nodes_num; i++) + { + n = thiz->all_nodes[i]; + printf("NODE(%3d)/----fail----> NODE(%3d)\n", + n->id, (n->failure_node)?n->failure_node->id:1); + for (j=0; j<n->outgoing_degree; j++) + { + e = &n->outgoing[j]; + printf(" |----("); + if(isgraph(e->alpha)) + printf("%c)---", e->alpha); + else + printf("0x%x)", e->alpha); + printf("--> NODE(%3d)\n", e->next->id); + } + if (n->matched_patterns_num) { + printf("Accepted patterns: {"); + for (j=0; j<n->matched_patterns_num; j++) + { + sid = n->matched_patterns[j]; + if(j) printf(", "); + switch (repcast) + { + case 'n': + printf("%ld", sid.rep.number); + break; + case 's': + printf("%s", sid.rep.stringy); + break; + } + } + printf("}\n"); + } + printf("---------------------------------\n"); + } +} +#endif /* __KERNEL__ */ + +/****************************************************************************** + * FUNCTION: ac_automata_register_nodeptr + * Adds the node pointer to all_nodes. + ******************************************************************************/ +static void ac_automata_register_nodeptr (AC_AUTOMATA_t * thiz, AC_NODE_t * node) +{ + if(thiz->all_nodes_num >= thiz->all_nodes_max) + { + thiz->all_nodes = ndpi_realloc(thiz->all_nodes, + thiz->all_nodes_max*sizeof(AC_NODE_t *), + (REALLOC_CHUNK_ALLNODES+thiz->all_nodes_max)*sizeof(AC_NODE_t *) + ); + thiz->all_nodes_max += REALLOC_CHUNK_ALLNODES; + } + thiz->all_nodes[thiz->all_nodes_num++] = node; +} + +/****************************************************************************** + * FUNCTION: ac_automata_union_matchstrs + * Collect accepted patterns of the node. the accepted patterns consist of the + * node's own accepted pattern plus accepted patterns of its failure node. + ******************************************************************************/ +static void ac_automata_union_matchstrs (AC_NODE_t * node) +{ + unsigned int i; + AC_NODE_t * m = node; + + while ((m = m->failure_node)) + { + for (i=0; i < m->matched_patterns_num; i++) + node_register_matchstr(node, &(m->matched_patterns[i])); + + if (m->final) + node->final = 1; + } + // TODO : sort matched_patterns? is that necessary? I don't think so. +} + +/****************************************************************************** + * FUNCTION: ac_automata_set_failure + * find failure node for the given node. + ******************************************************************************/ +static void ac_automata_set_failure +(AC_AUTOMATA_t * thiz, AC_NODE_t * node, AC_ALPHABET_t * alphas) +{ + unsigned int i, j; + AC_NODE_t * m; + + for (i=1; i < node->depth; i++) + { + m = thiz->root; + for (j=i; j < node->depth && m; j++) + m = node_find_next (m, alphas[j]); + if (m) + { + node->failure_node = m; + break; + } + } + if (!node->failure_node) + node->failure_node = thiz->root; +} + +/****************************************************************************** + * FUNCTION: ac_automata_traverse_setfailure + * Traverse all automata nodes using DFS (Depth First Search), meanwhile it set + * the failure node for every node it passes through. this function must be + * called after adding last pattern to automata. i.e. after calling this you + * can not add further pattern to automata. + ******************************************************************************/ +static void ac_automata_traverse_setfailure +(AC_AUTOMATA_t * thiz, AC_NODE_t * node, AC_ALPHABET_t * alphas) +{ + unsigned int i; + AC_NODE_t * next; + + for (i=0; i < node->outgoing_degree; i++) + { + alphas[node->depth] = node->outgoing[i].alpha; + next = node->outgoing[i].next; + + /* At every node look for its failure node */ + ac_automata_set_failure (thiz, next, alphas); + + /* Recursively call itself to traverse all nodes */ + ac_automata_traverse_setfailure (thiz, next, alphas); + } +} diff --git a/src/lib/third_party/src/node.c b/src/lib/third_party/src/node.c new file mode 100644 index 000000000..404fb24d4 --- /dev/null +++ b/src/lib/third_party/src/node.c @@ -0,0 +1,260 @@ +/* + * node.c: implementation of automata node + * This file is part of multifast. + * + Copyright 2010-2012 Kamiar Kanani <kamiar.kanani@gmail.com> + + multifast is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + multifast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with multifast. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __KERNEL__ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#endif + +#include "ndpi_api.h" + +#include "../include/node.h" +#include "sort.h" + +/* reallocation step for AC_NODE_t.matched_patterns */ +#define REALLOC_CHUNK_MATCHSTR 8 + +/* reallocation step for AC_NODE_t.outgoing array */ +#define REALLOC_CHUNK_OUTGOING 8 +/* TODO: For different depth of node, number of outgoing edges differs + considerably, It is efficient to use different chunk size for + different depths */ + +/* Private function prototype */ +void node_init (AC_NODE_t * thiz); +int node_edge_compare (const void * l, const void * r); +int node_has_matchstr (AC_NODE_t * thiz, AC_PATTERN_t * newstr); + + +/****************************************************************************** + * FUNCTION: node_create + * Create the node + ******************************************************************************/ +AC_NODE_t * node_create(void) +{ + AC_NODE_t * thiz = (AC_NODE_t *) ndpi_malloc (sizeof(AC_NODE_t)); + node_init(thiz); + node_assign_id(thiz); + return thiz; +} + +/****************************************************************************** + * FUNCTION: node_init + * Initialize node + ******************************************************************************/ +void node_init(AC_NODE_t * thiz) +{ + memset(thiz, 0, sizeof(AC_NODE_t)); + + thiz->outgoing_max = REALLOC_CHUNK_OUTGOING; + thiz->outgoing = (struct edge *) ndpi_malloc + (thiz->outgoing_max*sizeof(struct edge)); + + thiz->matched_patterns_max = REALLOC_CHUNK_MATCHSTR; + thiz->matched_patterns = (AC_PATTERN_t *) ndpi_malloc + (thiz->matched_patterns_max*sizeof(AC_PATTERN_t)); +} + +/****************************************************************************** + * FUNCTION: node_release + * Release node + ******************************************************************************/ +void node_release(AC_NODE_t * thiz) +{ + ndpi_free(thiz->matched_patterns); + ndpi_free(thiz->outgoing); + ndpi_free(thiz); +} + +/****************************************************************************** + * FUNCTION: node_find_next + * Find out the next node for a given Alpha to move. this function is used in + * the pre-processing stage in which edge array is not sorted. so it uses + * linear search. + ******************************************************************************/ +AC_NODE_t * node_find_next(AC_NODE_t * thiz, AC_ALPHABET_t alpha) +{ + int i; + + for (i=0; i < thiz->outgoing_degree; i++) + { + if(thiz->outgoing[i].alpha == alpha) + return (thiz->outgoing[i].next); + } + return NULL; +} + +/****************************************************************************** + * FUNCTION: node_findbs_next + * Find out the next node for a given Alpha. this function is used after the + * pre-processing stage in which we sort edges. so it uses Binary Search. + ******************************************************************************/ +AC_NODE_t * node_findbs_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha) +{ + int min, max, mid; + AC_ALPHABET_t amid; + + min = 0; + max = thiz->outgoing_degree - 1; + + while (min <= max) + { + mid = (min+max) >> 1; + amid = thiz->outgoing[mid].alpha; + if (alpha > amid) + min = mid + 1; + else if (alpha < amid) + max = mid - 1; + else + return (thiz->outgoing[mid].next); + } + return NULL; +} + +/****************************************************************************** + * FUNCTION: node_has_matchstr + * Determine if a final node contains a pattern in its accepted pattern list + * or not. return values: 1 = it has, 0 = it hasn't + ******************************************************************************/ +int node_has_matchstr (AC_NODE_t * thiz, AC_PATTERN_t * newstr) +{ + int i, j; + AC_PATTERN_t * str; + + for (i=0; i < thiz->matched_patterns_num; i++) + { + str = &thiz->matched_patterns[i]; + + if (str->length != newstr->length) + continue; + + for (j=0; j<(int)str->length; j++) + if(str->astring[j] != newstr->astring[j]) + continue; + + if (j == str->length) + return 1; + } + return 0; +} + +/****************************************************************************** + * FUNCTION: node_create_next + * Create the next node for the given alpha. + ******************************************************************************/ +AC_NODE_t * node_create_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha) +{ + AC_NODE_t * next; + next = node_find_next (thiz, alpha); + if (next) + /* The edge already exists */ + return NULL; + /* Otherwise register new edge */ + next = node_create (); + node_register_outgoing(thiz, next, alpha); + + return next; +} + +/****************************************************************************** + * FUNCTION: node_register_matchstr + * Adds the pattern to the list of accepted pattern. + ******************************************************************************/ +void node_register_matchstr (AC_NODE_t * thiz, AC_PATTERN_t * str) +{ + /* Check if the new pattern already exists in the node list */ + if (node_has_matchstr(thiz, str)) + return; + + /* Manage memory */ + if (thiz->matched_patterns_num >= thiz->matched_patterns_max) + { + thiz->matched_patterns = (AC_PATTERN_t *) ndpi_realloc + (thiz->matched_patterns, thiz->matched_patterns_max*sizeof(AC_PATTERN_t), + (REALLOC_CHUNK_MATCHSTR+thiz->matched_patterns_max)*sizeof(AC_PATTERN_t)); + + thiz->matched_patterns_max += REALLOC_CHUNK_MATCHSTR; + } + + thiz->matched_patterns[thiz->matched_patterns_num].astring = str->astring; + thiz->matched_patterns[thiz->matched_patterns_num].length = str->length; + thiz->matched_patterns[thiz->matched_patterns_num].rep = str->rep; + thiz->matched_patterns_num++; +} + +/****************************************************************************** + * FUNCTION: node_register_outgoing + * Establish an edge between two nodes + ******************************************************************************/ +void node_register_outgoing +(AC_NODE_t * thiz, AC_NODE_t * next, AC_ALPHABET_t alpha) +{ + if(thiz->outgoing_degree >= thiz->outgoing_max) + { + thiz->outgoing = (struct edge *) ndpi_realloc + (thiz->outgoing, thiz->outgoing_max*sizeof(struct edge), + (REALLOC_CHUNK_OUTGOING+thiz->outgoing_max)*sizeof(struct edge)); + thiz->outgoing_max += REALLOC_CHUNK_OUTGOING; + } + + thiz->outgoing[thiz->outgoing_degree].alpha = alpha; + thiz->outgoing[thiz->outgoing_degree++].next = next; +} + +/****************************************************************************** + * FUNCTION: node_assign_id + * assign a unique ID to the node (used for debugging purpose). + ******************************************************************************/ +void node_assign_id (AC_NODE_t * thiz) +{ + static int unique_id = 1; + thiz->id = unique_id ++; +} + +/****************************************************************************** + * FUNCTION: node_edge_compare + * Comparison function for qsort. see man qsort. + ******************************************************************************/ +int node_edge_compare (const void * l, const void * r) +{ + /* According to man page: + * The comparison function must return an integer less than, equal to, or + * greater than zero if the first argument is considered to be + * respectively less than, equal to, or greater than the second. if two + * members compare as equal, their order in the sorted array is undefined. + * + * NOTE: Because edge alphabets are unique in every node we ignore + * equivalence case. + **/ + if ( ((struct edge *)l)->alpha >= ((struct edge *)r)->alpha ) + return 1; + else + return -1; +} + +/****************************************************************************** + * FUNCTION: node_sort_edges + * sorts edges alphabets. + ******************************************************************************/ +void node_sort_edges (AC_NODE_t * thiz) +{ + sort ((void *)thiz->outgoing, thiz->outgoing_degree, sizeof(struct edge), node_edge_compare, NULL); +} diff --git a/src/lib/third_party/src/patricia.c b/src/lib/third_party/src/patricia.c new file mode 100644 index 000000000..b7b4c2010 --- /dev/null +++ b/src/lib/third_party/src/patricia.c @@ -0,0 +1,1076 @@ +/* + * $Id: patricia.c,v 1.7 2005/12/07 20:46:41 dplonka Exp $ + * Dave Plonka <plonka@doit.wisc.edu> + * + * This product includes software developed by the University of Michigan, + * Merit Network, Inc., and their contributors. + * + * This file had been called "radix.c" in the MRT sources. + * + * I renamed it to "patricia.c" since it's not an implementation of a general + * radix trie. Also I pulled in various requirements from "prefix.c" and + * "demo.c" so that it could be used as a standalone API. + + + https://github.com/deepfield/MRT/blob/master/COPYRIGHT + + Copyright (c) 1999-2013 + + The Regents of the University of Michigan ("The Regents") and Merit + Network, Inc. + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef __KERNEL__ +#include <assert.h> /* assert */ +#include <ctype.h> /* isdigit */ +#include <errno.h> /* errno */ +#include <math.h> /* sin */ +#include <stddef.h> /* NULL */ +#include <stdio.h> /* sprintf, fprintf, stderr */ +#include <stdlib.h> /* free, atol, calloc */ +#include <string.h> /* memcpy, strchr, strlen */ +#include <sys/types.h> /* BSD: for inet_addr */ +#ifndef WIN32 +#include <sys/socket.h> /* BSD, Linux: for inet_addr */ +#include <netinet/in.h> /* BSD, Linux: for inet_addr */ +#include <arpa/inet.h> /* BSD, Linux, Solaris: for inet_addr */ +#endif +#else +#define assert(a) ; +#endif /* __KERNEL__ */ + +#include "patricia.h" + +#ifdef __KERNEL__ + +long atol(const char *nptr) { + long l; + char *endp; + + l = simple_strtol(nptr, &endp, 10); + return(l); +} +#endif + +// #define PATRICIA_DEBUG + +void ndpi_DeleteEntry(void *a) { + ndpi_free(a); +} + +/* { from prefix.c */ + +/* ndpi_prefix_tochar + * convert prefix information to bytes + */ +u_char * +ndpi_prefix_tochar (prefix_t * prefix) +{ + if(prefix == NULL) + return (NULL); + + return ((u_char *) & prefix->add.sin); +} + +int ndpi_comp_with_mask (void *addr, void *dest, u_int mask) { + if( /* mask/8 == 0 || */ memcmp (addr, dest, mask / 8) == 0) { + int n = mask / 8; + int m = ((-1) << (8 - (mask % 8))); + + if(mask % 8 == 0 || (((u_char *)addr)[n] & m) == (((u_char *)dest)[n] & m)) + return (1); + } + return (0); +} + +#if 0 /* this implementation does not support IPv6, using system inet_pton */ +#ifndef WIN32 +/* inet_pton substitute implementation + * Uses inet_addr to convert an IP address in dotted decimal notation into + * unsigned long and copies the result to dst. + * Only supports AF_INET. Follows standard error return conventions of + * inet_pton. + */ +int +inet_pton (int af, const char *src, void *dst) +{ + u_long result; + + if(af == AF_INET) { + result = inet_addr(src); + if(result == -1) + return 0; + else { + memcpy (dst, &result, sizeof(struct in_addr)); + return 1; + } + } +#ifdef NT +#if defined(HAVE_IPV6) && (!defined(__KERNEL__)) + else if(af == AF_INET6) { + struct in6_addr Address; + return (inet6_addr(src, &Address)); + } +#endif /* HAVE_IPV6 */ +#endif /* NT */ +#ifndef NT + else { + printf("NOT SUPP\n"); + errno = EAFNOSUPPORT; + return -1; + } +#endif /* NT */ +} +#endif +#endif + +/* this allows imcomplete prefix */ +int +ndpi_my_inet_pton (int af, const char *src, void *dst) +{ + if(af == AF_INET) { + int i; + u_char xp[sizeof(struct in_addr)] = {0, 0, 0, 0}; + + for (i = 0; ; i++) { + int c, val; + + c = *src++; + if(!isdigit (c)) + return (-1); + val = 0; + do { + val = val * 10 + c - '0'; + if(val > 255) + return (0); + c = *src++; + } while (c && isdigit (c)); + xp[i] = val; + if(c == '\0') + break; + if(c != '.') + return (0); + if(i >= 3) + return (0); + } + memcpy (dst, xp, sizeof(struct in_addr)); + return (1); +#if defined(HAVE_IPV6) && (!defined(__KERNEL__)) + } else if(af == AF_INET6) { + return (inet_pton (af, src, dst)); +#endif /* HAVE_IPV6 */ + } else { +#ifndef NT +#ifndef __KERNEL__ + errno = EAFNOSUPPORT; +#endif +#endif /* NT */ + return -1; + } +} + +#define PATRICIA_MAX_THREADS 16 + +/* + * convert prefix information to ascii string with length + * thread safe and (almost) re-entrant implementation + */ +char * +ndpi_ndpi_prefix_toa2x (prefix_t *prefix, char *buff, int with_len) +{ + if(prefix == NULL) + return ((char*)"(Null)"); + assert (prefix->ref_count >= 0); + if(buff == NULL) { + + struct buffer { + char buffs[PATRICIA_MAX_THREADS][48+5]; + u_int i; + } *buffp; + +# if 0 + THREAD_SPECIFIC_DATA (struct buffer, buffp, 1); +# else + { /* for scope only */ + static struct buffer local_buff; + buffp = &local_buff; + } +# endif + if(buffp == NULL) { + /* XXX should we report an error? */ + return (NULL); + } + + buff = buffp->buffs[buffp->i++%PATRICIA_MAX_THREADS]; + } + if(prefix->family == AF_INET) { + u_char *a; + assert (prefix->bitlen <= sizeof(struct in_addr) * 8); + a = prefix_touchar (prefix); + if(with_len) { + sprintf (buff, "%d.%d.%d.%d/%d", a[0], a[1], a[2], a[3], + prefix->bitlen); + } + else { + sprintf (buff, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]); + } + return (buff); + } +#if defined(HAVE_IPV6) && (!defined(__KERNEL__)) + else if(prefix->family == AF_INET6) { + char *r; + r = (char *) inet_ntop (AF_INET6, &prefix->add.sin6, buff, 48 /* a guess value */ ); + if(r && with_len) { + assert (prefix->bitlen <= sizeof(struct in6_addr) * 8); + sprintf (buff + strlen (buff), "/%d", prefix->bitlen); + } + return (buff); + } +#endif /* HAVE_IPV6 */ + else + return (NULL); +} + +/* ndpi_prefix_toa2 + * convert prefix information to ascii string + */ +char * +ndpi_prefix_toa2 (prefix_t *prefix, char *buff) +{ + return (ndpi_ndpi_prefix_toa2x (prefix, buff, 0)); +} + +/* ndpi_prefix_toa + */ +char * +ndpi_prefix_toa (prefix_t * prefix) +{ + return (ndpi_prefix_toa2 (prefix, (char *) NULL)); +} + +prefix_t * +ndpi_New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix) +{ + int dynamic_allocated = 0; + int default_bitlen = sizeof(struct in_addr) * 8; + +#if defined(HAVE_IPV6) && (!defined(__KERNEL__)) + if(family == AF_INET6) { + default_bitlen = sizeof(struct in6_addr) * 8; + if(prefix == NULL) { + prefix = (prefix_t*)ndpi_calloc(1, sizeof (prefix_t)); + dynamic_allocated++; + } + memcpy (&prefix->add.sin6, dest, sizeof(struct in6_addr)); + } + else +#endif /* HAVE_IPV6 */ + if(family == AF_INET) { + if(prefix == NULL) { +#ifndef NT + prefix = (prefix_t*)ndpi_calloc(1, sizeof (prefix4_t)); +#else + //for some reason, compiler is getting + //prefix4_t size incorrect on NT + prefix = ndpi_calloc(1, sizeof (prefix_t)); +#endif /* NT */ + + dynamic_allocated++; + } + memcpy (&prefix->add.sin, dest, sizeof(struct in_addr)); + } + else { + return (NULL); + } + + prefix->bitlen = (bitlen >= 0)? bitlen: default_bitlen; + prefix->family = family; + prefix->ref_count = 0; + if(dynamic_allocated) { + prefix->ref_count++; + } + /* fprintf(stderr, "[C %s, %d]\n", ndpi_prefix_toa (prefix), prefix->ref_count); */ + return (prefix); +} + +prefix_t * +ndpi_New_Prefix (int family, void *dest, int bitlen) +{ + return (ndpi_New_Prefix2 (family, dest, bitlen, NULL)); +} + +/* ndpi_ascii2prefix + */ +prefix_t * +ndpi_ascii2prefix (int family, char *string) +{ + long bitlen; + long maxbitlen = 0; + char *cp; + struct in_addr sin; +#if defined(HAVE_IPV6) && (!defined(__KERNEL__)) + struct in6_addr sin6; +#endif /* HAVE_IPV6 */ + char save[MAXLINE]; + + if(string == NULL) + return (NULL); + + /* easy way to handle both families */ + if(family == 0) { + family = AF_INET; +#if defined(HAVE_IPV6) && (!defined(__KERNEL__)) + if(strchr (string, ':')) family = AF_INET6; +#endif /* HAVE_IPV6 */ + } + + if(family == AF_INET) { + maxbitlen = sizeof(struct in_addr) * 8; + } +#if defined(HAVE_IPV6) && (!defined(__KERNEL__)) + else if(family == AF_INET6) { + maxbitlen = sizeof(struct in6_addr) * 8; + } +#endif /* HAVE_IPV6 */ + + if((cp = strchr (string, '/')) != NULL) { + bitlen = atol (cp + 1); + /* *cp = '\0'; */ + /* copy the string to save. Avoid destroying the string */ + assert (cp - string < MAXLINE); + memcpy (save, string, cp - string); + save[cp - string] = '\0'; + string = save; + if((bitlen < 0) || (bitlen > maxbitlen)) + bitlen = maxbitlen; + } else { + bitlen = maxbitlen; + } + + if(family == AF_INET) { + if(ndpi_my_inet_pton (AF_INET, string, &sin) <= 0) + return (NULL); + return (ndpi_New_Prefix (AF_INET, &sin, bitlen)); + } + +#if defined(HAVE_IPV6) && (!defined(__KERNEL__)) + else if(family == AF_INET6) { + // Get rid of this with next IPv6 upgrade +#if defined(NT) && !defined(HAVE_INET_NTOP) + inet6_addr(string, &sin6); + return (ndpi_New_Prefix (AF_INET6, &sin6, bitlen)); +#else + if(inet_pton (AF_INET6, string, &sin6) <= 0) + return (NULL); +#endif /* NT */ + return (ndpi_New_Prefix (AF_INET6, &sin6, bitlen)); + } +#endif /* HAVE_IPV6 */ + else + return (NULL); +} + +prefix_t * +ndpi_Ref_Prefix (prefix_t * prefix) +{ + if(prefix == NULL) + return (NULL); + if(prefix->ref_count == 0) { + /* make a copy in case of a static prefix */ + return (ndpi_New_Prefix2 (prefix->family, &prefix->add, prefix->bitlen, NULL)); + } + prefix->ref_count++; + /* fprintf(stderr, "[A %s, %d]\n", ndpi_prefix_toa (prefix), prefix->ref_count); */ + return (prefix); +} + +void +ndpi_Deref_Prefix (prefix_t * prefix) +{ + if(prefix == NULL) + return; + /* for secure programming, raise an assert. no static prefix can call this */ + assert (prefix->ref_count > 0); + + prefix->ref_count--; + assert (prefix->ref_count >= 0); + if(prefix->ref_count <= 0) { + ndpi_DeleteEntry (prefix); + return; + } +} + +/* } */ + +/* #define PATRICIA_DEBUG 1 */ + +static int num_active_patricia = 0; + +/* these routines support continuous mask only */ + +patricia_tree_t * +ndpi_New_Patricia (int maxbits) +{ + patricia_tree_t *patricia = (patricia_tree_t*)ndpi_calloc(1, sizeof *patricia); + + patricia->maxbits = maxbits; + patricia->head = NULL; + patricia->num_active_node = 0; + assert((u_int)maxbits <= PATRICIA_MAXBITS); /* XXX */ + num_active_patricia++; + return (patricia); +} + + +/* + * if func is supplied, it will be called as func(node->data) + * before deleting the node + */ + +void +ndpi_Clear_Patricia (patricia_tree_t *patricia, void_fn_t func) +{ + assert (patricia); + if(patricia->head) { + + patricia_node_t *Xstack[PATRICIA_MAXBITS+1]; + patricia_node_t **Xsp = Xstack; + patricia_node_t *Xrn = patricia->head; + + while (Xrn) { + patricia_node_t *l = Xrn->l; + patricia_node_t *r = Xrn->r; + + if(Xrn->prefix) { + ndpi_Deref_Prefix (Xrn->prefix); + if(Xrn->data && func) + func (Xrn->data); + } + else { + assert (Xrn->data == NULL); + } + ndpi_DeleteEntry (Xrn); + patricia->num_active_node--; + + if(l) { + if(r) { + *Xsp++ = r; + } + Xrn = l; + } else if(r) { + Xrn = r; + } else if(Xsp != Xstack) { + Xrn = *(--Xsp); + } else { + Xrn = NULL; + } + } + } + assert (patricia->num_active_node == 0); + /* ndpi_DeleteEntry (patricia); */ +} + + +void +ndpi_Destroy_Patricia (patricia_tree_t *patricia, void_fn_t func) +{ + ndpi_Clear_Patricia (patricia, func); + ndpi_DeleteEntry (patricia); + num_active_patricia--; +} + + +/* + * if func is supplied, it will be called as func(node->prefix, node->data) + */ + +void +ndpi_patricia_process (patricia_tree_t *patricia, void_fn2_t func) +{ + patricia_node_t *node; + assert (func); + + PATRICIA_WALK (patricia->head, node) { + func (node->prefix, node->data); + } PATRICIA_WALK_END; +} + +size_t +ndpi_patricia_walk_inorder(patricia_node_t *node, void_fn2_t func) +{ + size_t n = 0; + assert(func); + + if(node->l) { + n += ndpi_patricia_walk_inorder(node->l, func); + } + + if(node->prefix) { + func(node->prefix, node->data); + n++; + } + + if(node->r) { + n += ndpi_patricia_walk_inorder(node->r, func); + } + + return n; +} + + +patricia_node_t * +ndpi_patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix) +{ + patricia_node_t *node; + u_char *addr; + u_int bitlen; + + assert (patricia); + assert (prefix); + assert (prefix->bitlen <= patricia->maxbits); + + if(patricia->head == NULL) + return (NULL); + + node = patricia->head; + addr = prefix_touchar (prefix); + bitlen = prefix->bitlen; + + while (node->bit < bitlen) { + + if(BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) { +#ifdef PATRICIA_DEBUG + if(node->prefix) + fprintf (stderr, "patricia_search_exact: take right %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_exact: take right at %u\n", + node->bit); +#endif /* PATRICIA_DEBUG */ + node = node->r; + } + else { +#ifdef PATRICIA_DEBUG + if(node->prefix) + fprintf (stderr, "patricia_search_exact: take left %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_exact: take left at %u\n", + node->bit); +#endif /* PATRICIA_DEBUG */ + node = node->l; + } + + if(node == NULL) + return (NULL); + } + +#ifdef PATRICIA_DEBUG + if(node->prefix) + fprintf (stderr, "patricia_search_exact: stop at %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_exact: stop at %u\n", node->bit); +#endif /* PATRICIA_DEBUG */ + if(node->bit > bitlen || node->prefix == NULL) + return (NULL); + assert (node->bit == bitlen); + assert (node->bit == node->prefix->bitlen); + if(ndpi_comp_with_mask (ndpi_prefix_tochar (node->prefix), ndpi_prefix_tochar (prefix), + bitlen)) { +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_search_exact: found %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + return (node); + } + return (NULL); +} + + +/* if inclusive != 0, "best" may be the given prefix itself */ +patricia_node_t * +ndpi_patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inclusive) +{ + patricia_node_t *node; + patricia_node_t *stack[PATRICIA_MAXBITS + 1]; + u_char *addr; + u_int bitlen; + int cnt = 0; + + assert (patricia); + assert (prefix); + assert (prefix->bitlen <= patricia->maxbits); + + if(patricia->head == NULL) + return (NULL); + + node = patricia->head; + addr = prefix_touchar (prefix); + bitlen = prefix->bitlen; + + while (node->bit < bitlen) { + + if(node->prefix) { +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_search_best: push %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + stack[cnt++] = node; + } + + if(BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) { +#ifdef PATRICIA_DEBUG + if(node->prefix) + fprintf (stderr, "patricia_search_best: take right %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_best: take right at %u\n", + node->bit); +#endif /* PATRICIA_DEBUG */ + node = node->r; + } + else { +#ifdef PATRICIA_DEBUG + if(node->prefix) + fprintf (stderr, "patricia_search_best: take left %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_best: take left at %u\n", + node->bit); +#endif /* PATRICIA_DEBUG */ + node = node->l; + } + + if(node == NULL) + break; + } + + if(inclusive && node && node->prefix) + stack[cnt++] = node; + +#ifdef PATRICIA_DEBUG + if(node == NULL) + fprintf (stderr, "patricia_search_best: stop at null\n"); + else if(node->prefix) + fprintf (stderr, "patricia_search_best: stop at %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_best: stop at %u\n", node->bit); +#endif /* PATRICIA_DEBUG */ + + if(cnt <= 0) + return (NULL); + + while (--cnt >= 0) { + node = stack[cnt]; +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_search_best: pop %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + if(ndpi_comp_with_mask (ndpi_prefix_tochar (node->prefix), + ndpi_prefix_tochar (prefix), + node->prefix->bitlen) && node->prefix->bitlen <= bitlen) { +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_search_best: found %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + return (node); + } + } + return (NULL); +} + + +patricia_node_t * +ndpi_patricia_search_best (patricia_tree_t *patricia, prefix_t *prefix) +{ + return (ndpi_patricia_search_best2 (patricia, prefix, 1)); +} + + +patricia_node_t * +ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) +{ + patricia_node_t *node, *new_node, *parent, *glue; + u_char *addr, *test_addr; + u_int bitlen, check_bit, differ_bit; + int i, j; + + assert (patricia); + assert (prefix); + assert (prefix->bitlen <= patricia->maxbits); + + if(patricia->head == NULL) { + node = (patricia_node_t*)ndpi_calloc(1, sizeof *node); + node->bit = prefix->bitlen; + node->prefix = ndpi_Ref_Prefix (prefix); + node->parent = NULL; + node->l = node->r = NULL; + node->data = NULL; + patricia->head = node; +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_lookup: new_node #0 %s/%d (head)\n", + ndpi_prefix_toa (prefix), prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + patricia->num_active_node++; + return (node); + } + + addr = prefix_touchar (prefix); + bitlen = prefix->bitlen; + node = patricia->head; + + while (node->bit < bitlen || node->prefix == NULL) { + + if(node->bit < patricia->maxbits && + BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) { + if(node->r == NULL) + break; +#ifdef PATRICIA_DEBUG + if(node->prefix) + fprintf (stderr, "patricia_lookup: take right %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_lookup: take right at %u\n", node->bit); +#endif /* PATRICIA_DEBUG */ + node = node->r; + } + else { + if(node->l == NULL) + break; +#ifdef PATRICIA_DEBUG + if(node->prefix) + fprintf (stderr, "patricia_lookup: take left %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_lookup: take left at %u\n", node->bit); +#endif /* PATRICIA_DEBUG */ + node = node->l; + } + + assert (node); + } + + assert (node->prefix); +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_lookup: stop at %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + + test_addr = prefix_touchar (node->prefix); + /* find the first bit different */ + check_bit = (node->bit < bitlen)? node->bit: bitlen; + differ_bit = 0; + for (i = 0; (u_int)i*8 < check_bit; i++) { + int r; + + if((r = (addr[i] ^ test_addr[i])) == 0) { + differ_bit = (i + 1) * 8; + continue; + } + /* I know the better way, but for now */ + for (j = 0; j < 8; j++) { + if(BIT_TEST (r, (0x80 >> j))) + break; + } + /* must be found */ + assert (j < 8); + differ_bit = i * 8 + j; + break; + } + if(differ_bit > check_bit) + differ_bit = check_bit; +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_lookup: differ_bit %d\n", differ_bit); +#endif /* PATRICIA_DEBUG */ + + parent = node->parent; + while (parent && parent->bit >= differ_bit) { + node = parent; + parent = node->parent; +#ifdef PATRICIA_DEBUG + if(node->prefix) + fprintf (stderr, "patricia_lookup: up to %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_lookup: up to %u\n", node->bit); +#endif /* PATRICIA_DEBUG */ + } + + if(differ_bit == bitlen && node->bit == bitlen) { + if(node->prefix) { +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_lookup: found %s/%d\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + return (node); + } + node->prefix = ndpi_Ref_Prefix (prefix); +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_lookup: new node #1 %s/%d (glue mod)\n", + ndpi_prefix_toa (prefix), prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + assert (node->data == NULL); + return (node); + } + + new_node = (patricia_node_t*)ndpi_calloc(1, sizeof *new_node); + new_node->bit = prefix->bitlen; + new_node->prefix = ndpi_Ref_Prefix (prefix); + new_node->parent = NULL; + new_node->l = new_node->r = NULL; + new_node->data = NULL; + patricia->num_active_node++; + + if(node->bit == differ_bit) { + new_node->parent = node; + if(node->bit < patricia->maxbits && + BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) { + assert (node->r == NULL); + node->r = new_node; + } + else { + assert (node->l == NULL); + node->l = new_node; + } +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_lookup: new_node #2 %s/%d (child)\n", + ndpi_prefix_toa (prefix), prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + return (new_node); + } + + if(bitlen == differ_bit) { + if(bitlen < patricia->maxbits && + BIT_TEST (test_addr[bitlen >> 3], 0x80 >> (bitlen & 0x07))) { + new_node->r = node; + } + else { + new_node->l = node; + } + new_node->parent = node->parent; + if(node->parent == NULL) { + assert (patricia->head == node); + patricia->head = new_node; + } + else if(node->parent->r == node) { + node->parent->r = new_node; + } + else { + node->parent->l = new_node; + } + node->parent = new_node; +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_lookup: new_node #3 %s/%d (parent)\n", + ndpi_prefix_toa (prefix), prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + } + else { + glue = (patricia_node_t*)ndpi_calloc(1, sizeof *glue); + glue->bit = differ_bit; + glue->prefix = NULL; + glue->parent = node->parent; + glue->data = NULL; + patricia->num_active_node++; + if(differ_bit < patricia->maxbits && + BIT_TEST (addr[differ_bit >> 3], 0x80 >> (differ_bit & 0x07))) { + glue->r = new_node; + glue->l = node; + } + else { + glue->r = node; + glue->l = new_node; + } + new_node->parent = glue; + + if(node->parent == NULL) { + assert (patricia->head == node); + patricia->head = glue; + } + else if(node->parent->r == node) { + node->parent->r = glue; + } + else { + node->parent->l = glue; + } + node->parent = glue; +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_lookup: new_node #4 %s/%d (glue+node)\n", + ndpi_prefix_toa (prefix), prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + } + return (new_node); +} + + +void +ndpi_patricia_remove (patricia_tree_t *patricia, patricia_node_t *node) +{ + patricia_node_t *parent, *child; + + assert (patricia); + assert (node); + + if(node->r && node->l) { +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_remove: #0 %s/%d (r & l)\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + + /* this might be a placeholder node -- have to check and make sure + * there is a prefix aossciated with it ! */ + if(node->prefix != NULL) + ndpi_Deref_Prefix (node->prefix); + node->prefix = NULL; + /* Also I needed to clear data pointer -- masaki */ + node->data = NULL; + return; + } + + if(node->r == NULL && node->l == NULL) { +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_remove: #1 %s/%d (!r & !l)\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + parent = node->parent; + ndpi_Deref_Prefix (node->prefix); + ndpi_DeleteEntry (node); + patricia->num_active_node--; + + if(parent == NULL) { + assert (patricia->head == node); + patricia->head = NULL; + return; + } + + if(parent->r == node) { + parent->r = NULL; + child = parent->l; + } + else { + assert (parent->l == node); + parent->l = NULL; + child = parent->r; + } + + if(parent->prefix) + return; + + /* we need to remove parent too */ + + if(parent->parent == NULL) { + assert (patricia->head == parent); + patricia->head = child; + } + else if(parent->parent->r == parent) { + parent->parent->r = child; + } + else { + assert (parent->parent->l == parent); + parent->parent->l = child; + } + child->parent = parent->parent; + ndpi_DeleteEntry (parent); + patricia->num_active_node--; + return; + } + +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_remove: #2 %s/%d (r ^ l)\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + if(node->r) { + child = node->r; + } + else { + assert (node->l); + child = node->l; + } + parent = node->parent; + child->parent = parent; + + ndpi_Deref_Prefix (node->prefix); + ndpi_DeleteEntry (node); + patricia->num_active_node--; + + if(parent == NULL) { + assert (patricia->head == node); + patricia->head = child; + return; + } + + if(parent->r == node) { + parent->r = child; + } + else { + assert (parent->l == node); + parent->l = child; + } +} + +/* { from demo.c */ +#if 0 + +patricia_node_t * +ndpi_make_and_lookup (patricia_tree_t *tree, char *string) +{ + prefix_t *prefix; + patricia_node_t *node; + + prefix = ndpi_ascii2prefix (AF_INET, string); + printf ("make_and_lookup: %s/%d\n", ndpi_prefix_toa (prefix), prefix->bitlen); + node = ndpi_patricia_lookup (tree, prefix); + ndpi_Deref_Prefix (prefix); + return (node); +} + +patricia_node_t * +ndpi_try_search_exact (patricia_tree_t *tree, char *string) +{ + prefix_t *prefix; + patricia_node_t *node; + + prefix = ndpi_ascii2prefix (AF_INET, string); + printf ("try_search_exact: %s/%d\n", ndpi_prefix_toa (prefix), prefix->bitlen); + if((node = patricia_search_exact (tree, prefix)) == NULL) { + printf ("try_search_exact: not found\n"); + } + else { + printf ("try_search_exact: %s/%d found\n", + ndpi_prefix_toa (node->prefix), node->prefix->bitlen); + } + ndpi_Deref_Prefix (prefix); + return (node); +} + +void +ndpi_lookup_then_remove (patricia_tree_t *tree, char *string) +{ + patricia_node_t *node; + + if((node = try_search_exact (tree, string))) + patricia_remove (tree, node); +} +#endif + +/* } */ diff --git a/src/lib/third_party/src/sort.c b/src/lib/third_party/src/sort.c new file mode 100644 index 000000000..d6545e85a --- /dev/null +++ b/src/lib/third_party/src/sort.c @@ -0,0 +1,130 @@ +/* + * A fast, small, non-recursive O(nlog n) sort for the Linux kernel + * + * Jan 23 2005 Matt Mackall <mpm@selenic.com> + */ + +#ifdef __KERNEL__ +#include <linux/types.h> +#else +#ifdef WIN32 +#include <stdint.h> +typedef uint32_t u_int32_t; +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#endif + +/* This is a function ported from the Linux kernel lib/sort.c */ + +static void u_int32_t_swap(void *a, void *b, int size) +{ + u_int32_t t = *(u_int32_t *)a; + *(u_int32_t *)a = *(u_int32_t *)b; + *(u_int32_t *)b = t; +} + +static void generic_swap(void *_a, void *_b, int size) +{ + char t; + char *a = (char*)_a; + char *b = (char*)_b; + + do { + t = *a; + *a++ = *b; + *b++ = t; + } while (--size > 0); +} + +/** + * sort - sort an array of elements + * @base: pointer to data to sort + * @num: number of elements + * @size: size of each element + * @cmp_func: pointer to comparison function + * @swap_func: pointer to swap function or NULL + * + * This function does a heapsort on the given array. You may provide a + * swap_func function optimized to your element type. + * + * Sorting time is O(n log n) both on average and worst-case. While + * qsort is about 20% faster on average, it suffers from exploitable + * O(n*n) worst-case behavior and extra memory requirements that make + * it less suitable for kernel use. + */ + +void sort(void *_base, size_t num, size_t size, + int (*cmp_func)(const void *, const void *), + void (*swap_func)(void *, void *, int size)) +{ + /* pre-scale counters for performance */ + int i = (num/2 - 1) * size, n = num * size, c, r; + char *base = (char*)_base; + + if (!swap_func) + swap_func = (size == 4 ? u_int32_t_swap : generic_swap); + + /* heapify */ + for ( ; i >= 0; i -= size) { + for (r = i; r * 2 + size < n; r = c) { + c = r * 2 + size; + if (c < n - size && + cmp_func(base + c, base + c + size) < 0) + c += size; + if (cmp_func(base + r, base + c) >= 0) + break; + swap_func(base + r, base + c, size); + } + } + + /* sort */ + for (i = n - size; i > 0; i -= size) { + swap_func(base, base + i, size); + for (r = 0; r * 2 + size < i; r = c) { + c = r * 2 + size; + if (c < i - size && + cmp_func(base + c, base + c + size) < 0) + c += size; + if (cmp_func(base + r, base + c) >= 0) + break; + swap_func(base + r, base + c, size); + } + } +} + + +#if 0 +/* a simple boot-time regression test */ + +int cmpint(const void *a, const void *b) +{ + return *(int *)a - *(int *)b; +} + +int main(int argc, char *argv[]) { + int *a, i, r = 1; + + a = ndpi_malloc(1000 * sizeof(int)); + + printf("testing sort()\n"); + + for (i = 0; i < 1000; i++) { + r = (r * 725861) % 6599; + a[i] = r; + } + + sort(a, 1000, sizeof(int), cmpint, NULL); + + for (i = 0; i < 999; i++) + if (a[i] > a[i+1]) { + printf("sort() failed!\n"); + break; + } + + return 0; +} + +#endif |