pax_global_header00006660000000000000000000000064126270505100014510gustar00rootroot0000000000000052 comment=6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/000077500000000000000000000000001262705051000173375ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/.gitignore000066400000000000000000000006351262705051000213330ustar00rootroot00000000000000*.[oa] *~ *o.cmd *.lo *.obj *o.cmd *.ko *.swp *.in *.la .libs .dirstamp stamp-h1 /configure /config.guess /config.h /config.h.in /config.sub /config.log /config.status /depcomp /install-sh /ltmain.sh /missing /Makefile /libndpi.pc /libtool /src/lib/Makefile /src/include/Makefile /example/ndpiReader /example/Makefile /aclocal.m4 /m4/libtool.m4 /m4/ltoptions.m4 /m4/ltsugar.m4 /m4/ltversion.m4 /m4/lt~obsolete.m4 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/.travis.yml000066400000000000000000000004601262705051000214500ustar00rootroot00000000000000language: c compiler: - clang - gcc install: - sudo apt-get update || true - sudo apt-get install build-essential - sudo apt-get install libpcap-dev libtool autoconf automake autogen before_script: - ./autogen.sh script: - ./configure - make after_script: - cd tests - ./do.sh nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/COPYING000066400000000000000000000167251262705051000204050ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/ChangeLog000066400000000000000000000006521262705051000211140ustar00rootroot000000000000002014-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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/INSTALL000066400000000000000000000363321262705051000203770ustar00rootroot00000000000000Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the `make install' phase executed with root privileges. 5. Optionally, type `make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior `make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type `make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide `make distcheck', which can by used by developers to test that all other targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. This is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple `-arch' options to the compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the `lipo' tool if you have problems. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of `${prefix}', so that specifying just `--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to `configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the `make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, `make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of `${prefix}'. Any directories that were specified during `configure', but not in terms of `${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the `DESTDIR' variable. For example, `make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before all installation names. The approach of `DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of `${prefix}' at `configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of `make' will be. For these packages, running `./configure --enable-silent-rules' sets the default to minimal output, which can be overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be overridden with `make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. On Haiku, software installed for all users goes in `/boot/common', not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of all of the options to `configure', and exit. `--help=short' `--help=recursive' Print a summary of the options unique to this package's `configure', and exit. The `short' variant lists options used only in the top level, while the `recursive' variant lists options also present in any nested packages. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/Makefile.am000066400000000000000000000002301262705051000213660ustar00rootroot00000000000000ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src/lib example pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libndpi.pc EXTRA_DIST = libndpi.sym autogen.sh nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/README.md000066400000000000000000000042711262705051000206220ustar00rootroot00000000000000![ntop][ntopng_logo] ![ntop][ntop_logo] # nDPI [![Build Status](https://travis-ci.org/ntop/nDPI.png?branch=master)](https://travis-ci.org/ntop/nDPI) ## What is nDPI ? nDPI is an open source LGPLv3 library for deep-packet inspection. Based on OpenDPI it includes ntop extensions. We have tried to push them into the OpenDPI source tree but nobody answered emails so we have decided to create our own source tree ### How To Compile nDPI 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) ### How To Add A New Protocol Dissector 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 ### Creating A Source File Tar Ball If you want to distribute a source tar file of nDPI do: - make dist ### Acknowledgements Many thanks to Radcom Ltd for supporting the development of nDPI. [ntopng_logo]: https://camo.githubusercontent.com/0f789abcef232035c05e0d2e82afa3cc3be46485/687474703a2f2f7777772e6e746f702e6f72672f77702d636f6e74656e742f75706c6f6164732f323031312f30382f6e746f706e672d69636f6e2d313530783135302e706e67 [ntop_logo]: https://camo.githubusercontent.com/58e2a1ecfff62d8ecc9d74633bd1013f26e06cba/687474703a2f2f7777772e6e746f702e6f72672f77702d636f6e74656e742f75706c6f6164732f323031352f30352f6e746f702e706e67 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/README.nDPI000066400000000000000000000010201262705051000210010ustar00rootroot00000000000000rerequisites for Compilation ----------------------------- Prerequisites - GNU autotools/libtool - libpcap or PF_RING (optional but recommended) On Ubuntu/Debian - apt-get install build-essential - apt-get install git autoconf automake autogen libpcap-dev libtool On Fedora/CentOS - yum groupinstall "Development tools" - yum install git autoconf automake autogen libpcap-devel libtool On MacOSX (using http://brew.sh) brew install autoconf automake libtool git On FreeBSD - pkg install autoconf automake libtool gmake git nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/README.protocols000066400000000000000000000020351262705051000222420ustar00rootroot00000000000000Tor --- 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/autogen.sh000077500000000000000000000012761262705051000213460ustar00rootroot00000000000000#!/bin/sh /bin/rm -f configure config.h config.h.in src/lib/Makefile.in AUTOCONF=$(which autoconf) AUTOMAKE=$(which automake) LIBTOOL=$(which libtool) LIBTOOLIZE=$(which libtoolize) AUTORECONF=$(which autoreconf) if test -z $AUTOCONF; then echo "autoconf is missing: please install it and try again" exit fi if test -z $AUTOMAKE; then echo "automake is missing: please install it and try again" exit fi if test -z $LIBTOOL && test -z $LIBTOOLIZE ; then echo "libtool and libtoolize is missing: please install it and try again" exit fi if test -z $AUTORECONF; then echo "autoreconf is missing: please install it and try again" exit fi autoreconf -ivf ./configure nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/configure.ac000066400000000000000000000053471262705051000216360ustar00rootroot00000000000000AC_INIT([libndpi], [1.7.1]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign subdir-objects]) LT_INIT AC_PROG_CC AX_PTHREAD if test -d ".git"; then : GIT_TAG=`git log -1 --format=%h` GIT_DATE=`git log -1 --format=%cd` # # On CentOS 6 `git rev-list HEAD --count` does not work # # GIT_NUM=`git log --pretty=oneline | wc -l | tr -d '[[:space:]]'` GIT_BRANCH=`git rev-parse --abbrev-ref HEAD` GIT_RELEASE="${PACKAGE_VERSION}-${GIT_BRANCH}-${GIT_NUM}-${GIT_TAG}" else GIT_RELEASE="${PACKAGE_VERSION}" GIT_DATE=`date` fi AC_DEFINE_UNQUOTED(NDPI_GIT_RELEASE, "${GIT_RELEASE}", [GIT Release]) AC_DEFINE_UNQUOTED(NDPI_GIT_DATE, "${GIT_DATE}", [Last GIT 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 `$PCAP_HOME/lib/pfring_config --libs`" 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 PKG_CONFIG=$(which pkg-config) 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 if ! test -z "$PKG_CONFIG"; then : CFLAGS="$CFLAGS $(pkg-config --cflags json-c)" LDFLAGS="$LDFLAGS $(pkg-config --libs json-c)" fi 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_CHECK_LIB(pthread, pthread_setaffinity_np, AC_DEFINE_UNQUOTED(HAVE_PTHREAD_SETAFFINITY_NP, 1, [libc has pthread_setaffinity_np])) AC_CONFIG_FILES([Makefile src/lib/Makefile example/Makefile libndpi.pc]) AC_CONFIG_HEADERS(config.h) AC_SUBST(GIT_RELEASE) AC_SUBST(SVN_DATE) AC_SUBST(JSON_C_LIB) AC_SUBST(PCAP_INC) AC_SUBST(PCAP_LIB) AC_SUBST(HAVE_PTHREAD_SETAFFINITY_NP) AC_OUTPUT nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/doc/000077500000000000000000000000001262705051000201045ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/doc/nDPI_QuickStartGuide.docx000066400000000000000000017746261262705051000247340ustar00rootroot00000000000000PK5FcM _rels/.relsJ1>E{7 "ҴzY`HfwC7LkQtA70)LHxM e`{Z܃*đ v~ ѧ*#Hzкؑ9ZA'{HN 3;՝ :Ԗ3-RY|DusDSɠ/ ~/}-==rɋNBё)]3Oķggeg_yPK5FI+docProps/core.xmlmj@ E -;RLJ!43`wbRsWOgq1 5-T(Zߞ'DMfe~Gc⬎* =ΪG:7"3foydˌ}DjQWaV#+-E` ybA-,J^ĭ<ͼ]Ï2v;1PK5F; |docProps/app.xmlν 0ݫgoSDJ.PCrIȉ{#t[ĊgO ex;Өߊ N^<G0YdXRd3\L >:0zrHI,qKHm~ |zM֛?~{ȞloPK5F|A ;word/document.xml}v8y ζK^fv9wO;igUSS2EвzǘϙQIFY%YݕI _lD˟cSvrj"] 29qn'᫝RI>/kST?f^4aoKB-2*r܉[4熴lKA(&L[v۔i3«(OV  u FerK񬘗 Sͅ8Z4`֚kc( iL3mFLP=fjfӻT)!m鋐=Mzvjs_W19ޫ 踷;} |%T:W.sɹquˬTr:|K12-t{bokwEj(~l@+k(m@JoZ9O$_ yf:'I7ʵ[9xm(XHNɩmݫɚ~ CXXytǒ0Uā!nR4i[[#Ux w{z(q5<vs^LJsK|:8=Ex<꜃c#nE[y{62y\Rv?F NDH\.յF|T)ه? y>ޟ] iκ'kjT-֪ǥZeYK;=2~]3-X;z|cG`ܛou N!9>6NėFC2Z>5=%W?m34ErxxP?o0X)E=bX(k8kPG QCĂ"4{4n"jΦZWrʥM\ >a.W$Ʉ`j|42ð7ћ 2ͣJ=>,-jQRuZ2n*?8 ¹ pb|X)tHnS=i^GJ;Be/ӓ{VkUD!;* Kς?\>O4ō:7\7aoaF{<=f>@[1!q.|>פ rZ𱡿U} lӓF؆z8yCh6@.pޥM˞O:@cbC$ _@!R<|tވ'Ho+,4IeȀdYc2C씜zH|D-ќۤZgSs0@qL8& DŽc1ᘞ~ߙRDŽc1pLˑOk:t쵚%s~ڰYhC:Z2RXB.Ӂӱ,6-pYFޒlQȀ:N2;?YSr񠸦U`|#4luW#E때 N@=wT7`qxG~HbFb݇\!.ŧZ{_p@8 = bQ\I{ `/7Cf|K?FzKI#,cf.' ~܆t'kBۋ-Nr#4a fB)^BӲv&}ZZ?-0ȖFz} 0%vnNi5ǐ508lCJDMy?W_W#Rzk):|=cMy|ÃS\0,e$Vf"ign0_Zi[e1wys?~|_N=Ap:W":; ;`5eWTeu@YُZ[[#R蠺4KF8f%Rt/N\`A(Q2>!O>~Jȕٕ\1m~<(y% KxV9IE]1lb7nj|2؍ Dڝ`kh8y*h8T0􂹠y ȉhHY#fc8z~bSܡE,iȩG.#u7߿9."Iu+_W1-a\dL;=A]r%a8q( vi"eŔUʦp҆Yp6óZ-H૙ܩ'5}3 WA%_S3)dMe(,,mT){ Inhi*rD9wRټ'7q'qI,ݎUrT+zeLIsR͑wy"Ha'd$5Ue_j$`M`92 I3) N]t"Qb,| a ܒs-; NQ=2R}xLTW 9#΋sF'( MVQOpfҙLNW^@/w [pM# ޸PϽH`Ozy J'51#B[jbm޹\y$"bnɱ=󉉮u\w\ZOʙ˃ *5w>0B=)@hy&ёj>I$ϑQZ,lk4Тw\ϋamzWset' )Tw|9h+4 ^m>SfuvB1S/ r2iؐʈ~5E6j6naSRsv5w Fk\9dMfop8uf֥seQ?扚 `o 7*Χdd嚹+/9{K7䨰otE#Qs"0"`WZMq|;<0{P=ݗuiWEV̔7^O~xoδJIɻj5pӃѺG ՒU&Bz=q8}{wG;Kq/hKƿSa]t[:*Aidy\L!ijT,e)h?pSYRvhV#}{_OP[7&\j?pNJi'b/i#'}b_m\)m@!nl|*@~jӌ2=f`pc \h~#veVpjCnޅ"{CuWP] >BA)8d$.G֘:G 0𣌁(}n,2B~[+ мU+%nLb^&A/( e(Z$:O|'MW0|x, Jl܋'|z vI;aUUL횛~ E&{!aI>ITi&s@AHՊs+;\dLjKZjݼIoe6 ".sw{TjzTKv҅=Zb$AmlGR6cʸ(i#Ωdf`\$1t)I1Lqj⋏4kԉƦXA>^|3F“y Êܩz=jWMڹEAyDT}-+ 1 g<} [c3Ѣ֌xX(p8Sl?抐frm/MFm E$!NiBnG%z|d6 fؓ['D}[28y`N|8#Y݌rmc;V&r-{4PMR&%?e#~>x^L/C4f?/!b^kSCbGse>B[q9*cwJeROI=6ZqROkd}V;tHvAv+Tb.2Lߜ&|/I+"ܘ ; ltA#u /\rsѻ4t&CA`pj ߿뫮S;"و HU+B[_<2By[䍒j1/M&C B !`&67rn}Ov;<-39bEhC;& lJdHАv9rUk{VG=dn?3)o7{==B?{ގکNPỒ;}R^e9b$z,md gm?jgw7 i}MߟdK)5pQ:.n9kXY5yn%̌ҞxdOmKzhM*RN]{9DB*=L/p(p6JdFРQsYrDvW &Mj:*o2IT9-[yc7z"i/G_+JJ%F dP$%jegط%nWjPEQP2Ap2`6H}&`2Ae9 A u ҷr ;!B.Y;V"{M[(Ay1bn-iu$@Wo\D2Lh6wU͎Iv @j|Х!7?h#(>B _ ls'V{մ*+fdpd-~?o2Aۜ! ]a+f?2uiG̱1u8)mCplqg~VjuBf(_8#WQ=8Dk;vR'w5z>8N~=%H_L~{im#ܑ1#Ya$u">Ji .uL8eoC n ,~Xd3ODK!>\#6ўF{ њjkSN :`M&-M'G}# !l!!hfpR-ԊҏWgH[j} K#z{uQ. ?Jha3 80mĉmIQ'/.DDAqdp^ _m^ .a7M|${6|TPoUh@mhHl)9H#i;T9]_;[*{4 S÷e0"[Ch6lLlW,,xӚ >9:sŬC4PQgnAΌz.yh2+ ;915ĞMАps!{.ڈ CGƦӶZ 3{x;CFƿ'<0lVH|X,Mzv4R2鉣„'I=-Oi2¤ D8ôW>s2ȮX{rWŽ'|ҌVJ0#@ N$;$ʞ?Ȧ/X _ߟf\cl$ `lk D3FP6IҺpjL^k]u0a0B=~A~Je@@+z4?91 ZDB5!ؽbK2~q ԴrZL@wHr#DX@HvHv|3]e+͜~4bbl;lX5-@M옔 ,|]II7ƒ_tW#SFtl:Vyt% s˔F"P׈}|\E?BaT0T+Oau-]Q*]a=treVRgf؞nh 4)2Iv2wlJPI9v2QIou+pap<JX\K[MeRR2Zy.KPW>*> =<<>F{p"dcx\*V!|⾾@XXG3Ԫrպ:[˟Q(kFN?"#o'אьoR+6]D"bҏ91J7XHA R,R )NP-8^=ō-;̖jK$ZT:c~<UB랩wlDSwL iiC8FPl20cD'|;c"" D!!_zȦ/X _ߟ9ol=d%:mlhsQk;!A)LIW1T.:P&3a0z~A~JeS2WXg$"=^i͑yh#Zjyk{|pE8ϑ=i1I"$wJ#DX@HvHv|pҸ?ew!!F \,\ypF(}Bݹ:B !^ Ϊ(Ǥ}N@t`څ >%r\,2ӊhOJ(! fv @O\*V+ώpC-T||{ĒJ$ =[B5["RP;*? $Oʹ1XK 1)k`_1jo@D<n18S P@xr닎?`-a2Z5@%Vվ"d|BVUbh*@]P?]__jZ>QX+ @E"Pԫ q*vTjP.U@]&PP}K շXGh"P+1}vRoP,kÂE.OBqv ^#5]K Z*n#!!!٭}$uRhb)׎~=$Lܐ\♮@\^K/IWNV+HHXFz(b 1Hh4,VJ|>,g0CaSB Hh* zkʥ<~m6mꪮ "Vs*ATd6m;wяxB    5k ?~8xb7.*yO- xe"v޿kL$p4`6/}B=z(IK.sQA ADDDD g_ XGwr}*]՟.{J V*݈\8L%Tꪓ kƹxX *\]'UG,-WbJo)tk|̵-{5IIlDD|.۩b77ĻTኯ{s+o4^qo {¹4XKKuq֚գMr_5j:ʵV7C:ڷ3$0cy?.6(vz&@G%#^bUGU.(bColQŗ3-q3" ws1L*HO#zd㷌 TH<^n%Ȫ";dMEro7a\f%+C-i4PZ.&S%ՠ(qZޮ ATHJu}i]9lV;(b~CᷙVǛ{և63P3MNKv}ܡJLo5rdTLAK^$a#w[BT7զN(> |Wm'2\=O)r]x^=[.S7 ;ݥݾ}6_>AGL Џ]-lxڨ/[=]ky{.8S5'+ҨH{r3ӰG@h`7@]_RBo0mk3 bdI#m{`WZ鑦Ԃ;lFRz]wN wD83wL%+mg8d я:"ol*[Д~볦l-'i(b. \h6qipi ,f F:FJOzr]Ow_@5DM٣' ,NC6u'^ dB̘SGb GhAv!v 1ÀZ_]KFWL Cl-N8S 6m:7Gш'皬~Q̖ӄӝӮ^2=$-p5Wdrer%B@2!FR<O [ӡBDa|e@@!ؾSpr)!tVhr7ee 2X)a܋:b^1[.#\DQDp zmE! c5Iصgk8ۋ5{umI+O)3O E70KzfbggyG3kGOl%V1gBy%>PWgĔ|\VE }˜EL,"P!ZE~9B *A˥GUGD&uS>P[𐃡ei#n64Q7ZcxI5UչG{)4}k.ev=$vVJϽNǖSubFKQ+䥣JMv83cJG.׺ˠ'6br}8P=~1^0VscDDRvJ3'&suZ2A: TKt CЮe Tx Kzxezv`SZ=9 L JhE|wnLZFxTXOr櫸?ZƤאSe5ϖ# Ʃ495u{i}$"a&gj89l ֊9-B&I6%I섉HP(U7G0ȼD3 Tlzj ; OqՓ@ς)5 g`[*B+e1!&:j*76M4L,RCMF %!{01ImTO7sNӐko={(z401z~^0=g LyͺCsrՌns\iڞ#be |̵4553އtԄ455))fz|7P}*Eu"y*f6F# i ;X4@0FCug#n.!vwZ-moTEЇ*wZ>c_89Eي)ZQ8HFK `cݱ}2 /ܼ{KMtmCGϿ M[mZv+bέn em*8yGAn˪l׮v혛7f~)J=:-m֩# `yF9$Of";zJ GZMC7 `wH>*6ZK•qʒ\8v`vS&pKW <]OP꽿"}F>~"o3 ÷{=p9֩2യ{ҴNXN. rjk9۰BJ M5\lh)p{`:Y_xbBjPI{qZO{߷ gsj gH`3qQ(܋Ԕm&vT ,*GJo!YWȖb{_nޜ]>3m. /J߁:Wm*oQr<$hot^I:t>Ȁ9C1! Dh뽙*G"eyH4s+c@{4fN$띍hS4R Wl]O (FF#=#z{0)y:&;p!%vT7``vuRE 6o|}oM}z,ǂcXp,8QvRKO}Z81^xh!J\9ߩ CgT57ywXp`9 %*J!TvXzO`2CqL|yC,)xkPF Xߢr&ɿ?gKD>BM١PG:T+玞q`VJUg*Ar|3 ig+z-!oB Dwc {|T50jd^c{mc),L;t+PK5FwXFword/styles.xmlZKs6WpxjDJ=Q2;i<;I I@@__I=8jM](.b?.w#]SGrwk.6rGv'z=rB׽0ƐHތdޚ0f4#^q0Q8`U|(MFb2ì5NF9sٯGg3@տN\ e`d@n2אXa&tS#%;kFIõ@# x-y1&\9#wW@Gs*e}ݾ -UƷ5tVa-FJєrK(f U])JPW Qi{}MYBF*B1HHׯ!% HhN+j6 3u zf1FSab?=XՖz9a,oDJ3"9`Aل˄) k\ӣ%4bYQ}V o!nV[ټ7z7Q)tL5A6D#uf JQ>!d )MYbtC'@ oyc\ {V$`pa'v$`V󏔊:a.6Ϭ+$: 7rsPQD./5uAWveMA(q9c{c(͡ū/=C$lIB稬lyq{$O>!+OGeUNr|O8Y}8^R_tA+Z!ϧqV.ӨZ^&rșzW+yU_՗WͥV~pʪѝ~|WM薩Vڏ O|٦myn7/eݼ젛vy34>M7'&eutSBRw;ǿw;ǿٿ[>G;&Mn]PHM fjiꂚU354uAMc:&\幍D5İ?`5YHM,npB >R[-x o[-x œx o[-x o[-x ޢ[-x o[-x ohx o[-x o[-Z-Bo[-x o[-xz!o[-x o[-x EKV-W>qoߴs_*n jiZ\Kp݊+mq1]kT#󟹘n~b鵸{^bZ_=s136W̠݁@ @O@ @@H @ @ 7<7Oq2҇7g}V nGO~@U2TI]%*tS%?wBͿ fV*p+ ­p+ܺ[{/n2uJ*gvR.3R)JeTHƴͿB}ö-ma[ma[*Xua[ma[*¶-l{ l-l ¶T ma[@ևma[ml ¶큰m¶-l R)maama[R-l ¶¶Cma[ؖJ-l Z¶-l R)maa[ ¶-l R)maa[¶-l R)maa[ ma[ؖJ-l  d-l ¶T ma[ض;l-6[ e,3iaݽˬ۽y²`2_X^ˆ2vJ9ҠhiRQ¬hiX0-Z-̋F hih05Z-̍1-F#Me1ir09F#L&c1ir09F+L& cɱX$L&Jw(ir09".?PK5F.zfword/theme/theme1.xml\Yo8~_!uJ 9j@5,([5EiI9~ix MXj;G]ܣ]xۣ[`ڣZp~t1zaK+=zM"].o2 IZir:2؃}-T뵕-qbIv[uY*>(b} gmџ"CH[,vtm4#d.n ĵ Y25Sd.ݒ!]X!jBdiK^MVYp{[JFi HLNg][.#?70ners:֔a!FcDpn&K九5Z4wF|=5G NRca4Q>X WfϣT)vS8{ZjWlfUrmfϱm[^ߨZڈeςl%J{$%b- sh#uq <0*5ǿ5A'j m'j[FcNA8t!Ѱƣ0|9Dbe?$R윖䫱)q!ewSS[W{ica:/GӉNX|/p6ĴRLasdT;BEcīZ)Q(RRd[Z9;ڤĦFxE/1yy,HW^.+FEr;cJHc2fv q1C UfEII!mZT%Zn]Olk[LٞAL.HwݭneѭM~^-N+1AtUYƒ KXe˕ht#䚋 %ZcΤr> eR2H,f!ɯb~ǣJMdIReDZBtlCF@Bel$gN S>Jnw{OSw`qLy~U֯|f-$`` i1ɨ6Y *)XƪoKN2ߦY^|5#&V=n|ٛڿ6(Wv\<dto;_{N_1&V dUG̫67olQg}#^0#] g>&Qad adbF0 #!-FB`d#a#`d#G-F#!F#C#!De]y] V4Kn3v(6mJMЭtP'b-G~my]|?秧8SQc/SUϢIpB%8Jp] @=`F @=`F#}7??~Cssp_߸#@@0}F >`F 7_TߦPK5F p # word/theme/_rels/theme1.xml.relsϱj1 Oa׺dZgzk@-nK I &_j#q%aw0O;oz!W b+G:e~YRXHC PK5FZ word/header2.xml]o +i*N5-jVݲY8^?V톏s/pshrؚi9e>ˮ)Y4XYӓv}W@sms[i_6 qMr3҆cQ\(5 ot@-=z@>iL){ƔEM;LɌ!`Y2>+}NZŤٕx,X /9Кm:h_baҹ z ڄ9b\QbxuX@[Ãucc '-I_WɄĒOdTM1?M<| f+UY!ykP<(wʫ,AIàif$I=}{ ky')Bva N 9)t:ϼPK5FNHCword/header3.xmlJ0}vEDEXVV m0ɄIںoozF)z 7?hH lFw۔iʖ};m(ۜk2Waز*G3hcIE% [p\hx[,( %Dm m'(5tn .G#=Z!}L\N+;cviFkll` 8GYѕx,Kы/sŝ\hhhFp]gW}QZkoi~Y%F/6WsjIZpJIN&]r5%.Jw PK5Fword/footer1.xmlݕMo0 ! :NK0bmwWd֪/rO]$/e,rrbfvE"tTTh99!+^IY \PWj+󏶊uYrw5'2 b v0 K>E):AX[:H<xJr5b$'UYOIάF]2 Zδc㦹ԫIXI1ixVmkucd*}iL+q1H;`t?IоH$YRҝ7wքDlOEN6Z;)[;oyU;⟌J?.! v Y.6$p)tChSdzE7"I0|X 9CNr-+Eq[Sjߑ`%'CSk/Y2_`@Vz) ]:vQW@o5$8mW~PK5Fword/footer2.xmlݕMo0 !:NK1bvWd֪/JOFvSvdzDZE{@,',#l!M/ϛsSpe nVׇ2YD :0WZ܇Gb[R; d#(ùTKG9!UG:X,ZDz9G9S\&9ۡzLKlg+0k8ӎoGaSJ{x80MڕV7;hտ@Y5Ǘkr[?4OR3&i}EUƆ.ºvxvzG!s0eq|KX񒳡)7,#E(!*z\.^XAoq.]tuLVCջPK5Fi-~word/footer3.xmlՔN0 gPK5F)s>$9$word/media/image1.png9$ۉPNG  IHDRP]~4 pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FdIDATx]k]uֹ3c;ƀMI?RP3Z7ZVMmʧZLb6=ү%Z4sbf8&fnV}?|u h(Xb|tر+fuG/@XKT.uL^_&LOCbsTw嬞mq%V*(\ Gx쉍YnkT朐wΚٳ ld~Ͼݛw޹LTL^pt7^G)pOLjy` rZOg.N` [89Mdo(?ǧ-yq \0: ZAqH3=Lf-Cjǔ{sZM;QD6dwM ܜP& D-XP e0łfGjFʲʅj[8@Ԧ$jtA{nmb2)=l/w\leCrW"Ze8M~l8ybUQQyR9R&i&z.N|z^ yfXkPN:4y9.:dmݚ̨9PYՒV iS^. )~$V5 -4ܗs8x5ـN`W9m]Gq DFa>9WYSŖY}^NJ'8/,t` p*2yx CgPSKڵN`-ٵi(U4FU@OUY;%&8_Yh:f0*>u l\[y8o^r]^yiZwl^7˰ʘfiÔT22X3p['-dg7۵[ȹ-\ ':-_>|i@'5,ƥT(j2mu5bysBc*Y)؝g5|m/[]T|Rf.ovp˸4-g(ȚҀkl4x#f]Z紘bnWRK)bEq(=fc2Up|T9 ^c ޹T&3WF'V^l'WMtb!C%}1k9iXGX]q`3 TB.\ ̕+dq{t"w7ZD !ZT1Lu j(j팒@XXRi [xiyMԦH< 0.N~Y]L? h'Ca}@,񨕆aɮgлX|z@ɓr3K.]&d׳ ˱~!Tv T3t') + Ѷ7pr=Vq{l^j2 /!8dn`EYr'I>`%,RkDlIFgu l]j&5\!?=*]AdoG*c[@AjR'B5͆awhugg{py0z2Q`p$/ؿE#un@߳@&.Ѕ(ڻkh3;ۻK_-[? Š-gdҹhiםBeUƚwFhiD\= /(\xU5[DO|jZt /@'?H`y3[6wog3KOjXj-9- =V2l)0m<--{l11CK [cyo = ^)$Z5hf'&E=`j@%kc3C_w[\t)kvφm]gV}`j&`e \S7X>MlN[6ƶ_ L+ń>; yצK1Uy ld'SX1. 򝥰 ie&3S#z>=ۂo*AN$^TA("NsHb,ZiĀH{/,ťX2>SSd&1ʤq=9ys.TKw2ξ ̾QPݠ%_w u#:Ot#TPTɂYP:3%F@9@}[/|ɟ+6> .{he9`(`YB(mrP8%7@jg]V"4,qfo{ <1bvTVƽς>еΓ@; '.axxx~}~`ju2>4  TwݿXt-aN笡nΩ6K&%XS[9dax5ƽr飦3ى͡!q u9ȧEǎ_@g t.ɭ_ty7v jxp['h<.xSp)=Շ$^mWq,5I0Mq*7D}Co+"UG80~-D u'OOJQ`*`\{AfZ<0&`U3nNq3du{p|LcqB@_r=6:.Ky=U\W(l_PgLֿw=TSXU*p䣴{ç?!ѯ)u)FgYPiQ&&5 Z:KM|8-3 b0s;V1֙8e/z&O,DmQP;P>N :T$tm (%Zʇ 8>B%hO*Q_'@{Z#5g!K|svp-G;M6fyd\'0OݒǀQ'P^hrbw=Łs#FDmBPZ< 4j@ 4A@c hL(&oȣHVB"u烙RwTJb!np!AڞMf1XNl-(w4x <'I@TsRSЂM,ܓ E_:T@tp{1S" A8cr4Dq#O2Yk'ޑn3LE`M~^6s]y9 ;;< Jhjޥ7wv , X9SX^$2Y  )IᑔP`"Eb(ϗ)#"ʀ6/]@CVQ̅ {M޹!5Y֓p~fֿwH?UU>PMɘ3 2-Dp<=J'JnGȶX nIe~ed0A>&|p{G6ùa.]V[mCrjI$B(7R9AiU('=XrhX߶['iW[e& 7@zXdJuCFYc}V? iڱǁy+%y-']chѯT8ӷ(]m/ k5oK3c46C !ɹ: ޸pO"Jä&(»o>oƽAk0x}{7 Sܷx5 ޸VL< n+9_ X|DG? do!mkjJ˰ 3@kyWxq`/HJνtU"(=ca̍ ?AmD'5J!LzmYȷahwa 3Φۭ]hH0D /1z3 oq2t5A =C;oS`"``5([tp,]ӟ DjyMpv!=jh 1xC1z~WCq#?.Cl;l;jЕGP(`JQ`dTR`opPiN"Juk{dm*60LP](QLtjL)M=CMK>JQސ ?wMoQ%ҶZYO;"{6qFAOGa`l%S]V |7BՔL05dXKE&&eAXx-~3 塒MkT:wF[E!ʖ,b$F7)뒃<e8r hGȆ_d6#րҩ%ĜJr:LbU0jYY7k@ tޟ>Cf_lÌ r rSkYeB' 2YuPdG+ױ__[ iS([ 1n eo1yۂ6hX9+dop# l?g@U%iuR`#:3' ebTӤJڄ+!X|;}m$kv-D`B/и_xnWz")Gj Y$eZ03ƒKzLQL!~ `AJT{}ZnILDJI\B2.Oe>3_PI C(9F/,]GƗMcO0a]vwx:(dsl;c$?`Pm^rM*'>rrFIp9W)iyaJw7a?}M3Vg$u}6j@VGʿ#J.:A_ pj<!^0Q` /p׵+/w>0QKf}RcwojC`a'UvYVZq=x_ L@9&5K;}(3$4y l2%8 pTpXb&q D2 ɛi'mZ 1ijgDjI13ҐL K'<&ViNUg\q\3=v74ÐZP'''>J&&,Qf5 S=~@Lm3X; Fjʘby;:;1IENDB`PK5F"Bfwword/media/image2.png4{<%ebR0S% 1p՜r> CZ U"I9bm9||mЯ?޷޷z|R?'{!O2~$Bo߅}/_'pgxcz?dZ#p5uF=s[%Ҵd_cʦ&OKGj{|S-PƊݧt6MnW]301#4[+ j >fpZ|cA"srD~eL9B#ʢsg $5:۠qx4 11xd>kdVRfD궅z?$Jݒ守b5v=0egU؍~] aEYKg%m ]}FU1cY/P+& Z/V~3ga0џWDO2TFn+)ёLR/jp`ɮ'>3){Oâ.)RX-w rr9|HDb/b]KgxxO+^qd[6Yg |G aFNN C {v T ֵGp˨0-c=e֛A.Rkjc iv7jfLC;,r'a42]W}#}L]|soGelJ =P$(OTMkPz&Ί`)ןh eMAE*T?RLwmjL,1[#ɚ.UTEӏ"rJS`&j{+{ô9$y8ɲ^*hDQP1Qөp>!-g=nS4 yQ=ؿύviCYK{eooumu|`^uQ8~*U 3k 9ȫ,8דB{^.IǮ?l^(!z%Ց9 O࿊Q6>=\s@kU={fW'yUFnWl* Uc_ͻ#H :RFA-Oä&z@F1g[Tq` 2Admڌ4ۢgb5@9CJA4w?:>-M0Fɔ/νl] r7iCy`x?4 ->!yPͧ"P꤅qlMT~d?{\Oo?Lap 7srMx 7tdX0d<3~o@Y:6q3ɨJEз_?opxgN9Z9F٬7 4VN_/*KZj.qEe>>.ޅᡟ5'bX:.ĩ'g$ʌ} |xh_G+Nn_tE[!8a Tu{%OxCO)'= J(8ZnA"#p4f.ţ8X\D?a bYZ_ڤn-hfsj(9FSHCr#+WR?bj_fw~"p]Ĕ15 hb(kd|LugHqE46wsGƻ61R49ÇQ怒m3?:*~SR'Q~1IÞuջ4{M҉% ? hb|{BoFZʲ3=7qDRcuynMk#ƴ7JV=Rphfn}H3<5hӪ \WHۉXsg}xI>oh2!=UhY4JXn UzJT'!=Ħ4s=K \neбĨ9xx85U#+U9kʢ -9Ћgl6)$bg}]φzJrطK U}Y B@eV밊Q]ÚǷCu-0FK}FbIFԊXD,NCdE(Dj*nqC7V;.qoh@V9E |%̌y\ÂS5heJת+(ENle#ڶ!xRŢXgu'fO^y` >\yʣ <|Ȣxmp#^+! #dEQ肳iݯ$F+R &~T4F;'wEZjlQM[_@FWf-Lb-XjJ,3n_8m7X?O35ob-0 w,}3/;PFk)>aW jgJ2_uHb= tṙlE=jS'd/v17e02J {m4(1mgo@mMǗVq ۠pGdy`oDZ#&g;S2uu5Xvг u^ M{yt@f8us\< 07_gey@lĭv{l8(XB=o_?x',pBkhxt$09v I{% h5l>_DyV'=AnlgSۯ'M_0HԊؙ!%Mfug5 >RbX5l\#FU 3iYÆG#+$n塛~а"IvWD[OVVgy8̸R*IE%3,e_,i49뵥dyM>U<L x`EV $ëmgGumޙ9[:қNH[6zbQir͌R%KMVav"NWZ>j0uTA,{+Bi_ "e^ip=]Vw d84Lx9G,ʮ\g|&U[NDFN4 Y`aDH]kn7\zM OF&+In A{6 9&!Ts_Ƥ}i ΢޸ZEyi#5"6 Ћ='F';ph&&xQD v29OGab~f&$a7/+.;lq#SO(  ߐ_,wt7y 66Ϸ&h/Ra=HL s]| vG'm0!={Lg .#/rw=w鳆%Z;տsGtF;U.y~UP+EC9]? De 5Yz~@-~E};,z1>4fJv #0YjA /߲Lh%`VY(%z̳kl$a0.]y !.Pr%rp H58]x"k~HcEr,r)[Aa&E# wJWCSD-ΑYج|DF,[Tc۶󌣒߆LGLg:NhyG𒨸'R!LUgjrJRMfh *b8frDzs+}.EPܷ1%,'e0:a5#qZi]yႮGAʫӝehȼͫM /te B.ͅm kAR"@uj g>̨2&nxD, D(O}fݱfb>?د(|sD/bTtUk](<(v딡)6)r]2R,ݱ9H݈#\ 7Saӧc/HVGM:XJʹ3S6*E%6&MYQJol$)Uyu^ _]\%Q,L2rլ40QHtPLRP=p ߡg5/R.¥us/ u)KҏN6>zA2j j [, ;\ڠf5 g* E̊+UCȋj"<=#G Ւ1[@~.zh@ߎʿUi[QsE>K/e";;0i}5Ьt1=ߒc,j#5*S"E aAoM=s~$ uLԙL,77FDIrYm*/ 2?n.wؤy.PEqZzE{k6cc/ S[+]e}_v=hm9AAZ׌BRen E]3VL32zɠy̼t&u6{-׼Yϡ8_z%Tt}ϹzĬ*e} 抜5 ^RX\r%_[ͅIU}~uuJيk"WW\ /#!QfM$5 6 G!] u[72#&`ZjjX]VV3K6śsOE BUS;EXxBǠ+2~[TW/.(ɠcF)c_N@9% .baKH3F0NEȦqP{@{d}Z$8(f7"0JQBze (9L}ӭ1ItwC!Vړm÷#~eR`"trs_ Zwנ%$I0,!xa+ |cFar lפrQ3U}T+t)!J6K!KnVY>_>]&O(ڻ6[ rDZ_ X$oH5֬مEUid 3= cY甬?W`◞WOi@>ɝwY:k¬8V-}S2 _nrBudlǾ&8&c?1^ẊkIo\+51Eؿ_P4>sjAQfHTS yr/FYޭihYF_h;6L1FFQ2'p`ټ#LKL`l&CϜ 7-" f,&_>APAn͢gL#h0ez= P8.q/A=vҒ<{'/JUc\C']t8Ǿc;.?I>"YJ4ą_< r$&w~CQ1-*E1sMI-v+a;E֌D)(G<.leÅ5 1 #pp(ab6dvLdhE36_|&uQZxw* ,|[suPU[R p{)#aPOAVx6ElmWܒHjq/.kvt٧N)XS6zj-vOXoS €QaѺr a"IZYFql&f73,˲ ++GRzWUϥfXߤIhgqgGjPf,AJʟ0$v 243e~NoZ,ġB0]o$a'r9X1o>$bZ냘- vEm_jÏeyI&a%_gM@梤Oً>U\9F-N4oOH< {^m3xx?vn} Ï`b7 u»jbn%ι ۑz#¤ k d&H7D:).M4dzL]yQ -`%pۘvҧuxDMoTeF kN0Ӌ , &5j؀>g츉TccU`Տ+)eaxE_ݔ?>x )*3_9xMAg:v5rK;iuda0)PdUR<`U0*oR>MSeN9#u$Y |ҽ) %Ca/W"zbULe_#;OӍ$+#Ĭֻ݁%FΣl+=oPݪ(k:^#dnt}FD{Fd;U C%W"LP/ӏǵN XD6$r|XQbeGtkznsӹJO6l^d vZÕz ~jP0q$jI2[2\zgXf%ʹ8 {W5 }AY,C[O0({}{YxK>v0VG vo;A5a͂fH@$@%e^>^5h˽[(lBU Uo@ωFNuz+6kG1-RX4 )[_*{>%6>e/Kd`9mMz# uh:_Uuso{xn<33GnL](il5\ ,'"׈&* ى)ؙ\u0_DcJ3MgJDWxBMMƠPSq:E׻3{oE  \g9i̠soMC- J{Nc+9,Y踄zp_[+qӦ$~'qVUiոGB*ᖽHE,V-3u&Ӊ7 .nSVJSgbb'd;뀕и0ceoqnZ#xe"C;LZSGecz^,@p *3QAC98=HwŠ1A3#$R]Ly+d|D4TR ]nr8V s\8u3aK/BZl> Wz,:'Tk2u /(?c޲_mA[=,z!YF Qoyb#iŌN[6oaҳmD%|fc,P\̰LT q-cnW d{ꖙK{!fHVP\n-lᡉt}ߦ} "#d[(Db@i@jXx.5x Iꑗbg iut0'a^JɆ1{?1Ez] 04>zU@fDBF]$)ݧHcfSz iv+_NL&W,aYNKQq'w=Iwyݖ^T4ezyeT|zXөOn tݷt*՛ IYb:HQK,z[+-9`1BTfU'L eKQG~ ({;,♳qN!ˆw ^<:4z%>+|JUasV_QǺ;bM [c&ZFWtFqY)7׸Q}HT1h@X(ҹ(?ߘiz,=OOsy4sP/jgӜAC=#l-v~(Wv/riEe9λG#t;kR&q^d2ԭpP5\c &iY&}bs=mzeӰHS=GơgsF ovY&T䧂jft^s:DV}۫ :3ZjIwݳTlٙ?.XUX{j_QVQA#Zg},2|wSz.t76uR9ëg=UUN$]gGU鱫ZI o{ʋ]Ke5]|S\|gY!:vmgFG,I^*ښ6_}&!^eUӋ]z ߇&yp3/M[`LylQ%h+ Pd_"q֬hTz~Ygdxn'^Ab|jpr5H+j_[:Dp<}2qC>uIUZ}#A^Z >]k~e">Bc*_}9'Z - 9h6{p[4CLSol!oTzwHa+bߵE-2bagDF^ϤJGgzo2 (/<hqՁW5M4S~Ȗ9Q)צl=C40,FǸ 4齝| @"DĎ_)viS% YW9'06oTF*ipL0:yDA&mkx9V7a oQֻݱ/HEYLh:Eet3g&3_2%k4.4q4T(Ow~5>Ji@%PtNE:KL EQZvuԩ_d뙦h'ԽVt?1lY&ptj_-l~jiNuٚv[% ʓflah&e%J;_/6)S7aT*nAO]X߶~Kr{D(ĈX((u;  YNf Ꚃ+3&+`qx$A-`BAoU}O+$wJ?Mez?0,hg}i4nHAC-7ʪ[o: 5 E VzM4j"BG,+fޫzdD^2RJRz UZ)W\黲0 db+Yt=Io LWv$Q[W6X+/ʣ Q): Ndq^=Woׂag59YeP?uMzaFU^ d^T = XkeP[FΊ-ҊJQ/2*>vOk6n4?菓v*OYJd pm/~ɧeuOjK֗UoNȡ:cʇzP}%gJk[ GdbdI !nJp\̹%odr=8٭w{ՁX2,njy<-ϯ`;A&ƛ,+#ڮ¨﫨bԿ.Ԥd6jQsiָ^ {;% ƢQm4b޷5sE~3==,5hU3STpF_2d]~D-J:k&ϣF<8J{7?Q>0g L!E;?ku܉ 3L!##sF=(hw;Bϻk@PmA9\%sߘz)apAU#䳖,hibS47q+P we!x)@YkhNPh{r=tv. l8$6X6nSE1G]㈩Qȟfxfz ӟG#)߯l;c3G'j{lUʧF1^ fDNlȺeo>%Avd{o C;0}~Ûjl 9c&Oc:TKNrRX ~Y9cagβt|",(ΪGLJD-P ^a8ڴ~0UG ,(jڻnKR7z£.C64A)+a!B+;ЬJ)%}i,=aمDeI'%p)9U;V @|!' -=̚R+Pr~*O4ez%P薯zs|g\ ;- _("S"q/m0<̰VCe*%&m/sIgKEN*JzrXׯ^> ι(#cD,Fp 2V!Qr>XRNP1*Y?Eg2&.;<w8});_0/m]%3۪sk?a|<(2Bhtza:D(WPNJ IdO}]zϥKl~ai_ 2Zo7S6T0e##a뻀QNL$[dAl( CxݙzM@/>rG[JssSfC}'# a6E (|m_?K-|dJX_?ⰽgD223O:rXuaukvG.M#_aRUxSG^'T0YG ~Ҹ)g՛v|߽ pb~*)aB_Vgg2]L]CY|tR/1o{ 9#NTPEnl-s~+;wнg ,V͸{:t`)($ k%]{cp Ty([JjR?C:k :Pal޵pn@~#6|Ja fG_m4EA *]aL3}%>eQ:ՓglD/E!/;v9c_ܓ Yg941ǎu%e]ےdռ<-EΕJ7$a[:>>]֤uezq X|tω g|aUX<$6k+ܒS 6,u |sҙ gD2=/?B,rX$ʹyS@tA-rHE.vu#G#|-Q=1qN#סcV^'`a/}.EP7b6z$5t4]audpR>YNߠZA n1\6c3+wy!b4gdbٟwVLJ;ZDF檎IL@y?B;3ld\E!.!sGzaGlo*:]ل\t@\u_V1&g f٠Du=h|7B~J<2lscXߛ2; ҕޯۦmz/]s?nQ۱p3Xn,n0sVN |l;Kp޲mY}ˮcٺ$Ng-x8$-+Y~ Zr`3o#YKx{i2gX眑ͪc1f%|}h1#bg &S r;1n^{Q1S󵋐Ȭ*u˟tdm[}!aqZpC&(N"ҥ"}j:/%JKYo\(=h=Mymhŝw,%iZѥ wiY$"hm5M-6W/uv5Q˥P}uE Z ƍ rEgfe|?JF׽&-[E%Z@ kJ *`8=]N>%I[b"UOiiml>},/Dȭ?N{{G?N-rOE.O[cVq)Ҍf:IOY'?:i2-!)sA1-|gi,LԑS瓓ZJVf=^jLSi8 DEgb6x;Ӓ(P{g@ h=Jo):TWPR.Z<U(j|׵5DY3z7AKc'5XVϛ\T`(,SJ;ܖ^XQ|uw]A9abg`C_sv%eV'2#8]ሩǂqO O`k`cXeȃhC[" ;+z$!Udǀ lTZ-ݯ8nZDH!@fA19_JY܉`nHpE$.8̍KgX &r *cI9V iHI i[Zf0uY^`63ZFƂX*2GtR~?GmHVvv"a(xwh/Vs9.H@/PX[CbqeC 5i|$dɽ(Rr?էd@~T]OQuMȍQ&u!C*}OIsrϪ]τ^s2e=\Dd#*'o -^S5l9l/ K@XiLKvm2y<+:0|s:\3C+='L?ȶ+`aZAïӃޗM^W%zTFϾ9+!c \ꇄSOY7eOvV3䳡ɪKFg]cˢB:Bkԍ>Z?Wȶ|*5I =S"J৕WӾ* \L*xo5phc}QbǘC r֔*׍P0Uߩ/>$;mx9 peP 2SL|ae\ Rݤ4iXoZBX7=j?YJZ.!! NW||RqUxS1c'rw0͊ i@U)+ [m67%&GNHM&&>5A+rf^gMl?ѿsOQmwe_@LNXlnF4oBLS5eu,e+ץbC'VjӲPeԕOI"QUM-et07/rR`;񥻞[-S$^+b"rGZ Pٚki]$#p?y Fn>O?)P3wW!&QN[n T}>}eY>ٌݭd$dǕwQGo|Q1O7"3+^ݿ =/6r)3TT[BcX0<Ib&hi_~3+ 1t/ '/ 'h@*ˣؕĨ3_{n]2<ґ#=V?~B:E…LQi![b2ʱyVTI]ϕg,Nk!0wEf=ڳWi]݇ɧMUk2`$23 KUcqgfO"E7^ޡI^ eϿl~'q˚BI43ɄbardVzYɶ*uDEO'UߨO:2E K wȖ2_E0Yg#m!7 XJȚ[~V#úyv"N*k5Ƒ`zhJW3=&CTG"XIWH#=:}i;FTTv|]t'X {T1|zd1A 긘T/O BaE /",,#xRhxfN7UNp_PJW1.t4Va}[:*]ixE7Ϙ]PQcOJy/z{%P! 䡦A CͲ DmQNWw쬨0HnQ?kujFßUDt햱̹Ui`CȺQ~M"`SZ0q؃b@,moeD*AzeYuyZ#)wࣕTzzNr=Ɛ Lo+Jkb ;O!\I*0žCwަ0hUOoCSq 0锄̞0kb3l˔I+1g2""[uӥ?X SA'\*mARޡPu9eewmusEuSD,S?ylit<eʝzTMd=Hv*)t WDLNOD_xU~^ݶ>|U WͻԛUmZB-zSsZ׎\?h[ߒ^*,jXzo7Rd\7xN&ȍ_zo16ZT)g{͓&UA|' [4FB>C'F7~RX6մeӍճp@iƿ;"vs3{pkU@}x{VT(~}"''?kQ>)Xx|zg:5}(P%qUµrG3ׅen*p; fEq".jdR+37Sն?-nj@0峛S](GV=oe32j3tL@vY;1y 14dOTF`OCq.EGFԙ$R7(3B _2n.K/E[(@%~Ոp @`6`[UzC׭ 3k!ȩ>0Zf)23"$_<:]vIpsF-z!$43e||3(iGϔ{{b{t­D[O 6ݱ!$h![OFق7z2uՕR[ $.,;t{Պz9;b5{ihS@?[ >Вdfx%%c.儆Y_'b6L:S [\rكD))N#tpُ=d=~n? +Wݣl R_F),b6iުb\E4in܊c/O| B< I-na9)\/KT6?[Xߚ̳d˃~)F)9ї'(Kȡ?N}%ּ~&K$I]d^b]zjw=%ٚ PV%E6Y]p~"1), h}\8m+>E@g+߾lhg"*I Do ^ u-._/1ܾz U1%33NV&1j`[[nio:, }9yҽ=i_G/p'Wo}@_zƟu@ 8w-Zrw: ‰~}bu{G*AB5Yo6~|Cdtxc (KyuH鐢$xXXy;oΫboyyDاS&aA-5%! ] }S< OQ\io`*"D*oȗ!K7%+=2+8 dx"Nק%O `s3Ec!DE|%x0W z}%Nj2Cv[| J&%+&R  _=duЋpjaH#n\_p)\As4Vts$뜉ԵO/ qI37^:&fuvC2TuYњ\\\3u5J)1fd~o+o@epZ |` ɜT/aGqYf1 /\rIv;sj_zFUr(Ҵ]U4lCs$ѫSČ*rQAQeSr6$1h4 ;"L8ecT9C\|H5f(CZvY+b7v  oWDNàN NJkoZZRd&tg}NA3W\=q0UPD !3jC)#sc$Q@-T~FE67t< f=pR2<29HN0~Y_ wuVX}tThf@/yJni?hj?M{PϷP~7!Z?]*=eU&,(oʶ;׳TAւ)~V)$h<( _q+;%ZS7+|(]xf,s3ܸ0IBQ;FXY^ͿܛQĆ+/Y%ηh5ݣTtcn'Qwf)>.'z{{J$ЃRG0J}* %4mg,ɨ_6tƧrn`LpD76YT363EmZ577)Tь= Cq]j g8QOjpL@0]ߧGLn‚fNvwQCy[`>yfI[c 9pIudSӦ{֪CnB$&m&*ת>KW] ق@#v7UYWEK-Y:l UJ +Ertw/{Y+cN8d 'iUzA}ȚoR:UK;z塞I6|.3(i{ϐmr xB29 ҔV_4V"]X įl#?طOiDOG_ϣ/d$Tv3IUǘլ`y)(RT.O%_`Ɏu/"xnmU_IZSi痫=v?;<}͂P -'K€`DztI{n= "PfoukkCI\\?& -jOKшk}LFQED=-|FV@z ?=$(nssޛ YS_W8|i!H!t6ԝ{Y^Q\>j8~&JYFKn~ jrm9Cn]xOH90F <^pH pZHF ͭi4tJddOA[ý;_[@,cR5x^$Ji 0=۩zPwb Ԓ+ks%xi/bKnDnr"'q'ǽnQfy>4Lk\!$N4lvb YK-U f߼9 нqfi@jSd@<;,ӻ"xSXeij1 ["H9S5QfTD$gR3-yAVQnoI,u7s"THy Ȧ{SצH 49q &!\aOzPDloCD3 LV#/3mߞ3fA?hw)9ƌFo'I',mCTuut"[?ŝI? ױg,Ow |kIozn ~ޞL4 EpB؟ynBQYD&r-x C0*x,GfwtlF=O2L?fn\1< b@|*Fp$hCӄz"l[ dDS7$wr=oT7[\oyY:2tib3O1,G="m=dJh>;tOhV39a ~k!ICudBIjM4?Se> 36`8I4ѭ蚭mQ\;*7 sN@PĄou5{, Vz#*zIB\fxy6s;~Y ٵ˻'"QΩMQv GG1[`\U.q`~ewX""FkFd'Da"eRT"T[JuBi֗fdELЀt7H8 lTuOOA9dVeEЙ[_q1SG oڻ[=I(b7t!vk@9e,mV_ҏn,-*29T8Μu;E Ŵ oB^Ruʏ-aKlzԙ.\%n~9tσvX5ry\Mw8xy1bgKqHZox@4AUŧ0(\(1(AS0p AϨ_ 0kj 3I8A1g8?פ&S瑌q pͤӫ;7\&GMbg)U:8iDjxizdm*ʧI~~5`=jqX;~gɏ2nTC駑 tּQQ~^%ȋx\'|Qǥ !μE(ĩ=r%'tRSۯj>zY`e _GwL{7DW 9F4*š_^4&?j=D:h~e Pǝ DA[IR~Bx eY؉Gi6Tz4)bK)[nГErM\H=fySVT85QB?C@Wa`ܸڨYFG+ةpEiwescsqoi;nAQ[fS1Pg}xlΈnr?G"B#ڽR3wekY+Gj6l&b Y-sؕ_)B5N>6̏K/,v'+]}pY*/g|<1ȐEFqƒN;hgM]YZ1:ҮպF% џg7WWVҰ˰[7 <"y+H ,n)LLR\EL0%g=qv6gv!./*uX*W&`@*) MC/7c .UHlrIGO?U!YxRK `Өwٸ,rٞ2O[ެ .)^O&d Fqh,sr.3)Uri/x3*bª1SыC.n tKhG|^U G?l`VCXTsfhHK?~_{?*=B;x޿G&9frd$?92!ϝ4Lɮleַ-sƦ4QZe1ѝ>؃{tVmRQ}tue#_wQ|)]˾k<8KlKKƿ3Ƃ偧r_;͈xKEyXMR))wwK$)>v6B_$# U|hxXRܩTi"u:=ѕPbXԶBSvo;i)[5fC,x{ds)vd r =x $LKuq6t;ua9'?x߳Y ov2otmPu [UKZshͥ,\UKFP0iDv>{A B ۏHV_fW9j M[XySDl^r2;0ϓl3… B, 4 9}:ޗ 5b㨋 w\py~g|r+v3vcm)KlPt2M"20XT3W++xZQif{M6ϳUo,"jQJp|` FMpX}Ku^j;";SvZ mJ b|dAj$ i2e/ X +y-X\] )b93jmCP{X"@KU9?q̙\~ 3c94sMP)*DqFtjv"pGt9LI0@oՋ4!8CUN_7yH9Kn-̕a6hNLX@{ < 3Dm.k]YyA9)ĭG-9Q}q|4$;Ol%|79S pR)u36'y 1&ypc|%:=Refݼ}qe. <)n&M%ceۉ:Gy!8? zSO j;6; "k|V܃MK/DžV8sIL ZHT({ 6#Yt5djg03(Ɨ2㞖aR?fh@T>[ؑkY Sq4})^]@N) X-<>D ??,j6=s;3'_Y4y_t?GNǝbMQdDdd[_^CV. VcK 4ҩm!>n=;uI?]/z E@H)6>.ȑJpAq{rOCah4ox5 قa8?R"dදީG t8N1O}Sqٌ;ٝV6M7Q/mJ3Cp NCYhizՠ>JȕsAGB" ݚ>,e]̖vQ̑/}9n&sfoE֙w.,Lt|mVMqZ2R~ts<'ŐQ~`QjP_l=?n@i+ qVB*s)ftLTʋ+擪RzmFmv2~JĒqm' "𑽀eBI3L-);MjqNKJ72+ppE=4l vwa_w\x/;E9XKK+rZ2v4wI6yrUq멆Ltw6다x%`-'8*`d7G%P8hťliZc$7b0^oOx3\dgnT{?{J0}U3'an2ȞYyQ"cL;ދԢ L2eyezAm=6ɠYmlM~r r+hZkpD+u2z`*l"5v6QA *1Ʒ)ِuβ3\U7iU1֮q0_Pa}sʫõP8vGsRvFEQSafӗuF8ur[dJ aqZ ntQs]kBqaN /WA1@ jP=ƒߠ^=⪰bP{u|)ǝo~I7rG'Z*e7ђ^+|Z C؅B`dw8(&aNFP6ih@Hq36{[q#/p(f K>w`Pt eWC`%ɛ8]KRq~L*1l,T8Z1 {ƴߨg%$XK?MTSse8~n'4 WtZ?] A.Vmn!⢒)l5)Q\9gĎc=hnR`XZVq~Kr%?gq=]58 `iA$g@X㻆A刈ן|FD=,mlA!nJ;;OL'DʯKw#D(kvMYvZYƘY Cc鱙Ƽi.zU"#qwUCٽyAv)N죆XR"AU1 /ziMwu[?V˓ t9`0&^#r;/*|j09]pG&^ÉpSg{Ny+h(ALMX XE6vR W.WD#q ;AM-uU 9s٢Rv1ySК mIoW)8vqce4.L`=n=KG#Fb^69{@=[YϱݷПY,Rh3'Xh)O%;ڛ]M+0< ?l9"D|O^/mbLp(JtroD5&FvQg(E?V\ݰ) l| %}r'%wJ"ND]@T 0-K[UY0eKo;WAM*kF,NsC?_| 'MaP;T]_pl'7@2S7~}/[yC-]3j O[^}Q^3;~%DI$m/QE+WL8#Vz "Jn#EJPOs ƗYߝLɐ=쯖4K9߼KvqI.[6+ VTVGCM>' $ԑ s4_*t˟79Y2!h5ѵ&}UlʈE9efRܚKʅnke(f.O_*˖Y %(o'ǐ 3"6&ǡ\.3$H3c=+@# Y-=PjlMC??$2윩^#)偡'M.P'V&($?>Rj/SF,PXs7#Z$BВ*oS.5,&(4D[r"G·5`НwT6ϊK_woclV$ΣPZKr7t%A߻OP7ez1oٟus9YxQ۝)T33XuM\`U X8H97kh2c)s{&UQa {b5w>1c_Ct+ RJiG&Jb_ 8\/D$󵹾FPA8`X> |UghܨSV1$rxnx?KD:JoqT=chC56Ra*E5(Yn*N''G]*03*:U:^.@-L 5!kX@:%_U0vl~5EBW_N?  _KkY_ӠE/tř:R0){?osQuqZgפ71XK̎yc 4 W`9nfa(>( TZr.q4ln5UL;z&ܞmad} J4W.q *S\6澂|sMx\Sp[Gބs^?5VsZn̝ܤSTBMkG,rBxK&%c=2 2K.Cy/1BpEiq΄?uEEH0(0l ߄nn̊>!n49*ku#>]dM-6q*JCޕMKإd0Jݚ=h*BxµfE&=㏜韯*HB˶9uMcb+qR.ݒY7`3 /@ƣ#*)b{J{#JNdSk yH jrh8b󮒍 vQku^gXloΏpk4[ipOQG mĻAmD^{,T.c!Dݲ,o*MB9C'p>i 7 WI"v0Y$@$>)E|{:a"6j.- AAh~{bkCY5c ݂VmGNZA[-@FuZo&Q7jn [/4` ?.Cۿ7_ @P͎@ؕ- /s,%/n0`l5<'3CcY8WHIom{-&QF+t2փ7C7Kc blOőS8!TCS?Hni]|vϏEG _ic'H^|Jr{ZZ,7SmL._o。)+[]}~^gImn=X^}IRliM>X[XO`=m&<^q'Wpo֞Iy!y:(| Aviy\?&Riw oTEpC{.3~r,e>֏_FU7 :Afe]O<bҐ%t܋wij=aus &֐ eu-Iǁc깷,8\)1rì"vFfrf;Νֽa=|JK[<4k8p"h{ n3.[1$S1d7Wtw3(gaWh3ZɺEU#\tdieO7`@8ȡ82I*LUr@k_t':^H-U?Ö_㪢 dU`q_ <][`)`IGiDjR@mfV/ݴKn' }"3\ec0 rMnD ԋC""#J*͟Dgڢ4A[Q [Ϭ[7_5($(YF&PlI;8R+ 4s- 1QOb%PL,B̠*dh <$ln?&DyYm=3η$奈CtU%r4qDb0:jaRP4;h3v6?:F"s8(.@'gIM pd$J(2U%|G> ̊v7wQ ϑp1A=L(ݸ&OV&7Tf/8Sّ@trQvH*ѫ?& ?Vok; }>mLPQeC^ w-8D#f ˹7wUMZcf܇y N:Fc^$2QR;k0既࿿|Nn KD'꾏1ZcޒfS9uHR!"O: :BEs.#!s'{E7t V\[ܦQ4./iѵI& MKaгHϣ'+$a$xr҉)0℧+Ʉ}}>y:9I9[]LFkSRJQ٭Wr6Tnj1I&;JDSǝ.hBi{r"fl2 ma(:|4r#U\j5F0"ʕ~|ֻ1W륺uH+8jd_MqE8ݥEn0rV'}JrJ1oɄkqoJs1=otX8dP;YP/^D̴YM^+A!}lQGVy.)̓*|븨'eihSLr ~kc\[;[a~!d%wXc^)EwsCSWh\ur(taa]' Iw/NsgwA3hxH1w=%Gn*7o$F0+ Q Eq@30Jha /㦧On ^q~Q)kMc"Btiԑ68^GM˺ApD }Ā\uW‚ѡ QP"&~fּCwo>B^&6m/ FKBXdYFh^S ?\a,d2%!Ao)+|R۩,4Y S0+9JN&D^DT:= ]^ B35+ {N}‡8y2VBݢK*[1T4ecTcʛ4ٗ- !r S$Bq#;UM?:΄;H*,f !%"L%}z袭=ߏRŝDOhi+4`>"G8V*_:3dE t~z=5Yn>O‘Gn.7ך1Τg PO$Qn2SFtwA`3Ǔ%jp]$\dGȌRJ:;Mk8染FnH GܞVsÓs'b6iX0PvKR ˃ϊa"ϤINP7+vQY˗~oh(}QGusȒ 8phTڲ$ĨaXW[c/ptlrG2z5 aP).gBde轖5ܮ|FݶOG2Ș+[7D3㐯b&@Y $ע4z-M7!wEȂS" }?;5LeË7s)RS-#&ΏTS1)Q/Ԥ5HEIaU |@9g4>D0ϝ]*:zTXtfoIܙ=@wc)kn?0ZSΰ8@G65aᵊd2ٽ"Cڒ1_b.7ZlAs ۤe[3)dMtFjU` njtO(}ؑ\|hYCޟbn,ć @A=rbǧ.0l=g5@*n{=>oZϪ_ {CV鹛aqPIuw3Xx. dS)r(漎CCJhѐc҂! ?f'|^\7x, -nĜWhsR.q]Vxfu a)!ߚPq_>5, ]<5}bV >m'g)<3٪#bq?''?$PLBT]`cZ[3ړOAeoMy,K6gtd7^g(mr#[=%YSWb>z"O2UKWV*< mYJ $+fj ?Rn:eWۜSdN_*|(l2/vĊZS ĦYLIhU~Џ\sX.Yv`QyHfY^sJXӜGXF (dTkN9pPOߦ/[3 Ѧp&Wr>rE-`[¡| }W[S~߽w{kU2a% ;B{weWHAձ1m}IO_~EC-XFyE_"" ~Cml#1\a$qO@yf0o$XqzŐmvrzR+I}˳^ { [EoUB&/|:dа$41۴׷$Pq)'<8a0“b@i{YexUrGJ~|iy楆&~gOy&jTT?ǧ!Ì!w>h\^LZ×61' jjp1 $zvwfYK EшʠrRa+Š/#?&$XuAw'2~I<[EDLT4OP369C iǞrk%yu!x;Wn3\6 ;QH>(^C~V{޹*cUXrK;ŭ]( R47{`6ޱyGhZ=+A+1Ɂ}kڎ+ C&7i8pW {oRDdq_?Ѽ p#G;SvuITә⊷瓪n2cr-}27J,TO-=ލ}ܫ$|FVo:u4DD 1wC}V~RF'PLTV6+p,e^T4Mm#s. Xs ae  |[PKec@az>E=R3Otuf+*Jہ(A= #4`/Fu"t@"5{Q.ӭ͢Ln Ꞵdck 1]fb29=vvkB3ig`lt@ػ+_SOU>?wg/) mt0rK`݄4eSPN.ٝ/\xd5_AAE7s˄/0= ^4M.(;+,!~ "P8y&,[Zz[&]6,rr)\KנYS-4@<^] ?Thsjd:`wVG\(:/eCSeW7%*RGo_g]8l_GXq١eO)FMٗGb˒+Fdm݇zIՑGk1ۜ z3Mn탉ŨR'qp~+H[2[Hhrھprs$CT+'Ν61O͋''O6婬>[|@BqD NS0^T9럨5T^լm*1af'פomz,vO>&~sXiXNVY~tִ V*1b"o9®E.8$K=DlV{[3\(E,1YC*V(mIHP"vInaGBd73ݤ|skWȢL%HPQۮ!-VkPSN053a=GpR&f5|o|cte.c'a:Vؑf駦d.~dzZ0;vW }q F7\wІġǞc47s[Vn\l4k4\vu{wItV1Rw kꚄO/=9)9U5*kܒH }y -@IB; XFB0m\-khm}<#ƽ/CB'jفh-)!LeWm7?g` kuHbOe%? _7/Jꚏ<;J{Y0P'p:4W4{fEFb}8܇@0m/''Aͽf!^OM#{1:c} [238(5ߨbPS5En UauįĴЪv~%]Կo53E0\G'!/`'Yh*E+xB6>ptZ-pENiShpuH9ϳ]0lvBoQ2]7ȅ׻LI12!Wۨre)zFnUL5ntL6aM [)1pƘ:~VkײQ7Q+|*A81Uh>qڕ*͉UG%4o(}~}o#;*4eO%c]("8>6]s "gB/-ńzfƪcºAQrg>#m%Kз?cyY K֏C~K'ڝ;@UoUaNa=O [Dt2gD%Q-t*<V=h]4CJcR 7NǾZq^ξ2j@'\Y$OOr --k9/w87 GB;%2)!,} `ND7r/RnerժnW,FO@ 5]1Ch`g:Ry_2Ks&FfZsvh}oa&QO2H: x<~. yMq'+R] ^wަ('SX TmvNT gܞn2!j9~%#so[{OIބ4O3>:h3f=&! o+$}W4q['LC*FVkh·/?H_0]R^|R2H L-sP7Ѯ㮝4jY_ wG\1@- آ"/EcQJ2 l:u>.9 цQۮOZ'\܍ EʄKbzj6`CX~) ./<bēk-W7n}?#u83֧sل}O]qQk9a㨻ϷPyS3#WVntI(52WطJR8F 2,njV?S 2SoQ0PVa_m̃}U`C@amJECݝ>^}>YY)=r#^:jӌu;IջFz^ֱIwG^ƨk+m+O#Lz̳'r<^:ʾtɝjj4=bu l 8c~ Edn:ςCcAB-PPK;k듍 JFK~%3CSrGEi#U؂85;+eᐟ\cnKVuq iLL%emn]B9-HPeisP{:- HhV&ef rb㏦{TAcEHOyɏ lWm# c&Qsr(e𘋶H,eާ*p㪎>ʸ?+6G rz.2{ 2t9JעzҏxH+,+aĂ);26B-WY"-{0Dh#LKe^Z;K| ׫ L:;`׈FgEEJIn2k8'7vJ*m|M6ߏCH} iԳSG[hg2tQ춼Y Pqܗo IÎȎsGůK[Z{u3.#!(,N/;rkIl<.G=GO4^2Jz0~DӐuW!׭dDHFNi&3(.p“Xri}8rcG'%g\CR\GRtC';89SPaONԍ~.ОHpߺt%L2!4@9g)Ms4\ Ű-ɉ쟡Jpa'h8&ym-ƎOΡfJk S;śٴQnX4ۘE3u8)5u1p`ImĻ$c 疳4-?~|]'%퐝vB'' #Ǔ#qNPQ3M ҆f㮜ՂԙQ`GUBŰc&ɒ@]ۉ m=OgXCśσ'>&d85‚MﯴXfC-6x4*CHC[@-!&JYՓ][T[+j&E8?vta͗?[oy}p69K{qȴh̓9QmD53:qr+*=4$=VEQ'e,E1⚹)Lnp5*RI{tL_vG%^{>P(OCB[V9?#j} 76&X]}q*މ{;K/?:ȂԊK=\X#ȟҵ7o('au)iZE\M*0]FIfr}]f>a hXjGpJ\Ṓtp1D5;ApyKj(g4*7{[5#rYq'%igMיz0CrIa5g],oI\-fPu{tDDj8̮9aԤ"? }MP!bX~Sipӷa u0Q2_Ľ(gׯe_#(lmI<DѨͽ7`U'T ai8 i(Dz,o׉)|yN"eqSʼx=}@gm?,a#]V Cǣ ;Y~ d!@g8á1sr"Xo9c]SA V3'RA ՕX/jw9RrdwzqZ.M]^&HEqUL>O_?c$4K&0D-Cy ;7F2<ԭaH]LHKw]uF{9^M$$|F~0% dɉ+ ~ j]NŁ}e,$-Gʒt)o7U}cå3YYbI(X'ڷ3h!NNPNJ_);M[Lt2MYה׎%/Ww'(a3 I]QhQ`cF.1sY'w7 u\  ]1olҟNtgy(=G $`o\3+%j^L3F(TO^Pvc[cӯ>:嫩}_慬p,E$sqKϰH|Qqb#Uɴ-5.(rc&U#ڗ54uM${q΁#o."f DI&nLRB ӂCW։#Վ<1HʻRzF5_PF6A-$ҏP^ϱ'M )G5o7#P,l}.z2R=}(_j< VwD4e@ߝ5"yVpK)/wWY>L䞔M-%ut7]`@X§aێlpft)ENv)xO(y5T7%mMZ{'̪Ò<0*EvLH++Fs'i}[eYw{ h^7VP7lei`}D7v=pZƊn]|lqe6]FE~D̈;_-q>I E;[[I8 TFmm76;S&a]C{ EnYi"]{~A$Wގ Z Դv"!jF8*3ёz8̥s(-!i7,~80qc,)Ğ^SIY_ 5=zGl? Nw*wm)z_H[Y-Z|ɇG.h ^$Q!':ܕ;e ھ:XOr=q4C֯*H̟/P._.!#tU+^gπf$4s%[͑-Q(ߋXOc#4G)) KV`VWkf+ y'lѾb?(Ds6t)W]$2z:tjJ e t9E?{ \O ^k߇<<$y,hbCs>˦Lb]%Ikf_)s:h3t7 (/_JC!7E<~8x¯HZ0˲,oJ|kq"[n+&+d^hGEڤ0hf H\6[QVZTQ&+'秄";WwlF®a2 )&@-q"!Ut{+vzDuM54^"K;mwհjLOM8%G>T3$)CE5$S\D ucb,*ėdd0NH7pAU7.UoXc.כPR[?YVVZeL8TWfn-^k84\ ^I%#À )ED墑֔zQƋ̟z8,drAjw."poxl]3\_^{tOn6yT^Ov-EV|SG<ԫ"y?Ƚ~j̛}wͰzdor|)V]֪!f^UfwlHO1B7/](o_w'W$.T7S퉅o+:==l-D8bJ*0ޙNU7.L((^ $9?zbbr+ -F ´QRYRPeۏͺa^d RI&0N!訯ٔiϸL8r [yK8qyJZH+e4m-= 2Y^ s)1:Iؼx"̓ZKP4,lgdǑ?},Zmdeo^ >A健`3ܓ򈓍T0{m绞UۈQlm\yݯ̬-8O-m"z|>qYV48ϴ 24Vw&gͣb67 o#]sj:s !8)zd+CL3]&x`hϖ $Xj9 .E=o {gԿ<9np% N3̈:r}E*+7tL wl޸Л-a1_e'2 o'5`צ߽? 6Ñ\Ȱ|vk-0N|ײ)}&v! n=0N2'jXFʴz_oMV q|WC.|A%v.mY-6UP{ (JV9]FR3 E Q쎤vsh뒽rY~"gV7ރc j}MM.v =nwuc̤P) jm`?|EիZ&S~^9a&JFKR)MHH{C=yV :ѪTr:5iŃCw/ Dw^,W/]%Kg?l z5&;`$tn&u}RF eUma0F#a '2װf;_C-Qhو&X XZ~ lSV4Qcnur#>4]l΋ o"RUi{x&Ь^_yj!ܿ,#b `QL(D-]:PLп q7GkUN,G.q:K ٕo&ML3XTky"s-\ojAmLՔBSp`dIN||ދlU]t%xF:E5ZNR[1#^EfiЌT̮;е8^)WfmsG[9 Xҩ(eXX: tG'OY+,d>p\W6΋HhHŻCˈ+^6Z} w1.B/qv7,rvB=:I,lI "VoeO{~n/yN#UuM6gW("tW4KV:,t9JĦ4qyۯw)HVHxd4ǎbCgEA '(ٗWpM(?`GDs5N2W)tocw5^vЏ-+G76N9isjdn>@$LcW c2ʟTd\P>08+]:_Tj_]j ?HV &ߔ6X ƚߞ;jnM](«$w[JU mTHD HB v` Mm#(DK鳓-v&?R.ʭ P7gHԉu_٬ T^+rgOaln(D=$x^=KPvo%Ꮇ: CqȌrͱ_"G$Rݾ]DuPŰ6#],kaPGLIUVZ6.{^miF$iU6Ny%3w7Z"ޒf/by-`L@[0ir B] W5`ih$)^ u]=?EC9chC-ଣ &fOQ)k:u0G~%$1ybuyɭQd8ϿgYXHˋӈ(f>Aۖ&_)@\i5X7)G(wM0jf*Þx8g>\_ ;a N$WIݾy9/xYb?=2.,q0%o7sO)ʖhޭzz)u&)쮐4 Dz84 06dd92FzN5n! -**IG5# kb(kq"}!! ͸?҇moi5AO Uu|֗?;{✟C$r f58oXn b/3ďGdg14ue' W\KYqB1QLely:+,A=;(sWm+Ӥ򪵓Q;f\pG,? x0dNĂqȝ<:B[\b2z,&Y':4W~{wߚX upMWtUSzC}=ҝ󷋪  FB ߏNrlHٕIRKeKRSFow4*! ϕzYɆsE.lK྇DӬ_5pdN„ཁgƵe\)`qڄ[fֹ]2]1NpAE|RN;"e>64z.uǗfO"Qps. jCLi-7 ܾt_|+Dx_r;⨃@nkEǠkMOo+Hwem+Z1%! kҧ? ~PA%IVByJ8G~ݻZw]ff|К/S5W}csnrUB.~՗!@U.e8BFj'sJ.3kcx9:cbOPS{=؇3tuA4î9ަ5ʫ3^Uk9_ @PDEƥױw;áʃcf+JudR`~uĸJZp:8n9=^Td'T;> XI(1y1 [?1e]S{AbcI%tpTĵzq.!.kVlwD *LOuX$ǹӇ̆S3lG\*_YF4PT<8%)U;NvN= 垊c=+i|y\rvr|]-8YoqP_r媟0~@KͰ4Ny{3WYY%(Oʼn4Y|w&s.xܢˣZ2YEJŻ,A>s#,}:5 5v׎!2}|N1|\l`tP#x rhQ99Α5Ey LÚQk #tfq|Wc2Wfr'ߣ&94ɚC?5f3_hԳր.$YԴ.֠ݹ#I f2Mz_ krO6k.Nw9(qTy;&9lJpuT`qRr2x1G ''yd5%v-Fb{<5c?pS 8Yy{C,)&i;C~,').k(wqeB؋ה, Z])'8++Cx4FXt|jD\` \f1 䢡|v.u 0eHd$0xu {+g4}nk 21WTUVvo8AuC%[gC󏅄ӛ~ >X;S:`8qq9F^K؜rl34pi7lQH 1z+nig0Txq%+4+x7;ڏK8#1-,' }H&%ջ~znp*eF5<+^b)TĮ@mL$4OxW4 4qrd]=/9;SڽͱsЙvƼbzQ屰vӳv+ۮ ϝO3s2|Sqƴm!1]qF),Kg:{4?rNn1D#d{z P /ҥQďGFcW3w>4S71٧`iҫ|=Acg @ߋ I@Hs0oB w$/R a\TSGX1=XARC6~d"Z3w50nN2 )8_qzH:z|TxvMͭ.4h 9tU8C.=$M҈[f p?ROv,'LڍZ~kIuƊȾiEYJ·l[L(O#z6ޡvhi8u2&lBCK .R.i!eWd2ѠM]w6)~oA+zChF\+6*~,u3v=(ˑmG`L`L׹CAZȩצV#MRQY9g$U P gK}."P[+\tr^Em=_l)@ 1{LDM b(X.,WWDOBk?V+2 fy][?_,% '͜eYwmK dI(g;_VDa6?b8j[Ynͨ'2xYGx9>/3p4<36_]p%%,Im@#z °8U]E J^4Q9 O1՛uQ%HhE=`יXhPBkޞ{6Q@3R?Yor 40@ Hyp) ;:=D ,j-z|qOFTQ!tnt~$$ӓS{oMx{y 6"w':_eT ~Bl=B7NX>ezLJ@\ ˧΂ko) F +1Pe/MZ#?Y.I"-8N)?F4Q|x|~s.~{;X/QsTu$)"9G}8-M{|vSf=-{%^9@JRs_HY/ H祪*0{ڎvސ!=Ê1A+xF\3Rĝd(hw)E)2.ʁPj('$Cw^ů?ŌhNIΎvN~@-=bZR 9]C􆼖"Uip 94̊xK'f t{(ƖYm66a ~8xcwr@%6&/҉JjnavqMkwAF9)g-nrA-|%R%n6 aaiACԌt00I9GwvdA<jdX` OHi*p]۴d40U>6UF|7sil~ktW8o8-R|XKw˛`)K& ]YZf׷'C{,W)?z41 a0VBq|O\ߚ]2`]mvsD$3][U4Yd:-w˞p|t؄xB)p3 pr,֐#J=$[8*[nK;+(p{XCHS{ciu8rp]á"tN#R.-0-1,  *Yʯml&oH4VTx*3{\.Seq銱6|عw5셱vOػɧTYXy.QG\X]旐}Gn]e)Lu?+2':{]F7Bb{DRnyڶ-vm/c818O"xޜSVqCbq[/Ӭyk':Ja- ʤڳBC|4^Cmnp=̠310yޏmGu&eN3%a8ܘXAZ| sY {w)M҂U1a%V$C26/\0|'*gۘpF'/z[K#MI+ fq;$X}"f㓢 p9 sz_3PD, M羱 5THyHGEGHxrr`ؑ2˕E+J" at(=T^l<+QONe6z6~HCpP垿- 'o\<8U KGaTa,Yf ''z/ S?BBqon`ŸŒ}P>/Mi0)H@ Gi-ymzG]rO C. 9'y$R,]X7[qÄF\I7{l;Y/2F6 Jr-]. fl#wA{F.Iw7.D_x|H`oLˬ. 2w@gq+Hɑ4r+;^Pa(0=feEDuH_ Ǚe./8{q _k7Z?F'pElj5^vcwv+cKamR4Y~.c9=5]ͣGţ6A:`ly ` -I]Gxg9u͠#PR5B~> XDA" 5b]-:<x5@..C(Q_Jp=oIk2qN?1%TX2so݅~V)hAN.<ΪQc i">BZLaABBgvqr뽠쵧{:@SsiQb\+/y梕`$U揂%9bv+^\G"+Iu̮n3Y /R<=.ٛ1JA?sh)}1ГWT♝R{+]e~Q6C1m*?rWW_olyVC4A9QTbޟ v@oF# @L&&y׿ǥD/VHrGKv݈+ Oܬ?{TT:$tN|i~u0WrE\`qh4"GGdHdwIuOGRR:tL>-ߓ0k`ז say($I(թAKl,#\a[Kw="F3*+b4~{{j5[l*(@ed*~_ʟH:n4XN1Q;xNh'Ԟ#.s_KK20} iWM&,ܳ >/,& vÚv۞@½^y~s7d5$x@#{YnLUW4-"œ6>—z״Up^0BWE2,Dh .& M\{ |o=|F;󘯡 B>֡.JHkeXJ]K0+;ٿ'aPKs7QjbIkLO+=/LJSc4 *cbnΙb1"!) V;g.axc9@ak*uKf/4~X__!h|Why=P+@k|/LD-3 r),>μ_ 2`g$C!qucM]{nB©e[4$ dWITM3Fn+Z /NYoJ_̾?N;kRvg.-B{Ԉ\&i5BaЀjP/$)̩حCV&xP_ JBpZMM ;>iR7EV"'bd43fMwW-7:o*(wJMPދ q.U LI_]Q>0h" UN0|KS WJYSŠol*4e~/Tm#K7z 46uh$=0X6QV;0 ѳ)yvx+>wPdY19n)s(g{VtPU0,9ewOũvKm<(NS?Y*߅tr𹇌jnV;+YɏLs*/ V&[7Ҫ U9tzs:6Utvk31QrN_smRƌ 9LuE3PvLݾႜ DOѪC[-"=x*̽,aQN[qyUzen[ϩ;,C.zX2(i5;֛ڈGp.1^d?Z 1X2Q xhM4 dT+zǂ; ;f-?GolZ.)k5 Q+ R6,堕Сr6UUM,eNȡY;+ +ca @+S@h:Co#?Qt@Ό3/5ࡍ TSi@Rf`]_YuٿJOoC;Kz^L>&Eভ-Q'eTJm;q'\VJLɪ' Aj~Ay2N0K2@ْ!sʚ_ߺэy̠ʵ&L %n@>p'v;iꂪA$v$,Y# \~pbh ="sn]p01simv:m?a&ip::>zb "o4r:Tb1|dnT}k<80=N2Q\9m5?k^,hH/Sۇ܉,|{]Fpk~]j$:qq8Td؟AN̤o+lW~~]x?w:p(I\dv $PEwyw<65 7%C+s3ׅ p&?vzwaJ~BC+, M׊wpda9u= JSQ͗"^mxEҫ9ٙ>rц_B5hj:h:ACM{Wߩ{aOwq|X<~\nwC?E4:K^ĵP5$sQD8X9TkVշSX J5=uG=.kz3;Rhsdq=&'K9{9TfԃI0W@k,^:}fc:t=uh]= &0ץ\T+ PKL_Ԣ!hؾo$︭҃P˘3{, d/nZKA8;`KR5aؾ+2XbYV@Fߒ@`\Ze~ϝLכT9X[&d  1 u+ٻ]9mmֽT+H¦f26|k.S&VKf3Ilj{c!Nd~E.}낁ao}E %rc@:(:>| "H E:Я̆Uȩ$'_nG,&SvjGLUwYHd~Ty6N\^)>I$pUa|&DG^yrXC\'#Ů y> ]pJg'_+7HIDՖH}gU*qNnONAK~r3fJXI5aə$(0t4lO[w6g(jR&oI.̖@hS"~I:ɝ^Xhz#q/h(ӱVbj|*{u00=>kܯ&6v1vӎgw:/vY:%ywϟV?։eᖱ{fg 壤3L06YݍSfɢ7%+PZ6>5mO,ct Y)r_`2(N,ؗn[v<-E A[̱ޞ 7oΠe)4M㏭~ FJLVi$j*|h|u XGZ2~8E?'WbQ\=3t_fe;xASmNl˨4zGRzKͶ2~6 k:ko`a5G]&źLbj+0 |ToA wsHI=b=3lCd-JI]FIQk2$'GpK芰bbIa07~u"`^LX癸PuZ>)ck#vcܡ*Nyϧ'l"BN[M_U\a^3&ʗ;M]C:Ii ߴO_Q4w\}/v݄ŕvJO20PԑeAxX$ؠefsܲP<(\j_cKQSwg+eb[LKQ/2rz[WcZXlmҲa 9LRTs6r>6尃9h~}~w]=vo||l UоmZeŴizy]>,ϲW/2 6A'(Y1V̑  Ol},f3\HJ*@[GiO8~7RݿPCq{=cm՜19MYKij_\ʘWc$7{+mThre !yCcCأ,U1I$µQՈ0PKL(&+gBIu N@bT?u>lR »lJ 4qg6 'ԑ3Yñ u~V2[P¢'D?wVSɥY2;nlkS~T^Ҹ F!YƲS` pfkp{zYʋ։L~eGQuã_}4H C"d/1L$C-@Ps^ rTyF/՜*箛x~}Kp5lyu7VwZK&}0f.kŘfMe# |b"_GgI X`62"_>mmXUJdFĄ^+ؤiF3<pZcw +N51E+%y&8htnAώնNux!}j"}sxzOh)+-{Sptiv kg4})@&ŦEo_)!6ߧF_v4 F\++ܛw_ŹBrZna#XPB>hF ų%bx,]kPC)٪j \]{]XAqC$IؿAPhX}f ٿl뎱@24!toɾ5cEi[%Ӿə6qPYYEW6>g8`N!J*_J<+6F 2n?U(/~k\Z_p8}J;3kY;h2up ^MKeE`Rl`p%/ڹ㺊>:QZcċ8 @EtnB8wvǢ(R RO=![1ʄk1g& Z-ೄ?&j쨸H̶5,(D=6Y Em$IYlMz}zm Ԑ*AXϢA_}32"D.bVKӴ U~w.P _F8,~Ms1z巜=(Db5.ʟ\{l\F,ň(Ȼo_ G6 F5$ 9iT=PM7aR惀[kIDXj^۱?,lx=vv2KH}> [xYY? oAC`ZQB'H96/`.`zj[Aծ~f ؘV3M_ E'Z6`$i=-̱:*AG?KFPcb-^ :VGq m 6;n"H}Tje*U`vE j;ԟn*f 3nϬ)M|'[D=[ak˅OK]YTN 6.W:rEˣT9'+iZ.w1QΩsŰ欇`*Ƭ>O$ m-K9q *J7JJ%Է[o7&3uY"frvXO,vCtL=%%?-P8bjMb`|>t*& &,?xWHSm[ xw*欍1$MBGO ?nI;ڻKu0Quli;Gg7ki4I QFhh8uS. ⥓:ʤWθG/ckt w]>|\SYDUjy /c;2HUv?0#5] `e#Fpi{½ *Cq 1  2'e|~@wނ|f{CfV *0J)aUffL*U;#/޻2z#/uonQ۰|wʮ{*7GI)'Lye)BB ).t3ĪW,iw~Ӄe!̓0ɝd55˾1Fj`ge$J=Sx2&pF>)B/Аػ-jyRʹWJHf|r% ÝvXl+g),\!ӅaH1ڛ'hckfA1iRy=D/Ba+=zbdh\ծae!t3ޖ* ^ ] m"ZjB.C70N괷PQ&k_>wMToYvf>|]4QIl kYŚ昅k1_j~`HFkb hV8G޹WN| L[ZA."K[h߭ kM4e4CVC[Ҝ$ov&dπB˥+ϓ" *934)D Q M'l׫/s~e GS鍃RDa]z8!^TMܽchr$ҫ#F򝕕SpJ$oU11-X Ѭ=ĢSÛ`*k*k _*̭揕*[[(3WCLֺ)~^ї)RftD"-Jc5yϝ,]w9(SA++ϫV<<}*—oޟiՉA֍ J'Nu$6Drw5ې槤O,!ެ<8t wV=@#i "RMp1 =[5p}D @}gϵ}@rb9Dsf7)-VUP]hQzPNkEXBb9 0 4>7h/y#8{#vrri.65:" S $(nXD&_ ݋|}׾g}4I|׵6lj«2X南cLXIXk q+k n˴^@ksR|UW\.7-41| Z  #3K#Gr֑I?Q΀rfICE+ć}죝u8/:0 :{Z+I1y."G7DmyjjHfxZTO M[niӁ`KmǢape'}VovNTQ -+⩹eW>;[N)/{?;ylq#WD~LUT',YSL^RzP~2i?KX&޷1@Y.'cuYL-o.a-@Lcc=/ja*))fo[JbZa`Rxmu^sU4Y,kU57z4z £MJ@_dUyq'GTGQgϋCEAK8/Z@jE3.%нMQAE![: 6nxN*7SWS4J?_E fygp2k/|#OBlIhMAfuhÜ[kXQt|3*<1⾴r z{Jc+%-%mȥ_ *b%vt :25gyqѯ&VFht|T8++S8%4Le HI.C8p-COBYD;_;tdd؁/v*s<^CdPsO'^M{.{gy"L"jt0YTSt는B3@܉ԱvrA*6 Qf3X62_լ~cY6@I0Y 3w-QG Sj?߰`hcCJUF+KzRt :8bB'.sCF^n!}/R m s.'`}7cR*+wd= e3wF|͘zǗ!Q

Moved Permanently

The document has moved here.


Apache/2.4.10 (Debian) Server at mail.tomasu.net Port 80
pNVYjj";$΁4E\N@)Ii` ? p?>sM& $BP=hI] 'y<1QpNVrr";$΁4EdT@)|Ii`(? p?>sM& $-Kȱwnx 'yBpNV,$΁4";E|Ɓ@) 7iI`@:7& $ p?>sMqK]mpNV= !"#$%&'()*+,-./01234567pNVb rr$΁4";EdƂ@) NiI`(7& $ p?>sM-@0Kȱx7 1Q'yBpNVAd jj";$΁4E\l@)lIi` ? p?>sM& $-Kȱx@07 'y]1QpNVe uu";$΁4Egm@) `Ii`+? p?>sM& $-Kȱx@0ޯ 'y]1QVNVJr< ~_9 &QG+, # $rs/0'(vwz{/<5=A |}3g9kE2@8jDfUmail.tomasu.net#   pNV jj$΁4";E\ƃ@) UiI` 7& $ p?>sM-@0Kȳ<6  1Q'y]pNV $΁4";Eƅ@)ӸiI`7& $ p?>sM-@0KȳqR~0U0 U00U%0++0PU I0G0; +10+0)+https://secure.comodo.net/CPS0g 0TUM0K0IGEChttp://crl.comodoca.com/COMODORSADomainValidationSecureServerCA.crl0+y0w0O+0Chttp://crt.comodoca.com/COMODORSADomainValidationSecureServerCA.crt0$+0http://ocsp.comodoca.com0/U(0&mail.tomasu.netwww.mail.tomasu.net0  *H  ^yw Mc#mWÎ)͖< 7@s ;,.d/ݝqrtSX `)ް1X*[(}v*೾e&sM& $-Kȳ@0/ 'yx1QpNVx $΁4";EƆ@)ҸiI`7& $ p?>sM-@0Kȳ IKی ^e> L°E^R/4H$dAgޞzS;|UoG |"Wp`-{*(!MoO%z5&FЬY5NCP?YlQ!XuPx>Lk;R$n'QEp%C J~m.'s]E0A Dڹ兂e0a0U#0~=<8220Uj:Z ؐVsC:(0U0U00U%0++0U 00U 0g 0LUE0C0A?=;http://crl.comodoca.com/COMODORSACertificationAuthority.crl0q+e0c0;+0/http://crt.comodoca.com/COMODORSAAddTrustCA.crt0$+0http://ocsp.comodoca.com0  *H  N+vOb6w'D>ff>I5ݕ56uPr|w ʣg.V{DB] PFYl݌:BK4{';o$;rctX<l?OȨ7El^&뭣 f5s2`N݊a,nRwhuQt8C(]G'`8;lrBoEٵsx#lT|UI^d>iͿHb FW3cJϏR >Qtt.Sz&Ҡ7[(;1W-ZpNV jj$΁4";E\Ɔ@)RiI` 7& $ p?>sM-@0Kȳ< 1Q'y]y^ f9C$=` [CGK՚_ԇŒ07B攨$QΒP@{Yݬw4ؐ-7`g B Ehf$7)F%Ԇ(jDp&#bopVwx%Pr:c4q ox0t0\'fVIp"0  *H  0o1 0 USE10U  AddTrust AB1&0$U AddTrust External TTP Network1"0 UAddTrust External CA Root0 000530104838Z 200530104838Z01 0 UGB10UGreater Manchester10USalford10U COMODO CA Limited1+0)U"COMODO RSA Certification Authority0"0  *H 0 T V $Dgt+7}#pqS*KVpraK=a> >\4zk眳zvq l߰~Ħ/OgCr ։k,폘~nب$CkbUllixH0Eխ |3WAsM& $-Kȳ@0 * 'yx1QpNV jj";$΁4E\@)TIi` ? p?>sM& $-Kȳ@0 %  'yx1QpNV 77$΁4";E)Ƈ@)iI`7& $ p?>sM-@0KȳvnRp\.HMȩs{#ޢMUzaEh^@k#yzkoF{=KؓYZA$`XGnF_ظ@͗9܇Ѧ;o8o:0600  *H 0o1 0 USE10U  AddTrust AB1&0$U AddTrust External TTP Network1"0 UAddTrust External CA Root0 000530104838Z 200530104838Z0o1 0 USE10U  AddTrust AB1&0$U AddTrust External TTP Network1"0 UAddTrust External CA Root0"0  *H 0 3-9N[l͵#ޛ3)L}JmPZ֗)ZIz.ʿ78->ApVO?2tȐT_x@<a^jPךNqqP` 8i&LO#:OΟioBkDǭmA_rZq7yeY7/ ’r8rE]*}D+C%aijX#3VuY)F +eBo{]S4Z'00Uz4&&T$T0 U0U00U#0z4&&T$Tsq0o1 0 USE10U  AddTrust AB1&0$U AddTrust External TTP Network1"0 UAddTrust External CA Root0  *H %#Aلy[#6ewAlG`Q2=&ǀZxy!L 5QҖ~Np9 Q-Fu$Bpg5J+zQBzc满+6 c~y{ @jݏBQEb!h C<|$ةs?V18q.ጘ1DLsIv`k.LZy .՞c&U؂Z{мǏNM IAY+UsM}ԑXdfFoXGX5u7%fWߥ+uV(% O+Ќ*!nBOdHmߵ~Ε]:~F?#*;"нM E%0CQ[}{M$Eos*#a&M47炦d騉n׫n8ÒP^*>kZnV%O#¯41~ϲ-07m&le*m~ y7ְVNǪM?B :G}t-AB@y͚VTapNV jj";$΁4E\@)SIi` ? p?>sM& $-Kȳ@0S<  'yx1QpNV" ";$΁4Eڽ@)ԮIi`? p?>sM& $-Kȳ@0SsM-@0SKȴ<>U 1R'yy,Ѕ]F*Aم86\]bKv 9SFGlr.%@R4ߖ5$B0N=daT?F'ĒёQVzg×sGh>?6j.uvpTMNP,<@ X5rW<&+ YDk%c wҾF!tɚX ݻ'tZ(3p|"DgpvQ7AP[r-,YއpNVN ";$΁4E@)Ii`? p?>sM& $-Kȴ@0eR 'y1R6m<Ŋ +&#D61APޘ)ݾO"=_>NXJ8` b/EWэ|az#]I;=sLhc[^bOA3JQHVGf}e5(i+sFpNV$΁4";EƋ@)͸iI`7& $ p?>sM-@0eKȴ@~ 1R<'yP3p|펜m=yz_f9 x,v R4-y͢&BA?Xl?XS]??cGdCFfJǫ7xL]|75ޱG(lJ얎sLjOw4iI4YN},7URss+@ h~aUЫޤpBdh%:sy?F[H#˵էS>Z_fy3p|V.؈R^o43p|j'p@ԇ%ƼTVnbEI2b>eyp4fd x(^':K=XhWD%$R!86ߛd$Z@X.6;,5h;&+3!**єLSvK/X6sPks|F>zG+w W*!qh}H} hs,wXc· ?vjr21!c٧'`C癕0/ܰ%/tN#Mɛ["EEto9Nz1r:D,O1w`)xFtܨԸd1&CiڧuvuwegwQR)Őz`3NrZO Ĕ-yi̗?tJB"UF[{(礓yZ[6kO2Ք۪YL e;(FUؚ@p$lhf\"8vHX#Eucg ,ul}cpY!">9ULO( ڂE,'Žo70NКfA!3H pNVjj";$΁4E\@)+Ii` ? p?>sM& $BP=hH 'yﷴ1QpNVz$΁4";Eƌ@)̸iI`7& $ p?>sM-@0Kȴ@Ҩ 1R<'yYXqO #07@tE:ƅ\3 1$zX=VdMoPgXk 7k Rhؗt鸥2GN)ܧK_Z =aKy0ۂfcE a{/z pv+%5KbXlY5]6\Tq+)K/#8>|~R HC)'bep"A8ePgUB μegLy~e,[ŷrqjm~,Dx{B6s=ձUzF%>:ϋU+^kNlIX(AtZ!ڤMFR+TFdCBzc328i0e+x1XW =8[s>?, =vh4U=),jvѽ#{t)Jt>ۈbj%L:ʤj.[Gg_l&;o~B+1/uu6ض;3w53]oim"{gh97)k^<>#k\XB e[͍ S/Vhoa^iz.WCX`\z\^cG1tVV٣xjIĸϣ~7-ZA:Vcg]=5"3eٹe &/SDhx *7UnB]7n9o ];Rˉ- Ţ&dsIt-;gu$%Un0A>x0FB|BMDD1_j]\7XzS. DO4A~$LVo(GFeV % y'ȸWjآ0櫦sM-@0eKȴ@ 1R<'yF(0I7[N.xgw<ׇAGΥLyR,aI ;O.4l=4a?zJ3G*];vdY^ V]w{neiX0PPd,S! 6ohEWhB=[e?$OTβ:a2H9rY86:8?2٨bC&Vcy+-=Ѭ7Øo[ցbˍQBZjf=>El3<9Vp$`vүo6yni'(+y8ĺKǿd~mi{Ju2ew[ nW08geCN~s5V[l 4}ޮZ*Hys hْ>|0 ȣ맪fbE?4΁;|K#JoZ!ѕ`;#47瞟ر=52j- .2=Y㥗~ E~:m$khMRuለ섒ۍN1$/R$ ^"savc BtU |񽁟I1m`2ƿ~.uA='>-,O#6d4-i1W&eosq C\Q)f^I$=8s+jtbWQݺ+ƒ k0/e5S=Ptԡ'hW{={- _Q?TJKO9٣uVZeٯ0ͫBǪi Q\fyrU6g Ƅ`ur:\}Le@Ck< KkNyq/%5ehjVŒ@~fz+v` 6>Lmd%qA^ll!kK&p+rH*&6E5cLNZ EK2o{uV|h ;ԝocTS3T_95^O+?3f!trv_!:( [~!NOKH&>ɍH=U{>Ck]`:IyVr9BwJ 6Z~OܝzwkpkIR||̛7e"xKB' hYYַuHX9GC]KSҤ\t%hNZg~ y扤k`,;[VQکjspKU!0$b2c}.h?vz2٩Lܠ~^MqOnaEzI6Ј(-GaQ>@!o MD!z|!^ d iU'pNVjj";$΁4E\@)*Ii` ? p?>sM& $-Kȴ@0e~# 'y︴1RsM-@0Kȴ@ 1R<'y"!P(4~bhb\sV#)Kc"CSl{'<njPgJP̿6&<47sTbb㟓9NN)vߓuȐy1~c|Z Jnpbv<-9knK9g Zy>I-~n4kZu?eK#n)rd!JKE/g~귻H3w%wk$c%L!Ợ8/ hg'^4H%{gy["N f.oN]2." lY70"4OleiT*]FFW}to̒V^4e6Bra")Hp Ɣ!8DR+c`*ſ@\C/B~Iٖ[`c&j)>;d[԰`GJ ~YU\d@߲QȝJ;P,@Ja5,T1G50҈e#x-fTv[KEZ=z>eP-X3ZA p kpى)WagAa\ [.p]pl.{j+mG7\jEbvBwrù.*.#T$`1gԻ_pw҆d=qHf/kO^ctIo1f?ao|]~5ʲg ɐD.ToF[!My6QnZ* t 'O%uhQV ֊o4PoZm .n#z9'etQURh=Nk]{\`tiTwWp<1'6x~~b&|?pj;58dV{1ƽI]RfZls?[ver !标q:eO5H 7F/d;Gޙy#%ytR${Gj[ Qd 1Z]_`y׹&rMm͕'w 6Ÿ~ w&푟ލIo#y-?! gߨ hn6nD Q  q^1úA/<3pNV$΁4";E{Ǝ@) +iI`?7& $ p?>sM-@0ĎKȴ@!  1R<'y3p|WG*Iw?"/pNVjj";$΁4E\@))Ii` ? p?>sM& $-Kȴ@0Ď 'yﺴ1RsM-@0ĭKȴ@ 1R@'y3p|TWC Q 'cdpNV(jj";$΁4E\@)(Ii` ? p?>sM& $-Kȴ@0π 'yT1RsM& $-Kȴ@0π 'yT1RsMPB=hsM& $BP=iH/ 'yҴ1RVqNVjj$΁4";E\Ƒ@) GiI` 7& $ p?>sM-@0Kȴ@ 1R['yqNVjj";$΁4E\@)Ii` ? p?>sM& $-Kȴ@0ЀM 'y״1R[qNVFF";$΁4E|@)ϮIi`@:? p?>sM& $C]nqNVC !"#$%&'()*+,-./01234567qNV$΁4";E|ƒ@) &iI`@:7& $ p?>sMC]nqNVC !"#$%&'()*+,-./01234567rNVH";$΁4E|@)Ii`@:? p?>sM& $<@]orNV7F !"#$%&'()*+,-./01234567rNV'$΁4";E|Ɠ@) %iI`@:7& $ p?>sM;@]orNV7F !"#$%&'()*+,-./01234567sNVM";$΁4E|@) Ii`@:? p?>sM& $9:]psNV9K !"#$%&'()*+,-./01234567sNV$΁4";E|Ɣ@) $iI`@:7& $ p?>sM8:]psNV9K !"#$%&'()*+,-./01234567nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/tests/pcap/BGP_Cisco_hdlc_slarp.pcap000066400000000000000000000023011262705051000262100ustar00rootroot00000000000000ò KX#V00E,@VddGu`@KX#V600E,?jddGYu`@&KX#VR,,E(@YddGuYӀP@=KX#V#ReeEa@ddGuYӀP@u9 FAKX#V,,E(?mddGYӀv P?=KX#VeeEa@2ddGYӀv P?(9nnnnFAKX#V&??E;@WddGYӹv P?9lKX#VҠ,,E(@WddGv YP?=KX#V??E;@CddGv YP?9lKX#VCCE?@RddGY̼vP?6PKX#VGE@ddGYvP?u9@@ @ddd 0@@ @dKX#VC,,E(@UddGvYzP?=|X#Vb ??E;@TddGYzvP?8}X#V,,E(@TddGvYԍP>=nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/tests/pcap/BGP_redist.pcap000066400000000000000000000005721262705051000242570ustar00rootroot00000000000000ò hJG-E@/ըlI 302 Moved

302 Moved

The document has moved here. gUK 66E(@@F w0P8{6DŽP;qgU 66E(@;Эw0 PDŽ8{6PgU 66E(@@F w0P8{6DŽP;qgU JJE<@@ wPW9 gU 66E(@;w PRBWPgU= 66E( @@ wPWRCP9gUu E @@W wPWRCP9DGET /?gfe_rd=cr&ei=1BxnVcP9OKKk8we50oDAAg HTTP/1.1 User-Agent: test Connection: close Host: www.google.com.br Accept-Encoding: gzip gU 66E(@;w PRCWIPgUE@6w PRCWIPRHTTP/1.1 200 OK Date: Thu, 28 May 2015 13:49:09 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 Set-Cookie: PREF=ID=f3373cd6d2e25ba5:FF=0:TM=1432820949:LM=1432820949:S=OZjW77lmG__Q5Kmq; expires=Sat, 27-May-2017 13:49:09 GMT; path=/; domain=.google.com.br Set-Cookie: NID=67=rqgs_bhWSk-wib3Ye5zq4f9pKorKgPbIkPJFMMH5RWwW9Ykskem1lOyZMAoSgpWpJjQc2qcVqXc0_lN8OO6ZwdacWsMYAJRu7QvkNdktESuIVF5v_dV9Vm0Focn_D91e; expires=Fri, 27-Nov-2015 13:49:09 GMT; path=/; domain=.google.com.br; HttpOnly P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info." Server: gws X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN Alternate-Protocol: 80:quic,p=0 Accept-Ranges: none Vary: Accept-Encoding Connection: close Google

kc7HLNRa#V/"V?۹L TN;ܧwd}&hcVo/Gpw_%/ws:1m^es"[ONn~04V'IG]r{Ί/hޒXmL_./Ez%]Og} w /}.21gV&1guIƉfihw*1yG]qSL0k/O]6ѡ`azR8]2Іpe>}Mݕlv*Vpn`5;q{p*1/ Ww^RZF<,{ M@΅w{ʥ pCtv ӻPiiq-M>Gy QB ҬT ^"dtbXS4iK2~ ts *¨R^ pAnG=C1ڲ9g{绪+o.x'M _ݰ?zFaЄH+9?3Qv"*tUwߍjs^[[bGOgGOLMEN OZaroo?6Uy=u-gf|xnQ+$Ns)8?58FShT =jѠn땾#:.H);K$;d]3}%ew{ TY s<[z}1{nm-Lؔ|W|x`sPyj[ ϗ tK/c4sT-?ׂ˪坷k\/=HkQ% i플tn\n/ˍ|Z6hֻ":@pR/cE6~KiC6ľ clO^#),B耫GdnnJG_ lR;7 ,6"Qcм ~pJJc&I.4^븫~L媇7ٲUN QH$zz\Gfw-wKn,O-c}vB0B90h'@h-C\N8 ["E3u-O,y>^eҶvkm<|5/%k\-z&XfXP-.>_+K=_laPS%U*Â~+oOxj مT>ڔ}2O VQV_Xȭ1aэy|95:tX39=T,zy8ȑ}3Ko1i6!p (%䥏\uϚ91-شH-)m0EC s`5mˋlBs]>,p?? FW8ZUG GPqBvD@(p]tߣv]y$z|~9O]"_Ywح~HKke/Ox*X^X(?Vz('~$y5_ ;7D~ (D}·ȣc^ĵ$۲%Qaͤ:S 2rSK'lD ?D[{LNEu3)[=vä/0o>NŗI&t6Z%|0#Ɛ512Q`t N87dp%=5 3eлbz?V$#_]ڝd5@@?+($߀u:Gtip" tif4W&y22{gNzn^|BXM?VйC@jiP> Z㓣^camTj޴Q9l2aOȆ5-]gN6V:]u4te.G @dն0gwĊ?ӨϙQ^ŏ:Cqo VCj )`T6JmX%)rF%p,[$1U0)p=;uOJukwuvXvgUK\֜]fA 5L#9McspG}v2$ ܡ_}ϖE{Wc~i5WLnX)Mm:Ј:!'D!SZ~Σ*f忷pX'N*Ǩ~輹,@ fxdCv=>]I&[r?ԂT#{T,M&l<Ǜ"ki3 ,==۳;H~A/̔y}( ]qRhM5&cxv#q{c [MC "<.4Gpbr506-y`sv5)BÇ7h_1p0rH6͘h/IP( LeDmmhs'NX09orVߜ\F?lZxM/r_n.s"pD.ijHVuzTB(͇6P]֔(㪞[,o]\` ʚ_vVΝ|e/V,"!4*{iJXr8Lb}˒cj} ZYʕǶI*$Fl$y5- G;x<?1oN[`*ȑ2IlKޝUl])|{lHдE7~GU~N|j6lYX[J*F(JB kM-x؞}@2rqY"ļk1ҲwMuT6RqJW*;Ұik}6l"lfd;|*oMNٯk̄R"[l2oGUD<44+GGM6PsK;>CVSL1zjX ֒h轶9#;5o |DIq:ZV6j-vQ͛:&:b\J*il.%;SڻӾn^Ȯzb_K I=m蓌."/k#̃ I ;Џ$Gic"-Jhڽ#FOl/H|]lM%]0U]xi U~l u+. hn^&nLpEzHYᡴ+.o,ԂF%Ib̀EcO4Ќi|*3vi}j@`2xZ-Lִ9h?wD 06~@+<_ JL6]^wi_6K#_B*V xI mY0O-_MՄwЀ׶ă FS3S'VGĕwmb6pW m?+>Ы彪b_ipY{_Wut+[y $Z &jU;z|0δ  QrDmڹ^>`(9J}v Q9xgGL:cHv 8 WVD!Keorc![ Ɖݦ^ѣv󿤙 QDl}dzUv>r;Ƒ%C}@<9ߴ+ߥ\(?yW}_Ap%Ԉn#Wl9x|*pG\Y{ N,[j'Il1'H^jzm=$d^g9SK"5/5t%?jPg3>܃_Yp\Ǝy"~EZ6Pg|Ur8n_U@|׊XNgy?9D%!%ELw~O<~pmiE)eΊ%&{fV\_yeTUXR |\ yS4R@N@!FR5Eu(͈WHɑA2__H $K5'm+k7m2n/ NQ|ȰWoǦ֎EcXl4X< 4;?>:ޘ(.Cܕ1f+'/wwwKT,ڣDYCBֲFH{'1Y4yOcHPmYFKo' a=Ɣ^ ۘ{FqtoS-f1_]xPBN(vK}ʯ1R+ssxIF=5Of^랢q[) >lIg,݆۹\{-y{ꔩ/^1tqת~BID/p$8pG.I FMtSi/m1j%W.C 5~M49p&|/9A]? [#k*HCѶ}M;㠋MK%ƯEN"[{*o@ $-i+GJ/5ci˦fOhg\<|SEi4s@05^^$e.J)u*9֤a✭&cأg)7ywŲi=xF0+_ڒWMv%rIn-Pu &!ULdM*N5CsvV=NI2Qf*d4=H6"`IqM8cD{R1FHCwn :Uf\Y[io|r(^WFٛѹZq5().YIN.qs#!<.Eu;&b}y b2 4jG\yY5X"he"@ 5,,4NŵpD zax ~mcb}f=;[q¼7ƹ20}g3!UgraDpX}68YkNYvIRu[%Q~)a&yAsƕa^Qh$KOC_:&>B 9m K0S&E[ sg~s#My3Vm'UnMj jVf:^į9Y ',iXod7xɭ”ި:ŸArmKJ0bٲ'J_3pAV " \?G5ۊ 5X03 MVdY~ 2sM%uavMU$)Oʳ -I致Cqe82tT#,~WN,MX8^xێވxR_ښ;vn-eiǥktbf 0M!T*&m w=:JlI'ipwsi`x0Q|x );}\KMWmK/HUWoe\aIGL79Mc=G@f/X#($1-'gػgw"Vː!L.:oӁc]&~F)/xd"5E`ł@ǧM/Q#@NZ'ܕH;ob6%onkOirTK |[LڟR, Hb:VrS-vTGfxjxV*cveeHAЍB||Je M>k7V'͆cx S+)/C20kIqU=AuCmb C`cAS٥+1zoYckW{ >;1rֺm6O:iK78/a`O*Q/gÉ=6UE]_C8 lǦS^PHa *HTi/ {?Ij0cٚKk7l%7  ɦƸDeudүaŜָ9nwK DgOUm;oNirqYB C΋E@k`p[#Z)kmi$jwBڑx\Q# kgtPoܷ<-+.EN%4^)s?<7rSo}G`\xtꗓv4Lb mʫۿ(ˈ4C Jh`f@zw?Q!t7--j2*u.) BΦ̏bٹזbc:EtoXܲ(G`_@pz"nhq|k"jQqK_|7'teSǿŚ (7!,N >K]g1MޤXY r&}e8StuTtE=T|9h@߻n( zĂhY|-Ȕ g2V $vݫlRB U+~Goq0zroCV3$UvJXОn,I -;d~$5GOj a iy !7>Na<- Bm6rhq0GNdGWyM=#Q]odޡ-~ ?: k?݋o] ^]\({\,< koʅR.5Y`zsvm\|1|vkN'[TH$wN!}s윸K۾L,>NܠR-~ f;􋈍[wIO#vY4(A]Ap)tAIg>R\S(?N>d2ޒ:Pլ d!.e+T? Y>S|;jΉ`*y5cqWF7i>ђB6lCG29߲4~9RR/{aO%VԊL_EZ.r#EZ<鉏J&YEH7yPHJQ ~b[ f¾v"fswWB$ˊh䏚.y zRbs" YSDz$_WPu$:u7CI!" ]WˬxqO;l_^4) /B/ZP7oysg^6MvXhRH/R2[:GDz2"z"?X)p_qHOi(o:.=v;nrW|էTϕ&V-~56-CZjl ;zw]`0p&>"-dX,eJQ=d=x⊏k|rFk染5(YH0&$ h,>|wtXqcU4%]D74,~WrNi%f CO* Cj3^gLLQi* q;IlSsy2iu֫r"տJ:v m+Aa&pk"I8֬46[D{,xҷe&XH4OO2Q:[ߨ@1·#G 6!:S ni9>3D2/`?/Zm(iRWf;?YCie?snVW!'rҾr$ZXy%ZOؘrcVڻ?Rcۨ{{6O@ ;RsPS~G:slV(S%"fˋ-")Rz8!2>خ1)Z +=Fd|"l&vnrΫ̚[Ξ&P&]玩5]TezV+iFcGo n5g_i:{ZuSkp+=3j9#l$'M@ytE^2^UZqrx8yxߥh3+siNp 0Dc״Ӫ,%NpneڢcΖ.9sMQˌ1e黜0ǶB0q>z3ceAlƽ6Z6E0A?9ȅ޾j@Tr{oD/P-_SFA fZx/x8p 2s@-9U-Y}]UW/y Ajoc׵[+s9ZDH?ƮУ04 "y F&.x{X\8+ѕM-foUuH[S1Y2ʌ[TfU`7`m@g3ă}ڊ_^.IvfBᰠr#\B˥F#ϔ\8PWSt&mry۸jQ^0VY:@K2gڐ7쎜<&> !T\Beyv$e.@ HNڴP~qҘdd׈6n$aVW/ g,[ UFj3ܱQxFcfo;_b畃]G]}a}֍_*=:t~?]RD;?U'[ВN"Nuo*_*l!VQ1CΞ'ioT[cl`"(h/rJ&K!uj4i*2ο֡j7 bt%\ G<c{,qbЊ WL[E.L(y 9d 3#1koȖ1M*fu>1xdsIr=[FTtB!z5(W]"u4v6]/D!) Q,( ;C!! ~g~#T[Z:ֱk!G6.l<Ê\ Ǽ,uZʏ% lH,8U/ ľ^RMY!P]OgeFzZaz.~TGdWFBzsVkꚜQ0-JfI,1pԬGVٙiDp8rYB֦_pIڢ^dj>5)Na Vf=G`_kXW jƟXK_܂/$WsY?^>O*B]5^i\k {@T)$._ +X}zNRccq܈v&2%E;Qko6} AݠCz `\T`C.5z-/Pmj?(W]r[et?>BB|9q58y&o=_e4wǿOCF ?6ߧ LjMkJqI bXGNs$CE TrTpU!rYiy~4 lrN5]; -bˎ pt3n><.bת,)02/lYrgd>Y;J,ޯ0`䁢/Pq[(x؊7ܜG >"rLv*JRE A /MFj0wCR=hG?IRQU WįC69p:UeR'vA6:QuAJ9^!фCD7.LT,0V5W.8n{÷W7r,&fe0p_0:R.D*|Bbޥ]6'`$sp4,rW.VQ.B3tJ;;yQ߷oXa5S#\}`mm7?G}~xƤ$|hDg>;aM)g^(瀢=g\4kʲ&IJHz* y YYy7@}Of90\Yl2IC2 (19=0HRt6DpL{O Ho`x6"$<n.~r'eeqT95gc 5|bPG.'[о,0Pc1[&Eǟ= Ӱf.9 ytRDQ*9c,GkSp<(}sXwE98}:bIuM?^Z(u;@-}ƃ7:J_⓰Z1kjilJS u`F;w}_фX@tm |Lj x;eiŰ5ewLZ} wx} ~י" FܤMJTcoYW4IcR-':wW¡y,JZYىo̠ ѹ5 HTsCi8pt~wNJ踲}ܱd0jPvzX>t DA2R]%e<ٗ%‚/4^*Jl N _UY+4ޙJ_yTwǥ$#ÉrөIA)4)OY;-E|.}<{]p6/6*մ¨IDTnRƈmf C,6Bd"ws uCm_`-1GuMQ*F8w6#kr*b܌.e+=~Ÿ?v\Xj Г~jd:*FG,H\6:Ҵu.DRRB JO/MFg6Sw>V)C0c(p>H]LZظbu ݂ &|;n e*ή+lޛ^xԋw}Ǥ}_njljtR=c(=/5F#a=*rdNX?kHBH7 J #b =T! gV_d)'4hrǭת6sڀ5n3w_7@K'{&qv%+]d4W^(Bjj開o\{r'o | ML%}T֛XW?x  M O$x[vև'_%v뺐FmaN8K ƙe!5EjdԽe? ֊c-F caʿ/Lgg [ i /|KN2_<7ΞZ`:$ nre^%}շ[2i&kVjͣ).O h02Jt3k[T5=guL%0RIy*߿W ȶo(~]6p|r+إVc/s@qJ=EN{+}8]540ub@28[! ԵC*Ӿ'&9o[\g"yS*~ZnIAnbE7TFެ3OvR41/3#'M#5!Fmk%$cN*Z[3*WJ ss,m8\qT: q FXj[{N LfX N{˥IȷijiAIJ,.GN׿7e>6U%3#{$EiN1aqߓtvjsm&@}є{]Q.Q.>ӱJ{L;7zmcgD- Yjwy;GH}]d >mMܿp7@,}?@W'.VDnZX1_8(k bSFm0y`>Qr?705|1"; Sm=n޺Fjb2$guP:H=LZEWygF-FiO{/AVS]?g rΑL4F_!PΎt)SZW`2frI|ںk#Lھdk0Vhh .>XPj.S׎^fT`ڏ@싅>ɩS͒Fn9)RՕIم>&3r%OQp84}Qyx^1N_ V|FWwwBV(]}w$k7?w><uRZ\]u5Ujߟe[C% h{x N~x.?j- d+.9L"i9sn8*02g܌K:iSH0,`V}Ɋg95VV%q=x·=쿝7 \8GU^sHf&/,Ӧn?w=-:׋X %cj913^JU^Mg*,d+SX K|s5{,~bV&Abʗ8fMCqYVO%EӔ%Sdj>T9#$+gc.ǽvbH?=U'%f_o: Dngش&rF'uO|دrVcy-yyakcD[vwk@g|TG؂fNCF;Glp=7UkGwOWoz1=O:;@9tj3c;#BMx~δDSz%JQKü1.hA05W^F,N9AQ_1#Q׺Y BVTA]< ?/V҆@ݥ4սUfqYrl!4i;y1.$$/6l 6yΛC'5( -|}1tFZVlɂh&Жӂ4\⇳$ьzc\I$TClYQPL@ 2 [M|Qw{uj9AP足-7I1t?E[6uQ/8`l0:S.ڍ|tD%' fmˎ0G"idrv퐅FftC|m !F^.iZk2lunj`{LuV{ojRq[vjϷc(Q:W;z L%=MϟbqwL yIM$+G̠Kđ S1ia&WnԤjZ [y+D]si$n!ċ gllvغÈq :KWYZQBTUuQ u|&;ai.e몊as spwj>w_4q]RXHR\u&7d+h7ffaD$j~CCԁ;~@ukB64~7+, _kX>Ovgo(Fo;2R]:H z8b]U|0JLMybi`soUlg>;ܦplxv͚W2| 6y;T`קjHS[O[e BC>P3ChJ"ivށʾ6\R5\ $90TS Sf՘1tzP}q)'Ғ 9%A1 ,d %AH?6QXu-(ԏiUmI 2 |AV"ꕵR AWXfk( CxY 9:"NN4׬y_Wrz%c&*-ujiu]iqQ= DtyM\N7qr`QV^1]maJ[M7r^4I\jiS læʌ5 1^<5ʣ=Fդd9)\ Up颽֐!rb7p1'v)mi@MYK Cu.F9SiϹe,wd+Ҍ1uD~V.ɳ<~sqj"éGmmrH+A]ڑ%Fq62%Q8\0з;G[[XnZ5Y(lA=n%+ۢ+Ƶ^Ȩ2prO]Hk dKw;\,_V%m?a/闡Z--]T?8pmȪ %gO|SO#Z*=ҫGEҕU-q]wwm<µi˰Xks kk!9y #Co(A 32{^iH,8u+*!u :-̵Ud,ͷԇ? -hoHk9G+Am pYaӎ[&wG|uVaFFJjwR ej1 )4Zy]si*XWcjEryeHoT=|"\<{,T yᖋk' x)i3xJM*+]82{r%0Q6iaa%}Yz'T .3vĢ8Riı+mkr4^tA $EU{SE(}68xY9$N!'5pKUH(/OxKD+;$Ysjhw&78MbWCS啾@w}uZKKeJxB-%x[ѩ=?Ob7{s٥= t eMaKMV˸4;tpe:Hg^sUs[o t9tu幂b@Gqmo4TwY۲*)]2 n2S0NL`+ o@\y7]6Z{")zHwn̺h'~VMLXDeCq'?̩`]v!Գ\h:xVV7L%EvfVS.bN09dҲaR&sĜ6#Hls>oNpxu|u6G43RT״rrZ!ΨEwa86+avŻp$,OJrЅ%GT3W^LxK0g]W\߰E0ݖ762xKhbCW%߉\WfFڿQnKbma]?Sm@gYuAi%5LC,k`zk>$g1%\<?H|^sx_;prz{jP{ۋ@k#*׸F2n _x~w:l,^=\ʻn݌KjklẎzS)VUefϦn4TS.kiRlV{z?5-ESEQ`q7ۅ{q;Rђn:g14B>I}1{ynrJίަdA!˄X~- )3Rumn#r" Md06_串8`\ȺUO@@\|ZCf)}YSˍ1(ZJ?AK`D"U(2ZlaO fr3fVTzcº;8A(YF2xay ƞG~v+- p;6U9̭ ,il &8z^孞 ;7?)<|(T"?C%Ey;%[D.tkɷR;nitht8f=OFłY&Q5kaW;DXgj1VV n6ؠftr4JLW0a [mH+5&q#0Z]E|Q!.8jteO_|87DOJm6żVäP@.]DoG}rypzX]8Z ;yFÂpr|V)!푹IJ' 6oxYvć{m]o׺:2{[E}SopR=7lMK1Hz+fSfwA 3zB!x.L+Qnp. _,QpdM` =^qL^`tGD+aϧqFoI[sd-a3b@ύNA_ P#vxIa%.hs&(ل d=u ; C v24jp˿?ǥi^橺j3JЌ[TE^63fi< \7L1"Mst\-& "@',Sg?I")0/Zx=a>]y|S6Ź7%EEhh,(QVF\&=QтuD2Vtd)DԩYuc\_wÿpd"PGտ@kwae ? &&0' ھR?R3Y>?D}܃<9zM}y&I^bNj0W^?Y8PQoK)ʙӓT"? MFyqZR4KPPs;R輖TccfJaE7;`>ʍ64OkP4*T(Y\24~56*cp2!b& reH: ǂ<,.[*;eh/'6GgL4ns@f2rr=wN(#+bϵ o2y%0v\?.'ٙ^w[1k*՘+}B5<&`F_c_ٌC SLǢvqo5&է\I܈zF 5bɹ~jvZƆ]Lܷ MhKrk`)TӗWwM?VB `xs{x_cxR]xc-EIᛧu I i-nV6aF/Z綉jb_fsGn|l 7Y5%=E<$ }Ey>}*>(P׀vz XY8:Rt!sܹ|oXP2΋˺ o?Xv^$=f5;!x@MÌ+@[BcqOעEIG[6'zk%_H+Ne`B7tÁfF p,ۣܶѷZp@ʮ z#dzTjM1#%əA+8uۛ+8tX,(g;FJ=(O3w_sb~7'd Y׳Na9dlbT:޳K mı&L|x[c ĵ&'TCϣ֛;>9SB YMQbSTQUH73fi6 O4S"oFߧ'uT;CLy>Z 3*D\*JGW5޷={lyd]R;Ti[ lٝ%V,wǴ)Ϲ=fϗ\%!o c>E9 cȳ$?@Hd<N_i8G7oPM Vn/-GjAe {vdnVꝼ"1s=Vcd^aQ p&E'WC;kbq?gWyyBN!;̙h]LJY]8DܮՕq_sW?e|(^|D 9i/߇2G=@Y&l ?$b?.Kl zinqyI'!S]@U px9ׇ+26n3dy>Hb _t8y3= 71vW ӲK 㒱nz=}U2_Bd~IcG#Jzo>w#;Ÿ}5󻡌 v5V*9dlauїRTUTt\h7Vz!+I /yOQ*0a8x);8`(dfD 9-‚T<j?9GgJJ:J|#rOA+%6bau?{&_#+onka*Ңgr"WacQ[ɦxP0#93zeTQQA1TgLۨk(kS \]L~)_U{e:ӚL#j W>0&4DizY%qdKC* YHiwZ3 m'ܕ={fنg_i"Ny/B Tqkvrm; >;AYՉ6Tq)W&ʢߪHJ6W} Ι{fY^PI V(Qcn'TM[a+iZѣ8_9;\Ƒd O>_WcvikJrJQmzEĮh>:o4d 6T|le> MEM~Zǹz~.Oo0Y;\|Rxl=(;3y0uzS͋cV@]0~**KJU_Xv#bVX>G(pjȲr_ u%1c;9o H̨)hBV@d7{eo}sY៖OՓL[y:+,|3c/^x~%iUR}r [xؓ=wY"(y@I፩PnsPC1P|DO:,'Px"*p*Gɦ[\њz58C ᕦD-zKاi{ Q8OЂVFodtW98/-a缥yjt.}5GMS^XL^tJzUij'0·!o1 a_wvQ-ۅbote< Y cRxex#, KAϹtF,ß`5݇FE{guRMNWM_q\~8}R"c-wVˉ!|Qc$漶,Xt%)TʅmVkxME\" vۖycvJp)(>})xTVtD@QejB3]-}ʲWĬ*pd*eP/7VWvL9:RBY!Z;!}i+}Wm6͒4 atRUV w5_Nbij&ϋaH dɮ@ݟ"مyb[vu,8(Cj0!)2m!;%m%V(LFK'3V޷d@1<X>@3FiH}Re3I|κq"kEt^;Q0?ҋq Foޟp1+ᤐV1̩: LC1 J ƏBV]îX0vαӔr -aܖY;t lt~j H0XBֺQh%-\?qȩt,hMPV.'Z#׭|`HZ6^sN}̓[-]e/5 yQY HM`cr0"dՂmE|tXoخHW.8ٛފXVJDPs=1k Ynv-U_-E9xP)MmT>%#y fd~-e3^ nceg13^n^6<Xc?7ް6K8ܵ/|_Rc$e)aHM<^:EGUZȨ585z AZ\9f.3"gX %Y6~f.[ڪHclsEmŝr 3vGk3m7e&%<Ə-_QkI-oN.NNo[',ۑYF\1m\Ɗ1gI ]Dح %ŃwTje*rJ#%cW[U6Zԥ<ҮT [(1:m=|R(N<>8N+KH[=ocE,c%8K#'; U6&[}cIjncKg?EgS!k_ y*Ud2X7okpYȟ6VCѮjk ) 7qy{& , ] K|U N/Xn}ΨC40LaQ:uSGg;,6vz9e>zKNJ>\Xb<k&6]10`YϱhfAh>`yuF 6-|cN@x{:GBHoM\g~x^Kzs@v`f̈u*)u|PL8s 2em+Sd?J=(M;Zdu $ILca^y谏Q-lÆ9>u9MU/q%Dylm5XUH0kr{`RF'Pr㡱36]iXUӫϔQoUD4|IfhQ-Pp217@C!sGpvѦc%A ͦk[ /1ZG<Yڼ˅dm>R4 kqFp+Od:"²Z+nj=3: (wa?Zv?ۦaJ6c_G"6=}S_">$~t8]n<- @mU &~j|v Ik,rJ e;|o[:7e?f`~JVR"\ ]q+k_dpٟۮcay#5#4NW}T$,feڇF.Jy0(%Մg{>=VT N5Gz!w6N/.B.9ɣe? O -H-p^RIk;B@hJ.]a G:ɪ_rPkc$,h33c"J .N9}sQ]fRZq4{i, WܘGNoyzSeb Ҭ1 R:/>ydxbE?g}ۈ : {(fl&5KG r޴fZ2Sԧ=_.qD\v2liB|.2mc cW-< ͇Oˮ"n3"H7KAPMXkR9GQ܀5 `)}7wD:Z@4cDoRĻKʡDWZHfClEL%^x WuXS4{Ʋ1;n@F^9οYG`_Gsy'6.JpO6up=53qx~AӘ# x-Ygҋ_9Jt3<]/3e{o^_J:I L R8|Lb !9RK]nK2&&瀝G ,2Uwɀ\xOjΔgLXIE&%y|Lm_-j9AJ0n$Y*u*~a^/X8IdvVہ0Kk~ivn/ƖkSO 55`6švl[P|Oqe:DJ^䣶f-VPaLq[/ova+oaG{>dExHX$[~%~YzF! |CR]#]&Im$F9"=3VFƲi$9}=a79}[6Ag>Va(t€}ӜFkMB:FL4#SuIPҁʩh!2Fz |/G(g:ů T,'adkCʨGz.-pf_b-NY`L"as͊6LA-Xj8*¼2 |ccμ>^[CapHpV\38\U.n\r}č_:$/a䉡Wd@g1ԏϚ4AK) ȧd\(Z~"y0ɿj4 4[9\l]g$rBϯhm//x3>9/ӣ'qK ~3mXphñ`Ѧbɾn}J=9L1MSDDz;Wcԋa|=?9[bJATޏ: Η?l*(?ϮK74g2)9+o8hZ9Wmn*JSEE%ecԠiJ=| ,I}N;c0-3=Nl]F2j/;[V&Hȣ {;*Ɩ[Kg_$d=6E' ! r,~xVL`4.}sHv^A BВ nJB6c0sn Rt_#7;,Y+D2eH$ԩ>@8Y/BWZ;͟y%r1S"vx_a`Ki5FfcD)9/dA٣CN`t>v\?R(*%/d|W}wnYa<޴N8?C%!UXNgT NI'&JWFN&TbpX-']d6션L I .HޖFLLKʮ̫irGV->9iѽ5!}AvS/wf`슘,omXiia"iÿyJ纆19*US9C5PЅMwOܧIʏOp]Ok uZ8ԱOLf4Hsy=@Mԑ>*d\s[z,WgX -'$a,7˟ܸIv*hlS:ug$dS}*BQؼJ5Kgyy0f5#^+w#ekڋO2?r5ARȑ8{Ց[ˋwm7\#znZ@DVk~(rp-OtmǩCa֊ȉ[q5MD6Kp_ bϾLOI/ʻnQ&^@BE1)4-ʯ4o:0 (ۢp mC_yaPuZ*),A;q^Gzߌ//V3ݯ,:鬯)qU ;|QLo!M܃dCeI|,NEuze &VJߒݶ\8Xljdʼ,:}2K'4|i=? T] unjm!NR*Eu¶1| c<0I'S: |b?Nz I ,:#~: 0 "s]|Ñ07(^mr_o4 2mC/܎q3<:Ж}+nAQrI7\idofT%80ρ MC5^)=LD$Mt Oݸ-nk6FOG'[Xb!z/íQm$ +! "^< mZK1ۀY1J.AҠVJ,i_d8j5u닼zt$ZoH',Zrn>7Jh=N睂:\,dA[J,ba%~rj.9/')@>pXQ=g{Ý XRO"}YthE(BaRـk1d<:n9 EvȰRsA`11 "OG(Sj7Z 姕K0]ڕ HKetv=^±~TYZ+>O'-G yݿAΟaѿ@%NaW&Te~[$@(o5g..^H*4M7S1 ,Pjd }qIMq#/5o\wU?zsuTV$Tδ3xы{S\fOCE_dj8baG骟d/--)3=/'8w%'OFdnTBPlQT5)HnV]fvbd?!Uy.iH|!-{3z2I+&C!B]Îzt3xs޴mXP}'[Ȕ34vO`:$9;| Iۈ:cWtap p] kFwJ$|= tz:OIް~8˺/W2Mw:!ni׸t9[f,x& 'I+%copݺ/᜷8OKŨDbPR9a gAa{T+جE!&|cAm }d:\MI7xusA7ttqmЯa3>sUto >36ܯZY6{q!>mIXֱAHGtu+ڰWWj|SlƏ501L'XYj˴ƣ.ۓ>yG\ѬM"ӡNI>9-Cb2ZnM1k? K?. b~•]p$MEO!cUӆ_1~iѣgKI羒Z> M>;c˷fϟ4Kau-RAMFg5P? %aJe*8(H~.AXB:Jo9T{0tI?ug縍 35]=8u7F'?cю7;[JX"Z)GZ/QâtzSu¡7*bSA2& 2z!iuMόfB0?߁G)3Mg杏)1=:ܪx{B]?'/Z<$^wA37,_Was ?\r1A!}݃q|LzY xn 1ND?PL-t!Ư M-l!*, zAq;M=ᖵ (#n1ys?oe256X7B >K/LD( z~dn;nmNdWUA,8uk$f{K@]!S6ma1c)سn*0ݜts4;/I-jL۔-nB>4AxŬ>O- ԚꉥS{4q/c:-뻸`*J@L\}VB7',qŜ{,=MNp/ˠuٴ>`RnU1iz۵A%H`NvCQ1ˑݔPՒJ[6Y*xGD o\-ns()؆u'ijYU|zh8+[7ETL~@^5fT5hWĩMl 76~%JXkt  ,QRIJ4Ȃ :I'ZB䊃*QwoLvSv_3'nɎڮGҡ״<ۯ,JՒ@(,8amdzP᫆Y_I(!i*F|i'b1}}.l&kٱPuظ 5M+- كO 7a%}Ti(n3+N :$ZEKaƾEO,:FdsI ]l&xk42 d欬99- [V 8K%7#qr窗J,XFo ֪[Ϡ4+̬>Kɮ `$xhsC[κͽyA `^ɺ;a3wyIU D= w;/uQpZUY4ᷤ$cz~l[ч +˚ ;RƈM6")-(;4?YU}%fFY"hV0~#K-= K k{l0,k š'.z׾5VݡiLeH٭~5;pQVhbFmgrl5=f-mnE^;eL+afrJz$ քHxtJy?Nx#w,!sRv ` O?m{*AcoU5T{ξ0>£PF-w1Iba@ /aK!%w2+卌{4Et'>2:1T|>2療 JRt6#!xVY1v/̃M\O@i3Lׂ߂c aW|#Pn?!宪RiXgo:^SDSwNc) rS ] 9i,ysg@^2gi{D+DC&ˈI^Uݵ.W{ZZ AJJdKD< |a0[ygC.nl8Bڒ#LQw׾h\@}_Ʀ3pyTgtjYTG,7AǤ y:gu&J_qw r,Jnq(ԯShJ[zkoԬp㓜[?|+>H=Qẹ=&ys.F>|8]x^\EǑ E&Y"&m Z)_jO*$ SD*طd՘W7&h d1W-2e{Ȇ 'jkGSƞNF"Lު "U+oI;lgROue7+09V=6HjH 6יt1m'gIrV(b!{M&ҟ:o7;cNEõD;&ۗ$CUIa p'*۪k ΐ_vfJGas글$փ"@q X(-1t#>qSY&E[wtV`=n(Wi@Gvn6r+CQ^"ʯvfL#WI1.pb?^U5TUR\ia]!Xup"dкKZfA (_MnеFev9^;gvoZ䨂G Qp t;ғ }}4sXXv  -$ tYX?+Xf\Ԝ=.XxMT{l8c9K,z#%~ 8MqPcӯ 3d*Zc4dETB!p O}Ax1ci%gX\ X1,-Z{ _ XmI?q@2]?Xok Sۘ.Ra&)Dox|1O7SJ d/jNp7w'D(`cЕ?)U=%gpDu``w(O85VPJZ|saa~G#8J{p|Rͫn:$8excCd YWYU8'Jf{dÒ᭹XqvSufߴ7u[K۠ lYΠJaYK#m`0%#)m D4236!MТM`#frYz p%Rp0OyEu7L :IiDGh] ek" g9RUWG}Q&3uwЭUYqT9Chdra_}LK馎G3ZtA opM8[Y| e;[B2GҖ 4F(3%gf^v]12hd M{Bh=m[Y+U߬{iTDgAyu&&!;tu(8Qb^9b7EKI@Q''rdʱO棛0sFU'*ܷپ vjbp3&}D u-G8 ˝<ȀyPr}oړ/MtWG$tXklИ.dt_t6wLu?#)Y'۾gt+4|d OPL#%?TuLV A_BѩZ M'M%6MCv?&085xϝ{l6NQ6Nɭ)Әv'{H,ge#*!Ii + ?1KQ_ ?Ti/%.QFPx8n듊Z"p7pĩޗXچe$>w's7?<'M,w<)+{%mw:;-i8&b@g{~`o7~-Ʈ'# bVRgygA^!ہɷI,b٣4MR ^rG&NM3J72t䜧VjdQ`~Ta۫dd Qb!"|0 FobZne--&? 7Oor,sctdV1;nH|OWԆ(& >I4%2. 忀Ćtԃ%t"` 2 PH!vFa~߷&FeC"(Oʩ$9 # ӯ-*se̠==YɽL޲K{kv&7 4yZ(d/j NbٖV|N£ӿذ;5]"ufBeXGiVAk n'7y\A<^6h<_bu0:%4P$ST 2n^3{>n98y&ժ kq$,Z"m߾1J?iP(04imu "bmX*VpI"\1pFf2c~gsE?^b^-8\ ԀvXh3"f?W I{CyƁfʼ>Rf]FϜmzy*_J̢p#ze_CYuAe*=vQ#Wln.O4i˜>KC  H}EA!YNAߘ O3݈s'qwڅf q䦭N<}1:]hEjmYUT\C|;`9h +`oXiij" TZl=ə[7ÇT+Su AfSQ kHwzJMXUYP@]֖ra,Ȭ&ТX"ܣ)4\ҕa%-u}fxUR9SߧBaRrjo^H_1'}dŴ$쟂 k NQ^ C>sly@"|(Z43$'&q_R'< iPb]tOƷ?1Ÿ>WiOjw%א볃(@ O$z}TCQcm^ՕKqBPy^FVڢ& O_O(x^׾\7N;pU&XNIYO v OΙu.de q\3RuA>" _ .&"{l.sPxMǂ?QÓ&v(_RF=qgl,Hl0tW @B~@][baM %~VMbQaoY>zvFAEd\,gQ2F" ]B|eQlA%3ۮ_c K{>Sax5@uyY+VqRҭ) S5X1buhF` ds ΫT1/05}Pe4KIv~lD(]d ٤g>L_P] tf㐕GDJR+?tv1G oEf 3ar҂G:y T} ٟLݐW|S 0 U{M 7lL81'WfBO͋dCaej3Ľ/ae/'IŇa'c|M)&$Ÿ́MŎ;eά>>xO0+_/6}B1zZ?ȯؙ{ҳ25?V4)y<8F+!Ȫ(7ցn+%jo;DO#߿Gk0z_kCzgEJ#G9əso,1jHkFYxuWc_,"r.m#jF഑xuCI)T1!`Y\TLEB|Ryj߃ת0Wj:zX~>nOX':XLbbA?x5$CZ&ޙV(a7tNOd2Aʦk^&>]mz E!j[! dP$iLk2_ 62#׭5Fvzᅥ=MIUzn% 'dAYcKǷ5 -%,EސdŹ[ؗOTSv+I!JgCEψ!;7ޗiDM3ɆI`GMy41)eӷ_p$lkq*c-oYJ&!)" %I7/xaK{ EB+g` Pb P[}{,z7[iZ0I{ k0op.?q>@ІY\x=L8Ug37 7ᶁ- 8AWG\ 2|9#IDpyZi᪶ؽeR'_h{Ҁoh:y*QS1I }XL!>i:[|6J?rʦtF<. qJBFէ=@@b$rl:0D$Pԋ߬!<1/#UuѐE/@X ŪOՐOףÅv&ʾ'@Ռˮd\nVHFo3sgˈ:.BF;]x SEJso:iffٌН{k cNoFZ4e4K\h29͝ #qKX), KX8}al# ]vbgaF$̬` p+" fu<0V] 1q*k螞^=ywޖ8kY/K#OABn1 ~]梨G'e];Z_1 Fծ.PUf,Z~UmUdJjyuO |8 WtފyG<<\}DU?li4йR$u'GӇԜe^r{,.&OKv*tC89Znh?? 18/Yc~yԲTWhdT$bquVzGSn C[#?6Ew?&d}{/z1!Y>:-xĩ75bh\htm_8X:_ZV̒./&bk1Nk- %[0L\kbZ1𑇌RQkfv!a26ì Cٖ/Oj}/у-SMRUHT&NK(HtMF{Ƃ9Ncll /^1}c9 5{{2ʟ}m-  nHkSB"*}oIGg=C?'_> z,ym*7QǠ8~M&sK >}z^B_fb!nqs1B~C̲s)nCc@:`kwɮa#;+YmV$v|rVz*HhOwNT%muQ>19aH}胒E ݰ5PjG b`~h2@2U}cNnAѵ6H% ԬZ-mDʴZ=V1ScNoZ]ݟ,k'nLyk >Wa]Dr1dx,aXݑ0Sk_X#4nHqpjN-4sK8)k&+kǜxayZxiNkЇJ-p$= ƪ?h,u]w)N~H}}@&ZmWuD2.c/(RI]X6.:i+cEr "CLQn+D%ϺXZZ=9-|I:[7w0 KE+ \o- <bZ%VWbl{/|i~|m ~ln&>v䬤%}ʠ̭|*g&,Ӂ@T<_c4e0{ Uy@lۨ±䛺ptڐžbl%[TbX5tJ(mzLt؜PAaU?1R{6Y`Ofy~%J(_}3(,{?|Q= ;O޹'#te1~j⺤>twOUh~7@(S7x !T=X@yiȷֹm `. M |V.'y?q}*R}B+idiHH&@QϩQE_KԐ5{?Π٣:غ%?bkPa>ksl"w?wsPDx|2u3YY[4(u&,?% (d$a98 M4sZqtzͱ!mDDGJCD?QGh~|ɮb13{Q]=>c}\G;7w%u@J1 m0-ZpnWqSЇo*cd+ݻG;Gdc7LR2K Ps .'8Gъ0N^n[gr/} g`[J Ovx5pTf0B͵ 瘮9Y?|yIFj4ﰃoa@62.VDz۫1s*F+T(j+J} L6W,_ؘp(䌽 ĆAp k:Xs377 ~+8Qb\ÈY\4+DVKecb\8{lSIZrjz?"HDM${KmM(7e)OPČ 6'd$e;up4uɤu0 ;V'kwCE7@ȪW 1Њj piĖ޵g+?zWm m:vk8?gS8oR]x7jv;g!_SE+W-iQhװ>1 Sx4Ut1VgfV=)樍y&Aa If]AdE5y<:S+}?1m )R7м$e$O3EI|'(:.WzhϏ\ ^\wO q|՞/^⍐/_GMQUIrؓ=*$:S08UO7o:tݟt8(6NS8?mS'uΔ?['\ѽx(6%e"|߷+v|v==׉Q#X~@ݗ=Zw]z@ECg/pE C~F&? t {{ҲWL {RB#54O<x 0n+;!Dz%zZU:yHN8$aݘQE0x?[j]晫3sK ` *KI%'".qxMTS;ޥa N~9 ?ØR|u:ۖl̂&XaNAV5M8-MZ[ ,Q&,YKZ<3B'A(2;dL[8`{NV/)V$S׮q6eayT5HtNa?ɂ*>pGIzP"wOyĴ!K;.7>ʖYJƼJ~#HB̾1.y[%@gr0\A25zP†!\;a_DŽچgOzOS2']>R(_ :Oұ}>gux^*JqͳK|$0mYSüjlqUU]c쿏5w"W' YE"&) tP\r: O6?/IY^ E hK2ck=&$JEbAS/򛻩c`ǿx9BRb* `4 7>,X`ֺMokN֏>٠ wSw:LB[yVx64+$gI$DTh5M' -5CE{j׾#s yiex'=Q_\X};"E{0hqs뇧J6 4 q:R˛aă!m<,tpWw~ԯi(݁YTSIe3K6׌ U¼M k)ѹiS@vjq:l,T<@kze:j `N:(-j֤#VTL~#~4'򯆥 R"?Ȕ}(ឧ?.K-衎]C8)KF遟:vSDk[6.vRX-kx; 6D|y: ސkuzVH(2\f}m3BmB Ly+dV(c-D6Wv`S9.Q{/I6I~0?X&˔'6>xV=|ߧdR*K'GmpkP 2d@ Ǩ|."n8tvp4k!p6,ϐbiq w뮐ភ?-zB 7Txe%FkT@mk[eF ~3w !kR%u/R M=,+:<5{;B [ yg}UܝbZ# }[D궋HI@8-BBqyIYPЊuc)Y#Kؕ`}u} .SOc;h!SRBãOrdTOO,:43YFRj:&:COdAoh2G㖮cUC܅xS@ɮlwWfjX)\`#9RnKLG) lvnjxRIJ#g PA+FſB/idR v(@I\ό`G$-d\,P\?}-ybjoudOb)gNK:rtge%ǖř#4 ^Ù}t~IřR.qKh΢͵bn=<3%%M֊vS՟$4]Vgx׸Rq5k `vW2LXzdXb薧[7ij-N@n^*t}~Iw !X(<(1 ˽ڐF%2ɟW]2D;J]\M4ipW( c&+GIzI͝Fle ɲ-ZW5ʻq(!,sP t .m0 dՊlmYAYxy$e"a|,=-[cک(2G .b{K9%Ҝ;[,xQO2[2*]4{sXWcm}Tsd(Z,xf#}`p{!wDP4`:⾛ }6`|-EFG m?0(0 >URa]?hd0jEp/8jo(cGCBmBov:Lk L,eM.SQ{"1PQƀ|N^Q"<Ӟ_xL:03j[̶F&gwH17f&-2jHf6T3*"TH>\6GQ`4 j.:f_4=?k Jj7pA.%WgF@ JK=)b_79=\Qį'g .b e^wĠ UmBߛQJ O/H{b[ǯ?e0^Z5:0c>CbSѪ m2@nd؍ ɤmx UŎol,'lX !8u麮d.ՀQ[-WFI޻m6}-\s+\gǐMg J<̌w YD ~nl6l)o_ܯTKdp$MK 1jHA\Hr4ڤ~M4ЪdKM[jb +a;Y>^;moyZDmqOw=38 =W"ƲMLɺN?$iƨs )r\\x'&}\MQDw;B0ؽ?ݴizRX;6\6ҒE߈\ #SOD~I2s6ֲJ# '5M]+Dau/ilf~+pOg ê/nYB[ΨFl)rZÜt`OWQdHΩlHFku qӕʏcq}ffO<Sv&)O# Ŧ9BY;TWRwq"1CWTU"mh5V3(4Y>OKCӲ\t- R1 +euxwzQ as19#<Ф%vfHʧ4ޖzmGw>Q\TWbACqq,c/7M?28moSehu3_D#Lz 3GE՛Vz©Rwν.nO+ (et>J= YMU\aYaA},Go.]x<Ȩ7fEo.m?O㦬C ə4לk(f>kQ[wǵ'Scߺ$]=J@)X!n=8tgrW=M+d\oڅxjKgbкEӷq祷?i-/oo;d;2v0ץag% [y̶Utt3\vϬd{ sTpvn|E>diÔ$%*}-*So>*6W 5hd"2]xZ$̷e[}!xc$7} 1$ʧc6C=(mb%6yw( Aeyê[" C}ivr*k)>0F2Ec8AVC11[@LqDwzhFrݷy}. EaAgܧ4|O3CJo(ٛ^sDnOZ6X$+vGۊr!vGg&J'B-ь3~wV!}]$rg4w?cd7CmXF͆eL Jq~>jn7\^HB1\pKULJSbGiG oo{y us~ؒNGIn߸CfညpӼѺ6VvYx<5 ;6u+2Ț^ `\jWALH8vKP9{ (ɁwD)j߯n7G{-PdJӑy;9 h~TRb(t:KS%3@ b<ۘ7|Fd\^ņ]+yaqu-]n~zOV[8R0jKܥN5xb{Sh g[-nBlT^Ξ.5Hr,PTtf3Ti}˛o Pp!Ldd_EsϦ7+͡JQw\]#1n`9i✯,:@ⷯu&xtpEMʼn+5 7᣻n=X,(PWwVNA)g3STk'dMޅJR &YA,Nc"-Xo٘O۾ t`ڃWG2~^ xpO@>3(j^RmϹ:6)}k,&]qc5c6dzEJ pXw薌M@"Ar2ɀ 1GRl"Nc⭝E016e@EΚ2=4mϽŔU á@pvuE4pb^Qhu74;hbu(dr}OT$se 3i;3<"JH>Bke܆EF0jk31/p8z^=}yT^3h`ѣtLD4;cddp[F3Td .)Oq*;x>- 2tQdy_gzNDɲVuI(DFNiUVoM|B8ݡJ>р~ͶY֠|(09Zq04& t$oKlAbGy2R1PPvb5$;x ]۪.M+Eα2(yumCd]لrut/wԴ<7GyV*L#rv;$rxA7elH{̊:?mRhs*2=XH|  rRΓ|/P.h l[GRE e#tkk6 QJv!kn /\n<[XѬmQf'v%:pƊy'Bzy]Y%n>WP&HfA7h^ 6M t>!; nͬxOd#~07+A!6];8ct7sǮ#2zmq4tZfebXڠ'<-{诲;)saKSv>HF%:jѲW_ ;_v 1'X<#V= ͨ7"˽/PW-rVq 'NV'&Ogy-+XazV\ʻ?iY 8W"c]߇DaoʰĆp"NEe}pc{HVLoz{ºf]alA0m7e2-4)+ * ҍ.}eה-7tX$gqjL[UMW91 JNNtYD|y١.u'(< `I[/3TcޫK8! º j?Ǩs"t{$hDtD1U\V9%V "m)D(t!Wb:MaS-sgRV9TsWaKQS]"XWasbP)0rӘm$1g#6h}n|<<^ ѹ=pk1ORF>&Ct*śR8!oj_׿(nMN5}JR.)HA nÛGU5f4ͻF{Sb"AaNGYT~hJIPD sWM{9s&cW`ƫ$9O=Ȝ""XMoFOFɲ^l4Nb&,gJN"D ,VjQݖ1>סM 4AVF t` 5l0`G)d2/~ f]WR3.n\=i=~,Pm ;3:mk0kirM*˺n"4isIF\J0.?}OJ&@ܚ0}w`tJ1;dj 4%mzD֏{?J"V'$ʅ> Wҋ5UHUusLB|.f<yVBbQAG؅t^)e.ҳbP@Wdi'4Xc{iREJ^ʕ]gED'K>貫 cup\T'zfSr;.hcV<7q}(XrY-9e]oW?iRp| #xUW X葐,BJ5vk^ꒃh0KsIN!_m*Mc|(!i76E/ ioCO'ܠK5az1X~/G.pD7sS¤馒 h<2ݵ{,{A9+-m4jiLaʳCE5ʹSK~śE ?K0ӹ?]_Г佝Tg'0bAIC"yH,:%^;& 3J/m i#fDe_ѳ抜6=SIԺ]ͩ0Zq+ gmvgh"M9:4| ZFSbs]Q7e /F*ԯAo˯m^W[N(gR7([4#sݹ.o}L#,} $A{ |mQ#)iO9 HLQ';(bQ&w%bh3(}B$>IO&>N3!p:Sń爮uJ|;[B`H/?9zhZ4hŪӖ:E+.2. jNz@d\*ٽmH4 2^ݿl wٸ*W므 _Dgh N+}^>Y3P[soFEHQϽq[W_lvX&w2Jv Ti >4-Vշ܍3j7U8;qĆgGseߨ+1Kt}ָe5Fzʺ+Ҥt7Sk0y>Z#,%<5:;b}:8wl}Q) O#_Ui6yd1Ң)DTCkWoVC=- 6~T(6~%.yIdB B囁ݚ!0?N6r2(fF:eg}zY )ίzuT=RoS|1~T/uLozAͨZ;wOMR+KIɩEA`ɷةbz\O{ә9T2b?Y p:I:Te|-x}Ex{{;C$=@w*)Cq3v.EF8{)SXEn$Zű@rİf?:K:Cwu%ϭXMB\"O[GZU%gC)_L&fbIL>q>MsbE4┋^%s3h!TYEn_'W{M%&ckٸJueغH)ݏ$l=tQ+LRDg>[#i5o<+a#l1gřJ2I)sWdJp _ꇼ$Oc NMJ/ܶ˃LI]RiPVimC!M\a8޶61I컾9iټDjVƱ yM²u-\}]@dGAJ4w74l8fV:DAX6akz x2hA'dqcM+&gKjrNҝ/NOvkۍ<#Pd\cIn|ؐ ×mN5TeK}!n=w_g,'sYrdh`k*ZnC zhV}O..yv!u3ûJU\, Lmh3- EAƉLѹ R5ӜZ%OwG <]h},sb|P}Xˊ%vvg*]^i w܀lXeqAM{ *Yfi7j=mJߩ1{|N\I<9Xs>ձՃbԡ& (;Q)|Vm{gKg\%ti%&h„F>myVf}S+Rix1&(g?Z4\>X_" MR)|h}Uׇ_W$| V <H[;ShZ2 1TMtsQuc37P__]'L:EMjab*m'";RDcJ X#̓/J~[__cC.ΦnlP*? B̯Y>LSizTڌm}tpWnʠ4@!ш ID8'0ٍo7htgE5Ai;j쐷dIjޥ;,c}&.mvvjtxiUfTA;( 7UP YqKryi96qZ9F$om j*o:\G}MV;JN.gwFO|*H΢0l/תZ;+ S%G]_&1w+KsHo0'w^6^wO0*LlW)3yC$t?Վ"u4qTٸm*n ALJ(8/kuGBa8W)6 G6_6$R],֐vs^ M;BPVsVTjfO|EDoDle0%Ͷ4}Qln'jW8~K/_>=vb=Ãׄ 3p7 .0=3Ц67b 43~_w|2#rSU_<|pC+YbIjl)rb0Ӝ_6\oMʯ'En|oO,a:Dʭ(][ZfWNujBs2%\1w At4b`}Ҁߦlbn`@\V}ln%EԶ(i^$@~Zn<wazt+I"7,t*Qk+Jo6E.Hig{ם~uE yIdz~8}s>>Hl-Tʩ [81H7%tЕ0L/+RtPEl"K\LzӍcΔc}TI[h4+X˷u "j1H1L줼V4{f +΍>Y]\:-YR;5 x}nExX\Efv*C}3Ot7 9b`M>=6Rqʞ;NH/@uY0_O&( 4Q;`乀ҧIL0EeýZVg Ex~d]hLE OX<-zِ;Ud+|exh Ⱦ}CGXpm?~]Ҟ}vOEWa:b;=ru]u,_'1M{.+Yᙹ""]O$p1kE֤VM7_J"\hE#l(فѿ_Z'ݥ U[PI Яjyڰ4|]"嫥T4]?`}&f{+ܽZ_:X{K~]QZU_^Mqi&:RJ m`9E3OKoQ&:gճMdMl^;U:9߂x؟|ɇ{MS̻%of0, fb2kk)h)'X/͝T9:11/6Msw|YϕĂ|E訴 evy4[p#3W2!Je=r7uĂsosa!̇ׯ|RԊ h*z&DA=/xE s +y ȁ+/$%یo4)8l?kꍄ#Sr$p7sb֏Ԅ2ԾE,A5-mW<{8&WJT:'?)բafֆ#l26<^d 2ju|LݮHm(2x;ǶZQH xbY* Siq-! Sչwh!B!tY%$PUJ94y266䌆ͦxA5.$1i{'=.?s!mJ 6DǬԦ>|>cY#O8Ã𒠚Դ"NSDb>N? !:ƧN|DZ̸vw_oΘoijAXNVϱ w0Q ߍz==Rh .@L84י"*' 8/Ɯ~fBK SYjN%YZ\|KY=",Np_3:s&ܫ1.s$G%u`SpBsjyM[ۈnrM_f_QZ2b (xsGwqsz<꾎:/}cNܞ{T>#iV~g_YhL"2wR.YiO ч"io坰C/#8^W]=LD4 5.US.vŁVGN2_F<*jQ6:Ҥ!~$H)u&a09?IE \dY ! 95jIFx3MY.gbiXI]57,bV<+]}w^NpI'da0KN w[ͧ,j;{YAKE&;X:^سph^6ݽt뛭 v=/=yϤcR:ї@R;G*}^15U|ds+.iP/gB0ˁtzn*׫Gt )5ǏVL<P& Ξ-My͝U7B'n(Cj|TPѠov"5aS(I{̷At{=$6;|0+<{β#]L(oQ}*I.ZYi]c9M&Eԣu2ԆB2e!upLuxS32߁Y/2Ґ9 | Sp2"+9gݪlTv:3{N'TF/E{tw"Sww!&nZ{ U$ř< 1dU R1u˲քuOʮv#'ⲍ{ua(4KZXH|UE J{q|Xbex'W[Ї 6p~`9SSp 9y1C l !8֟;cg2A"@Je:sYazlpfk$y_^8}Ji|.& WArQI֖Sr6]Z?b[p%y{_᜕:x9鰧/u߲=zH"x`)qAUF;r>Kct.L.uLà6\~L%&3EKa^ƽ[Ih&R[&tJi~CP;U!lҴ8P1v'CjzNUK ȇS?w< ׷s- ז..ƔvNdHf'\ƶiɃ?$Bva _CiT! ['Hއ.>1OgV_P.Mܑ_KaH#`N*?GMx-r95I7lًR# JλAϳ* vM\3hF`>.FW{GӃ*&mwI&u-vEi+ܝ2ǥtmV]QU`xWΛ{TLka AuUitcՓ*@:^86c&Vy4[<6#`|jELˇKpij1?mS`vYkvE^ɵCfC-Wr [b&Q2oTQBѷnJXy]L`ZiG~=H뾮3Z/[^ G Ka߂QS7ğUߟjn3="` Fb͒zqShзW:q".=hE򹃤/x`VY}ktkg(䫽Q:&ojֺm^z.u~sPbx|<&~`XV VE,Ѿ#_+"F›ƛ'?<i /H|GRWǃq`De?J&۝-*=睻:#m^Jx$Љ<AY\k{ o:,ȾbȜzauLTQM3NuS_59yWs̬Ye>bZLdv +Jq. 1 G,im3Yv8h#J]lτG 1 ʼn!ш 1L\>_YHwL L042f$}zn+K%k} k̎)_e6;d!: P SOĪ|hWvmQOδtY~_4u=4tJSR=߮<0-]0ӻb WiJֲy!FKmwhm D)ox?U lޟdm$m5ol^3[u$$'AEmv;Vg:I6A2 !iꖒIatIЦw2uIzsڏN'-Dx#夷ABK~m'}J=r{<-Wj ?./]rЈY3Dc y"N$haYMIA9 jru2|zoeɕ kʥ't>Rɼ2 SI^zS;}`T7XE}p 8`q8kמp}#y4Szkܓn+WҞ 9,21u&HIc?pz߹51W|1O͒Y E&p9݅2'|Biw9LaY'nQN<%NL oI⣑]V/fQi@O7?!7c^x8d=9l 6X2c)/۸V*Y>I ceR# "QœCF} kF7J+9»l?kʝ,`p[dSE wE~זItXX7{zb`tC[ziVʩC~gGw .H>{iN ۡ^Pjtm÷ K'gKH9`kRK4/ x5&:d̮bA!m[C٦+:JΧyn^;5nVL=O{paۚ S'ihګJ]`XD1hɇܞ26 ?eTcC3[ȦiU{c ؘunDjL-=ե-up}vryʩN{6aT љ&bYh20;Bec2VE1ь.>*:!DCD/V_PY,f%x(oN|D=jNjjۏȤWx:r Sq v@*^&L/ PqKК:2-2JWj>v =:TQ7)ߊ0nx :9$얱 Hihim]F"W"t~aVERamzہh < xyH.0!閞Kt$Y!CX96-orzZ.bh(mwOu[:9 b/9C x]>VJ#)GVrL:}{]Z*qc/mFO`qrZtV?.}=Sͨt*u>Jaq9RG![ PK>]a"nGz.,6] {`YS]db9M^K71W loǙ?Katج8wƱX,ЪAw"n:ߪ-)1¥ӆdUk:*iGr!ɔa0F8xB=y7EŊĒS]gdkAY*°)kU'Nk}? irʹo4([-_Di dok?$f-p+o!+{Z:jdx[ :FL_&c8c qȬaJEnd/dž|6[`ԑ**)tK݌7of?Z> ڪ8Y-ԘfQ!L(˥` I-A0*}3s0:SW%P azi\4oQGM|R 㿼M(F.7*̬9yTjC^9]Q3[A'}TYϦ'+,3OEbq}iAQW*FIMyΌ],?R1ύK=cE n|9DV}>=7! o9XbLR$Z3wJ(5[e 66KX$ɂ]n%Ȁ{M屫SZ rhdgvMlͅʃZ|#r *@e/UrJe5~N20"#8F %*/:QZvщL4uO S6cПJ6@Vr`IP4*4:g)/h@6WnX Ҙ,+ះ]Je琢O0T<:-b>)x9/6ƈo A@&aOػ!5&6VqV F{:g#hڴ .f;UC_A; % ɰli_و>h㶒YB2#dPke6jRzӹm%|4 W2%&C4f]b$){?7fTi)Կ? G'q;+,n f6쀖5-tә2%!|cL?yKN C)i>>bģ,ٌWЦv rKV—TcQD8#_ߛT ~ooE, &dyZo.&) cc@mu ZH O{E[n/FKǐ Ȍ5@$VlMLјu#hy|7;kǎ!8 |/]%/# t6:7nbP/-VQ+GY\6ʸF{琫5ݩ4\`3"rܾ< #<{|8ށFީҸT)0!>[BBP(Fꗟ1O%]Ks)(&ek1Ӌ9Fh%b4T@tac5y_X,u Ef]ժM-B|d-jBن0ۤQ$V ۔ic)XH xۡj^]k-H60[ËK###axݐ4uLdN2$b􁤉qԳ~~ D;i]wb.,u׺z=4)]Uοg\<"v@% 4;S~*W+Ŏ* ✪Ĵ'e( Օtoygf3(*󥕂DdOfYMʵ%Ko;t`_>n|þd~X S8`o\15FˬͽwRL52sjhc}h PjEj]Lz~V?٩`G2Ӈ=f[9ʖQɁ=g祩p."7^?kӓmr\"WYH(JeqS|`؊[z&I7B\2E;Je3w#6/,AK+O|I%%ѝQ(k6*f}ҳN3r(Ӑ=4`Ɋh}vBV]-k1/bָeiw6 Eʛ< W[ RQO&Eyd3ۜo$ r;U9sbZ='4;EҕLjk#f1// J0>UFI&ǹ9M@OKhv/s{66ޫ^)=%_CYW<Y - Ґ_V_  ?uz㏞$`;dK_wrO7d+MpqqwN6eMK@ Pu;Gc'j8 4*d?#ORs{z+| nby.`*YA,R@_O?Vbt^}GP""UykcMҵv5gf(B};zxl:MȔ֜f@ɬYM\5lW/-I-CB#,g=XF2 #7R%cDC!&Y(eWS,A/PSH*'qVIsA -6ahϪL݀iUOFYT5=Ė77e;a~ 2ghN-ᴨ_Z@wՄc&=j6w,x#'KO׍f[r@@B8dC`Ȝў2JK1:KT uu/籽ǧ4쑹QlW( $^DtQg_Ed'u@1dIFY0<zEV>c@^;p?ɵBv\=xrTg/bQ/]'Vzj ޘGqX3f;)IlBNB=UdV`}W11LozvR6a/_,R2bB͑0;r`NP7{W?@1펱_plM}|$4z'1o/OȼfEbkfޟZnBz1hn> 1Tۆx-dP{? +m[K1-g rQo&_٦i0-rVۛ#;3 sZE(eXIdkJ~oҟ!Qו[}nMw"^pD 0N~nDxWU{Ki mHduPG7PHXF|;lqѬyE(_V(YOY6c+7BitcP|LvAN|X>gխJS7r_@݇2P:ݪrN5z E&ol>Bnf494Dɳu"37ȇ8ؼtCo%] oc7N[=>KB։@.#EM7PUI}CXD#@  osȝrFY#@3eJezN7ppZD9&c'EU5~9:k!7UE3ql֧t!T >,܀J3 Y XA¢FM0$KoN 36`NM̿za*|'Z<ǿ7 k"HQ+I 1xpjA_#W/+߸χVrTrr?b&u1}$5 "C<:ui$Lfx&AP9\Q$~W,nQ&TZ6FG2xBZ\,E v3i>+I&Xdf"r}fc^&rB&y"'m=1<B- yz U]oZa_Mٟf<1jKayhyn_/tl8qv ؍2hiٌHS͈Jw!:|7>F4@NU]\[⼸qvɲ #;\6ȝv déVbPS?|.Cs ^Mn(ξu܌4."6+%KzlT[ D˝E-`MHOfɩk[Q)y5c}Z=ś8RmXg̤&Z& 6pţCux"ݓz5&cqV>Ezwd "Z74o8L<^rHAPx̖H͜1uC#i7S|0 #3vRiÓ/?=ƴ'%<&'MvW,ߛ#{"NF(.OZ.֍;uK}(UEC?9&PN\QZ?^"C?fTN]RAj޽ 7<>"%Pj2 = (mdN6Hɔ鮯 $_E ېBHRAnY{NjD mX VR7Vmi-6"7nn3|koIOf75*(. !(L?k: 4"EΧVH#$ՙ^- S-Gy --&E^Myxb>^ϛ4_bdS,;;-b+=r::6UNG<#]Y {ٸ-p&ljL΃M +l&ӷ@'nSWʯùs*>x/G8;,~ yXcDono{U;XQ3 ѕI8UpC :zE?ˀy6ѣnՊ_n5I+rTh3*kh0]x{1Gwjw0|lҌ < ӳˋ[|>gU߾rjwa [ΥVUh6.,:nj)%*i__[b6[ħd2 A^tyDhD=5e]̆}(FdW᙭Ô﹯c(g#8kB~;h ;({4Xi׭?==/7{4v)SYMrYXmz'1`ya_ed1G݋!ц[-l5s5[KSab|=@lXZ,7[q 85}㎿v*Zή|_X5/Z5[Sfr!**(!꺜KUiVl\8o^s5=`j)DnOia58E2[61?G@vݙTuk6POj|{/q~&VF!bg>4*;.u?|J63^wtݑ[H4ߞʳ*n "\{Nᒔ!<%o`h=m/'))6+u6d`h1Ɵi?jB97鉛2dl֏m9#[ތhvXV4!#15Z/"EUOCwEMAd3\: خA9Lddl^QR /nԓO$y7?ߡ)GvHtM74;+c|T)W. f_}r<܌T+D;*5{kXrqТh >;e﷿ vF}w`;`NK荢ʦ[M^>^A|5Tb^s\xq?._qDjkYnm2YjN^\_iVE踱>$lt}?^d7Xom}:'bF`^ǤeaFnж[#OxyCYL$DF=]jyUvE |X_嘫&FN.C%rH^#-`dxDq^,@ZrvZ>ZEѼ`Yi/,̵!wb:ֈGb| E`Le 4]fyR^PI{HVDrLKڈ7X ? A]x#V+N|/Kt([Q)G/l}%wFՉ6V?O@8ʫ뼘UEl&Oi-/HOw[?.HgG@۵܊lkK07R"r XM6D睑Ľ>vJmgW*12X[Az<$(FjfpV `"h͏8<ɛHCOi9Eh^[w}~9\~bV\]K ocS?O}6GbY@98ͨ!L 6";Y}~gqn>ywBKG,˵,YŮɑ5Z`l1XiUNlVtH66Q"rCmG(mTjcOl۪&a_9 uອVhDm,bw `ǿؼv s)>lT4'q7g Jӌr@8gvzKV%"#U &=Euo+ 7x{/nHA?!]‰|/^5r1M(4A|^=vHj٨HT_l"ۅ>sD߂y)؈3lgLx1XZ8B]ByR,z!skUs'u'5P>k3[2ʆv֑!((wIey)p>g7o\sX-.ę/ԭ?: I6 <e>:4hҷesi!`MghddN蠔6#|:^Zz"abϧs> n PV\H "l}|t|@cBd+5:A~.6%[&+avgObʂ S{)yb_?rKg^ԊM*ˈ-]o24]p")/?˰$@g6}c^%:i.@07nyxDD fl̢P.`0, PUW!Ni#lW$~uB׸Jj< W&ѡ.͖hL^1_+{޼酩SEˑwϠ=IJN񧁊j؅$C2RL٘VHCCpn0XzQ)W eM$\bkg/Rx_.;Yfa&czM/vK0Axu;OWpnf㹕r!U/dK'q'F tӼ E~d{sЇפWE݉׷b'E ⍲t#!Ut k,o"oym׾fN*Dv6ؚg]Vtp$'t"`CWˎϵ D_{eHJ#u!=7@3M`ek`à*GYn)LG@uaIN$4K88 /}WG}-&&[r`ً~O,7k8k_-=3-&;W$IL<\e8}$~Imrg=no9}RRI-tu1~RM2w׈1ټ:Tٙ\ YM`zUԇf -8DueLʌui9à?ؙ'wjzE)o/ɪbMmU # D* e* HܹjcmNZz#T u=51J9YfՂ֠jVkşC`qYŰXw^rdAzSBu 8 W |ޗ&BAeʅg4Xd%QFF ?7ޛ g#z8yv;h봈P´d^BhWa25yCo̪zqPzT}(S )&;8g2R˚B "|-PC72 ;%UxRZsae]mRnư%,,ʋaf+/7>hWΩ?`PB6O[Kh|ՠsz&Rµ tO21o>=$7}2̥m6FR"L$eMWf;SfMilX @_C1 &q~T4r'#SzȲV[Ϫe3{ HwMzJԵQ`O>1': ګ \:q+OٺZ[3]jQEU$Ĺ[h.8oUu< bD& *{jV3Kry܅]ц]Y;$wMorOX? _>\{y?p 71؛8찐g,:}J-+ޓJ@}g8?^Ǯ_t9b:6DOݫnݐB yuυAFN_V:0ڒY iG >oc ~b7F!J!r9(C05 σܻ;`Sh~)iDrsz>KmzcVu_Sky ;W/DFj%~ >Ԉ+U/4_˾r&f4m~t"i{ĦjkODfs4L?PPM71oP_Z U1:q6%Mu |Rކw)ojznz1HZ!(,1 ڻ?bGOz&ЁǏ<vVֻ2z 2r|ko=ք !/;qsUf35Ե љcG='?Dd|ɨnҘ ڻ 覽e="qDح]~a8Y@u/ۓO[6\րTN9-b.|on]x[mӭYrDqSېVA@]{*KC.ޖ 숟UEE]QSԹk`ܾLJ,|lӖR? p1çHy% 7E#q~'\j~yyĵa%& n:2J 7g~7u%z\/%[INTr?>]D , .Ԩ lPy$C}Jux(O9lo(ZEwκ<23s EMT訛4TY!%,+(C;앇Z|i.1@MX͈6dP !q0OcqeZh+3o\Ekii<%%~YOL(Qrht1f\@eYej߂fTyOOa(^i{FTq#T*mU5'2jyհ6Z_Vی`OOw1Y1ߊ'Iʴ93JE̚eFQw+}+q[n wMCP1ىX^x o撖ysmUp0R2 <@ h@YF` Xtפ"8B޴ڄ |{MfbɈ*&$mlzx^SL{>K$m5EWES*o|}U3zW᫉K#jՄvsW#6iQqH;^S6#lh|h~g kOt(6c~"[3fo[m֊ZhĐr[chQ_ UQnu|߃{N/a>~Kjϋ<ɨRz2~K : }>ŧܔ?`+_zk()<*UhS>ؤV&3pJBZб~x2\Xns,,;FmsEV @EI#?[85Fw]7vA&>Kȁ!t1E)-B=:lh!8|߇2i  |#.V!FTl( uv++f1P@"qV_1I1MyɅ']1MCϐe Mn _3CЙAJ\^\RcD|%IyTkg`HHw1:wGZ&WU|=sU=Ke XCaި&1_ (dgØthnTKh.;i鱹?4żWe͞EJV}.zU[dZh҉/Ӛ?6A+CXM{]]ˆ>Hd'MGQ\P36Gz]@xH$}XV,莝E'}_iTb%[qu*b\s9?@v#D,J2|p ;7b2|V)*!/HDq8!O~!}QfOp5\Ae|mOJ1[4]<|zmN3c'멖`==z8!N߾5ktd<6U|d;S_-O9f Rܧ}Ga5TΛT!\pk]+;jhO28c"GZ\]"Ė֣ +>2Z-2GK_T{Rbz{HX~nD{2w[%ɽ df[ydZAgmMZQun+<˟DBoy,YZY8>Ä8}U4z8 {Cs|BͨlmųqK5ǝʻc8ĤLIܢ{;[#XByKjİK0DqQudR-Y 5(`Y?>UM}I9zeF@ZM:SdvwY벲kb: 1t > LmC}.PK0~ F2wDpG%RbQlh82oV󒌜!|U-׌uG( GWG?/ ɥX4znWhVI`65}S虀zMyȯ (J| k-\;Dkt54#e+>߅iZ{Չ~ <'WO x!BT<?ssmS(nnŰt+6%4ג.|S(i:|- )gbpy7DʻT&nfm_*E MTB&5EzK? /v@_z^Gn AaPEN  mJGBa"I1lWXUۢ|t8~FzkUckWU7 :WyHa_:$"2͵*"g obNR\o0yzL,$5oSuxx@Y _;<Ж=H@L{uTr*j8Co!HC~„^~T`s@K3:|u3gѳ7|A'B eVʳ4:xኔ ǤW= _l9ܙ1u*rsҖ”bU>J̹#>Kzc2B^tfyg#9sJ׍Zˉ??Jp>@eQȲ+2RVyr{pKƁ Σ.ij)BA>bsZ=A\k/+߈ 9T5ijg]8{κ4$ty=9E1}JZ;ku:iqUd8@(岑M .A3g^k5!7X:huT"lZҘ-llz)n}]HueYTT䕼pܛ/%K6dxHfm۲!yS ׉t%X3m%NimDJݥ2Z7vKk^G0.+;ive<ܪcYiy2Ug-!qǠ&=7WA[*y1{&-DƟB"0g֛*9[F3mkܝ]kRnJ}W ]F`tEIcq1' bc:OTgfzZk*]W(Ols?wLGswqWB-uU`(שkn4Ĝ*H`%nοݪgja/?=8!&g%Oa%f_\YCR]TeFAŁ$ b\9k GVK(stCؾ}79GFm@/W5걗 DN Z[u 'Li=V1ڇ9U 7Pd4ӂ`sA~nyQCq5OA|!:鼬-1$Frc2[omI?$4?a ܥnlvQo]k0bXrJQ)Ҝ9$s9ls>osh\z\y=u'ʨrE:'+]glʄ{m:dhMxb d1 ),[@Ps!#SmCMGy%d ypM?=xş$Ȳ^Z,9AenVAnQ&tԪĬ^4k 3 ,EnuhATZ)4FV\Ivuv K~unXv-mbhGƜixa+àLx)_W1? I *Լ6FNۯ\: mP k5Vݽme֛fޙP" J5G PS&{wZ m"z'֖$J&[ץ\T%-ҲCП)r0l" &Soy y)EHӴ1k:͘EƮ|-:J:)N{9^jG~ެwvF"#qvW'$a4%+amwTp->t>U9~?kvp̵Ғӓa{?~%O߰O߆=:p yI'x|%LGww<~:нX00-eNڂڦH _F:ErK[)p//H?h SޘsRFy?Y!SiiZ"Z""xӪ5W;nk}+ 0ث=Q#UVսdv;diG;Xdqh#T8}p?9\j4΂nczx2a"89ѧ?K7|*pa* h$^͈0\+9'bZ@ga%tS{Y{Ka$Y5\lP{sIYX.Y)B&'hy} c۩qȮzÝeG2vI3خw]CN{:43YZ9rxߓ'hמI~1R[#[OzU&r n }*=d g <:>qaK LYok@o_^9 i84Bl~8`D{f c=[}B lWUn2 2t|k.nq%g'64[1ՉHzrSdQ8}h#q7]{Q19B{v_y46ĪBgkf3#VqjuzN&9Ǫ1̝)J}z{ׯdL>*}}#>%6:URm xT*jsݑ9LlZb4h+`k]'Z=p/k6G vmH4Iy#U1s>8 =ӆGUDEWS;d%0qN,<12[z~^#/~˷&]ZuݱI8m}Et*A3r ;Ghqh ڢ&MքL \Uq@Env$,4k 6\V3̿HIz([5gqv9plJiK)S(%+m֋''6&mp 6{cAO/E<'"6BOF=;@#S^d-uڬ r,~Y!M-U;SQݓ|*L#M>I]e۶t @זf@bz$eD:isFw:UnW dz$HX7af`iJ[o4QdZyT77|Wl* U^|kKnn(xQIoƂ [)BbphmC￈d*^C'Z틒:'i82}S V)z(nBb?ؘ[Ɲ{*i066(.{\/nϭxpV?K=jKYj{b/V߽7SIVasJDNQݥ̕Ѡ9,:yU,ehM6$I# >Xߺ6|9>X+Ӓ>﬜(iƭcvPK#9aݭ4daJFugOv{6fJjw,) TM P*AV~粔ue[[;r>I`z;u ׄdMDdLY$aÈ* Ű6a2+1?ѷԦσEd=TL2xXq[N\Mx0԰ZI!72&~hPEm{?ݚW߰K1̌tl:prz□݇9+ݡ֋,w+"rGob)t!i—6(xW2Rܨ[̊ G2@x?CUEJjh̠g M[jp#؆7U}M%R;S{,1 7FEV??H.Vp%Ŵ{xjܗ@GTKǽ|Yk :gJޗE[A(H#4;!xG+Gv =M+#es,؉^D~ ^UMgϻ.kkOu͜I;9] sty34rB4{A_,r@:Ip ? m=_]ĸr9pgGWx|luN>mfU(@OЗG؞=B)eGȮ=; ^*a>T;V8^CDs>vQk|W3p6Y_!P rg⥓uQEG2wg8P)?pw[Qq%vYc.9I.3WA§D5MI~=W(G`??q Η1ڼA vWP <.&áIoF_emeӖOjMBfXnxBB,MgEʐ#kKY yV[ 'Zx9O謓(vKAi0LE쐖8WlhG rq82X\[}dPqNW|_ˣ92;,;127_NJ_c`?Xl\.wZQ%G)G,Z}]BU^yڜ页ASYT_`z~&6"+z%0vgh?OM gH7.?z"=P$XLwq5WD%!C_19zCyfW=z\:b:]΁gh!PI/@|~#G˚s "Gs5OfaPJW tͲryL%ET1h" " ֔祎b_K&Wӝ ]ӝMׇ ? _!CTO^SVp׺BK/3Byq5s'tM|J>P!Vs']0p.zB[bo*ՙV]Un-|^N@KJO*t$2vcŪ0qdvrCGUWXLǥ7NךC._Ϝb^ci\R[n0Mą;Kt.%b+l&unj-}IDuJ8R^dE]ܢpDÐy\YandKB)҅{J$?Q8+zp]#,?WADEkE/d;HV93-ۨDuےVuZKNsІ]61'#݄;r Sณ|bgu1RNrDDճ'$h/BkR$W~;w>6B U76PV\ՍwE LyۗH fIω0[}߳_tZס D`#|P5;}R Y Q[gln 6Oaw-G_ ܆*N;-jXh ʩOrfy7OğvcfB}:pgV:tvJBhFVo1}~'mr,Iف(yW$4zEI2!Lܛ3x2ErpT)!Í~\]Y:JQeݢ[g-cPVqo e*ə~QyDnM<(u A׎uO)_JŒW22nK groZJ"B_,r[o锜{Ϭ.^_-SxeG=:*pI[3.5NyE`(z'>$Ps(3rJy>'D :bBL5w藼 BMږɁB^7_A^@ǁbO ,J#(ɒ{D4V ̝^ŇBoFF %yU/kd3Fu8I27hTG]BrF=)$m}!s c|OǁuZxHg2zJ)5> !)gfLrb#s dXhlE4/o]DDūnΉ _Txu@N×α`Q9zbF h!R/3P>@g2,Nrʩjܱ*)Tmryނ{tQׅfvyb*C'<8Q| 4[;Xsacn q1 SEM{~cE[1([m VϸOܑ.p-@xYSZ)#nKgcĂWiGq墍aUe7bf9ib*E1ҋś ع)&y@4 ukfِ*gֺWOFB.9jByoirPeb r",#BoOM`F~ U1vٞ|#-?j|O&|ȸA$u9Lz2gzZ󲮁rtcTy_Y>6=Vnl5i (Iyړ٘=(9n—$-A#"Y@-f)id]&Kv4$5!Fdu2&xv`$-x%G\d4& V75BK1GU'!2/BUqD 'Iճt <;LyNIjfiMbW;9cZEi3Ea93G2GXXbL9Q>s'ο'eqn]<:{E/C췣M c9xDhԈlY7Dls]3sb}qGi V)cʀe7V/YK5L2p0_Q<* KD_L6|]s BDoQ.a+j xF? ʔKM ߽҉ȹo=.Ȯ?oI&ZۻCk#A@d%hliAhg)`܄%\u Ma ǽ`2ZFQrW(P_Tnhfx?E[jj{wonAxӎ02uMh<4ws)~77)*Eɓ*7dF#Tt;yD׾HuY#?*Xk&in[*l 2t pF`K~G$T6$~tZae"/%Yۓҽ2})uc(&w$4 DMwoTrIc Vݻ/$`OugB/vC=kWAeLVlZd TD}7L8ꌥ$i=s:ߗp仉h- KHh~"x0J-2_ _R&\W|։{<}W w% o)h(UNY=5lG=;@|.\\q7<>BX?(;r%ݜ`r.$zuwXLr:S>TZ ,JnmY6 hF`١; nEMuTx7?7QY&F+|4 p>Zg({_[|Ӆm 1O [Y]a"}Ӄ[btI. fNm'}x\ M^3p$Z 2$fK S"}fC FR]ϽPbO=G3_^6L$%:=_(-Ε'TBrC"Wn=o,#zVfx~~ťH P{ 1g}&]fpp5ee7=8Ov@MǛrۙ 'A9Mtꅘlgc^z/=b{0sZsM߉̣Gi})v#* 7Bv{$kOڮ𲴩+HPeg΃L͚@֐g dc L7[L{?[ k3e6c 0MIC(ӯsD=A`;A9 ڗ4]P d[C^ يc;I}W$c<;I t/wLsکHC?[ܥ~eڂVf*)aͪh;+`XTy׊4RTuy3Hm!{o7Acv|ւcuWeelMӄE %k='XRbNn r4ZguⳒ$^[9_E3&/?ZΩ2xIwyzt)fH}?I/T^Consh(t*(vY}bc5 5"`НFtvM(tk5G Y9+6ͷDf>0 C}{6mu1QV] aA;R’/tGyQN콛߁%mGƗПzSqCޥ ǔ[/+QMR6tAM|AL_}Vu~ Ke)ȟ9swAE<2yJ@3p#yy9#N6n2 ]hʉKfcmȗ*XpfϊX'(Os ,b!V1ǀp鄗YLhoD͋MC.k*ji]ET[7sA2k9^6`W2o6-Ψ e8g0z[jr[߿b@4԰FzJƑnoC_H*?Y'wF;SKwhw$s]Y@iX..~ta|DpuM!Y԰/# $18e%kh|7j`LYYl9"j4q/bᴲN.ǫ㹧Ēx6(1fp_Ba&,R\ŋ#֭蓯cJ9 {&VzR,PԘyTE}O_Эꄋiۏ;M`idoj6+ǧwƦ}SJ |] ~dsnP{WEY 4N5yM ͧ[+ĕ )#j,Ej:4~b"'[IWr d pbl7MOU([9ӍǎJ8Ż{OܸGKԵ]$EGʹ}kRn{ɇ)_㩞^"Tגk%3ΩzT%N"|н4{bUfk[ݔڿxw$EÐЖV|<xD==t`b* O>q+K3y2]9}2zw x3 y>*2)3NW5B_W,ԑGd@)l/9de:O9ْ*4Xe݁2٣ҠZn _ bi 7{Wv /b@z4ɡ=.YuAh_m qXhh^i @pgT6:Z;xx{w:.OG||_vlBTz8Z0.2v6Hhx82HG({t:Mpf?4nHoJGz*57VQ87<3\I!\+{sbW82eO鸗*MTh@'|-I_C<7vudeFVa6;amWHʑe'@.soKp030a.=c~;ω䥓HuV86@/Ԁ99G"K- mmXe}ƶgͧL0S Vg(C7c<ɺL9û/r:㼳ϟjA6].xe]4Җ?R0`{a럖$wh0(BI̅wO1z <CGALSwi/]`kZWb#xF\b¢<5AՌ+iksUCyu]cE q.l#&%!P/QuuIFt0^#Q 3c>z5yk1F*)bb5o/]uܻ ܺerTog$,1@IWi"u9Z0mUF"DE0OxHigDRzhU꾺P 'eMil@IY' O1js ^Cnϊ~U6= ~dC+j`bq #4HjN*CrpDQߩMYK9MK F0|]6 v+G!GJdBLp8V@bTz#nA,f`F ›w-i"D fۆ=lKGi;Tۋt&L2(0 zE'  1â58sn{-qܷO+xTG Lin{`dVRj$ErnrЊ }m0Ĭ}]|jGEbI; A{!#0mq5ϠA1zl=*J/Eۊ˱Kݖ6 @t4@DNGݸzPq}]:k0iDisjB^G?"w 1ƧN{Sm6I^%Ba''n'[.zc9hR 9_iN2c@'f&hD,:^ktyK31; >uJ) ͸ƘVRk\! ޔosu@,3QgeF<[VZMz3[sC&wZKãI<3=g8˰FYQ@VOb bo)@{@Jn6Wg]y:E)%HF ~~BBZtRa9 ɑ?@dN'6|Rw|<6qv];#'ND =3(j*AA 3. XJt9scM)L*j3?zu:YK_]U*UT*3mFb13Qb'Ypl 2z&4d8r3!@-ffxݓ  N˙CfΪko$ŐˏlşejLvM{i"0a;{$0VpT~-hʁ ꊩVeyT8pSp.MN (Ɇz 0GwE g4F8v BP"]eC`_ƨ.Jx8u~Rt "mP} S[Ƞgecgo/Btb΢ MozN=$Ѵ%h% 1=V@n /4ݩZ_%N96a&8Uih{RՎՠǕoR^$qmo7ԃU8ƿ5bN*B<(j+b[Jfi$qYcT );\a'~yCY^!=Z+M;/| 99p&>U^2JtZԟ1,pcz}. B!ǨpIpB> 97SgZklP5&!FzDŽ77|u^j~,P"\ꈓcUĩ˘+䗇nzG.r\)ב⺒N5)1祢*r$AQyX} S`ƭ5E:fT4R5Az%o؉26͢CÁ5*m7&@7cIA 8ocG Sy$JŠaI2ZŽ']6zf-r%vHɲ#LJ@"},2IcKyHq".,ul>9}Qh2t!zFʪ-~J~Eyf_[LWd"9cE9j` XMĽ'%*꓁ґWwPks&W $mЫ'Nѐe;#C5a𥩅`yje)(b}iD:K_f)&xSҙ FrF\ l*HۀPE~bF6ߥe]o()ax'͓mK> Wހ%mR}_&-y,~QV*+ڒjhp_q2\h7p{_]X՛EG׮E[xhӴK꒣@NYqDX]BKwW-L]F~z>,l4l=HWT Z#} m|)ՐF޵rm@dpuRx|gjqTWa^o%>}tb۶S6%sh#DUk{kq^C$_UeK|Tz?.٤Ms6}YctH &7YZ*mv?\ Κ ~2j{{<כV%F4LS Uo)>HZ"ai+}ȐL4v=M!nl-7cŬYHY//K&u73BEdkzJqcOG;oe>K ,?9jݓ4q555;nԩCO[wȚ^9|K#*SO붟V]8v"oEgl KBQ ջ:.q+&ƞ237ejV|kXC2!qKoӎ5U<"7El%& g=5O\O6+e#>'o H9~ƪ}b=u`ݡER4b:8@:*=.?a ;,]6x(s2Hm$mNR,HڠH ukOvgVA"N$_wS 6ܰQ(C\TU1 oY1oEa92[vb.UoysMyŽ`jN,r@bfU7Nz1qw|?P>>Xؒ\ɝ/Ku3#rKF8}i %xͺ#"|jQ(fN<"M~;ےNJ%su,nwL[R~[7Dm$kݏ$V_z\jJ쳎f5̳E\[ē4җO]߲Hcn5m)~n8sJ%%1U\(;P98^4w~४%8 W ̴̚WU ƻo6 ݹO~11 4Pqkt*~F̪hu-DB*tHV}\Dg/zO4ƕȚGu87vu۝9l#ܔs>?mLEUnଊ#o%]0 ]\/%lLӛs8c8fySpInPyuԽOD\ Cż.')AU7/s}u2e#o+E+Kgʸ*<3c hh$ d[GǷsHL`<).!߁6ƌ1kclء#o)3-ߕrDأx+j_` ɂ_ŊxPTKJ loQ mj_J3T րF.i9$fY\n$?<:rگrEoȡ`<+d]?~8tb#k`3/X}]d`h_;S=Tv>AQ`if&jߨlWXNG,he?KaٙlƒTeizGS: C>B￿n ̳R(\'Vf6q$}?~O_Sʱj!7˿ v-eS7ҝ ?Q@l(4`uLrt>{M~| ][ȏi"SRzt9$޷Q Œo>'62P&촼RvGneB-U{Q8ɾ2YD KLpzw P첵_@d$Fe5Og{1!^-hBͽ m=Ik5l._Q%s?s ؉(V1ھb5ûI[-O?%`!nz9?T̔,87Q{?u\̩zc"(<Żr2տm/8rzx9_^~s.?Y9wdAWl$EEd)0*Zx/6,jS66UU:H5r-Tf4~6<''D7xq*j(Ĭ_w*d,l][jkd &ܹRIŖa?#!ȟA%X5&玏s[< 1ntrx㏎xoX}k]gBz`f)N{&3!̆5]|!ݱ4!cbl[h Vʫ&\,S2 DgC(: 9\] XkѲ3(Ga֑<)ƭ5^vb>%'V۞6c^W,RWLW>sKk+87$iHFM g0k:Y9x`d aɹ Gl#};{>a^ Ymgh?hx|] ~ wo!ʉ&jZ&Ёg.sGmb)6SFM>bv=>B^Š TE1`Y0:JWB|-$:.e]w l !n~Rf8szUCBj+k]Vk:GI3%b.4)^}Lx"t}b1Sq "X84'&pV$EUsN pE ~/<ͨxOJfW.A'3 YbRCު\*&xA Е8C)6}%-qJ*Uog6Q}21oya jBK#`tt#)N>vW~!e<8=v,4o$|5I9јZ`IrrsR{\:43fϹX  ;sN$Itw懴 +iln2Sf/c&n# B}W@uJt-mHfw9<{TV[ʍ]ټ]Bq%5ǟ<o5)K=yV ́ 36Bv'm?9{'v,œV0 (Nu*j*MP6ʣ^f|ʌCӚ对qrw l<f]ftҗ]O "r➫tƴY޶[i>`woIb8.ifPNâ\iM=bԲnMп>ꩃO~Œ0(b! FZN5Lt9?G",akK`U.WP-ܵ:Mϵ00$-bPŕvC W#JD&#ݡɘΏl0r Wr ИUD&_G,=zďxNS>zfu8(0H/ ߝC+ ?45e9uJ@;n )`6R6Ci-VoMw92"NMtEb+X2_UKAޙ~*2?ES?<Qy9eN<6~-!^hcDvwc$ΗVSOU\w~BTopuy\3n1o7wkA@cI/K&2h`UB[o&so"}g'#+q=ƸBh|b?ksKo4Qpo-xBJm>xx\:8D j#hڣub6ʨ'4Wk;$P&ҍ4$(CO53fPEǗC.]356htbfevV2*` +[Oy37c6ۨpF, ûi[t ^!n['eP1-xJq-uNkܣ?)6 f[ZێnqHo5uV1Gb<kv'ɷb[>XkS~"-s./[gk7 /ەPi:}zdӖI A#MYe'ܗF[ZT\?0cV~Yz5j &`ҝSj|bwMc2X_Bp(qn꺪%1yuN]B3ͺQ+ 7f=_*o:r>hpP.i9.c_=:A=20?[ğaU//?9sV%`9=st' px ,4Ltb?BHH:`Okؾ^]US؎<xց~"/Р e,smeX\|3ltNtc RǹpR#:Dݐ(Ad$<s+MR.@M`f w qv]w \C8~ DPL}O"],l!B/?9xLߣJn:~8y-ƙ#sZbrJ~XQ!mI}F-Ӳ".W_9ul(ؤkyB r'%1zcN E9,!R%7k lyIToщ~CT)tBb+-kxo¥09^]'b%aĸzPcG޳FL Iܑp {  ӁdwRw}"![k"=Gz{Hy.VZ6̥,V],[ߐu&Typ;7iw F]_d5+fH),^EԙcIOf9OMz+t92Q?O}|[лer>@4)>zmGE!J, ~Wo @|\څ> %5s{&o>*Ӥ#m~}_W&+VM=LJ]/ Ge'>r:KU׊k@0b}^9}KG?ut%>wDK7l稴#X@/(NdM c'-q]($Uu@ C~ƥ3`=<@f!ZYQHx5t7 90B%Lzd?7ZCXS g X`$EPґvAr+e"oʌ/t$Gs8i͢GQ[mL3 &ƙL3oN3p3kKWHy՞$0;s;|Tآ2#9jҰx  !:-cAwR EXSeb .8&ft]&K|0[ƞ{Ÿ/gEV!=-ep͝S 2n i.@KGUz_HF}-kF D0U'I ]OIEϺtMWEZ0gT͎dZ= "&VwlyYN;+~T' PjB|ێT(Aҝ|fC]xD #wS?Amhڈ6M{Ë0(>^ޅ[4ߗwBHQ{V*}n++::!m[W+iyyc0Ò hɏ$*-} }q@(w (o9#H9y셣X'raoc:dML}ԋ GK4U|.^Itiy4KUKE@w]6V^Ǫ2yt~1ly<L"B*0[}0KJ( N61『eE5WIjr"B ^kg/s* V;wy ~qˣ?#Ϝ6v^ɷe&*9qiphTǺji[<ںoQخLi(| /Uil=-ACg!F, >Imtۮ> UzƬDK̦g-Z뜸2n#BxVV2/F7mX2Q4oDxVv1RC ;%Yٺ|מ  ໝ Cg@Y^͉ڏ ʂfV&xW~Y˜,+c B95eeYI&!\[ _>{Z/ޔ.k-@T#o<4w1q_PXQӋɹg~K"py }7&mZH+aqgeİTL-?_eA;QCꌾOr+uQ#̮;fda!=l!i eVzLlgڣp{* Y1K|0?֒_ w[5T+y9=jی" ,`YyY0+ͦguZ'9 $dE&S2uܹ1Wy,mI~!c(Y4js0)Xus3y%:Lhqj\Iac<ȳӜ >_^^,pm"_?̕wԻ5' s'!̱~{7{-}IG5ӭFe7D\ߛ 'Lݶ:J@Pc ʅvQeKnj x ۣXӨ;_Jhl}e1}Hj x ^R?iݵz32+zvPp"ߗ{ 'ڱ{ҶiX c Ѭm?8n=G)4tt6~~刉T WNslcq)3E+?VKw"uh$,BF0a 79+!q% (G,Y6icܘV, sF{C.2FKp)`OH^',f5ZXn:|o0WIK7 <a?!w&/FtAS&!?*dϕ\jjSD"ĠB|! "y'bE׿1NH9y^_zͰ ^46h̹}tuu3hL$ JH#K |{9!ӓ>- ̽/=G &xRG6YT e<?u=$[cMUy_7<&x} ՐKHME`x=i9z ,T֨oS]OzwV=ѺiXʍmNQ4[e'J'Cji`J!F/I 7 G},b1o}]{[8!\)3 RmS?Z5J[L:04m5saF#.jr"nGzVNkBhKg? -Ξ\EM*gN˩}&KE7_׊ݻ㊉ 3ǯy1nqRKNgEޚf8bl?^AAk\7m],7K1jFcU36paآY 2IC N(Amt[D2{|k=bϺݾCZV$ImO7ԟ *`XMDp R^" >D{Pt01A1YQ竸0P ^Us2 NQIB*0H&Tj~  :痖|<+9Ge rY-< P X.Rɓۄ&*PmaIrl[xs$T jʱ%cf{6L'Sa vٳްj_{S(me!T}؛i;CtoR &'SeL#Li/K[봍SDa^6Y +ՃApWClHքg ZqJ[ZC8,];vv{[hF/_+|گr- ',#(VQx Vvk@ԗDN cЁ~;)^*Rnuq$dXUqx>,v/kh+ՄFv8m#8 *i}R(>I6soSOM2?ɩk>/s^n0)h-Z#j(wA%_VFy dKErC ӄROxq?.=RJ ͥ]Sʡɫ,mf60 H^Rӻ3m%Nې~gXB!&UCv @ȶڼM;-75n&)['kTJ)"KM7$JH^EtIC$U=@4 K%U G~89Q­tC"Bo$'OA"WMŷfVYMI@>LQsJFLy?51 qa]U+i8E05־OC&VV25/UL@&dbx8Jj0\$K*V;7XcolT7pIOn_śvvG3ӭR*M.v>XQ-5RW~u'Q*}rh-";}0YnVN:'5'C 6,Vm㰴2e'<#3,R벨 {~%`Z(J4jUfkؔe"| ETΦ GVXW=޴;8(\wa ,s|BwNTZPo! 5f--Ykm/D^tuF{mks4tlE,QRʏ@Jã)7*^de?5lֶx/t$b j @. {`C nvˮQ%e݆ήMnWg Yo2Z%㬄o]?q踝i35ԶwgX,#ܛk2tksg( [*6X$L}RvOP RNŀ9Y8Zxդ0bKc؉#ROPLYLT~kE|y.f݂UuX `R0i2Oc@'z}2`jf"n2qF![ڨLbƮQҧlVI,E I"L𜖍]6CW(Yz8vy;g=$h nz8꘿пLZC5sPaQ&ubNL*,$?[2u:bLjBDGaT8QF"<9C2jwa skcxywVȅ;X+<#\5,-->1x6_V5pnKX^>n=2ћjFg}rWԸ `'+d<JW70z{ \N==wZK@oʪfG(n̲ԮyB MV ;+iz&3ʂ, ..o', $4og7Q=47ξsjDV.b \6ix\&r|MF׻Q\^YXn9iܰ ]BAӇ <4& *ԣzRI7™/ -!@CHaT+&oKj2$/wr*)݌ fm9HfpM HꅬOSTce_\"I%;ؼ$b+jD8\ga}wFLI6P:T hFTe^[:B".8ɀTLWkVA }7>Zbn1*}`#67+m5UrZ -|Hy^ޅ`wEBy$QYPbV _t!l/o_lsK'Lz["QpDo.Jٕ q ]om%ڜ ,&rTmڅD{i&#Xv5kl2HއK"__@ E%.tlU~봎ɴgO%lפ`lL<lȉqpI*tcj/Hmy7',lD{XF$W([A3YtYQܢpH4}}"U(+Fݣnr"43%t% А}FC{;%|z91f| 7T&}.*f\MTQ1n\(2AHЂn"}]Ip9FC~i@7'%boiIC*FTWW,@ bS<.K%\(D}hh$bKtb'B+%5 % 6wtj{~fyv#syjY`ªx Vv1ɁFn ,DuHmm𲱦SI[T:֥*?)զデJ&dA:R@֐D$Qo_@ e=w(Mf`'&0v+d%Z.Z-̵xaGK)YT35/;>T7:LYԈ[A%*cQds%ҘU_3i{ w0pkqbv\><2*HG Xg4Ep.|b~h:5_9HO6XsޫiXJZmRՁIzS?s:Th l 9љRlլ!ߍ|.tR#<#(.<(Aj@YV.XSv3vVTr]V [žj:]gܗΘٶyjom3M9ۧD3VdI帣VK۠6UN+U*e;pk$kmZ϶+{졾⪐G͒hb)ykSv0cnd^Y5:y 419D Ph3G*-Q&2#}/ڼFu(NAec\H"V[-Ət3?SZIůhk؆,+ {1*KZ(Ai!-zHnz)JSH":|5mXL\ Lzw``ȁ`b~[ǭʨ S-TqNw6S#!4vCO-ZW}G=NZÆDlKiZo.1"J2oPukk$<]{_^3o: EzbQ׽M'&' 3 C:_rbְk.S1 im;|<ޝ %81[t'jFz׏_q_)ouCbJ6uJ_߿|RCzETdfSrj=!+ aˁN闑@uR@]5Y5/AŒc"g~p".aPǀG/ ,*,e[ۻȕ&D H6LSL0<~\'un9 繨QBTfVhۄApfWbþo|ͦe7mw%+ܼMϪjg/h:~6H|a>4Km Y,@MH*ܲ˾v7F) 0C;6R<^oVYY V[߷G'a@i`9`q\ YnPU(ڰڹ{Z-cSE? .bQCT355 ˾ D mgtw{bos?PG'ORIS:I>}Q.'}qhgFN1byt&gT=|mXtL~\V# 793iՉql@! j\~w,^%ŻoP?Z#4-!]_g8 +%l<].4g/H!76cؐf&=kJ/hŅ>1uL x $hPv/0 Ų)3 {CNi&PBL5y+~-cje/Jndd`)ܰޛ7(RCg~ ~}[$7/Jz pB),tɍnzqH`/]}BrXQh:P)/`2 أۏCaI6Ra ,EwBE  R8=B(ߑj+cJ]T r;z~QGBU&q휒ݕrmm/-ߪ*>ɝcV._O,JKi5n2yg.t>ݒK !S)-ضqYçgA\/)z.%O8N|H$##m0JyejE]0S|ggF##\J3~QjCMJ?Ӭ ܂;ğ/05_Xxe -ͯ W&؂~Ur86#RCB듴|ށ\@ُ cVD',&n~ !VlxeݤSN>`W fQ9R-)ETSJ2+zgc߰t= Մj١3Z;ڥ_``GgtQ[ܑB听3ַO4E}k+2 Z.zwHvKQ:Ԋ$D$ɨD(~L)`*ܺ|a{ɳmvtߨ΢8J}$ث$ebLFkn w8-Th8;Ӑ7<`n}yT2RcmQYB ˡ=UԡSP"ZkķLs{56ϟ5KmKv9/Mc9(xhY$4 *Ek&L:^kzl[ds9\84RmwD!=3gu7םRݭaQUd_>^6;qck/~KTO)n)T E ϷeE;i tLn7ԜБU@jD!*լk'ztt aF|]@`OnKN!) -a<-!|װaB[$B`2}Y 4+eMOU ,R+BUQgvWׄcBUf}o}޷hIBgBW{F3.qFEgK[e i:obIT;REqНsU31)M2y 1-Wa׍87/\<i#wʨ[9s@{nR̫YdnCoDz\G?-[amH&5)4PF.ΏkQf/YnNf-~=~9nW&A;~٨v;Ds$c^߬h̳!|'O8ӧՕtWũ/?8eeXd )oP,Vb:RyףxHQx5Ku*R B*Zc]^%e ;2NQ7-,b]c^{H7?n%SeLomW騶Yg$ ?CVV Bӷa;8ޗ4X`1Y {rq[澓%gs>Ⱥݼ6!uT2q9mw<9 ԫWme[u ޜZ/kh&Y+A? ܗmrkz5Ū?9Hy@:18,YPqJ qDmN6}7Au${YfUO9[H(cמK3q#7Q@?`dv ZQ` `5)O䡙۹py L3p#6e`<.I9g.#*$CȧgB5YeL(knIHst]بZ6LvML<84X҄TۙNjo^$-U4[!ָӺ2`"%OGKF`kzpI8*ڠxV'TpX1sHCCj1@\C\p颌nh_6U9TWP_N)KfcfyuM }I_}g} jFff3 ^:QPNYWF\SZ%acS~9Ϗ/3[qX<!|n;3_Y_)?cqؖ-KXNvtNF!3 5IRwu 1l\藬΁#(}+fI[=*JMz v&[LvayUaol #pz{Y%OoiW,19hAKwYMYȜUG..(6BL:c*Z)P'8:yIezk\xɹoLj^= %8:QҚ^e.b(Ob&EϷ@%M@pZf"%`{lf=үr&)+ .ZCR- _iel<-F!] UU^V2BND~{ԡ`Yp)Y֌:K'fI%-IQ9tcvj /ZTG &Q ^!{r$p#_Z7n _ &xf42irchɩڒLR] G`۩E{JDqAF~INNc6+2OڱOI2V ZM+põ4".2:P%Y X>V^9p e'h!a'#]\O9Sd{^r  2 h]nY<-Ȕ|_:1:\.rrRQq5ɯj+qÁ7}?fRs[{L|G;"%|Zd[G>Xu-|!j`g\>I+ȱR͎T $lzv~Z;[rAִ6ѳܝ2Jel]aDD&Mde6 ^eM>BT̜~|i-g3N|;|պ=3i?JD$sX TUq%3oMa}9ɸ7zO`RV`9Bce&\ʡ_'ɥ/͟„ ^ūNr[_*#VʳX?\ċwA[eFf1)#R,.9AU%e޻E$EyS +NLmdJrG24oՕVyDP:S2::_uO(R.m Y-o.x@tW <{*n䌧gzK4RE .gO]BP`"MTxe-~YiR:)Pÿ1тKLeJN?lv谢^}CKA%V&+anV;}/2a*GoEC[LyW+# PYN0Sb|̳͐$I_97=yb_s996Gc&UrZQ2_p`ĔQ\Ya1SMGŸ;7-MHBɡ^_ nv7,bu;T.1,{a~:xSV@m=sX(bo0U:AGT `˸͂rS8Y"ȅIB`湖CЋ(*1k5g/MWCW\iiwr⼒,Sj=RY;&MgD)'yYu͏C*]x3!['ՄY{Z$Mjl[ ㍒&|/PkA)KwqLXs_!xiIsr.;mkAOAb.1ID׷{e%~S2 { NCEHpJooύg^m%c6#Ɲķ'6>-ҌnbJΑb<{#]z ͟Y(EF?-zٛ3`4_[EDgdܿN-fE[OeᑻhFkXϯY.u2[ж|o)*p5wJ6TExq'z~c]VKgS+%&@=Rxj<\?Y!Z}x~kT^A Q#g(bUj IUԻhZ O B(~W@eHeh<&bh/}8ώl/~`;vyB.!ku; hH;ji l?~7$'F(y>XСH*VQr"oԩbC O+/¶9A%RO 9UBNc 8^b:+žib =NM%CTd0(Ԕ.o?2}uuCu~Ϛkϩ>/X7o?UͤP£K9ǝ?V4wcvQ'K:Wmkv^loJ;m8R=)$ 磘m&SᰱC {>(EݶQevڄC(qܧy ,8BD,9 9ޖ`GloxZlc" (MBzpp [',{$CE~TOiXDX &]iɹ43ou2,8bҙ.YĂNF'@FhX*>Oh" IKNmɃBr9) mpn8>6NX#`{~ %^Ɠ `783w"igL}•72/!~nu8kBk,c3PN<ʔ39hoߨ|Y(z 1x[r7!;U{ *j_z8[#3rtx ߣL*v#< ,zKTD9"Fw#swytQm aYOSGaJ05{Sޤ,$Ҫ'7|y4fVu!8:Z]{jJgeaf lFJJ< তe$iXaaV#:H6VC8dTd/uQ 7I15h|]:,k4*6mx͇8O¿aPit`e)b{s;i]x1,TUVٯ#۹)26w?u[g9xWbtq׮:H 5Ql]sK{-A' LR;k(5ǼVFM}%#O<ˁ1xhE2z\pEJ YFmwYsqv I-SSlƄ,%d<ҙs;;ƊK nTGVudX1Lrlu ?TOճA@ x*Av@}}6/)ϴ-T vB{(& On{k齟;ϳrri"[(֒ZKI^7" tm 9: 3k~H4.Pz?,2IܢOKm$,SԛbUܫ杁c)r^Β<60QлN|Vݘ-1eFqI?:1[ 懿Hgڂw>x%>ѯ.Yuq9VqSs^i ۫k[IKi: 'fShߗ:i:rFD4pHB nBFNQ\&CEVu5iŽY3>QltYBdxTJ4p=b-w([s{S|wk#isx ""UvaMTN]2c>Kals<*NY|,lo28`,lm\71 ŴO݀W^qFKm- GeG 3+G\xRoq_끖3ڎ*^3gwѾwPkJOHl*fqV/vظD2ÕvԔ rs/N&^V8@/FX!?Wڿ iՈ*ѻ#RZJ\°|k3msYXhq=VY5WM2'a6)26CyE ^|G }boSHV~bعFXt.*Xp\#;k[y}qvм ' )E!Wfč&:'B/.G)K,25kk9 0p_r"ޔtg*}eXki?*-dcW8Ҳg'>Tymy~V#Nה{OPJq?ckf&J87OPV:gLxѸ'$WgY_>9bw#h,E o%Ge#vץW8t1,4bGK&I?5wȟrL {97xjj$e$V/6ØBzrQyb ,fNװ|;:ׄT59T-ii{(D#SE8Gj +WC84 Hx7QzTN-27];=3IZ}TnG "Ds$?U<NJ: /f!J4W ^QEc9k-YeܖE<λER &*33!0~Uʄ5W+:Ւ^ʻB p9TC4rC"ʅ't}-MHɍ_9=V,L_a^? r~s1LoV*(`Tt; Ml$!.]}$iMJdXo p25u ܌^҉k}] E3TS}s ՚hL36Ł2xꐺg#眭1ѧ~e`uo1Qj]ya::rMW3C:s\6ʍtB ݐ=F`GV^޹on1r`u9B5j`}>#*O,ha #@n:l5塹ӋG{SH'p'E½xQǷ__v?]lnm86JY, #e"wDϭS", BX~;霚[uqnVͦ J׌_4oKa'⍈qvRJ?zR@RS.kt36ձ4 _ٴ͸{]sL"{`|D<ײYce:P;BVw2=uXXx?%ZL=2ϔښt΋E&maYDWX4qnA~Ҋm9O8?h^:y5-?&> ܰA%ݠS]d~Gx}^T9qh>amn=:'3zLq Dž#ObK7M\U fmc SzHYb] .3}c+ՋpՊ!=Ps$#tSS\S&]q) U'*TY:I$)H@?g0bqpl|d-8}]`Ԯ"e0\\J7o=T-o67<:L7)\XbdZ g_i뉜ﴱ#"'ߘƈMp,bK f^QdȦ%\FUg{7 CWQv" J /Qw|vP6w={ծGn!SZ)Us"|}W ЉEuyZiDK4g0/;U{^Kub*;GEy`(&B߼n6=/|L &:4ax]J4ρ"%]gDž8Zdt%ukȾ* zhFx=1Q#~{f'a(2~Hd^#Ũa_ 63g3Lynԧm{|q1hb W1hkt"rrա4fJ|76,AЇw/;=E<+Wb!]W>tm./$Uk|^յ0,a@~:&[ժ6nꉜ(8 552YKVw$j[7 f4W YY10Z")R` 66 ?R# _5D) {יZſ܊cu Ey$Sa, /*(we4 =jtgD^ks6)쭭@N2&|5aVM.ԝ5xPD^ 6z"͚xV! 76N,5F%EJD4+%sDegVR͵" ߖ5E@]bha¢:Ey1 7j馺_UDty+;:NyadTo1b+ig&#,iQ6f<@WA ҅#}-۩. 06jsQU9۷epJKNޙ3Q s-IAg3ƛ>"O}VϲEm󌁢[CqQ) &r0;B` lLCq5Jk)Լvg&((/|`=pIY2&~rdmX~.*m{3E:ޮe:9Bj#L cI##5!^j 60L'E^||HqnvTsm0'"auTIn_ wt~cݠwеס[f 9An.{Pq)O[O%J;\6?uIl:wMU{ iP Y]xb8#ä>QˏSL Y/6rq\6#p NSYﳛ"bS:ྑP8*'c3! 8lT$c%L,$*k I9gSdst#:Ir32G Y4{\!4Pԝ sw *׫6/X2N>P\,hh}yB]xJZ!},E*Tz1Y@+eNfyd]x3bh/+eL64׷s l ){mXqo[8蚖JȭXs6f3##Pa_K:m"_L/Y_6h8 04*qp4Swb95q衘_=!7;cӱOBm}A'/tIaP9p˸P/o[$`ZNctj _,@R@ OW÷d2g:ikȅZ ~/DwPm@ypW e& ܾ ?.OŃ"Ѵ"8;T,T/kp`+۩qVÍRT|ӷSg_o:#\1ī<-6W}L"逤I+~~I#6M|_Xo k;!(żsw:x0NPiZF ϸwh}1Cx ʚB>ީXz70{!4nQE)֊nfy mYXaR5Yp>%wΆ^H]FuK5? %谄3|SqÇ(QrYw33ڡ_[t9ϖ' NR[x'D$o=VjIn 88׫ЙV!\a D{H#d#@G4㍈.S5f߂3r!בHB> 9&K|=fO!ItV gz)jWTQsX:%36#;ۨ{JBY[fϪFy70 sw&M{pj!e/HlND樉EOh.]VᠹTpOLu{LGۧS?zQ9~:e JOn֋%|QԼ&P%L0|󷇲o*B8+.:uK7~w j}ߨj~:7GIeK*nLmOP t˘׹,-J&qFfA$I2xl/ewY q/5,W rOe5YyNkkѸ?l'qs՟g]opI !k~MwM XKlVEtvrY 4_cVEue5}"$ )g|VP޼Jhh#=+hkя~]׉ 'ƋS T=y{+#fm|űgK}:ێDQbt9$[},2Eo'wS/5CnVE볙)yFng/P~$6˫#%E |`~g",.pO~U QbH_ -9Lz]iLn] ^3~()WR/lQQc}g#Q^7yA7M /EiCCu-%)ow|>t\qq.l s ¸2_J$ZJ7Gwݮ?(&uK;ԣx>`[V֨D7UQ9 o늁k!hZzT^ϻAjGW7iO +nHt7N=K'o`l!_:}$R;[|^%*h1*=4MWhu_%TR6|9w }pZ]q̸= U>iz;^$22JTꐬ>榥IZӥ͆\eQS5Lo[tC_yqE]Q@W# += Є/L)#Vp:w$vmѹ EH|Uz*\B3jɓ,x1׌D.%d#؍P1Ǫja s!ּe9ccA>u" tWNeۧ ufߙKFKXї\&=ߗI•H83.J+4d֩m]UqR'~uGv N>vcU>EՐ9Np&&~n+6_^ Qxߠ]zH1boȼY,w1P1SQ`+9pe; iMiHt ~Ϻ LjY:D{7JM 8o Op'6bfjn]a<5tTq:7܇tA.sni:CqV@qusltCgzqkiIBԈ'3_VD]#f)%_3vzFߩ>mm Q܊ߓ|Qό4"H @ْܖl `˘ @nTP*ih 3d 5)O-C ]$[rb]L^|er"xs[{ &|M%dMI42[9 CUv{o8Ŏ־Y%vߡC1 1 =l *aVHV jæWv-62:h=i˥)K/fj?fϰc,0p I\ODl)Ҁf﷉H,A˦~î0zbiHLNeݖU~]I(%:]`nYZNy.Ee5u=ߏY^Oet|~}q[E?aCeNH=yj%/-nſ!U#_hMyii?\F( r8f_N&h;@ݽTv b e:  #;cq]wobyh䘹Я3X{:.17Xdp&mH^۫P )I7iĥw͹1ҩ(hOPmE# ic*4uY?@',8C~wLC ]YKWZpsR7W֯wbn+/:)s'0ܩ{Qnk٢ʔiL9fӻغ wyimQbJ1g29mc2Z}k5J.<Ͷu+ hcqF2\i=z7ch Y;BWJG\>`_#S.[h35_\zsm} #c91/Co/Ό46ޫeT==YB^ޣ;L~?bZT? 2gč'iG=(cdPZ탃 UBe9{wicj9'<5?< Q5c୏qdhbj4{Z$AAtL lARj$>+7G 'O40< _(/43.ANWrs")_vا\nf AL3X{VM#7FG5Qrf.>|z [=#gp# ̸wQ ?_fU׌AnP VWCui|փ NH LSeteCA.q& OQPVeLې]5SLV^B 1*0qmަ-9K}Ԗ$3.fy]ĺ^9rq{ƃkk5um=4Ph+ᯍ20l2=mߵ\XA=ZR%!QrcfLYϛGԭgd 0*":V#V DbG/PkC2+ҵ<:7>nP_O.uu7xIJ132]ç(G (tr\͸o"!R$P$UBI3EUZV^jf)*2r {Lg5" iyX[Rrïq"U.^Uֆ!#s $`䓞87h ![|,RܝY7˵ crlSptu{+˖ ]E-a_A/dѰ9ҩLp.ݱ麥;->BAyMd#Iy%t"'NMas(Ql۽TW@90Nw퍂maq Uq¿&κFd+f]jԺAW jVn.<9T "2׏9*K^,xaxӺvR6AR ߤZـtbo7 6u냴N´qNUWH jNr-32dR&~qds2IX OBfT˼ MmFYWvhnC+_>wfq/e̳QҞ FQ$U]o V'YH5ȴj%}Qȡ+=xhe QSܕ4檡 9A8PDI|5D} $=b6ʞ4 ۺKM Kⷝ#<_o+,fld͖ (dãje[s3K& iV *dĩneM͠ڧªA=)$]^W^6B,'r-Rdz9|#iBJsۨt9V.`3%QPU/՚H`G7 Nɲh~:yqSYF,?(_ UNXP/G=w7,c$\޸)]?S nB cU]=F@pa6>dӒBQ.iVW,JՅ7[(bHn)G\Qno/Һ<0l9Ws)Oio"F9J5rV!DʎNnHHߝ֗/ɲ-yk紀UO5֖_VRQ#USc#dgQS@٧n91Co{cJj0YK˽ˣ2cH\aA{nZy3$[zoD?d VskĬga`Թu3Ÿnl_0\^M?JӕbQ+*1G ‘*5Q>NJvp!ۥ=XM?!E$eC2<_~KxH}NT;Y5:{F-X_}L1HN Lh9Q[ fBH0I=ndd|譃!Jן5Lі ۫/;mTI)(xղ2svP封yc X~Uǫ<<>@ꢂ%}?J9sDN?z%l <t̜ӮUCWgNFE*m&fy eVCO߹%_3fH@"oAӝ $0ʻ{SF t2NLQ /¢j/8CVL%H]2)bJL#oxIuHJN92=Fě+dˆp 3X׭Yo%@@lxASl<9eٺэ?8$͐ e |M#b{;Y0a{wxgl{%[=Dx6>7MyE+,U4oVd"fr|aݞZ0$'eW~'^ "ڱ(&+)tEww̧Zn  Hx&RVPyڭEuDQҚKHD3`8<7㹾%lJA4^L;؊btG2%eJF"k3P$oQA )-3Ns,胵yR@@=q~5k/&?MkL:5Xг`S韀\ŢѨ"cJPW3t*CN+Bh;4Ўs,T<ʯ'iF~q;0._H95*XWox+#J9"6M͑WFB^JԚ^·3'tӾjvzb5Ol>,Y94_klQ\f^r;~}3a]kAё*T_LH#Ez~^Ak鼲yʂMS xYRTL3lX 2-qd~ٙk~{K;l7rOci3b.ISd,ȭz8;ɰ<]&<{l ުK-̄ʒ(ҿmQp4I/NJCh]vK?2%[M^ 3tqL~n*tj,x̣~?Rm'BX\&L4K ; VRgNQ;?:)ۡjξ*u7WY8hŃF /ȀfzkH}}lhȧuVGj+x^t߱¤xuTQ9PK Y3<SJAq,g,rzp2԰čTy8dSrr¾OjwsIz5_tZ@,J`F˓i}/çw'rOޏ{!U5yI[|әto^m}WǗxs?Dȋd!Y5VZYGԌCΐ]n"re H,T`Kit5i5J@bsnRqUn }~ 1ןa~X=jm3>ܗE{MZPVN#K RrA졾܅h<G -MjJ{cyк8[Y,SIՒ;QYA \.1*͛)8 oϩj['D+7kЎc2KҞ9ecdmeS^˷1}"GsXU]Hr4voQb5cKokxm{L'GT$u,{A2 KLHki!zr-cE4,2ioɽv<5H ًU4I.! dTCsz=Qew _Ljߘ]a-`scll逰GY23?~@WnTzW*q`wi9.P`H7= ,LHT^#ma%T{wyLPhƁ6tR` |ym̈́k7&3&_Lxeds 2!O5J}FΝ*R)ϟb-#VxBwc2UjũvNK;!h'_6AP4rbx:dG*j]ec>#7*?*MJ^t;vaQtbƌ2 mghosXVpB򖎶OI[(l{NDYw?d]^EnyƣܸREX*Z%;3,^5wFB-pF6Vu.]QwT23rkP#o ,M2? C96?gd?Sd-8 }-dM1EU4!G-Hewz=M߽u^aƈ)H ͝aBHBl#[-h0r6O)][ZE2* y;6.rc &m߼|"ꃣgD1@!S jvw inН dL:V2˙&:a( ):?+Ǩ$#Fp02C^&0+4eJ^'IVAb7E!?)0!AchYo9 77amo,&N -p]fz'غv@.7r G,f8f#C6~y%h٥wp<̉]T7nN7"4|,1 y_Ƕ_i q`]/ējCXGgЛἁ"?Vz #%08h`:*$kGҾVV㵑.ęn>onarB0k=bwʇ},4q.e~p9r!O쟎\'kIѮe2 J12 "[CPbZ mA,V^ٱ~⪭UȻ.׻aP5HVR N^ 4h"\LLn16K2.["6'Z#Esat'Ս#m"tGaqɼ HSZsE>n.l]oCkN*#a\977* Y y; iVDO bXAcGI@؄;ASAtՅQs=/kS:SXzesc润w4| s+:'86MJ W-jU'-_P̽9ָ ] 0 i&;×F7Rop'[}a i9h#E%|^T8=$ 4e e!K'Diu5Eۓ9";Ehq6LF7lF[.w ߒ T3X+Ţo-bT`cʇh*["W:E?:DG޽RX3;_aB'2-UI78FYr;/÷S{[pq]̎au[d`D(2/YM(<{baTn cpZM˚L |E7EG`/bpGǧvŜ#W۾s{]LK"i`gwQf:!r\٘&SdȔ`=g ƬV v̠rORn5۞*5?#i2TC pQ|OOV#B#%n=JI~mu5=nn1 eyYuKK%ﻣTf v컱d~n=HET kѵn ~hYpq\8ܓ;S=[m%8ftIRN1vb}DcyzR#!<-}e[y3L#[a)2.ϑr ;{NhMTtpuhod:;-C-ٲ DԊ9лArX{'MYO>ŜLǀv|Q2V"dNWSe<@|Bj;K$E4z{wݷNyG.zF6wznZa11ݛg¶GߥI*ޖ+ ,%~SX9O_=%JKw91>L&,.>> lN[Ğ_vMљm@,[EuRڄkєȨ-?RnHgİ=*.d!LCL:oP {]Dy>qh-oh ]kC*ɫoYUI=M@A8A9ъ1VS!Z~W*ėժ~=L$ }c"=~vjLD L@$Ojrl4~n8])Axc+{ӷnk `\e}.B'kTK#D757nIl_!0ɄZf:)VlSexm`3\F.{rʲ] BƨV`(6-*,6lF7S#7 L.UgRNi8xS]ɑ́a/S~Vp$5IQ%]I3%TUԛ[Ȃl)؅D.&2T[n=]I0XF*6tTA }qj3i}҅%qjI2nH8>KrͻY4Tǖ.t%6;lFc A 7t[#MEY.:iȒW?1 &[ǞulƞLi,KYu%$vH&tMX5=ޞ3bX~eR]~ްC&pkr2  ?Wg3{dXպQww i`o4q(}9 84U ss0DHftνxwKA8^56NlzTBD/Cxj66QP8 D kW3 k~t[̼ؔow Oc}[)K[۷m"fS2yrc-w%Q*PGMO}sS{թt1!ca}@rjok~ԅy}a:[O3"M@c.FS#Hd|k͆],b.f[X5\L;le'i+Q֫K G@h [úϏldŃt*1',Hl =yx(Ï4OqO<lPM EH^ ȀB_@o_F !9z=5~pJ\>$[qV9c Nu<8 ?hq׊ +uf>BEO &GvvAYw=Tٰs%s a1jhYj=KЕioaZcNTa[U^WWQ[\r]7|k <!iOmyf=9GjdB#) \h-|^܊b+T%ug>y&+(h燉@0J Rs E r!SLηeMcA.Pgk@FeW:*eX{Wey]mg+sLoI/1ANLyZd*}CA^m 5|LE;dP۝;!CؐZqz=)?FJמi9jPz6%q.9xFGX2{/5 KzSh6ALU M֩'w+Oj'x;sA2G-@B5iA9j9Q .b|X]Wmq>0 y~hnS$V F̲Oh5^e5P;rsH;s3(4#gdDIcjC>"=2g/՞9*z;HN%[>fРNM%p]eEbuS Ĥz4u:H5:>FHsPYׇ9XjL~&!AԺTފ/xBWpk@e 0}R18>IV[0ک[jwF7m9Ih ba52lQj~nPʗ>pUAkergck?4=rv]Ы36%|*Bbsn&6j%+zEMEc-H$рrSZZ~ uT3讂8֣~Vn{}~F;Qz,<{%6^ޱl7"M޻(U 44(C`_Om&4^z"\2TᖶJl@8B4mFƌkZQ3)o㏛)9I,$RR0'cx[Lxq q FFT'ʷ!JIWZw{GU%!ufCu@OE a&Qb+Tm%,>p;ptt$$~A/W% 8Jl~$$|[k1I7K:y< Ql wv3;vSB_?9xS~pCO𪧯|oms`[xFANG$¡Quqa8KzQfSNYa>)&e#؆?3U9y,-k%UeL}KE2Sc ۅT_- <)Wn&l90Z|XWdc&iK(*PA 7hpMG3l.2Xޛ΍XU;]6+q0~* fMcD;jϒxҌjduj QYe^U5u8K3mo> /H—"So9}ĴWgYgFhje7~,0nzzq܀7[Σ%C)LT\=XKW0 VhՑ+|a0)ZHnTF%}8-VVћŴV9ҠOn_4zCc@OS4>LmCI$/[^$E_ %QEJ o몞AԐg#LKp~"x-ЎdVqexjNiA~׍ x_͎LH FdR=/I|=>/5 YxI @?$[%|Dx'J+TQgՕ<g(򞢂h#S0A%CBP%:i+CvD6 w={T.,hդY؝_7pvwUOojo)bo~Ɏة*4q! =R_Ć$Zr@j ?/#V.g zd>5`-{3־zyO1mcB3$lJt*}ŕ~ǯZ IO89g塓xH 25:y&ym݅D^DnWd1z]a]]bHPF? YH!2nl6v i@iK 3'PǏB's>>ݼ|UpS`Y靽hOO[~4X+xMTt0?@x} 9Yy٘lt%UZtc|ްj@Ϸ@,[4Wr7JFt Kf&NJ8ZF``֝+sƓNq {~_dTF~ u6En=~Z[A壗nrj&xm5%H8E3*Wt#kgd܉cEdEڪOW98tMk\M"~Ss ąt[媢)~ӈ b\X}x;Vf|r˖8OB4Fϻ)JY^-q-R7[>•˂G&`?UAiы(5|9\V>^^두^Z)~vQ4iߺB\{V6E@ \?~!#ĦYE4g6Ar\2BgJva?nB靖~䏹li;9LwDef-t6;B ֮ DxN|Z,N[iT[/> 6k)H_Cl91zs %m_$#ݳ[paR IWɏ1)1#%P7񳭻Mܸ 7"NAJlᇟ[`1*sr>r95HvՀ^`\Mo)CdzT֢bmz(3j%ܡ7%.N6YZ_O.VXiFe67鯞"/Osq/>zBǀ&yEj<6EV*2 )=?z9GoNɉe@y{Z@Bύ ұCx^c>D=-N2KܬNgŭ@G%*ɘ~~C4m--WU؟hϑR»BD¥o׳(j>Lm-B|uƆL3W^ 0̜;Ble.l \TB 9]ScbGr!I-&Xm02} ?:n/`gr*@IWȟ 9M~2e{6u`L3"/٨[IQҏk%`31 XNN{KDRthYEٓKLBD jN VR| F_Y*D[M(ϔ!ӱ'8 bVIX\['yv nSRU wmާ,<>7fCd/ǐj.fi1DAuuB{tNU:Q87=WВK|5 s'3陶Ⱥ\M'/!T20|L-6{TW񕐮p χ&(IUFQFe;Ӵ5B9>\|aRe7BC܁t *K+I+c:*_aC.p7,,Zqvea$y`jɈ?_X'[CwMbN=Zy##,Q}xxU[3oglO\*_|%R-86Y0(¶*jxHW|^rCx'QY:1 "}zU j0o1Ub8o)JkX-o|׳Sc(2Moj%4B=aI>c6ӱbq0ሉ4.KZc?!Մ@(FN,<(H҉j NhˇUZ DJIM :Y)m¶RrЗ1LU1eWrg7ib^:~Q@TMb8;Lu45޷BA׎*H\I>u)G#2A5 uz35:E=rOt!dO4e-4|7dTp}f,r*S*(^i Q+nI(π0i>0C`LĹu$nd)#> B_IZXC<&׾V߂I,Cdrl|ܤ[L82#hϿݐ%#%0ȴG_m晔;Fi6k]%d|/>oXŇVcka+vUnP>]s׃,zD@fHJ)0~k3sg,Jc*b8EjƲ̌Cp7UD, D{5f}YojW^>L>ɑWg=TtIbΞx}o$Kz}`Γ{\sF|q:v#x(%F,Urw;$Z~k~iǀXvdEkfFVMR8B k_Qbdl Z8#YQV]NԲ9{o[ђ +_Je'c~ۆQ3RK;2++λC'xX.zX q=&ǜ%i]I#,*[Rn=q" Z*?eqUch \aC)/VZI짔,a'N7 2cw2?-x^2KI8[m.>$zHm?=!wGe/m{<>r Wrcl#-A=myr;e -@b ,odeC[ p(i{Z77-|nȍfe5Ln 4bX)q&dMVeHA1m ]:wRb1*4˰UȷDxԫP(`fFAǿU4X4WTM"aYApx_OȗUUkâ곟@omT$ʓPkp9ί>%w ns}=PRɳecQ* 7Aq3gyY&"7BCՊon[,I)-Pݾ fxsY^XwDDxԉvߕMxn:gvx\Kύ|!\g;o2m9ac*ZvMȔ>Yq2Z];)cn{ފcI 덙SqxVzZ MSpsqnTSs^(Ɉ\&#D~ HzߓtW:fwŏ{Ůb%=v3&;'<1t/֊ϕ+Ԙ1t}` k<ִ.IjaMQ߮E(R37ʜ$S^J~4|tӞQ!/l}O"SX3dˋgZGP!TΡW\ߦk<8,9T9gCLfs =W)f]<5FZ1sBKNs恐9Hm(t lVSy&1"oXP={Uϭ†3s- *zR!M-/0|+3g[~(-Y*0|7m%I+X|lfO[{9~~Zi9dXS?{Og+餽Y e75Qi9Rno݊匃T=QxiNPٔ5e, xZR)+HzrI%=ꈂJ=Y|i=/{I$|I5><"ttcEEV}P\,%ޮ :U\SD*JZnd%?<^/vI"hUjX@!k%L0>8ƨ 8/̲{nM5Pµ]5"IZj?&7I: ͬokFsnhA `+--V6ϖ-̶-*jJo2wВ"%;-߳5aRf^=Ej2fѪSEsI%s&v(8M2c.usG3p3F80ބ&ෂ56nNOS';>f5]WՠMR,"0?s^:::@ħM pfT20 :* M "G%&>ީ=ҭ5Ƈ|!0 #D,ga{3 3}bL_Jf;*`"Qx2 /7gbehlRՐk+ܕPM$|eƀ |N$lfbTlHԣ_Է+ g^"~tk6[֨\dH΅N\|mstf?GJIu]4aFUSr!4Z`R 1O;Ƴ EѹCgW1K޺"!hMQ|4X1EU'%db1nK=4RRŀ/?f$.B|IH;B'k'_83i#ra{uk[tG)C7X_^ךE|lfY.$ZZdi^o|=@NSǀ|EYwMO屨sRVw.^1hLj(eA`Q 9?̼sOa:|;@[MFk [3)$9R0.,}\` 0 ]r~#M>D6X62\ 33AѿK3?=pRO 7 G7VJe 1MȻW[ɧ$Q[# ^9YSѕ~ I4}zjka{ZG}Jae f?hqqZ&fS>ݗ O]W@RUwWvimhE KD[ʩĐwU!::hzEkNuK|u׃ sW&wp* Vt҅IDq# ᕞ_g[%p_:bwR7I*)ӳ]Ryjqxl_}!&{_:% BJ& D:!t߀uQƩXԤp"rlr.@;XM/ Nط}SDrLjBv%,C~RFbl BQ/G":L7Ϭ~\E⣑އWg!H+⽛Ğx@ksPz/8'ݰ1`fHC7΂ռZ Q,yrP_R@oB6FEeQ/Apo 5+n+@r"ix@႙+6"g #|jx2V6#oz,\!aG7]4R8[&]@Ǿ4kFWb5P^[ zk,"9H~<If!_ʓYVca2<9p;UO &66n3n ٙVѾ)es|KTz';v?X՘SX[F&5׃JOA_6HB;zw|aKS#vSU n 'E> 4ZJSjzqQw%ѳX+T8F ZA$E+џXB#g0*pZ5)B =ovrq$QqtcrSН'ȐU`(w%đ 禖 w%f7 ҶH)^W ,/{zg/pG_IǶXP`\Z&)R2b=u>sxR=r oJ'Y'}Qh~Ges) ȶd`G:8$ ^,j88K`ݵ}5S,4L'$mb5L*<SW!x*>RֶX,*Kߔ7͢h/aJx$UNcMhO+,!u%434_}mbī'K.jKn4TLWJ7Z_RK&YiŹq=ΔMך5)r֯W>BWqu~ RKs(EdSMcpK'<,:ω!Ud\Ԯ=z>ee2#M!2yO13qC\`63?PLTÛͺGuOGH<>[fˇJ74ҕXqvKg^ͭS~ےnBxλ66 \t]=tdi*;n΂ @T3t@RqFN08uM>ʹk?@{v'x2Mcs $HYx. HϢ?,(ߗ`?Hn;_b|2Iu({2Xhkq;!5ό;91R=6fO vmb~x~TE-PeC`U1_z𣞷<߉ZÊFnm׿5,"DL`4!09RJ q֡$NyX tr (tqéNO(o,61Y!=RtmVkr\%њ]-b7D~&w$*JI*CFTsXJ1É|i|n^dC?67xfљً9Hͳqr3`nO\Vx{-v:SJK=#g}:qks#ƾ:щp/畲{^-T{py WY]Ǎe%K Lϱ\&)1B9 EN11rQww?3^o:[CM&K,l9N<0ㄓƎjT|8*y{~jP߰I(Qb6vLjX}zj?2gMrTpp-`x:|.T9Հqu߫3h'w,ꆞrjի m5%o xC5"-p*w:zDdy`ibBiWK,fi4<·cS<0NktimoB;cM-)|lkU %w駛wsđVu_&7oI Wi⣢9Mٝc &${cy{b=Uu(g[ i!&V௠{)aa/~ rkTWЕH"~rbl1^FL~3z.w:%C [|'[R/n 6Yݝ|gS`DN!#X\ss$vXZ‍Y8[ɮkL~FDZQly:U^-E<$cxRlU2'lZh{L "\IaW22[G}ݏ>xrE%ծzB 4f$nՈ;ZQ4a(w\ꤛ1e:Q諭H o R|Y;eb` KYÕ d/ҿ}Us9Gyiv J&@c }j+/MO0A5}!ASϜ;@"_o[^5! l&3?>Pb0"I(#SOy8x GRc[&[}L)?wWnipDT4V{exMPx*M)TB U`9p(bUb,? snRPs;q;V>5f)5i3w?z|{2ԝL4'{rSK2gYfT& '?rk`5%ܑt #nE*օ[9q_Ū?XIQIm*:@ a߳ B^,t X6c*j&mj8p-='SDqdݟ p}nntb`{]sdv)ߏsw|T`>=T/xݽ\yC\}g/(y~JD*ASH=`.9!=R@4$P]vqrͫo!#m9366GĬLu70{ 91nif6e҅IP:TehZ4pgSB/n#Ƿی _]ޚ7\x(1='#1rVRpx; d[Pa4O2K0?$IU}1Xo1>Sp֤NRnSmRb.! 7 ^ KTjg?ب"{1}9x`wҰՔa9 sp̵pFymT;a~"3p]ڡlSxA3vdբ֥8s8?SMcpj} U sF j䃓ETpu1b 9 m o6HDZwzZaܫC<_{Gh~e%!2Lw>c-֕ wFo)mHxh H-zλl|,"[5LlH æhm/W;믔ПMo0\$LBA9nbAR:~5aV\X-4G+e< s@T/:'怮G\<K +_Es6OIuXR01T5A%p{La }^ DQQDÈ$qru(nI)6Yy(Žӝ,l-h=l9>H\dA kؠ3%ϹvEɺ=f b{ANRu }>?rǜxNU_eǟ 䉱4 ^2ӕ l~"/H"SbūV07oAx>Wamt0lD7gZȎB+u_QQ<4"|m)*Ei%90ʟ g]]}h̃#[C2ek86uڣ- CF;1fYL5r2U[ (c}{dy%V{=&Yw@.UnG]gY;msCGcPYʳ}.GpٛH;/j,T|#b+A"nP9Nb _cQzpl3]@52kSwͣe8$0QS$aR`%dvo'od(}ii XGNgDլ~dwաN,~=5 IfA*Lm-l:A8~˜J/m)l|c\xRa,@:!ܽ'^N=4mA2Za]63?MN%ռgpQē1Suq cf2)=c9cSoM|iXo%S bǟ1Z8t٬5t<;Tx ^ 630&}EFf֮gYe'\ / }ݥT`+2`ʩ'uY7OBLY-֜tiy̍ خہ}< `7c=|Pzd' R_X/n@>$mHk ބĺ9rZ]\\06I V\.3J\Wv&Ul0 a/+EKoMhp#댵N WGhKcT!wGnFEV@ ƙ#8jY L%C/W\j<أ ¦&&bqNݕc]=E  I/>sW3kRQכ(ǝW1ؽB߷ YWU3yY5*,\iBvG8f'[a!xF휠xD0T0@^~I)$)z/jc͐V#R$*ixyr, K~(08 6-dEk@) kף>~0 &tb[ZmoX>=ʐQ16&⭚ĮC)b4'چxSM^=.[X{TMM$ 1O\bVed ?!.6dY6K?nfϫA٢t\i]zi1!ߎAs'(X"_RhP*CNLٍIؚ]Zfi`pdgLP|"oƓ.o5;.X3I?n)@7}cy-]KVF'b8\lcN4Fפ,>&Ǔq+'jd]xh= ChԺx˅⊽=iє{w2ˑd@ (9&i4;Rt^Y!ZESd)r( )@@y]) 䰪iGu'6oF027xj` Tq'_?^ZnN6f?iĎm׊jI %Π0q`wYūUmòH+ G ;ۛh3b5ey˅1_M!͠D0}ϿQ* t._wZ [p{U,+LZz0-qܜ&u)TGF[&ZAU]#{3+VYJ7?-4UY^vqƄ艒 (ti\!`{nBg Ο94ˀRݝ;! mspAI㻫xjD;u} D׻G_1 NnMOO4vg3b,)Uɞ CmS:۾`io c H .n ({y `VְZ)P hc36'm#ikwO {Ԇ~0(Jx+=ѓfO7h\Ȩ, ? G}ԩZe+75kTńHWϺϥD&HS‡Pn:p,_搏 $~};G2~Iĩd] P{2֕ R5/ZPOfWg(|+.w _ujLtTeg\[\LׅUjTMW JX VlRD/U^TֲkFD2_0F & 6 ׫x1g[00Xg^*9PWӸ‰Y aҧ̉qRhɔݖޘtCը thcq7b""~{4A/) wӓgO?NFs 6=UIch-L[i ts7`-~' 30S&vkYOrT{B/_"D bgK !ε~.쉔_Ԉ8ˉuyDqIW IK&_&/LGH&^pՖ&Ϧl+YLyvt2nL8ɢkTt!~he'g;GsbK :@ZSj!6,*bx]SqHZy HNs4H,4KL?haZ?#iHUtJ#uv)[}Qa\ۥ:A![ *MzmwFM_x)(*qBI|&S~]}XH_/p%$2<oޡSnϟ&%rs7Gw}Yi^߿= T+K%=D;XP|gZqI%!6+^fqga1Ah_ ፯I/g.gNi+*4g2l1jR|רhrUv=1ጪ|lj/t8ٹiG{xYA'[zr'n)fïnU^(_FAMr}IbGsqfl,.MwUg4N$d7cmbG;s!Î ˈD;%uw㿢HEك t~bU"[W05Hh%籮AV7nsN55`zkewus6E=/9?Y7QTw0ϻ}!lA` o02 7Kxo _x-/H֕4>jƾ!tݨa?+Y=c(eh07r#[dqw2mD+pIn~.>@sME2:¥gB`u PV:)rM̹bxQ#PX6ȬtD[~^3Þד #rb2 mJȿݷ[BjaW%YgNb8֤?QXԨڪ>f8~i%c56&z|js1d?Rd/Zbݡϫ=NShCa:t-<6oydF,Ɋ7;S7֟`k>.waϔ衬[j꩘u8.l5 7nG[1FPMKgc῕d^?-^[)ْ>dӍXuO0&dS>biKfNxؼ~$@kiwi?mT4W7B9UJC'6 Ϭdm$uQ=Lz Nk&M!lf7$HUC?y37dT8"xXOB`Їs%4Bv5h7ug(FcpB݆C5׵Pm)7}^$͍*"r0F7R%u)~,NM(*UxK<31Su 淦ԛ37Z?g hwTC NV#A8ӻj6[}*nƯ&A ]6_DGu*Kn-J:fb챴pgi&Ҝm~Jw@>-_ԄeAgR7'eeN"-mo+Jri@xqEBKD[R&zIIb-q7 85{7AI/[)%e[P̚QhUB ~X&ω–6IaDt.]ƆJN/be"ȗ?aׂ}8lI{ovNɷXD[1gMxfa; -!6= Ym =6rJٺԙZҸ&7, m+唇KرE9%W?[15!6\3yuHú*/^*'UgG}!p@M|^0r@O玽gP?ƪd{{'zh[,߼ ٥Xqq{i݇7Rz?(lWt (|ɋ/ϡ({5r ~Gu3݊_zg::JӡP>U.cAe:S]*a{* 0Ty 4^|QHiҖ"T#q5(R\t֯3 3+*GrzگeE9kNt\FJƐ[ꌉS$(_|B}չKkƟZz#ܪ)q:߇a`T@ȱ*D~P*dظ)s+ItYpNuj}c'IdBa` xhEʊdڠfRs]ۻ嗐oddN@}TP}%&c#%+D^%Oz{ CP yrh*˝2C*$ :8ˮ*y ȝATDZ$00wp-un7x1m nn4ZY5VkޠxtMg`Z0L61HC#wׄiuuPr=ODAjw4Bt<Gij:m vIgV[prHDM,L-(~#.+X p0Ƣ$^ #+҉N-gG{ui?jl5e Y ؉.zs%Lz:[k޻H )fHtC ׇS(ŐojI͝muȭrmI)SR]gO\1ggR{(+fiy%0S`u5ԖhZos]s7tSN1uBKЁ ݙx vt_y8EML+ C_Cm[( U;O~@W#ZzD*gh^[z uvl [YLJGpCyK^Ȋ+ixíqM-׍VM#QOA8HceAd wK05XuHpW'SYX[ؙ* tdakQUL;T[؜R3RQiOҷo$H &}Z;)ɻ|8( dG&.]IjqkI(+z i]ΰ{\k%?",0bþ^'A #D:D3Q~.]غ`FN U[|#*UI R\|BrNDX,J!=\[pbɔXtQn'98Ul$M6:O4ѹ}e`RD!R\b vZjxq:y1E*)cF-RißfNBQ`~RWoՇV{k[&1ѣ+?|Z"¦JU=_T$J0.ѥFd3"ƉX~Nt1{nA|Z}7zsCp񯦪np)8&ǖ(&ʷs Yu+Tn q@iE="gD/nF#Hc>!^NqӀB7m/Ñ::aJMG\/Y&}8x m4v=H#@0܁Xˀ/4Ֆ\ꂢjl67>W,#m@`זJ1# aI?zN.2^ 7ĢP~y-^$CiF |Y%ůVx!o ʤ(iƨ6]"-չwS|'Z<"뀪1$v֡ȽKkT/Xv^?A88ߘzn䗾|QJgJcML3x~Y!Q3uԈϋ r9^] Wo U[␵_@gZ,Su}KxH \Ԣqq8#Piv;m\iCXTQfZ zѷE5'Nui<' \4!MW^]~`>[ Uj2TͰ=pu/i~so-%QX ~Ld.s i#R/Uq_D;95/ud"AA-Vӷ`2yy\v2B2 1(.G 1%!]bz esV箒YwI;N퇁kvą`ù7gm|Y{X&EXeU]*W&}q11_m:%mar=>`룗)kkk f]ND}qо3.s@z%f?/TyqSxDq6!_`ol.s$T"_2X",wuWS@sN[E/.[ 6leLyt=?1~8I̷7KVI1}U iA'fu'G/ ?ůo4}un6//k-e͊07}56 /]9/Hߔzʩ wFhxDbf)kۍ&)R`(Qo :fVy!`:P2ĚUlO.$ǘ!]] ' {;v8Gs.ZmP`1Ӆ@a7FMLn|ѣ#& \O|խhwWűVC@ڋE'˸kNrzI+,aYD4{@Z,}|@k˒L:lO5Qó1`l6%f\Ҽ_)##McǵicK] 5Hݵj\~b11nyڂg$Tl.J5ߜ!η_b$˧譞%?g}8Ӏ!uS洺oQ$[^ЄA#Wԥ!Z\)g<>IO 㲳2;2; +2ި<[h(:P>J?F^;!DDV\8M }R\rFR'JM.|pNo]*#T|a@\0M}HbRʢЖNTۘ񃢧jj<)qlG`6\PEl^rmK"ҪDT.Iw:fXϛdfrA9o#)Vq7X 2ͻƼEc|*Ǭ_N[ S9hl49=V6i~S.ƨFC6RB> n{"Q*!RzF4,T9__!Vj f<˪SlƳHJ:9V oly|],0ڜ7DI&Q;4$VN)D䴡eflg&zLXװe&CNTmy..|nLMp5\rFz9܏v5Mڢ@ s36F8wW _*xA}䯥y=svޛHC/fjˉ)ZdWa}[ʣK| lb?f>5SctٿAкs$No0+zojPw{>;ܤYWUjԑfKn$s@LdѮYhi+Vᖊƭls/~U_Cё3FqkYcTcц܉-8Po|/b'-!Q8&|0yC7we-'5ir>w_DLlޞl3j*OplM'feS%ՁY+z4ImAc.8 ]~GѦI尻-uw,Nl7άyu}CςۼآY!Nh`]}54̄niMb(UzN`&>X.PĹu)))nn3{k?0rPKB"ךpQ6 (@KUY$&h 37[OGqHZU5u<yX#sv~8|&jcN{ZN|AǬۯFK?(6-E\ރt",2\S$LovDV}LB3"HNih721N#0G;>oeܺ&⫉ri_4y8fQp WG7zsy 㐬M;mjɳ9;*Ba8]iOu3[y,y*ag4Ϯc"@W^!tUP^N !#[mDy$3Wp^9fbO4E;\/pgL,W;L` lyW -k~Z+e"&e*1烾k6M&PG&/WY̪y]LZ|N`$*_pĊLzij4*~t.蛈{trYE8yrrJ#Zn/Ufh 'OnuGhZ{?FUq艽Tsr#!8Ѣ7ZoPn{ ;hbLsw0)QX1A!,H,K֥!XÅz-yJXoBuhuBAҷt/-6P5D=.Df'n5S?V*7Dw+,]#Q|?zܽ]!F0m3tɛ`ɅTK8a%^sn[AO NOLjFBxQݙg=|i^ߣ˼PE31ښiRU1m_^n QjlE\%ʻaaG-icH"VP**c>D,` ;ߣ'f4`SB`^EaԼ Fp8aCbd؋RP8Ҽy+ [:/ɓZʼk[/Ϸ*Xu4MgXQ[{S )kR]!DrlRqYE';W^LZBcUB%4ТzLHNQ~Ԋss#$Lhˤ7`OzPxg}-^"V-]:kJʨv0Op*1 ^y軺 zy-E}?рs356׸T&fWMMͲ8`$A:%fMk;'>O:[uxƊZc 0)gU,}@EoDPwn:tE,&ՃٌZmSҊkF_QV):ݼll0iJKy>8 8 `wJkjF4"j^n^c8q́ri-T؍vcC2?-7[' |vw<t fpTmu_.Mg,oj NoUM\\T9t"V󟘻U t&hN5WkmJXӾD(/k6ϜзN8Ӕq'~΍Y"WgJ[d^֨9'&, #Xo_6K!sב e9jAWoDta~82AZY[?`I ԼѨY[鱷DIA߄9m}hȷmWhEV =]s)q6\jր,uCl8ַkjVfyy+tDK{QY3ĔY1}?g*JeLMi|nW4<3/@צ[Vl문A3NDO`Ŷ|Xl #Y!s;cЇ=hܽ`P_$7?xK_֋;O߉,[}-FS8zT9`@sf~^&@f)aϱ?sB9D/ } /DŽ 8 A0 (IQbW/j?Inј4Y혲dq1iNADٽ::Nh Wi=~BK{me5H=#RBtwhT|sU@͔xn˃:X{mšAci$Oqojl5ATPPnvUX5Itu~3BUr]paÜuNqLKвe|3%q&e,AL9(.M^}57z+^DGlcωBlVOWQ[ r-] MY u " $Fd7p{ݴUZ¡jϱ_\Yxd4:9V}9"W^@W``w4+‚U,gQ0z#Lµ~%5fj;,F7d 0Mp\1B!Еΰqwi=EQUcb?7i:k8S3Lfɡr7v=i}\}SfxӣIF}$B^㎜0FR(;+zժޣzV9PY/C.<_""ͱzѕ0~9i(ptCMyow ~n,*TnB+]sz^4o5"X`$z^Xv+T;.wvM3ն217g" &2Y<*pż,Ab{8/1r FqB ~{q-y\!ch]JGVE#/@Oyr 4)ֈc߳`2-.=hSʷRw›ISj]c *mSuwel<,'~x:7?mab;r7=[iiƽt*~26HPfV5h8"[On{I]4p8 -tvjJE,Wؒ*Gԣ,J*EZmnEpDE/w֡S_|1z%Hm :M |d7vʤ] )8y׌J) C8WVIZEE{%idM.G/yirT:U ;M :NDID6%+flIAnL/sRnt9Fp|($oFr$̵Wd$fhvS$uף{gdvsNin["4& <˾h=@280+z^.{׬,-& l?ʪuQ<3Rr{/a۲K{}R!{䅃C!9t׃36v.]}`7?[{Vc=-֍՚\iznXg)_cH0=!:RP*/k-yoR1ha 8b %/֌;@uBc[j$dh7kv+:k=4`P},k4kpA)0X XEϮʙ6HPxeڮ{z0.Ew@Is&8km)xR$5}dtBWh5׮3Ɲ ^Տ'9CG5 [!~IL[X(<"W,0fHqɯK0>ȯC$!0Vi*δp_=^O k,]&1I@0C_Bf®t`}քN t噐I,.3(Rhu0U^'$7;nP D͡>`Go L_* w Qܚx<s'-6zZ;6a46TY>?i[7=Br'H:hcI|adPB:K^¬T毘JʩC{TiC.}8pǹ=i- gXbdž;hIX=\:/Il|<8CnTDMN8 ~jkgȢ{gOl2h@؍R |A +[ ^2q7y8]sQ,I(:o}2HkxHBM0CO|AcԢ m}~NFJ+ N8T8URN2{Y79 /5FvvM\42|lk\XеUB_:ZuaKfS6 kLޔ|)nɢ)Fu' ~\e0{>w}=I[;0L f Tn=@8`qKĭ8*:>S,.9g8ЩDݏ%:>E=:NKGGMQ_F8{Q b*TL1püh?C&$xMJYŶJ51T*rfJ]SaHbXrb·m6h?x>v^W5֦8Sfy}&g`F&4HLXBMPs 6 =#z:3.5D̓dlEEdQ+#l$\~=Z(@W ի1Bekڛ3/6Hm-Q<"%Z|XGP~ԳORVi-yhE>+kh4qO;o-]eXJIa?VY j)\9Azcxulԟ4]2҅LKQef\cm)JɗbƎfJQV|ͳpuyˑ3@edҹC$U`ץf݂#Nfa`F̌[ QC/Θ<W}{ȠvK@8z8{_fFay2B~VT쒝R(8i ̄˗ύt:f%,pmL*p` bø{*P30='H U9Wq9rU9%5^EQCͱ{Z!ΘzOJ6@EHmwEu_SIYHJ2n>J/:-Xsqnˣ|/@?U"&HDlf8Xzy 6ߎ']ѓiT~O _Q =n%Btua .m%`e?C\$5CG֟m7ہWWlFWudҽNc4K9k c7it^%~1cc꾥H޹*P E*iWˡ]ry#Qw\~]nԸCd/pf0ɔՈse'dUUV3+.u߼qV~|"duCeq$^O5tIA $As o{qW^ yχx$+#"5NX(>>W_^á5PNx \p:2EɋI#DeU| pX)0+x%eLfG:Z2&M!ՊJ3AA ƫ Odz| ?]q@hnIƤ>Τqg+X\ҴT $ܢ׏dvm6ҝ]/:g .ud22_S=~VgZlu!4E'D@ƣ0Y}Va(faT}^kMFCs솯f*y-;h5"ەe7KUKm߲rӸ}6ztDC I֨56 tƈkY{ Yy93:2HẙJoMG ElQ.]|z[ (yt[`11P~G2R3J(rEog_7x~ȍ5䞣$>%xJS J Z*&a?]]pe j* "k^嵚L492;2~+{ϐg~R~[8u`y:qHY|0K4Ly#'D}"▿Yeck7R 640!˹@\ 0\Hm%0djfg ~1h+ۈ gW/te`EqZd;KGEa;S`j x~МT$p[ɺJN}7i1KCf* RrrzYC'㩝d )%Ch!kiej`4d)BT!bAqU0i jtʸ^BuwBkw:0e̴$(f)84>0'Z6C54#_JMM g> ՟GRKF)^@?%j_agCÍ^xϥ[P@&;$ȵߓF;o#WFI d$I{':u< 7Ⲇ$nfekt/H93adA2 1!{2q1ۈb$HbG|qY3<7!5:a0*v\wLv狇lmetSO|UH̪YeA|x Q&_.cjn,a%7 朐R^/5~ Gz㢋SR:w} ͔_xz4Z01҇`ꋧO^5wF.|pf>R=K7:סN:43 .7l.eL9(į :ElKw%5=Y2/S !#d>:g"e֚.ތ1 vI3uF AI 'U}k5S{]=L]zVU+$ 2`?Tƙǃ0=95(k_Cdw [H;/t )ii@x( u腶QzdN1X~ < J\b8e${sSCsVCR2="K*MrAq}0be`MTvgtJ7c%(2ȟ@No_РTDQV\-f ,:zJ٩q|ܦPjbzL\@ndiU Fk2YV Р @5?-Α8@Ǝ]2HZ/ޑ&rQkz[5?41iO:Y?H>5uNowRK%i`?t_:|摶Ju7`xG O?9hd,gXq82Φn1QQ'bJD)VȎcijʣ@ߒCP4 z-{^[ǐԳ]Wy8bixkmegy* p2dv޷$+Rm]N:B-}cLL h xYf bu3gvj&AS\Rb =U*XƫԷ_g<:? ZyY{vW7crq)̓%swƒDÕSf3*Vs@] (~,i [Lݞܶ"|8g#fXm *7Th-bڂ˜kч-o r{鎎 O=f17䊝0X6 56=b - gi3R#i؞S#)<0ò@ 5(-{Ký0Hp}$%-h*{Rlj[xHZ:n6Qh 2OtO_ovC-:?J+ !/}Ψ4F0r# G:(҂%|b&*Ow s%Y.NV^OxMy=ށn޼~Uԝu=RooUi[뀚<)4-A)#Gt]s&C̜u(a*V>gbiIgJoftWgQz{Ii'r ÿR`{|s(dpHH&p$ mL/3CYEuYOuXL3R T*1@,iM7hoC=Fs,V?%PT-]E^b9ilPKT6t Gk[>hC=^UxEܑb5LDB}%'Oa vtDS7DԀ0j^}Ϊm l;Wr%)i.w ?>S WM:Rq# }y ia-7 $չjьD):Hǽ_e6X/f*,?b!D$DYKs&vߥ(غ/Sޘc7F(pHC;2o/bϱ?$T`HyNy&]fz~f5]>4QB$SW[XݷǔlMd̙Ȅqe @ZG|VBX*zb']GK*Nn3ﺍ qvL/"RH^۫>*%o=ٝn'l19- (g}|bVt"j7jʑͣQD_~BjX>ך+16UҲNQ]6 lv#>\^|ziN-Δ'` ;WסLR$W[ɑ#i P%7(&=lZ uo(ɬ3|զhC b`<1`69x -K <5SlqWgЍ1X.neN:?96U6LkiĹj#T7 $* =',\7BVc7rǻLSsЀf)*j٫*v;Sc۹Q b[{߹ueTSTl!DX=l<BS!ȐYZ??m뮄g)keETTNT(ݰ+r pYU?)uyg-<ƘE6c:ײ$9С>u_q-Hn!eưyW,XLChwvj7 Il*t,n͢]\ORe:{˙4O'^fa)E.T C  7=/v2VC4i?oLfDjx[mpFjySk0xUU`3k-;\XJ3%V){~'/^}9:a1|_2lğ?{yQ?\x0 +.cj^%k25Yzk퇌yuHMhs>AK0λ,dGȯ_0@ xb|.8H ҰA VTR0}/lo>[H?@?Up[P]#3~>#S dQtPON1:yQˉtj&GbNjBUoqD3\~?H)ͫ+s ,u*XS"*wdNw^w "lE!;<.gߖdۢo{Ӥ:c WcƝ]>G%c{ k`"ZsmhxFJ g\x69!C:^yyq`5& ݧUJy;µ]R*wgN.~]zӪIȿ|+LGz6<¥V98Z /Ye \JY0VwU,wlh?<\"KZzl`8@%G#]sȗ|NbΘ].t1[׊mXKj/2{G5RNLs7@Ԗ^5Gs/jN3Dn-d6ywʖ>hvN^b P (Xd#ݜ_h06Π}uUt,Y2# ;z;9rL.MW%+,BDz)ܞ.҉Pc;~rM>!Hf LJ%pf> ^HO6$cu" UWWs`y{imȼObӕ>ǭhr뎙=400V FpU%V"i |5 u*x)83> (v廤/gj 8PZ0&lQQ[lv!U9TسK<5]g3 Mfq+D?g4goեo )6`=dTEL42>xai83J{&ᵴ)L0$, =>`c] %?r~ؕƔWrZl::p9eB鳳P/‡c+dMTW Z&uSXҪg2WwV4&ggppW+]ͭ=G 3D+ oVzw5]%/4~UVd5XIU>J1tEG)4m9î*ٵ:o?qC,3Ke/guT;AdSe/N?C*+~`CWĬNb5=2v6XƆ|s8+n ΁QhVK𗺰15]~名's좄ߊ۟_1C 4 y@pBH?0Dz0 3";y%~_fjLX{_E†];hצ#|5ig$;ׅa!mW1X3GIm$=SLpt5??߳xAp޺@&8n٥FʴɐZL_NW:{۟xO/&a+M6e6GǬ2#A0㤆<"_Fy/YK6#@-R3A~=UEY E2 i%@ g95{n\ ̾qV\LVx $ $Qwಞm↿UDkQ`HɟPUl؎xI~^_8c5D}>VM,651ڢ[oƜ!pPv1 ㎗Y& ~Ώ(:U1K]-_5Hj]iܝX;l`$n! HGe[Q fXvU1q \mx&n]ɧ"~zpi*Bpj2gOӇT!X Fͪ cL6CMI&3fn~eن8=Psw nkBMy{5g}Y}UVl08{qdfX2bS.6?<}8ܠ] f$3d>+"R z9M۵;u)d) J #;;s5qu?_V_*yo U3 sTBBrsGFXX@s.otݘu ao(}j'd[%w:t;16?L"< puh^}%'{e;@ ' rᗲ_;ery"Ʈ+1sMz hPf ^P?\c'!;ae}X.$ 4# ί=V1A;m\=n׳ b9'UI9}T@p Gb6xq[>VO/OAoUӇ8xn>[[{N6uBZ2oM, AG)0_Hew9N(AgO X8y6_Qr|E26{bi!Ytot3光y^g:LZi2B%gK;zr')HYqWUDo oeD2n^f%d,bGW0lxnT-i%52qeƌE'خX'hcL1RȚ72s<wuwQqfC2IJfm.^1 -aRhΤJd]YN~yʪbv!-OcnLLKj+JKKi%'3<@5}VѢ݃Gi<BEOŗ967taLR.U9[_pA>aQ9(\}bo@"͟A'-v׿H =%M2&W޸<OMrߩ:Q3͞'m֬}cao T8+ Y&uk=^>47۴F\O,@itءHi ďɔSOYlitH3Dϔx#Ψ ktOHCDQAUYV)@qI!fGSQE̷=XC KY:ڮ Dq2(3L%H{2Iiz76i0*tIIvc?(6 `AZ!0Z^Xg$)`F^40d\A>ݞ#8tȉqWY7UkMO9`I&˱@1h7/(2$ON޼tR[, J: ޳ip-Ѫ4E7d1B*> <錯 h_)ҜvV-xB:A&\ߏԝ ifH&Dv Z) \c>KE9l$K;ł~S25b']U?PnER׺#[j#T<콚DCB9%y^΋q,M]tI LU9i,m ` ckmɱHx'ՇAԼ y$2⧻$Hof8[wgrVy UWnsyn-SNq'GK0dŜRIXև}&xy/W"B*Lſ6)z\ Mi&bZTjBY>*E". b-3IW6Ị,ݤF]y/2YPٙ}[T8 G:G?0f(x}c.H ExU+O EnM9TKytUqKuLshz?­..&`LO0]xj/\'/ck8;~k$jauA7avGi= <͛xq֕M/z?c^KEl¿0&f1yDMM++>9^\7I,vu@FX j{I zH_"iS[?ջN"oMafu[U'"1:x{c鸀[Z^ES?fm} !SoXyb5vpM:ij|F! {"&+F&UzImLS[>zBVKnxh(ezmEbAtU1"tIy=15m.@NvvrakO@Xoog[BMJV|$^V+ZmoJ6N>UqzK_R6?Wt{%6UEv._d0u(#Tm=x30y@~)H֎ 5ыaunFuFZ4[njl ³2 Ǖ!)[¢W3q)kx/K9vAAv]b k> ){>,5Rrvh*f:[|m dY;2+[T8l͡,[}DCAcBWv;9k{ d{Stzr;5On1;dwM)uЖ3ڽ_>ԙ$sɒ$/Io &#TKR.2#;l7ҀoZ ɒn)~ oLvp4?9(퍞wBU[Uuc Z"슴 Ht lAI ON2{MZ0T~Se&ٝz\|(Hh+oׁhq>@?[# ͡&Y?Yt[}LuAP[EZ޸l p /Xm71@ڒt|,53s57c!2w0VhCo5X89؋V!fH?JJ*X"^T4ػ~lcĹUM;b)H:7[&3Ƙl>kB(㣽! ^X /'Noo HwϬ%Tҗ,wѸ4qu,WjoRl^L G%jNJz?b8bk D)4 -j"ctCӏ!I ؞[H=F߉M^}T(S쵲XOvEacϜƙ@Zk|ZF{N K(X.J=g_ Bעq3^4)zH}rnY7@V9Xb|!Nb\;ºx[@ ۃW_Rʼ(8úZ}{;D"E?t3 Hv晖|+=TBBQGg#ny$il-2ijUiNFhrk.: gݢr8w fT7[j,*-[O<>U0(a7Fh0N/u?@Bmu3JFٷa^;TQ+o)}[ZFTOa-`"A9/V OR d,5< +#f?PL]y !u)xO C]seqMKV@鼲t)+1AS1IFS,_$.\ wΝ^SZKCY "w7F,KQ+[VvxwqvJ&1BpC[חZ\ֽ;.EݵqJ'_|䋤Tg:q_]8R;fyf־G3"sD1T zۚ5-7؞eoYx\N0=J!s.*S5`ٕo6q+T+\wvvqB*D%jٵ&'09+n IPFߤbU:GKl?@[ \y6jC$C 5gOhI~#|@S>FfbE,AnV#SAX*ba[E0(1'fZ<,D{f_X׿sg"U{Iv8'hLv]gEke[_ >?1ֈ;Pc9ЮY,?iOr ZZ+R{'/ub[}zk/@pQ])㬉t GNN<jf, o/T{˘â9:oKh` M9IP})‘mWp[L*7*LM"zEhd7$k,6 p<,(.pi@ ju֐Yye"ń'HEvB IHo`\%^.t') c[<S1EͷƸT絖V1! 2S>҄Gj;VTilz槛$<]-gF)"1#Оo.]QS[1Sv Nka6I0T08Hj\L`Jꨪ5ZN ﬽/gZ-Wpq"$_!~F*#gg}wP;mi+9IfhnC.NxU1h'+lUєkfK+l0r3NOC֟@ 9PH]G(^d.͊9ժ1$uڞO?mj͵8ý iVfzĪ7S9uLe7"X݊l&0W^4$Iwgo-\]/躍 /zcU|Εc_|y]Gˌh`/>ĂiIvw,gsNwD$7ʄ"uCKM=LC=\[ow)pG^0bixɔLw۳s}8'L ŗ {+O;Wʦ< L2^> /WNDsNl2g;vA?eQHwObL,AOIJAلϏAwENcBBF+V`2My_o'&J[:!K6iGt$&P`=|.F +d[A:JqC|"Ŵsl|X/L2qkˈ4HcZ+uɷ}6Wy}u]RX^{R8,gui"9z{¯GG-,6TO1|ºߥ !Z؅pJj?$X[4;L³z['&?/r#(+uQټC˧e$]7|m]?3gHU.6$^U&y/bVڌVc2 ~gl;fKsmbI])#G)`\FoGC1+P[@b5VRz`njlnREZ,XWw9INx-G`cÛ8wO@㡬U k9YDh9ׇ؛5tÜu,p.j2J5^xΙUq"俆"{`6ͦg_ApJ麕BN֭`#ei߭檚ҕ/=9|e{$\{$;M-mO W8nŪn>Kb(|\7.m%QZZj">ZrxڂGߺ6Lkm2~-ziho=[wI[5 Z]F0Qd4&ؤrXjOaRNPl`ںyFHV1RX3'%vgbPf~T*%Sj[CnȾI;XmCc:x[|Q0@!@*tkյ'lH ׏:ߎT%L0Cbހ#9U!uuNP2lT#엨>\>`k1%R7c((dD 8_n a#Fms2Nڧ_W޲y4πɂes% N8A׭|s@AϊJy~Mư n?0LΦ&]^G`;,p+Ӓ;~+z*9- U͒[&ZoNRP!6;HHmpff ~x ځ=0f\xƟ喏wkLe(]>NMZiS{ۇߌ.9j\q^~ (7 3zo7q(**WXb#O rTV }j۹̸piaD@{5"!reT<5?n3)-ƾo37B!r{ ja'RONqѻR2GZzaKӆeʗ߰펫xmjyc)@"-S@'ג23 /Y,-Kh2B>g>p˘5@wMmq-nxee0+l5% nÊ&hOߦZ::<{BQA1{4|#-]kP3G|^O>Yd1e7ix%H.ͻkظY4ѥ*;t" at2OXq%m [':m͡3*Й=Q ;*W}qu!"m9ѳ!^rERr0% fw="@ *ڍQFpTc ;e!j B{!s7qrUW354k^+)])6mR dv @!p?+!iچbn/g4ɸ I`+BKLunj_ /R|7xHwMs\+{RrWHamKDю).ً$tq|~D{S3௰ߋ,W7`T&ߕܗ.?忻MlW |PֳOJ)C1RC yjb&&iNOGzm Sfȭ4^^X\nTI@W|)qGҗ|Ȁ![عڞKDÒ;Am"P,"<{Mʄ8'Az*mTbsBN[ɍJ\aeh8E~qT٭:ʴ9c.(Dz2ay0Ϧ]QPh^+@100օ۬3Y\1:iM[j Q"l6>ٙ`'*gkvmKjhwIįGEOvVVTݱpcv};Բ$J>CQ~4 {(VW Fv93ƻ_xB "}06EǭL?3d?0_nϏE9~\bb@Z@Ɩ[E2KVhFvW=B֧O>-tQOm7fN v[hfA+GaF0q!qUsx,5oIw JgjSep+O]h\0b$vWTk|)lqJ/υ͒wLy-e) v/$oPizR2aC@T`꿽a( NS91u4=4ݑg{9龹l d=wWA1O'>v sk9ء0Ys, WqRsdҙ:}^&c"Jd kOZKz_:%^xh%lϺ(}d9S C}\5=ved͐N|fs@ϡ0)'2;0hj4_7}G-m5'tXvVG7M{YP0Ij#sϻ̇Ww2O(ܤfH(GMbxt%SsjZo1679sL#xTf9;<ПX0Zo-bZZ&94AtR&VlwC{>Iu– *6^>Ԑ?hһ5_lmQ҅-TSp-( –c0Ԡs hU,s<quʣY< s~?"gb'Uo~ˀ0ʡf'!ST h@GU!CeFewe=WA3%~;oCV6R3NU'ī*pO f^OyudܻkV"!z5v?roMB³ފY, &RvF{%ˋ.8lUF?;ؖtdQуCM7=^vJ^n]c Ԃ dukO{oQ'y/g2nm"}vMFyksXٳl} Q+_hE2A_ővO1X>bcL~@'y=zw'B~Yg H%m9&E~"jP맩*a>z IerI[BY  M 9ĩ7Ht߭`|8+MV#}VE䏲u8LJ¿A罓ŢqX tsv*BIY|8_" Y' DЏQE }8J{&zy%*`s^C#گ=N!eByʊwZ[7g&! bqP>,Ju e3 $7؁< Y<F; I?xhGǫz}{Eu&q5)aF)4BxVIBNa5 uA,LXB`Gmsͬğ}XTPaH7Fc ƿmpB5y֗brH= s yZŽW;MQ]#2L{~Y)cQވuvj0,dK8VFEK;/Nhr)7 9;$_P@d;}V6VIiQ'<@RLS8_o\5(n? [`Ĩu=Θ?#u !8=rAn*0oegdRƊM;$`b_NCHSNFV]1IAc۽FMKi<|iR~?ǘj?R U6E'}gRԸF5ΟМYljelVpZ̓>3mQTILmDnѠ d:.s!l{_qcΝu^`qecqPWs;K81 ڢdE(&af\@p1ZMFA8X198łwm̂ Ϫl*2i54x<ID]wyl+ ˞F .sѾR([?S #$5˥VTgt"w@k3_dx׀y_*J_2J8HZI!+#O@$jҕ{鸞>VYVׅp4 ,Q7U8Cܯ(wVw\yP& ~<d~̔H|](X5bA܇y^JgFyQ ]`WGd o˖,qܲz&$b6 _|x %q pm!b@IuEo4t LcoH W㲸->=\ 9 ̈\7uz-'o1o~ yyһO:D.Dx~Z¢1rR{d SNFلWfXP3b/_dS?&"-^/o] r-^L%cmcH#ngSϵ#+WKAff4 I{&Ȇ+={T,&0 %}o~ nScz^Jkﭛ>ș;sKiYЯ6T~i`ᘬO4|ht1/v.i93s*\+~%1W-EcrSDGy>} %\հr6ěj~xຯO^ nXIYGv %%A g#A'hٓ`Ԋ bBzEO)GGP>=oH`H֤sḤ0%\m At'xsy6xاul9$&ێD&M]]pε:<)Ͻ=$6Ҡ嵵f=OR _C0ۘ6|2h6WG&+)nnAgT̃( &HwyP|Q۽'%Ο>ρZM@9s*@FSز([ QKjyb)aȵeBHWIF TNKa;(bYTcoQB\9]'T&ۧ& ,Mz $ Mf-00Ҩg4m H8Hf1LAwZ!/ħU]ůes/^2f=#zUx%0kqI>>#3[P6ސI5(YXʅӎ)R޽q'grвs\Ut'qap_m IJiBxVOɞ09O5Qx[CZ#GxҖAt "y+ r_NfD\ߠtyߧktk" t'DX14n#C5i+4@5 I~C&Su1䆝!YfA0Ϸ׆k8"ŇD`O"~3FH21_ӡXh>⼡6kۈom}KNhJ3 no$OK!BC?dTg6WKG|i`K.4rnֳq`r y°<4HΠg.`lbǂva.&> F}}jO&0=-7V4kۺv'L%I,;͔>tlgtxu[irD_>gfT<#\aGa2I$AĸA<ͨ/׋?) e;zs^eQ0D h;agrNl ^1Iw#4x:#oZK3dէ42+[F>NI_9, iqy60-Ñ:"$z Ǖ?@Uf!Y€LlΣ)UE\&ѡm!$VC!T-Y34&Vy6:1 $aCT9f"8-S.*6!S}DJ"c=(BQ[U[Әzb*xkߝU yxh"];S ./HW9Oiϵ(p? =gyCNW%8VE /2cX$C5n`ay96&^7W w̴Nr )WPzr)[e "C$)_d[ q:h/^+;u<{MOoG9|VwE{an7٘ކ_68}+D֍,wdHb!%_Ҏ=Y$x 4 *ίhVywh|9npY@J{R(o_hHX>$՗4N6I_6إ$a:$Fsʴjdڬ1ɞitgoБW_V[<5l(Spb@?TuKd}DMgWdI߿Տ~Il_+drwe-ѷ56,a|&]T(q^3=*|:vId߉=^"]_yZlmS*+ן:j}^6]7;lsLh?\Vti³O_|e1_ ¼54%%fjw֊.hX_{-$N=jmzwy0s /g@ zFg?7LK LD]P=Ň Tu:Z$ffDe>Z _My'I^@})Dʘ&,ixa|ˬ qW$<~UDr}qR7ۅSe7jjD?js 0]{we{G[wrU\g%b;є6|%>!ϐ [l.:KK Zr$v˰/̃.ϥ 3:ezxw^Qk+gZ 7^8MHIHMjV|!JϞPdU@ۘtZ䐆YĪ!vT/t\"YG ×]t>S RJL}m=Z_Vm W1?tއ$K,۸ٓvǚ2jdWt!wZ#^+h"jfCG}5ihl3&^KS@X8J *U8`B{nѧ mY@S\)\8?1 `s{i+;P$itIܡ{\̼{vTҍ 9=?ZZaxnE6|>P7%PY^ک)x;Gױ89{⽭Ӛ`Qoo@7Huw35uYw ØtV&oPbNWb^_69mң" RkBnkb}֤MLs1\JRcM'JUK,2%OS)H`%_eq0g쌷Kӧf1oC3w0TLM]> WɇVղwgDY5yL6{|\>&5:fP4#tʕS>Tl}ܥ>=n@Hmd$F'gVI{;I=ץ) Y?%4ݯ׭: zxH>r]fCƊ9%P( 2]iX^@kPҙr>5'ISV|U=>%FA=h|yuc+I.Y7ZK h,"̪aOy0W9<4fA/H/Ι>JxpHRQu-?f]ga+X6`$RqjN}פK Kw6^MnrA.I '#DJQMqX?kج[~:eG"v9a+.t6H}b#OוbQBPb2"jK3(ۄם&i0Ppʫ\"er!dbwg .$`ፖ'4+;k5CTko} MmZ0^O_ߐQՓOlBiiТ' zT¼fT7䠽tU< W0l-'B& 'ih`!ߡ^iEY՞ e`hegLT#ogfwLw~oV[m}oг'i01ܮ KV`ѳ6}Û+p:'H@.Х뇶IՏ v;y}ˀf84gk#%)x=0 ?=sەsYFEOHz\/4IY8L+jO/'X%a(KaDQ֟/tّx% ]j0%`k>] ,l #׭9#mnP=,4nLf*Z*HZRф8wۀڇ~ a )y8]hBhG2 ' չSSD7x[o[ē!+Z3nk^u5Ɉ+ѽ Cr?T8"T,^=cKR^Y.r)|u}'}PT.RIuV2 *:}6{yHv-8c7gЏBw<-=φTue^8ޱk(|[X>:qٍ<{Tg;XZTʼA:5˶DV9!3`%|l1r&D~zeh-_wՇ >0C4-k_ї|>{se<:O!OM^(Ӝ獐N+ ] P7 ؆XTHɹR{;ȥtY1ńՇMZ%?+ʣR:lOd Y=XLM^H e|<ʡڲ9ĤNyJt[VIT {&IwkW$c|+ }iMu6syk7:q$8%*e1܊dlyY4Όu/ѢD{#jOOm|>=:NQUbJ&m`!ߞLÿ0zFB3@~9UcCDRwۅ٥|'NN4Hi J틎U&Pޤ!ƮLuK1d N4B#'hYފkwr'|*ilEs?k 9i31#g7:XM%1 V?7suU}g1-a<ÀǠO7nuY%vݦi".n 3@HKGƐ־o$, 詅)cي̌*I L1J܂H#VPk/poi=o<齯ߺh<}Sw*g *+~r=3W;’JG??%+OP8IHes|q*خwɓ7ondyMNhaaxlHoR+VI287Fjʋ?MM]M8̿*%g@xL_:lxk]i>nYet~X(/6BttBkuף1pƷg8A6GD/r~/#͂*3QR쓝3J4 lrA1^Gӛx%~% %(VA&bee:šGR4R+OjYZ99Oh֟CS'-(| 't {uTS7r-Nezк;kZr^E hf1r`]Q: Y ѳCW{}U:BQ~m̚CjM:A8 y^HkH4\8LdI"3xQzBN%>D6~.$?QfU5!└"킃r(S}{ޅ{R>_LkmFwٕJvj!ѪRV'vBl*  `TO6ʆm&T,!88,l|X[xqbpL35hS TpG].q]zB Fڶhrj;{Аm@itlvdGϯܤO,"~~% "&=`un9X#uϋmHmp p:}S^ =n2S\pˌEH؂6jE)0iUt$/e&x[yk uM%_lR;pjHR 'cĝw" N l:枡TܜҔ"L'㦞P3J[-aJ D$L_ȘGHτbq|/l٩sbX!4IhlQ@|_3&}f խ[߁zB&kn}x2i;Ka߱Ə;kcggN]}=d\砷֑>FOj&L| G))Re'}IRh? `)U&@Bf<~vٳ| XM;. ,5Hh,M>,JQvXT3mHc&ui>$Ę*;[%V:t4m}>sI:PJy䚋AtELiأ n<=4{YH3:&ރl骾K 3} Pc1bH}&C^qR2ɫ}qT^=W<5Dgg8ݹlip p[:x3>ôÂPho|I?`b[lx͂rҘ;Y})[V@&<4uZ}Y,NySJ{4rs]HǏ_-~M0&B/N3/0Vx-qڋ*n9 yb/ؤ\=J8Օw9V%vs>0`ߜ|־߶gs(&,(5c9Wikj} 5TTdUJ}W)+b@cq&y_*v8 31dHt7 ~R?g_|^4r#.xpL\#$d.wx&_jl qtOIRz }|}Z Dt⬧Ĉ%LuA1,ԛTQV&0 =9}-WSl{9 j}( Z(:+ȋ{^dǞ1P4=ѐ1,!>^Ra@ȏ-z>;O[…%&Pc,;: u١NRʊQ I3XE6sޟuf*FwJu?k QjΧtygI]*@|Y'MVZ*FZvO҇;F2,ԤF9 Ӹ{0}7i&:.eBO?*Ah<*Z)kb  gfY9^++? uT^ x9œ?xY@ *~^{~$8`^D '33츪fuҲ5vϠNZ:ƩRGq(\E@WN]}zHHyBrI! |@ecĽ&#<4)NkHvv"savloUˡNgcO{G1.|ER'[19n'Z> ؞*Y h֞W^8tJjrytv˝4YQ_p=1VE)L auvUCRwB73XUQbY3_`u|X3]9:͛rkkb)PE͡(+fYFۊ:XJa~[ܿ5rZ%F_"`ܚǾ1j5Be4Av+PFUwPҔyKԕ.rkf9?<#m'T7>#Cxz!(;Q^PPkRcxD8}=9h&nIb3uE{-qPJNA/jOXwUa<YP»5kGeeD/@ѝ~OmyIDîsjfJZvq "dLE .$ϠOO*N$N_t\ 4i;;¥4>>*TC|$>L}2sv@k g,-dXGOdp/ g5fP=>W9*&(RPs[M0 9gan[Ic=ՠW]BqH7S Y669Gj Y:<RVȺw`$^Q3<ùXDz?2 ĦB36G5! ̪~oړٍ325+uDC^3㶪((L†\uO k(`Y8u\4̌%45]xWB͈ςK ȒkۻAW :l%WÐ!fVZУ5ö!dB|Q.۱@7#Ѓ 6+GƻeB*~%[bE078)6ĚNL::߲w9ھ2PK6,")U~/koTMBRra]=O=.#ƿ(/Wx}>S)@t+bPŝ޶:'k$o"Lk?oz";.Kaas-0:?-0DaIDtJ=[6k!#дo~F݊VqAlp嚵({MYNeյgݯs3#N^V|AH=(sg|sa&E㼵8S߃JGBo'/T)kkxs?]uA;T)G3Re,ñOXRX^vu_krœs_RfsT] }eKki؂w kz=3*a|#er1؊aIG ZȺ2wī$,fm8 7 `}Q6 ^_%E]\!dEwe'BFRNz}tMVt>":Q(xi$8Z d NTJIb'؋=^RD0ܓ&6;jWE.iC DqB\wt\T]PI 5e]c]fl!)spEQԬS2\=deiKs3Q\[SV 0Ywok2%mr`^lE1$6)7l,˛-' dYrW+c=]*`&Ҍ;Q&]$]@-MINmsJT) MD0I'sx0j_N5מT+@|eDkSy'4 i%K-\}UaY ?%0ulMIܿ5j8Tedp-$>cQHڏr&3(-8?jT.}ET+6U}YƋnޝgt9Cv>;q^/h[oT;H(k.N2Q?o[gmxJc)Tl ^-#?0BR`*Yf$ @!Ob-huO8UxpWq8qzz_ӛ:TIGЌC1i/,M09T3**!+}*^t؝aM)bZv?gkGl` 0tMXՌ&bm{c]K+&v_'=glK<.0<ڡJ%a3.*j0GɉͳYWdQ뼊ňְut-Zߊ]ꢍ?VzyHuuQItC W4Pl+]:w{ úc[G~+CgM:'qW"Sꄹhl6BD (]DVU?u8r1RQm)vNNĤQ(ZATxW_TM D%=MHɪ2xdJ" ]Je.1<}3.K23NAnjPɄN{gg[>ᣜB9?mڮt8pJdxs 4}11^6deB9%D?y~F3A8f%ప^1RX06m*LIONft ޾">"f^sD7]VG&e1PHW%·\K y}S:Ce?vUxjH6DY)ot׿>y";jtkÙS<$SDMxFS>ؚ!}h&`}ZPLql`+oLzDgԳa֋[#SI13(3 n2CQJAghhW.+ia?3 ^ˣiZެYD|v/qw΄蟎u7jek?a$.`鰀ʳ ,'pnad[ iX1av"p=V2^+mĮ`?.;Vw:'}~NΖG)eHQcDfUaNdGb8g -_<nq(3h:4ǰ-c ~[m_mLƈ/(&I"5zWWϹE:vo~M×:y$M@.?SRڠylU&y)#rgUuVIKߔ?`mmf*Wu?}Gף$Bl! d_?~XBD45,TW}hbsgM/dVT?9 ns[ g-2fD7'B4ͨ- 7si7%9뾐!I([nixTpja`4{w&Hh4 ܳAsg>a!*I{pS(@=if7NdַE'DG;̶K\7yh#>~Mm /}JV<ݝyΫViAX5Z 1c.ZRns@P B|96yUs/ rsgᳩJ fRzZ|4KfNMsJzRzEqSfkZ~ ̳PԧZTMxoJ nNU+uy kfr{F _?ƪѡ *(j aS)(?% ^w&4#;?ɷ<{;][a ҝl6f"F3UhO~[T`*0k҃+yB -4*tbZc<8 C.R0HlfsW"ш<{K;X 2L?; [7qIHq lVGp2O#nE*`4^0˚wO3o@󥟁 ݿ, 6h:󱚄 [.^4j˅&V @Q;I+yz~}rd /3q3#>]˓N`1OMv|;k 7ht83OhN 8s{+z6'a#BL*P@qA:z-^pꝏ IfL +g䗧4xa[{Myͨ͊rk=G';X ʥ̚uXF ^{0:eDs*H XB._N qS䪿0nnzF3&"5[W}%*gU4:*IIF|&]**ly+a@w{̳'jD$ӝwD#} 4'?]1VlaCU}/`KCDo02_SqS=[v)/\zbʓ̰dus3c>Πd@%v'L, excO^onY1((<L7Kr7]GŌ/J6wτg&7I5B^~r ^mܢ+u8-jiAX'#"p*5 =0b eʢDF)`ݫDcnKsѲIy[>߰/(D.;C5"fH!JDMxbAL]Jf4yـlP _,yr\aڛ J Mޗw:{8w&/6|܋Bg(4Qd>h_Kz F+wcއ[Z\E ;d#.qfsu==3s;!s}v7wgzہީ6g-]O߫6=>w#'h7v`o zawҷw@Lj`nGo jhXK-iobPG;"S f=#C̘vv+x k :h/kT44"`1c⮏ÝiֹpS b?C))حrm#R UK^!3Uc΅?ѬƆ84pq`[B ׳2Z/(ǔ(MC_|UpBLufY3>$"ڸA4.0=m -@%BsjfUUDVX/51+)<ʄ)Nyh$,ZϦֶbrO* [瞃~E\5ZKP@5d럎a%#yvoeC v oA =#5X#SHYk+QraSfn[#7~@gXFゅ g)jhsOh.-vG!#YM(%l] ,1t[f{F/:,` F!t#+2ԺTy5iv7{MGڊ ^WB Qdzn;ߘB uǷ9_w_hRmsvM$vJ:2u:-*p+y1Zv(^[0)W`s4Q$E6X՟osaO*?t$Zj*{%͂dOuo*(ĥ# qwlUuX ctu Ol"4M@ Ӧ734l [R#PnnSY 6<_#JJ$qc  wd|Q>g'd~)5ƐYv H3{.7& ]GY:XmY ݲޮc~#0XxiV7ђC=X#E/ߒlR+JNVȹ2\;ҟ o]/ IbŊ_FQ}L"6LՙpJL%G`)˖ZGfF<DT1ޣ5belލiL#Dq0nc|rN'Vͱ 6dwoIޜ \V*.cgř@+U}Mx;p.c[ʆzo&1BZfQg2wʹ^їOQ6CjiG3SY>:ƧAeyJ<*QcW- V=H|..}d:6Eq hLi5k: {vڙA,ա6n *vw k|x8l _tq^DF=qxSPߌ'RE^3>+dد<}yIp*5gT%$E/27 ri /W5 {@[8 },ho]H5CfWl&鞱) 2f(J5379 `4 `\mn"DIG JPC9^?au;mYt7ebϦl(I8>]G#R#L#ݹg$9mᱧ>ZEwy yxLސ GWDMO 9 4U$)2Hw= 襖Α5ٽUY߄]M%K aR7^86qmG7"(a.n?bxd11'Sģo&(Vb1V>kϞa V4l±\]b]RrՕQpddo͊vgo?K^ #~Ki4*=gd+1EQE٦x2Y2 >w IZP ^,Y$U'ϲX˲ueE+kvǟbOǤt\}٘R_/ވ3\ 1R Hq][>,|6OiT4~Q'v͝!V ':x(&+BtF~wxN!7T<;]ni eWKFB 2ĜN.A2^vYend9=_b2M\[Z%fS&OttS9JֆrTF BbcTAG/!zN7B$VF_ɝMNj10100xsD<B%Y</lcIsSRJ[^&Id2Wt7}B:ɱoUD60KbF.w? _w욓hY 3ʼ4yi- lFIJzC"ļ?i<GKzr0힐(uvPq!-vk6\Lf ȟ8RyVԱ礸SrہMp8]tQU`_$OEn!ȬJouG0Y c뿓_͹3 tuC rq uMh<ɽ{4)[難zPH[?3 K@'ۣ>W)yx&kXP _ukJVſ jaiBp[.9w Bt#LڿaӔ$zi]hg*"6A}c6Ls N࿍t*g.bJAM%G=@jH'_Q5jmk;jSzܦ^x-U3-Mmп=uiP;{?"Ozvhݍp{HGӂ-T +tw,o#'mJStkiyו&i-05rbN)6Kv~UV?0 V5/*%[[uɶ,h+}xNBwX] m0^j^1qIϥtE.MpP&L9,s`Q#50n@V4+ha]ݭϴ+b5dn^mjOL+W̰w46;h4>H|1Oi ȣ:rnzW\=zHOZ]5Tj9I*;')+:2 hxQuƹ 7}o:m.8)mR͜K؎=d ݕ`DxwZ*GK` *T" 4*ȗhŧCD`yu[7Q#2'n9/ HF=We碌=1d'IV*GbU}%Ih5'Sf- %Ǯ@̆Yaa0Q$zw١#PaK(;M70f+?uK0󓟈ޗZB%i߭/k}KF$_9HȑilO%uh#8dM ѫ6R](C۬8m*NFd+Z+r5\RKW?z#Skk7~q-]i lqMKDsw3cPa 㶪C'pc[_kſEBd$ jcJ#e+BղY%c/Z"=|!˵7UE!/.m:S֦ps_荁IB1XKn(9}.ź_w QKRמB%D}X%fqV&Nm|y^f='Lzb0ַ1)/z'/M 1G!EFGR(:IJ8sW?l)_猪`d^qg~bu;L7rEׂ<>V615_ ߐ3S(ƎO" &䀌mumYg)b69^ڼDSP8.,id#b s.I9 4}[I%%fҳ;9f&ljҴRtKm=2FYe0Ϲ^ U#EШQiXJsEVɔP RfϚN;U:mpwYt:aķ&'x]WKk_kfd4f`{`#~@=T0洫Kߊ)F@"\g]p}Ēlvq|Yڝ"E.{ &%bj?ϫչ4ҨC osfY*63um^C$yzyЫWXdgq?IsVyDlpKYQ R| oq?)]%LINh8k(Kdnѧ$!r>2x"d?2d\QuDg64]w")dᥚMp۳FHg;nAOH}t`r& zԴN5Qw腙5yO l,ak+K>mӗ,%rPK%ާKG>wB1,)n& 9|&' h^ys}z6ʸ}m+| :|Jg5} ϳquʇzm Fq50. 3S xCYܔidY+vB~ϟ]ҩ]ŧ >`I#&mUTK\*//IiQқWp " gv ˧e.W;P#3<%-RRzܔ$lh(ױ>%g:^[txӗ0ջUڥf#"1sJC{0F /1?ԕ1fC^fi?xf~CM?tء5Ǎkdq|H~Ј%(c6U aӰ<"Qڷ ",i鲶Փ;۵cpo,pv!="; ig߈ety(X>S; T\q]q1bf,f{D$u-1)<`0QDD/\.1TyɅ70i fRe@L: xPF]fc5 54%)P.,2j7'V-o0u-U3Slϭr ӂ))(p:$>zE>Yr+la9"9ĖiMm´pNDz{ifC@- l}J2XZd \x' ^66Tm.z?ٗasaOz[!~i򚬼Fn__t``vi}:W&BxM'mp2K:+H0{ҹ 7űv~Jzt:Pf2DtV$߽}ke3o>HCɁ ܿ~(c4V7(w>n 3dOeuMnOi'k$6L.|C2c2O(ǃJE5&7 Lѷb va#ti:g1~UOT=Xm*oZ~An٧8v}Gk;>듺%9E 8kHpp0~d鸃u!aD\Vêt(M1W} 9e‚!F`tx)жۃߏ 9eDqܚ 7>DD>?A!WMs.p*<];(゚"pko0n ҁLSWy%7* 3|wJXFwf8"-ItC0N?Ih_Z #1:O4̄Ӈ,WcݭIq I~GŰjۣQ'=)U HúgF[ޛ~Mq~|}LmoiB57/L͛r'NTY~&lGqbgoO~M/fϦِ9Z@Jq;B$Z_i& -PzN[G-ު`Ηmv* ܿ^Z1rCg !x'5!;8?7<H9 7Q'*;!'K?]8oj!.> W7K8226⣴!?e}kJ=8l"SlIăAvO0DTJx6/IMՏn=9D <7uT(%έsLd0,kRT .u#RPqF_)K &ୄdr1O]? J8>L6gג#Rá"NO#aWܚQE~7|۲:qTC1h Vِ~G$2}eQXPϯ+V Nͻ|$ K`@L4ο09|)~[2 < 5*Ҏ z"Gw4Du0Y M.:4{X9ijaJ!;#|[ kb`)ݢ Z$H6#i:QoɂۢYeJ#^˼UzB -)P0P$_6]iMn|uQه%#{\{ͯ~XYIޑ|wTEOOƺʦk܁J2[[FjeYI˻Z,+nڧ_ x != Z̞aVV&j2Ժ7lqqtLu,gB)ָ0kzBda52Ym܍ |TC0֒ #]6YYCڕPD_B} w2+,yXLЖ>8qe9VZo7_m5"S|}`@\ ݀!Prre₸W`>smф^GD劚zMȊ_(U}4.Obz -wEխ79K6eTgcXJEI˘K2 H$+*p䡖 ޵ SSr74.ZٷYgNC@Ȏu͛tŀ{ MuaeyqiKvj O_᷹-ӿ~2`sg'Ps-ɕMTY &y! vF=M:XFÙG6usp3x|ЮZ(T^5+Tѭ鹲I-}_"}M4{yoPiʄ ^X֟f+3)6ZI4X C~0w򐑶 QY/C;=݊%"ѩE8 {1c2AJUiTKׂI:Ԯb0Ξ#q4ht[ϞLi蛠Zu{P ݘ+]F+n0SdsW}9ioRdjIǜ}yAm*VĔvVP`jt%Mzk_q0ٓ eoWo38պ>)gn ";,cPZ,(갎^ ~T鑳`7UPNvDX IwPBO˳+ )^jy NGLp$B)tў/m@aܐq"i)֡_"!J* z=âk1dX鮎uɓVFޤN' BJ=jdzeXoaNL&m`%.t)a)iAMqg)L_iI]7!xĘCu'X=TYd8yܵ$z~4,gRk-vה>Y~[Y #CjR-h``݆Hf?^t5_߹@}tҼT[h!q [hb(&I*sf4zPV(t7[s~@p}wX >OtON/0 f=UK? -A13?#&I:OM@pu%[O !ƟX 2$[moe..oSpbh P x(S Ӱg!6=y킷Z-iٯ^;*bwBXķw3j@U:+Ṟ;jMf`mY91YAhAGeM1ƋqJ"UtD~_2h/?;;ilWF-,_H!_y񪗩'6[UF96䏒0{جGSg<B_kz~hPO>%3߳߱]l9e!y4QY"DL$C< C|vKC''hZl|{g> lMXqc41;-F-00Bf0>-a1>>k?UU GQnn[VYl3Sq|`)If4]ޅp# pesI^uGF{\hXG;Xv庇T;xo5F,X45KRSCKH|Q4,M=?ø؜ \@ I沲KvbvJ>' tW)6[ӷ҃Af>+8߂IА/%dw&lC8鈙Q;Dzf‚)>9<̓ŸĜ綂BJMKÍ0m4-o6FF3uǛiҋ{dmVc¤@L2H_`->I?|m'ˍEEb-|vaۛ֒кy LQr&chÂժg>݋XG+- t02%G&ӋE@ ϕJ-녉V33wWLMIi h˷0Q^EjW4oEjعҝC4x@dW82;/r0&:"q(d P*`p&eɊT4\ +4 v<"B]9w+,J(g"jNQ/yhģajMVōʦg',‚eyt| 2 +578+n'%"* ; 3U^zr\4<[?}E?dkk1n *ZE:l}N?~y ڣG 2RUs%T.:2"s2;ߛ0OKy['kJkItNZ;SinFKgdJewc2dc3qʂ}C}? bW~2;N$*7)N PgڕaSi/K=VUϝDu a6Y.\yuen5#Sܚt5m{ThG { ,G|˶q;'#|бa]vg^N CX'Vx˾Uu\`ZNդ)Fet]?a5̮RfJ8 }IP70y٠( (np I 6W"MZd@)1}xɒ~y_2wJ*'8,J 㥵Jo@f2S}tWf:ӚuTSH@ Pz&TK]wilC{nUA|6 xkhM(؊#oU5l5;E*m,p!{1(*yf&qvrv;3(tq-]݉=/>\s2LH9' VmFP"!kl !^1 ܯZ*/7v޽'Cx'÷BOdŎ.ƛ;C}5 /aa<,|P_7+E;:0brB`6.Eα\ *5I9 XY,@N/I\SzăF'M@zJbA-Z2Mx񧭕$q?E!2]r1[Ӊ&.PR&A`eD*67F4}AnUe75WW6hWxARF"bopWl 䰁BQ9Itաkf32cܴWRoXJ-dl1햿fZ]+E ǃe]ĪmI###C=}YvDr޷e^I峳O7OJ_s>W|QFVnFs61eb֧(Ҝlf92C@y ;iD qKaYd~bI@0 ;m:L4/d_@0K;+N.j:Bͪ YPGwAԯ! ΂S hE}0ݓU\@z'AAeD5k߰EqZkVUpe3@Жڌir^sh e‚': 4nAp0\D%NIpkWQD )z, ]č%Ôc $Zi_RaX+^DI|Kr]WC9"BrzB.5Rl4lh437I*5*~Օ5<)ԚʧfvY Ͽ$1sSmG'&P/OPDyۓµ;#| ӥ2X9s,'fy^+.(L/sӘvqK O pPchRI)e=&RŜZn&*ĝE5];qZÌĻ?߸jν`|S9+)yݢ-'~a6^"oXR J|d|O;?Gu5ׯ=u/Dh^?Q>Wv%>9ZxFxM{ Xw`Hɂ&X6ҩqї 5A(+*v(,[w-m) nż}Os%f=a'WsY7vl|Yk4+!ѹ#lQxҁsiuMVʆ^$cu&aA<))kz&-]ޘYn4v7"TK,s~F;yk:O*D_N`@J |f<*Qz{}j  &G+L6`lzCSy!}K#}Cbp;S:kl2Y݂A+k(%,яSzP\GqO?ߕ8rs]c) ҋuL{buUUjm&J짢 <.[qur  T/*R>H1|@1IHSH&OMܟhF+cR,(%ŢA*҅66m.Bf[_˳2,padƇs3).\Vv0*m?jn և# f;z2y(JtUb=D^Z=;S VMD՛=y8dp(c!W9QMp0^A- 9ʈsv #NV;j1tc5jM.읥Yp=a34 υ~Ĉx jͿvFUNߟA^oHƑJgJc/.u ! ~QFx;k5֤.S1c+ !?R(mM+A,]MM!z9JhbRF9LV,}J5xa -RJCſhjFO)z!yVoF\8K= 6g,<|Yյ :(d9 l;]-*B2|hO`8- 2.IRc6!8lagE iPklXմQ4b/h8`¯Wᥕb͛̔%RvWăG YAny.Q/iޜDck7sSĞ%jiSB{0Ù̏Ut?>@tSPFP,}e h1ZTY2^/d! Dw_ԐGTī|gMkBMt==I|f29j6pL4VuD_Cf\@AFS8{ZMPdo i˘\󻭌akL;T9Vby>vwp;]`@J6Zg:4aQS{~Hy{@^;Hà^a |tK5W݂?r +Y!HR#iP,H6 J7Z>t ~Z6qDz^Jj9Sa\x/=_y{N-l&ey KׁšjP&֭=hػ];Oxڙz֚̐XeUBy =rBtA B,D}ǼBt}mY+SrR'FSֳ/%`0(MOr-SKZ^@QkLj"iyy`x@W2w=61~g$>v~L=(ݵ1E5v]Y2\p^TxcG`a#)'m~ôirJ)'ÅR1H5C(8EU[I'rۯt :~@vI;fDM&LkEPWOcNHxu`qܹ/`PkI3ڍaV044ᘝ,YA[9mg[j+n&'xƤ.F2y]6x.mU): R/OΟ(q3ίUv#qh󦸈vO7cQM.Nʾgn:/ud_ds6۵4Tѓ?pO{_/%Ŭٕi8lݜ}&@KEe99Y]SOx k6Ena a:8U⺟YMFt'r[&UZ,@ٓYpchK+9gT']̸|evJnIi#TnQ7k ^&j{sgZMJEtK[TcWG?QCY3J7 !a~mֿڳ8걟OŦwPMQ=vusPBy'2h}y+XiMxwSXߞf2&-jRȔ% %E_iP1Qk0q&N-$Xy:W4SuEN}dx$ {aЛ!H]pCJ,\3 m {%{<]4XbeN{:%v2>XH_.ly){eLc;7O [6-sZc0j/ȧi9Qio&7-If[c@,*8rZc[C퍡2ЋFH/`w9W48qاhW:b줯K:?a9.cRUe9X+=p/L^(C+M_-1՞v| k/%UHr/a^DC9aBRaP9GcfC)͡M|<z\ChJ7A)BcUyD%;-%p u_=I+(Hw5;БslHQ{T80|,~xU>@W)2 VL=$5A.#%?Df:"3~ |{ĺx PhPԝ&|4{ΥӒ*ҧSe*F*0Bb-.ELi}}~l8J05W"^^^r}뱸;7KjM{&;gGR떈ּ(1}ܕQI&Ecxz,Ak_p5zo֩ʕQȅsF@"a?ˈ݇1WeژR>,K9iU KvbFKmd,`#нqMkM5wZV` L3fɆ6obbU3MTW?ï$MlP\lrzXLcC?a.?ݼ GƁoNgNй:\UAG p ;CSO G?wꗮ\zr l_G0ޗtϹzgY&};t rQ4 }vK&ԓY_چq=AkG_yV1DY2°uz|N:Y8ovh=%)ڈ!'MZyI*dOM?>/Ɲ+C:) <bi<%˭ȯMst Waw{.cD(uS?4wJp{-|pu E6iQ_--TAx.ҐУ7ib:5S.oW<Igmf'›w%(!E(1L vǺĘE+Wʍ~$QEd|64ʗD'̝iyec0V͍6׬i/3N}(3/]]]z?Gմ\VV ʦyD!Lc>oYc'ssu;>d䔤 @zEObKT|[=}|{Z6A+Q8g2th9?5[P1QlI?#v9cQSIȏa!=wI}cܘ^/ 0 æx-DD7 A 3mq*U&`JLc֢&gJf&_d4M|f,d{YKG^ҙ|8)d5bWyհ–$th^B |W1Қ'+fĐ!;{3L.xs䶽hڛJT$4ٛ<]>,Xw\ 4$ATm++CYyzH' v[3xل_ '|v$o'*h|Q 񸳮w|#|KTbo;\!IĬkݫ pAAcK`Ved-ccoz)$x,ׁ`S+@Y`3`em1 y8 &d<6x|@ Uk1c!FC?|̧;fK esKb(7DeE-F"e@&_ipcd]frm*Uҫ(f /N&2{&| ]j5'm!ʊNr~TK76DtNXI@m ]THnϐ=N}L Ux7KN\'tui\:J9uyU i oL1)oV6|[>oaKhjVWU;%9GޥΓCcȻSZj; lhϞގ7I(n_P9J|˜G<8YOFk(^om?)k4bVIVJ {JGС(]hQsäT_(,=1PdoGv{j֒sұQ6+ۅLc}:pu|SPؓ$|3%4gڧI}d 8ݣn,rƾ>ʹ]1lZS,# H|rj#6$NQ|Bvotƚ`a@Z S?JnV-f6׍R3Re<EhI'AݙSPj)IC/1ԕE=wtBdEAc¥B+yHmVT|Ġ?QiHbo'^sT&yDUg7V0{5 @1ojEsmEg̐ȩda#V~{yQ,oN*y/l m]Ab0ӥ~4ʳTmָ ]Ϟ^=ū$) ic̴A4Ή FyNWlF6X6.K\o^J.0[ׇ>k7̓]|l`t,90^ĉ~7|0օGҐX^9Q4Ec%$鉲g2"NXpGKdCqɗ -ϋ3+`UxU`K"4BpQVUv[>57^53F)SR9YjV H@iZud8f/8d1j(Oh"kV|ߝb+kG]9JJʟzozmo//`2NWx[8>1JMV%GPSqH׸ #td+}R}mw9k WYB7`7TvrCKmVgŬsf.xn(WHPT9WM9 0ywfkb yn:xmfxĨ[g^j V)Ю21A=3aAQpy9I[~&h-N==zn DX$-{2/|Δ YW:Z,: D'G~*ٲC:ю kV+R~$D8}gԏ ÉqvEYHm;y$KQ!2.m@&d.R#32+=0 \NK$0/ ܫ!XDmsh^d|Oʘ|*95}y~x:bnX2})Ĉ2Ц;uq|ƮdmtgiSibDgQ0<Ί<\~7dJ +o‹ܧgeq s85Ks\KuGa$e^:/UH|bU R]M^,=YHV6!)31qg r &ɥK)ԝ ?إ**xM@Ѫ/q} ^)t BLj_~+F29wn1ֽ n7z>vS9!kb~:ݮ mG4v ' UrO5;H$|S ,M?b6P7=ޕ8v䃜 ڽfLWFn,JXclꙠf_x>Jss8)jѹW(:J~c5]Zƞ=J&@QYk]W`#Y%{E F3@:hd3}J}<|to𧟙ɽA#tJ5̈́F)q[~ 5ٔ.5^ E*$NԜj>F6cykdG9qNkR,\{7|L=9T6GWFВ Ul=vщpH0Oy,XuFMy5f|unk$BJ,nI 2[3RxDcwwG@Tcs$11&d#&܍o9$}5=/+J.Z}|fGB*me*Ȭi\6V z O8CƝ ps"w\b ";J~R.}d]8&?q'CJʋAvF =W,ړս [XWʂHVUͳf!hQȨըsygJG|NIq+[U˯MOb гZqUghƱ[oM]i転m8bI"T M*T:{d뇊uA4/ u~Fsʹm_Y>vɢ~i'ʦ;e1DELBu}g ;Xi2ۘ8{FpW|$MCWa K͋>rϻMhh(dmzݒ6o!]VshN,bѐqk ^x5ڰo{  xCߟM,HWyx'Z\):w9{u*Wj4ݭ lYO͒wh GjiTJ5ķ\'0qd ".?*}EmV713)=}PSBܳ^eICvnpcBaG&~ I54y^݀  R[+sO"$j)'~H_'9RrhC44#9C{{p;/ŝ}&:yf71Kc-%6kJT̖ڻvd^׌\2~(Fz.G/:3Gl˺${]J|u-w"Ҋ#ᔟ<>X%8mq }X5ўWdϰ CDTAMj| -"qDhi&5neIS5#V9gwǛx{T7U`IyۣF);9󪚑pc\gٮEggU5;weEP~jڇψ*(EhD@lh ]yFLɊGӁr.Za!yёVG:! B~pcS9K%!3IyOV z!Fʬ8tM-MY\3!5]<|E"8F)PVMpsE.I z&fBI:>)l)J) ;8a HT]vw.77aOelgm:00k|* I8aטzi NeQ#Ci)*uzcee2#F'.)r-Z{!!kμv@x %(xއA֛> s ɻ(OjB}$c8d8PȖ 8E=oc7DJt1B2d&C,<́{a,oMTG[]|"T e]'B9gu!lg:gl|R.V1ïxZ6ffM*@̝ӖX+?`Z=QZ5_2Ka=`)q֣cPȯYS-,tx%e;/8ج./kQD0ȩធ0R{Yˆ&.3j%5Y}?nHic[iIH:ƅJQ}J\}WE˘Qе)MD&5> Q݈WݶZϨ{02N}#KWXCѢ ^(T{8D8`=B{-poO דUITu`2jm]OqQ'YuF:4lʯgبc!ȶE9zˤZYFZv>y Һm1\!*GB6I<6ԑ_^Z/e\5I2C>+=-ZrwAa.]?[5E/a@$9îgX5j^u(*fϝaEKUKPPuwAl%f-ָL}.k0Ssj1$wjƕL]&ϼzs٥FcIx 9Vo*^|9'}eCݶ1e&OP/9wm9GbiOGGSث>1%h2{?}ʋ6?5 ]9ߞ'ox$&ՀΊ~8vS&nxa QU݋VرaSov^Ir>3`e64DN5aHVq]'fӯFr_T`Vs3OI:9s 7&.9V̏P! Sa[r6 #.M Z`Aw+.s'ތ; ͆zǟaT h =/ouUnT",aUBZF9YDT*ϡVf <17Օ)Y /Is#̈́2 *4b;!EA)p7 XH*vشR;.GX̿lUx=* O6 ;>%-"uw#<5͘Zz=K֍?:դP:<$;DjBgfu$iJo 6ΗLϢ7yl8)y"FO^S ct@CWz6dQ]_r-?Ie[.J*-X(d?j+q `e =5(O)ɛ'RGCĘ-1[uAg.Z߁|$;mhk7}`.ZKay//-Ŕ(IXV9a4D?*u U}o%%ӭy}Ȟ.o8oJtdSGRe^. Gn' v)'-B|=Sӌ>b1zZ|F:SH%z}Z G;iiT$LDY4,^*>{`Sw1'mEz0t&[UD6STvRpiR6MU(Lh6Fh Fi _7gX\AJ6fd7"|GN6禅:pUTө ;-t$Fڇ*Y47YuM cZ kc|;~+[bk?5)`[Cɾfij"k5l㲕dwR ̌fCN5N++<|d>P5΄:cI)̝h5;Xl!0҄VDD07'H2+B`%Z{-x7s:54&F/hB{ו76T>j'8݌3vV^8J~ӯV}ʀPq`2PW3k@.Œ/")FjIօΗ#$NA7R9.aؐ7 y"7l@YUc ʴ Mѥ j*@AgW&:\ѣc"4X-~;E͓w6F +Z$o> FlB+,Y-ppj1qW,Isr&Ƴ%RAN;eJ(0me= 8lyV߀gbS/RwR>ҮlZuI#8+%M=1nMzg`=kt(ik«\9C"3gW&'BoS`r`ɿĀrڒ_NF|ĽZ8i~LxI" {܊X}޷Z)4z&+9=c:0r( f)d$IZ$k@ mPG. [ϖGl?ltC̄3fD pZb 4CFynF]a=8\/VœWeBh2}=qFݸ!#ķXL*`DW.&D6%G|MQP9N+m"8s|` ̔z#]<4ۀ5 z7ѨGٴKMQѦ\-׏ڻ zHjsAkmͷV݉/!hgo=s^Ťnʀ0@5a5n'-o=ut w%\( k.~*! tFh<3%m_G [O 0JnnLWƚ殑#NS|9(gFE=- VZRsir^R Hr>նU#*PWi!cJ!6 ֖nIjp;%L)h\O vSWC"}17Q][Z㪎Jv:ؙ6%[}7祋F#)DEyd\)fKFz. il ׷ѽEenA1BQ=caKTSISeW+k)|"DڮƅF +^2 Sj8>nK1NE1SUG/ @We`dWX|9!$<˖o/t,%qO(X]He_+}-ľ;>iUs]$>l.lECY#EL+ w&1 1AwwJm?(m^mFS{b|nOl%{'ѧ̄%k45K=uhTp\XP[Pv&K閪7E *o:)؝h8Qm(A1oqR5nx @Ä`]EEx)$ mzﻣ !ɡb-JV$"^l"I+t됞m7n$%[LsJ6= /E^ʈ=R_,~{UrJ°J[ko?~D騽$&nuF8?3J4RQ̇gY왖(ԚjjseEXW.7[O$NIfMﱥ҃"j  ݆̂J-QeJIU|o l狋Oz <f(:3<gɭgKgz Sk"yta}CoJ LW*JSf 3% wР1>3oJ/z g pނV;oab-պֶ ~ wrq͞zHZۤZ[*@XCзqҍMP,qꦈ7eդ$An㢨`ʇkI 4]AEõ* ^zn&pmšO[u b[!UၜFn ;$Qzϭ~ʛz)kxɢIUXٮc>$8z׵w@5- ]rW.ƶR_qމ1SX_r5`%mgl+6"O 'V(l[5x~6ܯ䥨φؑN3Ǐ"S7T)n&6?Y㮊bg0mt@[upg0Ȯ`p_]lań389~k~CrOܜoŸޙk^R6%f8~)+Cz=nyypvlܿīwM%Ν9$*0 l=3^MjD (Ѱ$;R$އ9>-CתW0܎ǿnd`U?Sk4ҊJ_1I))VN1zIsLo^lgb +:;D.0؟ Ui1bz*fUKgtb.yVM-q]>y) SYaYܚCbS ug$0FȂi,?$<Ѩ&1oHԊ6hCض]>]+~`h2m2wXzymvVqQ3קTkmH~>ùU}[-tIBs D5$q;@qȭ;jN̋;Yj"/vͩ{qNtVɏz51)VWh]~?5e)(A(q+QIi]ŃX4l#_L7;*|j鐸jDŸs@9*LBucH:w eu`:BCo#;E`kNĢ3*s[++;pgGnaL?\ 4J|6=UN πwHyp"a+̬ypfKڼ}ÆlKq{-Mq`uu2WB꽴?*,aU}ؗng:c\;(eN 韪ᵘmǼ;l&=BwRu;PxQ6j|p+W]/8#nҤZ4TBhM2p xL0=\tt0-IhcvDHH[i[S{7.T(qfqI,b3 2ŝDdͅ$-=Lc&y~2ӱF~4Ƣ^z3Z!G׀S8h ɧGDȆz dV̤54PS"}*G%<Q#zZ? Z\)<.K[{{êo0-7qQѨ*jm)vנt =7֩nFgx =Cb}hǾ/n 4m%7;)ﳻ j8N{#Huhܱe~TEsfA(oY!<PܫP0;0Ǒf/Ghjj&{]WV惜>0ڻQ@)DɽBŰ hd3f޲oTN阰n9/ek^;#]~_eoR7'я|y敃_bޛ/=sfAVˍ m/a+KkZGYm P4 k,V>*xTmڌ24aԀ.E(y\Ͱ.}`J=P#Eޡ"f[յ 3=#&E= !7O|/Fa–J>|C!Row}lfK49ř|RJFѓE?q ">60SͪG*'yT1TyKWb'?p@ :im3Xpظ[,[8$D`]Y#Ѡrrbd[MA/Ol=O^}V:qiTe5DiN*:gAc)w 홂;=_^ DYg-]a9Sʼnc}sui7is!mP\aa]菌[٧)AWIa|glYxDs0E1Z&޼tx:|פz&>fR_Ĵ,s&';Ok5k{ϝQSPMJ8Ccrw3 G9o^Ūm"{Ůb‚RQ+Yv]}~Ys^1ER{GcG PlO,`[>Bs>e-l+ ?~U&]v1r#+N1`}#E\6]\Fɑ3'G۹#5RLϪqM̡!Na`UT#s޿HG8.FyM(gX WhJTUp˄5t@hGKKu.藧+AJ-N.S%j3Ok2J X!p Ky#BYkXq8d,W}Ml[:҄9@C5!)2GU{IMbR?۲7q.beh E~R6}]U{AE>\d[%ّsO{[&`D^ױf_/xjDzś44@ӫ6hC{EMq)IFWۄ.+8{,Y%s([:V<ͯRO8̑>d,'~ ps30ϧV'^Qa[+Gґ~"mq[tָTJ%9h*+&6\0W);bw cnk37o^iToh-矦f#qÛo!Fy eW?-4N?ovcXyq&ϱ 4 vu,7nH uJ#Iѫ9g){}a1 jw1?%S A#“* e[oAWn^_IE4hwɖp2a\ I.{eעs.Cs,'q cA[ +7 |'b]Ga\%A ;JbM#uz^zt4-REKi1![ 2PCS僂,-k177?1z[y?p\mbPa+j{.UҭVGG%orZbӱH1)\M+[XVN?t9mPZۜRN}+ M^Snwʲw?J]!0fgG~( }BRDeanZ <%7BҵgۚnAVU$FP036hȜI5ۏ j1wRظm#j>R:ʡCwKcK!85Jy,*m\ە%{*%]zFAOuk"E)gźviZl[okηOmPjO֩>ln}ׇK{HoLqxjo,> /ӃZwo88 (ǍGY9譇Xhc#/G =ɐPBD ~_STeWK_Xcl 7x' 'x nbpTcUO+8băuhl5ԃ*sշ A2ݹn} /zfHɟi*dn~؞czbj*UY Tr8GXqb2>:61#QU?tjgһɻ, X8u~-p!`,]4rpZVB*K,eVɞ=6&[6-ǡ !SɸNI:N}qBR 5jf*T1EJdr Vo)D,1D2b),־٫ ڎ kͩWM&u8晨 7_Q9ۚX&dEʉGp A@G=X~Vc?)wNɺVG Z!I֫ TW dVUE ՝U#pUBks86P=+`f$r"X=n\O/,v" Dlk:*RJjrFHdcCBuNk@RFS= #ָMnypz.h+A:Qil9u;E5MXtHQi>:oΕad bF.Yqv2'ʨu`"IlU-`Legj]*@Vw۫M!$O%MC=<}Bh Y?:jzg1ǔR痻;ו5]5؆쫇;'4b͂P0`{ckV>MJ4 8FCdaC]89c1GXIK2gUzT{R֐6u.姰IG:^D%}TbŢ[>z1"ôJxMwڪV׬#(91(q u7,Qpjv~=J-ƻhU ` :/NW^trmōu 5D+x\04lyexT>zE@3Oou6:~s k2ˊåuq8BХJ/"|2.hF7codn#)MF7hɔvd T/ŗngX:3XV}t~d}ůOq$Х gEA;ls{#:lÐ.Y.OP-06&<b6` Y].AP%ahX]\ksh8tbx29U&Źx _D \иp] y݄HV *MU&EeM u aup, egPc|nW%<*c괾zK"| _E<8SωA{O vsj2 9s[Ѽ_&egru]m%{Nf*M>bP Mm‹:ɆIu膦v) CXK!t[s2 G󰠗 "Oɳ F &YsYUtIyEs#%0f˰ٻ!FJl#،+- a+sg)p#pɳ9L_vAV^9vZ$*UMjcPlT5Cҍ׀bg"j Dbyפ+*wwf8ҧ. 3«)m\.c1BgMTE7ǎl`ϯU-QNi*d,299DL!+ ]h}sJ&L!1/2f;eֆ׈}Mu:lY Y;Mv؍! jLDgP }P>Ac'6nJZf!)Ạww?y}ċ5Tq>q~c>UIlEA(-{]A{3’,gf""h-nL.2P,>*֙.e"'"gicc&7t2mҧqje {DY˨JgQ/T!yrB NrroM8 [QGmoC3tTFƂW_ Z ðmL~!G"m\CJ XRյC'C(ܦ9l"bdKo.ed͕8K#axHy&~tS>YI'}Yacnk&@+}QsL}u3w2m@c36fi%!AD F[ɺ6wfIIOj#,쿰.le2i)Pķ%ܧcgE-KHaIPd2Wo^`GyCHQuTcbΓ MW15kG95&\y Z.ߓRRra?6&؝i86/DYʪZk&a(JsKTUT3ˇIfJIE~OK̏J  98O(\ULo0kZv::E4%=ߴc (=@e[MQ=hJUk,bQ sdA(хk j[_WÚA"H^鐘Dפ* c?;LMUe&aH,TӰg.l3??e>۩/GRmD # syU\>kmGQ{lgT]OT?o2jD1*d [Qeʝ23[k5w,7"6=Cbh芔9kK f&M)A[V|fS'd'L̴ 'K O&!IW`'c 3y NC?d|HS"'KīWE iLd8~Z6?A:YjU6!iN:B4ꄧ 34[6ӧ-gu TƉ~F0;N͹̸'?XjNLY7}[f`Yjk2_ߊ0s;%"Z[&q)0%C 15qLKa^p+ 5~oMCN <$a7I7b_wIy'vZn 4OV@]M=ξs,v6lb,fl*fQ3l}_8 zW>=ޞUada hOK};o@K$CLߤ+ܘZ k+pFJ̺W(M|mQ+jL3V(K b1u͛z3qأU/u \{Mp/$2b)5(HKN*~]íS/EeK{ Uܫ~ϱNQ/+$j؛V9j_wj ـ0".6$c%+A,X %xjJ/:BLzĎe|A 0L35 *;>,'> =VD0=%%?};>¡ۗ++;Yd+ьn"|ֱS e"Z}>t^UCPGϼY\&%@{If9>K?5w-YJ%HK(%O␮FsM&ڃhZ\!ev #8!Φ9jTeyrqbS's1bAlG7[oc{^U_n) *7%e>)TFr!gJ }z]r谭&VdgF&z]̥ң qcB EbPvjSbjkiXBFKr;@l+0"Eb]W@~nߊvzG5s5Z5L_ ,lX4˯-C-E}ib#G6(`g{R뻃j 'fKfrj_#l#648b*pUMMj2\5/h.b"fe݇Y7,`T0}ݻQjw/ L,70e &tAv5NHl|N$&:mR$6`̶ nNa榜}R?BnlT'MC1SDT[EfЉ؀j tAו6&|pj˱Bf*L^!IQ3aЭ́,aaɏ&1\dpRD#;o2_QvHv+2oa6\*j陂FM~n|A])wYyIP3|:8҆Y4 k51*(` MNȦ,>tX=GF~gآT*|~$! OD"Oqdhk{fə #g/VHxj<GiNwbT| PB^sbᬂJghwp5$ho?]SP,֎%%\5W>lGW,oۙI OqG V`Bٴل|Q:Geaݨ_Cxy3r"(H wlC@ښ*ͧmc082y36Veyvdypο|e 1z!LjemԀ[@$Lsb:Ξblvkb]&KyMkUutAPVd–g BAu}w"k4i;w#vs~\Ai[3̩߬ތq^e1"/hUS*N2P|:lr} rNXzwXt\x4Hܦi|bi/ZoI+A@97:R[8|bYeawt-v ?%jsh#r)U3Nhޱ!o4 c8;,uֱށpYsXϞPy3q$ gU31|=B,%ٶ Z^҈*4I izcb Gi5OT[Tx4L(9ư/Қ\:WV|@򋗷)Yvs}l Tr+/g'~Wg sQ0ox hΗv$Z fC%5'eUWT@| 1k[eVSb re~o`ZQ‚3b>󿽀߅G-'Eky1g",w7&Hw&xeJ㕍eqַ'ξNHMQ";s;&7n!i'K|WDȏl11T6aFVr]7QV] ǾuAO`mncnCYQ.>r|\IT0sN Rz^ID4 竌Ҥkt }= v{pj|m*>D,-B xѾwƬqwr@BXS 82_fM+wl@x4 l7WZ4s;c-v}Pa]+yXYTUirkĠ>-^g#RB@WZ\fbl?@kS^۶V˱QQYޢN~E(d$}{rr^tIK ˽`S#+xB{t^^)(GO̺0/]|V\?X`63ӯߣdE: +s!" lV-xNbyV[\4*p4TI   U jb -/u| `6 ׼9ܽd)dK6%P[Gq`#6w-Ի\\0^=N%7o ,ھuUa _!V}v'>Fu7TT43G]4_t݀Ñ& iM^s_l(cX~LnˬWt:ayZ`~3EuzUnc zo&muA:JqXpJӧ)zX@_<:xDk;^|a )vړ״<Ǿ.MOa}:{sX_#7^ A.M̌_b^f`〚vWÇ'CHkz^­ lYO! nf !ȹЧ?ZGD'$&v5bt;g1eQwU=}J%vVlYU82$5k+t"^'J56?KQ4}\.x -[JIH/rBvgqe'$ɟsoJ^)0`2U\`"| )D/}l_63jdzBR'O"*{Ӿ(v!k?ğ6Wwr5:]Ȍ# XMÒD+]2!?&O:kR0GP^=b_*zxE)J8ss,Zi|e]ƒ1 BC_hc:9'13")@-H^M՝W=7%T=vsʊO?y #1:auS}Z⫊of;%'F"=ׯz5$1\#3<J:9.}cٷ:s}\ŖB&2򠃘d9SA|u*ƧWk)oˆ.;$%>y [WՂ *`6v yQjvI8PqhCݦ/_~8VmV]HE>8k;zkMlotUh$Dڍf~tҟ3up[:ҟ+19Z/ǗE!4[$rf>?eǖپ1g%Q1%W"ԇ@\6sC"FYE췪 d) 6}׸5X#糰B{4.3swyyqPڝ-ț"< a=llq!s#GLS牡ُfr'ؐ (3>ԣPy Y9;xR$N<ܸQ9E%_5V\2m%cxsr|x*&U|kZ=g^b~A<,Z{ gP[D HG I8&Vyшm!}1*ּT*-^Zß5x-҅pސο^.> .3ɭ+P(5\^L 7j*5TM)pM9̈(p+]d? GA6"h(ѿ\0;zlY2 ˽\o}&V9_z-X_nUԖ4ħ}܌[{_B 67fikT^^/ɮȱn_F`^VvGz}yn5]>P$> ,[̡Qy%bQ5wWm,+ɰ/oyD="Cl8d<ʮ9uU'23˄C4AIMD \L`bTMhX]lG줬Y/âk÷P°TdȜN CpW+Xln#ւc1MѰOxzV"a{k8Ѯß3B=ZdC#=ee3BOH1 QzsbHQ1Dm ,ZP$x% ZSh9rM!p zeaq-xwR^Fq :} #JA9 K5sIesp;Ps,UelVmq~ "d#[r5z>٢Xj.S%*Y ߙ9m\FOg:fnX#Ws%f uʝc"J @(`3z/?I!:lh>Zp|s䴣 ?@jG4qo~=CUQ/uf$G1l601g+z@MfOM^ED;D/eB:HJ xxMeV~y񫊪˿pHo?w\a źR<.\_ݳ 6:,K9&򪛙]` ;bMQ{d4&& ٌvۘh$  XjlΛb%~͝pclL:ҳtHrXK5Or978\8KT;Ƀ{Zt~y|Zm!>|vc[ЙGӹ3RV6R&ƒJ]Η0sTc0 Cu&)*Hc9|Bۜ͡Mo}{_yoի3j:.BLN:.gZZ۾0R/&> nwAM$zl}{jS}Ի=!v%u,9yD!-1#ӕSk~+Q:^6%f_v_(B*k^.!w s@η,g(_~^.m;}Ro?ī(Z@3pL|OmzN3 qەb昛j=N*X'rld?:c$9ZV/I*Lo;=#8U2(kiNdž9}HY), 6_+/46%Rr5/:.ZNE_{JZ "Nzqܾ޽>]Jcbh/tZn98NM(xBW Ĩz:Y6t8Ŀ!Ao4CdfS<7䊦9I߶ޜ^nrv=˨%W΢N 5ԋ! + evwE,Px\6ʓ"ZoPGTiUY'^#eM}T LID-(|拐B<[}=ZmVa EKv*rWYVQ`_Cn,7!>IJ1 16~Us]Rx/8s͹c__s/*7j:W7> ]66aX8̳5$"X3cD,j:`ٷHL50Qm{#1hTbO޼ZЫ];ũK2ą.M3HӇ 2!EwɈ.vf* ֲ(vJչ}[JxgkĤ?f>s:_ٟʢ@s"v_2`IIrsm,%D7IW$̪˫H)QK".yn:Im@ń_gh9 @I+.)G4^nW*#g7wij M> cZb5ʰ>C*&S8؎ک+!Td֫13҃w, zP~g1&9lo(Cxю(:Ieӟ|tEWP`8zEƙ&LEd{O ' m \ǹYJĜ| 2^s[3~0fH_M7wx d[>`q8]֤G>h۳Ҵ}Zw٩%5gozTZ&Gg*ƚI^tQķҟv9sdF;GnCBnrc,J#+Hi_o֫9tzEѴU: ҪNl`$iXxlJY[\Ψ En&zsLڮȕiKӀ1 tCx_1'&iiF~/繂yRr+9gwYOAVDPoUӁ\=*-m#SD&3m,m[ДqyeN Tb4,;'qx{Zi,{;Py@hlcR]/Z<)XK[lTKB!Юѧ2L@RFlAocF eB(\][ʅp¦nHT4lG(3Æ|>(܊\5* ?J; "c0CQWX+pahvT! _iQVb8+/ɕ屢௙>[ֿ_7{(#|N*ltnT"hy~Hc75͊ m '9& p_勈<ңxC>*&ϘmUF1߶֋λ#-; 9QC]#Y& ]C[ݹT5$guV87hMʻU:m+CcQ(^z{g_TPĊyD.rR֎\F-nt$ko'D!0"|o[S4Ĉeлe[DY--!qhkz/$y z 4 #E#A3>eBm[Ĭƨvhd.qGo AQpY@܌gіJ{CԪ l-?Zs$=Í$`ki>#Pz+m*uR:;-m䀧 }ʁ s$)] F޵>&8Oidߍu+d L"~1YJymp2Rjn|Sqn7\N61hV%17JpOKS;/32DDs,߯N~\y@~m#|\og?a||;{7 TtW'{ 4^(VRc>0*V --;(տr".l[vi\k{;3՘х&),i[ hQ5m||Iwd)ÁLpOYN\is|޲zpf#ft)xFk@#/F&ǗO޻kL[_;B}ЙBAkyo\>Aǂbt`SG=wyȒW, qFm|{wZ"(,^i%F@6AKЂyZPy2{,]7QInZP~WcFL]E{RLWJ5Y< Cܒtk!]7;"Ct*yr[iڂ'}YMq g5bn[KtG.S/-mJc] 4d=u2o/> 'g [Wj[ֹnUb%:2a7 jH\K.>ߚsBƨy7ϧ-M.i-ӥuMYS-̀Z&ozl7Ue)?_^Ypj}c*kJ]ddUb^>fQ\0jmsscUDDƝ >+M( 8O칤/eQgt$Kj'j:sҗ&r ߕU~@nj1-:sH09Cd__6N8\>lP( ^o_uoTnɎ;&u$'.;rbLn=m]Ul_ >2[_uoS;X=iZ)͢N|`S; t8IѧXIN-WJ"(RMO#9aV*K 7Khu_7{ fq'ْܷ~5*s uS=ާEzV$Z,Lh7#fՌsyrr2g#֔L'r3q2eֆUM7撩ż@E A" 2֪v25Kε6ɡaAhI%jPI8{&< ν[Q+JFv?ի fҌ6 C7}& $x%‚0^V 2%4ȁՄv.Q?Ǻ'H}[@ÊMjrhqż.mӻK'l|0TM# SRNO1 o{ S-\'2+e{HT 4|j&F Y/e3e;Ӌ"^;U:$ jNۛA>gd;=|I29}{>װ5r'L 6qX\VYo[S6ynȃDPUH1G 'Jt U-#MźMMkg]Hd`!b~{Q-Cs]E('d^x=}(${bv@u>ׂخ.`U>;Qbg[Fݶu73xj[`%*몊gĵyx֧(c.ʛ=#:\"(J"G ~VJcGS]o#jeXX)w)-Z9c_G!Nl`򚲳DgUi E}8@wq|1D2+}ogӟ2+{-ź,JNAF~NakT \jsl [4-ݰBߤg.1NӺWb teKW*F45M9CmN, >lUZ|WZ=ʢJgG2˫OdĦ/%}]l +ӽ }QBg!#5sEcؠ6;=i'G=oѡaܩ䠵G<(V^q<׹#Rϻs;~ 3ϴjjȪfOxr x"<ɗ3dxTmSC2l-JYny棃Ur`>; "g8T?JG"Քi-gZ|')y{2cp H1GR"\`=áLmrʈf*uӾjѠMĈ(0s, >F D4q{#;[cq(|q*4ZRŸ/^oMաۇ\ĭNZĒ!VP|]_\HA';bShP,ߴn^ G7&ۀ^=\3M`{oH:R 9;~'￀-qW].%P;jaή&TsD-`I^OIEW#t`x!PJy^;׽v9?~҉v]{!I>~uN\Lz,ww 1wÚͯ6m Y?|꯯bdrD68E-loŹ#)I 4,C> ucƗc0R\W<|Fj(q!ӳHLK# QpK0H>]y+Uߓ ۚ&`5q&qS\(L:B)a,ه.-L:QAw#2ʮ޵2͠築m;ݩVO){y .%'Ö[u*Uv%QKŗ?)w?3"ʊ$S@ŕO 6_}~XiVR"~r"@iSV8qZ.6O*Qw5mknU1r '(̊̃89Wn7fvIJ f53Rn4=AU+^0*Y"7"U^}H5'[y(P"d R 衔v.dSF'++ΨGB} XmuFo [isd-1W۷_'aGM2<؏MͶ8l+CDCM=S$o 0s)* @A*Bgh^ǾNU-ʰTY/nBpgO:[ĸ Z[LT Jߤy׉jz9~^n+]|R>ͳofoorw䃾$p>p?P)M_\q%WMdDr~WAV jkEK¢uP}ZZzQyۿ\a\ jya@ܼ֬ a  m]wd:g 7BHbqvCOL}HFt|i?D 'CJ?^O pSf=̂BߖLZl"fA`,Nbxr|QWə 3Xp 9N&Yeؚ?-ZiXTqNw.8!?$i2s+^Q:St{"( N9끕 Pxb:@8鞣ty(L]SVWr#]y}tlwg4.ޓMo6$gVdU5vTi]ʖ>)6 vOg{@a `G ZgÁc Nݵ>w"LJOm` .6ly0Y% 3NBqe#+l REߊ-Gm`z )ڴUωPyԯP?[PF$I.7‰721MJx)=,olA[aF.MO+lWEhU8Y{,}Lqi>*$یc%IژDaQ],Xnw?yo̚@K``wN&veD_$%-=| RLEn54B%6䰗k{sFJ1Dۙ9c {bnyb0kD F%8J _J[^u~HSotaiVxgf`#TvڼĘcdW#4 jKzlsl[ѭszqW=C v5jw#|:'9aivFCGyn9A$ U3rk0^K:-yxQ"ušHe0ebZ\.\I>VMfQz~bOjrPP{?Np7E<+ĝjEa~9^7%2@GX'_8\Q=_k=yI|fQp‡C+m}nSjDqK,6x3U7q=;GA;)j=j jݝ[ j4;fj̻oM`\% a#D)-OҊA-wAf=^s NH\[&Y|XғԽSB۵иQW#}ǑݞbkWk]#,ui]O7*>Ա҈!;ϕ&35iR|!HVy3w \<~n,8]3`aګ rܪQ}vPn#AogWheeu{+!\*`m1>EdHjب)p[(Z1 fAc?VVV*Rt"pj40V ؆H! D+M^) rҋqntw}8FT:\(,VqkAf% E"0䪝I~6oB$x1A"=> O۽SijT?o6/] ~84Sjv-y akH89? `@`MֿVę 3nQ BoSwnʣ[kޥRiiϓ8"qy,i1}ۙbuFiaG_ouu \JF}.~mϷ6z0J,K`>V?9ͺD-`>r}bve\ :4AY/_"t8;sPa"d7U菠0W%Do5Y.11.*A"Ğ$O"E2qRjBmf"θT %Pa^Ũw Pyhqjob3_%/NR`G6qdr {8kUVF*f~%&Ą4}= ;f t_SꊧO"ZXpn5<]x~*j׷| IX2>cAS_1ӓ^}諺{b{4>*e=-hPEqɠ;?rp c)nz(wI-o/S+Xb_~GFd),*ߜ9#rD*sr#yO2B?S;];*yctv՝E2 50]xjDyBq]Z݌oZ8%ZW\% a85;r&uhAcn=$r|f/ʞ^q2Jt5Wy-H ?CG](=^)ha Ү/gaGLI_N* qd#"9?\+ڞ}1/ar뚏H↮YaiL^i/%IQtUUNa7{JuMaeN+١,;'zq3;fDљyle쇥Nbz;jЊCƕ= %sKeb+0w*Ib;N!nk%6rʏ)ԔBְKk |V1 9a^]2fRwjNʵZґ[/|<-͙]H-ҵt VCkev^iP?yRjs1O̠%ݭȸ2cY5^7Xm~l*M.J{ذTZq*@+iBMCY~mjȟhB)BҼt+MԘ;jDsJ6ꐺGяdh̗{S+!.x=BFf5Ų0.`x*^RAQC] kZ9WWo-hspO˅ }B-6ΗhuImju Elsz.C:Xv3x#(0AyxR*=M)NOjLڛ]cA\ǟ#mMIs=% B;J;t9d_J y8,M<9o%=XDFC2isi F3#S 5QV8M!ņX,&&*p kЬ%L4A۳Ye]{6 8*qv ͓_GNuR8 \r(7|?8o~|~fGhf>5S3A\E3ף&|#|zѬ<ɬ,Yα &儴lb6u rՇ 8~zʣR5&8vXc||aL;[m$"ɼ.Q&ZZpZSG#/L2y$M=]cykʄ%u M4֤i5HfYύE+@7-Y?Iܛ/+_(Y#܋k#: .M;jJruw-=2Yr nR3A햻Tܰ]v^mbn{o\R42_غ5 0Ahี@̙C=+Vlj᪝L( f_\mEk5,bV`˯ofpqcJeAj}q6X4' S\ hZz79"ĽΣMt+9\$g )ԸR1f j'R&U贝?OV ů773TlqT|Inh;a&ڧWZ-q3>fuI_~lQYkeF-xXQqF%.`d$iw*fi$Rek`3HP؍; `~4)EXf 4Ol䙾/}{'9?K^;'US nݝ"9@i#Q$B Cܿ/9zdcs!R;BH2/}M|C,i<&mHVǘbK@bU>LfV{i[K{lxjă#dRCn ^ :9&[$D:f7NosD$-S,|VnlFz2V0٨QYb,`ꖑi0tgZ5Bv>҇]v+gJK= %7 g#,%{"FGrOcqZWEχfaqLł` 'g=8grTLćܜTÙH+ب+,~{E j=gEuLpFg6 g>x?/UM3rv[lа/`C; )F{YrZYtU &ʓ*/zN+; o4b F%S3Pam +3x)_d{*?`7d'aR,HPٔ!:H9gM2C&n֤VCz` VQK,<QgsZUV6$WIɖMB)~zF޴B$N6tٞ=]/%?z1+ҷr8ϔ2[?z&I-y2}by o ^qY7}JO+AkIZ54}Л2qXJf2>1pW%j7U״ǦB{8|_Jǭ7Ǣ$#ρz*H=.oMDf.bX6 9,*>B2wei@HCmS眜 DM ]ZB;3 ]ĕF},0w?4Q6^ϕK"LKnd32CY"  =oj3fOopΉ[Jق`2Mš]RBvpҋv 0= ^G?5ߘm BDXviYsǝ "o9Zbld#Z^0NkjQ[4Ey^]|E*@=?0)Z~Mo&3Ε|ҏJQ{|PS]˺̐Ιrm@ڷ˵K݀?Ng\ ~:d,0 m=Ӽ#lϤx{^90Hm̂o#Γ<{>0e:8}}d㷯~D:e)+=W}e%/*3^V25c~E=Dl'KOwטC'nIMf* юܮDiSA-gEwho}ʫDKv`v%:lLX^XK[d(81*LՊ>kg>'夝#w<ͳ|U?2ҕ@-ŕt4R khνGo\ nx~f/D #3[YF 7\*I)Ty]`btv]d5b#?`<+#aOԬBʠy20{Baտsٵ IW>czv𰊬H O3Vtӹ=Bjv2Ņ\=LRERObyQ\j`Tvf(IK/:`g)=b 4>tڊ[疗.$V<22`9ƥ( uj$5 xk`.Aɽ7D#G#ifò JvQ=B.=hy |!JGTuODުw;񍳅uk9bEMZ{3ըmīAgf )1khKb`-CM=Xϡr7nFDw?.ѪK׿xt {Q\ӑwGxl\Š(($'~{JI ZOWn(EB|2771\?e\`c*ųCARyw+]wߪX0V*Y~hg}%% dlM_ ugf$gQ-"c;A0#/+o h@an:tL|JTсCvFv<%FU%ٳJ2|fjJ&Xqtϲ=5ֆ+K?+pP&qi}qӤLῠ+Ƕ7[|pg~ {;]Bn_r4n&ʘnMrp ]YV:%uт lU8d쓏K|se >u5Ɉ)Qgi-ז@e?ы`xg:DXƨS XIh-?ySueoSA݃W/RURSl/Oh";PfOJȊD]=Uqmfcs85l-I/M3&>HJžRfד)LtSƞi4u!Y'"Aƃ_gz{-6XCC)hWF)#}#Ӏ4V!d'h"\fd~cutJqsO2^ dK"Uy,ؕfgW攘[c|ދyNvR688QQZ׷dO?dL!պGN@(܏cSyIE K:m #^tVMk6jb`?U<^8YۑSLv^PZ!e?=']f^3o0ִPF ʰ^y|\t ^RT{`?]tMȶz70DYp4)""l5 >='-_ݎۦuBF{=l^Ua*5/r%x^.OѵnC͢yN^!n(Ǚ2\#28[? VN Olm53 X~0oL^^#fk*xwU8EAx‰0-2 B5e!YWpww@.;,ԝ 9LԈd1I4_ I0˴G viGX&~+2Ipp)9]:Tғ ,3MPP0[epIf+pn05 St\g2G =53:9Y TWɈ}FF\42~h/oʌ\4r-U2\i\ fD[{2GLc3 %77)4&Љꔩ/f<yl8b6l ΟП_hVH4Mz|<=Ĭ!It*Iq22(ъj«J9o] ?t+R:!:p0s^ ~kj:iBܐ]5?67>D'}h]Y8{ќsSN}a5,~+SiS$ $1)›sp_. ZO-G@fI 6EUc؋~U ;Tf[lGhi' rֈ-Dk?$?w1Eh m^;|ywt%-Mezj9Hѳxi#ߙV] cw;FW+Y@6%l&҉)ۄ4A JDb`ϓK!kE|`Pv,Q*- Ž`<;~o<+25{zPwJ}%>zH~pvPΔa֍{T3+5|C̋nQy}3{Ǥ0*ԍuvZߧ"n (zn=!.oרNM`$"şDEʜ`a`}bЕ(Ù+3JWtaF1Gr;⡻c1pK%k[_Ep;i}>q0ݱ:.gC<<pER?.y%xkz];\= ஑m.xSQQқ$_  No+yWG e.tH(~Id>>f#ăPpBb6R}vEr#Sݍ?p'ReVN׍_ uq3Kmܞ&Mz(=R2-ܸ8i99>}B?l"%4诅o#ɮe_v\6\L:^.qBWnA"Ec?>̏\˶WfxՑ9M )_mQ&Jn`~HFwur2'wC6Bk%AKݔwϳ,՘eNMoJ҇PT]&g#j;>MwBd9ie/ԻJH^{פWU9Gl*.skj+ z\[O0z"Xֻ -q6Pϑ[*|A'ɓ2f^\|Lkю-~~ PֶTh=lh71o{_P)k- 17Q+T`4w2饺vt5[7N28|gg4wJĽ4TpZË Lj9~JD;ʹ]ҷ7Pquea$)E [gQ?u[#mXca `Y} #9z\$5+。HĊ1s"2Q uuaQ+`_S<Q|U O:H@ $)>ޝWʞ2t%p /,b}xF+`6Y²B\\56rn:a,Ee.iP<PXQx]*ZM$Ϣ8&x2y)m#Afv!ylw;Nܬ9̻i%t,;$#nfO2>n8[M/I/峪ޚ1|5JDewHDȆtuL-&.`z7TvףUs06_{6[ )d { D#eC[A*߻.6s#nˮN ҷgdhy2E_}y1Gqy`VcAQqS[]$p1?Zz۶>35pYY~>ƑKS_ה& 9tdg#>뼜j&_\K9m7C"%NU%IfPp7 mj ':JJ$X"ö`׺\zs=/tOIA2+1#V{s<"_PϏG<AzqLWp#Rw[??bomFK3 43F5kdÔT]3 \㺳|zmeXpn+gA긎Z}OubdRDcA!@j!tW Vi7B- G2'ZFm![՗orlA7 CIg:5 Y- !H<B,i*9& ~ v; `sUtKO^f}}ׅo\oXvLv: /J9ηmfT2.{8c-uf?aIW~ʟs59~љ s~xdt򽄷t拂 NaVMżp5Wf'SL5lsϋRy-Ws-Jc'TpC8p+FT`}dVħ\}d `&cw3]fRqk1srO_Lk >F* gfGD"h;N5$.u% XdR1?s]*|e̞UBzJ9ICfJګ?cYjNƼcf)DzZjD}!9ǥ ;e%kaq?I7?: w/|CK&%[vwmR-&(k}F1ě.A26SN3wcZ 1l$s~ ('<)zF&:̓:II-€\'ޗt<|x8Mf&4O7}RoMq-7$ΜWr4 2eШe*~žh(O-şsܸK:h>!V% <ʍ{\n⊀az掶6ؑEZő `:bX|,‰JZ4!Kh7wo|ۜz/gCnQ[V^:u&Y~>"RL{/"t(xQ2/69AWEr~,mYn[3bAqy@SEؽ\l[a'%g/IQѨ-]&f`4"`<%]eF8ZvƋQ,մOMc5r(ER@%Q._D@JC`*B]O8Lnfu"# &y`B=m @mmǗFptHP٤⏍UTĄ<_)qFÌ'A ',YYzz@,_i4sʬJy9t!d;Of̃j9[!xj]~WƎw$7E*LubNtﴣL {X[]We>dX[ Vj2_-w.ڐcB%EZbNNcWzFhK:s`0`#I梋Zlz08p𶬪3 Eʕ{XR^F?OOre\jなпu]ygt/[)}U95$/E==r?vLS< ^VJLcqWS[= OFi1v"=Qw^5wF(M_^Ϭ)ݼFbi\zGj9iD n/uחݮ:rrݷ$5c%s{#@`A6鲵j ЅDʙ9K"%fذ*Ȭw1}uA-u(;l[kT8Ibt9`iBLҫ[iW'IM[|ra=<+8SƋv4E*C xB?ڍ>ST1£Rf~Qs#7^x1%~Ymt,Fl hNRcЄN5+a,[bQ58/rÌ Y.մeVbA>˿1"Z18|ΑǦL<=1#/|U1iAnF[=7DQ#u‡rGE^j Tg+քQ¡GXb 9* vnd_=ʰߎJ雴yx } 'F*/mYn?jߪ xHdL(B )b&A=U:Q+,0 Wʛ^ֹQq]oN~WtH$m6=*R= rӇ? ;ܞ?pxJ=]iϕڰդ|_t:SOhXBcߍ#@w\.Q#@tEʞN r:P,2s@U&m3 bV MK[=͸~{(.%y*+4(s씖~S`a8 W7xXOz>cHmQq]Nl&FHe²(~-OcMtMCsG0Mڕ\3g M_[.Kۂ;ZĦ7Y!Wu֩(B0]sinUn-)|NtG}gxS(-HE.gñmTfZ6`2.㘵e&cw"ZnP7ǢR@NEjkbT3?["xDm Dq(X4:L!?Y`g^&mуvd/pj}c[AQvtnw%9zObfp%eR/ػ2GF%ӼdwW^gOg!o?R-bYWq%=?lVuene١kܒ >ܕΞw+GJDpnqiNIFMm|ⲑ\]-fnkfۓm#5&^D6EWAv5q..y;nGWg<4- ½{Tt1{7垖\ t8:[t,yJ y.DA>|蔡eg||M5u*XSҺ*.aCx|S*&rVm |MT? ⽝bÆ /;#?]Ls};^m6(lNd!AЦu[|y ߕeL.YK;o95r>72o_6nKՃ&g8<3 aM';]ѫ'}͓֍^HNP; 6+6U!;Dٯ*"EׯHdV|T[&V Tng)|=u{,f x+$:EGӫWv3c5K"+֯քN [xL,~A]μvDmlXk&e!,wuՖ6&)]ZɹaT@r?4 ؐIMhaF|GlXʪTJfd՚I9-l?׈؄!#'NV,@Ctzjd*S[Ϋ>}YSpB!:sDۨ0w?DS'{1"э ~ gHn7lϳBqqo*ryә-Z1//)u:'. ;={`^ HRAt9!јtofxO.mrIʼ-NGhM=5=$7k*bwme|Ճya!B>E ҄Vp?J3L,~uJIg] 3h.+^[){IiJ3E{y*\>Ǩ#kz5U,?^ i|^ݺѷbr|0qu%FO_S\~Q\6i`/i3ۡw#y?9nE\ů@/#Ƶ >,m㎝2C֤M< !ZٺӧR">l!\.]hk xvɳ+6/<|䕛 O=K{5p߯ǩƨʒ^C/)亚[[A9'bO;T0=yj$r8. a!L3^ɫqQ"'bU\1-UR,=s 3VQ*u:%!Q%Fd 6~n,=`$LzmHY#1qw3cUbN1x#j{ ߢJK=('wDdմ .S&,ѥm-kXE"ECɱ,{w zL4^I{O:;clRW4T $ T!0̭!x PaEtkl:gL1[-Tf5 qK rr&WG%D1֝+M)V`78B4rzGt1vxcvz0'X~Gƹ`9/ڎoIDrѷ{< HOX?t4$'"_>CBEQaaeII_ ]i w>M p[Wg??|V~vy;K >{s!f2tsJup+DM}3>0:YH)/V'HZۇ2v@-e7P`Su]'!0$b[YN7+x")ՑϦ4DY -^IȚ2Sa:P&uŋ! jL|@eKf'v_n[>_aū`M G;G7L^*oܰ|&%zKgsQ{ p+sw<-ms⤅%WLŖyhn~mBвt6 ZgR#VCbeÈYrycɗ@ނn-4Ts׆ѾڸһrWX?S|]G6!vw>M6bM)O)V!+RS/zsuңw)d_[b.Z$3 [ğKygbwȏ/7>=ڰFj3pG9LEpdcA3${eҎah?n%OXxV:X.A#59f& 50yPVߥh Ӵ- Wo[ЛrשdC ,cښ(^?vM'H]v2|K3j>ZWT?vId:xkȋv&Rt:|ch+7BR+XL)=?wߜқ =P.}zhwt:9n1am,JqU>s$}tBrٹX>u뵥`M0vmMNFkF&5~bnu'˸* N?$qF/Fd찝ȹ!^:gCs,sb U?8~0=7ڋ‰yƲU*:rxWaJ]pi7FqA7AUh5) mPaF/I9$ia;Fo9  {yw'_lO(j07'wNY5eSA=}nb#MhmcgNre^3Zm!>T3;s1n?1<>*Ƥ-)@4yQxtZPItrW Pa1p(3<P͸@L'ɉZ8]I9UQ˧ mJ[Ǫr|I=4@yv|C0XzZl^XVoA?|OuݸOGԃg0TTNh ޛ*1Sd\梚m>.ӥht^]y}WCknI?%@nj$ak7 >daTFX>:0KmoSs$0V0#g 7or[V]spې:9"1=-!E VX5̏k_^}~iYtjh4-K1(5O.2z|wupTjs[c-Ԟf~ }Pt"^yA(DVb=迆;bHgAɊd)i*1]Us_ @`s^ _)Rb;lZ=VC/$kb`lH*SF ղ\0 "/vud rٔ2&j%ӝ ,էoQ{yN2sQ۠bqIئiHzTnG4N9؝<=[zv2u[jDNCUSmaK;S/*nyiiq;'ø47{#`:ٛ~b49u;d:{?$Z/D\VlE@Ij}Wo9VrzTw>? +xGAwkZv!*^>=8~'HF3(=r:j \K&Zgs jl`[ϺS }";磧O8ʨMk`0?5'ͧd62 JcT6#7ςt/1V QgsJm sf"tEuCΛ !g`Ȟ=OeT`o [7}yD\ϴmh6;b $zb $oȴRZ)wGihNS oBeǫE8gؙs%Jh+,NUD#p6xض$brXzVTĢCP PYEw4FYcE Zf@.a޶ϟⶰ 6rzz8'yW1ɐKTަq&UL]$8ƀ-|k&@\rR LpY,EkԽAKI7&ݙJ.jܬ7ܒ8!)`6)r .JY>: )]R@밐/z0R|z4 `\>%($}EN:10;n2e5R+D9oBndoXh5vQ/jV4"'P_d,ߥja~Q34"P-~6TȧX[S zº%rdI܋M~f̐Ps-b|4p;D?Vy]Z?֤喝I5>D'2ƆS,~,iBf<+ۈm$qy7 $@Ƒ{`W*O~lzX^OV%e r'^<14}X۰oR|{nqG;|On_%_+IzhIOSx& $}H{iEgOu[ے\r]0̞"u}]#_Oww)Ӽ|nCVӫm:lyVݷ:N`\Es>_{U[,L3LJ]n8$nS*=6l6)&%[t`&OcOZDPA׋ǤfBN%;$B~<+8 shx^%zjexK6ZD-uBMV]OQwG&<JG'ؤÕV!i;ܑ @V6^i/ G)y05I:n+ M -̌KUlg$ɪ9rI5=XsTDf9Fmqf!]H4LdpL. 5`$fsXE:B_R6o*ϕзz ǏJ%~1N*,B+%0WoNV8}ᡙ"7*U>G*w ͘sf4TMzbSE<vo1{03A>/a?o*2]F>w\Y)Ϫ=>##M9+z_8e Yp(%=#hw+9I.{~r/5-ҼOݲܷn@_=R=%=IX`֖Np'MCڝ@T;>*W)2ԌuD6Љ:##Fc꾵Ԡv,urhZ*#z(K9:Z˺c78Svմ燽FN%]-)n!)ʁͧƄ%waF*I/YNӖl_1*1mQ6*(XP%s}w-np\m.o` 7`(Q^g gX,9dJdpZVHrOM%3hT_y O:Nw=Y>dKm"UR*@LHL<@w FR/>hY8tx6ԙNMK(]Ũ CfNzuKЧ\#zBP~+0n1ΠjUJmoBT?"61E$O Fzɸ IXi f3Ů3Q  >jgP|y22m<'sjR0Kh.ݻɵU)cm#4_m\1塀3etbH_ᑋ/.MnFߙwJs|8Q PhvH|"ܢ]G vݓr8b2Y45٦q=~K*! ?{zH(oaC1;jI1NxO6{]l,~. X(|H)wd'.~BƎ2)|'բ91/=*Hx4%W"AT5b;:b lP!WdSeSU7Z?_/L[$[Wc cg2Xٳ4~>iҠb &ck9ھfĒQ>#d:bJELղQ;ƅ0l_ݵ*G3c3uwg]MRbM^f#+#Z#1r+/mJ`;./Wbi2v6y7+3ūuBķGXvTtW:Aa-[*RPܞCpu_3+Y8S&=8,ԍ ɡ9F &H rȁ&gK1&+Oi$R\ 2@8f\jSLvf@$dQp6g#[ZT+STX%B=I89ZnU;u)ɞXNal^^(UoE{ZۖrOdg7fAt7aLq瑥,9}Pcw8A6HDN-.}~c9LXNNJ+8JWۼ3ҝ^9-W|n]X6& xX\7yAMZ-Dce{oXCqIxjx-急#]e΂雺V{b,*.,@ m\6}c|iDQFZmm~gķɦO$FՕDdey9k8?GI=W;eb6>cܰBp 4 u &,f׺o.KPysvy90bcICYm'Ӭ$Nh!mkoa9x89&Hx1BcNsBM ֤4fkWqzE,o.rZ4X薖% -̄\S(zzʽTmzql8Z,z쨋lp$K&ʹcu欳] U_HϨs,Jbe\tM nNI5ؚ;f+ؘ0Xēqq]{BJ6{p#\@5s_M_ϯ66"OAKū2p 0u+DQ0>7|'K:L}";nop Q&I 3kX[im㊅J8uHb;%%V6$Ln!zlf#[ &\ x/ݔNmT %NnD.@6?Kk@RrhW~XZIU#4d;ՄD^دa|**o_O[t ]YR%3jjcOBna -y:VafQ&N-o$QE˟*u).ki-:@ tm,3$§f3Iok@ha.WTtaŪrp/G1M W%2m/Md6Az8ѤxUpiK5K ׯK8 Ujc ̒~/Z}#EFmLiN0Th"IkGϫ|CQfN0t\q>6|^{ԓwrj.yL<K~ i6ȓ6b԰h ڣfoꙘ9D}+N R/^;G_8ZOiXnќԌ16L5H *JQqX~RϒT ت= ucA>a2h&dLKPkF]7#UmVAoA`$@X)_anPfN%4Jv2Pdt+&5B$(bdg[s[ubg*֣@H}-CAw҈T{q1܅Rv-yjR=Gf RkBixZY~U T2mZhKZWL#wc4b gJwN|Rk[-jxsa-b@j~$! Z*@W@?,vLAbO(z$첇ӏ;P*i8,Fwk_iĿ"-7b[մz.cYotɂaĈ*D3YOԹYYj'JkrmJ4BGk2͇dox}'uEjj=YSBsSXA.cަ]{tK;g'~sX^$t2͠,ŞX^ zn8vQX[<AwsVф+Pwz DR.~i=o?F{R_9e^ jAAϐV:`?kcR;Z4 wͰqb.$~]%-kCb] W9:c7H>Ǝb'sw:(<:x uqBGTjpյS02 0iȪ;"66wMX8z⼜]߄f莞{˂>YmJ\-.iנ$,vFR9,3u⦖(D39fv%sڋE_b./15INg+p6"gW>c`D,PJ yq:mN\Y .uJv>ԳFzX/`;l4JjH֗+W 4ȈPH*ٶFpZl]U tX-ڀ1Hvq>m/1 %]nggvu#Y`,O+/B"֮+ۗK j\E Im>bp[a3k_Z2ѣk KYgr)*_ѡ.C'SwZ"`%!K5D{'՛T*ֹqvu|'\[qRymL}񡯹{j;Gx;#`gp'Oi{<08(uP#e`?nm Q\NS)'&݃D[™aM\IjF䈃nFc 广f+n*=^}Eg/699 ghI¾-.nq,QM-7ĥv`4 uِ#?\2kۓɻe\:C+l g$<5mq ѡcF@;/\iCV:-%?2"9'wnB?sj i\T]yn>ddAZ畫Kccb;ϿιiJyXt@JvaQwVKqY;.2߯j>B6.>9],k򦛴lOrF6*gF.F_ώ |\wWx6ԲHG-{mbٙ[?(j:V 8%;:_TuBBS ޘ=`iԝw~8;-?,j"j2G^'M+Ok@}5ah9>Ur+ޢڼU^Rg~/xI╭K)mZlD, s Y?hVU 3 ZzWAhMy8k"Y}zrToL/YoH\Cň٘[:4 v21 b|d l}̶D`cТl^$nssE֯O4:p_]v+z~8]˺]ܟ̳b?xo9kV^#W2W -"ˀChTl $ 'ܽ|~Yv'"=(fK9)jgvL(SF=N c)a`5*e 9 0Eg8&eT5R_bhO׮TU+4Ϧi!¥360浵 LJڑ޸Vzr~xk7 Uʜ&ڴQ\=*5^uLԄ@3?j ]Gy~!PKO@V]bJr^}F@D sz+Be%c$|n"hnu_%T.W_'2K܄E[c5 u镛Ez2}-E%*zkѼ^$LBfowjY2̰xV`& r%{ RV[mvٍT!bHArioz}F4}\mt#ō0'S3Pj NA>v+\ da: pSG[̾n5Le *: 6} D#Zݖj],V=6oqSY.7u(#wԼJ]xZ:hЫ,u~{oi ÿYI`^7M'pqDžhBT-:ݫD5wJXr-ړu9|Q9n$F2/7qoǡ;*Ao^/hYɁǡbރW8t=6)nP95X~n/G貁[GENNzؕ)mG]ƃki&US]0s+Q/H Ϸ\Eq!X45wO X; c}qNqK|ȁfrb.Ȕձl褋n☹Ȑ뮓ߐ +X-%d[3yЀVVWR|zfΒvܔLY곛Jhܝ65P<m4kp[mǧ$eUb΍ѷq"9gP>gbӦ=E/;s޼3 .;S'p0m[ң'E.KtΎ@jzejzII? ة~?z8yIe4k~=/$~n,gUkpnqzxžV&= TwIiđy!h IVpY^ iv͋)ņu4 㧀R}üҩIX{yˏt`[gK{l,%tHikQRzP_]XU;*x.ٹI٨FC)7\:8h#qz@ȶg7Bʩ:i^lҤL GTbF|6H2sM20 j+a0?(HeTpzI`˚$4GMCdΔ̐& 9\~X}ld)Փ<|%KwIt.Vs\ή0 XD1,mHYӫa=iwkx7R\;NG,,C{|O{Ã|FY %-d+Jv4Ҏ*OXB]SփT7'&SDS(^n 'DR >Ȓ$-N5mֻ3'C;ؖ&}1e G :cC<`!2߫Fmdi om*ja<<@n8"PgdVʒBfY{qH@d?trME Yk)/ ߀Ka*ˌN琂U)sWdDMdY539~ ZV:*HX%dPpe=NT^TX@2ɫa>IR=p<9Ww;Vt7.mN?eݶ;I\4TklPtQ7q]6H4C+ Bh=]]b)Ci Ԥ )/)64 !>a_WG\hT8 cۛU0 !^61*O57׎|6Jf'Rp2o-*}͞1-zg}YDJ9vdǜTշ[tƟ:9&8rE]uۂZ~ ] \KGc6/$*9M;ZsF |o1'C U3m_`b|P)+Q[wl w#p R.# >dno 6$ٕBy( Wb, a lkdC@F$bV+ez,mg {h*.Gg]N8 5+S P%)K Ԡ<Ȥ;2];^m~-v>&'浀fNR3?[rCM?}ދ1ZRIVǰWqnv8S"3Uz`oGmxkHFK% cpvWXrQU!gok \dv=X ܥvzF |5P4cu>~ʿ;oJVW{u.ohYrb(m. 9OAGxդVrheJp1ߙb7g}<..a9=aw­rO]?El¦t?Qfv~l VK)= L绎BFy ו)g@S B/XPlIWaOܱYjz_6a"!q(#IyAgX7A}W7~?SM-T|\BbƐSҵj_j"79Dm}xoR}?,Vz.A3kqɀ Vk3؆:7  ؏A׹;ܵ$ZJhCvʤbgVMn˸_UWgFGNN c? RLk$ zG_#KP.AF,p~'3ʒToԤˉ*"/X$cDyGvs8}SyV$~:ٻ0S(JRW:*٥WDW? CHd\.7dW„oS0[5~T"o/4uPݭ-˛h9JRICᕝd,gZ\T{('UL =#ŝ" ^5b"g3&o>4ƃ苣w#7H/.bKT{HU:Mb[F&E|jA"UWIS/z~9$)9lE,W=J2wp_O.tLﭒ|2 >zHn7ʫG,gHE1'$J[8/͋#pjta,<ÊnQE kt焃HgC$n*$_6xy'Gayу,X~8EJ):š@$gc}?8WQz#h.IG|: ~s UB1xScF!®;VKtG[zJ91d$AN4X n){Ac m.|̟eBKƥ ?I \ƝKⷞ~+f,.wZ.Dp\ȢEE]v-g)ذYgivMϽvS%i~ov^^^ Mʚ}.ݞ~EL]E:Z| wdNeE;7S_T*f,|sNѯIX(5%k196&I32cV̭.] vJn.&OI'6YLp۳u_羣]ҩW!.Ta7&g 5ɖݐ{ߧ\+n"0pdt9>XsL4HZNz)n xY^C~ox*W37WvXf ^J7<$i2g]ֺ3H@B/>>)FbgŒay#iTm>!^I n0Axi)Y5.N̥6MQ C\:1v7轁 ȻQ>^㶿d!'c[.G7pcHXڴXUlgʟ7'TJdv'6ZH6%o> nizn9p#~Da"[rРWȦ@㼼')0j|;q(E)UxTp)u-]Fj6 TVe-rGN{t;Ay躅[]%޿kC9QG̭6"_ P)_SX& ˪_T1]cMpBCw趥c7DpdN{ŹA;,Nxq<5Pͳ؊o]0D=7LT ١ek譹gz =|mJ-tcPDڊ]iP'7wbϞ-6ĩOzIVVVRε]+W>kҹ4pȆa=v.?WVѬ:^?5t߿?&L*rکzQ޳o[\?GHzy%m 65wŚCh#=Ui>@W) cy.4&3YvPAlJ*fUb#,+09, b^e.;mXp\ s]SmTO)tL92R<s%~BmƖZ6N,R~ٞ)7hM'4dNh);HײjAW Z]62;Īu8hJ7>whU0ב\zUԼ꭮XIJ S648)i$ͣF\YSj.b.zBhJ6քH3ǯŻExS¬Q$6t@]"CE5Iߕ9NbY{V B{ 9Aa"Cɛ]gP=E$KI8DmUm:v4tCuм2z~bPt׫]ue;1EE˻&hr߫v)I :ОhIY5Ӟ$EU}L޸_[[b'~pUg&9 IHA<&ru:N``Nx/(T(l;n`П^bqC/=~]U.zw2inO\;c FZiD=ۆ@GO}_ &]k ?\bX! Y6#Cb\6?JiHg)5m6:4hѻgoKKz FhL|/yO.5fo!)w? BWar6kb ZmfuoIC7}f-%iUP1v9r !$JUk4$c6Dk&O"vo=__z#580)"]`x/dfT\dߑ<zbA&@ P6 "~EnuILM$RPCR= O r,Dv-*R9q{P=le\qjbJn0wE~{ :8WPz^J|:#bwjq~^ʓ>mQ/QM0d 噛#* Ó0~}Dv>A,!F5^zY4N{sN3]t/1^:u^/d!#xͺV 0/rgxniLߩJ؝%>cҫmu%th?wq>Y^3d~5)sXr[{ K \gx qGT,aTcc}yZ`Qלӏ!O5y%ҽk>7x99µ :rM#zդ-NbʃUt(}=9Фen!(R VCe -iqUk/2=U/ O8DA#GԤNQ/hm89N}x9\d:VDn҉>VضqSg3!iMQlEK4 8 ;lxyУRӲ&kto-is^ĭ'3'rCE %7ՙ;"e+)ڎW\X} *`dQf>bzv߼&6<9>*4qǎc]8G{z@!E.XdjP8k,]3\o)fr&erVS3Fn*K;5v=&y-9P+.Sp#96;@5XٝؒYs@;dI.m囥G\ZEdTk2GP>GɂˢDEڦD<1ҝiH츻2=t&xmyμ6>8DJL9 x+ 癮l*3 ҡkw^C" T tO?- ėw*=!(ZO"wed?IE{V8!+sc:-Ğ#YujL})s8C`XeoYi5M،3GUS7un<@>n83pPWRݬ'Ok(%OoAV^P:T!>@9Ū랟3rw\ó!&DGLq;bd.#?H}Ιz[ejF5' 6'm%ݶ;=c̩=.WKDDk,`Sv~vБF;ܔuxv4}tcZIDm/8<-(w,Ŷډ՞Oo_hMdJ?Ϊ;3ҳ"x_.xsS?A~)"''KUoʢEW߼1~J#ʼ@ilc%F lq5dXUtݐ$ײxR^SQDZ.J2ѵ$i)޸\sJ~)%rJCr,5w0(s:l?"+&JtC6p+x)`?8,>1R"H, :)HWc47ZmgM[XMVnHܤt(%#g@6^h&ݣʲW ^d;:z@$:g#q=ެ"/5Vub|a璧Y!3-][1*f:E,\˅npᛩ$#VS!\g#f (J2\d?g "so"]- eDaaZױ9ΑT3̢DmkakϖL"Qthdڶv(pqd&;~k/q;婟Bvx릎EȻH.dZP̍>w[&e6?!>SBfBrh`=N.qD 4 ܩZd1eFFz븒a.-K KԿR*$)b5!T́m~hTv} yQ }3%`oyq}I&%ro%v9.vMgo<n^r9ۊ~vD #+1v͹,R-ck噙lB:9PuRRۮjW]JͯmaGQW*:C\:^oHœX̣X^S/iIqNT.\ڏt$_6&"-icαGhgQKӜ'O}֧gDMT G:QeHWzsvh^-}\úD6}Jg'-Ѐ@F>w1&~^%y޷2i{"|<Ч1᝷7NZgi!eb髄e8n_3rw~')`s->nO%Y8H- Oq9XJRbeĽI\\~$2=K@e"<)XuxsͲVǂ L4'٧V6Dy-5[bcx Y`f7` 0d)I jt-L< `IܐVr{ӾcҸR J?=SY5Nᕤ!<çۭڅ7o0zEa>H-fO@mG@eъ#&ɼJ2' <=pH mPo'}vȭɥ1 ]LbQax)hee> ?u"Z*ya?"7`7\Xa}ts[*,xr#%ɤ8fBظW)©|r;1{B 3u`qIFW9XA2NN4Yt}- Z1܈ۢo.V[OmM+5d4ͫY[...R#v"Jt [eű pvJ;.\-kgqgi__cWboھ)(*si:eȳE4-0ՐOATzGq6[T0dY8,0].3WGYZ/fE$"UHOM5; i Q^`K߫߮:?k`跤CTl5 U%7‘/@.A(#͜);(= F7.DGFEMN,:q[G٦}D4+y1hUOf? 9NFeOe;D bֲ$`#|GV5NCKJ^=3-`H:TXb+u0Q4Vz 3{%^-7UZ,_i)(σzG/MT%n+`S~Ќh5뮻7(,c!}4@ z)xsڪ2(Q3|cg+JOcM&4l~[wC_m!ټO`ќk7yQ!n3IMԖfmrYp#n B $"2Cb}W4hQV=bKvdڼf=㒘F7"m wSvglgIKvd+K=6W٭nxԹ#.-mD"52zSnݖ51PI\8ۤbo Q!ԯ7TnmS+1L=,椥qq;`aU>4|:lG달\^}=t rSOp2޸KnM+A#x3h8WVJqefU.*5prsN\3щdK񦼆.5d;=ˌV$1yNL@yNsk+twUVL]Z)rsq >Yat>莵TDJ+᛾kWPLQjk9~(ZEYTY7۠M?~Q&]EXAX<=Y2oFT8 P$YGy Bפ7for"C.F? N{Yfa#W3 ɃkyC\OsT.J`T< ^]k*?Фn$jʹ7髜kdc6ί)*`g \t˽U%qL&^oHYoH{4ۘ{CsREDR+ 7_Fſ3!6f2~Dղc!-4[Q)8ܤznUMyYIu_ʳpg2h[NnΆpaօ+`- ox;E$'}[unRWr~&û2<;l-@Ȟ> Ҍ {pv ݩhL}RGN5f M%"-Q;M QD+Pڕ,ݭR2^թ j=cnFvOM%:!ìEӈAUV6(i0RD(gp/+QM$ޤY#}'E\:-(qЧWΖSe?Fd602zFEzmAyWq33RWYHڴag){wxC; Q$hFm*Vmwxޏ?&)5rϙm5gZ1q-nגIMj 915lGje6;ojH pp%<=,199pjJ@v3H5 }&ƹL۽7o*Sa 08X<#VQ*ǚ,ٙ4RP~OAv4 wU+sBشbFpil1c}XYӤ,Y+Vu_R}aw ~f~/Yo3Zi`"y2"]a+;{2Rg"12Nl?nknpÎ4dlė-? iJr[&2ĔS3&l (⁚a+-T'Z_fGRlX($*``' ƍx΋NO7"9(a ~jvL?idsLyMذ %'ū/P%.1{i)9gz6}>hh&;x(Xf)[hRvBX\yHk5)[&m$/u~ff`g/.}cݺ+)MnjYa,A4@l7-y ڗ=}F#'[6y]vn/3t^NudL!6,jVje1#WA/6Ǐ3FLݜm1rxڠm+ݮiv ]\ P&?m%;Js^ip={ wVPtd#4| 5:""c:0֭Cs¶b(#Bh9ӡŶ<)l7_o:&ҷd)FPzCە{EwLZ즗UXr3MrH BHv;- ]h8R T2,+[?`$&X HK-!MB}hΖ |i7Rk0fbs7`/\jˀ[?(bjJ) #c+]e;%(Ret%H3+@QpOPP<3j;cCa+믃­8lke!37ѕ%^oлڅ} HvK`,O [ٞ/o;-i|el|)mRB.4ki{1j}P&5kBF![ʨKvd.XW\ bFӮ~sPffG?k7<&? 79D|?h-*[LHFg9k cg~=JՀ-jcu +v+zYOܠ Uƣ{IX>)zY LEOc;ԓkꊚ%QHc**BEn6ԼW8:Z{ @;MZX2-~QX& 1.)0UMMKs(ὐ'܃mݔW*q*꿩` _),6F[ ]U#@߬^=~Ab%tMI~0EY!*2g5l;$D&heAäͅ-ɵj.]v\QypKVlk㒙a\|Q?䟱^@&Çwض.jYm̂6C]9 HV"'y~b;!"X1. |eH dh_zvQ)WC TC/8ZR3꘧#87P.iHųY٭B)j.`^ܭ(YNiוKΉV2A%ܲ5za53K6$'O"ib|W[Kғy?#87ndCxƈk໧xfx/a7c8`}빴7}X3/7{(ccNðd/e0&!k˜S"cPk^ɐwZnA x7CmdÂVKg*|D۵ Mٙ]JvdD-sA(c=MtX#>YtSFW*=|s埀'p텂3ZjA(jq6Z"x3瑾3+܊)29b?'d|-`^x̡X\(X XuXVB&Uqh$MKЅ6jDJV9Dc[ |R*.WΖ6(q4,BUU'3WJ8FY wZ;gP ;?~šھ}_"g+ME#hH!) OEp?{Ou>ۦtw5Nqq2tYO$&q6U"$[+uwxjW 5p7# >g@Fay^Ng< p E箂M #T9?pOb2R^u@UkV!_-e̸' 3lCɬ_; \e"oM澠$t62e#raRj7;<|;#YPY0ՁwƳ46r)U};3A^$0Ǥ-& 8}{OXZ#V;aA4<Oӗ9 > Q$p R!J(A֋;sQ4IBE׊θ:5^6Үa  \ke" 4TBJ)7\&ur3;\lObq_CEʲth<ϵqmSꤱ2ٗVNO_ p%r-ߊG/7LP:B^m<տ1tW|ǣs|6 Oy;<5CRySlj&+"YÏ/^7P2orS;!p)/-(J qOFF9,bиjҖ"7[$dܫuwMdr-=A1`\macSy~* ]U,Nfzt'=\3Ghwg; 9yi|64).Qye*.j}LhCc5^Go>k|+f,Bf9z]mz^hdSsӁZ" W#Jdr 263lpX*T2Dޕpk K^zUքmMhjuB]UAkK ܙB" .jy"x}Jm G \/@eo&&R&^ YRL H%5|{#a`1$ttp)"s= 1AŤ[f|=%}vWsQ:T\*M!T}M-Y *g9wg0`)mnIІHݪ?e~*iD/.a".TNucҿuѓ+QkuÍ_R_1:sLX\.I~䍽>ާt_-O*@E a)}WĝF<ѭF+#Yyt,*(fXƀVV{o5Ϫo;Np#(":JĹ>TzwFff#\t1-AǴ3):q3}})(.GN߽ ~5_k+t&ŔyxM(>`&1;"FjY?ݨ ٸ'N6E壖M.Cm!lCbHԛzefکUe)j9b𶐱CBbw𥰢pREg٢!X{_h֞;Sz4b͟<_e B-./YJr5ub"k 5}2vč9uɽʛ@XĠyMUW<6snrZ_'7J8$i o1 5:Z:i5#X.Ys/h8s:WMPĽ-^\ld'&!Ej [̟c-՛W~6Tp,7P]C /ܦEa,W]8hT`B1`*`Ggrա]FuuM.ΐk&"YoKw^ZJ&iƢ5܀UWbFx4LpDY,}oMFcY}?.J5"y{ھ2GFlU>VFkZj7/1p>o"ujؿFHjMl$Y}2pǖof˽A Rne…޸l "(@tX6^fD0qKYYdj9_:d]иZ>X^C/X8iP:Lz\ x77|3p*h8n.%,}(Q){HZqyz=HQ~ZʘJN$_(sZeYa|T$ lKmJhP^y#\I :{pQҐ27Bj[L" 7}NIg@?AoR*wFiyA{..%GU5AãUjNi" m mA8r>gYiٞv?RRf)}➒sWWrYR?[<>%oɟlWX 䑣1.`f:16)2faNeg{75K?@+%}m?Y+'wS3=еDӁP,\Jz>{i_c`kzz9,@fh{،/qi(9IUh)Z-k.`FH}0_O+l{IcĞޞX%e}%RQ!k~;g 0 Sa_G c;r.xxTQС@oiEB9>n4⺷8+4p Q9>gmP6nL܀W\`=KB{;HOtD!PցRYNP+ʋ.YEo&3mjŰ~'Mg'Ag7R_5?lO &pk̎fS)S\+&y{[3 1EN,l6ŹiUd`S]feB ϊB32>e{:$`D{^? @NnXЭkp N&sJ"Y+ i :ਞBkZf?e0C9vɠ-QZO$:ʢ V%HPBcݩe .(jf⻨f@|'0FlEz)Qg\=e5*:v`MNխט: 1ʫNwH!'AZ$u44ۏngη[wR{|PTɹQ==x_0yXr斿LA"A)G4WYT%i}S9l܂,5NQJźb\}}&Ga_ 4Qn!kNyp|;±PӉN'^h^_:|GNL\^*!d.PH*Q O<^Y+ݱT ~(9FEg!mv3<ʼnߝj ܛ-kiS -yTLᖈaoitO0HvA/lY9f:Fـ T8/C$V3eAyk*7>lt? Kh=JlE7sNTM-_tlIuFon5jsB|u$|̦B*wm::_]bWHdFpVa?^urzW7'F:9fg٠UEY];ʸ81+ܙ:.E|S(f @ٯg^%},?a#I8tm }uYfL4ܾj_;f}H1 z..Fg*} oĿF؎nBb U82\ari%FF~ڽq` ŁaLq/zpЌ AZټ9t"1Mzp2UtF&NعT)k?zUcLG^$1Y5wUr 0oQ#>tgC@j(򰓿AqHþ,$o ,N&B @>5 C?E%U\жʸqz%.=R^-;,1z)Cu YꜘOLछvAC}A),6eDq\VWMt^o~)=Zl_$1,߿h0bVP1-j1 ~(4AU^ ۰{ dR(q~_n ms>0Tg ln n ߥRſG|1 < }<>ۘuse`^Sk-7?* cJ?o^ hsuo[V[B֗׃f|) @d}d5>HDU%6oVݳE)n7V7wKzTB4mk{uSMAB2d=5M$K7E&z*g=7łHuD)(ϗ8!D>,.ǘV~$EMw25 i`PW.zrB~|1OIH奮N>$¼"@Hmg?t?3Zq;8F[*xC*c< XL:4s?3_.]+.f<ˮL3+zp ` p/ċ?DG&Ջ—4i8jNM0ma`O=CcԦ#A|O b)]@#gmq!KdNvxV 7E?tR)_FΜ, n))V>C F.[[gV^M'3_Zjʯ3`P&?'#;>h8ٞJIյB㻂YWTT0ҁpEC6:bzeyޛ|M]qyPaD[^jcIjg VPQZ"ˉ |Wm <Ľx~0#+^7'VL8Y">}(^fٓ2m??u)Y\I/ivO3iw8;+l p*@EYӜ=QlVnd'Aɓ*DfDl_hԜQ qz*M nS [0fAoZݔfArZB3ʅwQoe7|W;ﲗ~˕I)DGlzGҗb\9w1y6vڼ7W>*jO  ˭"^3mNt#GHOZ{ aI& ω光T4 i?z?|YKW4/c\֠*{F`=ld-@F_|)~u8UIq] _x ̒E.F ܂: ~%XE/ هC0!tMs)mS i_0C1^G ~L1PR~)*ZY(xku7I6ȋsxY s%PE'C#(yzcu@g)pc~4b 0~R+k7PKS<;@\ѯ~ۓvYẙw4]jJF*(~FQ*О}'ht_t>/xN /Y.'}&x9l]o^,r*^\ &6K6fJlJpyt"b3Kөk)QUsZw&3sA=*Vn{galQ]N3Έ9r+2L` +TC!Bv%/r~=oF 5$7YVUV{ohKCz1f/fXTnϝR#JJᨬCUTA_.#:Lͳ6]{ K*f}p5Y>cp{2*] J2+_;jMמ@~]]nͶ'N찄#OЛfBMζ9dIEώC!/dI\-O_!.;ā(ٺ0dV{`ȖBN0K7=Sȳ[qq620]k}QJb"܏{_ O\%mR_2kܛSX4%!BIM=S7uj,$k'`~jە\g47'6c8yi@ p2s$M|{VM(%8>R .F 4tr82ZBl; 5 ;`(jms=2(}X?YY0ce ةyF H69;3S0gЁ0E@T|DV-aқsk?%ӅKVDN &B 454.Y$-tYhU@zؖk$NumvredhbmbRڥ_ Oo9L,?d@X3L#vScT7L5.ͽ#/|h}=JlĈCq/-Cx7γKiDK4 -xM5rۙNoV %K Nug ,FolT^v%m#[9Jjh0.׽d/7![lK恦&R û^'Ja&Pc:~^ ' +q5{{?ޣ=]p'fٔ?:sݳIsG:D=!YmP ˅-L}\5rFgqA>(vy8etBUӂ αFHĂ4h1uB3@PeU'^͞3HN?K.4[tG' 2LH@ҖdI8\hʼ ]{`ch: dM|_*O҂oEcchS.aa3w8*=sӱoTž^{ml 7*om@=7[Z fCGKK2#|[to{Hpz_Ĥw%̔'oY౴r@kj2م\/x9E-V[Tg<"S D[p5[7 p%n6w?I=ׯM:vU.4G?8|KoW}g!Ks:'5 ?,^Xk譁a=ls_RKV ׏/̻F~+ݪ8nG&m=*z4-omž6\ޘW1u=]D6i557`ȹeCcbsܝ=W4ߚszꧧh5e-ARo>g)(0t]~ oB:'̳7 %e#e8) f0b~FQpH. N-{"~߷ff.ᴰgI CnW J5$\[>zX`P#]QiVyH4fWtutCwlyx#qfJa;n2?.90m $”}ϫZR] ( Qkl| ڌ\m`r0YY(,ٖ=U8* p7m HDQ(z&*3\̧X J\}bKAr=|k Y´m 6h̓釾$zsH,Nb޿X8&?#6O!FB-e'$Nj^?Mjҍ z &k,C/ y'.ܙiq@m(M˄t!| )6 Zʰѵh3Q=~!e%(yZt"aK5⼹RZum +&xT$as:bh>З6 ʂP[=ɺ.mqԊMUd b[i}CkX>胐ZĆLw8?X6=pу.=0~Zs(m|/ h' hn+SC*LxXgEUS-թmv.XY &R64ҝ&(.Q*aiSuÀZP?w;vsD%|O -?|௔#942/,Ο yD*d$rasٕiqmÓXiQ5%'wJƞUcSW>W^`dxmu!+g&%p/$ NqƛiϞь ܈ノ(^:|-_5YDJ]cW?؊s㛈 cн"Xۉx &,ͳނ8p~)pGdߔ$잉cvgD774tqU5_ܢ3^!nHwȤ46s;] [k&sT |0l/{l# in@eΞ'MZG[ ;ӳT'UCQG)K:`y56&{׆cN\NpOchpoZlll'MuFӳ][8fZ03,&~%kíg KA;{4ǗH BnUp'OzkMzꐺQ.~^ m: ]YM~7P85BC7gtd5~+k6S:U9T~}|QH>@qwJ3"lAihz {fbd&,5y7L5O/i? W5 csi2 iőghGao\>21.Ue ڞ1 ii! `Ap~0o@UB_-AIs.x[B[ (X#I`bQ=H[E}ab:z@{Qň1~wQ}I5siS2d?@C3U?I1{(O1%os*e#w; KmC,d[ܭ $՟tFMv<)3? 79j}4Dei?]0Ӵ˲vgxF/oF8/%qݤn5^-v iJNB-f^:GeR=&*܏Y֝#8y!UioʊV Y`kR@7]嚖gۄNJ,Es9=x^Sc4W?h3!il )E$P>m} \VIN?5SpY(Cr~_m:g0I88RZdJ*P4-*{cx;(Y!ުB`{rSd]/ϲd%ot4X Rʑq$g9~PO*GE|E%BI,d91Q:8cY :;fxTTHz}NWŹ GN#ySLY/^TEk} Oޢ-rƸp` m&upRhlGCA5DՆţ&;_Cg)Vcym\>t7/)S lJӢf 8;o`e)~IoL)qUomyQmCIUz<˧-V}W3Qh=Tw0P,o]󄞥jeޒ!asZ xY* fe ޷u_ŪfP^c} BUu9bm}+pC$P^ӯG,o%R~s;{F^l58pWđkB MFrH7Pm!`r!N:`]X`Gwϫ)9}PY QcEaP,SQ5ހ~l}Rac["Dל!YxP(`:|.))ӂV`HF~\p@53ʻkiq@SCp.c#I\jVӍ]fTg/[mFYycoMl|,U2嘤j) kGL)]2 Fe5kJp\sh4 뽿ݗ2ߝ(F]}x`yu2+锢weLw'# mb!w{"m0 HskvN6VG4ە0M^8I9=ɀ'y腀ve.r5`:b_j/:wH8 pq[%sCfg@wG%+G 1+I&]_I %Qwd.LO!ӴejR(|{ Yﰫx _o9&Em77\^T"^tYF>)(AGaQmV'"pui77 c]sh.b{6j[M?1>TG4!cK Viv-ʙWB e!95˶H2 *wOjdnt0rB&#F~D46±z;L,YR ?>])F[,ڲz,.e ki"F=L}q?F8mWy9;1v#G?ofڸq~Z|u$H(pkJ@cc*:١̀XE^{D~Rc{= '$[:Q̏aw;̬.wW _ +OJ8>Q7H}/˜+] ؂Z/ƅ==I'Jb\]7+gɳ:ۅWZ^̧<} &׃GlM5.|8Q rEt]NL֬dS-}6$u=2Q kmfm3 ĵ/'q0*X]mG`kZf)s&9]hVLDl8eTV,QMvXzbwZp۰[xxNjJP~e~3 Èmr^ᗲK&x%éZuVY3>cD{ߎ~[F.̈x㢊tW# T49y 9' u$(RU5'M.GrEqW$]ğSps yUru5gRrX˹Q,$@p!_ ȍ] tU]dz̰WtwxqEmhp!O>5,ؖfgA1bpE?)ۄtf !dzP_Wxs%b~jy,sخ-G],8IbF˵0v) Ӭ%FϨ췔"2yO$AF OR-~[% dQ񳆗^b>*:0q?(Q",Aߓ|.,+臔)X\0g7KK&a5*Q^;uIӍrijD'#) bcޣPL8gڼj (TKA_&a0V D_B$NGKr] fxBQ#0[vzlLw3QOjC2͸rO\F:=1V};uOxstAhh `dKF>&H(JkOtc>l5lW!64 6Zg$ BvdK.O4ޘʼ3M\r%!c&F2 Utr IJpMtvq,8tkd|QXsAr`H؅ k2c3uM_f|0ZvW`b3žf'0*r3J/d=-5t&Dc>0'@~>uc!w9LN>ۄR ]z7Jt-L$;]:YW%a9!J_HJ*zcr]ij!.m-^ dd}uO$:6Ovכ(<6y7bޕQB TgcbWln'NZ]mgKe>xO)2/XEl+NN:; k ;fsL Rp &bwdro25{7B#V]h[.8IuGB+kzK'3 /GJ{&MF8/la3ے @{W)!76"u? OwKfS435¯`3Qɔ`H#u~#o*<ѰcCb=)lz8.mQp_RFx4!Od~XiV%cљSLȝLzAqwtv&^ qPԛ#7ߜazof`#kot4@.8u\FX+Q¿VT(U) f `^=JL;KxY=R/#8AZR&VWu:IB_ps4ʎ診1bX>pw0u17(s|ב#_>^GT_uٛ?jBĂߦF#4 ޷ikA7y݃uzmP% ~E7kw;Z>ݡm B8jj&ZÔ'-KPsof =sAYJ=)ϻ-OqJ.>?}}Xr(JiFnr$䇪>ǖrt ZҦ)T ̌<#fws-Y^G*P'n%q7-uMNԢ 0J\Gi[e %lTv;?S=Z0-XSZϰˑ̬?nY =;44|֖ {äeS aϳpN-5¨Bw{r,{ς{wW[:[~w/GG후D[Ͳb(>96R=ޅgYXOC37%:ɡ$s-1{Y=O|S56z}G̈́!O`ʨBha[uvlLū-K%d=`tМV&^ ưZ|XFjGitxF{m]"*h /EM5^ѫscji8h2NUQWiNJtlcD3,v7 p lPԯ./&^JU>3N oon*KLV{ayn$%>@4YI00AD)țRom*/qT]5455¶*JFamtNJnc"RJl IPӲ샧GB6LJ}7|KvbMCҒq"Βpي\"<|KW"bBۮ/D3 anU{W]D'Nm Ϲ0U /P]Tm,ٙH='Xk8ykт7'x5zNi̒ԏ'L)F6p3=$YDĎϟu@=&^u2dsF=affۉ#|eحQݵ:W^%℟>BחUiQnV,C saIp܆9gJ"{M[XZ*LH1OEǩy2azz4!F|g ;^msBCjĻMl탶֙CWc fXI^ws'D- >Z8gz^5r2xP4p%8N˧dߔ׬\ogx3+94Z).*K5a4:S ^4ZJ:V#vpDAAr6tҿsS`X!`_5#)(s:t^gn*DV$nCqbYډ>Z0e1)s`lcLmZ25AȐ?^QָLIn fP&ߔ{@+MBnKPUu؁M ,BKjd]M`exJSysRLl}DJ XJɝGcoIVwRLeSũ`觸01||v.0Yס['{%":笈*V`MY@̲judl9JD0qˮ[(u~kc+6rYbnd tt0}LNά)ōD%DU$P43HУF1[H/~/FU(ɡbtȝ)l*o0ÖgP7 CwϯҦz,Y+D^15R<b:˦(iv^ zW4=+75sq=s(2iPl⻄eGu?`vp単7/ަ<&LjA"kM}xJ\ /vV=8hFNo09O%lEC(!^ܳvB:Α͙J\CuXvttLF݀˵\qx8uOTrnҐDO(HY]YFBڍkοEnݯpPȄۚތ5#ﮮ󲊶EͶ|/DATpN'ƪy||V]Ϋ8o|-{OPv[: w af1G,*onvX,-UՐk+8N:el%^Szn{bHPn>9 %8Nq- n @kTOR j1je**\4BR(?4/LU1QQ(?#BdHz/s{I>M6M Z'0u1WlZ*1:RmsӃx\:a>arW|/Tm_>Ǧ1-QܓG.L-u_>టx8xN<} 9OVٸWsKЏ;Cj+IKxL?+S+UH_w46ɒ L<`R'DQwRˏXkD3~fvDܦ9#xwj析ȐV EV2fkúCoNPU׈5GG,ᨅ7ZA+h;1oJaͺdve[b : wrּ poQ@yߐ4 րmOv, =(T[*8,ySչH .H61! (W5(Ƌk|bC6\-],]T Τ|{jh )OY{Zm 57΁P5}hֳطJb+&OYfx+ !(_rŋFa deoE]n\S`ԣ㆟$b0 : XK@q2r|P+%X,{pf~1S@> ( O2>ۏO}2::'agj*L:!G=oLO{^rZ ldKNWy}hօ_3>Dܸ|XVr Ll 8C||60|)EŖCFlE"(f0;_Z{ꅂ ||#= -;~PdaœHf2}կJy>M""řlfmKh>k t,h\Iojm٥HuNW$n;^ ^\).N8ӰC%)Z׬R!!`J3~,d;1k1Q`H0¤8q+U;JlȀGi동U[=W`YɐzN)-ł+zkCbSAI/O?*Z*t9=#[x螺&0A#9vxXq?使 5 y&`+鸽I118Y{:i>nlpo`Xk JV[)="ژhPܡүeb1<'`FH7"@&Btr\* hyƫQۋv=Q~vÄtp7a1КREfݏYۃ'+W4D*\h*n/~6qFg)L!']͛zJ kQUr >k< g1Ã|x-~#YͷcީE?J pgn$0cy ~=V.%\jmm\HUы0S'6tSoq7hJ(|WD#!E+,~z'LH͠ k6DdvK9B>t7n2sG]-LلIQ~ .TLL&D{R0rN^(Ս?F Th9p#+ <6=7XV^k%X0򓋤ye%b][q+῅bifr p"Eҿ7w6jgno#6б<8oqpUd 4'nM02DMwQ%hT%wu< &۝:{/A1r@=pt ؗT9:*!k0a?Um ]o q=]a#h:T3ywy4+V&" 6- >7@r"@N,IBSƁ6:g8R9Nj}2;r6+G] egG@;˷&;^瘔hkH=Ⅺ'bk pz|OJݒ) rݚ[np8yM.$ l*3'@4Q~NPWbH3Y'V{W8I}+[~!v5|bV~>JX'g pl7vJ8g}tw]=ʨT;]$dz=:ǿUo<LA+p:٥_{aqh[ᠹ$uҢ+wQZ#-U(d8uJMh JYOM5cIjhhN( .JXkY_A?r]AE Uq 2Yy\ʞTR@Cb{_UwJZl9C#&]9\^p̧\D60[/Io&|-{o*CE PْT +2 C IMJ:W0Z뫅FKG`vngVDd3<+pLgTΠX v&GUq}GfVuwzs*%OR_/=?ˬy_?wQb G3$ CNRJP"oMRWIo^2mᇈ[3p/{q..Z\Ks}:es瓓_Β=/mQעVj?L}]ܑIRh.p\H3r֗?{Co0=fvՖt&M[K,qeN)R۝WY﮲oIEu/ӆ7qF;$ړdcF s,_rh'DyV.OxNْT=?4y={͊,!YS>q .!uap\{ {Ow&N)ݪJzyjtkt>i1'u&h(o#OdrF=1}GZZ3NMH[[p Zqn3T\hsͶ-K- mKяpc]͖#nH-QLΌRFQ{q$q0"(e$/-qvcR%7D^JFgL麄)j6na<4ԬͲ;jUfxAe  {oI4p|0q$jnk'ϝ([7t2zd?K ٟ7>qP$O ?Zݕi=7"^ nX1% T0+[Ri2`t#zQ#g߯U(?cO#`KϲtiHX Ϳ\R 7pomKcox~ &M^M]y{Ts,p9^=F|W2u7 mz:,&Ư:4OFX 8eE_қ[*t5E /Sv eh26\P g IM ɮT QGn꾹=W-/5TXKNFQԣ^+0Pj+?؄=\yQߧKf/?&q`.SI.2P~3_W}.ԉR|=%ćr`d {pfnd47^u˷V lYb9/wʨ,_?A/)8#mGl ) f8la1cL &:sr:m`7fF|#m*1p%\ht6яZ2{oS y&1;=fpQb,)IT_6uu[ ==/MBg=2|d(~eqh|AsV!1P ]]yR7n _Rs[ҤYm@-nuTF1ҮԘXG8W/WrKSv.YV]3XP 2pLf%jNJrq_\cs˂O |%Dc8ȖMA08t\Z="v|RN: VD1{[AhHj.vׄX̿kΨpc^SLFY`FBh{3+k=mI9{c祺)QЗEuȽ d\mc%ɼGUUq߆x>t^R, }o1V8Px-*O׍{DRtojVyG1ODk@?c$tNEv^J>=Bh Irha۶~bUsG+.*H iy߽;_j mm +{8쓂$\ )l@t,C6m* 9p%F V쩋1 ]DS)cFg2`cZrCDI Aq= j8(&XV0{Fb{k{*E~hÎ7YKS.]n*U1ҶJf19G-HPp> c@l`}^CQBBPÂtala.{+)( uFsT~\J,jw%Mɳ`^’?&? b}ѩ72Q  SOW\@`t6a) @<Y3ۺl#gj8lsD2Q ǖuΞ}.gek_r9uŕc%i0>&FweMX)٫N yav|b _9۠2䩳pQ-l>$,Ԃɯ$m-Vd.]d떦lަskޠ2 ʄeܕBْlYpjҝS*Oj(6bnҽuIy5T$wuSк9˹u=qxnYj:ԽH/Ȏ]"IqgW[aY>庖(OOWj$#^fյ)ZO Ɩ 0Ԧ,:>;=yNv,$Z]9|Wt'E~1v*cg]Gx̮ r8USS;lEB1Y p׹hֆr0xmEFvRNjTmXzU!-9a ZbJ+Z%e%`VƖqb>lś55583`EmY[*z[#Q~]]ܖ `B~G΁J2К&re#v}Uz?a Q\aKwڏ˥ yόGy*:%l4\Zy\Tǚ-2jx.:bA~.*^rk }{Njٹ2 ŞC(GBlmuu}I?^ b?Ȃ.ahzǕc,`C~kgnڏ@6ʊ?K,T9CʇȲ)K]zp~Qk@ZnXmRr"k7@fg=ܮ{Ie$ڗMvLF;/+l5 +VDƩbWUfci1w->Snj'u9,mzΚډILѲ+xM_86:1!qAQ>!lC>-~&:=0pڬLRJP<zxF@VQ(y۽"&?J2vMoÍ`%^E|W?|׵kRidjԍoY+Ivݯj܋&xG\Gn2H6Ml=UwYYjˉx}oK,}(.wzH9oK@M\׊|55{4mQ& a v0е)6b-vpFe^20r%"܌p\o]~Ek677cc'& ?IQBM&*ͅ/ MYS Ats_]ƻww ejHHgi` 9buh]R/5N15=a#`%=$1)?B]XeS,:!{=Dtҁ%2Vj@Hce9I_lYAf 34yMw,,PxThX5(Vmh7i"' 0a}j\xSpJI$(a"V\[n|lV^Iuump^4 #尵b|-X>(ɐnX%K3?DO}v+rsZHgOGR=7N8n1nw);85W(y$bDleKeCw*y'nfӱDBHnǠR%zicT]zGڼd@$u멤nLir?~>g5cT8?4]ת`Mb{D<*]kBh.٥qvqS}i|0>'xj;񡙂v%D7A{s'L􎢪- Z5|0Fs0VkEg,kVc#QyU Sؒy|1k H览u,wLsvϓWފ{оβn#uLj 9yx၇j P{@lYqҷKfmx,\;nWB{$-+_-e6A9eDv;ATPuG,btU /@+\/^;ȟu𯜾?vO+,N>v.:=&(9$ލ^JQ9t!<^DaHu\C*=Ѩ&Ɓ]¶oc'DE`&G0vq U]xUTK_O~fّi^%|~Ůr3n#}Y`x^9yD&적iM.#C77AӔ,e{\(aG */tAsrM Sԝ.Và6pR2`ZEh$V@zF-zMLL)=+Kƹ SSg?V뭤Ć=/̖b!~; Xjengؗ~(='+*8p@l.a5oZN%2[5}Vr0ۨ|<>Ap?BՀ~z wXqۮxj)sM$Wšm#ɳ`M* {[3Xn_ 8[EymYwC<(=FȖI0b<,{"z[Nx#~XɯwOwd՞`VAVӐ0O 2*"4}D?1M_J& 'fܵo1?<͈g'/e5G3 C2-ʽ] q%Wx~Wtch$8e L6lY\T5(0_)*6BDDX KbU,h1l"I8ĺ|ѦW{X~v+ o^)Ŏ.م9##tkIokUW֊Ny恠ɿ@9ɼ *F9_})0E tn^#ӌQ` 7ۡs#ҝt#آB$d⡹rb@_ݑ?^O®]IY> )8tݹyJM*=VgPi# j~Óq 56+ ׼0N+FzaV#kE5bf\ K/9e(.ư<}r>Wي>l2,TãG:h;*&-;e,+3mx%`Sw]"n%UBQІL$)oyLQǼ[_ψotƽϸ)-! 4rIl)0q3\PmDu7}' jqj!QA*Y,dJ[~bS7)J͚UW EVn2ϤweNb);J8ͮJ1QߥNH)#gOEUG?GJEnye/sl$E\=4/`id)wiME|b,4zQQEl&u iZFCf6Wt]T`/\ភ4̮t)8@'>Yb˓秔ԇ@v;.T Xƞ)e]o̴c̄Cpv-)[z|:8-?Ln_fE_")fR(o\lAfYJDcliߖe1{>ve E`G*yV/c}fuqP2w`<0EXAEQP*0U:#d3lb`0$ s/ .d^U0V}K.p c`dFTZ[jYyz ((v wP\<[vf syJ9uTvׯs@)ԏCSQj.,;q@c'ݿ~ˌLZ֯S%j͚\,lU+9Fa%+(۳M5+O)PA'>WZRp{l61$ߑr41oŻv=% ZŐukfb3t v!AeR߳+ӑe+IߕqrWjDG(sK/mihYM ;t_]-w,IiFPv4 VLjx+0{;#Ln7/(?l>19Ut&)/ Wa-mJ{)ׄ:b+lyKGq˭H)37H_J%˺dĘ"d{؁r6H lflj0 n{Ag&u+Q5xӚԮش缔#l ب1.8[Q5V;ѓV a*xRK_o>x;ƚ'e&Q:(;S3g :ZOcS?F46 RN ZHl9@X +gQm !M5S?OCycQI71]#Ch 0J]=w͆,JG 蕚*( ~ğa3lH Tn֯$i4ܶ+6XZ qCY=̠{fc&32beUpU~sJIL-OI y@,jcQ+϶2VP6/g\GfZa:w(E-nF=•#.C2E% qR8'?'C]m`?u\Q^9?#ǩAڐY#3L"kRGH@ՂOfo.2dґ!)ڲVa ohf s\#Y{u;#Aܶr3' X ;59Y>lU>9B( 8 lhP=i_2ù/'Ga-XըUCx瀚` T"'4 V)Up9$Uj{mn--*͡]q?.& Jj6s>T VN7 FBہ׈ ]7&7gF-1V׭8j^R÷G3;3#={ZUM;f>zBULbN/Xv8~a vK gJ[+Xvxv41f *F&XFO=(Vnξr67RxsDC.Ʉ̌;fמ4fy N6vn=UBӧݓQ_1 e%#[ fF&T[qO=sh_U)1qªi*sH@8:䅄~åE^F,*J>M+SLlNFgP6TW ŵ *sgzxRVaK\ƒ ǝ::\ 1.rP)2IQGۘm.6_bsk4y^O=@T 3 HHs >]A*zRe^P\,0J'x)}7*dޥzh'_=FW]SD£xe%̮YvF961.L<}{@?$Dfy ^-=䖃rJQuO201^o=oc 0/B$CI#&hte$f|^sat粩\Ui _X)ΐVhb*ٟw#GS.{c6A]M*3̕w'+i"u40'.s9L$/,yqw=Lf>͛\qV~ED̘}RWm)wS'9 6MNm+ai4߰Rc0,e?xC&9Pf5ww4{{ DžFR*U<hiɐ! k:nݕtUvhѶ$vj)&i|* DĀ ~ :ت 4́`#?t\,64(9v#@Box JQgg̮c.~i|B[8{c.4j.k1D6BdY==|dSS}$ ǘ p)?<g7V3T :G8L(bKgOFʋH3 kY<"6熔;5Q !uĂy.~ cиlODSƫ `|G,-Biƺ #s=6П]q9]'%7 "Tu-@I1]E cŤzMR{-7a[ B+wa | ׆PtYrM"N1FʆO2|g٦R܄l[´8y1LZJ4%dn|Kmw?if5b+Յ?]9,KnnbZH/ͳI]My7kCʁ?J5 m2%$5AJ&DJ5s}p^GLX޴<%D_ Y`*ڷUwyhQZZ VHH$'w^Мz2]{兀6wQoOxO @~3.N 4@EYM&K$zmݚ?W"i|J(qWq@h]ir<[@ͥ!&ȫs@Y1:$n&s_3Nя ;,d0*JuO&6Bnnr>+I d&UuW)4I9 w.(6xKtڄd[/Ĕ r5HMy9vt2t؋7\-_y .g ]Ԑpfw8![ǯ>2jCMl>3>VUWn%txsLcA2f[ 뛘(}Mo^g}|h:;+ {q*SFm#I(!"nvH^{@/I:>p5S+/zup$%6uݻ1tcaP'[R*#qegͻ$-%hV p/\B1rkҐOӚȟ#=r5z߆B/=ؖBGjVl}͒dT{v:!:x(R|\/ q&ȋ}\/V7D a1 L c?W9`lcsmP Hq׻gvZEPܘ()K/ʄu'}S1QcH-JMR|ҭC>-ˌk'QU iްJ'OKt}|q_sqYlt#]b"c^I8|0 tLOCF3ER%nJG3:OF,CޜB?C "K$6N ɿTϓ|Zb׸QRR8ȟt?%] ;ʡq P++еSE]Dz{%U=rE/v8鋝·a!# :ȸ\k)+ M ϭ!?X%^=Z?heFE'u&Sq}/pcp)-r'D-YLk)B]p@VDY9܎v>UD 3R6-Eg`/4UY?7~)#SC?!=OIEzG&~ Ͷ BLHjl,rT٤xy͐5C[_swF󯛚⑂1/↵YsʒJ c30EЕbPl4FJ v Zm{Ck6@r* қ]v2llsg5~ 5|@,'qnk_PJWVX\;LtefN̈X2#WʰĵwzUt7G ?!q5Gqs_VTgr\,(Z|9P vheTrRP5ˣ=Y;NQ'?i!~]`_ϕݣ^&=[?#j xٿBzraԘvou 9WTj/*|Mx\qR.koO^:@ tސjmwa@?N:qn b3c"rz`FΨ밙[ rYԯ+9K92*ɟpS}hQ>ʹ jm8%mNi3;, 3꤃/<(LYiQ :N;@_Jۖs+i/yIobP"b~įm}Qzo1|]BXX͓,dߑHnk}k3h.JFbRv9@&}d\B.P[^.`5nhB 2GnK)`9e7XX:bKzFHτLmUkǾ+0 #͢$ 2~A͍{XQFJhB0խ-TlyuL2&7?~] j۳6ar*i+>IM"6p`kΤNUtkpթKL; NXP|u\Efd*:qFu>ddYMLÁaosD<}Riz|VjD#7͟q1BBUcȒmEp؉[B;8ji'(D{}DS_<.(e_6oOזSV>n NpGծV_>peDSѝT$6R (L2NM í3؞ݒ,N%@akBw`+ y_ |Nk}HS2c|x@nU*\x` n\ZsgGd}FR#\?lg^ER[VUoarNJ 5\efeUY^,n1i@Iw=2+>5.UU2wPN6Xє WߴojwO)gpo#W.\~k ljo E>HBu`361'X'7: j>\e_7YCHO'j8:,ɽꩯ`onQjM Y5TJ[9}UsSgXr%]D@J09ΫBXE̹ř]Uލ @poh)9=:rŅmmf6VqR𛾃Reos`ʱWZrƝ7v%-m_eX$҈/}N8D} ]$x S9q$[|Q q`#֣قCxz]P5!Ӥ!g =ҀB W? 3J5`/2il^r26<^ʈ:U[iO_veiur]^Dl#`T]F|pX}hJ8oEYۻ?xFoQ'*֝B ~HU륊 ~&Zo0^o{$Z-xKC🊤68m)5g%s@Xes}{q1l?Ÿթ^LCrJCɦ4Vջ <QiBpHf8ARI}f 6/BęΗ@!Y90^٘W2^Dƹ<*lS#R6BՇkbg )F?~*m5ܥw [>mO.W[oHA~nAoCD֜Fk[۲. ,2CgM: ^o΃i14*E{4D+kRJJs7CΑ̟)Ýwm66긦A;+ ~Ve?]"G~vM>-;'5eN1l W):@٪ZZ@J13,pM4(pNjBZܖ%fK(5Nz^uH#* uX}r˴+.HRuBgCe6`r:B0dmHՂگ@3ִIM` { ]~@21Zl8 IpoɝQcuIaaDŽ VW9)7/NSY$ CHc*^[)dvJ-N 4p,Mڻq|{׆^WRhTìJ;fo_̀JϘMƨ!8 eΏkbEξv͔"idԢQH @WQk;yhك Ͱ95CRھǥ_ 4]ez^t 8F!L3Z2@! ڠBjvXY(@ }b+af|uZ3[};.Gdh5tfBY(迾̣OgG\$" 8 ]s[!)U sܓ$M8IT+p<]oO8B=q a+ﳞj?wOmT!CګMQReq7Uk-F0B82 ~q1 yDάDžj yo̟M^E'XG;JI,2\ B]h*J<9N ÿy'?j7"՞ʱ+ƣ*jhR) =|`|KX#jL:!GM"fa[Rh"ދ7{O#v>8vJ O\VtC_9}AW.T 2týу߭I=1IDp̜ފa#w#♟K:ou|{Y޾ */ӣS(WD;dq*pQIqjGmwFOs/x}wI*`#,Zz?ҽƒ)LVքl՚>c/z,R[ZnіK9jEVV. yª N*ĕ3<8b$[w٠"q,R`GS)۫R!-rBp?Y ٸUquן)0Lzw{bU)TR1^ŀ2Z__H34 !8Mo Fa% ~J L笗mHK  vnh <(Z\W;v]q{fkib՟v"6_|ĭ1kλ}c3HxӕKG3?s[NF!Ʒ$CT'K `zx>J* '*'n[2w$l57*^ /s汩x&[Z-gȞL"M*qitFзܻ忦N`Z4Ss~g͈cNu7tgyp0Ȥi3 ?C^MKnNk{C!ko6;K8E*Ŋk0u."Hpm>\?yo%?K\% Ϧw UjHA~JNGhU%UrO3`s 2o02kb>SEzϱJdQ0gPN(z1ƅ?v2?to~^?`vM3V}L~pwsɤcZ)*e#|QNlHYu+R!P[q&=z.!w:5T.%o&EDjGmˆUat҆h5d(t]ʨo1Nֲ|Fc2k$ xKUCH Yy[Y4rB3'#.%׆-JhZ~2"6byIcnOc6}{:/VZ{4T\BieU"#nLF }́m̢?z3ے4D j@ogqNE,h@iN _?Xh z!'iS7Ҽn*opx{fޓ蔱 &ˠq k!-F} $pp o e*%-,aS0E2|RSH$;_[ i'Q.CIXrUO*VEĈm[D0mN887AzLki鬢6W 3d UÑM3Cazδ}ʶ)X@[[…mNb p ݓm;GLڲ*:{_<Y'h>S8ȱúq1[AiEAf3Ÿzs1EEl~^y;PHctKn9$rl<>-!|AjDWp[EaP)iIЮlJ'u-vv)o fv/A{ 㟓&({Ⱛ_3tgM<~o]a"f+huɐ@'~f>ߘs}WBjܛ>8,g#n;oX! Q;- qzbަJI3f]CYC|"4ܵ璡HT),[C@|.iIsk2b'ʠnWjjwqiU&DXٕ u _SEZ/Ur>ʰY%1Ë6VAY,+cRl_?R;jyd`oҩb{orٰ[|AE^N6֛ E(Q\f~;srQ dxrףncҨST E:S̓N_ 6„ɿPj_WBߵ$Idocl Op%".g˿qv Hl`tCAExma/tVH5n_.^UjBoaD[>[fl~SiMmY] Qy:viJ E{riu 67}W{GOҁIՆBtԄz1LEGf?cpJNp˾}䔺Bv=@{ ?ڜz`~EYN豃^[3hxP;/fw=8#;;âZPJյxlLlURHLTzu[qSy^)w&O"#/[Δ(Pd G̳>- r8St^`[:LF4gmGqsA3ti`)_t*ωфvb/S< IGjĖӬo*r{E{ŏ~W<-8xղb3? JssVvuEF*XTtu%*5e(̨{ű-=4:y߹Hp!5)?rӚl%?scjH[X Vxk5VEYb:> j a`J ܋eIJ3DZ.";}YW.p?!'}"-o?j v dLCvMI{|{2Zs+)F l3(j} 7_<@: ӊsUO9 lQCY-*5lŧ&X3rwn??Tv)pxF8܎cF#75?eM[cƦfO,7Vf2C*hzQs<}c"D:Q+r{vԉz򊗽e>ʌ(0_&z>#F+GjPG?5<~29=DoaOqʉϲ@19O{";T 5wN7y ^>1˝ت 77w1 UaV3fU(Rh|awխI&ld*'iXЏh b]B&ŕ=_dW] c͗aНw$ro2s,#ւ~3@RYW'`BoSg SNLp_}%Vc?Mޙsl`8FeJin-=Ƨ|rՎg Q lz]@׽9dp^LؽKWh{6AnmKIZ_rs`(Aǯne Zq'Y{sp 9MÐ1VFVhV!α 0ɷT}w{d c$87D;2L\'TxK=Z%[o1D2Ryկ9Ӓ G*J[#8v^m3ҟ H rxO8K뇸"vpj}{¡I,x@+ԩ[qSJbΤ)DJ4#bqmA?+o33`+?# j3uZmvqMbJx\OYi0Q$̈́2Vy} [aEk-Clb7xIt댺WOo63mgVBlY(B =mea;8bQMOiRA?(iXl`Yꎱ;pZ {-h6ML7ScѾɹĩ7qFo,([ R?tPH<Y"k@RD]$pV8,?EOE !HR)k4+n#J^ps}GP$EnW&5W NG΢@am0d 4'T@)XIWƙiJѳs!i z8]Pz7SNw=W~' Iw/4䒻[ ^wZ{9s 7:K{ASrhp^^&"=F yRw~>º;sٺ{e@PZ'{ w5-u3i;n?Lgl&+Kcc1ZWM/F}XޯqOX;o^r]jj^k1{ ?'NQc`4rsAYp7#=)r^fJOKkj $XQꞷxaS -7x}x CU!2"j R&;SL\U8xLH~ted[7DPڇ5Sόrė(ڛ.Wrv~5? ` goH Gdb͡㠊-P`ǿгR*&\9YkspŽ!ַ=g(x\ 0lT- V^&_܅gmj¤jG]K)rmyݺEex^v+t]ܨ Ws 1W3"Iu_߬0g`cSyL3Φ ֣ jCkj۝ "ٚ~lJ!9l-'@UpDcn z/;g{%GL5GN42%мr౩kzX~*}҇aW1_/dG[lm-s}yc$κHK̰V.kکAރavS- 7N*3878؃]ښv~=jed]NS@v0"A1nE7gK ;rN*k^q gl*v^(3Nib| ZjYI⡸nqվ;ɘ@['%KH3J˵*Or3nj98{ .(#ⳒRz)) P)?å;KOǁj`o6D0CM_& 4ZHtldq؆VWl0c.;)( ൫%I2]}o/ ^QN3ҽ!Z*efb$Q=E^lpJ3ȽqW -4%I@h/LM7!0+a7&uJw1KyWa*)wfS=|JlvxqܯA\`U(v{B#8AKLCRafh2~ 7hcLV$dH|(d9% .ZG",M,WZ&PǨqN:Dj6,:v<䋿GpoԊݖ J-@d |0wu fy;%yte/Юm cueMwү*'7G uiQy/+/rVp!a虡 yvMW GewOz?8?eR(!e4Oz|.>5yH?;\pεaa˜x@UR^p }I {B"E_<4diߐ\~Z^:^c-z ٣KQS >+lpc粃qB #TBV}%B\yALFC\)%Ĥ )q뮌"H~=u|g;G_yx]vo3ay3o5f*v爡d@Eb?-bkC§Ut@IJJ)!M[i㖩k:jwԢKtbTqf&tٓʐ]{3=4Ewp!zzrvuSM0yIǴ؉>><q'q&n^ټZJ2,4aKj w?\o\),RԩuSjձX9#]dMM aw?XYgd`13X5gn<<=fndg;gq4't=JV ]à m5 m*bIt¶gʙn=&0C zRʫ''t[DTFihE[D{f݃ɗvsTMNe'ol!jqIFCXIt?y[|"!G1VͪDA}x}7w=(fF[SSuA#M_zuMؑLC*u3w/y@ĭE5l>rm" CAVrf~PO2M Qdbew20;LMëc}s6Iw[e>p}*bh_dp0(4^u/&zTTU=bQޝ{EFla^yMuNRc-dvwL|G(gc?du6&Xm?pp8oMT ض rZdr*ç9{$Q?` Tyz PD9/n[F[t$q꺙_}8\݇yP=mp^>HZ`4kDUZ푨$z}+P[֓PqjBjfQ9FeBoh~mq;y>[rBnuZ(K+K_Lo'3׮*ZV)? 9trf(c:HQl%J,.q~=!]2oXl r@o.d&NПl ȿ1/tuSpȇ֪|!'&LQȨP̫Upp{'B)4^n6;u,P=_2z%e4g$** 60M&#5t؛7MkvF[dwdUV &N۷Y-}^pTuCVCⳛL͍V}o(0tF ֽҰX-E{EHfq*qe;Vu&1Lhq_u~# +n{դY@J2q ^&SWu]aeY(kNnr_=K@N4 i= !Y-)+zw}gGM  r,-Wbo%Gnl)VxX$*d'+_@<JPp&v2f?@ `V_hrwC ,ñMY#gjqY~Ǖ0_K:;w jl 0?Jcx6lZ1_,^VF\* {R-@{bgPB]4-1sD*ˡb>v"C64099M1Ow0eyU {|z Dj@l)Ct/[`Sw8DzHLƓMC/0/U}/+Zz|I- nPsygF>n"$,1m)ҿ!o5|U4+@m@_0]nU2;=iCθMw] 6$NX޶dJLF\o긠4}>BݛD&]~ 1èlSsY(,4*ٹ'+S>2V\ m5drf.Z5q_t^RY/:v5M^]@hˬJ\W[ƽCtas~`MhШ$Q+c`qX#TQXUƅrLY\1>_.;+Ym+Z_XoZ8k'Vs\"VM45,BmsmQ.KݭX8mb@2Nm@,* 6|ؽ)<ǷkNjGzVv; &U!E]sUFG{p[9t>uȃ:5`)"כP8*%|X#[a=9f.gih(wjpyUܨ`1`$_by@|yfݶ{b n丮k\b*EWA+ Kk󂷵[znm,Ptb6=1=l x"mewÞfuӟb;;r]#,TXŖƲRPַqW/8ɩd!,ohBZK_m ]H Ms&FVwo?0XJ8AOZO_@Ud&´ዃl~Pj =c3C8 ~9T͸)?PD%fQ`ApuPH<#~~'_ȽMē~UG 5iI& べi榎_j[.!8Y Mb|^z5mʋŪtm#v8֦ZmsH V. 2X :) B<.W[Sɠ]rzn,ͩNT7zZ Iv$9wZ-`z; u-$-0iX܂*ἇΨ ?';[&P3m)^1 ۵VFI rq\ \A6|.Y|؃\kC3hQnYaɠcɟ/!7m23]R1ۚ#Zr{k DL.ڹ3yQGӲw"?/ANk'l'<~ڷWq V{Il +Ӎ'ڪbf>day-ZG#*B^: (|3^⦊'2pF./O̦khM,dN[ZKs$P*6R;w]@JL3] @`ȵ`O[Ůx DW&\pu"[ __%rllp~/|3H#J xdԈZ?}0gaXWP[4Z- >]0Mׁۅ(,y{TΔS9x`IJTw''"Se ?0K:eoGT\f]|X6UioovYvǼNhᶞh׵e`ƌ&d+q },hc_oD*0MM)6NANZM6t}Z>ƉX_3ܭ[.meoVLg)O=`ͶF-X*xhՇmָ%-؀p./ K*aߝCe1$5~fxa3X2RnxUD3w+2z3vήW638luٗX6,N{s{Y0 gldM'-x<3yX"b=VCt{/cFɋ-.W5{$M 3Xܕ/GjW~;N:keJxyDc_)u 'Hй-)zMd8'O/+I !yݩxfhTόJ&TH 3 d1o,U5];ST|ߍ*ןU|^1T|2y ,*cemAq7 Fjup}`E&@!U+c/OBK= \5H,BuEW]l~x $ [tq3뤈zm SHnW=9B 15I? **lMЗ NJtWʈےev`{ ӎxk'-.2 hNPpZ.&5:[ь#9p݆+8G2a\2rު2g$S\C]Nm'9# QVMq {=tdy@gZJ*oA'U)-p5?=~] g@PC=LK(@{͘`RO^OrM߮|-x 6wXÀy屛tOfF)п75EBQ1_o#?~Yfkռ&1a ʙ)iM4ǺL㱶n [!fTKzMs趈0qz__ei@O<%MuuJkTNPuэ 6%Z44b'8PjpgL$z^UM$S)/ RZ]юsft*XdkE7b1|]s\)?vқ2$/v;nFsn?zA 3CqrC ~ }%(7!c5l\Q#t(\ris3_8nC4w=-;XQ\g:ُQ{ty =.Fy=*@ڄ$ #xVbk,`t;v$Cotqbz#h2 /c5!WᇮZHRJ3?kvJ/;ި$b`pK)xY͓<{Ô5d{m~sd[2,RX -sֆ~ gtld1B_tz:mrj,;8Uݿe+:&N*j EX641f ?9.V>c=@<ﴓ9+yy1m4\(ԝksY ULĎp{k;+ԘqL4$/yENar Z'P4sLZŀܬrҀv{`%;ˆm,n:MGJF6U؈TH+Co!:rw$v,/puM]0cqƻM'!Ok9I*!Ad-/CJ5Q $Ư6m0xGW=42ꨨ-ʹrkb.s SUJhO5 ̪͐;;((}eٛ%{i?A.9_,ni €n aQ)VISA^8"S!uXzoթc6Mmc_.%a?; k('slZ; c5KN5pz4V?\{#GFzxú񸯟"etP- "9:Y (T39SFR$co ~?jN̫͉]ܘ1/̃W[Y2ܘXU0L&w}7W]4wjןT:ºMa#tɜe\ues)ъ{h8^|4eiaV? \aoQxkU,KM'ٳ"^E++v=/egq ޤqm@ӠIeGVOyȞ풲ߔxG5i~O#ɈxPכ]o[+/\-1 u3F^IX$#@x:MgJrdx[T_O;cK'+(!3j&NMAYUDC׃n(zP\Lʰ&/;Kn of=MD. dRsO:͒Muxt NT̷- % 2O0>D33KS>[ʨ &GBH{샢]= m,V(x/% YS:E"7P[P΃oikKyqe4˦g.bqQ DS-(qfxâWƻ8[ )Qi; Q۾yܽ/#%)"LHT}y8) axm@唫K:!٨*P}\XH֥°6Dgfmr$ҔW?ul<46`^EΗ˒~ k^lYm b;6t0;l?3eGuЮuh@;ې ~6r]*F[ۏcvS{zSנ582`sbAێ; HmXkGLde+]}Ė2<-L{,fL7V6i󰿗+܆ٻZVHE]ӭ1ZodGjJ0!xpjkZ--o#~vZ8]ŷ,٤cSp 4wA\~)n{~~;6=A(<3wHW3ݎBNp;J/3ƞ?ϕK6vPK5FVdword/settings.xmlSMo@WTbpH!VM[ %HAzz;os},,ǬR}?XXJ^);a7k)2mm&Qd Hn؀XZrK^G{ec*hHr+z-esK5GBc<U$ vR^ў%j ^z6.JFRL:[(e5/B=ӹJx['ZZl[f[⼒;P3U~)È/H36ǺvGB^~ *?y͝^v|y']qrݽ.D8 xcw( vOg`-iǼe"`ु^ypO>RaEKM_P~k(.BWD-Kp-Z-DBaUyєet_PK5F cj word/_rels/document.xml.relso0W Ky ҩNäJ+`>俟I@- |s糝jWp^$-L.uկ y:ѐ-xrw{ Q>#Θ(/qcd8bnA{F<#n'$Zm-) )ވVR0.<+3) q_1}m.X)KFϮ |Lg S2T5R=?zM5WgVg:a4gW {hiLH, }}``Z]3}g`ÕmY#Ǖ8OU۠,GM<Mײn;N=E<4{)g.!ޔIq%faPN'cV HO0O{{\`| .O0^U/Ξ| }0 _/PK5F>ST [Content_Types].xmlŖM01JUUm0$6=wP>X <38ROCd Jeʌ\|eI@a!z{tbMXq u`RX__r'Z. l~BkL~4A8KwEUƄsR*Llcu0QUy<OA| IMCs!8B uרMoWДˉy:[;H/GQ4Rg;85 BFBI+Z(3GD8%϶Pt+v5ܾ>z~x#+zU?__x7a-~ ;7{O;g@HƜ(|PK>5FcM _rels/.relsPK>5FI+docProps/core.xmlPK>5F; |'docProps/app.xmlPK>5F|A ;word/document.xmlPK>5FwXFI>word/styles.xmlPK>5FĹ,"@Eword/fontTable.xmlPK>5F}y!Fword/numbering.xmlPK>5F.zfNword/theme/theme1.xmlPK>5F p # Vword/theme/_rels/theme1.xml.relsPK>5FEJLt$Wword/header1.xmlPK>5FZ Yword/header2.xmlPK>5FNHCZword/header3.xmlPK>5Fm\word/footer1.xmlPK>5F^word/footer2.xmlPK>5Fi-~`word/footer3.xmlPK>5F)s>$9$bword/media/image1.pngPK>5F"Bfwword/media/image2.pngPK>5FVdword/settings.xmlPK>5F cj (word/_rels/document.xml.relsPK>5F>ST d[Content_Types].xmlPKynDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/doc/nDPI_QuickStartGuide.pages000066400000000000000000003507271262705051000250650ustar00rootroot00000000000000PKIFiұPPIndex/Document.iwaPFBN"   **"2:z& :en"*2:@jDRDBB̍BB<?HP_LaserJet_M1120n_MFPiso-a4),x* cLA -R (08@HPX`hpx,enenit_ITBlank2012-02-01T09:05:37+0100Author-Date.ens 2H:A *̥ RnDPI - Quick Start Guide Open and Extensible LGPLv3 Deep Packet Inspection Library \ Vers$01.6 July 2015 © 1-15  TayXof Contents 1. Introduxp 4 1.1 Download Source 4 2.  5 2) Compiling  / Code"2 "Hthe demo pcapReaderB13  Comm!7,Line OptionsX4 Protocol File 6 3. Examples 8 3.1 Live Capture Mode2 c B3>U9 4. API4 10 5. Developcustom p  13 5!2V! reat;ew:3(3 Add your to {5 : Inis a AwliE1$ based on At!@currently maintained by ntop. In orderpprovide@ a cross-platformiexperience, we also support Windows, in additA`to Unix/Linux. Furthermor A0have modified2make it ' suitEHfor traffic monitor!NapplicaE.We S0achieved thisdisabEspeciDpfeatures that are unnecessarynnetworkJv,A rebyOedup )'ngine. -allows.(-layer detee{ of!}E0s, regardlessa;%bbeised. T mean itAposato both b knownbA#,non-standard_s (e.g.3 HTTP(zs o!!*n 80),EY%opposite6ASkype5<onJ> !4ecause nowaday e conceptpAX=.9P no longer holds. OvA(he past fewAthsAE`0added several9inclu!,: EnhancemenwM>]g)Zin term%speed/UQavencapsulIq% ed (Ain!{cijca8w analyse GTP tAllAI$). Ability!cozei2insaeg$ kernel so!ted!jitEdeaQi 7-EencrypAmcos}a decoASSL (2clE ,server) cert3 atesue\ASfig_outE!g GusA iden!pF9) Onl!}(Apple iClouat,wise would b)2ed21' sub-s stU-p matching R 4utomatically d? ed when%buildr(nProbe. How notha-v 4E)IitAa 5dalong!Me s !%be.MHhttps://github.com//a. : ~ St E! !very si g &eAile  must meetE*aierequi]U: GNU !v tools/lib @ gawk gcc To di)MneKo, tallAm 8fo^cv fDFedora yum groupll 1{s &!lib -r gcc-c++7D Debian apt-getAE2 -essaal2H$ Mac OSX }s(XXX (Pleasemac$s) OodA;,%ra9O.Ias- s: cd <%.#0directory> ./,gen.sh ./con ! AO ź!j!xf ndpiF M^*Ma'7ay ~duE\vB:/e_ 3 N  T *.H! |rTnN]eg(particular,7is2  $y a lot of!mRYoe . availz  a minimal lanJ each *M lisbelow: =L-i [-f0ter>][-s ] [-p <s'l ] [-wve j $ Usage: .az| SG !J /playf pas~ortslca(x-separa!8H)f jexpa of: "  Ca . B ra  dl8s!)e over) exisi. 2  . dM flag e%a6l . t%Jdits.u he" *fa}. m| Usa,., genewsqU fEX. Auns per;.Ֆ lowl Jdis$ QK ‘B,ыakis<. UDP 62.101.93h:53 > 192.168.1.132:56130 [%j: 5/DNS][2 pkts/260 bytes][chat.stackA flow] TCP>R932h{(61.94.220:8e7/<][8 f 1925g]682^58Odiy exchange 916Zd524d,conjugator.r$so.net] .NWbWB U"_ A1 s: R0d7995 > 157.55.133.142:1235Y40/U][3I7205M65@(223.47:3303A: 79975UM5471 U$127.23.238a5`:16384 > 240.199.103.219:R11 1611vW0JS kqW273U]2BhaSa&"B&< 6Dsf./iM8(ge, WhatsApC< U(S)Xɺec&{ ho  IHost:” decito embedR ran &drob popN$ Aho-Coras algorithmA hund $ ous!= is{ly (i.e./ enoughsus10 Gbit"f on )(ty hardwareYRlyocols at time Eat }r&tf # SubN  Form !(:"",:@ "(googlesynda"@G&vᔥ$"@Veneer .ZABav -j2, :, $ tcp:81, 81@H udp:5061-5062@SI$60,32  @iSCSI U3000@ 5 rpY# )*( -p)2wor V.M N_ _U_A4()iK. *Qf %,we show some.cas= VCYP< cP modeame -iek!9 a +.+2f* . $ ./<-i eth0 -s 20 - * NOTE:Sisapp!Y*!Z*). * I1w-) ly)b= * jto%jA& wdqtdo90. Feel * frece"d!X send Xe[r#--7($R[$: #### $) !(%M!...+&u%q20A pcaa P : 2390of1!$ total IP<1 17757430 d ique`  78  throughout: 122.30 pps / 709.92 Kb/sec G(lo&"s:  De ed) DNSt2 : 57.R : 7904v s: 26$SSL_No_Cer*pW48- W22920 W6" $ FaceBook  W13./ W74702 ) W!DropBox!W9 W66.  (!:W52 33.nVWO2> W170= W61913qW 4 3EiCe Q%m  wa $eu"otcpdumpa\B7 top$4-nW40 -w /var/tmp/ -v e:Genaon en1,k-t"(EN10MB (Eth1!t),? size 6553 Got 06475 6 ^C1221ZBd .recei$byw ter 02dropp !!9A been )]-& willB to launch:dl'ݑ i:NVV Aэ#ɿY)Rӊ 49112of iR332154*>14NAn(.612.80 KͲ3.09 Gz.bM :6/76 =zRW615 W2= = v.253`84?0 W7.Z z^152WU8 W1%+$B.FW164^!v6Qc-20121=-!(:2MW87=Wg3 2, &<larifys aSY &enow goaxpl# v "!%CO! .orgFP %$cu.*do by edi& . J$ echo '\"@nTop'> 1.2ըpRen1a 30 K o o o o o o n1V E*n 3*n WARNING: IPv4/IPv6qeD (z sl#AE,llQQ$discarded D75D757TRD176637f>D26DGZ NV v2 92us:6* z32516 W. 6=fW983 W2jSDnm.-W95. W1.m6h3.W25.iW.* zt2W489W6zt1.W92 2) zt2"( M 61279 W2v ~325\40.W6VW3 .3 R-1e7,is highlight N'0taken a]U*itialpr"NI*Rtoa8?+d+perlyv)d Makel_ToU,r&&,of 9i,r .*-Ta*34U1 es - w))ad-e* + : #" _main.h" e-b*15d@9+ Dex !bitmask%*i ;")m0X NDPI_PROTOCOL_BITMASK";( _struct =]_O_ ion_ E( ,ticks_resolu$ , m.,c_wrapper, 3debug_ f);!is fun/IgB]DZ!g eldsIF)5tF4@ings: u_int32_t per_s';
 ANstamp% pera:ond (ke 1000K milli D14). void* (*__-(lloc)(unsig63) }F1po'a memory%c :X!])( prtrM%z!1r, NULLAp09$ve environN4 EnJQ|s (notAaEe (se'!4ife>) via(appropriate-roE< themqEUyM. //rllf EBI0_SET_ALL(all)Qet_]mN2(%i, & 9 w&1:J u al&y"$yZ"l >$]%LsPY: dpV2)v: Patha Y/7W& gr)q%a-z R1 =<,nsty)U 8_2( .1 D,iph ? (uint8_t *):2f, ip, ,, src, dst!"fkI9FA  * *_.U2M 4 * :F.?A &$5 iah9 !Ychar *)G U 6)Ai length of 3len *bIL,:3 (IP he:=>c)sh,9 len P.le eV +. H/<Ÿ  ).I2id5src VoiB}J2subscri-st6)I(Vds NVde(f[mA'eesedD1&<8estro>k".nEexiJ> ,N`>`*)V k)ABtou clear iF(i^ _ *ptrr_45 . fur in" < uggG)to,%iG*$/Y *~.c,!?/src/W  s.h^!public_1 s.h K% c.d*orr/n?3_5s&>5. a@b2 !!J h"~ {%< . B@ Each is .0 a4 ent ? I4*n$`@ DPI.EQ  es =!at 5as"1 h4ctivity,low:'3E!!r;>67X/R 47o&  . 5RA-#, . rrespon#l-1w!1A nS7E. /I~,s_osdpi.h aJ!8 w " MY , 171 wheref&!m “name4=171B#ID'm:"! ?2N"$)%d89 ax(&!0 l^ 6libyh/my5: .c 9aentButils#ifdeff6S  & #endif1git be>Hf<>Sah  earch_( !jG , 64. ) { 2v*%  = &<->  ; ) LOG(b, ,1$_DEBUG, "m&=و...\n"4 /* skip mark"Cchecki2?]H. */ %( =->)8e&&_)[0] != NL) !* O ~2.!+$); } } aDa corUpr LaFCaPJ= icF  & 2y , 23' A12 $ B0 &v pay _ = A[  CEg{/ < if(“Found P”! i N 4U ` ]M Iint._add_&` R0 return; }6 /*ExDe*/ !  “e cF kADDYTO. ( !-> B};h R;y b)ic" are4Ec]ctGaa ( B z663!U ,MKdue_to_l a6 i~),a@%NO/*Cho7!t$of6 */e H CORRELATE9d REALi);!5bJN.d):[ 7    /:9  r/*. */Bz@ U# be assoc da) SELECTIONq ful@B=1B)  2 o g  Afm-cAA> & %*   K2*d  ] 3  ;K22e" oYV~6 2-j eB * dbm)}   v -") 2 1,a X6*{ .%-*> .#HB^QSAVE_DET6$_AS_UNKNOW.ZTOF.aq a UpJ0$back_buffedex  a++;" )l.i ->:H_> = aF Nv/ "R_is %u\n"2AV^*                  (b cf d e if g h i j k l m n o p q r s t u v     #0      < Fd Z Z# 7    Un    P   V   )' P P    i-  }    ( 2  s  1  >!">? ?2? @ @Z@7A AqM B  }BZaf   C  7D E F G H IA(J K HL M M M   %N O P PP< PQP PQafR S T U VWdXY Z [A[ [1\1 P\ ] ] ] #^a/^a_e` ab ca>dAeaffg ha$i j "݈""|33((͊(Ί(((!//FF^ Ռ]Î  S.ד0 $E %?9™ E A ʚu ?- @ AW"!#E aL ! , S֟S۠ 35A<2 : V  DMs k%%% .M  d   Z  Z  (  Pu  u k (R (\ F\ 2\ 2W FW "  P                l l S : 5   < %, !   !m 2m m Zm %m E E (E dE ( Z x 2   <    n %    <  (  (  <  <  (  (   o j L L 4L  L L A ; !/ !B!!,y,,|4(uo!!ɶɟɟ!ɟ!ɟɟ,ɟɟ,ə B$סA_ W W# #aT 2( ($    F   ( (  (( 2   n!J~Z<~ "y-!  P #~-~gX S N V ~~~D<D 17 2Ŧ%,2;(   !!@)EDB%C"%ūK! N ɜ Q<2Ń2  ō(^ #j  %Ű_ŰejV(V t"2"xA]w y < 7ϩ22CyC   =NN"Y "1 B || 8s "B  J  ,PZO  AJlLN30E ; I ;b  r" z fAA7 8J /e  * (  ( o  A =Qd svn.-@ Wdtrunk]d/- 3Der.cQ QL bookmark . 4  OLE_LINK2 !!% !0://multifast.;*forgeU /.5O K 5,en.wikipedia@/0/Aho%E2%80%93Ring_mL "R $Nq9" *sP* Chapter 1O ^8*  u"q>* *QT* PY](bT:T(Y* JBJ Z M( 2!G:B54 c*12/Jr5GJG5GZ<:(AA_B__B_TJT:TQ5N^:Ta:TBN?b:4(A* A* 4:4.?]>?F?59B qfR3U>U!::I!TH*  / y    S68  :6 : :::2 *S , -." .W code.goYYP/p/opendpi/!HO*2  B{LR?%?-?5|0??%??-?4>%>->0$>%>- %-jx0]>%43?-3_x0>%>?-.+J0X>%>-"0H=%>-0?%>b?-β0>%#A?-8`0>%.?-0u0>%t?-!A %=a?-0'r?%ԉQ?-ʐB4\c?%z8?-M;9 G?%?B8(?%@?-Hx*?-Pj0Xm?%?-94DR?%\>-Ч=xH<>-^0 d3>-x0UO?% >-,0.?%=-`0?%>-8=0P>%v>-0>%h=-`0p>%p!=-~ p ZX" F>%-3?-ܹMLAA? $J($ *˖@2\JHF\F$\:DB\J \6(B\J\6$B\J\J8B\J^\" A&`K=%+ ?-/?5L?2@$4 G>%-?-=>V$4u?%6^?-\=V$%u@Fl UQ?%;=iR0|>%X >-:.-EA:vB@ Z?r/4/ @ / ^A /^/@ 4v]p*? -!D(08R y~6/6e6(>9jl" - 6J 1>%S~;3A .;>% ""*(2:B-  d  !2!b:/ :: #         KI*AV  ! (;6' {***y*("*2d:\T:L+(v P*% 0 T9*AA*2:BJRZ`;61 !,!1!!X:MSAvKU~c;:1* !T    X:zk%I݆K:8'"=P9!!!sn(BJ5`:|,%Bd@!8Edzzzz:zzz`;:aJX:C.Kc67;:!,LAdAdAUX:cBLΑiMbM:8#]d@Y`9!AA`JJ5`:x0#6x@!2E^EU^A^A^A^x`:x0#6x4z}1::xxxxx:`;:AAAAo !     X:cTRG5 ʮ :K @ !*!Nl%Nc1F&&(+_Am:6(80*ٴAF&0 MAPKIFdIndex/ViewState.iwa * O *8 "  * fD"*0: DODHPX`hp}? DeC }DD%TPMacInspectorSegmentIdentifierFormat| 8    L  * I+ QX YC/D * 0"  A CXB%%@A-/0(8@ 0e`* 8FA *4 $511F3907-868E-4C33-B720-0F94B217D5FE"`  "*28@J RZbp08BTable 1p1@_@ L!mhZP  - b,QUf* V, (.nZ#PKIFFdIndex/Tables/DataList-10.iwaL . PKIFiIndex/Tables/DataList-8.iwaL .PKIFyjIndex/Tables/DataList-6.iwaL .PKIF=)Index/Tables/DataList-7.iwaL . PKIFp^%%Index/Tables/DataList-5.iwa!x . 2PKIF-Index/Tables/DataList-4.iwa.0* J J  (0 Jd *   Vx*"http://www.ntop.org/products/ndpi/* 2 : B PZ r-   & : S*$nDPI web*v PR:.W .j~[j:.T. ! sitePKIF*3Index/Tables/DataList-2.iwaL .PKIF&Index/Tables/DataList-9.iwaL . PKIFt#i7Index/Tables/Tile.iwa  .  *0 " "(E<><E82< #A]A@<<<<<<<<A<88A! xE@$ ID0PKIFt77&Index/Tables/HeaderStorageBucket-1.iwa39 .) A  . $A PKIFNv<<Index/Tables/DataList-3.iwa86 .& LGPLv3 nDPI LicensePKIFP/{{Index/Tables/DataList-1.iwaw.*% $" #" "!    B      0 "PKIFZ9P22$Index/Tables/HeaderStorageBucket.iwa., . 0B  C PKIF]UUIndex/DocumentStylesheet.iwaQa| *        <  dU# Z       Z- F_ #   2KE 7 A(  #(    2  B layout-style-default * *  *_    m  *i ) #>  !  $*#  %E    %m  ! * 00  - !*A%% %! 1 00 Z 8 R*PZ%(: JZa* H$ * a  ?DZb @A 6O*44XX6xBbar*ccZb@.*:1 Z9A*CourierNewPSMT@! %%- X5?b]T  A`B   C( D ` |   C!R=RjJRem-4mAmBmXCaY1*IUZB> bUY=J y m@ey @e1Aew mAe%AeDZAeJhAe| A=%>Z3f%$?%?-% b %  `B    C( D uF ` |    !<<0@eAeaAe Ae@BBM ."(*eyA J @% m  Z0A*4S0AeSAe>B8Be~h\Be>Be%IBY/MU^!CA3 $*>`Z* LucidaGrandeb} *}}mh 5 *̉̕1)- *)5 Z  0.o?%dr?-tIOa: @2'&-NRBR>RBRRBRRBRRBRRBRRBRRBRRBRRBRRBRRBRRBRRBR %*ש׵Zb=P]  u1*B2Z:92 XWώ@eWAe7VAeUώAe/AeAB% 2> @>  ٧,J Z# T*VAGRoundedLt-Normal $*  5Z Ab %w B!:BU QO !O j8 >L@e>@ep_Ae:LAeAep_AeUAe?AJZ}R:0;%=-X" Jd J^ & *I.b EXB]B@V9@ F* t5Z4IN%V&# XZ'JqZ  m * O AU)Jb X6wTXej?efff@eff@e,A3 (Ae̬AeA•@9DJZ2JB^W Y&(JZ!@ Helvetica@b3.JZRJen_GB4B)JBZF/&  &F>bx  ʙ V _.RV GPVtbbYai eUU?eUUU @A Ae:AA-. *hu{`Ae C?eq@eK]@e@e#AeM]5AeSAeqA]'E'hY' Z]JAUS!! JJgx   r$ @.v v L9@@J4]tQ@e]t@eFA8AeAeFAeEA%@Q%JKF <نZ% 29љ3B 1*bT ZT *7"7^9bjN@aWaR@pA:_ɡu&&a XBa %9 <1V:-NZR2F Z=x . B* Z0 0q]>?%@?-U-@i V!!% B.a *)&   7R#@Z{ !xJTZTi!L-f 0V}YnmA,Y5b*!5Q,JB = @NZ-TK9+RVbU9$fd ^d.JZwh`^h.HJ Z6M9R^h  \19J.MJaZ 9AJ;Z/F" ^UN ZUb6Q~*JZ4q9?%4>-*>Y~ ^a(DJ!Z2G f0Ž;%=-I*!Q1JZ" 4-Bold@bP)&  6& Z N~   B  ZX . D*%"bp XC C k !*NknPA[!7Y ٢\ yXNm F/H 0!+5N,,R6! *F7 6 !j 0$ @e$@e۶ ( Aem+Ae۶M pA A}BB n"NXBw~b  b)k$9- Yk B E~.^ 9RCVC^ :z$BPB PZ PPP J Z! FJRnnZQ>QbQ>QjQ>Q&Y 2#L"##'&l 1J N#{hn++J-o "* ݓb!$%& NQ v A&Q .7* e>=̬@]a(2Bf &Z f .FJ Z4nM Z!:d( ` A&FN ] b %&~&.l,J Z%RR @}B+B .Ibg+2>F >8(8+9 %%>%}`/J Zft  !nV .:RiZ 4TimesNewRoman)J__none:-tJ(Zb@PKIFr!Index/AnnotationAuthorStorage.iwa`   . . TuxPat>%>-@>5? 0X. Annamaria Tirinnanzi>9 %>-0>.n0$ virtualwin44`>%>- ? r.4D* Francalacci Yur n=?%-= :::. ?t0>%P>-;t.:L, Filippo Fontanellb<PKIFQQIndex/ThemeStylesheet.iwa5Q*                    #  d# -#( K < ##( Z (  A U A  K( #  #A( # F(K- --  P(  #-- (F #   Ai       F   <-  - -F 7# _ A A7#      AZ7 -7 d      iP# 4 table-2-LStyle list-s-291461d chart-0-series_3>J(34  /(2-paragraph_!7!  (Name-4-shapV0>Vo5>8>312=2.! 3>~26=5>g!L3:6 5-head2 > 3v3>v0R3Y1><!$ . Column11:=^51^>Eo:o3, !acterM null:31A3>318Ae>1ABaw64F>1j>j4!\T,stickyCommen#.>T2=4>AR }M!+>1abfBAy>x2a7BlEimage-0-QH:>1F%X>-26FNs%:% 6466Act-4YB>F!.lin%"!yE0mE>h1SF=!e>/2a&>A-=BLB@!>m1a.k}!9!a] automagick.7kjB!:j 94-bodyQEp񓍄.= w9 3.>E>160IB57BE!#NG4ATXB<yB%JA=>Q318363m}6ReBA?nA!BfBE[ movi1-2646F :h6]" ?>Z* u!N=B!: 1:DBEE>318 " tocGB]BR4!/A 6m02m636Rr % >V:Z2F[B={B:RV5=UB]]"8 !R!-3ӥ#$5-category ! .` 0hyperlinkGB}%C Bb632=k29R =JB4F=iu!Re4!O=O3FSestextboxUhapUBW)J1" nmk>sZ!YRY  S2iq@B: 2F>X' kSFWPFootnoteTextE 4Identifier]16wB  "aW]"]?1FBka%?P -16=BO4W <36< . % >4!&^:; 6AQ.g* 4:B!BA& 2:^6 1x R&BDRQ*0:{A3A6 2 6K60F=B!u !legend8B!R}"\ !N\ : $n,!16!Ń 36>jaJ}j/ b56b}>@ > KR 4=B0 $<>S?*B%!e>!";B*X.a6" ͠& ]4Y S VlR~a.7}5u}B?A!B(!; exj 4 -NonB`E>@y396]"# 5:4TRn}"u4N=B!:6: 22 B`e>AVxa16=B %E <36<=,gA&Ng M56M:3FR^A*>4>Yu2Yuٕh% BKar 6 5 R:5UB]B|=BxBR~3AR:z52؅>8Ro3=V19VnB1!B>4RI& -?=3BR3q=a,v :1 Qe>c4!ET8 >53k./"/O 0GEER2>~ v?2"]!B*!y0Yz8BA!B1}BWoR$5!>;xYkBE>8e>\  >G&=q R7V!2>=2B%>7BAe$m?ns>sE R: s :6B?AL>{GB'R1e>1:12B!e=-06%>318BA=B{*<   > '^+ J 0*?"O $9?%*9?-!9?5?P -@2'%b8] m> z `#R`>`Z v[? %o:@>`\" )[4  List 29.33%^ PX>e! mBmCm4X|Cr ! 8·ov )I s.)EZ aE!<%- Q@>B Heads-8 ?-fh$C@ a ?08" mn i%"?5< 6  % @ @@L*8mnF:*iQQ<2  Wood :  B  J  R Z%4?%C?-} ?E'bbjbr 4>%?->Nz JhbfH Ņ@jA ? a?0800`200 @@ r04Be -LpIX>% -X).ᆰ R?% -I=R RJ'BRT ZR R!CH)H RZʚvR R9 RJJ Jm AI JQf G:Qx AIĎr* RJah  R R)HVR !  n >q 0q@?%vE?-Z=I~ʊx8 " =* |  v Pl (?ep@eAe4RpA &  " R dX> vUU@eUUl Ae&lHAeUUiAmM  6p& * "2%  V 4  Fun :  B  J  R  ZH&N?%2?->5333? J J 0g?%!?-tN  J4 J J v J2  ZRK f Z2  ZR f Z2 Jm Jah  f  VRW & 3 %]?- R Q( | ^99 dP4Z@A* Helvetica:s :(@PX`hu}l! ,8be.%(=7@HP"jpx &W {le##  u '3%Z %4.V1>T-6¨]-V#B*I]  .! F $*;5%*P%IJ(Z @J P@A@L.D$* U :! Normal (Web) + (Latin) Century Schoolbook 18 pt Bold><2M3Z~•.DvR@yi% ing 1 AB&1I%3Z}8JjdF6u7ّn\  P4Zf\ $?%?-}~\ j ˯B?z8 r U.Y~ bFy3=U, Times-Roman22R{ " A0l* . Termine definizi].B_%44q=?%?New%A PSMTrEGBwRwkEBE2 )EB9H%H, - ElencozGm3GGGA"A AA ^G*y@* " Title AF27Q9 999  4$?e$ @e۶M@@em  A3VB -urJ AF& *'136 -N''''f']n# [* P4ZяPZZJ4; 0% BlockquoteF4" WWFWh:WAQ@Q@QN 3.wB? *wwww4Y]>V\xervV + No^V3UVVVVN&^6>CH%r Z4 ) 0>%>?-.+Jf)hJn > VJfrw-A (-1.UA L Z' 0i?%o?-q $ 0X>%>-" )چQQ> ?/ , 0&&&&7("e8J @2~!<+e8VRY?z-RRz-RRe8RRz-VRΚz-VRΚe8RR8VRrRRBRRBRRBRRBRRBRRBR` + uIa&(? D] Fill(er&eAQ?o?):"R->&G1 8@J 7, ApAAS'L Directional Key !fR4(GdH  %Right LB5x Lef =f-:( Medium Top LrR?23:A3@A3@;) %o+er Highbht??%@?-&@B#f $&%$* T 9{$%14C8JusIfdF(1<*%`H8H8H8H8\.\. >.M. $ Aem+Ak.M8pAp.AsV -6727 - - - -f -.bW.xq*bWbWbW[a-bW^bW NbW![@.7Bo+347777v7 "<<,*  ]#<C\Z )0'r?%ԉQ?-ʐBJPhD"jONJ_W*PZZ\<RZU15*NNZC"C-b B,E6t[L* ) Free Form^U^):3Z0 A7__none7R7>*/{C:{C!<ɰ@4@pA=]I?QI?]./Bk_////*1bE ހ"111111111tttttttttttttttttttttttttttt"t *G,* ! 1Fu2pQu;TOOOkOO?v&FH!6 ( >=M2 ANG1@M)=`BGnGg2: B9H] 9H%6=&`RkTkkkkk6k6kJ &5k 6k`0>%ߐ>-N`J`J`0>%?- N`J4`J`J```````v`J)a2ZRʟ2gU2Z2R2ZR2JjB2Z2X"jJ Jm````J! `f``VRΫ`&`0N?%#?-C3?vke{&qUQ CourB4T5F A* 0Newn1TZM)`^[qU2qU梫 B r[Y{x .[.[[ʣ[vRkI-kkkkk:&k 2k2k2k 4X>%\>-}!?.kJ J ,8>%>- w J4 J J* vvvvvvD(v>%>->5Yq6w X>JM  ZRʟ f Z2H ZR f Z2 " Jm Jah  f  VR 0*>%6$?-ҰT R f/S^/Jf/ &3*:$) Z1%`JRbvN*5^N*u1%;"6fB?(h  7 N*ZN*&W.ZB ZZZZZ\у*у. ZUA %26h-?`,"nn?&&ă3" xxxxVx< Blue Paper4:B B  JB  RB"% 4ף3%ш>-? J% J% J4% J% J% % % % % % % v% JZR % f% Z2% ZR% f% Z2% "% Jm% % % % Jah % f% % VR6% r&0s4%?-ѺP% R% " (R 5Db,  Ca&:&}r96g$::::f:"t.9B n9999r9Գzp ",%p p p p p Np Np Np Np J%:Xp Jp Jp fJ%J4p Jp J*p RRRRRRRJRJ ʄ ZRZ p fp Z2p ZRp fp Z2 J%Jmp p p p Jah p fp p VRp p 0W>%f$?-Vp jp ڱ& R#yD#####2#2#2#2#˙0ˇL?%ЎL?-ʅLy Jy Jy b˙J4y Jy Jy y y y y y y vy Jʍy ZRcy fy Z2y ZRy fy Z2y "y Jmy y y y Jah y fy y VRy y 0<?%?-R rL.6L4h=%?-=tA2ʮ\"Z\"N&M *  wb .*>#, Z ZX"ڢT %d3>-x&Q0? $0.?%=-= m!(? *˖@vV!6<M$ Z#" fM*MlRMZM$Jni$8? -Ӝ2#N&EJZ/J%*&nN BoldF^Z% Zrɜ00BM0 00` A..$BIQ"$$$$"$!9Nz0*;zz0o?%o?-oBWVz0>%>-ymQQmYQQ.zVV*z*z*z*z*z&s*z*z*z*z*z*zz"z[U%>-"6;Yj8u^.BV6' @@ 授.8 r.J~Hn>§3&T(* $ TF:J*&@V`Ηbg:fݥ Tb&hK٠ BodyJ+Im3Zh hr h5*5..ig1>-#*504W~IV.-։ gJںoQQgQQ.gVV*g*g*g*g*g*g*g*g*g*g*g*g*gFg Helv9&teticaO %-05?@? @2' (-NrR>RnRRBRRBRrRΚrRHRBRrRrRRBRRBRRBRRBRrR2||r@>RBRZ* ( Normal (Web)1paragraph-style-28*P3Z A* Times-Roman:Zw tableCell-1-bodyS!)*%&@Z @J @% 58 chart-4-p1zP_5 R4Z1x@A* Helv:!v$?%?-@vq-b(,˯B? -! 08ʞ$be.!J$=P=P5>P61PfPA+a*=~P## }$* [ @Ef Header + (Latin) Century Schoolbook 16 pt + Not BoldB+31)c3Z+3)+4Y BJ(^0####5#^#B$ H  List 15 list19igX>ea^mi mCm4X| Cr v 8·ov.$* %  ing 2 A"-V3ZF!^:JndV &  j 0 .'Z    2-EEQP Default Fillero  1|?E? ? ?"R->2G1 8@J , ApAA%L Directional Key fR4(GdH  %Right LB_ 1x Lef =f-:( Medium Top LrR?23:A3@A3B=  %f er Highbht?*Q>QX2 Green Paper :F  BF  JF  RF Z46>%t>->Mbbjbr 0>%?- Nz JhbfD H4j C  + 00fR `200 @@ r04 ? l!X>% -X)O .!N~%"w"^ -Rw"J'BRw"ZR@.Rw"!CH)Hw"Zʚw"ZRw"9w"Z2JJ Jm 0$ JQf JQxddr* RJah  R R)HVR!  n@c >q 0 ?%m?-I~ʔ #4*  uPZAwbN0 .>.B*j)j)j)j)N#B,-*,(,,,,AF @5-categoryaxis_0*$2#0$9?%*9?-!9"(8Mz)e r b#bbC3 ~[ E1o9(%o:u% 3B4$38.**&&* 9 AB01m****:* V-36.-4IP----^-+4 movie-2-?3ePZ ipaAaG4S2_nJTJ @ "+Z426mX>/(///xx x.^.I  b04 *a09AAAAfA.G*12422-If.e e3-valueb _?!b&b867m`z~tA;?~[`1;`.[. 3  Z3123<^" ,* & 53B51826 "M>-Bold:R>J V bg5N5?(.5[ !&?(4-footerRow* Z4 bH!n?K8.?B.7)r?ʍ???2?ޖ@ !-   5 %(Name-0-shap Z) ZQ > PZ5BB *hB:2z0>%.?-0u&n^B3>=rBBBBr headfa0>%t?-~. $* P 5rA 4 ptA JustifieJA2*A`AAAAA u f 2-legendZ &, S*NFBFFFF^~ 06~ 4%~ ~ ~ ~ b~ ` * R 0stickyComment2h)T ZS <:e*Vk >B8)e"n=9h.(4*P Z"428@Rq%>pIs&J4Z*uH "x NeubGZw Z ;2ڲI hInI'GGA. ^ $ SK00ColumnIB& 0c?%Ee?-d1nN.:5:::::.F8Rʹ6:LJ?D?D?DBAB.BL͊x x x x rx ^824fZI26OI2OI^.t* 6 Footnote Text kSFWP Iden r3Z5NNkSkSz?O} K=J11u8efff@eff@e,A8AeAe̬AeA^'L72!28!!!!b!.%t>->:H?J4H?JH?JH?H?H?H?H?H?.H?0(v>%>-)BGH?JBRUH?ZRʨ:H?fH?Zʃ&H?ZRH?fH?Z2H?JmH?H?H?H?Jah H?fH?H?VRδ>H?&H?B`?-&DΔNH?"H?.+w&+3J+X+B+" V^ 6^$1zf,RJYJJJJJ:FwJ RJRJRJq 0H=%>-4 q Jq Jq 0-@ Nq J4q Jq Jq q q q q q .q JG23 q JBR q ZR[q fq ZHq ZRq fq Z2q Jmq q q q Jah q fq q VR q &q 0n>%)>-*,JRJ N 2* '222(s"2^2 F2. e BodyJo4  o@/)itvmYlNooymBo#^ 1&% ~ j.1Z..;...0  Harvard209NA UU?eUU6 ?eOO ?m $iA:Xi(Bm̾Bm Cm33 ii4xx xxxx x^t:aT&5BV4  Fun :&D1?%>-">5333ZJZJZfJ4ZJZJZZZZZZZvZJ n ZZRD ZfZZ2ZZRZfZZ2Z"ZJmZZZZJah ZfZZVRZZ0d?%>-3QZ*Z&~Y=7NY=%6.Y=Y=Y=JY=FY= ..?MBH:-'LLLL.W?  " Cap2sFJ(9҄0A*H}-Obliqu84rkV?rz;)? ,4]tQ@e]t@eFA8AeAeFAeEA.GBullet2r)0@?etf*./x•*N14E4E4E4E4E"4E!c^*ۀB^ P4Z10PM~b8bb8e B4I & Page Numb.=acterz/ Za:Za9!Nb5bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.<,% Free FormNM03Zu A*,NewRomanPSMT^NJ__none$$z<jN3zPJ|,nG&n2o2image-5-S&qIZ ey+"F] B A$al Shadow JjkJC@r$?08"=!*<3!^&<<<<~< Blue"<<j1< < <"g1Dh;%H>-v>5Y "J "Jr&=fg1J4 "J "J " " " " " " "v "Ju] "ZR "f "Z2 "ZR "f "Z2 "" "Jm " " " "Jah  "f "ZVR6 g1&g10;%뢧>- "* "& |. 0S' " 0`Bpj4d3Z 4@A*CourierNewr -r-R20.SCV.SVk_z2u.e"BS_e"e"e"e"^#B1####.LD )3 LrF10#3 :L.$$6d8R3'58.?3'3'3'J3'Bd^B]$}0!%R c Z!d4.X^'aingF2-W*)WvRͦF^P6U3U*E*E55&&"CmFj* '888~5RP.~# &)BiiiiFaJV 2J3F>i`:0`n&bX&B70X}}}}R} Br& :2  B2  J2  R2( ZZX"4`|?%޲a?-,>Q a? $4>?%?-=$?E$ *˖@b\j\j\j\ $g?%!?-Rzvjv]j]]n]8*4  JVZRʺfJ^2fZ2jZXfVR d?-S/;I ʊNS&V .fB;4nJ!Zj"ttt2t."*"0J"YFYe"j5k>LwzA[uT.k1JJJJJ.Wp1%-1BWZQW!rF'>>>>20"?%ҷ>-l2&N20>%P|>-$\:\2\:\J.F v:v6]:]6]:]vV-Π ZRʪ fZnVstVKXfVR&&&03/?%z>-e"% Δ~:0N@3@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@^+6-3i4++R>~+9R+-X*.+++V+F+VR@,@@@@@h}*Q@bJ@h}*bB*"h}4>%$"?-_?.@J@JfbJ4@J@J@@@@@@@v@Je"@ZR4424Z2)ZR4f4Z2$")J+JmJah fVR^&.>%LY9.H~)*~)&b *x0*   2Jל*qZ Yo30Dl?%P>-f"&*@*D$:Chalk2{*naJJ*PZ^R 9.?B\"i*ݶ.`.T6Ϙ2 Rmo+mئ.ީ jmo~'6R'(''''F'.IAq=?"16RN:2JB+.8/B}8/8/8/8/z8/8/R :>qF8sFF&JJJJ4JJvJC ʿ*ZRʕ *f*Z2ZRfZ2 JmJah fVR0q?%b?-}"ΔN*& N R R R R CF J J 0>%?-InCFh J J v J9ʵ ZRʋ f Z2 ZR f Z2 " Jm Jah  f  VR L&L0W>%:?-O3L*L&C.A:h4ZAO$>%>- LfO.,Wg  $er1 2FS43ZD[TA*VAGRoundedLt-Norma-'(l:%-P5?Jen_USPX`hu} 1  ,Hbh,%B(=I@HP] 8jL?px T xibH ' chart-4-series_1* 6  w @8@@L*line68"O Z!T !@2')%N*Q>QT2 Gray Paper :B  BB  JB  RB Z% 44?%4?-4?Ebbjbr 4>%?->Nz JhbfD q<-A%ykC! ?0800`200 @@ r04B -apIX>% -X)B R0(v>%>-R RJ'B ZR@ R!CH)H RZ2vR R?%a5 -)B RJJ Jm   JQf G:Qx AIĎr* RJ!  R R)HVR!  n @ Ad> 09g?%g?-gI~ʔ 0*  U 0-4-shapestyle PZ )<0>%P|>-e "j.-.H?08*PZ2  @H@ah8@R  L  List 16 list--20 X>e*mQ mCm4X| Cr %8·ov-Ix* % Plain Textparagraph-U4-U3Z!H A*CourierNewPSMT:Z}   qaL  5 tableName-5ibSabZIZQmwAF  PZ^A1  3-5_7 4Z10@A* Helvetica^@vj ˯B?@ $be. f  !P & 0- i1    R @ Bright :2  B2  J2  R2( ZZX"0ݐ>%"'?-7Wzҁ? $0 8<%>-{@$?a,? *˖@b\j\j\j\08>%>- zvjv]j]]n].0΁Yb V6Rk ZR fJffZ2JHjZXfVR/& vC>%+?;RV .( t_ -2-   Z'0o?%o?-o ( 4_>%<>-=  QQ> ?/ , 0))&Z("%Z>$RRRRRR%RRRRRR%ZR2%%ZRʐRBRRBRRBRRBRRBRRBRRBR ~.3).....N.N.N.N.ZJ;.J.J0-@,.J4.J.J .......b.JBz ʱ t+z z  JeB r bZh fVRL>%U43v.m**m*4>m*2 P4Zm*0m*m*I9@*@*!#@* +40-categoryaxis&F*a.&0$9?%*9?-!9B$(8MAe0 r#bbj: ~[ 79:%o:!- 0V; $;DUh* ' Heading 1 A A"-.9I3ZQ.n.gN;;.;$Vd1402d144)%d1d1d1d1^d1.2 ! 2*2 automagic)MX>eUU?ma2A2X22 22xx x.^ $V $(Cell-2-body*$ Z4  >7@JK>e414*  )4Zb,. value6 ?>8mzvbʧ!@?v[?ƽȁc@.44* $ BodyZ45I3&I4@A* DejaVuSans^2 Jitv2LNAHA@*ABA./$* * (er & FooterF5333Z ~32tB6B YBC NB5*I&32B3  6֛BBBBrB( Green"B:F3F3F3F30X>%>-" NJNJNN3bhNJONJ*NBBBBBB:BW2W2Jڐ NZR8NfNZNZRNfNZ2|3JBJmNNNNJah BdBDBVRNN0W>%f$?-VNZNi k=.tL3  ~ Blue"   JL   4t;>%>->_ J J 4g?%!?-t>3 J4 J J* tLtLtLtLtLtLtLJ 2^L~O&JBR ZRʆ f ZHZR f Z2 Jm Jah  f  VR 4/k>% ?-2? R .{& {b7 AFw1<aKJbHanadV|a&a u 31-legendgZ M?*ATRXa\2P N1> * V "s RRRRx , ?% ?-Hx Jx Jx J4x Jx Jx x x x x x x vx JB x ZRb x fx Zʪx ZRx fx Z2x Jmx x x x Jah x fx x VRx x 0??%??-7?r.&  ^% 5 *`% &&&&^&. $* [ @M%  er + (Latin) Century Schoolbook 14 pt + Not BoldF?X1 P3Z <`A* LucidaGrandeb#:er:eX)JX)::eg"v j=X[%u.=X.)D=X=X.(.y[92*2r7R((((y[y[Zy[x>^(.b(uJb(Z_@h\["sY-Bolde0>%>?-.+JanXYNj]b.,^L*  textboxX:/^ ./^!/^$ Z#" f5^ax.ZB8i_ZZZZzZ.z 372 ||,,,,"Fj,,vv_:AN24222222.`H, HTML PreformatteJ5""4 A*`JnVm(  337B ff C 7 e ff L 33   f f DQ L + 337DRwnza"= ,*2 "TŨ-1}ad( Z " b8 G>%-?-=>5Yk2@SJG2c/f`*z*44 H2Fm2"my @A*TimesNewRomancGB#/R#/kVu#/@pF#/"41B r87N#2>.#0:0:0. &y1.y Xhhhh> x•.hvj9 - NZ4vZ0\m?%em?-Zm1 VZVOrOQ;.ZVV*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z&!Y*ZZ Z2q$'3Vr4D&RR&RRzQ*E&VΚ&VRΤzQvZZZZZZZZ6"MMRMvZR.- B1F-3"-.k &416k 5k k m$k |$p $u f z 4k @""h ~GrK?)LK?K?K?K?K?NK?NK?NK?NK?K?0F>%-3?-ܹ_72J2J20>%?-2K?J42J2J2222222v2JB$!v $ ZRʽ/$ E!$ Z2l R$ ZR$ 7A&7A$ Z2HJm2222Jah 2f2HVR3z&z *>%M?z+NΔv5]>V> 2V5FV fV. R">>>>20p?%(?-0&|?("0=_?%>-$\:\2\:\ NgZ*·v:v6]:]6]:]  *!  v &v V-v b ZRLb fb H9Hb b fb Zb >b FjF ZX f  VR & ` % ?-"% Δv !/~2movie-5-;Zg eVΟB F43B32~34u?%6^?-\=333.H [ !&,d(3-headerRow=&1d:AYne e N01B\:m .01jaja0101!#r&^a1Wt ^a^a^a^aV^a8  Wood :  B  J  R T06>%>-NTJTJ >%W - Nz;aJ4TJTJTTTTTTTvTJ  ZRʚ f Z2TZR f Z2T"TJm Jah  f  VR} & 0Q ?%q?-Z&8W*W".pF-JpFZZpF(F.M%$* % mBulletF@s<*Vl6V6VNmB.*4Jc a> Ks. * 5 B     V  Fun&Dz>%/?-م>5333z Jz Jz fJ4z Jz Jz z z z z z z vz Jʎ z ZRdz fz Z2z ZRz fz Z2z "z Jmz z z z Jah z fz 0RL!3%>-XQɛڤz Vz z 0?%bR?-0Δ~*nH.l")" )))))j-G&>TvlSvBRvB&Qv0$?%L?- J J fQvJ4 J J* QvQvQvQvQvQv>Qv8>2^T"JBR ZRʆ f ZH"ZR f Z2j-Jm Jah  f  VR &0k0?%:?-8*&).X8*X46XVX8X8S8b8I8HHHH.k!^ $&k!4k!ColumnRn!0>%>-;fn!.%&ln3N̉] knknknkn:kn.R]142=;1\f*|:2: *W@* TitleJ>-*MqA*N<`J&oVobgWW:*W=(tb4I?eI$@env@@e۶@eA Aj=&jJ,fZ22226S(^ZI482I&IIII^I "*p^]*-0JQTJYC 2 n0B*d6GDI ?"JN3*0>c[.3*GG3*3*;%w.Y3YYYYYZ 26RE2Diiii Jy0yyZ2322^.v:#\d5Bw2 k0W>%/l>-iBw5w Z#:dA}NZ4Zx2FEr F^[0[[[[[%[Z46~p5d3^A| . oB2 o o o oz o.P.RhB RhRhRhRh Qs.#Bwm=#"7"7"7"7AFr*"Q-OOOO~O*""ߎ&ߎ&ߎ&ߎ&ߎ06>%t>- *"J*"J*"fߎJ4*"J*"J**"ߎߎߎߎߎߎߎSBSJ~ *"ZR*"f*"Z2/ u*"ZR*"f*"Z2% OJm*"*"*"*"Jah *"f*"*"VR*"*"0 ?%m?-*"j*".s $* J / l5 6 ptF2e..Z!& SubSingJ6*@vtynyhN:B=.3)3' 9Fy3Z @A* "\Neuzz膴%8a &BE/ P4Z1,P`ZG!wzJ&^y6C$4N.ZI26q(3^w$WC6I5-f>Iz)W..BJ4vZ4524e}^AR?3?????2?2?2?2?ZJ0X?%>-y:8JJNXbhJOJ.J*;26JBR ZRfZHZRfZ2JmJah fVRT; %?-6Z6 @  ' TOCtoc&+/default/5&KZ;e^z^ .22 & J4>e318 :222J2F0&! 1FUMd3Z @A* Nj-ŋΔ~g6g, XC Na4&"r282m3B!mmmmjm.mR/h/h/h/h/h~/h@Bright :    B2  J2  R2 ZZX" W^>%??-q>5?? $0\3%l?- /,$?$3$ *˖@b\j\j\j\r%0>%?- zvjv]j]]n]LA D-%X%-QfCI= ?0800`200 @@ r04B -LtO% X>% -XIc!: !@2'e)3%8N R?%C-?1]R RV6R ZR@.R R!CH)H RH9H R R RZ2>EJj xai e Jf G:Qx Ail RZX R R)HVR!  nS @ Ad> 0?%,s?-OΔi  chart-5-paragraphStyle_2*P4Z0A* Helvetica: ^(@PX`hu}  ,Tbe.%B(=L@HP] jHpx dW {leL1#h* * Footnote Text A50-s!1-29)2 3Z-2 2Jen_US7N7bh,4f44VZ4-5*S!)_1)(]Z@(ZZZIZ.ZH* & Heading 5NV12).EVe.VnVdVViARER' $1-series_3%4 6 } @ 4@@L*line8"Pk:B *Q>Q<2  Wood :  B  J  R  Z 06,?%޳>-Xɩbbjb20-@ Nzb4bfl 6l4<?*<lllllllJ|lZR lflZ2v lZRlflZ2h J Jm****Jah *f**VRΖ *&*0i_?%X>-۽3ʊ~* ~ D  List 3 list 6 PX>e m mCm4X|Cr y8·ov N&q1> 5)K4Z?F $?%?-~ j ˯B?r ](  Legal24)KX> eUU?e, @eB@eh@@mAAAQXAE E x>^^0>7)Kz.-  - 46 .50)N// A!!6p 4  .vd[ !tableCell-1-footerRowI)L Z4 J @J/@@ @.$* J /[ er + (Latin) Century Schoolbook 14 ptF18 3Z@`A* LucidaGrande:Z=J r N *?  ;(F & Linkacter= hyperlink)1Z:X.d  72c1^X>x•.v^-P*  shape-4-) Zm0??%??-?)a?"jz- zL?08*P Z#" 2R#R,r66660:?%?-Z JJ0g?%!?-t NJ4JJvJơ"ZRfZ2ZRfZ2"JmJah _""F""VR&0 n?%uB?-x3ʊ~.~ &48 VP Gray Paper :B  BB  JB  RB  L>%- : J 0>%?- N J4 J J . 0(v>%>-)2^T,JBR ZR f ZH ZR f Z2JS Jm Jah  f  VR & >%- Z  (-1-K Z'0o?%o?-o,$ $0>%$"?-_ )uQQ> ?/ , 40:&;("NA0>%>-"΁*J^6>[RRRRNARRZR2YZRʚNARRAY RRBRRBRRBRRBR R0>%>-"ΐ R9.m+F<4R<)<<<<:<"t)(*2 *w)0Jw)  " `,8K=%+ ?-/?5A2@ Z)B)Bg2)"C3,* $ -9?1F-3 .<A*HB-Bold:n,!/~S3Bbg7?N7?~-(Nu42>1.4nu4!:~"u4u4u4:u4.u4*1126|.77777^3>5r7777 *j1(# ! None>j1 null.F& PlainFJN4. P3Z8D A*CourierNewPSMT^N2v2FF.2&26655;;;b;.HL332I3y8N9IIIxx x.^3.I8 " Numbered }82;K NN;;;;!9RT"3 4c*  9PZMOJ$nN4b..924HRi^ 02I1X;;bZ464:jZ? m"4d?d?Jd?VOZI262322222 N  4t-4-valueaxis_)F ?M0$9?%*9?-!98Nm5 z&#R`R?v[ ? pSYR%o:>/[ &R$^ BT))))).Pr_U-TSSSS Z2} q2A.r F.`T, :VNk3M3Z8@A* Times-Roman k W&,lTd2.BV }W~2TYYRUUUUUU6A6A6A6Al7,|>%b>-ip l7Jl7Jl708>%>- , l7J4l7Jl7J*l7:cUUUUUƏU:l7Y]16L Md"J4?l7ZRV4"="Z2R"ZR"JB"Z2+ l7Jml7l7l7l7J! l7fl7l7VRl7l70R8>%@| ?-ƜD3ڡ6~A~  .HTB::::r:.0&V227F"MNMNMNMNMNMN.*WByTM P4ZP&d%J~ ~ ~ !9~ &E0Ei c c c cR c2r >s>s>s>s2s4{?%ؒ>-y@=J& '"s4/I?%p>-l<$s\:\2s\:\N>%QO -*2sv:v6s]:]6s]:]s *s s sssssssV-( ZR fp&pfZ>.sVstVVVVVKXVfVVVRVVc %X>-Ɩ&I NV&sV V.B,+*0 sss_u }!5-legend'Z %nt..B7 vPKIF)s9$9$Data/logo_new_m-16.pngPNG  IHDRP]~4 pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FdIDATx]k]uֹ3c;ƀMI?RP3Z7ZVMmʧZLb6=ү%Z4sbf8&fnV}?|u h(Xb|tر+fuG/@XKT.uL^_&LOCbsTw嬞mq%V*(\ Gx쉍YnkT朐wΚٳ ld~Ͼݛw޹LTL^pt7^G)pOLjy` rZOg.N` [89Mdo(?ǧ-yq \0: ZAqH3=Lf-Cjǔ{sZM;QD6dwM ܜP& D-XP e0łfGjFʲʅj[8@Ԧ$jtA{nmb2)=l/w\leCrW"Ze8M~l8ybUQQyR9R&i&z.N|z^ yfXkPN:4y9.:dmݚ̨9PYՒV iS^. )~$V5 -4ܗs8x5ـN`W9m]Gq DFa>9WYSŖY}^NJ'8/,t` p*2yx CgPSKڵN`-ٵi(U4FU@OUY;%&8_Yh:f0*>u l\[y8o^r]^yiZwl^7˰ʘfiÔT22X3p['-dg7۵[ȹ-\ ':-_>|i@'5,ƥT(j2mu5bysBc*Y)؝g5|m/[]T|Rf.ovp˸4-g(ȚҀkl4x#f]Z紘bnWRK)bEq(=fc2Up|T9 ^c ޹T&3WF'V^l'WMtb!C%}1k9iXGX]q`3 TB.\ ̕+dq{t"w7ZD !ZT1Lu j(j팒@XXRi [xiyMԦH< 0.N~Y]L? h'Ca}@,񨕆aɮgлX|z@ɓr3K.]&d׳ ˱~!Tv T3t') + Ѷ7pr=Vq{l^j2 /!8dn`EYr'I>`%,RkDlIFgu l]j&5\!?=*]AdoG*c[@AjR'B5͆awhugg{py0z2Q`p$/ؿE#un@߳@&.Ѕ(ڻkh3;ۻK_-[? Š-gdҹhiםBeUƚwFhiD\= /(\xU5[DO|jZt /@'?H`y3[6wog3KOjXj-9- =V2l)0m<--{l11CK [cyo = ^)$Z5hf'&E=`j@%kc3C_w[\t)kvφm]gV}`j&`e \S7X>MlN[6ƶ_ L+ń>; yצK1Uy ld'SX1. 򝥰 ie&3S#z>=ۂo*AN$^TA("NsHb,ZiĀH{/,ťX2>SSd&1ʤq=9ys.TKw2ξ ̾QPݠ%_w u#:Ot#TPTɂYP:3%F@9@}[/|ɟ+6> .{he9`(`YB(mrP8%7@jg]V"4,qfo{ <1bvTVƽς>еΓ@; '.axxx~}~`ju2>4  TwݿXt-aN笡nΩ6K&%XS[9dax5ƽr飦3ى͡!q u9ȧEǎ_@g t.ɭ_ty7v jxp['h<.xSp)=Շ$^mWq,5I0Mq*7D}Co+"UG80~-D u'OOJQ`*`\{AfZ<0&`U3nNq3du{p|LcqB@_r=6:.Ky=U\W(l_PgLֿw=TSXU*p䣴{ç?!ѯ)u)FgYPiQ&&5 Z:KM|8-3 b0s;V1֙8e/z&O,DmQP;P>N :T$tm (%Zʇ 8>B%hO*Q_'@{Z#5g!K|svp-G;M6fyd\'0OݒǀQ'P^hrbw=Łs#FDmBPZ< 4j@ 4A@c hL(&oȣHVB"u烙RwTJb!np!AڞMf1XNl-(w4x <'I@TsRSЂM,ܓ E_:T@tp{1S" A8cr4Dq#O2Yk'ޑn3LE`M~^6s]y9 ;;< Jhjޥ7wv , X9SX^$2Y  )IᑔP`"Eb(ϗ)#"ʀ6/]@CVQ̅ {M޹!5Y֓p~fֿwH?UU>PMɘ3 2-Dp<=J'JnGȶX nIe~ed0A>&|p{G6ùa.]V[mCrjI$B(7R9AiU('=XrhX߶['iW[e& 7@zXdJuCFYc}V? iڱǁy+%y-']chѯT8ӷ(]m/ k5oK3c46C !ɹ: ޸pO"Jä&(»o>oƽAk0x}{7 Sܷx5 ޸VL< n+9_ X|DG? do!mkjJ˰ 3@kyWxq`/HJνtU"(=ca̍ ?AmD'5J!LzmYȷahwa 3Φۭ]hH0D /1z3 oq2t5A =C;oS`"``5([tp,]ӟ DjyMpv!=jh 1xC1z~WCq#?.Cl;l;jЕGP(`JQ`dTR`opPiN"Juk{dm*60LP](QLtjL)M=CMK>JQސ ?wMoQ%ҶZYO;"{6qFAOGa`l%S]V |7BՔL05dXKE&&eAXx-~3 塒MkT:wF[E!ʖ,b$F7)뒃<e8r hGȆ_d6#րҩ%ĜJr:LbU0jYY7k@ tޟ>Cf_lÌ r rSkYeB' 2YuPdG+ױ__[ iS([ 1n eo1yۂ6hX9+dop# l?g@U%iuR`#:3' ebTӤJڄ+!X|;}m$kv-D`B/и_xnWz")Gj Y$eZ03ƒKzLQL!~ `AJT{}ZnILDJI\B2.Oe>3_PI C(9F/,]GƗMcO0a]vwx:(dsl;c$?`Pm^rM*'>rrFIp9W)iyaJw7a?}M3Vg$u}6j@VGʿ#J.:A_ pj<!^0Q` /p׵+/w>0QKf}RcwojC`a'UvYVZq=x_ L@9&5K;}(3$4y l2%8 pTpXb&q D2 ɛi'mZ 1ijgDjI13ҐL K'<&ViNUg\q\3=v74ÐZP'''>J&&,Qf5 S=~@Lm3X; Fjʘby;:;1IENDB`PKIF6Index/Metadata.iwa.c U.($EA0EAE6C-B2E6-4734-BE72-F8135789BBE7-Tables/HeaderStorageBucket"*,P`MT /$DataList:-1"2*2  O5O3O7Kj J.M 1 Tile:m5Ď9B772:7 Ž84826a-i$2 ZPZ鿦ɎZ򙣴r6Z련uZ6`̅3_`55%577B776B7Ŏ78:76J7MPq#-10:8"F8:$4/ ViewStat]2)82P`A>LCalculationEngin.:0 2AH222     , " AI*"AĦз`&ThemeStylesheet9* :E/8DocumentN,i    2a9 =  %     %-  0  (  e  )aE-(*Annot%Author91%- 1, 2!   %   (    @  (     8  (-  (     P    ( 0  (   { x H    (  H (   (  aX=   %     ( @       H (- (  (   8 (  (  p! h 0  (  (    h8      `   X ( @     0i   x 8z ( (       H ށ2  -  -U    0     8   X    8   PH)E  0@   8  (x  H @   (@ (    8   d  8P  (  Ѽ  h P  p P    @ 0      H (    ((A@  (   @   0  " (  a  h  Ax G P  h     *  ]  } A] E   @!E   (  H    P H  (    p a% P!U  0      0  x  @ap   @   @M  -  @ 8  h 0 0  @ h (   0>  P    8 H  0  P  8  U6 - =5  U M    0  `0    X"K 8 P 0 0c   8  F   ` 0    0   @  h    0 (  (    Hc 0  X 0 !h   @     H   p  (  2  E =\:PZ캬ʧ  Zť;BZ7ع檳Z8\ꐣɧ(ZHIJ̕ճێXТĞ:ZoJoD|赩n\:نZH-Ւ\͛EZʢփ-Z˫Z9HӼޠuכq\˳ިѱ˿jZV!3Hݑְ4ݶ!3HㇱEooTdž&Z̜ݪZԅ˾아ZNVHң8V8\Ⱥ 8TR琹ƾƛY`"OJRApi8Gǎkh&gSimple_Noise_2x.jpeg*Ginger/00_T/S6&";Vlogo_new_m.png"l-16.png(:@PKIF|CffMetadata/Properties.plistffbplist00 XrevisionVlocale\documentUUID[versionUUIDXlanguage[isMultiPage_fileFormatVersionYshareUUID_'0::EA0EAE6C-B2E6-4734-BE72-F8135789BBE7Uen_IT_$4EB1C224-431F-4655-A085-C0EF667188AC_$EA0EAE6C-B2E6-4734-BE72-F8135789BBE7Ren U1.5.0_$4EB1C224-431F-4655-A085-C0EF667188AC")6BKWku$PKIF֫$$Metadata/DocumentIdentifier$$4EB1C224-431F-4655-A085-C0EF667188ACPKIF"Metadata/BuildVersionHistory.plist TE-v1.1.1 (Jan 16 2014) M5.5.3-2152-2 PKIF=$gztzt preview.jpgztztJFIFHH@ExifMM*iԠ8Photoshop 3.08BIM8BIM%ُ B~" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzC C  . ?((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((ithS<?1G()d̏)d̏)d̏)d̏)b?:} ( ( ( ( ( ( (?((((((((((((((((((((((((((((((((<$M|뚔Is&#tb+ _^O]_LC&r|?´+G74k/inU=|/#}K+r6SUpvg^n"IIkkk#?_ֽ,$-E8zg'W:ukG<7s, !gzWh: GCU@undf#ߌ׽p?CuӶ獛zur}ug}_P5YuK=*K dg]|0nfDʃ$Ҽ>A֩:P+Gvz|!Rsm}7?_}?O Nmxϗ*}nq]ern Q:sӓ\rڭyNpvM\fWN+qQϽKcP4k>/ƽ%VK ՚eO^7peK{)$lUA3˜V18mn2F_MhF+[Bă^ŗ^/o8&/U{׬_#_sƯѼ2έ,B|/8hҫEZ4QE~~vQEQEQEQEQEQE((((((((((((((((((((((((((((((((S ~sj3DȚAٍ~j?_;?_ 8)~oy˓ݼ˨bbEyk>'E`~OuQ\߈Z·V-<s\o>e %呁&`J+W\/i~-hfu(# X _8֢hgx}u/ Aiՠd|V_},6 &a[9A0=ӾS־ Kݘo[y99Iy +~&Sw>Ginvmn 7?$u;+P1mgwtفOեRXߙrNk넱҃ڬNܯ t߉?Ojz[c&Eyoį~3Ҿ Vvx* P$wkE ׈!E傃u*{www|Y{ d9b 7lOp 1T1t7QVrriwdYF}Nuȸ7u 9cudm'R7gn,!%W"|eMCß _Suv6s_7t? xa̶Ȳ\\~U@pvO^1_Vɨh:ol3Fk[C9wGDU5FpiR˱)*t!k*/;euw kv_SA:ӗmSρ?|CMߙ'fwӾq\jCܶq#]/QЮlQqKIKB { oƞ'o0pc԰7u&֒?SǍ09LGה5rh^  O]?U|`WI9_Ŀ?z_O4j 7FU_?U"Q  O]?_/ !TW$yFU_?U"Q  O]?_/ !TW$yk )M_-WJnp>eÜ$wQ/Ct[{GofʷqD$Թ`}A6x\)*H~AE>2j s? L"=;ⷆ4?_Q~.y:<,7(84(Vx_h t?Z6e,}TQX' 5F7n۵I/t^hѳoۿ^XKӪO[}^aO'ÿv|Gk6k7Pa#!`c>%/E񷎼gKv&kO6dDLH7<_Y_߁ĚޥkFAB4Obc@Pa\ Q(QTPJJP}2y9.k~mϠi4r޶rı^(ikipO4B,_'kω.PC~"𖚐v櫩iL&ƙe+`Yeg>iDnR+so\,M:=_K)`,gq_a`!_i/#/>;ԢѼ?xdbQ#ۣe)"V85~4h ;G>OdruGegR wo߸}e>/OŸ>z=Qv׏umK萒^^6bvI k~9~|YxB4; Alsm L>@ 6K m< _G|A<Zc.hYWw݆I]=k%PW#Ӣ{j6Mjߧ'2vg|e #,]|WțW]B6SK6W& IWMѸ` z~~3_g‘xOIJQc)BYX*#++;.t_5>6η]OZI*xWVm*m{-H06T}&&9QN_v.7bJOs菇>V|WT:ׂu m }PH4A,=|tM+ž$u+m[_|?v>_jRIt?>IUJWo]#HW_;-|YN{ 6ek}/k4 [bbmW?lN? 4#keJMkRub̓vzt?vȯ!~Ҿ49'QcӧԵ^#)&$h-1A+ۄ} ,iχ?״o h,?,BnZݯ³V<".7E<˷7_VNڙ~J/QR0((((((((((((((((((յ#AT/8q\]ʐBnw*'pEgzXŪh1\ZʓB] SСQEQEQ\׌4}KKy}t! ݘH &ݑT/]/K}WS0,PrB䚧xÞ"Zhwy{wͷ88\Q+sndG( eI}QEW{[mu+s2e $3ƌ +'.^H)ʲ0`zG9_py_֨' ö>-jqwͺ]{? iӳ}J|y,r.$nGR:Ed!<2暺4w9g?J]lIEsz!ލ7X4 etv ێkU5M2M@1eLb)L̤ gE%kmlOG061@ULxC^?~$6o j~kGusm$qGVHs2;+ =oa{a LU_:t-r|.smm)9QԴ"MGV'b7s 2H'Z?<;?Yjk CgqBznٱzN+5tօuoo~b~ Ծ*?toxK/ 6'"Uc+j`<ADjtdg|ܳs:'dfH[?XJ.}ys97o {\[{{Y;j|-_.ǯxpD?ȟ)/ψkm75>,1گ,yf4`(ɥCӦ<+V7ԶEI;+G"Ab2@< L]oOky z;]- MOy{_5S/iw|MCxzw%՝̟#EL@P Ꮘ;?|Ѽ<^j.<\\whأڻ-.'sW|5kzׇ4F OòkfK9.YYGb0qiۥ8:꼵/.u֏K/=͹|5d~)k|'CU#Zh:.$)p%і#RdF$V_O|qmgK6%tѽƮ &UX[YiH YAdv+81brFJ=xײZۛ}y(zRzt?-t__ +ޛkuD安}~jڳBHyPăWR9zǯZGF>{ $h|,#yIMV*ߤjzlTpI{hql+MMg@w*Ht5zTc(3חoNWIjZ%)J:_^e+k7o?d_~t$4"'5#\zdK7jP iB|B|Ǟ#!w|+u+7~"U#38<#^gyII~{j[vEҺ:6jePXvMe%fP:cZj٧_?<|Wo;]bC4}e#)$u淔Icai?Mhs(ofzZkJZ4ggkXE__>|y|Y_<=KT5 ags7v>C2EhUȏ o?mτ=yOP񿇵k6;+)O)i䪒}'}gGWIKF 0PHiRr!(zA%/ZT=ɻ)'o9]>4k~4i&j$F?> &߈ `tN7hJTIT]%{v,UN5Z|=;$O3^{@nk}-^}'JЭu'dq \xo&̐)RʅC);o]@y?>]Y4ۘۺ=DңFkH_X|W'>x !6Hmltk[Hqt7č3wߌrxR<;njDgr2LĕEk*{/[ӑϫn[]'7W\ϵt??j >,|Uּ)xkhzMgwfY7R,b0bTteO?i4E3mW7YW:WtCk~Ԫi$@GM |9ČwUިd^b3~Ny}0`/kO|j½jQhVYutoof{1qiXn Uud|=Ʈ޷TŪ˓M[nr=??U㵗Ew{yq-jZ~X-($O$W>3:>%ѧ|AJ|$}īy&EYNF鯏5|i^ fM2{m\.i{<,h\rrk'?>>f$uONR]/0h3\hk^im㲭4AF&SPvm>g]7JF݈i+-۲FiZ|V|Qw2x3Tz4VQ5;{Ut#!. &xƞ w JxLf K{)DNiɌF+=+O~¾MGv_ 5 G>]6-cAm.㿵EiMȊ3dz~̟m#x~-:sM.] \MB-q,F᠌+JbNܩS;hZkoovǫqWi4W_|iJu x#AOxk2&˫\&5n8yY*Omo>S>xzγCB4t Ɏt[.6<,+(4 iZ_Z߇<>x~'yo&ҽ[w>߱<K=3Gu MGVzƕ{%o:Dc@Ag=/X]=S!kj_n׫ٯj!%NJ~?-l>p$`y{awK B;gvX,J)ч[״nQZI8nR[/7%4R]Cំߵe߀>|x o7u?(=V=I$i\b06AO UW>!<7{E6협)6Jyx?5%ְ,Zi/pB6[$wp x |&txSwu%C )"]HTX9yIKykպr\irYki]/m/|'/ٵ%͌dp5L$A11{tm7h3_ՌZ].[H|@~qI\ZyA`".ݜnq+|Q\ARğ 5k}๼)m nݵ1y$Inۅ'(|cD"(,8wwyWr\)5 _5ӵnF^i?uJmv՚tM=xfÛ'k]O2xZj]Ũ-ȯicːa#)/|Wмk_ m;Idioڼur]dѣO-B>w;Hk>2pi:7-+.=>Ëvm;(]gVǙY0x ?.շ-gžmwqv,{dO/-|\t^u9WQ 4s!bH$"> _W· ~)Y]m]B"o(;%#&KuዯڗBumH]H&k\81 Kz?ٞH|0T0I%V]\/ Yˮɴve_%Kf ۿ:6+('r{OYrU*(v^rR{ܞnwQX |kosZ:8 ؂=A?֥]LZ z ZukIkyeuoHF(΍d}G4ɲx5fo!H BϵxƓ)x|5;bU?Zhvo*Kˈ#;fDmF PMJ^wVzk*m:m=n֏^^m{^@aCkQ/A{c/O@B`+II XmźX͐䧖Akg/|mcgxIԵos#SѮdOɔ$@K c'+߃o|%x&}}OG ہ;ב4bUOg \gO} S[VԵ ח=Fb8u' 5drK^ܪ:ixe(忧"nnN_D~$ |s7|-φ:5-"w.toۛqm`>goş ~)п 5h-ex{P罼Ԭ<蹈C9hG=YES>o>ᙷy^d>1u%]x]5 vgƋA`.dCQmIENRn}V+Dw+(Y򯏿o?GE_c ~i5ϣZns0t,$ `|A<{B2x{V4Yj˨iN<$2,"!"ۃZ?+y¯ykǪ;%fHQ%ekFRtܴx_[L[x;+Uk~1Zqʚ!Zq9 tq3EzhH׼M Ϳ FMC;Оoڼ/O+]/_Gk_/ i5 TQ'-.,b6Y M+FO5K;GwNWmΉJ.WȝJ_>mC>gSE|GZ\2&c4r׳I jv]>eMxsTmF(K[ybwce;[8o,?e? ,|f$>_WMk[hcrAP|y|D<49{fR){®=3೹:M\ܖN˽M=lmJ>oWe >M잭G[/|#!o5k?Z]65MnERE~1F1FdGG wS|~׼A¾Cf{M_VZEo-d$0ƩCd|ϣo7瀆#㶷_~IXK+IXtٵYl՗k(]>Q}Vޅ0|J{KSEn>׼H|C\jKF #ߌgg麱Szr}}m5JNy<˓OKy[KO?N}&wyj]YЯ. ZJyݡ@}>c_|s3wB=ׄΝ(o5GKԾW환Ȑ>_)_uxcp'|-n 'th<)o\鷺| v$N<|xE?oA5 G[M|Ricys*1/뮚~Of\0$[>77xīŸWWA F& vKoJY|Ծ#ڷ'vaZͤIug5vַ].!eJꮬ!t]𿊯W~.jqWӭtdYl]e0X .O_ŅGÍGǟY|,4.Aha{u[7],2$ipUpgʅtTMrrGykinׯ]v-?hOo?i={P.C%mR@ue}y% T8lK?şNGIO(.q{j[vH)W$o|u?_Ac Z kCזڽ%p paV ?w.x#wX,HVH>TR*6%g$Ŀy8}.F.nVהQE!Q@Q@Q@Q@Q@Q@(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((734m.5$E #V`Xla,($3կtMziGbV<˜,Q( qWg~i}_ \zΝ{ t6EUȽC/\v6 VLί %sjGKSTK 2\֖}ݿe'[zrܾKR^m)[%][nsjq&y O&i?$u6B{2} ]MFh6b/1ɽN.䌡Tlbە5 y~_l9oÚsi[/M_W77%Bi`k{mޫ %Ӡ!0*)ƣݤmufT`6]zhGwef~U WRѴbg{{$m廜J]p@M+|ƌxU$ ߇.|=}JƖ:j~ JyP.mRjv&Gk{93dRDKkO؇DYb>Z ) -i}>(٫۵h~zٮ_xgOF i,8iBKo Q]%"y*Fj^>'|3c7emK?Euow:[P abo8@44o7 4 I'-.EƭYl9!J̨έI^r^vk8/t}57ů x¶)Tb+KPK{rGQ˴j:5/Ѭn xY'mo쭤472]][i# y[8?xץ G9Xi0K4{ig$!mU2v <-?? ,kXkk|Aۓj:նw{yt.c8gWH(Q6Wh:$I+[LYi]uIX}=~|Oijki qht[Hm [lkhev'skŋGNCNGI"څw,'Hl|| ߀4i:~g8<wXeN+4]FYd;6R0m˿ u_ڧ5ko^קymtl況㼼1qeno\2L;U!J7wRq |ݬY^N1ߧbOK?袊4 ( ( ( ( ( (?((((((((((((((((((((((((((((((((((((.-mnXIPH 2XPFEOEQEQEQEQEQEQEQEQEQE(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((Giw]8&%7i 2%DKqSI޻O:z+/|SzL$-P⾁ ;w ,FІu C EgM#5mSԖݥPJm!p63W_OjwQE ( ( ( ( ( (?(((((((((((((((((((((((((((((((((((-7okN1Ic|4Zʍv[eqsj8.e(Z5Җ0P?i?U=eVG}?cѵOx m_G&aƍCUK^+EhK"䳂kBQ Dn>niBO>6O6G5Q ƵʁCB7M)&?Ur/mYji1m>nEklݕ֭߭5|oG;-}:lŪZwak&٢H#p+|W|i| *SJ& dԪTy;ߑN⮑x)?hue֗Ows2̇dT#x\?>xB-O!Y+s`&[X9F5jj]-i]w5f?+mQEŠ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((PKIF۞preview-micro.jpgJFIFHH@ExifMM*i&68Photoshop 3.08BIM8BIM%ُ B~6&" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzC C   ?(C_u2AsQ|6'W~[;xkT'V_M~zѧ>iIvwFfEfXHN0?ˍ^)J<{A #ymӎsZP+ws#XY@b24ǟ0HN= cwmM~_+)=qC/=N(wmfXF|dp{ʆxLk#r nA@PЌƖ :(((PKIF5Sn preview-web.jpg JFIFHH@ExifMM*i8Photoshop 3.08BIM8BIM%ُ B~" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzC C   ?(((((((|K i{{3&7#FFGoJ|eQg igZ)gdrTiIΚ>v 5(2N[]7FjIviF5i;UQE((((((('kqcp,4AHH|h.ct`!XQm [p1 l$\F9fG/e,m7;`t .kWYLUZXR+k󲺶~9NL <ʣWI^ܮ׷|A7 |4b1p1R4a#c3i |d'dMGBY`GB^ kpVʝyVI)|<)+Y.i~g{K2TcJ".g+ݻ/((((((((((((((((((((((((((u_t8#29" L6ñA3Ec.gB_ g/oa.`uuĽJAd;J+û]M{]"G!Yn4,~jF! 1 N0FTN}$Qx鬿gE\Ÿ A4{وU޻2Q\t mq^1^tQ_W?;z]QE((?Kjz%ֵ]KP8 1#~œ;A (m>0V7)RkUY'mc@ŎCt]0xEħl#FГ<⹐*|Q2P}ڊq/e|4JΙPۂ)B˂, 8:Ğ׬1@y##y F 08~1xl޲1V,-! d,[uy!RxY67?h}:8Iq*df|"]~ݢ>XԬ-lSGᎳvŀhGMAb[UpWBm^IgO,;8O0]\A} $Ld$o4 )w巀|Y4K3]XXfY+(EF#- r:ax3UuYXDn嵅ȉ=;ihdm$EY!k?xqpi%2e%f,W1p}tqǥ:=QE ?(((((((((((((((((((((((((((((((((((((ԵFhW3"3$^a^w;5(u|]GMfu3elcϡ (?(((((((SĺQ-oemFo"@Kl1޺5'D,;hZy1$$jXrhbKXm>m{HBX<]6PFH }MŮIFiұPPIndex/Document.iwaPK>IFd QIndex/ViewState.iwaPK>IF,z TIndex/Tables/DataList.iwaPK>IFiynTIndex/CalculationEngine.iwaPK>IFFd=XIndex/Tables/DataList-10.iwaPK>IFiXIndex/Tables/DataList-8.iwaPK>IFyjXIndex/Tables/DataList-6.iwaPK>IF=)7YIndex/Tables/DataList-7.iwaPK>IFp^%%YIndex/Tables/DataList-5.iwaPK>IF-YIndex/Tables/DataList-4.iwaPK>IF*3ndex/Tables/DataList-2.iwaPK>IF&ndex/Tables/DataList-9.iwaPK>IFt#i7Q\Index/Tables/Tile.iwaPK>IFt77&v]Index/Tables/HeaderStorageBucket-1.iwaPK>IFNv<<]Index/Tables/DataList-3.iwaPK>IFP/{{f^Index/Tables/DataList-1.iwaPK>IFZ9P22$_Index/Tables/HeaderStorageBucket.iwaPK>IF]UU_Index/DocumentStylesheet.iwaPK>IFr!tIndex/AnnotationAuthorStorage.iwaPK>IFQQruIndex/ThemeStylesheet.iwaPK>IF)s9$9$Data/logo_new_m-16.pngPK>IF6g3Index/Metadata.iwaPK>IF|CffwBMetadata/Properties.plistPK>IF֫$$(DMetadata/DocumentIdentifierPK>IF"DMetadata/BuildVersionHistory.plistPK>IF=$gztzt Epreview.jpgPK>IF۞preview-micro.jpgPK>IF5Sn preview-web.jpgPKnDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/doc/nDPI_QuickStartGuide.pdf000066400000000000000000004204031262705051000245240ustar00rootroot00000000000000%PDF-1.3 % 4 0 obj << /Length 5 0 R /Filter /FlateDecode >> stream xVn0+(M& ͡!u4'/)@ 9\C>5<-*^f7Gw-n۴l[X8^rLpf>zyBC'f7/ęZsL9k=&\;.FW'̽bh2`m%2tbE!; i/SP\X|Ic!/j4tMy,JXW('+RR:Wѣ +cSp1ε684jK6 9xL$-(|ntSrҫHedymwd;J#)P=q2cOU2]RB0x$ AHs#3 ܿ"jwoS7qoQ0[[;ЗńY7tc |FR7rRBC\6ׁѓy]Vr熚@O\Q{N#V?_ endstream endobj 5 0 obj 843 endobj 2 0 obj << /Type /Page /Parent 3 0 R /Resources 6 0 R /Contents 4 0 R /MediaBox [0 0 595 842] >> endobj 6 0 obj << /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT1 8 0 R >> /XObject << /Im1 10 0 R >> >> endobj 10 0 obj << /Length 11 0 R /Type /XObject /Subtype /Image /Width 86 /Height 43 /Interpolate true /ColorSpace 7 0 R /Intent /Perceptual /SMask 12 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xXytVhQ*֪ʱ=njVNS("D@%@ !+!"ne’/w߼o޼/_ж==޹gr޹;ޗulNx'_rCnvEc.&e*ٵSN&ݗ>:W/3 ukZ|z.ѭvQxӮ-ng_qTT@tN͕ycgxi- jTUW *?]*+xtB t~lPйyV%mŅiacyh.m*BQ=Zȶ KC];DegWzPPШŵ{y×J[C2Ĵh]5@)]5/W6F$Atuؕ(*j1d*G{N۷kW}.-n+ޮmƂIW2-#eߓFpSf,ŒQ@_q ؏gGW]qIoc/"KFe@n:*jXCQnGza2^%@6.ղrk )HhQ~+r0 c|U)!C7>Еh Ϲx[B.Z-k, K[8!a6_``<.` | , ! E*O[ٱ\gZ"12 5PUKxx1bHfo(PXEOejJy(k/S{nuSfV!>w-MA|8{i<]XD:kO |rW@ 7XJ| }7DKtdy(Kx<,GѡX>S䏁rh y{gºKnjy,^1;|t7gu~S\:k׃XD7&{%aKW$jI| 84Ўr_9dxhU Pee}D< QC$ZtP ΁ lM@ Ad!K23x{o][w&r3~弜z)3T8WRDlO|ky*G!3Y8bvr Z51~.}Zޛ3agZAT2ҵXiTAEchy>r)s {]CQT2s` ~T0'@t,9W9 XZ[}(-%-=-'|)_MKߣe zH(KIP ɃTi3O_8J т.Y:6R Xcv)=i3x5%EKޱ%"Pukg2v{&/{)wZcT{_rV3 /ƓZsxsN{ñP,{Ú$> !/xR+KZJ'a'OO:hf;x[{g?HI?Sz %NIoQқt7(QRW@pdzme̢yWs<>~xK,7I-D&p+ܕo&" bٛqˎoe=-`c\p[u,в?y'.В'~P` g= ;5iZЕ^(;'Y=}ڊ<tț8dQ˜@lhn'=]s~ukbtsWf W-v'?s, ?uLl*?BsuE-9ҪVՁߋmڵ<, i yʭ `n'6zra`vl~Pc{мUrd"?QP99hR$xCزn{ $RBLd t:bxJ9J mR)̒h^wp$us Y``Kb FLpm_J/.7 3bJkRK šx2?VZ7 PE,M j@kRFaM%&ƿ/M1T<3\ K$7_>/EPJ^: xV]K+>nIC&IbPF'6o9CW(9CMӁ"ZP]|kǫ1m<)3x5d1Zw-8\Ꭺ.{`Lޞ"r N:g6NEPzJxZFÚYn 'W1wA 4.]~,ѼݑZڀҺ,0B7Ap(i#Zr`?Hb R]'OC`djq/54U6)›Ӓ~LҬ_Jh>ü(o`BלŀdaV&?PHbpLb^(ѰcG@XK38hG+rHQక`] e}|格%ILbυ%X"X_ rbE)APTk)LcqѰ],GAر/m\4FQ!n)V`"ZVC@p?K]K0L3ҖP+ .F?FPqJRꞺ!-ӎn ?F1 ъ֣,~Kum7-0jhE%k #9 |5XE5R^l1ycKQw\VKSS$GNtQU5CwD]G~ކ۽3#f'klji{eemSi>hżE^g~!,~0 q7QpM\ER$N7*»ުrLG^+pkќ1~klxb`ն.g=е{,[ٕȺk54mWcW=Fuk*UW[(ZLGh89quTl^%A(O6צ`iSg$=3Hpg^z? 慜ɽ6\^٣V.yn{:{Z^W3p?r endstream endobj 11 0 obj 3303 endobj 12 0 obj << /Length 13 0 R /Type /XObject /Subtype /Image /Width 86 /Height 43 /ColorSpace /DeviceGray /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xc`R@!Zҋ{;~׉3100o@Ƌ12𝦮P. "lJ?ifQj*@e !b\1eVh5!04(-"T._2Q_mB6/~S xUY"¥Tg4110rʘ&Qz0LBjR#3+;'; L endstream endobj 13 0 obj 230 endobj 14 0 obj << /Length 15 0 R /N 3 /Alternate /DeviceRGB /Filter /FlateDecode >> stream xwTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf endstream endobj 15 0 obj 2612 endobj 7 0 obj [ /ICCBased 14 0 R ] endobj 16 0 obj << /Length 17 0 R /N 1 /Alternate /DeviceGray /Filter /FlateDecode >> stream xWTS[@ W)#̀tDJ 6bH Ć.łeEE]l+kłŊe-tQPł W5rp矿,RH2v2+s|frh<W$e%&A )׿WBP^3_Pă\( @@h܄tr)Cl.kd`H2qKlnAHjb++E)!@ @xHC|_* q "?YT!/* qG05b(C%S _Kȱ8W3eBȓ=d gH!~.sRU+*N!6|I03yܘD!M fU*O$d9["'tA\!(R3raj4{@֗RrD(qB,C R`L2E2;˕E!H"J;A:P¿< ݀+Q.878ؐK r (2@"\-9W T|8g\"S{etrTRW0W!WڧNRZ%&8 GLHd>FIUGhb;aigӀ+Uu߉8!U (ZJޭj\fpJ$q&)-Vư\6EĻt`oU䋠 UzouIvw b}[aS9ح|NiU2}e=}h `oNR/DIws/yPeSfLIXɂ+W -2W( H(w%굤L|UҞ fj6()D{hQudT:lH ?W܍|y;8}2S> Dõ~f>O9!!?1oS,Rם@Ut ݅Cg |amqtMwGG|ǧ!"MeB+?Uɔa#D2iDh44S/T5th ƕeU!0ѽ`B&(s^s:s`GK aØrcC8Uźp5G$;#Nue!GQA$Q.`/^(-rr L bz¯q!xx  H$WR CO%M'UIuӰ^dc?Lry&y1y#y82yBQ\) "TPQvSQPz(o445444$;5j\x1,\MEfUD Rk ;ZZZZZIZ"Zkjz=Q[D{q[/h4#-EӖi'ihot:ΧϡWOu4utX:uJuu\u ֭mֽ;g穗WXo9^}~>_V 0;p|m z ɆN<* ; 􍼍ҍf12ƌ9b34aL4\1ym:4T`ZiǴ,,l!渹ytMGQ9b_-P d[---,ٖRu'-¬VY6Y>fa`1ČS h!['4r=wvv9vZٗAAơᵣcBCNNR]NwiΡӜk$?rK.Х+*rzٍ&qur/vaQq(QYj/mO}r^.^<kiF4{Mq> }Z}6emol)`lo}r;i`̶1m[B!!߇tڄrCkCمFXYO2:<0|V,Q>^mTnԮ{&x4):6zy %ǩ ̊9>~K,e:.fqw%@'aeDi?'j&{&%LIٙ*uliit3"2Vdt5~ 晢̦,JVzV] 'LX1$I3&l>Y<))I;sykxOaU>A`QNpΊܕ}Pa_.Z/z9u~B f$_rЪpFeB5-piXY]R4In)lW8+Qt> %.%JF0ɛZfS6{k֖쩳[Y0g.{yy~)g(9?c~s<ͮ z ſ}۱hu>T+W1/->wk$gIRߥI]_| +qcU媗>W]y ubMڸM-[~p}gؚ=,6,z#Ma6[n{74:Vo%o-p[3sd{׎wZ\ ݥշ{K?Fްe񞪽`b}z@O?m8hpi,i8$<Քt9%?o?lsёGGxq'Ni}rkNu=}Lԙmcg>xC|/4痃.6] ryWBq5ε 񝗯]yc⍮ķZz^yWn={=]]G#ܿoEY^}Q}OxDdw7> stream xWKo7WLok{[-Z PкNVJb[~!9JJ\Ԇn ~C({GO>3| |fh[-S;[q=gw|og<0~;Zu~Gl(f7og"-]}Fk!JͿWs9u{{X/ l1Q2 z؀c`;W{uݷh[Px4 8;)X $OVGvy=W̗|%xu!N-46aD6(E"T3x)!t߹F@N J_VKQ• 6eUBH(HfkX*e rhEV3,dyPbQ3`ˆR&Xe]a9KY3,DN.E+d-aq~jO-?e-[O.)Rv~WHY"GCm7w0E#P3h}$`ιGhER:h)B7-ƚƖr%4P,_t! Y}83ˀlxy宄gܑ}_&/c-}\p/&ĩLCՑ~0w$KmZ~ Z\Zapyy&VF5u endstream endobj 20 0 obj 1022 endobj 18 0 obj << /Type /Page /Parent 3 0 R /Resources 21 0 R /Contents 19 0 R /MediaBox [0 0 595 842] /Annots 23 0 R >> endobj 21 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /Font << /TT1 8 0 R /TT2 22 0 R >> >> endobj 23 0 obj [ 24 0 R ] endobj 26 0 obj << /Length 27 0 R /Filter /FlateDecode >> stream xXKo6WLo܃zP ֹiM0CwJO_\K' :}5@ˏ=)3j/~B1^"Psb[(mքttFE8,e,It<%BfS`; 'A4ܕh`^pYص~RgZo`JzMU+ B prv>gg-IPNx)xEyp(t6Qe[p'sl8Z@5o?%0dD*9,Ԏ7RV1K+&I[.hNxqYN&z"y[D6ŷR׶V.JWc@aU1Sr_;›g2׍N&_F OE 5?{B`lFȉH+Dlu##B2F<QDMIYxAewe_pFN;]ߺ˾/PWy~?w]Ls?{_. endstream endobj 27 0 obj 1141 endobj 25 0 obj << /Type /Page /Parent 3 0 R /Resources 28 0 R /Contents 26 0 R /MediaBox [0 0 595 842] >> endobj 28 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT1 8 0 R /TT2 22 0 R >> >> endobj 30 0 obj << /Length 31 0 R /Filter /FlateDecode >> stream x˒E&j h^Ȥ,ɡIZ^XTd#Y`oC9Uf0`cȺyQY×PؿaM]*|x[oCyޫݛӧ"9~}Ncڼj&:mh&oҳ1L_GlX.m(m:{}~{v.9l E^˛o|wO4'«[p~   -Ch&4%!Ea8!Pŧ2 m0ǁ0;9 /`s!-FPRD8Z5PmF$i?;p3;u8YU;U1m( ޜ6hØ6WXX>G8^Mdq.PI䨔.o@98 K%%g~MAZaHGP뎡G5ȎށGe)$H/sxoNgSZtGeݳ% SIf E18OZ*-A> m1c"-v~L 5 7I*`ƙ4=r!%4R^E~Wԩ;)1*7 IPb;>=}12oEN>%o!3+qtbҠ2$U2h$.!ۤG(tJ!ш>2ȝutaE cI;WF^fQvrh5˫*-o땺.2]"ۦa3>< (rs..$>V𴸈d4F^ j)nJtsN|0}mY^2K^|@`V#/]ʛ`4>MU&:JP9qi 9  C+Nኈ`6K3vxb)R'ZORK \F:A ])%-Y@у/L QZnCq_Tଛޢ.p5͇)h{\IKfr-;<_+wO%H`n&J>uMma:Q{Q.+.ˮ^4yNv +׿(1.gD:Я1нjFLFcZ9oB>"!!Y-G%V~"AܖlzcAȗFDj²@XGl_dQ=$hW x37>i3H֢ͻCu]tUqF0L.u>\嫤 54h^G/D JRQ.AY57[T-X|Y/(lCQ!Au*v ݋{(GV-=g?|[mPlm|[mۓs''DjA䄑+٦ӡ"{dAEa|Z/oΤ"#,OZtLY\ \~_E-ea &?~Q%g*\EcO윟iix-?xj4k~_6CZ}HcME$Z"0 aLJQ͍bxHArxwo'(]h? %NO=S;#WlH1R~a2}q3iZuAv4#GM@4Kxu8ht0YR}%!Ӏ/ѣ#kS I w`Ajq 8x3.akY|_(`6l x5|<## 挿]g ,hgM<8+//3>{ċP!W#zP1AMFM UVNy<)+M~uk:q_Oޜ1rA a33ļ>Tvw*îIl$ѹ9S91߼56tыSbʯ?Х,̗]8'\ endstream endobj 31 0 obj 3699 endobj 29 0 obj << /Type /Page /Parent 3 0 R /Resources 32 0 R /Contents 30 0 R /MediaBox [0 0 595 842] /Annots 34 0 R >> endobj 32 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT3 33 0 R /TT1 8 0 R /TT2 22 0 R >> >> endobj 34 0 obj [ 35 0 R 36 0 R ] endobj 38 0 obj << /Length 39 0 R /Filter /FlateDecode >> stream xZێF}WԾqë$?$Np{` ~֌݆<>ER9mآI4)W?E@o1F֭+sOˊV:x4I#/L AM0%}bL_'y:Iěa7ˌ}lC׳pnr_]Ѩxsk~WyVs%[ef/>?یu}{ nhnZ>6tն(^joԶd%`i4aSJGJL8 @ E2yB944}i3x8U^(td(┷gBcCwhOW XԊD)|yO'b[(|p,J<*``~YQ Nrl_bmx\sBA"oL# 0%_ xXP/ .{=}t߬UV(t}ZGQM)nb&9}y^)L)#cF7)pjUʟ0r&[¸ PAbi׼̓zjg9K,B}Pzݩ*,&(<_0AU"o ӠWݼ[6Yw7T\|PXj^,p_'1 33qk+( m!ruwYՀńu: :%ቜ(p[?J$6憘{ *hM؁xD ÍxK H"6fQБATȲ&esnQ3mFVɞۄ%4VH߄E5˃p c fc 1y U$P&+(Ɂ!?iPRR0Z c5M#uAD0Kə B{I0 փ }]W\\3ZrVy佚a~ӇQA7C姁FWRtZ>)>=s>w,45ݬw}y wJmq-˄a?F[)sƇa B-t i #0MM"Sj2=N.<6ӧ""n+N雤zΞ֫B(+VقUwx@B>,Hk5NCќ8L;qj.ʏWtYA2_F/o~xjS$5W;*Ԛ,]gj>\׌ކpZ?o 2D91\<\ c{YJi0~@;.'/=Vj[SΜ_qKY[uY*w'>'U 'l[fZ(ǟgǻ%-T^ ׬c@9UeDxYO';-^-SS${CevX/XqW[ve6Wvъ;~1BnﶻCqUי}xT_]LV-ǖ}HMޗK] C;+GJ}O0X>Bg!1  &Eԓ>&rBBW.M£yR{Ty^3F:L|KvA>I,~W^Gm|Ӗ‰?z{6cBCƦ.́%dNy endstream endobj 39 0 obj 3015 endobj 37 0 obj << /Type /Page /Parent 3 0 R /Resources 40 0 R /Contents 38 0 R /MediaBox [0 0 595 842] >> endobj 40 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT5 42 0 R /TT4 41 0 R /TT1 8 0 R /TT2 22 0 R >> >> endobj 44 0 obj << /Length 45 0 R /Filter /FlateDecode >> stream x\MsܶW'S31Er9$n9(:(27R,\Jf3K,)=M҉Px? R\j^䪮Ojfb텬Oo}]UKk1Kb^j$b^"+Y/9S%<> 3=T1ɒ2N,$Q/ռ}nQ˥pR*^4THl'oz)(2+K>aG͹ԍ(hUGL-3h.IeDd!F%lV˓bZN#D$ BL!t$MSQb- cXU?OUըJEߌkY5\In 1D5wuuUG}1m[TgR_~}FWjV׫FqN Xc2kIPHTG +O6V5GexwH#O~dPid<#%)ũS4L&<ͧ6_|4vSHded3[DԒ0ke$ra:KHF1j5gk֎XP(j+=pK]&iQV`췂 m[Fd*󍩫Rsۙ(&ڭ ^"wk F*X\It5Vn){ [WOc9٨-:ZՆo86 =u#Z#vcuS^0B ڡZjhH' %+4\J76K6P1I'y2S1جZ[8H}e5bh/ب-h?Ïd,N%=fI6ӝdo6vd%"eф$jWl#=}gYǥrnG.~c96zr6Mf? (~eEG٧j#;3,jq  8s DlD܆3adM PB9Dmfqӕ˅$6#QRM (ܞA]r9zqȭNnyv_I[|7iɐCGv\^0}Ey%r! ndWNwr6,v2d{MMHiΙ`F?~6 '@^QہFAһ#&4R(3ƒ qt7jw˺~\)]Ϙ*~^Fp@y[r[^zejXGs3ڛ6sl 8tnaݬ+I1Q,v2E7=;[I&UtK{w^&*H@mmN>w6ii3}#9dK&a}OE.VvZR\ybЕf$ FIjF𛙚spgj1J[rP(*%GAܭv#`Llt$sZn.-qr2)Cx2n%y 4={XZP(1>N`quk2y"MuK.fR`XUt-EkM\@h NlLϞG7Es]7y,&ҽLzyMH700;Fa u] 2] k-EBYtAJI>FC|AFztG1Fv.\7^%p;بNAרMmO&FCH>p1#GOc"8R/9%AvR+8 ieX Ԃ@`x0Z baWA@& pwKntc$|r| y猶mG@sf@;'unt sw 9sErS$7堳$:FRKeJzc/|ZRxXTm{^H*ݎ]dsO?|"9:ry\=DeN٭ kd 'kwCEnln>08\wrK3 /qkzT{1t8ٽ J*xϦhW֖RԹ=ex@*N8%iT.a3f 񸃉 BDG7`⑄3gv䓝aj#Dڻ|iB4W15ɫ[>v4731D,],Qs D@C咘9 IsC;n6V%! QW= fu oSx@ { ˊa7 &`ʽ7 &SM U%_d\^9?NrWv$USe _ }x}yɷ]rʉNeU6WI6_ɻIN/^gli~y|{vzqy$Fڈ]WכD>[;$צ"zrR 1-H9`+^u']#Eyj\΍bzigOS{(*4m?5#eb3b ́fAskX3nWn+VbS0iR wΐ Z8dJ g&x9 2G)Kj2H03 !S^Bc,a@`GjG IpfFf$M3xĀzɷ)JkڎCnvReK~7SA0yY#p3 Gro?2,:Rɗ7:`\[q$CzcĄ!5 &bD$Vl! P Z+jbԝ#1Ĉ3  2%QE5=(PNuHCQF0"w){#Xd,f2i5vc1)<2gvQ~0G4G(:lB~90yiiM?6gB z3>rk0/ l>޺r]C1t]bD,@35KM#*:k |8C 0@ }AIn (<4 E%H pG MAG\ Zy šCQ3@ҁL %zf>l #gh:ҡ,T/:V0LBK?5C }ž25-%|:lqGb#kodvKDkYvEz2 &ńUg_%ҩ2v5v셎5 H. / cڰex YZCق3š̜$I}*o4ILQL~u0YOt4@0~ d F { 5( k.&(Ĩ0STP%k@H`j1`' ʼE(&h> СU9L_߳;*E5)F!5_kl״3 XoHC2%#Ɨ i/B endstream endobj 45 0 obj 4179 endobj 43 0 obj << /Type /Page /Parent 3 0 R /Resources 46 0 R /Contents 44 0 R /MediaBox [0 0 595 842] >> endobj 46 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT4 41 0 R /TT1 8 0 R /TT2 22 0 R >> >> endobj 48 0 obj << /Length 49 0 R /Filter /FlateDecode >> stream xZێ}ﯨ/Er.BX"F H FZNv,eA@e Mo_O.N;_e[rl{y#ry+Ew{3]V.a{-WAnնd[en[KUT&/wW=s=f]NlmYAmwWo.$ /^h<&=t g/SC폱ql/䟲VW]wMT<۩մ.Uz]Vֲ.jYTF,# ZMuxjk{Ө@>FC,f@|=㚲y3VsƜnQg.X8}t0U2 ֐Ko?3> )w$}CDPgxiƓ#HTrmDZ"rT٧vUІ{̈́.,"E-F/f*'UUwFAj!h`X sSt#ѽꔠ8lpw8.8S8@l|xP&k bs% I0p^3zsM'k7bkztd?\#BQݳ1@GǔMvWM-޳ ެK3) x"*ԃLhͱWhp<1)½酱Llf˒bbi]-[SŜQmh ~ ,ؼ@G|>MMNsGaaf$cDQ$Rmwl6Ǧ d]ixq3XGtRGU؊aMq`gӀ q38N3qk[poChK:8]g00!YԨ{y*WF2~B|/#3<\k\];)%!B^x\\ ߎV'o- ֲ\he8 mwsXAZ4?q\bWPzAckj X4wDx:T*KB9c2Z'u3[،@:1fSѨyn3S08!?=g*+ԡd<--b>t[JKeQ }`rJ2BMp\+ jA8I酣 'Qx ԝB6DջP@H$@ %(@sSDփ] \9a%1mTA3Hkj&4Rxd[0TO "dh9,@ i-pu)G)K=`}\d°@٥'|3 'xN^ `%*YQqQɢ &ǰ|zEpEށwvAʋG}YV\#9 ߥ:+UFN>+cw11o endstream endobj 49 0 obj 2465 endobj 47 0 obj << /Type /Page /Parent 3 0 R /Resources 50 0 R /Contents 48 0 R /MediaBox [0 0 595 842] /Annots 51 0 R >> endobj 50 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT4 41 0 R /TT1 8 0 R /TT2 22 0 R >> >> endobj 51 0 obj [ 52 0 R 53 0 R ] endobj 55 0 obj << /Length 56 0 R /Filter /FlateDecode >> stream xْ6_[+4>&qX}Xgd(e3ٯn0yY;eu@}wh| <ObG2'lu<ϱ~`]^[XsMR7q$t8ȏ &rypo}Bߍ$YRwowtөDpysNPS'iPqYo)A2uTGI N "7 ?Ɍd11P%|Ei , o4~DfքxN]$ @@jHx JIc:;HO [/ L-`2bAvzUiJI8'ɀįzdV#Gݫo 5T9=9%*jiƶ]zKBH1Tt -9) mq%\X+zvԹx ĵ(G.+^@ LxU g{amd}Qraq34lrsrTZ1^Xo3l8TA> 8XW}3T ۮM#.!>ܣX!`>( OA/ 0><Ꮔv5:66nߺT/'+I31­8!_eٵՌ5-WՌZcvnnv]ayW$nDR{&]O_f5 TU34., _6{7x4aWu~l:0רr`'_{OCTwcKشa$2. v@b7Z`tDgZ(;8:iL eصy D>Bt M~"[hț PNĒ20=13X(CϢTC8BYh:SFSZKXh<(89t2ϲgjS]ogPr!T;q>δPL[nS}QSP3ݵ8sWѮ!aT.wx-LX^uEY-Σ(nBUɧ*]Mh &]NZ!O<(Ǔeb'/#5F,c;8X5̉O5GnRvA䝚XXU܍9{RBYhEq^H]duIx,fLL4MkVզ^<0 &o4Tcߛ գTEXPƢȡ՗ZR0?^G &W}Zeڧ뫅CT1XZx z{i'֥۱^QX'ayI T\ U-vPF[.SRKd[F *fK VX`(k԰x0axg >;o͊Wadfq×W 1*H5U.L"ۜ= $7r4YnL2Ls֮R~~69pa[vkB\3,y\jȲ>Y/e):}]Gڤ=eqjRG׆ZݟMkxg[Ote$.ŝX\V?MA'M깭A!G|G\Hpît g*+Z[cד2UTHw?լ=]o隕w= F}߬mgx/\nOy"uGC^dnbn?\:)!8CI"`M7IOڃTog,֕sAiQ{_O'> endstream endobj 56 0 obj 3194 endobj 54 0 obj << /Type /Page /Parent 3 0 R /Resources 57 0 R /Contents 55 0 R /MediaBox [0 0 595 842] >> endobj 57 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT5 42 0 R /TT4 41 0 R /TT1 8 0 R /TT2 22 0 R >> >> endobj 60 0 obj << /Length 61 0 R /Filter /FlateDecode >> stream x]ms_qM=SAx6q8v,O>ԙMSIʊ}p/<$%gZ;c]}{v=x#> &DPlrXonEPNizqEq¹bq(E6pb8G٘fɼQFF|s)Fu卸^Ŀ<8/_q]͙.kssC V_Mtc;.7'1N,Xc/(#/FIC7Ҕ%;{a~HJ{ ADI-үv:7"^g#s FHe6CFJ!FY1j,i0J+8bZoJ&J}t7mQjΗ||&Lēg̹MAgtv/?+z2Oۊfu#Z\\|l.v7 nrO^JpQ/  pwѸ @֋ k!` W lnⷦS(j'5R͚6yjȳhif+ šfBlkK#_~("iS{+b#VӬT1i%mIw쨇/ӟ|˯zڭ UJޱ !Db .ٵTbmՄA(h vtv(amB(:.Kܶh cGhOH[6?0/ת!j^PS!i'/M;xdBT5x`p7;xQ‘xAcGhO'Aheæc<"&?M$}I`8y!!+LγQTsx]\qި>X9+EbѓL+=? BS\tCQ- ORSΩ7Nh^Dѫ*E.A.󱡷썔@qMs]`K}f s?/owjJt̷,S cf5]jimSR|ԛjka0U0++|7\9(>s) sNN{Rn%ɔҬ6'luAꪥL/l2RRd.f&Npk&p/w<|3y%Vcz #(JmT q7٥+K6G/_rܴӭDAy!2``B4xIz5lJ ԾóKm"Q<#hv\8S ۱dQkUYJJm-[*)+VR{Wd}jXϢ- ˊE|(F^a[|z__g_oߖU [R[Za6h\.rfexԤ1 ))'dT)-T&r\wsf.ڦ"e>sȤSV'sK]iGa'c :YDV²2L†7T^CŻcRaLԙ`D*bΧ$ELFJcEgD."?1?8IaD+J/<$}"z.O$H"_|+"_ E V_0(Z5 Y( ; y}*^t3qy= !&5EX^݉MT-XؚG94б$E-AU=/d:eדϔ;ܬMEs^HJćv>LMq<\nw`~u+';!R\|wMb1l=""`6LrD._^NLVonzF̗ŭNY~ 4Hk=61kr^53l1B61U5eAjeB[MAa\a̔˙4u5[ښN:Ntp!M"ӕۈúaDY,ވ% X\G#b2V{0O['kzVȍ6C/GzRZG-ybocb^tػp>zHъ~z hPE>z? ܵ*u7[֓P;4>$T@90%2.C{6;M+3Ą;7 FLQ !dk\{}[l.%1*C k࣒p. 3NEXB~]PGʅ5l' I497rk}g}#bσ:>d3PbVjY!$l/ 3 p5͎ ?c]g=<Ov:30xhV=ͣ_!O9ah>TbmfLb F?*F.%HG!8Xw&7:avN 1 ."- Dge'_& ?C k3:D(\DNXAO@(}.PCbg(a:NPPR*NP*PD kNi\ʾS]zK<BaۇP0,OyOG"h O*N+^neXɏ+ `{P<= Ba !Y.PڄP‘=JR'2c(}ֈx@(}ӘB  *1Ϗ0=>Ba'Hah5$=bT`r z򝢦{9ayJY:[x0LG穠ZQ$|9 T .s+|\?홠w.o[i&-Vwea䮓>&~YV;KY_l hz8fMtAڇ}0$[F"maٴPkϨ/ޘFSۜ&< endstream endobj 61 0 obj 4129 endobj 58 0 obj << /Type /Page /Parent 59 0 R /Resources 62 0 R /Contents 60 0 R /MediaBox [0 0 595 842] >> endobj 62 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT4 41 0 R /TT8 65 0 R /TT7 64 0 R /TT1 8 0 R /TT2 22 0 R >> >> endobj 67 0 obj << /Length 68 0 R /Filter /FlateDecode >> stream x[n}WT6@ l׹d8y,q֊g${DYO3>(A`꺜|wERW-*j\˳o3w{#-mڻT6MQ-,yUlQ$b^I,E |*]fRYRөR%mhYC +PRY85Qﷺ*:`Q-PmBw4S:)ͧΧ$5YBmgkiWZ|ڞ_]'Aa.0fY@S6М]$0AyZ[p/Zȁi[QL"C ]Q8v*#>9G8Uց[45Vĕm-#K:B-U" Ң!j5f 'F# AƐ`mHGЭ/:A04DHYXer&#۟,|Wo63f`uڰu.]]_5Kzg^miJǼ|ERfD42M5L4e>QEvp6cõ.v `2; :BF݌ ^g!!;ԁ81&f oh:ՔqBdh&\f;(CiB m[oA[i bo T$żH._Ԛ|IaJ۞O}}V}ޛ(o;iA9;qk[OqBE0XaCY*3u4/$m3fLMv/\ղmK]`bv3w?uhP s\mۆt+Рo,a%XF%UIJ)Iv)ch߮;jD@#֟4ۃm 62Nn!6Wޱ͂'GK hhfCEb5:SMmBy#*a/P*\(ț{>YԜlǓO4k@s`@<=dSVe; =žZQLvVUeŵ|T(=Ƣ#,wwuMDֲspvDqY9MJ[Y4YxQ1 cx^ţxD`C`WNjqg-'1j鯯]u_Q[ZPJzqo9!K]:Xoђ#wz} ky2:mvk/ф1VӯEi1MԸ0b),(]hP sh&B"$M] *&q݁Jb!n40]!1鵱HGc;CGBH(M,hV>טbCT2, JWZpkm!ÍWK6Ñ/nCAgr#vetD=0xa|477[ƾg1E"űHu]ׯb]l7Hn}lnV$h~n,Ow Æ:LPԓ@+&<)=x+ HALt!H 긘O@XRRtN<aa*wGL6*?xe%̾X Kc螙3̜xϼ;vwE:r *zǀ.;9dNfq9q6=Z6iӾ" .9MwM'UY tv_XJk_64ǯ:B4ښVm ö BlFbKd- }s+Jn6#GS =V6>f~O1q46.v2'wn/ޞ7a1{ωbn29*2==?/no[]]7ENooW/>M笿~:Q_NaS* )_N3O'C2 Q>ƼX1~8 endstream endobj 68 0 obj 3153 endobj 66 0 obj << /Type /Page /Parent 59 0 R /Resources 69 0 R /Contents 67 0 R /MediaBox [0 0 595 842] >> endobj 69 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT4 41 0 R /TT11 72 0 R /TT9 70 0 R /TT1 8 0 R /TT2 22 0 R >> >> endobj 74 0 obj << /Length 75 0 R /Filter /FlateDecode >> stream xZn6}WL޴ARP) 4FCSmzgM١3(dir\8:ʩ: гobww#tA]۷;ڷmdeѶJä*s,FIE7ϡfLY/ۊl2IRuqwT݁vz=J͆0 =m_'lLGwe/0/4'ռch=}c] v[6 +V`E3V=JmV+0i[a%2 3]P*k7f,iE\qTp'wh#yy'QNmIvUzdvhq*XvrkchG~̒eVu wLh|2@>0h!!!窭5.:v724Kqz;wUymSU2'pܟjj% X1B5D*y=:(GMނ7'"ZQpRu9" JksnAڿ &TQ7{ BH9? ^ÔjDkV Sz̏!8p[LU촤GhlK,uLIӶ6XWP V`8ϾJjl+ٗ%wvv<{2.H =@qmrff4^É$>F@O,`Gj ŀщ7̯ VOh)TW/p4C\!'aq%1 fPvx@ogvTWxR7|n41jO rߧ#X:)I`,Q 3$imYcc7lFǁp =$-# m&yubi #}>ʼn[q]i D9+Ѯʠ@3oTj>Y+Zr@،0>L=y!r3;",pFZ2JG\R:5qi\R+PsZ)*Kv±:z%?cO`= 1\ q@.~e1 8bRd&c{zFlErkDj"ҲђˆY3JQc n.o뿯K]mp1uqsڀUQb,r+:E Kx7E[~ͥަ d[4»W/tJnSNR*oKԚ2K?:餟$f|:<=xxݓDC-e#hE(ڥ}$)^*w~vU]+~ޥzi"yOo}毻͉w%sǙ)1.wzı˖.c endstream endobj 75 0 obj 2216 endobj 73 0 obj << /Type /Page /Parent 59 0 R /Resources 76 0 R /Contents 74 0 R /MediaBox [0 0 595 842] >> endobj 76 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT4 41 0 R /TT11 72 0 R /TT9 70 0 R /TT1 8 0 R /TT2 22 0 R >> >> endobj 78 0 obj << /Length 79 0 R /Filter /FlateDecode >> stream x_o0)o\ O"4J >ndP&{}~a;h˪ ej6,bvneg0o3ilq`*I,EQ%Te4NUML}5;&t[+*Ijg5a[,`GțZŐΆp?ص8;_up_X7xQ[ =* Ve[J8'R&Cg^`'1C/ISU&I (6{[qjR"ZiÂe$pshgg١ ]aMn4"oa>lɃ2,]19]=B\4֩s{?M r$θM 5m,T!|bjJj|=J FjvńZ"lvFSOru0ۅA=?9ʼ0(_+ޗLjwĻQ0,..BJOޜb mFJ$fpI^A >[q>``t'"ǮS <̖%/ԾAa?0 /M8{oNd$@{͇K~9pC[b\9aC?g7O D%[*S{QeeK/wv9kri#:;̀m$Cc fRI1y6WGmӨ#[\ endstream endobj 79 0 obj 748 endobj 77 0 obj << /Type /Page /Parent 59 0 R /Resources 80 0 R /Contents 78 0 R /MediaBox [0 0 595 842] >> endobj 80 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT1 8 0 R /TT2 22 0 R >> >> endobj 82 0 obj << /Length 83 0 R /Filter /FlateDecode >> stream xZnϧ8 WQD )븫b #Fkպo}r;CRM%"9s߹tM$KhT(64~ (QP弢zuʧU{Ѣ^O,lP^ߨ{FuO|#V]'yfL%a9hZ?4*g 7^@/>}4w n̳ͱyT~6E9aƲ^;h$2E+!f&V~` +gbH$U_ݚ߇S+A;BĪKt%`%d;7sju,oBHj<.fSx(P;j5PygvJD+ 2 AR/rܽ=EnL:YCmǝn=X86ON=u]q=cb!66jp@.Q1P1bLe>bi@XiaсB,l{ AR}ĦDZ (Idv$_Xa>J4J8(C\]@xxxxYհVtV*%;XLM,X>FZ0V ݈ EdCJ* 3ws4>3:G3XR4% (ڀJ$=PB`Ԣ gXQ:! WQ"\5 A4|* iKY40 !8K_~?;#ⷈ\S8.ݏ(ʪZ8]AK+5NA>TW f2۔5IYU8l/谨hjZdH)~8@.if7KCݜJ`0qE+`(bpoIiͶed6$&l\P5iM}W(BХ*#n}W4@huל: 7ւUs@2E;'cJe*&k*ɓ\k ^/ƅ7]R,clnbwDž#$0x !R{Su)]q]*M~81H{>4)_(nݿnHS+ʷsEer[<7xWOs5Ŷv{wr_bΎm1x]'~.;.16{9⩎.N92q1gw(rWwW?fc?bxg0b'7HJ^KIGY"u|,E{&`P<9vѵo꡻Ft"Y O9ڿi RjO9ȶzA&ߎVV83 qO=8_y~%!Or;<2r"!@/Vdn7f>ڱI%QZ%bkX>جΨ[É l ~+eUNE+| l$5MbYgGMc(ZJB\Nk!Pt< vc4$~b1q_Ҹ(ڋQ:D'g4:,rѰZ~K0^?KO!O,Qt|LqT!]KxrNG4~M`*՜w;/7&4!݆^ DBGH9_!> endobj 84 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT4 41 0 R /TT1 8 0 R /TT2 22 0 R >> >> endobj 86 0 obj << /Length 87 0 R /Filter /FlateDecode >> stream x[nO` sbJФ$oPh-9b~IR=]MBUuQɖ^~{}v͓ӆF;;Pz|,e2LQ:RwRaȇh|$btD,|Dmw+(՝>[ IN#x}-T721Wy*rn֫+rF/<.I3AJR <],<(O4|La V'Dxd?bf99P5bq‹wJ费ٌHw;,UWۍvۼb: ll=ޯO9CW+P oi3#hCBK߄*дqkR8{TALӮQb$58QoEvXC<CжZkEk׶&ӟê WBb -Zƾ<i @&ϵg 1-*VZ2ʘWc#RG| C*[ֿc>0ˑ%K_2.Bj(Y3Sf5SoGFYZO*t*DbX~ZL1lc邶NcK*%[oS}*86Qhj:7@# 0<)DI6g(jqx| &=aMZ`P:.Zf!`@C Os3i7= e,(cE;jAPѥp%$^]HZ$v)-TX?FA r\ g@QtR7r"ad!rOGitD"P]{hcu Ԣ@tV z)N J4/K3"8E6 *(A($ȩ1#JL "Բ2/CeiQ%+q;8/tu|F mfa"ժUVC+21Bd0ץ,aV>TG}NAs4@ XDqgbRm:ib;ފNIE"_B0+T10J <;coZmA=,l˫3A.a*`=&R*d U#X%(jΕx=x \J˵^+,^ gh9ƀ!Z稠!N1xV $AqP|"AIGi TT*|~eóQڠ[1@F C_5y9K c TzZ6ZTk/toě{QܩcZHm2W6 ά! +!Y8< pu8I_Z; CJS猰9d;<ށߖgjXT7'z7<4={ncw:\?z 3ks4᪔Cϰxp^իrp) ٔsrugPEr^^PFY*n-Z$̽׻T׼wy#Jc@ۛ`Hʗeo=IC.}wtT@Q|c Nb,nA-6fMnP(`mb/i\ ]PhY.jڿDڡL @hRϻej>wfm59qcnzC-QppBuF*:#.dGAfDAK,-E"C*R#~!8u16` ԑɗ,MD9\ Kk#J~8tȩx rd RĹ.=].<[E`7, 5P BjA`ƀ>PœC'bÎ*&cmy]r$ΰ>z bOaۨs%| +JoX sRZN,P+HNKi}&4p @/p*51O/((0cɏT4,Pn)Yi@PgE@{ 0z6qle0IZXx)]2>p6zBDie|~@"t]Y<: icy]= `$6A@cS7Ըs74tc}WTܢ0 I*cYyL(7[8㸛KjjxRzAuT 9M@TO3>Ŏ=\<$[U=C+`D'O 9/Al {ѵ)~{v%7[ endstream endobj 87 0 obj 2736 endobj 85 0 obj << /Type /Page /Parent 59 0 R /Resources 88 0 R /Contents 86 0 R /MediaBox [0 0 595 842] >> endobj 88 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT4 41 0 R /TT1 8 0 R /TT2 22 0 R >> >> endobj 90 0 obj << /Length 91 0 R /Filter /FlateDecode >> stream xZo}i#/=p'8XEip AF E7rv>>EN6˝7K~74 <#@;<8=,xGžM6&{zc>*;kۙX@2a-ԢؓԓF-lfzUkp 7Rmy-jk Qv!ZDG+UĪuTЧ=JiQT dH'j֡.pEHb>@+=_YęƄz ] 5Xyb3Mcϐ8^)YMuk r) "*3I+=LDMrS^'+V_^g4X/$9޽>^D/#Zh/b[lny=b9>rf0Ijd0]9xAQF";htjEyacu$IVHHUBIH:Mf4Kk4)mHMU{մ탈JHD_/)C4gxǭ25ZhUŗ8KAOH:ࠓ6Ue 3l4pdpqPt` b@2sQ@[]вRdP-<@O,cP3}z6,Q8͟+-tW@`8 npJ)n%J(v30N+c0JOn!z{KznAX IAz9RE햧BFi^)QhDIk,LO.8)-@) 4 Hk<L/U.w?@ \NDСMSz/MEm^AH_ҁ RrGj5 I]P']Eϭ)U#2;4]) }L*?Wpq֜Z*3tZ:eZ"v]X卙~)C;8*b65M/Q#lVHih>E 9J!J0m>g:둳Z!`niOYٶ5JnUttKݘjһj"&Ó\^ &{7c5M`eS;:z y7YI'wE@ J@ qL pΔtpaj-_nN>%(x*EUy* \!BvB#V++?1M_vWǿE_h-j5O\P>sz*S׬gJK,Y{\Ag,Kui>cϹͼ]ZZ ZuȞw:`D/3 |ˡlqg?͂M]o{zf?*xdz7يAƻ*?R݈ok+?\n~L'׳7a\(ՀBp:$s]ٻ!:r伖mL M?r.qnnqnC9 *ĹMv8G0O!4唌V!4ѲV?Ħ*F%XVrQM=VZ.0ṯ%h!_r)̀f68T*/V )\'lZ#KB+&cgI  1"fuo)b8AbAҲCHHz2W>/|0MKutf1ks1tCAC3 =f.UD,=Ն?ƁY!\ @`2㘁>D]%gm\;W+bCaD50=fX.To! m@ sXx⅁)}'#wam75䕱UDį-^~ =lOՊֻe &8WaWFj)0h?Z9+3 I.-- A2v{elՅSP۳ءM;Ge#'lU[[N&]*?VrvX_h^t"׵5)>%V[Tzܶݳ^ ٻ8딏5E!bG-@gs5)pd*2zZ {NEC h:,)^pVg:V0> endobj 92 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R /Cs2 9 0 R >> /Font << /TT4 41 0 R /TT1 8 0 R /TT2 22 0 R >> >> endobj 3 0 obj << /Type /Pages /Parent 93 0 R /Count 8 /Kids [ 2 0 R 18 0 R 25 0 R 29 0 R 37 0 R 43 0 R 47 0 R 54 0 R ] >> endobj 59 0 obj << /Type /Pages /Parent 93 0 R /Count 7 /Kids [ 58 0 R 66 0 R 73 0 R 77 0 R 81 0 R 85 0 R 89 0 R ] >> endobj 93 0 obj << /Type /Pages /MediaBox [0 0 595 842] /Count 15 /Kids [ 3 0 R 59 0 R ] >> endobj 94 0 obj << /Type /Catalog /Pages 93 0 R /Version /1.4 >> endobj 53 0 obj << /A 95 0 R /Border [ 0 0 0 ] /Type /Annot /Subtype /Link /Rect [138.5938 667.0938 199.8125 681.0938] >> endobj 95 0 obj << /Type /Action /S /URI /URI 96 0 R >> endobj 96 0 obj (http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm) endobj 52 0 obj << /A 97 0 R /Border [ 0 0 0 ] /Type /Annot /Subtype /Link /Rect [304.0938 681.0938 445.625 695.0938] >> endobj 97 0 obj << /Type /Action /S /URI /URI 98 0 R >> endobj 98 0 obj (http://multifast.sourceforge.net/) endobj 36 0 obj << /A 99 0 R /Border [ 0 0 0 ] /Type /Annot /Subtype /Link /Rect [236.2812 527.0938 292.4062 547.0938] >> endobj 99 0 obj << /Type /Action /S /URI /URI 100 0 R >> endobj 100 0 obj (https://svn.ntop.org/svn/ntop/trunk/nDPI/example/pcapReader.c) endobj 35 0 obj << /A 101 0 R /Border [ 0 0 0 ] /Type /Annot /Subtype /Link /Rect [235.875 721.0938 276.0312 735.0938] >> endobj 101 0 obj << /Type /Action /S /URI /URI 102 0 R >> endobj 102 0 obj (http://code.google.com/p/opendpi/) endobj 24 0 obj << /A 103 0 R /Border [ 0 0 0 ] /Type /Annot /Subtype /Link /Rect [271.0625 441.5938 454.0625 455.5938] >> endobj 103 0 obj << /Type /Action /S /URI /URI 104 0 R >> endobj 104 0 obj (http://www.ntop.org/products/ndpi/) endobj 70 0 obj << /Type /Font /Subtype /TrueType /BaseFont /JMOOMU+Times-Roman /FontDescriptor 105 0 R /Encoding /MacRomanEncoding /FirstChar 46 /LastChar 165 /Widths [ 250 0 0 500 500 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 350 ] >> endobj 105 0 obj << /Type /FontDescriptor /FontName /JMOOMU+Times-Roman /Flags 32 /FontBBox [-203 -428 1700 1272] /ItalicAngle 0 /Ascent 750 /Descent -250 /CapHeight 676 /StemV 102 /XHeight 461 /StemH 44 /MaxWidth 1721 /FontFile2 106 0 R >> endobj 106 0 obj << /Length 107 0 R /Length1 6516 /Filter /FlateDecode >> stream x9iteKEv:KuIHҝt'! TBw$ KA"MI!l2lAF7T*2A)818)FHUQ9w<~N}w~]_U/YtG`- zP׶t5J~ۗh;;Q,$B:{,c X6l>T=Q&Y z/`Qǰ<ךߛƚ :Xz`H׀#§kgU^BN=n x2zHo0_xGG.ErHq?`\ VOT#wUjxEEv-nj0eX22F@+k/҈'VFk[:x-ԁzK^ل5ل00sVM[\dEKDFD~@alI0D, n" ޣVU8m k Mľ]Q$|$oM!rJ˹B(Wx&WX+, riv?4_6h~ < lhV45aN. !`ܽq@Oۅ{Ҿ"X¿(21[-N?kpqH 1{)EkoU 1Zˠv%:9a s<5yB Ȓ F&U3- =L)zdT-Q1i!1Apb.fP;oz#6"BEMS=.H*FF;FVeJJH:_kq lwlge7߱ ]Q.bX'ڟ6kߌGvؽ~nuiY^;j_°lN[P]ީg=ڿSgH3vZ}-֖kn[e [y*썊-b˫(mTm){.kwZxK!n3 C> 2\K'_fҞٯLr VCxdxE\qHgn"i޽9|&|ߌGG"dcVI Im.4#B8r(k4­4VQ$pGd5p:.؇o2l'G֓:8jSvxr,H5WʼL ȚX/VcRYmUY`3lx*|@k7B-1|؏g+G~}^~:<y r<=ClZrjcF5Liv<>Sp1,ZW0 cdDlbv9b-l}|;|n WG#F^%ol䍲 - 5}J-?!8 'ȷ"Uʃ^̓2 *sf33,Ąx1n`cV9/s9   B{l%Red2/@HJ$yuRTR&Fk%T8^U>[CxVo}V:c6Mz͝~W[{ 8 Qb TXE q l{rcvijדf 2oϑ^+9+g;l8.VC}kH9~eUf>+6L9SV|jv{Lɮ tɒ+%]A F)+3|2n 'TߣQDln;shn Z$5*Hs| 6J@AMAo{T;#|-/ضדM5b'_(]kCˇe3lw^ H S4K0V2mhu;1~_^<ag*AR]MH6;uun>k_}{I e}>3V,Ү ;|ǡ)$# $ 9ʣuj֓&KJhS|#)qS>wEt-):mѾ>eODiED)m4`mCT^./ .7,!o _pOpOp5O1s ^7|H2=n)t0'l; ]p BzG) 8:hTNV~8,SŜgSlt}β,g+gYƢhRulufcIC+'*rx"wfE_ ́d  b!GJcc.I5ٖB;ihTOPrJGӃUc.Wm۬Zk6+.Mܘ$%29s#ў'o sۇd ,x`& BAHM1e`çp& H SYR1҅x(r™dJLNIVait}F[]C'7s-ӲxLM- c:FPM8i&fǠؕ3;.]N8MbR\v"%:95&ccX,9ՔjA^7OJmf`7 Z]mFĠ Pmwl5`P__oFE˥tΨ 11ql) RԁÁcX uXhGUT ڊSX8][ny7q"KՏSp?w;ᕅ>CߕREEf.TY:ChFm[\R\Y)69X'4 &\ʓF z] YJK]L~ޮy~0Y8}u"%i4]PS9rf5%8m*\Yo>f%.;~}(!ʉl#"~@ݛgFfW3yf؞m,zw-XXٳhVCZXW|[CoIπ$q +xA`Q<1fJzحws8 aoIKj11FfčPgřCP]MRBRŦB:8Nɋm %$n2IUwyb(} =8}5/5pQӰTDߠRđI}\8>-͒F##Kii%ղ[Js9[<+INb/?‚au U] R*6(tj**L%HB]iZg3퇜,VgL[hst|)YilRLOL)m Gu8\l*uGhGݦTEJ&RaGR+݁/?|Wra՞ne%WO=qu˄_ϩlwv]Tu> endobj 109 0 obj << /Length 110 0 R /Filter /FlateDecode >> stream x]n {bKq_Nr`X[HָsRl|0O= 03qc0Ht4$d}͸4EZw8=8C^#y2l)}႔A cT{.?\ǞJBt?\&-(RFnF ӑtFQJٖu*Zx6Ҧ}U)`o|&pA endstream endobj 110 0 obj 222 endobj 108 0 obj << /Type /FontDescriptor /FontName /VTHQYA+HelveticaNeue /Flags 4 /FontBBox [-951 -481 1987 1077] /ItalicAngle 0 /Ascent 952 /Descent -213 /CapHeight 714 /StemV 95 /Leading 28 /XHeight 517 /StemH 80 /AvgWidth 447 /MaxWidth 2225 /FontFile2 111 0 R >> endobj 111 0 obj << /Length 112 0 R /Length1 1788 /Filter /FlateDecode >> stream xUOL`_m P)j!lfS1#n$ Ĵ a@p<w҃ƣBILM<O^MM nN-.oydJ~dlY^|.~'G( g^f Ϊ:q&Q("ZŽ7€h /^ x@ 0#W'Q#j=Yĺ'k'kwp3:z[3!4?]H&=NAoA>:]{b}ԂQ* endstream endobj 112 0 obj 864 endobj 33 0 obj << /Type /Font /Subtype /TrueType /BaseFont /TGNVAO+TimesNewRomanPSMT /FontDescriptor 113 0 R /Encoding /MacRomanEncoding /FirstChar 165 /LastChar 165 /Widths [ 350 ] >> endobj 113 0 obj << /Type /FontDescriptor /FontName /TGNVAO+TimesNewRomanPSMT /Flags 32 /FontBBox [-568 -307 2000 1006] /ItalicAngle 0 /Ascent 891 /Descent -216 /CapHeight 662 /StemV 94 /Leading 42 /XHeight 447 /StemH 36 /AvgWidth 401 /MaxWidth 2000 /FontFile2 114 0 R >> endobj 114 0 obj << /Length 115 0 R /Length1 8068 /Filter /FlateDecode >> stream xY |TŹfM&3@v7' lL d`RK&`ŀJQZ`9ݠhj-XUZ-u 9?gww'oΜk7R?L b-d& kJN"+ZVK9ԮkoX1!vMAMca<O?{oy.=%A ֛RS<]R@m7j-bAhz\XMqfѦe&~" D l6^٘)a6aQ) F V]u^itJN\8WB'medYbB+(5.qEwZffIFӶ;6vZS)N "%b?EҮ*6(Z 4PPQzլA_ː[9[n=`?@#hĴN֎r) ,;#lpKN@PXb38 Pb1?"~N2omJC&ķ̙/gڟie}**`JcѕvMn&Hd9&p?s_- dzkL!1c&pڟu;J;U8ĹO dQS ?v&8q_3i } v>W2^r0Pc : JЃc}7K|l՚TeGq e=H{o+] 38+TmydVjy-iW :%|iTkk$Gf:74\4e)ߤv3zXb珴%νq'3^u;9wYI0> Owk:'C<)ftv-HHWJ1qfp >lkm..γN[]A6-ϖn,6md0qm(IE!VpcwD|[Q]8 )ښc%[oϕt#{(̥HDW"bkEMa4P/*j9#=aLV>mki_Û"I$nK91dFfDuS4|m2{C]@i6C!}6VFkd_QWϓfȇdgY,~dv6\uy<  wM3TZ!iC1a8. 6Ȃ 0ƪC;`jF@T߾)G߼ZTt12IXЗkWWl/i.jօx j@`{u貱n4Vu]vV-:hBR}PcXͱBX6eH5Pn!T qL5)rO(VFQDUv|n++ OTeBR4ŝ{JתrZ[[$__ܶ^*QC^k- >@U[US>kG p2T>ooߙ?hE*}/#X~A9şdÙV pE닪ÕԀ.ɼ48J~.3B[<Q,9rzQ]:lR4"I,I$U@^7| '@e>_ZE`$j-jcE0֢"Hp^P`A@`d[e3T`+V"'`8nWD;4ΫkH[mah fY+{⏉L *EmbZ:C^2B Z2Ki"gi kA6Aw _NwtWg17|^!붲;P#) {þ+y5|%ߊpрf}viE12va Bt2ۯra̅ȅoX߷=ȸ{˽( ӳk만34dV1fP,fKPblkBig}v;Y(?c'P^egS$x Vi|.7kü@n׈iREJerJyIy]JuAIݧ>mɵ,k9jrj⸺հyc >5Wb9ZA Ѣ"b^'֊;op7YX%w,_8r|A; ;xƀ=eeE_~G|Tcg}%r)g@:V~)WUO|#^QBvƋlRaX}®YgCa6j&cˋ^>|0B崘ki-+E\xvQӂM^feC` cۑg/ͧRl[rp{i-Ǿ?''ۨe`̆ox_ 1߱?]?B1^*Tfe9}}t2eDo- w10|;^3_M'?- >Os^LλX;jމ*7۩xX F[_)>~طӛ؏<,>F)>NwV;W_^bkq.zi\eԈTCSt#; Ɩ{pλDyJ_ /Z#| ,qس[Н6]R}?G9Ͼ0'#U̾0 <Ȣ叜0JKtJ"AΖKۧo[M!! #T7m΢ʹEu5in~յ f? -5 endstream endobj 115 0 obj 5519 endobj 41 0 obj << /Type /Font /Subtype /TrueType /BaseFont /XFZSRR+CourierNewPSMT /FontDescriptor 116 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 211 /Widths [ 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 600 ] >> endobj 116 0 obj << /Type /FontDescriptor /FontName /XFZSRR+CourierNewPSMT /Flags 33 /FontBBox [-122 -680 622 1021] /ItalicAngle 0 /Ascent 833 /Descent -300 /CapHeight 571 /StemV 0 /XHeight 423 /AvgWidth 600 /MaxWidth 600 /FontFile2 117 0 R >> endobj 117 0 obj << /Length 118 0 R /Length1 43760 /Filter /FlateDecode >> stream xԼwT?~νwΝ{۝}.˂ReYDn+*Į{,,Qc&j^K[hdg~sgXΞ~g!ѓ5')g_N?ń5*X(9m3 e˭(.Zzi BMp29tTʴi3W_(N){XΜ~=g?sa#-]lBϐ~t!7p7ihӎJKd<(GDRAfoQLY+\7ZoOl<^+&'u ? Fr^]h|={~~iI(VAq  ~?Y CXÓrmv#@H?~WX^E^EM?H(8{ vpEnw;Ho !{n1WL7"M~S100*`lנL׈펁qșf9yf]׈)Q̈́ʷ oU1`kiLR[*'3O3pmrF9'ǓxܺZ/|o+ٵr休T~)ӧ䴋$1'ғr:''މ|'1#Q (t?v`L}9#`$cc0If#VyW#=)?v\!Z$~mhi۴ foqBdy^EP͈|T"H]} 'WOHŽB5Ċ4XLGmv t!!,GXPVc}+&#CXa!Fڸ6~27e;崦z}T6͗aC.Ðår@'AFx}6 LF &p}B}R'F8^9g -EM)YkJqRL|kB؈4k m!a1b~i>ܵk1o2V62/_~~&6w~w ~mSܼY>n>~}\%v;h٤v@?*g˱$=p`9nc5p99A@r R)C]ʐMjRD@r\-a9ѓ D!!5 &v. |@РeRO!*w*CBMDCO AMT4%U/$U\Q*jQ]֫jZԜ$l'X"Kl/$9GpT͑ O&NM'?L\?<-2HSf+"iy"8}>5qPߐدꙵQdAgUWzJW^)Yz~njj;?D}reߘԱ?l*FyYY&랈y3kuճ{s*׮ #AԏCB, G?YK r?~[Bc}ZFY4"Ϣb^|> !OH< _cs { ;F:" 7{͂`po`?[p,pY8#2&}| YȘ鳶_(-30A?{ǸGG{\2#S-5c.4BiQ5Xn)7ɧdžvl׹||s:d9P.Dw}-.8%gBt?}@_,w{܏|\5_os  6J&SS7+6+Ur?}ĝH;7 m@`I;iX7 P&Q( § trlzvqv(:AYlg 7{uK >Gƺ4Ϧ]\BW`FFsa zsDӈSț\7VUj%3O^~IB#R9H''0?a&}\5!Ff8(8q>ຉ^-%>L& Xzs{5P6Yj⟒V@"hHNW\|w>(ɽG.ty\:Es|~&y&wP= .L ])L"l.Uzr; v{o%0'b6,Q AoJF*G[ z*y9当l51םF~%v%Ѐ5an dܫqr;9^3ɛ:a5x X&VFAv|4)i?)zJG{R1L3`g$HpΞ2 kD$9IpAy`? v=}c2i]t,fdV~Gdvhrst6mڀWwGt"cO2s'Τi)q) ӯWɏ .ې ɂȩ;q"n~s~}squ^~mY] ;tw[?+5IJܕݳx$xV+p%~MdtK4d[ړ;ϊ exU*[bu)q'_L$j4|xy8GP3 U5)2 HDRHPGG  0@&KƷt8JKDjY,[zX7P'gJ<{vP)r֚Ǔ#;Hx,Z)ќ|v3H^l=?rAi[9#|ExWxWT‘h,J&4ĉT㧶 r/4|8v TW'ܥl # :4/٩~{J.:f%&yv$%?5%YۮEQTܣK-SaU'=J` ;>7&zba`5A HbqDB]N2Di^N')a4&OOh4rJJ,)6G#}K/=I7mb qΧ 4'> _7Y Mr&v@ HXi:DUhf Lв;k벵5CPQlQjN鴈vA0uيګ訆a14r,%[m2PrmxӦãܑg韬?cˮ5crśW-}y&Xe8'c-GKwQe.5"D%4~@d$sQ|{}5z#@(oWO%qUYPoo Н3퀊aw" +z,~h,BLu4׶R*U"79Qm.%%Z}) 9ZjFzDmU#Ȥ2REa+%`$^I3{K<61TD@1*CHpT0a P0 J',^rKܼrʔ,.QL*זnYte[o][N[j«CY*4'.3X+WMz*@|N`:vrXjXu?ЗQə"*.R]Ѻ!ݭmF+ʤlEѤVVUEjRU6*QZ)h"|Ry4k{ u%ct~ @mi^̺;B=ikO8iJL` ituY>(HNಶd.Ւg9B_RJi\+u?w {'ɫ=vN`Asb:Yvq2&2ȸܙRGfTS# 3eT LET)!(1R":'Ѕ,Zir~Ht춇.C\&Qg7#sv+]&]`v>2Vی&d"LHU@Gx@mhHc29{DQM{T*{zw]b Y_N93t1)"OSa/0d&4ҡVF>*W<͑YȻe2H^ 57un{nz UÙWpŨ`#!ZDL=qWCpd/,jȡnIOK`;I?!؍l`919B"P?\%g~<_2gDԳ M'?Bq&ҙRFc. f,ќ9Y^ަ>Mv 'saơP }~k%=A:A)i, a)ˊ^X 9-V9&0WZRD5+2m%.cg]Gw9mdo; de`+#C$'#-єKi|7+ɰ+H[( TfRN C8Rj1[fnhKW{eN<]+nwɁmV4:Xt%BĆMmLgqp٬(of`v0xYd9v'\^4:xYhޑt6vkGYx5[w_}{ţ[f|,y^n"9-aW3l;gأ՞Ѥ$jGt<Ƹ{fI#F)c5 ԘBѧEÙG[8QhzgD%-Yd2EOr +88:'kreN:xsrг# U-,5 Qv6 [CKeJ}e]ZK9q-r&5?{'Z{’W^Uve;YkBY$OY0)/2مRLxq"O :Fջ;g0 gXqF񣿎;f_cxaƎK Js* @ǂq[)K$QG*QsQ.0ߘrHuׇ T8ZA¯)2JQ qWț|bzోzإEcw~97Clι>t:UZXyw7_*ޯ6"XKHjTWgMM ru誆77ܗaeEˋ֗Z_|]™^dF]W` Nx,]X9=Ho?s.s2R兤^o#n؋%r>s5(k Q8p $IL'p>4ȥ0f@4hbڈĄJ("q,4ICҰ*Y LE\WhvNXq|}Z4LΓ/}K Gjw-9YtW>|i kX2+ߌ-OP}"&9H xOv|Oٍ6($sIS`()\(Sw/C;1n%#U,@^,=8D]aA[倨W\p]}C"@5_ɼj65*`tB}@lNU+h(KkLpHjL72pg;ӹ|KlrS#:{(89f.MG <oXSjr*2e'+;ֲ\:t] -xU F7 BILTIk-,oѢuP$e](}\tebvsS Y`38Uh N "'Qq r©T j*:I獀H@N<]=ꖻ:I;E喁߿˃Q - g?dc!e{Stڹ C f̮T$B*Ò^bv*q-\nSԚA?,3H]+1?|܂ϖʜZ)t%SbuwHoW߮!%uG!zObv~oeR }!ʚg3;MR`_o_ $!S:RVX-JbEbfl [4Ꟊf}˜3NeTL6A7%ⵂ 3T*LHB"U0 lcwIdd=$lg; $Tpp"GYiշٜncu6VgcuߠäЭR-`X2'oysVj˹mqz͚_?z܆nz睛=Pm`+_w,Yp 9ղ{=].:1RCaS*E*HF҈J %Z}Q&H'fcC |dW Ec ՘ RZwU=[F0Wmx>+$!!g e-ZgMj{A 6btgZOrcK<4F &CdV'#2#(GD_)M`g,UXR)F % -.Ce B.Ql")pʩ( C^FaE2|ܞGe#cu;|O[~1~ÜKvD͟h5{3Q+kBW:%]я- ]Cg5& ;]Ca)+@W!U8`שҼj}Nry)O`/HwJˈwL"kU_U?$6ղp!6̒LK^-A7%?*wT|I!>c]2jK^7کQGI`aF߂ STrc MCչm \e-LX@څFhLrɿ]IMP+h G y8{(6ѻ]C&ZxJ빛!?B:=x=]f2RX"`I])o?qrt֪ SB Ʈ3Gˤs迠9vYr]. 2z za1|ٺ5\n0Lo4W̼-:vIfV ˲ƿI-#8b!S"ʊDJnĬ!URik<~{6buY6lv3m T(u&6tc 8ZD3ggqfsJyfi?/,FM,Jh7&,D@5ڛF{lUZgjL~/i??RQ Fk,=NW=LQ÷͔)"rƶFsoѰ &o\q`4y jXH,Mlw|OQ?N#]{.}tQ~IxA閶tp N|l\[m/sS!o/qwtwxf1k 6v e ,uʩr{OHY0DDtuG[in¸1A^!i\UZ{-zacƸhڥ >Ztdk[uqQпe= ר IgE3h 6'pk{2 $t/CzR< fmX#&c`̍X)6^yKU8Ti*`p&hXfg>+mZWJ;ԭԑr#yT_[RJG+ aκul+7J<0=)Lf܈LA^d+e]=J/_}ڸsǭ7O4&gs+3ޓDK~j8\qә L1+- ­K/>khs~8-j77MY:xh?ݦ˦x}qXNwK:fӚό3w>=/ݕ!iLd2]N9.%  [ j(3 ɧ5#e$IeI_$@ŀ*Ff}.UvLn1øc {Y X_ @';qɤ¢f6\:L4B)cy5L:avt4mɸG2jڈ0G`]My/m%&IU~ID_dMfzGERPu`$¶4|Xe Y{_4ug| b cаGհUa"3h+di+`)}2瘂e >ks/+V/ؖot-wНPO۔݀!/[iғے~mbcr}ؖc1Eձs2cBqvܴܼܢDQml 5ڒRqZS zC'驈)*sWW/+NyvS+Rԕ>RZRLD\jήČBߦ_ \*36^5}`Ƥ4kP1#7pA&۱++Ř$ hU=X%&_éLѴ٪YXҚИ6is]ghAQ)*޲b\1"3AU$(Ņ@}~r. Q/'.Cwl17Ar~k]rO/, oWq0M?W.| K[1 ' G}VWy2v}cT֕Νmr}B]'qzJmښ*c!GuQ_ru)s^AR4%qu_(w7yƪ@UEUt]k[I#~َxE6Ð`ؒYf{7O&^l,H^YGDV`^6Kګ0Y֐wvy.pk&3脗;>e//{uW~U!0-3;Ȝ4o}9wnrTxNx'?r1e[" uu,66ׇM/ۘcK˼?4%v]Fn9+geŧ6~wS~hq4rFwyA6\N2h#Ub|4STpÛr_" ;SbE/,pEb8td>[2 Wf3},-J|g8X< TK)QOOS1V*Tm/mm#f-e2\4)˸T,K#qW-4qB\XӨkcXtWͫUJ%иOuyz^g)(R"7߈ (|4c]f,п2ru[ QVCQ0+D1n`wzCGz w{vvI2=2`b󰝥+n,ڂ٧ Y22ƌ sۋL!kBE־|u_]5*vM|UQ቗\X* ̓h[u]ݾ*/_ᛱtu`):bg:o$W*v؟ ΐ*J [G} i 7e55thV%Җhkk.:e(F(Cb} /5*˪:`+kH64dk}"a? zЃT0Scoz:٣ hb,d$`? v*KJ?swW#sWL`%D؈/4o"9ı) 2ν'SZ&X(S.@X#HʝHw(v@>RB(WDACUx+}mKV6;7oc&q|W@.{ >Wҁ3ډs6J [ &3w.'8| j WwR[lE_{?[dy~FA>pl9Y(Ž&icaFsJΌ׍ / -m?/tqzi}mm_I]Mgɵ1[۞YlojOS8m> N[=yNh1A+Yɦlpld*|*ZaM%pRԌXBEX1Wm*(,jꄶ*b&P I*,ie<'\Up+tr ֶ6ZCUɅ;C!zz<8ztƧ) %UW꿪pkqB^'Ƅ "  {q&h, p=rN#\U̔),~#&㹈oPo="W5"GM6*~Qpuj8kE}NNT%PBp|ճH1n߈I,bY SẍEn0E̍pzmѾŬ+vȭP`'xXȝdU7] 'k!Tje;cV}ȭguƀ5T緘].@A|[$Qlg\=I0-W.{}yӏYPHhn1XFw }?7Lh؏0A}w}Ix8{o7q 0O2 la``h4[|$ep8*mWW_Vg|:CSFPO籱e',:6S^ZTPTHJ$R"NJ*`Oc8{}qe|x7s-+u N/Xzu<}u~MByemX&$sؘ֘x5A rJ6_ΣF @P8N}dyObyES&1$MaN7XB-ce^gL? QP&Qb)PGe$^ iG`¿_ < |+pCܓf?x\ėȐ"f=j(ͽzKiLj./GuTPGЙd +)+ K `Y4ŴEUëTӺrra2GB!Չ g9XRXF1]c󡵾:l˴!$-Ųie]ú[,,-XZ\3+ y7I`B#HT)ûAE$zdnY| @F,/.;~F"t~-X|[ ph HHӧI2Ή{ C>4="_0ř?Q|~ȥ|/o;??7ܢیN9󿌇-r)ܫj5kkPn6+zuY$֘kMNuK+Ę9fp y2`?R?j|L|۽m·]-S-Mw8os;-N牮Td''fNU{u1aI  Q9 bZ$ƔA|b+g\;; 3T2'Y)ƁJfrzkHE80;Tbٝv_El;B,U :Z֙Y7;ZSU>(zGDC ON96}1;`D01c_IuCkd B%ݬ"aUC,~^̽H/j݌UWsnŷJ}Y[s=2{/roN[;@Iz@I"$CpyNϞ6iN 濒sW:}S@1,'TeOӲ!mrѨBY :"Qt>V2)t 5B^C32 q#ztp@v@P\GW=ifGg×D?ȭ/rYm>Sf8mq4ykSWU%u[탥'-WT- >IXSLL87:;63[9fF=sNMZ{j?Yf~OS W(R S,S֘-mK6eGǥnH\uu76Ty[}UypݿuMBmM%hA9; vu994@Ѓ%g"tezkZ>/Fe,:V09<݇m>,kS\;Q/%xE |ƏIc#8S~*|R#eQ;Sˢ:?ձs;,cvjYG*Wa? E{R JLXsY -a0wiuf4yMhKYut{k 7B蓔4~#Q(D LL:SF]QE9CzDXr "ki{ I*kb^8ݻkw#ma~5MX3~hDZ-3'&z~OLl!Be dDZiӌ6BڙgOA89~QU((;e(P/X<q(h3]Nl(`?^&EoW0zۼˁMۼ{cLc8\ 1p~rT)3y8*X Osa6$k/=ȦMH]) dbw% 0X^<'/?r+)qzt+=J ;"6Vٜ.+LδW_Ҥ$C`j|m\k> 2gܬM|l82 gx;\rɚye՚0K{ BNx_D JX xNXҚdv'1YuxL.aD/H-lںEl[ZFofssOa ZlC7ĻNkdVJ'E%/9+ɉ >⫾?}^FKDƆSd6f>J 8/58SD'V9(;3KV/]V6=k 3EQA5q}:SQD%F6 ĠbHI0Qb .IP/N{{Ƙ][/t׽ssVfYr;k~%Mx୒nuK3̜ͼmsmQ NR"%11Bo.>\cpO;>g?=G,am=3<Ÿ˻ِ#}N aHr@~bB|PCW z qʦ,8f[> Ka8)\vٶai%1g%Oywuͅ* A=eOEbc?||Hvw\0^H_Bm]w%ޮcHH[5V2ZmKvjqmg;.nҷÆUmO&[ [;{ {:>лē cLy@ؚBχDo9Bs Ė8"4=H5Y_V"w<>ۙ-d[Ŧlsk(t%l)5Rvvvu@"澎qFOa(Ӽnc؁~uh Ol΂ʕ믺8>o1b$ˊ<,qJx>L Z+Ě6)yIjI<TE]7DO欩*BAm2ՠYJ `m+< a+fonhhj6vz:\SNf|&M?6UUNjR$$ [Slm:[[dkª*ᄧ3P|Vo.Z2?^)KKAEN`G 14~0~%>)99PuKn9"Yf q!o\뫞ޗV:r@fGާsJ~{J|C{țc>~li@Xne㚡kbA#ihaloSC hUi}wuC:(h狝Jɳg[svfrj&K,?l -〶 yp1E ʀTgcrGVTDFdo;Ѕ]89#gOu24E jK|]1ͳV*Rh *u|^zR:D2/XU >)'ϭeJ`[yg5[y<&LB1PMA̗.߄OP:&<h=u*Hd9(Tm|} *¤]J!lG|^W:İc.QcfSJj:]@}T}FݩT-j-xWjw544LȚ@m:vAѻZF<&dmBawhi uVc;93Bc\+}>K>*x('w-VMLEb k x&X;R>+,xVz6Exw5@/wƖK]};.=x(mp# U 쿽řg-}1\FɳP$J/,ѸY v%EYժ.j(0\bw7kRr% R:[BX>C6%/w .QkifqeW;w4ӓs-=|"l?jqe-_-^Dcd7,c˾\l~/$3^'8+d8RɸMJ]6 $U190J]ۍp]FAW[ӣgY4:-$C֑@q:f0l&K-R kRsj\l^E0ciʒmԠːbHcEndkQ:Jxk4g>^ rU/4j2(CML$3Po dFrFРu 6RMPm7hAc =lj PyªT39}n*#}5^+8Ǜ>,Y$/(/xn4܈Y4Q\&oUdNӦK/(QuQH-׵lx  hkj4ZI6OPA[⫛TVrf \L!gUp[)upkړZZڔ2LKJKRr[uV*E w&R}`FbH/ށtq.{qHw$?ﭗPe^I}.ZsݍԊ@tꡦCYҡe2V'g^]%ON_;{dc۹7 Ψ6B Wr/_ ca m ~mH,4]eZEבM=ay 9lv #  %ᩛXWoLV{?4,=3RZ54m չ3=6U4hNUv6Gi+[ߨ妄ۣؖM>z0'Jy ]eujph6e"FTyQ}HbLT28#!+Q+z>"}̜zނ柏#Q %| >+̻^zh*a^yA~&&)7˚Wp95OкJ7KgR/Cͥ6bܣZ(FEW{kܮi,ZGGQK&F;*}T[X`uc51aХ |71P zkcsGPkHc}ڿJpGP7>$FnsrvqukND/3T]`^]a^507G''Fgc<8>zZ\|@6p>O=]@38 \Ĥx2'3#@}[<-|ˤ|KKc>9bF/.:I:'utvj)mŢ&bIUV`C&9] ҚF/Re;W:)ŵl.˓k~E:pH ;MRtבNN) CLfpU(D F{P Fl bmcM(;t-_ L)N~0<GN{]Ք}Rq[{6n!@ET'∤gr1χx*1.lFLfZMkix$:T_7]>L/̺rIg7OvEݝc `2mVm-nn k{E慖&D  >@jc^$P4%}}Z}Jr)&g%ݧpO:['msDCDS f>V>>P<̽]ոL}[Fz3 靎6ē=7a+~_+FЙ, r  DM*7q>E~FDj9ZH{t=i֋ΞNoǺ;FO?s-{NXp bya99Vx71!X]|CkI «U2n7]j^ K,KlKy/ZV4,G5guG<`.\w+?L^ }Ɉ5`X3Ln6,m-TBo ERq,t|Gt'-8{l@; ,8BU>ﰋXlؘ׏j1x|fvDo]H[Q#ÁgB7N!: K(v#ե cJvHY *#ޝ|DZ탏<| ڦTU^hGUZ6d0 tsMloߴz=ӻwk I3 aA2Ysڔ4./Fʻh+m*Ym0sbƔUb q.%Mg<|#іt +8섵y9iQ tOVۜ8:>(CAʐ: K~{eiw )C`+]_:d㉦ E-{k~mڮm4.YT^(imQ'#3LB 4|3|Ku7#~34{bO9zhQI4GDmb4;  vylL5:< ѐ,bsap='*iwjFJL)n&D,@ ,Zv=6| 3lIlKE)e6*R.=U Tx&NY\TAN4‚ZeI/X@6Zd]lD[)vD gdejo/?R`~dlOR=2}%mK׵XbhA?mI;}9PohvAeUrqX1t"OӺYPh OfG*W4N}M禊UP]MPiLYj?[ SZaLZOۘq4PEUXs^H/3 mx3@+FF%HxJꨱcc˄c#8\iXr4q*(lO![3ö]h_RCǢ唇kkEQi3nu\E t bR /B n/A T 5elJM~HPty!2=y98g&|_ML~|3K&uo :U-}"BXo{;;[\k\?rlе$6 -`1P>(;4oNp&*ŕt~Jg՗'Vݾz:"aDHNf&J8bg8Ycz呢/(\z#+6ߜEqҵԩ߿ӋLӋys\,fDHP1'Ǒ8VKҭ'RiDjJ"IORiUIV-*jCE(-֢mQDycU,%Lp7#Fb?Owq"i0O5oD_6/`a0*2;zҶy!]"\c4+U۴hߒf?MZ.@3c2 oAoRvRȐIЌ,I5d Ǵ%N4܋ u9*xYۤA {gJdYo` Ն\*fh |llqN`<'w1԰8pIkHį78.0l l n^^ Qt$Xk"> e[ W!5RD6ju҄AK :Pe4O [edݰQR&$>gպeF! r8y\a9rP!,r #HV7HOf85تjNSѡ*0u#s;,ZnՂݐAű`څPAD $0ךFx:<SOjNra~.VEw6]_ۨ;OϰFO Z& xʆ8U1u%!eҶ6>ƺ,tڏߥB!tKMJw%8'JX'(~ž|Wxy!A[f< . %kjz; MڭXsb{J6 ɗH0}fdLәtf"x[U$SQqsC# eJEoՋƵz b 6RgDɰ*6jWU" bBLy)t#xzKR'0F4O]tdŏȴ0:ǨMFf;~Vr` A!OYԜ.B3$\{DGMA/E!bbq 6΀ֳLp*iXϻX-) \T."9yq.%,K EM:YKX*Zwt= Nuj wQjaF/L5eN;>X܌%Q~?p;-8n¿x=xukVq@דFvKUJF& L7x}mu ʇ92OC578i*9Aam? Y cS]9C (cׅ=+7 P%)b9Pӗ. "ea2g٪&~D/8)as魓ǷD%)Zw͹Ӫ4ˑOQgfyEd)A`2,>?B>&Yzc*=r7S?PÑ6[dWh",Au6~q+kajsɽ/Q^5Ir]ɿ&$Z \8%I XGt:5qhg 6ƧJS9Ō6\f4zZLorCVM<J&w0"&rk黯6-tL;mAW^eYJkR`,X ֘-^4buΖH0)Yv*WNi> endobj 120 0 obj << /Length 121 0 R /Filter /FlateDecode >> stream x]n {bKqv!E"? Zo EJ3?wv'Ǹ-ˆ'vMǩjv1Q pi YpzraćC42Teb႔Z)_bYdEϽ˾O9S="Fh*p"Qz`djUk)h⽒ݘsZU˃uq2p endstream endobj 121 0 obj 224 endobj 119 0 obj << /Type /FontDescriptor /FontName /YKOLSR+LucidaGrande /Flags 4 /FontBBox [-1067 -737 1641 1162] /ItalicAngle 0 /Ascent 967 /Descent -211 /CapHeight 723 /StemV 103 /XHeight 530 /StemH 77 /AvgWidth -490 /MaxWidth 1640 /FontFile2 122 0 R >> endobj 122 0 obj << /Length 123 0 R /Length1 8932 /Filter /FlateDecode >> stream xZ xTE>UN:O4$i ytF`vB7t AHސ QܙotYduqE׬oWvYGF޿ݐLƏtvΩsԩSvwP$,%Thoktz;3(kmyDn\-.'u+z] Ժs޶ LmC> m::8}sџyLji+e fN٘/,Ve9lZ r~m{"4ӴB)_`%緜!Jցn-Uj2l +S7'q'>;#Ls:0C#CfqFK]Qvwj2Y/YAz`KawDzu˵9[0noعtgNi箢Oe+ (nۄ֍Uon\ٕ?~zkPk9rEji`G]};JMl=.5%UG22cRU$Ө=54b i&V@_TG\3T 8+i_GfWӍaTlr* m½w[P l[AZh5s WsLl>J` HIT죈Kb?;gOE'@c }ԟk&h }Bd5xOP<LǔdԎ2$aeK#9"nIAUGr k$V9ee\~}>).~QIyQt;t8Y9 K~|+GG:"=/]/Gz"Rߚ]]M@gE)]%]59lr< 4[NH гrMBd dχT1 2\K"ȅ(?ٟ!wz;ECTc/"E>xP<·TTf1tqܨ?Y_WUVF&]Ukz5y|(,eOA4*qD5+-6ȶ|"rs;#&$8CJPUKW5m!ϲgH&;;ÞLQv&Rb)fӲ]_{[36{K{٥؛ /&<EN5F<!0~M2~J? YHn>j00 i}cd ,͑}I~K"<^![P,TUE ̉:3ӕ1)߈NaWDb~~D3/|chM?fɪπ} 40qgӣ .⬷!PNn u$*eokO, +J1rg/!"4;TI? 0/OB%аm`&jb~62ynĶC:lfvX h%M,6MAYήL6)( Y89,eCĒQr&믐*bYk Ͽ*?Yi3gK4=)YS %k#s#4S.ʲf3)fɔdF$r$&KKKeugIJ!)&ll0ؒog1Y TgsssSv8mBg3ǙLs&;%'9=H͵j..Ug+QInRg)jg{}઼7ʨY5F9 n o qmP[mT^ձ+īʽQ+5{8|5ԩ֧LPSg|ԨYC0::5(+Vj_(v܁(xQl`.Qf$bwTZGt` N0Vjwv0pu BUCK ]@)a)΍%\2mæPXSPu I E,vQ[=:tpwУ>ЫZ˝:\\ҡFZtC?an}i"=MjjȳB-v WavRBEx2z $(V~_iu ij 1"tOصC/iZ)/Vq13tN=Eh>BeԞh5F?Г m_S۬|<#G_ʃIx v.XgIx=j<|z)HqOߓNR T~'G\oƎ_tm&ڸ`$"15^`5څq]3^~OKySBC'{9y|-Xa>+ 98y?n[`қ7?!(ׅxUz.c V{=\nLH_VK9=?MN^*QL.܄dd.=t j(ͤsu|K]ctD~@vX?Zi&c}^)6SXMZX屺!Ck+L%fB'r7UxkMxANer$D\Z2ap\A~^nN5+bHOKMIN2I`ja׽^-㳰aU/Uc;ٕiF/5IQ)Q=|j2bU*E6٭v,&a}˖`V-6="jƙ+( LP6yՒxc895<,l3իGUݾ"<5.YJ^e*_)B#z;؆cQM6]sw"K}ut7`P_z8eicLp{S-_p-h:GQA{Q䃗jz'B7ƴ1:5EwBnS]}ჸ_WAG0pWp2wk:ѳ,8bB,nh~z[["MQYZw}؆G~[v&݅mhe(E.E$A 9v`4s+VX6-qjhz xV"b*i-TjSCNABOˠnuOc@Rh]]-Rb8.^D"ܬ =aSS]P,$&|bR)e;0R)V?@6<ى{ݹB9gB WA%z߬o`DXyt5kV_- G?np a8V;d#g6~Y ;`ST"|k|by8xsثll[l3d<^쳰s،&7%SZ6'˼k0;x6S$_m Cj #ν%FvD] 5īeZmRd8._&$$w` c.q'9ȑaT1ǯTDL[:d j&Z:NELpJC*jRwl, ESLgUSeb[U*;7lM#}ظbՁ}k㑝SvNM*k kElOvjZ2!l%ZEv˭bU_>Y8H4t,G،=a5ywvW(T|'e(OlҪ7WȲvn@n:|d~0,bZBU"_zq^o$@>XXoXjF'oE#N/P=^laLwjXXLėn+4|^}S!_[A` Ky8l cFf F &vv"z u3?wGxeoh+.'«/+kp>n;*14.=1BvDH}wH[«6תt[/']VH7$<ҍy馱C#"|wGxso8o7k"u9rYޚtD""Mf> endobj 124 0 obj << /Type /FontDescriptor /FontName /VUDFDR+CourierNewPS-BoldMT /Flags 33 /FontBBox [-192 -710 702 1222] /ItalicAngle 0 /Ascent 833 /Descent -300 /CapHeight 592 /StemV 0 /XHeight 443 /AvgWidth 600 /MaxWidth 600 /FontFile2 125 0 R >> endobj 125 0 obj << /Length 126 0 R /Length1 22236 /Filter /FlateDecode >> stream x |7~̾>d2KfLH&L6 !0OHB$ ;AbE@qXֽkmuHPjU+`KS?Ъd;wL=w{ι9se/!OD"_p>?z7/xY v%Dco%ٴZB^ua6]q+ir xjddӴp%]MG\{AHt%˯'F:pKzKz7\K/^з'W.!$zvDE-ԓD"qҁUMHr%!?Xe?Ѳf򓅽 Z_UHkϩ{GKX)v-7LUP$"%kt4$`%J3$HDD9چNqbzPo7i<&}=:svĬP/qI61SȗoH/`'RG PMb i )y̰+IC}V~E}~@ pq@@xF|;`tX1#Zqro1Zx`]}x}C38 hl<P͉?wbuVUx>0҃sa}H@ 't]83#8r@usT6aYNsv??9|s_ësxQg[9KOa Ƨ2+r8á䰟̯P,-~˨s# dBAhf!%~),& 8zG~~gr#  hY &LMhMnAyt<P hPr% ocA(@(JBY y}DXc ` ` Gw@NzOZ;֙(.W_ 42`pP!6|#VR#:ԈNaGVtN1]Nb#QvN@ 0 8 MV<$>PXc9&&/ACyL)PS;cC8&TԂ_TuzUTJ:RI!) m" E@RIA)$IRap1&K3Ÿ^lB~/ y0B n}<֏p;DagX);2G"g9pXX˹CrQ8$]“d)x]X tOtO>]>]OtOtq>]%,h N]S8S+NmNmS8S8qNmNm9S8SNmQq>I J@& IHGHG<<$x$9$x$# I#%G<88x#y#qsqGah^=䛆0Z5Z0ڸm݁6D-hi#Z\'о2-B#h] a[ru5 @ 88Y-!_* F nyxa v/ڍ[ۍƮvcGqFMAC{덛7.zqƆ덵'^o#zT1,$_<֑2&e e ϊL6犜O z'rE-"og&,G2gobG6/v9he+"g\!F0ƲEu :X/pbvȣX >Pހ*`ycFj/׃Hpq9d1  <<o釀' >B2#9kz^z?5?@\H";[xI< #0E>|BJ^E?twүV_!oӌSj%&b ia_f&Gn&?Ԕf&Q"KȵN#j̥p$99h5خ.O'nZV>[JzeIf1) I,#W|i@Q%䋿VIO/#=d% \ 0+$Ed*(,>M<>8*D'+lvM_Ҵ`'w)BVܣx5mI$=>itdN+ȍr7 y +n7z.KnPLoӗgBX&<+Fu5=IEDqʍ=DfZ|KL\dL|+l$Wb̿̿w? #3rj&LWKev}~H(Z& sUχWŷŷlBO+Ңyç.NwfO Ӓy&rp)źlǪL+$C!%֛(M0қ1??Ig/;LM`#+D8ZLPFxBG c<u1- ¦*(zw)R8F٢BeQݮW!o}hP H^ \/kt:;*GB#+t>,89JN3p#_N>EHմ"@) ae쇼ShA|?fIiA/BYE"-I\FcᣔTy*{c8ཿ.';i1~zyFQLTtԍ k󇂂<. r6Rqw'@.#t./XXC2oE{"O1;'32{9|$$!y{H!itx7Ցɹ Ev 9#WC h,I|CDo8:Cj&,T6(}qz}IS^Uʫ+󔳔I e2t)JQPR{rE K|@MgIk+*Á{H6QYBy ӞOJߓ~?ݗ{_N}jשGc^opyfi7{A }1כЫwc^.sD$= +H7Ydޘ[=е#%bs1'pivW2 AcDž@'ZRO4  G$9nA6YiQıDŽ^zGyiא=㪇.Yh涷i6~J]I5UxyYixBQ4R~v9yv"MF^ըUJ(PRHEShsX:˿ѝ kuRrUSF SS֔OפRԗÁp`.;(qE'Hx"\H@sj[J.1أ++%tzD}h4#B~s.hcnjNxdHK<`GYi6^^"̐*ISj&&J>$1˖ќ)Q$dRٹ&*oݺ%9wɷBdF`};:hk>JS٣P@J^nL{k̻*8v{2G9up0;7첓t%e$Kv4w̹HF:[c:͚wz8)kcxfJ: , #Y3l`2FR+1 kRRPҔ2"[OL{xsrT B8N/]>OPRօ6N隲ҍCpI/cuqy0f!@"?wI6 +<D%t񒼅a,5EJ=gu)dgς&м;Tg-8+-gqCY.5.=[ڈ b%.[z K )E*W5X<fsa. 顡qGgu#U54Ԕg5ϰUF`֭Rsb)C$`mia,2uGY̧C%|XH-(fwOCS+ A<]0ȋ#N*՟w9Ϊ"=!DRR$eqGdea-pa Qo-` m#GRHS$R4;c,.EO,\RLbv; _m-?Hi LC(Q*͜RVFX rآ tC #['{L2Ҙ;QtoF4_JAw;֭3[.=Ctlk~ҡ<w`uuPE+LoK_d[,A=и`In r(`*U\ xp~~xC?)zt=f *"OD"Q5^a-eu=cD |F<+v8KD8.Jy\V8NK3glt~XX=I֏3HTYH\ )YI`0LG_~Y7bPz[ lI8YL;di-q!h].c*JYhr"1+expDLkUE<3FlF)F 4cbFV{cA\@N%Doyv! 55֪JU]] Ԫ<{rEÃ>yutwN8z)Wᅱy޵?=unO\ӊŽ=U2yJKUMMF}q8VRU+z,Bl#_D֐ ȁЁq(3<8-YͰl60:=:HEv…$HZ|J-{jzK5x`AvH%-jǨ 5=ק*w}HX%kx|QjmpEh|~v:4F1 6aO`D訥JcSkЗ'WȺ.Sl`ݭub E1!yyY波V0Y5y]VgR$tjPK.7ULuW˖Zq~cc r~B>Rs4(X¿.X~%5 ˮR^weZFk&A@((6zcdoQ "2YA<2T CSźF+UbZIjxg*nFU6NcN,Z Vs]t/ᩪwƭlޤiq8)7m-)%^iQs.T_~zB{ņ ?os//?h~>'=j-+jL j*Jg7t-r ]oީUi"n:e&6b}"W{=.Du5^l6IA,`g_^,q+nw;ueorz5z+oxE Tњsm xkܢKD;QWxPxHl$&dyLϙCF}7,z+dmwnuc>;)qb\‘];ʭL!cB%%?GEddv.#n>E gǵ5%==\7g‹j3K'@+VMuz7g]Voٶg\={Ng}D +,nq*НZdXԺ>Vк4DݧVj |=ߖAwS]äy,wagqVϬ 0D:IBQ{/NXz|F}+.y30ź9scEh.v%a:EQ-N%dA65Z`d;bD]=^^ ICAvo ( 8. 0ۑ0q ;325L,VK"'![j4nl0Uؔ9IG)32 d|D-/pΐE2N 駢Dv\ j!{sƤ/`S1,4N}}=Xfau%Ғ፭LK,=QǠy<+V֤ױȯȼ_|^TDIT911<1Y%K]b֤Ui^VxGuTDNmGi%J&\LK&U:6Fq_ZҵYׯtRVJKKrYe*}b]5*FhŻ]!bkd]%1$,j9ߔ36{15.e{Y˖&%6R6c&QX|ƒD%AfIq<}"Z R+}-1C̦\'S_91gO)BOM'{}wTQm9W\k/=}o<fuK'{*03Q\E7^Q^WhRKyG ΩE`]%ޯ43WiȔrRju9ͫ5_k~A2 h\⅁OKNN2BYkNF#R( *f݄Ngj'jϦnWRjzDM՜ETKIĄ #cCAu]ߐ,LRqY<cY ۺ$Tj8b-*% ~2@f.JEzC0!(G` p  2 W2TR&ѝg6jaK HQ^vTUYrpX!lۣ+g=:!o9ޚg?VZ?MdIq%+XxMԵx=$6Hzgm?Xxc ?.MXkDke' Tzδ.~SDžjh JqVP 1Q_j*k#ҫ4I>;|2(%@4*e'slrz=(ߊ`IGNf zxd.id#cT1Ptt%wܦCK:gTB]xs'^X.ڹ5űwO% 'g:i$~+osK4M=?f%!Y7d?GyfzA!!ׇ[8o)_U-*ƾy";??ڥVtwaB'{kP>*}6S!p5~B͸F=X-t*Lq"'AZ!{\w`xFYQ?\X}rw lrݲ&k>`j+2smVN>ʼ&MbӃ#6&Y &Yc4㰕l:>;e dT;֒"efҀ8u;߫UpTyX0U9|'_d߄۾Hsⁿ_=}EtBA:~{T^rʍK/^1z74r-՞|OgG@ fZEE$WytP8c-5N[D3sV~`"QU;Z8BP=AMlͅ=^b]YVEVJ΄Sv;NSe^ +5:KTOdC  Aw |r-]iHK,+퐞I "^RH!Jw =Q~H@qOC2.pt uB?2w0g*5/wzh!\a+X} GmM+.MY/mbﯟp]ɥ)jԲ9,3ی}3[|[~V.۶o.umpmWO.yk)i{${ .ж;m*" mKC]#O*NDm(=1z=Y ==,_K<ԒCB'~nޓ]@K 3ZkYM-繳 XT'ھmLbUóXr1ca'PFHpCGHs;ְޓ]Y+Nv`A òɔÉ1YHci#9FzB.1Ұy9H#ii.6lEl, *&X`GzkFflǤ#=YH"42O6YUa֬hЏ0E,˂d,cq BV ,(&]f$ ʂ ,(bAX'})lESޅBTc8 +({eM(.:VoEW~۴`̈́)l'=8֨`IY"~VU3#ZѬZ$ul*/S]Vele6 gCR=Ρ'˸J)*XȜ0X`vug7*%ٰX-ѧME ~OkrZCaW$[?nM&mD9XBolOԑcmL?g}^r fʌ_?/ 6wpsCӗW*㫮W=uv4ק|,|@czGkYFPգtuCen8|$vSUx|a~MBӧ5{Q8ʀ 1`@e'dM ݷK0 k'\0 bug[2Nś,xr ]u-}z.~q)(DI5=$'Bcce''U*.*<|5x`G8ZC䴷G M{WU=.%"? #۔W%Q2^摱{ "XXYZr;[Μ2lId?=]yYV wtF=vvr ȁg Ar"]} ӂi,=5yp[t3w=`o끥S{OK,_,6"oo~?vsdžzz>Hc=V[\j\VG͉ͅ{.];w+>~XqEܢjZ8!11R<#)d}ލ0'uL5IdZ pᄚx˖*"Ϊԋmܐ ^NXnߖxK뾊|( : +! p,#cj_N͖,1/om˖[{qza4e}cME.ǃaQT]W/t!aܜ('bp~BXhnnkʹYƻĚwNW˞+`_HP$$βuEA^=0'Ƅ'Kۥ4,T{a!Bx<>U*Q%V#6rӶ-};Wy46[39ʮu3<]1xagp%C:}fZMd1Ȃ,hfA  03y3ذZXB,P8Hsh8#7f4|DВlaZwϧ#2.,̿\m E&#?F= 6U^Z I5^}IsȚN4oZtǜHMc_Οy-7ۂR`RdCd.(5֋>)ܚ,P\pNp֙_:sFgy9~YܫnY6gMHīҞT->ueŴp +k¬=`O>{>l?b?nIdv]RZ3~!چeX'QXq\#G[z`SzIJl?n 찟T{J*)2t ~yFw}l7eV6>?)x;/nݞ'hg~X8d=n#yD½Drz 9b=~f'b+WӪ (IαW#0C')Xq3P=I3b (q`]=w :s${t\_ @2t&\ 7y%[0[$ȬrpCY4ZGo\%m l*CYl1Ã:81'뙟̇g!yX`W/0oN|4Z< 8O4HUHs< xzxV<0KkYr;o|Iy=e?;s(N٪l/Z &&[& =ms6=~3l}59iW7 ; m6kYNqbi'[DAiy-`lVӚ`wof=^eދθAn{nf{Uf^o|8-7Kz{U>us<ϼ 9fֆ5Md.ʌהJQoiyyw1YcZ廚\mz?s,y%bR4SsN>/G"4M/S!2IBJcN޻*(-1/7XL݉#'{|? =Ž灥?{}Wl|LxB,`jzy,f@,KL(l*Po%45?UV'[_^ر_X.178OuHAs;"+8v?0~w2Dχi/Lpg2ᜉ_xWh>~i-`bR>YiFӼXcsEkW^?I endstream endobj 126 0 obj 15169 endobj 8 0 obj << /Type /Font /Subtype /TrueType /BaseFont /DOANIZ+VAGRoundedLt-Normal /FontDescriptor 127 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 212 /Widths [ 240 0 0 535 0 0 0 186 203 203 389 0 240 352 240 406 535 352 535 535 535 535 535 480 535 535 240 240 600 600 600 0 0 611 537 594 631 443 406 668 668 203 352 557 369 834 666 684 520 684 520 463 426 666 557 816 594 482 0 0 0 0 0 500 0 557 557 443 557 520 240 557 535 203 0 443 203 832 535 535 557 557 314 443 240 535 426 740 463 426 443 0 223 0 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 801 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 314 314 186 ] >> endobj 127 0 obj << /Type /FontDescriptor /FontName /DOANIZ+VAGRoundedLt-Normal /Flags 32 /FontBBox [-55 -223 1049 925] /ItalicAngle 0 /Ascent 773 /Descent -228 /CapHeight 726 /StemV 0 /XHeight 548 /AvgWidth 464 /MaxWidth 1094 /FontFile2 128 0 R >> endobj 128 0 obj << /Length 129 0 R /Length1 15184 /Filter /FlateDecode >> stream x{w|Tesn{g&2ɤdRH %$I%$NHI((Mk""bl,ꮊmem"(vWHIy{'A>x&̝9ϩs3kV]h&!,as Zls܁_XV}IHKx xs x k\s5KVt/\w6|֮Υg1k<3uN<5x=u8ޝO)"ap{"K'-g^"?xpT!p mtb܌*#]`M.X /o4xW&3+0y۔UM $$ Wg5B]WۨmR&nkAr߂WG* fB@DLP2J.s$9NQq34ǤmRHt1Im"QSک*WTم.W/[|_ w{J663YˬF^C(Tmpla=Nh%Єʔt&@BgBi%CHa?O_h뼴$c ϣnZl;[b&$r]?LUʡ_]Xh'vs;%l8\ٺ9c{e _[Pm9>GpkA{*<̫jί'Ggqn޼>ɇ;ۗG[Fez\\6jXU&r{~?є䌋ͷv7s~ ƅw; 9x.v'vgG?cwkbyq#p⢞7D>Z1v0GeMV/.?5"I$.6>.~st=:KQff]tҋ+= FRxwmUI#w{G|v6j`T2c CY<!ҭޏb/GU;?g1mC2gc_9U9"-Uc=|+gzx w g8AGH $Ad &!8 pA"TEI %q$$DW 4N242 3I&ޛEH6q$$R~x6)&sH >1ߥYN摊QÑ3ɷq+(XL+&[|[>AꅇAڡ[ߊ?KuWWS9e۴g: uԍ;.C-cq3Uv4yw{a6Do<ߧ|],o,g ; #+adWPG`#KBP1V'VlLImH|36[E҆˷'(2tJLL&`Q yәh&?D-0\&yi9mA~^n)ɉQS#A~=zti Y<Xræ$c 6<u`LOWB#"Sl6<Ϙs{DVϣ}r)Wq95j˶jF:ZP)x=!UtN%T Hkro;egvGVdI23n]C.9ZôIͪp2-hIz4Ca Ym|b +SZ]aiݏJ7;sq!Xth+#ZCØxf6U1>>qb@F%Aeº5Đgڣ BpCaarKV>S+7sݗ"}~#=FSߴһD1q >. &0XhxW Ł'l* 'R2Z8{\_E+ܕ]e~vl20PfG䌸({p^C$o^a4"C e~e{XlO\@MJ֕YcH+a>.Q>yeQ; ![ʒ<9{H_-hd^T?\qs}}~ҫXU}ܫ:t3j|,,U]~WZf6](PAl 2/ׂўOG4!FZUYI2z؃;0AipP2(ڗmž1lf_PUPj50> m &[J8`B#R`-߲mX0M"ST<>($,ᥕ8mJ#x{$ E7rw6f7'm pKm3f@= 8 cSbDXu3 [j 0 m0d>5p0LPQbGDx j/ʿF食Ca- G:~Ҙ;}=5ug<@,}},FqcF[ò9QӎtOqT80ujMنbd?8dq!>[T'e|[G^}r} Kpt)cȕHꈍ3S4Ҕ`3>j=Zs&#ΘDtS͗3Xji*0(xG >z :>9U*78MeCG>g?fP]}nmK)=1JTdF>F}ų:o|P)$)R"P"@š")&d܊An!)2fFU|l(x#Bg1[(zF3"@ghn~~vަϞDNh)qܲcQ/O657g߂}cɷ^*w=O? egdf(4㍯~uY(nA-㪃e9¦x1fDf/IZ+˘` !TюxE?dx 10)E{K8[5[vίzCtgZ+oؖͪpk[(ji H 531aZEh ] /X!ldP\-k26S$I iE, Ţ ˵;@%t' *]Gozge|;鏁iك# O.i֊G7:j\?ssӧ>prEۗe% msA\kub0ƃ䧨0vhBt$K"ي)lGFK$&80ldU\ĘɄrP#6Nʧٝ#Ї\Gu,E0 0\23@Mr:[W^KJgtf_BdMYB~YA ;"˱qª̈` Z@%M5+2(0_\DmEI_I^+?}9j ^_T?btioN\)"<!8voALI gMB޲c|RGHhX ARb1k#=f%9ݔ&@;) L$|V#F3Z2>D5}7տ}km<гӡ}`|^zB{wΎzݑ߹,7^s}jQ]A/}O0Hrd:\"Ƞ't7#t*6,խ+$Ck I 4T o@ڐPiJf4[|M0vlRhy#Ol_c˸+#:zt8..͖tW1ό]p ੳt7q|!!f-B}5!1xp~&L>?OzX,jIxP5 yÂuj4qMUov|[nZPu Je@3Yt ,ex/^3/!3Q $Yd4mcv+&g9ؖΎ)ww7MC:>%VMǢLxu&IMn%GGNals2Wu1+ؚmCq[ :Dǂ|a84YY|ekY$̭Śr/s+J5:˚ ]'doWzrr*L71\Ry}W݃Elܺj$&}hFf]czw$gSõV6 V eup6$hN)UI,6ݢY= Jà*Ɓv | nGDL?n>~oBs;Jng_54j3a Iû70HWv.lsN+w2Fe+:6z~hqev­4F H'AW6aBٽ6tJ3#||1". BhKF峰Ԉ0P{9,@U=cZOOB_uCBoV_2}MtD1[?7tDն~1ػ;~u.Aɂ(*xc8#Fk*2]S^&Rx&}*kFd.L& sXx2ljI_co_[鎜GiYM?ȇ30^HxVfc %}} !ht/wE: T3,bHQFZLv&zWDv]}n~=}n{7QM^qEg@6X >A?r]Gx 6!'=~Ɓ7.}L<X=E?{Iޒ+wi MQDOqKfٌ'.fHGas 9E-c{ƥkV_&-mqmc Z9Ö$F){rl2 `VL2qj–d+#\QΤ4E*JI v=:I~&t& {_O.6KYJjgrĉ"L"akO)16C-Xn[Z۴ߝv׬;׮X=7r qyu-/OimUq/W,ZԖ4)Yç _Ud4(3tU +;rO V#!rR87.QQThmMW:ڶ4쫪oELe"C{<>V/wHFRKlV<'n[  L16&}Z_7賰y/Wy.vEhۏA-c]K` 8?F/CXi^p)G/,FE(Hꯓ)CX z0*x0bZ|:T "}م+F[ziW yMKH;NJ O?V)J3"lZ!GJRh>VE``|@I60k)ևoY.;O" ױrˬ Nı=p Pq?k=: dCCfIw7S˴? < B{ ,M718LߤDPJjj;bUr %?z)-yt>zbr֌^+sQ pbd+QpOo}ͅcHpw{wmڎ7g9.W>{6wt׊u`&dr)dMWn8b" VQZgV(E/&3g+ %zb/t0ԆEN |ΦdXAP6`[TTv宦w`.:SLUS p7v:J;Q X>[2^^~ޠwiDk+}?Nܽ_+(q-Uav$jˡAi8ԩ87w\\# rML\TXtg 1^OvG>gBm dFǡ L(98M\Jz)m *%0!9˿j)(]6DWj{Hi> q9pC}1Is8A'Zrf4,uPeί7n=ڪN(ooR#V[m cbjhZR# 8ԉ Lf' hx2d<(GaZ)wZo\Hth95o957,m[_ղiMkϽ|T*-͹|X**k\Qtb-U.G@t ZɈF>6WiEF]_=73Mݒuc2s8kUV]aMj)X]Zm`Zf̪hqpKEGO\PϽ1樯&,aі/BD=Vy%4 <.[:$g3W.Nv/:$bղѳcE Wt7S"nP ijzSFOddfM\/'Gd&D ҋ68,a/V2Dazz\gAЉqG+`]KLX &{Pf@䂗7*̆Ͽa~X_勼% -V2 ւ^9?/`%~SCڲ֕#܀G-Jۈ/ f\5Dbq5q:3ǐP s}'b`Bkxd"C9F >)&&#b1afr p ]?n':zck`1o}3r$})\%^b>Mt"#'ذ$?۫䰯aZdC (hDSt4VwXя2."ni)*apMzi.&?%4?oF"Y@xn+8H~L\cE0$@e3mY)Xq$V-jt:h?<݂ܴut.g"_.4qD_wY鍣PQKk :G4nEY1/+VM:ر3Q8aV4|Mk?^]9a})W9Y\= uxIEE޸%{`I]Ӏ;{v{px<]@m?v9lwʤ#!oz"` !wFoz2ϴy,u=b{Qy):G諏{aC#[孒)lE姦_P~e4gHǺM~F^(%MTQJ$.BU.QV' u| BEO#rKMic*&%bvR} K$mg4{Zŭu|,Ro(c1>3?/|̈́SckKE̿`jȔ\]ߺn뭪umr<畂q{}DK 7bYo(%Dk6QroT5ֹ6fޞX<'*-XUQϾ`ENL%b.ݴŁz'\]f/ ʖoaG.U8vU#?Ӥɂ<ł u1BghI3 *ȝ"G65@Od7F/](g-i??A{+X%woxT6䃠?z>tnL?;wzOtt,~.)o<*<: ' p,Փ3&=0}XY{6m))҆*q˜;| X%˫<M4 :z`5CӂN $0E ^\چSq a3z5zN8]1x -^7tYI?_CWtit`6CO(B"nF4Fx]tAG#hBc $>*K(uME}FeȔ8*0 $v`Yu;ԔЍtS: pmcf/oTI>t;3Hkzל#XqZu> Shqth_y}O.~.": "eTVחሗ6Zg}լ/Fe+q]S,;B8wӨة Dj  oM^C!]BtDht_9OG>վ K/ _TmB,}`p\UtiåO"_Pn$#I5ց\엫0jZAaޏZCr{7l ,=wĂ%-Շ>-,+k6N4㬈edFqS%6\#aѡ*%> k3ueJ'2[Pr]ڂ)Z0暶 N,y{2 Jp,f4IӧΟ:)8J$~v[4/x0}zpt |jB\[s@Ro5$c)13 sܯ1;fW;U䭘٨M62C3kK̑sn3sMlH}Uq:Nzs}=gXT%8*5wάPI UQphbcin.)V(4`a@A4{z$@a5EmD?BڈnSϒYyv$](^:p N-j.=YוsW։=W fNj[%k@nTZSIJYhi@Hs%JJ.=X\ g]|09/U4rp+U UM7%ybKbh:̰#@^7,]Q眹od[ gsgV}ܖ]M3sv˻wj#F p!FDQrX"ԜJNgNCΘb9~%CXIvlwZ!uH]F0Ȁ 9)auâgȿ^sU_zvnf:oY!aa}}o?C/vp=8<څЕ2P]46ś j~Ȫ*б0ٿr!n?F%}e5fޖ}Gfmk` sݔ&kcCɴdJVyTe\iU 2x~xu_-/{5y ~RƬ* aX]Y2+nCj~1)oH^ҿ:eR5?ϯzJTjRCjI' d!YDɝE} *nIFj*WS:.*%K+^ټI endstream endobj 129 0 obj 11352 endobj 22 0 obj << /Type /Font /Subtype /TrueType /BaseFont /TTOTTL+VAGRoundedLt-Normal /FontDescriptor 130 0 R /ToUnicode 131 0 R /FirstChar 33 /LastChar 33 /Widths [ 0 ] >> endobj 131 0 obj << /Length 132 0 R /Filter /FlateDecode >> stream x]j0D= gc():EAk࿯zAz3gHJ` X gux%mU&*a[@mWF$\h '} kwD:rċAO>S/[F8<*Dc!'it4&U$j~O=?c endstream endobj 132 0 obj 207 endobj 130 0 obj << /Type /FontDescriptor /FontName /TTOTTL+VAGRoundedLt-Normal /Flags 4 /FontBBox [-55 -223 1049 925] /ItalicAngle 0 /Ascent 773 /Descent -228 /CapHeight 726 /StemV 0 /XHeight 548 /AvgWidth 464 /MaxWidth 1094 /FontFile2 133 0 R >> endobj 133 0 obj << /Length 134 0 R /Length1 1324 /Filter /FlateDecode >> stream xuTohe{.ɵMb2e0٥nEƬ3aڤKtm6;PFmPdDDa_? "eC?6d_WsIsw=W@K BvscR`̅x م3^ {flKY.6kU t9J՗\*^^B\ qUɘߘ Hwyia독y?IeP`$4ab?A8vѯ70'aJvk)* ]1˔_ ouf@!b蠘uiOp^ohIѾC8~Tf B(lګ;7ǬjvZ+)QVi{7_a8#x_<Fex pn;rX[ 2c:UKQ6kʔrD1us3 n+)c.}/J'/51%ᶰ)KUE<V%+u`soGin÷`g|. i`@Ud&٢aϞV/sHv;0L9:,3E/mpa7QL^u\L\r W/7F'kB|Oq&H }ʕDv!ysw ƈ(6bܧi!3{̣N(5fm:alsc%2s: s.80(%!ôϺzG7?#wDO6M=Zr2\en@Ώ6ma࣮7a]{~X6_R_2)D|2oYf&-IJμFHCXؗd) PiEdVY 4#PJNjuK3?~y2珧N}dr|n-zY endstream endobj 134 0 obj 959 endobj 42 0 obj << /Type /Font /Subtype /TrueType /BaseFont /MIQSPH+HelveticaNeue-Bold /FontDescriptor 135 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 32 /Widths [ 278 ] >> endobj 135 0 obj << /Type /FontDescriptor /FontName /MIQSPH+HelveticaNeue-Bold /Flags 32 /FontBBox [-1018 -481 1437 1141] /ItalicAngle 0 /Ascent 975 /Descent -217 /CapHeight 714 /StemV 157 /Leading 29 /XHeight 517 /StemH 132 /AvgWidth 478 /MaxWidth 1500 /FontFile2 136 0 R >> endobj 136 0 obj << /Length 137 0 R /Length1 1956 /Filter /FlateDecode >> stream xUod~>;IHfe6iΔBh%պ&Q[ F:;rZOB%P.ȡi@άB"~~] (,T+5+ 5wnnV@dW7;;emɩ,6RDG` KDٽЎ~VmJ d]Em)'kvh: U#"BMפ+2 ?Μ60QȔK/㞍su꯭1et$K/!SlqM gq )sZAw` gaY`vxRh- qD^z9]lǤW}(T&jXz1`njcLCml-v7J ב 0a Qh w"!}?>Ol+#ECu|oq`auJ 4v6/[g7EnM2| rPrtLԜ>YY[wuwfէʢ%kus2,+ؙPul]>,akç+IܬgUk3^hg C/ye-f fV,DJ/0wsl{'-nI|Oh :Wl^vVn;ʇΚsՕE endstream endobj 137 0 obj 952 endobj 138 0 obj (nDPI_QuickStartGuide.pages) endobj 139 0 obj (Mac OS X 10.10.4 Quartz PDFContext) endobj 140 0 obj (Pages) endobj 141 0 obj (D:20150713221834Z00'00') endobj 1 0 obj << /Title 138 0 R /Producer 139 0 R /Creator 140 0 R /CreationDate 141 0 R /ModDate 141 0 R >> endobj xref 0 142 0000000000 65535 f 0000136412 00000 n 0000000958 00000 n 0000052968 00000 n 0000000022 00000 n 0000000939 00000 n 0000001062 00000 n 0000007939 00000 n 0000120492 00000 n 0000011417 00000 n 0000001221 00000 n 0000004742 00000 n 0000004763 00000 n 0000005183 00000 n 0000005203 00000 n 0000007918 00000 n 0000007975 00000 n 0000011396 00000 n 0000012572 00000 n 0000011453 00000 n 0000012551 00000 n 0000012694 00000 n 0000132917 00000 n 0000012804 00000 n 0000054360 00000 n 0000014069 00000 n 0000012831 00000 n 0000014048 00000 n 0000014176 00000 n 0000018093 00000 n 0000014297 00000 n 0000018072 00000 n 0000018215 00000 n 0000061524 00000 n 0000018348 00000 n 0000054127 00000 n 0000053867 00000 n 0000021494 00000 n 0000018382 00000 n 0000021473 00000 n 0000021601 00000 n 0000067615 00000 n 0000134718 00000 n 0000026022 00000 n 0000021746 00000 n 0000026001 00000 n 0000026129 00000 n 0000028824 00000 n 0000026262 00000 n 0000028803 00000 n 0000028946 00000 n 0000029079 00000 n 0000053638 00000 n 0000053366 00000 n 0000032404 00000 n 0000029113 00000 n 0000032383 00000 n 0000032511 00000 n 0000036882 00000 n 0000053091 00000 n 0000032656 00000 n 0000036861 00000 n 0000036990 00000 n 0000000000 00000 n 0000059788 00000 n 0000104547 00000 n 0000040397 00000 n 0000037147 00000 n 0000040376 00000 n 0000040505 00000 n 0000054595 00000 n 0000000000 00000 n 0000098921 00000 n 0000042976 00000 n 0000040663 00000 n 0000042955 00000 n 0000043084 00000 n 0000044086 00000 n 0000043242 00000 n 0000044066 00000 n 0000044194 00000 n 0000046799 00000 n 0000044315 00000 n 0000046778 00000 n 0000046907 00000 n 0000049873 00000 n 0000047040 00000 n 0000049852 00000 n 0000049981 00000 n 0000052727 00000 n 0000050114 00000 n 0000052706 00000 n 0000052835 00000 n 0000053209 00000 n 0000053301 00000 n 0000053488 00000 n 0000053544 00000 n 0000053759 00000 n 0000053815 00000 n 0000053989 00000 n 0000054046 00000 n 0000054249 00000 n 0000054307 00000 n 0000054483 00000 n 0000054541 00000 n 0000055024 00000 n 0000055265 00000 n 0000059766 00000 n 0000060280 00000 n 0000059959 00000 n 0000060259 00000 n 0000060547 00000 n 0000061503 00000 n 0000061710 00000 n 0000061982 00000 n 0000067593 00000 n 0000068339 00000 n 0000068583 00000 n 0000098898 00000 n 0000099412 00000 n 0000099089 00000 n 0000099391 00000 n 0000099669 00000 n 0000104525 00000 n 0000104958 00000 n 0000105207 00000 n 0000120469 00000 n 0000121200 00000 n 0000121449 00000 n 0000132894 00000 n 0000133398 00000 n 0000133092 00000 n 0000133377 00000 n 0000133646 00000 n 0000134697 00000 n 0000134903 00000 n 0000135179 00000 n 0000136223 00000 n 0000136244 00000 n 0000136290 00000 n 0000136344 00000 n 0000136369 00000 n trailer << /Size 142 /Root 94 0 R /Info 1 0 R /ID [ <8f332d04d9467c5e2cb09f0ede8a83ad> <8f332d04d9467c5e2cb09f0ede8a83ad> ] >> startxref 136522 %%EOF nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/000077500000000000000000000000001262705051000207725ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/Makefile.am000066400000000000000000000004251262705051000230270ustar00rootroot00000000000000bin_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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/Win32/000077500000000000000000000000001262705051000216745ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/Win32/pcapExample.sln000066400000000000000000000016111262705051000246500ustar00rootroot00000000000000 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/Win32/pcapExample.suo000066400000000000000000011270001262705051000246640ustar00rootroot00000000000000ࡱ>  Q34Root Entry!@ (:%ProjInfoExTaskListUserTasks$TipPersistenceDev10+*$ f !#h&'()*I./124578:;=@ACDEFGJKLMNOPQRSTUVWXYZ[\]^_`abcdegqsuwxz{}~BI8ܐ'C  ^VsDebugPresentationPackage, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3auMicrosoft.VisualStudio.Debugger.DebuggerToolWindows.DataTips.PinnableTips.Extensibility.Persistence+ListenerDataStore RC:\ntop\dependencies\nDPI\exDebuggerWatches DebuggerBreakpoints(^DebuggerExceptions& DebuggerFindSource& *ample\Win32\le\C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\vc7\atlmfcC:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\vc7\crtDebuggerFindSymbol&)DebuggerMemoryWindows,TDebuggerBreakpointsWindow4 ExternalFilesProjectContents:B~MultiStartupProj=;4{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}.dwStartupOpt=;StartupProject=&{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6};?{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}.Release|DocumentWindowPositions0" HDocumentWindowUserData.SolutionConfiguration, ObjMgrContentsV8"56789:;<=I>JPKLMNORTSU 7_D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\example\pcapReader.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\nprobe\nprobe-win-32\getopt1.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\ndpi_main.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}||C:\ntop\nprobe\nProbe\nprobe_win32.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}||c:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinSock2.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\protocols\dns.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\third_party\src\ahocorasick.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\protocols\http.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\protocols\ssl.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}||c:\program files\microsoft visual studio 10.0\vc\include\string.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\include\ndpi_protocols.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\include\linux_compat.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\protocols\netflow.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\protocols\postgres.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}i@D:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\example\pcapReader.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B-ST:0:0:{3ae79031-e1bc-11d0-8f78-00a0c9110057}B-ST:0:0:{cf2ddc32-8cad-11d2-9302-005345000000}BD:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\nProbe\plugins\httpPlugin.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AWin32.fBatchBld=;={F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}.Debug|Win32.fBatchBld=;4{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3S$ A+HڪWLl #O¤EL%ү##G}'bm4S8fLd9Ll #O¤EL%ү##G}'bm4Q C:\ntop\dependencies\nDPI\exaClassViewContents$ ProjExplorerState$UnloadedProjects"HiddenSlnFolders"mple\Win32\pcapExample\pcapExample.vcxprojjC:\ntop\depe !C|dtCple\pcapExample.vcxprof{F6A2C0AE-2110-438A-87E4-7fC:\ntop\Source\Copia di ntop\utils\getopt\getopt.hC:\ntop\dependencies\nDPI\example\pcapEBackgroundLoadData&"TProjectTrustInformation0VC Project$rOutliningStateDir$%xample\pcapExample\pcapExample.cppjC:\ntop\dependencies\nDPI\src\include\linux_compat.hdC:$Bookmarks V001.01X C:\ntop\dependencies\nDPI\example\pcapExample\pcapExample\pcapExample.cpp!pFSdBookmarkState+(TaskListShortcuts$,OutliningStateEx1$,-OutliningStateEx8$%0bC:\ntop\dependencies\nDPI\src\include\ndpi_main.h8xO ]1 dC:\ntop\Source\Copia di ntop\utils\getopt\getopt.h my~O.sdC:\ntop\dependencies\nDPI\src\lib\protocols\dhcp.cܫ>cֽ1QOutliningStateEx6$*3OutliningStateEx9$+6OutliningStateEx2$9OutliningStateEx16&-/<\C:\ntop\dependencies\nDPI\example\pcapReader.cg;R7Lnu m+ZC:\ntop\dependencies\nDPI\src\lib\ndpi_main.c;8eLe:jEC:\ntop\dependencies\nDPI\example\pcapExample\pcapExampVsToolboxService">XmlPackageOptions$#?OutliningStateEx19&poOutliningStateEx18& role\netbios.objAC:\ntop\dependencies\nDPI\example\pcapExample\pcapExample\dns.objC:\ntop\nprobe\nProbe\nprobe_win32.c<open> c:\program files\microsoft visual studio 10.0\vc\include\string.h<open> c:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinSock2.h<open> m icrosoft visual studio 1\ntop\dependencies\nDPI\src\include\ndpi_main.hnC:\ntop\dependencies\nDPI\src\lib\protocols\postgres.cNC:\ntop\nprobe\nprobe-win-32\getopt1.clC:\ntop\dependencies\nDPI\src\lib\protocols\netflow.cc:\program filesD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}B|D:0:0:{6AD4397B-B4EF-4CDD-9C56-AC7E2100A69B}|nprobe.vcxproj|C:\ntop\nprobe\VERSION.C||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}DD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\example\pcapReader.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}DD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\nprobe\nprobe-win-32\getopt1.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}IBD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\nprobe\nprobe-win-32\getopt.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}DD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\ndpi_main.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}$DD:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}||C:\ntop\nprobe\nProbe\nprobe_win32.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}HXDD:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}||c:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinSock2.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}DD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\third_party\src\ahocorasick.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}DD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\protocols\http.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}QeDD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\protocols\ssl.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}ZeDD:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}||c:\program files\microsoft visual studio 10.0\vc\include\string.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}࿻DD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\include\ndpi_protocols.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}BD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\protocols\dhcp.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}BD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\include\ndpi_main.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}DD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\protocols\dns.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}PeDD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\include\linux_compat.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}!/DD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\protocols\netflow.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}+&2DD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxproj|C:\ntop\dependencies\nDPI\src\lib\protocols\postgres.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}\&cies\nDPI\src\lib\protocols\netflow.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}+&2DD:0:0:{F6A2C0AE-2110-438A-87E4-7C1CFCE064C6}|pcapExample\pcapExample.vcxprOutliningStateEx20&tqOutliningStateEx7$vOutliningStateEx14&(yOutliningStateEx13&|\microsoft visual studio 10.0\vc\include\string.h nC:\ntop\dependencies\nDPI\src\include\ndpi_protocols.h dC:\ntop\dependencies\nDPI\src\lib\protocols\ssl.c ^C:\ntop\dependencies\nDPI\example\pcapReader.c\C:\ntop\dependencies\nDPI\src\lib\ndpi_main.cfC:\ntop\dependencies\nDPI\src\lib\protocols\dhcp.c JC:\ntop\nprobe\nProbe\nprobe_win32.cLC:\ntop\nprobe\nprobe-win-32\getopt.cC:\ntop\dependencies\nDPI\src\lib\third_party\src\ahocorasick.cfC:\ntop\dependencies\nDPI\src\lib\protocols\http.c dC:\ntop\dependencies\nDPI\src\lib\protocols\dns.cLC:\ntop\nprobe\nprobe-win-32\getopt.hc:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinSock2.he\nprobe-win-32\getopt.}.dwStartupOpt=; ActiveCfg= Debug|Win32;0A\Include\WinSoC1CFCE064C6}=Debug|Win32Ks\Windows\v7.0A\Include\WinSock2.hLC:\ntop\nprobe\nprobe-win-32\getopt.hprotocols\dns.cLC:\ntop\nprobe\nprobe-win-32\getopt.hc:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinSock2.hJC:\ntop\nprobe\nprobe-win-32\getopt.hL!Ouq걸JC:\ntop\nprobe\nprobe-win-32\getopt.cEmgA??_ ;LC:\ntop\nprobe\nprobe-win-32\getopt1.c^НR0nգ" bC:\ntop\dependencies\nDPI\src\lib\protocols\dns.cm7JWrJ,: ~C:\ntop\dependencies\nDPI\src\lib\third_party\src\ahocorasick.c{kB+cfBa2U`dC:\ntop\dependencies\nDPI\src\lib\protocols\http.cxHiu=>]SbC:\ntop\dependencies\nDPI\src\liOutliningStateEx12&.'OutliningStateEx10&&OutliningStateEx5$OutliningStateEx4$b\protocols\ssl.c{'P9CElC:\ntop\dependencies\nDPI\src\include\ndpi_protocols.h+XohC:\ntop\dependencies\nDPI\src\include\linux_compat.h O^X%'&A/m/jC:\ntop\dependencies\nDPI\src\lib\protocols\netflow.cp &SXѩlC:\ntop\dependencies\nDPI\src\lib\protocols\postgres.cS0UrKkc:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinSock2.OutliningStateEx3$OutliningStateEx15&OutliningStateEx11&OutliningStateEx17&mh;OA[c:\program files\microsoft visual studio 10.0\vc\include\string.hkhHPT39HC:\ntop\nprobe\nProbe\nprobe_win32.c@\-0.8nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/Win32/pcapExample/000077500000000000000000000000001262705051000241335ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/Win32/pcapExample/pcapExample.cpp000066400000000000000000000002441262705051000270760ustar00rootroot00000000000000// pcapExample.cpp : Defines the entry point for the console application. // #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { return 0; } nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/Win32/pcapExample/pcapExample.vcxproj000066400000000000000000000333771262705051000300240ustar00rootroot00000000000000 Debug Win32 Release Win32 {F6A2C0AE-2110-438A-87E4-7C1CFCE064C6} Win32Proj pcapExample Application true Unicode Application false true Unicode true false NotUsing Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) C:\ntop\nprobe\nprobe-win-32;C:\ntop\winpcap\Include;C:\ntop\dependencies\nDPI\src\lib\third_party\include;C:\ntop\dependencies\nDPI\src\include;%(AdditionalIncludeDirectories) Console true Wsock32.lib;Ws2_32.lib;C:\ntop\winpcap\Lib\Packet.lib;C:\ntop\winpcap\Lib\wpcap.lib;%(AdditionalDependencies) Level3 Use MaxSpeed true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true true true nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/Win32/pcapExample/pcapExample.vcxproj.filters000066400000000000000000000441001262705051000314550ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/Win32/pcapExample/pcapExample.vcxproj.user000066400000000000000000000002171262705051000307640ustar00rootroot00000000000000 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/ndpiReader.c000066400000000000000000002115221262705051000232160ustar00rootroot00000000000000/* * ndpiReader.c * * Copyright (C) 2011-15 - ntop.org * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2014 - Matteo Bogo (JSON support) * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #ifdef linux #define _GNU_SOURCE #include #endif #include #include #ifdef WIN32 #include /* winsock.h is included automatically */ #include #include #include #define getopt getopt____ #else #include #include #endif #include #include #include #include #include #include #include #include "../config.h" #include "ndpi_api.h" #ifdef HAVE_JSON_C #include #endif #define MAX_NUM_READER_THREADS 16 #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 #define GTP_U_V1_PORT 2152 #define TZSP_PORT 37008 #define MAX_NDPI_FLOWS 200000000 #ifndef ETH_P_IP #define ETH_P_IP 0x0800 /* IPv4 */ #endif #ifndef ETH_P_IPv6 #define ETH_P_IPV6 0x86dd /* IPv6 */ #endif #define SLARP 0x8035 /* Cisco Slarp */ #define CISCO_D_PROTO 0x2000 /* Cisco Discovery Protocol */ #define VLAN 0x8100 #define MPLS_UNI 0x8847 #define MPLS_MULTI 0x8848 #define PPPoE 0x8864 #define SNAP 0xaa /* mask for FCF */ #define WIFI_DATA 0x2 /* 0000 0010 */ #define FCF_TYPE(fc) (((fc) >> 2) & 0x3) /* 0000 0011 = 0x3 */ #define FCF_SUBTYPE(fc) (((fc) >> 4) & 0xF) /* 0000 1111 = 0xF */ #define FCF_TO_DS(fc) ((fc) & 0x0100) #define FCF_FROM_DS(fc) ((fc) & 0x0200) /* mask for Bad FCF presence */ #define BAD_FCS 0x50 /* 0101 0000 */ /** * @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 FILE *results_file = NULL; static char *results_path = NULL; 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; 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, quiet_mode = 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; 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]; /** * @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 // 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[48], upper_name[48]; u_int8_t ip_version; u_int64_t last_seen; u_int64_t bytes; u_int32_t packets; // result only, not used for flow identification ndpi_protocol detected_protocol; char host_server_name[256]; struct { char client_certificate[48], server_certificate[48]; } ssl; void *src_id, *dst_id; } ndpi_flow_t; static u_int32_t size_flow_struct = 0; static void help(u_int long_help) { printf("ndpiReader -i [-f ][-s ]\n" " [-p ][-l [-q][-d][-h][-t][-v ]\n" " [-n ] [-w ] [-j ]\n\n" "Usage:\n" " -i | Specify a pcap file/playlist to read packets from or a device for live capture (comma-separated list)\n" " -f | Specify a BPF filter for filtering selected traffic\n" " -s | Maximum capture duration in seconds (live traffic capture only)\n" " -p .protos | Specify a protocol file (eg. protos.txt)\n" " -l | Number of detection loops (test only)\n" " -n | Number of threads. Default: number of interfaces in -i. Ignored with pcap files.\n" " -j | Specify a file to write the content of packets in .json format\n" #ifdef linux " -g | Thread affinity mask (one core id per thread)\n" #endif " -d | Disable protocol guess and use only DPI\n" " -q | Quiet mode\n" " -t | Dissect GTP/TZSP tunnels\n" " -r | Print nDPI version and git revision\n" " -w | Write test output on the specified file. This is useful for\n" " | testing purposes in order to compare results across runs\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:rp:w:q")) != 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 'r': printf("ndpiReader - nDPI (%s)\n", ndpi_revision()); exit(0); 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; case 'w': results_path = strdup(optarg); if((results_file = fopen(results_path, "w")) == NULL) { printf("Unable to write in file %s: quitting\n", results_path); return; } break; case 'q': quiet_mode = 1; 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 IPPROTO_ICMPV6: return("ICMPV6"); 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 FILE *out = results_file ? results_file : stdout; if(!json_flag) { fprintf(out, "\t%u", ++num_flows); fprintf(out, "\t%s %s%s%s:%u <-> %s%s%s:%u ", ipProto2Name(flow->protocol), (flow->ip_version == 6) ? "[" : "", flow->lower_name, (flow->ip_version == 6) ? "]" : "", ntohs(flow->lower_port), (flow->ip_version == 6) ? "[" : "", flow->upper_name, (flow->ip_version == 6) ? "]" : "", ntohs(flow->upper_port)); if(flow->vlan_id > 0) fprintf(out, "[VLAN: %u]", flow->vlan_id); if(flow->detected_protocol.master_protocol) { char buf[64]; fprintf(out, "[proto: %u.%u/%s]", flow->detected_protocol.master_protocol, flow->detected_protocol.protocol, ndpi_protocol2name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol, buf, sizeof(buf))); } else fprintf(out, "[proto: %u/%s]", flow->detected_protocol.protocol, ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.protocol)); fprintf(out, "[%u pkts/%llu bytes]", flow->packets, (long long unsigned int)flow->bytes); if(flow->host_server_name[0] != '\0') fprintf(out, "[Host: %s]", flow->host_server_name); if(flow->ssl.client_certificate[0] != '\0') fprintf(out, "[SSL client: %s]", flow->ssl.client_certificate); if(flow->ssl.server_certificate[0] != '\0') fprintf(out, "[SSL server: %s]", flow->ssl.server_certificate); fprintf(out, "\n"); } 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))); if(flow->detected_protocol.master_protocol) json_object_object_add(jObj,"detected.masterprotocol",json_object_new_int(flow->detected_protocol.master_protocol)); json_object_object_add(jObj,"detected.protocol",json_object_new_int(flow->detected_protocol.protocol)); if(flow->detected_protocol.master_protocol) { char tmp[256]; snprintf(tmp, sizeof(tmp), "%s.%s", ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.master_protocol), ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.protocol)); json_object_object_add(jObj,"detected.protocol.name", json_object_new_string(tmp)); } else 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.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.protocol != NDPI_PROTOCOL_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.protocol == NDPI_PROTOCOL_UNKNOWN) return; if((which == ndpi_preorder) || (which == ndpi_leaf)) /* Avoid walking the same node multiple times */ printFlow(thread_id, flow); } /* ***************************************************** */ static u_int16_t 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.protocol != NDPI_PROTOCOL_UNKNOWN) ndpi_thread_info[thread_id].stats.guessed_flow_protocols++; return(flow->detected_protocol.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((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */ if(enable_protocol_guess) { if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) { node_guess_undetected_protocol(thread_id, flow); // printFlow(thread_id, flow); } } ndpi_thread_info[thread_id].stats.protocol_counter[flow->detected_protocol.protocol] += flow->packets; ndpi_thread_info[thread_id].stats.protocol_counter_bytes[flow->detected_protocol.protocol] += flow->bytes; ndpi_thread_info[thread_id].stats.protocol_flows[flow->detected_protocol.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.protocol == NDPI_PROTOCOL_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, const struct ndpi_ipv6hdr *iph6, u_int16_t ip_offset, u_int16_t ipsize, u_int16_t l4_packet_len, struct ndpi_tcphdr **tcph, struct ndpi_udphdr **udph, u_int16_t *sport, u_int16_t *dport, struct ndpi_id_struct **src, struct ndpi_id_struct **dst, u_int8_t *proto, u_int8_t **payload, u_int16_t *payload_len, u_int8_t *src_to_dst_direction) { u_int32_t idx, l4_offset; 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, *l4; /* 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_ipv6hdr); 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; l4 = ((u_int8_t *) l3 + l4_offset); if(iph->protocol == 6 && l4_packet_len >= 20) { u_int tcp_len; ndpi_thread_info[thread_id].stats.tcp_count++; // tcp *tcph = (struct ndpi_tcphdr *)l4; *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest); if(iph->saddr < iph->daddr) { lower_port = (*tcph)->source, upper_port = (*tcph)->dest; *src_to_dst_direction = 1; } else { lower_port = (*tcph)->dest; upper_port = (*tcph)->source; *src_to_dst_direction = 0; if(iph->saddr == iph->daddr) { if(lower_port > upper_port) { u_int16_t p = lower_port; lower_port = upper_port; upper_port = p; } } } tcp_len = ndpi_min(4*(*tcph)->doff, l4_packet_len); *payload = &l4[tcp_len]; *payload_len = ndpi_max(0, l4_packet_len-4*(*tcph)->doff); } else if(iph->protocol == 17 && l4_packet_len >= 8) { // udp ndpi_thread_info[thread_id].stats.udp_count++; *udph = (struct ndpi_udphdr *)l4; *sport = ntohs((*udph)->source), *dport = ntohs((*udph)->dest); *payload = &l4[sizeof(struct ndpi_udphdr)]; *payload_len = ndpi_max(0, l4_packet_len-sizeof(struct ndpi_udphdr)); if(iph->saddr < iph->daddr) { lower_port = (*udph)->source, upper_port = (*udph)->dest; *src_to_dst_direction = 1; } else { lower_port = (*udph)->dest, upper_port = (*udph)->source; *src_to_dst_direction = 0; if(iph->saddr == iph->daddr) { if(lower_port > upper_port) { u_int16_t p = lower_port; lower_port = upper_port; upper_port = p; } } } *sport = ntohs(lower_port), *dport = ntohs(upper_port); } 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; newflow->ip_version = version; 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__); free(newflow); 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__); free(newflow); 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__); free(newflow); 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_ipv6hdr *iph6, u_int16_t ip_offset, struct ndpi_tcphdr **tcph, struct ndpi_udphdr **udph, u_int16_t *sport, u_int16_t *dport, struct ndpi_id_struct **src, struct ndpi_id_struct **dst, u_int8_t *proto, u_int8_t **payload, u_int16_t *payload_len, u_int8_t *src_to_dst_direction) { 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_ipv6hdr); iph.protocol = options[0]; } return(get_ndpi_flow(thread_id, 6, vlan_id, &iph, iph6, ip_offset, sizeof(struct ndpi_ipv6hdr), ntohs(iph6->ip6_ctlun.ip6_un1.ip6_un1_plen), tcph, udph, sport, dport, src, dst, proto, payload, payload_len, src_to_dst_direction)); } /* ***************************************************** */ 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); } /* ndpi_thread_info[thread_id].ndpi_struct->http_dont_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 = sizeof(struct ndpi_id_struct); size_flow_struct = sizeof(struct ndpi_flow_struct); // clear memory for results memset(ndpi_thread_info[thread_id].stats.protocol_counter, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_counter)); memset(ndpi_thread_info[thread_id].stats.protocol_counter_bytes, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_counter_bytes)); memset(ndpi_thread_info[thread_id].stats.protocol_flows, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_flows)); if(_protoFilePath != NULL) ndpi_load_protocols_file(ndpi_thread_info[thread_id].ndpi_struct, _protoFilePath); } /* ***************************************************** */ static void terminateDetection(u_int16_t thread_id) { int i; for(i=0; ilen - ip_offset ; rawsize = header->len static unsigned int packet_processing(u_int16_t thread_id, const u_int64_t time, u_int16_t vlan_id, const struct ndpi_iphdr *iph, struct ndpi_ipv6hdr *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_int8_t proto; struct ndpi_tcphdr *tcph = NULL; struct ndpi_udphdr *udph = NULL; u_int16_t sport, dport, payload_len; u_int8_t *payload; u_int8_t src_to_dst_direction= 1; if(iph) flow = get_ndpi_flow(thread_id, 4, vlan_id, iph, NULL, ip_offset, ipsize, ntohs(iph->tot_len) - (iph->ihl * 4), &tcph, &udph, &sport, &dport, &src, &dst, &proto, &payload, &payload_len, &src_to_dst_direction); else flow = get_ndpi_flow6(thread_id, vlan_id, iph6, ip_offset, &tcph, &udph, &sport, &dport, &src, &dst, &proto, &payload, &payload_len, &src_to_dst_direction); 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); flow->detected_protocol = ndpi_detection_process_packet(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow, iph ? (uint8_t *)iph : (uint8_t *)iph6, ipsize, time, src, dst); if((flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN) || ((proto == IPPROTO_UDP) && (flow->packets > 8)) || ((proto == IPPROTO_TCP) && (flow->packets > 10))) { flow->detection_completed = 1; if((flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) && (ndpi_flow->num_stun_udp_pkts > 0)) ndpi_set_detected_protocol(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow, NDPI_PROTOCOL_STUN, NDPI_PROTOCOL_UNKNOWN); snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name); if((proto == IPPROTO_TCP) && (flow->detected_protocol.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); } free_ndpi_flow(flow); if(verbose > 1) { if(enable_protocol_guess) { if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) { flow->detected_protocol.protocol = node_guess_undetected_protocol(thread_id, flow), flow->detected_protocol.master_protocol = NDPI_PROTOCOL_UNKNOWN; } } printFlow(thread_id, flow); } } 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 = NULL; json_object *jObj_main, *jObj_trafficStats, *jArray_detProto, *jObj; #endif long long unsigned int breed_stats[NUM_BREEDS] = { 0 }; memset(&cumulative_stats, 0, sizeof(cumulative_stats)); for(thread_id = 0; thread_id < num_threads; thread_id++) { if(ndpi_thread_info[thread_id].stats.total_wire_bytes == 0) continue; for(i=0; i 1500: %-13lu\n", (unsigned long)cumulative_stats.packet_len[5]); if(tot_usec > 0) { char buf[32], buf1[32]; float t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)tot_usec; float b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)tot_usec; float traffic_duration; if (live_capture) traffic_duration = tot_usec; else traffic_duration = (pcap_end.tv_sec*1000000 + pcap_end.tv_usec) - (pcap_start.tv_sec*1000000 + pcap_start.tv_usec); printf("\tnDPI throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)traffic_duration; b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)traffic_duration; printf("\tTraffic throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); printf("\tTraffic duration: %.3f sec\n", traffic_duration/1000000); } if(enable_protocol_guess) printf("\tGuessed flow protos: %-13u\n", cumulative_stats.guessed_flow_protocols); } } if(json_flag) { #ifdef HAVE_JSON_C if((json_fp = fopen(_jsonFilePath,"w")) == NULL) { printf("Error createing .json file %s\n", _jsonFilePath); 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) && (!quiet_mode)) 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(results_file) fprintf(results_file, "%s\t%llu\t%llu\t%u\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]); if((!json_flag) && (!quiet_mode)) { 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 if(json_fp) { 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) && (!quiet_mode)) { 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) { FILE *out = results_file ? results_file : stdout; if(!json_flag) fprintf(out, "\n"); num_flows = 0; for(thread_id = 0; thread_id < num_threads; thread_id++) { for(i=0; i 0) { if(!json_flag) { FILE *out = results_file ? results_file : stdout; fprintf(out, "\n\nUndetected flows:%s\n", undetected_flows_deleted ? " (expired flows are not listed below)" : ""); } if(json_flag) json_flag = 2; break; } } num_flows = 0; for(thread_id = 0; thread_id < num_threads; thread_id++) { if(ndpi_thread_info[thread_id].stats.protocol_counter[0] > 0) { for(i=0; i 0) { if((!json_flag) && (!quiet_mode)) 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) { /* * Declare pointers to packet headers */ /* --- Ethernet header --- */ const struct ndpi_ethhdr *ethernet; /* --- Ethernet II header --- */ const struct ndpi_ethhdr *ethernet_2; /* --- LLC header --- */ const struct ndpi_llc_header *llc; /* --- Cisco HDLC header --- */ const struct ndpi_chdlc *chdlc; /* --- SLARP frame --- */ struct ndpi_slarp *slarp; /* --- CDP --- */ struct ndpi_cdp *cdp; /* --- Radio Tap header --- */ const struct ndpi_radiotap_header *radiotap; /* --- Wifi header --- */ const struct ndpi_wifi_header *wifi; /* --- MPLS header --- */ struct ndpi_mpls_header *mpls; /** --- IP header --- **/ struct ndpi_iphdr *iph; /** --- IPv6 header --- **/ struct ndpi_ipv6hdr *iph6; /* lengths and offsets */ u_int16_t eth_offset = 0; u_int16_t radio_len; u_int16_t fc; u_int16_t type; int wifi_len; int llc_off; int pyld_eth_len = 0; int check; u_int32_t fcs; u_int64_t time; u_int16_t ip_offset, ip_len, ip6_offset; u_int16_t frag_off = 0, vlan_id = 0; u_int8_t proto = 0; u_int32_t label; u_int16_t thread_id = *((u_int16_t*)args); /* counters */ u_int8_t malformed_pkts = 0, vlan_packet = 0; u_int8_t slarp_pkts = 0, cdp_pkts = 0; /* Increment raw packet counter */ 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; } /* Check if capture is live or not */ 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; } /* setting time */ time = ((uint64_t) header->ts.tv_sec) * detection_tick_resolution + header->ts.tv_usec / (1000000 / detection_tick_resolution); /* safety check */ if(ndpi_thread_info[thread_id].last_time > time) { /* 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; } /* update last time value */ ndpi_thread_info[thread_id].last_time = time; /*** check Data Link type ***/ int datalink_type = ndpi_thread_info[thread_id]._pcap_datalink_type; datalink_check: switch(datalink_type) { case DLT_NULL : if(ntohl(*((u_int32_t*)&packet[eth_offset])) == 2) type = ETH_P_IP; else type = ETH_P_IPV6; ip_offset = 4 + eth_offset; /* Cisco PPP in HDLC-like framing - 50 */ case DLT_PPP_SERIAL: chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ type = ntohs(chdlc->proto_code); break; /* Cisco PPP with HDLC framing - 104 */ case DLT_C_HDLC: chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ type = ntohs(chdlc->proto_code); break; /* IEEE 802.3 Ethernet - 1 */ case DLT_EN10MB : ethernet = (struct ndpi_ethhdr *) &packet[eth_offset]; ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset; check = ntohs(ethernet->h_proto); if(check <= 1500) pyld_eth_len = check; else if (check >= 1536) type = check; if(pyld_eth_len != 0) { /* check for LLC layer with SNAP extension */ if(packet[ip_offset] == SNAP) { llc = (struct ndpi_llc_header *)(&packet[ip_offset]); type = llc->snap.proto_ID; ip_offset += + 8; } } break; /* Linux Cooked Capture - 113 */ case DLT_LINUX_SLL : type = (packet[eth_offset+14] << 8) + packet[eth_offset+15]; ip_offset = 16 + eth_offset; break; /* Radiotap link-layer - 127 */ case DLT_IEEE802_11_RADIO : radiotap = (struct ndpi_radiotap_header *) &packet[eth_offset]; radio_len = radiotap->len; /* Check Bad FCS presence */ if((radiotap->flags & BAD_FCS) == BAD_FCS) { malformed_pkts += 1; ndpi_thread_info[thread_id].stats.total_discarded_bytes += header->len; return; } fcs = header->len - 4; /* Calculate 802.11 header length (variable) */ wifi = (struct ndpi_wifi_header*)( packet + eth_offset + radio_len); fc = wifi->fc; /* check wifi data presence */ if(FCF_TYPE(fc) == WIFI_DATA) { if((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) || (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc))) wifi_len = 26; /* + 4 byte fcs */ } else /* no data frames */ break; /* Check ether_type from LLC */ llc = (struct ndpi_llc_header*)(packet + eth_offset + wifi_len + radio_len); if(llc->dsap == SNAP) type = ntohs(llc->snap.proto_ID); /* Set IP header offset */ ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header) + eth_offset; break; default: return; } /* check ether type */ if(type == 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 == MPLS_UNI || type == MPLS_MULTI) { mpls = (struct ndpi_mpls_header *) &packet[ip_offset]; label = ntohl(mpls->label); /* label = ntohl(*((u_int32_t*)&packet[ip_offset])); */ ndpi_thread_info[thread_id].stats.mpls_count++; type = ETH_P_IP, ip_offset += 4; while((label & 0x100) != 0x100) { ip_offset += 4; label = ntohl(mpls->label); } } else if(type == SLARP) { slarp = (struct ndpi_slarp *) &packet[ip_offset]; if(slarp->slarp_type == 0x02 || slarp->slarp_type == 0x00 || slarp->slarp_type == 0x01) { /* TODO if info are needed */ } slarp_pkts++; } else if(type == CISCO_D_PROTO) { cdp = (struct ndpi_cdp *) &packet[ip_offset]; cdp_pkts++; } else if(type == PPPoE) { ndpi_thread_info[thread_id].stats.pppoe_count++; type = ETH_P_IP; ip_offset += 8; } ndpi_thread_info[thread_id].stats.vlan_count += vlan_packet; iph_check: /* Check and set IP header size and total packet length */ 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) && (!quiet_mode)) 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(iph->protocol == 41) { ip_offset += ip_len; goto iph_check; } 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) && (!quiet_mode)) 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_ipv6hdr *)&packet[ip_offset]; proto = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; ip_len = sizeof(struct ndpi_ipv6hdr); 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) && (!quiet_mode)) 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; } } } else if((sport == TZSP_PORT) || (dport == TZSP_PORT)) { /* https://en.wikipedia.org/wiki/TZSP */ u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr); u_int8_t version = packet[offset]; u_int8_t type = packet[offset+1]; u_int16_t encapsulates = ntohs(*((u_int16_t*)&packet[offset+2])); if((version == 1) && (type == 0) && (encapsulates == 1)) { u_int8_t stop = 0; offset += 4; while((!stop) && (offset < header->caplen)) { u_int8_t tag_type = packet[offset]; u_int8_t tag_len; switch(tag_type) { case 0: /* PADDING Tag */ tag_len = 1; break; case 1: /* END Tag */ tag_len = 1, stop = 1; break; default: tag_len = packet[offset+1]; break; } offset += tag_len; if(offset >= header->caplen) return; /* Invalid packet */ else { eth_offset = offset; goto datalink_check; } } } } } /* 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; #if defined(linux) && defined(HAVE_PTHREAD_SETAFFINITY_NP) 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) && (!quiet_mode)) printf("Running thread %ld on core %d...\n", thread_id, core_affinity[thread_id]); } } else #endif if((!json_flag) && (!quiet_mode)) 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) && (!quiet_mode)) { printf("\n-----------------------------------------------------------\n" "* NOTE: This is demo app to show *some* nDPI features.\n" "* In this demo we have implemented only some basic features\n" "* just to show you what you can do with the library. Feel \n" "* free to extend it and send us the patches for inclusion\n" "------------------------------------------------------------\n\n"); printf("Using nDPI (%s) [%d thread(s)]\n", ndpi_revision(), num_threads); } signal(SIGINT, sigproc); for(i=0; itv_sec = (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 */ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/example/protos.txt000066400000000000000000000007351262705051000230660ustar00rootroot00000000000000# Format: # :,:,.....@ tcp:81,tcp:8181@HTTP udp:5061-5062@SIP tcp:860,udp:860,tcp:3260,udp:3260@iSCSI tcp:3000@ntop # Subprotocols # Format: # host:"",host:"",.....@ host:"googlesyndacation.com"@Google host:"venere.com"@Venere host:"kataweb.it",host:"repubblica.it"@Repubblica host:"ntop"@ntop # IP based Subprotocols # Format: # ip:,ip:,.....@ ip:213.75.170.11@CustomProtocol nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/lib000077700000000000000000000000001262705051000223122src/lib/.libsustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/libndpi.pc.in000066400000000000000000000003431262705051000217110ustar00rootroot00000000000000prefix=@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@ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/libndpi.sym000066400000000000000000000015071262705051000215150ustar00rootroot00000000000000ndpi_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_l4_detection_process_packet 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 ndpi_get_proto_by_id ndpi_get_protocol_id_master_proto ndpi_guess_protocol_id ndpi_protocol2name ndpi_get_lower_proto ndpi_is_proto ndpi_malloc ndpi_calloc ndpi_set_detected_protocol nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/m4/000077500000000000000000000000001262705051000176575ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/m4/ax_pthread.m4000066400000000000000000000326761262705051000222560ustar00rootroot00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also link it with them as well. e.g. you should link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threads programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name # (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 21 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) if test x"$ax_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case ${host_os} in solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" ;; darwin*) ax_pthread_flags="-pthread $ax_pthread_flags" ;; esac # Clang doesn't consider unrecognized options an error unless we specify # -Werror. We throw in some extra Clang-specific options to ensure that # this doesn't happen for GCC, which also accepts -Werror. AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags]) save_CFLAGS="$CFLAGS" ax_pthread_extra_flags="-Werror" CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])], [AC_MSG_RESULT([yes])], [ax_pthread_extra_flags= AC_MSG_RESULT([no])]) CFLAGS="$save_CFLAGS" if test x"$ax_pthread_ok" = xno; then for flag in $ax_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) if test x"$ax_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT([$ax_pthread_ok]) if test "x$ax_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $attr; return attr /* ; */])], [attr_name=$attr; break], []) done AC_MSG_RESULT([$attr_name]) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name], [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case ${host_os} in aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; osf* | hpux*) flag="-D_REENTRANT";; solaris*) if test "$GCC" = "yes"; then flag="-D_REENTRANT" else # TODO: What about Clang on Solaris? flag="-mt -D_REENTRANT" fi ;; esac AC_MSG_RESULT([$flag]) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])]) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: compile with *_r variant if test "x$GCC" != xyes; then case $host_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$ax_pthread_ok" = xyes; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/000077500000000000000000000000001262705051000211155ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/homebrew/000077500000000000000000000000001262705051000227255ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/homebrew/README000066400000000000000000000002631262705051000236060ustar00rootroot00000000000000=== 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 ndpinDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/homebrew/ndpi.rb000066400000000000000000000017101262705051000242030ustar00rootroot00000000000000class Ndpi < Formula desc "Deep Packet Inspection (DPI) library" homepage "http://www.ntop.org/products/ndpi/" url "https://downloads.sourceforge.net/project/ntop/nDPI/nDPI-1.7.tar.gz" sha256 "714b745103a072462130b0e14cf31b2eb5270f580b7c839da5cf5ea75150262d" bottle do cellar :any sha256 "e9464d314479ba3e7a91422e0bc606cfd5f6e72e94d6441cc4fa30e9c925da5c" => :yosemite sha256 "1d6b1d860669b42766baa276ed948c342e2fa4fd28663ba64a90fd0e200ba9c4" => :mavericks sha256 "b814918b4fb9588de7126061ce4ac3eb41a5c3eee27c7432b669f6dc6921bfde" => :mountain_lion end depends_on "autoconf" => :build depends_on "automake" => :build depends_on "pkg-config" => :build depends_on "libtool" => :build depends_on "json-c" def install system "./autogen.sh" system "./configure", "--prefix=#{prefix}" system "make" system "make", "install" end test do system "#{bin}/ndpiReader", "-i", test_fixtures("test.pcap") end end nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/000077500000000000000000000000001262705051000224375ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/Makefile000066400000000000000000000025711262705051000241040ustar00rootroot00000000000000# # 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/Makefile.in000066400000000000000000000025711262705051000245110ustar00rootroot00000000000000# # 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/configure000077500000000000000000002443451262705051000243620ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Makefile.in 1.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Makefile.in' PACKAGE_TARNAME='makefile-in' PACKAGE_VERSION='1.0' PACKAGE_STRING='Makefile.in 1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_subst_vars='LTLIBOBJS LIBOBJS PFRING_SVN_RELEASE SVN_RELEASE KERNEL DATE EXTN MACHINE PFRING_VERS NDPI_VERS target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking ' ac_precious_vars='build_alias host_alias target_alias' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures Makefile.in 1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/makefile-in] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of Makefile.in 1.0:";; esac cat <<\_ACEOF Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF Makefile.in configure 1.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by Makefile.in $as_me 1.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu NDPI_VERS=`cat ../../config.h | grep -w VERSION | cut -d \" -f 2` PFRING_VERS=`cat $HOME/PF_RING/kernel/linux/pf_ring.h | grep RING_VERSION | head -1 | cut -d '"' -f 2` SVN_RELEASE=`svn info ../.. | grep "^Revision"|cut -d " " -f 2` PFRING_SVN_RELEASE=`svn info $HOME/PF_RING | grep "^Revision"|cut -d " " -f 2` MACHINE=`uname -m` if test $MACHINE = "x86_64"; then EXTN="amd64" else EXTN="i386" fi DATE=`date -R` KERNEL=`uname -r` ac_config_files="$ac_config_files Makefile" ac_config_files="$ac_config_files debian/changelog" ac_config_files="$ac_config_files debian/files" ac_config_files="$ac_config_files debian/control" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Makefile.in $as_me 1.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ Makefile.in config.status 1.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "debian/changelog") CONFIG_FILES="$CONFIG_FILES debian/changelog" ;; "debian/files") CONFIG_FILES="$CONFIG_FILES debian/files" ;; "debian/control") CONFIG_FILES="$CONFIG_FILES debian/control" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/configure.in000066400000000000000000000013711262705051000247520ustar00rootroot00000000000000AC_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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/000077500000000000000000000000001262705051000236615ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/COPYRIGHT000066400000000000000000000431101262705051000251530ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/README000066400000000000000000000001641262705051000245420ustar00rootroot00000000000000This directory contains the files needed to build the package named 'nprobe' for the Debian GNU/Linux distribution. nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/changelog.in000066400000000000000000000001701262705051000261360ustar00rootroot00000000000000ndpi (@NDPI_VERS@-@SVN_RELEASE@) stable; urgency=high * Last packaged version -- Luca Deri @DATE@ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/compat000066400000000000000000000000021262705051000250570ustar00rootroot000000000000001 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/conffiles000066400000000000000000000000001262705051000255420ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/control.in000066400000000000000000000011211262705051000256640ustar00rootroot00000000000000Source: ndpi Section: free Priority: optional Maintainer: Luca Deri Standards-Version: @NDPI_VERSION@ Build-Depends: Build-Conflicts: Package: ndpi Architecture: @EXTN@ Depends: pfring (=@PFRING_VERS@-@PFRING_SVN_RELEASE@), libnuma Recommends: Suggests: Pre-Depends: Conflicts: Provides: Replaces: Description: A network probe. Package: ndpi-dev Section: libdevel Architecture: all Depends: ndpi (= ${binary:Version}), ${misc:Depends} Conflicts: Description: development library and header files for ndpi Headers, static libraries, and documentation for the ndpi library nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/dirs000066400000000000000000000000171262705051000245430ustar00rootroot00000000000000usr/local/ndpi nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/docs000066400000000000000000000000071262705051000245310ustar00rootroot00000000000000README nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/files.in000066400000000000000000000000521262705051000253100ustar00rootroot00000000000000ndpi_@NDPI_VERS@_@EXTN@.deb free optional nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/postinst000077500000000000000000000011051262705051000254670ustar00rootroot00000000000000#!/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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/postrm000066400000000000000000000002731262705051000251320ustar00rootroot00000000000000#!/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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/preinst000066400000000000000000000012301262705051000252640ustar00rootroot00000000000000#! /bin/sh # preinst script for nbox # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `install' # * `install' # * `upgrade' # * `abort-upgrade' case "$1" in install|upgrade) if test -f /usr/local/sbin/nprobe; then rm /usr/local/sbin/nprobe fi ;; abort-upgrade) ;; *) echo "preinst called with unknown argument \`$1'" >&2 exit 0 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. exit 0 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/prerm000077500000000000000000000004721262705051000247370ustar00rootroot00000000000000#!/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 0nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/packages/ubuntu/debian/rules000077500000000000000000000022361262705051000247440ustar00rootroot00000000000000#!/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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/000077500000000000000000000000001262705051000201265ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/include/000077500000000000000000000000001262705051000215515ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/include/Makefile.am000066400000000000000000000003431262705051000236050ustar00rootroot00000000000000library_includedir=$(includedir)/libndpi-1.4/libndpi library_include_HEADERS = ndpi_api.h \ ndpi_define.h \ ndpi_typedefs.h \ ndpi_main.h \ ndpi_protocol_ids.h \ ndpi_protocols.h \ ndpi_win32.h \ ndpi_includes.h nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/include/ndpi_api.h000066400000000000000000000254241262705051000235140ustar00rootroot00000000000000/* * ndpi_api.h * * Copyright (C) 2011-15 - ntop.org * Copyright (C) 2009-2011 by ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #ifndef __NDPI_API_H__ #define __NDPI_API_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 host host name * @param port port number */ 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 */ ndpi_protocol 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); u_int16_t ndpi_get_flow_masterprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); #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 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); ndpi_protocol 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); ndpi_protocol 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_host_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, char *string_to_match, u_int string_to_match_len, u_int16_t master_protocol_id); 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, u_int16_t master_protocol_id); int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_struct, ndpi_automa *automa, char *bigram_to_match); char* ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol proto, char *buf, u_int buf_len); 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 /* __NDPI_API_H__ */ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/include/ndpi_define.h000066400000000000000000000342721262705051000241760ustar00rootroot00000000000000/* * * Copyright (C) 2011-15 - ntop.org * Copyright (C) 2009-2011 by ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #ifndef __NDPI_DEFINE_INCLUDE_FILE__ #define __NDPI_DEFINE_INCLUDE_FILE__ /* gcc -E -dM - < /dev/null |grep ENDIAN */ #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include #endif #ifdef __OpenBSD__ #include #define __BYTE_ORDER BYTE_ORDER #if BYTE_ORDER == LITTLE_ENDIAN #define __LITTLE_ENDIAN__ #else #define __BIG_ENDIAN__ #endif/* BYTE_ORDER */ #endif/* __OPENBSD__ */ #if __BYTE_ORDER == __LITTLE_ENDIAN #ifndef __LITTLE_ENDIAN__ #define __LITTLE_ENDIAN__ #endif #else #ifndef __BIG_ENDIAN__ #define __BIG_ENDIAN__ #endif #endif #ifdef WIN32 #ifndef __LITTLE_ENDIAN__ #define __LITTLE_ENDIAN__ 1 #endif #endif #if !(defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__)) #if defined(__mips__) #undef __LITTLE_ENDIAN__ #undef __LITTLE_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 #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 */ #ifdef 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])) ) #define NDPI_NUM_BITS 256 #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 */ # 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 #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) #if defined(WIN32) && !defined(snprintf) #define snprintf _snprintf #endif #endif /* __NDPI_DEFINE_INCLUDE_FILE__ */ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/include/ndpi_includes.h000066400000000000000000000033051262705051000245430ustar00rootroot00000000000000/* * ndpi_includes.h * * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #ifndef __NDPI_INCLUDES_H__ #define __NDPI_INCLUDES_H__ #include #include #include #include #include #include #include #ifdef WIN32 #include "ndpi_win32.h" #else #include #include #include #include #include #include #include #include #include #if !defined __APPLE__ && !defined __FreeBSD__ && !defined __NetBSD__ && !defined __OpenBSD__ #include #include #if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ #include #if defined __NetBSD__ || defined __OpenBSD__ #include #ifdef __OpenBSD__ #include #endif #endif #endif #endif #endif /* Win32 */ #endif /* __NDPI_INCLUDES_H__ */ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/include/ndpi_main.h000066400000000000000000000127111262705051000236620ustar00rootroot00000000000000/* * ndpi_main.h * * Copyright (C) 2011-15 - ntop.org * Copyright (C) 2009-2011 by ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #ifndef __NDPI_MAIN_H__ #define __NDPI_MAIN_H__ #include "ndpi_includes.h" #include "ndpi_define.h" #include "ndpi_protocol_ids.h" #include "ndpi_typedefs.h" #include "ndpi_protocols.h" #include "ndpi_api.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_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol); 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 upper_detected_protocol, u_int16_t lower_detected_protocol); extern void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol); 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 u_int8_t ndpi_is_proto(ndpi_protocol p, u_int16_t proto); extern u_int16_t ndpi_get_lower_proto(ndpi_protocol p); 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); #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 #endif /* __NDPI_MAIN_H__ */ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/include/ndpi_protocol_ids.h000066400000000000000000000304471262705051000254440ustar00rootroot00000000000000/* * ndpi_protocol_ids.h * * Copyright (C) 2011-15 - ntop.org * Copyright (C) 2009-11 - ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #ifndef __NDPI_API_H__ #endif #ifndef __NDPI_PROTOCOLS_DEFAULT_H__ #define __NDPI_PROTOCOLS_DEFAULT_H__ #define NDPI_DETECTION_SUPPORT_IPV6 #define NDPI_PROTOCOL_HISTORY_SIZE 2 #define NDPI_PROTOCOL_UNKNOWN 0 #define NDPI_PROTOCOL_NO_MASTER_PROTO NDPI_PROTOCOL_UNKNOWN #define NDPI_PROTOCOL_IP_VRRP 73 #define NDPI_PROTOCOL_IP_IPSEC 79 #define NDPI_PROTOCOL_IP_GRE 80 #define NDPI_PROTOCOL_IP_ICMP 81 #define NDPI_PROTOCOL_IP_IGMP 82 #define NDPI_PROTOCOL_IP_EGP 83 #define NDPI_PROTOCOL_IP_SCTP 84 #define NDPI_PROTOCOL_IP_OSPF 85 #define NDPI_PROTOCOL_IP_IP_IN_IP 86 #define NDPI_PROTOCOL_IP_ICMPV6 102 #define NDPI_PROTOCOL_HTTP 7 #define NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV 60 #define NDPI_PROTOCOL_SSL_NO_CERT 64 /* SSL without certificate (Skype, Ultrasurf?) - ntop.org */ #define NDPI_PROTOCOL_SSL 91 #define NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC 110 #define NDPI_PROTOCOL_HTTP_CONNECT 130 #define NDPI_PROTOCOL_HTTP_PROXY 131 #define NDPI_PROTOCOL_SOCKS5 172 /* Tomasz Bujlow */ #define NDPI_PROTOCOL_SOCKS4 173 /* Tomasz Bujlow */ #define NDPI_PROTOCOL_FTP_CONTROL 1 /* Tomasz Bujlow */ #define NDPI_PROTOCOL_MAIL_POP 2 #define NDPI_PROTOCOL_MAIL_SMTP 3 #define NDPI_PROTOCOL_MAIL_IMAP 4 #define NDPI_PROTOCOL_DNS 5 #define NDPI_PROTOCOL_IPP 6 #define NDPI_PROTOCOL_MDNS 8 #define NDPI_PROTOCOL_NTP 9 #define NDPI_PROTOCOL_NETBIOS 10 #define NDPI_PROTOCOL_NFS 11 #define NDPI_PROTOCOL_SSDP 12 #define NDPI_PROTOCOL_BGP 13 #define NDPI_PROTOCOL_SNMP 14 #define NDPI_PROTOCOL_XDMCP 15 #define NDPI_PROTOCOL_SMB 16 #define NDPI_PROTOCOL_SYSLOG 17 #define NDPI_PROTOCOL_DHCP 18 #define NDPI_PROTOCOL_POSTGRES 19 #define NDPI_PROTOCOL_MYSQL 20 #define NDPI_PROTOCOL_TDS 21 #define NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK 22 #define NDPI_PROTOCOL_MAIL_POPS 23 #define NDPI_PROTOCOL_APPLEJUICE 24 #define NDPI_PROTOCOL_DIRECTCONNECT 25 #define NDPI_PROTOCOL_SOCRATES 26 #define NDPI_PROTOCOL_WINMX 27 #define NDPI_PROTOCOL_VMWARE 28 #define NDPI_PROTOCOL_MAIL_SMTPS 29 #define NDPI_PROTOCOL_FILETOPIA 30 #define NDPI_PROTOCOL_IMESH 31 #define NDPI_PROTOCOL_KONTIKI 32 #define NDPI_PROTOCOL_OPENFT 33 #define NDPI_PROTOCOL_FASTTRACK 34 #define NDPI_PROTOCOL_GNUTELLA 35 #define NDPI_PROTOCOL_EDONKEY 36 /* Tomasz Bujlow */ #define NDPI_PROTOCOL_BITTORRENT 37 #define NDPI_PROTOCOL_EPP 38 #define NDPI_PROTOCOL_XBOX 47 #define NDPI_PROTOCOL_QQ 48 #define NDPI_PROTOCOL_MOVE 49 #define NDPI_PROTOCOL_RTSP 50 #define NDPI_PROTOCOL_MAIL_IMAPS 51 #define NDPI_PROTOCOL_ICECAST 52 #define NDPI_PROTOCOL_PPLIVE 53 /* Tomasz Bujlow */ #define NDPI_PROTOCOL_PPSTREAM 54 #define NDPI_PROTOCOL_ZATTOO 55 #define NDPI_PROTOCOL_SHOUTCAST 56 #define NDPI_PROTOCOL_SOPCAST 57 #define NDPI_PROTOCOL_TVANTS 58 #define NDPI_PROTOCOL_TVUPLAYER 59 #define NDPI_PROTOCOL_QQLIVE 61 #define NDPI_PROTOCOL_THUNDER 62 #define NDPI_PROTOCOL_SOULSEEK 63 #define NDPI_PROTOCOL_IRC 65 #define NDPI_PROTOCOL_AYIYA 66 #define NDPI_PROTOCOL_UNENCRYPED_JABBER 67 #define NDPI_PROTOCOL_MSN 68 #define NDPI_PROTOCOL_OSCAR 69 #define NDPI_PROTOCOL_YAHOO 70 #define NDPI_PROTOCOL_BATTLEFIELD 71 #define NDPI_PROTOCOL_QUAKE 72 #define NDPI_PROTOCOL_STEAM 74 /* Tomasz Bujlow */ #define NDPI_PROTOCOL_HALFLIFE2 75 #define NDPI_PROTOCOL_WORLDOFWARCRAFT 76 #define NDPI_PROTOCOL_TELNET 77 #define NDPI_PROTOCOL_STUN 78 #define NDPI_PROTOCOL_RTP 87 #define NDPI_PROTOCOL_RDP 88 #define NDPI_PROTOCOL_VNC 89 #define NDPI_PROTOCOL_PCANYWHERE 90 #define NDPI_PROTOCOL_SSH 92 #define NDPI_PROTOCOL_USENET 93 #define NDPI_PROTOCOL_MGCP 94 #define NDPI_PROTOCOL_IAX 95 #define NDPI_PROTOCOL_TFTP 96 #define NDPI_PROTOCOL_AFP 97 #define NDPI_PROTOCOL_STEALTHNET 98 #define NDPI_PROTOCOL_AIMINI 99 #define NDPI_PROTOCOL_SIP 100 #define NDPI_PROTOCOL_TRUPHONE 101 #define NDPI_PROTOCOL_DHCPV6 103 #define NDPI_PROTOCOL_ARMAGETRON 104 #define NDPI_PROTOCOL_CROSSFIRE 105 #define NDPI_PROTOCOL_DOFUS 106 #define NDPI_PROTOCOL_FIESTA 107 #define NDPI_PROTOCOL_FLORENSIA 108 #define NDPI_PROTOCOL_GUILDWARS 109 #define NDPI_PROTOCOL_KERBEROS 111 #define NDPI_PROTOCOL_LDAP 112 #define NDPI_PROTOCOL_MAPLESTORY 113 #define NDPI_PROTOCOL_MSSQL 114 #define NDPI_PROTOCOL_PPTP 115 #define NDPI_PROTOCOL_WARCRAFT3 116 #define NDPI_PROTOCOL_WORLD_OF_KUNG_FU 117 #define NDPI_PROTOCOL_MEEBO 118 #define NDPI_PROTOCOL_DROPBOX 121 #define NDPI_PROTOCOL_SKYPE 125 #define NDPI_PROTOCOL_DCERPC 127 #define NDPI_PROTOCOL_NETFLOW 128 #define NDPI_PROTOCOL_SFLOW 129 #define NDPI_PROTOCOL_CITRIX 132 #define NDPI_PROTOCOL_SKYFILE_PREPAID 136 #define NDPI_PROTOCOL_SKYFILE_RUDICS 137 #define NDPI_PROTOCOL_SKYFILE_POSTPAID 138 #define NDPI_PROTOCOL_CITRIX_ONLINE 139 #define NDPI_PROTOCOL_WEBEX 141 #define NDPI_PROTOCOL_VIBER 144 #define NDPI_PROTOCOL_RADIUS 146 #define NDPI_SERVICE_WINDOWS_UPDATE 147 #define NDPI_PROTOCOL_TEAMVIEWER 148 /* xplico.org */ #define NDPI_PROTOCOL_LOTUS_NOTES 150 #define NDPI_PROTOCOL_SAP 151 #define NDPI_PROTOCOL_GTP 152 #define NDPI_PROTOCOL_UPNP 153 #define NDPI_PROTOCOL_LLMNR 154 #define NDPI_PROTOCOL_REMOTE_SCAN 155 #define NDPI_PROTOCOL_SPOTIFY 156 #define NDPI_PROTOCOL_H323 158 /* Remy Mudingay */ #define NDPI_PROTOCOL_OPENVPN 159 /* Remy Mudingay */ #define NDPI_PROTOCOL_NOE 160 /* Remy Mudingay */ #define NDPI_PROTOCOL_CISCOVPN 161 /* Remy Mudingay */ #define NDPI_PROTOCOL_TEAMSPEAK 162 /* Remy Mudingay */ #define NDPI_PROTOCOL_TOR 163 /* Remy Mudingay */ #define NDPI_PROTOCOL_SKINNY 164 /* Remy Mudingay */ #define NDPI_PROTOCOL_RTCP 165 /* Remy Mudingay */ #define NDPI_PROTOCOL_RSYNC 166 /* Remy Mudingay */ #define NDPI_PROTOCOL_ORACLE 167 /* Remy Mudingay */ #define NDPI_PROTOCOL_CORBA 168 /* Remy Mudingay */ #define NDPI_PROTOCOL_UBUNTUONE 169 /* Remy Mudingay */ #define NDPI_PROTOCOL_WHOIS_DAS 170 #define NDPI_PROTOCOL_COLLECTD 171 #define NDPI_PROTOCOL_RTMP 174 /* Tomasz Bujlow */ #define NDPI_PROTOCOL_FTP_DATA 175 /* Tomasz Bujlow */ #define NDPI_PROTOCOL_ZMQ 177 #define NDPI_PROTOCOL_MEGACO 181 /* Gianluca Costa */ #define NDPI_PROTOCOL_REDIS 182 #define NDPI_PROTOCOL_PANDO 183 /* Tomasz Bujlow */ #define NDPI_PROTOCOL_VHUA 184 #define NDPI_PROTOCOL_TELEGRAM 185 /* Gianluca Costa */ #define NDPI_PROTOCOL_QUIC 188 /* Andrea Buscarinu - Michele Campus */ #define NDPI_PROTOCOL_WHATSAPP_VOICE 189 #define NDPI_PROTOCOL_STARCRAFT 213 /* Matteo Bracci */ #define NDPI_PROTOCOL_TEREDO 214 #define NDPI_PROTOCOL_HEP 216 /* Sipcapture.org QXIP BV */ #define NDPI_PROTOCOL_UBNTAC2 217 /* Ubiquity UBNT AirControl 2 - Thomas Fjellstrom */ #define NDPI_PROTOCOL_MS_LYNC 218 #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 186 #define NDPI_SERVICE_GOOGLE 126 #define NDPI_SERVICE_NETFLIX 133 #define NDPI_SERVICE_LASTFM 134 #define NDPI_SERVICE_WAZE 135 #define NDPI_SERVICE_APPLE 140 #define NDPI_SERVICE_WHATSAPP 142 #define NDPI_SERVICE_APPLE_ICLOUD 143 #define NDPI_SERVICE_APPLE_ITUNES 145 #define NDPI_SERVICE_TUENTI 149 #define NDPI_SERVICE_WIKIPEDIA 176 /* Tomasz Bujlow */ #define NDPI_SERVICE_MSN NDPI_PROTOCOL_MSN /* Tomasz Bujlow */ #define NDPI_SERVICE_AMAZON 178 /* Tomasz Bujlow */ #define NDPI_SERVICE_EBAY 179 /* Tomasz Bujlow */ #define NDPI_SERVICE_CNN 180 /* Tomasz Bujlow */ #define NDPI_SERVICE_DROPBOX NDPI_PROTOCOL_DROPBOX /* Tomasz Bujlow */ #define NDPI_SERVICE_SKYPE NDPI_PROTOCOL_SKYPE /* Tomasz Bujlow */ #define NDPI_SERVICE_VIBER NDPI_PROTOCOL_VIBER /* Tomasz Bujlow */ #define NDPI_SERVICE_YAHOO NDPI_PROTOCOL_YAHOO /* Tomasz Bujlow */ #define NDPI_SERVICE_PANDORA 187 #define NDPI_PROTOCOL_EAQ 190 #define NDPI_SERVICE_TIMMEU 191 #define NDPI_SERVICE_TORCEDOR 192 #define NDPI_SERVICE_KAKAOTALK 193 /* KakaoTalk Chat (no voice call) */ #define NDPI_SERVICE_KAKAOTALK_VOICE 194 /* KakaoTalk Voice */ #define NDPI_SERVICE_TWITCH 195 /* Edoardo Dominici */ #define NDPI_SERVICE_QUICKPLAY 196 /* Streaming service used by various services such as hooq.tv */ #define NDPI_SERVICE_TIM 197 /* Traffic for tim.com.br and tim.it */ #define NDPI_PROTOCOL_MPEGTS 198 #define NDPI_SERVICE_SNAPCHAT 199 #define NDPI_SERVICE_SIMET 200 #define NDPI_SERVICE_OPENSIGNAL 201 #define NDPI_SERVICE_99TAXI 202 #define NDPI_SERVICE_EASYTAXI 203 #define NDPI_SERVICE_GLOBOTV 204 #define NDPI_SERVICE_TIMSOMDECHAMADA 205 #define NDPI_SERVICE_TIMMENU 206 #define NDPI_SERVICE_TIMPORTASABERTAS 207 #define NDPI_SERVICE_TIMRECARGA 208 #define NDPI_SERVICE_TIMBETA 209 #define NDPI_SERVICE_DEEZER 210 #define NDPI_SERVICE_INSTAGRAM 211 /* Andrea Buscarinu */ #define NDPI_SERVICE_MICROSOFT 212 #define NDPI_SERVICE_HOTSPOT_SHIELD 215 /* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE */ #define NDPI_LAST_IMPLEMENTED_PROTOCOL NDPI_PROTOCOL_MS_LYNC #define NDPI_MAX_SUPPORTED_PROTOCOLS (NDPI_LAST_IMPLEMENTED_PROTOCOL + 1) #define NDPI_MAX_NUM_CUSTOM_PROTOCOLS (NDPI_NUM_BITS-NDPI_LAST_IMPLEMENTED_PROTOCOL) #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/include/ndpi_protocols.h000066400000000000000000001056551262705051000247740ustar00rootroot00000000000000/* * ndpi_protocols.h * * Copyright (C) 2011-15 - ntop.org * Copyright (C) 2009-2011 by ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #ifndef __NDPI_PROTOCOLS_H__ #define __NDPI_PROTOCOLS_H__ #include "ndpi_main.h" 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); 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); /* 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_hep(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_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); void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_eaq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_kakaotalk_voice(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_mpegts(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_starcraft(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_ubntac2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); /* --- INIT FUNCTIONS --- */ void init_afp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_aimini_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_applejuice_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_armagetron_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ayiya_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_battlefield_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_bgp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_bittorrent_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_teredo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ciscovpn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_citrix_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_corba_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_crossfire_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_dcerpc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_dhcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_dhcpv6_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_directconnect_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_dns_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_dofus_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_directdownloadlink_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_dropbox_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_eaq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_edonkey_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_fasttrack_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_fiesta_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_filetopia_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_florensia_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ftp_control_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ftp_data_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_gnutella_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_gtp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_guildwars_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_h323_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_halflife2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_http_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_http_activesync_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_iax_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_icecast_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_imesh_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ipp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_irc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_jabber_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_kakaotalk_voice_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_kerberos_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_kontiki_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ldap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_lotus_notes_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mail_imap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mail_pop_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mail_smtp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_maplestory_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mdns_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_meebo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_megaco_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mgpc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mms_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_msn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mpegts_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mssql_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mysql_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_netbios_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_netflow_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_nfs_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_noe_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_non_tcp_udp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ntp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_openft_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_openvpn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_oracle_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_oscar_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_pando_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_pcanywhere_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_postgres_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_pplive_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ppstream_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_pptp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_qq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_quake_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_quic_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_radius_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_rdp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_redis_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_rsync_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_rtcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_rtmp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_rtp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_rtsp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_sflow_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_shoutcast_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_sip_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_hep_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_skinny_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_skype_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_smb_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_snmp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_socrates_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_sopcast_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_soulseek_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_spotify_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ssh_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ssl_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_starcraft_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_stealthnet_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_steam_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_stun_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_syslog_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ssdp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_tds_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_teamspeak_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_teamviewer_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_telegram_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_telnet_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_tftp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_thunder_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_tor_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_tvants_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_tvuplayer_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_twitter_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_usenet_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_veohtv_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_vhua_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_viber_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_vmware_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_vnc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_warcraft3_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_whois_das_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_winmx_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_world_of_warcraft_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_world_of_kung_fu_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_xbox_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_xdmcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_yahoo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_zattoo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_zmq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_stracraft_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_ubntac2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); #endif /* __NDPI_PROTOCOLS_H__ */ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/include/ndpi_typedefs.h000066400000000000000000000630671262705051000245730ustar00rootroot00000000000000/* * ndpi_typedefs.h * * Copyright (C) 2011-15 - ntop.org * Copyright (C) 2009-11 - ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #ifndef __NDPI_TYPEDEFS_H__ #define __NDPI_TYPEDEFS_H__ #include "ndpi_define.h" #define BT_ANNOUNCE #define SNAP_EXT /* NDPI_LOG_LEVEL */ typedef enum { NDPI_LOG_ERROR, NDPI_LOG_TRACE, NDPI_LOG_DEBUG } ndpi_log_level_t; /* NDPI_VISIT */ typedef enum { ndpi_preorder, ndpi_postorder, ndpi_endorder, ndpi_leaf } ndpi_VISIT; /* NDPI_NODE */ typedef struct node_t { char *key; struct node_t *left, *right; } ndpi_node; /* NDPI_MASK_SIZE */ typedef u_int32_t ndpi_ndpi_mask; /* NDPI_PROTO_BITMASK_STRUCT */ typedef struct ndpi_protocol_bitmask_struct { ndpi_ndpi_mask fds_bits[NDPI_NUM_FDS_BITS]; } ndpi_protocol_bitmask_struct_t; /* NDPI_DEBUG_FUNCTION_PTR (cast) */ typedef void (*ndpi_debug_function_ptr) (u_int32_t protocol, void *module_struct, ndpi_log_level_t log_level, const char *format, ...); /* ************************************************************ */ /* ******************* NDPI NETWORKS HEADERS ****************** */ /* ************************************************************ */ /* ++++++++++++++++++++++++ Cisco headers +++++++++++++++++++++ */ /* Cisco HDLC */ #ifdef _MSC_VER /* Windows */ #define PACK_ON __pragma(pack(push, 1)) #define PACK_OFF __pragma(pack(pop)) #elif defined(__GNUC__) /* GNU C */ #define PACK_ON #define PACK_OFF __attribute__((packed)) #endif PACK_ON struct ndpi_chdlc { u_int8_t addr; /* 0x0F (Unicast) - 0x8F (Broadcast) */ u_int8_t ctrl; /* always 0x00 */ u_int16_t proto_code; /* protocol type (e.g. 0x0800 IP) */ } PACK_OFF; /* SLARP - Serial Line ARP http://tinyurl.com/qa54e95 */ PACK_ON struct ndpi_slarp { /* address requests (0x00) address replies (0x01) keep-alive (0x02) */ u_int32_t slarp_type; u_int32_t addr_1; u_int32_t addr_2; } PACK_OFF; /* Cisco Discovery Protocol http://tinyurl.com/qa6yw9l */ PACK_ON struct ndpi_cdp { u_int8_t version; u_int8_t ttl; u_int16_t checksum; u_int16_t type; u_int16_t length; } PACK_OFF; /* +++++++++++++++ Ethernet header (IEEE 802.3) +++++++++++++++ */ PACK_ON struct ndpi_ethhdr { u_char h_dest[6]; /* destination eth addr */ u_char h_source[6]; /* source ether addr */ u_int16_t h_proto; /* data length (<= 1500) or type ID proto (>=1536) */ } PACK_OFF; /* +++++++++++++++++++ LLC header (IEEE 802.2) ++++++++++++++++ */ PACK_ON struct ndpi_snap_extension { u_int16_t oui; u_int8_t oui2; u_int16_t proto_ID; } PACK_OFF; PACK_ON struct ndpi_llc_header { u_int8_t dsap; u_int8_t ssap; u_int8_t ctrl; #ifdef SNAP_EXT struct ndpi_snap_extension snap; #endif } PACK_OFF; /* ++++++++++ RADIO TAP header (for IEEE 802.11) +++++++++++++ */ PACK_ON struct ndpi_radiotap_header { u_int8_t version; /* set to 0 */ u_int8_t pad; u_int16_t len; u_int32_t present; u_int64_t MAC_timestamp; u_int8_t flags; } PACK_OFF; /* ++++++++++++ Wireless header (IEEE 802.11) ++++++++++++++++ */ PACK_ON struct ndpi_wifi_header { u_int16_t fc; u_int16_t duration; u_char rcvr[6]; u_char trsm[6]; u_char dest[6]; u_int16_t seq_ctrl; /* u_int64_t ccmp - for data encription only - check fc.flag */ } PACK_OFF; /* +++++++++++++++++++++++ MPLS header +++++++++++++++++++++++ */ PACK_ON struct ndpi_mpls_header { u_int32_t label:20, exp:3, s:1, ttl:8; } PACK_OFF; /* ++++++++++++++++++++++++ IP header ++++++++++++++++++++++++ */ PACK_ON 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; } PACK_OFF; /* +++++++++++++++++++++++ IPv6 header +++++++++++++++++++++++ */ /* rfc3542 */ 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 */ }; PACK_ON struct ndpi_ipv6hdr { 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; } PACK_OFF; /* +++++++++++++++++++++++ TCP header +++++++++++++++++++++++ */ PACK_ON 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; } PACK_OFF; /* +++++++++++++++++++++++ UDP header +++++++++++++++++++++++ */ PACK_ON struct ndpi_udphdr { u_int16_t source; u_int16_t dest; u_int16_t len; u_int16_t check; } PACK_OFF; PACK_ON struct ndpi_dns_packet_header { u_int16_t transaction_id, flags, num_queries, answer_rrs, authority_rrs, additional_rrs; } PACK_OFF; typedef union { u_int32_t ipv4; u_int8_t ipv4_u_int8_t[4]; #ifdef NDPI_DETECTION_SUPPORT_IPV6 struct ndpi_in6_addr ipv6; #endif } ndpi_ip_addr_t; /* ************************************************************ */ /* ******************* ********************* ****************** */ /* ************************************************************ */ #ifdef NDPI_PROTOCOL_BITTORRENT typedef struct spinlock { volatile int val; } spinlock_t; typedef struct atomic { volatile int counter; } atomic_t; 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; }; 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: **/ 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 #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 } #ifndef 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 #ifdef NDPI_PROTOCOL_EAQ u_int8_t eaq_pkt_id; u_int32_t eaq_sequence; #endif } #ifndef 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]; #ifndef WIN32 __attribute__ ((__packed__)) #endif u_int16_t protocol_stack_info; 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_proto { u_int16_t master_protocol /* e.g. HTTP */, protocol /* e.g. FaceBook */; } ndpi_protocol; #define NDPI_PROTOCOL_NULL { NDPI_PROTOCOL_UNKNOWN , NDPI_PROTOCOL_UNKNOWN } 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, /* Used for DNS/HTTPS */ content_automa, /* Used for HTTP subprotocol_detection */ subprotocol_automa, /* Used for HTTP subprotocol_detection */ bigrams_automa, impossible_bigrams_automa; /* TOR */ /* 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; /* rstp */ u_int32_t orb_rstp_ts_timeout; /* yahoo */ 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_dont_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]; #ifndef WIN32 __attribute__ ((__packed__)) #endif u_int16_t protocol_stack_info; /* init parameter, internal used to set up timestamp,... */ u_int16_t guessed_protocol_id, guessed_host_proto_id; u_int8_t protocol_id_already_guessed:1, host_already_guessed:1, init_finished:1, setup_packet_direction:1, 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 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; /* Pointer to src or dst that identifies the server of this connection */ struct ndpi_id_struct *server_id; /* HTTP host or DNS query */ u_char host_server_name[256]; /* Via HTTP User-Agent */ u_char detected_os[32]; /* Via HTTP X-Forwarded-For */ u_char nat_ip[24]; /* 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 { u_int8_t request_code; u_int8_t version; } ntp; 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; u_int8_t num_stun_udp_pkts; #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 #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_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 #ifdef NDPI_PROTOCOL_STARCRAFT u_int32_t starcraft_udp_stage : 3; // 0-7 #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; #endif/* __NDPI_TYPEDEFS_H__ */ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/include/ndpi_unix.h000066400000000000000000000024741262705051000237260ustar00rootroot00000000000000/* * ndpi_unix.h * * Copyright (C) 2011-15 - ntop.org * Copyright (C) 2009-2011 by ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #ifndef __NDPI_UNIX_INCLUDE_FILE__ #define __NDPI_UNIX_INCLUDE_FILE__ #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include #if defined(__NetBSD__) || defined(__OpenBSD__) #include #if defined(__OpenBSD__) #include #endif #endif #endif #ifndef WIN32 #include #include #include #endif #endif /* __NDPI_UNIX_INCLUDE_FILE__ */ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/include/ndpi_win32.h000066400000000000000000000043651262705051000237060ustar00rootroot00000000000000/* * ndpi_win32.h * * Copyright (C) 2011-15 - ntop.org * Copyright (C) 2009-2011 by ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #ifndef __NDPI_WIN32_H__ #define __NDPI_WIN32_H__ #include #include #include #include #include /* getopt from: http://www.pwilson.net/sample.html. */ #include /* for getpid() and the exec..() family */ #include #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif #define _WS2TCPIP_H_ /* Avoid compilation problems */ extern char* strsep(char **sp, const char *sep); 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; typedef uint u_int; 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) memcpy(b, gmtime(a), sizeof(struct tm)) extern unsigned long waitForNextEvent(unsigned long ulDelay /* ms */); #define sleep(a /* sec */) waitForNextEvent(1000*a /* ms */) #endif /* __NDPI_WIN32_H__ */ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/000077500000000000000000000000001262705051000206745ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/Makefile.am000066400000000000000000000113231262705051000227300ustar00rootroot00000000000000lib_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/ndpi_define.h \ ../include/ndpi_main.h \ ../include/ndpi_protocol_ids.h \ ../include/ndpi_protocols.h \ ../include/ndpi_typedefs.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/eaq.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/hep.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/kakaotalk_voice.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/mpegts.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/quic.c \ protocols/radius.c \ protocols/rdp.c \ protocols/redis_net.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/starcraft.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/teredo.c \ protocols/tvants.c \ protocols/tvuplayer.c \ protocols/twitter.c \ protocols/ubntac2.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/zeromq.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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/ndpi_content_match.c.inc000066400000000000000000011525151262705051000254620ustar00rootroot00000000000000/* * ndpi_content_match.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 . * */ 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 (Microsoft CDN) 157.56.0.0/14, 157.60.0.0/16, 157.54.0.0/15 111.221.64.0 - 111.221.127.255 91.190.216.0/21 (AS198015 Skype Communications Sarl) */ { 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 }, { 0x6FDD4000 /* 111.221.64.0 */, 18, NDPI_PROTOCOL_SKYPE }, { 0x5BBED800 /* 91.190.216.0 */, 21, NDPI_PROTOCOL_SKYPE }, /* route: 5.42.160.0/19 descr: Blizzard Entertainment, Inc origin: AS57976 */ { 0x052AA000 /* 5.42.160.0 */, 19, NDPI_PROTOCOL_STARCRAFT }, /* 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 }, /* Twitch ingestion servers : https://api.twitch.tv/kraken/ingests Edoardo Dominici edoaramis@gmail.com */ { 0xB92ACC5D, 32, NDPI_SERVICE_TWITCH }, { 0xB92ACC92, 32, NDPI_SERVICE_TWITCH }, { 0xB92ACCA4, 32, NDPI_SERVICE_TWITCH }, { 0xB92ACCCD, 32, NDPI_SERVICE_TWITCH }, { 0xB92ACC30, 32, NDPI_SERVICE_TWITCH }, { 0xC709FE15, 32, NDPI_SERVICE_TWITCH }, { 0xC709FE19, 32, NDPI_SERVICE_TWITCH }, { 0xBCACD305, 32, NDPI_SERVICE_TWITCH }, { 0xC0104616, 32, NDPI_SERVICE_TWITCH }, { 0xC010461D, 32, NDPI_SERVICE_TWITCH }, { 0xC0104650, 32, NDPI_SERVICE_TWITCH }, { 0xC0104651, 32, NDPI_SERVICE_TWITCH }, { 0xC709FEA3, 32, NDPI_SERVICE_TWITCH }, { 0xC709FE87, 32, NDPI_SERVICE_TWITCH }, { 0xB92ACD85, 32, NDPI_SERVICE_TWITCH }, { 0xB92ACDA4, 32, NDPI_SERVICE_TWITCH }, { 0xC010419A, 32, NDPI_SERVICE_TWITCH }, { 0xC01041AD, 32, NDPI_SERVICE_TWITCH }, { 0xC0104172, 32, NDPI_SERVICE_TWITCH }, { 0xB92ACD68, 32, NDPI_SERVICE_TWITCH }, { 0xB92ACD55, 32, NDPI_SERVICE_TWITCH }, { 0xC0104219, 32, NDPI_SERVICE_TWITCH }, { 0xC010421A, 32, NDPI_SERVICE_TWITCH }, { 0xC010421B, 32, NDPI_SERVICE_TWITCH }, { 0xBCACD205, 32, NDPI_SERVICE_TWITCH }, { 0xBCACCB05, 32, NDPI_SERVICE_TWITCH }, { 0xC010413C, 32, NDPI_SERVICE_TWITCH }, { 0xC010413D, 32, NDPI_SERVICE_TWITCH }, { 0xC010413E, 32, NDPI_SERVICE_TWITCH }, { 0xBCACD105, 32, NDPI_SERVICE_TWITCH }, { 0xBCACD005, 32, NDPI_SERVICE_TWITCH }, { 0xBCACCA05, 32, NDPI_SERVICE_TWITCH }, { 0xB92ACD06, 32, NDPI_SERVICE_TWITCH }, { 0xB92ACD14, 32, NDPI_SERVICE_TWITCH }, { 0xB92ACCF3, 32, NDPI_SERVICE_TWITCH }, { 0xC709F9C7, 32, NDPI_SERVICE_TWITCH }, { 0xC709F9C9, 32, NDPI_SERVICE_TWITCH }, { 0xC709F9CB, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBA4, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBA6, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBAA, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBB1, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBE8, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBE9, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBEA, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBEB, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBFB, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBFC, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBFD, 32, NDPI_SERVICE_TWITCH }, { 0xC709FBFE, 32, NDPI_SERVICE_TWITCH }, { 0xC709FF4B, 32, NDPI_SERVICE_TWITCH }, { 0xC709FF4C, 32, NDPI_SERVICE_TWITCH }, { 0xC709F974, 32, NDPI_SERVICE_TWITCH }, { 0xC709F976, 32, NDPI_SERVICE_TWITCH }, { 0xC709F978, 32, NDPI_SERVICE_TWITCH }, { 0xC709F97D, 32, NDPI_SERVICE_TWITCH }, { 0xC709F985, 32, NDPI_SERVICE_TWITCH }, { 0xC709F986, 32, NDPI_SERVICE_TWITCH }, { 0xC709F987, 32, NDPI_SERVICE_TWITCH }, { 0xC709F98C, 32, NDPI_SERVICE_TWITCH }, { 0xC709F9C5, 32, NDPI_SERVICE_TWITCH }, /* Simet - 200.160.4.0/24 */ { 0xC8A00400, 24, NDPI_SERVICE_SIMET }, /* AnchorFree (Hotspot Shield) AnchorFree Inc. AFNETWORK-1 (NET-74-115-0-0-1) 74.115.0.0 - 74.115.7.255 */ { 0x4A730000, 21, NDPI_SERVICE_HOTSPOT_SHIELD }, { 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.", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, { ".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 }, { ".ebaystratus.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, { ".ebayimg.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 */ { ".google.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, { ".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 }, { ".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 }, { "nflxvideo.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 }, { ".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 }, { "appmeutim.tim.com.br", "TIM_Meu", NDPI_SERVICE_TIMMEU, NDPI_PROTOCOL_ACCEPTABLE }, { ".timtorcedor.com.br", "Torcedor", NDPI_SERVICE_TORCEDOR, NDPI_PROTOCOL_ACCEPTABLE }, { ".kakao.com", "KakaoTalk", NDPI_SERVICE_KAKAOTALK, NDPI_PROTOCOL_FUN }, { "ttvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN }, { "static-cdn.jtvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN }, { "www-cdn.jtvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN }, { "quickplay.com", "QuickPlay", NDPI_SERVICE_QUICKPLAY, NDPI_PROTOCOL_FUN }, { "tim.com.br", "TIM", NDPI_SERVICE_TIM, NDPI_PROTOCOL_ACCEPTABLE }, { "tim.it", "TIM", NDPI_SERVICE_TIM, NDPI_PROTOCOL_ACCEPTABLE }, /* https://support.cipafilter.com/index.php?/Knowledgebase/Article/View/117/0/snapchat---how-to-block */ { "feelinsonice.appspot.com", "Snapchat", NDPI_SERVICE_SNAPCHAT, NDPI_PROTOCOL_FUN }, { "feelinsonice-hrd.appspot.com", "Snapchat", NDPI_SERVICE_SNAPCHAT, NDPI_PROTOCOL_FUN }, { "feelinsonice.com", "Snapchat", NDPI_SERVICE_SNAPCHAT, NDPI_PROTOCOL_FUN }, /* Detected "instagram.c10r.facebook.com". Omitted "*amazonaws.com" and "*facebook.com" CDNs e.g. "ig-telegraph-shv-04-frc3.facebook.com" */ { ".cdninstagram.com", "Instagram", NDPI_SERVICE_INSTAGRAM, NDPI_PROTOCOL_FUN }, { "instagram.", "Instagram", NDPI_SERVICE_INSTAGRAM, NDPI_PROTOCOL_FUN }, { ".instagram.", "Instagram", NDPI_SERVICE_INSTAGRAM, NDPI_PROTOCOL_FUN }, { "igcdn-photos-", "Instagram", NDPI_SERVICE_INSTAGRAM, NDPI_PROTOCOL_FUN }, { "instagramimages-", "Instagram", NDPI_SERVICE_INSTAGRAM, NDPI_PROTOCOL_FUN }, { "instagramstatic-", "Instagram", NDPI_SERVICE_INSTAGRAM, NDPI_PROTOCOL_FUN }, { ".waze.com", "Waze", NDPI_SERVICE_WAZE, NDPI_PROTOCOL_ACCEPTABLE }, { "simet-", "Simet", NDPI_SERVICE_SIMET, NDPI_PROTOCOL_ACCEPTABLE }, { "opensignal.com", "OpenSignal", NDPI_SERVICE_OPENSIGNAL, NDPI_PROTOCOL_ACCEPTABLE }, { "99taxis.com", "99Taxi", NDPI_SERVICE_99TAXI, NDPI_PROTOCOL_ACCEPTABLE }, { "easytaxis.com", "EasyTaxi", NDPI_SERVICE_EASYTAXI, NDPI_PROTOCOL_ACCEPTABLE }, { ".globo.com", "GloboTV", NDPI_SERVICE_GLOBOTV, NDPI_PROTOCOL_ACCEPTABLE }, { ".glbimg.com", "GloboTV", NDPI_SERVICE_GLOBOTV, NDPI_PROTOCOL_ACCEPTABLE }, { "timsomdechamada.com.br", "SomDeChamada", NDPI_SERVICE_TIMSOMDECHAMADA, NDPI_PROTOCOL_ACCEPTABLE }, { ".tim.acotelbr.com.br", "TIM_Menu", NDPI_SERVICE_TIMMENU, NDPI_PROTOCOL_ACCEPTABLE }, { ".timbeta.com.br", "TIM_Beta", NDPI_SERVICE_TIMBETA, NDPI_PROTOCOL_ACCEPTABLE }, { "tim-geoportal.geoportal3d.com.br", "TIM_PortasAbertas", NDPI_SERVICE_TIMPORTASABERTAS, NDPI_PROTOCOL_ACCEPTABLE }, { ".m4u.com.br", "TIM_Recarga", NDPI_SERVICE_TIMRECARGA, NDPI_PROTOCOL_ACCEPTABLE }, { ".deezer.com", "Deezer", NDPI_SERVICE_DEEZER, NDPI_PROTOCOL_ACCEPTABLE }, { ".microsoft.com", "Microsoft", NDPI_SERVICE_MICROSOFT, NDPI_PROTOCOL_ACCEPTABLE }, { "update.microsoft.com", "WindowsUpdate", NDPI_SERVICE_WINDOWS_UPDATE, NDPI_PROTOCOL_ACCEPTABLE }, { ".windowsupdate.com", "WindowsUpdate", NDPI_SERVICE_WINDOWS_UPDATE, NDPI_PROTOCOL_ACCEPTABLE }, { "worldofwarcraft.com", "WorldOfWarcraft", NDPI_PROTOCOL_WORLDOFWARCRAFT, NDPI_PROTOCOL_FUN }, { ".anchorfree.", "HotspotShield", NDPI_SERVICE_HOTSPOT_SHIELD, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS }, { "hotspotshield.com", "HotspotShield", NDPI_SERVICE_HOTSPOT_SHIELD, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS }, { ".webex.com", "Webex", NDPI_PROTOCOL_WEBEX, NDPI_PROTOCOL_ACCEPTABLE }, { 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_SERVICE_WINDOWS_UPDATE, NDPI_PROTOCOL_ACCEPTABLE }, { "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 }, { "application/vnd.apple.mpegurl", NULL, NDPI_CONTENT_MPEG, NDPI_PROTOCOL_FUN }, { NULL, 0 } }; /* ****************************************************** */ /* Tor The tor protocol uses SSL to contact peers so it could be exchanged with standard SSL. However the host names such as - www.fgd2iwya7vinfutj5wq5we.com - www.qbtxzhetq4s2f.com - www.fgd2iwya7vinfutj5wq5we.net In essence www..com|net To do things properly we should check if host name in the certificate exists or if the IP address of the SSL peer resolves to a name. Unfortunately for performance reasons we can't afford to do a DNS lookup in nDPI (however apps can do it if possible) and thus we have created a heuristic algorithm that tries to check the host name (in the SSL certificate) to see if it looks like a random name or a real name. We cannot use a dictionary (how can the kernel read a file?) and this we use bigrams distribution to decide if the string looks like a word or just random chars. http://www3.nd.edu/~busiforc/handouts/cryptography/Letter%20Frequencies.html */ static const char *ndpi_en_bigrams[] = { "aa", "ba", "ca", "da", "ea", "fa", "ga", "ha", "ia", "ja", "ka", "la", "ma", "na", "oa", "pa", "qa", "ra", "sa", "ta", "ua", "va", "wa", "xa", "ya", "za", "ab", "bb", "db", "eb", "fb", "gb", "hb", "ib", "kb", "lb", "mb", "nb", "ob", "pb", "rb", "sb", "tb", "ub", "wb", "yb", "ac", "bc", "cc", "dc", "ec", "fc", "gc", "hc", "ic", "kc", "lc", "mc", "nc", "oc", "pc", "rc", "sc", "tc", "uc", "wc", "xc", "yc", "ad", "bd", "cd", "dd", "ed", "fd", "gd", "hd", "id", "kd", "ld", "md", "nd", "od", "pd", "rd", "sd", "td", "ud", "wd", "xd", "yd", "zd", "ae", "be", "ce", "de", "ee", "fe", "ge", "he", "ie", "je", "ke", "le", "me", "ne", "oe", "pe", "re", "se", "te", "ue", "ve", "we", "xe", "ye", "ze", "af", "bf", "df", "ef", "ff", "gf", "hf", "if", "kf", "lf", "mf", "nf", "of", "pf", "rf", "sf", "tf", "uf", "wf", "xf", "yf", "zf", "ag", "bg", "dg", "eg", "fg", "gg", "hg", "ig", "kg", "lg", "ng", "og", "pg", "rg", "sg", "tg", "ug", "wg", "yg", "ah", "bh", "ch", "dh", "eh", "fh", "gh", "hh", "ih", "kh", "lh", "mh", "nh", "oh", "ph", "rh", "sh", "th", "uh", "wh", "xh", "yh", "ai", "bi", "ci", "di", "ei", "fi", "gi", "hi", "ii", "ji", "ki", "li", "mi", "ni", "oi", "pi", "qi", "ri", "si", "ti", "ui", "vi", "wi", "xi", "yi", "zi", "aj", "bj", "dj", "ej", "fj", "gj", "hj", "ij", "jj", "kj", "lj", "nj", "oj", "pj", "rj", "sj", "tj", "uj", "wj", "yj", "ak", "ck", "dk", "ek", "gk", "ik", "kk", "lk", "mk", "nk", "ok", "pk", "rk", "sk", "tk", "uk", "wk", "yk", "zk", "al", "bl", "cl", "dl", "el", "fl", "gl", "hl", "il", "kl", "ll", "ml", "nl", "ol", "pl", "rl", "sl", "tl", "ul", "vl", "wl", "xl", "yl", "zl", "am", "bm", "cm", "dm", "em", "fm", "gm", "hm", "im", "km", "lm", "mm", "nm", "om", "pm", "rm", "sm", "tm", "um", "wm", "xm", "ym", "zm", "an", "bn", "cn", "dn", "en", "fn", "gn", "hn", "in", "kn", "ln", "mn", "nn", "on", "pn", "rn", "sn", "tn", "un", "wn", "xn", "yn", "ao", "bo", "co", "do", "eo", "fo", "go", "ho", "io", "jo", "ko", "lo", "mo", "no", "oo", "po", "ro", "so", "to", "uo", "vo", "wo", "xo", "yo", "zo", "ap", "bp", "dp", "ep", "fp", "gp", "hp", "ip", "kp", "lp", "mp", "np", "op", "pp", "rp", "sp", "tp", "up", "wp", "xp", "yp", "zp", "aq", "cq", "dq", "eq", "hq", "iq", "nq", "oq", "qq", "rq", "sq", "uq", "xq", "ar", "br", "cr", "dr", "er", "fr", "gr", "hr", "ir", "kr", "lr", "mr", "nr", "or", "pr", "rr", "sr", "tr", "ur", "vr", "wr", "xr", "yr", "as", "bs", "cs", "ds", "es", "fs", "gs", "hs", "is", "ks", "ls", "ms", "ns", "os", "ps", "rs", "ss", "ts", "us", "vs", "ws", "xs", "ys", "at", "bt", "ct", "dt", "et", "ft", "gt", "ht", "it", "kt", "lt", "mt", "nt", "ot", "pt", "rt", "st", "tt", "ut", "wt", "xt", "yt", "zt", "au", "bu", "cu", "du", "eu", "fu", "gu", "hu", "iu", "ju", "ku", "lu", "mu", "nu", "ou", "pu", "qu", "ru", "su", "tu", "uu", "vu", "wu", "xu", "yu", "zu", "av", "bv", "dv", "ev", "iv", "lv", "mv", "nv", "ov", "rv", "sv", "tv", "uv", "vv", "zv", "aw", "bw", "dw", "ew", "fw", "gw", "hw", "iw", "kw", "lw", "mw", "nw", "ow", "pw", "rw", "sw", "tw", "uw", "ww", "xw", "yw", "zw", "ax", "ex", "ix", "nx", "ox", "rx", "ux", "xx", "yx", "ay", "by", "cy", "dy", "ey", "fy", "gy", "hy", "ky", "ly", "my", "ny", "oy", "py", "ry", "sy", "ty", "uy", "vy", "wy", "xy", "yy", "zy", "az", "bz", "cz", "dz", "ez", "gz", "iz", "lz", "nz", "oz", "pz", "rz", "tz", "uz", "zz", NULL }; static const char *ndpi_en_impossible_bigrams[] = { "bk", "bq", "bx", "cb", "cf", "cg", "cj", "cp", "cv", "cw", "cx", "dx", "fk", "fq", "fv", "fx", "ee", "fz", "gq", "gv", "gx", "hh", "hk", "hv", "hx", "hz", "iy", "jb", "jc", "jd", "jf", "jg", "jh", "jk", "jl", "jm", "jn", "jp", "jq", "jr", "js", "jt", "jv", "jw", "jx", "jy", "jz", "kg", "kq", "kv", "kx", "kz", "lq", "lx", "mg", "mj", "mq", "mx", "mz", "pq", "pv", "px", "qb", "qc", "qd", "qe", "qf", "ii", "qg", "qh", "qj", "qk", "ql", "qm", "qn", "qo", "qp", "qr", "qs", "qt", "qv", "qw", "qx", "qy", "uu", "qz", "sx", "sz", "tq", "tx", "vb", "vc", "vd", "vf", "vg", "vh", "vj", "vk", "vm", "vn", "vp", "bw", "vq", "vt", "vw", "vx", "vz", "wq", "wv", "wx", "wz", "xb", "xg", "xj", "xk", "xv", "xz", "xw", "yd", "yp", "yj", "yq", "yv", "yz", "yw", "zb", "zc", "zg", "zh", "zj", "zn", "zq", "zr", "zs", "zx", "wh", "wk", "wb", "zk", "kp", "zk", "xy", NULL }; nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/ndpi_main.c000066400000000000000000005146421262705051000230120ustar00rootroot00000000000000/* * 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 . * */ #include #include #include "ahocorasick.h" #include "ndpi_api.h" #include "../../config.h" #include #ifndef WIN32 #include #endif #include "ndpi_content_match.c.inc" #include "third_party/include/ndpi_patricia.h" #include "third_party/src/ndpi_patricia.c" /* 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; int j; if(protoId >= NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS) { #ifdef DEBUG printf("[NDPI] %s(%s/protoId=%d): INTERNAL ERROR\n", __FUNCTION__, protoName, protoId); #endif return; } if(ndpi_mod->proto_defaults[protoId].protoName != NULL) { #ifdef DEBUG printf("[NDPI] %s(%s/protoId=%d): already initialized. Ignoring it\n", __FUNCTION__, protoName, protoId); #endif return; } name = ndpi_strdup(protoName); ndpi_mod->proto_defaults[protoId].protoName = name, ndpi_mod->proto_defaults[protoId].protoId = protoId, ndpi_mod->proto_defaults[protoId].protoBreed = breed; memcpy(&ndpi_mod->proto_defaults[protoId].master_tcp_protoId, tcp_master_protoId, 2*sizeof(u_int16_t)); memcpy(&ndpi_mod->proto_defaults[protoId].master_udp_protoId, udp_master_protoId, 2*sizeof(u_int16_t)); for(j=0; jproto_defaults[protoId], &ndpi_mod->udpRoot); if(tcpDefPorts[j].port_low != 0) addDefaultPort(&tcpDefPorts[j], &ndpi_mod->proto_defaults[protoId], &ndpi_mod->tcpRoot); } } /* ******************************************************************** */ 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) { #ifdef DEBUG printf("[NDPI] Adding [%s][%d]\n", value, protocol_id); #endif 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++) { u_int16_t no_master[2] = { NDPI_PROTOCOL_NO_MASTER_PROTO, NDPI_PROTOCOL_NO_MASTER_PROTO }; ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS]; 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; } ndpi_set_proto_defaults(ndpi_mod, ndpi_mod->proto_defaults[host_match[i].protocol_id].protoBreed, ndpi_mod->proto_defaults[host_match[i].protocol_id].protoId, no_master, no_master, ndpi_mod->proto_defaults[host_match[i].protocol_id].protoName, ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); } #ifdef DEBUG ac_automata_display(ndpi_mod->host_automa.ac_automa, 'n'); #endif 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]; /* 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_HEP, no_master, no_master, "HEP", ndpi_build_default_ports(ports_a, 9064, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 9063, 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, 6771, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TEREDO, no_master, no_master, "Teredo", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 3544, 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_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_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_FUN, NDPI_SERVICE_HOTSPOT_SHIELD, no_master, no_master, "HotspotShield", ndpi_build_default_ports(ports_a, 0, 0, 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, 3478, 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 */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHATSAPP_VOICE, no_master, no_master, "WhatsAppVoice", 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", ndpi_build_default_ports(ports_a, 0, 0, 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_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 */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_QUIC, no_master, no_master, "Quic", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 443, 80, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_EAQ, no_master, no_master, "EAQ", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 6000, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_SERVICE_KAKAOTALK_VOICE, no_master, no_master, "KakaoTalk_Voice", ndpi_build_default_ports(ports_a, 0, 0, 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_MPEGTS, no_master, no_master, "MPEG_TS", 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 */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_CONTENT_WEBM, no_master, no_master, "WebM", /* Courtesy of Shreeram Ramamoorthy Swaminathan */ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_H323, no_master, no_master,"H323", ndpi_build_default_ports(ports_a, 1719, 1720, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 1719, 1720, 0, 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_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_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_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_PROTOCOL_STARCRAFT, no_master, no_master, "Starcraft", ndpi_build_default_ports(ports_a, 1119, 0, 0, 0, 0), /* TCP */ ndpi_build_default_ports(ports_b, 1119, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_UBNTAC2, no_master, no_master, "UBNTAC2", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ ndpi_build_default_ports(ports_b, 10001, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MS_LYNC, no_master, no_master, "Lync", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ /* calling function for host and content matched protocols */ 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); memset(p, 0, sizeof(prefix_t)); 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 /* network byte order */) { prefix_t prefix; patricia_node_t *node; /* Make sure all in network byte order otherwise compares wont work */ 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 /* network byte order */) { 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(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 = htonl(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; } } /* ******************************************* */ static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, char *value, int protocol_id) { patricia_node_t *node; struct in_addr pin; inet_pton(AF_INET, value, &pin); if((node = add_to_ptree(ndpi_struct->protocols_ptree, AF_INET, &pin, 32)) != NULL) { node->value.user_value = protocol_id; } return(0); } #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) { int low = ndpi_min(sport, dport); int high = ndpi_max(sport, dport); node.default_port = low; /* Check server port first */ 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 = high; 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); } /* ******************************************************************** */ u_int ndpi_get_num_supported_protocols(struct ndpi_detection_module_struct *ndpi_mod) { return(ndpi_mod->ndpi_num_supported_protocols); } /* ******************************************************************** */ #ifdef WIN32 char * strsep(char **sp, char *sep) { char *p, *s; if (sp == NULL || *sp == NULL || **sp == '\0') return(NULL); s = *sp; p = s + strcspn(s, sep); if (*p != '\0') *p++ = '\0'; *sp = p; return(s); } #endif /* ******************************************************************** */ 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; proto[i] != '\0'; i++) { switch(proto[i]) { case '/': case '&': case '^': case ':': case ';': case '\'': case '"': case ' ': proto[i] = '_'; break; } } 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, is_ip = 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, "ip:", 3) == 0) is_ip = 1, value = &attr[3]; else if(strncmp(attr, "host:", 5) == 0) { /* host:"",host:"",.....@ */ value = &attr[5]; if(value[0] == '"') value++; /* remove leading " */ if(value[strlen(value)-1] == '"') value[strlen(value)-1] = '\0'; /* remove trailing " */ } if(is_tcp || is_udp) { if(sscanf(value, "%u-%u", (unsigned int *)&range.port_low, (unsigned int *)&range.port_high) != 2) range.port_low = range.port_high = atoi(&elem[4]); if(do_add) addDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot); else removeDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot); } else if(is_ip) { #ifdef NDPI_PROTOCOL_TOR ndpi_add_host_ip_subprotocol(ndpi_mod, value, subprotocol_id); #endif } else { if(do_add) ndpi_add_host_url_subprotocol(ndpi_mod, value, subprotocol_id, NDPI_PROTOCOL_ACCEPTABLE); else ndpi_remove_host_url_subprotocol(ndpi_mod, value, subprotocol_id); } } return(0); } /* ******************************************************************** */ /* Format: :,:,.....@ Example: tcp:80,tcp:3128@HTTP udp:139@NETBIOS */ int ndpi_load_protocols_file(struct ndpi_detection_module_struct *ndpi_mod, char* path) { 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); 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 if(ndpi_struct->proto_defaults[ndpi_protocol_id].protoIdx != 0) printf("[NDPI] Internal error: protocol %s/%u has been already registered\n", label, ndpi_protocol_id); else { #ifdef DEBUG printf("[NDPI] Adding %s with protocol id %d\n", label, ndpi_protocol_id); #endif } /* Set function 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; /* HTTP */ init_http_dissector(ndpi_struct, &a, detection_bitmask); /* Stracraft */ init_starcraft_dissector(ndpi_struct, &a, detection_bitmask); /* SSL */ init_ssl_dissector(ndpi_struct, &a, detection_bitmask); /* STUN */ init_stun_dissector(ndpi_struct, &a, detection_bitmask); /* RTP */ init_rtp_dissector(ndpi_struct, &a, detection_bitmask); /* RTSP */ init_rtsp_dissector(ndpi_struct, &a, detection_bitmask); /* RDP */ init_rdp_dissector(ndpi_struct, &a, detection_bitmask); /* SIP */ init_sip_dissector(ndpi_struct, &a, detection_bitmask); /* HEP */ init_hep_dissector(ndpi_struct, &a, detection_bitmask); /* Teredo */ init_teredo_dissector(ndpi_struct, &a, detection_bitmask); /* EDONKEY */ init_edonkey_dissector(ndpi_struct, &a, detection_bitmask); /* FASTTRACK */ init_fasttrack_dissector(ndpi_struct, &a, detection_bitmask); /* GNUTELLA */ init_gnutella_dissector(ndpi_struct, &a, detection_bitmask); /* WINMX */ init_winmx_dissector(ndpi_struct, &a, detection_bitmask); /* DIRECTCONNECT */ init_directconnect_dissector(ndpi_struct, &a, detection_bitmask); /* MSN */ init_msn_dissector(ndpi_struct, &a, detection_bitmask); /* YAHOO */ init_yahoo_dissector(ndpi_struct, &a, detection_bitmask); /* OSCAR */ init_oscar_dissector(ndpi_struct, &a, detection_bitmask); /* APPLEJUICE */ init_applejuice_dissector(ndpi_struct, &a, detection_bitmask); /* SOULSEEK */ init_soulseek_dissector(ndpi_struct, &a, detection_bitmask); /* IRC */ init_irc_dissector(ndpi_struct, &a, detection_bitmask); /* JABBER */ init_jabber_dissector(ndpi_struct, &a, detection_bitmask); /* MAIL_POP */ init_mail_pop_dissector(ndpi_struct, &a, detection_bitmask); /* MAIL_IMAP */ init_mail_imap_dissector(ndpi_struct, &a, detection_bitmask); /* MAIL_SMTP */ init_mail_smtp_dissector(ndpi_struct, &a, detection_bitmask); /* USENET */ init_usenet_dissector(ndpi_struct, &a, detection_bitmask); /* DNS */ init_dns_dissector(ndpi_struct, &a, detection_bitmask); /* FILETOPIA */ init_filetopia_dissector(ndpi_struct, &a, detection_bitmask); /* VMWARE */ init_vmware_dissector(ndpi_struct, &a, detection_bitmask); /* IMESH */ init_imesh_dissector(ndpi_struct, &a, detection_bitmask); /* MMS */ init_mms_dissector(ndpi_struct, &a, detection_bitmask); /* NON_TCP_UDP */ init_non_tcp_udp_dissector(ndpi_struct, &a, detection_bitmask); /* TVANTS */ init_tvants_dissector(ndpi_struct, &a, detection_bitmask); /* SOPCAST */ init_sopcast_dissector(ndpi_struct, &a, detection_bitmask); /* TVUPLAYER */ init_tvuplayer_dissector(ndpi_struct, &a, detection_bitmask); /* PPSTREAM */ init_ppstream_dissector(ndpi_struct, &a, detection_bitmask); /* PPLIVE */ init_pplive_dissector(ndpi_struct, &a, detection_bitmask); /* IAX */ init_iax_dissector(ndpi_struct, &a, detection_bitmask); /* MGPC */ init_mgpc_dissector(ndpi_struct, &a, detection_bitmask); /* ZATTOO */ init_zattoo_dissector(ndpi_struct, &a, detection_bitmask); /* QQ */ init_qq_dissector(ndpi_struct, &a, detection_bitmask); /* SSH */ init_ssh_dissector(ndpi_struct, &a, detection_bitmask); /* AYIYA */ init_ayiya_dissector(ndpi_struct, &a, detection_bitmask); /* THUNDER */ init_thunder_dissector(ndpi_struct, &a, detection_bitmask); /* VNC */ init_vnc_dissector(ndpi_struct, &a, detection_bitmask); /* TEAMVIEWER */ init_teamviewer_dissector(ndpi_struct, &a, detection_bitmask); /* DHCP */ init_dhcp_dissector(ndpi_struct, &a, detection_bitmask); /* SOCRATES */ init_socrates_dissector(ndpi_struct, &a, detection_bitmask); /* STEAM */ init_steam_dissector(ndpi_struct, &a, detection_bitmask); /* HALFLIFE2 */ init_halflife2_dissector(ndpi_struct, &a, detection_bitmask); /* XBOX */ init_xbox_dissector(ndpi_struct, &a, detection_bitmask); /* HTTP_APPLICATION_ACTIVESYNC */ init_http_activesync_dissector(ndpi_struct, &a, detection_bitmask); /* SMB */ init_smb_dissector(ndpi_struct, &a, detection_bitmask); /* TELNET */ init_telnet_dissector(ndpi_struct, &a, detection_bitmask); /* NTP */ init_ntp_dissector(ndpi_struct, &a, detection_bitmask); /* NFS */ init_nfs_dissector(ndpi_struct, &a, detection_bitmask); /* SSDP */ init_ssdp_dissector(ndpi_struct, &a, detection_bitmask); /* WORLD_OF_WARCRAFT */ init_world_of_warcraft_dissector(ndpi_struct, &a, detection_bitmask); /* POSTGRES */ init_postgres_dissector(ndpi_struct, &a, detection_bitmask); /* MYSQL */ init_mysql_dissector(ndpi_struct, &a, detection_bitmask); /* BGP */ init_bgp_dissector(ndpi_struct, &a, detection_bitmask); /* QUAKE */ init_quake_dissector(ndpi_struct, &a, detection_bitmask); /* BATTLEFIELD */ init_battlefield_dissector(ndpi_struct, &a, detection_bitmask); /* PCANYWHERE */ init_pcanywhere_dissector(ndpi_struct, &a, detection_bitmask); /* SNMP */ init_snmp_dissector(ndpi_struct, &a, detection_bitmask); /* KONTIKI */ init_kontiki_dissector(ndpi_struct, &a, detection_bitmask); /* ICECAST */ init_icecast_dissector(ndpi_struct, &a, detection_bitmask); /* SHOUTCAST */ init_shoutcast_dissector(ndpi_struct, &a, detection_bitmask); /* VEOHTV */ init_veohtv_dissector(ndpi_struct, &a, detection_bitmask); /* KERBEROS */ init_kerberos_dissector(ndpi_struct, &a, detection_bitmask); /* OPENFT */ init_openft_dissector(ndpi_struct, &a, detection_bitmask); /* SYSLOG */ init_syslog_dissector(ndpi_struct, &a, detection_bitmask); /* TDS */ init_tds_dissector(ndpi_struct, &a, detection_bitmask); /* DIRECT_DOWNLOAD_LINK */ init_directdownloadlink_dissector(ndpi_struct, &a, detection_bitmask); /* NETBIOS */ init_netbios_dissector(ndpi_struct, &a, detection_bitmask); /* MDNS */ init_mdns_dissector(ndpi_struct, &a, detection_bitmask); /* IPP */ init_ipp_dissector(ndpi_struct, &a, detection_bitmask); /* LDAP */ init_ldap_dissector(ndpi_struct, &a, detection_bitmask); /* WARCRAFT3 */ init_warcraft3_dissector(ndpi_struct, &a, detection_bitmask); /* XDMCP */ init_xdmcp_dissector(ndpi_struct, &a, detection_bitmask); /* TFTP */ init_tftp_dissector(ndpi_struct, &a, detection_bitmask); /* MSSQL */ init_mssql_dissector(ndpi_struct, &a, detection_bitmask); /* PPTP */ init_pptp_dissector(ndpi_struct, &a, detection_bitmask); /* STEALTHNET */ init_stealthnet_dissector(ndpi_struct, &a, detection_bitmask); /* DHCPV6 */ init_dhcpv6_dissector(ndpi_struct, &a, detection_bitmask); /* MEEBO */ init_meebo_dissector(ndpi_struct, &a, detection_bitmask); /* AFP */ init_afp_dissector(ndpi_struct, &a, detection_bitmask); /* AIMINI */ init_aimini_dissector(ndpi_struct, &a, detection_bitmask); /* FLORENSIA */ init_florensia_dissector(ndpi_struct, &a, detection_bitmask); /* MAPLESTORY */ init_maplestory_dissector(ndpi_struct, &a, detection_bitmask); /* DOFUS */ init_dofus_dissector(ndpi_struct, &a, detection_bitmask); /* WORLD_OF_KUNG_FU */ init_world_of_kung_fu_dissector(ndpi_struct, &a, detection_bitmask); /* FIESTA */ init_fiesta_dissector(ndpi_struct, &a, detection_bitmask); /* CROSSIFIRE */ init_crossfire_dissector(ndpi_struct, &a, detection_bitmask); /* GUILDWARS */ init_guildwars_dissector(ndpi_struct, &a, detection_bitmask); /* ARMAGETRON */ init_armagetron_dissector(ndpi_struct, &a, detection_bitmask); /* DROPBOX */ init_dropbox_dissector(ndpi_struct, &a, detection_bitmask); /* SPOTIFY */ init_spotify_dissector(ndpi_struct, &a, detection_bitmask); /* RADIUS */ init_radius_dissector(ndpi_struct, &a, detection_bitmask); /* CITRIX */ init_citrix_dissector(ndpi_struct, &a, detection_bitmask); /* LOTUS_NOTES */ init_lotus_notes_dissector(ndpi_struct, &a, detection_bitmask); /* GTP */ init_gtp_dissector(ndpi_struct, &a, detection_bitmask); /* DCERPC */ init_dcerpc_dissector(ndpi_struct, &a, detection_bitmask); /* NETFLOW */ init_netflow_dissector(ndpi_struct, &a, detection_bitmask); /* SFLOW */ init_sflow_dissector(ndpi_struct, &a, detection_bitmask); /* H323 */ init_h323_dissector(ndpi_struct, &a, detection_bitmask); /* OPENVPN */ init_openvpn_dissector(ndpi_struct, &a, detection_bitmask); /* NOE */ init_noe_dissector(ndpi_struct, &a, detection_bitmask); /* CISCOVPN */ init_ciscovpn_dissector(ndpi_struct, &a, detection_bitmask); /* TEAMSPEAK */ init_teamspeak_dissector(ndpi_struct, &a, detection_bitmask); /* VIBER */ init_viber_dissector(ndpi_struct, &a, detection_bitmask); /* TOR */ init_tor_dissector(ndpi_struct, &a, detection_bitmask); /* SKINNY */ init_skinny_dissector(ndpi_struct, &a, detection_bitmask); /* RTCP */ init_rtcp_dissector(ndpi_struct, &a, detection_bitmask); /* RSYNC */ init_rsync_dissector(ndpi_struct, &a, detection_bitmask); /* WHOIS_DAS */ init_whois_das_dissector(ndpi_struct, &a, detection_bitmask); /* ORACLE */ init_oracle_dissector(ndpi_struct, &a, detection_bitmask); /* CORBA */ init_corba_dissector(ndpi_struct, &a, detection_bitmask); /* RTMP */ init_rtmp_dissector(ndpi_struct, &a, detection_bitmask); /* FTP_CONTROL */ init_ftp_control_dissector(ndpi_struct, &a, detection_bitmask); /* FTP_DATA */ init_ftp_data_dissector(ndpi_struct, &a, detection_bitmask); /* PANDO */ init_pando_dissector(ndpi_struct, &a, detection_bitmask); /* MEGACO */ init_megaco_dissector(ndpi_struct, &a, detection_bitmask); /* REDIS */ init_redis_dissector(ndpi_struct, &a, detection_bitmask); /* VHUA */ init_vhua_dissector(ndpi_struct, &a, detection_bitmask); /* ZMQ */ init_zmq_dissector(ndpi_struct, &a, detection_bitmask); /* TWITTER */ init_twitter_dissector(ndpi_struct, &a, detection_bitmask); /* TELEGRAM */ init_telegram_dissector(ndpi_struct, &a, detection_bitmask); /* QUIC */ init_quic_dissector(ndpi_struct, &a, detection_bitmask); /* EAQ */ init_eaq_dissector(ndpi_struct, &a, detection_bitmask); /* KAKAOTALK_VOICE */ init_kakaotalk_voice_dissector(ndpi_struct, &a, detection_bitmask); /* MPEGTS */ init_mpegts_dissector(ndpi_struct, &a, detection_bitmask); /* UBNTAC2 */ init_ubntac2_dissector(ndpi_struct, &a, detection_bitmask); /* Put false-positive sensitive protocols at the end */ /* SKYPE */ init_skype_dissector(ndpi_struct, &a, detection_bitmask); /* BITTORRENT */ init_bittorrent_dissector(ndpi_struct, &a, detection_bitmask); /* ----------------------------------------------------------------- */ 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->ip6_ctlun.ip6_un1.ip6_un1_plen)) { l4ptr = (((const u_int8_t *) iph_v6) + sizeof(struct ndpi_ipv6hdr)); l4len = ntohs(iph_v6->ip6_ctlun.ip6_un1.ip6_un1_plen); l4protocol = iph_v6->ip6_ctlun.ip6_un1.ip6_un1_nxt; // 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; } void ndpi_apply_flow_protocol_to_packet(struct ndpi_flow_struct *flow, struct ndpi_packet_struct *packet) { memcpy(&packet->detected_protocol_stack, &flow->detected_protocol_stack, sizeof(packet->detected_protocol_stack)); memcpy(&packet->protocol_stack_info, &flow->protocol_stack_info, sizeof(packet->protocol_stack_info)); } 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; } 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; 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->ip6_src, &iphv6->ip6_dst) != 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 HAPPENING */ 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); } /* ********************************************************************************* */ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, const struct ndpi_iphdr *iph, struct ndpi_ipv6hdr *iph6, struct ndpi_tcphdr *tcp, struct ndpi_udphdr *udp, u_int8_t src_to_dst_direction, u_int8_t l4_proto, struct ndpi_id_struct *src, u_int16_t sport, struct ndpi_id_struct *dst, u_int16_t dport, u_int8_t *payload, u_int16_t payload_len) { NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet; u_int32_t a; ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; if(payload_len == 0) return(ret); flow->packet.tcp = tcp, flow->packet.udp = udp; flow->packet.payload = payload, flow->packet.payload_packet_len = payload_len; if(src_to_dst_direction) flow->src = src, flow->dst = dst; else flow->src = dst, flow->dst = src; ndpi_selection_packet = NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC; if((flow->packet.iph = iph) != NULL) ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IP | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6; #ifdef NDPI_DETECTION_SUPPORT_IPV6 else if((flow->packet.iphv6 = iph6) != NULL) ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6; #endif /* NDPI_DETECTION_SUPPORT_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->protocol_id_already_guessed) { flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, l4_proto, sport, dport); flow->protocol_id_already_guessed = 1; } } if(flow->packet.tcp_retransmission == 0) ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION; flow->packet.l4_protocol = l4_proto, flow->packet.packet_direction = src_to_dst_direction; check_ndpi_flow_func(ndpi_struct, flow, &ndpi_selection_packet); a = flow->packet.detected_protocol_stack[0]; if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, a) == 0) a = NDPI_PROTOCOL_UNKNOWN; if(a != NDPI_PROTOCOL_UNKNOWN) { int i; for(i=0; (ihost_server_name)) && (flow->host_server_name[i] != '\0'); i++) flow->host_server_name[i] = tolower(flow->host_server_name[i]); flow->host_server_name[i] ='\0'; } ret_protocols: if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) { ret.master_protocol = flow->detected_protocol_stack[1], ret.protocol = flow->detected_protocol_stack[0]; if(ret.protocol == ret.master_protocol) ret.master_protocol = NDPI_PROTOCOL_UNKNOWN; } else ret.protocol = flow->detected_protocol_stack[0]; if((ret.protocol == NDPI_PROTOCOL_UNKNOWN) && flow->packet.iph && (!flow->host_already_guessed)) { if((flow->guessed_host_proto_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->saddr)) == NDPI_PROTOCOL_UNKNOWN) { flow->guessed_host_proto_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->daddr); } flow->host_already_guessed = 1; } if((ret.protocol == NDPI_PROTOCOL_UNKNOWN) && (ret.master_protocol != NDPI_PROTOCOL_UNKNOWN)) ret.protocol = flow->guessed_host_proto_id; return(ret); } /* ********************************************************************************* */ ndpi_protocol 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; ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; if(flow == NULL) return(ret); if(flow->server_id == NULL) flow->server_id = dst; /* Default */ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) goto ret_protocols; /* need at least 20 bytes for ip header */ if(packetlen < 20) { /* reset protocol which is normally done in init_packet_header */ ndpi_int_reset_packet_protocol(&flow->packet); return(ret); } flow->packet.tick_timestamp_l = current_tick_l; flow->packet.tick_timestamp = (u_int32_t)current_tick_l/1000; /* 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(ret); /* 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->ip6_ctlun.ip6_un1.ip6_un1_nxt, 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; if((protocol != IPPROTO_TCP) && (protocol != IPPROTO_UDP)) { flow->detected_protocol_stack[0] = flow->guessed_protocol_id; goto ret_protocols; } } check_ndpi_flow_func(ndpi_struct, flow, &ndpi_selection_packet); a = flow->packet.detected_protocol_stack[0]; if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, a) == 0) a = NDPI_PROTOCOL_UNKNOWN; if(a != NDPI_PROTOCOL_UNKNOWN) { int i; for(i=0; (ihost_server_name)) && (flow->host_server_name[i] != '\0'); i++) flow->host_server_name[i] = tolower(flow->host_server_name[i]); flow->host_server_name[i] ='\0'; } ret_protocols: if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) { ret.master_protocol = flow->detected_protocol_stack[1], ret.protocol = flow->detected_protocol_stack[0]; if(ret.protocol == ret.master_protocol) ret.master_protocol = NDPI_PROTOCOL_UNKNOWN; } else ret.protocol = flow->detected_protocol_stack[0]; if((ret.protocol == NDPI_PROTOCOL_UNKNOWN) && flow->packet.iph && (!flow->host_already_guessed)) { if((flow->guessed_host_proto_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->saddr)) == NDPI_PROTOCOL_UNKNOWN) { flow->guessed_host_proto_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->daddr); } flow->host_already_guessed = 1; } if((ret.protocol == NDPI_PROTOCOL_UNKNOWN) && (ret.master_protocol != NDPI_PROTOCOL_UNKNOWN)) ret.protocol = flow->guessed_host_proto_id; return(ret); } 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_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) { struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; ndpi_int_change_protocol(ndpi_struct, flow, upper_detected_protocol, lower_detected_protocol); if(src != NULL) { NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, upper_detected_protocol); if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN) NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, lower_detected_protocol); } if(dst != NULL) { NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, upper_detected_protocol); if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN) NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, lower_detected_protocol); } } u_int16_t ndpi_get_flow_masterprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { return(flow->detected_protocol_stack[1]); } void ndpi_int_change_flow_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) { if(!flow) return; flow->detected_protocol_stack[0] = upper_detected_protocol, flow->detected_protocol_stack[1] = lower_detected_protocol; } void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) { 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(!packet) return; packet->detected_protocol_stack[0] = upper_detected_protocol, packet->detected_protocol_stack[1] = lower_detected_protocol; } /* * 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; struct ndpi_packet_struct *packet = &flow->packet; if(!packet) return 0; for(a = 0; a < NDPI_PROTOCOL_HISTORY_SIZE; a++) { if(packet->detected_protocol_stack[a] == protocol_id) return 1; } return 0; } /* 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 upper_detected_protocol, u_int16_t lower_detected_protocol) { ndpi_int_change_flow_protocol(ndpi_struct, flow, upper_detected_protocol, lower_detected_protocol); ndpi_int_change_packet_protocol(ndpi_struct, flow, upper_detected_protocol, lower_detected_protocol); } /* turns a packet back to unknown */ void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet) { int a; for(a = 0; a < NDPI_PROTOCOL_HISTORY_SIZE; a++) packet->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN; } void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow) { if(flow) { int a; for(a = 0; a < NDPI_PROTOCOL_HISTORY_SIZE; a++) { flow->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN; } } } 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 /* IPv6 */ if(packet->iphv6 != NULL) { if(packet->iphv6->ip6_src.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] && packet->iphv6->ip6_src.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] && packet->iphv6->ip6_src.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] && packet->iphv6->ip6_src.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3]) return 1; //else return 0; } #endif /* IPv4 */ 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 /* IPv6 */ if(packet->iphv6 != NULL) { if(packet->iphv6->ip6_dst.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] && packet->iphv6->ip6_dst.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] && packet->iphv6->ip6_dst.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] && packet->iphv6->ip6_dst.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3]) return 1; //else return 0; } #endif /* IPv4 */ if(packet->iph->saddr == 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 /* IPv6 */ if(packet->iphv6 != NULL) { ip->ipv6.u6_addr.u6_addr32[0] = packet->iphv6->ip6_src.u6_addr.u6_addr32[0]; ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_src.u6_addr.u6_addr32[1]; ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_src.u6_addr.u6_addr32[2]; ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_src.u6_addr.u6_addr32[3]; } else #endif /* IPv4 */ 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.u6_addr.u6_addr32[0] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[0]; ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[1]; ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[2]; ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[3]; } 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.u6_addr.u6_addr32[0] != 0 || ip->ipv6.u6_addr.u6_addr32[1] != 0 || ip->ipv6.u6_addr.u6_addr32[1] != 0 || ip->ipv6.u6_addr.u6_addr32[1] != 0) { const u_int16_t *b = ip->ipv6.u6_addr.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); } /* ****************************************************** */ ndpi_protocol 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) { ndpi_protocol p = NDPI_PROTOCOL_NULL; /* 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)) p.protocol = NDPI_PROTOCOL_SKYFILE_PREPAID; else if((sport == 4709) || (dport == 4709)) p.protocol = NDPI_PROTOCOL_SKYFILE_RUDICS; else if((sport == 4710) || (dport == 4710)) p.protocol = NDPI_PROTOCOL_SKYFILE_POSTPAID; } return(p); } /* ****************************************************** */ u_int8_t ndpi_is_proto(ndpi_protocol p, u_int16_t proto) { return(((p.protocol == proto) || (p.master_protocol == proto)) ? 1 : 0); } /* ****************************************************** */ u_int16_t ndpi_get_lower_proto(ndpi_protocol p) { return((p.master_protocol != NDPI_PROTOCOL_UNKNOWN) ? p.master_protocol : p.protocol); } /* ****************************************************** */ ndpi_protocol 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; ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; 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) { ret.protocol = rc, ret.master_protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport); if(ret.protocol == ret.master_protocol) ret.master_protocol = NDPI_PROTOCOL_UNKNOWN; return(ret); } rc = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport); if(rc != NDPI_PROTOCOL_UNKNOWN) { ret.protocol = rc; if(rc == NDPI_PROTOCOL_SSL) goto check_guessed_skype; else return(ret); } ret = ndpi_find_port_based_protocol(ndpi_struct, proto, shost, sport, dhost, dport); if(ret.protocol != NDPI_PROTOCOL_UNKNOWN) return(ret); check_guessed_skype: addr.s_addr = htonl(shost); if(ndpi_network_ptree_match(ndpi_struct, &addr) == NDPI_PROTOCOL_SKYPE) { ret.protocol = NDPI_PROTOCOL_SKYPE; } else { addr.s_addr = htonl(dhost); if(ndpi_network_ptree_match(ndpi_struct, &addr) == NDPI_PROTOCOL_SKYPE) ret.protocol = NDPI_PROTOCOL_SKYPE; } } else ret.protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport); return(ret); } /* ****************************************************** */ char* ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol proto, char *buf, u_int buf_len) { if(proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) { snprintf(buf, buf_len, "%s.%s", ndpi_get_proto_name(ndpi_mod, proto.master_protocol), ndpi_get_proto_name(ndpi_mod, proto.protocol)); } else snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_mod, proto.protocol)); return(buf); } /* ****************************************************** */ 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, u_int16_t master_protocol_id) { 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_host_subprotocol(%s): %s\n", m, ndpi_struct->proto_defaults[matching_protocol_id].protoName); } #endif if(matching_protocol_id != NDPI_PROTOCOL_UNKNOWN) { /* Move the protocol on slot 0 down one position */ packet->detected_protocol_stack[1] = master_protocol_id, packet->detected_protocol_stack[0] = matching_protocol_id; flow->detected_protocol_stack[0] = packet->detected_protocol_stack[0], flow->detected_protocol_stack[1] = packet->detected_protocol_stack[1]; 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_host_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, char *string_to_match, u_int string_to_match_len, u_int16_t master_protocol_id) { return(ndpi_automa_match_string_subprotocol(ndpi_struct, &ndpi_struct->host_automa, flow, string_to_match, string_to_match_len, master_protocol_id)); } /* ****************************************************** */ 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, u_int16_t master_protocol_id) { return(ndpi_automa_match_string_subprotocol(ndpi_struct, &ndpi_struct->content_automa, flow, string_to_match, string_to_match_len, master_protocol_id)); } /* ****************************************************** */ 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); } } /* ****************************************************** */ char* ndpi_revision() { return(NDPI_GIT_RELEASE); } /* ****************************************************** */ #ifdef WIN32 /* int pthread_mutex_init(pthread_mutex_t *mutex, void *unused) { unused = NULL; *mutex = CreateMutex(NULL, FALSE, NULL); return *mutex == NULL ? -1 : 0; } int pthread_mutex_destroy(pthread_mutex_t *mutex) { return CloseHandle(*mutex) == 0 ? -1 : 0; } int pthread_mutex_lock(pthread_mutex_t *mutex) { return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1; } int pthread_mutex_unlock(pthread_mutex_t *mutex) { return ReleaseMutex(*mutex) == 0 ? -1 : 0; } */ /* http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/port/gettimeofday.c;h=75a91993b74414c0a1c13a2a09ce739cb8aa8a08;hb=HEAD */ int gettimeofday(struct timeval * tp, struct timezone * tzp) { /* FILETIME of Jan 1 1970 00:00:00. */ const unsigned __int64 epoch = (__int64)(116444736000000000); FILETIME file_time; SYSTEMTIME system_time; ULARGE_INTEGER ularge; GetSystemTime(&system_time); SystemTimeToFileTime(&system_time, &file_time); ularge.LowPart = file_time.dwLowDateTime; ularge.HighPart = file_time.dwHighDateTime; tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L); tp->tv_usec = (long) (system_time.wMilliseconds * 1000); return 0; } #endif int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b) { int i; for(i=0; i. * * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_AFP static void ndpi_int_afp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_AFP, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_afp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("AFP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/aimini.c000066400000000000000000000321221262705051000243320ustar00rootroot00000000000000/* * aimini.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_AIMINI static void ndpi_int_aimini_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , */ /* ndpi_protocol_type_t protocol_type */) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_AIMINI, NDPI_PROTOCOL_UNKNOWN); } 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); } void init_aimini_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Aimini", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/applejuice.c000066400000000000000000000050321262705051000252050ustar00rootroot00000000000000/* * applejuice.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_APPLEJUICE static void ndpi_int_applejuice_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_APPLEJUICE, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_applejuice_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("AppleJuice", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/armagetron.c000066400000000000000000000106431262705051000252270ustar00rootroot00000000000000/* * armagetron.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ARMAGETRON, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_armagetron_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Armagetron", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/attic/000077500000000000000000000000001262705051000240245ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/attic/flash.c000066400000000000000000000073531262705051000252750ustar00rootroot00000000000000/* * flash.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_FLASH static void ndpi_int_flash_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_FLASH); } 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/attic/ftp.c000066400000000000000000000377561262705051000250030ustar00rootroot00000000000000/* * ftp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #include "ndpi_utils.h" #ifdef NDPI_PROTOCOL_FTP static void ndpi_int_ftp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_FTP); } /** * 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/attic/manolito.c000066400000000000000000000155071262705051000260220ustar00rootroot00000000000000/* * manolito.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_MANOLITO static void ndpi_int_manolito_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MANOLITO); 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/attic/popo.c000066400000000000000000000061541262705051000251530ustar00rootroot00000000000000/* * popo.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_POPO static void ndpi_int_popo_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_POPO); } 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/attic/secondlife.c000066400000000000000000000131071262705051000263050ustar00rootroot00000000000000/* * secondlife.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_utils.h" #ifdef NDPI_PROTOCOL_SECONDLIFE static void ndpi_int_secondlife_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , */ /* ndpi_protocol_type_t protocol_type */) { ndpi_set_detected_protocol(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); 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); 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); 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); 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ayiya.c000066400000000000000000000047341262705051000242100ustar00rootroot00000000000000/* * ayiya.c * * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ /* http://en.wikipedia.org/wiki/Anything_In_Anything http://tools.ietf.org/html/rfc4891 */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_AYIYA struct ayiya { u_int8_t flags[3]; u_int8_t next_header; u_int32_t epoch; u_int8_t identity[16]; u_int8_t signature[20]; }; void ndpi_search_ayiya(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if(packet->udp && (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)) { /* Ayiya is udp based, port 5072 */ if ((packet->udp->source == htons(5072) || packet->udp->dest == htons(5072)) /* check for ayiya new packet */ && (packet->payload_packet_len > 44) ) { /* FINISH */ struct ayiya *a = (struct ayiya*)packet->payload; u_int32_t epoch = ntohl(a->epoch), now; u_int32_t fireyears = 86400 * 365 * 5; now = flow->packet.tick_timestamp; if((epoch >= (now - fireyears)) && (epoch <= (now+86400 /* 1 day */))) ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_AYIYA, NDPI_PROTOCOL_UNKNOWN); return; } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_AYIYA); } } void init_ayiya_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Ayiya", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_AYIYA, ndpi_search_ayiya, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/battlefield.c000066400000000000000000000124031262705051000253430ustar00rootroot00000000000000/* * battlefield.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_BATTLEFIELD static void ndpi_int_battlefield_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BATTLEFIELD, NDPI_PROTOCOL_UNKNOWN); 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; } void init_battlefield_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("BattleField", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_BATTLEFIELD, ndpi_search_battlefield, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/bgp.c000066400000000000000000000047431262705051000236440ustar00rootroot00000000000000/* * bgp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_BGP static void ndpi_int_bgp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BGP, NDPI_PROTOCOL_UNKNOWN); } /* 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); } void init_bgp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("BGP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/bittorrent.c000066400000000000000000000434431262705051000252700ustar00rootroot00000000000000/* * bittorrent.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_BITTORRENT #define NDPI_PROTOCOL_UNSAFE_DETECTION 0 #define NDPI_PROTOCOL_SAFE_DETECTION 1 #define NDPI_PROTOCOL_PLAIN_DETECTION 0 #define NDPI_PROTOCOL_WEBSEED_DETECTION 2 static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, const u_int8_t save_detection, const u_int8_t encrypted_connection/* , */ /* ndpi_protocol_type_t protocol_type */) { ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BITTORRENT, NDPI_PROTOCOL_UNKNOWN); } 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; 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; int no_bittorrent = 0; /* This is broadcast */ if(packet->iph && (((packet->iph->saddr == 0xFFFFFFFF) || (packet->iph->daddr == 0xFFFFFFFF)) || (packet->udp && ((ntohs(packet->udp->source) == 3544) /* teredo.c */ || (ntohs(packet->udp->dest) == 3544))))) { NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BITTORRENT); 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) { char *bt_search = "BT-SEARCH * HTTP/1.1\r\n"; 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 */) { if(strncmp((const char*)packet->payload, bt_search, strlen(bt_search)) == 0) { ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ /* NDPI_REAL_PROTOCOL */); return; } else { /* 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; now = (u_int32_t)time(NULL); 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); } } } void init_bittorrent_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("BitTorrent", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_BITTORRENT, ndpi_search_bittorrent, NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/btlib.c000066400000000000000000000304451262705051000241660ustar00rootroot00000000000000/* * btlib.c * * Copyright (C) 2011-15 - ntop.org * Contributed by Vitaly Lavrov * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #ifndef NDPI_NO_STD_INC #include #include #include #include #include typedef unsigned char u_int8_t; typedef unsigned short int u_int16_t; typedef unsigned long long int u_int64_t; #include #include #include #endif typedef signed long long int i_int64_t; #include "btlib.h" 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; } #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; } nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/btlib.h000066400000000000000000000063141262705051000241710ustar00rootroot00000000000000/* * btlib.h * * Copyright (C) 2011-15 - ntop.org * Contributed by Vitaly Lavrov * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #define BDEC_MAXDEPT 8 typedef struct b_elem_s { const u_int8_t *s; size_t l; } b_elem_s_t; struct __attribute__ ((__packed__)) bt_nodes_data { u_int8_t id[20] ; u_int32_t ip; u_int16_t port; }; struct __attribute__ ((__packed__)) bt_ipv4p { u_int32_t ip; u_int16_t port; }; struct __attribute__ ((__packed__)) bt_ipv4p2 { struct bt_ipv4p d; u_int8_t pad[2]; }; struct __attribute__ ((__packed__)) bt_nodes6_data { u_int8_t id[20] ; u_int32_t ip[4]; u_int16_t port; }; struct __attribute__ ((__packed__)) bt_ipv6p { u_int32_t ip[4]; u_int16_t port; }; struct __attribute__ ((__packed__)) bt_ipv6p2 { struct bt_ipv6p d; u_int8_t pad[3]; }; /* a.id S r.id S a.info_hash S r.ip ipv4 a.name S r.nodes x(id,ipv4,port) -a.noseed 0|1 r.n S name of file a.port N r.p port -a.scrape 0|1 r.token S -a.seed 0|1 r.values x(ipv4,port) a.target S a.token S -a.vote N -a.want n4|n6 q announce_peer q find_node q get_peers q ping -q vote ip ipv4+port interval N min interval N peers x(ipv4,port) t 2/4/8b v 4/6b e S y e y r y q */ struct bt_parse_protocol { u_int16_t y_e:1, y_r:1, y_q:1, q_a_peer:1,q_f_node:1, q_g_peers:1,q_ping:1, h_int:1,h_mint:1,h_ip:1; struct { const u_int8_t *id, // 20 *info_hash, // 20 *target, // 20 *token, // 20|8 *name; // varlen u_int16_t name_len; u_int16_t port; u_int16_t t_len; } a; struct { const u_int8_t *id, // 20 *token, // 20|8 *values, // (6+2)*x *values6, // (18_3)*x *name; // varlen struct bt_ipv4p *ip; struct bt_nodes_data *nodes; struct bt_nodes6_data *nodes6; u_int16_t name_len; u_int16_t nn; // nodes num u_int16_t nv; // valuse num u_int16_t nn6; // nodes6 num u_int16_t nv6; // valuse6 num u_int16_t port; u_int16_t t_len; } r; int interval,min_interval; struct bt_ipv4p *peers; int n_peers; struct bt_ipv4p *ip; const u_int8_t *e_msg; u_int16_t e_len; u_int64_t t,v; }; typedef struct bt_parse_data_cb { struct bt_parse_protocol p; char buf[64]; int level; int t; union { i_int64_t i; b_elem_s_t s; } v; } bt_parse_data_cb_t; extern int bt_parse_debug; void dump_bt_proto_struct(struct bt_parse_protocol *p); const u_int8_t *bt_decode(const u_int8_t *b, size_t *l, int *ret, bt_parse_data_cb_t *cbd); nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ciscovpn.c000066400000000000000000000051411262705051000247110ustar00rootroot00000000000000/* * ciscovpn.c * Copyright (C) 2013 by Remy Mudingay * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_CISCOVPN static void ndpi_int_ciscovpn_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CISCOVPN, NDPI_PROTOCOL_UNKNOWN); } 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); } } void init_ciscovpn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("CiscoVPN", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_CISCOVPN, ndpi_search_ciscovpn, NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/citrix.c000066400000000000000000000065051262705051000243740ustar00rootroot00000000000000/* * citrix.c * * Copyright (C) 2012-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_CITRIX /* ************************************ */ static void ndpi_check_citrix(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; u_int32_t payload_len = packet->payload_packet_len; if(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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CITRIX, NDPI_PROTOCOL_UNKNOWN); } 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CITRIX, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_citrix_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Citrix", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/collectd.c000066400000000000000000000033431262705051000246600ustar00rootroot00000000000000/* * collectd.c * * Copyright (C) 2014 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_COLLECTD void ndpi_search_collectd(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; u_int len = 0; NDPI_LOG(NDPI_PROTOCOL_COLLECTD, ndpi_struct, NDPI_LOG_DEBUG, "search collectd.\n"); if (packet->udp == NULL) return; while(len < packet->payload_packet_len) { // u_int16_t elem_type = ntohs(*((u_int16_t*)&packet->payload[len])); u_int16_t elem_len = ntohs(*((u_int16_t*)&packet->payload[len+2])); if (elem_len == 0) break; len += elem_len; } if(len == packet->payload_packet_len) { NDPI_LOG(NDPI_PROTOCOL_COLLECTD, ndpi_struct, NDPI_LOG_DEBUG, "found COLLECTD.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_COLLECTD, NDPI_PROTOCOL_UNKNOWN); } 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/corba.c000066400000000000000000000044731262705051000241620ustar00rootroot00000000000000/* * corba.c * * Copyright (C) 2013 Remy Mudingay * * This module is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This module is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License. * If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_CORBA static void ndpi_int_corba_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CORBA, NDPI_PROTOCOL_UNKNOWN); } 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); } } void init_corba_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Corba", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/crossfire.c000066400000000000000000000070021262705051000250620ustar00rootroot00000000000000/* * crossfire.c * * Copyright (C) 2012-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ /* include files */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_CROSSFIRE static void ndpi_int_crossfire_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , ndpi_protocol_type_t protocol_type */) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CROSSFIRE, NDPI_PROTOCOL_UNKNOWN); } 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); 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); 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); } void init_crossfire_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Crossfire", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/dcerpc.c000066400000000000000000000045161262705051000243320ustar00rootroot00000000000000/* * dcerpc.c * * Copyright (C) 2011-13 by ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_DCERPC static void ndpi_int_dcerpc_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DCERPC, NDPI_PROTOCOL_UNKNOWN); } void ndpi_search_dcerpc(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; u_int16_t len_packet = (packet->payload[9]<<8) | packet->payload[8]; if((packet->tcp != NULL) && (packet->payload_packet_len >= 64) && (packet->payload[0] == 0x05) /* version 5 */ && (packet->payload[2] < 16) /* Packet type */ && (len_packet == packet->payload_packet_len) /* Packet Length */ ) { NDPI_LOG(NDPI_PROTOCOL_DCERPC, ndpi_struct, NDPI_LOG_DEBUG, "DCERPC match\n"); ndpi_int_dcerpc_add_connection(ndpi_struct, flow); return; } if(packet->payload_packet_len>1){ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DCERPC); } } void init_dcerpc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("DCE_RPC", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/dhcp.c000066400000000000000000000050111262705051000237770ustar00rootroot00000000000000/* * dhcp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_DHCP static void ndpi_int_dhcp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DHCP, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_dhcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("DHCP", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_DHCP, ndpi_search_dhcp_udp, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/dhcpv6.c000066400000000000000000000047161262705051000242660ustar00rootroot00000000000000/* * dhcpv6.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ /* include files */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_DHCPV6 static void ndpi_int_dhcpv6_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DHCPV6, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_dhcpv6_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("DHCPV6", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_DHCPV6, ndpi_search_dhcpv6_udp, NDPI_SELECTION_BITMASK_PROTOCOL_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/directconnect.c000066400000000000000000000415271262705051000257210ustar00rootroot00000000000000/* * directconnect.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_DIRECTCONNECT //#define NDPI_DEBUG_DIRECTCONNECT //#define NDPI_DIRECTCONNECT_PORT_DEBUG //#define NDPI_DEBUG_DIRECTCONNECT_CONN #define DIRECT_CONNECT_TYPE_HUB 0 #define DIRECT_CONNECT_TYPE_PEER 1 #define DIRECT_CONNECT_ADC_PEER 2 static u_int32_t skip_unknown_headers(const u_int8_t * payload, u_int32_t payload_len, u_int32_t pos) { u_int32_t i = pos; while (i < payload_len && payload[i] != 0x0a) i++; i++; return i; } static u_int16_t parse_binf_message(struct ndpi_detection_module_struct *ndpi_struct, const u_int8_t * payload, int payload_len) { u_int32_t i = 4; u_int16_t bytes_read = 0; u_int16_t ssl_port = 0; while (i < payload_len) { i = skip_unknown_headers(payload, payload_len, i); if ((i + 30) < payload_len) { if (memcmp(&payload[i], "DCTM", 4) == 0) { if (memcmp(&payload[i + 15], "ADCS", 4) == 0) { ssl_port = ntohs_ndpi_bytestream_to_number(&payload[i + 25], 5, &bytes_read); NDPI_LOG(NDPI_PROTOCOL_DIRECTCONNECT, ndpi_struct, NDPI_LOG_DEBUG, "directconnect ssl port parsed %d", ssl_port); } } } else { break; } } return ssl_port; } static void ndpi_int_directconnect_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, const u_int8_t connection_type) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_PROTOCOL_UNKNOWN); 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_PROTOCOL_UNKNOWN); 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_PROTOCOL_UNKNOWN); 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_PROTOCOL_UNKNOWN); 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_PROTOCOL_UNKNOWN); 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DIRECTCONNECT, NDPI_PROTOCOL_UNKNOWN); 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); } } void init_directconnect_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("DirectConnect", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/directdownloadlink.c000066400000000000000000001107221262705051000267470ustar00rootroot00000000000000/* * directdownloadlink.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-14svn - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK #ifdef NDPI_DEBUG_DIRECT_DOWNLOAD_LINK //#define NDPI_DEBUG_DIRECT_DOWNLOAD_LINK_NOTHING_FOUND //#define NDPI_DEBUG_DIRECT_DOWNLOAD_LINK_PACKET_TOO_SMALL #define NDPI_DEBUG_DIRECT_DOWNLOAD_LINK_IP #endif static void ndpi_int_direct_download_link_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, NDPI_PROTOCOL_UNKNOWN); 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; */ /* 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); } } void init_directdownloadlink_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Direct_Download_Link", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/dns.c000066400000000000000000000214061262705051000236530ustar00rootroot00000000000000/* * dns.c * * Copyright (C) 2012-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_DNS static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) { if(payload[i] == 0x00) return(1); else if(payload[i] == 0xC0) return(2); else { u_int8_t len = payload[i]; u_int8_t off = len + 1; if(off == 0) /* Bad packet */ return(0); else return(off + getNameLength(i+off, payload, payloadLen)); } } /* *********************************************** */ static char* ndpi_intoa_v4(unsigned int addr, char* buf, u_short bufLen) { char *cp, *retStr; uint byte; int n; cp = &buf[bufLen]; *--cp = '\0'; n = 4; do { byte = addr & 0xff; *--cp = byte % 10 + '0'; byte /= 10; if(byte > 0) { *--cp = byte % 10 + '0'; byte /= 10; if(byte > 0) *--cp = byte + '0'; } *--cp = '.'; addr >>= 8; } while (--n > 0); /* Convert the string to lowercase */ retStr = (char*)(cp+1); return(retStr); } /* *********************************************** */ static u_int16_t get16(int *i, const u_int8_t *payload) { u_int16_t v = *(u_int16_t*)&payload[*i]; (*i) += 2; return(ntohs(v)); } /* *********************************************** */ 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 ndpi_dns_packet_header))) { int i = packet->tcp ? 2 : 0; struct ndpi_dns_packet_header header, *dns = (struct ndpi_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 ndpi_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; 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); // Skip past the CLASS (2 octets) and TTL (4 octets) fields. i += 6; 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; int size_host_server_name = sizeof(flow->host_server_name); 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 < (size_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] != 0) { char a_buf[32]; int i; for(i=0; ihost_server_name[j], size_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_host_subprotocol(ndpi_struct, flow, (char *)flow->host_server_name, strlen((const char*)flow->host_server_name), NDPI_PROTOCOL_DNS); } 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_host_subprotocol() has matched a subprotocol */ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, (dport == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN); } } 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); } } } void init_dns_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("DNS", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/dofus.c000066400000000000000000000153351262705051000242130ustar00rootroot00000000000000/* * dofus.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_DOFUS static void ndpi_dofus_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DOFUS, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_dofus_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Dofus", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/dropbox.c000066400000000000000000000056321262705051000245470ustar00rootroot00000000000000/* * dropbox.c * * Copyright (C) 2011-13 by ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_DROPBOX static void ndpi_int_dropbox_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int8_t due_to_correlation) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DROPBOX, NDPI_PROTOCOL_UNKNOWN); } 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); } } } void init_dropbox_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("DROPBOX", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_DROPBOX, ndpi_search_dropbox, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/eaq.c000066400000000000000000000054051262705051000236360ustar00rootroot00000000000000/* * eaq.c * * Copyright (C) 2015 - 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 . * */ /* EAQ: Entitade Aferidora da Qualidade de Banda Larga http://www.brasilbandalarga.com.br */ #include "ndpi_api.h" #define EAQ_DEFAULT_PORT 6000 #define EAQ_DEFAULT_SIZE 16 #ifdef NDPI_PROTOCOL_EAQ static void ndpi_int_eaq_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_EAQ, NDPI_PROTOCOL_UNKNOWN); } void ndpi_search_eaq(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->udp->source), dport = ntohs(packet->udp->dest); if((packet->payload_packet_len != EAQ_DEFAULT_SIZE) || ((sport != EAQ_DEFAULT_PORT) && (dport != EAQ_DEFAULT_PORT))) { exclude_eaq: NDPI_LOG(NDPI_PROTOCOL_EAQ, ndpi_struct, NDPI_LOG_DEBUG, "Exclude eaq.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_EAQ); return; } if(packet->udp != NULL) { u_int32_t seq = (packet->payload[0] * 1000) + (packet->payload[1] * 100) + (packet->payload[2] * 10) + packet->payload[3]; if(flow->l4.udp.eaq_pkt_id == 0) flow->l4.udp.eaq_sequence = seq; else { if((flow->l4.udp.eaq_sequence == seq) || ((flow->l4.udp.eaq_sequence+1) == seq)) { ; /* Looks good */ } else goto exclude_eaq; } if(++flow->l4.udp.eaq_pkt_id == 4) { /* We have collected enough packets so we assume it's EAQ */ NDPI_LOG(NDPI_PROTOCOL_EAQ, ndpi_struct, NDPI_LOG_DEBUG, "found eaq.\n"); ndpi_int_eaq_add_connection(ndpi_struct, flow); } } else goto exclude_eaq; } void init_eaq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("EAQ", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_EAQ, ndpi_search_eaq, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/edonkey.c000066400000000000000000000162331262705051000245270ustar00rootroot00000000000000/* * edonkey.c * * Copyright (C) 2014 Tomasz Bujlow * * The signature is based on the Libprotoident library. * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_EDONKEY static void ndpi_int_edonkey_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_EDONKEY, NDPI_PROTOCOL_UNKNOWN); } 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); } } } void init_edonkey_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("eDonkey", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/fasttrack.c000066400000000000000000000070561262705051000250560ustar00rootroot00000000000000/* * fasttrack.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_FASTTRACK static void ndpi_int_fasttrack_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_FASTTRACK, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_fasttrack_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("FastTrack", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/fiesta.c000066400000000000000000000102441262705051000243400ustar00rootroot00000000000000/* * fiesta.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ /* include files */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_FIESTA static void ndpi_int_fiesta_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_FIESTA, NDPI_PROTOCOL_UNKNOWN); } 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; } void init_fiesta_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Fiesta", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/filetopia.c000066400000000000000000000067171262705051000250530ustar00rootroot00000000000000/* * filetopia.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_FILETOPIA static void ndpi_int_filetopia_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_FILETOPIA, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_filetopia_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Filetopia", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/florensia.c000066400000000000000000000131361262705051000250520ustar00rootroot00000000000000/* * florensia.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_FLORENSIA static void ndpi_florensia_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_FLORENSIA, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_florensia_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Florensia", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ftp_control.c000066400000000000000000000446061262705051000254270ustar00rootroot00000000000000/* * ftp_control.c * * Copyright (C) 2014 Tomasz Bujlow * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_FTP_CONTROL static void ndpi_int_ftp_control_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_FTP_CONTROL, NDPI_PROTOCOL_UNKNOWN); } 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); } } } void init_ftp_control_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("FTP_CONTROL", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ftp_data.c000066400000000000000000000213321262705051000246470ustar00rootroot00000000000000/* * ftp_data.c * * Copyright (C) 2014 Tomasz Bujlow * Copyright (C) 2014 - ntop.org * * The signature is based on the Libprotoident library. * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_FTP_DATA static void ndpi_int_ftp_data_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_FTP_DATA, NDPI_PROTOCOL_UNKNOWN); } static int ndpi_match_ftp_data_port(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if(packet->tcp->dest == htons(20) || packet->tcp->source == htons(20)) { return 1; } return 0; } static int ndpi_match_ftp_data_directory(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; u_int32_t payload_len = packet->payload_packet_len; if((payload_len >= 4) && ((packet->payload[0] == '-') || (packet->payload[0] == 'd')) && ((packet->payload[1] == '-') || (packet->payload[1] == 'r')) && ((packet->payload[2] == '-') || (packet->payload[2] == 'w')) && ((packet->payload[3] == '-') || (packet->payload[3] == 'x'))) { return 1; } return 0; } static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; /* A FTP packet is pretty long so 256 is a bit consrvative but it should be OK */ if(packet->payload_packet_len < 256) return 0; /* RIFF is a meta-format for storing AVI and WAV files */ if(match_first_bytes(packet->payload, "RIFF")) return 1; /* MZ is a .exe file */ if((packet->payload[0] == 'M') && (packet->payload[1] == 'Z') && (packet->payload[3] == 0x00)) return 1; /* Ogg files */ if(match_first_bytes(packet->payload, "OggS")) return 1; /* ZIP files */ if((packet->payload[0] == 'P') && (packet->payload[1] == 'K') && (packet->payload[2] == 0x03) && (packet->payload[3] == 0x04)) return 1; /* MPEG files */ if((packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x01) && (packet->payload[3] == 0xba)) return 1; /* RAR files */ if(match_first_bytes(packet->payload, "Rar!")) return 1; /* EBML */ if((packet->payload[0] == 0x1a) && (packet->payload[1] == 0x45) && (packet->payload[2] == 0xdf) && (packet->payload[3] == 0xa3)) return 1; /* JPG */ if((packet->payload[0] == 0xff) && (packet->payload[1] ==0xd8)) return 1; /* GIF */ if(match_first_bytes(packet->payload, "GIF8")) return 1; /* PHP scripts */ if((packet->payload[0] == 0x3c) && (packet->payload[1] == 0x3f) && (packet->payload[2] == 0x70) && (packet->payload[3] == 0x68)) return 1; /* Unix scripts */ if((packet->payload[0] == 0x23) && (packet->payload[1] == 0x21) && (packet->payload[2] == 0x2f) && (packet->payload[3] == 0x62)) return 1; /* PDFs */ if(match_first_bytes(packet->payload, "%PDF")) return 1; /* PNG */ if((packet->payload[0] == 0x89) && (packet->payload[1] == 'P') && (packet->payload[2] == 'N') && (packet->payload[3] == 'G')) return 1; /* HTML */ if(match_first_bytes(packet->payload, "payload[0] == 0x0a) && (packet->payload[1] == '<') && (packet->payload[2] == '!') && (packet->payload[3] == 'D')) return 1; /* 7zip */ if((packet->payload[0] == 0x37) && (packet->payload[1] == 0x7a) && (packet->payload[2] == 0xbc) && (packet->payload[3] == 0xaf)) return 1; /* gzip */ if((packet->payload[0] == 0x1f) && (packet->payload[1] == 0x8b) && (packet->payload[2] == 0x08)) return 1; /* XML */ if(match_first_bytes(packet->payload, "payload, "fLaC")) return 1; /* MP3 */ if((packet->payload[0] == 'I') && (packet->payload[1] == 'D') && (packet->payload[2] == '3') && (packet->payload[3] == 0x03)) return 1; if(match_first_bytes(packet->payload, "\xff\xfb\x90\xc0")) return 1; /* RPM */ if((packet->payload[0] == 0xed) && (packet->payload[1] == 0xab) && (packet->payload[2] == 0xee) && (packet->payload[3] == 0xdb)) return 1; /* Wz Patch */ if(match_first_bytes(packet->payload, "WzPa")) return 1; /* Flash Video */ if((packet->payload[0] == 'F') && (packet->payload[1] == 'L') && (packet->payload[2] == 'V') && (packet->payload[3] == 0x01)) return 1; /* .BKF (Microsoft Tape Format) */ if(match_first_bytes(packet->payload, "TAPE")) return 1; /* MS Office Doc file - this is unpleasantly geeky */ if((packet->payload[0] == 0xd0) && (packet->payload[1] == 0xcf) && (packet->payload[2] == 0x11) && (packet->payload[3] == 0xe0)) return 1; /* ASP */ if((packet->payload[0] == 0x3c) && (packet->payload[1] == 0x25) && (packet->payload[2] == 0x40) && (packet->payload[3] == 0x20)) return 1; /* WMS file */ if((packet->payload[0] == 0x3c) && (packet->payload[1] == 0x21) && (packet->payload[2] == 0x2d) && (packet->payload[3] == 0x2d)) return 1; /* ar archive, typically .deb files */ if(match_first_bytes(packet->payload, "!payload, "payload, "jabber", packet->payload_packet_len) == NULL)) return 1; if(match_first_bytes(packet->payload, "payload, "SPFI")) return 1; /* ABIF - Applied Biosystems */ if(match_first_bytes(packet->payload, "ABIF")) return 1; /* bzip2 - other digits are also possible instead of 9 */ if((packet->payload[0] == 'B') && (packet->payload[1] == 'Z') && (packet->payload[2] == 'h') && (packet->payload[3] == '9')) return 1; /* Some other types of files */ if((packet->payload[0] == '<') && (packet->payload[1] == 'c') && (packet->payload[2] == 'f')) return 1; if((packet->payload[0] == '<') && (packet->payload[1] == 'C') && (packet->payload[2] == 'F')) return 1; if(match_first_bytes(packet->payload, ".tem")) return 1; if(match_first_bytes(packet->payload, ".ite")) return 1; if(match_first_bytes(packet->payload, ".lef")) return 1; return 0; } static void ndpi_check_ftp_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if((packet->payload_packet_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...\n"); ndpi_int_ftp_data_add_connection(ndpi_struct, flow); } else NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FTP_DATA); } 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; } NDPI_LOG(NDPI_PROTOCOL_FTP_DATA, ndpi_struct, NDPI_LOG_DEBUG, "FTP_DATA detection...\n"); ndpi_check_ftp_data(ndpi_struct, flow); } void init_ftp_data_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("FTP_DATA", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_FTP_DATA, ndpi_search_ftp_data, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/gnutella.c000066400000000000000000000421601262705051000247020ustar00rootroot00000000000000/* * gnutella.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ /* include files */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_GNUTELLA static void ndpi_int_gnutella_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , */ /* ndpi_protocol_type_t protocol_type */) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_GNUTELLA, NDPI_PROTOCOL_UNKNOWN); 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); 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); 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); 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); } } /* 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); } } /* 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); 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); 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); 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); 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); 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); 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); 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); } /* 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); return; } } } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GNUTELLA); } void init_gnutella_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Gnutella", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/gtp.c000066400000000000000000000057011262705051000236610ustar00rootroot00000000000000/* * gtp.c * * Copyright (C) 2011-15 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_GTP struct gtp_header_generic { u_int8_t flags, message_type; u_int16_t message_len; u_int32_t teid; }; static void ndpi_check_gtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // const u_int8_t *packet_payload = packet->payload; u_int32_t payload_len = packet->payload_packet_len; if((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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_GTP, NDPI_PROTOCOL_UNKNOWN); 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); } void init_gtp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("GTP", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_GTP, ndpi_search_gtp, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/guildwars.c000066400000000000000000000063641262705051000250760ustar00rootroot00000000000000/* * guildwars.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_GUILDWARS, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_guildwars_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Guildwars", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/h323.c000066400000000000000000000071271262705051000235520ustar00rootroot00000000000000/* * h323.c * * Copyright (C) 2015 ntop.org * Copyright (C) 2013 Remy Mudingay * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_H323 struct tpkt { u_int8_t version, reserved; u_int16_t len; }; void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; u_int16_t dport = 0, sport = 0; NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "search H323.\n"); if(packet->tcp != NULL) { NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over tcp.\n"); /* H323 */ if((packet->payload[0] == 0x03) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) { struct tpkt *t = (struct tpkt*)packet->payload; u_int16_t len = ntohs(t->len); if(packet->payload_packet_len == len) { /* We need to check if this packet is in reality a RDP (Remote Desktop) packet encapsulated on TPTK */ if(packet->payload[4] == (packet->payload_packet_len - sizeof(struct tpkt) - 1)) { /* ISO 8073/X.224 */ if((packet->payload[5] == 0xE0 /* CC Connect Request */) || (packet->payload[5] == 0xD0 /* CC Connect Confirm */)) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RDP, NDPI_PROTOCOL_UNKNOWN); 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_PROTOCOL_UNKNOWN); } } 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_PROTOCOL_UNKNOWN); 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_PROTOCOL_UNKNOWN); 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_PROTOCOL_UNKNOWN); return; } else { NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_H323); return; } } } } void init_h323_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("H323", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_H323, ndpi_search_h323, NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/halflife2_and_mods.c000066400000000000000000000055501262705051000265710ustar00rootroot00000000000000/* * halflife2_and_mods.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_HALFLIFE2 static void ndpi_int_halflife2_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HALFLIFE2, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_halflife2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("HalfLife2", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_HALFLIFE2, ndpi_search_halflife2, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/hep.c000066400000000000000000000045541262705051000236500ustar00rootroot00000000000000/* * hep.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * Copyright (C) 2011-15 - QXIP BV * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_HEP static void ndpi_int_hep_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HEP, NDPI_PROTOCOL_UNKNOWN); } void ndpi_search_hep(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; NDPI_LOG(NDPI_PROTOCOL_HEP, ndpi_struct, NDPI_LOG_DEBUG, "searching for HEP.\n"); if (payload_len > 10) { if (memcmp(packet_payload, "HEP3", 4) == 0) { NDPI_LOG(NDPI_PROTOCOL_HEP, ndpi_struct, NDPI_LOG_DEBUG, "found HEP3.\n"); ndpi_int_hep_add_connection(ndpi_struct, flow); return; } } NDPI_LOG(NDPI_PROTOCOL_HEP, ndpi_struct, NDPI_LOG_DEBUG, "exclude HEP.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HEP); } void init_hep_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("HEP", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_HEP, ndpi_search_hep, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/http.c000066400000000000000000001260071262705051000240510ustar00rootroot00000000000000/* * http.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_HTTP static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int32_t protocol) { if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { /* This is HTTP and it is not a sub protocol (e.g. skype or dropbox) */ ndpi_search_tcp_or_udp(ndpi_struct, flow); /* If no custom protocol has been detected */ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { if(protocol != NDPI_PROTOCOL_HTTP) { ndpi_search_tcp_or_udp(ndpi_struct, flow); ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); } else { ndpi_int_reset_protocol(flow); ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); } } 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, packet->detected_protocol_stack[1] = NDPI_PROTOCOL_HTTP; 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, packet->detected_protocol_stack[1] = NDPI_PROTOCOL_HTTP; return; } } if((flow->l4.tcp.http_stage == 0) || (flow->http.url && flow->http_detected)) { /* Try matching subprotocols */ // ndpi_match_host_subprotocol(ndpi_struct, flow, (char*)packet->host_line.ptr, packet->host_line.len); /* NOTE If http_dont_dissect_response = 1 dissection of HTTP response mime types won't happen */ if(!ndpi_struct->http_dont_dissect_response) { if(flow->http.url && flow->http_detected) ndpi_match_host_subprotocol(ndpi_struct, flow, (char *)&flow->http.url[7], strlen((const char *)&flow->http.url[7]), NDPI_PROTOCOL_HTTP); } else ndpi_match_host_subprotocol(ndpi_struct, flow, (char *)flow->host_server_name, strlen((const char *)flow->host_server_name), NDPI_PROTOCOL_HTTP); } } /* 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_dont_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); } /* 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_dont_dissect_response) || flow->http_detected) ndpi_match_host_subprotocol(ndpi_struct, flow, (char*)packet->host_line.ptr, packet->host_line.len, NDPI_PROTOCOL_HTTP); /* 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_dont_dissect_response) parseHttpSubprotocol(ndpi_struct, flow); if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) && ((ndpi_struct->http_dont_dissect_response) || flow->http_detected)) ndpi_match_host_subprotocol(ndpi_struct, flow, (char *)flow->host_server_name, strlen((const char *)flow->host_server_name), NDPI_PROTOCOL_HTTP); if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) && ((ndpi_struct->http_dont_dissect_response) || flow->http_detected) && (packet->http_origin.len > 0)) ndpi_match_host_subprotocol(ndpi_struct, flow, (char *)packet->http_origin.ptr, packet->http_origin.len, NDPI_PROTOCOL_HTTP); 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_dont_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_dont_dissect_response) || flow->http_detected) ndpi_match_content_subprotocol(ndpi_struct, flow, (char*)packet->content_line.ptr, packet->content_line.len, NDPI_PROTOCOL_HTTP); } /* 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_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; packet->packet_lines_parsed_complete = 0; /* 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"); 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_dont_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 } check_content_type_and_change_protocol(ndpi_struct, flow); 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); } void init_http_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("HTTP",ndpi_struct, detection_bitmask, *id, 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); *id += 1; #if 0 ndpi_set_bitmask_protocol_detection("HTTP_Proxy", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #ifdef NDPI_CONTENT_MPEG ndpi_set_bitmask_protocol_detection("MPEG", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_FLASH ndpi_set_bitmask_protocol_detection("Flash", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_QUICKTIME ndpi_set_bitmask_protocol_detection("QuickTime", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_REALMEDIA ndpi_set_bitmask_protocol_detection("RealMedia", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_WINDOWSMEDIA ndpi_set_bitmask_protocol_detection("WindowsMedia", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_MMS ndpi_set_bitmask_protocol_detection("MMS", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_PROTOCOL_XBOX ndpi_set_bitmask_protocol_detection("Xbox", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_PROTOCOL_QQ ndpi_set_bitmask_protocol_detection("QQ", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_AVI ndpi_set_bitmask_protocol_detection("AVI", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_OGG ndpi_set_bitmask_protocol_detection("OggVorbis", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_PROTOCOL_MOVE ndpi_set_bitmask_protocol_detection("Move", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #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 } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/http_activesync.c000066400000000000000000000050141262705051000262730ustar00rootroot00000000000000/* * http_activesync.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC static void ndpi_int_activesync_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_APPLICATION_ACTIVESYNC, NDPI_PROTOCOL_HTTP); } 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); } void init_http_activesync_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("HTTP_Application_ActiveSync", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/iax.c000066400000000000000000000073061262705051000236530ustar00rootroot00000000000000/* * iax.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_IAX #define NDPI_IAX_MAX_INFORMATION_ELEMENTS 15 static void ndpi_int_iax_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_IAX, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_iax_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("IAX", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_IAX, ndpi_search_iax, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/icecast.c000066400000000000000000000073061262705051000245050ustar00rootroot00000000000000/* * icecast.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_ICECAST static void ndpi_int_icecast_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ICECAST, NDPI_PROTOCOL_UNKNOWN); } 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"); } void init_icecast_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("IceCast", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/imesh.c000066400000000000000000000376611262705051000242060ustar00rootroot00000000000000/* * imesh.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_IMESH static void ndpi_int_imesh_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , ndpi_protocol_type_t protocol_type */) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_IMESH, NDPI_PROTOCOL_UNKNOWN); } 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); } void init_imesh_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("iMESH", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ipp.c000066400000000000000000000107111262705051000236540ustar00rootroot00000000000000/* * ipp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_IPP static void ndpi_int_ipp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , ndpi_protocol_type_t protocol_type */) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_IPP, NDPI_PROTOCOL_UNKNOWN); } 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); 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); 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); } void init_ipp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("IPP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/irc.c000066400000000000000000000775031262705051000236550ustar00rootroot00000000000000/* * irc.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_IRC #define NDPI_IRC_FIND_LESS(time_err,less) {int t1 = 0; \ u_int32_t timestamp = time_err[0]; \ for(t1=0;t1 < NDPI_PROTOCOL_IRC_MAXPORT;t1++) { \ if(timestamp > time_err[t1]) { \ timestamp = time_err[t1]; \ less = t1;}}} static void ndpi_int_irc_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_IRC, NDPI_PROTOCOL_UNKNOWN); } #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 = (u_int16_t)((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++; } } } } } } } } } void init_irc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("IRC", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/jabber.c000066400000000000000000000301301262705051000243060ustar00rootroot00000000000000/* * jabber.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER struct jabber_string { char *string; u_int ndpi_protocol; }; static struct jabber_string jabber_strings[] = { #ifdef NDPI_PROTOCOL_TRUPHONE { "='im.truphone.com'", NDPI_PROTOCOL_TRUPHONE }, { "=\"im.truphone.com\"", NDPI_PROTOCOL_TRUPHONE }, #endif { 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_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); } 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); 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); } } 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); } } return; } if (packet->tcp != 0 && packet->payload_packet_len == 0) { return; } /* this part parses a packet and searches for port=. it works asymmetrically. */ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNENCRYPED_JABBER) { u_int16_t lastlen; u_int16_t j_port = 0; /* check for google jabber voip connections ... */ /* need big packet */ if (packet->payload_packet_len < 100) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "packet too small, return.\n"); return; } /* need message to or type for file-transfer */ if (memcmp(packet->payload, "payload, "payload_packet_len - 11; for (x = 10; x < lastlen; x++) { if (packet->payload[x] == 'p') { if (memcmp(&packet->payload[x], "port=", 5) == 0) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "port=\n"); if (src != NULL) { src->jabber_stun_or_ft_ts = packet->tick_timestamp; } if (dst != NULL) { dst->jabber_stun_or_ft_ts = packet->tick_timestamp; } x += 6; j_port = ntohs_ndpi_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x); NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER port : %u\n", ntohs(j_port)); if (src != NULL) { if (src->jabber_file_transfer_port[0] == 0 || src->jabber_file_transfer_port[0] == j_port) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port)); src->jabber_file_transfer_port[0] = j_port; } else { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[1] = j_port = %u;\n", ntohs(j_port)); src->jabber_file_transfer_port[1] = j_port; } } if (dst != NULL) { if (dst->jabber_file_transfer_port[0] == 0 || dst->jabber_file_transfer_port[0] == j_port) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port)); dst->jabber_file_transfer_port[0] = j_port; } else { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[1] = j_port = %u;\n", ntohs(j_port)); dst->jabber_file_transfer_port[1] = j_port; } } } } } } else if (memcmp(packet->payload, "payload, "payload, "payload_packet_len - 21; for (x = 8; x < lastlen; x++) { /* invalid character */ if (packet->payload[x] < 32 || packet->payload[x] > 127) { return; } if (packet->payload[x] == '@') { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER @\n"); break; } } if (x >= lastlen) { return; } lastlen = packet->payload_packet_len - 10; for (; x < lastlen; x++) { if (packet->payload[x] == 'p') { if (memcmp(&packet->payload[x], "port=", 5) == 0) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "port=\n"); if (src != NULL) { src->jabber_stun_or_ft_ts = packet->tick_timestamp; } if (dst != NULL) { dst->jabber_stun_or_ft_ts = packet->tick_timestamp; } x += 6; j_port = ntohs_ndpi_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x); NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER port : %u\n", ntohs(j_port)); if (src != NULL && src->jabber_voice_stun_used_ports < JABBER_MAX_STUN_PORTS - 1) { if (packet->payload[5] == 'o') { src->jabber_voice_stun_port[src->jabber_voice_stun_used_ports++] = j_port; } else { if (src->jabber_file_transfer_port[0] == 0 || src->jabber_file_transfer_port[0] == j_port) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port)); src->jabber_file_transfer_port[0] = j_port; } else { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[1] = j_port = %u;\n", ntohs(j_port)); src->jabber_file_transfer_port[1] = j_port; } } } if (dst != NULL && dst->jabber_voice_stun_used_ports < JABBER_MAX_STUN_PORTS - 1) { if (packet->payload[5] == 'o') { dst->jabber_voice_stun_port[dst->jabber_voice_stun_used_ports++] = j_port; } else { if (dst->jabber_file_transfer_port[0] == 0 || dst->jabber_file_transfer_port[0] == j_port) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port)); dst->jabber_file_transfer_port[0] = j_port; } else { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[1] = j_port = %u;\n", ntohs(j_port)); dst->jabber_file_transfer_port[1] = j_port; } } } return; } } } } return; } /* search for jabber here */ /* this part is working asymmetrically */ if ((packet->payload_packet_len > 13 && memcmp(packet->payload, "payload_packet_len >= NDPI_STATICSTRING_LEN("payload, "payload_packet_len-13; if(ndpi_strnstr((const char *)&packet->payload[13], "xmlns:stream='http://etherx.jabber.org/streams'", start) || ndpi_strnstr((const char *)&packet->payload[13], "xmlns:stream=\"http://etherx.jabber.org/streams\"", start)) { /* Protocol family */ ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER); /* 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 } void init_jabber_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Unencryped_Jabber", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/kakaotalk_voice.c000066400000000000000000000045501262705051000262170ustar00rootroot00000000000000/* * kakaotalk_voice.c * * Copyright (C) 2015 - 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 . * */ /* KakaoTalk (call only) http://www.kakao.com/services/talk/voices */ #include "ndpi_api.h" #ifdef NDPI_SERVICE_KAKAOTALK_VOICE void ndpi_search_kakaotalk_voice(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if(packet->iph && packet->udp && (packet->payload_packet_len > 0) ) { if((packet->payload[0] == 0x81) || (packet->payload[1] == 0xC8) || (packet->payload[2] == 0x00) || (packet->payload[3] == 0x0C)) { /* Looks good so far */ /* inetnum: 1.201.0.0 - 1.201.255.255 netname: KINXINC-KR */ if(((ntohl(packet->iph->saddr) & 0xFFFF0000 /* 255.255.0.0 */) == 0x01C90000 /* 1.201.0.0/16 */) || ((ntohl(packet->iph->daddr) & 0xFFFF0000 /* 255.255.0.0 */) == 0x01C90000 /* 1.201.0.0/16 */)) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_SERVICE_KAKAOTALK_VOICE, NDPI_PROTOCOL_UNKNOWN); return; } } } NDPI_LOG(NDPI_SERVICE_KAKAOTALK_VOICE, ndpi_struct, NDPI_LOG_DEBUG, "Exclude kakaotalk_voice.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_SERVICE_KAKAOTALK_VOICE); } void init_kakaotalk_voice_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("KakaoTalk_Voice", ndpi_struct, detection_bitmask, *id, NDPI_SERVICE_KAKAOTALK_VOICE, ndpi_search_kakaotalk_voice, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/kerberos.c000066400000000000000000000060331262705051000247020ustar00rootroot00000000000000/* * kerberos.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_KERBEROS, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_kerberos_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Kerberos", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/kontiki.c000066400000000000000000000055011262705051000245350ustar00rootroot00000000000000/* * kontiki.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_KONTIKI static void ndpi_int_kontiki_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_KONTIKI, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_kontiki_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Kontiki", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_KONTIKI, ndpi_search_kontiki, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ldap.c000066400000000000000000000075701262705051000240150ustar00rootroot00000000000000/* * ldap.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_LDAP, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_ldap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("LDAP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/lotus_notes.c000066400000000000000000000056361262705051000254540ustar00rootroot00000000000000/* * lotus_notes.c * * Copyright (C) 2012-15 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_LOTUS_NOTES /* ************************************ */ static void ndpi_check_lotus_notes(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // const u_int8_t *packet_payload = packet->payload; u_int32_t payload_len = packet->payload_packet_len; if(packet->tcp != NULL) { flow->l4.tcp.lotus_notes_packet_id++; if((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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_LOTUS_NOTES, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_lotus_notes_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("LotusNotes", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/mail_imap.c000066400000000000000000000410261262705051000250170ustar00rootroot00000000000000/* * mail_imap.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_MAIL_IMAP static void ndpi_int_mail_imap_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_IMAP, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_mail_imap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("MAIL_IMAP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/mail_pop.c000066400000000000000000000210251262705051000246640ustar00rootroot00000000000000/* * mail_pop.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_MAIL_POP #define POP_BIT_AUTH 0x0001 #define POP_BIT_APOP 0x0002 #define POP_BIT_USER 0x0004 #define POP_BIT_PASS 0x0008 #define POP_BIT_CAPA 0x0010 #define POP_BIT_LIST 0x0020 #define POP_BIT_STAT 0x0040 #define POP_BIT_UIDL 0x0080 #define POP_BIT_RETR 0x0100 #define POP_BIT_DELE 0x0200 #define POP_BIT_STLS 0x0400 static void ndpi_int_mail_pop_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_POP, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_mail_pop_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("MAIL_POP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/mail_smtp.c000066400000000000000000000201201262705051000250440ustar00rootroot00000000000000/* * mail_smtp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_MAIL_SMTP #define SMTP_BIT_220 0x01 #define SMTP_BIT_250 0x02 #define SMTP_BIT_235 0x04 #define SMTP_BIT_334 0x08 #define SMTP_BIT_354 0x10 #define SMTP_BIT_HELO_EHLO 0x20 #define SMTP_BIT_MAIL 0x40 #define SMTP_BIT_RCPT 0x80 #define SMTP_BIT_AUTH 0x100 #define SMTP_BIT_STARTTLS 0x200 #define SMTP_BIT_DATA 0x400 #define SMTP_BIT_NOOP 0x800 #define SMTP_BIT_RSET 0x1000 #define SMTP_BIT_TlRM 0x2000 static void ndpi_int_mail_smtp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_SMTP, NDPI_PROTOCOL_UNKNOWN); } 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[4] == 't') && (packet->line[a].ptr[5] == 'T' || packet->line[a].ptr[5] == 't') && (packet->line[a].ptr[6] == 'L' || packet->line[a].ptr[6] == 'l') && (packet->line[a].ptr[7] == 'S' || packet->line[a].ptr[7] == '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); } void init_mail_smtp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("MAIL_SMTP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/maplestory.c000066400000000000000000000102171262705051000252640ustar00rootroot00000000000000/* * maplestory.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_MAPLESTORY static void ndpi_int_maplestory_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MAPLESTORY, NDPI_PROTOCOL_UNKNOWN); } 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); 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); 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); 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); } void init_maplestory_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("MapleStory", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/mdns.c000066400000000000000000000125141262705051000240300ustar00rootroot00000000000000/* * mdns.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_MDNS #define NDPI_MAX_MDNS_REQUESTS 128 static void ndpi_int_mdns_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MDNS, NDPI_PROTOCOL_UNKNOWN); } 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->ip6_dst.u6_addr.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); } void init_mdns_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("MDNS", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_MDNS, ndpi_search_mdns, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/meebo.c000066400000000000000000000162661262705051000241660ustar00rootroot00000000000000/* * meebo.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_MEEBO static void ndpi_int_meebo_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MEEBO, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_meebo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Meebo", ndpi_struct, detection_bitmask, *id, 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[*id].detection_bitmask, NDPI_CONTENT_FLASH); #endif *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/megaco.c000066400000000000000000000046731262705051000243310ustar00rootroot00000000000000/* * megaco.c * * Copyright (C) 2014 by Gianluca Costa http://www.capanalysis.net * Copyright (C) 2012-15 - ntop.org * * This module is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This module is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License. * If not, see . */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_MEGACO void ndpi_search_megaco(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; NDPI_LOG(NDPI_PROTOCOL_MEGACO, ndpi_struct, NDPI_LOG_DEBUG, "search for MEGACO.\n"); if(packet->udp != NULL) { if((packet->payload_packet_len > 4 && packet->payload[0] == '!' && packet->payload[1] == '/' && packet->payload[2] == '1' && packet->payload[3] == ' ' && packet->payload[4] == '[') || (packet->payload_packet_len > 9 && packet->payload[0] == 'M' && packet->payload[1] == 'E' && packet->payload[2] == 'G' && packet->payload[3] == 'A' && packet->payload[4] == 'C' && packet->payload[5] == 'O' && packet->payload[6] == '/' && packet->payload[7] == '1' && packet->payload[8] == ' ' && packet->payload[9] == '[')) { NDPI_LOG(NDPI_PROTOCOL_MEGACO, ndpi_struct, NDPI_LOG_DEBUG, "found MEGACO.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MEGACO, NDPI_PROTOCOL_UNKNOWN); 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); } void init_megaco_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Megaco", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_MEGACO, ndpi_search_megaco, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/mgcp.c000066400000000000000000000072151262705051000240170ustar00rootroot00000000000000/* * mgcp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_MGCP static void ndpi_int_mgcp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MGCP, NDPI_PROTOCOL_UNKNOWN); } #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); } void init_mgpc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("MGCP", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_MGCP, ndpi_search_mgcp, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/mms.c000066400000000000000000000065521262705051000236700ustar00rootroot00000000000000/* * mms.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_CONTENT_MMS static void ndpi_int_mms_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_CONTENT_MMS, NDPI_PROTOCOL_UNKNOWN); } 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 */ } void init_mms_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("MMS", ndpi_struct, detection_bitmask, *id, NDPI_CONTENT_MMS, ndpi_search_mms_tcp, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/mpegts.c000066400000000000000000000042061262705051000243650ustar00rootroot00000000000000/* * mpegts.c (MPEG Transport Stream) * https://en.wikipedia.org/wiki/MPEG_transport_stream * * Copyright (C) 2015 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_MPEGTS void ndpi_search_mpegts(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_MPEGTS, ndpi_struct, NDPI_LOG_DEBUG, "search for MPEGTS.\n"); if((packet->udp != NULL) && ((packet->payload_packet_len % 188) == 0)) { u_int i, num_chunks = packet->payload_packet_len / 188; for(i=0; ipayload[offset] != 0x47) goto no_mpegts; } /* This looks MPEG TS */ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MPEGTS, NDPI_PROTOCOL_UNKNOWN); return; } no_mpegts: NDPI_LOG(NDPI_PROTOCOL_MPEGTS, ndpi_struct, NDPI_LOG_DEBUG, "Excluded MPEGTS.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MPEGTS); } void init_mpegts_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("MPEG_TS", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_MPEGTS, ndpi_search_mpegts, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/msn.c000066400000000000000000000537741262705051000237010ustar00rootroot00000000000000/* * msn.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_MSN #define MAX_PACKETS_FOR_MSN 100 static void ndpi_int_msn_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , */ /* ndpi_protocol_type_t protocol_type */) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MSN, NDPI_PROTOCOL_UNKNOWN); } 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); 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); } 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); } else { ndpi_int_msn_add_connection(ndpi_struct, flow); } 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); 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); 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); 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); return; } } } /* now test for http login that uses a gateway, at least 400 a bytes packet */ /* for this case the asymmetric detection is asym (1) */ if (packet->payload_packet_len > 400) { if (( #ifdef NDPI_PROTOCOL_HTTP packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || #endif (memcmp(packet->payload, "POST ", 5) == 0))) { u_int16_t c; if (memcmp(&packet->payload[5], "http://", 7) == 0) { /* * We are searching for a paten "POST http://gateway.messenger.hotmail.com/gateway/gateway.dll" or * "POST http:///gateway/gateway.dll" * POST http:// is 12 byte so we are searching for 13 to 70 byte for this paten. */ for (c = 13; c < 50; c++) { if (memcmp(&packet->payload[c], "/", 1) == 0) { if (memcmp(&packet->payload[c], "/gateway/gateway.dll", 20) == 0) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found pattern http://.../gateway/gateway.ddl.\n"); status = 1; break; } } } } else if ((memcmp(&packet->payload[5], "/gateway/gateway.dll", 20) == 0)) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found pattern http://.../gateway/gateway.ddl.\n"); status = 1; } } if (status) { u_int16_t a; ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->content_line.ptr != NULL && ((packet->content_line.len == 23 && memcmp(packet->content_line.ptr, "text/xml; charset=utf-8", 23) == 0) || (packet->content_line.len == 24 && memcmp(packet->content_line.ptr, "text/html; charset=utf-8", 24) == 0) || (packet->content_line.len == 33 && memcmp(packet->content_line.ptr, "application/x-www-form-urlencoded", 33) == 0) )) { if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) != 0) || (dst != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) != 0)) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found MSN with pattern text/xml; charset=utf-8.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow); 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); 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); 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); 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); 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); 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); 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); 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); 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_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_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_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_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_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_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); } /* 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); } } } void init_msn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { NDPI_BITMASK_RESET(ndpi_struct->callback_buffer[*id].excluded_protocol_bitmask); ndpi_set_bitmask_protocol_detection("MSN", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/mssql.c000066400000000000000000000047241262705051000242320ustar00rootroot00000000000000/* * mssql.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MSSQL, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_mssql_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("MsSQL", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/mysql.c000066400000000000000000000060631262705051000242360ustar00rootroot00000000000000/* * mysql.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_MYSQL static void ndpi_int_mysql_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MYSQL, NDPI_PROTOCOL_UNKNOWN); } void ndpi_search_mysql_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { 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); } void init_mysql_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("MySQL", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/netbios.c000066400000000000000000000331001262705051000245240ustar00rootroot00000000000000/* * netbios.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_NETBIOS /* The function below has been inherited by tcpdump */ static int netbios_name_interpret(char *in, char *out, u_int out_len) { int ret = 0, 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; break; } *out = ((in[0]-'A')<<4) + (in[1]-'A'); in += 2; out++, ret++; } *out = 0; /* Courtesy of Roberto F. De Luca */ /* Trim trailing whitespace from the returned string */ for(out--; out>=b && *out==' '; out--) *out = '\0'; return(ret); } static void ndpi_int_netbios_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NETBIOS, NDPI_PROTOCOL_UNKNOWN); } 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[64]; NDPI_LOG(NDPI_PROTOCOL_NETBIOS, ndpi_struct, NDPI_LOG_DEBUG, "found netbios with checked ip-address.\n"); if(netbios_name_interpret((char*)&packet->payload[12], 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); } void init_netbios_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("NETBIOS", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/netflow.c000066400000000000000000000157521262705051000245540ustar00rootroot00000000000000/* * netflow.c * * Copyright (C) 2011-15 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_NETFLOW #ifdef WIN32 extern int gettimeofday(struct timeval * tp, struct timezone * tzp); #endif #define do_gettimeofday(a) gettimeofday(a, NULL) struct flow_ver1_rec { u_int32_t srcaddr; /* Source IP Address */ u_int32_t dstaddr; /* Destination IP Address */ u_int32_t nexthop; /* Next hop router's IP Address */ u_int16_t input; /* Input interface index */ u_int16_t output; /* Output interface index */ u_int32_t dPkts; /* Packets sent in Duration */ u_int32_t dOctets; /* Octets sent in Duration */ u_int32_t first; /* SysUptime at start of flow */ u_int32_t last; /* and of last packet of the flow */ u_int16_t srcport; /* TCP/UDP source port number (.e.g, FTP, Telnet, etc.,or equivalent) */ u_int16_t dstport; /* TCP/UDP destination port number (.e.g, FTP, Telnet, etc.,or equivalent) */ u_int16_t pad; /* pad to word boundary */ u_int8_t proto; /* IP protocol, e.g., 6=TCP, 17=UDP, etc... */ u_int8_t tos; /* IP Type-of-Service */ u_int8_t pad2[7]; /* pad to word boundary */ }; struct flow_ver5_rec { u_int32_t srcaddr; /* Source IP Address */ u_int32_t dstaddr; /* Destination IP Address */ u_int32_t nexthop; /* Next hop router's IP Address */ u_int16_t input; /* Input interface index */ u_int16_t output; /* Output interface index */ u_int32_t dPkts; /* Packets sent in Duration (milliseconds between 1st & last packet in this flow)*/ u_int32_t dOctets; /* Octets sent in Duration (milliseconds between 1st & last packet in this flow)*/ u_int32_t first; /* SysUptime at start of flow */ u_int32_t last; /* and of last packet of the flow */ u_int16_t srcport; /* TCP/UDP source port number (.e.g, FTP, Telnet, etc.,or equivalent) */ u_int16_t dstport; /* TCP/UDP destination port number (.e.g, FTP, Telnet, etc.,or equivalent) */ u_int8_t pad1; /* pad to word boundary */ u_int8_t tcp_flags; /* Cumulative OR of tcp flags */ u_int8_t proto; /* IP protocol, e.g., 6=TCP, 17=UDP, etc... */ u_int8_t tos; /* IP Type-of-Service */ u_int16_t src_as; /* source peer/origin Autonomous System */ u_int16_t dst_as; /* dst peer/origin Autonomous System */ u_int8_t src_mask; /* source route's mask bits */ u_int8_t dst_mask; /* destination route's mask bits */ u_int16_t pad2; /* pad to word boundary */ }; struct flow_ver7_rec { u_int32_t srcaddr; /* Source IP Address */ u_int32_t dstaddr; /* Destination IP Address */ u_int32_t nexthop; /* Next hop router's IP Address */ u_int16_t input; /* Input interface index */ u_int16_t output; /* Output interface index */ u_int32_t dPkts; /* Packets sent in Duration */ u_int32_t dOctets; /* Octets sent in Duration */ u_int32_t first; /* SysUptime at start of flow */ u_int32_t last; /* and of last packet of the flow */ u_int16_t srcport; /* TCP/UDP source port number (.e.g, FTP, Telnet, etc.,or equivalent) */ u_int16_t dstport; /* TCP/UDP destination port number (.e.g, FTP, Telnet, etc.,or equivalent) */ u_int8_t flags; /* Shortcut mode(dest only,src only,full flows*/ u_int8_t tcp_flags; /* Cumulative OR of tcp flags */ u_int8_t proto; /* IP protocol, e.g., 6=TCP, 17=UDP, etc... */ u_int8_t tos; /* IP Type-of-Service */ u_int16_t dst_as; /* dst peer/origin Autonomous System */ u_int16_t src_as; /* source peer/origin Autonomous System */ u_int8_t dst_mask; /* destination route's mask bits */ u_int8_t src_mask; /* source route's mask bits */ u_int16_t pad2; /* pad to word boundary */ u_int32_t router_sc; /* Router which is shortcut by switch */ }; 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], expected_len = 0; switch(version) { case 1: case 5: case 7: case 9: if((n == 0) || (n > 30)) return; switch(version) { case 1: expected_len = n * sizeof(struct flow_ver1_rec) + 16 /* header */; break; case 5: expected_len = n * sizeof(struct flow_ver5_rec) + 24 /* header */; break; case 7: expected_len = n * sizeof(struct flow_ver7_rec) + 24 /* header */; break; case 9: /* We need to check the template */ break; } if((expected_len > 0) && (expected_len != payload_len)) { NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NETFLOW); 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NETFLOW, NDPI_PROTOCOL_UNKNOWN); 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); } void init_netflow_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("NetFlow", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_NETFLOW, ndpi_search_netflow, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/nfs.c000066400000000000000000000063711262705051000236610ustar00rootroot00000000000000/* * nfs.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_NFS static void ndpi_int_nfs_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NFS, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_nfs_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("NFS", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/noe.c000066400000000000000000000044761262705051000236600ustar00rootroot00000000000000/* * noe.c (Alcatel new office environment) * * Copyright (C) 2013 Remy Mudingay * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_NOE static void ndpi_int_noe_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NOE, NDPI_PROTOCOL_UNKNOWN); } 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); } } void init_noe_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("NOE", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_NOE, ndpi_search_noe, NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/non_tcp_udp.c000066400000000000000000000154101262705051000253750ustar00rootroot00000000000000/* * non_tcp_udp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #if defined(NDPI_PROTOCOL_IP_IPSEC) || defined(NDPI_PROTOCOL_IP_GRE) || defined(NDPI_PROTOCOL_IP_ICMP) || defined(NDPI_PROTOCOL_IP_IGMP) || defined(NDPI_PROTOCOL_IP_EGP) || defined(NDPI_PROTOCOL_IP_SCTP) || defined(NDPI_PROTOCOL_IP_OSPF) || defined(NDPI_PROTOCOL_IP_IP_IN_IP) #define set_protocol_and_bmask(nprot) \ { \ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask,nprot) != 0) \ { \ ndpi_set_detected_protocol(ndpi_struct, flow, \ nprot, NDPI_PROTOCOL_UNKNOWN); \ } \ } 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 */ } } void init_non_tcp_udp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { /* always add non tcp/udp if one protocol is compiled in */ NDPI_SAVE_AS_BITMASK(ndpi_struct->callback_buffer[*id].detection_bitmask, NDPI_PROTOCOL_UNKNOWN); #ifdef NDPI_CONTENT_IP_IPSEC ndpi_set_bitmask_protocol_detection("IP_IPSEC", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_IP_GRE ndpi_set_bitmask_protocol_detection("IP_GRE", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_IP_ICMP ndpi_set_bitmask_protocol_detection("IP_ICMP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_IP_IGMP ndpi_set_bitmask_protocol_detection("IP_IGMP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_IP_EGP ndpi_set_bitmask_protocol_detection("IP_EGP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_IP_SCTP ndpi_set_bitmask_protocol_detection("IP_SCTP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_IP_OSPF ndpi_set_bitmask_protocol_detection("IP_OSPF", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_IP_IP_IN_IP ndpi_set_bitmask_protocol_detection("IP_IP_IN_IP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif #ifdef NDPI_CONTENT_IP_ICMPV6 ndpi_set_bitmask_protocol_detection("IP_ICMPV6", ndpi_struct, detection_bitmask, *id, 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); *id += 1; #endif } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ntp.c000066400000000000000000000056561262705051000237010ustar00rootroot00000000000000/* * ntp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_NTP static void ndpi_int_ntp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NTP, NDPI_PROTOCOL_UNKNOWN); } /* 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"); // It's not correct because packets could be bigger //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."); // 38 in binary representation is 00111000 flow->protos.ntp.version = (packet->payload[0] & 0x38) >> 3; if (flow->protos.ntp.version == 2) { flow->protos.ntp.request_code = packet->payload[3]; } 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); } void init_ntp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("NTP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/openft.c000066400000000000000000000047701262705051000243670ustar00rootroot00000000000000/* * openft.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_OPENFT static void ndpi_int_openft_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENFT, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_openft_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("OpenFT", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/openvpn.c000066400000000000000000000053161262705051000245560ustar00rootroot00000000000000/* * h323.c * * Copyright (C) 2013 Remy Mudingay * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_OPENVPN void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) { struct ndpi_packet_struct* packet = &flow->packet; u_int16_t dport = 0, sport = 0; if (packet->udp != NULL) { sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); if ((packet->payload_packet_len >= 25) && (sport == 443 || dport == 443) && (packet->payload[0] == 0x17 && packet->payload[1] == 0x01 && packet->payload[2] == 0x00 && packet->payload[3] == 0x00)) { NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, "found openvpn udp 443.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN); 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN); 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN); return; } } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OPENVPN); } void init_openvpn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("OpenVPN", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_OPENVPN, ndpi_search_openvpn, NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/oracle.c000066400000000000000000000057711262705051000243430ustar00rootroot00000000000000/* * oracle.c * * Copyright (C) 2013 Remy Mudingay * * This module is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This module is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License. * If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_ORACLE static void ndpi_int_oracle_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ORACLE, NDPI_PROTOCOL_UNKNOWN); } 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); } } void init_oracle_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Oracle", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/oscar.c000066400000000000000000000621701262705051000242010ustar00rootroot00000000000000/* * oscar.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #define FLAPVERSION 0x00000001 /* Flap channels */ #define SIGNON 0x01 #define DATA 0x02 #define O_ERROR 0x03 #define SIGNOFF 0x04 #define KEEP_ALIVE 0x05 /* Signon tags */ #define SCREEN_NAME 0x0001 #define PASSWD 0x0002 #define CLIENT_NAME 0x0003 #define BOS 0x0005 #define LOGIN_COOKIE 0x0006 #define MAJOR_VERSION 0x0017 #define MINOR_VERSION 0x0018 #define POINT_VERSION 0x0019 #define BUILD_NUM 0x001a #define MULTICONN_FLAGS 0x004a #define CLIENT_LANG 0x00OF #define CLIENT_CNTRY 0x00OE #define CLIENT_RECONNECT 0x0094 /* Family */ #define GE_SE_CTL 0x0001 #define LOC_SRV 0x0002 #define BUDDY_LIST 0x0003 #define IM 0x0004 #define IS 0x0006 #define ACC_ADM 0x0007 #define POPUP 0x0008 #define PMS 0x0009 #define USS 0x000b #define CHAT_ROOM_SETUP 0x000d #define CHAT_ROOM_ACT 0x000e #define USER_SRCH 0x000f #define BUDDY_ICON_SERVER 0x0010 #define SERVER_STORED_INFO 0x0013 #define ICQ 0x0015 #define INIT_AUTH 0x0017 #define EMAIL 0x0018 #define IS_EXT 0x0085 #ifdef NDPI_PROTOCOL_OSCAR static void ndpi_int_oscar_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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR, NDPI_PROTOCOL_UNKNOWN); if (src != NULL) { src->oscar_last_safe_access_time = packet->tick_timestamp; } if (dst != NULL) { dst->oscar_last_safe_access_time = packet->tick_timestamp; } } /** Oscar connection work on FLAP protocol. FLAP is a low-level communications protocol that facilitates the development of higher-level, datagram-oriented, communications layers. It is used on the TCP connection between all clients and servers. Here is format of FLAP datagram **/ static void ndpi_search_oscar_tcp_connect(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { int excluded = 0; // u_int8_t channel; u_int16_t family; u_int16_t type; u_int16_t flag; u_int32_t req_ID; struct ndpi_packet_struct * packet = &flow->packet; struct ndpi_id_struct * src = flow->src; struct ndpi_id_struct * dst = flow->dst; /* FLAP__Header * * [ 6 byte FLAP header ] * +-----------+--------------+-------------+--------------+ * | 0x2a (1B) | Channel (1B) | SeqNum (2B) | PyldLen (2B) | * +-----------+--------------+-------------+--------------+ * * [ 4 byte of data ] * * */ if (packet->payload_packet_len >= 6 && packet->payload[0] == 0x2a) { /* FLAP__FRAME_TYPE (Channel)*/ u_int8_t channel = get_u_int8_t(packet->payload, 1); /* Initialize the FLAP connection. SIGNON -> FLAP__SIGNON_FRAME +--------------------------------------------------+ + FLAP__Header | 6 byte + + FlapVersion | 4 byte (Always 1 = 0x00000001) + + TLVs | [Class: FLAP__SIGNON_TAGS] TLVs + +--------------------------------------------------+ */ if (channel == SIGNON && get_u_int16_t(packet->payload, 4) == htons(packet->payload_packet_len - 6) && get_u_int32_t(packet->payload, 6) == htonl(FLAPVERSION)) { /* No TLVs */ if(packet->payload_packet_len == 10) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Sign In \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); return; } /* /\* SCREEN_NAME *\/ */ /* if (get_u_int16_t(packet->payload, 10) == htons(SCREEN_NAME)) /\* packet->payload[10] == 0x00 && packet->payload[11] == 0x01 *\/ */ /* { */ /* NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Screen Name \n"); */ /* ndpi_int_oscar_add_connection(ndpi_struct, flow); */ /* return; */ /* } */ /* /\* PASSWD *\/ */ /* if (get_u_int16_t(packet->payload, 10) == htons(PASSWD)) /\* packet->payload[10] == 0x00 && packet->payload[11] == 0x02 *\/ */ /* { */ /* NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Password (roasted) \n"); */ /* ndpi_int_oscar_add_connection(ndpi_struct, flow); */ /* return; */ /* } */ /* CLIENT_NAME */ if (get_u_int16_t(packet->payload, 10) == htons(CLIENT_NAME)) /* packet->payload[10] == 0x00 && packet->payload[11] == 0x03 */ { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Client Name \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); return; } /* LOGIN_COOKIE */ if (get_u_int16_t(packet->payload, 10) == htons(LOGIN_COOKIE) && get_u_int16_t(packet->payload, 12) == htons(0x0100)) { if(get_u_int16_t(packet->payload, packet->payload_packet_len - 5) == htons(MULTICONN_FLAGS)) /* MULTICONN_FLAGS */ { if(get_u_int16_t(packet->payload, packet->payload_packet_len - 3) == htons(0x0001)) if((get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x00) || (get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x01) || (get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x03)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Login \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); return; } } } /* MAJOR_VERSION */ if (get_u_int16_t(packet->payload, 10) == htons(MAJOR_VERSION)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Major_Version \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); return; } /* MINOR_VERSION */ if (get_u_int16_t(packet->payload, 10) == htons(MINOR_VERSION)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Minor_Version \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); return; } /* POINT_VERSION */ if (get_u_int16_t(packet->payload, 10) == htons(POINT_VERSION)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Point_Version \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); return; } /* BUILD_NUM */ if (get_u_int16_t(packet->payload, 10) == htons(BUILD_NUM)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Build_Num \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); return; } /* CLIENT_RECONNECT */ if (get_u_int16_t(packet->payload, 10) == htons(CLIENT_RECONNECT)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Client_Reconnect \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); return; } } /* Messages using the FLAP connection, usually a SNAC message. DATA -> FLAP__DATA_FRAME +-------------------------+ + FLAP__Header | 6 byte + + SNAC__Header | 10 byte + + snac | + +-------------------------+ SNAC__Header +----------------------------------------------+ + ID | 4 byte (2 foodgroup + 2 type) + + FLAGS | 2 byte + + requestId | 4 byte + +----------------------------------------------+ */ if (channel == DATA) { family = get_u_int16_t(packet->payload, 6); type = get_u_int16_t(packet->payload, 8); flag = get_u_int16_t(packet->payload, 10); req_ID = get_u_int32_t(packet->payload, 12); /* Family 0x0001 */ if (family == htons(GE_SE_CTL)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; case (0x0006): break; case (0x0007): break; case (0x0008): break; case (0x0009): break; case (0x000a): break; case (0x000b): break; case (0x000c): break; case (0x000d): break; case (0x000e): break; case (0x000f): break; case (0x0010): break; case (0x0011): break; case (0x0012): break; case (0x0013): break; case (0x0014): break; case (0x0015): break; case (0x0016): break; case (0x0017): break; case (0x0018): break; case (0x001e): break; case (0x001f): break; case (0x0020): break; case (0x0021): break; default: excluded = 1; } } /* Family 0x0002 */ if (family == htons(LOC_SRV)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; case (0x0006): break; case (0x0007): break; case (0x0008): break; case (0x0009): break; case (0x000a): break; case (0x000b): break; case (0x000c): break; case (0x000f): break; case (0x0010): break; case (0x0015): break; default: excluded = 1; } } /* Family 0x0003 */ if (family == htons(BUDDY_LIST)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; case (0x0006): break; case (0x0007): break; case (0x0008): break; case (0x0009): break; case (0x000a): break; case (0x000b): break; case (0x000c): break; default: excluded = 1; } } /* Family 0x0004 */ if (family == htons(IM)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; case (0x0006): break; case (0x0007): break; case (0x0008): break; case (0x0009): break; case (0x000a): break; case (0x000b): break; case (0x000c): break; case (0x0014): break; default: excluded = 1; } } /* Family 0x0006 */ if (family == htons(IS)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; default: excluded = 1; } } /* Family 0x0007 */ if (family == htons(ACC_ADM)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; case (0x0006): break; case (0x0007): break; case (0x0008): break; case (0x0009): break; default: excluded = 1; } } /* Family 0x0008 */ if (family == htons(POPUP)) { switch (type) { case (0x0001): break; case (0x0002): break; default: excluded = 1; } } /* Family 0x0009 */ if (family == htons(PMS)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; case (0x0006): break; case (0x0007): break; case (0x0008): break; case (0x0009): break; case (0x000a): break; case (0x000b): break; default: excluded = 1; } } /* Family 0x000b */ if (family == htons(USS)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; default: excluded = 1; } } /* Family 0x000d */ if (family == htons(CHAT_ROOM_SETUP)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; case (0x0006): break; case (0x0007): break; case (0x0008): break; case (0x0009): break; default: excluded = 1; } } /* Family 0x000e */ if (family == htons(CHAT_ROOM_ACT)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; case (0x0006): break; case (0x0007): break; case (0x0008): break; case (0x0009): break; default: excluded = 1; } } /* Family 0x000f */ if (family == htons(USER_SRCH)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; default: excluded = 1; } } /* Family 0x0010 */ if (family == htons(BUDDY_ICON_SERVER)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; case (0x0006): break; case (0x0007): break; default: excluded = 1; } } /* Family 0x0013 */ if (family == htons(SERVER_STORED_INFO)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; case (0x0006): break; case (0x0007): break; case (0x0008): break; case (0x0009): break; case (0x000a): break; case (0x000e): break; case (0x000f): break; case (0x0011): break; case (0x0012): break; case (0x0014): break; case (0x0015): break; case (0x0016): break; case (0x0018): break; case (0x001a): break; case (0x001b): break; case (0x001c): break; default: excluded = 1; } } /* Family 0x0015 */ if (family == htons(ICQ)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; default: excluded = 1; } } /* Family 0x0017 */ if (family == htons(INIT_AUTH)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; case (0x0004): break; case (0x0005): break; case (0x0006): break; case (0x0007): break; case (0x000a): break; case (0x000b): break; default: excluded = 1; } } /* Family 0x0018 */ if (family == htons(EMAIL)) { /* TODO */ } /* Family 0x0085 */ if (family == htons(IS_EXT)) { switch (type) { case (0x0001): break; case (0x0002): break; case (0x0003): break; default: excluded = 1; } } if(excluded == 1) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "exclude oscar.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OSCAR); } /* flag */ if (flag == htons(0x0000)|| flag == htons(0x8000) || flag == htons(0x0001)) { /* request ID */ if((req_ID <= 4294967295)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); return; } } } /* ERROR -> FLAP__ERROR_CHANNEL_0x03 A FLAP error - rare */ if (channel == O_ERROR) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected - Error frame \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); return; } /* Close down the FLAP connection gracefully. SIGNOFF: FLAP__SIGNOFF_CHANNEL_0x04 */ if (channel == SIGNOFF) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected - Signoff frame \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); return; } /* Send a heartbeat to server to help keep connection open. KEEP_ALIVE: FLAP__KEEP_ALIVE_CHANNEL_0x05 */ if (channel == KEEP_ALIVE) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected - Keep Alive frame \n"); ndpi_int_oscar_add_connection(ndpi_struct, flow); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); } } void init_oscar_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Oscar", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/pando.c000066400000000000000000000166321262705051000241750ustar00rootroot00000000000000/* * pando.c * * Copyright (C) 2014 Tomasz Bujlow * * The signature is based on the Libprotoident library. * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_PANDO static void ndpi_int_pando_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_PANDO, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_pando_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Pando_Media_Booster", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/pcanywhere.c000066400000000000000000000046701262705051000252400ustar00rootroot00000000000000/* * pcanywhere.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_PCANYWHERE static void ndpi_int_pcanywhere_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_PCANYWHERE, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_pcanywhere_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("PcAnywhere", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/postgres.c000066400000000000000000000121001262705051000247240ustar00rootroot00000000000000/* * postgres.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_POSTGRES static void ndpi_int_postgres_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_POSTGRES, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_postgres_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("PostgreSQL", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/pplive.c000066400000000000000000000245171262705051000243740ustar00rootroot00000000000000/* * pplive.c * * Copyright (C) 2014 Tomasz Bujlow * * The signature is mostly based on the Libprotoident library * except the detection of HTTP Steam flows. * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_PPLIVE static void ndpi_int_pplive_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_PPLIVE, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_pplive_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("PPLive", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_PPLIVE, ndpi_search_pplive, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ppstream.c000066400000000000000000000104171262705051000247220ustar00rootroot00000000000000/* * ppstream.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_PPSTREAM static void ndpi_int_ppstream_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_PPSTREAM, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_ppstream_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("PPStream", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/pptp.c000066400000000000000000000051231262705051000240500ustar00rootroot00000000000000/* * pptp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ /* include files */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_PPTP static void ndpi_int_pptp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_PPTP, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_pptp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("PPTP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/qq.c000066400000000000000000000573211262705051000235150ustar00rootroot00000000000000/* * qq.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_QQ static void ndpi_int_qq_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , */ /* ndpi_protocol_type_t protocol_type */) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QQ, NDPI_PROTOCOL_UNKNOWN); } /* * 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[13] = // maybe version numbers { 0x1549, 0x1801, 0x180d, 0x0961, 0x01501, 0x0e35, 0x113f, 0x0b37, 0x1131, 0x163a, 0x1e0d, 0x3619,}; u_int16_t no_of_patterns = 12, 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); 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); 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); 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); 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); 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); 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); return; } return; } if (packet->udp->dest == htons(9000) || packet->udp->source == htons(9000)) { if (packet->payload_packet_len > 3 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0202 && ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len) { flow->qq_stage++; if (flow->qq_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern 02 02 four times.\n"); ndpi_int_qq_add_connection(ndpi_struct, flow); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); } void init_qq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("QQ", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_QQ, ndpi_search_qq, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/quake.c000066400000000000000000000077151262705051000242040ustar00rootroot00000000000000/* * quake.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_QUAKE static void ndpi_int_quake_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUAKE, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_quake_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Quake", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_QUAKE, ndpi_search_quake, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/quic.c000066400000000000000000000134321262705051000240300ustar00rootroot00000000000000/* * quic.c * * Andrea Buscarinu - * Michele Campus - * * Copyright (C) 2012-15 - ntop.org * * This module is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This module is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License. * If not, see . * */ #include "ndpi_api.h" #define QUIC_NO_V_RES_RSV 0xC3 // 1100 0011 #define QUIC_CID_MASK 0x0C // 0000 1100 #define QUIC_VER_MASK 0x01 // 0000 0001 #define QUIC_SEQ_MASK 0x30 // 0011 0000 #define CID_LEN_8 0x0C // 0000 1100 #define CID_LEN_4 0x08 // 0000 1000 #define CID_LEN_1 0x04 // 0000 0100 #define CID_LEN_0 0x00 // 0000 0000 #define SEQ_LEN_6 0x30 // 0011 0000 #define SEQ_LEN_4 0x20 // 0010 0000 #define SEQ_LEN_2 0x10 // 0001 0000 #define SEQ_LEN_1 0x00 // 0000 0000 #define SEQ_CONV(ARR) (ARR[0] | ARR[1] | ARR[2] | ARR[3] | ARR[4] | ARR[5] << 8) #ifdef NDPI_PROTOCOL_QUIC static void ndpi_int_quic_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN); } static int connect_id(const unsigned char pflags) { u_int cid_len; // Check CID length. switch (pflags & QUIC_CID_MASK) { case CID_LEN_8: cid_len = 8; break; case CID_LEN_4: cid_len = 4; break; case CID_LEN_1: cid_len = 1; break; case CID_LEN_0: cid_len = 0; break; default: return -1; } // Return offset. return cid_len + 1; } static int sequence(const unsigned char *payload) { unsigned char conv[6] = {0}; u_int seq_value = -1; int seq_lens; int cid_offs; int i; // Search SEQ bytes length. switch (payload[0] & QUIC_SEQ_MASK) { case SEQ_LEN_6: seq_lens = 6; break; case SEQ_LEN_4: seq_lens = 4; break; case SEQ_LEN_2: seq_lens = 2; break; case SEQ_LEN_1: seq_lens = 1; break; default: return -1; } // Retrieve SEQ offset. cid_offs = connect_id(payload[0]); if (cid_offs >= 0 && seq_lens > 0) { for (i = 0; i < seq_lens; i++) conv[i] = payload[cid_offs + i]; seq_value = SEQ_CONV(conv); } // Return SEQ dec value; return seq_value; } void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; int ver_offs; if(packet->udp != NULL) { u_int16_t sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "calculating quic over udp.\n"); if((((sport == 80) || (dport == 80) || (sport == 443) || (dport == 443)))) { NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); // Settings without version. First check if PUBLIC FLAGS & SEQ bytes are 0x0. SEQ must be 1 at least. if ((packet->payload[0] == 0x00 && packet->payload[1] != 0x00) || ((packet->payload[0] & QUIC_NO_V_RES_RSV) == 0)) { if (sequence(packet->payload) < 1) { NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); } NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found quic.\n"); ndpi_int_quic_add_connection(ndpi_struct, flow); } // Check if version, than the CID length. else if (packet->payload[0] & QUIC_VER_MASK) { // Skip CID length. ver_offs = connect_id(packet->payload[0]); if (ver_offs >= 0) { unsigned char vers[] = {packet->payload[ver_offs], packet->payload[ver_offs + 1], packet->payload[ver_offs + 2], packet->payload[ver_offs + 3]}; // Version Match. if ((vers[0] == 'Q' && vers[1] == '0') && ((vers[2] == '2' && (vers[3] == '5' || vers[3] == '4' || vers[3] == '3' || vers[3] == '2' || vers[3] == '1' || vers[3] == '0')) || (vers[2] == '1' && (vers[3] == '9' || vers[3] == '8' || vers[3] == '7' || vers[3] == '6' || vers[3] == '5' || vers[3] == '4' || vers[3] == '3' || vers[3] == '2' || vers[3] == '1' || vers[3] == '0')) || (vers[2] == '0' && vers[3] == '9'))) { NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found quic.\n"); ndpi_int_quic_add_connection(ndpi_struct, flow); } } } } else { NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); } } } void init_quic_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Quic", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_QUIC, ndpi_search_quic, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/radius.c000066400000000000000000000047501262705051000243610ustar00rootroot00000000000000/* * radius.c * * Copyright (C) 2012-15 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_RADIUS struct radius_header { u_int8_t code; u_int8_t packet_id; u_int16_t len; }; static void ndpi_check_radius(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // const u_int8_t *packet_payload = packet->payload; u_int32_t payload_len = packet->payload_packet_len; if(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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RADIUS, NDPI_PROTOCOL_UNKNOWN); 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); } void init_radius_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Radius", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_RADIUS, ndpi_search_radius, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/rdp.c000066400000000000000000000050711262705051000236540ustar00rootroot00000000000000/* * rdp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_RDP static void ndpi_int_rdp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RDP, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_rdp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("RDP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/redis_net.c000066400000000000000000000065751262705051000250550ustar00rootroot00000000000000/* * redis.c * * Copyright (C) 2011-15 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_REDIS static void ndpi_int_redis_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_REDIS, NDPI_PROTOCOL_UNKNOWN); } 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); } } } void init_redis_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Redis", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/rsync.c000066400000000000000000000047771262705051000242410ustar00rootroot00000000000000/* * rsync.c * * Copyright (C) 2013 Remy Mudingay * * This module is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This module is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License. * If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_RSYNC static void ndpi_int_rsync_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RSYNC, NDPI_PROTOCOL_UNKNOWN); } 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); } } void init_rsync_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("RSYNC", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/rtcp.c000066400000000000000000000061141262705051000240360ustar00rootroot00000000000000/* * rtcp.c (RTP Control Protocol) * * Copyright (C) 2013 Remy Mudingay * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_RTCP static void ndpi_int_rtcp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RTCP, NDPI_PROTOCOL_UNKNOWN); } 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) { /* Let's check first the RTCP packet length */ u_int16_t len, offset = 0, rtcp_section_len; while(offset < packet->payload_packet_len) { len = packet->payload[2+offset] * 256 + packet->payload[2+offset+1]; rtcp_section_len = (len + 1) * 4; if(((offset+rtcp_section_len) > packet->payload_packet_len) || (rtcp_section_len == 0)) goto exclude_rtcp; else offset += rtcp_section_len; } 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 { exclude_rtcp: 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); } } void init_rtcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("RTCP", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_RTCP, ndpi_search_rtcp, NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/rtmp.c000066400000000000000000000100731262705051000240470ustar00rootroot00000000000000/* * rtmp.c * * Copyright (C) 2014 Tomasz Bujlow * * The signature is based on the Libprotoident library. * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_RTMP static void ndpi_int_rtmp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RTMP, NDPI_PROTOCOL_UNKNOWN); } 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); } } } void init_rtmp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("RTMP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/rtp.c000066400000000000000000000355121262705051000236770ustar00rootroot00000000000000/* * rtp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_RTP /* http://www.myskypelab.com/2014/05/microsoft-lync-wireshark-plugin.html */ static u_int8_t isValidMSRTPType(u_int8_t payloadType) { switch(payloadType) { case 0: /* G.711 u-Law */ case 3: /* GSM 6.10 */ case 4: /* G.723.1 */ case 8: /* G.711 A-Law */ case 9: /* G.722 */ case 13: /* Comfort Noise */ case 96: /* Dynamic RTP */ case 97: /* Redundant Audio Data Payload */ case 101: /* DTMF */ case 103: /* SILK Narrowband */ case 104: /* SILK Wideband */ case 111: /* Siren */ case 112: /* G.722.1 */ case 114: /* RT Audio Wideband */ case 115: /* RT Audio Narrowband */ case 116: /* G.726 */ case 117: /* G.722 */ case 118: /* Comfort Noise Wideband */ case 34: /* H.263 [MS-H26XPF] */ case 121: /* RT Video */ case 122: /* H.264 [MS-H264PF] */ case 123: /* H.264 FEC [MS-H264PF] */ case 127: /* x-data */ return(1 /* RTP */); break; case 200: /* RTCP PACKET SENDER */ case 201: /* RTCP PACKET RECEIVER */ case 202: /* RTCP Source Description */ case 203: /* RTCP Bye */ return(2 /* RTCP */); break; default: 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 payloadType, 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) || ((payload[0] & 0xFF) == 0xA0)) /* RTP magic byte[1] */ && ((payload_type < 72) || (payload_type > 76)) && ((payload_type <= 34) || ((payload_type >= 96) && (payload_type <= 127)) /* http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml */ ) && (*ssid != 0) ) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "Found RTP.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RTP, NDPI_PROTOCOL_UNKNOWN); return; } else if((payload_len >= 12) && (((payload[0] & 0xFF) == 0x80) || ((payload[0] & 0xFF) == 0xA0)) /* RTP magic byte[1] */ && (payloadType = isValidMSRTPType(payload[1] & 0xFF))) { if(payloadType == 1 /* RTP */) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "Found MS Lync\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MS_LYNC, NDPI_PROTOCOL_UNKNOWN); } else /* RTCP */ { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "Found MS RTCP\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RTCP, NDPI_PROTOCOL_UNKNOWN); } } /* No luck this time */ 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RTP, NDPI_PROTOCOL_UNKNOWN); } /* * 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 void init_rtp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("RTP", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_RTP, ndpi_search_rtp, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif /* NDPI_PROTOCOL_RTP */ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/rtsp.c000066400000000000000000000111541262705051000240560ustar00rootroot00000000000000/* * rtsp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_RTSP #ifndef NDPI_PROTOCOL_RTP #error RTSP requires RTP detection to work correctly #endif #ifndef NDPI_PROTOCOL_RTSP #error RTSP requires RTSP detection to work correctly #endif #ifndef NDPI_PROTOCOL_RDP #error RTSP requires RDP detection to work correctly #endif static void ndpi_int_rtsp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , */ /* ndpi_protocol_type_t protocol_type */) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RTSP, NDPI_PROTOCOL_UNKNOWN); } /* 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); 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; } void init_rtsp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("RTSP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/sflow.c000066400000000000000000000041411262705051000242160ustar00rootroot00000000000000/* * sflow.c * * Copyright (C) 2011-15 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_SFLOW static void ndpi_check_sflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // const u_int8_t *packet_payload = packet->payload; u_int32_t payload_len = packet->payload_packet_len; if((packet->udp != NULL) && (payload_len >= 24) /* Version */ && (packet->payload[0] == 0) && (packet->payload[1] == 0) && (packet->payload[2] == 0) && ((packet->payload[3] == 2) || (packet->payload[3] == 5))) { NDPI_LOG(NDPI_PROTOCOL_SFLOW, ndpi_struct, NDPI_LOG_DEBUG, "Found sflow.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SFLOW, NDPI_PROTOCOL_UNKNOWN); 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); } void init_sflow_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("sFlow", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_SFLOW, ndpi_search_sflow, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/shoutcast.c000066400000000000000000000110401262705051000250750ustar00rootroot00000000000000/* * shoutcast.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_SHOUTCAST static void ndpi_int_shoutcast_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SHOUTCAST, NDPI_PROTOCOL_UNKNOWN); } 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"); } void init_shoutcast_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("ShoutCast", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/sip.c000066400000000000000000000175701262705051000236710ustar00rootroot00000000000000/* * sip.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_SIP static void ndpi_int_sip_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int8_t due_to_correlation) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SIP, NDPI_PROTOCOL_UNKNOWN); } #if !defined(WIN32) static inline #else __forceinline static #endif void ndpi_search_sip_handshake(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; const u_int8_t *packet_payload = packet->payload; u_int32_t payload_len = packet->payload_packet_len; if (payload_len > 4) { /* search for STUN Turn ChannelData Prefix */ u_int16_t message_len = ntohs(get_u_int16_t(packet->payload, 2)); if (payload_len - 4 == message_len) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found STUN TURN ChannelData prefix.\n"); payload_len -= 4; packet_payload += 4; } } #ifndef NDPI_PROTOCOL_YAHOO if (payload_len >= 14 && packet_payload[payload_len - 2] == 0x0d && packet_payload[payload_len - 1] == 0x0a) #endif #ifdef NDPI_PROTOCOL_YAHOO if (payload_len >= 14) #endif { if ((memcmp(packet_payload, "NOTIFY ", 7) == 0 || memcmp(packet_payload, "notify ", 7) == 0) && (memcmp(&packet_payload[7], "SIP:", 4) == 0 || memcmp(&packet_payload[7], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip NOTIFY.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } if ((memcmp(packet_payload, "REGISTER ", 9) == 0 || memcmp(packet_payload, "register ", 9) == 0) && (memcmp(&packet_payload[9], "SIP:", 4) == 0 || memcmp(&packet_payload[9], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip REGISTER.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } if ((memcmp(packet_payload, "INVITE ", 7) == 0 || memcmp(packet_payload, "invite ", 7) == 0) && (memcmp(&packet_payload[7], "SIP:", 4) == 0 || memcmp(&packet_payload[7], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip INVITE.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } /* seen this in second direction on the third position, * maybe it could be deleted, if somebody sees it in the first direction, * please delete this comment. */ /* if (memcmp(packet_payload, "SIP/2.0 200 OK", 14) == 0 || memcmp(packet_payload, "sip/2.0 200 OK", 14) == 0) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip SIP/2.0 0K.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } */ if (memcmp(packet_payload, "SIP/2.0 ", 8) == 0 || memcmp(packet_payload, "sip/2.0 ", 8) == 0) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip SIP/2.0 *.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } if ((memcmp(packet_payload, "BYE ", 4) == 0 || memcmp(packet_payload, "bye ", 4) == 0) && (memcmp(&packet_payload[4], "SIP:", 4) == 0 || memcmp(&packet_payload[4], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip BYE.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } if ((memcmp(packet_payload, "ACK ", 4) == 0 || memcmp(packet_payload, "ack ", 4) == 0) && (memcmp(&packet_payload[4], "SIP:", 4) == 0 || memcmp(&packet_payload[4], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip ACK.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } if ((memcmp(packet_payload, "CANCEL ", 7) == 0 || memcmp(packet_payload, "cancel ", 7) == 0) && (memcmp(&packet_payload[4], "SIP:", 7) == 0 || memcmp(&packet_payload[4], "sip:", 7) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip CANCEL.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } /* Courtesy of Miguel Quesada */ if ((memcmp(packet_payload, "OPTIONS ", 8) == 0 || memcmp(packet_payload, "options ", 8) == 0) && (memcmp(&packet_payload[8], "SIP:", 4) == 0 || memcmp(&packet_payload[8], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip OPTIONS.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } } /* add bitmask for tcp only, some stupid udp programs * send a very few (< 10 ) packets before invite (mostly a 0x0a0x0d, but just search the first 3 payload_packets here */ if (packet->udp != NULL && flow->packet_counter < 20) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "need next packet.\n"); return; } #ifdef NDPI_PROTOCOL_STUN /* for STUN flows we need some more packets */ if (packet->udp != NULL && flow->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN && flow->packet_counter < 40) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "need next STUN packet.\n"); return; } #endif if (payload_len == 4 && get_u_int32_t(packet_payload, 0) == 0) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "maybe sip. need next packet.\n"); return; } #ifdef NDPI_PROTOCOL_YAHOO if (payload_len > 30 && packet_payload[0] == 0x90 && packet_payload[3] == payload_len - 20 && get_u_int32_t(packet_payload, 4) == 0 && get_u_int32_t(packet_payload, 8) == 0) { flow->sip_yahoo_voice = 1; NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "maybe sip yahoo. need next packet.\n"); } if (flow->sip_yahoo_voice && flow->packet_counter < 10) { return; } #endif NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "exclude sip.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SIP); return; } void ndpi_search_sip(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_flow_struct *flow = ndpi_struct->flow; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "sip detection...\n"); /* skip marked packets */ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_SIP) { if (packet->tcp_retransmission == 0) { ndpi_search_sip_handshake(ndpi_struct, flow); } } } void init_sip_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("SIP", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_SIP, ndpi_search_sip, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,/* Fix courtesy of Miguel Quesada */ SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/skinny.c000066400000000000000000000063271262705051000244070ustar00rootroot00000000000000/* * skinny.c * * Copyright (C) 2013 Remy Mudingay * * This module is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This module is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License. * If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_SKINNY static void ndpi_int_skinny_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SKINNY, NDPI_PROTOCOL_UNKNOWN); } 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); } } void init_skinny_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("CiscoSkinny", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/skype.c000066400000000000000000000106051262705051000242210ustar00rootroot00000000000000/* * skype.c * * Copyright (C) 2011-15 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_SKYPE static u_int8_t is_skype_host(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t host) { struct in_addr pin; pin.s_addr = host; return((ndpi_network_ptree_match(ndpi_struct, &pin) == NDPI_PROTOCOL_SKYPE) ? 1 : 0); } u_int8_t is_skype_flow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if(packet->iph) { /* Skype connections are identified by some SSL-like communications without SSL certificate being exchanged */ if(is_skype_host(ndpi_struct, packet->iph->saddr) || is_skype_host(ndpi_struct, 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; if(flow->host_server_name[0] != '\0') return; /* Skype AS8220 212.161.8.0/24 */ if(is_skype_flow(ndpi_struct, flow)) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE, NDPI_PROTOCOL_UNKNOWN); return; } if(packet->udp != NULL) { flow->l4.udp.skype_packet_id++; if(flow->l4.udp.skype_packet_id < 5) { u_int16_t dport = ntohs(packet->udp->dest); /* skype-to-skype */ if(dport != 1119) /* It can be confused with battle.net */ { 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE, NDPI_PROTOCOL_UNKNOWN); } } 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE, NDPI_PROTOCOL_UNKNOWN); } /* 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); } void init_skype_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Skype", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_SKYPE, ndpi_search_skype, NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/smb.c000066400000000000000000000046321262705051000236520ustar00rootroot00000000000000/* * smb.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_SMB static void ndpi_int_smb_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SMB, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_smb_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("SMB", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/snmp.c000066400000000000000000000117561262705051000240530ustar00rootroot00000000000000/* * snmp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_SNMP static void ndpi_int_snmp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SNMP, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_snmp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("SNMP", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_SNMP, ndpi_search_snmp, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/socks4.c000066400000000000000000000073511262705051000243000ustar00rootroot00000000000000/* * socks4.c * * Copyright (C) 2014 Tomasz Bujlow * * The signature is based on the Libprotoident library. * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_SOCKS4 static void ndpi_int_socks4_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SOCKS4, NDPI_PROTOCOL_UNKNOWN); } 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/socks5.c000066400000000000000000000071171262705051000243010ustar00rootroot00000000000000/* * socks5.c * * Copyright (C) 2014 Tomasz Bujlow * * The signature is based on the Libprotoident library. * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_SOCKS5 static void ndpi_int_socks5_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SOCKS5, NDPI_PROTOCOL_UNKNOWN); } 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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/socrates.c000066400000000000000000000065101262705051000247110ustar00rootroot00000000000000/* * socrates.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_SOCRATES static void ndpi_socrates_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SOCRATES, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_socrates_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Socrates", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/sopcast.c000066400000000000000000000220141262705051000245370ustar00rootroot00000000000000/* * sopcast.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_SOPCAST static void ndpi_int_sopcast_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SOPCAST, NDPI_PROTOCOL_UNKNOWN); } /** * 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); } void init_sopcast_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Sopcast", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/soulseek.c000066400000000000000000000276561262705051000247360ustar00rootroot00000000000000/* * soulseek.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_SOULSEEK static void ndpi_int_soulseek_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SOULSEEK, NDPI_PROTOCOL_UNKNOWN); 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); } } void init_soulseek_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Soulseek", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/spotify.c000066400000000000000000000121241262705051000245610ustar00rootroot00000000000000/* * spotify.c * * Copyright (C) 2011-13 by ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_SPOTIFY static void ndpi_int_spotify_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int8_t due_to_correlation) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SPOTIFY, NDPI_PROTOCOL_UNKNOWN); } 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SPOTIFY, NDPI_PROTOCOL_UNKNOWN); } 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_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SPOTIFY, NDPI_PROTOCOL_UNKNOWN); 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); } } } void init_spotify_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("SPOTIFY", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_SPOTIFY, ndpi_search_spotify, NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ssdp.c000066400000000000000000000053771262705051000240510ustar00rootroot00000000000000/* * ssdp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_SSDP static void ndpi_int_ssdp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SSDP, NDPI_PROTOCOL_UNKNOWN); } /* 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); } void init_ssdp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("SSDP", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_SSDP, ndpi_search_ssdp, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ssh.c000066400000000000000000000053641262705051000236710ustar00rootroot00000000000000/* * ssh.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_SSH static void ndpi_int_ssh_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow){ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SSH, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_ssh_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("SSH", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ssl.c000066400000000000000000000562721262705051000237010ustar00rootroot00000000000000/* * ssl.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" /* #define CERTIFICATE_DEBUG 1 */ #ifdef NDPI_PROTOCOL_SSL #define NDPI_MAX_SSL_REQUEST_SIZE 10000 /* Skype.c */ extern u_int8_t is_skype_flow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int32_t protocol) { if((protocol != NDPI_PROTOCOL_SSL) && (protocol != NDPI_PROTOCOL_SSL_NO_CERT)) { ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); } 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_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); } } /* Can't call libc functions from kernel space, define some stub instead */ #define ndpi_isalpha(ch) (((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z')) #define ndpi_isdigit(ch) ((ch) >= '0' && (ch) <= '9') #define ndpi_isspace(ch) (((ch) >= '\t' && (ch) <= '\r') || ((ch) == ' ')) #define ndpi_isprint(ch) ((ch) >= 0x20 && (ch) <= 0x7e) #define ndpi_ispunct(ch) (((ch) >= '!' && (ch) <= '/') || \ ((ch) >= ':' && (ch) <= '@') || \ ((ch) >= '[' && (ch) <= '`') || \ ((ch) >= '{' && (ch) <= '~')) static void stripCertificateTrailer(char *buffer, int buffer_len) { int i; // printf("->%s<-\n", buffer); for(i=0; i 0) i--; while(i > 0) { if(!ndpi_isalpha(buffer[i])) { buffer[i] = '\0'; buffer_len = i; i--; } else break; } for(i=buffer_len; i>0; i--) { if(buffer[i] == '.') break; else if(ndpi_isdigit(buffer[i])) buffer[i] = '\0', buffer_len = i; } } /* Code fixes courtesy of Alexsandro Brahm */ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, char *buffer, int buffer_len) { struct ndpi_packet_struct *packet = &flow->packet; #ifdef CERTIFICATE_DEBUG { static u_int8_t id = 0; printf("-> [%u] %02X\n", ++id, packet->payload[0] & 0xFF); } #endif /* Nothing matched so far: let's decode the certificate with some heuristics Patches courtesy of Denys Fedoryshchenko */ if(packet->payload[0] == 0x16 /* Handshake */) { u_int16_t total_len = (packet->payload[3] << 8) + packet->payload[4] + 5 /* SSL Header */; u_int8_t handshake_protocol = packet->payload[5]; /* handshake protocol a bit misleading, it is message type according TLS specs */ memset(buffer, 0, buffer_len); /* Truncate total len, search at least in incomplete packet */ if(total_len > packet->payload_packet_len) total_len = packet->payload_packet_len; /* At least "magic" 3 bytes, null for string end, otherwise no need to waste cpu cycles */ if(total_len > 4) { int i; if(handshake_protocol == 0x02 || handshake_protocol == 0xb /* Server Hello and Certificate message types are interesting for us */) { u_int num_found = 0; flow->l4.tcp.ssl_seen_server_cert = 1; /* Check after handshake protocol header (5 bytes) and message header (4 bytes) */ for(i = 9; i < packet->payload_packet_len-3; i++) { if(((packet->payload[i] == 0x04) && (packet->payload[i+1] == 0x03) && (packet->payload[i+2] == 0x0c)) || ((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x03))) { u_int8_t server_len = packet->payload[i+3]; if(packet->payload[i] == 0x55) { num_found++; if(num_found != 2) continue; } if(server_len+i+3 < packet->payload_packet_len) { char *server_name = (char*)&packet->payload[i+4]; u_int8_t begin = 0, len, j, num_dots; while(begin < server_len) { if(!ndpi_isprint(server_name[begin])) begin++; else break; } // len = ndpi_min(server_len-begin, buffer_len-1); len = buffer_len-1; strncpy(buffer, &server_name[begin], len); buffer[len] = '\0'; /* We now have to check if this looks like an IP address or host name */ for(j=0, num_dots = 0; j=2) break; } } if(num_dots >= 2) { stripCertificateTrailer(buffer, buffer_len); snprintf(flow->protos.ssl.server_certificate, sizeof(flow->protos.ssl.server_certificate), "%s", buffer); return(1 /* Server Certificate */); } } } } } else if(handshake_protocol == 0x01 /* Client Hello */) { u_int offset, base_offset = 43; u_int16_t session_id_len = packet->payload[base_offset]; if((session_id_len+base_offset+2) <= total_len) { u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8); offset = base_offset + session_id_len + cypher_len + 2; flow->l4.tcp.ssl_seen_client_cert = 1; if(offset < total_len) { u_int16_t compression_len; u_int16_t extensions_len; compression_len = packet->payload[offset+1]; offset += compression_len + 3; if(offset < total_len) { extensions_len = packet->payload[offset]; if((extensions_len+offset) < total_len) { u_int16_t extension_offset = 1; /* Move to the first extension */ while(extension_offset < extensions_len) { u_int16_t extension_id, extension_len; memcpy(&extension_id, &packet->payload[offset+extension_offset], 2); extension_offset += 2; memcpy(&extension_len, &packet->payload[offset+extension_offset], 2); extension_offset += 2; extension_id = ntohs(extension_id), extension_len = ntohs(extension_len); if(extension_id == 0) { u_int begin = 0,len; char *server_name = (char*)&packet->payload[offset+extension_offset]; while(begin < extension_len) { if((!ndpi_isprint(server_name[begin])) || ndpi_ispunct(server_name[begin]) || ndpi_isspace(server_name[begin])) begin++; else break; } len = (u_int)ndpi_min(extension_len-begin, buffer_len-1); strncpy(buffer, &server_name[begin], len); buffer[len] = '\0'; stripCertificateTrailer(buffer, buffer_len); snprintf(flow->protos.ssl.client_certificate, sizeof(flow->protos.ssl.client_certificate), "%s", buffer); /* We're happy now */ return(2 /* Client Certificate */); } extension_offset += extension_len; } } } } } } } } return(0); /* Not found */ } int sslDetectProtocolFromCertificate(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if((packet->payload_packet_len > 9) && (packet->payload[0] == 0x16 /* consider only specific SSL packets (handshake) */)) { 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_host_subprotocol(ndpi_struct, flow, certificate, strlen(certificate), NDPI_PROTOCOL_SSL) != NDPI_PROTOCOL_UNKNOWN) return(rc); /* Fix courtesy of Gianluca Costa */ #ifdef NDPI_PROTOCOL_TOR if(ndpi_is_ssl_tor(ndpi_struct, flow, certificate) != 0) return(rc); #endif } if(((packet->ssl_certificate_num_checks >= 2) && flow->l4.tcp.seen_syn && flow->l4.tcp.seen_syn_ack && flow->l4.tcp.seen_ack /* We have seen the 3-way handshake */) || (flow->protos.ssl.server_certificate[0] != '\0') || (flow->protos.ssl.client_certificate[0] != '\0') ) ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL); } } return(0); } static void ssl_mark_and_payload_search_for_other_protocols(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { #if defined(NDPI_PROTOCOL_MEEBO)|| defined(NDPI_PROTOCOL_TOR) || defined(NDPI_PROTOCOL_VPN_X) || defined(NDPI_PROTOCOL_UNENCRYPED_JABBER) || defined (NDPI_PROTOCOL_OSCAR) || defined (NDPI_PROTOCOL_ITUNES) || defined (NDPI_SERVICE_GMAIL) struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=flow->src; // struct ndpi_id_struct *dst=flow->dst; u_int32_t a; u_int32_t end; #if defined(NDPI_PROTOCOL_UNENCRYPED_JABBER) if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) goto check_for_ssl_payload; #endif #if defined(NDPI_PROTOCOL_OSCAR) if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_OSCAR) != 0) goto check_for_ssl_payload; #endif goto no_check_for_ssl_payload; check_for_ssl_payload: end = packet->payload_packet_len - 20; for (a = 5; a < end; a++) { #ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER if(packet->payload[a] == 't') { if(memcmp(&packet->payload[a], "talk.google.com", 15) == 0) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "ssl jabber packet match\n"); if(NDPI_COMPARE_PROTOCOL_TO_BITMASK (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) { ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER); return; } } } #endif #ifdef NDPI_PROTOCOL_OSCAR if(packet->payload[a] == 'A' || packet->payload[a] == 'k' || packet->payload[a] == 'c' || packet->payload[a] == 'h') { if(((a + 19) < packet->payload_packet_len && memcmp(&packet->payload[a], "America Online Inc.", 19) == 0) // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 ) // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0) || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0) || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "corehc@aol.net", 14) == 0) || ((a + 41) < packet->payload_packet_len && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0) || ((a + 28) < packet->payload_packet_len && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0) || ((a + 32) < packet->payload_packet_len && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); if(flow->dst != NULL && packet->payload_packet_len > 75) { memcpy(flow->dst->oscar_ssl_session_id, &packet->payload[44], 32); flow->dst->oscar_ssl_session_id[32] = '\0'; flow->dst->oscar_last_safe_access_time = packet->tick_timestamp; } ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR); return; } } if(packet->payload[a] == 'm' || packet->payload[a] == 's') { if((a + 21) < packet->payload_packet_len && (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0 || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR); return; } } #endif } no_check_for_ssl_payload: #endif if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "found ssl connection.\n"); sslDetectProtocolFromCertificate(ndpi_struct, flow); if(!packet->ssl_certificate_detected && (!(flow->l4.tcp.ssl_seen_client_cert && flow->l4.tcp.ssl_seen_server_cert))) { /* SSL without certificate (Skype, Ultrasurf?) */ ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL_NO_CERT); } else ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL); } } static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // // struct ndpi_id_struct *src=flow->src; // struct ndpi_id_struct *dst=flow->dst; if((packet->payload_packet_len >= 5) && (packet->payload[0] == 0x16) && (packet->payload[1] == 0x03) && ((packet->payload[2] == 0x00) || (packet->payload[2] == 0x01) || (packet->payload[2] == 0x02) || (packet->payload[2] == 0x03) )) { u_int32_t temp; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search sslv3\n"); // SSLv3 Record if(packet->payload_packet_len >= 1300) { return 1; } temp = ntohs(get_u_int16_t(packet->payload, 3)) + 5; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp); if(packet->payload_packet_len == temp || (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) { return 1; } if(packet->payload_packet_len < temp && temp < 5000 && packet->payload_packet_len > 9) { /* the server hello may be split into small packets */ u_int32_t cert_start; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "maybe SSLv3 server hello split into smaller packets\n"); /* lets hope at least the server hello and the start of the certificate block are in the first packet */ cert_start = ntohs(get_u_int16_t(packet->payload, 7)) + 5 + 4; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "suspected start of certificate: %u\n", cert_start); if(cert_start < packet->payload_packet_len && packet->payload[cert_start] == 0x0b) { NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "found 0x0b at suspected start of certificate block\n"); return 2; } } if((packet->payload_packet_len > temp && packet->payload_packet_len > 100) && packet->payload_packet_len > 9) { /* the server hello may be split into small packets and the certificate has its own SSL Record * so temp contains only the length for the first ServerHello block */ u_int32_t cert_start; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "maybe SSLv3 server hello split into smaller packets but with seperate record for the certificate\n"); /* lets hope at least the server hello record and the start of the certificate record are in the first packet */ cert_start = ntohs(get_u_int16_t(packet->payload, 7)) + 5 + 5 + 4; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "suspected start of certificate: %u\n", cert_start); if(cert_start < packet->payload_packet_len && packet->payload[cert_start] == 0x0b) { NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "found 0x0b at suspected start of certificate block\n"); return 2; } } if(packet->payload_packet_len >= temp + 5 && (packet->payload[temp] == 0x14 || packet->payload[temp] == 0x16) && packet->payload[temp + 1] == 0x03) { u_int32_t temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; } temp += temp2; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp); if(packet->payload_packet_len == temp) { return 1; } if(packet->payload_packet_len >= temp + 5 && packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; } temp += temp2; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp); if(packet->payload_packet_len == temp) { return 1; } if(packet->payload_packet_len >= temp + 5 && packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; } temp += temp2; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp); if(temp == packet->payload_packet_len) { return 1; } } } } } return 0; } void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=flow->src; // struct ndpi_id_struct *dst=flow->dst; u_int8_t ret; if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) { if(flow->l4.tcp.ssl_stage == 3 && packet->payload_packet_len > 20 && flow->packet_counter < 5) { /* this should only happen, when we detected SSL with a packet that had parts of the certificate in subsequent packets * so go on checking for certificate patterns for a couple more packets */ NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "ssl flow but check another packet for patterns\n"); ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow); if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) { /* still ssl so check another packet */ return; } else { /* protocol has changed so we are done */ return; } } return; } NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search ssl\n"); { /* Check if this is whatsapp first (this proto runs over port 443) */ if((packet->payload_packet_len > 5) && ((packet->payload[0] == 'W') && (packet->payload[1] == 'A') && (packet->payload[4] == 0) && (packet->payload[2] <= 9) && (packet->payload[3] <= 9))) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_SERVICE_WHATSAPP, NDPI_PROTOCOL_UNKNOWN); 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; } void init_ssl_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("SSL", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/starcraft.c000066400000000000000000000132671262705051000250660ustar00rootroot00000000000000/* * starcraft.c * * Copyright (C) 2015 - Matteo Bracci * Copyright (C) 2015 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_STARCRAFT /* Sender or receiver are one of the known login portals? */ u_int8_t sc2_match_logon_ip(struct ndpi_packet_struct* packet) { if (packet->iph == NULL) return 0; u_int32_t source_ip = ntohl(packet->iph->saddr); u_int32_t dest_ip = ntohl(packet->iph->daddr); return (ndpi_ips_match(source_ip, dest_ip, 0xD5F87F82, 32) // EU 213.248.127.130 || ndpi_ips_match(source_ip, dest_ip, 0x0C81CE82, 32) // US 12.129.206.130 || ndpi_ips_match(source_ip, dest_ip, 0x79FEC882, 32) // KR 121.254.200.130 || ndpi_ips_match(source_ip, dest_ip, 0xCA09424C, 32) // SG 202.9.66.76 || ndpi_ips_match(source_ip, dest_ip, 0x0C81ECFE, 32)); // BETA 12.129.236.254 } /* The main TCP flow starts with the user login and stays alive until the logout. Although hard to read, judging from what happens elsewhere this flow probably contains all the data transfer generated by the user interaction with the client, e.g. chatting or looking at someone's match history. The current way to detect this is plain dumb packet matching. */ u_int8_t ndpi_check_starcraft_tcp(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) { if (sc2_match_logon_ip(&flow->packet) && flow->packet.tcp->dest == htons(1119) //bnetgame port && flow->packet.payload_packet_len >= 10 && (match_first_bytes(flow->packet.payload, "\x4a\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66") || match_first_bytes(flow->packet.payload, "\x49\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66"))) return 1; else return -1; } /* UPD traffic is the actual game data and it uses a port owned by Blizzard itself, 1119. Therefore the real key point here is to make sure that it's actually Starcraft 2 that is using the port and not some other Blizzard software. The flow is taken if a pattern in the size of some subsequent packets is found. */ u_int8_t ndpi_check_starcraft_udp(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) { struct ndpi_packet_struct* packet = &flow->packet; /* First off, filter out any traffic not using port 1119, removing the chance of any false positive if we assume that non allowed protocols don't use the port */ if (packet->udp->source != htons(1119) && packet->udp->dest != htons(1119)) return -1; /* Then try to detect the size pattern */ switch (flow->starcraft_udp_stage) { case 0: if (packet->payload_packet_len == 20) flow->starcraft_udp_stage = 1; break; case 1: if (packet->payload_packet_len == 20) flow->starcraft_udp_stage = 2; break; case 2: if (packet->payload_packet_len == 75 || packet->payload_packet_len == 85) flow->starcraft_udp_stage = 3; break; case 3: if (packet->payload_packet_len == 20) flow->starcraft_udp_stage = 4; break; case 4: if (packet->payload_packet_len == 548) flow->starcraft_udp_stage = 5; break; case 5: if (packet->payload_packet_len == 548) flow->starcraft_udp_stage = 6; break; case 6: if (packet->payload_packet_len == 548) flow->starcraft_udp_stage = 7; break; case 7: if (packet->payload_packet_len == 484) return 1; break; } return(0); } void ndpi_search_starcraft(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) { NDPI_LOG(NDPI_PROTOCOL_STARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "Starcraft protocol detection...\n"); if (flow->packet.detected_protocol_stack[0] != NDPI_PROTOCOL_STARCRAFT) { struct ndpi_packet_struct* packet = &flow->packet; int8_t result = 0; if (packet->udp != NULL) { result = ndpi_check_starcraft_udp(ndpi_struct, flow); if (result == 1) { //printf("Found Starcraft 2 [Game, UDP]\n"); NDPI_LOG(NDPI_PROTOCOL_STARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "Found Starcraft 2 [Game, UDP]\n"); } } else if (packet->tcp != NULL) { result = ndpi_check_starcraft_tcp(ndpi_struct, flow); if (result == 1) { //printf("Found Starcraft 2 [Client, TCP]\n"); NDPI_LOG(NDPI_PROTOCOL_STARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "Found Starcraft 2 [Client, TCP]\n"); } } if (result == 1) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_STARCRAFT, NDPI_PROTOCOL_UNKNOWN); } else if (result == -1) { NDPI_LOG(NDPI_PROTOCOL_STARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "Starcraft excluded\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_STARCRAFT); } } } void init_starcraft_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Starcraft", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_STARCRAFT, ndpi_search_starcraft, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/stealthnet.c000066400000000000000000000046151262705051000252450ustar00rootroot00000000000000/* * stealthnet.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_STEALTHNET static void ndpi_int_stealthnet_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_STEALTHNET, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_stealthnet_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Stealthnet", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/steam.c000066400000000000000000000332201262705051000241750ustar00rootroot00000000000000/* * steam.c * * Copyright (C) 2014 Tomasz Bujlow * * The signature is mostly based on the Libprotoident library * except the detection of HTTP Steam flows. * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_STEAM static void ndpi_int_steam_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_STEAM, NDPI_PROTOCOL_UNKNOWN); } 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; NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, 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); } void init_steam_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Steam", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/stun.c000066400000000000000000000241221262705051000240560ustar00rootroot00000000000000/* * stun.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_STUN #define MAX_NUM_STUN_PKTS 6 struct stun_packet_header { u_int16_t msg_type, msg_len; u_int32_t cookie; u_int8_t transaction_id[8]; }; static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *ndpi_struct, u_int proto, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, proto, NDPI_PROTOCOL_UNKNOWN); } 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, struct ndpi_flow_struct *flow, const u_int8_t * payload, const u_int16_t payload_length, u_int8_t *is_whatsapp, u_int8_t *is_lync) { u_int16_t msg_type, msg_len; struct stun_packet_header *h = (struct stun_packet_header*)payload; if(payload_length < sizeof(struct stun_packet_header)) return(NDPI_IS_NOT_STUN); if((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"); goto udp_stun_found; } msg_type = ntohs(h->msg_type) & 0x3EEF, msg_len = ntohs(h->msg_len); if((payload[0] != 0x80) && ((msg_len+20) > payload_length)) return(NDPI_IS_NOT_STUN); /* printf("msg_type=%04X, msg_len=%u\n", msg_type, msg_len); */ if((payload_length == (msg_len+20)) && ((msg_type <= 0x000b) /* http://www.3cx.com/blog/voip-howto/stun-details/ */)) { u_int offset = 20; /* This can either be the standard RTCP or Ms Lync RTCP that later will becomg Ms Lync RTP. In this case we need to be careful before deciding about the protocol before dissecting the packet */ while(offset < payload_length) { u_int16_t attribute = ntohs(*((u_int16_t*)&payload[offset])); u_int16_t len = ntohs(*((u_int16_t*)&payload[offset+2])); switch(attribute) { case 0x8054: /* Candidate Identifier */ if((len == 4) && (payload[offset+4] == 0x31) && (payload[offset+5] == 0x00) && (payload[offset+6] == 0x00) && (payload[offset+7] == 0x00)) { *is_lync = 1; return(NDPI_IS_STUN); } break; case 0x8070: /* Implementation Version */ if((len == 4) && (payload[offset+4] == 0x00) && (payload[offset+5] == 0x00) && (payload[offset+6] == 0x00) && (payload[offset+7] == 0x02)) { *is_lync = 1; return(NDPI_IS_STUN); } break; } offset += len + 4; } goto udp_stun_found; } #ifdef ORIGINAL_CODE /* * 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"); goto udp_stun_found; } 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"); goto udp_stun_found; } } 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)) || ((payload[a + padding] == 0x40) && (payload[a + padding + 1] == 0x00)) )) { if((payload[a + padding] == 0x40) && (payload[a + padding + 1] == 0x00)) goto udp_stun_found; 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"); goto udp_stun_found; } } else { break; } } } #endif if( ((flow->num_stun_udp_pkts > 0) && (msg_type == 0x0800)) || ((msg_type == 0x0800) && (msg_len == 106)) ) { *is_whatsapp = 1; return NDPI_IS_STUN; /* This is WhatsApp Voice */ } else return NDPI_IS_NOT_STUN; udp_stun_found: flow->num_stun_udp_pkts++; return((flow->num_stun_udp_pkts < MAX_NUM_STUN_PKTS) ? NDPI_IS_NOT_STUN : NDPI_IS_STUN); } void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; u_int8_t is_whatsapp = 0, is_lync = 0; 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, flow, packet->payload + 2, packet->payload_packet_len - 2, &is_whatsapp, &is_lync) == NDPI_IS_STUN) { NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found TCP stun.\n"); ndpi_int_stun_add_connection(ndpi_struct, NDPI_PROTOCOL_STUN, flow); return; } } } if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload, packet->payload_packet_len, &is_whatsapp, &is_lync) == NDPI_IS_STUN) { if(is_lync) { NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "Found MS Lync\n"); ndpi_int_stun_add_connection(ndpi_struct, NDPI_PROTOCOL_MS_LYNC, flow); } else { NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found UDP stun.\n"); ndpi_int_stun_add_connection(ndpi_struct, is_whatsapp ? NDPI_PROTOCOL_WHATSAPP_VOICE : NDPI_PROTOCOL_STUN, flow); } return; } if(flow->num_stun_udp_pkts >= MAX_NUM_STUN_PKTS) { 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); } } void init_stun_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("STUN", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_STUN, ndpi_search_stun, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/syslog.c000066400000000000000000000120131262705051000244010ustar00rootroot00000000000000/* * syslog.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_SYSLOG static void ndpi_int_syslog_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SYSLOG, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_syslog_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Syslog", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/tcp_udp.c000066400000000000000000000050311262705051000245210ustar00rootroot00000000000000/* * tcp_or_udp.c * * Copyright (C) 2011-15 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" /* ndpi_main.c */ extern u_int8_t ndpi_is_tor_flow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); u_int ndpi_search_tcp_or_udp_raw(struct ndpi_detection_module_struct *ndpi_struct, u_int8_t protocol, u_int32_t saddr, u_int32_t daddr, /* host endianess */ u_int16_t sport, u_int16_t dport) /* host endianess */ { u_int16_t rc; if(protocol == IPPROTO_UDP) { if((sport == dport) && (sport == 17500)) { return(NDPI_PROTOCOL_DROPBOX); } } if((rc = ndpi_host_ptree_match(ndpi_struct, htonl(saddr))) != NDPI_PROTOCOL_UNKNOWN) return(rc); return(ndpi_host_ptree_match(ndpi_struct, htonl(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(flow->host_server_name[0] != '\0') return; if(ndpi_is_tor_flow(ndpi_struct, flow)) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TOR, NDPI_PROTOCOL_UNKNOWN); 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->ip6_ctlun.ip6_un1.ip6_un1_nxt, #else 0, #endif ntohl(packet->iph->saddr), ntohl(packet->iph->daddr), sport, dport); if(proto != NDPI_PROTOCOL_UNKNOWN) ndpi_set_detected_protocol(ndpi_struct, flow, proto, NDPI_PROTOCOL_UNKNOWN); } } nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/tds.c000066400000000000000000000064631262705051000236670ustar00rootroot00000000000000/* * tds.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_TDS static void ndpi_int_tds_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TDS, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_tds_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("TDS", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/teamspeak.c000066400000000000000000000063421262705051000250430ustar00rootroot00000000000000/* * teamspeak.c * * Copyright (C) 2013 Remy Mudingay * * This module is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This module is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License. * If not, see . */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_TEAMSPEAK static void ndpi_int_teamspeak_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TEAMSPEAK, NDPI_PROTOCOL_UNKNOWN); } 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; } void init_teamspeak_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("TeamSpeak", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_TEAMSPEAK, ndpi_search_teamspeak, NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/teamviewer.c000066400000000000000000000076111262705051000252410ustar00rootroot00000000000000/* * teamviewer.c * * Copyright (C) 2012 by Gianluca Costa xplico.org * Copyright (C) 2012-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_TEAMVIEWER static void ndpi_int_teamview_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TEAMVIEWER, NDPI_PROTOCOL_UNKNOWN); 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); } void init_teamviewer_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("TeamViewer", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_TEAMVIEWER, ndpi_search_teamview, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/telegram.c000066400000000000000000000053311262705051000246660ustar00rootroot00000000000000/* * telegram.c * * Copyright (C) 2014 by Gianluca Costa xplico.org * Copyright (C) 2012-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_TELEGRAM static void ndpi_int_telegram_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TELEGRAM, NDPI_PROTOCOL_UNKNOWN); 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); } void init_telegram_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Telegram", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_TELEGRAM, ndpi_search_telegram, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/telnet.c000066400000000000000000000074001262705051000243600ustar00rootroot00000000000000/* * telnet.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_TELNET static void ndpi_int_telnet_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TELNET, NDPI_PROTOCOL_UNKNOWN); } #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; } void init_telnet_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Telnet", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/teredo.c000066400000000000000000000033701262705051000243510ustar00rootroot00000000000000/* * teredo.c * * Copyright (C) 2015 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_TEREDO /* https://en.wikipedia.org/wiki/Teredo_tunneling */ void ndpi_search_teredo(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if(packet->udp && ((ntohs(packet->udp->source) == 3544) || (ntohs(packet->udp->dest) == 3544)) && (packet->payload_packet_len >= 40 /* IPv6 header */)) ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TEREDO, NDPI_PROTOCOL_UNKNOWN); else NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TEREDO); } void init_teredo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("TEREDO", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_TEREDO, ndpi_search_teredo, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/tftp.c000066400000000000000000000055711262705051000240510ustar00rootroot00000000000000/* * tftp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_TFTP static void ndpi_int_tftp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TFTP, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_tftp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("TFTP", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_TFTP, ndpi_search_tftp, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/thunder.c000066400000000000000000000201651262705051000245410ustar00rootroot00000000000000/* * thunder.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_THUNDER static void ndpi_int_thunder_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , ndpi_protocol_type_t protocol_type */) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_THUNDER, NDPI_PROTOCOL_UNKNOWN); 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); 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); 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); 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); } } } 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); } } void init_thunder_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Thunder", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/tor.c000066400000000000000000000064761262705051000237050ustar00rootroot00000000000000/* * tor.c * * Copyright (C) 2015 ntop.org * Copyright (C) 2013 Remy Mudingay * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_TOR static void ndpi_int_tor_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TOR, NDPI_PROTOCOL_UNKNOWN); } 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 { #ifdef PENDANTIC_TOR_CHECK if(gethostbyname(certificate) == NULL) { ndpi_int_tor_add_connection(ndpi_struct, flow); return(1); } #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); } } void init_tor_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Tor", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/tvants.c000066400000000000000000000066611262705051000244140ustar00rootroot00000000000000/* * tvants.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_TVANTS static void ndpi_int_tvants_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TVANTS, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_tvants_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Tvants", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/tvuplayer.c000066400000000000000000000165251262705051000251300ustar00rootroot00000000000000/* * tvuplayer.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_TVUPLAYER static void ndpi_int_tvuplayer_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , */ /* ndpi_protocol_type_t protocol_type */) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TVUPLAYER, NDPI_PROTOCOL_UNKNOWN); } 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); } void init_tvuplayer_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("TVUplayer", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/twitter.c000066400000000000000000000046641262705051000246000ustar00rootroot00000000000000/* * twitter.c * * Copyright (C) 2014 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_SERVICE_TWITTER static void ndpi_int_twitter_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_SERVICE_TWITTER, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_twitter_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("TWITTER", ndpi_struct, detection_bitmask, *id, NDPI_SERVICE_TWITTER, ndpi_search_twitter, NDPI_SELECTION_BITMASK_PROTOCOL_TCP, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/ubntac2.c000066400000000000000000000043061262705051000244250ustar00rootroot00000000000000/* * ubntac2.c * * Copyright (C) 2015 Thomas Fjellstrom * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_UBNTAC2 static void ndpi_int_ubntac2_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_UBNTAC2, NDPI_PROTOCOL_UNKNOWN); } void ndpi_search_ubntac2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; NDPI_LOG(NDPI_PROTOCOL_UBNTAC2, ndpi_struct, NDPI_LOG_TRACE, "UBNTAC2 detection... plen:%i %i:%i\n", packet->payload_packet_len, ntohs(packet->udp->source), ntohs(packet->udp->dest)); if (packet->payload_packet_len >= 135 && (packet->udp->source == htons(10001) || packet->udp->dest == htons(10001)) && memcmp(&(packet->payload[36]), "UBNT", 4) == 0) { NDPI_LOG(NDPI_PROTOCOL_UBNTAC2, ndpi_struct, NDPI_LOG_DEBUG, "UBNT AirControl 2 request\n"); ndpi_int_ubntac2_add_connection(ndpi_struct, flow); return; } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_UBNTAC2); } void init_ubntac2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("UBNTAC2", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_UBNTAC2, ndpi_search_ubntac2, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/usenet.c000066400000000000000000000075651262705051000244040ustar00rootroot00000000000000/* * usenet.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_USENET static void ndpi_int_usenet_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_USENET, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_usenet_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Usenet", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/veohtv.c000066400000000000000000000120741262705051000244030ustar00rootroot00000000000000/* * veohtv.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV static void ndpi_int_veohtv_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , ndpi_protocol_type_t protocol_type */) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV, NDPI_PROTOCOL_UNKNOWN); } 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); 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); 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); 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); 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); return; } } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP_APPLICATION_VEOHTV); } void init_veohtv_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("HTTP_APPLICATION_VEOHTV", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/vhua.c000066400000000000000000000052531262705051000240340ustar00rootroot00000000000000/* * vhua.c * * Copyright (C) 2011-15 - ntop.org * * nDPI is free software: you can vhuatribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" /* http://www.vhua.com Skype-like Chinese phone protocol */ #ifdef NDPI_PROTOCOL_VHUA static void ndpi_int_vhua_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_VHUA, NDPI_PROTOCOL_UNKNOWN); 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); } } void init_vhua_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("VHUA", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_VHUA, ndpi_search_vhua, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/viber.c000066400000000000000000000043761262705051000242050ustar00rootroot00000000000000/* * viber.c * * Copyright (C) 2013 Remy Mudingay * Copyright (C) 2013 - 2014 ntop.org * * This module is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This module is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License. * If not, see . */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_VIBER void ndpi_search_viber(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; NDPI_LOG(NDPI_PROTOCOL_VIBER, ndpi_struct, NDPI_LOG_DEBUG, "search for VIBER.\n"); if(packet->udp != NULL) { NDPI_LOG(NDPI_PROTOCOL_VIBER, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over udp.\n"); if((packet->payload_packet_len == 12 && packet->payload[2] == 0x03 && packet->payload[3] == 0x00) || (packet->payload_packet_len == 20 && packet->payload[2] == 0x09 && packet->payload[3] == 0x00) || ((packet->payload_packet_len < 135) && (packet->payload[0] == 0x11))) { NDPI_LOG(NDPI_PROTOCOL_VIBER, ndpi_struct, NDPI_LOG_DEBUG, "found VIBER.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_VIBER, NDPI_PROTOCOL_UNKNOWN); 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); } void init_viber_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("VIBER", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_VIBER, ndpi_search_viber, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/vmware.c000066400000000000000000000036021262705051000243660ustar00rootroot00000000000000/* * vmware.c * * Copyright (C) 2011-15 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_VMWARE void ndpi_search_vmware(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; /* Check whether this is an VMWARE flow */ if((packet->payload_packet_len == 66) && (ntohs(packet->udp->dest) == 902) && ((packet->payload[0] & 0xFF) == 0xA4)) { NDPI_LOG(NDPI_PROTOCOL_VMWARE, ndpi_struct, NDPI_LOG_DEBUG, "Found vmware.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_VMWARE, NDPI_PROTOCOL_UNKNOWN); } 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); } } void init_vmware_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("VMWARE", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_VMWARE, ndpi_search_vmware, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/vnc.c000066400000000000000000000053351262705051000236600ustar00rootroot00000000000000/* * vnc.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_VNC static void ndpi_int_vnc_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_VNC, NDPI_PROTOCOL_UNKNOWN); } /* 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); } void init_vnc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("VNC", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/warcraft3.c000066400000000000000000000100271262705051000247600ustar00rootroot00000000000000/* * warcraft3.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ /* include files */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_WARCRAFT3 static void ndpi_int_warcraft3_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WARCRAFT3, NDPI_PROTOCOL_UNKNOWN); } 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_int16_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); } void init_warcraft3_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Warcraft3", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/whoisdas.c000066400000000000000000000050011262705051000247010ustar00rootroot00000000000000/* * whoisdas.c * * Copyright (C) 2013 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_WHOIS_DAS void ndpi_search_whois_das(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; u_int16_t sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); if ((packet->tcp != NULL) && ( ((sport == 43) || (dport == 43)) || ((sport == 4343) || (dport == 4343)) ) ) { if(packet->payload_packet_len > 0) { u_int max_len = sizeof(flow->host_server_name)-1; u_int i, j; for(i=strlen((const char *)flow->host_server_name), j=0; (ipayload_packet_len); i++, j++) { if((packet->payload[j] == '\n') || (packet->payload[j] == '\r')) break; flow->host_server_name[i] = packet->payload[j]; } flow->host_server_name[i] = '\0'; flow->server_id = ((sport == 43) || (sport == 4343)) ? flow->src : flow->dst; NDPI_LOG(NDPI_PROTOCOL_WHOIS_DAS, ndpi_struct, NDPI_LOG_DEBUG, "[WHOIS/DAS] %s\n", flow->host_server_name); } ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WHOIS_DAS, NDPI_PROTOCOL_UNKNOWN); } 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); } } void init_whois_das_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Whois-DAS", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/winmx.c000066400000000000000000000100321262705051000242220ustar00rootroot00000000000000/* * winmx.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_WINMX static void ndpi_int_winmx_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); static void ndpi_int_winmx_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WINMX, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_winmx_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("WinMX", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/world_of_kung_fu.c000066400000000000000000000054531262705051000264240ustar00rootroot00000000000000/* * world_of_kung_fu.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ /* include files */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_WORLD_OF_KUNG_FU static void ndpi_int_world_of_kung_fu_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WORLD_OF_KUNG_FU, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_world_of_kung_fu_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("WorldOfKungFu", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/world_of_warcraft.c000066400000000000000000000221241262705051000265710ustar00rootroot00000000000000/* * world_of_warcraft.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_WORLDOFWARCRAFT static void ndpi_int_worldofwarcraft_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , */ /* ndpi_protocol_type_t protocol_type */) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WORLDOFWARCRAFT, NDPI_PROTOCOL_UNKNOWN); } #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_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_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_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_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_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_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_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_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_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); } void init_world_of_warcraft_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("WorldOfWarcraft", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/xbox.c000066400000000000000000000105521262705051000240470ustar00rootroot00000000000000/* * xbox.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_XBOX static void ndpi_int_xbox_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_XBOX, NDPI_PROTOCOL_UNKNOWN); } 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... */ } void init_xbox_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Xbox", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_XBOX, ndpi_search_xbox, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, NO_SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/xdmcp.c000066400000000000000000000060721262705051000242040ustar00rootroot00000000000000/* * xdmcp.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_protocols.h" #ifdef NDPI_PROTOCOL_XDMCP static void ndpi_int_xdmcp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_XDMCP, NDPI_PROTOCOL_UNKNOWN); } 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); } void init_xdmcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("XDMCP", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/yahoo.c000066400000000000000000000405641262705051000242140ustar00rootroot00000000000000/* * yahoo.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_YAHOO struct ndpi_yahoo_header { u_int8_t YMSG_str[4]; u_int16_t version; u_int16_t nothing0; u_int16_t len; u_int16_t service; u_int32_t status; u_int32_t session_id; }; /* This function checks the pattern 'packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; const struct ndpi_yahoo_header *yahoo = (struct ndpi_yahoo_header *) packet->payload; if (packet->payload_packet_len == 0) { return; } /* packet must be at least 20 bytes long */ if (packet->payload_packet_len >= 20 && memcmp(yahoo->YMSG_str, "YMSG", 4) == 0 && ((packet->payload_packet_len - 20) == ntohs(yahoo->len) || check_ymsg(packet->payload, packet->payload_packet_len))) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO FOUND\n"); flow->yahoo_detection_finished = 2; if (ntohs(yahoo->service) == 24 || ntohs(yahoo->service) == 152 || ntohs(yahoo->service) == 74) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO conference or chat invite found"); if (src != NULL) { src->yahoo_conf_logged_in = 1; } if (dst != NULL) { dst->yahoo_conf_logged_in = 1; } } if (ntohs(yahoo->service) == 27 || ntohs(yahoo->service) == 155 || ntohs(yahoo->service) == 160) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO conference or chat logoff found"); if (src != NULL) { src->yahoo_conf_logged_in = 0; src->yahoo_voice_conf_logged_in = 0; } } NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow); 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); 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); 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); 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); 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); return; } } if (packet->parsed_lines > 8 && packet->line[8].len > 250 && packet->line[8].ptr != NULL) { if (memcmp(packet->line[8].ptr, "line[8].len, packet->line[8].ptr)) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found HTTP Proxy Yahoo Chat payload, "GET /Messenger.", 15) == 0) { if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0) || (dst != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0)) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO HTTP GET /Messenger. match\n"); NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow); 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); 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); return; } } } /* found another http login command for yahoo, it is like OSCAR */ /* detect http connections */ if (packet->payload_packet_len > 50 && (memcmp(packet->payload, "content-length: ", 16) == 0)) { ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->parsed_lines > 2 && packet->line[1].len == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "first line is empty.\n"); if (packet->line[2].len > 13 && memcmp(packet->line[2].ptr, "payload_packet_len > 38 && memcmp(packet->payload, "CONNECT scs.msg.yahoo.com:5050 HTTP/1.", 38) == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO-HTTP FOUND\n"); NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow); 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); return; } /* asymmetric detection for SNDIMG not done yet. * See ./Yahoo8.1-VideoCall-LAN.pcap and ./Yahoo-VideoCall-inPublicIP.pcap */ if (packet->payload_packet_len == 8 && (memcmp(packet->payload, "", 8) == 0 || memcmp(packet->payload, "", 8) == 0 || memcmp(packet->payload, "", 8) == 0 || memcmp(packet->payload, "", 8) == 0)) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO SNDIMG or REQIMG or RVWCFG or RUPCFG FOUND\n"); if (src != NULL) { if (memcmp(packet->payload, "", 8) == 0) { src->yahoo_video_lan_dir = 0; } else { src->yahoo_video_lan_dir = 1; } src->yahoo_video_lan_timer = packet->tick_timestamp; } if (dst != NULL) { if (memcmp(packet->payload, "", 8) == 0) { dst->yahoo_video_lan_dir = 0; } else { dst->yahoo_video_lan_dir = 1; } dst->yahoo_video_lan_timer = packet->tick_timestamp; } NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO subtype VIDEO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow); 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_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_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "IMG MARKED"); return; } } } /* detect YAHOO over HTTP proxy */ #ifdef NDPI_PROTOCOL_HTTP if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP) #endif { if (flow->l4.tcp.yahoo_http_proxy_stage == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "YAHOO maybe HTTP proxy packet 1 => need next packet\n"); flow->l4.tcp.yahoo_http_proxy_stage = 1 + packet->packet_direction; return; } if (flow->l4.tcp.yahoo_http_proxy_stage == 1 + packet->packet_direction) { if ((packet->payload_packet_len > 250) && (memcmp(packet->payload, "payload_packet_len, packet->payload)) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found HTTP Proxy Yahoo Chat need next packet\n"); return; } if (flow->l4.tcp.yahoo_http_proxy_stage == 2 - packet->packet_direction) { ndpi_parse_packet_line_info_any(ndpi_struct, flow); if (packet->parsed_lines >= 9) { if (packet->line[4].ptr != NULL && packet->line[4].len >= 9 && packet->line[8].ptr != NULL && packet->line[8].len >= 6 && memcmp(packet->line[4].ptr, "line[8].ptr, "excluded_protocol_bitmask, NDPI_PROTOCOL_YAHOO); } #if !defined(WIN32) static inline #else __forceinline static #endif void ndpi_search_yahoo_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_id_struct *src = flow->src; if (src == NULL || NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) == 0) { goto excl_yahoo_udp; } excl_yahoo_udp: NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_YAHOO); } void ndpi_search_yahoo(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "search yahoo\n"); if (packet->payload_packet_len > 0 && flow->yahoo_detection_finished == 0) { if (packet->tcp != NULL && packet->tcp_retransmission == 0) { if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN #ifdef NDPI_PROTOCOL_HTTP || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP #endif #ifdef NDPI_PROTOCOL_SSL || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL #endif ) { ndpi_search_yahoo_tcp(ndpi_struct, flow); } } else if (packet->udp != NULL) { ndpi_search_yahoo_udp(ndpi_struct, flow); } } if (packet->payload_packet_len > 0 && flow->yahoo_detection_finished == 2) { if (packet->tcp != NULL && packet->tcp_retransmission == 0) { ndpi_search_yahoo_tcp(ndpi_struct, flow); } } } void init_yahoo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("YAHOO", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_YAHOO, ndpi_search_yahoo, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/zattoo.c000066400000000000000000000240021262705051000244020ustar00rootroot00000000000000/* * zattoo.c * * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-15 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_ZATTOO static void ndpi_int_zattoo_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow/* , */ /* ndpi_protocol_type_t protocol_type */) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ZATTOO, NDPI_PROTOCOL_UNKNOWN); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); } void init_zattoo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Zattoo", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_ZATTOO, ndpi_search_zattoo, NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/protocols/zeromq.c000066400000000000000000000077321262705051000244120ustar00rootroot00000000000000/* * zmq.c * * Copyright (C) 2011-15 - ntop.org * * nDPI is free software: you can zmqtribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * nDPI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with nDPI. If not, see . * */ #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_ZMQ static void ndpi_int_zmq_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ZMQ, NDPI_PROTOCOL_UNKNOWN); 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); } } } void init_zmq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("ZeroMQ", ndpi_struct, detection_bitmask, *id, 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); *id += 1; } #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/000077500000000000000000000000001262705051000232255ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/include/000077500000000000000000000000001262705051000246505ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/include/actypes.h000066400000000000000000000132411262705051000264720ustar00rootroot00000000000000/* * actypes.h: Includes basic data types of ahocorasick library * This file is part of multifast. * Copyright 2010-2012 Kamiar Kanani multifast is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. multifast is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with multifast. If not, see . */ #ifndef _AC_TYPES_H_ #define _AC_TYPES_H_ /* AC_ALPHABET_t: * defines the alphabet type. * Actually defining AC_ALPHABET_t as a char will work, but sometimes we deal * with streams of other (bigger) types e.g. integers, specific enum, objects. * Although they consists of string of bytes (chars), but using their specific * types for AC_ALPHABET_t will lead to a better performance. so instead of * dealing with strings of chars, we assume dealing with strings of * AC_ALPHABET_t and leave it optional for other developers to define their * own alphabets. **/ typedef char AC_ALPHABET_t; /* AC_REP_t: * Provides a more readable representative for a pattern. * because patterns themselves are not always suitable for displaying * (e.g. for hex patterns), we offer this type to improve intelligibility * of output. furthermore, sometimes it is useful, for example while * retrieving patterns from a database, to maintain their identifiers in the * automata for further reference. we provisioned two possible types as a * union for this purpose. you can add your desired type in it. **/ typedef union { char * stringy; /* null-terminated string */ unsigned long number; } AC_REP_t; /* AC_PATTERN_t: * This is the pattern type that must be fed into AC automata. * the 'astring' field is not null-terminated, due to it can contain zero * value bytes. the 'length' field determines the number of AC_ALPHABET_t it * carries. the 'representative' field is described in AC_REP_t. despite * 'astring', 'representative' can have duplicate values for different given * AC_PATTERN_t. it is an optional field and you can just fill it with 0. * CAUTION: * Not always the 'astring' points to the correct position in memory. * it is the responsibility of your program to maintain a permanent allocation * for astring field of the added pattern to automata. **/ typedef struct { AC_ALPHABET_t * astring; /* String of alphabets */ unsigned int length; /* Length of pattern */ AC_REP_t rep; /* Representative string (optional) */ } AC_PATTERN_t; /* AC_TEXT_t: * The input text type that is fed to ac_automata_search() to be searched. * it is similar to AC_PATTERN_t. actually we could use AC_PATTERN_t as input * text, but for the purpose of being more readable, we defined this new type. **/ typedef struct { AC_ALPHABET_t * astring; /* String of alphabets */ unsigned int length; /* Length of string */ } AC_TEXT_t; /* AC_MATCH_t: * Provides the structure for reporting a match event. * a match event occurs when the automata reaches a final node. any final * node can match one or more pattern at a position in a text. the * 'patterns' field holds these matched patterns. obviously these * matched patterns have same end-position in the text. there is a relationship * between matched patterns: the shorter one is a factor (tail) of the longer * one. the 'position' maintains the end position of matched patterns. the * start position of patterns could be found by knowing their 'length' in * AC_PATTERN_t. e.g. suppose "recent" and "cent" are matched at * position 40 in the text, then the start position of them are 34 and 36 * respectively. finally the field 'match_num' maintains the number of * matched patterns. **/ typedef struct { AC_PATTERN_t * patterns; /* Array of matched pattern */ long position; /* The end position of matching pattern(s) in the text */ unsigned int match_num; /* Number of matched patterns */ } AC_MATCH_t; /* AC_ERROR_t: * Error that may occur while adding a pattern to the automata. * it is returned by ac_automata_add(). **/ typedef enum { ACERR_SUCCESS = 0, /* No error occurred */ ACERR_DUPLICATE_PATTERN, /* Duplicate patterns */ ACERR_LONG_PATTERN, /* Pattern length is longer than AC_PATTRN_MAX_LENGTH */ ACERR_ZERO_PATTERN, /* Empty pattern (zero length) */ ACERR_AUTOMATA_CLOSED, /* Automata is closed. after calling ac_automata_finalize() you can not add new patterns to the automata. */ } AC_ERROR_t; /* MATCH_CALBACK_t: * This is the call-back function type that must be given to automata at * initialization to report match occurrence to the caller. * at a match event, the automata will reach you using this function and sends * you a pointer to AC_MATCH_t. using that pointer you can handle * matches. you can send parameters to the call-back function when you call * ac_automata_search(). at call-back, the automata will sent you those * parameters as the second parameter (void *) of MATCH_CALBACK_t. inside * the call-back function you can cast it to whatever you want. * If you return 0 from MATCH_CALBACK_t function to the automata, it will * continue searching, otherwise it will return from ac_automata_search() * to your calling function. **/ typedef int (*MATCH_CALBACK_f)(AC_MATCH_t *, void *); /* AC_PATTRN_MAX_LENGTH: * Maximum acceptable pattern length in AC_PATTERN_t.length **/ #define AC_PATTRN_MAX_LENGTH 1024 #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/include/ahocorasick.h000066400000000000000000000052021262705051000273060ustar00rootroot00000000000000/* * ahocorasick.h: the main ahocorasick header file. * This file is part of multifast. * Copyright 2010-2012 Kamiar Kanani multifast is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. multifast is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with multifast. If not, see . */ #ifndef _AUTOMATA_H_ #define _AUTOMATA_H_ #include "node.h" typedef struct { /* The root of the Aho-Corasick trie */ AC_NODE_t * root; /* maintain all nodes pointers. it will be used to access or release * all nodes. */ AC_NODE_t ** all_nodes; unsigned int all_nodes_num; /* Number of all nodes in the automata */ unsigned int all_nodes_max; /* Current max allocated memory for *all_nodes */ AC_MATCH_t match; /* Any match is reported with this */ MATCH_CALBACK_f match_callback; /* Match call-back function */ /* this flag indicates that if automata is finalized by * ac_automata_finalize() or not. 1 means finalized and 0 * means not finalized (is open). after finalizing automata you can not * add pattern to automata anymore. */ unsigned short automata_open; /* It is possible to feed a large input to the automata chunk by chunk to * be searched using ac_automata_search(). in fact by default automata * thinks that all chunks are related unless you do ac_automata_reset(). * followings are variables that keep track of searching state. */ AC_NODE_t * current_node; /* Pointer to current node while searching */ unsigned long base_position; /* Represents the position of current chunk related to whole input text */ /* Statistic Variables */ unsigned long total_patterns; /* Total patterns in the automata */ } AC_AUTOMATA_t; AC_AUTOMATA_t * ac_automata_init (MATCH_CALBACK_f mc); AC_ERROR_t ac_automata_add (AC_AUTOMATA_t * thiz, AC_PATTERN_t * str); void ac_automata_finalize (AC_AUTOMATA_t * thiz); int ac_automata_search (AC_AUTOMATA_t * thiz, AC_TEXT_t * str, void * param); void ac_automata_reset (AC_AUTOMATA_t * thiz); void ac_automata_release (AC_AUTOMATA_t * thiz); void ac_automata_display (AC_AUTOMATA_t * thiz, char repcast); #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/include/ndpi_patricia.h000066400000000000000000000243641262705051000276400ustar00rootroot00000000000000/* * $Id: ndpi_patricia.h,v 1.6 2005/12/07 20:53:01 dplonka Exp $ * Dave Plonka * * This product includes software developed by the University of Michigan, * Merit Network, Inc., and their contributors. * * This file had been called "radix.h" in the MRT sources. * * I renamed it to "ndpi_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 _NDPI_PATRICIA_H #define _NDPI_PATRICIA_H #ifndef WIN32 #define PATRICIA_IPV6 HAVE_IPV6 #else #undef PATRICIA_IPV6 #endif /* typedef unsigned int u_int; */ /* { from defs.h */ #define prefix_touchar(prefix) ((u_char *)&(prefix)->add.sin) #define MAXLINE 1024 #define BIT_TEST(f, b) ((f) & (b)) /* } */ #define addroute make_and_lookup #include /* for u_* definitions (on FreeBSD 5) */ #include /* for EAFNOSUPPORT */ #ifndef EAFNOSUPPORT # defined EAFNOSUPPORT WSAEAFNOSUPPORT #else #ifndef WIN32 # include /* for struct in_addr */ #endif #endif #ifndef WIN32 #include /* for AF_INET */ #else #include #include /* IPv6 */ #endif /* { 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 PATRICIA_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); #ifdef WIN32 #define PATRICIA_MAXBITS 128 #else #define PATRICIA_MAXBITS (sizeof(struct in6_addr) * 8) #endif #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 /* _NDPI_PATRICIA_H */ /************************* [newtool.gif] MRT Credits The Multi-Threaded Routing Toolkit _________________________________________________________________ MRT was developed by [1]Merit Network, Inc., under National Science Foundation grant NCR-9318902, "Experimentation with Routing Technology to be Used for Inter-Domain Routing in the Internet." Current MRT Staff * [2]Craig Labovitz * [3]Makaki Hirabaru * [4]Farnam Jahanian * Susan Hares * Susan R. Harris * Nathan Binkert * Gerald Winters Project Alumni * [5]Marc Unangst * John Scudder The BGP4+ extension was originally written by Francis Dupont . The public domain Struct C-library of linked list, hash table and memory allocation routines was developed by Jonathan Dekock . Susan Rebecca Harris provided help with the documentation. David Ward provided bug fixes and helpful suggestions. Some sections of code and architecture ideas were taken from the GateD routing daemon. The first port to Linux with IPv6 was done by Pedro Roque . Some interface routines to the Linux kernel were originally written by him. Alexey Kuznetsov made enhancements to 1.4.3a and fixed the Linux kernel intarface. Linux's netlink interface was written, referring to his code "iproute2". We would also like to thank our other colleagues in Japan, Portugal, the Netherlands, the UK, and the US for their many contributions to the MRT development effort. _________________________________________________________________ Cisco is a registered trademark of Cisco Systems Inc. _________________________________________________________________ Merit Network 4251 Plymouth Road Suite C Ann Arbor, MI 48105-2785 734-764-9430 info@merit.edu _________________________________________________________________ 1999 Merit Network, Inc. [6]www@merit.edu References 1. http://www.merit.edu/ 2. http://www.merit.edu/~labovit 3. http://www.merit.edu/~masaki 4. http://www.eecs.umich.edu/~farnam 5. http://www.contrib.andrew.cmu.edu/~mju/ 6. mailto:www@merit.edu ------------ Copyright (c) 1997, 1998, 1999 The Regents of the University of Michigan ("The Regents") and Merit Network, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the University of Michigan, Merit Network, Inc., and their contributors. 4. Neither the name of the University, Merit Network, nor the names of their contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ************************ */ nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/include/node.h000066400000000000000000000046121262705051000257510ustar00rootroot00000000000000/* * node.h: automata node header file * This file is part of multifast. * Copyright 2010-2012 Kamiar Kanani multifast is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. multifast is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with multifast. If not, see . */ #ifndef _NODE_H_ #define _NODE_H_ #include "actypes.h" /* Forward Declaration */ struct edge; /* automata node */ typedef struct ac_node { int id; /* Node ID : for debugging purpose */ short int final; /* 0: no ; 1: yes, it is a final node */ struct ac_node * failure_node; /* The failure node of this node */ unsigned short depth; /* depth: distance between this node and the root */ /* Matched patterns */ AC_PATTERN_t * matched_patterns; /* Array of matched patterns */ unsigned short matched_patterns_num; /* Number of matched patterns at this node */ unsigned short matched_patterns_max; /* Max capacity of allocated memory for matched_patterns */ /* Outgoing Edges */ struct edge * outgoing; /* Array of outgoing edges */ unsigned short outgoing_degree; /* Number of outgoing edges */ unsigned short outgoing_max; /* Max capacity of allocated memory for outgoing */ } AC_NODE_t; /* The Edge of the Node */ struct edge { AC_ALPHABET_t alpha; /* Edge alpha */ struct ac_node * next; /* Target of the edge */ }; AC_NODE_t * node_create (void); AC_NODE_t * node_create_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha); void node_register_matchstr (AC_NODE_t * thiz, AC_PATTERN_t * str); void node_register_outgoing (AC_NODE_t * thiz, AC_NODE_t * next, AC_ALPHABET_t alpha); AC_NODE_t * node_find_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha); AC_NODE_t * node_findbs_next (AC_NODE_t * thiz, AC_ALPHABET_t alpha); void node_release (AC_NODE_t * thiz); void node_assign_id (AC_NODE_t * thiz); void node_sort_edges (AC_NODE_t * thiz); #endif nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/include/sort.h000066400000000000000000000003241262705051000260070ustar00rootroot00000000000000/* 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)); nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/src/000077500000000000000000000000001262705051000240145ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/src/ahocorasick.c000066400000000000000000000303371262705051000264540ustar00rootroot00000000000000/* * ahocorasick.c: implementation of ahocorasick library's functions * This file is part of multifast. * Copyright 2010-2012 Kamiar Kanani multifast is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. multifast is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with multifast. If not, see . */ #include #include #include #include #include "ndpi_api.h" #include "ahocorasick.h" /* Allocation step for automata.all_nodes */ #define REALLOC_CHUNK_ALLNODES 200 /* Private function prototype */ static void ac_automata_register_nodeptr (AC_AUTOMATA_t * thiz, AC_NODE_t * node); static void ac_automata_union_matchstrs (AC_NODE_t * node); static void ac_automata_set_failure (AC_AUTOMATA_t * thiz, AC_NODE_t * node, AC_ALPHABET_t * alphas); static void ac_automata_traverse_setfailure (AC_AUTOMATA_t * thiz, AC_NODE_t * node, AC_ALPHABET_t * alphas); /****************************************************************************** * FUNCTION: ac_automata_init * Initialize automata; allocate memories and set initial values * PARAMS: * MATCH_CALBACK mc: call-back function * the call-back function will be used to reach the caller on match occurrence ******************************************************************************/ AC_AUTOMATA_t * ac_automata_init (MATCH_CALBACK_f mc) { AC_AUTOMATA_t * thiz = (AC_AUTOMATA_t *)ndpi_malloc(sizeof(AC_AUTOMATA_t)); memset (thiz, 0, sizeof(AC_AUTOMATA_t)); thiz->root = node_create (); thiz->all_nodes_max = REALLOC_CHUNK_ALLNODES; thiz->all_nodes = (AC_NODE_t **) ndpi_malloc (thiz->all_nodes_max*sizeof(AC_NODE_t *)); thiz->match_callback = mc; ac_automata_register_nodeptr (thiz, thiz->root); ac_automata_reset (thiz); thiz->total_patterns = 0; thiz->automata_open = 1; return thiz; } /****************************************************************************** * FUNCTION: ac_automata_add * Adds pattern to the automata. * PARAMS: * AC_AUTOMATA_t * thiz: the pointer to the automata * AC_PATTERN_t * patt: the pointer to added pattern * RETUERN VALUE: AC_ERROR_t * the return value indicates the success or failure of adding action ******************************************************************************/ AC_ERROR_t ac_automata_add (AC_AUTOMATA_t * thiz, AC_PATTERN_t * patt) { unsigned int i; AC_NODE_t * n = thiz->root; AC_NODE_t * next; AC_ALPHABET_t alpha; if(!thiz->automata_open) return ACERR_AUTOMATA_CLOSED; if (!patt->length) return ACERR_ZERO_PATTERN; if (patt->length > AC_PATTRN_MAX_LENGTH) return ACERR_LONG_PATTERN; for (i=0; ilength; i++) { alpha = patt->astring[i]; if ((next = node_find_next(n, alpha))) { n = next; continue; } else { next = node_create_next(n, alpha); next->depth = n->depth + 1; n = next; ac_automata_register_nodeptr(thiz, n); } } if(n->final) return ACERR_DUPLICATE_PATTERN; n->final = 1; node_register_matchstr(n, patt); thiz->total_patterns++; return ACERR_SUCCESS; } /****************************************************************************** * FUNCTION: ac_automata_finalize * Locate the failure node for all nodes and collect all matched pattern for * every node. it also sorts outgoing edges of node, so binary search could be * performed on them. after calling this function the automate literally will * be finalized and you can not add new patterns to the automate. * PARAMS: * AC_AUTOMATA_t * thiz: the pointer to the automata ******************************************************************************/ void ac_automata_finalize (AC_AUTOMATA_t * thiz) { unsigned int i; AC_ALPHABET_t *alphas; AC_NODE_t * node; if((alphas = ndpi_malloc(AC_PATTRN_MAX_LENGTH)) != NULL) { ac_automata_traverse_setfailure (thiz, thiz->root, alphas); for (i=0; i < thiz->all_nodes_num; i++) { node = thiz->all_nodes[i]; ac_automata_union_matchstrs (node); node_sort_edges (node); } thiz->automata_open = 0; /* do not accept patterns any more */ ndpi_free(alphas); } } /****************************************************************************** * FUNCTION: ac_automata_search * Search in the input text using the given automata. on match event it will * call the call-back function. and the call-back function in turn after doing * its job, will return an integer value to ac_automata_search(). 0 value means * continue search, and non-0 value means stop search and return to the caller. * PARAMS: * AC_AUTOMATA_t * thiz: the pointer to the automata * AC_TEXT_t * txt: the input text that must be searched * void * param: this parameter will be send to call-back function. it is * useful for sending parameter to call-back function from caller function. * RETURN VALUE: * -1: failed call; automata is not finalized * 0: success; continue searching; call-back sent me a 0 value * 1: success; stop searching; call-back sent me a non-0 value ******************************************************************************/ int ac_automata_search (AC_AUTOMATA_t * thiz, AC_TEXT_t * txt, void * param) { unsigned long position; AC_NODE_t *curr; AC_NODE_t *next; if(thiz->automata_open) /* you must call ac_automata_locate_failure() first */ return -1; position = 0; curr = thiz->current_node; /* This is the main search loop. * it must be keep as lightweight as possible. */ while (position < txt->length) { if(!(next = node_findbs_next(curr, txt->astring[position]))) { if(curr->failure_node /* we are not in the root node */) curr = curr->failure_node; else position++; } else { curr = next; position++; } if(curr->final && next) /* We check 'next' to find out if we came here after a alphabet * transition or due to a fail. in second case we should not report * matching because it was reported in previous node */ { thiz->match.position = position + thiz->base_position; thiz->match.match_num = curr->matched_patterns_num; thiz->match.patterns = curr->matched_patterns; /* we found a match! do call-back */ if (thiz->match_callback(&thiz->match, param)) return 1; } } /* save status variables */ thiz->current_node = curr; thiz->base_position += position; return 0; } /****************************************************************************** * FUNCTION: ac_automata_reset * reset the automata and make it ready for doing new search on a new text. * when you finished with the input text, you must reset automata state for * new input, otherwise it will not work. * PARAMS: * AC_AUTOMATA_t * thiz: the pointer to the automata ******************************************************************************/ void ac_automata_reset (AC_AUTOMATA_t * thiz) { thiz->current_node = thiz->root; thiz->base_position = 0; } /****************************************************************************** * FUNCTION: ac_automata_release * Release all allocated memories to the automata * PARAMS: * AC_AUTOMATA_t * thiz: the pointer to the automata ******************************************************************************/ void ac_automata_release (AC_AUTOMATA_t * thiz) { unsigned int i; AC_NODE_t * n; for (i=0; i < thiz->all_nodes_num; i++) { n = thiz->all_nodes[i]; node_release(n); } ndpi_free(thiz->all_nodes); ndpi_free(thiz); } /****************************************************************************** * FUNCTION: ac_automata_display * Prints the automata to output in human readable form. it is useful for * debugging purpose. * PARAMS: * AC_AUTOMATA_t * thiz: the pointer to the automata * char repcast: 'n': print AC_REP_t as number, 's': print AC_REP_t as string ******************************************************************************/ void ac_automata_display (AC_AUTOMATA_t * thiz, char repcast) { unsigned int i, j; AC_NODE_t * n; struct edge * e; AC_PATTERN_t sid; printf("---------------------------------\n"); for (i=0; iall_nodes_num; i++) { n = thiz->all_nodes[i]; printf("NODE(%3d)/----fail----> NODE(%3d)\n", n->id, (n->failure_node)?n->failure_node->id:1); for (j=0; joutgoing_degree; j++) { e = &n->outgoing[j]; printf(" |----("); if(isgraph(e->alpha)) printf("%c)---", e->alpha); else printf("0x%x)", e->alpha); printf("--> NODE(%3d)\n", e->next->id); } if (n->matched_patterns_num) { printf("Accepted patterns: {"); for (j=0; jmatched_patterns_num; j++) { sid = n->matched_patterns[j]; if(j) printf(", "); switch (repcast) { case 'n': printf("%ld", sid.rep.number); break; case 's': printf("%s", sid.rep.stringy); break; } } printf("}\n"); } printf("---------------------------------\n"); } } /****************************************************************************** * 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); } } nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/src/ndpi_patricia.c000066400000000000000000000617641262705051000270040ustar00rootroot00000000000000/* * $Id: patricia.c,v 1.7 2005/12/07 20:46:41 dplonka Exp $ * Dave Plonka * * This product includes software developed by the University of Michigan, * Merit Network, Inc., and their contributors. * * This file had been called "radix.c" in the MRT sources. * * I renamed it to "patricia.c" since it's not an implementation of a general * radix trie. Also I pulled in various requirements from "prefix.c" and * "demo.c" so that it could be used as a standalone API. https://github.com/deepfield/MRT/blob/master/COPYRIGHT Copyright (c) 1999-2013 The Regents of the University of Michigan ("The Regents") and Merit Network, Inc. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include /* assert */ #include /* isdigit */ #include /* errno */ #include /* sin */ #include /* NULL */ #include /* sprintf, fprintf, stderr */ #include /* free, atol, calloc */ #include /* memcpy, strchr, strlen */ #include /* BSD: for inet_addr */ #ifndef WIN32 #include /* BSD, Linux: for inet_addr */ #include /* BSD, Linux: for inet_addr */ #include /* BSD, Linux, Solaris: for inet_addr */ #endif #include "ndpi_patricia.h" 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); } /* 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(PATRICIA_IPV6) } else if(af == AF_INET6) { return (inet_pton (af, src, dst)); #endif /* PATRICIA_IPV6 */ } else { #ifndef NT errno = EAFNOSUPPORT; #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_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(PATRICIA_IPV6) 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 /* PATRICIA_IPV6 */ else return (NULL); } /* ndpi_prefix_toa2 * convert prefix information to ascii string */ char * ndpi_prefix_toa2 (prefix_t *prefix, char *buff) { return (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(PATRICIA_IPV6) 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 /* PATRICIA_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(PATRICIA_IPV6) struct in6_addr sin6; #endif /* PATRICIA_IPV6 */ char save[MAXLINE]; if(string == NULL) return (NULL); /* easy way to handle both families */ if(family == 0) { family = AF_INET; #if defined(PATRICIA_IPV6) if(strchr (string, ':')) family = AF_INET6; #endif /* PATRICIA_IPV6 */ } if(family == AF_INET) { maxbitlen = sizeof(struct in_addr) * 8; } #if defined(PATRICIA_IPV6) else if(family == AF_INET6) { maxbitlen = sizeof(struct in6_addr) * 8; } #endif /* PATRICIA_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(PATRICIA_IPV6) 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 /* PATRICIA_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 nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/src/node.c000066400000000000000000000207651262705051000251170ustar00rootroot00000000000000/* * node.c: implementation of automata node * This file is part of multifast. * Copyright 2010-2012 Kamiar Kanani multifast is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. multifast is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with multifast. If not, see . */ #include #include #include #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); } nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/src/lib/third_party/src/sort.c000066400000000000000000000043421262705051000251520ustar00rootroot00000000000000/* * A fast, small, non-recursive O(nlog n) sort for the Linux kernel * * Jan 23 2005 Matt Mackall */ #ifdef WIN32 #include typedef uint32_t u_int32_t; #endif #include #include #include /* 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); } } } nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/tests/000077500000000000000000000000001262705051000205015ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/tests/do.sh000077500000000000000000000012761262705051000214500ustar00rootroot00000000000000 READER=../example/ndpiReader RC=0 PCAPS=`cd pcap; /bin/ls *.pcap` build_results() { for f in $PCAPS; do #echo $f # create result files if not present [ ! -f result/$f.out ] && $READER -q -i pcap/$f -w result/$f.out -v 1 done } check_results() { for f in $PCAPS; do if [ -f result/$f.out ]; then CMD="$READER -q -i pcap/$f -w /tmp/reader.out -v 1" $CMD NUM_DIFF=`diff result/$f.out /tmp/reader.out | wc -l` if [ $NUM_DIFF -eq 0 ]; then printf "%-32s\tOK\n" "$f" else printf "%-32s\tERROR\n" "$f" echo "$CMD" diff result/$f.out /tmp/reader.out RC=1 fi /bin/rm /tmp/reader.out fi done } build_results check_results exit $RC nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/tests/pcap/000077500000000000000000000000001262705051000214245ustar00rootroot00000000000000nDPI-6f3d5a7b33fdb1bd016c7ac32e09711c5c076b51/tests/pcap/6in4tunnel.pcap000066400000000000000000001225551262705051000243110ustar00rootroot00000000000000ò]NV";$΁4E|@)7Ii`@:? p?>sM& $]Z]NV !"#$%&'()*+,-./01234567]NV\y$΁4";E|V@) biI`@:7& $ p?>sM߽]Z]NV !"#$%&'()*+,-./01234567^NVB";$΁4E@)Ii`~:@ p?& $Ҁ`N6& $ p?%2,KR}}pI 1=u)e+U^:ZS;eڴCear^NV";$΁4E|@)ˮIi`@:? p?>sM& $][^NVi !"#$%&'()*+,-./01234567^NV%{$΁4";E|W@) aiI`@:7& $ p?>sM][^NVi !"#$%&'()*+,-./01234567_NV";$΁4E|4@)Ii`@:? p?>sM& $U]\_NV1 !"#$%&'()*+,-./01234567_NV$΁4";E|X@) `iI`@:7& $ p?>sMT]\_NV1 !"#$%&'()*+,-./01234567`NVI";$΁4E|@)Ii`@:? p?>sM& $]]`NV !"#$%&'()*+,-./01234567`NV$΁4";E|Y@) _iI`@:7& $ p?>sM]]`NV !"#$%&'()*+,-./01234567aNVe";$΁4E|C@)uIi`@:? p?>sM& $]^aNV !"#$%&'()*+,-./01234567aNV$΁4";E|Z@) ^iI`@:7& $ p?>sM]^aNV !"#$%&'()*+,-./01234567bNV";$΁4E|@)Ii`@:? p?>sM& $m]_bNV !"#$%&'()*+,-./01234567bNVҚ$΁4";E|[@) ]iI`@:7& $ p?>sMl]_bNV !"#$%&'()*+,-./01234567cNV";$΁4E|@)Ii`@:? p?>sM& $]`cNV !"#$%&'()*+,-./01234567cNV$΁4";E|\@) \iI`@:7& $ p?>sM]`cNV !"#$%&'()*+,-./01234567dNVG";$΁4E|Y@)_Ii`@:? p?>sM& $]adNV !"#$%&'()*+,-./01234567dNVѦ$΁4";E|]@) [iI`@:7& $ p?>sM]adNV !"#$%&'()*+,-./01234567dNV ";$΁4Ew@)(Ii`;@ p?*( ΰ 5;estarc10rfacebookcom)dNV ";$΁4Ew@)'Ii`;@ p?*( ΰ 5;xstarc10rfacebookcom)dNV $΁4";E^@) ӸiI`8*( ΰ p?5^starc10rfacebookcom <*(oΰ ansbRP*( ΰ PE c*( ΰ cE dNV $΁4";E_@) ޸iI`8*( ΰ p?5starc10rfacebookcom <xansbFD*( ΰ DE W*( ΰ WE dNVrr";$΁4Ed@)8Ii`(? p?>sM*(oΰ 'uXp' 'yeNVJrr$΁4";Ed`@) piIh(3*(oΰ  p?>sM˳ 'uX6 )8'yeNVLjj";$΁4E\@)?Ii` ? p?>sM*(oΰ 'uX˳ ƀ 'y )8eNVO66";$΁4E(@)rIi`? p?>sM*(oΰ 'uX˳ ƀẍ 'y )8i@l?|,WҸٕcNE5fՉp]"{+/ 39/5 www.facebook.com  #3tspdy/3.1h2-14h2http/1.1uP eNVEjj$΁4";E\a@) wiIh 3*(oΰ  p?>sM˳ 'uYy;s )8~'y eNVB$΁4";Ed@)iIh3*(oΰ  p?>sM˳ 'uYy; )8~'y tpT d:tX qCJwLޠ4+H #3t/h2-14spdy/3.1-fb-0.5spdy/3.1spdy/3http/1.1 d ` ]00ߠaqX>` F 0  *H 0f1 0 UUS10U  DigiCert Inc10U www.digicert.com1%0#UDigiCert High Assurance CA-30 140828000000Z 151231120000Z0a1 0 UUS1 0 UCA10U Menlo Park10U Facebook, Inc.10U *.facebook.com0Y0*H=*H=B5YTۿNXG"ҞI*%FBP_%1\Nd Fҡpo0k0U#0Ps) yH0UC @K03nqϊ0U0*.facebook.com facebook.com*.xz.fbcdn.net messenger.comfb.com*.m.facebook.com *.fbsbx.com*.xy.fbcdn.net*.messenger.com*.fb.com *.fbcdn.net*.xx.fbcdn.net*.facebook.net0U0U%0++0aUZ0X0*(&$http://crl3.digicert.com/ca3-g29.crl0*(&$http://crl4.digicert.com/ca3-g29.crl0BU ;0907 `Hl0*0(+https://www.digicert.com/CPS0{+o0m0$+0http://ocsp.digicert.com0E+09http://cacerts.digicert.com/DigiCertHighAssuranceCA-3.crt0 U00  *H 2*G9zb~A ;3gѩ]0?Doushe3*E ZZkջ'x^sQ^[X 'E;kiI[(ͬcaeNVww$΁4";Eie@)fiIh-3*(oΰ  p?>sM˳<'uYy;be )8~'y &FlUna\0X0@ _M[?;0  *H 0l1 0 UUS10U  DigiCert Inc10U www.digicert.com1+0)U"DigiCert High Assurance EV Root CA0 080402120000Z 220403000000Z0f1 0 UUS10U  DigiCert Inc10U www.digicert.com1%0#UDigiCert High Assurance CA-30"0  *H 0 a )^47Q"a pLPc&uA`B)6(e1tm6/(Ff*y&zՎmO^=Y{^6lS2>dXi BQD$zz1i]l~ RDJ:#䛶[Kε*7¸\#5^|>~òe{],<:http://crl3.digicert.com/DigiCertHighAssuranceEVRootCA.crl0@><:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl0U#0>iGԘ&cd+0UPs) yH0  *H HlS8*C횼>u."Ya͇ uT(F`ܾQ,|1p7[ Xj$HGF1_N4ǐ1МߊV:t]qBt_ލC|Uizaa3M9%5+$&(yw/W|Z0W~G1¿0|]$_jtkF!)Ԏ^BJ2okQX?m!jN ]Zva AIuJ_5}Qnk(D#O[q=ݟ ×w [۹WzD6<8nzF0D Xs5hB.ϏB[QEߢ1 >ҷ&^JHՌlm1{H^ĵeNVjj";$΁4E\@)<Ii` ? p?>sM*(oΰ 'uYy˳<|' 'y#)8~eNV=jj";$΁4E\@);Ii` ? p?>sM*(oΰ 'uYy˳It 'y#)8~eNV  ";$΁4E@)Ii`? p?>sM*(oΰ 'uYy˳I 'y%)8~FBAkyD6^z(OsM*(oΰ 'uZ˳I 'y%)8~0uce:%5La:E,jx؏d&eNV-";$΁4E@)Ii`R? p?>sM*(oΰ 'uZP˳Iܟ 'y%)8~-vM&}f %VԶ1ة?,XeNV{";$΁4E@) Ii`J? p?>sM*(oΰ 'uZ˳Iy 'y%)8~%7f95X%²`4h0r/eNVF..";$΁4E @)qIi`? p?>sM*(oΰ 'uZ˳I$ 'y%)8~Pa-o@HW{FFm;'UIʜύ KE_p)Zm.^+Ww?jx$Ý@S"Ҍ{/1幆Y< Ti5R(c)9;)V|k G.+l)`߰X]K 2Tl6VH_*U,mu zc\[}Mn6wC*#X1NhzoH |{bDDF|Xohp8YV1ge.oT +l_E3-c幌~Bͮ\䫥t_<lkia~u |kLw9dM!T|TkkimK܅ ef6t G^uvHXX??e)tWћ"ZW!p Ly9_sM*(oΰ 'u]p˳ILq 'y%)8~ :j (mvMЕ3if)Y%Zm6jE&1sBOQYztu㗩 B 9PtfkۢuX t 1|3R蹚OI S$VtMeF4p=H~ۮKkMn]'3Hmɤ&ۂǺA9_܎P ͒c1ZnM1(.n! z+1f& `v7BژA\R6)Z?B,^FlMweNVM";$΁4E@)Ii`? p?>sM*(oΰ 'ub˳I 'y%)8~m7jD濻?"¦'-0cS՘v\:j̙maOjx5VXd;T(.JY=ׁ@hhDwכ}H7Û|bJSl7~Eo 5,uD[XʉjS=SS[ x;x΅{= *>Z+=fB%NjռD 9HˌOX X{iW[ V]/CШzmx_@zR@djA SPev򵾙aqk 0* ^\Wh] r۽U<_IT¿5&1$L1*/ Lj1Ƹ<&MF+r Wp8bĞ^ƺ5Z@8eےFY^]Է5y@8݊x;VըI~O9[Xt:0{FYN9ݘAxO. k`k,pwɀlӸzU凉dr3V9Kզ3̭Sv"u-l^%"FK^PwY6$Yͣ{I4bΩRT/i[i{t[1cS,a.K QK*nXR0a|!-gh [torrdomn¡SBi}8PT(ei]vqq17o>ϾPkAL 4o%55Y,Ҝ{svxv_UUGKfM_#G6!u.dP$&+l'lwZ/LiO"ۺȇ#ctG 75E=;aYigȦ`B0LN\ӛH577"'ϐ$ ;eNVvvjj$΁4";E\e@) siIh 3*(oΰ  p?>sM˳I'u]pEqf )8'y%eNVGzll$΁4";E^f@) piIh"3*(oΰ  p?>sM˳I'u]pEb )8'y%O 0_R0g̛YcMu8u˔b_<wf _= Ӑ;U~/gcA~nS 4 LOtun R(w5Tp5Q]98zoR,{^,}"V3~ Q b2$7f%/J@@{(6Bk~2WalxieNVmz$΁4";Eg@) 'iIhj3*(oΰ  p?>sM˳K'u]pE )8'y%E6棎^K<1|1v14͍!M'D^lsD_]N$?0(HQeNVz$΁4";Eh@) FiIhJ3*(oΰ  p?>sM˳'u]pE )8'y%%6'])W;Xx0`,/mcBqeNV{jj";$΁4E\@)#Ii` ? p?>sM*(oΰ 'uf˳*f  'y>)8eNV}";$΁4E@)Ii`F? p?>sM*(oΰ 'uf˳*sY 'y>)8!|@# Gv]g:|% veNV7vv$΁4";Ehi@) ciIh,3*(oΰ  p?>sM˳'u]pE!n )9'y% 'ub'ufeNVz""$΁4";Ej@)iI`:2*(oΰ  p?>sM/d/ p?>sM*(oΰ 'u]p˳ILq 'y%)8~ :j (mvMЕ3if)Y%Zm6jE&1sBOQYztu㗩 B 9PtfkۢuX t 1|3R蹚OI S$VtMeF4p=H~ۮKksM*(oΰ 'u]p˳*b 'yD)9 :j (mvMЕ3if)Y%Zm6jE&1sBOQYztu㗩 B 9PtfkۢuX t 1|3R蹚OI S$VtMeF4p=H~ۮKkMn]'3Hmɤ&ۂǺA9_܎P ͒c1ZnM1(.n! z+1f& `v7BژA\R6)Z?B,^FeNVwtt";$΁4Ef@)Ii`*? p?>sM*(oΰ 'ub˳*H 'yD)9lMweNV0vv$΁4";Ehk@) aiIh,3*(oΰ  p?>sM˳'u]pE  )9V'y% 'ub'ufeNV^vv$΁4";Ehl@) `iIh,3*(oΰ  p?>sM˳'ubܰPL )9i'yD 'ub'ufeNVbjj$΁4";E\m@) kiIh 3*(oΰ  p?>sM˳'ufPf )9i'yDeNVcF$΁4";En@) "iIhh3*(oΰ  p?>sM˳'ufP8 )9'yDC6xɖz(Bs eU ZvH8ʖUV0gbGf%Ȼ|SDm\/<^z\WW'u{ܑB='AR2- g\I9ނ~nkXP>V6#R&!&q> (Ñ]8no,]2 uBzDwgo:y?5„Ib Ql{^r,cm&-2KGwEOݬeQ(*r} SYڂ9o?qD~-w}f>^G.k1ĎݼD^Jpvt1P>W !FgoL4H̤5'CD[`NLbO%>T "̣.pFNUa5=V#5ޚQ-OЙ|YUMڟm\Z8\~ L:Ǯc  ?-GK8e?;˲z <sVA8_ʹsA`ZDƶJס[zcTo=IX0}bΖwxb=KS讍U|9ޮ-ԡ>7-n\'\ӗ֝m4e2UY_k]b7j)L~l&Gtk?؟X hnpʧA>_@!"$,K X-BAӿ[!Mk6y$ ;pҭ h >7@H05v؍}aQDyԍ)$GF|xbnKO3%o̕R&by`?0s(Fh+?o(U՗nnYz- T1ڂ":eV/Xn;Q[E'PglTPg*YƨsdJY\.=ZyXD&١t4! D7cc߂b$.{}ڲ)`79fV8ϝeNV!J$΁4";Eo@) ĸiIh3*(oΰ  p?>sM˳'ufP )9'yD6.&2 )b/y>^Хz_)k|vvY(tGDTO]%5wHAYd|B,9Ou!snuU4MO¹&z< 0}]0!Dvָc,ȎOĪ֞s~`v$R6)73:MG`)>K~P5 ZDhv<Lt9вtLh dLk@#BBj:aeNV@J$΁4";Ep@) 8iIhP3*(oΰ  p?>sM˳!'ufP- )9'yD+6Qt?=[#V^&mdCeNVpKjj";$΁4E\@)Ii` ? p?>sM*(oΰ 'uf˳!V] 'yl)9eNVjj";$΁4E\@)Ii` ? p?>sM*(oΰ 'uf˳!܀V] 'yv)9eNV ";$΁4E|@)خIi`@:? p?>sM& $҇]beNV  !"#$%&'()*+,-./01234567eNVw$΁4";E|q@) GiI`@:7& $ p?>sMч]beNV  !"#$%&'()*+,-./01234567fNVj";$΁4E|Y@)_Ii`@:? p?>sM& $w]cfNV !"#$%&'()*+,-./01234567fNVA$΁4";E|r@) FiI`@:7& $ p?>sMv]cfNV !"#$%&'()*+,-./01234567gNV";$΁4E| @)Ii`@:? p?>sM& $0y]dgNVN !"#$%&'()*+,-./01234567gNV$΁4";E|s@) EiI`@:7& $ p?>sM/y]dgNVN !"#$%&'()*+,-./01234567hNV8$΁4";Et@) 6iI`N7& $ p?mi rsao=mE5 1IvW)@n~-9 fD{}-揜hNV$΁4";Eu@) 5iI`N7& $ p?mi rsaoiA 1IvU)z=xm>{$={n) rΆ3L/$\hNVljj";$΁4E\L@)Ii` ? p?mi rsao& $= vo1IhNVjj";$΁4E\M@)Ii` ? p?mi rsao& $iπ, vo1IhNV ";$΁4E|X@)`Ii`@:? p?>sM& $Ar]ehNV< !"#$%&'()*+,-./01234567hNVi$΁4";E|v@) BiI`@:7& $ p?>sM@r]ehNV< !"#$%&'()*+,-./01234567iNV$";$΁4E|@)Ii`@:? p?>sM& $!m]fiNV[" !"#$%&'()*+,-./01234567iNV$΁4";E|w@) AiI`@:7& $ p?>sM m]fiNV[" !"#$%&'()*+,-./01234567jNVB)";$΁4E|)@)Ii`@:? p?>sM& $g]gjNV& !"#$%&'()*+,-./01234567jNVt$΁4";E|x@) @iI`@:7& $ p?>sMg]gjNV& !"#$%&'()*+,-./01234567kNV*";$΁4E|_@)YIi`@:? p?>sM& $e]hkNVt( !"#$%&'()*+,-./01234567kNVT$΁4";E|y@) ?iI`@:7& $ p?>sMe]hkNVt( !"#$%&'()*+,-./01234567lNV0";$΁4E|@)Ii`@:? p?>sM& $:^]ilNV?. !"#$%&'()*+,-./01234567lNV$΁4";E|z@) >iI`@:7& $ p?>sM9^]ilNV?. !"#$%&'()*+,-./01234567mNV4";$΁4E|1@)Ii`@:? p?>sM& $X]jmNV2 !"#$%&'()*+,-./01234567mNV$΁4";E|{@) =iI`@:7& $ p?>sMX]jmNV2 !"#$%&'()*+,-./01234567nNV8";$΁4E|W@)aIi`@:? p?>sM& $S]knNV6 !"#$%&'()*+,-./01234567nNVK$΁4";E||@) sMS]knNV6 !"#$%&'()*+,-./01234567oNVI=";$΁4E|@)Ii`@:? p?>sM& $N]loNV: !"#$%&'()*+,-./01234567oNV$΁4";E|}@) ;iI`@:7& $ p?>sMN]loNV: !"#$%&'()*+,-./01234567pNVrr";$΁4Ed%@)Ii`(? p?>sM& $BP^nÏ 'ypNVrr$΁4";Ed~@) RiI`(7& $ p?>sMPB=)_7 1Q'ypNVjj";$΁4E\:@)Ii` ? p?>sM& $BP_=*Lj 'y 1QpNVN";$΁4E;@)Ii`? p?>sM& $BP_=* 'y 1QGET / HTTP/1.1 User-Agent: Wget/1.16.3 (linux-gnu) Accept: */* Accept-Encoding: identity Host: mail.tomasu.net Connection: Keep-Alive pNVb?";$΁4E|M@)kIi`@:? p?>sM& $rK]mpNV= !"#$%&'()*+,-./01234567pNVOjj$΁4";E\@) YiI` 7& $ p?>sMPB=*sMPB=*< 1Q'y HTTP/1.1 301 Moved Permanently Date: Wed, 07 Oct 2015 16:55:13 GMT Server: Apache/2.4.10 (Debian) Location: https://mail.tomasu.net/ Content-Length: 313 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html; charset=iso-8859-1 301 Moved Permanently