NintendoZaedus
NintendoZaedus

Reputation: 683

libtins Sniffer undefined

#include <iostream>
#include <tins/tins.h>

using namespace Tins;
using namespace std;

bool callback(const PDU& pdu) {
    // Find the IP layer
    const IP& ip = pdu.rfind_pdu<IP>();
    // Find the TCP layer
    const TCP& tcp = pdu.rfind_pdu<TCP>();
    cout << ip.src_addr() << ":" << tcp.sport() << " -> "
         << ip.dst_addr() << ":" << tcp.dport() << endl;
    return true;
}

int main() {
    Sniffer("eth0").sniff_loop(callback);
}

I have the default code libtins gives you, but for some reason Sniffer is undefined. I have included all libs in my linker.

Also it gives me the following error when I built:

-- Build started: Project: Packet Sniffing, Configuration: Debug x64 ------
1>Packet Sniffing.cpp
1>C:\Users\usr\Documents\Code\C++ Projects\static\libtins\include\tins\macros.h(37,10): fatal error C1083: Cannot open include file: 'tins/config.h': No such file or directory
1>Done building project "Packet Sniffing.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I have checked and there is no file called config.h however there is one called config.h.in. When I removed .in it gave me another error:

1>------ Build started: Project: Packet Sniffing, Configuration: Debug x64 ------
1>Packet Sniffing.cpp
1>C:\Users\usr\Documents\Code\C++ Projects\static\libtins\include\tins\config.h(5,1): fatal error C1021: invalid preprocessor command 'cmakedefine'
1>Done building project "Packet Sniffing.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

The only instruction I didn't understand on their website is when they say

You also need to add this macro definition to your project:

TINS_STATIC

I don't exactly know what this means so this might also be the issue.

Thanks in advance!

Upvotes: 2

Views: 1605

Answers (1)

Here are instructions for using libtins on Windows. You can either use a pre-compiled library or compile libtins yourself. If you are unsure, I would recommend using a pre-compiled version of libtins, because it is less work.

All of these instructions are based on link.

Using a pre-compiled libtins on Windows

  • Download the pre-compiled libtins. Select your required target platform here (debug/release, 32/64 bit). Towards the right, click on "Artifacts", then download the zip archive. Unpack the zip. Inside you will find a include and a lib folder.

  • Download the npcap SDK from here. Unpack the zip archive. Inside you will find a Include and a Lib folder. Note the lib folder has the 64 bit variant as a sub-folder (Lib/x64).

  • In Visual Studio, open your project settings. At the top, ensure that the configuration/platform match your required target platform (debug/release, 32/64 bit).

    • Under C/C++ > General > Additional include directories, add the include directories of libtins and npcap. E.g. it should look something like <some-path>\libtins-vs2015-x64-release\libtins\include;<some-path>\npcap-sdk-1.05\Include;%(AdditionalIncludeDirectories).

      Explanation: Without this, Visual Studio will not be able to find the headers of libtins and npcap. You would get errors such as:

      • E1696 cannot open source file "tins/tins.h"
      • E0020 identifier "PDU" is undefined
      • E1696 cannot open source file "pcap.h"
      • E0020 identifier "pcap_t" is undefined
    • Under C/C++ > Preprocessor > Preprocessor definitions, add TINS_STATIC.

      Explanation: This is equivalent to adding #define TINS_STATIC in your code before including any libtins headers. It will cause libtins to omit any dllexport/dllimport statements in its headers, which would be needed if you would use libtins as a shared/dynamic library, instead of as a static library (for more info see link, link and in the libtins source code, include/tins/macros.h for how TINS_STATIC is used). Without this you would get errors such as:

      • C4251 'Tins::DNS::records_data_': class 'std::vector<uint8_t,std::allocator<uint8_t>>' needs to have dll-interface to be used by clients of class 'Tins::DNS'
      • LNK2001 unresolved external symbol "__declspec(dllimport) public: __cdecl Tins::Sniffer::Sniffer(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)"
    • Under Linker > General > Additional library directories, add the lib directories of libtins and npcap. Choose the right lib directory for npcacp (32/64 bit) depending on your target platform. The result should look something like <some-path>\libtins-vs2015-x64-release\libtins\lib;<some-path>\npcap-sdk-1.05\Lib\x64;%(AdditionalLibraryDirectories).

      Explanation: Without this, Visual Studio will be unable to find the libtins and npcap libraries. You would get errors such as:

      • LNK1181 cannot open input file 'tins.lib'
      • LNK1181 cannot open input file 'Packet.lib'
    • Under Linker > Input > Additional dependencies, add tins.lib, the npcap libraries Packet.lib, wpcap.lib, and the Windows libraries Iphlpapi.lib, Ws2_32.lib. The result should look something like tins.lib;Packet.lib;wpcap.lib;Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies).

      Explanation: This will direct Visual Studio to link against the libtins and npcap binaries and also the necessary Windows networking libraries. Without this, you would get errors such as:

      • LNK2001 unresolved external symbol "public: __cdecl Tins::Sniffer::Sniffer(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)"
      • LNK2001 unresolved external symbol pcap_lookupnet
      • LNK2001 unresolved external symbol GetAdaptersAddresses
      • LNK2001 unresolved external symbol __imp_inet_pton
    • In your source code, ensure you add #include <algorithm> before including any libtins headers.

      Explanation: Without this I got C2039 'min': is not a member of 'std'.

  • Your code should now compile. However, note that eth0 is a Linux-specific interface name. In all likelihood, it will not give you any output on Windows. Refer to this link on how to identify the network interface name on Windows. So instead of eth0, your name should be something longer of the form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX}.

Compiling libtins from source on Windows

As a prerequisite, you should know how to use a command prompt.

  • Install cmake (link)
  • Download the libtins source code (link), unpack the archive.
  • Download the npcap SDK as before. I did not attempt to also compile npcap from source.
  • In the libtins source code folder, open a command prompt. Run the following commands, adapt the PCAP_ROOT_DIR to where you have downloaded the npcap SDK. Also adapt to your desired configuration (debug/release).
mkdir build
cd build
& 'C:\Program Files\CMake\bin\cmake.exe' ../ -DPCAP_ROOT_DIR=<some-path>\npcap-sdk-1.05\ -DLIBTINS_ENABLE_WPA2=0 -DLIBTINS_BUILD_SHARED=off -DCMAKE_BUILD_TYPE=Release
& 'C:\Program Files\CMake\bin\cmake.exe' --build . --config Release
  • In the libtins source folder under .\build\lib\Release, you should now have a tins.lib.
  • Follow the instructions for Visual Studio given above, but adapt the paths for libtins to your self-compiled version:
    • For "Additional library directories", use e.g. <some-path>\libtins-master\build\lib\Release.
    • For "Additional include directories", use e.g. <some-path>\libtins-master\include.

Note that this will not enable all features of libtins. For that you would need to install additional dependencies (openssl, boost). The first cmake command should tell you which features have been enabled.

Upvotes: 6

Related Questions